thirdweb 5.105.21 → 5.105.23
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/web/wallets/shared/WalletConnectConnection.js +7 -33
- package/dist/cjs/react/web/wallets/shared/WalletConnectConnection.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/utils/web/isMobile.js +0 -2
- package/dist/cjs/utils/web/isMobile.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 +21 -4
- 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/injected/index.js +55 -0
- package/dist/cjs/wallets/injected/index.js.map +1 -1
- package/dist/cjs/wallets/smart/index.js +61 -0
- package/dist/cjs/wallets/smart/index.js.map +1 -1
- package/dist/cjs/wallets/wallet-connect/controller.js +27 -25
- package/dist/cjs/wallets/wallet-connect/controller.js.map +1 -1
- 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/web/wallets/shared/WalletConnectConnection.js +8 -34
- package/dist/esm/react/web/wallets/shared/WalletConnectConnection.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/utils/web/isMobile.js +2 -2
- package/dist/esm/utils/web/isMobile.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 +21 -4
- 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/injected/index.js +56 -1
- package/dist/esm/wallets/injected/index.js.map +1 -1
- package/dist/esm/wallets/smart/index.js +61 -0
- package/dist/esm/wallets/smart/index.js.map +1 -1
- package/dist/esm/wallets/wallet-connect/controller.js +27 -25
- package/dist/esm/wallets/wallet-connect/controller.js.map +1 -1
- 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/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/react/web/wallets/shared/WalletConnectConnection.d.ts.map +1 -1
- package/dist/types/transaction/actions/estimate-gas.d.ts.map +1 -1
- package/dist/types/utils/web/isMobile.d.ts +0 -8
- package/dist/types/utils/web/isMobile.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/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/controller.d.ts.map +1 -1
- package/package.json +3 -3
- 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/web/wallets/shared/WalletConnectConnection.tsx +11 -46
- package/src/transaction/actions/estimate-gas.ts +14 -42
- package/src/utils/web/isMobile.ts +2 -2
- package/src/version.ts +1 -1
- package/src/wallets/coinbase/coinbase-web.ts +66 -0
- package/src/wallets/create-wallet.ts +53 -31
- 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/injected/index.ts +63 -0
- package/src/wallets/interfaces/wallet.ts +31 -0
- package/src/wallets/smart/index.ts +69 -1
- package/src/wallets/wallet-connect/controller.ts +28 -25
- 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,14 +1,5 @@
|
|
|
1
|
-
import { getAddress } from "../../utils/address.js";
|
|
2
1
|
import type { Prettify } from "../../utils/type-utils.js";
|
|
3
|
-
import {
|
|
4
|
-
type CoinbaseWalletCreationOptions,
|
|
5
|
-
isCoinbaseSDKWallet,
|
|
6
|
-
} from "../coinbase/coinbase-web.js";
|
|
7
|
-
import { isInAppWallet } from "../in-app/core/wallet/index.js";
|
|
8
|
-
import { getInjectedProvider } from "../injected/index.js";
|
|
9
|
-
import type { Ethereum } from "../interfaces/ethereum.js";
|
|
10
2
|
import type { Wallet } from "../interfaces/wallet.js";
|
|
11
|
-
import { isWalletConnect } from "../wallet-connect/controller.js";
|
|
12
3
|
import type { WalletId } from "../wallet-types.js";
|
|
13
4
|
import type { WalletCapabilities, WalletCapabilitiesRecord } from "./types.js";
|
|
14
5
|
|
|
@@ -52,64 +43,32 @@ export async function getCapabilities<const ID extends WalletId = WalletId>({
|
|
|
52
43
|
};
|
|
53
44
|
}
|
|
54
45
|
|
|
55
|
-
if (
|
|
56
|
-
|
|
57
|
-
"../smart/lib/smart-wallet-capabilities.js"
|
|
58
|
-
);
|
|
59
|
-
return smartWalletGetCapabilities({ wallet });
|
|
46
|
+
if (account.getCapabilities) {
|
|
47
|
+
return account.getCapabilities({ chainId });
|
|
60
48
|
}
|
|
61
49
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
return inAppWalletGetCapabilities({ wallet });
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// TODO: Add Wallet Connect support
|
|
70
|
-
if (isWalletConnect(wallet)) {
|
|
71
|
-
return {
|
|
72
|
-
message: "getCapabilities is not yet supported with Wallet Connect",
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
let provider: Ethereum;
|
|
77
|
-
if (isCoinbaseSDKWallet(wallet)) {
|
|
78
|
-
const { getCoinbaseWebProvider } = await import(
|
|
79
|
-
"../coinbase/coinbase-web.js"
|
|
80
|
-
);
|
|
81
|
-
const config = wallet.getConfig() as CoinbaseWalletCreationOptions;
|
|
82
|
-
provider = (await getCoinbaseWebProvider(config)) as Ethereum;
|
|
83
|
-
} else {
|
|
84
|
-
provider = getInjectedProvider(wallet.id);
|
|
85
|
-
}
|
|
50
|
+
throw new Error(
|
|
51
|
+
`Failed to get capabilities, wallet ${wallet.id} does not support EIP-5792`,
|
|
52
|
+
);
|
|
53
|
+
}
|
|
86
54
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
capabilitiesCopy[key] = value;
|
|
101
|
-
}
|
|
102
|
-
capabilities[Number(chainId)] = capabilitiesCopy;
|
|
103
|
-
}
|
|
104
|
-
return (
|
|
105
|
-
typeof chainId === "number" ? capabilities[chainId] : capabilities
|
|
106
|
-
) as never;
|
|
107
|
-
} catch (error: unknown) {
|
|
108
|
-
if (/unsupport|not support|not available/i.test((error as Error).message)) {
|
|
109
|
-
return {
|
|
110
|
-
message: `${wallet.id} does not support wallet_getCapabilities, reach out to them directly to request EIP-5792 support.`,
|
|
111
|
-
};
|
|
55
|
+
export function toGetCapabilitiesResult(
|
|
56
|
+
result: Record<string, WalletCapabilities>,
|
|
57
|
+
chainId?: number,
|
|
58
|
+
): GetCapabilitiesResult {
|
|
59
|
+
const capabilities = {} as WalletCapabilitiesRecord<
|
|
60
|
+
WalletCapabilities,
|
|
61
|
+
number
|
|
62
|
+
>;
|
|
63
|
+
for (const [chainId, capabilities_] of Object.entries(result)) {
|
|
64
|
+
capabilities[Number(chainId)] = {};
|
|
65
|
+
const capabilitiesCopy = {} as WalletCapabilities;
|
|
66
|
+
for (const [key, value] of Object.entries(capabilities_)) {
|
|
67
|
+
capabilitiesCopy[key] = value;
|
|
112
68
|
}
|
|
113
|
-
|
|
69
|
+
capabilities[Number(chainId)] = capabilitiesCopy;
|
|
114
70
|
}
|
|
71
|
+
return (
|
|
72
|
+
typeof chainId === "number" ? capabilities[chainId] : capabilities
|
|
73
|
+
) as never;
|
|
115
74
|
}
|
|
@@ -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
|
|