thirdweb 5.48.2 → 5.48.3-nightly-a8e2bc58c9e8fe5b75d6c27d406e6b80d5d067e2-20240828000339
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/exports/wallets/smart.js +4 -2
- package/dist/cjs/exports/wallets/smart.js.map +1 -1
- package/dist/cjs/extensions/erc1155/drops/write/claimTo.js.map +1 -1
- package/dist/cjs/extensions/erc4337/__generated__/IEntryPoint_v07/events/PostOpRevertReason.js +32 -0
- package/dist/cjs/extensions/erc4337/__generated__/IEntryPoint_v07/events/PostOpRevertReason.js.map +1 -0
- package/dist/cjs/extensions/erc4337/__generated__/IEntryPoint_v07/read/getUserOpHash.js +153 -0
- package/dist/cjs/extensions/erc4337/__generated__/IEntryPoint_v07/read/getUserOpHash.js.map +1 -0
- package/dist/cjs/extensions/prebuilts/__generated__/VoteERC20/write/initialize.js +184 -0
- package/dist/cjs/extensions/prebuilts/__generated__/VoteERC20/write/initialize.js.map +1 -0
- package/dist/cjs/extensions/prebuilts/deploy-vote.js +122 -0
- package/dist/cjs/extensions/prebuilts/deploy-vote.js.map +1 -0
- package/dist/cjs/react/core/hooks/pay/useBuyWithCryptoQuote.js +5 -1
- package/dist/cjs/react/core/hooks/pay/useBuyWithCryptoQuote.js.map +1 -1
- package/dist/cjs/react/core/hooks/pay/useBuyWithFiatQuote.js +5 -1
- package/dist/cjs/react/core/hooks/pay/useBuyWithFiatQuote.js.map +1 -1
- package/dist/cjs/react/core/hooks/transaction/useSendAndConfirmTransaction.js +12 -0
- package/dist/cjs/react/core/hooks/transaction/useSendAndConfirmTransaction.js.map +1 -1
- package/dist/cjs/react/native/hooks/transaction/useSendTransaction.js +11 -0
- package/dist/cjs/react/native/hooks/transaction/useSendTransaction.js.map +1 -1
- package/dist/cjs/react/web/ui/TransactionButton/index.js +13 -0
- package/dist/cjs/react/web/ui/TransactionButton/index.js.map +1 -1
- package/dist/cjs/transaction/actions/send-and-confirm-transaction.js +13 -0
- package/dist/cjs/transaction/actions/send-and-confirm-transaction.js.map +1 -1
- package/dist/cjs/transaction/actions/send-transaction.js +13 -0
- package/dist/cjs/transaction/actions/send-transaction.js.map +1 -1
- package/dist/cjs/transaction/actions/zksync/send-eip712-transaction.js +1 -1
- package/dist/cjs/transaction/actions/zksync/send-eip712-transaction.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/web/lib/in-app-account.js +5 -1
- package/dist/cjs/wallets/in-app/web/lib/in-app-account.js.map +1 -1
- package/dist/cjs/wallets/in-app/web/utils/iFrameCommunication/IframeCommunicator.js +1 -0
- package/dist/cjs/wallets/in-app/web/utils/iFrameCommunication/IframeCommunicator.js.map +1 -1
- package/dist/cjs/wallets/smart/index.js +13 -2
- package/dist/cjs/wallets/smart/index.js.map +1 -1
- package/dist/cjs/wallets/smart/lib/bundler.js +11 -2
- package/dist/cjs/wallets/smart/lib/bundler.js.map +1 -1
- package/dist/cjs/wallets/smart/lib/constants.js +27 -13
- package/dist/cjs/wallets/smart/lib/constants.js.map +1 -1
- package/dist/cjs/wallets/smart/lib/packUserOp.js +75 -0
- package/dist/cjs/wallets/smart/lib/packUserOp.js.map +1 -0
- package/dist/cjs/wallets/smart/lib/paymaster.js +11 -1
- package/dist/cjs/wallets/smart/lib/paymaster.js.map +1 -1
- package/dist/cjs/wallets/smart/lib/userop.js +201 -66
- package/dist/cjs/wallets/smart/lib/userop.js.map +1 -1
- package/dist/cjs/wallets/smart/lib/utils.js +1 -1
- package/dist/cjs/wallets/smart/lib/utils.js.map +1 -1
- package/dist/cjs/wallets/smart/smart-wallet.js +2 -1
- package/dist/cjs/wallets/smart/smart-wallet.js.map +1 -1
- package/dist/cjs/wallets/smart/types.js.map +1 -1
- package/dist/esm/exports/wallets/smart.js +1 -1
- package/dist/esm/exports/wallets/smart.js.map +1 -1
- package/dist/esm/extensions/erc1155/drops/write/claimTo.js.map +1 -1
- package/dist/esm/extensions/erc4337/__generated__/IEntryPoint_v07/events/PostOpRevertReason.js +29 -0
- package/dist/esm/extensions/erc4337/__generated__/IEntryPoint_v07/events/PostOpRevertReason.js.map +1 -0
- package/dist/esm/extensions/erc4337/__generated__/IEntryPoint_v07/read/getUserOpHash.js +145 -0
- package/dist/esm/extensions/erc4337/__generated__/IEntryPoint_v07/read/getUserOpHash.js.map +1 -0
- package/dist/esm/extensions/prebuilts/__generated__/VoteERC20/write/initialize.js +177 -0
- package/dist/esm/extensions/prebuilts/__generated__/VoteERC20/write/initialize.js.map +1 -0
- package/dist/esm/extensions/prebuilts/deploy-vote.js +119 -0
- package/dist/esm/extensions/prebuilts/deploy-vote.js.map +1 -0
- package/dist/esm/react/core/hooks/pay/useBuyWithCryptoQuote.js +5 -1
- package/dist/esm/react/core/hooks/pay/useBuyWithCryptoQuote.js.map +1 -1
- package/dist/esm/react/core/hooks/pay/useBuyWithFiatQuote.js +5 -1
- package/dist/esm/react/core/hooks/pay/useBuyWithFiatQuote.js.map +1 -1
- package/dist/esm/react/core/hooks/transaction/useSendAndConfirmTransaction.js +12 -0
- package/dist/esm/react/core/hooks/transaction/useSendAndConfirmTransaction.js.map +1 -1
- package/dist/esm/react/native/hooks/transaction/useSendTransaction.js +11 -0
- package/dist/esm/react/native/hooks/transaction/useSendTransaction.js.map +1 -1
- package/dist/esm/react/web/ui/TransactionButton/index.js +13 -0
- package/dist/esm/react/web/ui/TransactionButton/index.js.map +1 -1
- package/dist/esm/transaction/actions/send-and-confirm-transaction.js +13 -0
- package/dist/esm/transaction/actions/send-and-confirm-transaction.js.map +1 -1
- package/dist/esm/transaction/actions/send-transaction.js +13 -0
- package/dist/esm/transaction/actions/send-transaction.js.map +1 -1
- package/dist/esm/transaction/actions/zksync/send-eip712-transaction.js +1 -1
- package/dist/esm/transaction/actions/zksync/send-eip712-transaction.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/web/lib/in-app-account.js +5 -1
- package/dist/esm/wallets/in-app/web/lib/in-app-account.js.map +1 -1
- package/dist/esm/wallets/in-app/web/utils/iFrameCommunication/IframeCommunicator.js +1 -0
- package/dist/esm/wallets/in-app/web/utils/iFrameCommunication/IframeCommunicator.js.map +1 -1
- package/dist/esm/wallets/smart/index.js +14 -3
- package/dist/esm/wallets/smart/index.js.map +1 -1
- package/dist/esm/wallets/smart/lib/bundler.js +12 -3
- package/dist/esm/wallets/smart/lib/bundler.js.map +1 -1
- package/dist/esm/wallets/smart/lib/constants.js +23 -10
- package/dist/esm/wallets/smart/lib/constants.js.map +1 -1
- package/dist/esm/wallets/smart/lib/packUserOp.js +65 -0
- package/dist/esm/wallets/smart/lib/packUserOp.js.map +1 -0
- package/dist/esm/wallets/smart/lib/paymaster.js +12 -2
- package/dist/esm/wallets/smart/lib/paymaster.js.map +1 -1
- package/dist/esm/wallets/smart/lib/userop.js +202 -67
- package/dist/esm/wallets/smart/lib/userop.js.map +1 -1
- package/dist/esm/wallets/smart/lib/utils.js +1 -1
- package/dist/esm/wallets/smart/lib/utils.js.map +1 -1
- package/dist/esm/wallets/smart/smart-wallet.js +3 -2
- package/dist/esm/wallets/smart/smart-wallet.js.map +1 -1
- package/dist/esm/wallets/smart/types.js.map +1 -1
- package/dist/types/exports/wallets/smart.d.ts +2 -2
- package/dist/types/exports/wallets/smart.d.ts.map +1 -1
- package/dist/types/extensions/erc1155/drops/write/claimTo.d.ts +2 -3
- package/dist/types/extensions/erc1155/drops/write/claimTo.d.ts.map +1 -1
- package/dist/types/extensions/erc4337/__generated__/IEntryPoint_v07/events/PostOpRevertReason.d.ts +57 -0
- package/dist/types/extensions/erc4337/__generated__/IEntryPoint_v07/events/PostOpRevertReason.d.ts.map +1 -0
- package/dist/types/extensions/erc4337/__generated__/IEntryPoint_v07/read/getUserOpHash.d.ts +123 -0
- package/dist/types/extensions/erc4337/__generated__/IEntryPoint_v07/read/getUserOpHash.d.ts.map +1 -0
- package/dist/types/extensions/prebuilts/__generated__/VoteERC20/write/initialize.d.ts +129 -0
- package/dist/types/extensions/prebuilts/__generated__/VoteERC20/write/initialize.d.ts.map +1 -0
- package/dist/types/extensions/prebuilts/deploy-vote.d.ts +82 -0
- package/dist/types/extensions/prebuilts/deploy-vote.d.ts.map +1 -0
- package/dist/types/react/core/hooks/pay/useBuyWithCryptoQuote.d.ts.map +1 -1
- package/dist/types/react/core/hooks/pay/useBuyWithFiatQuote.d.ts.map +1 -1
- package/dist/types/react/core/hooks/transaction/useSendAndConfirmTransaction.d.ts +12 -0
- package/dist/types/react/core/hooks/transaction/useSendAndConfirmTransaction.d.ts.map +1 -1
- package/dist/types/react/native/hooks/transaction/useSendTransaction.d.ts +11 -0
- package/dist/types/react/native/hooks/transaction/useSendTransaction.d.ts.map +1 -1
- package/dist/types/react/web/ui/TransactionButton/index.d.ts +13 -0
- package/dist/types/react/web/ui/TransactionButton/index.d.ts.map +1 -1
- package/dist/types/transaction/actions/send-and-confirm-transaction.d.ts +13 -0
- package/dist/types/transaction/actions/send-and-confirm-transaction.d.ts.map +1 -1
- package/dist/types/transaction/actions/send-transaction.d.ts +13 -0
- package/dist/types/transaction/actions/send-transaction.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/web/lib/in-app-account.d.ts.map +1 -1
- package/dist/types/wallets/in-app/web/utils/iFrameCommunication/IframeCommunicator.d.ts.map +1 -1
- package/dist/types/wallets/smart/index.d.ts.map +1 -1
- package/dist/types/wallets/smart/lib/bundler.d.ts +3 -3
- package/dist/types/wallets/smart/lib/bundler.d.ts.map +1 -1
- package/dist/types/wallets/smart/lib/constants.d.ts +6 -6
- package/dist/types/wallets/smart/lib/constants.d.ts.map +1 -1
- package/dist/types/wallets/smart/lib/packUserOp.d.ts +16 -0
- package/dist/types/wallets/smart/lib/packUserOp.d.ts.map +1 -0
- package/dist/types/wallets/smart/lib/paymaster.d.ts +3 -3
- package/dist/types/wallets/smart/lib/paymaster.d.ts.map +1 -1
- package/dist/types/wallets/smart/lib/userop.d.ts +6 -4
- package/dist/types/wallets/smart/lib/userop.d.ts.map +1 -1
- package/dist/types/wallets/smart/lib/utils.d.ts +2 -2
- package/dist/types/wallets/smart/lib/utils.d.ts.map +1 -1
- package/dist/types/wallets/smart/smart-wallet.d.ts.map +1 -1
- package/dist/types/wallets/smart/types.d.ts +62 -9
- package/dist/types/wallets/smart/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/exports/wallets/smart.ts +4 -2
- package/src/extensions/erc1155/drops/write/claimTo.ts +2 -3
- package/src/extensions/erc4337/__generated__/IEntryPoint_v07/events/PostOpRevertReason.ts +49 -0
- package/src/extensions/erc4337/__generated__/IEntryPoint_v07/read/getUserOpHash.ts +181 -0
- package/src/extensions/prebuilts/__generated__/VoteERC20/write/initialize.ts +230 -0
- package/src/extensions/prebuilts/deploy-vote.test.ts +73 -0
- package/src/extensions/prebuilts/deploy-vote.ts +213 -0
- package/src/extensions/vote/read/proposalExists.test.ts +123 -0
- package/src/react/core/hooks/pay/useBuyWithCryptoQuote.ts +16 -1
- package/src/react/core/hooks/pay/useBuyWithFiatQuote.ts +16 -1
- package/src/react/core/hooks/transaction/useSendAndConfirmTransaction.ts +12 -0
- package/src/react/native/hooks/transaction/useSendTransaction.tsx +11 -0
- package/src/react/web/ui/TransactionButton/index.tsx +13 -0
- package/src/transaction/actions/send-and-confirm-transaction.ts +13 -0
- package/src/transaction/actions/send-transaction.ts +13 -0
- package/src/transaction/actions/zksync/send-eip712-transaction.ts +1 -1
- package/src/version.ts +1 -1
- package/src/wallets/in-app/web/lib/in-app-account.ts +5 -1
- package/src/wallets/in-app/web/utils/iFrameCommunication/IframeCommunicator.ts +1 -0
- package/src/wallets/smart/index.ts +21 -5
- package/src/wallets/smart/lib/bundler.ts +21 -5
- package/src/wallets/smart/lib/constants.ts +29 -10
- package/src/wallets/smart/lib/packUserOp.ts +79 -0
- package/src/wallets/smart/lib/paymaster.ts +22 -5
- package/src/wallets/smart/lib/userop.ts +292 -85
- package/src/wallets/smart/lib/utils.ts +11 -4
- package/src/wallets/smart/smart-wallet-integration-v07.test.ts +206 -0
- package/src/wallets/smart/smart-wallet-integration.test.ts +1 -1
- package/src/wallets/smart/smart-wallet-zksync.test.ts +3 -3
- package/src/wallets/smart/smart-wallet.ts +4 -2
- package/src/wallets/smart/types.ts +73 -9
@@ -6,22 +6,24 @@ import {
|
|
6
6
|
getContract,
|
7
7
|
} from "../../../contract/contract.js";
|
8
8
|
import { getNonce } from "../../../extensions/erc4337/__generated__/IEntryPoint/read/getNonce.js";
|
9
|
+
import { getUserOpHash as getUserOpHashV06 } from "../../../extensions/erc4337/__generated__/IEntryPoint/read/getUserOpHash.js";
|
10
|
+
import { getUserOpHash as getUserOpHashV07 } from "../../../extensions/erc4337/__generated__/IEntryPoint_v07/read/getUserOpHash.js";
|
9
11
|
import { getDefaultGasOverrides } from "../../../gas/fee-data.js";
|
10
12
|
import { encode } from "../../../transaction/actions/encode.js";
|
11
13
|
import type { PreparedTransaction } from "../../../transaction/prepare-transaction.js";
|
12
14
|
import type { TransactionReceipt } from "../../../transaction/types.js";
|
13
|
-
import { encodeAbiParameters } from "../../../utils/abi/encodeAbiParameters.js";
|
14
15
|
import { isContractDeployed } from "../../../utils/bytecode/is-contract-deployed.js";
|
15
16
|
import type { Hex } from "../../../utils/encoding/hex.js";
|
16
17
|
import { hexToBytes } from "../../../utils/encoding/to-bytes.js";
|
17
18
|
import { isThirdwebUrl } from "../../../utils/fetch.js";
|
18
|
-
import { keccak256 } from "../../../utils/hashing/keccak256.js";
|
19
19
|
import { resolvePromisedValue } from "../../../utils/promise/resolve-promised-value.js";
|
20
20
|
import type { Account } from "../../interfaces/wallet.js";
|
21
21
|
import type {
|
22
22
|
BundlerOptions,
|
23
|
+
PaymasterResult,
|
23
24
|
SmartWalletOptions,
|
24
|
-
|
25
|
+
UserOperationV06,
|
26
|
+
UserOperationV07,
|
25
27
|
} from "../types.js";
|
26
28
|
import {
|
27
29
|
estimateUserOpGas,
|
@@ -32,8 +34,11 @@ import { prepareCreateAccount } from "./calls.js";
|
|
32
34
|
import {
|
33
35
|
DUMMY_SIGNATURE,
|
34
36
|
ENTRYPOINT_ADDRESS_v0_6,
|
37
|
+
ENTRYPOINT_ADDRESS_v0_7,
|
35
38
|
getDefaultBundlerUrl,
|
39
|
+
getEntryPointVersion,
|
36
40
|
} from "./constants.js";
|
41
|
+
import { getPackedUserOperation } from "./packUserOp.js";
|
37
42
|
import { getPaymasterAndData } from "./paymaster.js";
|
38
43
|
import { generateRandomUint192 } from "./utils.js";
|
39
44
|
|
@@ -102,7 +107,7 @@ export async function createUnsignedUserOp(args: {
|
|
102
107
|
adminAddress: string;
|
103
108
|
sponsorGas: boolean;
|
104
109
|
overrides?: SmartWalletOptions["overrides"];
|
105
|
-
}): Promise<
|
110
|
+
}): Promise<UserOperationV06 | UserOperationV07> {
|
106
111
|
const {
|
107
112
|
transaction: executeTx,
|
108
113
|
accountContract,
|
@@ -113,24 +118,88 @@ export async function createUnsignedUserOp(args: {
|
|
113
118
|
} = args;
|
114
119
|
const chain = executeTx.chain;
|
115
120
|
const client = executeTx.client;
|
116
|
-
|
117
|
-
const initCode = isDeployed
|
118
|
-
? "0x"
|
119
|
-
: await getAccountInitCode({
|
120
|
-
factoryContract: factoryContract,
|
121
|
-
adminAddress,
|
122
|
-
accountSalt: overrides?.accountSalt,
|
123
|
-
createAccountOverride: overrides?.createAccount,
|
124
|
-
});
|
125
|
-
const callData = await encode(executeTx);
|
121
|
+
|
126
122
|
const bundlerOptions = {
|
127
123
|
client,
|
128
124
|
chain,
|
129
125
|
entrypointAddress: overrides?.entrypointAddress,
|
130
126
|
};
|
131
127
|
|
128
|
+
const entrypointVersion = getEntryPointVersion(
|
129
|
+
args.overrides?.entrypointAddress || ENTRYPOINT_ADDRESS_v0_6,
|
130
|
+
);
|
131
|
+
|
132
|
+
const [isDeployed, callData, gasFees, nonce] = await Promise.all([
|
133
|
+
isContractDeployed(accountContract),
|
134
|
+
encode(executeTx),
|
135
|
+
getGasFees({
|
136
|
+
executeTx,
|
137
|
+
bundlerOptions,
|
138
|
+
chain,
|
139
|
+
client,
|
140
|
+
}),
|
141
|
+
getAccountNonce({
|
142
|
+
accountContract,
|
143
|
+
chain,
|
144
|
+
client,
|
145
|
+
entrypointAddress: overrides?.entrypointAddress,
|
146
|
+
getNonceOverride: overrides?.getAccountNonce,
|
147
|
+
}),
|
148
|
+
]);
|
149
|
+
|
150
|
+
const { maxFeePerGas, maxPriorityFeePerGas } = gasFees;
|
151
|
+
|
152
|
+
if (entrypointVersion === "v0.7") {
|
153
|
+
return populateUserOp_v0_7({
|
154
|
+
bundlerOptions,
|
155
|
+
factoryContract,
|
156
|
+
accountContract,
|
157
|
+
adminAddress,
|
158
|
+
sponsorGas,
|
159
|
+
overrides,
|
160
|
+
isDeployed,
|
161
|
+
nonce,
|
162
|
+
callData,
|
163
|
+
maxFeePerGas,
|
164
|
+
maxPriorityFeePerGas,
|
165
|
+
});
|
166
|
+
}
|
167
|
+
|
168
|
+
// default to v0.6
|
169
|
+
return populateUserOp_v0_6({
|
170
|
+
bundlerOptions,
|
171
|
+
factoryContract,
|
172
|
+
accountContract,
|
173
|
+
adminAddress,
|
174
|
+
sponsorGas,
|
175
|
+
overrides,
|
176
|
+
isDeployed,
|
177
|
+
nonce,
|
178
|
+
callData,
|
179
|
+
maxFeePerGas,
|
180
|
+
maxPriorityFeePerGas,
|
181
|
+
});
|
182
|
+
}
|
183
|
+
|
184
|
+
async function getGasFees(args: {
|
185
|
+
executeTx: PreparedTransaction;
|
186
|
+
bundlerOptions: BundlerOptions;
|
187
|
+
chain: Chain;
|
188
|
+
client: ThirdwebClient;
|
189
|
+
}): Promise<{
|
190
|
+
maxFeePerGas: bigint;
|
191
|
+
maxPriorityFeePerGas: bigint;
|
192
|
+
}> {
|
193
|
+
const { executeTx, bundlerOptions, chain, client } = args;
|
132
194
|
let { maxFeePerGas, maxPriorityFeePerGas } = executeTx;
|
133
|
-
|
195
|
+
|
196
|
+
const entrypointVersion = getEntryPointVersion(
|
197
|
+
bundlerOptions.entrypointAddress || ENTRYPOINT_ADDRESS_v0_6,
|
198
|
+
);
|
199
|
+
const bundlerVersion = entrypointVersion === "v0.6" ? "v1" : "v2";
|
200
|
+
const bundlerUrl =
|
201
|
+
bundlerOptions?.bundlerUrl ?? getDefaultBundlerUrl(chain, bundlerVersion);
|
202
|
+
|
134
203
|
if (isThirdwebUrl(bundlerUrl)) {
|
135
204
|
// get gas prices from bundler
|
136
205
|
const bundlerGasPrice = await getUserOpGasFees({
|
@@ -160,16 +229,175 @@ export async function createUnsignedUserOp(args: {
|
|
160
229
|
maxFeePerGas = resolvedMaxFeePerGas ?? feeData.maxFeePerGas ?? 0n;
|
161
230
|
}
|
162
231
|
}
|
232
|
+
return { maxFeePerGas, maxPriorityFeePerGas };
|
233
|
+
}
|
163
234
|
|
164
|
-
|
235
|
+
async function populateUserOp_v0_7(args: {
|
236
|
+
bundlerOptions: BundlerOptions;
|
237
|
+
factoryContract: ThirdwebContract;
|
238
|
+
accountContract: ThirdwebContract;
|
239
|
+
adminAddress: string;
|
240
|
+
sponsorGas: boolean;
|
241
|
+
overrides?: SmartWalletOptions["overrides"];
|
242
|
+
isDeployed: boolean;
|
243
|
+
nonce: bigint;
|
244
|
+
callData: Hex;
|
245
|
+
maxFeePerGas: bigint;
|
246
|
+
maxPriorityFeePerGas: bigint;
|
247
|
+
}): Promise<UserOperationV07> {
|
248
|
+
const {
|
249
|
+
bundlerOptions,
|
250
|
+
isDeployed,
|
251
|
+
factoryContract,
|
165
252
|
accountContract,
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
253
|
+
adminAddress,
|
254
|
+
sponsorGas,
|
255
|
+
overrides,
|
256
|
+
nonce,
|
257
|
+
callData,
|
258
|
+
maxFeePerGas,
|
259
|
+
maxPriorityFeePerGas,
|
260
|
+
} = args;
|
261
|
+
const { chain, client } = bundlerOptions;
|
262
|
+
const factory = isDeployed ? undefined : factoryContract.address;
|
263
|
+
const factoryData = isDeployed
|
264
|
+
? "0x"
|
265
|
+
: await encode(
|
266
|
+
prepareCreateAccount({
|
267
|
+
factoryContract: factoryContract,
|
268
|
+
adminAddress,
|
269
|
+
accountSalt: overrides?.accountSalt,
|
270
|
+
createAccountOverride: overrides?.createAccount,
|
271
|
+
}),
|
272
|
+
);
|
171
273
|
|
172
|
-
const partialOp:
|
274
|
+
const partialOp: UserOperationV07 = {
|
275
|
+
sender: accountContract.address,
|
276
|
+
nonce,
|
277
|
+
callData,
|
278
|
+
maxFeePerGas,
|
279
|
+
maxPriorityFeePerGas,
|
280
|
+
callGasLimit: 0n,
|
281
|
+
verificationGasLimit: 0n,
|
282
|
+
preVerificationGas: 0n,
|
283
|
+
factory,
|
284
|
+
factoryData,
|
285
|
+
paymaster: undefined,
|
286
|
+
paymasterData: "0x",
|
287
|
+
paymasterVerificationGasLimit: 0n,
|
288
|
+
paymasterPostOpGasLimit: 0n,
|
289
|
+
signature: DUMMY_SIGNATURE,
|
290
|
+
};
|
291
|
+
|
292
|
+
if (sponsorGas) {
|
293
|
+
const paymasterResult = (await getPaymasterAndData({
|
294
|
+
userOp: partialOp,
|
295
|
+
chain,
|
296
|
+
client,
|
297
|
+
entrypointAddress: overrides?.entrypointAddress,
|
298
|
+
paymasterOverride: overrides?.paymaster,
|
299
|
+
})) as Extract<PaymasterResult, { paymaster: string }>;
|
300
|
+
if (paymasterResult.paymaster && paymasterResult.paymasterData) {
|
301
|
+
partialOp.paymaster = paymasterResult.paymaster;
|
302
|
+
partialOp.paymasterData = paymasterResult.paymasterData as Hex;
|
303
|
+
}
|
304
|
+
// paymaster can have the gas limits in the response
|
305
|
+
if (
|
306
|
+
paymasterResult.callGasLimit &&
|
307
|
+
paymasterResult.verificationGasLimit &&
|
308
|
+
paymasterResult.preVerificationGas &&
|
309
|
+
paymasterResult.paymasterPostOpGasLimit &&
|
310
|
+
paymasterResult.paymasterVerificationGasLimit
|
311
|
+
) {
|
312
|
+
partialOp.callGasLimit = paymasterResult.callGasLimit;
|
313
|
+
partialOp.verificationGasLimit = paymasterResult.verificationGasLimit;
|
314
|
+
partialOp.preVerificationGas = paymasterResult.preVerificationGas;
|
315
|
+
partialOp.paymasterPostOpGasLimit =
|
316
|
+
paymasterResult.paymasterPostOpGasLimit;
|
317
|
+
partialOp.paymasterVerificationGasLimit =
|
318
|
+
paymasterResult.paymasterVerificationGasLimit;
|
319
|
+
} else {
|
320
|
+
// otherwise fallback to bundler for gas limits
|
321
|
+
const estimates = await estimateUserOpGas({
|
322
|
+
userOp: partialOp,
|
323
|
+
options: bundlerOptions,
|
324
|
+
});
|
325
|
+
partialOp.callGasLimit = estimates.callGasLimit;
|
326
|
+
partialOp.verificationGasLimit = estimates.verificationGasLimit;
|
327
|
+
partialOp.preVerificationGas = estimates.preVerificationGas;
|
328
|
+
partialOp.paymasterPostOpGasLimit =
|
329
|
+
paymasterResult.paymasterPostOpGasLimit || 0n;
|
330
|
+
partialOp.paymasterVerificationGasLimit =
|
331
|
+
paymasterResult.paymasterVerificationGasLimit || 0n;
|
332
|
+
// need paymaster to re-sign after estimates
|
333
|
+
const paymasterResult2 = (await getPaymasterAndData({
|
334
|
+
userOp: partialOp,
|
335
|
+
chain,
|
336
|
+
client,
|
337
|
+
entrypointAddress: overrides?.entrypointAddress,
|
338
|
+
paymasterOverride: overrides?.paymaster,
|
339
|
+
})) as Extract<PaymasterResult, { paymaster: string }>;
|
340
|
+
if (paymasterResult2.paymaster && paymasterResult2.paymasterData) {
|
341
|
+
partialOp.paymaster = paymasterResult2.paymaster;
|
342
|
+
partialOp.paymasterData = paymasterResult2.paymasterData as Hex;
|
343
|
+
}
|
344
|
+
}
|
345
|
+
} else {
|
346
|
+
// not gasless, so we just need to estimate gas limits
|
347
|
+
const estimates = await estimateUserOpGas({
|
348
|
+
userOp: partialOp,
|
349
|
+
options: bundlerOptions,
|
350
|
+
});
|
351
|
+
partialOp.callGasLimit = estimates.callGasLimit;
|
352
|
+
partialOp.verificationGasLimit = estimates.verificationGasLimit;
|
353
|
+
partialOp.preVerificationGas = estimates.preVerificationGas;
|
354
|
+
partialOp.paymasterPostOpGasLimit = estimates.paymasterPostOpGasLimit || 0n;
|
355
|
+
partialOp.paymasterVerificationGasLimit =
|
356
|
+
estimates.paymasterVerificationGasLimit || 0n;
|
357
|
+
}
|
358
|
+
return {
|
359
|
+
...partialOp,
|
360
|
+
signature: "0x" as Hex,
|
361
|
+
};
|
362
|
+
}
|
363
|
+
|
364
|
+
async function populateUserOp_v0_6(args: {
|
365
|
+
bundlerOptions: BundlerOptions;
|
366
|
+
factoryContract: ThirdwebContract;
|
367
|
+
accountContract: ThirdwebContract;
|
368
|
+
adminAddress: string;
|
369
|
+
sponsorGas: boolean;
|
370
|
+
overrides?: SmartWalletOptions["overrides"];
|
371
|
+
isDeployed: boolean;
|
372
|
+
nonce: bigint;
|
373
|
+
callData: Hex;
|
374
|
+
maxFeePerGas: bigint;
|
375
|
+
maxPriorityFeePerGas: bigint;
|
376
|
+
}): Promise<UserOperationV06> {
|
377
|
+
const {
|
378
|
+
bundlerOptions,
|
379
|
+
isDeployed,
|
380
|
+
factoryContract,
|
381
|
+
accountContract,
|
382
|
+
adminAddress,
|
383
|
+
sponsorGas,
|
384
|
+
overrides,
|
385
|
+
nonce,
|
386
|
+
callData,
|
387
|
+
maxFeePerGas,
|
388
|
+
maxPriorityFeePerGas,
|
389
|
+
} = args;
|
390
|
+
const { chain, client } = bundlerOptions;
|
391
|
+
const initCode = isDeployed
|
392
|
+
? "0x"
|
393
|
+
: await getAccountInitCode({
|
394
|
+
factoryContract: factoryContract,
|
395
|
+
adminAddress,
|
396
|
+
accountSalt: overrides?.accountSalt,
|
397
|
+
createAccountOverride: overrides?.createAccount,
|
398
|
+
});
|
399
|
+
|
400
|
+
const partialOp: UserOperationV06 = {
|
173
401
|
sender: accountContract.address,
|
174
402
|
nonce,
|
175
403
|
initCode,
|
@@ -191,7 +419,10 @@ export async function createUnsignedUserOp(args: {
|
|
191
419
|
entrypointAddress: overrides?.entrypointAddress,
|
192
420
|
paymasterOverride: overrides?.paymaster,
|
193
421
|
});
|
194
|
-
const paymasterAndData =
|
422
|
+
const paymasterAndData =
|
423
|
+
"paymasterAndData" in paymasterResult
|
424
|
+
? paymasterResult.paymasterAndData
|
425
|
+
: "0x";
|
195
426
|
if (paymasterAndData && paymasterAndData !== "0x") {
|
196
427
|
partialOp.paymasterAndData = paymasterAndData as Hex;
|
197
428
|
}
|
@@ -222,11 +453,12 @@ export async function createUnsignedUserOp(args: {
|
|
222
453
|
entrypointAddress: overrides?.entrypointAddress,
|
223
454
|
paymasterOverride: overrides?.paymaster,
|
224
455
|
});
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
456
|
+
const paymasterAndData2 =
|
457
|
+
"paymasterAndData" in paymasterResult2
|
458
|
+
? paymasterResult2.paymasterAndData
|
459
|
+
: "0x";
|
460
|
+
if (paymasterAndData2 && paymasterAndData2 !== "0x") {
|
461
|
+
partialOp.paymasterAndData = paymasterAndData2 as Hex;
|
230
462
|
}
|
231
463
|
}
|
232
464
|
}
|
@@ -242,7 +474,7 @@ export async function createUnsignedUserOp(args: {
|
|
242
474
|
}
|
243
475
|
return {
|
244
476
|
...partialOp,
|
245
|
-
signature: "0x",
|
477
|
+
signature: "0x" as Hex,
|
246
478
|
};
|
247
479
|
}
|
248
480
|
|
@@ -265,17 +497,41 @@ export async function createUnsignedUserOp(args: {
|
|
265
497
|
* @walletUtils
|
266
498
|
*/
|
267
499
|
export async function signUserOp(args: {
|
268
|
-
|
500
|
+
client: ThirdwebClient;
|
501
|
+
userOp: UserOperationV06 | UserOperationV07;
|
269
502
|
chain: Chain;
|
270
503
|
entrypointAddress?: string;
|
271
504
|
adminAccount: Account;
|
272
|
-
}): Promise<
|
505
|
+
}): Promise<UserOperationV06 | UserOperationV07> {
|
273
506
|
const { userOp, chain, entrypointAddress, adminAccount } = args;
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
507
|
+
|
508
|
+
const entrypointVersion = getEntryPointVersion(
|
509
|
+
entrypointAddress || ENTRYPOINT_ADDRESS_v0_6,
|
510
|
+
);
|
511
|
+
|
512
|
+
let userOpHash: Hex;
|
513
|
+
|
514
|
+
if (entrypointVersion === "v0.7") {
|
515
|
+
const packedUserOp = getPackedUserOperation(userOp as UserOperationV07);
|
516
|
+
userOpHash = await getUserOpHashV07({
|
517
|
+
contract: getContract({
|
518
|
+
address: entrypointAddress || ENTRYPOINT_ADDRESS_v0_7,
|
519
|
+
chain,
|
520
|
+
client: args.client,
|
521
|
+
}),
|
522
|
+
userOp: packedUserOp,
|
523
|
+
});
|
524
|
+
} else {
|
525
|
+
userOpHash = await getUserOpHashV06({
|
526
|
+
contract: getContract({
|
527
|
+
address: entrypointAddress || ENTRYPOINT_ADDRESS_v0_6,
|
528
|
+
chain,
|
529
|
+
client: args.client,
|
530
|
+
}),
|
531
|
+
userOp: userOp as UserOperationV06,
|
532
|
+
});
|
533
|
+
}
|
534
|
+
|
279
535
|
if (adminAccount.signMessage) {
|
280
536
|
const signature = await adminAccount.signMessage({
|
281
537
|
message: {
|
@@ -336,52 +592,3 @@ async function getAccountNonce(options: {
|
|
336
592
|
sender: accountContract.address,
|
337
593
|
});
|
338
594
|
}
|
339
|
-
|
340
|
-
/**
|
341
|
-
* Get the hash of a user operation.
|
342
|
-
* @param args - The user operation, entrypoint address, and chain ID
|
343
|
-
* @returns - The hash of the user operation
|
344
|
-
* @walletUtils
|
345
|
-
*/
|
346
|
-
function getUserOpHash(args: {
|
347
|
-
userOp: UserOperation;
|
348
|
-
entryPoint: string;
|
349
|
-
chainId: number;
|
350
|
-
}): Hex {
|
351
|
-
const { userOp, entryPoint, chainId } = args;
|
352
|
-
const hashedInitCode = keccak256(userOp.initCode);
|
353
|
-
const hashedCallData = keccak256(userOp.callData);
|
354
|
-
const hashedPaymasterAndData = keccak256(userOp.paymasterAndData);
|
355
|
-
|
356
|
-
const packedUserOp = encodeAbiParameters(
|
357
|
-
[
|
358
|
-
{ type: "address" },
|
359
|
-
{ type: "uint256" },
|
360
|
-
{ type: "bytes32" },
|
361
|
-
{ type: "bytes32" },
|
362
|
-
{ type: "uint256" },
|
363
|
-
{ type: "uint256" },
|
364
|
-
{ type: "uint256" },
|
365
|
-
{ type: "uint256" },
|
366
|
-
{ type: "uint256" },
|
367
|
-
{ type: "bytes32" },
|
368
|
-
],
|
369
|
-
[
|
370
|
-
userOp.sender,
|
371
|
-
userOp.nonce,
|
372
|
-
hashedInitCode,
|
373
|
-
hashedCallData,
|
374
|
-
userOp.callGasLimit,
|
375
|
-
userOp.verificationGasLimit,
|
376
|
-
userOp.preVerificationGas,
|
377
|
-
userOp.maxFeePerGas,
|
378
|
-
userOp.maxPriorityFeePerGas,
|
379
|
-
hashedPaymasterAndData,
|
380
|
-
],
|
381
|
-
);
|
382
|
-
const encoded = encodeAbiParameters(
|
383
|
-
[{ type: "bytes32" }, { type: "address" }, { type: "uint256" }],
|
384
|
-
[keccak256(packedUserOp), entryPoint, BigInt(chainId)],
|
385
|
-
);
|
386
|
-
return keccak256(encoded);
|
387
|
-
}
|
@@ -1,7 +1,12 @@
|
|
1
1
|
import { concat } from "viem";
|
2
2
|
import type { Chain } from "../../../chains/types.js";
|
3
3
|
import { isHex, numberToHex, toHex } from "../../../utils/encoding/hex.js";
|
4
|
-
import type {
|
4
|
+
import type {
|
5
|
+
UserOperationV06,
|
6
|
+
UserOperationV06Hexed,
|
7
|
+
UserOperationV07,
|
8
|
+
UserOperationV07Hexed,
|
9
|
+
} from "../types.js";
|
5
10
|
|
6
11
|
export const generateRandomUint192 = (): bigint => {
|
7
12
|
const rand1 = BigInt(Math.floor(Math.random() * 0x100000000));
|
@@ -32,14 +37,16 @@ export const randomNonce = () => {
|
|
32
37
|
/**
|
33
38
|
* @internal
|
34
39
|
*/
|
35
|
-
export function hexlifyUserOp(
|
40
|
+
export function hexlifyUserOp(
|
41
|
+
userOp: UserOperationV06 | UserOperationV07,
|
42
|
+
): UserOperationV06Hexed | UserOperationV07Hexed {
|
36
43
|
return Object.fromEntries(
|
37
44
|
Object.entries(userOp).map(([key, val]) => [
|
38
45
|
key,
|
39
46
|
// turn any value that's not hex into hex
|
40
|
-
isHex(val) ? val : toHex(val),
|
47
|
+
val === undefined || val === null || isHex(val) ? val : toHex(val),
|
41
48
|
]),
|
42
|
-
) as
|
49
|
+
) as UserOperationV06Hexed | UserOperationV07Hexed;
|
43
50
|
}
|
44
51
|
|
45
52
|
export function isNativeAAChain(chain: Chain) {
|
@@ -0,0 +1,206 @@
|
|
1
|
+
import { beforeAll, describe, expect, it } from "vitest";
|
2
|
+
import { TEST_CLIENT } from "../../../test/src/test-clients.js";
|
3
|
+
import { typedData } from "../../../test/src/typed-data.js";
|
4
|
+
import { verifySignature } from "../../auth/verify-signature.js";
|
5
|
+
import { type ThirdwebContract, getContract } from "../../contract/contract.js";
|
6
|
+
import { parseEventLogs } from "../../event/actions/parse-logs.js";
|
7
|
+
|
8
|
+
import { sepolia } from "../../chains/chain-definitions/sepolia.js";
|
9
|
+
import {
|
10
|
+
addAdmin,
|
11
|
+
adminUpdatedEvent,
|
12
|
+
} from "../../exports/extensions/erc4337.js";
|
13
|
+
import { balanceOf } from "../../extensions/erc1155/__generated__/IERC1155/read/balanceOf.js";
|
14
|
+
import { claimTo } from "../../extensions/erc1155/drops/write/claimTo.js";
|
15
|
+
import { checkContractWalletSignature } from "../../extensions/erc1271/checkContractWalletSignature.js";
|
16
|
+
import { setContractURI } from "../../extensions/marketplace/__generated__/IMarketplace/write/setContractURI.js";
|
17
|
+
import { estimateGasCost } from "../../transaction/actions/estimate-gas-cost.js";
|
18
|
+
import { sendAndConfirmTransaction } from "../../transaction/actions/send-and-confirm-transaction.js";
|
19
|
+
import { sendBatchTransaction } from "../../transaction/actions/send-batch-transaction.js";
|
20
|
+
import { waitForReceipt } from "../../transaction/actions/wait-for-tx-receipt.js";
|
21
|
+
import { getAddress } from "../../utils/address.js";
|
22
|
+
import { isContractDeployed } from "../../utils/bytecode/is-contract-deployed.js";
|
23
|
+
import type { Account, Wallet } from "../interfaces/wallet.js";
|
24
|
+
import { generateAccount } from "../utils/generateAccount.js";
|
25
|
+
import { ENTRYPOINT_ADDRESS_v0_7 } from "./lib/constants.js";
|
26
|
+
import { smartWallet } from "./smart-wallet.js";
|
27
|
+
|
28
|
+
let wallet: Wallet;
|
29
|
+
let smartAccount: Account;
|
30
|
+
let smartWalletAddress: string;
|
31
|
+
let personalAccount: Account;
|
32
|
+
let accountContract: ThirdwebContract;
|
33
|
+
|
34
|
+
const chain = sepolia;
|
35
|
+
const client = TEST_CLIENT;
|
36
|
+
const contract = getContract({
|
37
|
+
client,
|
38
|
+
chain,
|
39
|
+
address: "0xe2cb0eb5147b42095c2FfA6F7ec953bb0bE347D8",
|
40
|
+
});
|
41
|
+
|
42
|
+
describe.runIf(process.env.TW_SECRET_KEY).sequential(
|
43
|
+
"SmartWallet 0.7 core tests",
|
44
|
+
{
|
45
|
+
retry: 0,
|
46
|
+
timeout: 240_000,
|
47
|
+
},
|
48
|
+
() => {
|
49
|
+
beforeAll(async () => {
|
50
|
+
personalAccount = await generateAccount({
|
51
|
+
client,
|
52
|
+
});
|
53
|
+
wallet = smartWallet({
|
54
|
+
chain,
|
55
|
+
gasless: true,
|
56
|
+
overrides: {
|
57
|
+
entrypointAddress: ENTRYPOINT_ADDRESS_v0_7,
|
58
|
+
},
|
59
|
+
});
|
60
|
+
smartAccount = await wallet.connect({
|
61
|
+
client: TEST_CLIENT,
|
62
|
+
personalAccount,
|
63
|
+
});
|
64
|
+
smartWalletAddress = smartAccount.address;
|
65
|
+
accountContract = getContract({
|
66
|
+
address: smartWalletAddress,
|
67
|
+
chain,
|
68
|
+
client,
|
69
|
+
});
|
70
|
+
});
|
71
|
+
|
72
|
+
it("can connect", async () => {
|
73
|
+
expect(smartWalletAddress).toHaveLength(42);
|
74
|
+
});
|
75
|
+
|
76
|
+
it("should revert on unsuccessful transactions", async () => {
|
77
|
+
const tx = sendAndConfirmTransaction({
|
78
|
+
transaction: setContractURI({
|
79
|
+
contract,
|
80
|
+
uri: "https://example.com",
|
81
|
+
}),
|
82
|
+
account: smartAccount,
|
83
|
+
});
|
84
|
+
|
85
|
+
await expect(tx).rejects.toMatchInlineSnapshot(`
|
86
|
+
[TransactionError: Error - Not authorized
|
87
|
+
|
88
|
+
contract: ${contract.address}
|
89
|
+
chainId: 11155111]
|
90
|
+
`);
|
91
|
+
});
|
92
|
+
|
93
|
+
it("can execute a tx", async () => {
|
94
|
+
const tx = await sendAndConfirmTransaction({
|
95
|
+
transaction: claimTo({
|
96
|
+
contract,
|
97
|
+
quantity: 1n,
|
98
|
+
to: smartWalletAddress,
|
99
|
+
tokenId: 0n,
|
100
|
+
}),
|
101
|
+
account: smartAccount,
|
102
|
+
});
|
103
|
+
expect(tx.transactionHash).toHaveLength(66);
|
104
|
+
const isDeployed = await isContractDeployed(accountContract);
|
105
|
+
expect(isDeployed).toEqual(true);
|
106
|
+
const balance = await balanceOf({
|
107
|
+
contract,
|
108
|
+
owner: getAddress(smartWalletAddress),
|
109
|
+
tokenId: 0n,
|
110
|
+
});
|
111
|
+
expect(balance).toEqual(1n);
|
112
|
+
});
|
113
|
+
|
114
|
+
it("can estimate a tx", async () => {
|
115
|
+
const estimates = await estimateGasCost({
|
116
|
+
transaction: claimTo({
|
117
|
+
contract,
|
118
|
+
quantity: 1n,
|
119
|
+
to: smartWalletAddress,
|
120
|
+
tokenId: 0n,
|
121
|
+
}),
|
122
|
+
account: smartAccount,
|
123
|
+
});
|
124
|
+
expect(estimates.wei.toString()).not.toBe("0");
|
125
|
+
});
|
126
|
+
|
127
|
+
it("can execute a batched tx", async () => {
|
128
|
+
const tx = await sendBatchTransaction({
|
129
|
+
account: smartAccount,
|
130
|
+
transactions: [
|
131
|
+
claimTo({
|
132
|
+
contract,
|
133
|
+
quantity: 1n,
|
134
|
+
to: smartWalletAddress,
|
135
|
+
tokenId: 0n,
|
136
|
+
}),
|
137
|
+
claimTo({
|
138
|
+
contract,
|
139
|
+
quantity: 1n,
|
140
|
+
to: smartWalletAddress,
|
141
|
+
tokenId: 0n,
|
142
|
+
}),
|
143
|
+
],
|
144
|
+
});
|
145
|
+
expect(tx.transactionHash).toHaveLength(66);
|
146
|
+
await waitForReceipt({
|
147
|
+
client,
|
148
|
+
transactionHash: tx.transactionHash,
|
149
|
+
chain,
|
150
|
+
});
|
151
|
+
const balance = await balanceOf({
|
152
|
+
contract,
|
153
|
+
owner: getAddress(smartWalletAddress),
|
154
|
+
tokenId: 0n,
|
155
|
+
});
|
156
|
+
expect(balance).toEqual(3n);
|
157
|
+
});
|
158
|
+
|
159
|
+
it("can sign and verify 1271 with replay protection", async () => {
|
160
|
+
const message = "hello world";
|
161
|
+
const signature = await smartAccount.signMessage({ message });
|
162
|
+
const isValidV1 = await verifySignature({
|
163
|
+
message,
|
164
|
+
signature,
|
165
|
+
address: smartWalletAddress,
|
166
|
+
chain,
|
167
|
+
client,
|
168
|
+
});
|
169
|
+
expect(isValidV1).toEqual(true);
|
170
|
+
const isValidV2 = await checkContractWalletSignature({
|
171
|
+
message,
|
172
|
+
signature,
|
173
|
+
contract: accountContract,
|
174
|
+
});
|
175
|
+
expect(isValidV2).toEqual(true);
|
176
|
+
|
177
|
+
// sign typed data
|
178
|
+
const signatureTyped = await smartAccount.signTypedData({
|
179
|
+
...typedData.basic,
|
180
|
+
primaryType: "Mail",
|
181
|
+
});
|
182
|
+
expect(signatureTyped.length).toBe(132);
|
183
|
+
|
184
|
+
// add admin
|
185
|
+
const newAdmin = await generateAccount({ client });
|
186
|
+
const receipt = await sendAndConfirmTransaction({
|
187
|
+
account: smartAccount,
|
188
|
+
transaction: addAdmin({
|
189
|
+
account: smartAccount,
|
190
|
+
adminAddress: newAdmin.address,
|
191
|
+
contract: getContract({
|
192
|
+
address: smartAccount.address,
|
193
|
+
chain,
|
194
|
+
client,
|
195
|
+
}),
|
196
|
+
}),
|
197
|
+
});
|
198
|
+
const logs = parseEventLogs({
|
199
|
+
events: [adminUpdatedEvent()],
|
200
|
+
logs: receipt.logs,
|
201
|
+
});
|
202
|
+
expect(logs.some((l) => l.args.signer === newAdmin.address)).toBe(true);
|
203
|
+
expect(logs.some((l) => l.args.isAdmin)).toBe(true);
|
204
|
+
});
|
205
|
+
},
|
206
|
+
);
|