@devlab.group/agent-commerce 2.1.0 → 2.2.1
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 +35 -5
- package/dist/ap2.js +3 -3
- package/dist/{chunk-LZS5BL3W.js → chunk-2DAJAJI7.js} +23 -5
- package/dist/chunk-2DAJAJI7.js.map +1 -0
- package/dist/{chunk-UHMYRV3J.js → chunk-BNUD4RBN.js} +22 -7
- package/dist/chunk-BNUD4RBN.js.map +1 -0
- package/dist/{chunk-IFGRCXME.js → chunk-REBY2IEP.js} +24 -20
- package/dist/chunk-REBY2IEP.js.map +1 -0
- package/dist/{chunk-SY6GUYSQ.js → chunk-XYHDQ22D.js} +3 -3
- package/dist/{chunk-SY6GUYSQ.js.map → chunk-XYHDQ22D.js.map} +1 -1
- package/dist/cli/ap2-HLBIUSTK.js +678 -0
- package/dist/cli/ap2-HLBIUSTK.js.map +1 -0
- package/dist/cli/chunk-2LN5PO5I.js +1352 -0
- package/dist/cli/chunk-2LN5PO5I.js.map +1 -0
- package/dist/cli/chunk-3EQBCFZY.js +53 -0
- package/dist/cli/chunk-3EQBCFZY.js.map +1 -0
- package/dist/cli/chunk-3M6U7ILB.js +8 -0
- package/dist/cli/chunk-3M6U7ILB.js.map +1 -0
- package/dist/cli/chunk-3MGAJ5FX.js +70 -0
- package/dist/cli/chunk-3MGAJ5FX.js.map +1 -0
- package/dist/cli/chunk-5K4XEAZV.js +113 -0
- package/dist/cli/chunk-5K4XEAZV.js.map +1 -0
- package/dist/cli/chunk-AA3FIEAR.js +27 -0
- package/dist/cli/chunk-AA3FIEAR.js.map +1 -0
- package/dist/cli/chunk-FHCFR2GS.js +17 -0
- package/dist/cli/chunk-FHCFR2GS.js.map +1 -0
- package/dist/cli/chunk-ILUYEQSV.js +1744 -0
- package/dist/cli/chunk-ILUYEQSV.js.map +1 -0
- package/dist/cli/chunk-KTV52MCU.js +338 -0
- package/dist/cli/chunk-KTV52MCU.js.map +1 -0
- package/dist/cli/chunk-OSTCU6ZK.js +44 -0
- package/dist/cli/chunk-OSTCU6ZK.js.map +1 -0
- package/dist/cli/chunk-OZ4LAWBK.js +256 -0
- package/dist/cli/chunk-OZ4LAWBK.js.map +1 -0
- package/dist/cli/chunk-QQ3WY5L3.js +271 -0
- package/dist/cli/chunk-QQ3WY5L3.js.map +1 -0
- package/dist/cli/chunk-QY3K6PEQ.js +8 -0
- package/dist/cli/chunk-QY3K6PEQ.js.map +1 -0
- package/dist/cli/chunk-QZ6TOMX6.js +1413 -0
- package/dist/cli/chunk-QZ6TOMX6.js.map +1 -0
- package/dist/cli/chunk-SNM3OVCY.js +625 -0
- package/dist/cli/chunk-SNM3OVCY.js.map +1 -0
- package/dist/cli/chunk-SPAYKVUP.js +118 -0
- package/dist/cli/chunk-SPAYKVUP.js.map +1 -0
- package/dist/cli/chunk-TPC4EJLT.js +11 -0
- package/dist/cli/chunk-TPC4EJLT.js.map +1 -0
- package/dist/cli/config-VYAJGZXE.js +11 -0
- package/dist/cli/config-VYAJGZXE.js.map +1 -0
- package/dist/cli/index.js +150 -3627
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/mcp-HFD7ZNCQ.js +559 -0
- package/dist/cli/mcp-HFD7ZNCQ.js.map +1 -0
- package/dist/cli/near-5AY3HWYF.js +58 -0
- package/dist/cli/near-5AY3HWYF.js.map +1 -0
- package/dist/cli/provider-JV5HCQGR.js +396 -0
- package/dist/cli/provider-JV5HCQGR.js.map +1 -0
- package/dist/cli/run-WV44B62Y.js +7301 -0
- package/dist/cli/run-WV44B62Y.js.map +1 -0
- package/dist/cli/svm-3MMYFPC7.js +33 -0
- package/dist/cli/svm-3MMYFPC7.js.map +1 -0
- package/dist/cli/x402-NADFV5CD.js +96 -0
- package/dist/cli/x402-NADFV5CD.js.map +1 -0
- package/dist/index.d.ts +12 -3
- package/dist/index.js +82 -11
- package/dist/index.js.map +1 -1
- package/dist/mcp.js +6 -16
- package/dist/mcp.js.map +1 -1
- package/dist/mpp.js +3 -3
- package/dist/{networks-olfflCI_.d.ts → networks-DTWRlj-K.d.ts} +2 -2
- package/dist/x402.d.ts +7 -2
- package/dist/x402.js +4 -4
- package/package.json +2 -2
- package/dist/chunk-IFGRCXME.js.map +0 -1
- package/dist/chunk-LZS5BL3W.js.map +0 -1
- package/dist/chunk-UHMYRV3J.js.map +0 -1
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { computeSvmReplayKey } from './chunk-OSTCU6ZK.js';
|
|
2
|
+
import { isRecord } from './chunk-3M6U7ILB.js';
|
|
3
|
+
import { getAddressEncoder, getProgramDerivedAddress, address } from '@solana/kit';
|
|
4
|
+
import { transactionMessageHash, decodeTransactionFromPayload } from '@x402/svm';
|
|
5
|
+
|
|
6
|
+
var MAX_TRANSACTION_BASE64 = 1644;
|
|
7
|
+
var ASSOCIATED_TOKEN_PROGRAM = "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL";
|
|
8
|
+
async function associatedTokenAccount(owner, mint, tokenProgram) {
|
|
9
|
+
const encoder = getAddressEncoder();
|
|
10
|
+
const [account] = await getProgramDerivedAddress({
|
|
11
|
+
programAddress: address(ASSOCIATED_TOKEN_PROGRAM),
|
|
12
|
+
seeds: [owner, tokenProgram, mint].map((key) => encoder.encode(address(key)))
|
|
13
|
+
});
|
|
14
|
+
return account;
|
|
15
|
+
}
|
|
16
|
+
function svmReplayKey(payload, network) {
|
|
17
|
+
if (!isRecord(payload)) return "invalid_exact_svm_payload_transaction";
|
|
18
|
+
const transaction = payload["transaction"];
|
|
19
|
+
if (typeof transaction !== "string" || transaction.length > MAX_TRANSACTION_BASE64) {
|
|
20
|
+
return "invalid_exact_svm_payload_transaction";
|
|
21
|
+
}
|
|
22
|
+
let messageHash;
|
|
23
|
+
try {
|
|
24
|
+
messageHash = transactionMessageHash(decodeTransactionFromPayload({ transaction }));
|
|
25
|
+
} catch {
|
|
26
|
+
return "invalid_exact_svm_payload_transaction_could_not_be_decoded";
|
|
27
|
+
}
|
|
28
|
+
return { replayKey: computeSvmReplayKey({ network, messageHash }) };
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export { associatedTokenAccount, svmReplayKey };
|
|
32
|
+
//# sourceMappingURL=svm-3MMYFPC7.js.map
|
|
33
|
+
//# sourceMappingURL=svm-3MMYFPC7.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/payments/x402/svm.ts"],"names":[],"mappings":";;;;;AAgBA,IAAM,sBAAA,GAAyB,IAAA;AAE/B,IAAM,wBAAA,GAA2B,8CAAA;AAMjC,eAAsB,sBAAA,CACpB,KAAA,EACA,IAAA,EACA,YAAA,EACiB;AACjB,EAAA,MAAM,UAAU,iBAAA,EAAkB;AAClC,EAAA,MAAM,CAAC,OAAO,CAAA,GAAI,MAAM,wBAAA,CAAyB;AAAA,IAC/C,cAAA,EAAgB,QAAQ,wBAAwB,CAAA;AAAA,IAChD,KAAA,EAAO,CAAC,KAAA,EAAO,YAAA,EAAc,IAAI,CAAA,CAAE,GAAA,CAAI,CAAC,GAAA,KAAQ,OAAA,CAAQ,MAAA,CAAO,OAAA,CAAQ,GAAG,CAAC,CAAC;AAAA,GAC7E,CAAA;AACD,EAAA,OAAO,OAAA;AACT;AAMO,SAAS,YAAA,CAAa,SAAkB,OAAA,EAAiD;AAC9F,EAAA,IAAI,CAAC,QAAA,CAAS,OAAO,CAAA,EAAG,OAAO,uCAAA;AAC/B,EAAA,MAAM,WAAA,GAAc,QAAQ,aAAa,CAAA;AACzC,EAAA,IAAI,OAAO,WAAA,KAAgB,QAAA,IAAY,WAAA,CAAY,SAAS,sBAAA,EAAwB;AAClF,IAAA,OAAO,uCAAA;AAAA,EACT;AACA,EAAA,IAAI,WAAA;AACJ,EAAA,IAAI;AACF,IAAA,WAAA,GAAc,sBAAA,CAAuB,4BAAA,CAA6B,EAAE,WAAA,EAAa,CAAC,CAAA;AAAA,EACpF,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,4DAAA;AAAA,EACT;AACA,EAAA,OAAO,EAAE,SAAA,EAAW,mBAAA,CAAoB,EAAE,OAAA,EAAS,WAAA,EAAa,CAAA,EAAE;AACpE","file":"svm-3MMYFPC7.js","sourcesContent":["/**\n * Solana `exact` payload inspection: bounded decoding and the replay identity.\n * The provider loads this module only for a Solana offer, so an EVM-only\n * deployment never imports `@x402/svm` or `@solana/kit`.\n *\n * The facilitator checks the transaction itself: the fee payer, signatures,\n * instruction layout, mint, recipient token account and amount, and a\n * simulation. Its smart-wallet path accepts layouts the gateway could not\n * parse, so the gateway does not read the transfer.\n */\nimport { address, getAddressEncoder, getProgramDerivedAddress } from '@solana/kit';\nimport { decodeTransactionFromPayload, transactionMessageHash } from '@x402/svm';\nimport { isRecord } from '../../core/is-record';\nimport { computeSvmReplayKey } from './replay-key';\n\n// A Solana transaction fits a 1232-byte packet, which is 1644 base64 characters\nconst MAX_TRANSACTION_BASE64 = 1644;\n\nconst ASSOCIATED_TOKEN_PROGRAM = 'ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL';\n\n/**\n * The associated token account of `owner` for `mint`, where the SDK client\n * sends a Solana `exact` payment. Its transaction cannot create the account.\n */\nexport async function associatedTokenAccount(\n owner: string,\n mint: string,\n tokenProgram: string,\n): Promise<string> {\n const encoder = getAddressEncoder();\n const [account] = await getProgramDerivedAddress({\n programAddress: address(ASSOCIATED_TOKEN_PROGRAM),\n seeds: [owner, tokenProgram, mint].map((key) => encoder.encode(address(key))),\n });\n return account;\n}\n\n/**\n * Returns the Solana `exact` replay key, or an SDK refusal reason for a\n * missing, oversized or undecodable transaction.\n */\nexport function svmReplayKey(payload: unknown, network: string): { replayKey: string } | string {\n if (!isRecord(payload)) return 'invalid_exact_svm_payload_transaction';\n const transaction = payload['transaction'];\n if (typeof transaction !== 'string' || transaction.length > MAX_TRANSACTION_BASE64) {\n return 'invalid_exact_svm_payload_transaction';\n }\n let messageHash: string;\n try {\n messageHash = transactionMessageHash(decodeTransactionFromPayload({ transaction }));\n } catch {\n return 'invalid_exact_svm_payload_transaction_could_not_be_decoded';\n }\n return { replayKey: computeSvmReplayKey({ network, messageHash }) };\n}\n"]}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { chainIdFromCaip2 } from './chunk-QZ6TOMX6.js';
|
|
2
|
+
export { createX402PaymentProvider } from './chunk-QZ6TOMX6.js';
|
|
3
|
+
import './chunk-KTV52MCU.js';
|
|
4
|
+
export { SUPPORTED_NETWORK_IDS } from './chunk-OZ4LAWBK.js';
|
|
5
|
+
import './chunk-OSTCU6ZK.js';
|
|
6
|
+
import './chunk-QY3K6PEQ.js';
|
|
7
|
+
import { CommerceError } from './chunk-QQ3WY5L3.js';
|
|
8
|
+
import './chunk-3M6U7ILB.js';
|
|
9
|
+
import { PaymentRequirementsV2Schema } from '@x402/core/schemas';
|
|
10
|
+
import { getAddress, toHex } from 'viem';
|
|
11
|
+
import { privateKeyToAccount } from 'viem/accounts';
|
|
12
|
+
|
|
13
|
+
var X402_VERSION = 2;
|
|
14
|
+
var TRANSFER_WITH_AUTHORIZATION_TYPES = {
|
|
15
|
+
TransferWithAuthorization: [
|
|
16
|
+
{ name: "from", type: "address" },
|
|
17
|
+
{ name: "to", type: "address" },
|
|
18
|
+
{ name: "value", type: "uint256" },
|
|
19
|
+
{ name: "validAfter", type: "uint256" },
|
|
20
|
+
{ name: "validBefore", type: "uint256" },
|
|
21
|
+
{ name: "nonce", type: "bytes32" }
|
|
22
|
+
]
|
|
23
|
+
};
|
|
24
|
+
async function createPaymentProof(options) {
|
|
25
|
+
const requirements = PaymentRequirementsV2Schema.parse(options.accepts);
|
|
26
|
+
const method = requirements.extra?.["assetTransferMethod"];
|
|
27
|
+
if (method !== void 0 && method !== "eip3009") {
|
|
28
|
+
throw new CommerceError(
|
|
29
|
+
"INPUT_INVALID",
|
|
30
|
+
`createPaymentProof: signs EIP-3009 only, and this offer uses "${String(method)}"; sign it with the SDK's x402Client`
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
if (!requirements.extra || typeof requirements.extra["name"] !== "string" || typeof requirements.extra["version"] !== "string") {
|
|
34
|
+
throw new CommerceError(
|
|
35
|
+
"INPUT_INVALID",
|
|
36
|
+
"createPaymentProof: payment requirement is missing extra.name/extra.version, so the EIP-712 domain cannot be built"
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
const chainId = chainIdFromCaip2(requirements.network);
|
|
40
|
+
if (chainId === void 0) {
|
|
41
|
+
throw new CommerceError(
|
|
42
|
+
"INPUT_INVALID",
|
|
43
|
+
`createPaymentProof: network "${requirements.network}" is not a CAIP-2 eip155 identifier, so there is no chain id to sign against`
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
const account = privateKeyToAccount(options.buyerPrivateKey);
|
|
47
|
+
const nonce = options.overrides?.nonce ?? randomNonce();
|
|
48
|
+
const nowSeconds = Math.floor(Date.now() / 1e3);
|
|
49
|
+
const validAfter = options.overrides?.validAfter ?? 0;
|
|
50
|
+
const validBefore = options.overrides?.validBefore ?? nowSeconds + requirements.maxTimeoutSeconds;
|
|
51
|
+
const to = getAddress(options.overrides?.payTo ?? requirements.payTo);
|
|
52
|
+
const value = BigInt(options.overrides?.value ?? requirements.amount);
|
|
53
|
+
const signature = await account.signTypedData({
|
|
54
|
+
domain: {
|
|
55
|
+
name: requirements.extra["name"],
|
|
56
|
+
version: requirements.extra["version"],
|
|
57
|
+
chainId,
|
|
58
|
+
verifyingContract: getAddress(requirements.asset)
|
|
59
|
+
},
|
|
60
|
+
types: TRANSFER_WITH_AUTHORIZATION_TYPES,
|
|
61
|
+
primaryType: "TransferWithAuthorization",
|
|
62
|
+
message: {
|
|
63
|
+
from: account.address,
|
|
64
|
+
to,
|
|
65
|
+
value,
|
|
66
|
+
validAfter: BigInt(validAfter),
|
|
67
|
+
validBefore: BigInt(validBefore),
|
|
68
|
+
nonce
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
const payload = {
|
|
72
|
+
x402Version: X402_VERSION,
|
|
73
|
+
accepted: requirements,
|
|
74
|
+
payload: {
|
|
75
|
+
signature,
|
|
76
|
+
authorization: {
|
|
77
|
+
from: account.address,
|
|
78
|
+
to,
|
|
79
|
+
value: value.toString(),
|
|
80
|
+
validAfter: validAfter.toString(),
|
|
81
|
+
validBefore: validBefore.toString(),
|
|
82
|
+
nonce
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
return Buffer.from(JSON.stringify(payload), "utf8").toString("base64");
|
|
87
|
+
}
|
|
88
|
+
function randomNonce() {
|
|
89
|
+
const bytes = new Uint8Array(32);
|
|
90
|
+
crypto.getRandomValues(bytes);
|
|
91
|
+
return toHex(bytes);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export { createPaymentProof };
|
|
95
|
+
//# sourceMappingURL=x402-NADFV5CD.js.map
|
|
96
|
+
//# sourceMappingURL=x402-NADFV5CD.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/payments/x402/client.ts"],"names":[],"mappings":"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","file":"x402-NADFV5CD.js","sourcesContent":["/**\n * Client-side payment helper: builds and EIP-712-signs an x402 v2 `exact`/EVM\n * authorization on the buyer's side. The demo buyer agent and the test suites\n * use it, and the `/x402` entry exports it. The gateway never calls it and\n * never holds a buyer key.\n *\n * It signs directly rather than through the SDK's `x402Client` because of\n * `overrides`: negative tests need deliberately wrong authorizations that a\n * conforming client will not produce. The x402 settlement E2E suite also\n * settles a payment built by `x402Client` itself to cover interoperability.\n */\n\nimport { PaymentRequirementsV2Schema } from '@x402/core/schemas';\nimport type { PaymentPayload, PaymentRequirements } from '@x402/core/types';\nimport { getAddress, toHex } from 'viem';\nimport { privateKeyToAccount } from 'viem/accounts';\nimport { CommerceError } from '../../core';\nimport { chainIdFromCaip2 } from './chain';\n\nexport interface CreatePaymentProofOptions {\n /** The buyer's private key. It signs locally and is never sent anywhere */\n readonly buyerPrivateKey: `0x${string}`;\n /** One entry from PaymentRequiredEnvelope.payment.accepts, verbatim */\n readonly accepts: Readonly<Record<string, unknown>>;\n /** For negative tests only: a wrong amount, recipient, nonce or validity window */\n readonly overrides?: {\n readonly value?: string;\n readonly payTo?: string;\n readonly nonce?: `0x${string}`;\n readonly validBefore?: number;\n readonly validAfter?: number;\n };\n}\n\nconst X402_VERSION = 2;\n\nconst TRANSFER_WITH_AUTHORIZATION_TYPES = {\n TransferWithAuthorization: [\n { name: 'from', type: 'address' },\n { name: 'to', type: 'address' },\n { name: 'value', type: 'uint256' },\n { name: 'validAfter', type: 'uint256' },\n { name: 'validBefore', type: 'uint256' },\n { name: 'nonce', type: 'bytes32' },\n ],\n} as const;\n\n/** Returns the base64 `PAYMENT-SIGNATURE` value to send back to the gateway */\nexport async function createPaymentProof(options: CreatePaymentProofOptions): Promise<string> {\n const requirements = PaymentRequirementsV2Schema.parse(options.accepts);\n const method = requirements.extra?.['assetTransferMethod'];\n if (method !== undefined && method !== 'eip3009') {\n throw new CommerceError(\n 'INPUT_INVALID',\n `createPaymentProof: signs EIP-3009 only, and this offer uses \"${String(method)}\"; sign it with the SDK's x402Client`,\n );\n }\n if (\n !requirements.extra ||\n typeof requirements.extra['name'] !== 'string' ||\n typeof requirements.extra['version'] !== 'string'\n ) {\n throw new CommerceError(\n 'INPUT_INVALID',\n 'createPaymentProof: payment requirement is missing extra.name/extra.version, so the EIP-712 domain cannot be built',\n );\n }\n\n const chainId = chainIdFromCaip2(requirements.network);\n if (chainId === undefined) {\n throw new CommerceError(\n 'INPUT_INVALID',\n `createPaymentProof: network \"${requirements.network}\" is not a CAIP-2 eip155 identifier, so there is no chain id to sign against`,\n );\n }\n\n const account = privateKeyToAccount(options.buyerPrivateKey);\n\n const nonce = options.overrides?.nonce ?? randomNonce();\n const nowSeconds = Math.floor(Date.now() / 1000);\n // 0, as in the SDK's own v2 client: nothing here wants the authorization\n // delayed\n const validAfter = options.overrides?.validAfter ?? 0;\n const validBefore = options.overrides?.validBefore ?? nowSeconds + requirements.maxTimeoutSeconds;\n const to = getAddress((options.overrides?.payTo ?? requirements.payTo) as `0x${string}`);\n const value = BigInt(options.overrides?.value ?? requirements.amount);\n\n const signature = await account.signTypedData({\n domain: {\n name: requirements.extra['name'],\n version: requirements.extra['version'],\n chainId,\n verifyingContract: getAddress(requirements.asset as `0x${string}`),\n },\n types: TRANSFER_WITH_AUTHORIZATION_TYPES,\n primaryType: 'TransferWithAuthorization',\n message: {\n from: account.address,\n to,\n value,\n validAfter: BigInt(validAfter),\n validBefore: BigInt(validBefore),\n nonce,\n },\n });\n\n // v2 echoes the chosen requirement back as `accepted` so a stateless\n // facilitator knows which offer was taken. The gateway verifies against its\n // own copy.\n const payload: PaymentPayload = {\n x402Version: X402_VERSION,\n accepted: requirements as PaymentRequirements,\n payload: {\n signature,\n authorization: {\n from: account.address,\n to,\n value: value.toString(),\n validAfter: validAfter.toString(),\n validBefore: validBefore.toString(),\n nonce,\n },\n },\n };\n\n return Buffer.from(JSON.stringify(payload), 'utf8').toString('base64');\n}\n\nfunction randomNonce(): `0x${string}` {\n const bytes = new Uint8Array(32);\n crypto.getRandomValues(bytes);\n return toHex(bytes);\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { I as IsoTimestamp, D as DecimalAmount, P as PaymentMethodName, a as Com
|
|
|
3
3
|
export { f as AdapterHealthComponent, g as AuthorizationMethodName, h as BackendMethod, i as DEFAULT_BACKEND_TIMEOUT_MS, J as JsonSchema, N as NOOP_LOGGER, j as PAYMENT_METHOD_NAMES, k as PROTOCOL_NAMES, l as PaymentChallenge, m as PaymentContext, n as PaymentRequirement, o as PaymentResult, p as PaymentSettlementContext, q as PaymentVerificationContext, r as Pricing, s as ProtocolName, t as systemClock } from './runtime-7vLNYvmU.js';
|
|
4
4
|
import { M as MppNetwork } from './constants-nackLItD.js';
|
|
5
5
|
import { X as X402PaymentFlow, a as X402FacilitatorConfig } from './guardrails-CX_jYXvZ.js';
|
|
6
|
-
import { C as CustomNetworks } from './networks-
|
|
6
|
+
import { C as CustomNetworks } from './networks-DTWRlj-K.js';
|
|
7
7
|
import { a as AuthorizationRequirement, b as AuthorizationSubmission, A as AuthorizationProvider } from './authorization-CMkIuAkO.js';
|
|
8
8
|
export { c as AuthorizationFinalizeContext, d as AuthorizationRecord, e as AuthorizationVerification, f as AuthorizationVerificationContext } from './authorization-CMkIuAkO.js';
|
|
9
9
|
import { D as DeliveredOutcome, P as PaymentRequiredOutcome, C as CommerceEvent, a as PaymentAttempt, b as CommerceReceipt, E as ExecutionPipeline, c as ProtocolAdapter, H as HttpProtocolAdapter, A as AdapterHttpRoute, d as ProtocolAdapterContext } from './protocol-adapter-CfxU8Z2T.js';
|
|
@@ -329,6 +329,13 @@ interface ListOptions {
|
|
|
329
329
|
readonly limit?: number;
|
|
330
330
|
readonly requestId?: string;
|
|
331
331
|
}
|
|
332
|
+
interface ReceiptListOptions extends ListOptions {
|
|
333
|
+
/**
|
|
334
|
+
* When true, return only receipts counted by {@link ReceiptStore.countUndeliveredReceipts}.
|
|
335
|
+
* Stores ignoring this flag also return delivered receipts.
|
|
336
|
+
*/
|
|
337
|
+
readonly undelivered?: boolean;
|
|
338
|
+
}
|
|
332
339
|
interface ReceiptStore {
|
|
333
340
|
init(): Promise<void>;
|
|
334
341
|
/** Append a canonical event. Must not throw into the caller's flow */
|
|
@@ -347,7 +354,7 @@ interface ReceiptStore {
|
|
|
347
354
|
updatePaymentAttempt(update: PaymentAttemptUpdate): Promise<void>;
|
|
348
355
|
saveReceipt(receipt: CommerceReceipt): Promise<void>;
|
|
349
356
|
getReceipt(id: string): Promise<CommerceReceipt | undefined>;
|
|
350
|
-
listReceipts(options?:
|
|
357
|
+
listReceipts(options?: ReceiptListOptions): Promise<readonly CommerceReceipt[]>;
|
|
351
358
|
/**
|
|
352
359
|
* Total receipts held. `listReceipts` clamps every page, so counting a list's
|
|
353
360
|
* length would stop at the clamp.
|
|
@@ -496,6 +503,8 @@ interface GatewayConfig {
|
|
|
496
503
|
readonly paymentFlow?: X402PaymentFlow;
|
|
497
504
|
/** Resources whose `paymentFlow` overrides the rail's, by resource id */
|
|
498
505
|
readonly resourcePaymentFlows?: Readonly<Record<string, X402PaymentFlow>>;
|
|
506
|
+
/** Resources that set `mimeType`, by resource id; others declare `application/json` */
|
|
507
|
+
readonly resourceMimeTypes?: Readonly<Record<string, string>>;
|
|
499
508
|
readonly facilitator: X402FacilitatorConfig;
|
|
500
509
|
readonly allowMainnet?: boolean;
|
|
501
510
|
readonly allowUnauthenticatedFacilitator?: boolean;
|
|
@@ -716,4 +725,4 @@ interface SqliteReceiptStoreOptions {
|
|
|
716
725
|
}
|
|
717
726
|
declare function createSqliteReceiptStore(options: SqliteReceiptStoreOptions): ReceiptStore;
|
|
718
727
|
|
|
719
|
-
export { A2A_AGENT_CARD_PATH, A2A_PROTOCOL_VERSION, A2A_SPEC_VERSION, type A2aAdapterOptions, ACP_API_VERSION, ACP_SPEC_VERSION, ACP_WELL_KNOWN_PATH, AUTHORIZATION_HEADER, AUTHORIZATION_INPUT_FIELD, type AcpAdapterOptions, AdapterDescriptor, AdapterHealth, AdapterHttpRoute, AuthorizationProvider, AuthorizationRequirement, AuthorizationSubmission, type BackendExecutor, BackendHandler, type BackendRequest, type BackendResponse, COMMERCE_ERROR_CODES, COMMERCE_ERROR_HTTP_STATUS, Clock, CommerceError, type CommerceErrorCode, type CommerceErrorInfo, type CommerceErrorOptions, CommerceEvent, CommerceReceipt, CommerceResource, DELIVERY_SUMMARY_META_KEY, DecimalAmount, DeliveredOutcome, type DeliverySummary, type ErrorEnvelope, ExecutionPipeline, type GatewayConfig, type GatewayInstance, type GatewayOptions, HttpProtocolAdapter, IdGenerator, IsoTimestamp, type ListOptions, Logger, MAX_AUTHORIZATION_HEADER_BYTES, PAYMENT_HEADER, PAYMENT_INPUT_FIELD, PAYMENT_REQUIRED_HEADER, PAYMENT_RESPONSE_HEADER, PaymentAttempt, type PaymentAttemptReservation, type PaymentAttemptUpdate, PaymentMethodName, PaymentProvider, type PaymentRequiredEnvelope, PaymentRequiredOutcome, PaymentSubmission, ProtocolAdapter, ProtocolAdapterContext, RESERVED_INPUT_FIELDS, RETRYABLE_ERROR_CODES, type ReceiptStore, ResourceRegistry, createA2aAdapter, createAcpAdapter, createGateway, createSqliteReceiptStore, extractReservedInputFields, isCommerceError, isPaymentRequiredEnvelope, loadConfig, parseAuthorizationHeader, parseAuthorizationSubmission, parseConfig, createSqliteReceiptStore as receipts, toCommerceError, toDeliverySummary, toErrorEnvelope, toPaymentRequiredEnvelope };
|
|
728
|
+
export { A2A_AGENT_CARD_PATH, A2A_PROTOCOL_VERSION, A2A_SPEC_VERSION, type A2aAdapterOptions, ACP_API_VERSION, ACP_SPEC_VERSION, ACP_WELL_KNOWN_PATH, AUTHORIZATION_HEADER, AUTHORIZATION_INPUT_FIELD, type AcpAdapterOptions, AdapterDescriptor, AdapterHealth, AdapterHttpRoute, AuthorizationProvider, AuthorizationRequirement, AuthorizationSubmission, type BackendExecutor, BackendHandler, type BackendRequest, type BackendResponse, COMMERCE_ERROR_CODES, COMMERCE_ERROR_HTTP_STATUS, Clock, CommerceError, type CommerceErrorCode, type CommerceErrorInfo, type CommerceErrorOptions, CommerceEvent, CommerceReceipt, CommerceResource, DELIVERY_SUMMARY_META_KEY, DecimalAmount, DeliveredOutcome, type DeliverySummary, type ErrorEnvelope, ExecutionPipeline, type GatewayConfig, type GatewayInstance, type GatewayOptions, HttpProtocolAdapter, IdGenerator, IsoTimestamp, type ListOptions, Logger, MAX_AUTHORIZATION_HEADER_BYTES, PAYMENT_HEADER, PAYMENT_INPUT_FIELD, PAYMENT_REQUIRED_HEADER, PAYMENT_RESPONSE_HEADER, PaymentAttempt, type PaymentAttemptReservation, type PaymentAttemptUpdate, PaymentMethodName, PaymentProvider, type PaymentRequiredEnvelope, PaymentRequiredOutcome, PaymentSubmission, ProtocolAdapter, ProtocolAdapterContext, RESERVED_INPUT_FIELDS, RETRYABLE_ERROR_CODES, type ReceiptListOptions, type ReceiptStore, ResourceRegistry, createA2aAdapter, createAcpAdapter, createGateway, createSqliteReceiptStore, extractReservedInputFields, isCommerceError, isPaymentRequiredEnvelope, loadConfig, parseAuthorizationHeader, parseAuthorizationSubmission, parseConfig, createSqliteReceiptStore as receipts, toCommerceError, toDeliverySummary, toErrorEnvelope, toPaymentRequiredEnvelope };
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { openSqliteDatabase, AP2_SPEC_VERSION, AP2_MODES, AP2_DEFAULT_CLOCK_SKEW_SECONDS, AP2_JWK_MEMBERS, AP2_KEY_TYPE, AP2_SIGNING_ALGORITHM, AP2_JWK_CURVE, AP2_JWK_COORDINATE_BYTES, AP2_MAX_CLOCK_SKEW_SECONDS } from './chunk-
|
|
1
|
+
import { openSqliteDatabase, AP2_SPEC_VERSION, AP2_MODES, AP2_DEFAULT_CLOCK_SKEW_SECONDS, AP2_JWK_MEMBERS, AP2_KEY_TYPE, AP2_SIGNING_ALGORITHM, AP2_JWK_CURVE, AP2_JWK_COORDINATE_BYTES, AP2_MAX_CLOCK_SKEW_SECONDS } from './chunk-2DAJAJI7.js';
|
|
2
2
|
import { readCappedBody, createBearerCheck, MCP_TOOL_NAME_PATTERN, settlementResponse, joinUrl, settlementResponseFromDetails, settlementFailure, x402ErrorCode, x402RefusalStatus } from './chunk-ES3V6ECS.js';
|
|
3
3
|
import { MPP_DEFAULT_NETWORK, isMppNetwork, MPP_NETWORKS, MPP_DEFAULT_PAYMENT_FLOW, MPP_MIN_CHALLENGE_SECRET_LENGTH, MPP_PROFILE } from './chunk-6Z2H53CG.js';
|
|
4
4
|
import { contentDigest, CONTENT_DIGEST_METADATA_KEY, mppProblem, mppProblemDetail } from './chunk-5ZYXBCDX.js';
|
|
5
|
-
import { X402_PAYMENT_FLOWS, validateCustomNetworks, findX402Network, X402_DEFAULT_PAYMENT_FLOW, resolveX402Deployment, SETTLE_AFTER_BACKEND_METADATA_KEY, resolveDeploymentMode, requireX402Network, resolveX402Option, isEvmAddress, isEvmZeroAddress, x402OfferName, REUSE_REJECTED_AUTHORIZATION_METADATA_KEY } from './chunk-
|
|
6
|
-
import { RESERVED_INPUT_FIELDS, PROTOCOL_NAMES, PAYMENT_METHOD_NAMES, PAYMENT_HEADER, AUTHORIZATION_HEADER, CommerceError, systemClock, NOOP_LOGGER, PACKAGE_VERSION, toCommerceError, DEFAULT_BACKEND_TIMEOUT_MS, isCommerceError, describeError, isHttpProtocolAdapter, toLogInfo, extractReservedInputFields, parseAuthorizationHeader, toPaymentRequiredEnvelope, PAYMENT_REQUIRED_HEADER, PAYMENT_RESPONSE_HEADER, toErrorEnvelope, DELIVERY_SUMMARY_META_KEY, toDeliverySummary, PAYMENT_INPUT_FIELD, AUTHORIZATION_INPUT_FIELD, parseAuthorizationSubmission } from './chunk-
|
|
7
|
-
export { AUTHORIZATION_HEADER, AUTHORIZATION_INPUT_FIELD, COMMERCE_ERROR_CODES, COMMERCE_ERROR_HTTP_STATUS, COMMERCE_EVENT_TYPES, CommerceError, DEFAULT_BACKEND_TIMEOUT_MS, DELIVERY_SUMMARY_META_KEY, MAX_AUTHORIZATION_HEADER_BYTES, NOOP_LOGGER, PAYMENT_HEADER, PAYMENT_INPUT_FIELD, PAYMENT_METHOD_NAMES, PAYMENT_REQUIRED_HEADER, PAYMENT_RESPONSE_HEADER, PROTOCOL_NAMES, RESERVED_INPUT_FIELDS, RETRYABLE_ERROR_CODES, extractReservedInputFields, isCommerceError, isHttpProtocolAdapter, isPaymentRequiredEnvelope, parseAuthorizationHeader, parseAuthorizationSubmission, systemClock, toCommerceError, toDeliverySummary, toErrorEnvelope, toPaymentRequiredEnvelope } from './chunk-
|
|
5
|
+
import { X402_PAYMENT_FLOWS, validateCustomNetworks, findX402Network, X402_DEFAULT_PAYMENT_FLOW, resolveX402Deployment, SETTLE_AFTER_BACKEND_METADATA_KEY, resolveDeploymentMode, requireX402Network, resolveX402Option, isEvmAddress, isEvmZeroAddress, x402OfferName, REUSE_REJECTED_AUTHORIZATION_METADATA_KEY } from './chunk-REBY2IEP.js';
|
|
6
|
+
import { RESERVED_INPUT_FIELDS, PROTOCOL_NAMES, PAYMENT_METHOD_NAMES, PAYMENT_HEADER, AUTHORIZATION_HEADER, CommerceError, systemClock, NOOP_LOGGER, PACKAGE_VERSION, toCommerceError, DEFAULT_BACKEND_TIMEOUT_MS, isCommerceError, describeError, isHttpProtocolAdapter, toLogInfo, extractReservedInputFields, parseAuthorizationHeader, toPaymentRequiredEnvelope, PAYMENT_REQUIRED_HEADER, PAYMENT_RESPONSE_HEADER, toErrorEnvelope, DELIVERY_SUMMARY_META_KEY, toDeliverySummary, PAYMENT_INPUT_FIELD, AUTHORIZATION_INPUT_FIELD, parseAuthorizationSubmission } from './chunk-XYHDQ22D.js';
|
|
7
|
+
export { AUTHORIZATION_HEADER, AUTHORIZATION_INPUT_FIELD, COMMERCE_ERROR_CODES, COMMERCE_ERROR_HTTP_STATUS, COMMERCE_EVENT_TYPES, CommerceError, DEFAULT_BACKEND_TIMEOUT_MS, DELIVERY_SUMMARY_META_KEY, MAX_AUTHORIZATION_HEADER_BYTES, NOOP_LOGGER, PAYMENT_HEADER, PAYMENT_INPUT_FIELD, PAYMENT_METHOD_NAMES, PAYMENT_REQUIRED_HEADER, PAYMENT_RESPONSE_HEADER, PROTOCOL_NAMES, RESERVED_INPUT_FIELDS, RETRYABLE_ERROR_CODES, extractReservedInputFields, isCommerceError, isHttpProtocolAdapter, isPaymentRequiredEnvelope, parseAuthorizationHeader, parseAuthorizationSubmission, systemClock, toCommerceError, toDeliverySummary, toErrorEnvelope, toPaymentRequiredEnvelope } from './chunk-XYHDQ22D.js';
|
|
8
8
|
import { isRecord } from './chunk-2CJNA7MS.js';
|
|
9
9
|
import { promises, accessSync, constants } from 'fs';
|
|
10
10
|
import * as path from 'path';
|
|
@@ -678,7 +678,9 @@ function normalizeX402(raw, resources) {
|
|
|
678
678
|
facilitator,
|
|
679
679
|
...allowMainnet !== void 0 ? { allowMainnet } : {},
|
|
680
680
|
...allowUnauthenticatedFacilitator !== void 0 ? { allowUnauthenticatedFacilitator } : {},
|
|
681
|
-
...networks !== void 0 ? { customNetworks: networks } : {}
|
|
681
|
+
...networks !== void 0 ? { customNetworks: networks } : {},
|
|
682
|
+
// resolveX402Option required the token's own metadata
|
|
683
|
+
allowOtherEvmToken: true
|
|
682
684
|
});
|
|
683
685
|
if (firstMode !== void 0 && mode !== firstMode) {
|
|
684
686
|
throw x402Invalid(
|
|
@@ -810,6 +812,9 @@ function normalizeMpp(raw) {
|
|
|
810
812
|
var SUPPORTED_CONFIG_VERSION = 1;
|
|
811
813
|
var NumberOrString = z.union([z.number(), z.string()]);
|
|
812
814
|
var BooleanOrString = z.union([z.boolean(), z.string()]);
|
|
815
|
+
var MediaType = z.string().regex(/^[A-Za-z0-9][\w!#$&^.+-]*\/[A-Za-z0-9][\w!#$&^.+-]*(?:[ \t]*;.*)?$/, {
|
|
816
|
+
message: "must be a media type such as application/json"
|
|
817
|
+
});
|
|
813
818
|
var RpcUrl = z.string().min(1).refine(isHttpUrl, { message: "must be an http:// or https:// URL" });
|
|
814
819
|
function isHttpUrl(value) {
|
|
815
820
|
try {
|
|
@@ -955,6 +960,8 @@ var ResourceEntrySchema = z.object({
|
|
|
955
960
|
description: z.string().optional(),
|
|
956
961
|
input: JsonSchemaValueSchema.optional(),
|
|
957
962
|
output: JsonSchemaValueSchema.optional(),
|
|
963
|
+
// What the backend returns; x402 challenges declare it, `application/json` by default
|
|
964
|
+
mimeType: MediaType.optional(),
|
|
958
965
|
backend: BackendHandlerSchema,
|
|
959
966
|
pricing: PricingSchema,
|
|
960
967
|
expose: z.array(z.string().min(1)).min(1),
|
|
@@ -2803,6 +2810,13 @@ function normalizeResource(id, entry, protocols, x402, mpp, ap2) {
|
|
|
2803
2810
|
{ details: { path: `resources.${id}.paymentFlow`, resourceId: id } }
|
|
2804
2811
|
);
|
|
2805
2812
|
}
|
|
2813
|
+
if (entry.mimeType !== void 0 && (entry.pricing.type !== "fixed" || !paymentMethods.includes("x402"))) {
|
|
2814
|
+
throw new CommerceError(
|
|
2815
|
+
"CONFIG_INVALID",
|
|
2816
|
+
`Resource "${id}" sets mimeType, which requires fixed pricing and "x402" in payments`,
|
|
2817
|
+
{ details: { path: `resources.${id}.mimeType`, resourceId: id } }
|
|
2818
|
+
);
|
|
2819
|
+
}
|
|
2806
2820
|
const pricing = entry.pricing.type === "free" ? { type: "free" } : { type: "fixed", amount: entry.pricing.amount, currency: entry.pricing.currency };
|
|
2807
2821
|
const authorization = normalizeResourceAuthorization(id, entry, pricing, ap2);
|
|
2808
2822
|
return {
|
|
@@ -2897,7 +2911,17 @@ function normalize(raw) {
|
|
|
2897
2911
|
);
|
|
2898
2912
|
return Object.keys(flows).length > 0 ? { resourcePaymentFlows: flows } : {};
|
|
2899
2913
|
};
|
|
2900
|
-
const
|
|
2914
|
+
const mimeTypes = Object.fromEntries(
|
|
2915
|
+
resources.flatMap((resource) => {
|
|
2916
|
+
const mimeType = raw.resources[resource.id]?.mimeType;
|
|
2917
|
+
return mimeType !== void 0 ? [[resource.id, mimeType]] : [];
|
|
2918
|
+
})
|
|
2919
|
+
);
|
|
2920
|
+
const x402WithFlows = x402 !== void 0 ? {
|
|
2921
|
+
...x402,
|
|
2922
|
+
...flowOverrides2("x402"),
|
|
2923
|
+
...Object.keys(mimeTypes).length > 0 ? { resourceMimeTypes: mimeTypes } : {}
|
|
2924
|
+
} : x402;
|
|
2901
2925
|
const mppWithFlows = mpp !== void 0 ? { ...mpp, ...flowOverrides2("mpp") } : mpp;
|
|
2902
2926
|
if (protocols.acp.enabled) validateAcpCheckoutMapping(protocols.acp, resources);
|
|
2903
2927
|
if (protocols.a2a.enabled && !resources.some((r) => r.exposedVia.includes("a2a"))) {
|
|
@@ -3716,7 +3740,12 @@ function registerRoutes(options) {
|
|
|
3716
3740
|
server.get(
|
|
3717
3741
|
"/api/receipts",
|
|
3718
3742
|
{ onRequest: tokenHook },
|
|
3719
|
-
ledgerHandler(
|
|
3743
|
+
ledgerHandler(
|
|
3744
|
+
"receipts",
|
|
3745
|
+
(list, query) => options.store.listReceipts(
|
|
3746
|
+
parseFlag(query["undelivered"], "undelivered") ? { ...list, undelivered: true } : list
|
|
3747
|
+
)
|
|
3748
|
+
)
|
|
3720
3749
|
);
|
|
3721
3750
|
server.get(
|
|
3722
3751
|
"/api/events",
|
|
@@ -3741,8 +3770,10 @@ function digestingStream(request) {
|
|
|
3741
3770
|
function ledgerHandler(key, list) {
|
|
3742
3771
|
return async (request, reply) => {
|
|
3743
3772
|
try {
|
|
3744
|
-
const
|
|
3745
|
-
|
|
3773
|
+
const query = request.query;
|
|
3774
|
+
const limit = parseLimit(query["limit"]);
|
|
3775
|
+
const page = await list(limit !== void 0 ? { limit } : {}, query);
|
|
3776
|
+
return { [key]: page };
|
|
3746
3777
|
} catch (error) {
|
|
3747
3778
|
const commerceError = toCommerceError(error);
|
|
3748
3779
|
reply.status(commerceError.httpStatus).send(toErrorEnvelope(commerceError));
|
|
@@ -3819,11 +3850,32 @@ async function handleInvoke(request, reply, options) {
|
|
|
3819
3850
|
}
|
|
3820
3851
|
reply.header("cache-control", "private");
|
|
3821
3852
|
}
|
|
3853
|
+
const contentType = relayedContentType(outcome.headers?.["content-type"], outcome.body);
|
|
3854
|
+
if (contentType !== void 0) reply.type(contentType);
|
|
3855
|
+
if (typeof outcome.body === "string") {
|
|
3856
|
+
reply.header("content-security-policy", "sandbox");
|
|
3857
|
+
reply.header("x-content-type-options", "nosniff");
|
|
3858
|
+
}
|
|
3822
3859
|
reply.status(outcome.backendStatus).send(outcome.body);
|
|
3823
3860
|
} catch (error) {
|
|
3824
3861
|
sendInvokeError(reply, toCommerceError(error), paymentMethod);
|
|
3825
3862
|
}
|
|
3826
3863
|
}
|
|
3864
|
+
function relayedContentType(header2, body) {
|
|
3865
|
+
if (header2 === void 0) return void 0;
|
|
3866
|
+
const [essence = "", ...parameters] = (header2.match(/(?:[^;"]|"(?:[^"\\]|\\.)*"?)+/g) ?? []).map(
|
|
3867
|
+
(part) => part.trim()
|
|
3868
|
+
);
|
|
3869
|
+
const json = /[/+]json$/i.test(essence);
|
|
3870
|
+
if (!isTextType(essence) || json === (typeof body === "string")) return void 0;
|
|
3871
|
+
const kept = parameters.filter(
|
|
3872
|
+
(parameter) => parameter !== "" && !/^charset\s*=/i.test(parameter)
|
|
3873
|
+
);
|
|
3874
|
+
return [essence, ...kept, "charset=utf-8"].join("; ");
|
|
3875
|
+
}
|
|
3876
|
+
function isTextType(essence) {
|
|
3877
|
+
return /^text\//i.test(essence) || /[/+](?:json|xml)$/i.test(essence) || /^application\/(?:java|ecma)script$/i.test(essence);
|
|
3878
|
+
}
|
|
3827
3879
|
var PROVIDER_UNAVAILABLE_CODES = /* @__PURE__ */ new Set([
|
|
3828
3880
|
"PAYMENT_PROVIDER_UNAVAILABLE",
|
|
3829
3881
|
"AUTHORIZATION_PROVIDER_UNAVAILABLE"
|
|
@@ -3909,6 +3961,14 @@ function parseLimit(value) {
|
|
|
3909
3961
|
}
|
|
3910
3962
|
return n;
|
|
3911
3963
|
}
|
|
3964
|
+
function parseFlag(value, field) {
|
|
3965
|
+
if (Array.isArray(value)) return parseFlag(value[0], field);
|
|
3966
|
+
if (value === void 0 || value === "false") return false;
|
|
3967
|
+
if (value === "true") return true;
|
|
3968
|
+
throw new CommerceError("INPUT_INVALID", `Query parameter "${field}" must be true or false`, {
|
|
3969
|
+
details: { field }
|
|
3970
|
+
});
|
|
3971
|
+
}
|
|
3912
3972
|
|
|
3913
3973
|
// src/gateway/server.ts
|
|
3914
3974
|
var REQUEST_ID_HEADER = "x-request-id";
|
|
@@ -10399,6 +10459,7 @@ function clampListLimit(limit) {
|
|
|
10399
10459
|
const base = limit !== void 0 && Number.isFinite(limit) ? limit : DEFAULT_LIST_LIMIT;
|
|
10400
10460
|
return Math.min(Math.max(Math.trunc(base), 1), MAX_LIST_LIMIT);
|
|
10401
10461
|
}
|
|
10462
|
+
var UNDELIVERED = "backend_status NOT BETWEEN 200 AND 299";
|
|
10402
10463
|
var defaultIds = {
|
|
10403
10464
|
next: (prefix) => prefix !== void 0 ? `${prefix}_${randomUUID()}` : randomUUID()
|
|
10404
10465
|
};
|
|
@@ -10424,11 +10485,17 @@ function createSqliteReceiptStore(options) {
|
|
|
10424
10485
|
const listReceiptsByRequestStmt = db.prepare(
|
|
10425
10486
|
"SELECT * FROM receipts WHERE request_id = ? ORDER BY delivered_at DESC, seq DESC LIMIT ?"
|
|
10426
10487
|
);
|
|
10488
|
+
const listUndeliveredReceiptsStmt = db.prepare(
|
|
10489
|
+
`SELECT * FROM receipts WHERE ${UNDELIVERED} ORDER BY delivered_at DESC, seq DESC LIMIT ?`
|
|
10490
|
+
);
|
|
10491
|
+
const listUndeliveredReceiptsByRequestStmt = db.prepare(
|
|
10492
|
+
`SELECT * FROM receipts WHERE request_id = ? AND ${UNDELIVERED} ORDER BY delivered_at DESC, seq DESC LIMIT ?`
|
|
10493
|
+
);
|
|
10427
10494
|
const countReceiptsStmt = db.prepare(
|
|
10428
10495
|
"SELECT COUNT(*) AS count FROM receipts"
|
|
10429
10496
|
);
|
|
10430
10497
|
const countUndeliveredReceiptsStmt = db.prepare(
|
|
10431
|
-
|
|
10498
|
+
`SELECT COUNT(*) AS count FROM receipts WHERE ${UNDELIVERED}`
|
|
10432
10499
|
);
|
|
10433
10500
|
const insertEventStmt = db.prepare(
|
|
10434
10501
|
`INSERT INTO events (id, type, request_id, resource_id, at, adapter, payment_provider, duration_ms, status, data_json)
|
|
@@ -10587,7 +10654,11 @@ function createSqliteReceiptStore(options) {
|
|
|
10587
10654
|
},
|
|
10588
10655
|
async listReceipts(listOptions = {}) {
|
|
10589
10656
|
const limit = clampListLimit(listOptions.limit);
|
|
10590
|
-
const
|
|
10657
|
+
const undelivered = listOptions.undelivered === true;
|
|
10658
|
+
const rows = listOptions.requestId !== void 0 ? (undelivered ? listUndeliveredReceiptsByRequestStmt : listReceiptsByRequestStmt).all(
|
|
10659
|
+
listOptions.requestId,
|
|
10660
|
+
limit
|
|
10661
|
+
) : (undelivered ? listUndeliveredReceiptsStmt : listReceiptsStmt).all(limit);
|
|
10591
10662
|
return rows.map(rowToReceipt);
|
|
10592
10663
|
},
|
|
10593
10664
|
// Exact total, not bounded by the listReceipts clamp (see ReceiptStore.countReceipts)
|