@1llet.xyz/erc4337-gasless-sdk 0.2.0 → 0.4.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.
package/README.md CHANGED
@@ -17,20 +17,14 @@ yarn add @1llet.xyz/erc4337-gasless-sdk viem
17
17
  Define the chain configuration (including your Bundler URL and Paymaster).
18
18
 
19
19
  ```typescript
20
- import { type ChainConfig } from "@1llet.xyz/erc4337-gasless-sdk";
21
- import { baseSepolia } from "viem/chains";
22
-
23
- const config: ChainConfig = {
24
- chain: baseSepolia,
25
- // Your Bundler URL (must support ERC-4337 methods)
26
- bundlerUrl: "https://api.yourbundler.com/rpc",
27
- // Optional: Override RPC URL (defaults to chain.rpcUrls.default)
28
- // rpcUrl: "https://sepolia.base.org",
29
-
30
- // Addresses are automatically resolved for supported chains (Base, Base Sepolia)
31
- // You can override them if needed:
32
- // factoryAddress: "0x...",
33
- };
20
+ // 1. Import Config (Chain Registry)
21
+ import { BASE_SEPOLIA, type ChainConfig } from "@1llet.xyz/erc4337-gasless-sdk";
22
+ import { AccountAbstraction } from "@1llet.xyz/erc4337-gasless-sdk";
23
+
24
+ // 2. Initialize
25
+ const aa = new AccountAbstraction(BASE_SEPOLIA);
26
+
27
+ await aa.connect();
34
28
  ```
35
29
 
36
30
  ### 2. Initialize & Connect
@@ -163,14 +157,31 @@ const receipt = await aa.sendBatchTransaction([
163
157
  ]);
164
158
 
165
159
  // 3. Transfer ERC-20 Tokens (Helper)
166
- // Automatically encodes the transfer call
167
- const receipt = await aa.transfer(
168
- usdcAddress,
169
- recipientAddress,
170
- 1000000n // 1 USDC
171
- );
160
+ // Automatically encodes the
161
+ // 1. Transfer ERC-20 (USDC)
162
+ await aa.transfer("USDC", recipient, amount);
163
+
164
+ // 2. Transfer Native Token (ETH)
165
+ // The SDK detects the "ETH" symbol and sends a native transaction
166
+ await aa.transfer("ETH", recipient, amount);
167
+ ```
168
+
169
+ // 2. Transfer Native Token (ETH)
170
+ // The SDK detects the "ETH" symbol and sends a native transaction
171
+ await aa.transfer("ETH", recipient, amount);
172
172
  ```
173
173
 
174
+ ### Funding the Account
175
+
176
+ Easily deposit ETH from the connected wallet (EOA) to the Smart Account.
177
+
178
+ ```typescript
179
+ // Deposit 0.1 ETH
180
+ const txHash = await aa.deposit(100000000000000000n);
181
+ ```
182
+
183
+ ### High-Level Methods
184
+
174
185
  ### Error Decoding
175
186
  The SDK now automatically tries to decode cryptic "0x..." errors from the EntryPoint into readable messages like:
176
187
  - `Smart Account Error: Transfer amount exceeds balance`
