Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion sdk/src/services/BackendWalletService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,7 @@ export class BackendWalletService {
*/
transactionHash: string;
/**
* An amount in native token (decimals allowed). Example: "1.5"
* An amount in native token (decimals allowed). Example: "0.1"
*/
amount: string;
};
Expand Down
22 changes: 15 additions & 7 deletions sdk/src/services/Erc1155Service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1743,17 +1743,21 @@ export class Erc1155Service {
xBackendWalletAddress: string,
requestBody: {
/**
* Address of the wallet to transfer to
* The recipient address.
*/
to: string;
/**
* the tokenId to transfer
* The token ID to transfer.
*/
tokenId: string;
/**
* the amount of tokens to transfer
* The amount of tokens to transfer.
*/
amount: string;
/**
* A valid hex string
*/
data?: string;
txOverrides?: {
/**
* Gas limit for the transaction
Expand Down Expand Up @@ -1838,21 +1842,25 @@ export class Erc1155Service {
xBackendWalletAddress: string,
requestBody: {
/**
* Address of the token owner
* The sender address.
*/
from: string;
/**
* Address of the wallet to transferFrom to
* The recipient address.
*/
to: string;
/**
* the tokenId to transferFrom
* The token ID to transfer.
*/
tokenId: string;
/**
* the amount of tokens to transfer
* The amount of tokens to transfer.
*/
amount: string;
/**
* A valid hex string
*/
data?: string;
txOverrides?: {
/**
* Gas limit for the transaction
Expand Down
12 changes: 6 additions & 6 deletions sdk/src/services/Erc20Service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -673,17 +673,17 @@ export class Erc20Service {
* @returns any Default Response
* @throws ApiError
*/
public erc20Transfer(
public transfer(
chain: string,
contractAddress: string,
xBackendWalletAddress: string,
requestBody: {
/**
* Address of the wallet you want to send the tokens to
* The recipient address.
*/
toAddress: string;
/**
* The amount of tokens you want to send
* The amount of tokens to transfer.
*/
amount: string;
txOverrides?: {
Expand Down Expand Up @@ -770,15 +770,15 @@ export class Erc20Service {
xBackendWalletAddress: string,
requestBody: {
/**
* Address of the wallet sending the tokens
* The sender address.
*/
fromAddress: string;
/**
* Address of the wallet you want to send the tokens to
* The recipient address.
*/
toAddress: string;
/**
* The amount of tokens you want to send
* The amount of tokens to transfer.
*/
amount: string;
txOverrides?: {
Expand Down
10 changes: 5 additions & 5 deletions sdk/src/services/Erc721Service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -735,11 +735,11 @@ export class Erc721Service {
xBackendWalletAddress: string,
requestBody: {
/**
* Address of the wallet to transfer to
* The recipient address.
*/
to: string;
/**
* The tokenId to transfer
* The token ID to transfer.
*/
tokenId: string;
txOverrides?: {
Expand Down Expand Up @@ -826,15 +826,15 @@ export class Erc721Service {
xBackendWalletAddress: string,
requestBody: {
/**
* Address of the token owner
* The sender address.
*/
from: string;
/**
* Address of the wallet to transferFrom to
* The recipient address.
*/
to: string;
/**
* the tokenId to transferFrom
* The token ID to transfer.
*/
tokenId: string;
txOverrides?: {
Expand Down
62 changes: 43 additions & 19 deletions src/server/routes/contract/extensions/erc1155/write/transfer.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import { Type, type Static } from "@sinclair/typebox";
import type { FastifyInstance } from "fastify";
import { StatusCodes } from "http-status-codes";
import { queueTx } from "../../../../../../db/transactions/queueTx";
import { getContract } from "../../../../../../utils/cache/getContract";
import { getContract, type Hex } from "thirdweb";
import { safeTransferFrom } from "thirdweb/extensions/erc1155";
import { getChain } from "../../../../../../utils/chain";
import { getChecksumAddress } from "../../../../../../utils/primitiveTypes";
import { thirdwebClient } from "../../../../../../utils/sdk";
import { queueTransaction } from "../../../../../../utils/transaction/queueTransation";
import { AddressSchema, HexSchema } from "../../../../../schemas/address";
import { NumberStringSchema } from "../../../../../schemas/number";
import {
erc1155ContractParamSchema,
requestQuerystringSchema,
Expand All @@ -16,15 +22,19 @@ import { getChainIdFromChain } from "../../../../../utils/chain";
// INPUTS
const requestSchema = erc1155ContractParamSchema;
const requestBodySchema = Type.Object({
to: Type.String({
description: "Address of the wallet to transfer to",
}),
to: {
...AddressSchema,
description: "The recipient address.",
},
tokenId: Type.String({
description: "the tokenId to transfer",
...NumberStringSchema,
description: "The token ID to transfer.",
}),
amount: Type.String({
description: "the amount of tokens to transfer",
...NumberStringSchema,
description: "The amount of tokens to transfer.",
}),
data: Type.Optional(HexSchema),
...txOverridesWithValueSchema.properties,
});

Expand Down Expand Up @@ -62,29 +72,43 @@ export async function erc1155transfer(fastify: FastifyInstance) {
handler: async (request, reply) => {
const { chain, contractAddress } = request.params;
const { simulateTx } = request.query;
const { to, tokenId, amount, txOverrides } = request.body;
const { to, tokenId, amount, data, txOverrides } = request.body;
const {
"x-backend-wallet-address": walletAddress,
"x-account-address": accountAddress,
"x-idempotency-key": idempotencyKey,
"x-account-factory-address": accountFactoryAddress,
"x-account-salt": accountSalt,
} = request.headers as Static<typeof walletWithAAHeaderSchema>;

const chainId = await getChainIdFromChain(chain);
const contract = await getContract({
chainId,
contractAddress,
walletAddress,
accountAddress,
client: thirdwebClient,
chain: await getChain(chainId),
address: contractAddress,
});
const tx = await contract.erc1155.transfer.prepare(to, tokenId, amount);

const queueId = await queueTx({
tx,
chainId,
simulateTx,
extension: "erc1155",
idempotencyKey,
const transaction = safeTransferFrom({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

safeTransferFrom can fail if the recipient is a contract that does not implement the onReceived hook. This is generally desirable behaviour, but could fail transfers to smart accounts that do not implement this method. Most smart accounts do implement this though, including ours I think, but would be best to confirm once.

contract,
from: getChecksumAddress(walletAddress),
to: getChecksumAddress(to),
tokenId: BigInt(tokenId),
value: BigInt(amount),
data: (data as Hex | undefined) ?? "0x",
});

const queueId = await queueTransaction({
transaction,
fromAddress: getChecksumAddress(walletAddress),
toAddress: getChecksumAddress(contractAddress),
Comment on lines +102 to +103
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Making sure the from/to here is always backend wallet -> contract (as opposed to above when building the transaction where from/to are the sender/recipient addresses).

accountAddress: getChecksumAddress(accountAddress),
accountFactoryAddress: getChecksumAddress(accountFactoryAddress),
accountSalt,
txOverrides,
idempotencyKey,
shouldSimulate: simulateTx,
functionName: "safeTransferFrom",
extension: "erc1155",
});

reply.status(StatusCodes.OK).send({
Expand Down
82 changes: 51 additions & 31 deletions src/server/routes/contract/extensions/erc1155/write/transferFrom.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import { Type, type Static } from "@sinclair/typebox";
import type { FastifyInstance } from "fastify";
import { StatusCodes } from "http-status-codes";
import { queueTx } from "../../../../../../db/transactions/queueTx";
import { getContract } from "../../../../../../utils/cache/getContract";
import { getContract, type Hex } from "thirdweb";
import { safeTransferFrom } from "thirdweb/extensions/erc1155";
import { getChain } from "../../../../../../utils/chain";
import { getChecksumAddress } from "../../../../../../utils/primitiveTypes";
import { thirdwebClient } from "../../../../../../utils/sdk";
import { queueTransaction } from "../../../../../../utils/transaction/queueTransation";
import { AddressSchema, HexSchema } from "../../../../../schemas/address";
import { NumberStringSchema } from "../../../../../schemas/number";
import {
erc1155ContractParamSchema,
requestQuerystringSchema,
Expand All @@ -16,18 +22,23 @@ import { getChainIdFromChain } from "../../../../../utils/chain";
// INPUTS
const requestSchema = erc1155ContractParamSchema;
const requestBodySchema = Type.Object({
from: Type.String({
description: "Address of the token owner",
}),
to: Type.String({
description: "Address of the wallet to transferFrom to",
}),
tokenId: Type.String({
description: "the tokenId to transferFrom",
}),
amount: Type.String({
description: "the amount of tokens to transfer",
}),
from: {
...AddressSchema,
description: "The sender address.",
},
to: {
...AddressSchema,
description: "The recipient address.",
},
tokenId: {
...NumberStringSchema,
description: "The token ID to transfer.",
},
amount: {
...NumberStringSchema,
description: "The amount of tokens to transfer.",
},
data: Type.Optional(HexSchema),
...txOverridesWithValueSchema.properties,
});

Expand Down Expand Up @@ -69,34 +80,43 @@ export async function erc1155transferFrom(fastify: FastifyInstance) {
handler: async (request, reply) => {
const { chain, contractAddress } = request.params;
const { simulateTx } = request.query;
const { from, to, tokenId, amount, txOverrides } = request.body;
const { from, to, tokenId, amount, data, txOverrides } = request.body;
const {
"x-backend-wallet-address": walletAddress,
"x-account-address": accountAddress,
"x-idempotency-key": idempotencyKey,
"x-account-factory-address": accountFactoryAddress,
"x-account-salt": accountSalt,
} = request.headers as Static<typeof walletWithAAHeaderSchema>;

const chainId = await getChainIdFromChain(chain);
const contract = await getContract({
chainId,
contractAddress,
walletAddress,
accountAddress,
client: thirdwebClient,
chain: await getChain(chainId),
address: contractAddress,
});
const tx = await contract.erc1155.transferFrom.prepare(
from,
to,
tokenId,
amount,
);

const queueId = await queueTx({
tx,
chainId,
simulateTx,
extension: "erc1155",
idempotencyKey,
const transaction = safeTransferFrom({
contract,
from: getChecksumAddress(from),
to: getChecksumAddress(to),
tokenId: BigInt(tokenId),
value: BigInt(amount),
data: (data as Hex | undefined) ?? "0x",
});

const queueId = await queueTransaction({
transaction,
fromAddress: getChecksumAddress(walletAddress),
toAddress: getChecksumAddress(contractAddress),
accountAddress: getChecksumAddress(accountAddress),
accountFactoryAddress: getChecksumAddress(accountFactoryAddress),
accountSalt,
txOverrides,
idempotencyKey,
shouldSimulate: simulateTx,
functionName: "safeTransferFrom",
extension: "erc1155",
});

reply.status(StatusCodes.OK).send({
Expand Down
Loading
Loading