@armory-sh/client-web3 0.2.10 → 0.2.12

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.
Files changed (3) hide show
  1. package/dist/index.d.ts +12 -156
  2. package/dist/index.js +66 -394
  3. package/package.json +2 -2
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Web3BaseWalletAccount, Web3BaseWallet } from 'web3-types';
2
- import { PaymentPayloadV1, PaymentPayloadV2, CustomToken, NetworkConfig, PaymentRequirementsV1, PaymentRequirementsV2, SettlementResponseV1, SettlementResponseV2, X402PaymentRequiredV1, PaymentRequiredV2, X402PaymentPayloadV1 } from '@armory-sh/base';
3
- export { EIP712_TYPES as CORE_EIP712_TYPES, USDC_DOMAIN as CORE_USDC_DOMAIN, NETWORKS, NetworkConfig, PaymentPayload, PaymentPayloadV1, PaymentPayloadV2, PaymentRequirements, PaymentRequirementsV1, PaymentRequirementsV2, SettlementResponse, SettlementResponseV1, SettlementResponseV2, V1_HEADERS, V2_HEADERS, combineSignatureV2, createEIP712Domain as createCoreEIP712Domain, createTransferWithAuthorization as createCoreTransferWithAuthorization, createNonce, decodePaymentV1, decodePaymentV2, decodeSettlementV1, decodeSettlementV2, encodePaymentV1, encodePaymentV2, encodeSettlementV1, encodeSettlementV2, getMainnets, getNetworkByChainId, getNetworkConfig, getPaymentHeaderName, getPaymentRequiredHeaderName, getPaymentResponseHeaderName, getPaymentVersion, getRequirementsVersion, getSettlementVersion, getTestnets, getTxHash, isSettlementSuccessful, isV1, isV2, isX402V1Payload, isX402V1Requirements, isX402V1Settlement, isX402V2Payload, isX402V2Requirements, isX402V2Settlement, parseSignatureV2, validateTransferWithAuthorization as validateCoreTransferWithAuthorization } from '@armory-sh/base';
2
+ import { NetworkConfig, CustomToken, PaymentPayloadV2, PaymentRequirementsV2, SettlementResponseV2 } from '@armory-sh/base';
3
+ export { EIP3009Authorization, PaymentPayloadV2, PaymentRequirementsV2, SchemePayloadV2, SettlementResponseV2 } from '@armory-sh/base';
4
4
 
5
5
  type Web3Account = Web3BaseWalletAccount | Web3BaseWallet<Web3BaseWalletAccount>;
6
6
  /** Token configuration - can use pre-configured tokens from @armory-sh/tokens */
