kokio-sdk 0.0.1

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.
Files changed (36) hide show
  1. package/.env.example +1 -0
  2. package/.github/workflows/npm_publish.yaml +19 -0
  3. package/LICENSE +21 -0
  4. package/package.json +45 -0
  5. package/src/abis/BeaconProxy.json +985 -0
  6. package/src/abis/DeviceWallet.json +907 -0
  7. package/src/abis/DeviceWalletFactory.json +739 -0
  8. package/src/abis/ESIMWallet.json +486 -0
  9. package/src/abis/ESIMWalletFactory.json +467 -0
  10. package/src/abis/LazyWalletRegistry.json +734 -0
  11. package/src/abis/P256Verifier.json +73 -0
  12. package/src/abis/Registry.json +811 -0
  13. package/src/abis/RegistryHelper.json +382 -0
  14. package/src/abis/index.ts +21 -0
  15. package/src/config.ts +46 -0
  16. package/src/interface/P256VerifierClass.ts +19 -0
  17. package/src/interface/constantsClass.ts +35 -0
  18. package/src/interface/deviceWalletClass.ts +62 -0
  19. package/src/interface/deviceWalletFactoryClass.ts +35 -0
  20. package/src/interface/eSIMWalletClass.ts +55 -0
  21. package/src/interface/eSIMWalletFactoryClass.ts +36 -0
  22. package/src/interface/lazyWalletRegistryClass.ts +34 -0
  23. package/src/interface/smartAccountClass.ts +26 -0
  24. package/src/interface/utilsClass.ts +21 -0
  25. package/src/logic/P256Verifier.ts +31 -0
  26. package/src/logic/account-kit/createSmartAccount.ts +282 -0
  27. package/src/logic/constants.ts +188 -0
  28. package/src/logic/deviceWallet.ts +175 -0
  29. package/src/logic/deviceWalletFactory.ts +70 -0
  30. package/src/logic/eSIMWallet.ts +149 -0
  31. package/src/logic/eSIMWalletFactory.ts +78 -0
  32. package/src/logic/lazyWalletRegistry.ts +98 -0
  33. package/src/logic/services/turnkeyClient.ts +80 -0
  34. package/src/logic/utils.ts +86 -0
  35. package/src/types.ts +38 -0
  36. package/tsconfig.json +114 -0
