@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
package/dist/mandate.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `buildClosedMandate` — construct an unsigned closed (one-shot) PaymentMandate.
|
|
3
|
+
*
|
|
4
|
+
* The wallet + invoice rails (and the demo) build a closed mandate, sign it via
|
|
5
|
+
* `signPaymentMandate`, then settle it with a single transfer. Closed + one-shot per
|
|
6
|
+
* PMT-10 / PMT-INV-14. `orderHash`/`legId` (EXC-R2) bind the leg to an ExchangeOrder.
|
|
7
|
+
*/
|
|
8
|
+
import { computeMandateId } from './index.js';
|
|
9
|
+
const ZERO32 = ('0x' + '00'.repeat(32));
|
|
10
|
+
/** Build the unsigned closed mandate (signature `'0x'`); sign with `signPaymentMandate`. */
|
|
11
|
+
export function buildClosedMandate(input) {
|
|
12
|
+
const validFrom = input.validFrom ?? 0;
|
|
13
|
+
return {
|
|
14
|
+
mandateId: computeMandateId({ payer: input.payer, nonce: input.nonce, rail: input.rail, chain: input.chain }),
|
|
15
|
+
payer: input.payer,
|
|
16
|
+
payee: input.payee,
|
|
17
|
+
granter: input.granter ?? input.payer,
|
|
18
|
+
rail: input.rail,
|
|
19
|
+
amountPolicy: { kind: 'exact', amount: input.amount, asset: input.asset, chain: input.chain },
|
|
20
|
+
nonce: input.nonce,
|
|
21
|
+
maxRedemptions: 1,
|
|
22
|
+
validFrom,
|
|
23
|
+
expiresAt: input.expiresAt,
|
|
24
|
+
contextBinding: {
|
|
25
|
+
...(input.resource ? { resource: input.resource } : {}),
|
|
26
|
+
orderHash: input.orderHash,
|
|
27
|
+
legId: input.legId,
|
|
28
|
+
chain: input.chain,
|
|
29
|
+
asset: input.asset,
|
|
30
|
+
nonce: input.nonce,
|
|
31
|
+
validFrom,
|
|
32
|
+
expiresAt: input.expiresAt,
|
|
33
|
+
},
|
|
34
|
+
delegationRef: input.delegationRef,
|
|
35
|
+
mode: 'closed',
|
|
36
|
+
reasonHash: input.reasonHash ?? ZERO32,
|
|
37
|
+
signature: '0x',
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=mandate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mandate.js","sourceRoot":"","sources":["../src/mandate.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,gBAAgB,EAAoE,MAAM,YAAY,CAAC;AAEhH,MAAM,MAAM,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAU,CAAC;AAoBjD,4FAA4F;AAC5F,MAAM,UAAU,kBAAkB,CAAC,KAAyB;IAC1D,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,IAAI,CAAC,CAAC;IACvC,OAAO;QACL,SAAS,EAAE,gBAAgB,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC;QAC7G,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,KAAK;QACrC,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,YAAY,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE;QAC7F,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,cAAc,EAAE,CAAC;QACjB,SAAS;QACT,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,cAAc,EAAE;YACd,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACvD,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,SAAS;YACT,SAAS,EAAE,KAAK,CAAC,SAAS;SAC3B;QACD,aAAa,EAAE,KAAK,CAAC,aAAa;QAClC,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE,KAAK,CAAC,UAAU,IAAI,MAAM;QACtC,SAAS,EAAE,IAAI;KAChB,CAAC;AACJ,CAAC"}
|
package/dist/ops.d.ts
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Payment ops core (spec 243 §5.5) — the plumbing every mature payment stack needs:
|
|
3
|
+
* an idempotent event model + webhook-style subscribers, reconciliation/payment-detection,
|
|
4
|
+
* and receipt export. In-process for W1 (the app delivers webhooks later). Pure — no I/O.
|
|
5
|
+
*/
|
|
6
|
+
import type { Address } from '@agenticprimitives/types';
|
|
7
|
+
import type { Hex32 } from './index.js';
|
|
8
|
+
export type PaymentEventType = 'payment.created' | 'payment.reserved' | 'payment.settling' | 'payment.settled' | 'payment.failed' | 'payment.refunded' | 'payment.expired' | 'payment.disputed' | 'entitlement.issued' | 'entitlement.consumed';
|
|
9
|
+
export interface PaymentEvent {
|
|
10
|
+
/** dedupe key — re-emitting the same key is a no-op (at-least-once producers, exactly-once consumers) */
|
|
11
|
+
idempotencyKey: string;
|
|
12
|
+
type: PaymentEventType;
|
|
13
|
+
at: number;
|
|
14
|
+
orderHash?: Hex32;
|
|
15
|
+
mandateId?: Hex32;
|
|
16
|
+
data?: Record<string, unknown>;
|
|
17
|
+
}
|
|
18
|
+
export interface PaymentEventLog {
|
|
19
|
+
/** Returns `{ accepted: false }` when `idempotencyKey` was already seen (no re-emit, no re-notify). */
|
|
20
|
+
emit(event: PaymentEvent): {
|
|
21
|
+
accepted: boolean;
|
|
22
|
+
};
|
|
23
|
+
list(): PaymentEvent[];
|
|
24
|
+
byType(type: PaymentEventType): PaymentEvent[];
|
|
25
|
+
byOrder(orderHash: Hex32): PaymentEvent[];
|
|
26
|
+
/** Webhook-style subscriber — invoked once per ACCEPTED event. Returns an unsubscribe fn. */
|
|
27
|
+
subscribe(fn: (event: PaymentEvent) => void): () => void;
|
|
28
|
+
}
|
|
29
|
+
export declare function createPaymentEventLog(): PaymentEventLog;
|
|
30
|
+
export interface ReceiptRow {
|
|
31
|
+
mandateId: Hex32;
|
|
32
|
+
payer: Address;
|
|
33
|
+
payee: Address;
|
|
34
|
+
asset: Address;
|
|
35
|
+
amount: bigint;
|
|
36
|
+
settlementHash: Hex32;
|
|
37
|
+
at: number;
|
|
38
|
+
orderHash?: Hex32;
|
|
39
|
+
/** set on a refund leg — the original charge it reverses */
|
|
40
|
+
refunds?: Hex32;
|
|
41
|
+
}
|
|
42
|
+
export interface ReceiptFilter {
|
|
43
|
+
payer?: Address;
|
|
44
|
+
payee?: Address;
|
|
45
|
+
orderHash?: Hex32;
|
|
46
|
+
asset?: Address;
|
|
47
|
+
}
|
|
48
|
+
export declare function listReceiptsBy(receipts: ReceiptRow[], filter: ReceiptFilter): ReceiptRow[];
|
|
49
|
+
/** Net balance change for `account` across the receipt set (incoming as payee − outgoing as payer). */
|
|
50
|
+
export declare function balanceDelta(receipts: ReceiptRow[], account: Address): bigint;
|
|
51
|
+
/** Payment detection: is `orderHash` paid (optionally to ≥ `expectedAmount`)? From receipts, not logs. */
|
|
52
|
+
export declare function isOrderPaid(receipts: ReceiptRow[], orderHash: Hex32, expectedAmount?: bigint): boolean;
|
|
53
|
+
export declare function exportReceiptsJSON(receipts: ReceiptRow[]): string;
|
|
54
|
+
export declare function exportReceiptsCSV(receipts: ReceiptRow[]): string;
|
|
55
|
+
//# sourceMappingURL=ops.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ops.d.ts","sourceRoot":"","sources":["../src/ops.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC,MAAM,MAAM,gBAAgB,GACxB,iBAAiB,GACjB,kBAAkB,GAClB,kBAAkB,GAClB,iBAAiB,GACjB,gBAAgB,GAChB,kBAAkB,GAClB,iBAAiB,GACjB,kBAAkB,GAClB,oBAAoB,GACpB,sBAAsB,CAAC;AAE3B,MAAM,WAAW,YAAY;IAC3B,yGAAyG;IACzG,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,gBAAgB,CAAC;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,CAAC,EAAE,KAAK,CAAC;IAClB,SAAS,CAAC,EAAE,KAAK,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,eAAe;IAC9B,uGAAuG;IACvG,IAAI,CAAC,KAAK,EAAE,YAAY,GAAG;QAAE,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC;IACjD,IAAI,IAAI,YAAY,EAAE,CAAC;IACvB,MAAM,CAAC,IAAI,EAAE,gBAAgB,GAAG,YAAY,EAAE,CAAC;IAC/C,OAAO,CAAC,SAAS,EAAE,KAAK,GAAG,YAAY,EAAE,CAAC;IAC1C,6FAA6F;IAC7F,SAAS,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;CAC1D;AAED,wBAAgB,qBAAqB,IAAI,eAAe,CAoBvD;AAID,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,KAAK,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,KAAK,CAAC;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,CAAC,EAAE,KAAK,CAAC;IAClB,4DAA4D;IAC5D,OAAO,CAAC,EAAE,KAAK,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,KAAK,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAID,wBAAgB,cAAc,CAAC,QAAQ,EAAE,UAAU,EAAE,EAAE,MAAM,EAAE,aAAa,GAAG,UAAU,EAAE,CAQ1F;AAED,uGAAuG;AACvG,wBAAgB,YAAY,CAAC,QAAQ,EAAE,UAAU,EAAE,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,CAO7E;AAED,0GAA0G;AAC1G,wBAAgB,WAAW,CAAC,QAAQ,EAAE,UAAU,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,OAAO,CAMtG;AAID,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,UAAU,EAAE,GAAG,MAAM,CAMjE;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,UAAU,EAAE,GAAG,MAAM,CAMhE"}
|
package/dist/ops.js
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Payment ops core (spec 243 §5.5) — the plumbing every mature payment stack needs:
|
|
3
|
+
* an idempotent event model + webhook-style subscribers, reconciliation/payment-detection,
|
|
4
|
+
* and receipt export. In-process for W1 (the app delivers webhooks later). Pure — no I/O.
|
|
5
|
+
*/
|
|
6
|
+
export function createPaymentEventLog() {
|
|
7
|
+
const events = [];
|
|
8
|
+
const seen = new Set();
|
|
9
|
+
const subs = new Set();
|
|
10
|
+
return {
|
|
11
|
+
emit(event) {
|
|
12
|
+
if (seen.has(event.idempotencyKey))
|
|
13
|
+
return { accepted: false };
|
|
14
|
+
seen.add(event.idempotencyKey);
|
|
15
|
+
events.push(event);
|
|
16
|
+
for (const fn of subs)
|
|
17
|
+
fn(event);
|
|
18
|
+
return { accepted: true };
|
|
19
|
+
},
|
|
20
|
+
list: () => [...events],
|
|
21
|
+
byType: (type) => events.filter((e) => e.type === type),
|
|
22
|
+
byOrder: (orderHash) => events.filter((e) => e.orderHash?.toLowerCase() === orderHash.toLowerCase()),
|
|
23
|
+
subscribe(fn) {
|
|
24
|
+
subs.add(fn);
|
|
25
|
+
return () => subs.delete(fn);
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
const eq = (a, b) => (a && b ? a.toLowerCase() === b.toLowerCase() : a === b);
|
|
30
|
+
export function listReceiptsBy(receipts, filter) {
|
|
31
|
+
return receipts.filter((r) => (filter.payer === undefined || eq(r.payer, filter.payer)) &&
|
|
32
|
+
(filter.payee === undefined || eq(r.payee, filter.payee)) &&
|
|
33
|
+
(filter.asset === undefined || eq(r.asset, filter.asset)) &&
|
|
34
|
+
(filter.orderHash === undefined || eq(r.orderHash, filter.orderHash)));
|
|
35
|
+
}
|
|
36
|
+
/** Net balance change for `account` across the receipt set (incoming as payee − outgoing as payer). */
|
|
37
|
+
export function balanceDelta(receipts, account) {
|
|
38
|
+
let delta = 0n;
|
|
39
|
+
for (const r of receipts) {
|
|
40
|
+
if (eq(r.payee, account))
|
|
41
|
+
delta += r.amount;
|
|
42
|
+
if (eq(r.payer, account))
|
|
43
|
+
delta -= r.amount;
|
|
44
|
+
}
|
|
45
|
+
return delta;
|
|
46
|
+
}
|
|
47
|
+
/** Payment detection: is `orderHash` paid (optionally to ≥ `expectedAmount`)? From receipts, not logs. */
|
|
48
|
+
export function isOrderPaid(receipts, orderHash, expectedAmount) {
|
|
49
|
+
const charges = receipts.filter((r) => eq(r.orderHash, orderHash) && !r.refunds);
|
|
50
|
+
if (charges.length === 0)
|
|
51
|
+
return false;
|
|
52
|
+
if (expectedAmount === undefined)
|
|
53
|
+
return true;
|
|
54
|
+
const total = charges.reduce((s, r) => s + r.amount, 0n);
|
|
55
|
+
return total >= expectedAmount;
|
|
56
|
+
}
|
|
57
|
+
// ── export ──────────────────────────────────────────────────────────
|
|
58
|
+
export function exportReceiptsJSON(receipts) {
|
|
59
|
+
return JSON.stringify(receipts.map((r) => ({ ...r, amount: r.amount.toString() })), null, 2);
|
|
60
|
+
}
|
|
61
|
+
export function exportReceiptsCSV(receipts) {
|
|
62
|
+
const header = 'mandateId,payer,payee,asset,amount,settlementHash,at,orderHash,refunds';
|
|
63
|
+
const rows = receipts.map((r) => [r.mandateId, r.payer, r.payee, r.asset, r.amount.toString(), r.settlementHash, r.at, r.orderHash ?? '', r.refunds ?? ''].join(','));
|
|
64
|
+
return [header, ...rows].join('\n');
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=ops.js.map
|
package/dist/ops.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ops.js","sourceRoot":"","sources":["../src/ops.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Escrow rail (spec 243 §5.5, over PaymentEscrow.sol) — hold-and-capture for an order.
|
|
3
|
+
*
|
|
4
|
+
* Powers the deliver-then-pay flow: payer deposits a hold keyed by `orderHash` → provider
|
|
5
|
+
* fulfils → `release` captures to the payee (and the app mints the entitlement, pay-AFTER-
|
|
6
|
+
* fulfillment) → on failure/expiry `refund`/`reclaim` returns the funds. Builders emit the
|
|
7
|
+
* `{to: escrow, value, data}` calls an SA executes; deposit needs a prior `approve`
|
|
8
|
+
* (`buildErc20Approve`). App reads hold state via `getHold` (readContract), not log scans.
|
|
9
|
+
*/
|
|
10
|
+
import { type Address } from 'viem';
|
|
11
|
+
import type { TransferPlan } from '../transfer.js';
|
|
12
|
+
import type { Hex32 } from '../index.js';
|
|
13
|
+
/** Mirrors PaymentEscrow.Status. */
|
|
14
|
+
export declare enum EscrowStatus {
|
|
15
|
+
None = 0,
|
|
16
|
+
Held = 1,
|
|
17
|
+
Captured = 2,
|
|
18
|
+
Refunded = 3,
|
|
19
|
+
Reclaimed = 4
|
|
20
|
+
}
|
|
21
|
+
export declare const ESCROW_ABI: readonly [{
|
|
22
|
+
readonly type: "function";
|
|
23
|
+
readonly name: "deposit";
|
|
24
|
+
readonly stateMutability: "nonpayable";
|
|
25
|
+
readonly inputs: readonly [{
|
|
26
|
+
readonly name: "orderHash";
|
|
27
|
+
readonly type: "bytes32";
|
|
28
|
+
}, {
|
|
29
|
+
readonly name: "asset";
|
|
30
|
+
readonly type: "address";
|
|
31
|
+
}, {
|
|
32
|
+
readonly name: "amount";
|
|
33
|
+
readonly type: "uint256";
|
|
34
|
+
}, {
|
|
35
|
+
readonly name: "payee";
|
|
36
|
+
readonly type: "address";
|
|
37
|
+
}, {
|
|
38
|
+
readonly name: "refundTo";
|
|
39
|
+
readonly type: "address";
|
|
40
|
+
}, {
|
|
41
|
+
readonly name: "releaser";
|
|
42
|
+
readonly type: "address";
|
|
43
|
+
}, {
|
|
44
|
+
readonly name: "expiry";
|
|
45
|
+
readonly type: "uint64";
|
|
46
|
+
}];
|
|
47
|
+
readonly outputs: readonly [];
|
|
48
|
+
}, {
|
|
49
|
+
readonly type: "function";
|
|
50
|
+
readonly name: "release";
|
|
51
|
+
readonly stateMutability: "nonpayable";
|
|
52
|
+
readonly inputs: readonly [{
|
|
53
|
+
readonly name: "payer";
|
|
54
|
+
readonly type: "address";
|
|
55
|
+
}, {
|
|
56
|
+
readonly name: "orderHash";
|
|
57
|
+
readonly type: "bytes32";
|
|
58
|
+
}];
|
|
59
|
+
readonly outputs: readonly [];
|
|
60
|
+
}, {
|
|
61
|
+
readonly type: "function";
|
|
62
|
+
readonly name: "refund";
|
|
63
|
+
readonly stateMutability: "nonpayable";
|
|
64
|
+
readonly inputs: readonly [{
|
|
65
|
+
readonly name: "payer";
|
|
66
|
+
readonly type: "address";
|
|
67
|
+
}, {
|
|
68
|
+
readonly name: "orderHash";
|
|
69
|
+
readonly type: "bytes32";
|
|
70
|
+
}];
|
|
71
|
+
readonly outputs: readonly [];
|
|
72
|
+
}, {
|
|
73
|
+
readonly type: "function";
|
|
74
|
+
readonly name: "reclaim";
|
|
75
|
+
readonly stateMutability: "nonpayable";
|
|
76
|
+
readonly inputs: readonly [{
|
|
77
|
+
readonly name: "orderHash";
|
|
78
|
+
readonly type: "bytes32";
|
|
79
|
+
}];
|
|
80
|
+
readonly outputs: readonly [];
|
|
81
|
+
}, {
|
|
82
|
+
readonly type: "function";
|
|
83
|
+
readonly name: "getHold";
|
|
84
|
+
readonly stateMutability: "view";
|
|
85
|
+
readonly inputs: readonly [{
|
|
86
|
+
readonly name: "payer";
|
|
87
|
+
readonly type: "address";
|
|
88
|
+
}, {
|
|
89
|
+
readonly name: "orderHash";
|
|
90
|
+
readonly type: "bytes32";
|
|
91
|
+
}];
|
|
92
|
+
readonly outputs: readonly [{
|
|
93
|
+
readonly type: "tuple";
|
|
94
|
+
readonly components: readonly [{
|
|
95
|
+
readonly name: "payer";
|
|
96
|
+
readonly type: "address";
|
|
97
|
+
}, {
|
|
98
|
+
readonly name: "asset";
|
|
99
|
+
readonly type: "address";
|
|
100
|
+
}, {
|
|
101
|
+
readonly name: "amount";
|
|
102
|
+
readonly type: "uint256";
|
|
103
|
+
}, {
|
|
104
|
+
readonly name: "payee";
|
|
105
|
+
readonly type: "address";
|
|
106
|
+
}, {
|
|
107
|
+
readonly name: "refundTo";
|
|
108
|
+
readonly type: "address";
|
|
109
|
+
}, {
|
|
110
|
+
readonly name: "releaser";
|
|
111
|
+
readonly type: "address";
|
|
112
|
+
}, {
|
|
113
|
+
readonly name: "expiry";
|
|
114
|
+
readonly type: "uint64";
|
|
115
|
+
}, {
|
|
116
|
+
readonly name: "status";
|
|
117
|
+
readonly type: "uint8";
|
|
118
|
+
}];
|
|
119
|
+
}];
|
|
120
|
+
}, {
|
|
121
|
+
readonly type: "function";
|
|
122
|
+
readonly name: "statusOf";
|
|
123
|
+
readonly stateMutability: "view";
|
|
124
|
+
readonly inputs: readonly [{
|
|
125
|
+
readonly name: "payer";
|
|
126
|
+
readonly type: "address";
|
|
127
|
+
}, {
|
|
128
|
+
readonly name: "orderHash";
|
|
129
|
+
readonly type: "bytes32";
|
|
130
|
+
}];
|
|
131
|
+
readonly outputs: readonly [{
|
|
132
|
+
readonly type: "uint8";
|
|
133
|
+
}];
|
|
134
|
+
}];
|
|
135
|
+
export interface EscrowDepositInput {
|
|
136
|
+
escrow: Address;
|
|
137
|
+
orderHash: Hex32;
|
|
138
|
+
asset: Address;
|
|
139
|
+
amount: bigint;
|
|
140
|
+
payee: Address;
|
|
141
|
+
/** where refund/reclaim returns; defaults on-chain to the payer (msg.sender) when zero */
|
|
142
|
+
refundTo?: Address;
|
|
143
|
+
/** extra address allowed to release besides the payee; 0 = payee-only */
|
|
144
|
+
releaser?: Address;
|
|
145
|
+
expiry: number;
|
|
146
|
+
}
|
|
147
|
+
/** The deposit call (the payer SA must `approve` the escrow for `asset` first). */
|
|
148
|
+
export declare function buildEscrowDeposit(input: EscrowDepositInput): TransferPlan;
|
|
149
|
+
/** Capture the hold to the payee (payee or configured releaser executes). EXT-PMT-3: holds are keyed by
|
|
150
|
+
* (payer, orderHash), so the releasing party must pass the payer. Cannot release at/after expiry. */
|
|
151
|
+
export declare function buildEscrowRelease(escrow: Address, payer: Address, orderHash: Hex32): TransferPlan;
|
|
152
|
+
/** Payee-consented refund to the payer, before capture. */
|
|
153
|
+
export declare function buildEscrowRefund(escrow: Address, payer: Address, orderHash: Hex32): TransferPlan;
|
|
154
|
+
/** Payer reclaims after expiry (never released). Payer-initiated → keyed off msg.sender on-chain. */
|
|
155
|
+
export declare function buildEscrowReclaim(escrow: Address, orderHash: Hex32): TransferPlan;
|
|
156
|
+
//# sourceMappingURL=escrow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"escrow.d.ts","sourceRoot":"","sources":["../../src/rails/escrow.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAsB,KAAK,OAAO,EAAE,MAAM,MAAM,CAAC;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEzC,oCAAoC;AACpC,oBAAY,YAAY;IACtB,IAAI,IAAI;IACR,IAAI,IAAI;IACR,QAAQ,IAAI;IACZ,QAAQ,IAAI;IACZ,SAAS,IAAI;CACd;AAED,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyCb,CAAC;AAEX,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,KAAK,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;IACf,0FAA0F;IAC1F,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,yEAAyE;IACzE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;CAChB;AAID,mFAAmF;AACnF,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,kBAAkB,GAAG,YAAY,CAU1E;AAED;sGACsG;AACtG,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,GAAG,YAAY,CAElG;AACD,2DAA2D;AAC3D,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,GAAG,YAAY,CAEjG;AACD,qGAAqG;AACrG,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,GAAG,YAAY,CAElF"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Escrow rail (spec 243 §5.5, over PaymentEscrow.sol) — hold-and-capture for an order.
|
|
3
|
+
*
|
|
4
|
+
* Powers the deliver-then-pay flow: payer deposits a hold keyed by `orderHash` → provider
|
|
5
|
+
* fulfils → `release` captures to the payee (and the app mints the entitlement, pay-AFTER-
|
|
6
|
+
* fulfillment) → on failure/expiry `refund`/`reclaim` returns the funds. Builders emit the
|
|
7
|
+
* `{to: escrow, value, data}` calls an SA executes; deposit needs a prior `approve`
|
|
8
|
+
* (`buildErc20Approve`). App reads hold state via `getHold` (readContract), not log scans.
|
|
9
|
+
*/
|
|
10
|
+
import { encodeFunctionData } from 'viem';
|
|
11
|
+
/** Mirrors PaymentEscrow.Status. */
|
|
12
|
+
export var EscrowStatus;
|
|
13
|
+
(function (EscrowStatus) {
|
|
14
|
+
EscrowStatus[EscrowStatus["None"] = 0] = "None";
|
|
15
|
+
EscrowStatus[EscrowStatus["Held"] = 1] = "Held";
|
|
16
|
+
EscrowStatus[EscrowStatus["Captured"] = 2] = "Captured";
|
|
17
|
+
EscrowStatus[EscrowStatus["Refunded"] = 3] = "Refunded";
|
|
18
|
+
EscrowStatus[EscrowStatus["Reclaimed"] = 4] = "Reclaimed";
|
|
19
|
+
})(EscrowStatus || (EscrowStatus = {}));
|
|
20
|
+
export const ESCROW_ABI = [
|
|
21
|
+
{
|
|
22
|
+
type: 'function',
|
|
23
|
+
name: 'deposit',
|
|
24
|
+
stateMutability: 'nonpayable',
|
|
25
|
+
inputs: [
|
|
26
|
+
{ name: 'orderHash', type: 'bytes32' },
|
|
27
|
+
{ name: 'asset', type: 'address' },
|
|
28
|
+
{ name: 'amount', type: 'uint256' },
|
|
29
|
+
{ name: 'payee', type: 'address' },
|
|
30
|
+
{ name: 'refundTo', type: 'address' },
|
|
31
|
+
{ name: 'releaser', type: 'address' },
|
|
32
|
+
{ name: 'expiry', type: 'uint64' },
|
|
33
|
+
],
|
|
34
|
+
outputs: [],
|
|
35
|
+
},
|
|
36
|
+
{ type: 'function', name: 'release', stateMutability: 'nonpayable', inputs: [{ name: 'payer', type: 'address' }, { name: 'orderHash', type: 'bytes32' }], outputs: [] },
|
|
37
|
+
{ type: 'function', name: 'refund', stateMutability: 'nonpayable', inputs: [{ name: 'payer', type: 'address' }, { name: 'orderHash', type: 'bytes32' }], outputs: [] },
|
|
38
|
+
{ type: 'function', name: 'reclaim', stateMutability: 'nonpayable', inputs: [{ name: 'orderHash', type: 'bytes32' }], outputs: [] },
|
|
39
|
+
{
|
|
40
|
+
type: 'function',
|
|
41
|
+
name: 'getHold',
|
|
42
|
+
stateMutability: 'view',
|
|
43
|
+
inputs: [{ name: 'payer', type: 'address' }, { name: 'orderHash', type: 'bytes32' }],
|
|
44
|
+
outputs: [
|
|
45
|
+
{
|
|
46
|
+
type: 'tuple',
|
|
47
|
+
components: [
|
|
48
|
+
{ name: 'payer', type: 'address' },
|
|
49
|
+
{ name: 'asset', type: 'address' },
|
|
50
|
+
{ name: 'amount', type: 'uint256' },
|
|
51
|
+
{ name: 'payee', type: 'address' },
|
|
52
|
+
{ name: 'refundTo', type: 'address' },
|
|
53
|
+
{ name: 'releaser', type: 'address' },
|
|
54
|
+
{ name: 'expiry', type: 'uint64' },
|
|
55
|
+
{ name: 'status', type: 'uint8' },
|
|
56
|
+
],
|
|
57
|
+
},
|
|
58
|
+
],
|
|
59
|
+
},
|
|
60
|
+
{ type: 'function', name: 'statusOf', stateMutability: 'view', inputs: [{ name: 'payer', type: 'address' }, { name: 'orderHash', type: 'bytes32' }], outputs: [{ type: 'uint8' }] },
|
|
61
|
+
];
|
|
62
|
+
const ZERO = '0x0000000000000000000000000000000000000000';
|
|
63
|
+
/** The deposit call (the payer SA must `approve` the escrow for `asset` first). */
|
|
64
|
+
export function buildEscrowDeposit(input) {
|
|
65
|
+
return {
|
|
66
|
+
to: input.escrow,
|
|
67
|
+
value: 0n,
|
|
68
|
+
data: encodeFunctionData({
|
|
69
|
+
abi: ESCROW_ABI,
|
|
70
|
+
functionName: 'deposit',
|
|
71
|
+
args: [input.orderHash, input.asset, input.amount, input.payee, input.refundTo ?? ZERO, input.releaser ?? ZERO, BigInt(input.expiry)],
|
|
72
|
+
}),
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
/** Capture the hold to the payee (payee or configured releaser executes). EXT-PMT-3: holds are keyed by
|
|
76
|
+
* (payer, orderHash), so the releasing party must pass the payer. Cannot release at/after expiry. */
|
|
77
|
+
export function buildEscrowRelease(escrow, payer, orderHash) {
|
|
78
|
+
return { to: escrow, value: 0n, data: encodeFunctionData({ abi: ESCROW_ABI, functionName: 'release', args: [payer, orderHash] }) };
|
|
79
|
+
}
|
|
80
|
+
/** Payee-consented refund to the payer, before capture. */
|
|
81
|
+
export function buildEscrowRefund(escrow, payer, orderHash) {
|
|
82
|
+
return { to: escrow, value: 0n, data: encodeFunctionData({ abi: ESCROW_ABI, functionName: 'refund', args: [payer, orderHash] }) };
|
|
83
|
+
}
|
|
84
|
+
/** Payer reclaims after expiry (never released). Payer-initiated → keyed off msg.sender on-chain. */
|
|
85
|
+
export function buildEscrowReclaim(escrow, orderHash) {
|
|
86
|
+
return { to: escrow, value: 0n, data: encodeFunctionData({ abi: ESCROW_ABI, functionName: 'reclaim', args: [orderHash] }) };
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=escrow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"escrow.js","sourceRoot":"","sources":["../../src/rails/escrow.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Invoice rail (spec 243 §5.5, new) — request-for-payment (Request-Network pattern).
|
|
3
|
+
*
|
|
4
|
+
* A push artifact: the issuer publishes an `Invoice` (line items + total + payee + due);
|
|
5
|
+
* the payer reviews and pays it via the wallet rail, deriving a closed mandate bound to
|
|
6
|
+
* `invoiceId`/`orderHash`. The receipt links invoice ↔ settlement; "is this invoice paid?"
|
|
7
|
+
* resolves from receipts, never `eth_getLogs` (ADR-0012). No protocol dependency.
|
|
8
|
+
*/
|
|
9
|
+
import { type Address } from 'viem';
|
|
10
|
+
import type { TransferPlan } from '../transfer.js';
|
|
11
|
+
import type { PaymentMandate, AssetRef, Hex32 } from '../index.js';
|
|
12
|
+
export interface InvoiceLineItem {
|
|
13
|
+
description: string;
|
|
14
|
+
amount: bigint;
|
|
15
|
+
}
|
|
16
|
+
export interface Invoice {
|
|
17
|
+
invoiceId: Hex32;
|
|
18
|
+
issuer: Address;
|
|
19
|
+
/** treasury that receives payment — MAY differ from the issuer */
|
|
20
|
+
payTo: Address;
|
|
21
|
+
lineItems: InvoiceLineItem[];
|
|
22
|
+
amount: bigint;
|
|
23
|
+
asset: AssetRef;
|
|
24
|
+
chain: number;
|
|
25
|
+
/** due time (unix seconds) — becomes the mandate's expiry at pay time */
|
|
26
|
+
dueAt: number;
|
|
27
|
+
/** hash of the memo body (body lives in a vault — privacy §6) */
|
|
28
|
+
memoHash: Hex32;
|
|
29
|
+
/** optional ExchangeOrder linkage (273/274); defaults to `invoiceId` at pay time */
|
|
30
|
+
orderHash?: Hex32;
|
|
31
|
+
}
|
|
32
|
+
export interface InvoiceInput {
|
|
33
|
+
issuer: Address;
|
|
34
|
+
payTo: Address;
|
|
35
|
+
lineItems: InvoiceLineItem[];
|
|
36
|
+
asset: AssetRef;
|
|
37
|
+
chain: number;
|
|
38
|
+
dueAt: number;
|
|
39
|
+
nonce: bigint;
|
|
40
|
+
memo?: string;
|
|
41
|
+
orderHash?: Hex32;
|
|
42
|
+
}
|
|
43
|
+
export declare function computeInvoiceId(args: {
|
|
44
|
+
issuer: Address;
|
|
45
|
+
payTo: Address;
|
|
46
|
+
amount: bigint;
|
|
47
|
+
asset: Address;
|
|
48
|
+
chain: number;
|
|
49
|
+
nonce: bigint;
|
|
50
|
+
}): Hex32;
|
|
51
|
+
/** Build an invoice; `amount` = sum of line items. */
|
|
52
|
+
export declare function buildInvoice(input: InvoiceInput): Invoice;
|
|
53
|
+
/**
|
|
54
|
+
* Pay an invoice via the wallet rail. Derives a closed mandate bound to the invoice
|
|
55
|
+
* (`orderHash = invoice.orderHash ?? invoiceId`) + the transfer plan. Sign the returned
|
|
56
|
+
* mandate with `signPaymentMandate`, then submit `plan`.
|
|
57
|
+
*/
|
|
58
|
+
export declare function payInvoice(invoice: Invoice, payer: Address, opts: {
|
|
59
|
+
nonce: bigint;
|
|
60
|
+
validFrom?: number;
|
|
61
|
+
}): {
|
|
62
|
+
mandate: PaymentMandate;
|
|
63
|
+
plan: TransferPlan;
|
|
64
|
+
};
|
|
65
|
+
//# sourceMappingURL=invoice.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invoice.d.ts","sourceRoot":"","sources":["../../src/rails/invoice.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAA2C,KAAK,OAAO,EAAE,MAAM,MAAM,CAAC;AAG7E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAInE,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,OAAO;IACtB,SAAS,EAAE,KAAK,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,kEAAkE;IAClE,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,EAAE,eAAe,EAAE,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,QAAQ,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,yEAAyE;IACzE,KAAK,EAAE,MAAM,CAAC;IACd,iEAAiE;IACjE,QAAQ,EAAE,KAAK,CAAC;IAChB,oFAAoF;IACpF,SAAS,CAAC,EAAE,KAAK,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,EAAE,eAAe,EAAE,CAAC;IAC7B,KAAK,EAAE,QAAQ,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,KAAK,CAAC;CACnB;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,KAAK,CAO/I;AAED,sDAAsD;AACtD,wBAAgB,YAAY,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAezD;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,OAAO,EAAE,cAAc,CAAC;IAAC,IAAI,EAAE,YAAY,CAAA;CAAE,CAiBzJ"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Invoice rail (spec 243 §5.5, new) — request-for-payment (Request-Network pattern).
|
|
3
|
+
*
|
|
4
|
+
* A push artifact: the issuer publishes an `Invoice` (line items + total + payee + due);
|
|
5
|
+
* the payer reviews and pays it via the wallet rail, deriving a closed mandate bound to
|
|
6
|
+
* `invoiceId`/`orderHash`. The receipt links invoice ↔ settlement; "is this invoice paid?"
|
|
7
|
+
* resolves from receipts, never `eth_getLogs` (ADR-0012). No protocol dependency.
|
|
8
|
+
*/
|
|
9
|
+
import { keccak256, encodeAbiParameters, toBytes } from 'viem';
|
|
10
|
+
import { buildClosedMandate } from '../mandate.js';
|
|
11
|
+
import { buildWalletTransferPlan } from './wallet.js';
|
|
12
|
+
const ZERO32 = ('0x' + '00'.repeat(32));
|
|
13
|
+
export function computeInvoiceId(args) {
|
|
14
|
+
return keccak256(encodeAbiParameters([{ type: 'address' }, { type: 'address' }, { type: 'uint256' }, { type: 'address' }, { type: 'uint256' }, { type: 'uint256' }], [args.issuer, args.payTo, args.amount, args.asset, BigInt(args.chain), args.nonce]));
|
|
15
|
+
}
|
|
16
|
+
/** Build an invoice; `amount` = sum of line items. */
|
|
17
|
+
export function buildInvoice(input) {
|
|
18
|
+
const amount = input.lineItems.reduce((s, li) => s + li.amount, 0n);
|
|
19
|
+
if (amount <= 0n)
|
|
20
|
+
throw new Error('[invoice] amount must be > 0');
|
|
21
|
+
return {
|
|
22
|
+
invoiceId: computeInvoiceId({ issuer: input.issuer, payTo: input.payTo, amount, asset: input.asset.id, chain: input.chain, nonce: input.nonce }),
|
|
23
|
+
issuer: input.issuer,
|
|
24
|
+
payTo: input.payTo,
|
|
25
|
+
lineItems: input.lineItems,
|
|
26
|
+
amount,
|
|
27
|
+
asset: input.asset,
|
|
28
|
+
chain: input.chain,
|
|
29
|
+
dueAt: input.dueAt,
|
|
30
|
+
memoHash: input.memo ? keccak256(toBytes(input.memo)) : ZERO32,
|
|
31
|
+
orderHash: input.orderHash,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Pay an invoice via the wallet rail. Derives a closed mandate bound to the invoice
|
|
36
|
+
* (`orderHash = invoice.orderHash ?? invoiceId`) + the transfer plan. Sign the returned
|
|
37
|
+
* mandate with `signPaymentMandate`, then submit `plan`.
|
|
38
|
+
*/
|
|
39
|
+
export function payInvoice(invoice, payer, opts) {
|
|
40
|
+
const orderHash = invoice.orderHash ?? invoice.invoiceId;
|
|
41
|
+
const mandate = buildClosedMandate({
|
|
42
|
+
rail: 'wallet',
|
|
43
|
+
payer,
|
|
44
|
+
payee: invoice.payTo,
|
|
45
|
+
asset: invoice.asset,
|
|
46
|
+
amount: invoice.amount,
|
|
47
|
+
chain: invoice.chain,
|
|
48
|
+
nonce: opts.nonce,
|
|
49
|
+
validFrom: opts.validFrom,
|
|
50
|
+
expiresAt: invoice.dueAt,
|
|
51
|
+
orderHash,
|
|
52
|
+
legId: invoice.invoiceId,
|
|
53
|
+
reasonHash: invoice.memoHash,
|
|
54
|
+
});
|
|
55
|
+
return { mandate, plan: buildWalletTransferPlan(mandate) };
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=invoice.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invoice.js","sourceRoot":"","sources":["../../src/rails/invoice.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
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 type { Address } from '@agenticprimitives/types';
|
|
11
|
+
import type { TransferPlan } from '../transfer.js';
|
|
12
|
+
import type { PaymentMandate, AssetRef, Hex32 } from '../index.js';
|
|
13
|
+
export interface RecurringInput {
|
|
14
|
+
payer: Address;
|
|
15
|
+
payee: Address;
|
|
16
|
+
asset: AssetRef;
|
|
17
|
+
chain: number;
|
|
18
|
+
amountPerPeriod: bigint;
|
|
19
|
+
windowSeconds: number;
|
|
20
|
+
/** total spend ceiling across all periods (aggregate cap) */
|
|
21
|
+
totalCap: bigint;
|
|
22
|
+
validFrom: number;
|
|
23
|
+
validUntil: number;
|
|
24
|
+
/** base nonce; period N's charge uses `startNonce + N` */
|
|
25
|
+
startNonce: bigint;
|
|
26
|
+
}
|
|
27
|
+
export interface RecurringTemplate extends RecurringInput {
|
|
28
|
+
templateId: Hex32;
|
|
29
|
+
/** number of periods the totalCap covers at amountPerPeriod */
|
|
30
|
+
periods: number;
|
|
31
|
+
}
|
|
32
|
+
export declare function buildRecurringTemplate(input: RecurringInput): RecurringTemplate;
|
|
33
|
+
export interface RecurringCaveatParams {
|
|
34
|
+
maxAmountPerCharge: bigint;
|
|
35
|
+
maxAggregate: bigint;
|
|
36
|
+
maxRedemptionsPerWindow: number;
|
|
37
|
+
windowSeconds: number;
|
|
38
|
+
validUntil: number;
|
|
39
|
+
}
|
|
40
|
+
/** The values the app feeds to `delegation.buildPaymentMandateCaveats` for the one-time authorization. */
|
|
41
|
+
export declare function recurringCaveatParams(t: RecurringTemplate): RecurringCaveatParams;
|
|
42
|
+
/** The time window in which period N may be charged (the enforcer rejects an early re-charge). */
|
|
43
|
+
export declare function periodWindow(t: RecurringTemplate, period: number): {
|
|
44
|
+
start: number;
|
|
45
|
+
end: number;
|
|
46
|
+
};
|
|
47
|
+
/** Derive the closed per-charge mandate + transfer plan for period N. Sign the mandate, then settle. */
|
|
48
|
+
export declare function deriveScheduledCharge(t: RecurringTemplate, period: number): {
|
|
49
|
+
mandate: PaymentMandate;
|
|
50
|
+
plan: TransferPlan;
|
|
51
|
+
window: {
|
|
52
|
+
start: number;
|
|
53
|
+
end: number;
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
//# sourceMappingURL=recurring.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recurring.d.ts","sourceRoot":"","sources":["../../src/rails/recurring.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AAIxD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEnE,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,QAAQ,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,6DAA6D;IAC7D,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,0DAA0D;IAC1D,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAkB,SAAQ,cAAc;IACvD,UAAU,EAAE,KAAK,CAAC;IAClB,+DAA+D;IAC/D,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,cAAc,GAAG,iBAAiB,CAW/E;AAED,MAAM,WAAW,qBAAqB;IACpC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,uBAAuB,EAAE,MAAM,CAAC;IAChC,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,0GAA0G;AAC1G,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,iBAAiB,GAAG,qBAAqB,CAQjF;AAED,kGAAkG;AAClG,wBAAgB,YAAY,CAAC,CAAC,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAGjG;AAED,wGAAwG;AACxG,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,cAAc,CAAC;IAAC,IAAI,EAAE,YAAY,CAAC;IAAC,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,CAiBnK"}
|