@t402/wdk-gasless 1.0.0 → 2.4.0
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 +240 -0
- package/dist/cjs/index.d.ts +14 -42
- package/dist/cjs/index.js +34 -19
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.d.mts +14 -42
- package/dist/esm/index.mjs +35 -25
- package/dist/esm/index.mjs.map +1 -1
- package/package.json +22 -21
package/README.md
ADDED
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
# @t402/wdk-gasless
|
|
2
|
+
|
|
3
|
+
Gasless USDT0 payments with Tether WDK and ERC-4337 Account Abstraction.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Gasless Payments**: Send USDT0/USDC without paying gas fees
|
|
8
|
+
- **ERC-4337 Integration**: Uses Safe smart accounts with Account Abstraction
|
|
9
|
+
- **Batch Payments**: Execute multiple transfers in a single transaction
|
|
10
|
+
- **Multi-Chain Support**: Ethereum, Arbitrum, Base, Optimism, Ink, Berachain, Unichain
|
|
11
|
+
- **Paymaster Sponsorship**: Optional gas sponsorship via paymasters
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install @t402/wdk-gasless
|
|
17
|
+
# or
|
|
18
|
+
pnpm add @t402/wdk-gasless
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### Peer Dependencies
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install @tetherto/wdk @tetherto/wdk-wallet-evm
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Quick Start
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
import { createWdkGaslessClient } from '@t402/wdk-gasless'
|
|
31
|
+
import { createPublicClient, http } from 'viem'
|
|
32
|
+
import { arbitrum } from 'viem/chains'
|
|
33
|
+
|
|
34
|
+
// Create a public client
|
|
35
|
+
const publicClient = createPublicClient({
|
|
36
|
+
chain: arbitrum,
|
|
37
|
+
transport: http(),
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
// Create the gasless client
|
|
41
|
+
const client = await createWdkGaslessClient({
|
|
42
|
+
wdkAccount: myWdkAccount, // From @tetherto/wdk
|
|
43
|
+
publicClient,
|
|
44
|
+
chainId: 42161, // Arbitrum
|
|
45
|
+
bundler: {
|
|
46
|
+
bundlerUrl: 'https://api.pimlico.io/v2/arbitrum/rpc?apikey=YOUR_KEY',
|
|
47
|
+
chainId: 42161,
|
|
48
|
+
},
|
|
49
|
+
paymaster: {
|
|
50
|
+
address: '0x...',
|
|
51
|
+
url: 'https://api.pimlico.io/v2/arbitrum/rpc?apikey=YOUR_KEY',
|
|
52
|
+
type: 'sponsoring',
|
|
53
|
+
},
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
// Execute a gasless payment
|
|
57
|
+
const result = await client.pay({
|
|
58
|
+
to: '0xRecipientAddress...',
|
|
59
|
+
amount: 1000000n, // 1 USDT0 (6 decimals)
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
// Wait for confirmation
|
|
63
|
+
const receipt = await result.wait()
|
|
64
|
+
console.log('Payment confirmed:', receipt.txHash)
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## API Reference
|
|
68
|
+
|
|
69
|
+
### `createWdkGaslessClient(config)`
|
|
70
|
+
|
|
71
|
+
Creates a new gasless payment client.
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
interface CreateWdkGaslessClientConfig {
|
|
75
|
+
wdkAccount: WdkAccount // WDK account from @tetherto/wdk
|
|
76
|
+
publicClient: PublicClient // Viem public client
|
|
77
|
+
chainId: number // Chain ID
|
|
78
|
+
bundler: BundlerConfig // Bundler configuration
|
|
79
|
+
paymaster?: PaymasterConfig // Optional paymaster for gas sponsorship
|
|
80
|
+
saltNonce?: bigint // Salt for address generation (default: 0n)
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### `WdkGaslessClient`
|
|
85
|
+
|
|
86
|
+
#### `pay(params): Promise<GaslessPaymentResult>`
|
|
87
|
+
|
|
88
|
+
Execute a single gasless payment.
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
interface GaslessPaymentParams {
|
|
92
|
+
to: Address // Recipient address
|
|
93
|
+
amount: bigint // Amount in token decimals
|
|
94
|
+
token?: 'USDT0' | 'USDC' | Address // Token (default: 'USDT0')
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
interface GaslessPaymentResult {
|
|
98
|
+
userOpHash: Hex // UserOperation hash
|
|
99
|
+
sender: Address // Smart account address
|
|
100
|
+
sponsored: boolean // Whether gas was sponsored
|
|
101
|
+
wait(): Promise<GaslessPaymentReceipt>
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
#### `payBatch(params): Promise<GaslessPaymentResult>`
|
|
106
|
+
|
|
107
|
+
Execute multiple payments in a single transaction.
|
|
108
|
+
|
|
109
|
+
```typescript
|
|
110
|
+
interface BatchPaymentParams {
|
|
111
|
+
payments: Array<{
|
|
112
|
+
to: Address
|
|
113
|
+
amount: bigint
|
|
114
|
+
token?: 'USDT0' | 'USDC' | Address
|
|
115
|
+
}>
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
#### `canSponsor(params): Promise<SponsorshipInfo>`
|
|
120
|
+
|
|
121
|
+
Check if a payment can be gas-sponsored.
|
|
122
|
+
|
|
123
|
+
```typescript
|
|
124
|
+
interface SponsorshipInfo {
|
|
125
|
+
canSponsor: boolean
|
|
126
|
+
reason?: string
|
|
127
|
+
estimatedGasCost?: bigint
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
#### `getBalance(token?): Promise<bigint>`
|
|
132
|
+
|
|
133
|
+
Get the token balance of the smart account.
|
|
134
|
+
|
|
135
|
+
#### `getFormattedBalance(token?, decimals?): Promise<string>`
|
|
136
|
+
|
|
137
|
+
Get the formatted token balance (human-readable).
|
|
138
|
+
|
|
139
|
+
#### `getAccountAddress(): Promise<Address>`
|
|
140
|
+
|
|
141
|
+
Get the smart account address.
|
|
142
|
+
|
|
143
|
+
#### `isAccountDeployed(): Promise<boolean>`
|
|
144
|
+
|
|
145
|
+
Check if the smart account is deployed on-chain.
|
|
146
|
+
|
|
147
|
+
## Supported Chains
|
|
148
|
+
|
|
149
|
+
| Chain | Chain ID | USDT0 | USDC |
|
|
150
|
+
| --------- | -------- | ----- | ---- |
|
|
151
|
+
| Ethereum | 1 | ✅ | ✅ |
|
|
152
|
+
| Arbitrum | 42161 | ✅ | ✅ |
|
|
153
|
+
| Base | 8453 | ✅ | ✅ |
|
|
154
|
+
| Optimism | 10 | ✅ | ✅ |
|
|
155
|
+
| Ink | 57073 | ✅ | - |
|
|
156
|
+
| Berachain | 80094 | ✅ | - |
|
|
157
|
+
| Unichain | 130 | ✅ | - |
|
|
158
|
+
|
|
159
|
+
## Constants
|
|
160
|
+
|
|
161
|
+
```typescript
|
|
162
|
+
import {
|
|
163
|
+
USDT0_ADDRESSES,
|
|
164
|
+
USDC_ADDRESSES,
|
|
165
|
+
CHAIN_IDS,
|
|
166
|
+
getTokenAddress,
|
|
167
|
+
getChainName,
|
|
168
|
+
} from '@t402/wdk-gasless'
|
|
169
|
+
|
|
170
|
+
// Get USDT0 address on Arbitrum
|
|
171
|
+
const usdt0 = USDT0_ADDRESSES.arbitrum
|
|
172
|
+
// '0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9'
|
|
173
|
+
|
|
174
|
+
// Get chain name from ID
|
|
175
|
+
const chainName = getChainName(42161)
|
|
176
|
+
// 'arbitrum'
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## Smart Account Architecture
|
|
180
|
+
|
|
181
|
+
This package uses Safe smart accounts with ERC-4337 support:
|
|
182
|
+
|
|
183
|
+
- **Safe Singleton**: `0x29fcB43b46531BcA003ddC8FCB67FFE91900C762`
|
|
184
|
+
- **Safe 4337 Module**: `0xa581c4A4DB7175302464fF3C06380BC3270b4037` (v0.3.0)
|
|
185
|
+
- **Proxy Factory**: `0x4e1DCf7AD4e460CfD30791CCC4F9c8a4f820ec67`
|
|
186
|
+
- **EntryPoint**: `0x0000000071727De22E5E9d8BAf0edAc6f37da032` (v0.7)
|
|
187
|
+
|
|
188
|
+
## Examples
|
|
189
|
+
|
|
190
|
+
### Batch Payment
|
|
191
|
+
|
|
192
|
+
```typescript
|
|
193
|
+
const result = await client.payBatch({
|
|
194
|
+
payments: [
|
|
195
|
+
{ to: '0xAlice...', amount: 500000n }, // 0.5 USDT0
|
|
196
|
+
{ to: '0xBob...', amount: 300000n }, // 0.3 USDT0
|
|
197
|
+
{ to: '0xCharlie...', amount: 200000n }, // 0.2 USDT0
|
|
198
|
+
],
|
|
199
|
+
})
|
|
200
|
+
|
|
201
|
+
const receipt = await result.wait()
|
|
202
|
+
console.log(`Batch payment in tx: ${receipt.txHash}`)
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### Check Sponsorship
|
|
206
|
+
|
|
207
|
+
```typescript
|
|
208
|
+
const sponsorship = await client.canSponsor({
|
|
209
|
+
to: '0xRecipient...',
|
|
210
|
+
amount: 1000000n,
|
|
211
|
+
})
|
|
212
|
+
|
|
213
|
+
if (sponsorship.canSponsor) {
|
|
214
|
+
console.log('Payment will be free!')
|
|
215
|
+
} else {
|
|
216
|
+
console.log(`Gas cost: ${sponsorship.estimatedGasCost} wei`)
|
|
217
|
+
}
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### Using USDC Instead
|
|
221
|
+
|
|
222
|
+
```typescript
|
|
223
|
+
const result = await client.pay({
|
|
224
|
+
to: '0xRecipient...',
|
|
225
|
+
amount: 1000000n,
|
|
226
|
+
token: 'USDC',
|
|
227
|
+
})
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
## Related Packages
|
|
231
|
+
|
|
232
|
+
- `@t402/core` - Core protocol types and client
|
|
233
|
+
- `@t402/wdk` - Tether WDK integration
|
|
234
|
+
- `@t402/wdk-bridge` - Cross-chain LayerZero bridging
|
|
235
|
+
- `@t402/wdk-multisig` - Safe multi-sig wallets
|
|
236
|
+
- `@t402/evm` - EVM mechanism implementation
|
|
237
|
+
|
|
238
|
+
## License
|
|
239
|
+
|
|
240
|
+
Apache-2.0
|
package/dist/cjs/index.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { PublicClient, Address, Hex } from 'viem';
|
|
2
2
|
import { SmartAccountSigner, BundlerConfig, PaymasterConfig } from '@t402/evm';
|
|
3
3
|
export { BundlerConfig, PaymasterConfig, SmartAccountSigner, UserOperationReceipt } from '@t402/evm';
|
|
4
|
+
import { WdkAccount } from '@t402/wdk';
|
|
5
|
+
export { WdkAccount } from '@t402/wdk';
|
|
4
6
|
|
|
5
7
|
/**
|
|
6
8
|
* WDK Gasless Types
|
|
@@ -9,41 +11,7 @@ export { BundlerConfig, PaymasterConfig, SmartAccountSigner, UserOperationReceip
|
|
|
9
11
|
*/
|
|
10
12
|
|
|
11
13
|
/**
|
|
12
|
-
* WDK
|
|
13
|
-
*/
|
|
14
|
-
interface WdkAccount {
|
|
15
|
-
/** Get the account's address */
|
|
16
|
-
getAddress(): Promise<string>;
|
|
17
|
-
/** Get the account's native balance */
|
|
18
|
-
getBalance(): Promise<bigint>;
|
|
19
|
-
/** Get the account's token balance */
|
|
20
|
-
getTokenBalance(tokenAddress: string): Promise<bigint>;
|
|
21
|
-
/** Sign a message */
|
|
22
|
-
signMessage(message: string): Promise<string>;
|
|
23
|
-
/** Sign typed data (EIP-712) */
|
|
24
|
-
signTypedData(params: {
|
|
25
|
-
domain: {
|
|
26
|
-
name?: string;
|
|
27
|
-
version?: string;
|
|
28
|
-
chainId?: number;
|
|
29
|
-
verifyingContract?: string;
|
|
30
|
-
};
|
|
31
|
-
types: Record<string, Array<{
|
|
32
|
-
name: string;
|
|
33
|
-
type: string;
|
|
34
|
-
}>>;
|
|
35
|
-
primaryType: string;
|
|
36
|
-
message: Record<string, unknown>;
|
|
37
|
-
}): Promise<string>;
|
|
38
|
-
/** Send a transaction */
|
|
39
|
-
sendTransaction(params: {
|
|
40
|
-
to: string;
|
|
41
|
-
value?: bigint;
|
|
42
|
-
data?: string;
|
|
43
|
-
}): Promise<string>;
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* WDK instance interface
|
|
14
|
+
* WDK instance interface (simplified wrapper for gasless context)
|
|
47
15
|
*/
|
|
48
16
|
interface WdkInstance {
|
|
49
17
|
/** Get accounts */
|
|
@@ -92,7 +60,7 @@ interface GaslessPaymentParams {
|
|
|
92
60
|
/** Amount to send (in token decimals, e.g., 1000000 for 1 USDT) */
|
|
93
61
|
amount: bigint;
|
|
94
62
|
/** Token to send (defaults to USDT0) */
|
|
95
|
-
token?:
|
|
63
|
+
token?: 'USDT0' | 'USDC' | Address;
|
|
96
64
|
}
|
|
97
65
|
/**
|
|
98
66
|
* Parameters for a batch payment
|
|
@@ -105,7 +73,7 @@ interface BatchPaymentParams {
|
|
|
105
73
|
/** Amount to send */
|
|
106
74
|
amount: bigint;
|
|
107
75
|
/** Token to send (defaults to USDT0) */
|
|
108
|
-
token?:
|
|
76
|
+
token?: 'USDT0' | 'USDC' | Address;
|
|
109
77
|
}>;
|
|
110
78
|
}
|
|
111
79
|
/**
|
|
@@ -205,11 +173,11 @@ declare class WdkGaslessClient {
|
|
|
205
173
|
/**
|
|
206
174
|
* Get the token balance of the smart account
|
|
207
175
|
*/
|
|
208
|
-
getBalance(token?:
|
|
176
|
+
getBalance(token?: 'USDT0' | 'USDC' | Address): Promise<bigint>;
|
|
209
177
|
/**
|
|
210
178
|
* Get the formatted token balance
|
|
211
179
|
*/
|
|
212
|
-
getFormattedBalance(token?:
|
|
180
|
+
getFormattedBalance(token?: 'USDT0' | 'USDC' | Address, decimals?: number): Promise<string>;
|
|
213
181
|
/**
|
|
214
182
|
* Estimate gas for a single transaction
|
|
215
183
|
*/
|
|
@@ -310,7 +278,7 @@ declare const SAFE_4337_ADDRESSES: {
|
|
|
310
278
|
declare class WdkSmartAccount implements SmartAccountSigner {
|
|
311
279
|
private readonly wdkAccount;
|
|
312
280
|
private readonly publicClient;
|
|
313
|
-
private readonly
|
|
281
|
+
private readonly _chainId;
|
|
314
282
|
private readonly owners;
|
|
315
283
|
private readonly threshold;
|
|
316
284
|
private readonly saltNonce;
|
|
@@ -329,6 +297,10 @@ declare class WdkSmartAccount implements SmartAccountSigner {
|
|
|
329
297
|
* Get the WDK account's EOA address
|
|
330
298
|
*/
|
|
331
299
|
getOwnerAddress(): Promise<Address>;
|
|
300
|
+
/**
|
|
301
|
+
* Get the chain ID
|
|
302
|
+
*/
|
|
303
|
+
getChainId(): number;
|
|
332
304
|
/**
|
|
333
305
|
* Get the smart account address (counterfactual)
|
|
334
306
|
*/
|
|
@@ -400,10 +372,10 @@ declare const DEFAULT_BUNDLER_URLS: Record<number, string>;
|
|
|
400
372
|
/**
|
|
401
373
|
* Get token address for a chain
|
|
402
374
|
*/
|
|
403
|
-
declare function getTokenAddress(token:
|
|
375
|
+
declare function getTokenAddress(token: 'USDT0' | 'USDC' | Address, chainName: string): Address;
|
|
404
376
|
/**
|
|
405
377
|
* Get chain name from chain ID
|
|
406
378
|
*/
|
|
407
379
|
declare function getChainName(chainId: number): string;
|
|
408
380
|
|
|
409
|
-
export { type BatchPaymentParams, CHAIN_IDS, type CreateWdkGaslessClientConfig, DEFAULT_BUNDLER_URLS, type GaslessPaymentParams, type GaslessPaymentReceipt, type GaslessPaymentResult, SAFE_4337_ADDRESSES, type SponsorshipInfo, USDC_ADDRESSES, USDT0_ADDRESSES,
|
|
381
|
+
export { type BatchPaymentParams, CHAIN_IDS, type CreateWdkGaslessClientConfig, DEFAULT_BUNDLER_URLS, type GaslessPaymentParams, type GaslessPaymentReceipt, type GaslessPaymentResult, SAFE_4337_ADDRESSES, type SponsorshipInfo, USDC_ADDRESSES, USDT0_ADDRESSES, WdkGaslessClient, type WdkGaslessClientConfig, type WdkInstance, WdkSmartAccount, type WdkSmartAccountConfig, createWdkGaslessClient, createWdkSmartAccount, getChainName, getTokenAddress };
|
package/dist/cjs/index.js
CHANGED
|
@@ -134,7 +134,7 @@ var SAFE_4337_MODULE_ABI = [
|
|
|
134
134
|
var WdkSmartAccount = class {
|
|
135
135
|
wdkAccount;
|
|
136
136
|
publicClient;
|
|
137
|
-
|
|
137
|
+
_chainId;
|
|
138
138
|
owners;
|
|
139
139
|
threshold;
|
|
140
140
|
saltNonce;
|
|
@@ -146,7 +146,7 @@ var WdkSmartAccount = class {
|
|
|
146
146
|
constructor(config) {
|
|
147
147
|
this.wdkAccount = config.wdkAccount;
|
|
148
148
|
this.publicClient = config.publicClient;
|
|
149
|
-
this.
|
|
149
|
+
this._chainId = config.chainId;
|
|
150
150
|
this.threshold = config.threshold ?? 1;
|
|
151
151
|
this.saltNonce = config.saltNonce ?? 0n;
|
|
152
152
|
this.owners = config.additionalOwners ?? [];
|
|
@@ -171,6 +171,12 @@ var WdkSmartAccount = class {
|
|
|
171
171
|
await this.initialize();
|
|
172
172
|
return this.cachedOwnerAddress;
|
|
173
173
|
}
|
|
174
|
+
/**
|
|
175
|
+
* Get the chain ID
|
|
176
|
+
*/
|
|
177
|
+
getChainId() {
|
|
178
|
+
return this._chainId;
|
|
179
|
+
}
|
|
174
180
|
/**
|
|
175
181
|
* Get the smart account address (counterfactual)
|
|
176
182
|
*/
|
|
@@ -248,10 +254,7 @@ var WdkSmartAccount = class {
|
|
|
248
254
|
functionName: "createProxyWithNonce",
|
|
249
255
|
args: [SAFE_4337_ADDRESSES.singleton, safeSetupData, this.saltNonce]
|
|
250
256
|
});
|
|
251
|
-
this.cachedInitCode = (0, import_viem.concat)([
|
|
252
|
-
SAFE_4337_ADDRESSES.proxyFactory,
|
|
253
|
-
createProxyData
|
|
254
|
-
]);
|
|
257
|
+
this.cachedInitCode = (0, import_viem.concat)([SAFE_4337_ADDRESSES.proxyFactory, createProxyData]);
|
|
255
258
|
return this.cachedInitCode;
|
|
256
259
|
}
|
|
257
260
|
/**
|
|
@@ -261,10 +264,10 @@ var WdkSmartAccount = class {
|
|
|
261
264
|
if (this.deploymentChecked) {
|
|
262
265
|
return this.isAccountDeployed;
|
|
263
266
|
}
|
|
267
|
+
this.deploymentChecked = true;
|
|
264
268
|
await this.initialize();
|
|
265
269
|
const address = this.cachedAddress ?? await this.getAddress();
|
|
266
270
|
const code = await this.publicClient.getCode({ address });
|
|
267
|
-
this.deploymentChecked = true;
|
|
268
271
|
this.isAccountDeployed = code !== void 0 && code !== "0x";
|
|
269
272
|
return this.isAccountDeployed;
|
|
270
273
|
}
|
|
@@ -357,7 +360,7 @@ var USDT0_ADDRESSES = {
|
|
|
357
360
|
arbitrum: "0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9",
|
|
358
361
|
ink: "0x0200C29006150606B650577BBE7B6248F58470c1",
|
|
359
362
|
berachain: "0x779Ded0c9e1022225f8E0630b35a9b54bE713736",
|
|
360
|
-
unichain: "
|
|
363
|
+
unichain: "0x9151434b16b9763660705744891fA906F660EcC5",
|
|
361
364
|
base: "0x6C96dE32CEa08842dcc4058c14d3aaAD7Fa41dee",
|
|
362
365
|
optimism: "0x6C96dE32CEa08842dcc4058c14d3aaAD7Fa41dee"
|
|
363
366
|
};
|
|
@@ -375,7 +378,7 @@ var CHAIN_IDS = {
|
|
|
375
378
|
optimism: 10,
|
|
376
379
|
polygon: 137,
|
|
377
380
|
ink: 57073,
|
|
378
|
-
berachain:
|
|
381
|
+
berachain: 80094,
|
|
379
382
|
unichain: 130
|
|
380
383
|
};
|
|
381
384
|
var DEFAULT_BUNDLER_URLS = {
|
|
@@ -450,6 +453,12 @@ var WdkGaslessClient = class {
|
|
|
450
453
|
* Gas is sponsored by a paymaster if configured.
|
|
451
454
|
*/
|
|
452
455
|
async pay(params) {
|
|
456
|
+
if (!params.to || params.to === "0x0000000000000000000000000000000000000000") {
|
|
457
|
+
throw new Error("Recipient address must not be the zero address");
|
|
458
|
+
}
|
|
459
|
+
if (params.amount <= 0n) {
|
|
460
|
+
throw new Error("Payment amount must be greater than zero");
|
|
461
|
+
}
|
|
453
462
|
const token = params.token ?? "USDT0";
|
|
454
463
|
const tokenAddress = getTokenAddress(token, this.chainName);
|
|
455
464
|
const callData = (0, import_viem2.encodeFunctionData)({
|
|
@@ -505,6 +514,20 @@ var WdkGaslessClient = class {
|
|
|
505
514
|
* All payments are executed atomically.
|
|
506
515
|
*/
|
|
507
516
|
async payBatch(params) {
|
|
517
|
+
if (!params.payments || params.payments.length === 0) {
|
|
518
|
+
throw new Error("Batch payments must contain at least one payment");
|
|
519
|
+
}
|
|
520
|
+
if (params.payments.length > 50) {
|
|
521
|
+
throw new Error("Batch payments must not exceed 50 payments");
|
|
522
|
+
}
|
|
523
|
+
for (const payment of params.payments) {
|
|
524
|
+
if (!payment.to || payment.to === "0x0000000000000000000000000000000000000000") {
|
|
525
|
+
throw new Error("Recipient address must not be the zero address");
|
|
526
|
+
}
|
|
527
|
+
if (payment.amount <= 0n) {
|
|
528
|
+
throw new Error("Payment amount must be greater than zero");
|
|
529
|
+
}
|
|
530
|
+
}
|
|
508
531
|
const intents = params.payments.map((payment) => {
|
|
509
532
|
const token = payment.token ?? "USDT0";
|
|
510
533
|
const tokenAddress = getTokenAddress(token, this.chainName);
|
|
@@ -641,11 +664,7 @@ var WdkGaslessClient = class {
|
|
|
641
664
|
*/
|
|
642
665
|
async estimateGas(intent) {
|
|
643
666
|
const sender = await this.signer.getAddress();
|
|
644
|
-
const callData = this.signer.encodeExecute(
|
|
645
|
-
intent.to,
|
|
646
|
-
intent.value ?? 0n,
|
|
647
|
-
intent.data ?? "0x"
|
|
648
|
-
);
|
|
667
|
+
const callData = this.signer.encodeExecute(intent.to, intent.value ?? 0n, intent.data ?? "0x");
|
|
649
668
|
try {
|
|
650
669
|
return await this.bundler.estimateUserOperationGas({
|
|
651
670
|
sender,
|
|
@@ -688,11 +707,7 @@ var WdkGaslessClient = class {
|
|
|
688
707
|
async getPaymasterData(_gasEstimate) {
|
|
689
708
|
if (!this.paymaster) return void 0;
|
|
690
709
|
const sender = await this.signer.getAddress();
|
|
691
|
-
return this.paymaster.getPaymasterData(
|
|
692
|
-
{ sender },
|
|
693
|
-
this.chainId,
|
|
694
|
-
import_evm.ENTRYPOINT_V07_ADDRESS
|
|
695
|
-
);
|
|
710
|
+
return this.paymaster.getPaymasterData({ sender }, this.chainId, import_evm.ENTRYPOINT_V07_ADDRESS);
|
|
696
711
|
}
|
|
697
712
|
};
|
|
698
713
|
async function createWdkGaslessClient(config) {
|
package/dist/cjs/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/index.ts","../../src/client.ts","../../src/account.ts","../../src/constants.ts"],"sourcesContent":["/**\n * @t402/wdk-gasless\n *\n * Gasless USDT0 payments using Tether WDK and ERC-4337 Account Abstraction.\n *\n * This package enables users to send USDT0 payments without holding any ETH\n * for gas fees. It works by:\n *\n * 1. Wrapping a WDK account in a Safe smart account (ERC-4337)\n * 2. Using a paymaster to sponsor gas fees\n * 3. Submitting UserOperations through a bundler\n *\n * @example Basic usage\n * ```typescript\n * import { createWdkGaslessClient } from '@t402/wdk-gasless';\n * import { createPublicClient, http } from 'viem';\n * import { arbitrum } from 'viem/chains';\n *\n * // Create public client\n * const publicClient = createPublicClient({\n * chain: arbitrum,\n * transport: http(),\n * });\n *\n * // Create gasless client\n * const client = await createWdkGaslessClient({\n * wdkAccount: myWdkAccount,\n * publicClient,\n * chainId: 42161,\n * bundler: {\n * bundlerUrl: 'https://api.pimlico.io/v2/arbitrum/rpc?apikey=...',\n * chainId: 42161,\n * },\n * paymaster: {\n * address: '0x...',\n * url: 'https://api.pimlico.io/v2/arbitrum/rpc?apikey=...',\n * type: 'sponsoring',\n * },\n * });\n *\n * // Check balance\n * const balance = await client.getFormattedBalance();\n * console.log(`USDT0 Balance: ${balance}`);\n *\n * // Execute gasless payment\n * const result = await client.pay({\n * to: '0x...',\n * amount: 1000000n, // 1 USDT0 (6 decimals)\n * });\n *\n * console.log('UserOp submitted:', result.userOpHash);\n * console.log('Sponsored (free gas):', result.sponsored);\n *\n * // Wait for confirmation\n * const receipt = await result.wait();\n * console.log('Confirmed in tx:', receipt.txHash);\n * ```\n *\n * @example Batch payments\n * ```typescript\n * // Send to multiple recipients in one transaction\n * const result = await client.payBatch({\n * payments: [\n * { to: '0xAlice...', amount: 1000000n }, // 1 USDT0\n * { to: '0xBob...', amount: 2000000n }, // 2 USDT0\n * { to: '0xCharlie...', amount: 500000n }, // 0.5 USDT0\n * ],\n * });\n * ```\n *\n * @example Check sponsorship eligibility\n * ```typescript\n * const info = await client.canSponsor({\n * to: '0x...',\n * amount: 1000000n,\n * });\n *\n * if (info.canSponsor) {\n * console.log('Payment will be sponsored (free gas)');\n * } else {\n * console.log('Not sponsored:', info.reason);\n * console.log('Estimated gas cost:', info.estimatedGasCost);\n * }\n * ```\n *\n * @packageDocumentation\n */\n\n// Main client\nexport {\n WdkGaslessClient,\n createWdkGaslessClient,\n} from \"./client.js\";\nexport type { CreateWdkGaslessClientConfig } from \"./client.js\";\n\n// Smart account\nexport {\n WdkSmartAccount,\n createWdkSmartAccount,\n SAFE_4337_ADDRESSES,\n} from \"./account.js\";\n\n// Types\nexport type {\n WdkAccount,\n WdkInstance,\n WdkSmartAccountConfig,\n WdkGaslessClientConfig,\n GaslessPaymentParams,\n BatchPaymentParams,\n GaslessPaymentResult,\n GaslessPaymentReceipt,\n SponsorshipInfo,\n} from \"./types.js\";\n\n// Constants\nexport {\n USDT0_ADDRESSES,\n USDC_ADDRESSES,\n CHAIN_IDS,\n DEFAULT_BUNDLER_URLS,\n getTokenAddress,\n getChainName,\n} from \"./constants.js\";\n\n// Re-export essential types from @t402/evm for convenience\nexport type {\n SmartAccountSigner,\n BundlerConfig,\n PaymasterConfig,\n UserOperationReceipt,\n} from \"@t402/evm\";\n","/**\n * WDK Gasless Client\n *\n * High-level client for executing gasless USDT0 payments using\n * Tether WDK accounts and ERC-4337 Account Abstraction.\n */\n\nimport type { Address, Hex, PublicClient } from \"viem\";\nimport { encodeFunctionData, parseUnits, formatUnits } from \"viem\";\nimport {\n BundlerClient,\n PaymasterClient,\n UserOpBuilder,\n ENTRYPOINT_V07_ADDRESS,\n} from \"@t402/evm\";\nimport type {\n SmartAccountSigner,\n BundlerConfig,\n PaymasterConfig,\n TransactionIntent,\n GasEstimate,\n PaymasterData,\n} from \"@t402/evm\";\nimport type {\n WdkGaslessClientConfig,\n GaslessPaymentParams,\n BatchPaymentParams,\n GaslessPaymentResult,\n GaslessPaymentReceipt,\n SponsorshipInfo,\n WdkAccount,\n} from \"./types.js\";\nimport { WdkSmartAccount, createWdkSmartAccount } from \"./account.js\";\nimport { getTokenAddress, getChainName } from \"./constants.js\";\n\n/**\n * ERC20 transfer ABI\n */\nconst ERC20_TRANSFER_ABI = [\n {\n inputs: [\n { name: \"to\", type: \"address\" },\n { name: \"amount\", type: \"uint256\" },\n ],\n name: \"transfer\",\n outputs: [{ name: \"\", type: \"bool\" }],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n] as const;\n\n/**\n * ERC20 balanceOf ABI\n */\nconst ERC20_BALANCE_ABI = [\n {\n inputs: [{ name: \"account\", type: \"address\" }],\n name: \"balanceOf\",\n outputs: [{ name: \"\", type: \"uint256\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n] as const;\n\n/**\n * WDK Gasless Client\n *\n * Provides a simple API for executing gasless USDT0 payments using\n * WDK accounts and ERC-4337 smart accounts.\n */\nexport class WdkGaslessClient {\n private readonly signer: SmartAccountSigner;\n private readonly builder: UserOpBuilder;\n private readonly bundler: BundlerClient;\n private readonly paymaster?: PaymasterClient;\n private readonly chainId: number;\n private readonly publicClient: PublicClient;\n private readonly chainName: string;\n\n constructor(config: WdkGaslessClientConfig) {\n this.signer = config.signer;\n this.builder = new UserOpBuilder();\n this.bundler = new BundlerClient(config.bundler);\n this.paymaster = config.paymaster\n ? new PaymasterClient(config.paymaster)\n : undefined;\n this.chainId = config.chainId;\n this.publicClient = config.publicClient;\n this.chainName = getChainName(config.chainId);\n }\n\n /**\n * Execute a gasless payment\n *\n * Sends USDT0 (or other tokens) without the user paying gas fees.\n * Gas is sponsored by a paymaster if configured.\n */\n async pay(params: GaslessPaymentParams): Promise<GaslessPaymentResult> {\n const token = params.token ?? \"USDT0\";\n const tokenAddress = getTokenAddress(token, this.chainName);\n\n // Build the transfer call data\n const callData = encodeFunctionData({\n abi: ERC20_TRANSFER_ABI,\n functionName: \"transfer\",\n args: [params.to, params.amount],\n });\n\n // Create the transaction intent\n const intent: TransactionIntent = {\n to: tokenAddress,\n value: 0n,\n data: callData,\n };\n\n // Estimate gas\n const gasEstimate = await this.estimateGas(intent);\n\n // Get paymaster data if configured\n const paymasterData = await this.getPaymasterData(gasEstimate);\n const sponsored = paymasterData !== undefined;\n\n // Build the UserOperation\n const userOp = await this.builder.buildUserOp(\n this.signer,\n intent,\n this.publicClient,\n gasEstimate,\n paymasterData,\n );\n\n // Sign the UserOperation\n const signedUserOp = await this.builder.signUserOp(\n userOp,\n this.signer,\n this.publicClient,\n this.chainId,\n );\n\n // Submit to bundler\n const result = await this.bundler.sendUserOperation(signedUserOp);\n const sender = await this.signer.getAddress();\n\n return {\n userOpHash: result.userOpHash,\n sender,\n sponsored,\n wait: async (): Promise<GaslessPaymentReceipt> => {\n const receipt = await result.wait();\n return {\n userOpHash: receipt.userOpHash,\n txHash: receipt.receipt.transactionHash,\n blockNumber: receipt.receipt.blockNumber,\n success: receipt.success,\n gasUsed: receipt.actualGasUsed,\n gasCost: receipt.actualGasCost,\n reason: receipt.reason,\n };\n },\n };\n }\n\n /**\n * Execute multiple payments in a single transaction\n *\n * More gas efficient than individual payments.\n * All payments are executed atomically.\n */\n async payBatch(params: BatchPaymentParams): Promise<GaslessPaymentResult> {\n // Build transaction intents for all payments\n const intents: TransactionIntent[] = params.payments.map((payment) => {\n const token = payment.token ?? \"USDT0\";\n const tokenAddress = getTokenAddress(token, this.chainName);\n\n return {\n to: tokenAddress,\n value: 0n,\n data: encodeFunctionData({\n abi: ERC20_TRANSFER_ABI,\n functionName: \"transfer\",\n args: [payment.to, payment.amount],\n }),\n };\n });\n\n // Estimate gas for batch\n const gasEstimate = await this.estimateBatchGas(intents);\n\n // Get paymaster data\n const paymasterData = await this.getPaymasterData(gasEstimate);\n const sponsored = paymasterData !== undefined;\n\n // Build batch UserOperation\n const userOp = await this.builder.buildBatchUserOp(\n this.signer,\n intents,\n this.publicClient,\n gasEstimate,\n paymasterData,\n );\n\n // Sign and submit\n const signedUserOp = await this.builder.signUserOp(\n userOp,\n this.signer,\n this.publicClient,\n this.chainId,\n );\n\n const result = await this.bundler.sendUserOperation(signedUserOp);\n const sender = await this.signer.getAddress();\n\n return {\n userOpHash: result.userOpHash,\n sender,\n sponsored,\n wait: async (): Promise<GaslessPaymentReceipt> => {\n const receipt = await result.wait();\n return {\n userOpHash: receipt.userOpHash,\n txHash: receipt.receipt.transactionHash,\n blockNumber: receipt.receipt.blockNumber,\n success: receipt.success,\n gasUsed: receipt.actualGasUsed,\n gasCost: receipt.actualGasCost,\n reason: receipt.reason,\n };\n },\n };\n }\n\n /**\n * Check if a payment can be sponsored (free gas)\n */\n async canSponsor(params: GaslessPaymentParams): Promise<SponsorshipInfo> {\n if (!this.paymaster) {\n return {\n canSponsor: false,\n reason: \"No paymaster configured\",\n };\n }\n\n const token = params.token ?? \"USDT0\";\n const tokenAddress = getTokenAddress(token, this.chainName);\n\n const callData = encodeFunctionData({\n abi: ERC20_TRANSFER_ABI,\n functionName: \"transfer\",\n args: [params.to, params.amount],\n });\n\n const sender = await this.signer.getAddress();\n const encodedCallData = this.signer.encodeExecute(tokenAddress, 0n, callData);\n\n try {\n const canSponsor = await this.paymaster.willSponsor(\n { sender, callData: encodedCallData },\n this.chainId,\n ENTRYPOINT_V07_ADDRESS,\n );\n\n if (canSponsor) {\n return { canSponsor: true };\n } else {\n // Estimate gas cost if not sponsored\n const intent: TransactionIntent = {\n to: tokenAddress,\n value: 0n,\n data: callData,\n };\n const gasEstimate = await this.estimateGas(intent);\n const gasPrice = await this.publicClient.getGasPrice();\n const estimatedGasCost =\n (gasEstimate.verificationGasLimit +\n gasEstimate.callGasLimit +\n gasEstimate.preVerificationGas) *\n gasPrice;\n\n return {\n canSponsor: false,\n reason: \"Payment not eligible for sponsorship\",\n estimatedGasCost,\n };\n }\n } catch (error) {\n return {\n canSponsor: false,\n reason: error instanceof Error ? error.message : \"Unknown error\",\n };\n }\n }\n\n /**\n * Get the smart account address\n */\n async getAccountAddress(): Promise<Address> {\n return this.signer.getAddress();\n }\n\n /**\n * Check if the smart account is deployed\n */\n async isAccountDeployed(): Promise<boolean> {\n return this.signer.isDeployed();\n }\n\n /**\n * Get the token balance of the smart account\n */\n async getBalance(token: \"USDT0\" | \"USDC\" | Address = \"USDT0\"): Promise<bigint> {\n const tokenAddress = getTokenAddress(token, this.chainName);\n const accountAddress = await this.signer.getAddress();\n\n const balance = await this.publicClient.readContract({\n address: tokenAddress,\n abi: ERC20_BALANCE_ABI,\n functionName: \"balanceOf\",\n args: [accountAddress],\n });\n\n return balance as bigint;\n }\n\n /**\n * Get the formatted token balance\n */\n async getFormattedBalance(\n token: \"USDT0\" | \"USDC\" | Address = \"USDT0\",\n decimals = 6,\n ): Promise<string> {\n const balance = await this.getBalance(token);\n return formatUnits(balance, decimals);\n }\n\n /**\n * Estimate gas for a single transaction\n */\n private async estimateGas(intent: TransactionIntent): Promise<GasEstimate> {\n const sender = await this.signer.getAddress();\n const callData = this.signer.encodeExecute(\n intent.to,\n intent.value ?? 0n,\n intent.data ?? \"0x\",\n );\n\n try {\n return await this.bundler.estimateUserOperationGas({\n sender,\n callData,\n });\n } catch {\n // Return defaults if estimation fails\n return {\n verificationGasLimit: 150000n,\n callGasLimit: 100000n,\n preVerificationGas: 50000n,\n };\n }\n }\n\n /**\n * Estimate gas for a batch transaction\n */\n private async estimateBatchGas(\n intents: TransactionIntent[],\n ): Promise<GasEstimate> {\n const sender = await this.signer.getAddress();\n const callData = this.signer.encodeExecuteBatch(\n intents.map((i) => i.to),\n intents.map((i) => i.value ?? 0n),\n intents.map((i) => (i.data ?? \"0x\") as Hex),\n );\n\n try {\n return await this.bundler.estimateUserOperationGas({\n sender,\n callData,\n });\n } catch {\n // Return defaults with multiplier for batch size\n return {\n verificationGasLimit: 150000n,\n callGasLimit: 100000n * BigInt(intents.length),\n preVerificationGas: 50000n,\n };\n }\n }\n\n /**\n * Get paymaster data if configured\n */\n private async getPaymasterData(\n _gasEstimate: GasEstimate,\n ): Promise<PaymasterData | undefined> {\n if (!this.paymaster) return undefined;\n\n const sender = await this.signer.getAddress();\n\n return this.paymaster.getPaymasterData(\n { sender },\n this.chainId,\n ENTRYPOINT_V07_ADDRESS,\n );\n }\n}\n\n/**\n * Configuration for creating a WDK gasless client\n */\nexport interface CreateWdkGaslessClientConfig {\n /** WDK account to use as the signer */\n wdkAccount: WdkAccount;\n /** Public client for chain interactions */\n publicClient: PublicClient;\n /** Chain ID */\n chainId: number;\n /** Bundler configuration */\n bundler: BundlerConfig;\n /** Optional paymaster for gas sponsorship */\n paymaster?: PaymasterConfig;\n /** Salt nonce for address generation (defaults to 0) */\n saltNonce?: bigint;\n}\n\n/**\n * Create a WDK gasless client\n *\n * This is the main entry point for using WDK with gasless payments.\n *\n * @example\n * ```typescript\n * import { createWdkGaslessClient } from '@t402/wdk-gasless';\n *\n * const client = await createWdkGaslessClient({\n * wdkAccount: myWdkAccount,\n * publicClient,\n * chainId: 42161, // Arbitrum\n * bundler: {\n * bundlerUrl: 'https://api.pimlico.io/v2/arbitrum/rpc?apikey=...',\n * chainId: 42161,\n * },\n * paymaster: {\n * address: '0x...',\n * url: 'https://api.pimlico.io/v2/arbitrum/rpc?apikey=...',\n * type: 'sponsoring',\n * },\n * });\n *\n * // Execute gasless payment\n * const result = await client.pay({\n * to: '0x...',\n * amount: 1000000n, // 1 USDT0\n * });\n *\n * const receipt = await result.wait();\n * console.log('Payment confirmed:', receipt.txHash);\n * ```\n */\nexport async function createWdkGaslessClient(\n config: CreateWdkGaslessClientConfig,\n): Promise<WdkGaslessClient> {\n // Create the WDK smart account\n const smartAccount = await createWdkSmartAccount({\n wdkAccount: config.wdkAccount,\n publicClient: config.publicClient,\n chainId: config.chainId,\n saltNonce: config.saltNonce,\n });\n\n // Create the gasless client\n return new WdkGaslessClient({\n signer: smartAccount,\n bundler: config.bundler,\n paymaster: config.paymaster,\n chainId: config.chainId,\n publicClient: config.publicClient,\n });\n}\n","/**\n * WDK Smart Account\n *\n * Wraps a Tether WDK account to work with ERC-4337 smart accounts.\n * Creates a Safe smart account with the WDK account as the owner/signer.\n */\n\nimport type { Address, Hex, PublicClient } from \"viem\";\nimport {\n encodeFunctionData,\n encodeAbiParameters,\n concat,\n keccak256,\n getContractAddress,\n hexToBytes,\n createWalletClient,\n http,\n custom,\n} from \"viem\";\nimport type { SmartAccountSigner } from \"@t402/evm\";\nimport type { WdkAccount, WdkSmartAccountConfig } from \"./types.js\";\n\n/**\n * Safe 4337 module addresses (v0.3.0)\n * Deployed on all major EVM chains at the same addresses\n */\nexport const SAFE_4337_ADDRESSES = {\n /** Safe 4337 Module */\n module: \"0xa581c4A4DB7175302464fF3C06380BC3270b4037\" as Address,\n /** Safe Module Setup */\n moduleSetup: \"0x2dd68b007B46fBe91B9A7c3EDa5A7a1063cB5b47\" as Address,\n /** Safe Singleton */\n singleton: \"0x29fcB43b46531BcA003ddC8FCB67FFE91900C762\" as Address,\n /** Safe Proxy Factory */\n proxyFactory: \"0x4e1DCf7AD4e460CfD30791CCC4F9c8a4f820ec67\" as Address,\n /** Safe Fallback Handler */\n fallbackHandler: \"0xfd0732Dc9E303f09fCEf3a7388Ad10A83459Ec99\" as Address,\n /** Add Modules Lib */\n addModulesLib: \"0x8EcD4ec46D4D2a6B64fE960B3D64e8B94B2234eb\" as Address,\n} as const;\n\n/**\n * Safe Proxy Factory ABI\n */\nconst PROXY_FACTORY_ABI = [\n {\n inputs: [\n { name: \"singleton\", type: \"address\" },\n { name: \"initializer\", type: \"bytes\" },\n { name: \"saltNonce\", type: \"uint256\" },\n ],\n name: \"createProxyWithNonce\",\n outputs: [{ name: \"proxy\", type: \"address\" }],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [\n { name: \"singleton\", type: \"address\" },\n { name: \"initializer\", type: \"bytes\" },\n { name: \"saltNonce\", type: \"uint256\" },\n ],\n name: \"proxyCreationCode\",\n outputs: [{ name: \"\", type: \"bytes\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n] as const;\n\n/**\n * Safe Singleton ABI\n */\nconst SAFE_ABI = [\n {\n inputs: [\n { name: \"owners\", type: \"address[]\" },\n { name: \"threshold\", type: \"uint256\" },\n { name: \"to\", type: \"address\" },\n { name: \"data\", type: \"bytes\" },\n { name: \"fallbackHandler\", type: \"address\" },\n { name: \"paymentToken\", type: \"address\" },\n { name: \"payment\", type: \"uint256\" },\n { name: \"paymentReceiver\", type: \"address\" },\n ],\n name: \"setup\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n] as const;\n\n/**\n * Add Modules Lib ABI\n */\nconst ADD_MODULES_LIB_ABI = [\n {\n inputs: [{ name: \"modules\", type: \"address[]\" }],\n name: \"enableModules\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n] as const;\n\n/**\n * Safe 4337 Module ABI\n */\nconst SAFE_4337_MODULE_ABI = [\n {\n inputs: [\n { name: \"to\", type: \"address\" },\n { name: \"value\", type: \"uint256\" },\n { name: \"data\", type: \"bytes\" },\n { name: \"operation\", type: \"uint8\" },\n ],\n name: \"executeUserOp\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [\n { name: \"tos\", type: \"address[]\" },\n { name: \"values\", type: \"uint256[]\" },\n { name: \"datas\", type: \"bytes[]\" },\n { name: \"operations\", type: \"uint8[]\" },\n ],\n name: \"executeUserOpBatch\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n] as const;\n\n/**\n * WDK Smart Account\n *\n * Creates a Safe smart account using a WDK account as the owner/signer.\n * Implements SmartAccountSigner for ERC-4337 compatibility.\n */\nexport class WdkSmartAccount implements SmartAccountSigner {\n private readonly wdkAccount: WdkAccount;\n private readonly publicClient: PublicClient;\n private readonly chainId: number;\n private readonly owners: Address[];\n private readonly threshold: number;\n private readonly saltNonce: bigint;\n\n private cachedAddress?: Address;\n private cachedInitCode?: Hex;\n private cachedOwnerAddress?: Address;\n private deploymentChecked = false;\n private isAccountDeployed = false;\n\n constructor(config: WdkSmartAccountConfig) {\n this.wdkAccount = config.wdkAccount;\n this.publicClient = config.publicClient;\n this.chainId = config.chainId;\n this.threshold = config.threshold ?? 1;\n this.saltNonce = config.saltNonce ?? 0n;\n\n // Owners will be set when we get the WDK account address\n this.owners = config.additionalOwners ?? [];\n }\n\n /**\n * Initialize the account (fetch WDK address)\n * Call this before using the account\n */\n async initialize(): Promise<void> {\n if (!this.cachedOwnerAddress) {\n const address = await this.wdkAccount.getAddress();\n this.cachedOwnerAddress = address as Address;\n\n // Add WDK account as the first owner if not already in owners\n if (!this.owners.includes(this.cachedOwnerAddress)) {\n this.owners.unshift(this.cachedOwnerAddress);\n }\n }\n }\n\n /**\n * Get the WDK account's EOA address\n */\n async getOwnerAddress(): Promise<Address> {\n await this.initialize();\n return this.cachedOwnerAddress!;\n }\n\n /**\n * Get the smart account address (counterfactual)\n */\n async getAddress(): Promise<Address> {\n await this.initialize();\n\n if (this.cachedAddress) {\n return this.cachedAddress;\n }\n\n const initCode = await this.getInitCode();\n\n // If already deployed, get address from code\n if (initCode === \"0x\") {\n // Need to compute it anyway for first time\n const initializerData = await this.buildInitializer();\n const salt = keccak256(\n encodeAbiParameters(\n [{ type: \"bytes32\" }, { type: \"uint256\" }],\n [keccak256(initializerData), this.saltNonce],\n ),\n );\n\n const proxyCreationCode = (await this.publicClient.readContract({\n address: SAFE_4337_ADDRESSES.proxyFactory,\n abi: PROXY_FACTORY_ABI,\n functionName: \"proxyCreationCode\",\n args: [SAFE_4337_ADDRESSES.singleton, initializerData, this.saltNonce],\n })) as Hex;\n\n this.cachedAddress = getContractAddress({\n bytecode: proxyCreationCode,\n from: SAFE_4337_ADDRESSES.proxyFactory,\n opcode: \"CREATE2\",\n salt,\n });\n } else {\n // Extract initializer from init code\n const initializerData = `0x${initCode.slice(2 + 40 * 2)}` as Hex;\n\n const salt = keccak256(\n encodeAbiParameters(\n [{ type: \"bytes32\" }, { type: \"uint256\" }],\n [keccak256(initializerData), this.saltNonce],\n ),\n );\n\n const proxyCreationCode = (await this.publicClient.readContract({\n address: SAFE_4337_ADDRESSES.proxyFactory,\n abi: PROXY_FACTORY_ABI,\n functionName: \"proxyCreationCode\",\n args: [SAFE_4337_ADDRESSES.singleton, initializerData, this.saltNonce],\n })) as Hex;\n\n this.cachedAddress = getContractAddress({\n bytecode: proxyCreationCode,\n from: SAFE_4337_ADDRESSES.proxyFactory,\n opcode: \"CREATE2\",\n salt,\n });\n }\n\n return this.cachedAddress;\n }\n\n /**\n * Sign a UserOperation hash using the WDK account\n */\n async signUserOpHash(userOpHash: Hex): Promise<Hex> {\n await this.initialize();\n\n // Sign the hash using WDK account's signMessage\n // The hash is signed as raw bytes (personal_sign format)\n const signature = await this.wdkAccount.signMessage(userOpHash);\n\n // Format signature for Safe (add signature type byte)\n // Type 0: EOA signature\n return concat([signature as Hex, \"0x00\"]) as Hex;\n }\n\n /**\n * Get the account's init code for deployment\n */\n async getInitCode(): Promise<Hex> {\n await this.initialize();\n\n // Check if already deployed\n if (await this.isDeployed()) {\n return \"0x\" as Hex;\n }\n\n if (this.cachedInitCode) {\n return this.cachedInitCode;\n }\n\n const safeSetupData = await this.buildInitializer();\n\n // Build factory call data\n const createProxyData = encodeFunctionData({\n abi: PROXY_FACTORY_ABI,\n functionName: \"createProxyWithNonce\",\n args: [SAFE_4337_ADDRESSES.singleton, safeSetupData, this.saltNonce],\n });\n\n // Init code = factory address + factory call data\n this.cachedInitCode = concat([\n SAFE_4337_ADDRESSES.proxyFactory,\n createProxyData,\n ]) as Hex;\n\n return this.cachedInitCode;\n }\n\n /**\n * Check if the account is deployed\n */\n async isDeployed(): Promise<boolean> {\n if (this.deploymentChecked) {\n return this.isAccountDeployed;\n }\n\n await this.initialize();\n const address = this.cachedAddress ?? (await this.getAddress());\n const code = await this.publicClient.getCode({ address });\n\n this.deploymentChecked = true;\n this.isAccountDeployed = code !== undefined && code !== \"0x\";\n\n return this.isAccountDeployed;\n }\n\n /**\n * Encode a call to the account's execute function\n */\n encodeExecute(target: Address, value: bigint, data: Hex): Hex {\n return encodeFunctionData({\n abi: SAFE_4337_MODULE_ABI,\n functionName: \"executeUserOp\",\n args: [target, value, data, 0], // operation: CALL\n });\n }\n\n /**\n * Encode a batch call to the account's executeBatch function\n */\n encodeExecuteBatch(targets: Address[], values: bigint[], datas: Hex[]): Hex {\n if (targets.length !== values.length || targets.length !== datas.length) {\n throw new Error(\"Array lengths must match\");\n }\n\n const operations = targets.map(() => 0); // All CALL operations\n\n return encodeFunctionData({\n abi: SAFE_4337_MODULE_ABI,\n functionName: \"executeUserOpBatch\",\n args: [targets, values, datas, operations],\n });\n }\n\n /**\n * Build the Safe setup initializer data\n */\n private async buildInitializer(): Promise<Hex> {\n await this.initialize();\n\n // Build Safe setup data with 4337 module\n const setupModulesData = encodeFunctionData({\n abi: ADD_MODULES_LIB_ABI,\n functionName: \"enableModules\",\n args: [[SAFE_4337_ADDRESSES.module]],\n });\n\n return encodeFunctionData({\n abi: SAFE_ABI,\n functionName: \"setup\",\n args: [\n this.owners,\n BigInt(this.threshold),\n SAFE_4337_ADDRESSES.addModulesLib, // to: AddModulesLib\n setupModulesData, // data: enableModules([module])\n SAFE_4337_ADDRESSES.fallbackHandler,\n \"0x0000000000000000000000000000000000000000\" as Address, // paymentToken\n 0n, // payment\n \"0x0000000000000000000000000000000000000000\" as Address, // paymentReceiver\n ],\n });\n }\n\n /**\n * Get the Safe's owners\n */\n getOwners(): Address[] {\n return [...this.owners];\n }\n\n /**\n * Get the Safe's threshold\n */\n getThreshold(): number {\n return this.threshold;\n }\n\n /**\n * Clear cached values (useful after deployment)\n */\n clearCache(): void {\n this.cachedAddress = undefined;\n this.cachedInitCode = undefined;\n this.deploymentChecked = false;\n this.isAccountDeployed = false;\n }\n}\n\n/**\n * Create a WDK smart account\n */\nexport async function createWdkSmartAccount(\n config: WdkSmartAccountConfig,\n): Promise<WdkSmartAccount> {\n const account = new WdkSmartAccount(config);\n await account.initialize();\n return account;\n}\n","/**\n * WDK Gasless Constants\n *\n * Addresses and configuration for gasless USDT0 payments.\n */\n\nimport type { Address } from \"viem\";\n\n/**\n * USDT0 OFT addresses by chain\n */\nexport const USDT0_ADDRESSES: Record<string, Address> = {\n ethereum: \"0x6C96dE32CEa08842dcc4058c14d3aaAD7Fa41dee\",\n arbitrum: \"0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9\",\n ink: \"0x0200C29006150606B650577BBE7B6248F58470c1\",\n berachain: \"0x779Ded0c9e1022225f8E0630b35a9b54bE713736\",\n unichain: \"0x588ce4F028D8e7B53B687865d6A67b3A54C75518\",\n base: \"0x6C96dE32CEa08842dcc4058c14d3aaAD7Fa41dee\",\n optimism: \"0x6C96dE32CEa08842dcc4058c14d3aaAD7Fa41dee\",\n} as const;\n\n/**\n * USDC addresses by chain\n */\nexport const USDC_ADDRESSES: Record<string, Address> = {\n ethereum: \"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\",\n arbitrum: \"0xaf88d065e77c8cC2239327C5EDb3A432268e5831\",\n base: \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\",\n optimism: \"0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85\",\n polygon: \"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359\",\n} as const;\n\n/**\n * Chain IDs for supported networks\n */\nexport const CHAIN_IDS: Record<string, number> = {\n ethereum: 1,\n arbitrum: 42161,\n base: 8453,\n optimism: 10,\n polygon: 137,\n ink: 57073,\n berachain: 80084,\n unichain: 130,\n} as const;\n\n/**\n * Default bundler URLs by chain (using public endpoints)\n */\nexport const DEFAULT_BUNDLER_URLS: Record<number, string> = {\n 1: \"https://api.pimlico.io/v2/ethereum/rpc\",\n 42161: \"https://api.pimlico.io/v2/arbitrum/rpc\",\n 8453: \"https://api.pimlico.io/v2/base/rpc\",\n 10: \"https://api.pimlico.io/v2/optimism/rpc\",\n 137: \"https://api.pimlico.io/v2/polygon/rpc\",\n} as const;\n\n/**\n * Get token address for a chain\n */\nexport function getTokenAddress(\n token: \"USDT0\" | \"USDC\" | Address,\n chainName: string,\n): Address {\n if (token.startsWith(\"0x\")) {\n return token as Address;\n }\n\n const addresses = token === \"USDT0\" ? USDT0_ADDRESSES : USDC_ADDRESSES;\n const address = addresses[chainName.toLowerCase()];\n\n if (!address) {\n throw new Error(`Token ${token} not available on ${chainName}`);\n }\n\n return address;\n}\n\n/**\n * Get chain name from chain ID\n */\nexport function getChainName(chainId: number): string {\n const entry = Object.entries(CHAIN_IDS).find(([, id]) => id === chainId);\n if (!entry) {\n throw new Error(`Unsupported chain ID: ${chainId}`);\n }\n return entry[0];\n}\n"],"mappings":"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","names":["import_viem"]}
|
|
1
|
+
{"version":3,"sources":["../../src/index.ts","../../src/client.ts","../../src/account.ts","../../src/constants.ts"],"sourcesContent":["/**\n * @t402/wdk-gasless\n *\n * Gasless USDT0 payments using Tether WDK and ERC-4337 Account Abstraction.\n *\n * This package enables users to send USDT0 payments without holding any ETH\n * for gas fees. It works by:\n *\n * 1. Wrapping a WDK account in a Safe smart account (ERC-4337)\n * 2. Using a paymaster to sponsor gas fees\n * 3. Submitting UserOperations through a bundler\n *\n * @example Basic usage\n * ```typescript\n * import { createWdkGaslessClient } from '@t402/wdk-gasless';\n * import { createPublicClient, http } from 'viem';\n * import { arbitrum } from 'viem/chains';\n *\n * // Create public client\n * const publicClient = createPublicClient({\n * chain: arbitrum,\n * transport: http(),\n * });\n *\n * // Create gasless client\n * const client = await createWdkGaslessClient({\n * wdkAccount: myWdkAccount,\n * publicClient,\n * chainId: 42161,\n * bundler: {\n * bundlerUrl: 'https://api.pimlico.io/v2/arbitrum/rpc?apikey=...',\n * chainId: 42161,\n * },\n * paymaster: {\n * address: '0x...',\n * url: 'https://api.pimlico.io/v2/arbitrum/rpc?apikey=...',\n * type: 'sponsoring',\n * },\n * });\n *\n * // Check balance\n * const balance = await client.getFormattedBalance();\n * console.log(`USDT0 Balance: ${balance}`);\n *\n * // Execute gasless payment\n * const result = await client.pay({\n * to: '0x...',\n * amount: 1000000n, // 1 USDT0 (6 decimals)\n * });\n *\n * console.log('UserOp submitted:', result.userOpHash);\n * console.log('Sponsored (free gas):', result.sponsored);\n *\n * // Wait for confirmation\n * const receipt = await result.wait();\n * console.log('Confirmed in tx:', receipt.txHash);\n * ```\n *\n * @example Batch payments\n * ```typescript\n * // Send to multiple recipients in one transaction\n * const result = await client.payBatch({\n * payments: [\n * { to: '0xAlice...', amount: 1000000n }, // 1 USDT0\n * { to: '0xBob...', amount: 2000000n }, // 2 USDT0\n * { to: '0xCharlie...', amount: 500000n }, // 0.5 USDT0\n * ],\n * });\n * ```\n *\n * @example Check sponsorship eligibility\n * ```typescript\n * const info = await client.canSponsor({\n * to: '0x...',\n * amount: 1000000n,\n * });\n *\n * if (info.canSponsor) {\n * console.log('Payment will be sponsored (free gas)');\n * } else {\n * console.log('Not sponsored:', info.reason);\n * console.log('Estimated gas cost:', info.estimatedGasCost);\n * }\n * ```\n *\n * @packageDocumentation\n */\n\n// Main client\nexport { WdkGaslessClient, createWdkGaslessClient } from './client.js'\nexport type { CreateWdkGaslessClientConfig } from './client.js'\n\n// Smart account\nexport { WdkSmartAccount, createWdkSmartAccount, SAFE_4337_ADDRESSES } from './account.js'\n\n// Types\nexport type {\n WdkAccount,\n WdkInstance,\n WdkSmartAccountConfig,\n WdkGaslessClientConfig,\n GaslessPaymentParams,\n BatchPaymentParams,\n GaslessPaymentResult,\n GaslessPaymentReceipt,\n SponsorshipInfo,\n} from './types.js'\n\n// Constants\nexport {\n USDT0_ADDRESSES,\n USDC_ADDRESSES,\n CHAIN_IDS,\n DEFAULT_BUNDLER_URLS,\n getTokenAddress,\n getChainName,\n} from './constants.js'\n\n// Re-export essential types from @t402/evm for convenience\nexport type {\n SmartAccountSigner,\n BundlerConfig,\n PaymasterConfig,\n UserOperationReceipt,\n} from '@t402/evm'\n","/**\n * WDK Gasless Client\n *\n * High-level client for executing gasless USDT0 payments using\n * Tether WDK accounts and ERC-4337 Account Abstraction.\n */\n\nimport type { Address, Hex, PublicClient } from 'viem'\nimport { encodeFunctionData, formatUnits } from 'viem'\nimport { BundlerClient, PaymasterClient, UserOpBuilder, ENTRYPOINT_V07_ADDRESS } from '@t402/evm'\nimport type {\n SmartAccountSigner,\n BundlerConfig,\n PaymasterConfig,\n TransactionIntent,\n GasEstimate,\n PaymasterData,\n} from '@t402/evm'\nimport type {\n WdkGaslessClientConfig,\n GaslessPaymentParams,\n BatchPaymentParams,\n GaslessPaymentResult,\n GaslessPaymentReceipt,\n SponsorshipInfo,\n WdkAccount,\n} from './types.js'\nimport { createWdkSmartAccount } from './account.js'\nimport { getTokenAddress, getChainName } from './constants.js'\n\n/**\n * ERC20 transfer ABI\n */\nconst ERC20_TRANSFER_ABI = [\n {\n inputs: [\n { name: 'to', type: 'address' },\n { name: 'amount', type: 'uint256' },\n ],\n name: 'transfer',\n outputs: [{ name: '', type: 'bool' }],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n] as const\n\n/**\n * ERC20 balanceOf ABI\n */\nconst ERC20_BALANCE_ABI = [\n {\n inputs: [{ name: 'account', type: 'address' }],\n name: 'balanceOf',\n outputs: [{ name: '', type: 'uint256' }],\n stateMutability: 'view',\n type: 'function',\n },\n] as const\n\n/**\n * WDK Gasless Client\n *\n * Provides a simple API for executing gasless USDT0 payments using\n * WDK accounts and ERC-4337 smart accounts.\n */\nexport class WdkGaslessClient {\n private readonly signer: SmartAccountSigner\n private readonly builder: UserOpBuilder\n private readonly bundler: BundlerClient\n private readonly paymaster?: PaymasterClient\n private readonly chainId: number\n private readonly publicClient: PublicClient\n private readonly chainName: string\n\n constructor(config: WdkGaslessClientConfig) {\n this.signer = config.signer\n this.builder = new UserOpBuilder()\n this.bundler = new BundlerClient(config.bundler)\n this.paymaster = config.paymaster ? new PaymasterClient(config.paymaster) : undefined\n this.chainId = config.chainId\n this.publicClient = config.publicClient\n this.chainName = getChainName(config.chainId)\n }\n\n /**\n * Execute a gasless payment\n *\n * Sends USDT0 (or other tokens) without the user paying gas fees.\n * Gas is sponsored by a paymaster if configured.\n */\n async pay(params: GaslessPaymentParams): Promise<GaslessPaymentResult> {\n // Validate payment params\n if (!params.to || params.to === '0x0000000000000000000000000000000000000000') {\n throw new Error('Recipient address must not be the zero address')\n }\n\n if (params.amount <= 0n) {\n throw new Error('Payment amount must be greater than zero')\n }\n\n const token = params.token ?? 'USDT0'\n const tokenAddress = getTokenAddress(token, this.chainName)\n\n // Build the transfer call data\n const callData = encodeFunctionData({\n abi: ERC20_TRANSFER_ABI,\n functionName: 'transfer',\n args: [params.to, params.amount],\n })\n\n // Create the transaction intent\n const intent: TransactionIntent = {\n to: tokenAddress,\n value: 0n,\n data: callData,\n }\n\n // Estimate gas\n const gasEstimate = await this.estimateGas(intent)\n\n // Get paymaster data if configured\n const paymasterData = await this.getPaymasterData(gasEstimate)\n const sponsored = paymasterData !== undefined\n\n // Build the UserOperation\n const userOp = await this.builder.buildUserOp(\n this.signer,\n intent,\n this.publicClient,\n gasEstimate,\n paymasterData,\n )\n\n // Sign the UserOperation\n const signedUserOp = await this.builder.signUserOp(\n userOp,\n this.signer,\n this.publicClient,\n this.chainId,\n )\n\n // Submit to bundler\n const result = await this.bundler.sendUserOperation(signedUserOp)\n const sender = await this.signer.getAddress()\n\n return {\n userOpHash: result.userOpHash,\n sender,\n sponsored,\n wait: async (): Promise<GaslessPaymentReceipt> => {\n const receipt = await result.wait()\n return {\n userOpHash: receipt.userOpHash,\n txHash: receipt.receipt.transactionHash,\n blockNumber: receipt.receipt.blockNumber,\n success: receipt.success,\n gasUsed: receipt.actualGasUsed,\n gasCost: receipt.actualGasCost,\n reason: receipt.reason,\n }\n },\n }\n }\n\n /**\n * Execute multiple payments in a single transaction\n *\n * More gas efficient than individual payments.\n * All payments are executed atomically.\n */\n async payBatch(params: BatchPaymentParams): Promise<GaslessPaymentResult> {\n // Validate batch params\n if (!params.payments || params.payments.length === 0) {\n throw new Error('Batch payments must contain at least one payment')\n }\n\n if (params.payments.length > 50) {\n throw new Error('Batch payments must not exceed 50 payments')\n }\n\n for (const payment of params.payments) {\n if (!payment.to || payment.to === '0x0000000000000000000000000000000000000000') {\n throw new Error('Recipient address must not be the zero address')\n }\n if (payment.amount <= 0n) {\n throw new Error('Payment amount must be greater than zero')\n }\n }\n\n // Build transaction intents for all payments\n const intents: TransactionIntent[] = params.payments.map((payment) => {\n const token = payment.token ?? 'USDT0'\n const tokenAddress = getTokenAddress(token, this.chainName)\n\n return {\n to: tokenAddress,\n value: 0n,\n data: encodeFunctionData({\n abi: ERC20_TRANSFER_ABI,\n functionName: 'transfer',\n args: [payment.to, payment.amount],\n }),\n }\n })\n\n // Estimate gas for batch\n const gasEstimate = await this.estimateBatchGas(intents)\n\n // Get paymaster data\n const paymasterData = await this.getPaymasterData(gasEstimate)\n const sponsored = paymasterData !== undefined\n\n // Build batch UserOperation\n const userOp = await this.builder.buildBatchUserOp(\n this.signer,\n intents,\n this.publicClient,\n gasEstimate,\n paymasterData,\n )\n\n // Sign and submit\n const signedUserOp = await this.builder.signUserOp(\n userOp,\n this.signer,\n this.publicClient,\n this.chainId,\n )\n\n const result = await this.bundler.sendUserOperation(signedUserOp)\n const sender = await this.signer.getAddress()\n\n return {\n userOpHash: result.userOpHash,\n sender,\n sponsored,\n wait: async (): Promise<GaslessPaymentReceipt> => {\n const receipt = await result.wait()\n return {\n userOpHash: receipt.userOpHash,\n txHash: receipt.receipt.transactionHash,\n blockNumber: receipt.receipt.blockNumber,\n success: receipt.success,\n gasUsed: receipt.actualGasUsed,\n gasCost: receipt.actualGasCost,\n reason: receipt.reason,\n }\n },\n }\n }\n\n /**\n * Check if a payment can be sponsored (free gas)\n */\n async canSponsor(params: GaslessPaymentParams): Promise<SponsorshipInfo> {\n if (!this.paymaster) {\n return {\n canSponsor: false,\n reason: 'No paymaster configured',\n }\n }\n\n const token = params.token ?? 'USDT0'\n const tokenAddress = getTokenAddress(token, this.chainName)\n\n const callData = encodeFunctionData({\n abi: ERC20_TRANSFER_ABI,\n functionName: 'transfer',\n args: [params.to, params.amount],\n })\n\n const sender = await this.signer.getAddress()\n const encodedCallData = this.signer.encodeExecute(tokenAddress, 0n, callData)\n\n try {\n const canSponsor = await this.paymaster.willSponsor(\n { sender, callData: encodedCallData },\n this.chainId,\n ENTRYPOINT_V07_ADDRESS,\n )\n\n if (canSponsor) {\n return { canSponsor: true }\n } else {\n // Estimate gas cost if not sponsored\n const intent: TransactionIntent = {\n to: tokenAddress,\n value: 0n,\n data: callData,\n }\n const gasEstimate = await this.estimateGas(intent)\n const gasPrice = await this.publicClient.getGasPrice()\n const estimatedGasCost =\n (gasEstimate.verificationGasLimit +\n gasEstimate.callGasLimit +\n gasEstimate.preVerificationGas) *\n gasPrice\n\n return {\n canSponsor: false,\n reason: 'Payment not eligible for sponsorship',\n estimatedGasCost,\n }\n }\n } catch (error) {\n return {\n canSponsor: false,\n reason: error instanceof Error ? error.message : 'Unknown error',\n }\n }\n }\n\n /**\n * Get the smart account address\n */\n async getAccountAddress(): Promise<Address> {\n return this.signer.getAddress()\n }\n\n /**\n * Check if the smart account is deployed\n */\n async isAccountDeployed(): Promise<boolean> {\n return this.signer.isDeployed()\n }\n\n /**\n * Get the token balance of the smart account\n */\n async getBalance(token: 'USDT0' | 'USDC' | Address = 'USDT0'): Promise<bigint> {\n const tokenAddress = getTokenAddress(token, this.chainName)\n const accountAddress = await this.signer.getAddress()\n\n const balance = await this.publicClient.readContract({\n address: tokenAddress,\n abi: ERC20_BALANCE_ABI,\n functionName: 'balanceOf',\n args: [accountAddress],\n })\n\n return balance as bigint\n }\n\n /**\n * Get the formatted token balance\n */\n async getFormattedBalance(\n token: 'USDT0' | 'USDC' | Address = 'USDT0',\n decimals = 6,\n ): Promise<string> {\n const balance = await this.getBalance(token)\n return formatUnits(balance, decimals)\n }\n\n /**\n * Estimate gas for a single transaction\n */\n private async estimateGas(intent: TransactionIntent): Promise<GasEstimate> {\n const sender = await this.signer.getAddress()\n const callData = this.signer.encodeExecute(intent.to, intent.value ?? 0n, intent.data ?? '0x')\n\n try {\n return await this.bundler.estimateUserOperationGas({\n sender,\n callData,\n })\n } catch {\n // Return defaults if estimation fails\n return {\n verificationGasLimit: 150000n,\n callGasLimit: 100000n,\n preVerificationGas: 50000n,\n }\n }\n }\n\n /**\n * Estimate gas for a batch transaction\n */\n private async estimateBatchGas(intents: TransactionIntent[]): Promise<GasEstimate> {\n const sender = await this.signer.getAddress()\n const callData = this.signer.encodeExecuteBatch(\n intents.map((i) => i.to),\n intents.map((i) => i.value ?? 0n),\n intents.map((i) => (i.data ?? '0x') as Hex),\n )\n\n try {\n return await this.bundler.estimateUserOperationGas({\n sender,\n callData,\n })\n } catch {\n // Return defaults with multiplier for batch size\n return {\n verificationGasLimit: 150000n,\n callGasLimit: 100000n * BigInt(intents.length),\n preVerificationGas: 50000n,\n }\n }\n }\n\n /**\n * Get paymaster data if configured\n */\n private async getPaymasterData(_gasEstimate: GasEstimate): Promise<PaymasterData | undefined> {\n if (!this.paymaster) return undefined\n\n const sender = await this.signer.getAddress()\n\n return this.paymaster.getPaymasterData({ sender }, this.chainId, ENTRYPOINT_V07_ADDRESS)\n }\n}\n\n/**\n * Configuration for creating a WDK gasless client\n */\nexport interface CreateWdkGaslessClientConfig {\n /** WDK account to use as the signer */\n wdkAccount: WdkAccount\n /** Public client for chain interactions */\n publicClient: PublicClient\n /** Chain ID */\n chainId: number\n /** Bundler configuration */\n bundler: BundlerConfig\n /** Optional paymaster for gas sponsorship */\n paymaster?: PaymasterConfig\n /** Salt nonce for address generation (defaults to 0) */\n saltNonce?: bigint\n}\n\n/**\n * Create a WDK gasless client\n *\n * This is the main entry point for using WDK with gasless payments.\n *\n * @example\n * ```typescript\n * import { createWdkGaslessClient } from '@t402/wdk-gasless';\n *\n * const client = await createWdkGaslessClient({\n * wdkAccount: myWdkAccount,\n * publicClient,\n * chainId: 42161, // Arbitrum\n * bundler: {\n * bundlerUrl: 'https://api.pimlico.io/v2/arbitrum/rpc?apikey=...',\n * chainId: 42161,\n * },\n * paymaster: {\n * address: '0x...',\n * url: 'https://api.pimlico.io/v2/arbitrum/rpc?apikey=...',\n * type: 'sponsoring',\n * },\n * });\n *\n * // Execute gasless payment\n * const result = await client.pay({\n * to: '0x...',\n * amount: 1000000n, // 1 USDT0\n * });\n *\n * const receipt = await result.wait();\n * console.log('Payment confirmed:', receipt.txHash);\n * ```\n */\nexport async function createWdkGaslessClient(\n config: CreateWdkGaslessClientConfig,\n): Promise<WdkGaslessClient> {\n // Create the WDK smart account\n const smartAccount = await createWdkSmartAccount({\n wdkAccount: config.wdkAccount,\n publicClient: config.publicClient,\n chainId: config.chainId,\n saltNonce: config.saltNonce,\n })\n\n // Create the gasless client\n return new WdkGaslessClient({\n signer: smartAccount,\n bundler: config.bundler,\n paymaster: config.paymaster,\n chainId: config.chainId,\n publicClient: config.publicClient,\n })\n}\n","/**\n * WDK Smart Account\n *\n * Wraps a Tether WDK account to work with ERC-4337 smart accounts.\n * Creates a Safe smart account with the WDK account as the owner/signer.\n */\n\nimport type { Address, Hex, PublicClient } from 'viem'\nimport {\n encodeFunctionData,\n encodeAbiParameters,\n concat,\n keccak256,\n getContractAddress,\n} from 'viem'\nimport type { SmartAccountSigner } from '@t402/evm'\nimport type { WdkAccount, WdkSmartAccountConfig } from './types.js'\n\n/**\n * Safe 4337 module addresses (v0.3.0)\n * Deployed on all major EVM chains at the same addresses\n */\nexport const SAFE_4337_ADDRESSES = {\n /** Safe 4337 Module */\n module: '0xa581c4A4DB7175302464fF3C06380BC3270b4037' as Address,\n /** Safe Module Setup */\n moduleSetup: '0x2dd68b007B46fBe91B9A7c3EDa5A7a1063cB5b47' as Address,\n /** Safe Singleton */\n singleton: '0x29fcB43b46531BcA003ddC8FCB67FFE91900C762' as Address,\n /** Safe Proxy Factory */\n proxyFactory: '0x4e1DCf7AD4e460CfD30791CCC4F9c8a4f820ec67' as Address,\n /** Safe Fallback Handler */\n fallbackHandler: '0xfd0732Dc9E303f09fCEf3a7388Ad10A83459Ec99' as Address,\n /** Add Modules Lib */\n addModulesLib: '0x8EcD4ec46D4D2a6B64fE960B3D64e8B94B2234eb' as Address,\n} as const\n\n/**\n * Safe Proxy Factory ABI\n */\nconst PROXY_FACTORY_ABI = [\n {\n inputs: [\n { name: 'singleton', type: 'address' },\n { name: 'initializer', type: 'bytes' },\n { name: 'saltNonce', type: 'uint256' },\n ],\n name: 'createProxyWithNonce',\n outputs: [{ name: 'proxy', type: 'address' }],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n inputs: [\n { name: 'singleton', type: 'address' },\n { name: 'initializer', type: 'bytes' },\n { name: 'saltNonce', type: 'uint256' },\n ],\n name: 'proxyCreationCode',\n outputs: [{ name: '', type: 'bytes' }],\n stateMutability: 'view',\n type: 'function',\n },\n] as const\n\n/**\n * Safe Singleton ABI\n */\nconst SAFE_ABI = [\n {\n inputs: [\n { name: 'owners', type: 'address[]' },\n { name: 'threshold', type: 'uint256' },\n { name: 'to', type: 'address' },\n { name: 'data', type: 'bytes' },\n { name: 'fallbackHandler', type: 'address' },\n { name: 'paymentToken', type: 'address' },\n { name: 'payment', type: 'uint256' },\n { name: 'paymentReceiver', type: 'address' },\n ],\n name: 'setup',\n outputs: [],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n] as const\n\n/**\n * Add Modules Lib ABI\n */\nconst ADD_MODULES_LIB_ABI = [\n {\n inputs: [{ name: 'modules', type: 'address[]' }],\n name: 'enableModules',\n outputs: [],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n] as const\n\n/**\n * Safe 4337 Module ABI\n */\nconst SAFE_4337_MODULE_ABI = [\n {\n inputs: [\n { name: 'to', type: 'address' },\n { name: 'value', type: 'uint256' },\n { name: 'data', type: 'bytes' },\n { name: 'operation', type: 'uint8' },\n ],\n name: 'executeUserOp',\n outputs: [],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n inputs: [\n { name: 'tos', type: 'address[]' },\n { name: 'values', type: 'uint256[]' },\n { name: 'datas', type: 'bytes[]' },\n { name: 'operations', type: 'uint8[]' },\n ],\n name: 'executeUserOpBatch',\n outputs: [],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n] as const\n\n/**\n * WDK Smart Account\n *\n * Creates a Safe smart account using a WDK account as the owner/signer.\n * Implements SmartAccountSigner for ERC-4337 compatibility.\n */\nexport class WdkSmartAccount implements SmartAccountSigner {\n private readonly wdkAccount: WdkAccount\n private readonly publicClient: PublicClient\n private readonly _chainId: number\n private readonly owners: Address[]\n private readonly threshold: number\n private readonly saltNonce: bigint\n\n private cachedAddress?: Address\n private cachedInitCode?: Hex\n private cachedOwnerAddress?: Address\n private deploymentChecked = false\n private isAccountDeployed = false\n\n constructor(config: WdkSmartAccountConfig) {\n this.wdkAccount = config.wdkAccount\n this.publicClient = config.publicClient\n this._chainId = config.chainId\n this.threshold = config.threshold ?? 1\n this.saltNonce = config.saltNonce ?? 0n\n\n // Owners will be set when we get the WDK account address\n this.owners = config.additionalOwners ?? []\n }\n\n /**\n * Initialize the account (fetch WDK address)\n * Call this before using the account\n */\n async initialize(): Promise<void> {\n if (!this.cachedOwnerAddress) {\n const address = await this.wdkAccount.getAddress()\n this.cachedOwnerAddress = address as Address\n\n // Add WDK account as the first owner if not already in owners\n if (!this.owners.includes(this.cachedOwnerAddress)) {\n this.owners.unshift(this.cachedOwnerAddress)\n }\n }\n }\n\n /**\n * Get the WDK account's EOA address\n */\n async getOwnerAddress(): Promise<Address> {\n await this.initialize()\n return this.cachedOwnerAddress!\n }\n\n /**\n * Get the chain ID\n */\n getChainId(): number {\n return this._chainId\n }\n\n /**\n * Get the smart account address (counterfactual)\n */\n async getAddress(): Promise<Address> {\n await this.initialize()\n\n if (this.cachedAddress) {\n return this.cachedAddress\n }\n\n const initCode = await this.getInitCode()\n\n // If already deployed, get address from code\n if (initCode === '0x') {\n // Need to compute it anyway for first time\n const initializerData = await this.buildInitializer()\n const salt = keccak256(\n encodeAbiParameters(\n [{ type: 'bytes32' }, { type: 'uint256' }],\n [keccak256(initializerData), this.saltNonce],\n ),\n )\n\n const proxyCreationCode = (await this.publicClient.readContract({\n address: SAFE_4337_ADDRESSES.proxyFactory,\n abi: PROXY_FACTORY_ABI,\n functionName: 'proxyCreationCode',\n args: [SAFE_4337_ADDRESSES.singleton, initializerData, this.saltNonce],\n })) as Hex\n\n this.cachedAddress = getContractAddress({\n bytecode: proxyCreationCode,\n from: SAFE_4337_ADDRESSES.proxyFactory,\n opcode: 'CREATE2',\n salt,\n })\n } else {\n // Extract initializer from init code\n const initializerData = `0x${initCode.slice(2 + 40 * 2)}` as Hex\n\n const salt = keccak256(\n encodeAbiParameters(\n [{ type: 'bytes32' }, { type: 'uint256' }],\n [keccak256(initializerData), this.saltNonce],\n ),\n )\n\n const proxyCreationCode = (await this.publicClient.readContract({\n address: SAFE_4337_ADDRESSES.proxyFactory,\n abi: PROXY_FACTORY_ABI,\n functionName: 'proxyCreationCode',\n args: [SAFE_4337_ADDRESSES.singleton, initializerData, this.saltNonce],\n })) as Hex\n\n this.cachedAddress = getContractAddress({\n bytecode: proxyCreationCode,\n from: SAFE_4337_ADDRESSES.proxyFactory,\n opcode: 'CREATE2',\n salt,\n })\n }\n\n return this.cachedAddress\n }\n\n /**\n * Sign a UserOperation hash using the WDK account\n */\n async signUserOpHash(userOpHash: Hex): Promise<Hex> {\n await this.initialize()\n\n // Sign the hash using WDK account's signMessage\n // The hash is signed as raw bytes (personal_sign format)\n const signature = await this.wdkAccount.signMessage(userOpHash)\n\n // Format signature for Safe (add signature type byte)\n // Type 0: EOA signature\n return concat([signature as Hex, '0x00']) as Hex\n }\n\n /**\n * Get the account's init code for deployment\n */\n async getInitCode(): Promise<Hex> {\n await this.initialize()\n\n // Check if already deployed\n if (await this.isDeployed()) {\n return '0x' as Hex\n }\n\n if (this.cachedInitCode) {\n return this.cachedInitCode\n }\n\n const safeSetupData = await this.buildInitializer()\n\n // Build factory call data\n const createProxyData = encodeFunctionData({\n abi: PROXY_FACTORY_ABI,\n functionName: 'createProxyWithNonce',\n args: [SAFE_4337_ADDRESSES.singleton, safeSetupData, this.saltNonce],\n })\n\n // Init code = factory address + factory call data\n this.cachedInitCode = concat([SAFE_4337_ADDRESSES.proxyFactory, createProxyData]) as Hex\n\n return this.cachedInitCode\n }\n\n /**\n * Check if the account is deployed\n */\n async isDeployed(): Promise<boolean> {\n if (this.deploymentChecked) {\n return this.isAccountDeployed\n }\n\n // Set flag early to break infinite recursion:\n // getAddress() → getInitCode() → isDeployed() → getAddress() → ...\n // Default assumption (not deployed) is correct for init code computation.\n this.deploymentChecked = true\n\n await this.initialize()\n const address = this.cachedAddress ?? (await this.getAddress())\n const code = await this.publicClient.getCode({ address })\n\n this.isAccountDeployed = code !== undefined && code !== '0x'\n\n return this.isAccountDeployed\n }\n\n /**\n * Encode a call to the account's execute function\n */\n encodeExecute(target: Address, value: bigint, data: Hex): Hex {\n return encodeFunctionData({\n abi: SAFE_4337_MODULE_ABI,\n functionName: 'executeUserOp',\n args: [target, value, data, 0], // operation: CALL\n })\n }\n\n /**\n * Encode a batch call to the account's executeBatch function\n */\n encodeExecuteBatch(targets: Address[], values: bigint[], datas: Hex[]): Hex {\n if (targets.length !== values.length || targets.length !== datas.length) {\n throw new Error('Array lengths must match')\n }\n\n const operations = targets.map(() => 0) // All CALL operations\n\n return encodeFunctionData({\n abi: SAFE_4337_MODULE_ABI,\n functionName: 'executeUserOpBatch',\n args: [targets, values, datas, operations],\n })\n }\n\n /**\n * Build the Safe setup initializer data\n */\n private async buildInitializer(): Promise<Hex> {\n await this.initialize()\n\n // Build Safe setup data with 4337 module\n const setupModulesData = encodeFunctionData({\n abi: ADD_MODULES_LIB_ABI,\n functionName: 'enableModules',\n args: [[SAFE_4337_ADDRESSES.module]],\n })\n\n return encodeFunctionData({\n abi: SAFE_ABI,\n functionName: 'setup',\n args: [\n this.owners,\n BigInt(this.threshold),\n SAFE_4337_ADDRESSES.addModulesLib, // to: AddModulesLib\n setupModulesData, // data: enableModules([module])\n SAFE_4337_ADDRESSES.fallbackHandler,\n '0x0000000000000000000000000000000000000000' as Address, // paymentToken\n 0n, // payment\n '0x0000000000000000000000000000000000000000' as Address, // paymentReceiver\n ],\n })\n }\n\n /**\n * Get the Safe's owners\n */\n getOwners(): Address[] {\n return [...this.owners]\n }\n\n /**\n * Get the Safe's threshold\n */\n getThreshold(): number {\n return this.threshold\n }\n\n /**\n * Clear cached values (useful after deployment)\n */\n clearCache(): void {\n this.cachedAddress = undefined\n this.cachedInitCode = undefined\n this.deploymentChecked = false\n this.isAccountDeployed = false\n }\n}\n\n/**\n * Create a WDK smart account\n */\nexport async function createWdkSmartAccount(\n config: WdkSmartAccountConfig,\n): Promise<WdkSmartAccount> {\n const account = new WdkSmartAccount(config)\n await account.initialize()\n return account\n}\n","/**\n * WDK Gasless Constants\n *\n * Addresses and configuration for gasless USDT0 payments.\n */\n\nimport type { Address } from 'viem'\n\n/**\n * USDT0 OFT addresses by chain\n */\nexport const USDT0_ADDRESSES: Record<string, Address> = {\n ethereum: '0x6C96dE32CEa08842dcc4058c14d3aaAD7Fa41dee',\n arbitrum: '0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9',\n ink: '0x0200C29006150606B650577BBE7B6248F58470c1',\n berachain: '0x779Ded0c9e1022225f8E0630b35a9b54bE713736',\n unichain: '0x9151434b16b9763660705744891fA906F660EcC5',\n base: '0x6C96dE32CEa08842dcc4058c14d3aaAD7Fa41dee',\n optimism: '0x6C96dE32CEa08842dcc4058c14d3aaAD7Fa41dee',\n} as const\n\n/**\n * USDC addresses by chain\n */\nexport const USDC_ADDRESSES: Record<string, Address> = {\n ethereum: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',\n arbitrum: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',\n base: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',\n optimism: '0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85',\n polygon: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',\n} as const\n\n/**\n * Chain IDs for supported networks\n */\nexport const CHAIN_IDS: Record<string, number> = {\n ethereum: 1,\n arbitrum: 42161,\n base: 8453,\n optimism: 10,\n polygon: 137,\n ink: 57073,\n berachain: 80094,\n unichain: 130,\n} as const\n\n/**\n * Default bundler URLs by chain (using public endpoints)\n */\nexport const DEFAULT_BUNDLER_URLS: Record<number, string> = {\n 1: 'https://api.pimlico.io/v2/ethereum/rpc',\n 42161: 'https://api.pimlico.io/v2/arbitrum/rpc',\n 8453: 'https://api.pimlico.io/v2/base/rpc',\n 10: 'https://api.pimlico.io/v2/optimism/rpc',\n 137: 'https://api.pimlico.io/v2/polygon/rpc',\n} as const\n\n/**\n * Get token address for a chain\n */\nexport function getTokenAddress(token: 'USDT0' | 'USDC' | Address, chainName: string): Address {\n if (token.startsWith('0x')) {\n return token as Address\n }\n\n const addresses = token === 'USDT0' ? USDT0_ADDRESSES : USDC_ADDRESSES\n const address = addresses[chainName.toLowerCase()]\n\n if (!address) {\n throw new Error(`Token ${token} not available on ${chainName}`)\n }\n\n return address\n}\n\n/**\n * Get chain name from chain ID\n */\nexport function getChainName(chainId: number): string {\n const entry = Object.entries(CHAIN_IDS).find(([, id]) => id === chainId)\n if (!entry) {\n throw new Error(`Unsupported chain ID: ${chainId}`)\n }\n return entry[0]\n}\n"],"mappings":"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","names":["import_viem"]}
|
package/dist/esm/index.d.mts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { PublicClient, Address, Hex } from 'viem';
|
|
2
2
|
import { SmartAccountSigner, BundlerConfig, PaymasterConfig } from '@t402/evm';
|
|
3
3
|
export { BundlerConfig, PaymasterConfig, SmartAccountSigner, UserOperationReceipt } from '@t402/evm';
|
|
4
|
+
import { WdkAccount } from '@t402/wdk';
|
|
5
|
+
export { WdkAccount } from '@t402/wdk';
|
|
4
6
|
|
|
5
7
|
/**
|
|
6
8
|
* WDK Gasless Types
|
|
@@ -9,41 +11,7 @@ export { BundlerConfig, PaymasterConfig, SmartAccountSigner, UserOperationReceip
|
|
|
9
11
|
*/
|
|
10
12
|
|
|
11
13
|
/**
|
|
12
|
-
* WDK
|
|
13
|
-
*/
|
|
14
|
-
interface WdkAccount {
|
|
15
|
-
/** Get the account's address */
|
|
16
|
-
getAddress(): Promise<string>;
|
|
17
|
-
/** Get the account's native balance */
|
|
18
|
-
getBalance(): Promise<bigint>;
|
|
19
|
-
/** Get the account's token balance */
|
|
20
|
-
getTokenBalance(tokenAddress: string): Promise<bigint>;
|
|
21
|
-
/** Sign a message */
|
|
22
|
-
signMessage(message: string): Promise<string>;
|
|
23
|
-
/** Sign typed data (EIP-712) */
|
|
24
|
-
signTypedData(params: {
|
|
25
|
-
domain: {
|
|
26
|
-
name?: string;
|
|
27
|
-
version?: string;
|
|
28
|
-
chainId?: number;
|
|
29
|
-
verifyingContract?: string;
|
|
30
|
-
};
|
|
31
|
-
types: Record<string, Array<{
|
|
32
|
-
name: string;
|
|
33
|
-
type: string;
|
|
34
|
-
}>>;
|
|
35
|
-
primaryType: string;
|
|
36
|
-
message: Record<string, unknown>;
|
|
37
|
-
}): Promise<string>;
|
|
38
|
-
/** Send a transaction */
|
|
39
|
-
sendTransaction(params: {
|
|
40
|
-
to: string;
|
|
41
|
-
value?: bigint;
|
|
42
|
-
data?: string;
|
|
43
|
-
}): Promise<string>;
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* WDK instance interface
|
|
14
|
+
* WDK instance interface (simplified wrapper for gasless context)
|
|
47
15
|
*/
|
|
48
16
|
interface WdkInstance {
|
|
49
17
|
/** Get accounts */
|
|
@@ -92,7 +60,7 @@ interface GaslessPaymentParams {
|
|
|
92
60
|
/** Amount to send (in token decimals, e.g., 1000000 for 1 USDT) */
|
|
93
61
|
amount: bigint;
|
|
94
62
|
/** Token to send (defaults to USDT0) */
|
|
95
|
-
token?:
|
|
63
|
+
token?: 'USDT0' | 'USDC' | Address;
|
|
96
64
|
}
|
|
97
65
|
/**
|
|
98
66
|
* Parameters for a batch payment
|
|
@@ -105,7 +73,7 @@ interface BatchPaymentParams {
|
|
|
105
73
|
/** Amount to send */
|
|
106
74
|
amount: bigint;
|
|
107
75
|
/** Token to send (defaults to USDT0) */
|
|
108
|
-
token?:
|
|
76
|
+
token?: 'USDT0' | 'USDC' | Address;
|
|
109
77
|
}>;
|
|
110
78
|
}
|
|
111
79
|
/**
|
|
@@ -205,11 +173,11 @@ declare class WdkGaslessClient {
|
|
|
205
173
|
/**
|
|
206
174
|
* Get the token balance of the smart account
|
|
207
175
|
*/
|
|
208
|
-
getBalance(token?:
|
|
176
|
+
getBalance(token?: 'USDT0' | 'USDC' | Address): Promise<bigint>;
|
|
209
177
|
/**
|
|
210
178
|
* Get the formatted token balance
|
|
211
179
|
*/
|
|
212
|
-
getFormattedBalance(token?:
|
|
180
|
+
getFormattedBalance(token?: 'USDT0' | 'USDC' | Address, decimals?: number): Promise<string>;
|
|
213
181
|
/**
|
|
214
182
|
* Estimate gas for a single transaction
|
|
215
183
|
*/
|
|
@@ -310,7 +278,7 @@ declare const SAFE_4337_ADDRESSES: {
|
|
|
310
278
|
declare class WdkSmartAccount implements SmartAccountSigner {
|
|
311
279
|
private readonly wdkAccount;
|
|
312
280
|
private readonly publicClient;
|
|
313
|
-
private readonly
|
|
281
|
+
private readonly _chainId;
|
|
314
282
|
private readonly owners;
|
|
315
283
|
private readonly threshold;
|
|
316
284
|
private readonly saltNonce;
|
|
@@ -329,6 +297,10 @@ declare class WdkSmartAccount implements SmartAccountSigner {
|
|
|
329
297
|
* Get the WDK account's EOA address
|
|
330
298
|
*/
|
|
331
299
|
getOwnerAddress(): Promise<Address>;
|
|
300
|
+
/**
|
|
301
|
+
* Get the chain ID
|
|
302
|
+
*/
|
|
303
|
+
getChainId(): number;
|
|
332
304
|
/**
|
|
333
305
|
* Get the smart account address (counterfactual)
|
|
334
306
|
*/
|
|
@@ -400,10 +372,10 @@ declare const DEFAULT_BUNDLER_URLS: Record<number, string>;
|
|
|
400
372
|
/**
|
|
401
373
|
* Get token address for a chain
|
|
402
374
|
*/
|
|
403
|
-
declare function getTokenAddress(token:
|
|
375
|
+
declare function getTokenAddress(token: 'USDT0' | 'USDC' | Address, chainName: string): Address;
|
|
404
376
|
/**
|
|
405
377
|
* Get chain name from chain ID
|
|
406
378
|
*/
|
|
407
379
|
declare function getChainName(chainId: number): string;
|
|
408
380
|
|
|
409
|
-
export { type BatchPaymentParams, CHAIN_IDS, type CreateWdkGaslessClientConfig, DEFAULT_BUNDLER_URLS, type GaslessPaymentParams, type GaslessPaymentReceipt, type GaslessPaymentResult, SAFE_4337_ADDRESSES, type SponsorshipInfo, USDC_ADDRESSES, USDT0_ADDRESSES,
|
|
381
|
+
export { type BatchPaymentParams, CHAIN_IDS, type CreateWdkGaslessClientConfig, DEFAULT_BUNDLER_URLS, type GaslessPaymentParams, type GaslessPaymentReceipt, type GaslessPaymentResult, SAFE_4337_ADDRESSES, type SponsorshipInfo, USDC_ADDRESSES, USDT0_ADDRESSES, WdkGaslessClient, type WdkGaslessClientConfig, type WdkInstance, WdkSmartAccount, type WdkSmartAccountConfig, createWdkGaslessClient, createWdkSmartAccount, getChainName, getTokenAddress };
|
package/dist/esm/index.mjs
CHANGED
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
// src/client.ts
|
|
2
2
|
import { encodeFunctionData as encodeFunctionData2, formatUnits } from "viem";
|
|
3
|
-
import {
|
|
4
|
-
BundlerClient,
|
|
5
|
-
PaymasterClient,
|
|
6
|
-
UserOpBuilder,
|
|
7
|
-
ENTRYPOINT_V07_ADDRESS
|
|
8
|
-
} from "@t402/evm";
|
|
3
|
+
import { BundlerClient, PaymasterClient, UserOpBuilder, ENTRYPOINT_V07_ADDRESS } from "@t402/evm";
|
|
9
4
|
|
|
10
5
|
// src/account.ts
|
|
11
6
|
import {
|
|
@@ -109,7 +104,7 @@ var SAFE_4337_MODULE_ABI = [
|
|
|
109
104
|
var WdkSmartAccount = class {
|
|
110
105
|
wdkAccount;
|
|
111
106
|
publicClient;
|
|
112
|
-
|
|
107
|
+
_chainId;
|
|
113
108
|
owners;
|
|
114
109
|
threshold;
|
|
115
110
|
saltNonce;
|
|
@@ -121,7 +116,7 @@ var WdkSmartAccount = class {
|
|
|
121
116
|
constructor(config) {
|
|
122
117
|
this.wdkAccount = config.wdkAccount;
|
|
123
118
|
this.publicClient = config.publicClient;
|
|
124
|
-
this.
|
|
119
|
+
this._chainId = config.chainId;
|
|
125
120
|
this.threshold = config.threshold ?? 1;
|
|
126
121
|
this.saltNonce = config.saltNonce ?? 0n;
|
|
127
122
|
this.owners = config.additionalOwners ?? [];
|
|
@@ -146,6 +141,12 @@ var WdkSmartAccount = class {
|
|
|
146
141
|
await this.initialize();
|
|
147
142
|
return this.cachedOwnerAddress;
|
|
148
143
|
}
|
|
144
|
+
/**
|
|
145
|
+
* Get the chain ID
|
|
146
|
+
*/
|
|
147
|
+
getChainId() {
|
|
148
|
+
return this._chainId;
|
|
149
|
+
}
|
|
149
150
|
/**
|
|
150
151
|
* Get the smart account address (counterfactual)
|
|
151
152
|
*/
|
|
@@ -223,10 +224,7 @@ var WdkSmartAccount = class {
|
|
|
223
224
|
functionName: "createProxyWithNonce",
|
|
224
225
|
args: [SAFE_4337_ADDRESSES.singleton, safeSetupData, this.saltNonce]
|
|
225
226
|
});
|
|
226
|
-
this.cachedInitCode = concat([
|
|
227
|
-
SAFE_4337_ADDRESSES.proxyFactory,
|
|
228
|
-
createProxyData
|
|
229
|
-
]);
|
|
227
|
+
this.cachedInitCode = concat([SAFE_4337_ADDRESSES.proxyFactory, createProxyData]);
|
|
230
228
|
return this.cachedInitCode;
|
|
231
229
|
}
|
|
232
230
|
/**
|
|
@@ -236,10 +234,10 @@ var WdkSmartAccount = class {
|
|
|
236
234
|
if (this.deploymentChecked) {
|
|
237
235
|
return this.isAccountDeployed;
|
|
238
236
|
}
|
|
237
|
+
this.deploymentChecked = true;
|
|
239
238
|
await this.initialize();
|
|
240
239
|
const address = this.cachedAddress ?? await this.getAddress();
|
|
241
240
|
const code = await this.publicClient.getCode({ address });
|
|
242
|
-
this.deploymentChecked = true;
|
|
243
241
|
this.isAccountDeployed = code !== void 0 && code !== "0x";
|
|
244
242
|
return this.isAccountDeployed;
|
|
245
243
|
}
|
|
@@ -332,7 +330,7 @@ var USDT0_ADDRESSES = {
|
|
|
332
330
|
arbitrum: "0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9",
|
|
333
331
|
ink: "0x0200C29006150606B650577BBE7B6248F58470c1",
|
|
334
332
|
berachain: "0x779Ded0c9e1022225f8E0630b35a9b54bE713736",
|
|
335
|
-
unichain: "
|
|
333
|
+
unichain: "0x9151434b16b9763660705744891fA906F660EcC5",
|
|
336
334
|
base: "0x6C96dE32CEa08842dcc4058c14d3aaAD7Fa41dee",
|
|
337
335
|
optimism: "0x6C96dE32CEa08842dcc4058c14d3aaAD7Fa41dee"
|
|
338
336
|
};
|
|
@@ -350,7 +348,7 @@ var CHAIN_IDS = {
|
|
|
350
348
|
optimism: 10,
|
|
351
349
|
polygon: 137,
|
|
352
350
|
ink: 57073,
|
|
353
|
-
berachain:
|
|
351
|
+
berachain: 80094,
|
|
354
352
|
unichain: 130
|
|
355
353
|
};
|
|
356
354
|
var DEFAULT_BUNDLER_URLS = {
|
|
@@ -425,6 +423,12 @@ var WdkGaslessClient = class {
|
|
|
425
423
|
* Gas is sponsored by a paymaster if configured.
|
|
426
424
|
*/
|
|
427
425
|
async pay(params) {
|
|
426
|
+
if (!params.to || params.to === "0x0000000000000000000000000000000000000000") {
|
|
427
|
+
throw new Error("Recipient address must not be the zero address");
|
|
428
|
+
}
|
|
429
|
+
if (params.amount <= 0n) {
|
|
430
|
+
throw new Error("Payment amount must be greater than zero");
|
|
431
|
+
}
|
|
428
432
|
const token = params.token ?? "USDT0";
|
|
429
433
|
const tokenAddress = getTokenAddress(token, this.chainName);
|
|
430
434
|
const callData = encodeFunctionData2({
|
|
@@ -480,6 +484,20 @@ var WdkGaslessClient = class {
|
|
|
480
484
|
* All payments are executed atomically.
|
|
481
485
|
*/
|
|
482
486
|
async payBatch(params) {
|
|
487
|
+
if (!params.payments || params.payments.length === 0) {
|
|
488
|
+
throw new Error("Batch payments must contain at least one payment");
|
|
489
|
+
}
|
|
490
|
+
if (params.payments.length > 50) {
|
|
491
|
+
throw new Error("Batch payments must not exceed 50 payments");
|
|
492
|
+
}
|
|
493
|
+
for (const payment of params.payments) {
|
|
494
|
+
if (!payment.to || payment.to === "0x0000000000000000000000000000000000000000") {
|
|
495
|
+
throw new Error("Recipient address must not be the zero address");
|
|
496
|
+
}
|
|
497
|
+
if (payment.amount <= 0n) {
|
|
498
|
+
throw new Error("Payment amount must be greater than zero");
|
|
499
|
+
}
|
|
500
|
+
}
|
|
483
501
|
const intents = params.payments.map((payment) => {
|
|
484
502
|
const token = payment.token ?? "USDT0";
|
|
485
503
|
const tokenAddress = getTokenAddress(token, this.chainName);
|
|
@@ -616,11 +634,7 @@ var WdkGaslessClient = class {
|
|
|
616
634
|
*/
|
|
617
635
|
async estimateGas(intent) {
|
|
618
636
|
const sender = await this.signer.getAddress();
|
|
619
|
-
const callData = this.signer.encodeExecute(
|
|
620
|
-
intent.to,
|
|
621
|
-
intent.value ?? 0n,
|
|
622
|
-
intent.data ?? "0x"
|
|
623
|
-
);
|
|
637
|
+
const callData = this.signer.encodeExecute(intent.to, intent.value ?? 0n, intent.data ?? "0x");
|
|
624
638
|
try {
|
|
625
639
|
return await this.bundler.estimateUserOperationGas({
|
|
626
640
|
sender,
|
|
@@ -663,11 +677,7 @@ var WdkGaslessClient = class {
|
|
|
663
677
|
async getPaymasterData(_gasEstimate) {
|
|
664
678
|
if (!this.paymaster) return void 0;
|
|
665
679
|
const sender = await this.signer.getAddress();
|
|
666
|
-
return this.paymaster.getPaymasterData(
|
|
667
|
-
{ sender },
|
|
668
|
-
this.chainId,
|
|
669
|
-
ENTRYPOINT_V07_ADDRESS
|
|
670
|
-
);
|
|
680
|
+
return this.paymaster.getPaymasterData({ sender }, this.chainId, ENTRYPOINT_V07_ADDRESS);
|
|
671
681
|
}
|
|
672
682
|
};
|
|
673
683
|
async function createWdkGaslessClient(config) {
|
package/dist/esm/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/client.ts","../../src/account.ts","../../src/constants.ts"],"sourcesContent":["/**\n * WDK Gasless Client\n *\n * High-level client for executing gasless USDT0 payments using\n * Tether WDK accounts and ERC-4337 Account Abstraction.\n */\n\nimport type { Address, Hex, PublicClient } from \"viem\";\nimport { encodeFunctionData, parseUnits, formatUnits } from \"viem\";\nimport {\n BundlerClient,\n PaymasterClient,\n UserOpBuilder,\n ENTRYPOINT_V07_ADDRESS,\n} from \"@t402/evm\";\nimport type {\n SmartAccountSigner,\n BundlerConfig,\n PaymasterConfig,\n TransactionIntent,\n GasEstimate,\n PaymasterData,\n} from \"@t402/evm\";\nimport type {\n WdkGaslessClientConfig,\n GaslessPaymentParams,\n BatchPaymentParams,\n GaslessPaymentResult,\n GaslessPaymentReceipt,\n SponsorshipInfo,\n WdkAccount,\n} from \"./types.js\";\nimport { WdkSmartAccount, createWdkSmartAccount } from \"./account.js\";\nimport { getTokenAddress, getChainName } from \"./constants.js\";\n\n/**\n * ERC20 transfer ABI\n */\nconst ERC20_TRANSFER_ABI = [\n {\n inputs: [\n { name: \"to\", type: \"address\" },\n { name: \"amount\", type: \"uint256\" },\n ],\n name: \"transfer\",\n outputs: [{ name: \"\", type: \"bool\" }],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n] as const;\n\n/**\n * ERC20 balanceOf ABI\n */\nconst ERC20_BALANCE_ABI = [\n {\n inputs: [{ name: \"account\", type: \"address\" }],\n name: \"balanceOf\",\n outputs: [{ name: \"\", type: \"uint256\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n] as const;\n\n/**\n * WDK Gasless Client\n *\n * Provides a simple API for executing gasless USDT0 payments using\n * WDK accounts and ERC-4337 smart accounts.\n */\nexport class WdkGaslessClient {\n private readonly signer: SmartAccountSigner;\n private readonly builder: UserOpBuilder;\n private readonly bundler: BundlerClient;\n private readonly paymaster?: PaymasterClient;\n private readonly chainId: number;\n private readonly publicClient: PublicClient;\n private readonly chainName: string;\n\n constructor(config: WdkGaslessClientConfig) {\n this.signer = config.signer;\n this.builder = new UserOpBuilder();\n this.bundler = new BundlerClient(config.bundler);\n this.paymaster = config.paymaster\n ? new PaymasterClient(config.paymaster)\n : undefined;\n this.chainId = config.chainId;\n this.publicClient = config.publicClient;\n this.chainName = getChainName(config.chainId);\n }\n\n /**\n * Execute a gasless payment\n *\n * Sends USDT0 (or other tokens) without the user paying gas fees.\n * Gas is sponsored by a paymaster if configured.\n */\n async pay(params: GaslessPaymentParams): Promise<GaslessPaymentResult> {\n const token = params.token ?? \"USDT0\";\n const tokenAddress = getTokenAddress(token, this.chainName);\n\n // Build the transfer call data\n const callData = encodeFunctionData({\n abi: ERC20_TRANSFER_ABI,\n functionName: \"transfer\",\n args: [params.to, params.amount],\n });\n\n // Create the transaction intent\n const intent: TransactionIntent = {\n to: tokenAddress,\n value: 0n,\n data: callData,\n };\n\n // Estimate gas\n const gasEstimate = await this.estimateGas(intent);\n\n // Get paymaster data if configured\n const paymasterData = await this.getPaymasterData(gasEstimate);\n const sponsored = paymasterData !== undefined;\n\n // Build the UserOperation\n const userOp = await this.builder.buildUserOp(\n this.signer,\n intent,\n this.publicClient,\n gasEstimate,\n paymasterData,\n );\n\n // Sign the UserOperation\n const signedUserOp = await this.builder.signUserOp(\n userOp,\n this.signer,\n this.publicClient,\n this.chainId,\n );\n\n // Submit to bundler\n const result = await this.bundler.sendUserOperation(signedUserOp);\n const sender = await this.signer.getAddress();\n\n return {\n userOpHash: result.userOpHash,\n sender,\n sponsored,\n wait: async (): Promise<GaslessPaymentReceipt> => {\n const receipt = await result.wait();\n return {\n userOpHash: receipt.userOpHash,\n txHash: receipt.receipt.transactionHash,\n blockNumber: receipt.receipt.blockNumber,\n success: receipt.success,\n gasUsed: receipt.actualGasUsed,\n gasCost: receipt.actualGasCost,\n reason: receipt.reason,\n };\n },\n };\n }\n\n /**\n * Execute multiple payments in a single transaction\n *\n * More gas efficient than individual payments.\n * All payments are executed atomically.\n */\n async payBatch(params: BatchPaymentParams): Promise<GaslessPaymentResult> {\n // Build transaction intents for all payments\n const intents: TransactionIntent[] = params.payments.map((payment) => {\n const token = payment.token ?? \"USDT0\";\n const tokenAddress = getTokenAddress(token, this.chainName);\n\n return {\n to: tokenAddress,\n value: 0n,\n data: encodeFunctionData({\n abi: ERC20_TRANSFER_ABI,\n functionName: \"transfer\",\n args: [payment.to, payment.amount],\n }),\n };\n });\n\n // Estimate gas for batch\n const gasEstimate = await this.estimateBatchGas(intents);\n\n // Get paymaster data\n const paymasterData = await this.getPaymasterData(gasEstimate);\n const sponsored = paymasterData !== undefined;\n\n // Build batch UserOperation\n const userOp = await this.builder.buildBatchUserOp(\n this.signer,\n intents,\n this.publicClient,\n gasEstimate,\n paymasterData,\n );\n\n // Sign and submit\n const signedUserOp = await this.builder.signUserOp(\n userOp,\n this.signer,\n this.publicClient,\n this.chainId,\n );\n\n const result = await this.bundler.sendUserOperation(signedUserOp);\n const sender = await this.signer.getAddress();\n\n return {\n userOpHash: result.userOpHash,\n sender,\n sponsored,\n wait: async (): Promise<GaslessPaymentReceipt> => {\n const receipt = await result.wait();\n return {\n userOpHash: receipt.userOpHash,\n txHash: receipt.receipt.transactionHash,\n blockNumber: receipt.receipt.blockNumber,\n success: receipt.success,\n gasUsed: receipt.actualGasUsed,\n gasCost: receipt.actualGasCost,\n reason: receipt.reason,\n };\n },\n };\n }\n\n /**\n * Check if a payment can be sponsored (free gas)\n */\n async canSponsor(params: GaslessPaymentParams): Promise<SponsorshipInfo> {\n if (!this.paymaster) {\n return {\n canSponsor: false,\n reason: \"No paymaster configured\",\n };\n }\n\n const token = params.token ?? \"USDT0\";\n const tokenAddress = getTokenAddress(token, this.chainName);\n\n const callData = encodeFunctionData({\n abi: ERC20_TRANSFER_ABI,\n functionName: \"transfer\",\n args: [params.to, params.amount],\n });\n\n const sender = await this.signer.getAddress();\n const encodedCallData = this.signer.encodeExecute(tokenAddress, 0n, callData);\n\n try {\n const canSponsor = await this.paymaster.willSponsor(\n { sender, callData: encodedCallData },\n this.chainId,\n ENTRYPOINT_V07_ADDRESS,\n );\n\n if (canSponsor) {\n return { canSponsor: true };\n } else {\n // Estimate gas cost if not sponsored\n const intent: TransactionIntent = {\n to: tokenAddress,\n value: 0n,\n data: callData,\n };\n const gasEstimate = await this.estimateGas(intent);\n const gasPrice = await this.publicClient.getGasPrice();\n const estimatedGasCost =\n (gasEstimate.verificationGasLimit +\n gasEstimate.callGasLimit +\n gasEstimate.preVerificationGas) *\n gasPrice;\n\n return {\n canSponsor: false,\n reason: \"Payment not eligible for sponsorship\",\n estimatedGasCost,\n };\n }\n } catch (error) {\n return {\n canSponsor: false,\n reason: error instanceof Error ? error.message : \"Unknown error\",\n };\n }\n }\n\n /**\n * Get the smart account address\n */\n async getAccountAddress(): Promise<Address> {\n return this.signer.getAddress();\n }\n\n /**\n * Check if the smart account is deployed\n */\n async isAccountDeployed(): Promise<boolean> {\n return this.signer.isDeployed();\n }\n\n /**\n * Get the token balance of the smart account\n */\n async getBalance(token: \"USDT0\" | \"USDC\" | Address = \"USDT0\"): Promise<bigint> {\n const tokenAddress = getTokenAddress(token, this.chainName);\n const accountAddress = await this.signer.getAddress();\n\n const balance = await this.publicClient.readContract({\n address: tokenAddress,\n abi: ERC20_BALANCE_ABI,\n functionName: \"balanceOf\",\n args: [accountAddress],\n });\n\n return balance as bigint;\n }\n\n /**\n * Get the formatted token balance\n */\n async getFormattedBalance(\n token: \"USDT0\" | \"USDC\" | Address = \"USDT0\",\n decimals = 6,\n ): Promise<string> {\n const balance = await this.getBalance(token);\n return formatUnits(balance, decimals);\n }\n\n /**\n * Estimate gas for a single transaction\n */\n private async estimateGas(intent: TransactionIntent): Promise<GasEstimate> {\n const sender = await this.signer.getAddress();\n const callData = this.signer.encodeExecute(\n intent.to,\n intent.value ?? 0n,\n intent.data ?? \"0x\",\n );\n\n try {\n return await this.bundler.estimateUserOperationGas({\n sender,\n callData,\n });\n } catch {\n // Return defaults if estimation fails\n return {\n verificationGasLimit: 150000n,\n callGasLimit: 100000n,\n preVerificationGas: 50000n,\n };\n }\n }\n\n /**\n * Estimate gas for a batch transaction\n */\n private async estimateBatchGas(\n intents: TransactionIntent[],\n ): Promise<GasEstimate> {\n const sender = await this.signer.getAddress();\n const callData = this.signer.encodeExecuteBatch(\n intents.map((i) => i.to),\n intents.map((i) => i.value ?? 0n),\n intents.map((i) => (i.data ?? \"0x\") as Hex),\n );\n\n try {\n return await this.bundler.estimateUserOperationGas({\n sender,\n callData,\n });\n } catch {\n // Return defaults with multiplier for batch size\n return {\n verificationGasLimit: 150000n,\n callGasLimit: 100000n * BigInt(intents.length),\n preVerificationGas: 50000n,\n };\n }\n }\n\n /**\n * Get paymaster data if configured\n */\n private async getPaymasterData(\n _gasEstimate: GasEstimate,\n ): Promise<PaymasterData | undefined> {\n if (!this.paymaster) return undefined;\n\n const sender = await this.signer.getAddress();\n\n return this.paymaster.getPaymasterData(\n { sender },\n this.chainId,\n ENTRYPOINT_V07_ADDRESS,\n );\n }\n}\n\n/**\n * Configuration for creating a WDK gasless client\n */\nexport interface CreateWdkGaslessClientConfig {\n /** WDK account to use as the signer */\n wdkAccount: WdkAccount;\n /** Public client for chain interactions */\n publicClient: PublicClient;\n /** Chain ID */\n chainId: number;\n /** Bundler configuration */\n bundler: BundlerConfig;\n /** Optional paymaster for gas sponsorship */\n paymaster?: PaymasterConfig;\n /** Salt nonce for address generation (defaults to 0) */\n saltNonce?: bigint;\n}\n\n/**\n * Create a WDK gasless client\n *\n * This is the main entry point for using WDK with gasless payments.\n *\n * @example\n * ```typescript\n * import { createWdkGaslessClient } from '@t402/wdk-gasless';\n *\n * const client = await createWdkGaslessClient({\n * wdkAccount: myWdkAccount,\n * publicClient,\n * chainId: 42161, // Arbitrum\n * bundler: {\n * bundlerUrl: 'https://api.pimlico.io/v2/arbitrum/rpc?apikey=...',\n * chainId: 42161,\n * },\n * paymaster: {\n * address: '0x...',\n * url: 'https://api.pimlico.io/v2/arbitrum/rpc?apikey=...',\n * type: 'sponsoring',\n * },\n * });\n *\n * // Execute gasless payment\n * const result = await client.pay({\n * to: '0x...',\n * amount: 1000000n, // 1 USDT0\n * });\n *\n * const receipt = await result.wait();\n * console.log('Payment confirmed:', receipt.txHash);\n * ```\n */\nexport async function createWdkGaslessClient(\n config: CreateWdkGaslessClientConfig,\n): Promise<WdkGaslessClient> {\n // Create the WDK smart account\n const smartAccount = await createWdkSmartAccount({\n wdkAccount: config.wdkAccount,\n publicClient: config.publicClient,\n chainId: config.chainId,\n saltNonce: config.saltNonce,\n });\n\n // Create the gasless client\n return new WdkGaslessClient({\n signer: smartAccount,\n bundler: config.bundler,\n paymaster: config.paymaster,\n chainId: config.chainId,\n publicClient: config.publicClient,\n });\n}\n","/**\n * WDK Smart Account\n *\n * Wraps a Tether WDK account to work with ERC-4337 smart accounts.\n * Creates a Safe smart account with the WDK account as the owner/signer.\n */\n\nimport type { Address, Hex, PublicClient } from \"viem\";\nimport {\n encodeFunctionData,\n encodeAbiParameters,\n concat,\n keccak256,\n getContractAddress,\n hexToBytes,\n createWalletClient,\n http,\n custom,\n} from \"viem\";\nimport type { SmartAccountSigner } from \"@t402/evm\";\nimport type { WdkAccount, WdkSmartAccountConfig } from \"./types.js\";\n\n/**\n * Safe 4337 module addresses (v0.3.0)\n * Deployed on all major EVM chains at the same addresses\n */\nexport const SAFE_4337_ADDRESSES = {\n /** Safe 4337 Module */\n module: \"0xa581c4A4DB7175302464fF3C06380BC3270b4037\" as Address,\n /** Safe Module Setup */\n moduleSetup: \"0x2dd68b007B46fBe91B9A7c3EDa5A7a1063cB5b47\" as Address,\n /** Safe Singleton */\n singleton: \"0x29fcB43b46531BcA003ddC8FCB67FFE91900C762\" as Address,\n /** Safe Proxy Factory */\n proxyFactory: \"0x4e1DCf7AD4e460CfD30791CCC4F9c8a4f820ec67\" as Address,\n /** Safe Fallback Handler */\n fallbackHandler: \"0xfd0732Dc9E303f09fCEf3a7388Ad10A83459Ec99\" as Address,\n /** Add Modules Lib */\n addModulesLib: \"0x8EcD4ec46D4D2a6B64fE960B3D64e8B94B2234eb\" as Address,\n} as const;\n\n/**\n * Safe Proxy Factory ABI\n */\nconst PROXY_FACTORY_ABI = [\n {\n inputs: [\n { name: \"singleton\", type: \"address\" },\n { name: \"initializer\", type: \"bytes\" },\n { name: \"saltNonce\", type: \"uint256\" },\n ],\n name: \"createProxyWithNonce\",\n outputs: [{ name: \"proxy\", type: \"address\" }],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [\n { name: \"singleton\", type: \"address\" },\n { name: \"initializer\", type: \"bytes\" },\n { name: \"saltNonce\", type: \"uint256\" },\n ],\n name: \"proxyCreationCode\",\n outputs: [{ name: \"\", type: \"bytes\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n] as const;\n\n/**\n * Safe Singleton ABI\n */\nconst SAFE_ABI = [\n {\n inputs: [\n { name: \"owners\", type: \"address[]\" },\n { name: \"threshold\", type: \"uint256\" },\n { name: \"to\", type: \"address\" },\n { name: \"data\", type: \"bytes\" },\n { name: \"fallbackHandler\", type: \"address\" },\n { name: \"paymentToken\", type: \"address\" },\n { name: \"payment\", type: \"uint256\" },\n { name: \"paymentReceiver\", type: \"address\" },\n ],\n name: \"setup\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n] as const;\n\n/**\n * Add Modules Lib ABI\n */\nconst ADD_MODULES_LIB_ABI = [\n {\n inputs: [{ name: \"modules\", type: \"address[]\" }],\n name: \"enableModules\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n] as const;\n\n/**\n * Safe 4337 Module ABI\n */\nconst SAFE_4337_MODULE_ABI = [\n {\n inputs: [\n { name: \"to\", type: \"address\" },\n { name: \"value\", type: \"uint256\" },\n { name: \"data\", type: \"bytes\" },\n { name: \"operation\", type: \"uint8\" },\n ],\n name: \"executeUserOp\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [\n { name: \"tos\", type: \"address[]\" },\n { name: \"values\", type: \"uint256[]\" },\n { name: \"datas\", type: \"bytes[]\" },\n { name: \"operations\", type: \"uint8[]\" },\n ],\n name: \"executeUserOpBatch\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n] as const;\n\n/**\n * WDK Smart Account\n *\n * Creates a Safe smart account using a WDK account as the owner/signer.\n * Implements SmartAccountSigner for ERC-4337 compatibility.\n */\nexport class WdkSmartAccount implements SmartAccountSigner {\n private readonly wdkAccount: WdkAccount;\n private readonly publicClient: PublicClient;\n private readonly chainId: number;\n private readonly owners: Address[];\n private readonly threshold: number;\n private readonly saltNonce: bigint;\n\n private cachedAddress?: Address;\n private cachedInitCode?: Hex;\n private cachedOwnerAddress?: Address;\n private deploymentChecked = false;\n private isAccountDeployed = false;\n\n constructor(config: WdkSmartAccountConfig) {\n this.wdkAccount = config.wdkAccount;\n this.publicClient = config.publicClient;\n this.chainId = config.chainId;\n this.threshold = config.threshold ?? 1;\n this.saltNonce = config.saltNonce ?? 0n;\n\n // Owners will be set when we get the WDK account address\n this.owners = config.additionalOwners ?? [];\n }\n\n /**\n * Initialize the account (fetch WDK address)\n * Call this before using the account\n */\n async initialize(): Promise<void> {\n if (!this.cachedOwnerAddress) {\n const address = await this.wdkAccount.getAddress();\n this.cachedOwnerAddress = address as Address;\n\n // Add WDK account as the first owner if not already in owners\n if (!this.owners.includes(this.cachedOwnerAddress)) {\n this.owners.unshift(this.cachedOwnerAddress);\n }\n }\n }\n\n /**\n * Get the WDK account's EOA address\n */\n async getOwnerAddress(): Promise<Address> {\n await this.initialize();\n return this.cachedOwnerAddress!;\n }\n\n /**\n * Get the smart account address (counterfactual)\n */\n async getAddress(): Promise<Address> {\n await this.initialize();\n\n if (this.cachedAddress) {\n return this.cachedAddress;\n }\n\n const initCode = await this.getInitCode();\n\n // If already deployed, get address from code\n if (initCode === \"0x\") {\n // Need to compute it anyway for first time\n const initializerData = await this.buildInitializer();\n const salt = keccak256(\n encodeAbiParameters(\n [{ type: \"bytes32\" }, { type: \"uint256\" }],\n [keccak256(initializerData), this.saltNonce],\n ),\n );\n\n const proxyCreationCode = (await this.publicClient.readContract({\n address: SAFE_4337_ADDRESSES.proxyFactory,\n abi: PROXY_FACTORY_ABI,\n functionName: \"proxyCreationCode\",\n args: [SAFE_4337_ADDRESSES.singleton, initializerData, this.saltNonce],\n })) as Hex;\n\n this.cachedAddress = getContractAddress({\n bytecode: proxyCreationCode,\n from: SAFE_4337_ADDRESSES.proxyFactory,\n opcode: \"CREATE2\",\n salt,\n });\n } else {\n // Extract initializer from init code\n const initializerData = `0x${initCode.slice(2 + 40 * 2)}` as Hex;\n\n const salt = keccak256(\n encodeAbiParameters(\n [{ type: \"bytes32\" }, { type: \"uint256\" }],\n [keccak256(initializerData), this.saltNonce],\n ),\n );\n\n const proxyCreationCode = (await this.publicClient.readContract({\n address: SAFE_4337_ADDRESSES.proxyFactory,\n abi: PROXY_FACTORY_ABI,\n functionName: \"proxyCreationCode\",\n args: [SAFE_4337_ADDRESSES.singleton, initializerData, this.saltNonce],\n })) as Hex;\n\n this.cachedAddress = getContractAddress({\n bytecode: proxyCreationCode,\n from: SAFE_4337_ADDRESSES.proxyFactory,\n opcode: \"CREATE2\",\n salt,\n });\n }\n\n return this.cachedAddress;\n }\n\n /**\n * Sign a UserOperation hash using the WDK account\n */\n async signUserOpHash(userOpHash: Hex): Promise<Hex> {\n await this.initialize();\n\n // Sign the hash using WDK account's signMessage\n // The hash is signed as raw bytes (personal_sign format)\n const signature = await this.wdkAccount.signMessage(userOpHash);\n\n // Format signature for Safe (add signature type byte)\n // Type 0: EOA signature\n return concat([signature as Hex, \"0x00\"]) as Hex;\n }\n\n /**\n * Get the account's init code for deployment\n */\n async getInitCode(): Promise<Hex> {\n await this.initialize();\n\n // Check if already deployed\n if (await this.isDeployed()) {\n return \"0x\" as Hex;\n }\n\n if (this.cachedInitCode) {\n return this.cachedInitCode;\n }\n\n const safeSetupData = await this.buildInitializer();\n\n // Build factory call data\n const createProxyData = encodeFunctionData({\n abi: PROXY_FACTORY_ABI,\n functionName: \"createProxyWithNonce\",\n args: [SAFE_4337_ADDRESSES.singleton, safeSetupData, this.saltNonce],\n });\n\n // Init code = factory address + factory call data\n this.cachedInitCode = concat([\n SAFE_4337_ADDRESSES.proxyFactory,\n createProxyData,\n ]) as Hex;\n\n return this.cachedInitCode;\n }\n\n /**\n * Check if the account is deployed\n */\n async isDeployed(): Promise<boolean> {\n if (this.deploymentChecked) {\n return this.isAccountDeployed;\n }\n\n await this.initialize();\n const address = this.cachedAddress ?? (await this.getAddress());\n const code = await this.publicClient.getCode({ address });\n\n this.deploymentChecked = true;\n this.isAccountDeployed = code !== undefined && code !== \"0x\";\n\n return this.isAccountDeployed;\n }\n\n /**\n * Encode a call to the account's execute function\n */\n encodeExecute(target: Address, value: bigint, data: Hex): Hex {\n return encodeFunctionData({\n abi: SAFE_4337_MODULE_ABI,\n functionName: \"executeUserOp\",\n args: [target, value, data, 0], // operation: CALL\n });\n }\n\n /**\n * Encode a batch call to the account's executeBatch function\n */\n encodeExecuteBatch(targets: Address[], values: bigint[], datas: Hex[]): Hex {\n if (targets.length !== values.length || targets.length !== datas.length) {\n throw new Error(\"Array lengths must match\");\n }\n\n const operations = targets.map(() => 0); // All CALL operations\n\n return encodeFunctionData({\n abi: SAFE_4337_MODULE_ABI,\n functionName: \"executeUserOpBatch\",\n args: [targets, values, datas, operations],\n });\n }\n\n /**\n * Build the Safe setup initializer data\n */\n private async buildInitializer(): Promise<Hex> {\n await this.initialize();\n\n // Build Safe setup data with 4337 module\n const setupModulesData = encodeFunctionData({\n abi: ADD_MODULES_LIB_ABI,\n functionName: \"enableModules\",\n args: [[SAFE_4337_ADDRESSES.module]],\n });\n\n return encodeFunctionData({\n abi: SAFE_ABI,\n functionName: \"setup\",\n args: [\n this.owners,\n BigInt(this.threshold),\n SAFE_4337_ADDRESSES.addModulesLib, // to: AddModulesLib\n setupModulesData, // data: enableModules([module])\n SAFE_4337_ADDRESSES.fallbackHandler,\n \"0x0000000000000000000000000000000000000000\" as Address, // paymentToken\n 0n, // payment\n \"0x0000000000000000000000000000000000000000\" as Address, // paymentReceiver\n ],\n });\n }\n\n /**\n * Get the Safe's owners\n */\n getOwners(): Address[] {\n return [...this.owners];\n }\n\n /**\n * Get the Safe's threshold\n */\n getThreshold(): number {\n return this.threshold;\n }\n\n /**\n * Clear cached values (useful after deployment)\n */\n clearCache(): void {\n this.cachedAddress = undefined;\n this.cachedInitCode = undefined;\n this.deploymentChecked = false;\n this.isAccountDeployed = false;\n }\n}\n\n/**\n * Create a WDK smart account\n */\nexport async function createWdkSmartAccount(\n config: WdkSmartAccountConfig,\n): Promise<WdkSmartAccount> {\n const account = new WdkSmartAccount(config);\n await account.initialize();\n return account;\n}\n","/**\n * WDK Gasless Constants\n *\n * Addresses and configuration for gasless USDT0 payments.\n */\n\nimport type { Address } from \"viem\";\n\n/**\n * USDT0 OFT addresses by chain\n */\nexport const USDT0_ADDRESSES: Record<string, Address> = {\n ethereum: \"0x6C96dE32CEa08842dcc4058c14d3aaAD7Fa41dee\",\n arbitrum: \"0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9\",\n ink: \"0x0200C29006150606B650577BBE7B6248F58470c1\",\n berachain: \"0x779Ded0c9e1022225f8E0630b35a9b54bE713736\",\n unichain: \"0x588ce4F028D8e7B53B687865d6A67b3A54C75518\",\n base: \"0x6C96dE32CEa08842dcc4058c14d3aaAD7Fa41dee\",\n optimism: \"0x6C96dE32CEa08842dcc4058c14d3aaAD7Fa41dee\",\n} as const;\n\n/**\n * USDC addresses by chain\n */\nexport const USDC_ADDRESSES: Record<string, Address> = {\n ethereum: \"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\",\n arbitrum: \"0xaf88d065e77c8cC2239327C5EDb3A432268e5831\",\n base: \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\",\n optimism: \"0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85\",\n polygon: \"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359\",\n} as const;\n\n/**\n * Chain IDs for supported networks\n */\nexport const CHAIN_IDS: Record<string, number> = {\n ethereum: 1,\n arbitrum: 42161,\n base: 8453,\n optimism: 10,\n polygon: 137,\n ink: 57073,\n berachain: 80084,\n unichain: 130,\n} as const;\n\n/**\n * Default bundler URLs by chain (using public endpoints)\n */\nexport const DEFAULT_BUNDLER_URLS: Record<number, string> = {\n 1: \"https://api.pimlico.io/v2/ethereum/rpc\",\n 42161: \"https://api.pimlico.io/v2/arbitrum/rpc\",\n 8453: \"https://api.pimlico.io/v2/base/rpc\",\n 10: \"https://api.pimlico.io/v2/optimism/rpc\",\n 137: \"https://api.pimlico.io/v2/polygon/rpc\",\n} as const;\n\n/**\n * Get token address for a chain\n */\nexport function getTokenAddress(\n token: \"USDT0\" | \"USDC\" | Address,\n chainName: string,\n): Address {\n if (token.startsWith(\"0x\")) {\n return token as Address;\n }\n\n const addresses = token === \"USDT0\" ? USDT0_ADDRESSES : USDC_ADDRESSES;\n const address = addresses[chainName.toLowerCase()];\n\n if (!address) {\n throw new Error(`Token ${token} not available on ${chainName}`);\n }\n\n return address;\n}\n\n/**\n * Get chain name from chain ID\n */\nexport function getChainName(chainId: number): string {\n const entry = Object.entries(CHAIN_IDS).find(([, id]) => id === chainId);\n if (!entry) {\n throw new Error(`Unsupported chain ID: ${chainId}`);\n }\n return entry[0];\n}\n"],"mappings":"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","names":["encodeFunctionData","encodeFunctionData"]}
|
|
1
|
+
{"version":3,"sources":["../../src/client.ts","../../src/account.ts","../../src/constants.ts"],"sourcesContent":["/**\n * WDK Gasless Client\n *\n * High-level client for executing gasless USDT0 payments using\n * Tether WDK accounts and ERC-4337 Account Abstraction.\n */\n\nimport type { Address, Hex, PublicClient } from 'viem'\nimport { encodeFunctionData, formatUnits } from 'viem'\nimport { BundlerClient, PaymasterClient, UserOpBuilder, ENTRYPOINT_V07_ADDRESS } from '@t402/evm'\nimport type {\n SmartAccountSigner,\n BundlerConfig,\n PaymasterConfig,\n TransactionIntent,\n GasEstimate,\n PaymasterData,\n} from '@t402/evm'\nimport type {\n WdkGaslessClientConfig,\n GaslessPaymentParams,\n BatchPaymentParams,\n GaslessPaymentResult,\n GaslessPaymentReceipt,\n SponsorshipInfo,\n WdkAccount,\n} from './types.js'\nimport { createWdkSmartAccount } from './account.js'\nimport { getTokenAddress, getChainName } from './constants.js'\n\n/**\n * ERC20 transfer ABI\n */\nconst ERC20_TRANSFER_ABI = [\n {\n inputs: [\n { name: 'to', type: 'address' },\n { name: 'amount', type: 'uint256' },\n ],\n name: 'transfer',\n outputs: [{ name: '', type: 'bool' }],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n] as const\n\n/**\n * ERC20 balanceOf ABI\n */\nconst ERC20_BALANCE_ABI = [\n {\n inputs: [{ name: 'account', type: 'address' }],\n name: 'balanceOf',\n outputs: [{ name: '', type: 'uint256' }],\n stateMutability: 'view',\n type: 'function',\n },\n] as const\n\n/**\n * WDK Gasless Client\n *\n * Provides a simple API for executing gasless USDT0 payments using\n * WDK accounts and ERC-4337 smart accounts.\n */\nexport class WdkGaslessClient {\n private readonly signer: SmartAccountSigner\n private readonly builder: UserOpBuilder\n private readonly bundler: BundlerClient\n private readonly paymaster?: PaymasterClient\n private readonly chainId: number\n private readonly publicClient: PublicClient\n private readonly chainName: string\n\n constructor(config: WdkGaslessClientConfig) {\n this.signer = config.signer\n this.builder = new UserOpBuilder()\n this.bundler = new BundlerClient(config.bundler)\n this.paymaster = config.paymaster ? new PaymasterClient(config.paymaster) : undefined\n this.chainId = config.chainId\n this.publicClient = config.publicClient\n this.chainName = getChainName(config.chainId)\n }\n\n /**\n * Execute a gasless payment\n *\n * Sends USDT0 (or other tokens) without the user paying gas fees.\n * Gas is sponsored by a paymaster if configured.\n */\n async pay(params: GaslessPaymentParams): Promise<GaslessPaymentResult> {\n // Validate payment params\n if (!params.to || params.to === '0x0000000000000000000000000000000000000000') {\n throw new Error('Recipient address must not be the zero address')\n }\n\n if (params.amount <= 0n) {\n throw new Error('Payment amount must be greater than zero')\n }\n\n const token = params.token ?? 'USDT0'\n const tokenAddress = getTokenAddress(token, this.chainName)\n\n // Build the transfer call data\n const callData = encodeFunctionData({\n abi: ERC20_TRANSFER_ABI,\n functionName: 'transfer',\n args: [params.to, params.amount],\n })\n\n // Create the transaction intent\n const intent: TransactionIntent = {\n to: tokenAddress,\n value: 0n,\n data: callData,\n }\n\n // Estimate gas\n const gasEstimate = await this.estimateGas(intent)\n\n // Get paymaster data if configured\n const paymasterData = await this.getPaymasterData(gasEstimate)\n const sponsored = paymasterData !== undefined\n\n // Build the UserOperation\n const userOp = await this.builder.buildUserOp(\n this.signer,\n intent,\n this.publicClient,\n gasEstimate,\n paymasterData,\n )\n\n // Sign the UserOperation\n const signedUserOp = await this.builder.signUserOp(\n userOp,\n this.signer,\n this.publicClient,\n this.chainId,\n )\n\n // Submit to bundler\n const result = await this.bundler.sendUserOperation(signedUserOp)\n const sender = await this.signer.getAddress()\n\n return {\n userOpHash: result.userOpHash,\n sender,\n sponsored,\n wait: async (): Promise<GaslessPaymentReceipt> => {\n const receipt = await result.wait()\n return {\n userOpHash: receipt.userOpHash,\n txHash: receipt.receipt.transactionHash,\n blockNumber: receipt.receipt.blockNumber,\n success: receipt.success,\n gasUsed: receipt.actualGasUsed,\n gasCost: receipt.actualGasCost,\n reason: receipt.reason,\n }\n },\n }\n }\n\n /**\n * Execute multiple payments in a single transaction\n *\n * More gas efficient than individual payments.\n * All payments are executed atomically.\n */\n async payBatch(params: BatchPaymentParams): Promise<GaslessPaymentResult> {\n // Validate batch params\n if (!params.payments || params.payments.length === 0) {\n throw new Error('Batch payments must contain at least one payment')\n }\n\n if (params.payments.length > 50) {\n throw new Error('Batch payments must not exceed 50 payments')\n }\n\n for (const payment of params.payments) {\n if (!payment.to || payment.to === '0x0000000000000000000000000000000000000000') {\n throw new Error('Recipient address must not be the zero address')\n }\n if (payment.amount <= 0n) {\n throw new Error('Payment amount must be greater than zero')\n }\n }\n\n // Build transaction intents for all payments\n const intents: TransactionIntent[] = params.payments.map((payment) => {\n const token = payment.token ?? 'USDT0'\n const tokenAddress = getTokenAddress(token, this.chainName)\n\n return {\n to: tokenAddress,\n value: 0n,\n data: encodeFunctionData({\n abi: ERC20_TRANSFER_ABI,\n functionName: 'transfer',\n args: [payment.to, payment.amount],\n }),\n }\n })\n\n // Estimate gas for batch\n const gasEstimate = await this.estimateBatchGas(intents)\n\n // Get paymaster data\n const paymasterData = await this.getPaymasterData(gasEstimate)\n const sponsored = paymasterData !== undefined\n\n // Build batch UserOperation\n const userOp = await this.builder.buildBatchUserOp(\n this.signer,\n intents,\n this.publicClient,\n gasEstimate,\n paymasterData,\n )\n\n // Sign and submit\n const signedUserOp = await this.builder.signUserOp(\n userOp,\n this.signer,\n this.publicClient,\n this.chainId,\n )\n\n const result = await this.bundler.sendUserOperation(signedUserOp)\n const sender = await this.signer.getAddress()\n\n return {\n userOpHash: result.userOpHash,\n sender,\n sponsored,\n wait: async (): Promise<GaslessPaymentReceipt> => {\n const receipt = await result.wait()\n return {\n userOpHash: receipt.userOpHash,\n txHash: receipt.receipt.transactionHash,\n blockNumber: receipt.receipt.blockNumber,\n success: receipt.success,\n gasUsed: receipt.actualGasUsed,\n gasCost: receipt.actualGasCost,\n reason: receipt.reason,\n }\n },\n }\n }\n\n /**\n * Check if a payment can be sponsored (free gas)\n */\n async canSponsor(params: GaslessPaymentParams): Promise<SponsorshipInfo> {\n if (!this.paymaster) {\n return {\n canSponsor: false,\n reason: 'No paymaster configured',\n }\n }\n\n const token = params.token ?? 'USDT0'\n const tokenAddress = getTokenAddress(token, this.chainName)\n\n const callData = encodeFunctionData({\n abi: ERC20_TRANSFER_ABI,\n functionName: 'transfer',\n args: [params.to, params.amount],\n })\n\n const sender = await this.signer.getAddress()\n const encodedCallData = this.signer.encodeExecute(tokenAddress, 0n, callData)\n\n try {\n const canSponsor = await this.paymaster.willSponsor(\n { sender, callData: encodedCallData },\n this.chainId,\n ENTRYPOINT_V07_ADDRESS,\n )\n\n if (canSponsor) {\n return { canSponsor: true }\n } else {\n // Estimate gas cost if not sponsored\n const intent: TransactionIntent = {\n to: tokenAddress,\n value: 0n,\n data: callData,\n }\n const gasEstimate = await this.estimateGas(intent)\n const gasPrice = await this.publicClient.getGasPrice()\n const estimatedGasCost =\n (gasEstimate.verificationGasLimit +\n gasEstimate.callGasLimit +\n gasEstimate.preVerificationGas) *\n gasPrice\n\n return {\n canSponsor: false,\n reason: 'Payment not eligible for sponsorship',\n estimatedGasCost,\n }\n }\n } catch (error) {\n return {\n canSponsor: false,\n reason: error instanceof Error ? error.message : 'Unknown error',\n }\n }\n }\n\n /**\n * Get the smart account address\n */\n async getAccountAddress(): Promise<Address> {\n return this.signer.getAddress()\n }\n\n /**\n * Check if the smart account is deployed\n */\n async isAccountDeployed(): Promise<boolean> {\n return this.signer.isDeployed()\n }\n\n /**\n * Get the token balance of the smart account\n */\n async getBalance(token: 'USDT0' | 'USDC' | Address = 'USDT0'): Promise<bigint> {\n const tokenAddress = getTokenAddress(token, this.chainName)\n const accountAddress = await this.signer.getAddress()\n\n const balance = await this.publicClient.readContract({\n address: tokenAddress,\n abi: ERC20_BALANCE_ABI,\n functionName: 'balanceOf',\n args: [accountAddress],\n })\n\n return balance as bigint\n }\n\n /**\n * Get the formatted token balance\n */\n async getFormattedBalance(\n token: 'USDT0' | 'USDC' | Address = 'USDT0',\n decimals = 6,\n ): Promise<string> {\n const balance = await this.getBalance(token)\n return formatUnits(balance, decimals)\n }\n\n /**\n * Estimate gas for a single transaction\n */\n private async estimateGas(intent: TransactionIntent): Promise<GasEstimate> {\n const sender = await this.signer.getAddress()\n const callData = this.signer.encodeExecute(intent.to, intent.value ?? 0n, intent.data ?? '0x')\n\n try {\n return await this.bundler.estimateUserOperationGas({\n sender,\n callData,\n })\n } catch {\n // Return defaults if estimation fails\n return {\n verificationGasLimit: 150000n,\n callGasLimit: 100000n,\n preVerificationGas: 50000n,\n }\n }\n }\n\n /**\n * Estimate gas for a batch transaction\n */\n private async estimateBatchGas(intents: TransactionIntent[]): Promise<GasEstimate> {\n const sender = await this.signer.getAddress()\n const callData = this.signer.encodeExecuteBatch(\n intents.map((i) => i.to),\n intents.map((i) => i.value ?? 0n),\n intents.map((i) => (i.data ?? '0x') as Hex),\n )\n\n try {\n return await this.bundler.estimateUserOperationGas({\n sender,\n callData,\n })\n } catch {\n // Return defaults with multiplier for batch size\n return {\n verificationGasLimit: 150000n,\n callGasLimit: 100000n * BigInt(intents.length),\n preVerificationGas: 50000n,\n }\n }\n }\n\n /**\n * Get paymaster data if configured\n */\n private async getPaymasterData(_gasEstimate: GasEstimate): Promise<PaymasterData | undefined> {\n if (!this.paymaster) return undefined\n\n const sender = await this.signer.getAddress()\n\n return this.paymaster.getPaymasterData({ sender }, this.chainId, ENTRYPOINT_V07_ADDRESS)\n }\n}\n\n/**\n * Configuration for creating a WDK gasless client\n */\nexport interface CreateWdkGaslessClientConfig {\n /** WDK account to use as the signer */\n wdkAccount: WdkAccount\n /** Public client for chain interactions */\n publicClient: PublicClient\n /** Chain ID */\n chainId: number\n /** Bundler configuration */\n bundler: BundlerConfig\n /** Optional paymaster for gas sponsorship */\n paymaster?: PaymasterConfig\n /** Salt nonce for address generation (defaults to 0) */\n saltNonce?: bigint\n}\n\n/**\n * Create a WDK gasless client\n *\n * This is the main entry point for using WDK with gasless payments.\n *\n * @example\n * ```typescript\n * import { createWdkGaslessClient } from '@t402/wdk-gasless';\n *\n * const client = await createWdkGaslessClient({\n * wdkAccount: myWdkAccount,\n * publicClient,\n * chainId: 42161, // Arbitrum\n * bundler: {\n * bundlerUrl: 'https://api.pimlico.io/v2/arbitrum/rpc?apikey=...',\n * chainId: 42161,\n * },\n * paymaster: {\n * address: '0x...',\n * url: 'https://api.pimlico.io/v2/arbitrum/rpc?apikey=...',\n * type: 'sponsoring',\n * },\n * });\n *\n * // Execute gasless payment\n * const result = await client.pay({\n * to: '0x...',\n * amount: 1000000n, // 1 USDT0\n * });\n *\n * const receipt = await result.wait();\n * console.log('Payment confirmed:', receipt.txHash);\n * ```\n */\nexport async function createWdkGaslessClient(\n config: CreateWdkGaslessClientConfig,\n): Promise<WdkGaslessClient> {\n // Create the WDK smart account\n const smartAccount = await createWdkSmartAccount({\n wdkAccount: config.wdkAccount,\n publicClient: config.publicClient,\n chainId: config.chainId,\n saltNonce: config.saltNonce,\n })\n\n // Create the gasless client\n return new WdkGaslessClient({\n signer: smartAccount,\n bundler: config.bundler,\n paymaster: config.paymaster,\n chainId: config.chainId,\n publicClient: config.publicClient,\n })\n}\n","/**\n * WDK Smart Account\n *\n * Wraps a Tether WDK account to work with ERC-4337 smart accounts.\n * Creates a Safe smart account with the WDK account as the owner/signer.\n */\n\nimport type { Address, Hex, PublicClient } from 'viem'\nimport {\n encodeFunctionData,\n encodeAbiParameters,\n concat,\n keccak256,\n getContractAddress,\n} from 'viem'\nimport type { SmartAccountSigner } from '@t402/evm'\nimport type { WdkAccount, WdkSmartAccountConfig } from './types.js'\n\n/**\n * Safe 4337 module addresses (v0.3.0)\n * Deployed on all major EVM chains at the same addresses\n */\nexport const SAFE_4337_ADDRESSES = {\n /** Safe 4337 Module */\n module: '0xa581c4A4DB7175302464fF3C06380BC3270b4037' as Address,\n /** Safe Module Setup */\n moduleSetup: '0x2dd68b007B46fBe91B9A7c3EDa5A7a1063cB5b47' as Address,\n /** Safe Singleton */\n singleton: '0x29fcB43b46531BcA003ddC8FCB67FFE91900C762' as Address,\n /** Safe Proxy Factory */\n proxyFactory: '0x4e1DCf7AD4e460CfD30791CCC4F9c8a4f820ec67' as Address,\n /** Safe Fallback Handler */\n fallbackHandler: '0xfd0732Dc9E303f09fCEf3a7388Ad10A83459Ec99' as Address,\n /** Add Modules Lib */\n addModulesLib: '0x8EcD4ec46D4D2a6B64fE960B3D64e8B94B2234eb' as Address,\n} as const\n\n/**\n * Safe Proxy Factory ABI\n */\nconst PROXY_FACTORY_ABI = [\n {\n inputs: [\n { name: 'singleton', type: 'address' },\n { name: 'initializer', type: 'bytes' },\n { name: 'saltNonce', type: 'uint256' },\n ],\n name: 'createProxyWithNonce',\n outputs: [{ name: 'proxy', type: 'address' }],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n inputs: [\n { name: 'singleton', type: 'address' },\n { name: 'initializer', type: 'bytes' },\n { name: 'saltNonce', type: 'uint256' },\n ],\n name: 'proxyCreationCode',\n outputs: [{ name: '', type: 'bytes' }],\n stateMutability: 'view',\n type: 'function',\n },\n] as const\n\n/**\n * Safe Singleton ABI\n */\nconst SAFE_ABI = [\n {\n inputs: [\n { name: 'owners', type: 'address[]' },\n { name: 'threshold', type: 'uint256' },\n { name: 'to', type: 'address' },\n { name: 'data', type: 'bytes' },\n { name: 'fallbackHandler', type: 'address' },\n { name: 'paymentToken', type: 'address' },\n { name: 'payment', type: 'uint256' },\n { name: 'paymentReceiver', type: 'address' },\n ],\n name: 'setup',\n outputs: [],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n] as const\n\n/**\n * Add Modules Lib ABI\n */\nconst ADD_MODULES_LIB_ABI = [\n {\n inputs: [{ name: 'modules', type: 'address[]' }],\n name: 'enableModules',\n outputs: [],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n] as const\n\n/**\n * Safe 4337 Module ABI\n */\nconst SAFE_4337_MODULE_ABI = [\n {\n inputs: [\n { name: 'to', type: 'address' },\n { name: 'value', type: 'uint256' },\n { name: 'data', type: 'bytes' },\n { name: 'operation', type: 'uint8' },\n ],\n name: 'executeUserOp',\n outputs: [],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n inputs: [\n { name: 'tos', type: 'address[]' },\n { name: 'values', type: 'uint256[]' },\n { name: 'datas', type: 'bytes[]' },\n { name: 'operations', type: 'uint8[]' },\n ],\n name: 'executeUserOpBatch',\n outputs: [],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n] as const\n\n/**\n * WDK Smart Account\n *\n * Creates a Safe smart account using a WDK account as the owner/signer.\n * Implements SmartAccountSigner for ERC-4337 compatibility.\n */\nexport class WdkSmartAccount implements SmartAccountSigner {\n private readonly wdkAccount: WdkAccount\n private readonly publicClient: PublicClient\n private readonly _chainId: number\n private readonly owners: Address[]\n private readonly threshold: number\n private readonly saltNonce: bigint\n\n private cachedAddress?: Address\n private cachedInitCode?: Hex\n private cachedOwnerAddress?: Address\n private deploymentChecked = false\n private isAccountDeployed = false\n\n constructor(config: WdkSmartAccountConfig) {\n this.wdkAccount = config.wdkAccount\n this.publicClient = config.publicClient\n this._chainId = config.chainId\n this.threshold = config.threshold ?? 1\n this.saltNonce = config.saltNonce ?? 0n\n\n // Owners will be set when we get the WDK account address\n this.owners = config.additionalOwners ?? []\n }\n\n /**\n * Initialize the account (fetch WDK address)\n * Call this before using the account\n */\n async initialize(): Promise<void> {\n if (!this.cachedOwnerAddress) {\n const address = await this.wdkAccount.getAddress()\n this.cachedOwnerAddress = address as Address\n\n // Add WDK account as the first owner if not already in owners\n if (!this.owners.includes(this.cachedOwnerAddress)) {\n this.owners.unshift(this.cachedOwnerAddress)\n }\n }\n }\n\n /**\n * Get the WDK account's EOA address\n */\n async getOwnerAddress(): Promise<Address> {\n await this.initialize()\n return this.cachedOwnerAddress!\n }\n\n /**\n * Get the chain ID\n */\n getChainId(): number {\n return this._chainId\n }\n\n /**\n * Get the smart account address (counterfactual)\n */\n async getAddress(): Promise<Address> {\n await this.initialize()\n\n if (this.cachedAddress) {\n return this.cachedAddress\n }\n\n const initCode = await this.getInitCode()\n\n // If already deployed, get address from code\n if (initCode === '0x') {\n // Need to compute it anyway for first time\n const initializerData = await this.buildInitializer()\n const salt = keccak256(\n encodeAbiParameters(\n [{ type: 'bytes32' }, { type: 'uint256' }],\n [keccak256(initializerData), this.saltNonce],\n ),\n )\n\n const proxyCreationCode = (await this.publicClient.readContract({\n address: SAFE_4337_ADDRESSES.proxyFactory,\n abi: PROXY_FACTORY_ABI,\n functionName: 'proxyCreationCode',\n args: [SAFE_4337_ADDRESSES.singleton, initializerData, this.saltNonce],\n })) as Hex\n\n this.cachedAddress = getContractAddress({\n bytecode: proxyCreationCode,\n from: SAFE_4337_ADDRESSES.proxyFactory,\n opcode: 'CREATE2',\n salt,\n })\n } else {\n // Extract initializer from init code\n const initializerData = `0x${initCode.slice(2 + 40 * 2)}` as Hex\n\n const salt = keccak256(\n encodeAbiParameters(\n [{ type: 'bytes32' }, { type: 'uint256' }],\n [keccak256(initializerData), this.saltNonce],\n ),\n )\n\n const proxyCreationCode = (await this.publicClient.readContract({\n address: SAFE_4337_ADDRESSES.proxyFactory,\n abi: PROXY_FACTORY_ABI,\n functionName: 'proxyCreationCode',\n args: [SAFE_4337_ADDRESSES.singleton, initializerData, this.saltNonce],\n })) as Hex\n\n this.cachedAddress = getContractAddress({\n bytecode: proxyCreationCode,\n from: SAFE_4337_ADDRESSES.proxyFactory,\n opcode: 'CREATE2',\n salt,\n })\n }\n\n return this.cachedAddress\n }\n\n /**\n * Sign a UserOperation hash using the WDK account\n */\n async signUserOpHash(userOpHash: Hex): Promise<Hex> {\n await this.initialize()\n\n // Sign the hash using WDK account's signMessage\n // The hash is signed as raw bytes (personal_sign format)\n const signature = await this.wdkAccount.signMessage(userOpHash)\n\n // Format signature for Safe (add signature type byte)\n // Type 0: EOA signature\n return concat([signature as Hex, '0x00']) as Hex\n }\n\n /**\n * Get the account's init code for deployment\n */\n async getInitCode(): Promise<Hex> {\n await this.initialize()\n\n // Check if already deployed\n if (await this.isDeployed()) {\n return '0x' as Hex\n }\n\n if (this.cachedInitCode) {\n return this.cachedInitCode\n }\n\n const safeSetupData = await this.buildInitializer()\n\n // Build factory call data\n const createProxyData = encodeFunctionData({\n abi: PROXY_FACTORY_ABI,\n functionName: 'createProxyWithNonce',\n args: [SAFE_4337_ADDRESSES.singleton, safeSetupData, this.saltNonce],\n })\n\n // Init code = factory address + factory call data\n this.cachedInitCode = concat([SAFE_4337_ADDRESSES.proxyFactory, createProxyData]) as Hex\n\n return this.cachedInitCode\n }\n\n /**\n * Check if the account is deployed\n */\n async isDeployed(): Promise<boolean> {\n if (this.deploymentChecked) {\n return this.isAccountDeployed\n }\n\n // Set flag early to break infinite recursion:\n // getAddress() → getInitCode() → isDeployed() → getAddress() → ...\n // Default assumption (not deployed) is correct for init code computation.\n this.deploymentChecked = true\n\n await this.initialize()\n const address = this.cachedAddress ?? (await this.getAddress())\n const code = await this.publicClient.getCode({ address })\n\n this.isAccountDeployed = code !== undefined && code !== '0x'\n\n return this.isAccountDeployed\n }\n\n /**\n * Encode a call to the account's execute function\n */\n encodeExecute(target: Address, value: bigint, data: Hex): Hex {\n return encodeFunctionData({\n abi: SAFE_4337_MODULE_ABI,\n functionName: 'executeUserOp',\n args: [target, value, data, 0], // operation: CALL\n })\n }\n\n /**\n * Encode a batch call to the account's executeBatch function\n */\n encodeExecuteBatch(targets: Address[], values: bigint[], datas: Hex[]): Hex {\n if (targets.length !== values.length || targets.length !== datas.length) {\n throw new Error('Array lengths must match')\n }\n\n const operations = targets.map(() => 0) // All CALL operations\n\n return encodeFunctionData({\n abi: SAFE_4337_MODULE_ABI,\n functionName: 'executeUserOpBatch',\n args: [targets, values, datas, operations],\n })\n }\n\n /**\n * Build the Safe setup initializer data\n */\n private async buildInitializer(): Promise<Hex> {\n await this.initialize()\n\n // Build Safe setup data with 4337 module\n const setupModulesData = encodeFunctionData({\n abi: ADD_MODULES_LIB_ABI,\n functionName: 'enableModules',\n args: [[SAFE_4337_ADDRESSES.module]],\n })\n\n return encodeFunctionData({\n abi: SAFE_ABI,\n functionName: 'setup',\n args: [\n this.owners,\n BigInt(this.threshold),\n SAFE_4337_ADDRESSES.addModulesLib, // to: AddModulesLib\n setupModulesData, // data: enableModules([module])\n SAFE_4337_ADDRESSES.fallbackHandler,\n '0x0000000000000000000000000000000000000000' as Address, // paymentToken\n 0n, // payment\n '0x0000000000000000000000000000000000000000' as Address, // paymentReceiver\n ],\n })\n }\n\n /**\n * Get the Safe's owners\n */\n getOwners(): Address[] {\n return [...this.owners]\n }\n\n /**\n * Get the Safe's threshold\n */\n getThreshold(): number {\n return this.threshold\n }\n\n /**\n * Clear cached values (useful after deployment)\n */\n clearCache(): void {\n this.cachedAddress = undefined\n this.cachedInitCode = undefined\n this.deploymentChecked = false\n this.isAccountDeployed = false\n }\n}\n\n/**\n * Create a WDK smart account\n */\nexport async function createWdkSmartAccount(\n config: WdkSmartAccountConfig,\n): Promise<WdkSmartAccount> {\n const account = new WdkSmartAccount(config)\n await account.initialize()\n return account\n}\n","/**\n * WDK Gasless Constants\n *\n * Addresses and configuration for gasless USDT0 payments.\n */\n\nimport type { Address } from 'viem'\n\n/**\n * USDT0 OFT addresses by chain\n */\nexport const USDT0_ADDRESSES: Record<string, Address> = {\n ethereum: '0x6C96dE32CEa08842dcc4058c14d3aaAD7Fa41dee',\n arbitrum: '0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9',\n ink: '0x0200C29006150606B650577BBE7B6248F58470c1',\n berachain: '0x779Ded0c9e1022225f8E0630b35a9b54bE713736',\n unichain: '0x9151434b16b9763660705744891fA906F660EcC5',\n base: '0x6C96dE32CEa08842dcc4058c14d3aaAD7Fa41dee',\n optimism: '0x6C96dE32CEa08842dcc4058c14d3aaAD7Fa41dee',\n} as const\n\n/**\n * USDC addresses by chain\n */\nexport const USDC_ADDRESSES: Record<string, Address> = {\n ethereum: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',\n arbitrum: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',\n base: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',\n optimism: '0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85',\n polygon: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',\n} as const\n\n/**\n * Chain IDs for supported networks\n */\nexport const CHAIN_IDS: Record<string, number> = {\n ethereum: 1,\n arbitrum: 42161,\n base: 8453,\n optimism: 10,\n polygon: 137,\n ink: 57073,\n berachain: 80094,\n unichain: 130,\n} as const\n\n/**\n * Default bundler URLs by chain (using public endpoints)\n */\nexport const DEFAULT_BUNDLER_URLS: Record<number, string> = {\n 1: 'https://api.pimlico.io/v2/ethereum/rpc',\n 42161: 'https://api.pimlico.io/v2/arbitrum/rpc',\n 8453: 'https://api.pimlico.io/v2/base/rpc',\n 10: 'https://api.pimlico.io/v2/optimism/rpc',\n 137: 'https://api.pimlico.io/v2/polygon/rpc',\n} as const\n\n/**\n * Get token address for a chain\n */\nexport function getTokenAddress(token: 'USDT0' | 'USDC' | Address, chainName: string): Address {\n if (token.startsWith('0x')) {\n return token as Address\n }\n\n const addresses = token === 'USDT0' ? USDT0_ADDRESSES : USDC_ADDRESSES\n const address = addresses[chainName.toLowerCase()]\n\n if (!address) {\n throw new Error(`Token ${token} not available on ${chainName}`)\n }\n\n return address\n}\n\n/**\n * Get chain name from chain ID\n */\nexport function getChainName(chainId: number): string {\n const entry = Object.entries(CHAIN_IDS).find(([, id]) => id === chainId)\n if (!entry) {\n throw new Error(`Unsupported chain ID: ${chainId}`)\n }\n return entry[0]\n}\n"],"mappings":"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","names":["encodeFunctionData","encodeFunctionData"]}
|
package/package.json
CHANGED
|
@@ -1,18 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@t402/wdk-gasless",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.4.0",
|
|
4
4
|
"main": "./dist/cjs/index.js",
|
|
5
5
|
"module": "./dist/esm/index.js",
|
|
6
6
|
"types": "./dist/cjs/index.d.ts",
|
|
7
|
-
"scripts": {
|
|
8
|
-
"build": "tsup",
|
|
9
|
-
"test": "vitest run --pool=forks",
|
|
10
|
-
"test:watch": "vitest",
|
|
11
|
-
"format": "prettier -c .prettierrc --write \"**/*.{ts,js,cjs,json,md}\"",
|
|
12
|
-
"format:check": "prettier -c .prettierrc --check \"**/*.{ts,js,cjs,json,md}\"",
|
|
13
|
-
"lint": "eslint . --ext .ts --fix",
|
|
14
|
-
"lint:check": "eslint . --ext .ts"
|
|
15
|
-
},
|
|
16
7
|
"keywords": [
|
|
17
8
|
"t402",
|
|
18
9
|
"payment",
|
|
@@ -31,28 +22,29 @@
|
|
|
31
22
|
"description": "Gasless USDT0 payments with Tether WDK and ERC-4337 Account Abstraction",
|
|
32
23
|
"devDependencies": {
|
|
33
24
|
"@eslint/js": "^9.24.0",
|
|
34
|
-
"@types/node": "^
|
|
25
|
+
"@types/node": "^25.2.0",
|
|
35
26
|
"@typescript-eslint/eslint-plugin": "^8.29.1",
|
|
36
27
|
"@typescript-eslint/parser": "^8.29.1",
|
|
37
28
|
"eslint": "^9.24.0",
|
|
38
29
|
"eslint-plugin-import": "^2.31.0",
|
|
39
|
-
"eslint-plugin-jsdoc": "^
|
|
30
|
+
"eslint-plugin-jsdoc": "^62.5.0",
|
|
40
31
|
"eslint-plugin-prettier": "^5.2.6",
|
|
32
|
+
"glob": "^13.0.0",
|
|
41
33
|
"prettier": "3.5.2",
|
|
42
34
|
"tsup": "^8.4.0",
|
|
43
|
-
"tsx": "^4.
|
|
35
|
+
"tsx": "^4.21.0",
|
|
44
36
|
"typescript": "^5.7.3",
|
|
45
|
-
"vite": "^
|
|
37
|
+
"vite": "^7.3.1",
|
|
46
38
|
"vite-tsconfig-paths": "^5.1.4",
|
|
47
|
-
"vitest": "^3.
|
|
39
|
+
"vitest": "^3.2.4"
|
|
48
40
|
},
|
|
49
41
|
"dependencies": {
|
|
50
|
-
"@t402/core": "
|
|
51
|
-
"@t402/
|
|
52
|
-
"@t402/
|
|
53
|
-
"viem": "^2.39.3"
|
|
42
|
+
"@t402/core": "2.4.0",
|
|
43
|
+
"@t402/wdk": "2.4.0",
|
|
44
|
+
"@t402/evm": "2.4.0"
|
|
54
45
|
},
|
|
55
46
|
"peerDependencies": {
|
|
47
|
+
"viem": "^2.0.0",
|
|
56
48
|
"@tetherto/wdk": ">=1.0.0-beta.0",
|
|
57
49
|
"@tetherto/wdk-wallet-evm": ">=1.0.0-beta.0"
|
|
58
50
|
},
|
|
@@ -78,5 +70,14 @@
|
|
|
78
70
|
},
|
|
79
71
|
"files": [
|
|
80
72
|
"dist"
|
|
81
|
-
]
|
|
82
|
-
|
|
73
|
+
],
|
|
74
|
+
"scripts": {
|
|
75
|
+
"build": "tsup",
|
|
76
|
+
"test": "vitest run --pool=forks",
|
|
77
|
+
"test:watch": "vitest",
|
|
78
|
+
"format": "prettier -c .prettierrc --write \"**/*.{ts,js,cjs,json,md}\"",
|
|
79
|
+
"format:check": "prettier -c .prettierrc --check \"**/*.{ts,js,cjs,json,md}\"",
|
|
80
|
+
"lint": "eslint . --ext .ts --fix",
|
|
81
|
+
"lint:check": "eslint . --ext .ts"
|
|
82
|
+
}
|
|
83
|
+
}
|