@t402/extensions 2.4.0 → 2.6.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/dist/cjs/bazaar/index.d.ts +1 -1
- package/dist/cjs/eip2612-gas-sponsoring/index.d.ts +337 -0
- package/dist/cjs/eip2612-gas-sponsoring/index.js +314 -0
- package/dist/cjs/eip2612-gas-sponsoring/index.js.map +1 -0
- package/dist/cjs/erc20-approval-gas-sponsoring/index.d.ts +316 -0
- package/dist/cjs/erc20-approval-gas-sponsoring/index.js +264 -0
- package/dist/cjs/erc20-approval-gas-sponsoring/index.js.map +1 -0
- package/dist/cjs/{index-DYNleT-u.d.ts → index-Mk5Ypp8M.d.ts} +2 -2
- package/dist/cjs/index.d.ts +4 -1
- package/dist/cjs/index.js +650 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/payment-id/index.d.ts +142 -0
- package/dist/cjs/payment-id/index.js +101 -0
- package/dist/cjs/payment-id/index.js.map +1 -0
- package/dist/cjs/sign-in-with-x/index.d.ts +2 -1
- package/dist/cjs/sign-in-with-x/index.js +55 -0
- package/dist/cjs/sign-in-with-x/index.js.map +1 -1
- package/dist/esm/bazaar/index.d.mts +1 -1
- package/dist/esm/chunk-OAWKCEAR.mjs +226 -0
- package/dist/esm/chunk-OAWKCEAR.mjs.map +1 -0
- package/dist/esm/chunk-S36A7YLQ.mjs +70 -0
- package/dist/esm/chunk-S36A7YLQ.mjs.map +1 -0
- package/dist/esm/chunk-VINC22RD.mjs +278 -0
- package/dist/esm/chunk-VINC22RD.mjs.map +1 -0
- package/dist/esm/{chunk-J3ZMNCIA.mjs → chunk-YKZ5P2JW.mjs} +56 -1
- package/dist/esm/chunk-YKZ5P2JW.mjs.map +1 -0
- package/dist/esm/eip2612-gas-sponsoring/index.d.mts +337 -0
- package/dist/esm/eip2612-gas-sponsoring/index.mjs +27 -0
- package/dist/esm/eip2612-gas-sponsoring/index.mjs.map +1 -0
- package/dist/esm/erc20-approval-gas-sponsoring/index.d.mts +316 -0
- package/dist/esm/erc20-approval-gas-sponsoring/index.mjs +31 -0
- package/dist/esm/erc20-approval-gas-sponsoring/index.mjs.map +1 -0
- package/dist/esm/{index-DYNleT-u.d.mts → index-Mk5Ypp8M.d.mts} +2 -2
- package/dist/esm/index.d.mts +4 -1
- package/dist/esm/index.mjs +67 -1
- package/dist/esm/payment-id/index.d.mts +142 -0
- package/dist/esm/payment-id/index.mjs +17 -0
- package/dist/esm/payment-id/index.mjs.map +1 -0
- package/dist/esm/sign-in-with-x/index.d.mts +2 -1
- package/dist/esm/sign-in-with-x/index.mjs +1 -1
- package/package.json +53 -16
- package/dist/esm/chunk-J3ZMNCIA.mjs.map +0 -1
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { B as BAZAAR, a as BazaarClientExtension, b as BodyDiscoveryExtension, c as BodyDiscoveryInfo, D as DiscoveryExtension, d as DiscoveryInfo, e as DiscoveryResource, f as DiscoveryResourcesResponse, L as ListDiscoveryResourcesParams, Q as QueryDiscoveryExtension, g as QueryDiscoveryInfo, V as ValidationResult, h as bazaarResourceServerExtension, i as declareDiscoveryExtension, j as extractDiscoveryInfo, k as extractDiscoveryInfoFromExtension, l as extractDiscoveryInfoV1, m as extractResourceMetadataV1, n as isDiscoverableV1, v as validateAndExtract, o as validateDiscoveryExtension, w as withBazaar } from '../index-Mk5Ypp8M.js';
|
|
2
2
|
import '@t402/core/http';
|
|
3
3
|
import '@t402/core/types';
|
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EIP-2612 Gas Sponsoring Extension Type Definitions
|
|
3
|
+
*
|
|
4
|
+
* EIP-2612 permit-based gas sponsoring for the t402 payment protocol.
|
|
5
|
+
* Allows facilitators to sponsor gas fees by having clients sign off-chain
|
|
6
|
+
* permits instead of submitting on-chain approval transactions.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Information provided by server about gas sponsoring availability.
|
|
10
|
+
*/
|
|
11
|
+
interface Eip2612GasSponsorExtensionInfo {
|
|
12
|
+
/** CAIP-2 network identifiers where gas sponsoring is available */
|
|
13
|
+
sponsoredNetworks: string[];
|
|
14
|
+
/** Maximum token amount (in base units) the sponsor will cover per permit */
|
|
15
|
+
maxAmount: string;
|
|
16
|
+
/** Default permit deadline in seconds from now */
|
|
17
|
+
permitDeadline: number;
|
|
18
|
+
/** Address of the sponsor/facilitator that will call permit + transferFrom */
|
|
19
|
+
sponsorAddress: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Gas sponsor extension declaration for server responses.
|
|
23
|
+
*/
|
|
24
|
+
interface Eip2612GasSponsorExtension {
|
|
25
|
+
/** Extension information */
|
|
26
|
+
info: Eip2612GasSponsorExtensionInfo;
|
|
27
|
+
/** JSON Schema for validation */
|
|
28
|
+
schema: object;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Complete gas sponsor payload from client including permit signature.
|
|
32
|
+
*/
|
|
33
|
+
interface Eip2612GasSponsorPayload {
|
|
34
|
+
/** CAIP-2 network identifier (must be in sponsoredNetworks) */
|
|
35
|
+
network: string;
|
|
36
|
+
/** Full hex-encoded EIP-2612 permit signature (65 bytes, r + s + v) */
|
|
37
|
+
permitSignature: string;
|
|
38
|
+
/** Token owner address (the client's wallet) */
|
|
39
|
+
owner: string;
|
|
40
|
+
/** Spender address (must match sponsorAddress) */
|
|
41
|
+
spender: string;
|
|
42
|
+
/** Token amount in base units */
|
|
43
|
+
value: string;
|
|
44
|
+
/** Unix timestamp for permit expiry */
|
|
45
|
+
deadline: number;
|
|
46
|
+
/** Recovery parameter from signature */
|
|
47
|
+
v: number;
|
|
48
|
+
/** Signature r component (32 bytes hex) */
|
|
49
|
+
r: string;
|
|
50
|
+
/** Signature s component (32 bytes hex) */
|
|
51
|
+
s: string;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Options for declaring gas sponsor extension on server.
|
|
55
|
+
*/
|
|
56
|
+
interface DeclareEip2612GasSponsorOptions {
|
|
57
|
+
/** CAIP-2 network identifiers where gas sponsoring is available */
|
|
58
|
+
sponsoredNetworks: string[];
|
|
59
|
+
/** Maximum token amount (in base units) the sponsor will cover per permit */
|
|
60
|
+
maxAmount: string;
|
|
61
|
+
/** Default permit deadline in seconds from now (defaults to 300 = 5 minutes) */
|
|
62
|
+
permitDeadline?: number;
|
|
63
|
+
/** Address of the sponsor/facilitator */
|
|
64
|
+
sponsorAddress: string;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Options for validating gas sponsor payloads.
|
|
68
|
+
*/
|
|
69
|
+
interface ValidateEip2612GasSponsorOptions {
|
|
70
|
+
/** Custom time function for testing (defaults to Date.now) */
|
|
71
|
+
now?: () => number;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Result of gas sponsor payload validation.
|
|
75
|
+
*/
|
|
76
|
+
interface Eip2612GasSponsorValidationResult {
|
|
77
|
+
/** Whether the payload is valid */
|
|
78
|
+
valid: boolean;
|
|
79
|
+
/** Error message if invalid */
|
|
80
|
+
error?: string;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Parameters for creating an EIP-2612 permit signature.
|
|
84
|
+
*/
|
|
85
|
+
interface CreatePermitParams {
|
|
86
|
+
/** EIP-712 signer interface */
|
|
87
|
+
signer: PermitSigner;
|
|
88
|
+
/** ERC-20 token contract address */
|
|
89
|
+
tokenAddress: string;
|
|
90
|
+
/** Token name (used in EIP-712 domain) */
|
|
91
|
+
tokenName: string;
|
|
92
|
+
/** Chain ID (numeric, e.g. 8453 for Base) */
|
|
93
|
+
chainId: number;
|
|
94
|
+
/** Spender address (the facilitator/sponsor) */
|
|
95
|
+
spender: string;
|
|
96
|
+
/** Token amount in base units */
|
|
97
|
+
value: string;
|
|
98
|
+
/** Unix timestamp for permit expiry */
|
|
99
|
+
deadline: number;
|
|
100
|
+
/** Current permit nonce for the owner (defaults to 0) */
|
|
101
|
+
nonce?: number;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Signer interface for EIP-2612 permit signing.
|
|
105
|
+
*/
|
|
106
|
+
interface PermitSigner {
|
|
107
|
+
/** Wallet address */
|
|
108
|
+
address: string;
|
|
109
|
+
/**
|
|
110
|
+
* Sign EIP-712 typed data and return hex-encoded signature.
|
|
111
|
+
*
|
|
112
|
+
* @param data - EIP-712 typed data to sign
|
|
113
|
+
* @returns Hex-encoded signature
|
|
114
|
+
*/
|
|
115
|
+
signTypedData(data: {
|
|
116
|
+
domain: Record<string, unknown>;
|
|
117
|
+
types: Record<string, Array<{
|
|
118
|
+
name: string;
|
|
119
|
+
type: string;
|
|
120
|
+
}>>;
|
|
121
|
+
primaryType: string;
|
|
122
|
+
message: Record<string, unknown>;
|
|
123
|
+
}): Promise<string>;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* EIP-2612 Gas Sponsoring Extension Server-Side Implementation
|
|
128
|
+
*
|
|
129
|
+
* Provides functions for servers to declare gas sponsoring requirements,
|
|
130
|
+
* parse client headers, and validate permit payloads.
|
|
131
|
+
*/
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Declares an EIP-2612 gas sponsor extension for server responses.
|
|
135
|
+
*
|
|
136
|
+
* @param options - Extension declaration options
|
|
137
|
+
* @returns Gas sponsor extension object ready for response
|
|
138
|
+
*
|
|
139
|
+
* @example
|
|
140
|
+
* ```typescript
|
|
141
|
+
* const extension = declareEip2612GasSponsorExtension({
|
|
142
|
+
* sponsoredNetworks: ["eip155:8453", "eip155:42161"],
|
|
143
|
+
* maxAmount: "1000000000",
|
|
144
|
+
* sponsorAddress: "0xFacilitator...",
|
|
145
|
+
* });
|
|
146
|
+
* ```
|
|
147
|
+
*/
|
|
148
|
+
declare function declareEip2612GasSponsorExtension(options: DeclareEip2612GasSponsorOptions): Eip2612GasSponsorExtension;
|
|
149
|
+
/**
|
|
150
|
+
* Parses an EIP-2612 gas sponsor header from client request.
|
|
151
|
+
*
|
|
152
|
+
* The header format is base64-encoded JSON.
|
|
153
|
+
*
|
|
154
|
+
* @param header - Base64-encoded gas sponsor header value
|
|
155
|
+
* @returns Parsed gas sponsor payload
|
|
156
|
+
* @throws Error if header is invalid
|
|
157
|
+
*
|
|
158
|
+
* @example
|
|
159
|
+
* ```typescript
|
|
160
|
+
* const payload = parseEip2612GasSponsorHeader(
|
|
161
|
+
* request.headers['x-t402-eip2612-gas-sponsoring']
|
|
162
|
+
* );
|
|
163
|
+
* ```
|
|
164
|
+
*/
|
|
165
|
+
declare function parseEip2612GasSponsorHeader(header: string): Eip2612GasSponsorPayload;
|
|
166
|
+
/**
|
|
167
|
+
* Validates an EIP-2612 gas sponsor payload against server extension info.
|
|
168
|
+
*
|
|
169
|
+
* @param payload - The gas sponsor payload from the client
|
|
170
|
+
* @param extensionInfo - The server's gas sponsor extension info
|
|
171
|
+
* @param options - Validation options
|
|
172
|
+
* @returns Validation result
|
|
173
|
+
*
|
|
174
|
+
* @example
|
|
175
|
+
* ```typescript
|
|
176
|
+
* const result = validateEip2612GasSponsorPayload(payload, extension.info);
|
|
177
|
+
* if (!result.valid) {
|
|
178
|
+
* throw new Error(result.error);
|
|
179
|
+
* }
|
|
180
|
+
* ```
|
|
181
|
+
*/
|
|
182
|
+
declare function validateEip2612GasSponsorPayload(payload: Eip2612GasSponsorPayload, extensionInfo: Eip2612GasSponsorExtensionInfo, options?: ValidateEip2612GasSponsorOptions): Eip2612GasSponsorValidationResult;
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* EIP-2612 Gas Sponsoring Extension Client-Side Implementation
|
|
186
|
+
*
|
|
187
|
+
* Provides functions for clients to create EIP-2612 permit signatures
|
|
188
|
+
* and encode gas sponsor payloads for transmission.
|
|
189
|
+
*/
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Extension key for EIP-2612 gas sponsoring in payment requirements.
|
|
193
|
+
*/
|
|
194
|
+
declare const EIP2612_GAS_SPONSOR_EXTENSION_KEY = "eip2612GasSponsoring";
|
|
195
|
+
/**
|
|
196
|
+
* HTTP header name for EIP-2612 gas sponsor payload.
|
|
197
|
+
*/
|
|
198
|
+
declare const EIP2612_GAS_SPONSOR_HEADER_NAME = "X-T402-EIP2612-Gas-Sponsoring";
|
|
199
|
+
/**
|
|
200
|
+
* Creates an EIP-2612 permit signature using EIP-712 typed data signing.
|
|
201
|
+
*
|
|
202
|
+
* @param params - Permit signing parameters
|
|
203
|
+
* @returns Permit data including the signature components
|
|
204
|
+
*
|
|
205
|
+
* @example
|
|
206
|
+
* ```typescript
|
|
207
|
+
* const permit = await createPermitSignature({
|
|
208
|
+
* signer: wallet,
|
|
209
|
+
* tokenAddress: "0xUSDT...",
|
|
210
|
+
* tokenName: "Tether USD",
|
|
211
|
+
* chainId: 8453,
|
|
212
|
+
* spender: facilitatorAddress,
|
|
213
|
+
* value: "1000000",
|
|
214
|
+
* deadline: Math.floor(Date.now() / 1000) + 300,
|
|
215
|
+
* });
|
|
216
|
+
* ```
|
|
217
|
+
*/
|
|
218
|
+
declare function createPermitSignature(params: CreatePermitParams): Promise<{
|
|
219
|
+
owner: string;
|
|
220
|
+
spender: string;
|
|
221
|
+
value: string;
|
|
222
|
+
deadline: number;
|
|
223
|
+
v: number;
|
|
224
|
+
r: string;
|
|
225
|
+
s: string;
|
|
226
|
+
permitSignature: string;
|
|
227
|
+
}>;
|
|
228
|
+
/**
|
|
229
|
+
* Creates a gas sponsor payload from permit data and network.
|
|
230
|
+
*
|
|
231
|
+
* @param permit - Permit signature data from createPermitSignature
|
|
232
|
+
* @param network - CAIP-2 network identifier (e.g., "eip155:8453")
|
|
233
|
+
* @returns Gas sponsor payload ready for header encoding
|
|
234
|
+
*
|
|
235
|
+
* @example
|
|
236
|
+
* ```typescript
|
|
237
|
+
* const payload = createEip2612GasSponsorPayload(permit, "eip155:8453");
|
|
238
|
+
* ```
|
|
239
|
+
*/
|
|
240
|
+
declare function createEip2612GasSponsorPayload(permit: {
|
|
241
|
+
owner: string;
|
|
242
|
+
spender: string;
|
|
243
|
+
value: string;
|
|
244
|
+
deadline: number;
|
|
245
|
+
v: number;
|
|
246
|
+
r: string;
|
|
247
|
+
s: string;
|
|
248
|
+
permitSignature: string;
|
|
249
|
+
}, network: string): Eip2612GasSponsorPayload;
|
|
250
|
+
/**
|
|
251
|
+
* Encodes a gas sponsor payload for transmission in HTTP header.
|
|
252
|
+
*
|
|
253
|
+
* @param payload - The gas sponsor payload to encode
|
|
254
|
+
* @returns Base64-encoded JSON string
|
|
255
|
+
*
|
|
256
|
+
* @example
|
|
257
|
+
* ```typescript
|
|
258
|
+
* const header = encodeEip2612GasSponsorHeader(payload);
|
|
259
|
+
* fetch(url, {
|
|
260
|
+
* headers: { [EIP2612_GAS_SPONSOR_HEADER_NAME]: header }
|
|
261
|
+
* });
|
|
262
|
+
* ```
|
|
263
|
+
*/
|
|
264
|
+
declare function encodeEip2612GasSponsorHeader(payload: Eip2612GasSponsorPayload): string;
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* EIP-2612 Gas Sponsoring Extension Facilitator-Side Implementation
|
|
268
|
+
*
|
|
269
|
+
* Provides functions for facilitators to extract permit data from payment
|
|
270
|
+
* extensions, validate permits, and prepare on-chain submission.
|
|
271
|
+
*/
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Extracts the EIP-2612 gas sponsor payload from payment extensions.
|
|
275
|
+
*
|
|
276
|
+
* @param extensions - The extensions map from a PaymentPayload
|
|
277
|
+
* @returns The gas sponsor payload if present, or null
|
|
278
|
+
*
|
|
279
|
+
* @example
|
|
280
|
+
* ```typescript
|
|
281
|
+
* const permit = extractEip2612GasSponsorPayload(paymentPayload.extensions);
|
|
282
|
+
* if (permit) {
|
|
283
|
+
* // Submit permit tx then settle via Permit2
|
|
284
|
+
* }
|
|
285
|
+
* ```
|
|
286
|
+
*/
|
|
287
|
+
declare function extractEip2612GasSponsorPayload(extensions: Record<string, unknown> | undefined): Eip2612GasSponsorPayload | null;
|
|
288
|
+
/**
|
|
289
|
+
* Validates and extracts the EIP-2612 gas sponsor payload in one step.
|
|
290
|
+
*
|
|
291
|
+
* This is a convenience function for facilitators that combines extraction
|
|
292
|
+
* and validation against the server's extension info.
|
|
293
|
+
*
|
|
294
|
+
* @param extensions - The extensions map from a PaymentPayload
|
|
295
|
+
* @param extensionInfo - The server's gas sponsor extension info
|
|
296
|
+
* @returns Validation result with the extracted payload if valid
|
|
297
|
+
*
|
|
298
|
+
* @example
|
|
299
|
+
* ```typescript
|
|
300
|
+
* const result = validateAndExtractPermit(
|
|
301
|
+
* paymentPayload.extensions,
|
|
302
|
+
* extensionInfo
|
|
303
|
+
* );
|
|
304
|
+
* if (result.valid && result.payload) {
|
|
305
|
+
* // Submit permit() on token contract, then settle via Permit2
|
|
306
|
+
* }
|
|
307
|
+
* ```
|
|
308
|
+
*/
|
|
309
|
+
declare function validateAndExtractPermit(extensions: Record<string, unknown> | undefined, extensionInfo: Eip2612GasSponsorExtensionInfo): Eip2612GasSponsorValidationResult & {
|
|
310
|
+
payload?: Eip2612GasSponsorPayload;
|
|
311
|
+
};
|
|
312
|
+
/**
|
|
313
|
+
* Builds the EIP-2612 permit function call data for on-chain submission.
|
|
314
|
+
*
|
|
315
|
+
* Returns the ABI-encoded parameters needed to call `permit(owner, spender, value, deadline, v, r, s)`
|
|
316
|
+
* on the token contract.
|
|
317
|
+
*
|
|
318
|
+
* @param payload - The validated gas sponsor payload
|
|
319
|
+
* @returns Object with the permit call parameters
|
|
320
|
+
*
|
|
321
|
+
* @example
|
|
322
|
+
* ```typescript
|
|
323
|
+
* const permitCall = buildPermitCallData(payload);
|
|
324
|
+
* // Use permitCall with your preferred web3 library to submit the tx
|
|
325
|
+
* ```
|
|
326
|
+
*/
|
|
327
|
+
declare function buildPermitCallData(payload: Eip2612GasSponsorPayload): {
|
|
328
|
+
owner: string;
|
|
329
|
+
spender: string;
|
|
330
|
+
value: string;
|
|
331
|
+
deadline: number;
|
|
332
|
+
v: number;
|
|
333
|
+
r: string;
|
|
334
|
+
s: string;
|
|
335
|
+
};
|
|
336
|
+
|
|
337
|
+
export { type CreatePermitParams, type DeclareEip2612GasSponsorOptions, EIP2612_GAS_SPONSOR_EXTENSION_KEY, EIP2612_GAS_SPONSOR_HEADER_NAME, type Eip2612GasSponsorExtension, type Eip2612GasSponsorExtensionInfo, type Eip2612GasSponsorPayload, type Eip2612GasSponsorValidationResult, type PermitSigner, type ValidateEip2612GasSponsorOptions, buildPermitCallData, createEip2612GasSponsorPayload, createPermitSignature, declareEip2612GasSponsorExtension, encodeEip2612GasSponsorHeader, extractEip2612GasSponsorPayload, parseEip2612GasSponsorHeader, validateAndExtractPermit, validateEip2612GasSponsorPayload };
|
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/eip2612-gas-sponsoring/index.ts
|
|
21
|
+
var eip2612_gas_sponsoring_exports = {};
|
|
22
|
+
__export(eip2612_gas_sponsoring_exports, {
|
|
23
|
+
EIP2612_GAS_SPONSOR_EXTENSION_KEY: () => EIP2612_GAS_SPONSOR_EXTENSION_KEY,
|
|
24
|
+
EIP2612_GAS_SPONSOR_HEADER_NAME: () => EIP2612_GAS_SPONSOR_HEADER_NAME,
|
|
25
|
+
buildPermitCallData: () => buildPermitCallData,
|
|
26
|
+
createEip2612GasSponsorPayload: () => createEip2612GasSponsorPayload,
|
|
27
|
+
createPermitSignature: () => createPermitSignature,
|
|
28
|
+
declareEip2612GasSponsorExtension: () => declareEip2612GasSponsorExtension,
|
|
29
|
+
encodeEip2612GasSponsorHeader: () => encodeEip2612GasSponsorHeader,
|
|
30
|
+
extractEip2612GasSponsorPayload: () => extractEip2612GasSponsorPayload,
|
|
31
|
+
parseEip2612GasSponsorHeader: () => parseEip2612GasSponsorHeader,
|
|
32
|
+
validateAndExtractPermit: () => validateAndExtractPermit,
|
|
33
|
+
validateEip2612GasSponsorPayload: () => validateEip2612GasSponsorPayload
|
|
34
|
+
});
|
|
35
|
+
module.exports = __toCommonJS(eip2612_gas_sponsoring_exports);
|
|
36
|
+
|
|
37
|
+
// src/eip2612-gas-sponsoring/server.ts
|
|
38
|
+
var EIP2612_GAS_SPONSOR_SCHEMA = {
|
|
39
|
+
type: "object",
|
|
40
|
+
required: ["network", "permitSignature", "owner", "spender", "value", "deadline", "v", "r", "s"],
|
|
41
|
+
properties: {
|
|
42
|
+
network: { type: "string" },
|
|
43
|
+
permitSignature: { type: "string" },
|
|
44
|
+
owner: { type: "string" },
|
|
45
|
+
spender: { type: "string" },
|
|
46
|
+
value: { type: "string" },
|
|
47
|
+
deadline: { type: "number" },
|
|
48
|
+
v: { type: "number" },
|
|
49
|
+
r: { type: "string" },
|
|
50
|
+
s: { type: "string" }
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
function declareEip2612GasSponsorExtension(options) {
|
|
54
|
+
const info = {
|
|
55
|
+
sponsoredNetworks: options.sponsoredNetworks,
|
|
56
|
+
maxAmount: options.maxAmount,
|
|
57
|
+
permitDeadline: options.permitDeadline ?? 300,
|
|
58
|
+
sponsorAddress: options.sponsorAddress
|
|
59
|
+
};
|
|
60
|
+
return {
|
|
61
|
+
info,
|
|
62
|
+
schema: EIP2612_GAS_SPONSOR_SCHEMA
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
function parseEip2612GasSponsorHeader(header) {
|
|
66
|
+
if (!header) {
|
|
67
|
+
throw new Error("Missing EIP-2612 gas sponsor header");
|
|
68
|
+
}
|
|
69
|
+
try {
|
|
70
|
+
const decoded = Buffer.from(header, "base64").toString("utf-8");
|
|
71
|
+
const payload = JSON.parse(decoded);
|
|
72
|
+
const required = [
|
|
73
|
+
"network",
|
|
74
|
+
"permitSignature",
|
|
75
|
+
"owner",
|
|
76
|
+
"spender",
|
|
77
|
+
"value",
|
|
78
|
+
"deadline",
|
|
79
|
+
"v",
|
|
80
|
+
"r",
|
|
81
|
+
"s"
|
|
82
|
+
];
|
|
83
|
+
for (const field of required) {
|
|
84
|
+
if (!(field in payload)) {
|
|
85
|
+
throw new Error(`Missing required field: ${field}`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return payload;
|
|
89
|
+
} catch (error) {
|
|
90
|
+
if (error instanceof SyntaxError) {
|
|
91
|
+
throw new Error("Invalid EIP-2612 gas sponsor header: malformed JSON");
|
|
92
|
+
}
|
|
93
|
+
throw error;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
function validateEip2612GasSponsorPayload(payload, extensionInfo, options = {}) {
|
|
97
|
+
const now = options.now ? options.now() : Date.now();
|
|
98
|
+
const nowSeconds = Math.floor(now / 1e3);
|
|
99
|
+
if (!extensionInfo.sponsoredNetworks.includes(payload.network)) {
|
|
100
|
+
return {
|
|
101
|
+
valid: false,
|
|
102
|
+
error: `Network ${payload.network} is not in sponsored networks: ${extensionInfo.sponsoredNetworks.join(", ")}`
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
const payloadValue = BigInt(payload.value);
|
|
106
|
+
const maxAmount = BigInt(extensionInfo.maxAmount);
|
|
107
|
+
if (payloadValue > maxAmount) {
|
|
108
|
+
return {
|
|
109
|
+
valid: false,
|
|
110
|
+
error: `Value ${payload.value} exceeds maximum amount ${extensionInfo.maxAmount}`
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
if (payload.deadline <= nowSeconds) {
|
|
114
|
+
return {
|
|
115
|
+
valid: false,
|
|
116
|
+
error: "Permit deadline has expired"
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
const maxDeadline = nowSeconds + extensionInfo.permitDeadline;
|
|
120
|
+
if (payload.deadline > maxDeadline) {
|
|
121
|
+
return {
|
|
122
|
+
valid: false,
|
|
123
|
+
error: `Permit deadline ${payload.deadline} exceeds maximum allowed deadline ${maxDeadline}`
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
if (payload.spender.toLowerCase() !== extensionInfo.sponsorAddress.toLowerCase()) {
|
|
127
|
+
return {
|
|
128
|
+
valid: false,
|
|
129
|
+
error: `Spender ${payload.spender} does not match sponsor address ${extensionInfo.sponsorAddress}`
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
const sigHex = payload.permitSignature.startsWith("0x") ? payload.permitSignature.slice(2) : payload.permitSignature;
|
|
133
|
+
if (sigHex.length !== 130) {
|
|
134
|
+
return {
|
|
135
|
+
valid: false,
|
|
136
|
+
error: `Invalid permit signature length: expected 130 hex chars, got ${sigHex.length}`
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
if (payload.v !== 27 && payload.v !== 28) {
|
|
140
|
+
return {
|
|
141
|
+
valid: false,
|
|
142
|
+
error: `Invalid v value: expected 27 or 28, got ${payload.v}`
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
const rHex = payload.r.startsWith("0x") ? payload.r.slice(2) : payload.r;
|
|
146
|
+
if (rHex.length !== 64) {
|
|
147
|
+
return {
|
|
148
|
+
valid: false,
|
|
149
|
+
error: `Invalid r length: expected 64 hex chars, got ${rHex.length}`
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
const sHex = payload.s.startsWith("0x") ? payload.s.slice(2) : payload.s;
|
|
153
|
+
if (sHex.length !== 64) {
|
|
154
|
+
return {
|
|
155
|
+
valid: false,
|
|
156
|
+
error: `Invalid s length: expected 64 hex chars, got ${sHex.length}`
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
return { valid: true };
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// src/eip2612-gas-sponsoring/client.ts
|
|
163
|
+
var EIP2612_GAS_SPONSOR_EXTENSION_KEY = "eip2612GasSponsoring";
|
|
164
|
+
var EIP2612_GAS_SPONSOR_HEADER_NAME = "X-T402-EIP2612-Gas-Sponsoring";
|
|
165
|
+
async function createPermitSignature(params) {
|
|
166
|
+
const { signer, tokenAddress, tokenName, chainId, spender, value, deadline, nonce = 0 } = params;
|
|
167
|
+
const domain = {
|
|
168
|
+
name: tokenName,
|
|
169
|
+
version: "1",
|
|
170
|
+
chainId,
|
|
171
|
+
verifyingContract: tokenAddress
|
|
172
|
+
};
|
|
173
|
+
const types = {
|
|
174
|
+
Permit: [
|
|
175
|
+
{ name: "owner", type: "address" },
|
|
176
|
+
{ name: "spender", type: "address" },
|
|
177
|
+
{ name: "value", type: "uint256" },
|
|
178
|
+
{ name: "nonce", type: "uint256" },
|
|
179
|
+
{ name: "deadline", type: "uint256" }
|
|
180
|
+
]
|
|
181
|
+
};
|
|
182
|
+
const message = {
|
|
183
|
+
owner: signer.address,
|
|
184
|
+
spender,
|
|
185
|
+
value,
|
|
186
|
+
nonce,
|
|
187
|
+
deadline
|
|
188
|
+
};
|
|
189
|
+
const signature = await signer.signTypedData({
|
|
190
|
+
domain,
|
|
191
|
+
types,
|
|
192
|
+
primaryType: "Permit",
|
|
193
|
+
message
|
|
194
|
+
});
|
|
195
|
+
const sigHex = signature.startsWith("0x") ? signature.slice(2) : signature;
|
|
196
|
+
if (sigHex.length !== 130) {
|
|
197
|
+
throw new Error(`Invalid signature length: expected 130 hex chars, got ${sigHex.length}`);
|
|
198
|
+
}
|
|
199
|
+
const r = "0x" + sigHex.slice(0, 64);
|
|
200
|
+
const s = "0x" + sigHex.slice(64, 128);
|
|
201
|
+
let v = parseInt(sigHex.slice(128, 130), 16);
|
|
202
|
+
if (v < 27) {
|
|
203
|
+
v += 27;
|
|
204
|
+
}
|
|
205
|
+
return {
|
|
206
|
+
owner: signer.address,
|
|
207
|
+
spender,
|
|
208
|
+
value,
|
|
209
|
+
deadline,
|
|
210
|
+
v,
|
|
211
|
+
r,
|
|
212
|
+
s,
|
|
213
|
+
permitSignature: signature.startsWith("0x") ? signature : "0x" + signature
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
function createEip2612GasSponsorPayload(permit, network) {
|
|
217
|
+
return {
|
|
218
|
+
network,
|
|
219
|
+
permitSignature: permit.permitSignature,
|
|
220
|
+
owner: permit.owner,
|
|
221
|
+
spender: permit.spender,
|
|
222
|
+
value: permit.value,
|
|
223
|
+
deadline: permit.deadline,
|
|
224
|
+
v: permit.v,
|
|
225
|
+
r: permit.r,
|
|
226
|
+
s: permit.s
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
function encodeEip2612GasSponsorHeader(payload) {
|
|
230
|
+
const json = JSON.stringify(payload);
|
|
231
|
+
if (typeof Buffer !== "undefined") {
|
|
232
|
+
return Buffer.from(json, "utf-8").toString("base64");
|
|
233
|
+
}
|
|
234
|
+
return btoa(json);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// src/eip2612-gas-sponsoring/facilitator.ts
|
|
238
|
+
function extractEip2612GasSponsorPayload(extensions) {
|
|
239
|
+
if (!extensions) {
|
|
240
|
+
return null;
|
|
241
|
+
}
|
|
242
|
+
const raw = extensions[EIP2612_GAS_SPONSOR_EXTENSION_KEY];
|
|
243
|
+
if (!raw || typeof raw !== "object") {
|
|
244
|
+
return null;
|
|
245
|
+
}
|
|
246
|
+
const payload = raw;
|
|
247
|
+
const required = [
|
|
248
|
+
"network",
|
|
249
|
+
"permitSignature",
|
|
250
|
+
"owner",
|
|
251
|
+
"spender",
|
|
252
|
+
"value",
|
|
253
|
+
"deadline",
|
|
254
|
+
"v",
|
|
255
|
+
"r",
|
|
256
|
+
"s"
|
|
257
|
+
];
|
|
258
|
+
for (const field of required) {
|
|
259
|
+
if (!(field in payload)) {
|
|
260
|
+
return null;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
return {
|
|
264
|
+
network: payload.network,
|
|
265
|
+
permitSignature: payload.permitSignature,
|
|
266
|
+
owner: payload.owner,
|
|
267
|
+
spender: payload.spender,
|
|
268
|
+
value: payload.value,
|
|
269
|
+
deadline: payload.deadline,
|
|
270
|
+
v: payload.v,
|
|
271
|
+
r: payload.r,
|
|
272
|
+
s: payload.s
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
function validateAndExtractPermit(extensions, extensionInfo) {
|
|
276
|
+
const payload = extractEip2612GasSponsorPayload(extensions);
|
|
277
|
+
if (!payload) {
|
|
278
|
+
return {
|
|
279
|
+
valid: false,
|
|
280
|
+
error: `Missing or invalid ${EIP2612_GAS_SPONSOR_EXTENSION_KEY} extension in payment`
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
const result = validateEip2612GasSponsorPayload(payload, extensionInfo);
|
|
284
|
+
if (!result.valid) {
|
|
285
|
+
return result;
|
|
286
|
+
}
|
|
287
|
+
return { valid: true, payload };
|
|
288
|
+
}
|
|
289
|
+
function buildPermitCallData(payload) {
|
|
290
|
+
return {
|
|
291
|
+
owner: payload.owner,
|
|
292
|
+
spender: payload.spender,
|
|
293
|
+
value: payload.value,
|
|
294
|
+
deadline: payload.deadline,
|
|
295
|
+
v: payload.v,
|
|
296
|
+
r: payload.r,
|
|
297
|
+
s: payload.s
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
301
|
+
0 && (module.exports = {
|
|
302
|
+
EIP2612_GAS_SPONSOR_EXTENSION_KEY,
|
|
303
|
+
EIP2612_GAS_SPONSOR_HEADER_NAME,
|
|
304
|
+
buildPermitCallData,
|
|
305
|
+
createEip2612GasSponsorPayload,
|
|
306
|
+
createPermitSignature,
|
|
307
|
+
declareEip2612GasSponsorExtension,
|
|
308
|
+
encodeEip2612GasSponsorHeader,
|
|
309
|
+
extractEip2612GasSponsorPayload,
|
|
310
|
+
parseEip2612GasSponsorHeader,
|
|
311
|
+
validateAndExtractPermit,
|
|
312
|
+
validateEip2612GasSponsorPayload
|
|
313
|
+
});
|
|
314
|
+
//# sourceMappingURL=index.js.map
|