@agenticprimitives/payments 0.0.0-alpha.10
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/LICENSE +21 -0
- package/README.md +44 -0
- package/dist/entitlement/index.d.ts +125 -0
- package/dist/entitlement/index.d.ts.map +1 -0
- package/dist/entitlement/index.js +128 -0
- package/dist/entitlement/index.js.map +1 -0
- package/dist/entitlement/voucher.d.ts +85 -0
- package/dist/entitlement/voucher.d.ts.map +1 -0
- package/dist/entitlement/voucher.js +109 -0
- package/dist/entitlement/voucher.js.map +1 -0
- package/dist/index.d.ts +135 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +60 -0
- package/dist/index.js.map +1 -0
- package/dist/mandate-sign.d.ts +187 -0
- package/dist/mandate-sign.d.ts.map +1 -0
- package/dist/mandate-sign.js +177 -0
- package/dist/mandate-sign.js.map +1 -0
- package/dist/mandate.d.ts +33 -0
- package/dist/mandate.d.ts.map +1 -0
- package/dist/mandate.js +40 -0
- package/dist/mandate.js.map +1 -0
- package/dist/ops.d.ts +55 -0
- package/dist/ops.d.ts.map +1 -0
- package/dist/ops.js +66 -0
- package/dist/ops.js.map +1 -0
- package/dist/rails/escrow.d.ts +156 -0
- package/dist/rails/escrow.d.ts.map +1 -0
- package/dist/rails/escrow.js +88 -0
- package/dist/rails/escrow.js.map +1 -0
- package/dist/rails/invoice.d.ts +65 -0
- package/dist/rails/invoice.d.ts.map +1 -0
- package/dist/rails/invoice.js +57 -0
- package/dist/rails/invoice.js.map +1 -0
- package/dist/rails/recurring.d.ts +56 -0
- package/dist/rails/recurring.d.ts.map +1 -0
- package/dist/rails/recurring.js +58 -0
- package/dist/rails/recurring.js.map +1 -0
- package/dist/rails/wallet.d.ts +16 -0
- package/dist/rails/wallet.d.ts.map +1 -0
- package/dist/rails/wallet.js +20 -0
- package/dist/rails/wallet.js.map +1 -0
- package/dist/rails/x402/executor.d.ts +118 -0
- package/dist/rails/x402/executor.d.ts.map +1 -0
- package/dist/rails/x402/executor.js +243 -0
- package/dist/rails/x402/executor.js.map +1 -0
- package/dist/rails/x402/index.d.ts +11 -0
- package/dist/rails/x402/index.d.ts.map +1 -0
- package/dist/rails/x402/index.js +8 -0
- package/dist/rails/x402/index.js.map +1 -0
- package/dist/rails/x402/nonce-store.d.ts +30 -0
- package/dist/rails/x402/nonce-store.d.ts.map +1 -0
- package/dist/rails/x402/nonce-store.js +35 -0
- package/dist/rails/x402/nonce-store.js.map +1 -0
- package/dist/rails/x402/quote.d.ts +41 -0
- package/dist/rails/x402/quote.d.ts.map +1 -0
- package/dist/rails/x402/quote.js +84 -0
- package/dist/rails/x402/quote.js.map +1 -0
- package/dist/rails/x402/resource.d.ts +42 -0
- package/dist/rails/x402/resource.d.ts.map +1 -0
- package/dist/rails/x402/resource.js +71 -0
- package/dist/rails/x402/resource.js.map +1 -0
- package/dist/rails/x402/wire.d.ts +81 -0
- package/dist/rails/x402/wire.d.ts.map +1 -0
- package/dist/rails/x402/wire.js +125 -0
- package/dist/rails/x402/wire.js.map +1 -0
- package/dist/receipt.d.ts +36 -0
- package/dist/receipt.d.ts.map +1 -0
- package/dist/receipt.js +50 -0
- package/dist/receipt.js.map +1 -0
- package/dist/refund.d.ts +29 -0
- package/dist/refund.d.ts.map +1 -0
- package/dist/refund.js +19 -0
- package/dist/refund.js.map +1 -0
- package/dist/split.d.ts +27 -0
- package/dist/split.d.ts.map +1 -0
- package/dist/split.js +33 -0
- package/dist/split.js.map +1 -0
- package/dist/transfer.d.ts +51 -0
- package/dist/transfer.d.ts.map +1 -0
- package/dist/transfer.js +54 -0
- package/dist/transfer.js.map +1 -0
- package/package.json +61 -0
- package/spec.md +5 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Recurring profile (spec 243 §5.5 / PMT-10) — NOT a rail, a mandate pattern.
|
|
3
|
+
*
|
|
4
|
+
* The payer authorizes ONCE (an open payment delegation whose caveats carry the per-charge
|
|
5
|
+
* cap + the frequency window + the aggregate cap); each period derives a CLOSED per-charge
|
|
6
|
+
* mandate settled via the wallet rail. The `PaymentEnforcer`'s on-chain frequency window +
|
|
7
|
+
* aggregate cap do the real enforcement — `recurringCaveatParams` returns the values the app
|
|
8
|
+
* feeds to `delegation.buildPaymentMandateCaveats` (payments doesn't runtime-import delegation).
|
|
9
|
+
*/
|
|
10
|
+
import { keccak256, encodeAbiParameters } from 'viem';
|
|
11
|
+
import { buildClosedMandate } from '../mandate.js';
|
|
12
|
+
import { buildWalletTransferPlan } from './wallet.js';
|
|
13
|
+
export function buildRecurringTemplate(input) {
|
|
14
|
+
if (input.amountPerPeriod <= 0n)
|
|
15
|
+
throw new Error('[recurring] amountPerPeriod must be > 0');
|
|
16
|
+
if (input.totalCap < input.amountPerPeriod)
|
|
17
|
+
throw new Error('[recurring] totalCap must be >= amountPerPeriod');
|
|
18
|
+
if (input.windowSeconds <= 0)
|
|
19
|
+
throw new Error('[recurring] windowSeconds must be > 0');
|
|
20
|
+
const templateId = keccak256(encodeAbiParameters([{ type: 'address' }, { type: 'address' }, { type: 'uint256' }, { type: 'uint256' }, { type: 'uint256' }], [input.payer, input.payee, input.amountPerPeriod, BigInt(input.windowSeconds), input.startNonce]));
|
|
21
|
+
return { ...input, templateId, periods: Number(input.totalCap / input.amountPerPeriod) };
|
|
22
|
+
}
|
|
23
|
+
/** The values the app feeds to `delegation.buildPaymentMandateCaveats` for the one-time authorization. */
|
|
24
|
+
export function recurringCaveatParams(t) {
|
|
25
|
+
return {
|
|
26
|
+
maxAmountPerCharge: t.amountPerPeriod,
|
|
27
|
+
maxAggregate: t.totalCap,
|
|
28
|
+
maxRedemptionsPerWindow: 1, // one charge per window
|
|
29
|
+
windowSeconds: t.windowSeconds,
|
|
30
|
+
validUntil: t.validUntil,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/** The time window in which period N may be charged (the enforcer rejects an early re-charge). */
|
|
34
|
+
export function periodWindow(t, period) {
|
|
35
|
+
const start = t.validFrom + period * t.windowSeconds;
|
|
36
|
+
return { start, end: start + t.windowSeconds };
|
|
37
|
+
}
|
|
38
|
+
/** Derive the closed per-charge mandate + transfer plan for period N. Sign the mandate, then settle. */
|
|
39
|
+
export function deriveScheduledCharge(t, period) {
|
|
40
|
+
if (period < 0 || period >= t.periods)
|
|
41
|
+
throw new Error(`[recurring] period out of range [0, ${t.periods})`);
|
|
42
|
+
const window = periodWindow(t, period);
|
|
43
|
+
const mandate = buildClosedMandate({
|
|
44
|
+
rail: 'wallet',
|
|
45
|
+
payer: t.payer,
|
|
46
|
+
payee: t.payee,
|
|
47
|
+
asset: t.asset,
|
|
48
|
+
amount: t.amountPerPeriod,
|
|
49
|
+
chain: t.chain,
|
|
50
|
+
nonce: t.startNonce + BigInt(period),
|
|
51
|
+
validFrom: window.start,
|
|
52
|
+
expiresAt: window.end,
|
|
53
|
+
orderHash: t.templateId,
|
|
54
|
+
legId: ('0x' + period.toString(16).padStart(64, '0')),
|
|
55
|
+
});
|
|
56
|
+
return { mandate, plan: buildWalletTransferPlan(mandate), window };
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=recurring.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recurring.js","sourceRoot":"","sources":["../../src/rails/recurring.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wallet rail (spec 243 §5.3/§5.5) — direct SA→SA transfer of a CLOSED mandate.
|
|
3
|
+
*
|
|
4
|
+
* Plain "checkout" pay: no budget delegation, no 402 round-trip. The payer SA executes a
|
|
5
|
+
* single ERC-20 transfer to the payee. Nullifier + receipt are identical to x402 (EXC-D3
|
|
6
|
+
* evidence symmetry). Ports the smart-agent `PledgeRegistry` cryptographic-rail pattern.
|
|
7
|
+
*/
|
|
8
|
+
import { type ClosedMandateInput } from '../mandate.js';
|
|
9
|
+
import { type TransferPlan } from '../transfer.js';
|
|
10
|
+
import type { PaymentMandate } from '../index.js';
|
|
11
|
+
export declare const WALLET_RAIL: "wallet";
|
|
12
|
+
/** Build an unsigned closed wallet-rail mandate (sign with `signPaymentMandate`). */
|
|
13
|
+
export declare function buildWalletMandate(input: Omit<ClosedMandateInput, 'rail'>): PaymentMandate;
|
|
14
|
+
/** The settlement plan for a closed wallet mandate: a direct transfer payer → payee. */
|
|
15
|
+
export declare function buildWalletTransferPlan(mandate: PaymentMandate): TransferPlan;
|
|
16
|
+
//# sourceMappingURL=wallet.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wallet.d.ts","sourceRoot":"","sources":["../../src/rails/wallet.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,EAAsB,KAAK,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAC5E,OAAO,EAAsB,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACvE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,eAAO,MAAM,WAAW,EAAG,QAAiB,CAAC;AAE7C,qFAAqF;AACrF,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,IAAI,CAAC,kBAAkB,EAAE,MAAM,CAAC,GAAG,cAAc,CAE1F;AAED,wFAAwF;AACxF,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,cAAc,GAAG,YAAY,CAE7E"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wallet rail (spec 243 §5.3/§5.5) — direct SA→SA transfer of a CLOSED mandate.
|
|
3
|
+
*
|
|
4
|
+
* Plain "checkout" pay: no budget delegation, no 402 round-trip. The payer SA executes a
|
|
5
|
+
* single ERC-20 transfer to the payee. Nullifier + receipt are identical to x402 (EXC-D3
|
|
6
|
+
* evidence symmetry). Ports the smart-agent `PledgeRegistry` cryptographic-rail pattern.
|
|
7
|
+
*/
|
|
8
|
+
import { mandateAmount } from '../mandate-sign.js';
|
|
9
|
+
import { buildClosedMandate } from '../mandate.js';
|
|
10
|
+
import { buildErc20Transfer } from '../transfer.js';
|
|
11
|
+
export const WALLET_RAIL = 'wallet';
|
|
12
|
+
/** Build an unsigned closed wallet-rail mandate (sign with `signPaymentMandate`). */
|
|
13
|
+
export function buildWalletMandate(input) {
|
|
14
|
+
return buildClosedMandate({ ...input, rail: 'wallet' });
|
|
15
|
+
}
|
|
16
|
+
/** The settlement plan for a closed wallet mandate: a direct transfer payer → payee. */
|
|
17
|
+
export function buildWalletTransferPlan(mandate) {
|
|
18
|
+
return buildErc20Transfer(mandate.amountPolicy.asset.id, mandate.payee, mandateAmount(mandate));
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=wallet.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wallet.js","sourceRoot":"","sources":["../../src/rails/wallet.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAA2B,MAAM,eAAe,CAAC;AAC5E,OAAO,EAAE,kBAAkB,EAAqB,MAAM,gBAAgB,CAAC;AAGvE,MAAM,CAAC,MAAM,WAAW,GAAG,QAAiB,CAAC;AAE7C,qFAAqF;AACrF,MAAM,UAAU,kBAAkB,CAAC,KAAuC;IACxE,OAAO,kBAAkB,CAAC,EAAE,GAAG,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;AAC1D,CAAC;AAED,wFAAwF;AACxF,MAAM,UAAU,uBAAuB,CAAC,OAAuB;IAC7D,OAAO,kBAAkB,CAAC,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,EAAa,EAAE,OAAO,CAAC,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC;AAC7G,CAAC"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { type Address, type Hex } from 'viem';
|
|
2
|
+
import type { Delegation } from '@agenticprimitives/delegation';
|
|
3
|
+
import { type PaymentMandate } from '../../index.js';
|
|
4
|
+
import type { Hex32 } from './resource.js';
|
|
5
|
+
import type { PaymentQuote } from './quote.js';
|
|
6
|
+
import type { NonceReservationStore } from './nonce-store.js';
|
|
7
|
+
/** x402-specific bits the mandate carries (PaymentMandate.railConfig). Binds the mandate to its quote. */
|
|
8
|
+
export interface X402RailConfig {
|
|
9
|
+
quoteId: Hex32;
|
|
10
|
+
resourceHash: Hex32;
|
|
11
|
+
}
|
|
12
|
+
/** PAY-RAIL-4 — the rail-scoped replay nullifier. */
|
|
13
|
+
export declare function computeNullifier(args: {
|
|
14
|
+
rail: string;
|
|
15
|
+
chainId: number;
|
|
16
|
+
payer: Address;
|
|
17
|
+
payee: Address;
|
|
18
|
+
asset: Address;
|
|
19
|
+
mandateId: Hex32;
|
|
20
|
+
nonce: bigint;
|
|
21
|
+
resourceHash: Hex32;
|
|
22
|
+
}): Hex32;
|
|
23
|
+
/**
|
|
24
|
+
* PAY-RAIL-1 — synchronous mandate verification against its persisted quote. Returns the first failure
|
|
25
|
+
* reason (or null). The async checks (revocation, nonce-unused) run in the rail's settle() flow.
|
|
26
|
+
*/
|
|
27
|
+
export declare function verifyMandate(mandate: PaymentMandate, quote: PaymentQuote, opts: {
|
|
28
|
+
now: number;
|
|
29
|
+
}): {
|
|
30
|
+
valid: true;
|
|
31
|
+
} | {
|
|
32
|
+
valid: false;
|
|
33
|
+
reason: string;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* PAY-RAIL-2 — build the redemption plan: DelegationManager.redeemDelegation(paymentDelegation,
|
|
37
|
+
* USDC.transfer(treasury, amount)) with the PaymentEnforcer caveat's `args` filled with the mandate's
|
|
38
|
+
* (mandateId, nonce, resourceHash) at REDEMPTION time. The caller submits `{to, value, data}` from the
|
|
39
|
+
* service relayer as a sponsored UserOp.
|
|
40
|
+
*/
|
|
41
|
+
export declare function buildRedemptionCalldata(args: {
|
|
42
|
+
mandate: PaymentMandate;
|
|
43
|
+
delegation: Delegation;
|
|
44
|
+
delegationManager: Address;
|
|
45
|
+
paymentEnforcer: Address;
|
|
46
|
+
asset: Address;
|
|
47
|
+
resourceHash: Hex32;
|
|
48
|
+
}): {
|
|
49
|
+
to: Address;
|
|
50
|
+
value: bigint;
|
|
51
|
+
data: Hex;
|
|
52
|
+
};
|
|
53
|
+
export interface X402RailDeps {
|
|
54
|
+
chainId: number;
|
|
55
|
+
delegationManager: Address;
|
|
56
|
+
paymentEnforcer: Address;
|
|
57
|
+
asset: Address;
|
|
58
|
+
nonceStore: NonceReservationStore;
|
|
59
|
+
/** Off-chain revocation read (the app wires `delegation.isRevoked`). Checked BEFORE settling; the DM
|
|
60
|
+
* also enforces revocation on-chain (PAY-DEL-3). */
|
|
61
|
+
isRevoked: (delegationHash: Hex32) => Promise<boolean>;
|
|
62
|
+
/** Submit the redemption (a sponsored UserOp from the service relayer, X402-D4). Injected by the app /
|
|
63
|
+
* agent-account layer; returns the settlement tx hash. */
|
|
64
|
+
submitRedemption: (plan: {
|
|
65
|
+
to: Address;
|
|
66
|
+
value: bigint;
|
|
67
|
+
data: Hex;
|
|
68
|
+
}) => Promise<{
|
|
69
|
+
settlementHash: Hex32;
|
|
70
|
+
}>;
|
|
71
|
+
/** PAY-RAIL-6 — dry-run the redemption (eth_call / estimateGas) BEFORE the nonce is burned, so a
|
|
72
|
+
* reverting or griefing settlement is rejected without consuming the one-shot mandate. Injected by
|
|
73
|
+
* the app; omit to skip simulation. Returns ok + optional gas estimate. */
|
|
74
|
+
simulate?: (plan: {
|
|
75
|
+
to: Address;
|
|
76
|
+
value: bigint;
|
|
77
|
+
data: Hex;
|
|
78
|
+
}) => Promise<{
|
|
79
|
+
ok: boolean;
|
|
80
|
+
reason?: string;
|
|
81
|
+
gas?: bigint;
|
|
82
|
+
}>;
|
|
83
|
+
/** Anti-griefing: reject a settlement whose simulated gas exceeds this cap. */
|
|
84
|
+
maxGasPerSettlement?: bigint;
|
|
85
|
+
/** Anti-griefing: abort `submitRedemption` if it doesn't resolve within this many ms (settlement timeout). */
|
|
86
|
+
settlementTimeoutMs?: number;
|
|
87
|
+
/** EXT-PMT-2: verify the payer's per-charge mandate signature (PMT-INV-12) BEFORE settling. The app
|
|
88
|
+
* wires this as `(m) => verifyPaymentMandateSignature(m, domainOpts, read1271)` (ERC-1271 via the payer
|
|
89
|
+
* SA). REQUIRED by default — settle refuses unless this is supplied OR `allowUnsignedMandate` is set. */
|
|
90
|
+
verifyMandateSignature?: (mandate: PaymentMandate) => Promise<boolean>;
|
|
91
|
+
/** EXT-PMT-2 opt-out: settle an UNSIGNED per-charge mandate. Use ONLY when the mandate is authored
|
|
92
|
+
* in-process and the on-chain authority is the signed DELEGATION + PaymentEnforcer caps (the demo
|
|
93
|
+
* model — the per-charge mandate is a redundant artifact there). A relayer settling a payer-supplied
|
|
94
|
+
* mandate MUST supply `verifyMandateSignature` instead (ADR-0013 safe-by-default). */
|
|
95
|
+
allowUnsignedMandate?: boolean;
|
|
96
|
+
now?: () => number;
|
|
97
|
+
}
|
|
98
|
+
export type SettleResult = {
|
|
99
|
+
ok: true;
|
|
100
|
+
settlementHash: Hex32;
|
|
101
|
+
mandateId: Hex32;
|
|
102
|
+
idempotent: boolean;
|
|
103
|
+
} | {
|
|
104
|
+
ok: false;
|
|
105
|
+
reason: string;
|
|
106
|
+
};
|
|
107
|
+
/** The staged x402 rail. `settle` runs verify → revoke → reserve(nullifier) → simulate → submit →
|
|
108
|
+
* receipt; a safe retry of an already-settled request returns the original receipt (idempotent). */
|
|
109
|
+
export declare function createX402Rail(deps: X402RailDeps): {
|
|
110
|
+
rail: "x402";
|
|
111
|
+
verifyMandate: typeof verifyMandate;
|
|
112
|
+
settle: (input: {
|
|
113
|
+
mandate: PaymentMandate;
|
|
114
|
+
delegation: Delegation;
|
|
115
|
+
quote: PaymentQuote;
|
|
116
|
+
}) => Promise<SettleResult>;
|
|
117
|
+
};
|
|
118
|
+
//# sourceMappingURL=executor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../../src/rails/x402/executor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
// Spec 272 PAY-RAIL-1..6 — the staged x402 rail executor (verify → revoke-check → reserve → prepare →
|
|
2
|
+
// submit → receipt). Delegation-native settlement (X402-D2): the redemption is
|
|
3
|
+
// DelegationManager.redeemDelegation(paymentDelegation, USDC.transfer(treasury, amount)) gated by the
|
|
4
|
+
// on-chain PaymentEnforcer. This package owns the LOGIC; on-chain submission (a sponsored UserOp,
|
|
5
|
+
// X402-D4) + the revocation read are INJECTED (payments is type-only on delegation, forbids agent-account).
|
|
6
|
+
import { encodeAbiParameters, encodeFunctionData, keccak256, toHex } from 'viem';
|
|
7
|
+
import { assertContextBindingValid, assertClosedMandateInvariants } from '../../index.js';
|
|
8
|
+
import { fromCaip2 } from './quote.js';
|
|
9
|
+
const TRANSFER_ABI = [
|
|
10
|
+
{
|
|
11
|
+
type: 'function',
|
|
12
|
+
name: 'transfer',
|
|
13
|
+
stateMutability: 'nonpayable',
|
|
14
|
+
inputs: [
|
|
15
|
+
{ name: 'to', type: 'address' },
|
|
16
|
+
{ name: 'amount', type: 'uint256' },
|
|
17
|
+
],
|
|
18
|
+
outputs: [{ type: 'bool' }],
|
|
19
|
+
},
|
|
20
|
+
];
|
|
21
|
+
const DELEGATION_TUPLE = {
|
|
22
|
+
name: 'delegations',
|
|
23
|
+
type: 'tuple[]',
|
|
24
|
+
components: [
|
|
25
|
+
{ name: 'delegator', type: 'address' },
|
|
26
|
+
{ name: 'delegate', type: 'address' },
|
|
27
|
+
{ name: 'authority', type: 'bytes32' },
|
|
28
|
+
{
|
|
29
|
+
name: 'caveats',
|
|
30
|
+
type: 'tuple[]',
|
|
31
|
+
components: [
|
|
32
|
+
{ name: 'enforcer', type: 'address' },
|
|
33
|
+
{ name: 'terms', type: 'bytes' },
|
|
34
|
+
{ name: 'args', type: 'bytes' },
|
|
35
|
+
],
|
|
36
|
+
},
|
|
37
|
+
{ name: 'salt', type: 'uint256' },
|
|
38
|
+
{ name: 'signature', type: 'bytes' },
|
|
39
|
+
],
|
|
40
|
+
};
|
|
41
|
+
const REDEEM_ABI = [
|
|
42
|
+
{
|
|
43
|
+
type: 'function',
|
|
44
|
+
name: 'redeemDelegation',
|
|
45
|
+
stateMutability: 'nonpayable',
|
|
46
|
+
inputs: [
|
|
47
|
+
DELEGATION_TUPLE,
|
|
48
|
+
{ name: 'target', type: 'address' },
|
|
49
|
+
{ name: 'value', type: 'uint256' },
|
|
50
|
+
{ name: 'data', type: 'bytes' },
|
|
51
|
+
],
|
|
52
|
+
outputs: [],
|
|
53
|
+
},
|
|
54
|
+
];
|
|
55
|
+
/** PAY-RAIL-4 — the rail-scoped replay nullifier. */
|
|
56
|
+
export function computeNullifier(args) {
|
|
57
|
+
return keccak256(encodeAbiParameters([
|
|
58
|
+
{ type: 'string' },
|
|
59
|
+
{ type: 'uint256' },
|
|
60
|
+
{ type: 'address' },
|
|
61
|
+
{ type: 'address' },
|
|
62
|
+
{ type: 'address' },
|
|
63
|
+
{ type: 'bytes32' },
|
|
64
|
+
{ type: 'uint256' },
|
|
65
|
+
{ type: 'bytes32' },
|
|
66
|
+
], [args.rail, BigInt(args.chainId), args.payer, args.payee, args.asset, args.mandateId, args.nonce, args.resourceHash]));
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* PAY-RAIL-1 — synchronous mandate verification against its persisted quote. Returns the first failure
|
|
70
|
+
* reason (or null). The async checks (revocation, nonce-unused) run in the rail's settle() flow.
|
|
71
|
+
*/
|
|
72
|
+
export function verifyMandate(mandate, quote, opts) {
|
|
73
|
+
try {
|
|
74
|
+
assertContextBindingValid(mandate.contextBinding);
|
|
75
|
+
assertClosedMandateInvariants(mandate);
|
|
76
|
+
}
|
|
77
|
+
catch (e) {
|
|
78
|
+
return { valid: false, reason: e instanceof Error ? e.message : 'invariant' };
|
|
79
|
+
}
|
|
80
|
+
if (mandate.mode !== 'closed')
|
|
81
|
+
return { valid: false, reason: 'final charge requires a closed mandate' };
|
|
82
|
+
if (mandate.maxRedemptions !== 1)
|
|
83
|
+
return { valid: false, reason: 'closed mandate must be one-shot' };
|
|
84
|
+
if (mandate.rail !== 'x402')
|
|
85
|
+
return { valid: false, reason: `wrong rail ${mandate.rail}` };
|
|
86
|
+
const rc = mandate.railConfig;
|
|
87
|
+
if (!rc?.quoteId || rc.quoteId !== quote.quoteId)
|
|
88
|
+
return { valid: false, reason: 'quote mismatch (quoteId)' };
|
|
89
|
+
if (rc.resourceHash !== quote.resourceHash)
|
|
90
|
+
return { valid: false, reason: 'quote mismatch (resourceHash)' };
|
|
91
|
+
if (mandate.payee.toLowerCase() !== quote.payTo.toLowerCase())
|
|
92
|
+
return { valid: false, reason: 'payee != treasury' };
|
|
93
|
+
if (mandate.amountPolicy.kind !== 'exact')
|
|
94
|
+
return { valid: false, reason: 'flat per-call requires exact amountPolicy' };
|
|
95
|
+
if (mandate.amountPolicy.amount !== quote.amount)
|
|
96
|
+
return { valid: false, reason: 'amount mismatch' };
|
|
97
|
+
if (mandate.amountPolicy.asset.id.toLowerCase() !== quote.asset.toLowerCase())
|
|
98
|
+
return { valid: false, reason: 'asset mismatch' };
|
|
99
|
+
if (mandate.amountPolicy.chain !== fromCaip2(quote.network))
|
|
100
|
+
return { valid: false, reason: 'chain mismatch' };
|
|
101
|
+
if (mandate.nonce !== quote.nonce)
|
|
102
|
+
return { valid: false, reason: 'nonce mismatch' };
|
|
103
|
+
if (mandate.expiresAt <= opts.now)
|
|
104
|
+
return { valid: false, reason: 'mandate expired' };
|
|
105
|
+
if (mandate.validFrom > opts.now)
|
|
106
|
+
return { valid: false, reason: 'mandate not yet valid' };
|
|
107
|
+
return { valid: true };
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* PAY-RAIL-2 — build the redemption plan: DelegationManager.redeemDelegation(paymentDelegation,
|
|
111
|
+
* USDC.transfer(treasury, amount)) with the PaymentEnforcer caveat's `args` filled with the mandate's
|
|
112
|
+
* (mandateId, nonce, resourceHash) at REDEMPTION time. The caller submits `{to, value, data}` from the
|
|
113
|
+
* service relayer as a sponsored UserOp.
|
|
114
|
+
*/
|
|
115
|
+
export function buildRedemptionCalldata(args) {
|
|
116
|
+
const amount = args.mandate.amountPolicy.amount;
|
|
117
|
+
const transferData = encodeFunctionData({
|
|
118
|
+
abi: TRANSFER_ABI,
|
|
119
|
+
functionName: 'transfer',
|
|
120
|
+
args: [args.mandate.payee, amount],
|
|
121
|
+
});
|
|
122
|
+
// Fill the PaymentEnforcer caveat's redeem-time args = abi.encode(mandateId, nonce, resourceHash).
|
|
123
|
+
const enforcerArgs = encodeAbiParameters([{ type: 'bytes32' }, { type: 'bytes32' }, { type: 'bytes32' }], [args.mandate.mandateId, toHex(args.mandate.nonce, { size: 32 }), args.resourceHash]);
|
|
124
|
+
const pe = args.paymentEnforcer.toLowerCase();
|
|
125
|
+
// EXT-PMT-2: the delegation MUST carry the PaymentEnforcer caveat — otherwise this would encode a
|
|
126
|
+
// redemption that moves USDC with NO on-chain spend/frequency/nonce enforcement attached.
|
|
127
|
+
if (!args.delegation.caveats.some((c) => c.enforcer.toLowerCase() === pe)) {
|
|
128
|
+
throw new Error('buildRedemptionCalldata: delegation has no PaymentEnforcer caveat — refusing to encode an unenforced payment (EXT-PMT-2)');
|
|
129
|
+
}
|
|
130
|
+
const caveats = args.delegation.caveats.map((c) => c.enforcer.toLowerCase() === pe
|
|
131
|
+
? { enforcer: c.enforcer, terms: c.terms, args: enforcerArgs }
|
|
132
|
+
: { enforcer: c.enforcer, terms: c.terms, args: c.args ?? '0x' });
|
|
133
|
+
const data = encodeFunctionData({
|
|
134
|
+
abi: REDEEM_ABI,
|
|
135
|
+
functionName: 'redeemDelegation',
|
|
136
|
+
args: [
|
|
137
|
+
[
|
|
138
|
+
{
|
|
139
|
+
delegator: args.delegation.delegator,
|
|
140
|
+
delegate: args.delegation.delegate,
|
|
141
|
+
authority: args.delegation.authority,
|
|
142
|
+
caveats,
|
|
143
|
+
salt: args.delegation.salt,
|
|
144
|
+
signature: args.delegation.signature,
|
|
145
|
+
},
|
|
146
|
+
],
|
|
147
|
+
args.asset,
|
|
148
|
+
0n,
|
|
149
|
+
transferData,
|
|
150
|
+
],
|
|
151
|
+
});
|
|
152
|
+
return { to: args.delegationManager, value: 0n, data };
|
|
153
|
+
}
|
|
154
|
+
function withTimeout(p, ms) {
|
|
155
|
+
return new Promise((resolve, reject) => {
|
|
156
|
+
const t = setTimeout(() => reject(new Error(`settlement timed out after ${ms}ms`)), ms);
|
|
157
|
+
p.then((v) => { clearTimeout(t); resolve(v); }, (e) => { clearTimeout(t); reject(e); });
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
/** The staged x402 rail. `settle` runs verify → revoke → reserve(nullifier) → simulate → submit →
|
|
161
|
+
* receipt; a safe retry of an already-settled request returns the original receipt (idempotent). */
|
|
162
|
+
export function createX402Rail(deps) {
|
|
163
|
+
const now = deps.now ?? (() => Math.floor(Date.now() / 1000));
|
|
164
|
+
async function settle(input) {
|
|
165
|
+
const { mandate, delegation, quote } = input;
|
|
166
|
+
const v = verifyMandate(mandate, quote, { now: now() });
|
|
167
|
+
if (!v.valid)
|
|
168
|
+
return { ok: false, reason: v.reason };
|
|
169
|
+
// PAY-H2 (seam audit): verifyMandate binds mandate.asset === quote.asset, but settlement transfers
|
|
170
|
+
// against the RAIL's configured `deps.asset` (computeNullifier + buildRedemptionCalldata). If the rail
|
|
171
|
+
// is wired for a different asset than the quote (e.g. USDC 6-dec vs an 18-dec token), it would move
|
|
172
|
+
// `quote.amount` atomic units of the WRONG asset — over/under-charging by decimals/asset divergence.
|
|
173
|
+
// Assert quote.asset === deps.asset BEFORE reserving the nonce or building calldata (fail-closed).
|
|
174
|
+
if (quote.asset.toLowerCase() !== deps.asset.toLowerCase()) {
|
|
175
|
+
return { ok: false, reason: 'rail asset does not match the quoted asset' };
|
|
176
|
+
}
|
|
177
|
+
// EXT-PMT-2: enforce the payer's per-charge mandate signature (fail-closed by default).
|
|
178
|
+
if (deps.verifyMandateSignature) {
|
|
179
|
+
if (!(await deps.verifyMandateSignature(mandate)))
|
|
180
|
+
return { ok: false, reason: 'mandate signature invalid' };
|
|
181
|
+
}
|
|
182
|
+
else if (!deps.allowUnsignedMandate) {
|
|
183
|
+
return { ok: false, reason: 'no mandate-signature verifier and allowUnsignedMandate not set (EXT-PMT-2)' };
|
|
184
|
+
}
|
|
185
|
+
const delegationHash = mandate.delegationRef;
|
|
186
|
+
if (delegationHash && (await deps.isRevoked(delegationHash)))
|
|
187
|
+
return { ok: false, reason: 'payment delegation revoked' };
|
|
188
|
+
const nullifier = computeNullifier({
|
|
189
|
+
rail: 'x402',
|
|
190
|
+
chainId: deps.chainId,
|
|
191
|
+
payer: mandate.payer,
|
|
192
|
+
payee: mandate.payee,
|
|
193
|
+
asset: deps.asset,
|
|
194
|
+
mandateId: mandate.mandateId,
|
|
195
|
+
nonce: mandate.nonce,
|
|
196
|
+
resourceHash: quote.resourceHash,
|
|
197
|
+
});
|
|
198
|
+
const reserved = await deps.nonceStore.reserve(nullifier);
|
|
199
|
+
if (!reserved.ok) {
|
|
200
|
+
if (reserved.state === 'settled' && reserved.receipt) {
|
|
201
|
+
return { ok: true, settlementHash: reserved.receipt.settlementHash, mandateId: reserved.receipt.mandateId, idempotent: true };
|
|
202
|
+
}
|
|
203
|
+
return { ok: false, reason: `duplicate settlement (${reserved.state})` };
|
|
204
|
+
}
|
|
205
|
+
const plan = buildRedemptionCalldata({
|
|
206
|
+
mandate,
|
|
207
|
+
delegation,
|
|
208
|
+
delegationManager: deps.delegationManager,
|
|
209
|
+
paymentEnforcer: deps.paymentEnforcer,
|
|
210
|
+
asset: deps.asset,
|
|
211
|
+
resourceHash: quote.resourceHash,
|
|
212
|
+
});
|
|
213
|
+
// PAY-RAIL-6 — simulate before burning the nonce: a reverting or over-gas settlement is
|
|
214
|
+
// rejected as RETRYABLE so the one-shot mandate survives for a corrected resubmit.
|
|
215
|
+
if (deps.simulate) {
|
|
216
|
+
const sim = await deps.simulate(plan);
|
|
217
|
+
if (!sim.ok) {
|
|
218
|
+
await deps.nonceStore.markFailed(nullifier, true);
|
|
219
|
+
return { ok: false, reason: `simulation reverted${sim.reason ? `: ${sim.reason}` : ''}` };
|
|
220
|
+
}
|
|
221
|
+
if (deps.maxGasPerSettlement !== undefined && sim.gas !== undefined && sim.gas > deps.maxGasPerSettlement) {
|
|
222
|
+
await deps.nonceStore.markFailed(nullifier, true);
|
|
223
|
+
return { ok: false, reason: `settlement gas ${sim.gas} exceeds cap ${deps.maxGasPerSettlement}` };
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
await deps.nonceStore.markSettling(nullifier);
|
|
227
|
+
try {
|
|
228
|
+
const submit = deps.submitRedemption(plan);
|
|
229
|
+
const { settlementHash } = deps.settlementTimeoutMs
|
|
230
|
+
? await withTimeout(submit, deps.settlementTimeoutMs)
|
|
231
|
+
: await submit;
|
|
232
|
+
const receipt = { settlementHash, mandateId: mandate.mandateId };
|
|
233
|
+
await deps.nonceStore.markSettled(nullifier, receipt);
|
|
234
|
+
return { ok: true, settlementHash, mandateId: mandate.mandateId, idempotent: false };
|
|
235
|
+
}
|
|
236
|
+
catch (e) {
|
|
237
|
+
await deps.nonceStore.markFailed(nullifier, true);
|
|
238
|
+
return { ok: false, reason: e instanceof Error ? e.message : 'settlement failed' };
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
return { rail: 'x402', verifyMandate, settle };
|
|
242
|
+
}
|
|
243
|
+
//# sourceMappingURL=executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.js","sourceRoot":"","sources":["../../../src/rails/x402/executor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type { PaymentResource, Hex32 } from './resource.js';
|
|
2
|
+
export { ZERO_HASH, canonicalizePaymentResource, hashRequestBody, redactPaymentMetadata } from './resource.js';
|
|
3
|
+
export type { PaymentQuote } from './quote.js';
|
|
4
|
+
export { computeQuoteId, buildPaymentQuote, quoteMismatch, toCaip2, fromCaip2 } from './quote.js';
|
|
5
|
+
export type { PaymentRequirements, PaymentRequiredBody, SettlementResponse, PaymentSignaturePayload } from './wire.js';
|
|
6
|
+
export { X402_VERSION, HEADER_PAYMENT_REQUIRED, HEADER_PAYMENT_SIGNATURE, HEADER_PAYMENT_RESPONSE, ASSET_TRANSFER_METHOD, buildPaymentRequired, parsePaymentRequired, buildPaymentSignature, parsePaymentSignature, buildPaymentResponse, parsePaymentResponse, serializeMandate, deserializeMandate, } from './wire.js';
|
|
7
|
+
export type { NonceReservationStore, NonceState, SettledReceipt, ReserveResult } from './nonce-store.js';
|
|
8
|
+
export { createMemoryNonceStore } from './nonce-store.js';
|
|
9
|
+
export type { X402RailConfig, X402RailDeps, SettleResult } from './executor.js';
|
|
10
|
+
export { computeNullifier, verifyMandate, buildRedemptionCalldata, createX402Rail } from './executor.js';
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/rails/x402/index.ts"],"names":[],"mappings":"AAGA,YAAY,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,2BAA2B,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAE/G,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,aAAa,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAElG,YAAY,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,MAAM,WAAW,CAAC;AACvH,OAAO,EACL,YAAY,EACZ,uBAAuB,EACvB,wBAAwB,EACxB,uBAAuB,EACvB,qBAAqB,EACrB,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,EACrB,qBAAqB,EACrB,oBAAoB,EACpB,oBAAoB,EACpB,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,WAAW,CAAC;AAEnB,YAAY,EAAE,qBAAqB,EAAE,UAAU,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACzG,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAE1D,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAChF,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,uBAAuB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// @agenticprimitives/payments — x402 rail (spec 272). HTTP-native pay-per-use over the spec-243
|
|
2
|
+
// PaymentMandate. Consumed as `import { x402 } from '@agenticprimitives/payments'`.
|
|
3
|
+
export { ZERO_HASH, canonicalizePaymentResource, hashRequestBody, redactPaymentMetadata } from './resource.js';
|
|
4
|
+
export { computeQuoteId, buildPaymentQuote, quoteMismatch, toCaip2, fromCaip2 } from './quote.js';
|
|
5
|
+
export { X402_VERSION, HEADER_PAYMENT_REQUIRED, HEADER_PAYMENT_SIGNATURE, HEADER_PAYMENT_RESPONSE, ASSET_TRANSFER_METHOD, buildPaymentRequired, parsePaymentRequired, buildPaymentSignature, parsePaymentSignature, buildPaymentResponse, parsePaymentResponse, serializeMandate, deserializeMandate, } from './wire.js';
|
|
6
|
+
export { createMemoryNonceStore } from './nonce-store.js';
|
|
7
|
+
export { computeNullifier, verifyMandate, buildRedemptionCalldata, createX402Rail } from './executor.js';
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/rails/x402/index.ts"],"names":[],"mappings":"AAAA,gGAAgG;AAChG,oFAAoF;AAGpF,OAAO,EAAE,SAAS,EAAE,2BAA2B,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAG/G,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,aAAa,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAGlG,OAAO,EACL,YAAY,EACZ,uBAAuB,EACvB,wBAAwB,EACxB,uBAAuB,EACvB,qBAAqB,EACrB,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,EACrB,qBAAqB,EACrB,oBAAoB,EACpB,oBAAoB,EACpB,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,WAAW,CAAC;AAGnB,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAG1D,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,uBAAuB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { Hex32 } from './resource.js';
|
|
2
|
+
export type NonceState = 'unseen' | 'reserved' | 'settling' | 'settled' | 'failed_retryable' | 'failed_terminal';
|
|
3
|
+
export interface SettledReceipt {
|
|
4
|
+
settlementHash: Hex32;
|
|
5
|
+
mandateId: Hex32;
|
|
6
|
+
}
|
|
7
|
+
export type ReserveResult = {
|
|
8
|
+
ok: true;
|
|
9
|
+
} | {
|
|
10
|
+
ok: false;
|
|
11
|
+
state: Exclude<NonceState, 'unseen'>;
|
|
12
|
+
receipt?: SettledReceipt;
|
|
13
|
+
};
|
|
14
|
+
export interface NonceReservationStore {
|
|
15
|
+
/** Atomically claim the nullifier. `unseen`/`failed_retryable` → reserved (ok). `settled` → not-ok
|
|
16
|
+
* WITH the original receipt (safe-retry returns it). `reserved`/`settling`/`failed_terminal` →
|
|
17
|
+
* not-ok (concurrent duplicate / permanently failed). */
|
|
18
|
+
reserve(nullifier: Hex32): Promise<ReserveResult>;
|
|
19
|
+
markSettling(nullifier: Hex32): Promise<void>;
|
|
20
|
+
markSettled(nullifier: Hex32, receipt: SettledReceipt): Promise<void>;
|
|
21
|
+
markFailed(nullifier: Hex32, retryable: boolean): Promise<void>;
|
|
22
|
+
get(nullifier: Hex32): Promise<{
|
|
23
|
+
state: NonceState;
|
|
24
|
+
receipt?: SettledReceipt;
|
|
25
|
+
} | undefined>;
|
|
26
|
+
}
|
|
27
|
+
/** In-memory store (single-worker / tests). A durable adapter (KV / D1) implements the same interface;
|
|
28
|
+
* the reserve() must be ATOMIC there (compare-and-set) to actually block concurrent duplicates. */
|
|
29
|
+
export declare function createMemoryNonceStore(): NonceReservationStore;
|
|
30
|
+
//# sourceMappingURL=nonce-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nonce-store.d.ts","sourceRoot":"","sources":["../../../src/rails/x402/nonce-store.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAE3C,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,UAAU,GAAG,UAAU,GAAG,SAAS,GAAG,kBAAkB,GAAG,iBAAiB,CAAC;AAEjH,MAAM,WAAW,cAAc;IAC7B,cAAc,EAAE,KAAK,CAAC;IACtB,SAAS,EAAE,KAAK,CAAC;CAClB;AAED,MAAM,MAAM,aAAa,GACrB;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GACZ;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,OAAO,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IAAC,OAAO,CAAC,EAAE,cAAc,CAAA;CAAE,CAAC;AAElF,MAAM,WAAW,qBAAqB;IACpC;;8DAE0D;IAC1D,OAAO,CAAC,SAAS,EAAE,KAAK,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IAClD,YAAY,CAAC,SAAS,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9C,WAAW,CAAC,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtE,UAAU,CAAC,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChE,GAAG,CAAC,SAAS,EAAE,KAAK,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,UAAU,CAAC;QAAC,OAAO,CAAC,EAAE,cAAc,CAAA;KAAE,GAAG,SAAS,CAAC,CAAC;CAC7F;AAOD;oGACoG;AACpG,wBAAgB,sBAAsB,IAAI,qBAAqB,CA0B9D"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// Spec 272 PAY-RAIL-4/5 — the off-chain nullifier reservation store. A redeemed mandate/nonce cannot
|
|
2
|
+
// settle twice (the on-chain nonce is the durable guard; this blocks concurrent duplicates + caches the
|
|
3
|
+
// original receipt for safe retries). State machine: unseen → reserved → settling → settled |
|
|
4
|
+
// failed_retryable | failed_terminal.
|
|
5
|
+
/** In-memory store (single-worker / tests). A durable adapter (KV / D1) implements the same interface;
|
|
6
|
+
* the reserve() must be ATOMIC there (compare-and-set) to actually block concurrent duplicates. */
|
|
7
|
+
export function createMemoryNonceStore() {
|
|
8
|
+
const rows = new Map();
|
|
9
|
+
return {
|
|
10
|
+
async reserve(nullifier) {
|
|
11
|
+
const row = rows.get(nullifier);
|
|
12
|
+
if (!row || row.state === 'unseen' || row.state === 'failed_retryable') {
|
|
13
|
+
rows.set(nullifier, { state: 'reserved' });
|
|
14
|
+
return { ok: true };
|
|
15
|
+
}
|
|
16
|
+
if (row.state === 'settled')
|
|
17
|
+
return { ok: false, state: 'settled', receipt: row.receipt };
|
|
18
|
+
return { ok: false, state: row.state };
|
|
19
|
+
},
|
|
20
|
+
async markSettling(nullifier) {
|
|
21
|
+
const row = rows.get(nullifier) ?? { state: 'unseen' };
|
|
22
|
+
rows.set(nullifier, { ...row, state: 'settling' });
|
|
23
|
+
},
|
|
24
|
+
async markSettled(nullifier, receipt) {
|
|
25
|
+
rows.set(nullifier, { state: 'settled', receipt });
|
|
26
|
+
},
|
|
27
|
+
async markFailed(nullifier, retryable) {
|
|
28
|
+
rows.set(nullifier, { state: retryable ? 'failed_retryable' : 'failed_terminal' });
|
|
29
|
+
},
|
|
30
|
+
async get(nullifier) {
|
|
31
|
+
return rows.get(nullifier);
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=nonce-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nonce-store.js","sourceRoot":"","sources":["../../../src/rails/x402/nonce-store.ts"],"names":[],"mappings":"AAAA,qGAAqG;AACrG,wGAAwG;AACxG,8FAA8F;AAC9F,sCAAsC;AA+BtC;oGACoG;AACpG,MAAM,UAAU,sBAAsB;IACpC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAe,CAAC;IACpC,OAAO;QACL,KAAK,CAAC,OAAO,CAAC,SAAS;YACrB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YAChC,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,KAAK,QAAQ,IAAI,GAAG,CAAC,KAAK,KAAK,kBAAkB,EAAE,CAAC;gBACvE,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC;gBAC3C,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;YACtB,CAAC;YACD,IAAI,GAAG,CAAC,KAAK,KAAK,SAAS;gBAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC;YAC1F,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC;QACzC,CAAC;QACD,KAAK,CAAC,YAAY,CAAC,SAAS;YAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;YACvD,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,EAAE,GAAG,GAAG,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC;QACrD,CAAC;QACD,KAAK,CAAC,WAAW,CAAC,SAAS,EAAE,OAAO;YAClC,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC;QACrD,CAAC;QACD,KAAK,CAAC,UAAU,CAAC,SAAS,EAAE,SAAS;YACnC,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,iBAAiB,EAAE,CAAC,CAAC;QACrF,CAAC;QACD,KAAK,CAAC,GAAG,CAAC,SAAS;YACjB,OAAO,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC7B,CAAC;KACF,CAAC;AACJ,CAAC"}
|