@@ -9,11 +9,15 @@ import {
9
9
type Address ,
10
10
} from "thirdweb" ;
11
11
import { transfer as transferERC20 } from "thirdweb/extensions/erc20" ;
12
- import { isContractDeployed , resolvePromisedValue } from "thirdweb/utils" ;
12
+ import { isContractDeployed } from "thirdweb/utils" ;
13
13
import { getChain } from "../../../shared/utils/chain" ;
14
- import { normalizeAddress } from "../../../shared/utils/primitive-types" ;
14
+ import {
15
+ getChecksumAddress ,
16
+ normalizeAddress ,
17
+ } from "../../../shared/utils/primitive-types" ;
15
18
import { thirdwebClient } from "../../../shared/utils/sdk" ;
16
19
import { insertTransaction } from "../../../shared/utils/transaction/insert-transaction" ;
20
+ import { queueTransaction } from "../../../shared/utils/transaction/queue-transation" ;
17
21
import type { InsertedTransaction } from "../../../shared/utils/transaction/types" ;
18
22
import { createCustomError } from "../../middleware/error" ;
19
23
import { AddressSchema } from "../../schemas/address" ;
@@ -25,7 +29,7 @@ import {
25
29
} from "../../schemas/shared-api-schemas" ;
26
30
import { txOverridesWithValueSchema } from "../../schemas/tx-overrides" ;
27
31
import {
28
- walletHeaderSchema ,
32
+ walletWithAAHeaderSchema ,
29
33
walletWithAddressParamSchema ,
30
34
} from "../../schemas/wallet" ;
31
35
import { getChainIdFromChain } from "../../utils/chain" ;
@@ -70,7 +74,7 @@ export async function transfer(fastify: FastifyInstance) {
70
74
operationId : "transfer" ,
71
75
params : requestSchema ,
72
76
body : requestBodySchema ,
73
- headers : walletHeaderSchema ,
77
+ headers : walletWithAAHeaderSchema ,
74
78
querystring : requestQuerystringSchema ,
75
79
response : {
76
80
...standardResponseSchema ,
@@ -88,31 +92,50 @@ export async function transfer(fastify: FastifyInstance) {
88
92
const {
89
93
"x-backend-wallet-address" : walletAddress ,
90
94
"x-idempotency-key" : idempotencyKey ,
95
+ "x-account-address" : accountAddress ,
96
+ "x-account-factory-address" : accountFactoryAddress ,
97
+ "x-account-salt" : accountSalt ,
91
98
"x-transaction-mode" : transactionMode ,
92
- } = request . headers as Static < typeof walletHeaderSchema > ;
99
+ } = request . headers as Static < typeof walletWithAAHeaderSchema > ;
93
100
const { simulateTx : shouldSimulate } = request . query ;
94
101
95
102
// Resolve inputs.
96
103
const currencyAddress = normalizeAddress ( _currencyAddress ) ;
97
104
const chainId = await getChainIdFromChain ( chain ) ;
98
105
99
- let insertedTransaction : InsertedTransaction ;
106
+ let queueId : string ;
100
107
if (
101
108
currencyAddress === ZERO_ADDRESS ||
102
109
currencyAddress === NATIVE_TOKEN_ADDRESS
103
110
) {
104
- insertedTransaction = {
105
- isUserOp : false ,
111
+ // Native token transfer - use insertTransaction directly
112
+ const insertedTransaction : InsertedTransaction = {
106
113
chainId,
107
114
from : walletAddress as Address ,
108
115
to : to as Address ,
109
116
data : "0x" ,
110
117
value : toWei ( amount ) ,
111
- extension : "none" ,
112
- functionName : "transfer" ,
113
118
transactionMode,
114
119
...parseTransactionOverrides ( txOverrides ) ,
120
+ ...( accountAddress
121
+ ? {
122
+ isUserOp : true ,
123
+ accountAddress : getChecksumAddress ( accountAddress ) ,
124
+ signerAddress : getChecksumAddress ( walletAddress ) ,
125
+ target : getChecksumAddress ( to ) ,
126
+ accountFactoryAddress : getChecksumAddress (
127
+ accountFactoryAddress ,
128
+ ) ,
129
+ accountSalt,
130
+ }
131
+ : { isUserOp : false } ) ,
115
132
} ;
133
+
134
+ queueId = await insertTransaction ( {
135
+ insertedTransaction,
136
+ idempotencyKey,
137
+ shouldSimulate,
138
+ } ) ;
116
139
} else {
117
140
const contract = getContract ( {
118
141
client : thirdwebClient ,
@@ -131,31 +154,25 @@ export async function transfer(fastify: FastifyInstance) {
131
154
) ;
132
155
}
133
156
157
+ // ERC20 token transfer - use queueTransaction with PreparedTransaction
134
158
const transaction = transferERC20 ( { contract, to, amount } ) ;
135
159
136
- insertedTransaction = {
137
- isUserOp : false ,
138
- chainId ,
139
- from : walletAddress as Address ,
140
- to : ( await resolvePromisedValue ( transaction . to ) ) as
141
- | Address
142
- | undefined ,
143
- data : await resolvePromisedValue ( transaction . data ) ,
144
- value : 0n ,
145
- extension : "erc20" ,
160
+ queueId = await queueTransaction ( {
161
+ transaction ,
162
+ fromAddress : getChecksumAddress ( walletAddress ) ,
163
+ toAddress : getChecksumAddress ( to ) ,
164
+ accountAddress : getChecksumAddress ( accountAddress ) ,
165
+ accountFactoryAddress : getChecksumAddress ( accountFactoryAddress ) ,
166
+ accountSalt ,
167
+ txOverrides ,
168
+ idempotencyKey ,
169
+ shouldSimulate ,
146
170
functionName : "transfer" ,
147
- functionArgs : [ to , amount , currencyAddress ] ,
171
+ extension : "erc20" ,
148
172
transactionMode,
149
- ...parseTransactionOverrides ( txOverrides ) ,
150
- } ;
173
+ } ) ;
151
174
}
152
175
153
- const queueId = await insertTransaction ( {
154
- insertedTransaction,
155
- idempotencyKey,
156
- shouldSimulate,
157
- } ) ;
158
-
159
176
reply . status ( StatusCodes . OK ) . send ( {
160
177
result : {
161
178
queueId,
0 commit comments