@@ -8,7 +8,7 @@ type Token = CustomToken;
8
8
  interface Web3ClientConfig {
9
9
  account: Web3Account;
10
10
  network: NetworkConfig | string;
11
- version?: 1 | 2;
11
+ version?: 2;
12
12
  rpcUrl?: string;
13
13
  /** Pre-configured token object (overrides individual fields below) */
14
14
  token?: Token;
@@ -18,15 +18,12 @@ interface Web3ClientConfig {
18
18
  domainVersion?: string;
19
19
  }
20
20
  interface PaymentSignatureResult {
21
- v?: number;
22
- r?: string;
23
- s?: string;
24
21
  signature?: {
25
22
  v: number;
26
23
  r: string;
27
24
  s: string;
28
25
  };
29
- payload: PaymentPayloadV1 | PaymentPayloadV2;
26
+ payload: PaymentPayloadV2;
30
27
  }
31
28
  interface PaymentSignOptions {
32
29
  amount: string | bigint;
@@ -35,31 +32,24 @@ interface PaymentSignOptions {
35
32
  expiry?: number;
36
33
  validAfter?: number;
37
34
  }
38
- interface X402RequestContext {
39
- url: string;
40
- method: string;
41
- headers: Record<string, string> | Headers;
42
- body?: string | Record<string, unknown> | null;
43
- version: 1 | 2;
44
- }
45
35
  interface X402TransportOptions {
46
36
  client: Web3X402Client;
47
37
  autoSign?: boolean;
48
38
  maxRetries?: number;
49
39
  }
40
+ interface X402Transport {
41
+ fetch(url: string | Request, init?: RequestInit): Promise<Response>;
42
+ getClient(): Web3X402Client;
43
+ }
50
44
  interface Web3X402Client {
51
45
  fetch(url: string | Request, init?: RequestInit): Promise<Response>;
52
46
  getAccount(): Web3Account;
53
47
  getNetwork(): NetworkConfig;
54
- getVersion(): 1 | 2;
48
+ getVersion(): 2;
55
49
  signPayment(options: PaymentSignOptions): Promise<PaymentSignatureResult>;
56
50
  createPaymentHeaders(options: PaymentSignOptions): Promise<Headers>;
57
- handlePaymentRequired(requirements: PaymentRequirementsV1 | PaymentRequirementsV2): Promise<PaymentSignatureResult>;
58
- verifySettlement(response: SettlementResponseV1 | SettlementResponseV2): boolean;
59
- }
60
- interface X402Transport {
61
- fetch(url: string | Request, init?: RequestInit): Promise<Response>;
62
- getClient(): Web3X402Client;
51
+ handlePaymentRequired(requirements: PaymentRequirementsV2): Promise<PaymentSignatureResult>;
52
+ verifySettlement(response: SettlementResponseV2): boolean;
63
53
  }
64
54
  interface Web3TransferWithAuthorization {
65
55
  from: string;
@@ -76,10 +66,6 @@ interface Web3EIP712Domain {
76
66
  verifyingContract: string;
77
67
  [key: string]: string | number;
78
68
  }
79
- declare const isV1Requirements: (requirements: PaymentRequirementsV1 | PaymentRequirementsV2) => requirements is PaymentRequirementsV1;
80
- declare const isV2Requirements: (requirements: PaymentRequirementsV1 | PaymentRequirementsV2) => requirements is PaymentRequirementsV2;
81
- declare const isV1Settlement: (response: SettlementResponseV1 | SettlementResponseV2) => response is SettlementResponseV1;
82
- declare const isV2Settlement: (response: SettlementResponseV1 | SettlementResponseV2) => response is SettlementResponseV2;
83
69
 
84
70
  declare const createX402Client: (config: Web3ClientConfig) => Web3X402Client;
85
71
 
@@ -87,137 +73,7 @@ declare const createX402Client: (config: Web3ClientConfig) => Web3X402Client;
87
73
  * Create an x402 transport layer for handling payment-required responses
88
74
  */
89
75
  declare const createX402Transport: (options: X402TransportOptions) => X402Transport;
90
- /**
91
- * Create a fetch function bound to an x402 transport
92
- */
93
- declare const createFetchWithX402: (transport: X402Transport) => (url: string | Request, init?: RequestInit) => Promise<Response>;
94
-
95
- /**
96
- * X402 Protocol Detection and Parsing Functions
97
- *
98
- * Handles both x402 V1 and V2 protocol detection and parsing from HTTP responses.
99
- */
100
76
 
101
- type X402Version = 1 | 2;
102
- interface ParsedPaymentRequired {
103
- version: X402Version;
104
- requirements: PaymentRequirementsV1[] | PaymentRequirementsV2[];
105
- raw: X402PaymentRequiredV1 | PaymentRequiredV2;
106
- }
107
- /**
108
- * Detect x402 protocol version from response headers
109
- * Returns V2 if PAYMENT-REQUIRED header exists, V1 for X-PAYMENT-REQUIRED
110
- * Falls back to body detection if no headers present
111
- */
112
- declare const detectX402Version: (response: Response, fallbackVersion?: X402Version) => X402Version;
113
- /**
114
- * Detect version from a parsed payment required object
115
- */
116
- declare const detectVersionFromObject: (obj: unknown) => X402Version | null;
117
- /**
118
- * Parse PAYMENT-REQUIRED header or response body
119
- * Handles both V1 (base64 encoded) and V2 (JSON) formats
120
- */
121
- declare const parsePaymentRequired: (response: Response, version?: X402Version) => Promise<ParsedPaymentRequired>;
122
- /**
123
- * Parse payment required from header value
124
- */
125
- declare const parsePaymentRequiredFromHeader: (header: string, version: X402Version) => ParsedPaymentRequired;
126
- /**
127
- * Parse payment required from response body
128
- */
129
- declare const parsePaymentRequiredFromBody: (body: string, version: X402Version) => ParsedPaymentRequired;
130
- /**
131
- * Create x402 V1 payment payload
132
- */
133
- declare const createX402V1Payment: (params: {
134
- from: string;
135
- to: string;
136
- value: string;
137
- nonce: `0x${string}`;
138
- validAfter: string;
139
- validBefore: string;
140
- signature: `0x${string}`;
141
- network: string;
142
- }) => X402PaymentPayloadV1;
143
- /**
144
- * Create x402 V2 payment payload
145
- */
146
- declare const createX402V2Payment: (params: {
147
- from: string;
148
- to: string;
149
- value: string;
150
- nonce: `0x${string}`;
151
- validAfter: string;
152
- validBefore: string;
153
- signature: `0x${string}`;
154
- accepted: PaymentRequirementsV2;
155
- resource?: {
156
- url: string;
157
- description?: string;
158
- mimeType?: string;
159
- };
160
- }) => PaymentPayloadV2;
161
- /**
162
- * Create payment header for request
163
- */
164
- declare const createPaymentHeader: (payload: X402PaymentPayloadV1 | PaymentPayloadV2, version: X402Version) => string;
165
- /**
166
- * Get the payment header name for a version
167
- */
168
- declare const getPaymentHeader: (version: X402Version) => string;
169
- /**
170
- * Get the payment required header name for a version
171
- */
172
- declare const getPaymentRequiredHeader: (version: X402Version) => string;
173
- /**
174
- * Check if response indicates payment is required
175
- */
176
- declare const isPaymentRequiredResponse: (response: Response) => boolean;
177
- /**
178
- * Extract requirements for a specific scheme from accepts array
179
- * Uses type assertion to handle union types
180
- */
181
- declare const selectSchemeRequirements: (requirements: PaymentRequirementsV1[] | PaymentRequirementsV2[], scheme?: string) => PaymentRequirementsV1 | PaymentRequirementsV2 | undefined;
182
-
183
- declare const EIP712_TYPES: {
184
- readonly EIP712Domain: readonly [{
185
- readonly name: "name";
186
- readonly type: "string";
187
- }, {
188
- readonly name: "version";
189
- readonly type: "string";
190
- }, {
191
- readonly name: "chainId";
192
- readonly type: "uint256";
193
- }, {
194
- readonly name: "verifyingContract";
195
- readonly type: "address";
196
- }];
197
- readonly TransferWithAuthorization: readonly [{
198
- readonly name: "from";
199
- readonly type: "address";
200
- }, {
201
- readonly name: "to";
202
- readonly type: "address";
203
- }, {
204
- readonly name: "value";
205
- readonly type: "uint256";
206
- }, {
207
- readonly name: "validAfter";
208
- readonly type: "uint256";
209
- }, {
210
- readonly name: "validBefore";
211
- readonly type: "uint256";
212
- }, {
213
- readonly name: "nonce";
214
- readonly type: "uint256";
215
- }];
216
- };
217
- declare const USDC_DOMAIN: {
218
- readonly NAME: "USD Coin";
219
- readonly VERSION: "2";
220
- };
221
77
  declare const createEIP712Domain: (chainId: number | string, contractAddress: string, domainName?: string, domainVersion?: string) => Web3EIP712Domain;
222
78
  declare const createTransferWithAuthorization: (params: Web3TransferWithAuthorization) => Record<string, string>;
223
79
  declare const validateTransferWithAuthorization: (message: Web3TransferWithAuthorization) => boolean;
@@ -239,4 +95,4 @@ declare const signWithPrivateKey: (_privateKey: string, _domain: Web3EIP712Domai
239
95
  s: string;
240
96
  }>;
241
97
 
242
- export { EIP712_TYPES, type ParsedPaymentRequired, type PaymentSignOptions, type PaymentSignatureResult, type Token, USDC_DOMAIN, type Web3Account, type Web3ClientConfig, type Web3EIP712Domain, type Web3TransferWithAuthorization, type Web3X402Client, type X402RequestContext, type X402Transport, type X402TransportOptions, type X402Version, adjustVForChainId, concatenateSignature, createEIP712Domain, createFetchWithX402, createPaymentHeader, createTransferWithAuthorization, createX402Client, createX402Transport, createX402V1Payment, createX402V2Payment, detectVersionFromObject, detectX402Version, getPaymentHeader, getPaymentRequiredHeader, isPaymentRequiredResponse, isV1Requirements, isV1Settlement, isV2Requirements, isV2Settlement, parsePaymentRequired, parsePaymentRequiredFromBody, parsePaymentRequiredFromHeader, parseSignature, selectSchemeRequirements, signTypedData, signWithPrivateKey, validateTransferWithAuthorization };
98
+ export { adjustVForChainId, concatenateSignature, createEIP712Domain, createTransferWithAuthorization, createX402Client, createX402Transport, parseSignature, signTypedData, signWithPrivateKey, validateTransferWithAuthorization };
package/dist/index.js CHANGED
@@ -2,32 +2,13 @@
2
2
  import { Web3 } from "web3";
3
3
  import {
4
4
  getNetworkConfig,
5
- encodePaymentV1,
6
5
  encodePaymentV2,
7
- isX402V1Requirements,
8
- isX402V2Requirements,
6
+ networkToCaip2,
9
7
  combineSignatureV2,
10
- V1_HEADERS as V1_HEADERS2,
11
8
  V2_HEADERS as V2_HEADERS2
12
9
  } from "@armory-sh/base";
13
10
 
14
11
  // src/eip3009.ts
15
- var EIP712_TYPES = {
16
- EIP712Domain: [
17
- { name: "name", type: "string" },
18
- { name: "version", type: "string" },
19
- { name: "chainId", type: "uint256" },
20
- { name: "verifyingContract", type: "address" }
21
- ],
22
- TransferWithAuthorization: [
23
- { name: "from", type: "address" },
24
- { name: "to", type: "address" },
25
- { name: "value", type: "uint256" },
26
- { name: "validAfter", type: "uint256" },
27
- { name: "validBefore", type: "uint256" },
28
- { name: "nonce", type: "uint256" }
29
- ]
30
- };
31
12
  var USDC_DOMAIN = {
32
13
  NAME: "USD Coin",
33
14
  VERSION: "2"
@@ -125,107 +106,40 @@ var signWithPrivateKey = async (_privateKey, _domain, _message) => {
125
106
 
126
107
  // src/protocol.ts
127
108
  import {
128
- V1_HEADERS,
129
109
  V2_HEADERS,
130
- decodeX402PaymentRequiredV1,
131
- isX402V1PaymentRequired,
132
- isX402V2PaymentRequired,
133
- getPaymentRequiredHeaderName,
134
- getPaymentHeaderName
110
+ isX402V2PaymentRequired
135
111
  } from "@armory-sh/base";
136
- var detectX402Version = (response, fallbackVersion = 2) => {
137
- if (response.headers.has(V2_HEADERS.PAYMENT_REQUIRED)) {
138
- return 2;
139
- }
140
- if (response.headers.has(V1_HEADERS.PAYMENT_REQUIRED)) {
141
- return 1;
142
- }
143
- if (response.headers.has("Payment-Required")) {
144
- return 2;
145
- }
146
- return fallbackVersion;
147
- };
148
- var detectVersionFromObject = (obj) => {
149
- if (isX402V2PaymentRequired(obj)) return 2;
150
- if (isX402V1PaymentRequired(obj)) return 1;
151
- return null;
152
- };
153
- var parsePaymentRequired = async (response, version) => {
154
- const detectedVersion = version ?? detectX402Version(response);
155
- const headerName = getPaymentRequiredHeaderName(detectedVersion);
156
- const header = response.headers.get(headerName);
157
- if (header) {
158
- return parsePaymentRequiredFromHeader(header, detectedVersion);
159
- }
160
- const body = await response.clone().text();
161
- return parsePaymentRequiredFromBody(body, detectedVersion);
112
+ var detectX402Version = (_response, _fallbackVersion = 2) => {
113
+ return 2;
162
114
  };
163
- var parsePaymentRequiredFromHeader = (header, version) => {
164
- if (version === 1) {
165
- const decoded = decodeX402PaymentRequiredV1(header);
166
- return {
167
- version: 1,
168
- requirements: decoded.accepts,
169
- raw: decoded
170
- };
171
- }
172
- let parsed;
173
- try {
174
- parsed = JSON.parse(header);
175
- } catch {
176
- const decoded = Buffer.from(header, "base64").toString("utf-8");
177
- parsed = JSON.parse(decoded);
115
+ var parsePaymentRequired = async (response, _version) => {
116
+ const v2Header = response.headers.get(V2_HEADERS.PAYMENT_REQUIRED);
117
+ if (!v2Header) {
118
+ throw new Error("No PAYMENT-REQUIRED header found in V2 response");
178
119
  }
179
- return {
180
- version: 2,
181
- requirements: parsed.accepts,
182
- raw: parsed
183
- };
184
- };
185
- var parsePaymentRequiredFromBody = (body, version) => {
186
- let parsed;
187
120
  try {
188
- parsed = JSON.parse(body);
189
- } catch {
190
- const decoded = Buffer.from(body, "base64").toString("utf-8");
191
- parsed = JSON.parse(decoded);
192
- }
193
- const detectedVersion = detectVersionFromObject(parsed) ?? version;
194
- if (detectedVersion === 1 && isX402V1PaymentRequired(parsed)) {
121
+ let parsed;
122
+ try {
123
+ parsed = JSON.parse(v2Header);
124
+ } catch {
125
+ const decoded = Buffer.from(v2Header, "base64").toString("utf-8");
126
+ parsed = JSON.parse(decoded);
127
+ }
128
+ if (!isX402V2PaymentRequired(parsed)) {
129
+ throw new Error("Invalid x402 V2 payment required format");
130
+ }
131
+ if (!parsed.accepts || parsed.accepts.length === 0) {
132
+ throw new Error("No payment requirements found in accepts array");
133
+ }
195
134
  return {
196
- version: 1,
135
+ version: 2,
197
136
  requirements: parsed.accepts,
198
137
  raw: parsed
199
138
  };
139
+ } catch (error) {
140
+ if (error instanceof Error) throw error;
141
+ throw new Error(`Failed to parse V2 PAYMENT-REQUIRED header: ${error}`);
200
142
  }
201
- if (detectedVersion === 2 && isX402V2PaymentRequired(parsed)) {
202
- const v2Parsed = parsed;
203
- return {
204
- version: 2,
205
- requirements: v2Parsed.accepts,
206
- raw: v2Parsed
207
- };
208
- }
209
- throw new Error("Unable to parse payment required response");
210
- };
211
- var createX402V1Payment = (params) => {
212
- const authorization = {
213
- from: params.from,
214
- to: params.to,
215
- value: params.value,
216
- validAfter: params.validAfter,
217
- validBefore: params.validBefore,
218
- nonce: params.nonce
219
- };
220
- return {
221
- x402Version: 1,
222
- scheme: "exact",
223
- network: params.network,
224
- payload: {
225
- signature: params.signature,
226
- authorization
227
- }
228
- };
229
143
  };
230
144
  var createX402V2Payment = (params) => {
231
145
  const authorization = {
@@ -240,37 +154,20 @@ var createX402V2Payment = (params) => {
240
154
  x402Version: 2,
241
155
  scheme: params.accepted.scheme,
242
156
  network: params.accepted.network,
243
- resource: params.resource,
244
157
  payload: {
245
158
  signature: params.signature,
246
159
  authorization
247
- }
160
+ },
161
+ resource: params.resource
248
162
  };
249
163
  };
250
- var createPaymentHeader = (payload, version) => {
251
- const headerName = getPaymentHeaderName(version);
252
- const encoded = Buffer.from(JSON.stringify(payload)).toString("base64");
253
- return encoded;
254
- };
255
- var getPaymentHeader = (version) => {
256
- return getPaymentHeaderName(version);
257
- };
258
- var getPaymentRequiredHeader = (version) => {
259
- return getPaymentRequiredHeaderName(version);
260
- };
261
164
  var isPaymentRequiredResponse = (response) => {
262
165
  if (response.status === 402) return true;
263
- return response.headers.has(V1_HEADERS.PAYMENT_REQUIRED) || response.headers.has(V2_HEADERS.PAYMENT_REQUIRED) || response.headers.has("Payment-Required");
264
- };
265
- var selectSchemeRequirements = (requirements, scheme = "exact") => {
266
- return requirements.find(
267
- (r) => "scheme" in r && r.scheme === scheme
268
- );
166
+ return response.headers.has(V2_HEADERS.PAYMENT_REQUIRED);
269
167
  };
270
168
 
271
169
  // src/client.ts
272
170
  var DEFAULT_EXPIRY_SECONDS = 3600;
273
- var DEFAULT_VALID_AFTER = 0;
274
171
  var extractDomainConfig = (config) => {
275
172
  if (config.token) {
276
173
  return {
@@ -334,64 +231,6 @@ var signTypedDataWrapper = async (account, domain, message) => {
334
231
  }
335
232
  throw new Error("Account does not support EIP-712 signing.");
336
233
  };
337
- var signPaymentV1 = async (state, params) => {
338
- const { from, to, amount, nonce, expiry, validAfter } = params;
339
- const { network, domainName, domainVersion } = state;
340
- const domain = createEIP712Domain(network.chainId, network.usdcAddress, domainName, domainVersion);
341
- const message = createTransferWithAuthorization({
342
- from,
343
- to,
344
- value: amount,
345
- validAfter: `0x${validAfter.toString(16)}`,
346
- validBefore: `0x${expiry.toString(16)}`,
347
- nonce: `0x${nonce}`
348
- });
349
- const signature = await signTypedDataWrapper(state.account, domain, message);
350
- const legacyPayload = {
351
- from,
352
- to,
353
- amount,
354
- nonce,
355
- expiry,
356
- v: signature.v,
357
- r: signature.r,
358
- s: signature.s,
359
- chainId: network.chainId,
360
- contractAddress: network.usdcAddress,
361
- network: network.name.toLowerCase().replace(" ", "-")
362
- };
363
- return { v: signature.v, r: signature.r, s: signature.s, payload: legacyPayload };
364
- };
365
- var handlePaymentRequirements = async (requirements, state) => {
366
- const version = detectVersionFromRequirements(requirements);
367
- if (version === 1) {
368
- const req2 = requirements;
369
- if (isX402V1Requirements(req2)) {
370
- const x402Req = req2;
371
- return signPayment({
372
- amount: x402Req.maxAmountRequired,
373
- to: x402Req.payTo
374
- }, state);
375
- }
376
- const legacyReq = req2;
377
- return signPayment({
378
- amount: legacyReq.amount,
379
- to: legacyReq.payTo,
380
- expiry: legacyReq.expiry
381
- }, state);
382
- }
383
- const req = requirements;
384
- const to = typeof req.payTo === "string" ? req.payTo : "0x0000000000000000000000000000000000000000";
385
- const from = getAddress(state.account);
386
- return signPaymentV2(state, {
387
- from,
388
- to,
389
- amount: req.amount,
390
- nonce: crypto.randomUUID(),
391
- expiry: Math.floor(Date.now() / 1e3) + DEFAULT_EXPIRY_SECONDS,
392
- accepted: req
393
- });
394
- };
395
234
  var signPaymentV2 = async (state, params) => {
396
235
  const { from, to, amount, nonce, expiry, accepted } = params;
397
236
  const { network, domainName, domainVersion } = state;
@@ -408,7 +247,7 @@ var signPaymentV2 = async (state, params) => {
408
247
  const combinedSig = combineSignatureV2(signature.v, signature.r, signature.s);
409
248
  const defaultAccepted = accepted ?? {
410
249
  scheme: "exact",
411
- network: network.caip2Id,
250
+ network: networkToCaip2(network.name),
412
251
  amount,
413
252
  asset: network.usdcAddress,
414
253
  payTo: to,
@@ -422,6 +261,7 @@ var signPaymentV2 = async (state, params) => {
422
261
  validAfter: "0x0",
423
262
  validBefore: `0x${expiry.toString(16)}`,
424
263
  signature: combinedSig,
264
+ network: defaultAccepted.network,
425
265
  accepted: defaultAccepted
426
266
  });
427
267
  return {
@@ -440,32 +280,23 @@ var createX402Client = (config) => {
440
280
  if (response.status === 402) {
441
281
  const version = detectX402Version(response, state.version);
442
282
  const parsed = await parsePaymentRequired(response, version);
443
- const selectedRequirements = selectSchemeRequirements(parsed.requirements, "exact");
283
+ const selectedRequirements = parsed.requirements[0];
444
284
  if (!selectedRequirements) {
445
285
  throw new Error("No supported payment scheme found in requirements");
446
286
  }
447
287
  const from = getAddress(state.account);
448
- let result;
449
- if (version === 1) {
450
- result = await handlePaymentRequirements(selectedRequirements, state);
451
- } else {
452
- const req = selectedRequirements;
453
- const to = typeof req.payTo === "string" ? req.payTo : "0x0000000000000000000000000000000000000000";
454
- result = await signPaymentV2(state, {
455
- from,
456
- to,
457
- amount: req.amount,
458
- nonce: crypto.randomUUID(),
459
- expiry: Math.floor(Date.now() / 1e3) + DEFAULT_EXPIRY_SECONDS,
460
- accepted: req
461
- });
462
- }
288
+ const req = selectedRequirements;
289
+ const to = typeof req.payTo === "string" ? req.payTo : "0x0000000000000000000000000000000000000000";
290
+ const result = await signPaymentV2(state, {
291
+ from,
292
+ to,
293
+ amount: req.amount,
294
+ nonce: crypto.randomUUID(),
295
+ expiry: Math.floor(Date.now() / 1e3) + DEFAULT_EXPIRY_SECONDS,
296
+ accepted: req
297
+ });
463
298
  const paymentHeaders = new Headers(init?.headers);
464
- if (version === 1) {
465
- paymentHeaders.set(V1_HEADERS2.PAYMENT, encodePaymentV1(result.payload));
466
- } else {
467
- paymentHeaders.set(V2_HEADERS2.PAYMENT_SIGNATURE, encodePaymentV2(result.payload));
468
- }
299
+ paymentHeaders.set(V2_HEADERS2.PAYMENT_SIGNATURE, encodePaymentV2(result.payload));
469
300
  response = await fetch2(url, { ...init, headers: paymentHeaders });
470
301
  }
471
302
  return response;
@@ -481,89 +312,46 @@ var createX402Client = (config) => {
481
312
  const amount = options.amount.toString();
482
313
  const nonce = options.nonce ?? crypto.randomUUID();
483
314
  const expiry = options.expiry ?? Math.floor(Date.now() / 1e3) + DEFAULT_EXPIRY_SECONDS;
484
- if (state.version === 1) {
485
- return signPaymentV1(state, {
486
- from,
487
- to,
488
- amount,
489
- nonce,
490
- expiry,
491
- validAfter: options.validAfter ?? DEFAULT_VALID_AFTER
492
- });
493
- }
494
315
  return signPaymentV2(state, { from, to, amount, nonce, expiry });
495
316
  },
496
317
  createPaymentHeaders: async (options) => {
497
- const result = await signPayment(options, state);
318
+ const from = getAddress(state.account);
319
+ const to = options.to;
320
+ const amount = options.amount.toString();
321
+ const nonce = options.nonce ?? crypto.randomUUID();
322
+ const expiry = options.expiry ?? Math.floor(Date.now() / 1e3) + DEFAULT_EXPIRY_SECONDS;
323
+ const result = await signPaymentV2(state, { from, to, amount, nonce, expiry });
498
324
  const headers = new Headers();
499
- if (state.version === 1) {
500
- headers.set("X-PAYMENT", encodePaymentV1(result.payload));
501
- } else {
502
- headers.set("PAYMENT-SIGNATURE", encodePaymentV2(result.payload));
503
- }
325
+ headers.set("PAYMENT-SIGNATURE", encodePaymentV2(result.payload));
504
326
  return headers;
505
327
  },
506
328
  handlePaymentRequired: async (requirements) => {
507
- return handlePaymentRequirements(requirements, state);
329
+ const from = getAddress(state.account);
330
+ const to = typeof requirements.payTo === "string" ? requirements.payTo : "0x0000000000000000000000000000000000000000";
331
+ return signPaymentV2(state, {
332
+ from,
333
+ to,
334
+ amount: requirements.amount,
335
+ nonce: crypto.randomUUID(),
336
+ expiry: Math.floor(Date.now() / 1e3) + DEFAULT_EXPIRY_SECONDS,
337
+ accepted: requirements
338
+ });
508
339
  },
509
340
  verifySettlement: (response) => {
510
- if ("success" in response) {
511
- return response.success;
512
- }
513
- return false;
341
+ return response.success === true;
514
342
  }
515
343
  };
516
344
  };
517
- var detectVersionFromRequirements = (requirements) => {
518
- if (isX402V2Requirements(requirements)) {
519
- return 2;
520
- }
521
- if (isX402V1Requirements(requirements)) {
522
- return 1;
523
- }
524
- if ("contractAddress" in requirements) {
525
- return 1;
526
- }
527
- return 2;
528
- };
529
- var signPayment = async (options, state) => {
530
- const from = getAddress(state.account);
531
- if (state.version === 1) {
532
- return signPaymentV1(state, {
533
- from,
534
- to: options.to,
535
- amount: options.amount.toString(),
536
- nonce: options.nonce ?? crypto.randomUUID(),
537
- expiry: options.expiry ?? Math.floor(Date.now() / 1e3) + DEFAULT_EXPIRY_SECONDS,
538
- validAfter: options.validAfter ?? DEFAULT_VALID_AFTER
539
- });
540
- }
541
- return signPaymentV2(state, {
542
- from,
543
- to: options.to,
544
- amount: options.amount.toString(),
545
- nonce: options.nonce ?? crypto.randomUUID(),
546
- expiry: options.expiry ?? Math.floor(Date.now() / 1e3) + DEFAULT_EXPIRY_SECONDS
547
- });
548
- };
549
345
 
550
346
  // src/transport.ts
551
347
  import {
552
- V1_HEADERS as V1_HEADERS3,
553
348
  V2_HEADERS as V2_HEADERS3,
554
- encodePaymentV1 as encodePaymentV12,
555
- encodePaymentV2 as encodePaymentV22,
556
- isX402V1Requirements as isX402V1Requirements2,
557
- isX402V2Requirements as isX402V2Requirements2
349
+ encodePaymentV2 as encodePaymentV22
558
350
  } from "@armory-sh/base";
559
351
  var DEFAULT_MAX_RETRIES = 3;
560
- var createPaymentHeaders = (payload, version) => {
352
+ var createPaymentHeaders = (payload, _version) => {
561
353
  const headers = new Headers();
562
- if (version === 1) {
563
- headers.set(V1_HEADERS3.PAYMENT, encodePaymentV12(payload));
564
- } else {
565
- headers.set(V2_HEADERS3.PAYMENT_SIGNATURE, encodePaymentV22(payload));
566
- }
354
+ headers.set(V2_HEADERS3.PAYMENT_SIGNATURE, encodePaymentV22(payload));
567
355
  return headers;
568
356
  };
569
357
  var isPaymentRelatedError = (error) => error.message.includes("402") || error.message.includes("payment") || error.message.includes("signature") || error.message.includes("Payment");
@@ -575,20 +363,12 @@ var backoff = (attempt) => {
575
363
  var handlePaymentRequired = async (response, client) => {
576
364
  const version = detectX402Version(response, client.getVersion());
577
365
  const parsed = await parsePaymentRequired(response, version);
578
- const selectedRequirements = selectSchemeRequirements(parsed.requirements, "exact");
366
+ const selectedRequirements = parsed.requirements[0];
579
367
  if (!selectedRequirements) {
580
368
  throw new Error("No supported payment scheme found in requirements");
581
369
  }
582
- let result;
583
- if (version === 1 && isX402V1Requirements2(selectedRequirements)) {
584
- const req = selectedRequirements;
585
- result = await client.handlePaymentRequired(req);
586
- } else if (version === 2 && isX402V2Requirements2(selectedRequirements)) {
587
- const req = selectedRequirements;
588
- result = await client.handlePaymentRequired(req);
589
- } else {
590
- result = await client.handlePaymentRequired(selectedRequirements);
591
- }
370
+ const req = selectedRequirements;
371
+ const result = await client.handlePaymentRequired(req);
592
372
  return createPaymentHeaders(result.payload, version);
593
373
  };
594
374
  var mergePaymentHeaders = (init = {}, paymentHeaders) => {
@@ -631,123 +411,15 @@ var createX402Transport = (options) => {
631
411
  }
632
412
  };
633
413
  };
634
- var createFetchWithX402 = (transport) => (url, init) => transport.fetch(url, init);
635
-
636
- // src/types.ts
637
- var isV1Requirements = (requirements) => "contractAddress" in requirements;
638
- var isV2Requirements = (requirements) => "chainId" in requirements && "assetId" in requirements;
639
- var isV1Settlement = (response) => "success" in response;
640
- var isV2Settlement = (response) => "status" in response;
641
-
642
- // src/index.ts
643
- import {
644
- V1_HEADERS as V1_HEADERS4,
645
- V2_HEADERS as V2_HEADERS4,
646
- encodePaymentV1 as encodePaymentV13,
647
- decodePaymentV1,
648
- encodeSettlementV1,
649
- decodeSettlementV1,
650
- encodePaymentV2 as encodePaymentV23,
651
- decodePaymentV2,
652
- encodeSettlementV2,
653
- decodeSettlementV2,
654
- isV1,
655
- isV2,
656
- getPaymentVersion,
657
- getRequirementsVersion,
658
- getSettlementVersion,
659
- getPaymentHeaderName as getPaymentHeaderName2,
660
- getPaymentResponseHeaderName,
661
- getPaymentRequiredHeaderName as getPaymentRequiredHeaderName2,
662
- isSettlementSuccessful,
663
- getTxHash,
664
- NETWORKS,
665
- getNetworkConfig as getNetworkConfig2,
666
- getNetworkByChainId,
667
- getMainnets,
668
- getTestnets,
669
- isX402V1Payload,
670
- isX402V2Payload,
671
- isX402V1Requirements as isX402V1Requirements3,
672
- isX402V2Requirements as isX402V2Requirements3,
673
- isX402V1Settlement,
674
- isX402V2Settlement,
675
- combineSignatureV2 as combineSignatureV22,
676
- parseSignatureV2,
677
- createNonce as createNonce2,
678
- EIP712_TYPES as EIP712_TYPES2,
679
- USDC_DOMAIN as USDC_DOMAIN2,
680
- createEIP712Domain as createEIP712Domain2,
681
- createTransferWithAuthorization as createTransferWithAuthorization2,
682
- validateTransferWithAuthorization as validateTransferWithAuthorization2
683
- } from "@armory-sh/base";
684
414
  export {
685
- EIP712_TYPES2 as CORE_EIP712_TYPES,
686
- USDC_DOMAIN2 as CORE_USDC_DOMAIN,
687
- EIP712_TYPES,
688
- NETWORKS,
689
- USDC_DOMAIN,
690
- V1_HEADERS4 as V1_HEADERS,
691
- V2_HEADERS4 as V2_HEADERS,
692
415
  adjustVForChainId,
693
- combineSignatureV22 as combineSignatureV2,
694
416
  concatenateSignature,
695
- createEIP712Domain2 as createCoreEIP712Domain,
696
- createTransferWithAuthorization2 as createCoreTransferWithAuthorization,
697
417
  createEIP712Domain,
698
- createFetchWithX402,
699
- createNonce2 as createNonce,
700
- createPaymentHeader,
701
418
  createTransferWithAuthorization,
702
419
  createX402Client,
703
420
  createX402Transport,
704
- createX402V1Payment,
705
- createX402V2Payment,
706
- decodePaymentV1,
707
- decodePaymentV2,
708
- decodeSettlementV1,
709
- decodeSettlementV2,
710
- detectVersionFromObject,
711
- detectX402Version,
712
- encodePaymentV13 as encodePaymentV1,
713
- encodePaymentV23 as encodePaymentV2,
714
- encodeSettlementV1,
715
- encodeSettlementV2,
716
- getMainnets,
717
- getNetworkByChainId,
718
- getNetworkConfig2 as getNetworkConfig,
719
- getPaymentHeader,
720
- getPaymentHeaderName2 as getPaymentHeaderName,
721
- getPaymentRequiredHeader,
722
- getPaymentRequiredHeaderName2 as getPaymentRequiredHeaderName,
723
- getPaymentResponseHeaderName,
724
- getPaymentVersion,
725
- getRequirementsVersion,
726
- getSettlementVersion,
727
- getTestnets,
728
- getTxHash,
729
- isPaymentRequiredResponse,
730
- isSettlementSuccessful,
731
- isV1,
732
- isV1Requirements,
733
- isV1Settlement,
734
- isV2,
735
- isV2Requirements,
736
- isV2Settlement,
737
- isX402V1Payload,
738
- isX402V1Requirements3 as isX402V1Requirements,
739
- isX402V1Settlement,
740
- isX402V2Payload,
741
- isX402V2Requirements3 as isX402V2Requirements,
742
- isX402V2Settlement,
743
- parsePaymentRequired,
744
- parsePaymentRequiredFromBody,
745
- parsePaymentRequiredFromHeader,
746
421
  parseSignature,
747
- parseSignatureV2,
748
- selectSchemeRequirements,
749
422
  signTypedData,
750
423
  signWithPrivateKey,
751
- validateTransferWithAuthorization2 as validateCoreTransferWithAuthorization,
752
424
  validateTransferWithAuthorization
753
425
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@armory-sh/client-web3",
3
- "version": "0.2.10",
3
+ "version": "0.2.12",
4
4
  "license": "MIT",
5
5
  "author": "Sawyer Cutler <sawyer@dirtroad.dev>",
6
6
  "type": "module",
@@ -27,7 +27,7 @@
27
27
  "directory": "packages/client-web3"
28
28
  },
29
29
  "dependencies": {
30
- "@armory-sh/base": "^0.2.13",
30
+ "@armory-sh/base": "^0.2.16",
31
31
  "web3": "4.16.0",
32
32
  "web3-types": "1.10.0"
33
33
  },