Skip to content

Commit 913f99a

Browse files
authored
[TSv4] ZkSync AA & Default Factory (thirdweb-dev#3232)
1 parent 5938f0d commit 913f99a

File tree

14 files changed

+588
-14
lines changed

14 files changed

+588
-14
lines changed

.changeset/eleven-poems-hammer.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@thirdweb-dev/wallets": patch
3+
---
4+
5+
[TSv4] ZkSync Smart Wallet Support

.changeset/heavy-birds-fail.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@thirdweb-dev/unity-js-bridge": patch
3+
"@thirdweb-dev/react": patch
4+
---
5+
6+
Default account factory support

legacy_packages/react/src/evm/hooks/wallets/useSmartWallet.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
import type { SmartWalletConfigOptions } from "../../../wallet/wallets/smartWallet/types";
1111
import {
1212
getSmartWalletAddress,
13+
DEFAULT_FACTORY_ADDRESS,
1314
type SmartWalletConnectionArgs,
1415
} from "@thirdweb-dev/wallets/evm/wallets/smart-wallet";
1516
import { useCallback } from "react";
@@ -226,7 +227,7 @@ export function useSmartWallet<W extends WalletInstance>(
226227
async (args: { personalWalletAddress: string; data?: BytesLike }) => {
227228
return getSmartWalletAddress(
228229
context.activeChain,
229-
options.factoryAddress,
230+
options.factoryAddress || DEFAULT_FACTORY_ADDRESS,
230231
args.personalWalletAddress,
231232
args.data,
232233
);

legacy_packages/unity-js-bridge/src/thirdweb-bridge.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ class ThirdwebBridge implements TWBridge {
173173
// biome-ignore lint/suspicious/noExplicitAny: TODO: fix use of any
174174
(globalThis as any).X_SDK_PLATFORM = "unity";
175175
// biome-ignore lint/suspicious/noExplicitAny: TODO: fix use of any
176-
(globalThis as any).X_SDK_VERSION = "4.15.2";
176+
(globalThis as any).X_SDK_VERSION = "4.16.1";
177177
// biome-ignore lint/suspicious/noExplicitAny: TODO: fix use of any
178178
(globalThis as any).X_SDK_OS = browser?.os ?? "unknown";
179179
}

legacy_packages/wallets/src/evm/connectors/smart-wallet/index.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,11 @@ import {
1212
TransactionOptions,
1313
UserOpOptions,
1414
} from "./types";
15-
import { ACCOUNT_CORE_ABI, ENTRYPOINT_ADDRESS } from "./lib/constants";
15+
import {
16+
ACCOUNT_CORE_ABI,
17+
ENTRYPOINT_ADDRESS,
18+
DEFAULT_FACTORY_ADDRESS,
19+
} from "./lib/constants";
1620
import { EVMWallet } from "../../interfaces";
1721
import { ERC4337EthersSigner } from "./lib/erc4337-signer";
1822
import { BigNumber, constants, ethers, providers, utils } from "ethers";
@@ -69,7 +73,7 @@ export class SmartWalletConnector extends Connector<SmartWalletConnectionArgs> {
6973
this.config.secretKey,
7074
),
7175
gasless: config.gasless,
72-
factoryAddress: config.factoryAddress,
76+
factoryAddress: config.factoryAddress || DEFAULT_FACTORY_ADDRESS,
7377
accountAddress: params.accountAddress,
7478
factoryInfo: {
7579
createAccount:
@@ -538,6 +542,9 @@ export class SmartWalletConnector extends Connector<SmartWalletConnectionArgs> {
538542
* @returns The account factory contract.
539543
*/
540544
async getFactoryContract(): Promise<SmartContract> {
545+
if (!this.config.factoryAddress) {
546+
throw new Error("Factory address not set!");
547+
}
541548
const sdk = ThirdwebSDK.fromSigner(
542549
await this.getSigner(),
543550
this.config.chain,

legacy_packages/wallets/src/evm/connectors/smart-wallet/lib/constants.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
export const ENTRYPOINT_ADDRESS = "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"; // v0.6
22
export const ERC6551_REGISTRY = "0x02101dfB77FDE026414827Fdc604ddAF224F0921";
33
export const MANAGED_ACCOUNT_GAS_BUFFER = 50000;
4+
export const DEFAULT_FACTORY_ADDRESS =
5+
"0x85e23b94e7F5E9cC1fF78BCe78cfb15B81f0DF00";
46

57
export const ACCOUNT_CORE_ABI = [
68
{

legacy_packages/wallets/src/evm/connectors/smart-wallet/lib/http-rpc-client.ts

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@ import { UserOperationStruct } from "@account-abstraction/contracts";
33
import { isTwUrl } from "../../../utils/url";
44
import { hexlifyUserOp } from "./utils";
55
import { setAnalyticsHeaders } from "../../../utils/headers";
6-
import { EstimateUserOpGasRawResult, EstimateUserOpGasResult } from "../types";
6+
import {
7+
EstimateUserOpGasRawResult,
8+
EstimateUserOpGasResult,
9+
ZkTransactionInput,
10+
} from "../types";
711
import { MANAGED_ACCOUNT_GAS_BUFFER } from "./constants";
812

913
export const DEBUG = false; // TODO set as public flag
@@ -85,6 +89,9 @@ export class HttpRpcClient {
8589
}
8690

8791
async validateChainId(): Promise<void> {
92+
if (this.chainId === 300 || this.chainId === 324) {
93+
return;
94+
}
8895
// validate chainId is in sync with expected chainid
8996
const chain = await this.userOpJsonRpcProvider.send("eth_chainId", []);
9097
const bundlerChain = parseInt(chain);
@@ -162,6 +169,27 @@ export class HttpRpcClient {
162169
);
163170
}
164171

172+
async zkPaymasterData(
173+
transactionInput: providers.TransactionRequest,
174+
): Promise<any> {
175+
await this.initializing;
176+
return await this.userOpJsonRpcProvider.send("zk_paymasterData", [
177+
await hexlifyUserOp({
178+
...transactionInput,
179+
gas: transactionInput.gasLimit,
180+
}),
181+
]);
182+
}
183+
184+
async zkBroadcastTransaction(
185+
transactionInput: ZkTransactionInput,
186+
): Promise<any> {
187+
await this.initializing;
188+
return await this.userOpJsonRpcProvider.send("zk_broadcastTransaction", [
189+
transactionInput,
190+
]);
191+
}
192+
165193
private async printUserOperation(
166194
method: string,
167195
[userOp1, entryPointAddress]: [UserOperationStruct, string],

legacy_packages/wallets/src/evm/connectors/smart-wallet/lib/utils.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ import { BigNumber, utils } from "ethers";
22
import { UserOperationStruct } from "@account-abstraction/contracts";
33

44
export async function hexlifyUserOp(
5-
op: Partial<UserOperationStruct>,
5+
// TODO: types
6+
op: Partial<UserOperationStruct | any>,
67
): Promise<any> {
78
const userOp = await utils.resolveProperties(op);
89
return Object.keys(userOp)

legacy_packages/wallets/src/evm/connectors/smart-wallet/types.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import { UserOperationStruct } from "@account-abstraction/contracts";
1414

1515
export type SmartWalletConfig = {
1616
chain: ChainOrRpcUrl;
17-
factoryAddress: string;
17+
factoryAddress?: string;
1818
clientId?: string;
1919
secretKey?: string;
2020
gasless: boolean;
@@ -171,3 +171,18 @@ export type EstimateUserOpGasResult = {
171171
verificationGasLimit: BigNumber;
172172
callGasLimit: BigNumber;
173173
};
174+
175+
export type ZkTransactionInput = {
176+
nonce?: string;
177+
from: string;
178+
to: string;
179+
gas: string;
180+
gasPrice?: string;
181+
value?: string;
182+
data?: string;
183+
maxFeePerGas: string;
184+
maxPriorityFeePerGas: string;
185+
chainId?: string;
186+
signedTransaction: string;
187+
paymaster: string;
188+
};

legacy_packages/wallets/src/evm/connectors/smart-wallet/utils.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
import {
22
ChainOrRpcUrl,
3+
getChainProvider,
34
isContractDeployed,
45
ThirdwebSDK,
56
} from "@thirdweb-dev/sdk";
67
import { BytesLike } from "ethers";
78
import { ENTRYPOINT_ADDRESS } from "./lib/constants";
89
import { EntryPoint__factory } from "@account-abstraction/contracts";
10+
import { Zksync, ZksyncSepoliaTestnet } from "@thirdweb-dev/chains";
911

1012
export type AccessibleSmartWallets = {
1113
owned: string;
@@ -99,6 +101,19 @@ export async function isSmartWalletDeployed(
99101
return isDeployed;
100102
}
101103

104+
export async function isZkSyncChain(
105+
network: ChainOrRpcUrl,
106+
clientId?: string,
107+
secretKey?: string,
108+
) {
109+
const provider = getChainProvider(network, {
110+
clientId,
111+
secretKey,
112+
});
113+
const chainId = (await provider.getNetwork()).chainId;
114+
return chainId === Zksync.chainId || chainId === ZksyncSepoliaTestnet.chainId;
115+
}
116+
102117
/**
103118
* Get the associated smart wallet address for a given personal wallet address
104119
* @param chain - The chain to use

0 commit comments

Comments
 (0)