@clawnch/clawncher-sdk 0.2.0 → 0.3.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 +190 -0
- package/dist/errors.d.ts +1 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +3 -0
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -1
- package/dist/liquidity.d.ts +14 -8
- package/dist/liquidity.d.ts.map +1 -1
- package/dist/liquidity.js +149 -15
- package/dist/liquidity.js.map +1 -1
- package/dist/permit2.d.ts +258 -0
- package/dist/permit2.d.ts.map +1 -0
- package/dist/permit2.js +520 -0
- package/dist/permit2.js.map +1 -0
- package/dist/uniswap-abis.d.ts +525 -0
- package/dist/uniswap-abis.d.ts.map +1 -1
- package/dist/uniswap-abis.js +432 -1
- package/dist/uniswap-abis.js.map +1 -1
- package/dist/uniswap-chains.d.ts +77 -0
- package/dist/uniswap-chains.d.ts.map +1 -0
- package/dist/uniswap-chains.js +362 -0
- package/dist/uniswap-chains.js.map +1 -0
- package/dist/uniswap-quoter.d.ts +178 -0
- package/dist/uniswap-quoter.d.ts.map +1 -0
- package/dist/uniswap-quoter.js +432 -0
- package/dist/uniswap-quoter.js.map +1 -0
- package/dist/uniswap-trading.d.ts +203 -0
- package/dist/uniswap-trading.d.ts.map +1 -0
- package/dist/uniswap-trading.js +380 -0
- package/dist/uniswap-trading.js.map +1 -0
- package/package.json +3 -1
package/dist/permit2.js
ADDED
|
@@ -0,0 +1,520 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Permit2 — EIP-712 signature-based token approvals for Uniswap V4.
|
|
3
|
+
*
|
|
4
|
+
* Permit2 replaces per-contract ERC20 approvals with a two-step model:
|
|
5
|
+
* 1. Owner approves Permit2 once (ERC20.approve(Permit2, MAX))
|
|
6
|
+
* 2. For each swap/LP action, owner signs an EIP-712 permit granting
|
|
7
|
+
* the router/PositionManager a time-limited, amount-limited allowance
|
|
8
|
+
*
|
|
9
|
+
* Two transfer modes:
|
|
10
|
+
*
|
|
11
|
+
* **AllowanceTransfer** — used by PositionManager for LP operations
|
|
12
|
+
* - On-chain nonce tracking (uint48, auto-incremented per token+spender)
|
|
13
|
+
* - Supports amount limits and expiration timestamps
|
|
14
|
+
* - sign PermitSingle/PermitBatch → call permit() → router calls transferFrom()
|
|
15
|
+
*
|
|
16
|
+
* **SignatureTransfer** — used by UniversalRouter for swaps
|
|
17
|
+
* - Off-chain nonce (uint256, bitmap-based, single-use)
|
|
18
|
+
* - No on-chain state change for the permit itself
|
|
19
|
+
* - sign PermitTransferFrom → router calls permitTransferFrom() in one tx
|
|
20
|
+
* - Supports "witness" data for swap parameters
|
|
21
|
+
*
|
|
22
|
+
* @see https://docs.uniswap.org/contracts/permit2/overview
|
|
23
|
+
* @see https://github.com/Uniswap/permit2
|
|
24
|
+
*/
|
|
25
|
+
import { erc20Abi, maxUint256, maxUint160, } from 'viem';
|
|
26
|
+
import { Permit2ABI } from './uniswap-abis.js';
|
|
27
|
+
import { ClawnchErrorCode, ClawnchDeployError } from './errors.js';
|
|
28
|
+
// ============================================================================
|
|
29
|
+
// Constants
|
|
30
|
+
// ============================================================================
|
|
31
|
+
/** Permit2 is deployed at the same address on all chains */
|
|
32
|
+
export const PERMIT2_ADDRESS = '0x000000000022D473030F116dDEE9F6B43aC78BA3';
|
|
33
|
+
/** 30 days in seconds — default permit expiration */
|
|
34
|
+
const DEFAULT_PERMIT_EXPIRATION = 30 * 24 * 60 * 60;
|
|
35
|
+
/** 30 minutes — default signature deadline */
|
|
36
|
+
const DEFAULT_SIG_DEADLINE = 30 * 60;
|
|
37
|
+
const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
|
|
38
|
+
// ============================================================================
|
|
39
|
+
// EIP-712 Domain & Types
|
|
40
|
+
// ============================================================================
|
|
41
|
+
/** Permit2 EIP-712 domain (same for all chains — uses chainId at signing time) */
|
|
42
|
+
function getPermit2Domain(chainId) {
|
|
43
|
+
return {
|
|
44
|
+
name: 'Permit2',
|
|
45
|
+
chainId,
|
|
46
|
+
verifyingContract: PERMIT2_ADDRESS,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
// ── AllowanceTransfer EIP-712 types ─────────────────────────────────────
|
|
50
|
+
const PERMIT_DETAILS_TYPE = {
|
|
51
|
+
PermitDetails: [
|
|
52
|
+
{ name: 'token', type: 'address' },
|
|
53
|
+
{ name: 'amount', type: 'uint160' },
|
|
54
|
+
{ name: 'expiration', type: 'uint48' },
|
|
55
|
+
{ name: 'nonce', type: 'uint48' },
|
|
56
|
+
],
|
|
57
|
+
};
|
|
58
|
+
const PERMIT_SINGLE_TYPES = {
|
|
59
|
+
PermitSingle: [
|
|
60
|
+
{ name: 'details', type: 'PermitDetails' },
|
|
61
|
+
{ name: 'spender', type: 'address' },
|
|
62
|
+
{ name: 'sigDeadline', type: 'uint256' },
|
|
63
|
+
],
|
|
64
|
+
...PERMIT_DETAILS_TYPE,
|
|
65
|
+
};
|
|
66
|
+
const PERMIT_BATCH_TYPES = {
|
|
67
|
+
PermitBatch: [
|
|
68
|
+
{ name: 'details', type: 'PermitDetails[]' },
|
|
69
|
+
{ name: 'spender', type: 'address' },
|
|
70
|
+
{ name: 'sigDeadline', type: 'uint256' },
|
|
71
|
+
],
|
|
72
|
+
...PERMIT_DETAILS_TYPE,
|
|
73
|
+
};
|
|
74
|
+
// ── SignatureTransfer EIP-712 types ─────────────────────────────────────
|
|
75
|
+
const TOKEN_PERMISSIONS_TYPE = {
|
|
76
|
+
TokenPermissions: [
|
|
77
|
+
{ name: 'token', type: 'address' },
|
|
78
|
+
{ name: 'amount', type: 'uint256' },
|
|
79
|
+
],
|
|
80
|
+
};
|
|
81
|
+
const PERMIT_TRANSFER_FROM_TYPES = {
|
|
82
|
+
PermitTransferFrom: [
|
|
83
|
+
{ name: 'permitted', type: 'TokenPermissions' },
|
|
84
|
+
{ name: 'spender', type: 'address' },
|
|
85
|
+
{ name: 'nonce', type: 'uint256' },
|
|
86
|
+
{ name: 'deadline', type: 'uint256' },
|
|
87
|
+
],
|
|
88
|
+
...TOKEN_PERMISSIONS_TYPE,
|
|
89
|
+
};
|
|
90
|
+
const PERMIT_BATCH_TRANSFER_FROM_TYPES = {
|
|
91
|
+
PermitBatchTransferFrom: [
|
|
92
|
+
{ name: 'permitted', type: 'TokenPermissions[]' },
|
|
93
|
+
{ name: 'spender', type: 'address' },
|
|
94
|
+
{ name: 'nonce', type: 'uint256' },
|
|
95
|
+
{ name: 'deadline', type: 'uint256' },
|
|
96
|
+
],
|
|
97
|
+
...TOKEN_PERMISSIONS_TYPE,
|
|
98
|
+
};
|
|
99
|
+
// ============================================================================
|
|
100
|
+
// Permit2Client
|
|
101
|
+
// ============================================================================
|
|
102
|
+
export class Permit2Client {
|
|
103
|
+
wallet;
|
|
104
|
+
publicClient;
|
|
105
|
+
chainId;
|
|
106
|
+
constructor(config) {
|
|
107
|
+
if (!config.wallet) {
|
|
108
|
+
throw new ClawnchDeployError(ClawnchErrorCode.WALLET_NOT_CONFIGURED, 'Wallet client is required for Permit2Client');
|
|
109
|
+
}
|
|
110
|
+
this.wallet = config.wallet;
|
|
111
|
+
this.publicClient = config.publicClient;
|
|
112
|
+
this.chainId = config.chainId ?? 8453;
|
|
113
|
+
}
|
|
114
|
+
/** Owner address */
|
|
115
|
+
get owner() {
|
|
116
|
+
return this.wallet.account.address;
|
|
117
|
+
}
|
|
118
|
+
// ==========================================================================
|
|
119
|
+
// Step 0: Ensure ERC20 → Permit2 approval
|
|
120
|
+
// ==========================================================================
|
|
121
|
+
/**
|
|
122
|
+
* Ensure a token has approved the Permit2 contract for max spending.
|
|
123
|
+
*
|
|
124
|
+
* This is a one-time operation per token. After this, all future
|
|
125
|
+
* permits are gas-free (off-chain signatures).
|
|
126
|
+
*
|
|
127
|
+
* @returns Transaction hash if approval was needed, null if already approved
|
|
128
|
+
*/
|
|
129
|
+
async ensureTokenApproval(token) {
|
|
130
|
+
if (token === ZERO_ADDRESS)
|
|
131
|
+
return null; // native ETH
|
|
132
|
+
const currentAllowance = await this.publicClient.readContract({
|
|
133
|
+
address: token,
|
|
134
|
+
abi: erc20Abi,
|
|
135
|
+
functionName: 'allowance',
|
|
136
|
+
args: [this.owner, PERMIT2_ADDRESS],
|
|
137
|
+
});
|
|
138
|
+
// If already approved for > half of max, skip
|
|
139
|
+
if (currentAllowance > maxUint256 / 2n)
|
|
140
|
+
return null;
|
|
141
|
+
const txHash = await this.wallet.writeContract({
|
|
142
|
+
account: this.wallet.account,
|
|
143
|
+
address: token,
|
|
144
|
+
abi: erc20Abi,
|
|
145
|
+
functionName: 'approve',
|
|
146
|
+
args: [PERMIT2_ADDRESS, maxUint256],
|
|
147
|
+
chain: null,
|
|
148
|
+
});
|
|
149
|
+
await this.publicClient.waitForTransactionReceipt({ hash: txHash });
|
|
150
|
+
return txHash;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Batch-approve multiple tokens for Permit2.
|
|
154
|
+
* Only sends transactions for tokens that need approval.
|
|
155
|
+
*
|
|
156
|
+
* @returns Map of token → txHash (only tokens that needed approval)
|
|
157
|
+
*/
|
|
158
|
+
async ensureTokenApprovals(tokens) {
|
|
159
|
+
const results = new Map();
|
|
160
|
+
// Check all allowances in parallel
|
|
161
|
+
const allowances = await Promise.all(tokens.filter(t => t !== ZERO_ADDRESS).map(async (token) => {
|
|
162
|
+
const allowance = await this.publicClient.readContract({
|
|
163
|
+
address: token,
|
|
164
|
+
abi: erc20Abi,
|
|
165
|
+
functionName: 'allowance',
|
|
166
|
+
args: [this.owner, PERMIT2_ADDRESS],
|
|
167
|
+
});
|
|
168
|
+
return { token, allowance };
|
|
169
|
+
}));
|
|
170
|
+
// Approve tokens that need it (sequentially to avoid nonce issues)
|
|
171
|
+
for (const { token, allowance } of allowances) {
|
|
172
|
+
if (allowance <= maxUint256 / 2n) {
|
|
173
|
+
const txHash = await this.wallet.writeContract({
|
|
174
|
+
account: this.wallet.account,
|
|
175
|
+
address: token,
|
|
176
|
+
abi: erc20Abi,
|
|
177
|
+
functionName: 'approve',
|
|
178
|
+
args: [PERMIT2_ADDRESS, maxUint256],
|
|
179
|
+
chain: null,
|
|
180
|
+
});
|
|
181
|
+
await this.publicClient.waitForTransactionReceipt({ hash: txHash });
|
|
182
|
+
results.set(token, txHash);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return results;
|
|
186
|
+
}
|
|
187
|
+
// ==========================================================================
|
|
188
|
+
// AllowanceTransfer: Read state
|
|
189
|
+
// ==========================================================================
|
|
190
|
+
/**
|
|
191
|
+
* Read the current Permit2 allowance for a token/spender pair.
|
|
192
|
+
*/
|
|
193
|
+
async getAllowance(token, spender) {
|
|
194
|
+
const result = await this.publicClient.readContract({
|
|
195
|
+
address: PERMIT2_ADDRESS,
|
|
196
|
+
abi: Permit2ABI,
|
|
197
|
+
functionName: 'allowance',
|
|
198
|
+
args: [this.owner, token, spender],
|
|
199
|
+
});
|
|
200
|
+
return {
|
|
201
|
+
amount: result[0],
|
|
202
|
+
expiration: Number(result[1]),
|
|
203
|
+
nonce: Number(result[2]),
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Check if a Permit2 allowance is sufficient and not expired.
|
|
208
|
+
*/
|
|
209
|
+
async isAllowanceSufficient(token, spender, requiredAmount) {
|
|
210
|
+
const allowance = await this.getAllowance(token, spender);
|
|
211
|
+
const now = Math.floor(Date.now() / 1000);
|
|
212
|
+
return allowance.amount >= requiredAmount && allowance.expiration > now;
|
|
213
|
+
}
|
|
214
|
+
// ==========================================================================
|
|
215
|
+
// AllowanceTransfer: Sign PermitSingle
|
|
216
|
+
// ==========================================================================
|
|
217
|
+
/**
|
|
218
|
+
* Sign a PermitSingle for a single token → spender allowance.
|
|
219
|
+
*
|
|
220
|
+
* This is an off-chain operation (no gas). The returned signature
|
|
221
|
+
* can be submitted by the spender to claim the allowance.
|
|
222
|
+
*
|
|
223
|
+
* Used by: PositionManager (LP operations), UniversalRouter (some flows)
|
|
224
|
+
*/
|
|
225
|
+
async signPermitSingle(params) {
|
|
226
|
+
const { nonce } = await this.getAllowance(params.token, params.spender);
|
|
227
|
+
const amount = params.amount ?? maxUint160;
|
|
228
|
+
const expiration = Math.floor(Date.now() / 1000) + (params.expirationSeconds ?? DEFAULT_PERMIT_EXPIRATION);
|
|
229
|
+
const sigDeadline = BigInt(Math.floor(Date.now() / 1000) + (params.sigDeadlineSeconds ?? DEFAULT_SIG_DEADLINE));
|
|
230
|
+
const permit = {
|
|
231
|
+
details: {
|
|
232
|
+
token: params.token,
|
|
233
|
+
amount,
|
|
234
|
+
expiration,
|
|
235
|
+
nonce,
|
|
236
|
+
},
|
|
237
|
+
spender: params.spender,
|
|
238
|
+
sigDeadline,
|
|
239
|
+
};
|
|
240
|
+
const signature = await this.wallet.signTypedData({
|
|
241
|
+
account: this.wallet.account,
|
|
242
|
+
domain: getPermit2Domain(this.chainId),
|
|
243
|
+
types: PERMIT_SINGLE_TYPES,
|
|
244
|
+
primaryType: 'PermitSingle',
|
|
245
|
+
message: {
|
|
246
|
+
details: {
|
|
247
|
+
token: permit.details.token,
|
|
248
|
+
amount: permit.details.amount,
|
|
249
|
+
expiration: permit.details.expiration,
|
|
250
|
+
nonce: permit.details.nonce,
|
|
251
|
+
},
|
|
252
|
+
spender: permit.spender,
|
|
253
|
+
sigDeadline: permit.sigDeadline,
|
|
254
|
+
},
|
|
255
|
+
});
|
|
256
|
+
return { permit, signature, owner: this.owner };
|
|
257
|
+
}
|
|
258
|
+
// ==========================================================================
|
|
259
|
+
// AllowanceTransfer: Sign PermitBatch
|
|
260
|
+
// ==========================================================================
|
|
261
|
+
/**
|
|
262
|
+
* Sign a PermitBatch for multiple tokens → single spender.
|
|
263
|
+
*
|
|
264
|
+
* Used by PositionManager when minting LP with two tokens.
|
|
265
|
+
*/
|
|
266
|
+
async signPermitBatch(params) {
|
|
267
|
+
const sigDeadline = BigInt(Math.floor(Date.now() / 1000) + (params.sigDeadlineSeconds ?? DEFAULT_SIG_DEADLINE));
|
|
268
|
+
// Fetch nonces for all tokens in parallel
|
|
269
|
+
const detailsPromises = params.tokens.map(async (t) => {
|
|
270
|
+
const { nonce } = await this.getAllowance(t.token, params.spender);
|
|
271
|
+
const amount = t.amount ?? maxUint160;
|
|
272
|
+
const expiration = Math.floor(Date.now() / 1000) + (t.expirationSeconds ?? DEFAULT_PERMIT_EXPIRATION);
|
|
273
|
+
return { token: t.token, amount, expiration, nonce };
|
|
274
|
+
});
|
|
275
|
+
const details = await Promise.all(detailsPromises);
|
|
276
|
+
const permit = {
|
|
277
|
+
details,
|
|
278
|
+
spender: params.spender,
|
|
279
|
+
sigDeadline,
|
|
280
|
+
};
|
|
281
|
+
const signature = await this.wallet.signTypedData({
|
|
282
|
+
account: this.wallet.account,
|
|
283
|
+
domain: getPermit2Domain(this.chainId),
|
|
284
|
+
types: PERMIT_BATCH_TYPES,
|
|
285
|
+
primaryType: 'PermitBatch',
|
|
286
|
+
message: {
|
|
287
|
+
details: permit.details.map(d => ({
|
|
288
|
+
token: d.token,
|
|
289
|
+
amount: d.amount,
|
|
290
|
+
expiration: d.expiration,
|
|
291
|
+
nonce: d.nonce,
|
|
292
|
+
})),
|
|
293
|
+
spender: permit.spender,
|
|
294
|
+
sigDeadline: permit.sigDeadline,
|
|
295
|
+
},
|
|
296
|
+
});
|
|
297
|
+
return { permit, signature, owner: this.owner };
|
|
298
|
+
}
|
|
299
|
+
// ==========================================================================
|
|
300
|
+
// AllowanceTransfer: Submit permit on-chain
|
|
301
|
+
// ==========================================================================
|
|
302
|
+
/**
|
|
303
|
+
* Submit a signed PermitSingle to the Permit2 contract.
|
|
304
|
+
*
|
|
305
|
+
* After this, the spender can call transferFrom() on Permit2.
|
|
306
|
+
* In practice, this is often bundled in the same tx as the router call
|
|
307
|
+
* via multicall, so you may not need to call this separately.
|
|
308
|
+
*/
|
|
309
|
+
async submitPermitSingle(signed) {
|
|
310
|
+
const txHash = await this.wallet.writeContract({
|
|
311
|
+
account: this.wallet.account,
|
|
312
|
+
address: PERMIT2_ADDRESS,
|
|
313
|
+
abi: Permit2ABI,
|
|
314
|
+
functionName: 'permit',
|
|
315
|
+
args: [
|
|
316
|
+
signed.owner,
|
|
317
|
+
{
|
|
318
|
+
details: {
|
|
319
|
+
token: signed.permit.details.token,
|
|
320
|
+
amount: signed.permit.details.amount,
|
|
321
|
+
expiration: signed.permit.details.expiration,
|
|
322
|
+
nonce: signed.permit.details.nonce,
|
|
323
|
+
},
|
|
324
|
+
spender: signed.permit.spender,
|
|
325
|
+
sigDeadline: signed.permit.sigDeadline,
|
|
326
|
+
},
|
|
327
|
+
signed.signature,
|
|
328
|
+
],
|
|
329
|
+
chain: null,
|
|
330
|
+
});
|
|
331
|
+
await this.publicClient.waitForTransactionReceipt({ hash: txHash });
|
|
332
|
+
return txHash;
|
|
333
|
+
}
|
|
334
|
+
// ==========================================================================
|
|
335
|
+
// AllowanceTransfer: Direct approve (no signature, on-chain)
|
|
336
|
+
// ==========================================================================
|
|
337
|
+
/**
|
|
338
|
+
* Directly approve a spender on Permit2 (no signature, costs gas).
|
|
339
|
+
*
|
|
340
|
+
* Simpler but requires an on-chain tx. For agent wallets that control
|
|
341
|
+
* their own private key, this is often easier than signing a permit.
|
|
342
|
+
*/
|
|
343
|
+
async directApprove(token, spender, amount = maxUint160, expirationSeconds = DEFAULT_PERMIT_EXPIRATION) {
|
|
344
|
+
const expiration = Math.floor(Date.now() / 1000) + expirationSeconds;
|
|
345
|
+
const txHash = await this.wallet.writeContract({
|
|
346
|
+
account: this.wallet.account,
|
|
347
|
+
address: PERMIT2_ADDRESS,
|
|
348
|
+
abi: Permit2ABI,
|
|
349
|
+
functionName: 'approve',
|
|
350
|
+
args: [token, spender, amount, expiration],
|
|
351
|
+
chain: null,
|
|
352
|
+
});
|
|
353
|
+
await this.publicClient.waitForTransactionReceipt({ hash: txHash });
|
|
354
|
+
return txHash;
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* Direct-approve multiple tokens for a spender in sequence.
|
|
358
|
+
*/
|
|
359
|
+
async directApproveBatch(tokens, spender, amount = maxUint160, expirationSeconds = DEFAULT_PERMIT_EXPIRATION) {
|
|
360
|
+
const hashes = [];
|
|
361
|
+
for (const token of tokens) {
|
|
362
|
+
const sufficient = await this.isAllowanceSufficient(token, spender, amount);
|
|
363
|
+
if (!sufficient) {
|
|
364
|
+
const hash = await this.directApprove(token, spender, amount, expirationSeconds);
|
|
365
|
+
hashes.push(hash);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
return hashes;
|
|
369
|
+
}
|
|
370
|
+
// ==========================================================================
|
|
371
|
+
// SignatureTransfer: Sign PermitTransferFrom
|
|
372
|
+
// ==========================================================================
|
|
373
|
+
/**
|
|
374
|
+
* Sign a PermitTransferFrom for the UniversalRouter.
|
|
375
|
+
*
|
|
376
|
+
* This creates a single-use, nonce-specific permit. The router
|
|
377
|
+
* calls `permitTransferFrom()` which atomically verifies the sig
|
|
378
|
+
* and transfers the tokens.
|
|
379
|
+
*
|
|
380
|
+
* @param params.nonce - Must be an unused nonce. Use `findUnusedNonce()` to find one.
|
|
381
|
+
*/
|
|
382
|
+
async signPermitTransferFrom(params) {
|
|
383
|
+
const deadline = BigInt(Math.floor(Date.now() / 1000) + (params.deadlineSeconds ?? DEFAULT_SIG_DEADLINE));
|
|
384
|
+
const permit = {
|
|
385
|
+
permitted: { token: params.token, amount: params.amount },
|
|
386
|
+
nonce: params.nonce,
|
|
387
|
+
deadline,
|
|
388
|
+
};
|
|
389
|
+
const signature = await this.wallet.signTypedData({
|
|
390
|
+
account: this.wallet.account,
|
|
391
|
+
domain: getPermit2Domain(this.chainId),
|
|
392
|
+
types: PERMIT_TRANSFER_FROM_TYPES,
|
|
393
|
+
primaryType: 'PermitTransferFrom',
|
|
394
|
+
message: {
|
|
395
|
+
permitted: {
|
|
396
|
+
token: permit.permitted.token,
|
|
397
|
+
amount: permit.permitted.amount,
|
|
398
|
+
},
|
|
399
|
+
spender: params.spender,
|
|
400
|
+
nonce: permit.nonce,
|
|
401
|
+
deadline: permit.deadline,
|
|
402
|
+
},
|
|
403
|
+
});
|
|
404
|
+
return { permit, signature, owner: this.owner };
|
|
405
|
+
}
|
|
406
|
+
// ==========================================================================
|
|
407
|
+
// SignatureTransfer: Nonce management
|
|
408
|
+
// ==========================================================================
|
|
409
|
+
/**
|
|
410
|
+
* Check if a specific nonce has been used (SignatureTransfer).
|
|
411
|
+
*
|
|
412
|
+
* Permit2 uses a bitmap: nonce N is stored in word N/256, bit N%256.
|
|
413
|
+
*/
|
|
414
|
+
async isNonceUsed(nonce) {
|
|
415
|
+
const word = nonce / 256n;
|
|
416
|
+
const bit = nonce % 256n;
|
|
417
|
+
const bitmap = await this.publicClient.readContract({
|
|
418
|
+
address: PERMIT2_ADDRESS,
|
|
419
|
+
abi: Permit2ABI,
|
|
420
|
+
functionName: 'nonceBitmap',
|
|
421
|
+
args: [this.owner, word],
|
|
422
|
+
});
|
|
423
|
+
return (bitmap & (1n << bit)) !== 0n;
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* Find an unused nonce for SignatureTransfer.
|
|
427
|
+
*
|
|
428
|
+
* Scans from `startNonce` forward until an unused one is found.
|
|
429
|
+
* Uses bitmap reads for efficiency (checks 256 nonces per read).
|
|
430
|
+
*/
|
|
431
|
+
async findUnusedNonce(startNonce = 0n) {
|
|
432
|
+
const word = startNonce / 256n;
|
|
433
|
+
const bitmap = await this.publicClient.readContract({
|
|
434
|
+
address: PERMIT2_ADDRESS,
|
|
435
|
+
abi: Permit2ABI,
|
|
436
|
+
functionName: 'nonceBitmap',
|
|
437
|
+
args: [this.owner, word],
|
|
438
|
+
});
|
|
439
|
+
// Find first unused bit in this word
|
|
440
|
+
const startBit = startNonce % 256n;
|
|
441
|
+
for (let bit = startBit; bit < 256n; bit++) {
|
|
442
|
+
if ((bitmap & (1n << bit)) === 0n) {
|
|
443
|
+
return word * 256n + bit;
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
// All bits in this word used — try next word
|
|
447
|
+
return this.findUnusedNonce((word + 1n) * 256n);
|
|
448
|
+
}
|
|
449
|
+
// ==========================================================================
|
|
450
|
+
// Lockdown: Emergency revocation
|
|
451
|
+
// ==========================================================================
|
|
452
|
+
/**
|
|
453
|
+
* Revoke all Permit2 allowances for specific token/spender pairs.
|
|
454
|
+
*
|
|
455
|
+
* Sets amount=0 and expiration=0 for each pair. This is the
|
|
456
|
+
* emergency kill switch if you need to revoke access immediately.
|
|
457
|
+
*/
|
|
458
|
+
async lockdown(pairs) {
|
|
459
|
+
const txHash = await this.wallet.writeContract({
|
|
460
|
+
account: this.wallet.account,
|
|
461
|
+
address: PERMIT2_ADDRESS,
|
|
462
|
+
abi: Permit2ABI,
|
|
463
|
+
functionName: 'lockdown',
|
|
464
|
+
args: [pairs.map(p => ({ token: p.token, spender: p.spender }))],
|
|
465
|
+
chain: null,
|
|
466
|
+
});
|
|
467
|
+
await this.publicClient.waitForTransactionReceipt({ hash: txHash });
|
|
468
|
+
return txHash;
|
|
469
|
+
}
|
|
470
|
+
// ==========================================================================
|
|
471
|
+
// Convenience: Full permit flow for a swap
|
|
472
|
+
// ==========================================================================
|
|
473
|
+
/**
|
|
474
|
+
* Complete AllowanceTransfer flow for a single token:
|
|
475
|
+
* 1. Ensure ERC20 → Permit2 approval
|
|
476
|
+
* 2. Check if Permit2 allowance is sufficient for the spender
|
|
477
|
+
* 3. If not, sign a PermitSingle and submit it
|
|
478
|
+
*
|
|
479
|
+
* Returns the current nonce after the flow completes.
|
|
480
|
+
*/
|
|
481
|
+
async ensurePermit2Allowance(token, spender, amount) {
|
|
482
|
+
// Step 1: ERC20 → Permit2
|
|
483
|
+
const approvalTxHash = await this.ensureTokenApproval(token);
|
|
484
|
+
// Step 2: Check Permit2 → Spender
|
|
485
|
+
const sufficient = await this.isAllowanceSufficient(token, spender, amount);
|
|
486
|
+
if (sufficient) {
|
|
487
|
+
return { approvalTxHash, permitTxHash: null };
|
|
488
|
+
}
|
|
489
|
+
// Step 3: Direct approve on Permit2 (simpler for agent wallets)
|
|
490
|
+
const permitTxHash = await this.directApprove(token, spender, maxUint160);
|
|
491
|
+
return { approvalTxHash, permitTxHash };
|
|
492
|
+
}
|
|
493
|
+
/**
|
|
494
|
+
* Complete flow for two tokens (LP operations):
|
|
495
|
+
* 1. Ensure ERC20 → Permit2 for both
|
|
496
|
+
* 2. Direct-approve both on Permit2 for the spender
|
|
497
|
+
*/
|
|
498
|
+
async ensurePermit2AllowancePair(token0, token1, spender, amount0, amount1) {
|
|
499
|
+
// ERC20 approvals in parallel
|
|
500
|
+
const [token0ApprovalTx, token1ApprovalTx] = await Promise.all([
|
|
501
|
+
this.ensureTokenApproval(token0),
|
|
502
|
+
this.ensureTokenApproval(token1),
|
|
503
|
+
]);
|
|
504
|
+
// Permit2 allowances (sequential to avoid nonce issues)
|
|
505
|
+
const [suf0, suf1] = await Promise.all([
|
|
506
|
+
this.isAllowanceSufficient(token0, spender, amount0),
|
|
507
|
+
this.isAllowanceSufficient(token1, spender, amount1),
|
|
508
|
+
]);
|
|
509
|
+
let permit0Tx = null;
|
|
510
|
+
let permit1Tx = null;
|
|
511
|
+
if (!suf0) {
|
|
512
|
+
permit0Tx = await this.directApprove(token0, spender, maxUint160);
|
|
513
|
+
}
|
|
514
|
+
if (!suf1) {
|
|
515
|
+
permit1Tx = await this.directApprove(token1, spender, maxUint160);
|
|
516
|
+
}
|
|
517
|
+
return { token0ApprovalTx, token1ApprovalTx, permit0Tx, permit1Tx };
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
//# sourceMappingURL=permit2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permit2.js","sourceRoot":"","sources":["../src/permit2.ts"],"names":[],"mappings":"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"}
|