@1llet.xyz/erc4337-gasless-sdk 0.4.29 → 0.4.31

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
@@ -1,6 +1,6 @@
1
1
  # ERC-4337 Gasless SDK ⛽️
2
2
 
3
- A lightweight, typed SDK to integrate Account Abstraction (ERC-4337) into your dApp. It handles Smart Account creation, gasless transactions, and token approvals seamlessly.
3
+ A lightweight, typed SDK to integrate Account Abstraction (ERC-4337) and Cross-Chain transfers into your dApp. It handles Smart Account creation, gasless transactions, and orchestrates cross-chain bridges.
4
4
 
5
5
  ## 📦 Installation
6
6
 
@@ -10,243 +10,127 @@ npm install @1llet.xyz/erc4337-gasless-sdk viem
10
10
  yarn add @1llet.xyz/erc4337-gasless-sdk viem
11
11
  ```
12
12
 
13
- ## 🚀 Quick Start
13
+ ## 🚀 Quick Start (Account Abstraction)
14
14
 
15
- ### 1. Configuration
15
+ ### 1. Configuration & Initialization
16
16
 
17
- Define the chain configuration (including your Bundler URL and Paymaster).
17
+ Import chain configurations directly from the SDK.
18
18
 
19
19
  ```typescript
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";
20
+ import { BASE_MAINNET, AccountAbstraction } from "@1llet.xyz/erc4337-gasless-sdk";
23
21
 
24
- // 2. Initialize
25
- const aa = new AccountAbstraction(BASE_SEPOLIA);
26
-
27
- await aa.connect();
22
+ // Initialize with a supported chain
23
+ const aa = new AccountAbstraction(BASE_MAINNET);
28
24
  ```
29
25
 
30
- ### 2. Initialize & Connect
31
-
32
- Two modes are supported: **Browser (MetaMask)** and **Server/Script (Private Key)**.
26
+ ### 2. Connect Wallet
33
27
 
34
- #### Option A: Browser (MetaMask)
28
+ Supports **Browser (MetaMask)** and **Private Key (Server)**.
35
29
 
36
30
  ```typescript
37
- import { AccountAbstraction } from "@1llet.xyz/erc4337-gasless-sdk";
38
-
39
- const aa = new AccountAbstraction(config);
40
-
41
- // Connect to MetaMask (or any injected provider)
42
- // This calculates the Smart Account address deterministically (Counterfactual)
31
+ // A. Browser (MetaMask / Injected)
43
32
  const { owner, smartAccount } = await aa.connect();
44
33
 
45
- console.log("EOA Owner:", owner);
34
+ // B. Private Key (Backend / Bots)
35
+ const { owner, smartAccount } = await aa.connect("0xMY_PRIVATE_KEY");
36
+
37
+ console.log("EOA:", owner);
46
38
  console.log("Smart Account:", smartAccount);
47
39
  ```
48
40
 
49
- #### Option B: Server / Backend (Private Key)
41
+ ### 3. Send Gasless Transactions
50
42
 
51
- Initialize with a private key to sign transactions locally (no popup). Useful for bots or backends.
43
+ Transactions are sponsored by the Paymaster automatically.
52
44
 
53
45
  ```typescript
