@agent-score/commerce 1.1.0 → 1.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 +27 -12
- package/dist/{_response-RpEB7-vl.d.ts → _response-C2yFQoIA.d.ts} +1 -1
- package/dist/{_response-DS-LR590.d.mts → _response-DpB-cm2c.d.mts} +1 -1
- package/dist/agent_instructions-DiMSGkdm.d.mts +133 -0
- package/dist/agent_instructions-DiMSGkdm.d.ts +133 -0
- package/dist/challenge/index.d.mts +18 -116
- package/dist/challenge/index.d.ts +18 -116
- package/dist/challenge/index.js +41 -27
- package/dist/challenge/index.js.map +1 -1
- package/dist/challenge/index.mjs +40 -27
- package/dist/challenge/index.mjs.map +1 -1
- package/dist/core.js +1 -1
- package/dist/core.js.map +1 -1
- package/dist/core.mjs +1 -1
- package/dist/core.mjs.map +1 -1
- package/dist/discovery/index.d.mts +245 -2
- package/dist/discovery/index.d.ts +245 -2
- package/dist/discovery/index.js +276 -56
- package/dist/discovery/index.js.map +1 -1
- package/dist/discovery/index.mjs +269 -55
- package/dist/discovery/index.mjs.map +1 -1
- package/dist/identity/express.d.mts +2 -2
- package/dist/identity/express.d.ts +2 -2
- package/dist/identity/express.js +48 -25
- package/dist/identity/express.js.map +1 -1
- package/dist/identity/express.mjs +48 -25
- package/dist/identity/express.mjs.map +1 -1
- package/dist/identity/fastify.d.mts +2 -2
- package/dist/identity/fastify.d.ts +2 -2
- package/dist/identity/fastify.js +48 -25
- package/dist/identity/fastify.js.map +1 -1
- package/dist/identity/fastify.mjs +48 -25
- package/dist/identity/fastify.mjs.map +1 -1
- package/dist/identity/hono.d.mts +2 -2
- package/dist/identity/hono.d.ts +2 -2
- package/dist/identity/hono.js +48 -25
- package/dist/identity/hono.js.map +1 -1
- package/dist/identity/hono.mjs +48 -25
- package/dist/identity/hono.mjs.map +1 -1
- package/dist/identity/nextjs.d.mts +2 -2
- package/dist/identity/nextjs.d.ts +2 -2
- package/dist/identity/nextjs.js +48 -25
- package/dist/identity/nextjs.js.map +1 -1
- package/dist/identity/nextjs.mjs +48 -25
- package/dist/identity/nextjs.mjs.map +1 -1
- package/dist/identity/web.d.mts +2 -2
- package/dist/identity/web.d.ts +2 -2
- package/dist/identity/web.js +48 -25
- package/dist/identity/web.js.map +1 -1
- package/dist/identity/web.mjs +48 -25
- package/dist/identity/web.mjs.map +1 -1
- package/dist/index.d.mts +12 -12
- package/dist/index.d.ts +12 -12
- package/dist/index.js +47 -24
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +47 -24
- package/dist/index.mjs.map +1 -1
- package/dist/payment/index.d.mts +136 -49
- package/dist/payment/index.d.ts +136 -49
- package/dist/payment/index.js +161 -73
- package/dist/payment/index.js.map +1 -1
- package/dist/payment/index.mjs +160 -72
- package/dist/payment/index.mjs.map +1 -1
- package/dist/{signer-Cvdwn6Cs.d.mts → signer-kCAJUZwp.d.mts} +10 -12
- package/dist/{signer-Cvdwn6Cs.d.ts → signer-kCAJUZwp.d.ts} +10 -12
- package/dist/stripe-multichain/index.d.mts +2 -2
- package/dist/stripe-multichain/index.d.ts +2 -2
- package/dist/stripe-multichain/index.js.map +1 -1
- package/dist/stripe-multichain/index.mjs.map +1 -1
- package/package.json +13 -4
package/dist/payment/index.mjs
CHANGED
|
@@ -90,15 +90,15 @@ var rails = {
|
|
|
90
90
|
decimals: USDC.base.sepolia.decimals,
|
|
91
91
|
asset: USDC.base.sepolia.address
|
|
92
92
|
},
|
|
93
|
-
"
|
|
94
|
-
method: "
|
|
93
|
+
"mpp-solana-mainnet": {
|
|
94
|
+
method: "solana",
|
|
95
95
|
network: networks.solana.mainnet.caip2,
|
|
96
96
|
currency: USDC.solana.mainnet.mint,
|
|
97
97
|
decimals: USDC.solana.mainnet.decimals,
|
|
98
98
|
asset: USDC.solana.mainnet.mint
|
|
99
99
|
},
|
|
100
|
-
"
|
|
101
|
-
method: "
|
|
100
|
+
"mpp-solana-devnet": {
|
|
101
|
+
method: "solana",
|
|
102
102
|
network: networks.solana.devnet.caip2,
|
|
103
103
|
currency: USDC.solana.devnet.mint,
|
|
104
104
|
decimals: USDC.solana.devnet.decimals,
|
|
@@ -168,11 +168,6 @@ function registerX402SchemesV1V2(server, network, scheme) {
|
|
|
168
168
|
|
|
169
169
|
// src/payment/x402_server.ts
|
|
170
170
|
async function createX402Server(opts = {}) {
|
|
171
|
-
for (const rail of opts.rails ?? []) {
|
|
172
|
-
if (rail.startsWith("x402-solana") && rail.endsWith("-upto")) {
|
|
173
|
-
throw new Error(`Rail "${rail}" not supported \u2014 @x402/svm does not ship an upto scheme yet (EVM-only).`);
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
171
|
const x402Core = await dynamicImport("@x402/core/server") ?? null;
|
|
177
172
|
if (!x402Core) {
|
|
178
173
|
throw new Error(
|
|
@@ -196,7 +191,6 @@ async function createX402Server(opts = {}) {
|
|
|
196
191
|
const server = new x402Core.x402ResourceServer(facilitator);
|
|
197
192
|
let evmExactModule = null;
|
|
198
193
|
let evmUptoModule = null;
|
|
199
|
-
let svmModule = null;
|
|
200
194
|
for (const rail of opts.rails ?? []) {
|
|
201
195
|
const isUpto = rail.endsWith("-upto");
|
|
202
196
|
if (rail.startsWith("x402-base")) {
|
|
@@ -215,13 +209,6 @@ async function createX402Server(opts = {}) {
|
|
|
215
209
|
}
|
|
216
210
|
registerX402SchemesV1V2(server, network, new evmExactModule.ExactEvmScheme());
|
|
217
211
|
}
|
|
218
|
-
} else if (rail.startsWith("x402-solana")) {
|
|
219
|
-
svmModule ??= await dynamicImport("@x402/svm/exact/server");
|
|
220
|
-
if (!svmModule?.ExactSvmScheme) {
|
|
221
|
-
throw new Error("@x402/svm not installed \u2014 `npm install @x402/svm` for x402 solana rails.");
|
|
222
|
-
}
|
|
223
|
-
const network = rail === "x402-solana-mainnet" ? networks.solana.mainnet.caip2 : networks.solana.devnet.caip2;
|
|
224
|
-
registerX402SchemesV1V2(server, network, new svmModule.ExactSvmScheme());
|
|
225
212
|
}
|
|
226
213
|
}
|
|
227
214
|
for (const { network, scheme } of opts.schemes ?? []) {
|
|
@@ -250,9 +237,60 @@ async function dynamicImport(moduleName) {
|
|
|
250
237
|
}
|
|
251
238
|
|
|
252
239
|
// src/payment/x402_settle.ts
|
|
240
|
+
function classifyX402SettleResult(result) {
|
|
241
|
+
if (result.success) return null;
|
|
242
|
+
switch (result.phase) {
|
|
243
|
+
case "no_requirements":
|
|
244
|
+
return {
|
|
245
|
+
status: 500,
|
|
246
|
+
code: "payment_internal_error",
|
|
247
|
+
message: "Failed to build x402 payment requirements for this configuration",
|
|
248
|
+
nextSteps: {
|
|
249
|
+
action: "contact_support",
|
|
250
|
+
user_message: "The merchant could not produce a payment challenge for this request. Try again later or contact support."
|
|
251
|
+
}
|
|
252
|
+
};
|
|
253
|
+
case "verify_failed":
|
|
254
|
+
return {
|
|
255
|
+
status: 400,
|
|
256
|
+
code: "payment_proof_invalid",
|
|
257
|
+
message: "Payment credential failed verification; regenerate from a fresh 402 challenge",
|
|
258
|
+
nextSteps: {
|
|
259
|
+
action: "regenerate_payment_credential",
|
|
260
|
+
user_message: "The payment credential was rejected at verify time. Discard it, fetch a fresh 402 challenge, and re-sign."
|
|
261
|
+
}
|
|
262
|
+
};
|
|
263
|
+
case "facilitator_error":
|
|
264
|
+
return {
|
|
265
|
+
status: 503,
|
|
266
|
+
code: "payment_provider_unavailable",
|
|
267
|
+
message: "Payment provider could not process this network configuration",
|
|
268
|
+
nextSteps: {
|
|
269
|
+
action: "try_different_rail",
|
|
270
|
+
user_message: "This rail is currently unavailable. Pick a different rail from the 402 challenge and retry."
|
|
271
|
+
}
|
|
272
|
+
};
|
|
273
|
+
case "settle_failed":
|
|
274
|
+
return {
|
|
275
|
+
status: 503,
|
|
276
|
+
code: "payment_provider_unavailable",
|
|
277
|
+
message: "Payment credential verified but on-chain settlement failed",
|
|
278
|
+
nextSteps: {
|
|
279
|
+
action: "retry_or_swap_method",
|
|
280
|
+
retry_after_seconds: 10,
|
|
281
|
+
user_message: "Transient settlement error. Retry in a few seconds, or pick a different rail from the 402 challenge."
|
|
282
|
+
}
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
}
|
|
253
286
|
async function processX402Settle(input) {
|
|
254
287
|
const server = input.x402Server;
|
|
255
|
-
|
|
288
|
+
let builtRequirements;
|
|
289
|
+
try {
|
|
290
|
+
builtRequirements = await server.buildPaymentRequirements(input.resourceConfig);
|
|
291
|
+
} catch (err) {
|
|
292
|
+
return { success: false, phase: "facilitator_error", step: "build_requirements", error: err };
|
|
293
|
+
}
|
|
256
294
|
const matchedRequirement = builtRequirements[0];
|
|
257
295
|
if (!matchedRequirement) {
|
|
258
296
|
return { success: false, phase: "no_requirements", reason: "x402Server.buildPaymentRequirements returned empty" };
|
|
@@ -261,13 +299,23 @@ async function processX402Settle(input) {
|
|
|
261
299
|
const path = new URL(input.resourceMeta.url).pathname;
|
|
262
300
|
return { method: "POST", adapter: { getPath: () => path }, routePattern: path };
|
|
263
301
|
})();
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
input.
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
302
|
+
let enrichedExt;
|
|
303
|
+
try {
|
|
304
|
+
enrichedExt = input.extension !== void 0 ? server.enrichExtensions(input.extension, transportContext) : void 0;
|
|
305
|
+
} catch (err) {
|
|
306
|
+
return { success: false, phase: "facilitator_error", step: "enrich_extensions", error: err };
|
|
307
|
+
}
|
|
308
|
+
let verifyResult;
|
|
309
|
+
try {
|
|
310
|
+
verifyResult = await server.processPaymentRequest(
|
|
311
|
+
input.payload,
|
|
312
|
+
input.resourceConfig,
|
|
313
|
+
input.resourceMeta,
|
|
314
|
+
enrichedExt
|
|
315
|
+
);
|
|
316
|
+
} catch (err) {
|
|
317
|
+
return { success: false, phase: "facilitator_error", step: "process_payment_request", error: err };
|
|
318
|
+
}
|
|
271
319
|
if (!verifyResult.success) {
|
|
272
320
|
return { success: false, phase: "verify_failed", verifyResult };
|
|
273
321
|
}
|
|
@@ -291,30 +339,15 @@ var X402_SUPPORTED_BASE_NETWORKS = /* @__PURE__ */ new Set([
|
|
|
291
339
|
networks.base.mainnet.caip2,
|
|
292
340
|
networks.base.sepolia.caip2
|
|
293
341
|
]);
|
|
294
|
-
var X402_SUPPORTED_SVM_NETWORKS = /* @__PURE__ */ new Set([
|
|
295
|
-
networks.solana.mainnet.caip2,
|
|
296
|
-
networks.solana.devnet.caip2
|
|
297
|
-
]);
|
|
298
342
|
function validateX402NetworkConfig(input) {
|
|
299
343
|
if (!X402_SUPPORTED_BASE_NETWORKS.has(input.baseNetwork)) {
|
|
300
344
|
throw new Error(
|
|
301
345
|
`X402_BASE_NETWORK=${input.baseNetwork} is not supported. Use one of: ${[...X402_SUPPORTED_BASE_NETWORKS].join(", ")}`
|
|
302
346
|
);
|
|
303
347
|
}
|
|
304
|
-
if (!X402_SUPPORTED_SVM_NETWORKS.has(input.svmNetwork)) {
|
|
305
|
-
throw new Error(
|
|
306
|
-
`X402_SVM_NETWORK=${input.svmNetwork} is not supported. Use one of: ${[...X402_SUPPORTED_SVM_NETWORKS].join(", ")}`
|
|
307
|
-
);
|
|
308
|
-
}
|
|
309
|
-
if (input.baseNetwork === input.svmNetwork) {
|
|
310
|
-
throw new Error(
|
|
311
|
-
`X402_BASE_NETWORK and X402_SVM_NETWORK must be different (both set to ${input.baseNetwork}).`
|
|
312
|
-
);
|
|
313
|
-
}
|
|
314
348
|
}
|
|
315
349
|
var EVM_ADDRESS_RE = /^0x[0-9a-fA-F]{40}$/;
|
|
316
|
-
var
|
|
317
|
-
var REGENERATE_WARNING = "If you're trying to pay with Tempo USDC, use `tempo request` (sends Authorization: Payment), not a manual X-Payment header. Do NOT use `tempo wallet transfer` \u2014 that sends USDC on-chain but will not complete the MPP handshake. For x402 on Base/Solana, use `agentscore-pay pay` so the X-Payment credential is signed and submitted; bare wallet transfers do not complete the handshake.";
|
|
350
|
+
var REGENERATE_WARNING = "Use `agentscore-pay pay --chain base` (or `tempo request` for Tempo USDC) so the credential is signed and submitted via the protocol handshake. Do NOT use `tempo wallet transfer` \u2014 that sends USDC on-chain but does not complete the handshake.";
|
|
318
351
|
function regenerateBody(message, userMessage) {
|
|
319
352
|
return {
|
|
320
353
|
error: { code: "payment_proof_invalid", message },
|
|
@@ -352,18 +385,27 @@ async function verifyX402Request(input) {
|
|
|
352
385
|
}
|
|
353
386
|
const signedNetwork = payload.accepted?.network;
|
|
354
387
|
const signedPayTo = payload.accepted?.payTo;
|
|
355
|
-
if (!signedNetwork || signedNetwork !== input.
|
|
388
|
+
if (!signedNetwork || signedNetwork !== input.acceptedNetwork) {
|
|
389
|
+
if (signedNetwork && signedNetwork.toLowerCase().startsWith("solana:")) {
|
|
390
|
+
return {
|
|
391
|
+
ok: false,
|
|
392
|
+
status: 400,
|
|
393
|
+
body: regenerateBody(
|
|
394
|
+
`x402 on ${signedNetwork} is not accepted; Solana payments must use the \`solana/charge\` rail advertised in the 402 challenge. This server accepts x402 on ${input.acceptedNetwork} only.`,
|
|
395
|
+
"Solana payments are not accepted over x402 at this merchant. Pick the `solana/charge` rail from the 402 challenge and re-sign."
|
|
396
|
+
)
|
|
397
|
+
};
|
|
398
|
+
}
|
|
356
399
|
return {
|
|
357
400
|
ok: false,
|
|
358
401
|
status: 400,
|
|
359
402
|
body: regenerateBody(
|
|
360
|
-
`Unsupported x402 network ${signedNetwork ?? "<missing>"}; this server accepts ${input.
|
|
361
|
-
"The credential signed for an unsupported network. Pick
|
|
403
|
+
`Unsupported x402 network ${signedNetwork ?? "<missing>"}; this server accepts ${input.acceptedNetwork}.`,
|
|
404
|
+
"The credential signed for an unsupported network. Pick the accepted network from the 402 challenge and re-sign."
|
|
362
405
|
)
|
|
363
406
|
};
|
|
364
407
|
}
|
|
365
|
-
const
|
|
366
|
-
const addressShapeOk = isSolana ? typeof signedPayTo === "string" && SOLANA_ADDRESS_RE.test(signedPayTo) : typeof signedPayTo === "string" && EVM_ADDRESS_RE.test(signedPayTo);
|
|
408
|
+
const addressShapeOk = typeof signedPayTo === "string" && EVM_ADDRESS_RE.test(signedPayTo);
|
|
367
409
|
if (!signedPayTo || !addressShapeOk) {
|
|
368
410
|
return {
|
|
369
411
|
ok: false,
|
|
@@ -384,7 +426,7 @@ async function verifyX402Request(input) {
|
|
|
384
426
|
)
|
|
385
427
|
};
|
|
386
428
|
}
|
|
387
|
-
return { ok: true, payload, signedNetwork, signedPayTo
|
|
429
|
+
return { ok: true, payload, signedNetwork, signedPayTo };
|
|
388
430
|
}
|
|
389
431
|
|
|
390
432
|
// src/stripe-multichain/mppx_stripe.ts
|
|
@@ -443,6 +485,29 @@ async function createMppxServer(opts) {
|
|
|
443
485
|
})
|
|
444
486
|
);
|
|
445
487
|
}
|
|
488
|
+
if (opts.rails?.solana) {
|
|
489
|
+
const solanaMpp = await dynamicImport2("@solana/mpp/server");
|
|
490
|
+
if (!solanaMpp?.charge) {
|
|
491
|
+
throw new Error(
|
|
492
|
+
"@solana/mpp not installed \u2014 `npm install @solana/mpp @solana/kit` to use the solana rail."
|
|
493
|
+
);
|
|
494
|
+
}
|
|
495
|
+
const s = opts.rails.solana;
|
|
496
|
+
const network = s.network ?? "mainnet-beta";
|
|
497
|
+
const defaultMint = network === "mainnet-beta" ? USDC.solana.mainnet.mint : USDC.solana.devnet.mint;
|
|
498
|
+
const defaultDecimals = network === "mainnet-beta" ? USDC.solana.mainnet.decimals : USDC.solana.devnet.decimals;
|
|
499
|
+
methods.push(
|
|
500
|
+
solanaMpp.charge({
|
|
501
|
+
recipient: s.recipient,
|
|
502
|
+
currency: s.currency ?? defaultMint,
|
|
503
|
+
decimals: s.decimals ?? defaultDecimals,
|
|
504
|
+
network,
|
|
505
|
+
...s.rpcUrl ? { rpcUrl: s.rpcUrl } : {},
|
|
506
|
+
...s.signer ? { signer: s.signer } : {},
|
|
507
|
+
...s.tokenProgram ? { tokenProgram: s.tokenProgram } : {}
|
|
508
|
+
})
|
|
509
|
+
);
|
|
510
|
+
}
|
|
446
511
|
if (opts.rails?.stripe) {
|
|
447
512
|
const stripeMethod = await createMppxStripe(opts.rails.stripe);
|
|
448
513
|
methods.push(stripeMethod);
|
|
@@ -550,6 +615,44 @@ function clampKey(key) {
|
|
|
550
615
|
}
|
|
551
616
|
|
|
552
617
|
// src/signer.ts
|
|
618
|
+
var TOKEN_PROGRAM = "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA";
|
|
619
|
+
var TOKEN_2022_PROGRAM = "TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb";
|
|
620
|
+
var TRANSFER_CHECKED_DISCRIMINATOR = 12;
|
|
621
|
+
async function extractSolanaSignerFromCredential(credential) {
|
|
622
|
+
const payload = credential.payload;
|
|
623
|
+
if (!payload?.transaction || payload.type !== "transaction") return null;
|
|
624
|
+
const moduleName = "@solana/kit";
|
|
625
|
+
const kit = await import(moduleName).catch(() => null);
|
|
626
|
+
if (!kit?.getBase64Codec || !kit.getTransactionDecoder || !kit.getCompiledTransactionMessageDecoder) {
|
|
627
|
+
return null;
|
|
628
|
+
}
|
|
629
|
+
try {
|
|
630
|
+
const txBytes = kit.getBase64Codec().encode(payload.transaction);
|
|
631
|
+
const decoded = kit.getTransactionDecoder().decode(txBytes);
|
|
632
|
+
const message = kit.getCompiledTransactionMessageDecoder().decode(decoded.messageBytes);
|
|
633
|
+
for (const ix of message.instructions) {
|
|
634
|
+
const programId = message.staticAccounts[ix.programAddressIndex];
|
|
635
|
+
if (programId !== TOKEN_PROGRAM && programId !== TOKEN_2022_PROGRAM) continue;
|
|
636
|
+
const data = ix.data;
|
|
637
|
+
if (!data || data.length === 0 || data[0] !== TRANSFER_CHECKED_DISCRIMINATOR) continue;
|
|
638
|
+
const accountIndices = ix.accountIndices ?? [];
|
|
639
|
+
const authorityIndex = accountIndices[3];
|
|
640
|
+
if (authorityIndex === void 0) continue;
|
|
641
|
+
if (authorityIndex >= message.staticAccounts.length) {
|
|
642
|
+
console.warn(
|
|
643
|
+
"[gate] Solana TransferChecked authority resolves through an address lookup table; signer-match recovery requires the static-account form. Skipping."
|
|
644
|
+
);
|
|
645
|
+
continue;
|
|
646
|
+
}
|
|
647
|
+
const authority = message.staticAccounts[authorityIndex];
|
|
648
|
+
if (authority) return authority;
|
|
649
|
+
}
|
|
650
|
+
return null;
|
|
651
|
+
} catch (err) {
|
|
652
|
+
console.warn("[gate] Solana credential decode failed:", err instanceof Error ? err.message : err);
|
|
653
|
+
return null;
|
|
654
|
+
}
|
|
655
|
+
}
|
|
553
656
|
async function extractPaymentSigner(request, x402PaymentHeader) {
|
|
554
657
|
const authHeader = request.headers.get("authorization");
|
|
555
658
|
if (authHeader) {
|
|
@@ -559,8 +662,12 @@ async function extractPaymentSigner(request, x402PaymentHeader) {
|
|
|
559
662
|
if (mppx?.Credential?.extractPaymentScheme(authHeader)) {
|
|
560
663
|
const credential = mppx.Credential.fromRequest(request);
|
|
561
664
|
const source = credential.source;
|
|
562
|
-
const
|
|
563
|
-
if (
|
|
665
|
+
const evmMatch = source?.match(/^did:pkh:eip155:\d+:(0x[0-9a-fA-F]{40})$/);
|
|
666
|
+
if (evmMatch) return { address: evmMatch[1].toLowerCase(), network: "evm" };
|
|
667
|
+
const solMatch = source?.match(/^did:pkh:solana:[1-9A-HJ-NP-Za-km-z]{32,44}:([1-9A-HJ-NP-Za-km-z]{32,44})$/);
|
|
668
|
+
if (solMatch) return { address: solMatch[1], network: "solana" };
|
|
669
|
+
const solanaFromTx = await extractSolanaSignerFromCredential(credential);
|
|
670
|
+
if (solanaFromTx) return { address: solanaFromTx, network: "solana" };
|
|
564
671
|
}
|
|
565
672
|
} catch (err) {
|
|
566
673
|
console.warn("[gate] MPP signer extraction failed:", err instanceof Error ? err.message : err);
|
|
@@ -570,28 +677,9 @@ async function extractPaymentSigner(request, x402PaymentHeader) {
|
|
|
570
677
|
try {
|
|
571
678
|
const decoded = atob(x402PaymentHeader);
|
|
572
679
|
const parsed = JSON.parse(decoded);
|
|
573
|
-
const
|
|
574
|
-
if (
|
|
575
|
-
|
|
576
|
-
if (typeof from === "string" && /^0x[0-9a-fA-F]{40}$/.test(from)) {
|
|
577
|
-
return { address: from.toLowerCase(), network: "evm" };
|
|
578
|
-
}
|
|
579
|
-
} else if (network.startsWith("solana:")) {
|
|
580
|
-
const transaction = parsed?.payload?.transaction;
|
|
581
|
-
if (typeof transaction === "string") {
|
|
582
|
-
const moduleName = "@x402/svm";
|
|
583
|
-
const svm = await import(moduleName).catch(() => null);
|
|
584
|
-
if (svm?.decodeTransactionFromPayload && svm.getTokenPayerFromTransaction) {
|
|
585
|
-
const tx = svm.decodeTransactionFromPayload({ transaction });
|
|
586
|
-
const payer = svm.getTokenPayerFromTransaction(tx);
|
|
587
|
-
if (typeof payer === "string" && payer.length > 0) return { address: payer, network: "solana" };
|
|
588
|
-
}
|
|
589
|
-
}
|
|
590
|
-
} else {
|
|
591
|
-
const from = parsed?.payload?.authorization?.from;
|
|
592
|
-
if (typeof from === "string" && /^0x[0-9a-fA-F]{40}$/.test(from)) {
|
|
593
|
-
return { address: from.toLowerCase(), network: "evm" };
|
|
594
|
-
}
|
|
680
|
+
const from = parsed?.payload?.authorization?.from;
|
|
681
|
+
if (typeof from === "string" && /^0x[0-9a-fA-F]{40}$/.test(from)) {
|
|
682
|
+
return { address: from.toLowerCase(), network: "evm" };
|
|
595
683
|
}
|
|
596
684
|
} catch (err) {
|
|
597
685
|
console.warn("[gate] x402 signer extraction failed:", err instanceof Error ? err.message : err);
|
|
@@ -612,12 +700,12 @@ export {
|
|
|
612
700
|
SETTLEMENT_OVERRIDES_HEADER,
|
|
613
701
|
USDC,
|
|
614
702
|
X402_SUPPORTED_BASE_NETWORKS,
|
|
615
|
-
X402_SUPPORTED_SVM_NETWORKS,
|
|
616
703
|
aliasAmountFields,
|
|
617
704
|
buildIdempotencyKey,
|
|
618
705
|
buildPaymentDirective,
|
|
619
706
|
buildPaymentHeaders,
|
|
620
707
|
buildPaymentRequestBlob,
|
|
708
|
+
classifyX402SettleResult,
|
|
621
709
|
createMppxServer,
|
|
622
710
|
createX402Server,
|
|
623
711
|
dispatchSettlementByNetwork,
|