thirdweb 5.105.20 → 5.105.22
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/extensions/erc1155/read/getOwnedNFTs.js +1 -0
- package/dist/cjs/extensions/erc1155/read/getOwnedNFTs.js.map +1 -1
- package/dist/cjs/extensions/erc721/read/getOwnedNFTs.js +1 -0
- package/dist/cjs/extensions/erc721/read/getOwnedNFTs.js.map +1 -1
- package/dist/cjs/insight/get-nfts.js +3 -3
- package/dist/cjs/insight/get-nfts.js.map +1 -1
- package/dist/cjs/insight/get-tokens.js +3 -2
- package/dist/cjs/insight/get-tokens.js.map +1 -1
- package/dist/cjs/react/core/hooks/wallets/useConnect.js +10 -1
- package/dist/cjs/react/core/hooks/wallets/useConnect.js.map +1 -1
- package/dist/cjs/transaction/actions/estimate-gas.js +3 -24
- package/dist/cjs/transaction/actions/estimate-gas.js.map +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/cjs/wallets/coinbase/coinbase-web.js +56 -0
- package/dist/cjs/wallets/coinbase/coinbase-web.js.map +1 -1
- package/dist/cjs/wallets/create-wallet.js +62 -13
- package/dist/cjs/wallets/create-wallet.js.map +1 -1
- package/dist/cjs/wallets/eip5792/get-calls-status.js +40 -63
- package/dist/cjs/wallets/eip5792/get-calls-status.js.map +1 -1
- package/dist/cjs/wallets/eip5792/get-capabilities.js +14 -49
- package/dist/cjs/wallets/eip5792/get-capabilities.js.map +1 -1
- package/dist/cjs/wallets/eip5792/send-calls.js +34 -48
- package/dist/cjs/wallets/eip5792/send-calls.js.map +1 -1
- package/dist/cjs/wallets/in-app/core/{eip5972 → eip5792}/in-app-wallet-calls.js +1 -5
- package/dist/cjs/wallets/in-app/core/eip5792/in-app-wallet-calls.js.map +1 -0
- package/dist/cjs/wallets/in-app/core/eip7702/minimal-account.js +650 -5
- package/dist/cjs/wallets/in-app/core/eip7702/minimal-account.js.map +1 -1
- package/dist/cjs/wallets/in-app/core/wallet/enclave-wallet.js +32 -1
- package/dist/cjs/wallets/in-app/core/wallet/enclave-wallet.js.map +1 -1
- package/dist/cjs/wallets/in-app/core/wallet/in-app-core.js +3 -3
- package/dist/cjs/wallets/in-app/core/wallet/in-app-core.js.map +1 -1
- package/dist/cjs/wallets/in-app/web/in-app.js +18 -0
- package/dist/cjs/wallets/in-app/web/in-app.js.map +1 -1
- package/dist/cjs/wallets/injected/index.js +55 -0
- package/dist/cjs/wallets/injected/index.js.map +1 -1
- package/dist/cjs/wallets/smart/index.js +63 -2
- package/dist/cjs/wallets/smart/index.js.map +1 -1
- package/dist/cjs/wallets/smart/smart-wallet.js +1 -1
- package/dist/cjs/wallets/smart/smart-wallet.js.map +1 -1
- package/dist/cjs/wallets/wallet-connect/qr-overlay.js +231 -0
- package/dist/cjs/wallets/wallet-connect/qr-overlay.js.map +1 -0
- package/dist/esm/extensions/erc1155/read/getOwnedNFTs.js +1 -0
- package/dist/esm/extensions/erc1155/read/getOwnedNFTs.js.map +1 -1
- package/dist/esm/extensions/erc721/read/getOwnedNFTs.js +1 -0
- package/dist/esm/extensions/erc721/read/getOwnedNFTs.js.map +1 -1
- package/dist/esm/insight/get-nfts.js +3 -3
- package/dist/esm/insight/get-nfts.js.map +1 -1
- package/dist/esm/insight/get-tokens.js +3 -2
- package/dist/esm/insight/get-tokens.js.map +1 -1
- package/dist/esm/react/core/hooks/wallets/useConnect.js +10 -1
- package/dist/esm/react/core/hooks/wallets/useConnect.js.map +1 -1
- package/dist/esm/transaction/actions/estimate-gas.js +3 -24
- package/dist/esm/transaction/actions/estimate-gas.js.map +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/esm/wallets/coinbase/coinbase-web.js +56 -0
- package/dist/esm/wallets/coinbase/coinbase-web.js.map +1 -1
- package/dist/esm/wallets/create-wallet.js +62 -13
- package/dist/esm/wallets/create-wallet.js.map +1 -1
- package/dist/esm/wallets/eip5792/get-calls-status.js +39 -63
- package/dist/esm/wallets/eip5792/get-calls-status.js.map +1 -1
- package/dist/esm/wallets/eip5792/get-capabilities.js +13 -49
- package/dist/esm/wallets/eip5792/get-capabilities.js.map +1 -1
- package/dist/esm/wallets/eip5792/send-calls.js +33 -48
- package/dist/esm/wallets/eip5792/send-calls.js.map +1 -1
- package/dist/esm/wallets/in-app/core/{eip5972 → eip5792}/in-app-wallet-calls.js +1 -5
- package/dist/esm/wallets/in-app/core/eip5792/in-app-wallet-calls.js.map +1 -0
- package/dist/esm/wallets/in-app/core/eip7702/minimal-account.js +650 -5
- package/dist/esm/wallets/in-app/core/eip7702/minimal-account.js.map +1 -1
- package/dist/esm/wallets/in-app/core/wallet/enclave-wallet.js +32 -1
- package/dist/esm/wallets/in-app/core/wallet/enclave-wallet.js.map +1 -1
- package/dist/esm/wallets/in-app/core/wallet/in-app-core.js +3 -3
- package/dist/esm/wallets/in-app/core/wallet/in-app-core.js.map +1 -1
- package/dist/esm/wallets/in-app/web/in-app.js +18 -0
- package/dist/esm/wallets/in-app/web/in-app.js.map +1 -1
- package/dist/esm/wallets/injected/index.js +56 -1
- package/dist/esm/wallets/injected/index.js.map +1 -1
- package/dist/esm/wallets/smart/index.js +63 -2
- package/dist/esm/wallets/smart/index.js.map +1 -1
- package/dist/esm/wallets/smart/smart-wallet.js +1 -1
- package/dist/esm/wallets/smart/smart-wallet.js.map +1 -1
- package/dist/esm/wallets/wallet-connect/qr-overlay.js +228 -0
- package/dist/esm/wallets/wallet-connect/qr-overlay.js.map +1 -0
- package/dist/types/bridge/Webhook.d.ts +2 -2
- package/dist/types/insight/get-nfts.d.ts +1 -0
- package/dist/types/insight/get-nfts.d.ts.map +1 -1
- package/dist/types/insight/get-tokens.d.ts +1 -0
- package/dist/types/insight/get-tokens.d.ts.map +1 -1
- package/dist/types/react/core/hooks/wallets/useConnect.d.ts +1 -0
- package/dist/types/react/core/hooks/wallets/useConnect.d.ts.map +1 -1
- package/dist/types/react/core/hooks/wallets/useWaitForCallsReceipt.d.ts +1 -1
- package/dist/types/react/core/utils/storage.d.ts +1 -1
- package/dist/types/react/web/utils/storage.d.ts +1 -1
- package/dist/types/transaction/actions/estimate-gas.d.ts.map +1 -1
- package/dist/types/version.d.ts +1 -1
- package/dist/types/wallets/coinbase/coinbase-web.d.ts.map +1 -1
- package/dist/types/wallets/create-wallet.d.ts.map +1 -1
- package/dist/types/wallets/eip5792/get-calls-status.d.ts +2 -1
- package/dist/types/wallets/eip5792/get-calls-status.d.ts.map +1 -1
- package/dist/types/wallets/eip5792/get-capabilities.d.ts +1 -0
- package/dist/types/wallets/eip5792/get-capabilities.d.ts.map +1 -1
- package/dist/types/wallets/eip5792/send-calls.d.ts +6 -1
- package/dist/types/wallets/eip5792/send-calls.d.ts.map +1 -1
- package/dist/types/wallets/in-app/core/{eip5972 → eip5792}/in-app-wallet-calls.d.ts +3 -2
- package/dist/types/wallets/in-app/core/eip5792/in-app-wallet-calls.d.ts.map +1 -0
- package/dist/types/wallets/in-app/core/eip7702/minimal-account.d.ts.map +1 -1
- package/dist/types/wallets/in-app/core/wallet/enclave-wallet.d.ts.map +1 -1
- package/dist/types/wallets/in-app/web/in-app.d.ts +18 -0
- package/dist/types/wallets/in-app/web/in-app.d.ts.map +1 -1
- package/dist/types/wallets/injected/index.d.ts.map +1 -1
- package/dist/types/wallets/interfaces/wallet.d.ts +22 -0
- package/dist/types/wallets/interfaces/wallet.d.ts.map +1 -1
- package/dist/types/wallets/smart/index.d.ts.map +1 -1
- package/dist/types/wallets/wallet-connect/qr-overlay.d.ts +58 -0
- package/dist/types/wallets/wallet-connect/qr-overlay.d.ts.map +1 -0
- package/dist/types/wallets/wallet-connect/types.d.ts +13 -0
- package/dist/types/wallets/wallet-connect/types.d.ts.map +1 -1
- package/package.json +4 -2
- package/src/extensions/erc1155/read/getOwnedNFTs.ts +1 -0
- package/src/extensions/erc721/read/getOwnedNFTs.ts +1 -0
- package/src/insight/get-nfts.ts +4 -3
- package/src/insight/get-tokens.ts +4 -2
- package/src/react/core/hooks/wallets/useConnect.ts +11 -1
- package/src/transaction/actions/estimate-gas.ts +14 -42
- package/src/version.ts +1 -1
- package/src/wallets/coinbase/coinbase-web.ts +66 -0
- package/src/wallets/create-wallet.ts +85 -24
- package/src/wallets/eip5792/get-calls-status.test.ts +156 -146
- package/src/wallets/eip5792/get-calls-status.ts +44 -73
- package/src/wallets/eip5792/get-capabilities.test.ts +216 -205
- package/src/wallets/eip5792/get-capabilities.ts +23 -64
- package/src/wallets/eip5792/send-calls.test.ts +183 -189
- package/src/wallets/eip5792/send-calls.ts +53 -71
- package/src/wallets/in-app/core/{eip5972 → eip5792}/in-app-wallet-calls.ts +4 -8
- package/src/wallets/in-app/core/eip7702/minimal-account.ts +666 -5
- package/src/wallets/in-app/core/wallet/enclave-wallet.ts +36 -1
- package/src/wallets/in-app/core/wallet/in-app-core.ts +4 -4
- package/src/wallets/in-app/web/in-app.ts +18 -0
- package/src/wallets/injected/index.ts +63 -0
- package/src/wallets/interfaces/wallet.ts +31 -0
- package/src/wallets/smart/index.ts +71 -3
- package/src/wallets/smart/smart-wallet.ts +1 -1
- package/src/wallets/wallet-connect/qr-overlay.ts +322 -0
- package/src/wallets/wallet-connect/types.ts +13 -0
- package/dist/cjs/wallets/in-app/core/eip5972/in-app-wallet-calls.js.map +0 -1
- package/dist/cjs/wallets/in-app/core/eip5972/in-app-wallet-capabilities.js +0 -41
- package/dist/cjs/wallets/in-app/core/eip5972/in-app-wallet-capabilities.js.map +0 -1
- package/dist/cjs/wallets/smart/lib/smart-wallet-capabilities.js +0 -30
- package/dist/cjs/wallets/smart/lib/smart-wallet-capabilities.js.map +0 -1
- package/dist/esm/wallets/in-app/core/eip5972/in-app-wallet-calls.js.map +0 -1
- package/dist/esm/wallets/in-app/core/eip5972/in-app-wallet-capabilities.js +0 -38
- package/dist/esm/wallets/in-app/core/eip5972/in-app-wallet-capabilities.js.map +0 -1
- package/dist/esm/wallets/smart/lib/smart-wallet-capabilities.js +0 -27
- package/dist/esm/wallets/smart/lib/smart-wallet-capabilities.js.map +0 -1
- package/dist/types/wallets/in-app/core/eip5972/in-app-wallet-calls.d.ts.map +0 -1
- package/dist/types/wallets/in-app/core/eip5972/in-app-wallet-capabilities.d.ts +0 -20
- package/dist/types/wallets/in-app/core/eip5972/in-app-wallet-capabilities.d.ts.map +0 -1
- package/dist/types/wallets/smart/lib/smart-wallet-capabilities.d.ts +0 -20
- package/dist/types/wallets/smart/lib/smart-wallet-capabilities.d.ts.map +0 -1
- package/src/wallets/in-app/core/eip5972/in-app-wallet-capabilities.ts +0 -47
- package/src/wallets/smart/lib/smart-wallet-capabilities.ts +0 -32
|
@@ -1,20 +1,15 @@
|
|
|
1
1
|
import { afterEach } from "node:test";
|
|
2
|
-
import {
|
|
2
|
+
import { describe, expect, test, vi } from "vitest";
|
|
3
3
|
import {
|
|
4
4
|
ANVIL_CHAIN,
|
|
5
5
|
FORKED_ETHEREUM_CHAIN,
|
|
6
6
|
} from "../../../test/src/chains.js";
|
|
7
7
|
import { TEST_CLIENT } from "../../../test/src/test-clients.js";
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
TEST_ACCOUNT_A,
|
|
11
|
-
TEST_ACCOUNT_B,
|
|
12
|
-
TEST_ACCOUNT_C,
|
|
13
|
-
} from "../../../test/src/test-wallets.js";
|
|
8
|
+
import { TEST_ACCOUNT_A } from "../../../test/src/test-wallets.js";
|
|
14
9
|
import { sepolia } from "../../exports/chains.js";
|
|
15
|
-
import { approve } from "../../exports/extensions/erc20.js";
|
|
16
10
|
import { prepareTransaction } from "../../transaction/prepare-transaction.js";
|
|
17
11
|
import { numberToHex } from "../../utils/encoding/hex.js";
|
|
12
|
+
import { stringify } from "../../utils/json.js";
|
|
18
13
|
import { METAMASK } from "../constants.js";
|
|
19
14
|
import { createWallet } from "../create-wallet.js";
|
|
20
15
|
import type { Wallet } from "../interfaces/wallet.js";
|
|
@@ -35,167 +30,153 @@ const SEND_CALLS_OPTIONS: Omit<SendCallsOptions, "wallet"> = {
|
|
|
35
30
|
),
|
|
36
31
|
};
|
|
37
32
|
|
|
38
|
-
const RAW_UNSUPPORTED_ERROR = {
|
|
39
|
-
code: -32601,
|
|
40
|
-
message: "some nonsense the wallet sends us about not supporting",
|
|
41
|
-
};
|
|
42
|
-
|
|
43
33
|
const mocks = vi.hoisted(() => ({
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
sendAndConfirmTransaction: vi.fn(),
|
|
47
|
-
sendBatchTransaction: vi.fn(),
|
|
34
|
+
sendCalls: vi.fn(),
|
|
35
|
+
inAppWalletSendCalls: vi.fn(),
|
|
48
36
|
}));
|
|
49
37
|
|
|
50
|
-
|
|
38
|
+
// Mock the in-app wallet calls implementation
|
|
39
|
+
vi.mock("../in-app/core/eip5792/in-app-wallet-calls.js", () => {
|
|
51
40
|
return {
|
|
52
|
-
|
|
53
|
-
request: mocks.injectedRequest,
|
|
54
|
-
}),
|
|
41
|
+
inAppWalletSendCalls: mocks.inAppWalletSendCalls,
|
|
55
42
|
};
|
|
56
43
|
});
|
|
57
44
|
|
|
58
|
-
|
|
59
|
-
return {
|
|
60
|
-
sendAndConfirmTransaction:
|
|
61
|
-
mocks.sendAndConfirmTransaction.mockResolvedValue({
|
|
62
|
-
transactionHash:
|
|
63
|
-
"0x9b7bb827c2e5e3c1a0a44dc53e573aa0b3af3bd1f9f5ed03071b100bb039eaff",
|
|
64
|
-
}),
|
|
65
|
-
};
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
vi.mock("../../transaction/actions/send-batch-transaction.js", () => {
|
|
69
|
-
return {
|
|
70
|
-
sendBatchTransaction: mocks.sendBatchTransaction.mockResolvedValue({
|
|
71
|
-
transactionHash:
|
|
72
|
-
"0x9b7bb827c2e5e3c1a0a44dc53e573aa0b3af3bd1f9f5ed03071b100bb039eaff",
|
|
73
|
-
}),
|
|
74
|
-
};
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
describe.sequential("injected wallet", () => {
|
|
45
|
+
describe.sequential("sendCalls general", () => {
|
|
78
46
|
const wallet: Wallet = createWallet(METAMASK);
|
|
79
47
|
|
|
80
|
-
beforeAll(() => {
|
|
81
|
-
mocks.injectedRequest.mockResolvedValue("0x123456");
|
|
82
|
-
});
|
|
83
|
-
|
|
84
48
|
afterEach(() => {
|
|
85
49
|
vi.clearAllMocks();
|
|
86
50
|
});
|
|
87
51
|
|
|
88
|
-
test("with no
|
|
89
|
-
wallet.getChain = vi.fn().mockReturnValue(
|
|
90
|
-
wallet.getAccount = vi.fn().mockReturnValue(
|
|
52
|
+
test("with no account should fail to send calls", async () => {
|
|
53
|
+
wallet.getChain = vi.fn().mockReturnValue(ANVIL_CHAIN);
|
|
54
|
+
wallet.getAccount = vi.fn().mockReturnValue(undefined);
|
|
91
55
|
|
|
92
56
|
const promise = sendCalls({ wallet, ...SEND_CALLS_OPTIONS });
|
|
93
57
|
await expect(promise).rejects.toMatchInlineSnapshot(
|
|
94
|
-
"[Error: Cannot send calls, no
|
|
58
|
+
"[Error: Cannot send calls, no account connected for wallet: io.metamask]",
|
|
95
59
|
);
|
|
96
60
|
});
|
|
97
61
|
|
|
98
|
-
test("
|
|
62
|
+
test("without sendCalls support should fail", async () => {
|
|
99
63
|
wallet.getChain = vi.fn().mockReturnValue(ANVIL_CHAIN);
|
|
100
|
-
wallet.getAccount = vi.fn().mockReturnValue(
|
|
64
|
+
wallet.getAccount = vi.fn().mockReturnValue({
|
|
65
|
+
...TEST_ACCOUNT_A,
|
|
66
|
+
// no sendCalls method
|
|
67
|
+
});
|
|
101
68
|
|
|
102
69
|
const promise = sendCalls({ wallet, ...SEND_CALLS_OPTIONS });
|
|
103
70
|
await expect(promise).rejects.toMatchInlineSnapshot(
|
|
104
|
-
"[Error: Cannot send calls,
|
|
71
|
+
"[Error: Cannot send calls, wallet io.metamask does not support EIP-5792]",
|
|
105
72
|
);
|
|
106
73
|
});
|
|
107
74
|
|
|
108
|
-
test("should
|
|
75
|
+
test("should delegate to account.sendCalls", async () => {
|
|
76
|
+
const mockAccount = {
|
|
77
|
+
...TEST_ACCOUNT_A,
|
|
78
|
+
sendCalls: mocks.sendCalls.mockResolvedValue({
|
|
79
|
+
id: "0x123456",
|
|
80
|
+
client: TEST_CLIENT,
|
|
81
|
+
chain: ANVIL_CHAIN,
|
|
82
|
+
}),
|
|
83
|
+
};
|
|
84
|
+
|
|
109
85
|
wallet.getChain = vi.fn().mockReturnValue(ANVIL_CHAIN);
|
|
110
|
-
wallet.getAccount = vi.fn().mockReturnValue(
|
|
86
|
+
wallet.getAccount = vi.fn().mockReturnValue(mockAccount);
|
|
111
87
|
|
|
112
88
|
const result = await sendCalls({ wallet, ...SEND_CALLS_OPTIONS });
|
|
113
89
|
|
|
114
90
|
expect(result.id).toEqual("0x123456");
|
|
115
|
-
expect(
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
{
|
|
119
|
-
atomicRequired: false,
|
|
120
|
-
calls: [
|
|
121
|
-
{
|
|
122
|
-
data: "0xabcdef",
|
|
123
|
-
to: "0x2a4f24F935Eb178e3e7BA9B53A5Ee6d8407C0709",
|
|
124
|
-
value: undefined,
|
|
125
|
-
},
|
|
126
|
-
{
|
|
127
|
-
data: "0x",
|
|
128
|
-
to: "0xa922b54716264130634d6ff183747a8ead91a40b",
|
|
129
|
-
value: numberToHex(123n),
|
|
130
|
-
},
|
|
131
|
-
],
|
|
132
|
-
capabilities: undefined,
|
|
133
|
-
chainId: numberToHex(ANVIL_CHAIN.id),
|
|
134
|
-
from: TEST_ACCOUNT_A.address,
|
|
135
|
-
version: "2.0.0",
|
|
136
|
-
},
|
|
137
|
-
],
|
|
91
|
+
expect(result.wallet).toBe(wallet);
|
|
92
|
+
expect(mocks.sendCalls).toHaveBeenCalledWith({
|
|
93
|
+
calls: SEND_CALLS_OPTIONS.calls,
|
|
138
94
|
});
|
|
139
95
|
});
|
|
140
96
|
|
|
141
|
-
test("should
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
}
|
|
150
|
-
const preparedTx2 = approve({
|
|
151
|
-
amount: 100,
|
|
152
|
-
contract: USDT_CONTRACT,
|
|
153
|
-
spender: TEST_ACCOUNT_C.address,
|
|
154
|
-
});
|
|
97
|
+
test("should switch chain if needed", async () => {
|
|
98
|
+
const mockAccount = {
|
|
99
|
+
...TEST_ACCOUNT_A,
|
|
100
|
+
sendCalls: mocks.sendCalls.mockResolvedValue({
|
|
101
|
+
id: "0x123456",
|
|
102
|
+
client: TEST_CLIENT,
|
|
103
|
+
chain: sepolia,
|
|
104
|
+
}),
|
|
105
|
+
};
|
|
155
106
|
|
|
156
|
-
const
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
});
|
|
107
|
+
const switchChainMock = vi.fn();
|
|
108
|
+
wallet.getChain = vi.fn().mockReturnValue(ANVIL_CHAIN);
|
|
109
|
+
wallet.getAccount = vi.fn().mockReturnValue(mockAccount);
|
|
110
|
+
wallet.switchChain = switchChainMock;
|
|
161
111
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
params: [
|
|
112
|
+
// Create calls with sepolia chain to trigger chain switch
|
|
113
|
+
const sepoliaCallsOptions = {
|
|
114
|
+
calls: [
|
|
166
115
|
{
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
116
|
+
data: "0xabcdef" as const,
|
|
117
|
+
to: "0x2a4f24F935Eb178e3e7BA9B53A5Ee6d8407C0709",
|
|
118
|
+
},
|
|
119
|
+
].map((call) =>
|
|
120
|
+
prepareTransaction({ ...call, chain: sepolia, client: TEST_CLIENT }),
|
|
121
|
+
),
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
await sendCalls({ wallet, ...sepoliaCallsOptions });
|
|
125
|
+
|
|
126
|
+
expect(switchChainMock).toHaveBeenCalledWith(sepolia);
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
describe.sequential("injected wallet account.sendCalls", () => {
|
|
131
|
+
// These tests verify the behavior of the sendCalls method on injected wallet accounts
|
|
132
|
+
// The actual implementation is in packages/thirdweb/src/wallets/injected/index.ts
|
|
133
|
+
|
|
134
|
+
test("should handle successful sendCalls", async () => {
|
|
135
|
+
const mockProvider = {
|
|
136
|
+
request: vi.fn().mockResolvedValue("0x123456"),
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
// Mock what an injected account with sendCalls would look like
|
|
140
|
+
const injectedAccount = {
|
|
141
|
+
...TEST_ACCOUNT_A,
|
|
142
|
+
sendCalls: async (_options: SendCallsOptions) => {
|
|
143
|
+
// This mimics the implementation in injected/index.ts
|
|
144
|
+
const callId = await mockProvider.request({
|
|
145
|
+
method: "wallet_sendCalls",
|
|
146
|
+
params: [
|
|
174
147
|
{
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
148
|
+
atomicRequired: false,
|
|
149
|
+
calls: [
|
|
150
|
+
{
|
|
151
|
+
data: "0xabcdef",
|
|
152
|
+
to: "0x2a4f24F935Eb178e3e7BA9B53A5Ee6d8407C0709",
|
|
153
|
+
value: undefined,
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
data: "0x",
|
|
157
|
+
to: "0xa922b54716264130634d6ff183747a8ead91a40b",
|
|
158
|
+
value: numberToHex(123n),
|
|
159
|
+
},
|
|
160
|
+
],
|
|
161
|
+
capabilities: undefined,
|
|
162
|
+
chainId: numberToHex(ANVIL_CHAIN.id),
|
|
163
|
+
from: TEST_ACCOUNT_A.address,
|
|
164
|
+
version: "2.0.0",
|
|
178
165
|
},
|
|
179
166
|
],
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
},
|
|
185
|
-
],
|
|
186
|
-
});
|
|
187
|
-
});
|
|
167
|
+
});
|
|
168
|
+
return { id: callId, client: TEST_CLIENT, chain: ANVIL_CHAIN };
|
|
169
|
+
},
|
|
170
|
+
};
|
|
188
171
|
|
|
189
|
-
|
|
172
|
+
const wallet: Wallet = createWallet(METAMASK);
|
|
190
173
|
wallet.getChain = vi.fn().mockReturnValue(ANVIL_CHAIN);
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
...SEND_CALLS_OPTIONS,
|
|
195
|
-
});
|
|
174
|
+
wallet.getAccount = vi.fn().mockReturnValue(injectedAccount);
|
|
175
|
+
|
|
176
|
+
const result = await sendCalls({ wallet, ...SEND_CALLS_OPTIONS });
|
|
196
177
|
|
|
197
178
|
expect(result.id).toEqual("0x123456");
|
|
198
|
-
expect(
|
|
179
|
+
expect(mockProvider.request).toHaveBeenCalledWith({
|
|
199
180
|
method: "wallet_sendCalls",
|
|
200
181
|
params: [
|
|
201
182
|
{
|
|
@@ -213,7 +194,7 @@ describe.sequential("injected wallet", () => {
|
|
|
213
194
|
},
|
|
214
195
|
],
|
|
215
196
|
capabilities: undefined,
|
|
216
|
-
chainId: numberToHex(
|
|
197
|
+
chainId: numberToHex(ANVIL_CHAIN.id),
|
|
217
198
|
from: TEST_ACCOUNT_A.address,
|
|
218
199
|
version: "2.0.0",
|
|
219
200
|
},
|
|
@@ -221,14 +202,39 @@ describe.sequential("injected wallet", () => {
|
|
|
221
202
|
});
|
|
222
203
|
});
|
|
223
204
|
|
|
224
|
-
test("
|
|
225
|
-
|
|
226
|
-
|
|
205
|
+
test("should handle provider errors", async () => {
|
|
206
|
+
const mockProvider = {
|
|
207
|
+
request: vi.fn().mockRejectedValue({
|
|
208
|
+
code: -32601,
|
|
209
|
+
message: "some nonsense the wallet sends us about not supporting",
|
|
210
|
+
}),
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
const injectedAccount = {
|
|
214
|
+
...TEST_ACCOUNT_A,
|
|
215
|
+
sendCalls: async (_options: SendCallsOptions) => {
|
|
216
|
+
try {
|
|
217
|
+
const callId = await mockProvider.request({
|
|
218
|
+
method: "wallet_sendCalls",
|
|
219
|
+
params: [],
|
|
220
|
+
});
|
|
221
|
+
return { id: callId, client: TEST_CLIENT, chain: ANVIL_CHAIN };
|
|
222
|
+
} catch (error) {
|
|
223
|
+
if (/unsupport|not support/i.test((error as Error).message)) {
|
|
224
|
+
throw new Error(
|
|
225
|
+
`io.metamask errored calling wallet_sendCalls, with error: ${stringify(error)}`,
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
throw error;
|
|
229
|
+
}
|
|
230
|
+
},
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
const wallet: Wallet = createWallet(METAMASK);
|
|
227
234
|
wallet.getChain = vi.fn().mockReturnValue(ANVIL_CHAIN);
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
});
|
|
235
|
+
wallet.getAccount = vi.fn().mockReturnValue(injectedAccount);
|
|
236
|
+
|
|
237
|
+
const promise = sendCalls({ wallet, ...SEND_CALLS_OPTIONS });
|
|
232
238
|
|
|
233
239
|
await expect(promise).rejects.toMatchInlineSnapshot(
|
|
234
240
|
`[Error: io.metamask errored calling wallet_sendCalls, with error: {"code":-32601,"message":"some nonsense the wallet sends us about not supporting"}]`,
|
|
@@ -237,27 +243,37 @@ describe.sequential("injected wallet", () => {
|
|
|
237
243
|
});
|
|
238
244
|
|
|
239
245
|
describe.sequential("in-app wallet", () => {
|
|
240
|
-
|
|
246
|
+
const wallet: Wallet = createWallet("inApp");
|
|
241
247
|
|
|
242
248
|
afterEach(() => {
|
|
243
249
|
vi.clearAllMocks();
|
|
244
250
|
});
|
|
245
251
|
|
|
246
|
-
test("should send
|
|
247
|
-
|
|
248
|
-
|
|
252
|
+
test("should send calls via inAppWalletSendCalls", async () => {
|
|
253
|
+
// Configure the mock to return the expected value
|
|
254
|
+
mocks.inAppWalletSendCalls.mockResolvedValue("0x789abc");
|
|
249
255
|
|
|
250
|
-
|
|
256
|
+
const inAppAccount = {
|
|
257
|
+
...TEST_ACCOUNT_A,
|
|
258
|
+
sendCalls: async (options: SendCallsOptions) => {
|
|
259
|
+
const id = await mocks.inAppWalletSendCalls({
|
|
260
|
+
account: inAppAccount,
|
|
261
|
+
calls: options.calls,
|
|
262
|
+
});
|
|
263
|
+
return { id, client: TEST_CLIENT, chain: ANVIL_CHAIN };
|
|
264
|
+
},
|
|
265
|
+
};
|
|
251
266
|
|
|
252
|
-
|
|
253
|
-
|
|
267
|
+
wallet.getChain = vi.fn().mockReturnValue(ANVIL_CHAIN);
|
|
268
|
+
wallet.getAccount = vi.fn().mockReturnValue(inAppAccount);
|
|
254
269
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
270
|
+
const result = await sendCalls({ wallet, ...SEND_CALLS_OPTIONS });
|
|
271
|
+
|
|
272
|
+
expect(result.id).toEqual("0x789abc");
|
|
273
|
+
expect(mocks.inAppWalletSendCalls).toHaveBeenCalledWith({
|
|
274
|
+
account: inAppAccount,
|
|
275
|
+
calls: SEND_CALLS_OPTIONS.calls,
|
|
276
|
+
});
|
|
261
277
|
});
|
|
262
278
|
|
|
263
279
|
test("without account should fail", async () => {
|
|
@@ -267,21 +283,6 @@ describe.sequential("in-app wallet", () => {
|
|
|
267
283
|
"[Error: Cannot send calls, no account connected for wallet: inApp]",
|
|
268
284
|
);
|
|
269
285
|
});
|
|
270
|
-
|
|
271
|
-
test("with smart account should send batch calls", async () => {
|
|
272
|
-
wallet = createWallet("inApp", {
|
|
273
|
-
smartAccount: { chain: FORKED_ETHEREUM_CHAIN, sponsorGas: true },
|
|
274
|
-
});
|
|
275
|
-
wallet.getChain = vi.fn().mockReturnValue(FORKED_ETHEREUM_CHAIN);
|
|
276
|
-
wallet.getAccount = vi.fn().mockReturnValue({
|
|
277
|
-
...TEST_ACCOUNT_A,
|
|
278
|
-
sendBatchTransaction: vi.fn(), // must specify this to make it behave like a smart account without connecting
|
|
279
|
-
});
|
|
280
|
-
|
|
281
|
-
await sendCalls({ wallet, ...SEND_CALLS_OPTIONS });
|
|
282
|
-
|
|
283
|
-
expect(mocks.sendBatchTransaction).toHaveBeenCalledTimes(1);
|
|
284
|
-
});
|
|
285
286
|
});
|
|
286
287
|
|
|
287
288
|
describe.sequential("smart wallet", () => {
|
|
@@ -289,44 +290,37 @@ describe.sequential("smart wallet", () => {
|
|
|
289
290
|
chain: FORKED_ETHEREUM_CHAIN,
|
|
290
291
|
sponsorGas: true,
|
|
291
292
|
});
|
|
292
|
-
wallet.getAccount = vi.fn().mockReturnValue({
|
|
293
|
-
...TEST_ACCOUNT_A,
|
|
294
|
-
sendBatchTransaction: vi.fn(), // must specify this to make it behave like a smart account without connecting
|
|
295
|
-
});
|
|
296
293
|
|
|
297
294
|
afterEach(() => {
|
|
298
295
|
vi.clearAllMocks();
|
|
299
296
|
});
|
|
300
297
|
|
|
301
|
-
test("should send
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
await sendCalls({ wallet, ...SEND_CALLS_OPTIONS });
|
|
298
|
+
test("should send calls via inAppWalletSendCalls", async () => {
|
|
299
|
+
// Configure the mock to return the expected value
|
|
300
|
+
mocks.inAppWalletSendCalls.mockResolvedValue("0x789abc");
|
|
305
301
|
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
vi.clearAllMocks();
|
|
318
|
-
});
|
|
302
|
+
const smartAccount = {
|
|
303
|
+
...TEST_ACCOUNT_A,
|
|
304
|
+
sendBatchTransaction: vi.fn(),
|
|
305
|
+
sendCalls: async (options: SendCallsOptions) => {
|
|
306
|
+
const id = await mocks.inAppWalletSendCalls({
|
|
307
|
+
account: smartAccount,
|
|
308
|
+
calls: options.calls,
|
|
309
|
+
});
|
|
310
|
+
return { id, client: TEST_CLIENT, chain: ANVIL_CHAIN };
|
|
311
|
+
},
|
|
312
|
+
};
|
|
319
313
|
|
|
320
|
-
test("should send batch transacition", async () => {
|
|
321
314
|
wallet.getChain = vi.fn().mockReturnValue(ANVIL_CHAIN);
|
|
322
|
-
wallet.getAccount = vi.fn().mockReturnValue(
|
|
323
|
-
...TEST_ACCOUNT_A,
|
|
324
|
-
sendBatchTransaction: vi.fn(), // we have to mock this because it doesn't get set until the wallet is connected
|
|
325
|
-
});
|
|
315
|
+
wallet.getAccount = vi.fn().mockReturnValue(smartAccount);
|
|
326
316
|
|
|
327
|
-
await sendCalls({ wallet, ...SEND_CALLS_OPTIONS });
|
|
317
|
+
const result = await sendCalls({ wallet, ...SEND_CALLS_OPTIONS });
|
|
328
318
|
|
|
329
|
-
expect(
|
|
319
|
+
expect(result.id).toEqual("0x789abc");
|
|
320
|
+
expect(mocks.inAppWalletSendCalls).toHaveBeenCalledWith({
|
|
321
|
+
account: smartAccount,
|
|
322
|
+
calls: SEND_CALLS_OPTIONS.calls,
|
|
323
|
+
});
|
|
330
324
|
});
|
|
331
325
|
});
|
|
332
326
|
|
|
@@ -4,24 +4,14 @@ import type { Chain } from "../../chains/types.js";
|
|
|
4
4
|
import type { ThirdwebClient } from "../../client/client.js";
|
|
5
5
|
import { encode } from "../../transaction/actions/encode.js";
|
|
6
6
|
import type { PreparedTransaction } from "../../transaction/prepare-transaction.js";
|
|
7
|
-
import {
|
|
7
|
+
import { getAddress } from "../../utils/address.js";
|
|
8
8
|
import { type Hex, numberToHex } from "../../utils/encoding/hex.js";
|
|
9
|
-
import { stringify } from "../../utils/json.js";
|
|
10
9
|
import {
|
|
11
10
|
type PromisedObject,
|
|
12
11
|
resolvePromisedValue,
|
|
13
12
|
} from "../../utils/promise/resolve-promised-value.js";
|
|
14
13
|
import type { OneOf, Prettify } from "../../utils/type-utils.js";
|
|
15
|
-
import {
|
|
16
|
-
type CoinbaseWalletCreationOptions,
|
|
17
|
-
isCoinbaseSDKWallet,
|
|
18
|
-
} from "../coinbase/coinbase-web.js";
|
|
19
|
-
import { isInAppWallet } from "../in-app/core/wallet/index.js";
|
|
20
|
-
import { getInjectedProvider } from "../injected/index.js";
|
|
21
|
-
import type { Ethereum } from "../interfaces/ethereum.js";
|
|
22
|
-
import type { Wallet } from "../interfaces/wallet.js";
|
|
23
|
-
import { isSmartWallet } from "../smart/index.js";
|
|
24
|
-
import { isWalletConnect } from "../wallet-connect/controller.js";
|
|
14
|
+
import type { Account, Wallet } from "../interfaces/wallet.js";
|
|
25
15
|
import type { WalletId } from "../wallet-types.js";
|
|
26
16
|
import type {
|
|
27
17
|
EIP5792Call,
|
|
@@ -129,19 +119,7 @@ export type SendCallsResult = Prettify<{
|
|
|
129
119
|
export async function sendCalls<const ID extends WalletId>(
|
|
130
120
|
options: SendCallsOptions<ID>,
|
|
131
121
|
): Promise<SendCallsResult> {
|
|
132
|
-
const {
|
|
133
|
-
wallet,
|
|
134
|
-
calls,
|
|
135
|
-
capabilities,
|
|
136
|
-
version = "2.0.0",
|
|
137
|
-
chain = wallet.getChain(),
|
|
138
|
-
} = options;
|
|
139
|
-
|
|
140
|
-
if (!chain) {
|
|
141
|
-
throw new Error(
|
|
142
|
-
`Cannot send calls, no active chain found for wallet: ${wallet.id}`,
|
|
143
|
-
);
|
|
144
|
-
}
|
|
122
|
+
const { wallet, chain } = options;
|
|
145
123
|
|
|
146
124
|
const account = wallet.getAccount();
|
|
147
125
|
if (!account) {
|
|
@@ -154,17 +132,44 @@ export async function sendCalls<const ID extends WalletId>(
|
|
|
154
132
|
if (!firstCall) {
|
|
155
133
|
throw new Error("No calls to send");
|
|
156
134
|
}
|
|
157
|
-
const client = firstCall.client;
|
|
158
135
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
);
|
|
164
|
-
const id = await inAppWalletSendCalls({ account, calls });
|
|
165
|
-
return { chain, client, id, wallet };
|
|
136
|
+
const callChain = firstCall.chain || chain;
|
|
137
|
+
|
|
138
|
+
if (wallet.getChain()?.id !== callChain.id) {
|
|
139
|
+
await wallet.switchChain(callChain);
|
|
166
140
|
}
|
|
167
141
|
|
|
142
|
+
// check internal implementations
|
|
143
|
+
if (account.sendCalls) {
|
|
144
|
+
const { wallet: _, ...optionsWithoutWallet } = options;
|
|
145
|
+
const result = await account.sendCalls(optionsWithoutWallet);
|
|
146
|
+
return {
|
|
147
|
+
...result,
|
|
148
|
+
wallet,
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
throw new Error(
|
|
153
|
+
`Cannot send calls, wallet ${wallet.id} does not support EIP-5792`,
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export async function toProviderCallParams(
|
|
158
|
+
options: Omit<SendCallsOptions, "wallet">,
|
|
159
|
+
account: Account,
|
|
160
|
+
): Promise<{ callParams: ViemWalletSendCallsParameters; chain: Chain }> {
|
|
161
|
+
const firstCall = options.calls[0];
|
|
162
|
+
if (!firstCall) {
|
|
163
|
+
throw new Error("No calls to send");
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const {
|
|
167
|
+
calls,
|
|
168
|
+
capabilities,
|
|
169
|
+
version = "2.0.0",
|
|
170
|
+
chain = firstCall.chain,
|
|
171
|
+
} = options;
|
|
172
|
+
|
|
168
173
|
const preparedCalls: EIP5792Call[] = await Promise.all(
|
|
169
174
|
calls.map(async (call) => {
|
|
170
175
|
const { to, value } = call;
|
|
@@ -178,18 +183,26 @@ export async function sendCalls<const ID extends WalletId>(
|
|
|
178
183
|
resolvePromisedValue(value),
|
|
179
184
|
]);
|
|
180
185
|
|
|
186
|
+
if (_to) {
|
|
187
|
+
return {
|
|
188
|
+
data: _data as Hex,
|
|
189
|
+
to: getAddress(_to),
|
|
190
|
+
value:
|
|
191
|
+
typeof _value === "bigint" || typeof _value === "number"
|
|
192
|
+
? numberToHex(_value)
|
|
193
|
+
: undefined,
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
|
|
181
197
|
return {
|
|
182
198
|
data: _data as Hex,
|
|
183
|
-
to:
|
|
184
|
-
value:
|
|
185
|
-
typeof _value === "bigint" || typeof _value === "number"
|
|
186
|
-
? numberToHex(_value)
|
|
187
|
-
: undefined,
|
|
199
|
+
to: undefined,
|
|
200
|
+
value: undefined,
|
|
188
201
|
};
|
|
189
202
|
}),
|
|
190
203
|
);
|
|
191
204
|
|
|
192
|
-
const injectedWalletCallParams:
|
|
205
|
+
const injectedWalletCallParams: ViemWalletSendCallsParameters = [
|
|
193
206
|
{
|
|
194
207
|
// see: https://eips.ethereum.org/EIPS/eip-5792#wallet_sendcalls
|
|
195
208
|
atomicRequired: options.atomicRequired ?? false,
|
|
@@ -201,36 +214,5 @@ export async function sendCalls<const ID extends WalletId>(
|
|
|
201
214
|
},
|
|
202
215
|
];
|
|
203
216
|
|
|
204
|
-
|
|
205
|
-
throw new Error("sendCalls is not yet supported for Wallet Connect");
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
let provider: Ethereum;
|
|
209
|
-
if (isCoinbaseSDKWallet(wallet)) {
|
|
210
|
-
const { getCoinbaseWebProvider } = await import(
|
|
211
|
-
"../coinbase/coinbase-web.js"
|
|
212
|
-
);
|
|
213
|
-
const config = wallet.getConfig() as CoinbaseWalletCreationOptions;
|
|
214
|
-
provider = (await getCoinbaseWebProvider(config)) as Ethereum;
|
|
215
|
-
} else {
|
|
216
|
-
provider = getInjectedProvider(wallet.id);
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
try {
|
|
220
|
-
const callId = await provider.request({
|
|
221
|
-
method: "wallet_sendCalls",
|
|
222
|
-
params: injectedWalletCallParams as ViemWalletSendCallsParameters, // The viem type definition is slightly different
|
|
223
|
-
});
|
|
224
|
-
if (typeof callId === "object" && "id" in callId) {
|
|
225
|
-
return { chain, client, id: callId.id, wallet };
|
|
226
|
-
}
|
|
227
|
-
return { chain, client, id: callId, wallet };
|
|
228
|
-
} catch (error) {
|
|
229
|
-
if (/unsupport|not support/i.test((error as Error).message)) {
|
|
230
|
-
throw new Error(
|
|
231
|
-
`${wallet.id} errored calling wallet_sendCalls, with error: ${error instanceof Error ? error.message : stringify(error)}`,
|
|
232
|
-
);
|
|
233
|
-
}
|
|
234
|
-
throw error;
|
|
235
|
-
}
|
|
217
|
+
return { callParams: injectedWalletCallParams, chain };
|
|
236
218
|
}
|