thirdweb 5.105.40 → 5.105.42-nightly-2d76cf904079cc74809f571b67ac746fad7aa04f-20250909000351
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/erc7702/__generated__/MinimalAccount/events/Executed.js +4 -2
- package/dist/cjs/extensions/erc7702/__generated__/MinimalAccount/events/Executed.js.map +1 -1
- package/dist/cjs/extensions/erc7702/__generated__/MinimalAccount/events/SessionCreated.js +3 -2
- package/dist/cjs/extensions/erc7702/__generated__/MinimalAccount/events/SessionCreated.js.map +1 -1
- package/dist/cjs/extensions/erc7702/__generated__/MinimalAccount/events/ValueReceived.js +32 -0
- package/dist/cjs/extensions/erc7702/__generated__/MinimalAccount/events/ValueReceived.js.map +1 -0
- package/dist/cjs/extensions/erc7702/__generated__/MinimalAccount/read/eip712Domain.js +7 -7
- package/dist/cjs/extensions/erc7702/__generated__/MinimalAccount/read/eip712Domain.js.map +1 -1
- package/dist/cjs/extensions/erc7702/__generated__/MinimalAccount/read/getCallPoliciesForSigner.js +20 -20
- package/dist/cjs/extensions/erc7702/__generated__/MinimalAccount/read/getCallPoliciesForSigner.js.map +1 -1
- package/dist/cjs/extensions/erc7702/__generated__/MinimalAccount/read/getSessionExpirationForSigner.js +1 -1
- package/dist/cjs/extensions/erc7702/__generated__/MinimalAccount/read/getSessionExpirationForSigner.js.map +1 -1
- package/dist/cjs/extensions/erc7702/__generated__/MinimalAccount/read/getSessionStateForSigner.js +20 -20
- package/dist/cjs/extensions/erc7702/__generated__/MinimalAccount/read/getSessionStateForSigner.js.map +1 -1
- package/dist/cjs/extensions/erc7702/__generated__/MinimalAccount/read/getTransferPoliciesForSigner.js +9 -9
- package/dist/cjs/extensions/erc7702/__generated__/MinimalAccount/read/getTransferPoliciesForSigner.js.map +1 -1
- package/dist/cjs/extensions/erc7702/__generated__/MinimalAccount/read/isWildcardSigner.js +1 -1
- package/dist/cjs/extensions/erc7702/__generated__/MinimalAccount/read/isWildcardSigner.js.map +1 -1
- package/dist/cjs/extensions/erc7702/__generated__/MinimalAccount/write/createSessionWithSig.js +45 -45
- package/dist/cjs/extensions/erc7702/__generated__/MinimalAccount/write/createSessionWithSig.js.map +1 -1
- package/dist/cjs/extensions/erc7702/__generated__/MinimalAccount/write/execute.js +14 -14
- package/dist/cjs/extensions/erc7702/__generated__/MinimalAccount/write/execute.js.map +1 -1
- package/dist/cjs/extensions/erc7702/__generated__/MinimalAccount/write/executeWithSig.js +18 -18
- package/dist/cjs/extensions/erc7702/__generated__/MinimalAccount/write/executeWithSig.js.map +1 -1
- package/dist/cjs/gas/fee-data.js +1 -1
- package/dist/cjs/gas/fee-data.js.map +1 -1
- package/dist/cjs/react/core/hooks/pay/useBuyWithFiatQuotesForProviders.js +1 -0
- package/dist/cjs/react/core/hooks/pay/useBuyWithFiatQuotesForProviders.js.map +1 -1
- package/dist/cjs/react/core/hooks/transaction/useSendTransaction.js.map +1 -1
- package/dist/cjs/react/web/hooks/transaction/useSendTransaction.js +1 -1
- package/dist/cjs/react/web/hooks/transaction/useSendTransaction.js.map +1 -1
- package/dist/cjs/react/web/ui/Bridge/BridgeOrchestrator.js +2 -2
- package/dist/cjs/react/web/ui/Bridge/BridgeOrchestrator.js.map +1 -1
- package/dist/cjs/react/web/ui/Bridge/BuyWidget.js +1 -1
- package/dist/cjs/react/web/ui/Bridge/BuyWidget.js.map +1 -1
- package/dist/cjs/react/web/ui/Bridge/CheckoutWidget.js +1 -1
- package/dist/cjs/react/web/ui/Bridge/CheckoutWidget.js.map +1 -1
- package/dist/cjs/react/web/ui/Bridge/TransactionWidget.js +1 -1
- package/dist/cjs/react/web/ui/Bridge/TransactionWidget.js.map +1 -1
- package/dist/cjs/react/web/ui/Bridge/payment-selection/FiatProviderSelection.js +2 -1
- package/dist/cjs/react/web/ui/Bridge/payment-selection/FiatProviderSelection.js.map +1 -1
- package/dist/cjs/react/web/ui/Bridge/payment-selection/PaymentSelection.js +2 -2
- package/dist/cjs/react/web/ui/Bridge/payment-selection/PaymentSelection.js.map +1 -1
- package/dist/cjs/react/web/ui/ConnectWallet/Modal/AllWalletsUI.js +2 -6
- package/dist/cjs/react/web/ui/ConnectWallet/Modal/AllWalletsUI.js.map +1 -1
- package/dist/cjs/react/web/ui/ConnectWallet/Modal/ConnectModalContent.js +1 -1
- package/dist/cjs/react/web/ui/ConnectWallet/Modal/ConnectModalContent.js.map +1 -1
- package/dist/cjs/react/web/ui/TransactionButton/TransactionModal.js +1 -1
- package/dist/cjs/react/web/ui/TransactionButton/TransactionModal.js.map +1 -1
- package/dist/cjs/react/web/wallets/in-app/WalletAuth.js +1 -1
- package/dist/cjs/react/web/wallets/in-app/WalletAuth.js.map +1 -1
- package/dist/cjs/stories/Bridge/BridgeOrchestrator.stories.js +1 -0
- package/dist/cjs/stories/Bridge/BridgeOrchestrator.stories.js.map +1 -1
- package/dist/cjs/stories/Bridge/PaymentSelection.stories.js +1 -0
- package/dist/cjs/stories/Bridge/PaymentSelection.stories.js.map +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/cjs/version.js.map +1 -1
- package/dist/cjs/wallets/in-app/core/eip7702/minimal-account.js +117 -10
- package/dist/cjs/wallets/in-app/core/eip7702/minimal-account.js.map +1 -1
- package/dist/esm/extensions/erc7702/__generated__/MinimalAccount/events/Executed.js +4 -2
- package/dist/esm/extensions/erc7702/__generated__/MinimalAccount/events/Executed.js.map +1 -1
- package/dist/esm/extensions/erc7702/__generated__/MinimalAccount/events/SessionCreated.js +3 -2
- package/dist/esm/extensions/erc7702/__generated__/MinimalAccount/events/SessionCreated.js.map +1 -1
- package/dist/esm/extensions/erc7702/__generated__/MinimalAccount/events/ValueReceived.js +29 -0
- package/dist/esm/extensions/erc7702/__generated__/MinimalAccount/events/ValueReceived.js.map +1 -0
- package/dist/esm/extensions/erc7702/__generated__/MinimalAccount/read/eip712Domain.js +7 -7
- package/dist/esm/extensions/erc7702/__generated__/MinimalAccount/read/eip712Domain.js.map +1 -1
- package/dist/esm/extensions/erc7702/__generated__/MinimalAccount/read/getCallPoliciesForSigner.js +20 -20
- package/dist/esm/extensions/erc7702/__generated__/MinimalAccount/read/getCallPoliciesForSigner.js.map +1 -1
- package/dist/esm/extensions/erc7702/__generated__/MinimalAccount/read/getSessionExpirationForSigner.js +1 -1
- package/dist/esm/extensions/erc7702/__generated__/MinimalAccount/read/getSessionExpirationForSigner.js.map +1 -1
- package/dist/esm/extensions/erc7702/__generated__/MinimalAccount/read/getSessionStateForSigner.js +20 -20
- package/dist/esm/extensions/erc7702/__generated__/MinimalAccount/read/getSessionStateForSigner.js.map +1 -1
- package/dist/esm/extensions/erc7702/__generated__/MinimalAccount/read/getTransferPoliciesForSigner.js +9 -9
- package/dist/esm/extensions/erc7702/__generated__/MinimalAccount/read/getTransferPoliciesForSigner.js.map +1 -1
- package/dist/esm/extensions/erc7702/__generated__/MinimalAccount/read/isWildcardSigner.js +1 -1
- package/dist/esm/extensions/erc7702/__generated__/MinimalAccount/read/isWildcardSigner.js.map +1 -1
- package/dist/esm/extensions/erc7702/__generated__/MinimalAccount/write/createSessionWithSig.js +45 -45
- package/dist/esm/extensions/erc7702/__generated__/MinimalAccount/write/createSessionWithSig.js.map +1 -1
- package/dist/esm/extensions/erc7702/__generated__/MinimalAccount/write/execute.js +14 -14
- package/dist/esm/extensions/erc7702/__generated__/MinimalAccount/write/execute.js.map +1 -1
- package/dist/esm/extensions/erc7702/__generated__/MinimalAccount/write/executeWithSig.js +18 -18
- package/dist/esm/extensions/erc7702/__generated__/MinimalAccount/write/executeWithSig.js.map +1 -1
- package/dist/esm/gas/fee-data.js +1 -1
- package/dist/esm/gas/fee-data.js.map +1 -1
- package/dist/esm/react/core/hooks/pay/useBuyWithFiatQuotesForProviders.js +1 -0
- package/dist/esm/react/core/hooks/pay/useBuyWithFiatQuotesForProviders.js.map +1 -1
- package/dist/esm/react/core/hooks/transaction/useSendTransaction.js.map +1 -1
- package/dist/esm/react/web/hooks/transaction/useSendTransaction.js +1 -1
- package/dist/esm/react/web/hooks/transaction/useSendTransaction.js.map +1 -1
- package/dist/esm/react/web/ui/Bridge/BridgeOrchestrator.js +2 -2
- package/dist/esm/react/web/ui/Bridge/BridgeOrchestrator.js.map +1 -1
- package/dist/esm/react/web/ui/Bridge/BuyWidget.js +1 -1
- package/dist/esm/react/web/ui/Bridge/BuyWidget.js.map +1 -1
- package/dist/esm/react/web/ui/Bridge/CheckoutWidget.js +1 -1
- package/dist/esm/react/web/ui/Bridge/CheckoutWidget.js.map +1 -1
- package/dist/esm/react/web/ui/Bridge/TransactionWidget.js +1 -1
- package/dist/esm/react/web/ui/Bridge/TransactionWidget.js.map +1 -1
- package/dist/esm/react/web/ui/Bridge/payment-selection/FiatProviderSelection.js +2 -1
- package/dist/esm/react/web/ui/Bridge/payment-selection/FiatProviderSelection.js.map +1 -1
- package/dist/esm/react/web/ui/Bridge/payment-selection/PaymentSelection.js +2 -2
- package/dist/esm/react/web/ui/Bridge/payment-selection/PaymentSelection.js.map +1 -1
- package/dist/esm/react/web/ui/ConnectWallet/Modal/AllWalletsUI.js +2 -6
- package/dist/esm/react/web/ui/ConnectWallet/Modal/AllWalletsUI.js.map +1 -1
- package/dist/esm/react/web/ui/ConnectWallet/Modal/ConnectModalContent.js +1 -1
- package/dist/esm/react/web/ui/ConnectWallet/Modal/ConnectModalContent.js.map +1 -1
- package/dist/esm/react/web/ui/TransactionButton/TransactionModal.js +1 -1
- package/dist/esm/react/web/ui/TransactionButton/TransactionModal.js.map +1 -1
- package/dist/esm/react/web/wallets/in-app/WalletAuth.js +1 -1
- package/dist/esm/react/web/wallets/in-app/WalletAuth.js.map +1 -1
- package/dist/esm/stories/Bridge/BridgeOrchestrator.stories.js +1 -0
- package/dist/esm/stories/Bridge/BridgeOrchestrator.stories.js.map +1 -1
- package/dist/esm/stories/Bridge/PaymentSelection.stories.js +1 -0
- package/dist/esm/stories/Bridge/PaymentSelection.stories.js.map +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/esm/version.js.map +1 -1
- package/dist/esm/wallets/in-app/core/eip7702/minimal-account.js +117 -10
- package/dist/esm/wallets/in-app/core/eip7702/minimal-account.js.map +1 -1
- package/dist/types/extensions/erc7702/__generated__/MinimalAccount/events/Executed.d.ts +25 -8
- package/dist/types/extensions/erc7702/__generated__/MinimalAccount/events/Executed.d.ts.map +1 -1
- package/dist/types/extensions/erc7702/__generated__/MinimalAccount/events/SessionCreated.d.ts +14 -4
- package/dist/types/extensions/erc7702/__generated__/MinimalAccount/events/SessionCreated.d.ts.map +1 -1
- package/dist/types/extensions/erc7702/__generated__/MinimalAccount/events/ValueReceived.d.ts +54 -0
- package/dist/types/extensions/erc7702/__generated__/MinimalAccount/events/ValueReceived.d.ts.map +1 -0
- package/dist/types/react/core/hooks/pay/useBuyWithFiatQuotesForProviders.d.ts +4 -0
- package/dist/types/react/core/hooks/pay/useBuyWithFiatQuotesForProviders.d.ts.map +1 -1
- package/dist/types/react/core/hooks/transaction/useSendTransaction.d.ts +4 -0
- package/dist/types/react/core/hooks/transaction/useSendTransaction.d.ts.map +1 -1
- package/dist/types/react/web/hooks/transaction/useSendTransaction.d.ts.map +1 -1
- package/dist/types/react/web/ui/Bridge/BridgeOrchestrator.d.ts +5 -1
- package/dist/types/react/web/ui/Bridge/BridgeOrchestrator.d.ts.map +1 -1
- package/dist/types/react/web/ui/Bridge/BuyWidget.d.ts +4 -0
- package/dist/types/react/web/ui/Bridge/BuyWidget.d.ts.map +1 -1
- package/dist/types/react/web/ui/Bridge/CheckoutWidget.d.ts +4 -0
- package/dist/types/react/web/ui/Bridge/CheckoutWidget.d.ts.map +1 -1
- package/dist/types/react/web/ui/Bridge/TransactionWidget.d.ts +2 -0
- package/dist/types/react/web/ui/Bridge/TransactionWidget.d.ts.map +1 -1
- package/dist/types/react/web/ui/Bridge/payment-selection/FiatProviderSelection.d.ts +2 -1
- package/dist/types/react/web/ui/Bridge/payment-selection/FiatProviderSelection.d.ts.map +1 -1
- package/dist/types/react/web/ui/Bridge/payment-selection/PaymentSelection.d.ts +5 -1
- package/dist/types/react/web/ui/Bridge/payment-selection/PaymentSelection.d.ts.map +1 -1
- package/dist/types/react/web/ui/ConnectWallet/Modal/AllWalletsUI.d.ts +0 -1
- package/dist/types/react/web/ui/ConnectWallet/Modal/AllWalletsUI.d.ts.map +1 -1
- package/dist/types/react/web/ui/ConnectWallet/Modal/ConnectModalContent.d.ts.map +1 -1
- package/dist/types/react/web/ui/TransactionButton/TransactionModal.d.ts +1 -0
- package/dist/types/react/web/ui/TransactionButton/TransactionModal.d.ts.map +1 -1
- package/dist/types/react/web/wallets/in-app/WalletAuth.d.ts.map +1 -1
- package/dist/types/stories/Bridge/BridgeOrchestrator.stories.d.ts +1 -0
- package/dist/types/stories/Bridge/BridgeOrchestrator.stories.d.ts.map +1 -1
- package/dist/types/stories/Bridge/PaymentSelection.stories.d.ts +1 -0
- package/dist/types/stories/Bridge/PaymentSelection.stories.d.ts.map +1 -1
- package/dist/types/version.d.ts +1 -1
- package/dist/types/version.d.ts.map +1 -1
- package/dist/types/wallets/in-app/core/eip7702/minimal-account.d.ts +64 -0
- package/dist/types/wallets/in-app/core/eip7702/minimal-account.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/extensions/erc7702/__generated__/MinimalAccount/events/Executed.ts +17 -4
- package/src/extensions/erc7702/__generated__/MinimalAccount/events/SessionCreated.ts +11 -5
- package/src/extensions/erc7702/__generated__/MinimalAccount/events/ValueReceived.ts +47 -0
- package/src/extensions/erc7702/__generated__/MinimalAccount/read/eip712Domain.ts +7 -7
- package/src/extensions/erc7702/__generated__/MinimalAccount/read/getCallPoliciesForSigner.ts +20 -20
- package/src/extensions/erc7702/__generated__/MinimalAccount/read/getSessionExpirationForSigner.ts +1 -1
- package/src/extensions/erc7702/__generated__/MinimalAccount/read/getSessionStateForSigner.ts +20 -20
- package/src/extensions/erc7702/__generated__/MinimalAccount/read/getTransferPoliciesForSigner.ts +9 -9
- package/src/extensions/erc7702/__generated__/MinimalAccount/read/isWildcardSigner.ts +1 -1
- package/src/extensions/erc7702/__generated__/MinimalAccount/write/createSessionWithSig.ts +47 -47
- package/src/extensions/erc7702/__generated__/MinimalAccount/write/execute.ts +16 -16
- package/src/extensions/erc7702/__generated__/MinimalAccount/write/executeWithSig.ts +20 -20
- package/src/extensions/erc7702/account/sessionkey.test.ts +2 -4
- package/src/gas/fee-data.ts +1 -1
- package/src/react/core/hooks/pay/useBuyWithFiatQuotesForProviders.ts +5 -0
- package/src/react/core/hooks/transaction/useSendTransaction.ts +4 -0
- package/src/react/web/hooks/transaction/useSendTransaction.tsx +1 -0
- package/src/react/web/ui/Bridge/BridgeOrchestrator.tsx +7 -0
- package/src/react/web/ui/Bridge/BuyWidget.tsx +6 -0
- package/src/react/web/ui/Bridge/CheckoutWidget.tsx +6 -0
- package/src/react/web/ui/Bridge/TransactionWidget.tsx +4 -0
- package/src/react/web/ui/Bridge/payment-selection/FiatProviderSelection.tsx +3 -0
- package/src/react/web/ui/Bridge/payment-selection/PaymentSelection.tsx +7 -0
- package/src/react/web/ui/ConnectWallet/Modal/AllWalletsUI.tsx +5 -12
- package/src/react/web/ui/ConnectWallet/Modal/ConnectModalContent.tsx +0 -1
- package/src/react/web/ui/TransactionButton/TransactionModal.tsx +2 -0
- package/src/react/web/wallets/in-app/WalletAuth.tsx +0 -1
- package/src/stories/Bridge/BridgeOrchestrator.stories.tsx +1 -0
- package/src/stories/Bridge/PaymentSelection.stories.tsx +1 -0
- package/src/version.ts +1 -1
- package/src/wallets/in-app/core/eip7702/minimal-account.ts +149 -10
- package/src/wallets/in-app/web/lib/in-app-gateway.test.ts +87 -103
- package/src/wallets/in-app/web/lib/in-app-integration.test.ts +1 -2
@@ -14,6 +14,9 @@ import type { SignedAuthorization } from "../../../../transaction/actions/eip770
|
|
14
14
|
import { toSerializableTransaction } from "../../../../transaction/actions/to-serializable-transaction.js";
|
15
15
|
import type { SendTransactionResult } from "../../../../transaction/types.js";
|
16
16
|
import { getAddress } from "../../../../utils/address.js";
|
17
|
+
import { getClientFetch } from "../../../../utils/fetch.js";
|
18
|
+
import { stringify } from "../../../../utils/json.js";
|
19
|
+
import { withCache } from "../../../../utils/promise/withCache.js";
|
17
20
|
import { randomBytesHex } from "../../../../utils/random.js";
|
18
21
|
import type {
|
19
22
|
Account,
|
@@ -23,11 +26,140 @@ import {
|
|
23
26
|
executeWithSignature,
|
24
27
|
getQueuedTransactionHash,
|
25
28
|
} from "../../../smart/lib/bundler.js";
|
29
|
+
import { getDefaultBundlerUrl } from "../../../smart/lib/constants.js";
|
26
30
|
import type { BundlerOptions } from "../../../smart/types.js";
|
27
31
|
|
28
|
-
|
29
|
-
|
32
|
+
interface DelegationContractResponse {
|
33
|
+
id: string;
|
34
|
+
jsonrpc: string;
|
35
|
+
result: {
|
36
|
+
delegationContract: string;
|
37
|
+
};
|
38
|
+
}
|
39
|
+
|
40
|
+
/**
|
41
|
+
* Fetches the delegation contract address from the bundler using the tw_getDelegationContract RPC method
|
42
|
+
* @internal
|
43
|
+
*/
|
44
|
+
async function getDelegationContractAddress(args: {
|
45
|
+
client: ThirdwebClient;
|
46
|
+
chain: Chain;
|
47
|
+
bundlerUrl?: string;
|
48
|
+
}): Promise<string> {
|
49
|
+
const { client, chain, bundlerUrl } = args;
|
50
|
+
const url = bundlerUrl ?? getDefaultBundlerUrl(chain);
|
51
|
+
|
52
|
+
// Create a cache key based on the bundler URL to ensure we cache per chain/bundler
|
53
|
+
const cacheKey = `delegation-contract:${url}`;
|
54
|
+
|
55
|
+
return withCache(
|
56
|
+
async () => {
|
57
|
+
const fetchWithHeaders = getClientFetch(client);
|
58
|
+
|
59
|
+
const response = await fetchWithHeaders(url, {
|
60
|
+
useAuthToken: true,
|
61
|
+
body: stringify({
|
62
|
+
id: 1,
|
63
|
+
jsonrpc: "2.0",
|
64
|
+
method: "tw_getDelegationContract",
|
65
|
+
params: [],
|
66
|
+
}),
|
67
|
+
headers: {
|
68
|
+
"Content-Type": "application/json",
|
69
|
+
},
|
70
|
+
method: "POST",
|
71
|
+
});
|
72
|
+
|
73
|
+
if (!response.ok) {
|
74
|
+
throw new Error(
|
75
|
+
`Failed to fetch delegation contract: ${response.status} ${response.statusText}`,
|
76
|
+
);
|
77
|
+
}
|
30
78
|
|
79
|
+
const result: DelegationContractResponse = await response.json();
|
80
|
+
|
81
|
+
if ((result as any).error) {
|
82
|
+
throw new Error(
|
83
|
+
`Delegation contract RPC error: ${JSON.stringify((result as any).error)}`,
|
84
|
+
);
|
85
|
+
}
|
86
|
+
|
87
|
+
if (!result.result?.delegationContract) {
|
88
|
+
throw new Error(
|
89
|
+
"Invalid response: missing delegationContract in result",
|
90
|
+
);
|
91
|
+
}
|
92
|
+
|
93
|
+
return result.result.delegationContract;
|
94
|
+
},
|
95
|
+
{ cacheKey, cacheTime: 24 * 60 * 60 * 1000 }, // cache for 24 hours
|
96
|
+
);
|
97
|
+
}
|
98
|
+
|
99
|
+
/**
|
100
|
+
* Creates an EIP-7702 account that enables EOA (Externally Owned Account) delegation
|
101
|
+
* to smart contract functionality. This allows an EOA to delegate its code execution
|
102
|
+
* to a minimal account contract, enabling features like batch transactions and sponsored gas.
|
103
|
+
*
|
104
|
+
* The minimal account leverages EIP-7702 authorization to delegate the EOA's code to a
|
105
|
+
* MinimalAccount contract, allowing the EOA to execute smart contract functions while
|
106
|
+
* maintaining its original address and private key control.
|
107
|
+
*
|
108
|
+
* @param args - Configuration object for creating the minimal account
|
109
|
+
* @param args.client - The thirdweb client instance for blockchain interactions
|
110
|
+
* @param args.adminAccount - The EOA account that will be delegated to the minimal account contract
|
111
|
+
* @param args.sponsorGas - Optional flag to enable sponsored gas transactions via bundler
|
112
|
+
*
|
113
|
+
* @returns An Account object with enhanced capabilities including batch transactions and EIP-5792 support
|
114
|
+
*
|
115
|
+
* @example
|
116
|
+
* ```typescript
|
117
|
+
* import { createThirdwebClient, sendBatchTransaction } from "thirdweb";
|
118
|
+
* import { privateKeyToAccount } from "thirdweb/wallets";
|
119
|
+
* import { create7702MinimalAccount } from "thirdweb/wallets/in-app";
|
120
|
+
* import { sepolia } from "thirdweb/chains";
|
121
|
+
*
|
122
|
+
* // Create a client
|
123
|
+
* const client = createThirdwebClient({
|
124
|
+
* clientId: "your-client-id"
|
125
|
+
* });
|
126
|
+
*
|
127
|
+
* // Create an EOA account
|
128
|
+
* const adminAccount = privateKeyToAccount({
|
129
|
+
* client,
|
130
|
+
* privateKey: "0x..."
|
131
|
+
* });
|
132
|
+
*
|
133
|
+
* // Wrap it with a EIP-7702 account
|
134
|
+
* const minimal7702Account = create7702MinimalAccount({
|
135
|
+
* client,
|
136
|
+
* adminAccount,
|
137
|
+
* sponsorGas: true // Enable sponsored transactions
|
138
|
+
* });
|
139
|
+
*
|
140
|
+
* // Send a batch of transactions
|
141
|
+
* const result = await sendBatchTransaction({
|
142
|
+
* account: minimal7702Account,
|
143
|
+
* transactions: [
|
144
|
+
* {
|
145
|
+
* to: "0x...",
|
146
|
+
* data: "0x...",
|
147
|
+
* value: 0n,
|
148
|
+
* chainId: sepolia.id
|
149
|
+
* },
|
150
|
+
* {
|
151
|
+
* to: "0x...",
|
152
|
+
* data: "0x...",
|
153
|
+
* value: 0n,
|
154
|
+
* chainId: sepolia.id
|
155
|
+
* }
|
156
|
+
* ]});
|
157
|
+
*
|
158
|
+
* console.log("Batch transaction hash:", result.transactionHash);
|
159
|
+
* ```
|
160
|
+
*
|
161
|
+
* @wallet
|
162
|
+
*/
|
31
163
|
export const create7702MinimalAccount = (args: {
|
32
164
|
client: ThirdwebClient;
|
33
165
|
adminAccount: Account;
|
@@ -49,7 +181,14 @@ export const create7702MinimalAccount = (args: {
|
|
49
181
|
});
|
50
182
|
// check if account has been delegated already
|
51
183
|
let authorization: SignedAuthorization | undefined;
|
52
|
-
const
|
184
|
+
const delegationContractAddress = await getDelegationContractAddress({
|
185
|
+
client,
|
186
|
+
chain,
|
187
|
+
});
|
188
|
+
const isMinimalAccount = await is7702MinimalAccount(
|
189
|
+
eoaContract,
|
190
|
+
delegationContractAddress,
|
191
|
+
);
|
53
192
|
if (!isMinimalAccount) {
|
54
193
|
// if not, sign authorization
|
55
194
|
let nonce = firstTx.nonce
|
@@ -58,12 +197,12 @@ export const create7702MinimalAccount = (args: {
|
|
58
197
|
await getNonce({
|
59
198
|
client,
|
60
199
|
address: adminAccount.address,
|
61
|
-
chain
|
200
|
+
chain,
|
62
201
|
}),
|
63
202
|
);
|
64
203
|
nonce += sponsorGas ? 0n : 1n;
|
65
204
|
const auth = await adminAccount.signAuthorization?.({
|
66
|
-
address:
|
205
|
+
address: getAddress(delegationContractAddress),
|
67
206
|
chainId: firstTx.chainId,
|
68
207
|
nonce,
|
69
208
|
});
|
@@ -76,7 +215,7 @@ export const create7702MinimalAccount = (args: {
|
|
76
215
|
// send transaction from executor, needs signature
|
77
216
|
const wrappedCalls = {
|
78
217
|
calls: txs.map((tx) => ({
|
79
|
-
data: tx.data ?? "0x",
|
218
|
+
data: tx.data ?? "0x",
|
80
219
|
target: getAddress(tx.to ?? ""),
|
81
220
|
value: tx.value ?? 0n,
|
82
221
|
})),
|
@@ -131,7 +270,7 @@ export const create7702MinimalAccount = (args: {
|
|
131
270
|
const executeTx = execute({
|
132
271
|
calls: txs.map((tx) => ({
|
133
272
|
data: tx.data ?? "0x",
|
134
|
-
target: tx.to ?? "",
|
273
|
+
target: getAddress(tx.to ?? ""),
|
135
274
|
value: tx.value ?? 0n,
|
136
275
|
})),
|
137
276
|
contract: eoaContract,
|
@@ -228,7 +367,7 @@ async function getNonce(args: {
|
|
228
367
|
"../../../../rpc/actions/eth_getTransactionCount.js"
|
229
368
|
).then(({ eth_getTransactionCount }) =>
|
230
369
|
eth_getTransactionCount(rpcRequest, {
|
231
|
-
address,
|
370
|
+
address: getAddress(address),
|
232
371
|
blockTag: "pending",
|
233
372
|
}),
|
234
373
|
);
|
@@ -238,14 +377,14 @@ async function getNonce(args: {
|
|
238
377
|
async function is7702MinimalAccount(
|
239
378
|
// biome-ignore lint/suspicious/noExplicitAny: TODO properly type tw contract
|
240
379
|
eoaContract: ThirdwebContract<any>,
|
380
|
+
delegationContractAddress: string,
|
241
381
|
): Promise<boolean> {
|
242
382
|
const code = await getBytecode(eoaContract);
|
243
383
|
const isDelegated = code.length > 0 && code.startsWith("0xef0100");
|
244
384
|
const target = `0x${code.slice(8, 48)}`;
|
245
385
|
return (
|
246
386
|
isDelegated &&
|
247
|
-
target.toLowerCase() ===
|
248
|
-
MINIMAL_ACCOUNT_IMPLEMENTATION_ADDRESS.toLowerCase()
|
387
|
+
target.toLowerCase() === delegationContractAddress.toLowerCase()
|
249
388
|
);
|
250
389
|
}
|
251
390
|
|
@@ -1,126 +1,110 @@
|
|
1
|
-
import {
|
1
|
+
import {
|
2
|
+
configure,
|
3
|
+
isSuccessResponse,
|
4
|
+
sendTransaction,
|
5
|
+
signMessage,
|
6
|
+
} from "@thirdweb-dev/engine";
|
2
7
|
import { beforeAll, describe, expect, it } from "vitest";
|
3
8
|
import { TEST_CLIENT } from "~test/test-clients.js";
|
4
9
|
import { sepolia } from "../../../../chains/chain-definitions/sepolia.js";
|
5
|
-
import { createThirdwebClient } from "../../../../client/client.js";
|
6
10
|
import { waitForTransactionHash } from "../../../../engine/wait-for-tx-hash.js";
|
7
|
-
import {
|
8
|
-
getThirdwebBaseUrl,
|
9
|
-
setThirdwebDomains,
|
10
|
-
} from "../../../../utils/domains.js";
|
11
|
-
import { getClientFetch } from "../../../../utils/fetch.js";
|
12
11
|
import { stringify } from "../../../../utils/json.js";
|
13
12
|
import type { Account } from "../../../interfaces/wallet.js";
|
14
13
|
import { inAppWallet } from "../in-app.js";
|
15
14
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
.skip("InAppWallet Gateway Tests", () => {
|
20
|
-
let account: Account;
|
21
|
-
let authToken: string | null | undefined;
|
22
|
-
const clientIdFetch = getClientFetch(
|
23
|
-
createThirdwebClient({
|
24
|
-
clientId: TEST_CLIENT.clientId,
|
25
|
-
}),
|
26
|
-
);
|
15
|
+
describe.runIf(process.env.TW_SECRET_KEY)("InAppWallet Gateway Tests", () => {
|
16
|
+
let account: Account;
|
17
|
+
let authToken: string | null | undefined;
|
27
18
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
inAppWallet: "embedded-wallet.thirdweb-dev.com",
|
33
|
-
rpc: "rpc.thirdweb-dev.com",
|
34
|
-
});
|
35
|
-
const wallet = inAppWallet();
|
36
|
-
account = await wallet.connect({
|
37
|
-
client: TEST_CLIENT,
|
38
|
-
strategy: "backend",
|
39
|
-
walletSecret: "test-secret",
|
40
|
-
});
|
41
|
-
authToken = wallet.getAuthToken();
|
42
|
-
expect(authToken).toBeDefined();
|
19
|
+
beforeAll(async () => {
|
20
|
+
configure({
|
21
|
+
clientId: TEST_CLIENT.clientId,
|
22
|
+
secretKey: TEST_CLIENT.secretKey,
|
43
23
|
});
|
24
|
+
const wallet = inAppWallet();
|
25
|
+
account = await wallet.connect({
|
26
|
+
client: TEST_CLIENT,
|
27
|
+
strategy: "backend",
|
28
|
+
walletSecret: "test-secret",
|
29
|
+
});
|
30
|
+
authToken = wallet.getAuthToken?.();
|
31
|
+
expect(authToken).toBeDefined();
|
32
|
+
});
|
44
33
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
});
|
49
|
-
|
50
|
-
// sign via api
|
51
|
-
const signResult = await signMessage({
|
52
|
-
baseUrl: getThirdwebBaseUrl("engineCloud"),
|
53
|
-
body: {
|
54
|
-
params: [
|
55
|
-
{
|
56
|
-
format: "text",
|
57
|
-
message: "Hello, world!",
|
58
|
-
},
|
59
|
-
],
|
60
|
-
signingOptions: {
|
61
|
-
from: account.address,
|
62
|
-
type: "EOA",
|
63
|
-
},
|
64
|
-
},
|
65
|
-
bodySerializer: stringify,
|
66
|
-
fetch: clientIdFetch,
|
67
|
-
headers: {
|
68
|
-
"x-wallet-access-token": authToken,
|
69
|
-
},
|
70
|
-
});
|
71
|
-
|
72
|
-
const signatureResult = signResult.data?.result[0];
|
73
|
-
if (signatureResult && "result" in signatureResult) {
|
74
|
-
expect(signatureResult.result.signature).toEqual(rawSignature);
|
75
|
-
} else {
|
76
|
-
throw new Error(
|
77
|
-
`Failed to sign message: ${stringify(signatureResult?.error) || "Unknown error"}`,
|
78
|
-
);
|
79
|
-
}
|
34
|
+
it("should sign a message with backend strategy", async () => {
|
35
|
+
const rawSignature = await account.signMessage({
|
36
|
+
message: "Hello, world!",
|
80
37
|
});
|
81
38
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
chainId: sepolia.id,
|
86
|
-
from: account.address,
|
87
|
-
type: "auto" as const,
|
88
|
-
},
|
39
|
+
// sign via api
|
40
|
+
const signResult = await signMessage({
|
41
|
+
body: {
|
89
42
|
params: [
|
90
43
|
{
|
91
|
-
|
92
|
-
|
93
|
-
value: "0",
|
44
|
+
format: "text",
|
45
|
+
message: "Hello, world!",
|
94
46
|
},
|
95
47
|
],
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
body,
|
100
|
-
bodySerializer: stringify,
|
101
|
-
fetch: clientIdFetch,
|
102
|
-
headers: {
|
103
|
-
"x-wallet-access-token": authToken,
|
48
|
+
signingOptions: {
|
49
|
+
from: account.address,
|
50
|
+
type: "EOA",
|
104
51
|
},
|
105
|
-
}
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
}
|
52
|
+
},
|
53
|
+
headers: {
|
54
|
+
"x-wallet-access-token": authToken,
|
55
|
+
},
|
56
|
+
});
|
111
57
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
throw new Error("No transaction ID found");
|
116
|
-
}
|
58
|
+
if (signResult.error) {
|
59
|
+
throw new Error(`Error signing message: ${stringify(signResult.error)}`);
|
60
|
+
}
|
117
61
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
62
|
+
const signatureResult = signResult.data?.result?.[0];
|
63
|
+
if (signatureResult && isSuccessResponse(signatureResult)) {
|
64
|
+
expect(signatureResult.result.signature).toEqual(rawSignature);
|
65
|
+
} else {
|
66
|
+
throw new Error(
|
67
|
+
`Failed to sign message: ${stringify(signatureResult?.error) || "Unknown error"}`,
|
68
|
+
);
|
69
|
+
}
|
70
|
+
});
|
122
71
|
|
123
|
-
|
124
|
-
|
72
|
+
it("should queue a 4337 transaction", async () => {
|
73
|
+
const body = {
|
74
|
+
executionOptions: {
|
75
|
+
chainId: sepolia.id,
|
76
|
+
from: account.address,
|
77
|
+
type: "auto" as const,
|
78
|
+
},
|
79
|
+
params: [
|
80
|
+
{
|
81
|
+
data: "0x",
|
82
|
+
to: account.address,
|
83
|
+
value: "0",
|
84
|
+
},
|
85
|
+
],
|
86
|
+
};
|
87
|
+
const result = await sendTransaction({
|
88
|
+
body,
|
89
|
+
headers: {
|
90
|
+
"x-wallet-access-token": authToken,
|
91
|
+
},
|
125
92
|
});
|
93
|
+
if (result.error) {
|
94
|
+
throw new Error(`Error sending transaction: ${stringify(result.error)}`);
|
95
|
+
}
|
96
|
+
|
97
|
+
const txId = result.data?.result.transactions[0]?.id;
|
98
|
+
if (!txId) {
|
99
|
+
throw new Error("No transaction ID found");
|
100
|
+
}
|
101
|
+
|
102
|
+
const tx = await waitForTransactionHash({
|
103
|
+
client: TEST_CLIENT,
|
104
|
+
transactionId: txId,
|
105
|
+
});
|
106
|
+
|
107
|
+
console.log(tx.transactionHash);
|
108
|
+
expect(tx.transactionHash).toBeDefined();
|
126
109
|
});
|
110
|
+
});
|
@@ -73,8 +73,7 @@ describe.runIf(process.env.TW_SECRET_KEY)(
|
|
73
73
|
if (!executedLog) {
|
74
74
|
throw new Error("No executed log found");
|
75
75
|
}
|
76
|
-
expect(executedLog.args.
|
77
|
-
expect(executedLog.args.value).toBe(0n);
|
76
|
+
expect(executedLog.args.user).toBe(account.address);
|
78
77
|
});
|
79
78
|
|
80
79
|
it("should sponsor gas for a 4337 smart account", async () => {
|