thirdweb 5.105.19-nightly-8260af3a9258595b53f021a64a1e015791d33949-20250724000414 → 5.105.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/pay/buyWithCrypto/getQuote.js +8 -8
- package/dist/cjs/pay/buyWithCrypto/getQuote.js.map +1 -1
- package/dist/cjs/pay/buyWithCrypto/getTransfer.js +4 -4
- package/dist/cjs/pay/buyWithCrypto/getTransfer.js.map +1 -1
- package/dist/cjs/pay/buyWithFiat/getQuote.js +3 -3
- package/dist/cjs/pay/buyWithFiat/getQuote.js.map +1 -1
- package/dist/cjs/react/core/hooks/usePaymentMethods.js +2 -2
- package/dist/cjs/react/core/hooks/usePaymentMethods.js.map +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/cjs/version.js.map +1 -1
- package/dist/cjs/wallets/smart/lib/signing.js +26 -95
- package/dist/cjs/wallets/smart/lib/signing.js.map +1 -1
- package/dist/esm/pay/buyWithCrypto/getQuote.js +8 -8
- package/dist/esm/pay/buyWithCrypto/getQuote.js.map +1 -1
- package/dist/esm/pay/buyWithCrypto/getTransfer.js +4 -4
- package/dist/esm/pay/buyWithCrypto/getTransfer.js.map +1 -1
- package/dist/esm/pay/buyWithFiat/getQuote.js +3 -3
- package/dist/esm/pay/buyWithFiat/getQuote.js.map +1 -1
- package/dist/esm/react/core/hooks/usePaymentMethods.js +2 -2
- package/dist/esm/react/core/hooks/usePaymentMethods.js.map +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/esm/version.js.map +1 -1
- package/dist/esm/wallets/smart/lib/signing.js +27 -96
- package/dist/esm/wallets/smart/lib/signing.js.map +1 -1
- package/dist/types/version.d.ts +1 -1
- package/dist/types/version.d.ts.map +1 -1
- package/dist/types/wallets/smart/lib/signing.d.ts +2 -3
- package/dist/types/wallets/smart/lib/signing.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/pay/buyWithCrypto/getQuote.ts +8 -8
- package/src/pay/buyWithCrypto/getTransfer.ts +4 -4
- package/src/pay/buyWithFiat/getQuote.ts +3 -3
- package/src/react/core/hooks/usePaymentMethods.ts +2 -2
- package/src/version.ts +1 -1
- package/src/wallets/smart/lib/signing.ts +34 -121
- package/src/wallets/smart/smart-wallet-integration.test.ts +1 -76
|
@@ -1,20 +1,12 @@
|
|
|
1
1
|
import type * as ox__TypedData from "ox/TypedData";
|
|
2
2
|
import { serializeErc6492Signature } from "../../../auth/serialize-erc6492-signature.js";
|
|
3
|
-
import {
|
|
4
|
-
verifyEip1271Signature,
|
|
5
|
-
verifyHash,
|
|
6
|
-
} from "../../../auth/verify-hash.js";
|
|
3
|
+
import { verifyEip1271Signature } from "../../../auth/verify-hash.js";
|
|
7
4
|
import type { Chain } from "../../../chains/types.js";
|
|
8
5
|
import type { ThirdwebClient } from "../../../client/client.js";
|
|
9
|
-
import {
|
|
10
|
-
getContract,
|
|
11
|
-
type ThirdwebContract,
|
|
12
|
-
} from "../../../contract/contract.js";
|
|
6
|
+
import type { ThirdwebContract } from "../../../contract/contract.js";
|
|
13
7
|
import { encode } from "../../../transaction/actions/encode.js";
|
|
14
|
-
import { readContract } from "../../../transaction/read-contract.js";
|
|
15
8
|
import { encodeAbiParameters } from "../../../utils/abi/encodeAbiParameters.js";
|
|
16
9
|
import { isContractDeployed } from "../../../utils/bytecode/is-contract-deployed.js";
|
|
17
|
-
import type { Hex } from "../../../utils/encoding/hex.js";
|
|
18
10
|
import { hashMessage } from "../../../utils/hashing/hashMessage.js";
|
|
19
11
|
import { hashTypedData } from "../../../utils/hashing/hashTypedData.js";
|
|
20
12
|
import type { SignableMessage } from "../../../utils/types.js";
|
|
@@ -40,33 +32,24 @@ export async function smartAccountSignMessage({
|
|
|
40
32
|
message: SignableMessage;
|
|
41
33
|
}) {
|
|
42
34
|
const originalMsgHash = hashMessage(message);
|
|
43
|
-
const is712Factory = await checkFor712Factory({
|
|
44
|
-
accountContract,
|
|
45
|
-
factoryContract,
|
|
46
|
-
originalMsgHash,
|
|
47
|
-
});
|
|
48
35
|
|
|
49
36
|
let sig: `0x${string}`;
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
);
|
|
37
|
+
const wrappedMessageHash = encodeAbiParameters(
|
|
38
|
+
[{ type: "bytes32" }],
|
|
39
|
+
[originalMsgHash],
|
|
40
|
+
);
|
|
55
41
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
} else {
|
|
68
|
-
sig = await options.personalAccount.signMessage({ message });
|
|
69
|
-
}
|
|
42
|
+
sig = await options.personalAccount.signTypedData({
|
|
43
|
+
domain: {
|
|
44
|
+
chainId: options.chain.id,
|
|
45
|
+
name: "Account",
|
|
46
|
+
verifyingContract: accountContract.address,
|
|
47
|
+
version: "1",
|
|
48
|
+
},
|
|
49
|
+
message: { message: wrappedMessageHash },
|
|
50
|
+
primaryType: "AccountMessage",
|
|
51
|
+
types: { AccountMessage: [{ name: "message", type: "bytes" }] },
|
|
52
|
+
});
|
|
70
53
|
|
|
71
54
|
const isDeployed = await isContractDeployed(accountContract);
|
|
72
55
|
if (isDeployed) {
|
|
@@ -96,19 +79,7 @@ export async function smartAccountSignMessage({
|
|
|
96
79
|
signature: sig,
|
|
97
80
|
});
|
|
98
81
|
|
|
99
|
-
|
|
100
|
-
const isValid = await verifyHash({
|
|
101
|
-
address: accountContract.address,
|
|
102
|
-
chain: accountContract.chain,
|
|
103
|
-
client: accountContract.client,
|
|
104
|
-
hash: originalMsgHash,
|
|
105
|
-
signature: erc6492Sig,
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
if (isValid) {
|
|
109
|
-
return erc6492Sig;
|
|
110
|
-
}
|
|
111
|
-
throw new Error("Unable to verify ERC-6492 signature after signing.");
|
|
82
|
+
return erc6492Sig;
|
|
112
83
|
}
|
|
113
84
|
}
|
|
114
85
|
|
|
@@ -138,33 +109,23 @@ export async function smartAccountSignTypedData<
|
|
|
138
109
|
}
|
|
139
110
|
|
|
140
111
|
const originalMsgHash = hashTypedData(typedData);
|
|
141
|
-
// check if the account contract supports EIP721 domain separator based signing
|
|
142
|
-
const is712Factory = await checkFor712Factory({
|
|
143
|
-
accountContract,
|
|
144
|
-
factoryContract,
|
|
145
|
-
originalMsgHash,
|
|
146
|
-
});
|
|
147
112
|
|
|
148
113
|
let sig: `0x${string}`;
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
});
|
|
165
|
-
} else {
|
|
166
|
-
sig = await options.personalAccount.signTypedData(typedData);
|
|
167
|
-
}
|
|
114
|
+
const wrappedMessageHash = encodeAbiParameters(
|
|
115
|
+
[{ type: "bytes32" }],
|
|
116
|
+
[originalMsgHash],
|
|
117
|
+
);
|
|
118
|
+
sig = await options.personalAccount.signTypedData({
|
|
119
|
+
domain: {
|
|
120
|
+
chainId: options.chain.id,
|
|
121
|
+
name: "Account",
|
|
122
|
+
verifyingContract: accountContract.address,
|
|
123
|
+
version: "1",
|
|
124
|
+
},
|
|
125
|
+
message: { message: wrappedMessageHash },
|
|
126
|
+
primaryType: "AccountMessage",
|
|
127
|
+
types: { AccountMessage: [{ name: "message", type: "bytes" }] },
|
|
128
|
+
});
|
|
168
129
|
|
|
169
130
|
const isDeployed = await isContractDeployed(accountContract);
|
|
170
131
|
if (isDeployed) {
|
|
@@ -194,21 +155,7 @@ export async function smartAccountSignTypedData<
|
|
|
194
155
|
signature: sig,
|
|
195
156
|
});
|
|
196
157
|
|
|
197
|
-
|
|
198
|
-
const isValid = await verifyHash({
|
|
199
|
-
address: accountContract.address,
|
|
200
|
-
chain: accountContract.chain,
|
|
201
|
-
client: accountContract.client,
|
|
202
|
-
hash: originalMsgHash,
|
|
203
|
-
signature: erc6492Sig,
|
|
204
|
-
});
|
|
205
|
-
|
|
206
|
-
if (isValid) {
|
|
207
|
-
return erc6492Sig;
|
|
208
|
-
}
|
|
209
|
-
throw new Error(
|
|
210
|
-
"Unable to verify signature on smart account, please make sure the admin wallet has permissions and the signature is valid.",
|
|
211
|
-
);
|
|
158
|
+
return erc6492Sig;
|
|
212
159
|
}
|
|
213
160
|
}
|
|
214
161
|
|
|
@@ -233,40 +180,6 @@ export async function confirmContractDeployment(args: {
|
|
|
233
180
|
}
|
|
234
181
|
}
|
|
235
182
|
|
|
236
|
-
async function checkFor712Factory({
|
|
237
|
-
factoryContract,
|
|
238
|
-
accountContract,
|
|
239
|
-
originalMsgHash,
|
|
240
|
-
}: {
|
|
241
|
-
factoryContract: ThirdwebContract;
|
|
242
|
-
accountContract: ThirdwebContract;
|
|
243
|
-
originalMsgHash: Hex;
|
|
244
|
-
}) {
|
|
245
|
-
try {
|
|
246
|
-
const implementationAccount = await readContract({
|
|
247
|
-
contract: factoryContract,
|
|
248
|
-
method: "function accountImplementation() public view returns (address)",
|
|
249
|
-
});
|
|
250
|
-
// check if the account contract supports EIP721 domain separator or modular based signing
|
|
251
|
-
const is712Factory = await readContract({
|
|
252
|
-
contract: getContract({
|
|
253
|
-
address: implementationAccount,
|
|
254
|
-
chain: accountContract.chain,
|
|
255
|
-
client: accountContract.client,
|
|
256
|
-
}),
|
|
257
|
-
method:
|
|
258
|
-
"function getMessageHash(bytes32 _hash) public view returns (bytes32)",
|
|
259
|
-
params: [originalMsgHash],
|
|
260
|
-
})
|
|
261
|
-
.then((res) => res !== "0x")
|
|
262
|
-
.catch(() => false);
|
|
263
|
-
|
|
264
|
-
return is712Factory;
|
|
265
|
-
} catch {
|
|
266
|
-
return false;
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
|
|
270
183
|
/**
|
|
271
184
|
* Deployes a smart account via a dummy transaction. If the account is already deployed, this will do nothing.
|
|
272
185
|
*
|
|
@@ -47,7 +47,6 @@ const contract = getContract({
|
|
|
47
47
|
chain,
|
|
48
48
|
client,
|
|
49
49
|
});
|
|
50
|
-
const factoryAddress = "0x564cf6453a1b0FF8DB603E92EA4BbD410dea45F3"; // pre 712
|
|
51
50
|
|
|
52
51
|
describe.runIf(process.env.TW_SECRET_KEY).sequential(
|
|
53
52
|
"SmartWallet core tests",
|
|
@@ -301,79 +300,6 @@ describe.runIf(process.env.TW_SECRET_KEY).sequential(
|
|
|
301
300
|
expect(logs.some((l) => l.args.isAdmin)).toBe(true);
|
|
302
301
|
});
|
|
303
302
|
|
|
304
|
-
it("can use a different factory without replay protection", async () => {
|
|
305
|
-
const wallet = smartWallet({
|
|
306
|
-
chain,
|
|
307
|
-
factoryAddress: factoryAddress,
|
|
308
|
-
gasless: true,
|
|
309
|
-
});
|
|
310
|
-
|
|
311
|
-
// should not be able to switch chains before connecting
|
|
312
|
-
await expect(
|
|
313
|
-
wallet.switchChain(baseSepolia),
|
|
314
|
-
).rejects.toMatchInlineSnapshot(
|
|
315
|
-
"[Error: Cannot switch chain without a previous connection]",
|
|
316
|
-
);
|
|
317
|
-
|
|
318
|
-
const newAccount = await wallet.connect({ client, personalAccount });
|
|
319
|
-
const message = "hello world";
|
|
320
|
-
const signature = await newAccount.signMessage({ message });
|
|
321
|
-
const isValidV1 = await verifySignature({
|
|
322
|
-
address: newAccount.address,
|
|
323
|
-
chain,
|
|
324
|
-
client,
|
|
325
|
-
message,
|
|
326
|
-
signature,
|
|
327
|
-
});
|
|
328
|
-
expect(isValidV1).toEqual(true);
|
|
329
|
-
|
|
330
|
-
// sign typed data
|
|
331
|
-
const signatureTyped = await newAccount.signTypedData({
|
|
332
|
-
...typedData.basic,
|
|
333
|
-
primaryType: "Mail",
|
|
334
|
-
});
|
|
335
|
-
const isValidV2 = await verifyTypedData({
|
|
336
|
-
address: newAccount.address,
|
|
337
|
-
chain,
|
|
338
|
-
client,
|
|
339
|
-
signature: signatureTyped,
|
|
340
|
-
...typedData.basic,
|
|
341
|
-
});
|
|
342
|
-
expect(isValidV2).toEqual(true);
|
|
343
|
-
|
|
344
|
-
// add admin pre-deployment
|
|
345
|
-
const newAdmin = await generateAccount({ client });
|
|
346
|
-
const receipt = await sendAndConfirmTransaction({
|
|
347
|
-
account: newAccount,
|
|
348
|
-
transaction: addAdmin({
|
|
349
|
-
account: newAccount,
|
|
350
|
-
adminAddress: newAdmin.address,
|
|
351
|
-
contract: getContract({
|
|
352
|
-
address: newAccount.address,
|
|
353
|
-
chain,
|
|
354
|
-
client,
|
|
355
|
-
}),
|
|
356
|
-
}),
|
|
357
|
-
});
|
|
358
|
-
const logs = parseEventLogs({
|
|
359
|
-
events: [adminUpdatedEvent()],
|
|
360
|
-
logs: receipt.logs,
|
|
361
|
-
});
|
|
362
|
-
expect(logs.map((l) => l.args.signer)).toContain(newAdmin.address);
|
|
363
|
-
expect(logs.map((l) => l.args.isAdmin)).toContain(true);
|
|
364
|
-
|
|
365
|
-
// should not be able to switch chains since factory not deployed elsewhere
|
|
366
|
-
await expect(
|
|
367
|
-
wallet.switchChain(baseSepolia),
|
|
368
|
-
).rejects.toMatchInlineSnapshot(
|
|
369
|
-
"[Error: Factory contract not deployed on chain: 84532]",
|
|
370
|
-
);
|
|
371
|
-
|
|
372
|
-
// check can disconnnect
|
|
373
|
-
await wallet.disconnect();
|
|
374
|
-
expect(wallet.getAccount()).toBeUndefined();
|
|
375
|
-
});
|
|
376
|
-
|
|
377
303
|
it("can switch chains", async () => {
|
|
378
304
|
await wallet.switchChain(baseSepolia);
|
|
379
305
|
expect(wallet.getChain()?.id).toEqual(baseSepolia.id);
|
|
@@ -424,7 +350,7 @@ describe.runIf(process.env.TW_SECRET_KEY).sequential(
|
|
|
424
350
|
tokenId: 0n,
|
|
425
351
|
}),
|
|
426
352
|
}),
|
|
427
|
-
sleep(
|
|
353
|
+
sleep(1500).then(() =>
|
|
428
354
|
sendAndConfirmTransaction({
|
|
429
355
|
account: newSmartAccount,
|
|
430
356
|
transaction: claimTo({
|
|
@@ -453,7 +379,6 @@ describe.runIf(process.env.TW_SECRET_KEY).sequential(
|
|
|
453
379
|
it("can use a different paymaster", async () => {
|
|
454
380
|
const wallet = smartWallet({
|
|
455
381
|
chain,
|
|
456
|
-
factoryAddress: factoryAddress,
|
|
457
382
|
gasless: true,
|
|
458
383
|
overrides: {
|
|
459
384
|
paymaster: async () => {
|