54
- const PRIVATE_KEY = "0x..."; // Your EOA Private Key
55
-
56
- // Connect using the private key
57
- const { owner, smartAccount } = await aa.connect(PRIVATE_KEY);
58
-
59
- console.log("Local Signer:", owner);
60
- // seamless transaction execution...
61
- await aa.transfer("USDC", recipient, amount);
62
- ```
63
-
64
- ### 3. Send a Gasless Transaction
46
+ // 1. Transfer ERC-20 (USDC)
47
+ await aa.transfer("USDC", recipientAddress, 1000000n); // 1 USDC (6 decimals)
65
48
 
66
- Send a transaction where the Gas is paid by the Paymaster (sponsored).
49
+ // 2. Transfer Native Token (ETH/DAI/MATIC)
50
+ // The SDK detects the native asset from chain config
51
+ await aa.transfer("ETH", recipientAddress, parseEther("0.1"));
67
52
 
68
- ```typescript
69
- import { encodeFunctionData, parseAbi } from "viem";
70
-
71
- // Example: Calling a precise function on a contract
72
- const myContractAbi = parseAbi(["function safeMint(address to)"]);
73
- const callData = encodeFunctionData({
74
- abi: myContractAbi,
75
- functionName: "safeMint",
76
- args: [smartAccount]
53
+ // 3. Any Contract Call (e.g. Mint NFT)
54
+ await aa.sendTransaction({
55
+ target: "0xNftContract",
56
+ data: encodeFunctionData({ ... })
77
57
  });
78
-
79
- // Build the UserOperation
80
- // This automatically handles: InitCode (if not deployed), Gas Estimation, and Paymaster data
81
- const userOp = await aa.buildUserOperationBatch([
82
- {
83
- target: "0xMyNftContract...",
84
- value: 0n,
85
- data: callData
86
- }
87
- ]);
88
-
89
- // Sign with the EOA (MetaMask)
90
- const signedOp = await aa.signUserOperation(userOp);
91
-
92
- // Send to Bundler
93
- const userOpHash = await aa.sendUserOperation(signedOp);
94
- console.log("Transaction sent! Hash:", userOpHash);
95
-
96
- // Wait for confirmation
97
- const receipt = await aa.waitForUserOperation(userOpHash);
98
- console.log("Transaction confirmed in block:", receipt.receipt.blockNumber);
99
58
  ```
100
59
 
101
- ### 4. Special Feature: Approval Support
60
+ ---
102
61
 
103
- Fund the user's EOA with native ETH (via the Paymaster/Bundler) if they need to execute a legacy `approve` transaction and have no gas.
62
+ ## 🌉 Cross-Chain Transfer Manager
104
63
 
105
- ```typescript
106
- try {
107
- const result = await aa.requestApprovalSupport(
108
- usdcAddress,
109
- spenderAddress,
110
- amount
111
- );
112
-
113
- if (result.fundingNeeded) {
114
- console.log(`User was funded with ${result.fundedAmount} ETH to pay for gas!`);
115
- }
116
- } catch (e) {
117
- console.error("Failed to fund user:", e);
118
- }
119
- ```
120
-
121
- ## 🛠️ Build Locally
122
-
123
- ```bash
124
- git clone https://github.com/your-repo/erc4337-gasless-sdk.git
125
- cd erc4337-gasless-sdk
126
- npm install
127
- npm run build
128
- ```
129
-
130
- ## � API Reference
131
-
132
- ### Balances & Allowances
64
+ The `TransferManager` orchestrates transfers between chains, choosing the best strategy (CCTP, Near Intents) or signaling a direct transfer if on the same chain.
133
65
 
134
66
  ```typescript
135
- // Get Smart Account USDC Balance
136
- const balance = await aa.getUsdcBalance();
137
-
138
- // Get EOA (Wallet) USDC Balance
139
- const eoaBalance = await aa.getEoaUsdcBalance();
140
-
141
- // Check how much USDC the Smart Account is allowed to spend from EOA
142
- const allowance = await aa.getAllowance();
143
- ```
144
-
145
- ### Account Management
146
-
147
- ```typescript
148
- // Check if the Smart Account is already deployed on-chain
149
- const isDeployed = await aa.isAccountDeployed();
150
-
151
- // Get the Counterfactual Address (deterministic address based on owner)
152
- const address = await aa.getSmartAccountAddress(ownerAddress);
153
-
154
- // Deploy the account (Abstracts build -> sign -> send -> wait)
155
- // Returns the transaction receipt
156
- const receipt = await aa.deployAccount();
157
- ```
158
-
159
- ### Simplified Transactions (v0.2.0+)
160
-
161
- Send transactions without manually building, signing, and waiting.
162
-
163
- ```typescript
164
- // 1. Send ETH or Call Contract (Single)
165
- const receipt = await aa.sendTransaction({
166
- target: "0x123...",
167
- value: 1000000000000000000n, // 1 ETH
168
- data: "0x..." // Optional callData
169
- });
170
-
171
- // 2. Send Multiple Transactions (Batch)
172
- // Great for approving + swapping, or multiple transfers
173
- const receipt = await aa.sendBatchTransaction([
174
- { target: "0xToken...", data: encodeApproveData },
175
- { target: "0xSwap...", data: encodeSwapData }
176
- ]);
177
-
178
- // 3. Transfer ERC-20 Tokens (Helper)
179
- // Automatically encodes the
180
- // 1. Transfer ERC-20 (USDC)
181
- await aa.transfer("USDC", recipient, amount);
182
-
183
- // 2. Transfer Native Token (ETH)
184
- // The SDK detects the "ETH" symbol and sends a native transaction
185
- await aa.transfer("ETH", recipient, amount);
67
+ import { TransferManager, BridgeContext } from "@1llet.xyz/erc4337-gasless-sdk";
68
+
69
+ const transferManager = new TransferManager();
70
+
71
+ const context: BridgeContext = {
72
+ sourceChain: "Base",
73
+ destChain: "Optimism",
74
+ sourceToken: "USDC",
75
+ destToken: "USDC",
76
+ amount: "10.5", // Human readable string
77
+ recipient: "0xRecipient...",
78
+ senderAddress: "0xSender...",
79
+ facilitatorPrivateKey: "0x..." // For CCTP/Near verification usage (Backend)
80
+ };
81
+
82
+ const result = await transferManager.execute(context);
83
+
84
+ if (result.success) {
85
+ if (result.transactionHash === "DIRECT_TRANSFER_REQUIRED") {
86
+ // Signal to Client: Execute direct transfer on same chain!
87
+ console.log("Execute local transfer:", result.data);
88
+ } else {
89
+ // Cross-chain initiated
90
+ console.log("Bridge Tx:", result.transactionHash);
91
+ }
92
+ } else {
93
+ console.error("Error:", result.errorReason);
94
+ }
186
95
  ```
187
96
 
188
- // 2. Transfer Native Token (ETH)
189
- // The SDK detects the "ETH" symbol and sends a native transaction
190
- await aa.transfer("ETH", recipient, amount);
191
- ```
97
+ ## 🛠️ Supported Chains
192
98
 
193
- ### Funding the Account
99
+ The SDK exports pre-configured objects:
194
100
 
195
- Easily deposit ETH from the connected wallet (EOA) to the Smart Account.
101
+ - `BASE_MAINNET`
102
+ - `BASE_SEPOLIA`
103
+ - `OPTIMISM_MAINNET`
104
+ - `GNOSIS_MAINNET`
196
105
 
197
106
  ```typescript
198
- // Deposit 0.1 ETH
199
- const txHash = await aa.deposit(100000000000000000n);
107
+ import { GNOSIS_MAINNET } from "@1llet.xyz/erc4337-gasless-sdk";
200
108
  ```
201
109
 
202
- ### High-Level Methods
203
-
204
- ### Error Decoding
205
- The SDK now automatically tries to decode cryptic "0x..." errors from the EntryPoint into readable messages like:
206
- - `Smart Account Error: Transfer amount exceeds balance`
207
- - `Smart Account: Native transfer failed`
110
+ ## 📄 API Reference
208
111
 
209
- ### Simplified Approvals
112
+ ### AccountAbstraction
210
113
 
211
- ```typescript
212
- // Approve a token for a spender (e.g. Smart Account)
213
- // Automatically handles:
214
- // 1. Checks if funding is needed (Gasless flow support)
215
- // 2. Encodes function data
216
- // 3. Sends transaction via Wallet
217
- // Returns the txHash or "NOT_NEEDED"
218
- const txHash = await aa.approveToken(usdcAddress, spenderAddress, amount);
219
- ```
114
+ | Method | Description |
115
+ |--------|-------------|
116
+ | `connect(privateKey?)` | Connects to wallet and calculates Smart Account address |
117
+ | `isAccountDeployed()` | Checks if Smart Account exists on-chain |
118
+ | `deployAccount()` | Deploys the Smart Account (usually updated automatically on first tx) |
119
+ | `transfer(token, to, amount)` | Simplest way to send tokens or ETH |
120
+ | `sendTransaction(tx)` | Send a raw transaction (target, value, data) |
121
+ | `sendBatchTransaction(txs)` | Send multiple transactions in one UserOp (Atomic) |
122
+ | `approveToken(token, spender, amount)` | Approve a spender (handles gasless logic if needed) |
123
+ | `getSmartAccountAddress(owner)` | Get deterministic address for any EOA |
220
124
 
221
125
  ### Utilities
222
126
 
223
127
  ```typescript
224
- // Get current Nonce
225
- const nonce = await aa.getNonce();
226
-
227
- // Get UserOp Hash (for manual signing or verification)
228
- const hash = aa.getUserOpHash(userOp);
229
- ```
128
+ import { CHAIN_CONFIGS } from "@1llet.xyz/erc4337-gasless-sdk";
230
129
 
231
- ### Constants & Exports
232
-
233
- The SDK exports useful constants and ABIs so you don't need to redefine them:
234
-
235
- ```typescript
236
- import {
237
- DEPLOYMENTS,
238
- erc20Abi,
239
- factoryAbi,
240
- entryPointAbi
241
- } from "@1llet.xyz/erc4337-gasless-sdk";
242
-
243
- // Access known contract addresses
244
- const usdcOnBase = DEPLOYMENTS[8453].usdc;
245
-
246
- // Use ABIs directly
247
- console.log(erc20Abi);
130
+ // Access config by Chain ID
131
+ const config = CHAIN_CONFIGS[8453];
248
132
  ```
249
133
 
250
- ## �📄 License
134
+ ## License
251
135
 
252
136
  MIT
package/dist/index.d.mts CHANGED
@@ -79,17 +79,10 @@ declare class AccountAbstraction {
79
79
  * Get the Smart Account address for an owner
80
80
  */
81
81
  getSmartAccountAddress(owner: Address): Promise<Address>;
82
- /**
83
- * Check if the Smart Account is deployed
84
- */
85
- isAccountDeployed(): Promise<boolean>;
86
82
  getTokenAddress(token: string | Address): Address;
87
83
  getBalance(token: string | Address): Promise<bigint>;
88
84
  getEoaBalance(token: string | Address): Promise<bigint>;
89
- getUsdcBalance(): Promise<bigint>;
90
- getEoaUsdcBalance(): Promise<bigint>;
91
85
  getAllowance(token?: string | Address): Promise<bigint>;
92
- deployAccount(): Promise<UserOpReceipt>;
93
86
  sendTransaction(tx: {
94
87
  target: Address;
95
88
  value?: bigint;
@@ -106,7 +99,6 @@ declare class AccountAbstraction {
106
99
  * Approve a token for the Smart Account
107
100
  */
108
101
  approveToken(token: Address, spender: Address, amount?: bigint): Promise<Hash | "NOT_NEEDED">;
109
- buildUserOperationBatch(transactions: any[]): Promise<UserOperation>;
110
102
  signUserOperation(userOp: UserOperation): Promise<UserOperation>;
111
103
  sendUserOperation(userOp: UserOperation): Promise<Hash>;
112
104
  waitForUserOperation(hash: Hash, timeout?: number): Promise<UserOpReceipt>;
@@ -130,7 +122,6 @@ declare global {
130
122
 
131
123
  declare class BundlerClient {
132
124
  private bundlerUrl;
133
- private chainId;
134
125
  private entryPointAddress;
135
126
  constructor(config: ChainConfig, entryPointAddress: Address);
136
127
  private call;
@@ -282,9 +273,9 @@ declare const erc20Abi: readonly [{
282
273
  declare const CHAIN_ID_TO_KEY: Record<string, string>;
283
274
 
284
275
  declare const ChainKeyEnum: z.ZodEnum<{
285
- Base: "Base";
286
276
  Optimism: "Optimism";
287
277
  Arbitrum: "Arbitrum";
278
+ Base: "Base";
288
279
  Unichain: "Unichain";
289
280
  Polygon: "Polygon";
290
281
  Avalanche: "Avalanche";
package/dist/index.d.ts CHANGED
@@ -79,17 +79,10 @@ declare class AccountAbstraction {
79
79
  * Get the Smart Account address for an owner
80
80
  */
81
81
  getSmartAccountAddress(owner: Address): Promise<Address>;
82
- /**
83
- * Check if the Smart Account is deployed
84
- */
85
- isAccountDeployed(): Promise<boolean>;
86
82
  getTokenAddress(token: string | Address): Address;
87
83
  getBalance(token: string | Address): Promise<bigint>;
88
84
  getEoaBalance(token: string | Address): Promise<bigint>;
89
- getUsdcBalance(): Promise<bigint>;
90
- getEoaUsdcBalance(): Promise<bigint>;
91
85
  getAllowance(token?: string | Address): Promise<bigint>;
92
- deployAccount(): Promise<UserOpReceipt>;
93
86
  sendTransaction(tx: {
94
87
  target: Address;
95
88
  value?: bigint;
@@ -106,7 +99,6 @@ declare class AccountAbstraction {
106
99
  * Approve a token for the Smart Account
107
100
  */
108
101
  approveToken(token: Address, spender: Address, amount?: bigint): Promise<Hash | "NOT_NEEDED">;
109
- buildUserOperationBatch(transactions: any[]): Promise<UserOperation>;
110
102
  signUserOperation(userOp: UserOperation): Promise<UserOperation>;
111
103
  sendUserOperation(userOp: UserOperation): Promise<Hash>;
112
104
  waitForUserOperation(hash: Hash, timeout?: number): Promise<UserOpReceipt>;
@@ -130,7 +122,6 @@ declare global {
130
122
 
131
123
  declare class BundlerClient {
132
124
  private bundlerUrl;
133
- private chainId;
134
125
  private entryPointAddress;
135
126
  constructor(config: ChainConfig, entryPointAddress: Address);
136
127
  private call;
@@ -282,9 +273,9 @@ declare const erc20Abi: readonly [{
282
273
  declare const CHAIN_ID_TO_KEY: Record<string, string>;
283
274
 
284
275
  declare const ChainKeyEnum: z.ZodEnum<{
285
- Base: "Base";
286
276
  Optimism: "Optimism";
287
277
  Arbitrum: "Arbitrum";
278
+ Base: "Base";
288
279
  Unichain: "Unichain";
289
280
  Polygon: "Polygon";
290
281
  Avalanche: "Avalanche";