@@ -0,0 +1,36 @@
1
+ import { Address, WalletClient } from "viem";
2
+ import {
3
+ _addRegistryAddress,
4
+ _deployESIMWalletWithEOA,
5
+ _deployESIMWalletWithUserOp,
6
+ _getCurrentESIMWalletImplementation
7
+ } from "../logic/eSIMWalletFactory.js"
8
+ import { SmartAccountClient } from "@aa-sdk/core";
9
+
10
+ export class eSIMWalletFactorySubPackage {
11
+
12
+ smartAccountClient;
13
+ walletClient;
14
+
15
+ constructor(walletClient: WalletClient, smartAccountClient: SmartAccountClient) {
16
+ this.smartAccountClient = smartAccountClient;
17
+ this.walletClient = walletClient
18
+ }
19
+
20
+ deployESIMWalletWithEOA (deviceWalletAddress: Address, salt: bigint) {
21
+ return _deployESIMWalletWithEOA (this.walletClient, deviceWalletAddress, salt);
22
+ }
23
+
24
+
25
+ deployESIMWalletWithUserOp (deviceWalletAddress: Address, salt: bigint) {
26
+ return _deployESIMWalletWithUserOp (this.smartAccountClient, deviceWalletAddress, salt);
27
+ }
28
+
29
+ addRegistryAddress (registryContractAddress: Address) {
30
+ return _addRegistryAddress(this.smartAccountClient, registryContractAddress);
31
+ }
32
+
33
+ _getCurrentESIMWalletImplementation () {
34
+ return _getCurrentESIMWalletImplementation(this.smartAccountClient);
35
+ }
36
+ }
@@ -0,0 +1,34 @@
1
+ import { Address, Hex, WalletClient } from "viem";
2
+ import {
3
+ _batchPopulateHistory,
4
+ _deployLazyWalletAndSetESIMIdentifier,
5
+ _isLazyWalletDeployed,
6
+ _switchESIMIdentifierToNewDeviceIdentifier
7
+ } from "../logic/lazyWalletRegistry.js"
8
+ import { DataBundleDetails } from "../types";
9
+ import { SmartAccountClient } from "@aa-sdk/core";
10
+
11
+ export class lazyWalletRegistrySubPackage {
12
+
13
+ client;
14
+
15
+ constructor(client: SmartAccountClient) {
16
+ this.client = client;
17
+ }
18
+
19
+ _batchPopulateHistory (deviceUniqueIdentifiers: Array<string>, eSIMUniqueIdentifiers: Array<Array<string>>, dataBundleDetails: Array<Array<DataBundleDetails>>) {
20
+ return _batchPopulateHistory(this.client, deviceUniqueIdentifiers, eSIMUniqueIdentifiers, dataBundleDetails);
21
+ }
22
+
23
+ _deployLazyWalletAndSetESIMIdentifier (deviceOwnerPublicKey: Hex[2], deviceUniqueIdentifier: string, salt: bigint, depositAmount: bigint) {
24
+ return _deployLazyWalletAndSetESIMIdentifier(this.client, deviceOwnerPublicKey, deviceUniqueIdentifier, salt, depositAmount);
25
+ }
26
+
27
+ _isLazyWalletDeployed (deviceUniqueIdentifier: string) {
28
+ return _isLazyWalletDeployed(this.client, deviceUniqueIdentifier);
29
+ }
30
+
31
+ _switchESIMIdentifierToNewDeviceIdentifier (eSIMIdentifier: string, oldDeviceIdentifier: string, newDeviceIdentifier: string) {
32
+ return _switchESIMIdentifierToNewDeviceIdentifier(this.client, eSIMIdentifier, oldDeviceIdentifier, newDeviceIdentifier);
33
+ }
34
+ }
@@ -0,0 +1,26 @@
1
+ import { Address, WalletClient } from "viem";
2
+ import { _getSmartWallet, _getSmartWalletClient } from "../logic/account-kit/createSmartAccount.js";
3
+ import { P256Key, SignedRequest } from "../types";
4
+ import { SmartAccountClient, SmartContractAccount } from "@aa-sdk/core";
5
+ import { TurnkeyClient } from "@turnkey/http";
6
+
7
+ export class smartAccountSubPackage {
8
+
9
+ client;
10
+ turnkeyClient;
11
+ organizationId;
12
+
13
+ constructor(client: WalletClient, turnkeyClient: TurnkeyClient, organiationId: string) {
14
+ this.client = client;
15
+ this.turnkeyClient = turnkeyClient;
16
+ this.organizationId = organiationId;
17
+ }
18
+
19
+ getSmartWallet (deviceUniqueIdentifier: string, deviceWalletOwnerKey: P256Key, salt: bigint, sender?: Address) {
20
+ return _getSmartWallet(this.client, this.turnkeyClient, this.organizationId, deviceUniqueIdentifier, deviceWalletOwnerKey, salt, sender)
21
+ }
22
+
23
+ getSmartWalletClient (account: SmartContractAccount) {
24
+ return _getSmartWalletClient(this.client, account)
25
+ }
26
+ }
@@ -0,0 +1,21 @@
1
+ import { WalletClient } from "viem";
2
+ import { _add0x, _remove0x } from "../logic/utils.js";
3
+ import { AccountOp, SmartAccountClient } from "@aa-sdk/core";
4
+
5
+ export class UtilsSubPackage {
6
+
7
+ client;
8
+
9
+ constructor(client: WalletClient) {
10
+ this.client = client;
11
+ }
12
+
13
+ add0x(data: string) {
14
+ _add0x(data);
15
+ }
16
+
17
+ remove0x(data: string) {
18
+ _remove0x(data);
19
+ }
20
+
21
+ }
@@ -0,0 +1,31 @@
1
+ import { encodeFunctionData, WalletClient } from "viem";
2
+ import { WebAuthnSignature } from "../types.js";
3
+ import { SmartAccountClient } from "@aa-sdk/core";
4
+ import { _getChainSpecificConstants, customErrors } from "./constants.js";
5
+ import { P256Verifier } from "../abis/index.js";
6
+
7
+ export const _verifySignature = async (
8
+ client: SmartAccountClient,
9
+ message: string,
10
+ requireMessageVerification: boolean,
11
+ webAuthnSignature: WebAuthnSignature,
12
+ x: bigint,
13
+ y: bigint
14
+ ) => {
15
+
16
+ const values = _getChainSpecificConstants(await client.getChainId());
17
+ if(!client.account) throw new Error(customErrors.MISSING_SMART_WALLET)
18
+
19
+ // UserOp
20
+ return client.sendUserOperation({
21
+ account: client.account,
22
+ uo:{
23
+ target: values.factoryAddresses.P256VERIFIER,
24
+ data: encodeFunctionData({
25
+ abi: P256Verifier,
26
+ functionName: "deployLazyWalletAndSetESIMIdentifier",
27
+ args: [message, requireMessageVerification, webAuthnSignature, x, y]
28
+ })
29
+ }
30
+ });
31
+ }
@@ -0,0 +1,282 @@
1
+ import {
2
+ AccountOp,
3
+ createSmartAccountClient,
4
+ getEntryPoint,
5
+ SmartContractAccount,
6
+ toSmartContractAccount,
7
+ } from "@aa-sdk/core";
8
+ import {
9
+ http,
10
+ type SignableMessage,
11
+ type Hash,
12
+ WalletClient,
13
+ Hex,
14
+ encodeFunctionData,
15
+ Address,
16
+ encodePacked,
17
+ encodeAbiParameters,
18
+ getContract,
19
+ TypedDataDefinition,
20
+ TypedData
21
+ } from "viem";
22
+ import { TurnkeyClient } from "@turnkey/http";
23
+ import { BytesLike, ethers, hexlify } from "ethers";
24
+ import { _getChainSpecificConstants, ZERO } from "../constants.js";
25
+ import { _add0x, _concatUint8Arrays, _remove0x, _shouldRemoveLeadingZero } from "../utils.js";
26
+ import { P256Key, WebAuthnSignature } from "../../types.js";
27
+ import { DeviceWallet, DeviceWalletFactory } from "../../abis/index.js";
28
+ import { _signMessageWithTurnkey, _signTypedDataWithTurnkey } from "../services/turnkeyClient.js";
29
+
30
+ const _encodeExecute = async (tx: AccountOp) => {
31
+
32
+ return encodeFunctionData({
33
+ abi: DeviceWallet,
34
+ functionName: "execute",
35
+ args: [{
36
+ dest: tx.target,
37
+ value: tx.value ?? ZERO,
38
+ data: tx.data
39
+ }]
40
+ });
41
+ }
42
+
43
+ const _encodeBatchExecute = async (txs: AccountOp[]) => {
44
+
45
+ const new_txs:{dest:Address, value:bigint, data: Hex | '0x'}[] = [];
46
+
47
+ for (let i=0; i<txs.length; ++i) {
48
+ new_txs.push({
49
+ dest: txs[i].target,
50
+ value: txs[i].value ?? ZERO,
51
+ data: txs[i].data
52
+ })
53
+ }
54
+
55
+ return encodeFunctionData({
56
+ abi: DeviceWallet,
57
+ functionName: "executeBatch",
58
+ args: [new_txs]
59
+ });
60
+ }
61
+
62
+ const _getAccountInitCode = async (client: WalletClient, deviceUniqueIdentifier: string, deviceWalletOwnerKey: P256Key, salt: bigint): Promise<Hex> => {
63
+
64
+ // To send with user operations
65
+ const chainID = await client.getChainId();
66
+ const values = _getChainSpecificConstants(chainID);
67
+
68
+ const callData = encodeFunctionData({
69
+ abi: DeviceWalletFactory,
70
+ functionName: "createAccount",
71
+ args: [deviceUniqueIdentifier, deviceWalletOwnerKey, salt, ZERO],
72
+ })
73
+
74
+ return values.factoryAddresses.DEVICE_WALLET_FACTORY.concat(_remove0x(callData)) as Hex;
75
+ }
76
+
77
+ const getInitCodeHash = async (client: WalletClient, deviceUniqueIdentifier: string, deviceWalletOwnerKey: P256Key): Promise<BytesLike> => {
78
+
79
+ const chainID = await client.getChainId();
80
+ const values = _getChainSpecificConstants(chainID);
81
+
82
+ // off-chain computation of the DeviceWallet address
83
+ const registry = values.factoryAddresses.REGISTRY;
84
+ const deviceWalletFactoryAddress = values.factoryAddresses.DEVICE_WALLET_FACTORY;
85
+
86
+ const deviceWalletFactory = getContract({
87
+ abi: DeviceWalletFactory,
88
+ address: deviceWalletFactoryAddress,
89
+ client
90
+ });
91
+
92
+ const beacon = await deviceWalletFactory.read.beacon([]);
93
+
94
+ const abiCoder = ethers.AbiCoder.defaultAbiCoder();
95
+
96
+ // Encode the DeviceWallet.init with the init params
97
+ const deviceWallet = new ethers.Interface(DeviceWallet);
98
+ const deviceWalletInitData = deviceWallet.encodeFunctionData("init", [
99
+ registry,
100
+ deviceWalletOwnerKey,
101
+ deviceUniqueIdentifier,
102
+ ]);
103
+
104
+ const beaconProxyBytecode = "0x60a06040526040516105bf3803806105bf83398101604081905261002291610387565b61002c828261003e565b506001600160a01b031660805261047e565b610047826100fe565b6040516001600160a01b038316907f1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e90600090a28051156100f2576100ed826001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156100c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100e79190610447565b82610211565b505050565b6100fa610288565b5050565b806001600160a01b03163b60000361013957604051631933b43b60e21b81526001600160a01b03821660048201526024015b60405180910390fd5b807fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d5080546001600160a01b0319166001600160a01b0392831617905560408051635c60da1b60e01b81529051600092841691635c60da1b9160048083019260209291908290030181865afa1580156101b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101d99190610447565b9050806001600160a01b03163b6000036100fa57604051634c9c8ce360e01b81526001600160a01b0382166004820152602401610130565b6060600080846001600160a01b03168460405161022e9190610462565b600060405180830381855af49150503d8060008114610269576040519150601f19603f3d011682016040523d82523d6000602084013e61026e565b606091505b50909250905061027f8583836102a9565b95945050505050565b34156102a75760405163b398979f60e01b815260040160405180910390fd5b565b6060826102be576102b982610308565b610301565b81511580156102d557506001600160a01b0384163b155b156102fe57604051639996b31560e01b81526001600160a01b0385166004820152602401610130565b50805b9392505050565b8051156103185780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b80516001600160a01b038116811461034857600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101561037e578181015183820152602001610366565b50506000910152565b6000806040838503121561039a57600080fd5b6103a383610331565b60208401519092506001600160401b03808211156103c057600080fd5b818501915085601f8301126103d457600080fd5b8151818111156103e6576103e661034d565b604051601f8201601f19908116603f0116810190838211818310171561040e5761040e61034d565b8160405282815288602084870101111561042757600080fd5b610438836020830160208801610363565b80955050505050509250929050565b60006020828403121561045957600080fd5b61030182610331565b60008251610474818460208701610363565b9190910192915050565b6080516101276104986000396000601e01526101276000f3fe6080604052600a600c565b005b60186014601a565b60a0565b565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156079573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190609b919060c3565b905090565b3660008037600080366000845af43d6000803e80801560be573d6000f35b3d6000fd5b60006020828403121560d457600080fd5b81516001600160a01b038116811460ea57600080fd5b939250505056fea2646970667358221220d2ef783a147afe4beaf6cec0d85c3b6cd6a11a48e1a7f60eac2d7a83dac8508e64736f6c63430008190033";
105
+
106
+ // Encode BeaconProxy constructor args
107
+ const beaconProxyConstructorArgs = abiCoder.encode(
108
+ ["address", "bytes"],
109
+ [beacon, deviceWalletInitData]
110
+ );
111
+
112
+ // Compute initCode
113
+ const initCode:BytesLike = ethers.concat([beaconProxyBytecode, beaconProxyConstructorArgs]);
114
+
115
+ return ethers.keccak256(initCode);
116
+ }
117
+
118
+ const prepareSaltForCreate2 = (sender: Address, salt: BigInt): BytesLike => {
119
+
120
+ // Calculating unique salt based on createAccount function's implementation
121
+ const abiCoder = ethers.AbiCoder.defaultAbiCoder();
122
+ const encoded = abiCoder.encode(
123
+ ["address", "uint256"],
124
+ [sender, salt]
125
+ );
126
+ const uniqueSaltBytes32 = ethers.keccak256(encoded);
127
+
128
+ return uniqueSaltBytes32;
129
+ }
130
+
131
+ // NOTE: Sender is the address that deploys the contract.
132
+ // In case of ERC-4337, it is the Entry Point contract address
133
+ const getCounterFactualAddress = async (client: WalletClient, deviceUniqueIdentifier: string, deviceWalletOwnerKey: P256Key, salt: BigInt, sender?: Address):Promise<Hex> => {
134
+
135
+ const chainID = await client.getChainId();
136
+ const values = _getChainSpecificConstants(chainID);
137
+ const deviceWalletFactoryAddress = values.factoryAddresses.DEVICE_WALLET_FACTORY;
138
+
139
+ sender = sender? sender : values.factoryAddresses.SENDER_CREATOR;
140
+ const uniqueSaltBytes32 = prepareSaltForCreate2(sender, salt);
141
+ const initCodeHash = await getInitCodeHash(client, deviceUniqueIdentifier, deviceWalletOwnerKey);
142
+
143
+ // Calculate deterministic address from init code hash
144
+ const create2Address = ethers.getCreate2Address(deviceWalletFactoryAddress, uniqueSaltBytes32, initCodeHash);
145
+
146
+ return ethers.getAddress(create2Address) as Address;
147
+ }
148
+
149
+ const _encodeSignature = async (webAuthnSignature: WebAuthnSignature): Promise<Hex> => {
150
+
151
+ const signature = encodePacked(
152
+ ["uint8", "uint48", "bytes"],
153
+ [
154
+ 1,
155
+ 0,
156
+ encodeAbiParameters([
157
+ {
158
+ type: "tuple",
159
+ name: "credentials",
160
+ components: [
161
+ {
162
+ name: "authenticatorData",
163
+ type: "bytes",
164
+ },
165
+ {
166
+ name: "clientDataJSON",
167
+ type: "string",
168
+ },
169
+ {
170
+ name: "challengeIndex",
171
+ type: "uint256",
172
+ },
173
+ {
174
+ name: "typeIndex",
175
+ type: "uint256",
176
+ },
177
+ {
178
+ name: "r",
179
+ type: "uint256",
180
+ },
181
+ {
182
+ name: "s",
183
+ type: "uint256",
184
+ },
185
+ ],
186
+ },
187
+ ],
188
+ [
189
+ {
190
+ authenticatorData: _add0x(webAuthnSignature.authenticatorData),
191
+ clientDataJSON: JSON.stringify(webAuthnSignature.clientDataJSON),
192
+ challengeIndex: BigInt(23),
193
+ typeIndex: BigInt(1),
194
+ r: webAuthnSignature.r,
195
+ s: webAuthnSignature.s,
196
+ },
197
+ ]),
198
+ ],
199
+ );
200
+
201
+ return signature;
202
+ }
203
+
204
+ const _signMessage = async (message: SignableMessage, turnkeyClient: TurnkeyClient, organiationId: string, signWith: Address): Promise<Hex> => {
205
+
206
+ const webAuthnSignature = await _signMessageWithTurnkey(turnkeyClient, organiationId, signWith, message);
207
+
208
+ return _encodeSignature(webAuthnSignature);
209
+ }
210
+
211
+ const _signTypedData = async <
212
+ const typedData extends TypedData | Record<string, unknown>,
213
+ primaryType extends keyof typedData | "EIP712Domain" = keyof typedData
214
+ > (typedData: TypedDataDefinition<typedData, primaryType>, turnkeyClient: TurnkeyClient, organiationId: string, signWith: Address): Promise<Hex> => {
215
+
216
+ const webAuthnSignature = await _signTypedDataWithTurnkey(turnkeyClient, organiationId, signWith, typedData);
217
+
218
+ return _encodeSignature(webAuthnSignature);
219
+ }
220
+
221
+ const _signUserOperationHash = async (hash: Hex, turnkeyClient: TurnkeyClient, organiationId: string, signWith: Address): Promise<Hex> => {
222
+
223
+ const message = encodePacked(["uint8", "uint48", "bytes32"], [1, 0, hash]);
224
+ return _signMessage(message, turnkeyClient, organiationId, signWith);
225
+ }
226
+
227
+ export const _getSmartWallet = async (client: WalletClient, turnkeyClient: TurnkeyClient, organiationId: string, deviceUniqueIdentifier: string, deviceWalletOwnerKey: P256Key, salt: bigint, sender?: Address): Promise<SmartContractAccount> => {
228
+
229
+ const chainID = await client.getChainId();
230
+ const values = _getChainSpecificConstants(chainID);
231
+
232
+ if (!client.account) throw new Error ('Error: No signer account found with WalletClient')
233
+ const signWith = client.account.address;
234
+
235
+ return toSmartContractAccount({
236
+ /// REQUIRED PARAMS ///
237
+ source: "MyAccount",
238
+ transport: http(values.rpcURL),
239
+
240
+ chain: values.chain,
241
+
242
+ // The EntryPointDef that your account is compatible with
243
+ entryPoint: getEntryPoint(values.chain, {addressOverride: values.factoryAddresses.ENTRY_POINT}),
244
+
245
+ getAccountInitCode: async (): Promise<Hex> => await _getAccountInitCode(client, deviceUniqueIdentifier, deviceWalletOwnerKey, salt),
246
+
247
+ // getAccountInitCodeHash: async (): Promise<BytesLike> => await getInitCodeHash(client, deviceUniqueIdentifier, deviceWalletOwnerKey),
248
+
249
+ // an invalid signature that doesn't cause your account to revert during validation
250
+ getDummySignature: async (): Promise<Hash> => "0xfffffffffffffffffffffffffffffff0000000000000000000000000000000007aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1c", //from Alchemy docs
251
+
252
+ // given a UO in the form of {target, data, value} should output the calldata for calling your contract's execution method
253
+ encodeExecute: async (uo): Promise<Hash> => _encodeExecute(uo),
254
+
255
+ signMessage: async ({ message }): Promise<Hash> => _signMessage(message, turnkeyClient, organiationId, signWith),
256
+
257
+ signTypedData: async (typedData): Promise<Hash> => _signTypedData(typedData, turnkeyClient, organiationId, signWith),
258
+
259
+ /// OPTIONAL PARAMS ///
260
+ // if you already know your account's address, pass that in here to avoid generating a new counterfactual
261
+ accountAddress: await getCounterFactualAddress(client, deviceUniqueIdentifier, deviceWalletOwnerKey, salt, sender),
262
+ // if your account supports batching, this should take an array of UOs and return the calldata for calling your contract's batchExecute method
263
+ encodeBatchExecute: async (uos): Promise<Hash> => _encodeBatchExecute(uos),
264
+ // if your contract expects a different signing scheme than the default signMessage scheme, you can override that here
265
+ signUserOperationHash: async (hash): Promise<Hash> => _signUserOperationHash(hash, turnkeyClient, organiationId, signWith),
266
+ // allows you to define the calldata for upgrading your account
267
+ // encodeUpgradeToAndCall: async (params): Promise<Hash> => "0x...",
268
+ });
269
+ }
270
+
271
+ export const _getSmartWalletClient = async (client: WalletClient, account: SmartContractAccount) => {
272
+
273
+ const chainID = await client.getChainId();
274
+ const values = _getChainSpecificConstants(chainID);
275
+
276
+ return createSmartAccountClient({
277
+ // created above
278
+ account: account,
279
+ chain: values.chain,
280
+ transport: http(values.rpcURL),
281
+ });
282
+ }
@@ -0,0 +1,188 @@
1
+ import * as dotenv from 'dotenv';
2
+ dotenv.config();
3
+
4
+ import { WalletClient } from "viem";
5
+
6
+ import {
7
+ mainnet,
8
+ sepolia,
9
+ optimism,
10
+ optimismSepolia,
11
+ arbitrum,
12
+ arbitrumSepolia
13
+ } from "viem/chains";
14
+
15
+ export const ZERO = BigInt('0');
16
+
17
+ export const API_KEY = process.env.API_KEY;
18
+
19
+ export enum CHAIN_ID {
20
+ MAINNET = 1,
21
+ SEPOLIA = 11155111,
22
+ OPTIMISM_MAINNET = 10,
23
+ OPTIMISM_SEPOLIA = 11155420,
24
+ ARBITRUM_ONE = 42161,
25
+ ARBITRUM_SEPOLIA = 421614,
26
+ }
27
+
28
+ export const rpcURLs: Record<string, string> = {
29
+ mainnet: `https://eth-mainnet.g.alchemy.com/v2/${API_KEY}`,
30
+ sepolia: `https://eth-sepolia.g.alchemy.com/v2/${API_KEY}`,
31
+ optimismMainnet : `https://opt-mainnet.g.alchemy.com/v2/${API_KEY}`,
32
+ optimismSepolia: `https://opt-sepolia.g.alchemy.com/v2/${API_KEY}`,
33
+ arbitrum: `https://arb-mainnet.g.alchemy.com/v2/${API_KEY}`,
34
+ arbitrumSepolia: `https://arb-sepolia.g.alchemy.com/v2/${API_KEY}`,
35
+ }
36
+
37
+ export interface chainSpecifcConstants {
38
+ factoryAddresses:
39
+ typeof sepoliaFactoryAddresses |
40
+ typeof mainnetFactoryAddresses |
41
+ typeof optimismMainnetFactoryAddresses |
42
+ typeof optimismSepoliaFactoryAddresses |
43
+ typeof arbitrumOneFactoryAddresses |
44
+ typeof arbitrumSepoliaFactoryAddresses;
45
+ chain:
46
+ typeof mainnet |
47
+ typeof sepolia |
48
+ typeof optimism |
49
+ typeof optimismSepolia |
50
+ typeof arbitrum |
51
+ typeof arbitrumSepolia
52
+ rpcURL: string;
53
+ customErrors: typeof customErrors;
54
+ }
55
+
56
+ export const sepoliaFactoryAddresses: Record<string, `0x${string}`> = {
57
+ DEVICE_WALLET_FACTORY: '0x63005d8214533fC7209678Aa39F7b9b0b51a7bcB',
58
+ ESIM_WALLET_FACTORY: '0xB4473979ff8cE4e09161B08f74EEb66BD7718076',
59
+ LAZY_WALLET_REGISTRY: '0x8a1E53b903efcc6b252CE4bD3b255202318505Ef',
60
+ REGISTRY: '0xCa447f5C75C57f6C59027304A5Fb5A09F0E005c9',
61
+ ENTRY_POINT: '0x0000000071727De22E5E9d8BAf0edAc6f37da032',
62
+ SENDER_CREATOR: '0x9406Cc6185a346906296840746125a0E44976454',
63
+ P256VERIFIER: '0xF04f3b3935aD461D17d4a8a78E7ea21d4a61AEb1'
64
+ }
65
+
66
+ export const mainnetFactoryAddresses: Record<string, `0x${string}`> = {
67
+ DEVICE_WALLET_FACTORY: '0x',
68
+ ESIM_WALLET_FACTORY: '0x',
69
+ LAZY_WALLET_REGISTRY: '0x',
70
+ REGISTRY: '0x',
71
+ ENTRY_POINT: '0x',
72
+ SENDER_CREATOR: '0x',
73
+ P256VERIFIER: '0x'
74
+ }
75
+
76
+ export const optimismMainnetFactoryAddresses: Record<string, `0x${string}`> = {
77
+ DEVICE_WALLET_FACTORY: '0x',
78
+ ESIM_WALLET_FACTORY: '0x',
79
+ LAZY_WALLET_REGISTRY: '0x',
80
+ REGISTRY: '0x',
81
+ ENTRY_POINT: '0x',
82
+ SENDER_CREATOR: '0x',
83
+ P256VERIFIER: '0x'
84
+ }
85
+
86
+ export const optimismSepoliaFactoryAddresses: Record<string, `0x${string}`> = {
87
+ DEVICE_WALLET_FACTORY: '0x3feA4dB0C0bBB73142d5bB6b776EE238884a3705',
88
+ ESIM_WALLET_FACTORY: '0xaD2Ba6248D0e6990a844C94ACE78F8775A68b631',
89
+ LAZY_WALLET_REGISTRY: '0x29b98C32D83604664fd0742b9112b0825a74849F',
90
+ REGISTRY: '0xaeB98F0f092fCb4a476ea3a5EB6A4B9E3D63A686',
91
+ ENTRY_POINT: '0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789',
92
+ SENDER_CREATOR: '0x7fc98430eaedbb6070b35b39d798725049088348',
93
+ P256VERIFIER: '0x5349aEA97Faa6D5d6D78A8847068300a4eC9D39E'
94
+ }
95
+
96
+ export const arbitrumOneFactoryAddresses: Record<string, `0x${string}`> = {
97
+ DEVICE_WALLET_FACTORY: '0x',
98
+ ESIM_WALLET_FACTORY: '0x',
99
+ LAZY_WALLET_REGISTRY: '0x',
100
+ REGISTRY: '0x',
101
+ ENTRY_POINT: '0x',
102
+ SENDER_CREATOR: '0x',
103
+ P256VERIFIER: '0x'
104
+ }
105
+
106
+ export const arbitrumSepoliaFactoryAddresses: Record<string, `0x${string}`> = {
107
+ DEVICE_WALLET_FACTORY: '0x',
108
+ ESIM_WALLET_FACTORY: '0x',
109
+ LAZY_WALLET_REGISTRY: '0x',
110
+ REGISTRY: '0x',
111
+ ENTRY_POINT: '0x',
112
+ SENDER_CREATOR: '0x',
113
+ P256VERIFIER: '0x'
114
+ }
115
+
116
+ export const customErrors: Record<string, string> = {
117
+ NULL_OR_UNDEFINED_VALUE: "Error: Null or undefined value provided",
118
+ MISSING_SMART_WALLET: "Error: Client does not have smart wallet account associated",
119
+ MISSING_EOA_WALLET: "Error: Client does not have EOA wallet associated"
120
+ }
121
+
122
+ export const _extractChainID = async (client: WalletClient) => {
123
+
124
+ if (!client) {
125
+ throw "Invalid Signer or Provider instance";
126
+ }
127
+ return client.getChainId();
128
+ }
129
+
130
+ export const _getChainSpecificConstants = (
131
+ chainID:
132
+ CHAIN_ID.SEPOLIA |
133
+ CHAIN_ID.MAINNET |
134
+ CHAIN_ID.OPTIMISM_MAINNET |
135
+ CHAIN_ID.OPTIMISM_SEPOLIA |
136
+ CHAIN_ID.ARBITRUM_ONE |
137
+ CHAIN_ID.ARBITRUM_SEPOLIA
138
+ ): chainSpecifcConstants => {
139
+
140
+ if (chainID == CHAIN_ID.SEPOLIA) {
141
+ return {
142
+ factoryAddresses: sepoliaFactoryAddresses,
143
+ chain: sepolia,
144
+ rpcURL: rpcURLs.sepolia,
145
+ customErrors: customErrors
146
+ }
147
+ }
148
+ else if (chainID == CHAIN_ID.MAINNET) {
149
+ return {
150
+ factoryAddresses: mainnetFactoryAddresses,
151
+ chain: mainnet,
152
+ rpcURL: rpcURLs.mainnet,
153
+ customErrors: customErrors
154
+ }
155
+ }
156
+ else if (chainID == CHAIN_ID.OPTIMISM_MAINNET) {
157
+ return {
158
+ factoryAddresses: optimismMainnetFactoryAddresses,
159
+ chain: optimism,
160
+ rpcURL: rpcURLs.optimismMainnet,
161
+ customErrors: customErrors
162
+ }
163
+ }
164
+ else if (chainID == CHAIN_ID.OPTIMISM_SEPOLIA) {
165
+ return {
166
+ factoryAddresses: optimismSepoliaFactoryAddresses,
167
+ chain: optimismSepolia,
168
+ rpcURL: rpcURLs.optimismSepolia,
169
+ customErrors: customErrors
170
+ }
171
+ }
172
+ else if (chainID == CHAIN_ID.ARBITRUM_ONE) {
173
+ return {
174
+ factoryAddresses: arbitrumOneFactoryAddresses,
175
+ chain: arbitrum,
176
+ rpcURL: rpcURLs.arbitrum,
177
+ customErrors: customErrors
178
+ }
179
+ }
180
+ else {
181
+ return {
182
+ factoryAddresses: arbitrumSepoliaFactoryAddresses,
183
+ chain: arbitrumSepolia,
184
+ rpcURL: rpcURLs.arbitrumSepolia,
185
+ customErrors: customErrors
186
+ }
187
+ }
188
+ }