@@ -0,0 +1,275 @@
1
+ import { Chain, Address, Hash, Hex } from 'viem';
2
+
3
+ interface Token {
4
+ symbol: string;
5
+ decimals: number;
6
+ address: Address;
7
+ }
8
+ interface ChainConfig {
9
+ chain: Chain;
10
+ rpcUrl?: string;
11
+ bundlerUrl: string;
12
+ entryPointAddress?: Address;
13
+ factoryAddress?: Address;
14
+ paymasterAddress?: Address;
15
+ tokens: Token[];
16
+ }
17
+ interface UserOperation {
18
+ sender: Address;
19
+ nonce: bigint;
20
+ initCode: Hex;
21
+ callData: Hex;
22
+ callGasLimit: bigint;
23
+ verificationGasLimit: bigint;
24
+ preVerificationGas: bigint;
25
+ maxFeePerGas: bigint;
26
+ maxPriorityFeePerGas: bigint;
27
+ paymasterAndData: Hex;
28
+ signature: Hex;
29
+ }
30
+ interface GasEstimate {
31
+ callGasLimit: string;
32
+ verificationGasLimit: string;
33
+ preVerificationGas: string;
34
+ maxFeePerGas: string;
35
+ maxPriorityFeePerGas: string;
36
+ }
37
+ interface UserOpReceipt {
38
+ userOpHash: Hash;
39
+ sender: Address;
40
+ success: boolean;
41
+ actualGasCost: string;
42
+ receipt: {
43
+ transactionHash: Hash;
44
+ blockNumber: string;
45
+ };
46
+ }
47
+ interface ApprovalSupportResult {
48
+ type: "permit" | "approve" | "none";
49
+ gasCost?: string;
50
+ fundingNeeded?: string;
51
+ fundedAmount?: string;
52
+ }
53
+
54
+ /**
55
+ * ERC-4337 Account Abstraction Client
56
+ */
57
+ declare class AccountAbstraction {
58
+ private owner;
59
+ private smartAccountAddress;
60
+ private chainConfig;
61
+ private publicClient;
62
+ private bundlerClient;
63
+ private tokenService;
64
+ private userOpBuilder;
65
+ private entryPointAddress;
66
+ private factoryAddress;
67
+ constructor(chainConfig: ChainConfig);
68
+ /**
69
+ * Connect to MetaMask and get the owner address
70
+ */
71
+ connect(): Promise<{
72
+ owner: Address;
73
+ smartAccount: Address;
74
+ }>;
75
+ /**
76
+ * Get the Smart Account address for an owner
77
+ */
78
+ getSmartAccountAddress(owner: Address): Promise<Address>;
79
+ /**
80
+ * Check if the Smart Account is deployed
81
+ */
82
+ isAccountDeployed(): Promise<boolean>;
83
+ getTokenAddress(token: string | Address): Address;
84
+ getUsdcBalance(): Promise<bigint>;
85
+ getEoaUsdcBalance(): Promise<bigint>;
86
+ getAllowance(): Promise<bigint>;
87
+ deployAccount(): Promise<UserOpReceipt>;
88
+ sendTransaction(tx: {
89
+ target: Address;
90
+ value?: bigint;
91
+ data?: Hex;
92
+ }): Promise<UserOpReceipt>;
93
+ sendBatchTransaction(txs: {
94
+ target: Address;
95
+ value?: bigint;
96
+ data?: Hex;
97
+ }[]): Promise<UserOpReceipt>;
98
+ deposit(amount: bigint): Promise<Hash>;
99
+ transfer(token: Address | string, recipient: Address, amount: bigint): Promise<UserOpReceipt>;
100
+ /**
101
+ * Approve a token for the Smart Account
102
+ */
103
+ approveToken(token: Address, spender: Address, amount?: bigint): Promise<Hash | "NOT_NEEDED">;
104
+ buildUserOperationBatch(transactions: any[]): Promise<UserOperation>;
105
+ signUserOperation(userOp: UserOperation): Promise<UserOperation>;
106
+ sendUserOperation(userOp: UserOperation): Promise<Hash>;
107
+ waitForUserOperation(hash: Hash, timeout?: number): Promise<UserOpReceipt>;
108
+ requestApprovalSupport(token: Address, spender: Address, amount: bigint): Promise<ApprovalSupportResult>;
109
+ private decodeError;
110
+ getOwner(): `0x${string}` | null;
111
+ getSmartAccount(): `0x${string}` | null;
112
+ }
113
+ declare global {
114
+ interface Window {
115
+ ethereum?: {
116
+ request: (args: {
117
+ method: string;
118
+ params?: unknown[];
119
+ }) => Promise<unknown>;
120
+ on: (event: string, callback: (args: unknown) => void) => void;
121
+ removeListener: (event: string, callback: (args: unknown) => void) => void;
122
+ };
123
+ }
124
+ }
125
+
126
+ declare class BundlerClient {
127
+ private bundlerUrl;
128
+ private chainId;
129
+ private entryPointAddress;
130
+ constructor(config: ChainConfig, entryPointAddress: Address);
131
+ private call;
132
+ estimateGas(userOp: Partial<UserOperation>): Promise<GasEstimate>;
133
+ sendUserOperation(userOp: UserOperation): Promise<Hash>;
134
+ waitForUserOperation(userOpHash: Hash, timeout?: number): Promise<UserOpReceipt>;
135
+ requestApprovalSupport(token: Address, owner: Address, spender: Address, amount: bigint): Promise<ApprovalSupportResult>;
136
+ }
137
+
138
+ declare const BASE_MAINNET: ChainConfig;
139
+ declare const BASE_SEPOLIA: ChainConfig;
140
+ declare const CHAIN_CONFIGS: Record<number, ChainConfig>;
141
+
142
+ declare const entryPointAbi: readonly [{
143
+ readonly inputs: readonly [{
144
+ readonly name: "sender";
145
+ readonly type: "address";
146
+ }, {
147
+ readonly name: "key";
148
+ readonly type: "uint192";
149
+ }];
150
+ readonly name: "getNonce";
151
+ readonly outputs: readonly [{
152
+ readonly name: "nonce";
153
+ readonly type: "uint256";
154
+ }];
155
+ readonly stateMutability: "view";
156
+ readonly type: "function";
157
+ }];
158
+ declare const smartAccountAbi: readonly [{
159
+ readonly inputs: readonly [{
160
+ readonly name: "target";
161
+ readonly type: "address";
162
+ }, {
163
+ readonly name: "value";
164
+ readonly type: "uint256";
165
+ }, {
166
+ readonly name: "data";
167
+ readonly type: "bytes";
168
+ }];
169
+ readonly name: "execute";
170
+ readonly outputs: readonly [];
171
+ readonly stateMutability: "nonpayable";
172
+ readonly type: "function";
173
+ }, {
174
+ readonly inputs: readonly [{
175
+ readonly name: "targets";
176
+ readonly type: "address[]";
177
+ }, {
178
+ readonly name: "values";
179
+ readonly type: "uint256[]";
180
+ }, {
181
+ readonly name: "datas";
182
+ readonly type: "bytes[]";
183
+ }];
184
+ readonly name: "executeBatch";
185
+ readonly outputs: readonly [];
186
+ readonly stateMutability: "nonpayable";
187
+ readonly type: "function";
188
+ }];
189
+ declare const erc20Abi: readonly [{
190
+ readonly inputs: readonly [{
191
+ readonly name: "account";
192
+ readonly type: "address";
193
+ }];
194
+ readonly name: "balanceOf";
195
+ readonly outputs: readonly [{
196
+ readonly name: "";
197
+ readonly type: "uint256";
198
+ }];
199
+ readonly stateMutability: "view";
200
+ readonly type: "function";
201
+ }, {
202
+ readonly inputs: readonly [{
203
+ readonly name: "to";
204
+ readonly type: "address";
205
+ }, {
206
+ readonly name: "amount";
207
+ readonly type: "uint256";
208
+ }];
209
+ readonly name: "transfer";
210
+ readonly outputs: readonly [{
211
+ readonly name: "";
212
+ readonly type: "bool";
213
+ }];
214
+ readonly stateMutability: "nonpayable";
215
+ readonly type: "function";
216
+ }, {
217
+ readonly inputs: readonly [{
218
+ readonly name: "spender";
219
+ readonly type: "address";
220
+ }, {
221
+ readonly name: "amount";
222
+ readonly type: "uint256";
223
+ }];
224
+ readonly name: "approve";
225
+ readonly outputs: readonly [{
226
+ readonly name: "";
227
+ readonly type: "bool";
228
+ }];
229
+ readonly stateMutability: "nonpayable";
230
+ readonly type: "function";
231
+ }, {
232
+ readonly inputs: readonly [{
233
+ readonly name: "owner";
234
+ readonly type: "address";
235
+ }, {
236
+ readonly name: "spender";
237
+ readonly type: "address";
238
+ }];
239
+ readonly name: "allowance";
240
+ readonly outputs: readonly [{
241
+ readonly name: "";
242
+ readonly type: "uint256";
243
+ }];
244
+ readonly stateMutability: "view";
245
+ readonly type: "function";
246
+ }, {
247
+ readonly inputs: readonly [{
248
+ readonly name: "from";
249
+ readonly type: "address";
250
+ }, {
251
+ readonly name: "to";
252
+ readonly type: "address";
253
+ }, {
254
+ readonly name: "amount";
255
+ readonly type: "uint256";
256
+ }];
257
+ readonly name: "transferFrom";
258
+ readonly outputs: readonly [{
259
+ readonly name: "";
260
+ readonly type: "bool";
261
+ }];
262
+ readonly stateMutability: "nonpayable";
263
+ readonly type: "function";
264
+ }, {
265
+ readonly inputs: readonly [];
266
+ readonly name: "decimals";
267
+ readonly outputs: readonly [{
268
+ readonly name: "";
269
+ readonly type: "uint8";
270
+ }];
271
+ readonly stateMutability: "view";
272
+ readonly type: "function";
273
+ }];
274
+
275
+ export { AccountAbstraction, BASE_MAINNET, BASE_SEPOLIA, BundlerClient, CHAIN_CONFIGS, type ChainConfig, type Token, type UserOpReceipt, type UserOperation, entryPointAbi, erc20Abi, smartAccountAbi };
@@ -0,0 +1,275 @@
1
+ import { Chain, Address, Hash, Hex } from 'viem';
2
+
3
+ interface Token {
4
+ symbol: string;
5
+ decimals: number;
6
+ address: Address;
7
+ }
8
+ interface ChainConfig {
9
+ chain: Chain;
10
+ rpcUrl?: string;
11
+ bundlerUrl: string;
12
+ entryPointAddress?: Address;
13
+ factoryAddress?: Address;
14
+ paymasterAddress?: Address;
15
+ tokens: Token[];
16
+ }
17
+ interface UserOperation {
18
+ sender: Address;
19
+ nonce: bigint;
20
+ initCode: Hex;
21
+ callData: Hex;
22
+ callGasLimit: bigint;
23
+ verificationGasLimit: bigint;
24
+ preVerificationGas: bigint;
25
+ maxFeePerGas: bigint;
26
+ maxPriorityFeePerGas: bigint;
27
+ paymasterAndData: Hex;
28
+ signature: Hex;
29
+ }
30
+ interface GasEstimate {
31
+ callGasLimit: string;
32
+ verificationGasLimit: string;
33
+ preVerificationGas: string;
34
+ maxFeePerGas: string;
35
+ maxPriorityFeePerGas: string;
36
+ }
37
+ interface UserOpReceipt {
38
+ userOpHash: Hash;
39
+ sender: Address;
40
+ success: boolean;
41
+ actualGasCost: string;
42
+ receipt: {
43
+ transactionHash: Hash;
44
+ blockNumber: string;
45
+ };
46
+ }
47
+ interface ApprovalSupportResult {
48
+ type: "permit" | "approve" | "none";
49
+ gasCost?: string;
50
+ fundingNeeded?: string;
51
+ fundedAmount?: string;
52
+ }
53
+
54
+ /**
55
+ * ERC-4337 Account Abstraction Client
56
+ */
57
+ declare class AccountAbstraction {
58
+ private owner;
59
+ private smartAccountAddress;
60
+ private chainConfig;
61
+ private publicClient;
62
+ private bundlerClient;
63
+ private tokenService;
64
+ private userOpBuilder;
65
+ private entryPointAddress;
66
+ private factoryAddress;
67
+ constructor(chainConfig: ChainConfig);
68
+ /**
69
+ * Connect to MetaMask and get the owner address
70
+ */
71
+ connect(): Promise<{
72
+ owner: Address;
73
+ smartAccount: Address;
74
+ }>;
75
+ /**
76
+ * Get the Smart Account address for an owner
77
+ */
78
+ getSmartAccountAddress(owner: Address): Promise<Address>;
79
+ /**
80
+ * Check if the Smart Account is deployed
81
+ */
82
+ isAccountDeployed(): Promise<boolean>;
83
+ getTokenAddress(token: string | Address): Address;
84
+ getUsdcBalance(): Promise<bigint>;
85
+ getEoaUsdcBalance(): Promise<bigint>;
86
+ getAllowance(): Promise<bigint>;
87
+ deployAccount(): Promise<UserOpReceipt>;
88
+ sendTransaction(tx: {
89
+ target: Address;
90
+ value?: bigint;
91
+ data?: Hex;
92
+ }): Promise<UserOpReceipt>;
93
+ sendBatchTransaction(txs: {
94
+ target: Address;
95
+ value?: bigint;
96
+ data?: Hex;
97
+ }[]): Promise<UserOpReceipt>;
98
+ deposit(amount: bigint): Promise<Hash>;
99
+ transfer(token: Address | string, recipient: Address, amount: bigint): Promise<UserOpReceipt>;
100
+ /**
101
+ * Approve a token for the Smart Account
102
+ */
103
+ approveToken(token: Address, spender: Address, amount?: bigint): Promise<Hash | "NOT_NEEDED">;
104
+ buildUserOperationBatch(transactions: any[]): Promise<UserOperation>;
105
+ signUserOperation(userOp: UserOperation): Promise<UserOperation>;
106
+ sendUserOperation(userOp: UserOperation): Promise<Hash>;
107
+ waitForUserOperation(hash: Hash, timeout?: number): Promise<UserOpReceipt>;
108
+ requestApprovalSupport(token: Address, spender: Address, amount: bigint): Promise<ApprovalSupportResult>;
109
+ private decodeError;
110
+ getOwner(): `0x${string}` | null;
111
+ getSmartAccount(): `0x${string}` | null;
112
+ }
113
+ declare global {
114
+ interface Window {
115
+ ethereum?: {
116
+ request: (args: {
117
+ method: string;
118
+ params?: unknown[];
119
+ }) => Promise<unknown>;
120
+ on: (event: string, callback: (args: unknown) => void) => void;
121
+ removeListener: (event: string, callback: (args: unknown) => void) => void;
122
+ };
123
+ }
124
+ }
125
+
126
+ declare class BundlerClient {
127
+ private bundlerUrl;
128
+ private chainId;
129
+ private entryPointAddress;
130
+ constructor(config: ChainConfig, entryPointAddress: Address);
131
+ private call;
132
+ estimateGas(userOp: Partial<UserOperation>): Promise<GasEstimate>;
133
+ sendUserOperation(userOp: UserOperation): Promise<Hash>;
134
+ waitForUserOperation(userOpHash: Hash, timeout?: number): Promise<UserOpReceipt>;
135
+ requestApprovalSupport(token: Address, owner: Address, spender: Address, amount: bigint): Promise<ApprovalSupportResult>;
136
+ }
137
+
138
+ declare const BASE_MAINNET: ChainConfig;
139
+ declare const BASE_SEPOLIA: ChainConfig;
140
+ declare const CHAIN_CONFIGS: Record<number, ChainConfig>;
141
+
142
+ declare const entryPointAbi: readonly [{
143
+ readonly inputs: readonly [{
144
+ readonly name: "sender";
145
+ readonly type: "address";
146
+ }, {
147
+ readonly name: "key";
148
+ readonly type: "uint192";
149
+ }];
150
+ readonly name: "getNonce";
151
+ readonly outputs: readonly [{
152
+ readonly name: "nonce";
153
+ readonly type: "uint256";
154
+ }];
155
+ readonly stateMutability: "view";
156
+ readonly type: "function";
157
+ }];
158
+ declare const smartAccountAbi: readonly [{
159
+ readonly inputs: readonly [{
160
+ readonly name: "target";
161
+ readonly type: "address";
162
+ }, {
163
+ readonly name: "value";
164
+ readonly type: "uint256";
165
+ }, {
166
+ readonly name: "data";
167
+ readonly type: "bytes";
168
+ }];
169
+ readonly name: "execute";
170
+ readonly outputs: readonly [];
171
+ readonly stateMutability: "nonpayable";
172
+ readonly type: "function";
173
+ }, {
174
+ readonly inputs: readonly [{
175
+ readonly name: "targets";
176
+ readonly type: "address[]";
177
+ }, {
178
+ readonly name: "values";
179
+ readonly type: "uint256[]";
180
+ }, {
181
+ readonly name: "datas";
182
+ readonly type: "bytes[]";
183
+ }];
184
+ readonly name: "executeBatch";
185
+ readonly outputs: readonly [];
186
+ readonly stateMutability: "nonpayable";
187
+ readonly type: "function";
188
+ }];
189
+ declare const erc20Abi: readonly [{
190
+ readonly inputs: readonly [{
191
+ readonly name: "account";
192
+ readonly type: "address";
193
+ }];
194
+ readonly name: "balanceOf";
195
+ readonly outputs: readonly [{
196
+ readonly name: "";
197
+ readonly type: "uint256";
198
+ }];
199
+ readonly stateMutability: "view";
200
+ readonly type: "function";
201
+ }, {
202
+ readonly inputs: readonly [{
203
+ readonly name: "to";
204
+ readonly type: "address";
205
+ }, {
206
+ readonly name: "amount";
207
+ readonly type: "uint256";
208
+ }];
209
+ readonly name: "transfer";
210
+ readonly outputs: readonly [{
211
+ readonly name: "";
212
+ readonly type: "bool";
213
+ }];
214
+ readonly stateMutability: "nonpayable";
215
+ readonly type: "function";
216
+ }, {
217
+ readonly inputs: readonly [{
218
+ readonly name: "spender";
219
+ readonly type: "address";
220
+ }, {
221
+ readonly name: "amount";
222
+ readonly type: "uint256";
223
+ }];
224
+ readonly name: "approve";
225
+ readonly outputs: readonly [{
226
+ readonly name: "";
227
+ readonly type: "bool";
228
+ }];
229
+ readonly stateMutability: "nonpayable";
230
+ readonly type: "function";
231
+ }, {
232
+ readonly inputs: readonly [{
233
+ readonly name: "owner";
234
+ readonly type: "address";
235
+ }, {
236
+ readonly name: "spender";
237
+ readonly type: "address";
238
+ }];
239
+ readonly name: "allowance";
240
+ readonly outputs: readonly [{
241
+ readonly name: "";
242
+ readonly type: "uint256";
243
+ }];
244
+ readonly stateMutability: "view";
245
+ readonly type: "function";
246
+ }, {
247
+ readonly inputs: readonly [{
248
+ readonly name: "from";
249
+ readonly type: "address";
250
+ }, {
251
+ readonly name: "to";
252
+ readonly type: "address";
253
+ }, {
254
+ readonly name: "amount";
255
+ readonly type: "uint256";
256
+ }];
257
+ readonly name: "transferFrom";
258
+ readonly outputs: readonly [{
259
+ readonly name: "";
260
+ readonly type: "bool";
261
+ }];
262
+ readonly stateMutability: "nonpayable";
263
+ readonly type: "function";
264
+ }, {
265
+ readonly inputs: readonly [];
266
+ readonly name: "decimals";
267
+ readonly outputs: readonly [{
268
+ readonly name: "";
269
+ readonly type: "uint8";
270
+ }];
271
+ readonly stateMutability: "view";
272
+ readonly type: "function";
273
+ }];
274
+
275
+ export { AccountAbstraction, BASE_MAINNET, BASE_SEPOLIA, BundlerClient, CHAIN_CONFIGS, type ChainConfig, type Token, type UserOpReceipt, type UserOperation, entryPointAbi, erc20Abi, smartAccountAbi };