@daski/pay 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +102 -0
  3. package/dist/bin/daski.d.ts +3 -0
  4. package/dist/bin/daski.d.ts.map +1 -0
  5. package/dist/bin/daski.js +187 -0
  6. package/dist/bin/daski.js.map +1 -0
  7. package/dist/cli/args.d.ts +11 -0
  8. package/dist/cli/args.d.ts.map +1 -0
  9. package/dist/cli/args.js +82 -0
  10. package/dist/cli/args.js.map +1 -0
  11. package/dist/cli/errors.d.ts +24 -0
  12. package/dist/cli/errors.d.ts.map +1 -0
  13. package/dist/cli/errors.js +23 -0
  14. package/dist/cli/errors.js.map +1 -0
  15. package/dist/cli/output.d.ts +8 -0
  16. package/dist/cli/output.d.ts.map +1 -0
  17. package/dist/cli/output.js +76 -0
  18. package/dist/cli/output.js.map +1 -0
  19. package/dist/cli/prompt.d.ts +12 -0
  20. package/dist/cli/prompt.d.ts.map +1 -0
  21. package/dist/cli/prompt.js +101 -0
  22. package/dist/cli/prompt.js.map +1 -0
  23. package/dist/cli/redact.d.ts +26 -0
  24. package/dist/cli/redact.d.ts.map +1 -0
  25. package/dist/cli/redact.js +55 -0
  26. package/dist/cli/redact.js.map +1 -0
  27. package/dist/commands/buy.d.ts +15 -0
  28. package/dist/commands/buy.d.ts.map +1 -0
  29. package/dist/commands/buy.js +276 -0
  30. package/dist/commands/buy.js.map +1 -0
  31. package/dist/commands/doctor.d.ts +29 -0
  32. package/dist/commands/doctor.d.ts.map +1 -0
  33. package/dist/commands/doctor.js +173 -0
  34. package/dist/commands/doctor.js.map +1 -0
  35. package/dist/commands/order.d.ts +18 -0
  36. package/dist/commands/order.d.ts.map +1 -0
  37. package/dist/commands/order.js +256 -0
  38. package/dist/commands/order.js.map +1 -0
  39. package/dist/commands/signPayment.d.ts +10 -0
  40. package/dist/commands/signPayment.d.ts.map +1 -0
  41. package/dist/commands/signPayment.js +162 -0
  42. package/dist/commands/signPayment.js.map +1 -0
  43. package/dist/commands/wallet.d.ts +11 -0
  44. package/dist/commands/wallet.d.ts.map +1 -0
  45. package/dist/commands/wallet.js +104 -0
  46. package/dist/commands/wallet.js.map +1 -0
  47. package/dist/config.d.ts +64 -0
  48. package/dist/config.d.ts.map +1 -0
  49. package/dist/config.js +200 -0
  50. package/dist/config.js.map +1 -0
  51. package/dist/context.d.ts +36 -0
  52. package/dist/context.d.ts.map +1 -0
  53. package/dist/context.js +54 -0
  54. package/dist/context.js.map +1 -0
  55. package/dist/gateway/balance.d.ts +16 -0
  56. package/dist/gateway/balance.d.ts.map +1 -0
  57. package/dist/gateway/balance.js +23 -0
  58. package/dist/gateway/balance.js.map +1 -0
  59. package/dist/gateway/catalog.d.ts +49 -0
  60. package/dist/gateway/catalog.d.ts.map +1 -0
  61. package/dist/gateway/catalog.js +161 -0
  62. package/dist/gateway/catalog.js.map +1 -0
  63. package/dist/gateway/client.d.ts +80 -0
  64. package/dist/gateway/client.d.ts.map +1 -0
  65. package/dist/gateway/client.js +128 -0
  66. package/dist/gateway/client.js.map +1 -0
  67. package/dist/gateway/lifecycle.d.ts +45 -0
  68. package/dist/gateway/lifecycle.d.ts.map +1 -0
  69. package/dist/gateway/lifecycle.js +96 -0
  70. package/dist/gateway/lifecycle.js.map +1 -0
  71. package/dist/gateway/purchase.d.ts +119 -0
  72. package/dist/gateway/purchase.d.ts.map +1 -0
  73. package/dist/gateway/purchase.js +250 -0
  74. package/dist/gateway/purchase.js.map +1 -0
  75. package/dist/index.d.ts +26 -0
  76. package/dist/index.d.ts.map +1 -0
  77. package/dist/index.js +26 -0
  78. package/dist/index.js.map +1 -0
  79. package/dist/paths.d.ts +6 -0
  80. package/dist/paths.d.ts.map +1 -0
  81. package/dist/paths.js +11 -0
  82. package/dist/paths.js.map +1 -0
  83. package/dist/signers/cdp.d.ts +7 -0
  84. package/dist/signers/cdp.d.ts.map +1 -0
  85. package/dist/signers/cdp.js +42 -0
  86. package/dist/signers/cdp.js.map +1 -0
  87. package/dist/signers/circle.d.ts +53 -0
  88. package/dist/signers/circle.d.ts.map +1 -0
  89. package/dist/signers/circle.js +136 -0
  90. package/dist/signers/circle.js.map +1 -0
  91. package/dist/signers/index.d.ts +23 -0
  92. package/dist/signers/index.d.ts.map +1 -0
  93. package/dist/signers/index.js +22 -0
  94. package/dist/signers/index.js.map +1 -0
  95. package/dist/signers/local.d.ts +3 -0
  96. package/dist/signers/local.d.ts.map +1 -0
  97. package/dist/signers/local.js +24 -0
  98. package/dist/signers/local.js.map +1 -0
  99. package/dist/signers/selfTest.d.ts +46 -0
  100. package/dist/signers/selfTest.d.ts.map +1 -0
  101. package/dist/signers/selfTest.js +113 -0
  102. package/dist/signers/selfTest.js.map +1 -0
  103. package/dist/store/keystore.d.ts +19 -0
  104. package/dist/store/keystore.d.ts.map +1 -0
  105. package/dist/store/keystore.js +226 -0
  106. package/dist/store/keystore.js.map +1 -0
  107. package/dist/store/orders.d.ts +39 -0
  108. package/dist/store/orders.d.ts.map +1 -0
  109. package/dist/store/orders.js +91 -0
  110. package/dist/store/orders.js.map +1 -0
  111. package/dist/version.d.ts +2 -0
  112. package/dist/version.d.ts.map +1 -0
  113. package/dist/version.js +21 -0
  114. package/dist/version.js.map +1 -0
  115. package/package.json +59 -0
@@ -0,0 +1,119 @@
1
+ import { type OrderBinding, type PolicyConfig, type SignerAdapter } from "@daski/x402-scheme";
2
+ import { type Address } from "viem";
3
+ import { CliError } from "../cli/errors.js";
4
+ import { updateOrder, type OrderRecord } from "../store/orders.js";
5
+ import { GatewayClient, type McpToolResult, type PaymentChallenge, type PaymentRequirement, type PaymentSubmission } from "./client.js";
6
+ /** The spec-01 tool; absent on today's sandbox, where we fall back. */
7
+ export declare const CHALLENGE_TOOL = "daski_get_payment_challenge";
8
+ export declare const BUY_TOOL = "daski_buy_outcome";
9
+ export interface ChallengeResult {
10
+ challenge: PaymentChallenge;
11
+ requirement: PaymentRequirement;
12
+ binding: OrderBinding | undefined;
13
+ /** True when the spec-01 challenge tool served this. */
14
+ viaChallengeTool: boolean;
15
+ }
16
+ /** A fresh reconciliation key. Also the idempotency key the gateway echoes. */
17
+ export declare function newIntentId(): string;
18
+ /**
19
+ * Step 1: obtain a payment challenge. Prefers `daski_get_payment_challenge`
20
+ * and falls back to an unpaid `daski_buy_outcome`, which is the same challenge
21
+ * by a longer road.
22
+ */
23
+ export declare function requestChallenge(options: {
24
+ client: GatewayClient;
25
+ providerAgentId: string;
26
+ outcomeId: string;
27
+ request: Record<string, unknown>;
28
+ payerAddress: Address;
29
+ }): Promise<ChallengeResult>;
30
+ export interface AuthorizeOptions {
31
+ policy: PolicyConfig;
32
+ signer: SignerAdapter;
33
+ challenge: ChallengeResult;
34
+ providerAgentId: string;
35
+ outcomeId: string;
36
+ /** What the human approved, in atomic units. */
37
+ approvedQuoteAtomic: bigint;
38
+ intentId: string;
39
+ nowSeconds?: number;
40
+ }
41
+ export interface AuthorizedPayment {
42
+ submission: PaymentSubmission;
43
+ amountAtomic: bigint;
44
+ nonce: string;
45
+ }
46
+ /**
47
+ * Steps 3 and 4: validate, recompute, sign. The authorization is built here
48
+ * rather than accepted, and the §4 validator sees it before the wallet does.
49
+ */
50
+ export declare function authorizePayment(options: AuthorizeOptions): Promise<AuthorizedPayment>;
51
+ export interface SubmitOptions {
52
+ client: GatewayClient;
53
+ providerAgentId: string;
54
+ outcomeId: string;
55
+ request: Record<string, unknown>;
56
+ submission: PaymentSubmission;
57
+ /** Pass the payload as a tool argument instead of `_meta`. */
58
+ legacyArg?: boolean;
59
+ timeoutMs?: number;
60
+ }
61
+ /**
62
+ * Step 5: the paid retry. The payload rides in `_meta["x402/payment"]` unless
63
+ * `--legacy-arg` asks for the argument form.
64
+ */
65
+ export declare function submitPayment(options: SubmitOptions): Promise<McpToolResult>;
66
+ export interface ReconcileOptions {
67
+ client: GatewayClient;
68
+ signer: SignerAdapter;
69
+ record: OrderRecord;
70
+ payer: Address;
71
+ chainId: number;
72
+ gatewayUrl: string;
73
+ submission: PaymentSubmission;
74
+ request: Record<string, unknown>;
75
+ legacyArg?: boolean;
76
+ }
77
+ export interface ReconcileOutcome {
78
+ /** `settled` when an order exists; `absent` when provably none does. */
79
+ status: "settled" | "absent";
80
+ orderHandle?: string | undefined;
81
+ body?: Record<string, unknown> | undefined;
82
+ /** How the conclusion was reached, for the audit log. */
83
+ evidence: string;
84
+ }
85
+ /**
86
+ * The ambiguous-outcome path. Never signs anything: it replays what was
87
+ * already signed, then corroborates against the payer's own history.
88
+ */
89
+ export declare function reconcileAmbiguousPurchase(options: ReconcileOptions): Promise<ReconcileOutcome>;
90
+ interface PayerOrderRow {
91
+ orderHandle: string;
92
+ providerAgentId: string;
93
+ outcomeId: string;
94
+ grossAmount: string;
95
+ state: string;
96
+ createdAt: string;
97
+ /** Present once the gateway echoes the buyer's idempotency key. */
98
+ paymentIdentifier?: string;
99
+ }
100
+ /**
101
+ * The payer's order history. When the gateway echoes `paymentIdentifier` on a
102
+ * row, we filter by it exactly as §2 specifies; until then the rows carry no
103
+ * such field and the caller matches on the intent's other invariants.
104
+ */
105
+ export declare function listPayerOrders(options: {
106
+ client: GatewayClient;
107
+ signer: SignerAdapter;
108
+ payer: Address;
109
+ chainId: number;
110
+ gatewayUrl: string;
111
+ intentId?: string | undefined;
112
+ }): Promise<PayerOrderRow[]>;
113
+ /** Records the intent before signing, so an interruption is recoverable. */
114
+ export declare function recordIntent(record: Omit<OrderRecord, "createdAt" | "updatedAt">): OrderRecord;
115
+ export { updateOrder };
116
+ export declare function purchaseFailure(result: McpToolResult): CliError;
117
+ /** Human-readable price, for approval prompts and receipts. */
118
+ export declare function priceLine(amountAtomic: bigint): string;
119
+ //# sourceMappingURL=purchase.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"purchase.d.ts","sourceRoot":"","sources":["../../src/gateway/purchase.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,250 @@
1
+ /**
2
+ * The purchase flow, and the ambiguous-outcome path.
3
+ *
4
+ * The dangerous moment in a buyer bridge is not the signature — it is the
5
+ * silence after it. A timeout, a dropped socket, or a
6
+ * `PAYMENT_PENDING_RECONCILIATION` leaves us unable to say whether money
7
+ * moved. The rule (§2) is: reconcile before any re-sign. A second signature
8
+ * over a fresh challenge is a second order, and a second charge.
9
+ *
10
+ * Two facts make reconciliation provable rather than heuristic:
11
+ *
12
+ * 1. The recipe nonce is deterministic, so an identical resubmission is
13
+ * byte-identical, and the gateway's published retry policy treats an
14
+ * identical signed authorization as `transport-retry-same-purchase`.
15
+ * Replaying what we already signed cannot create a second order.
16
+ * 2. The payer's own order history corroborates it independently.
17
+ *
18
+ * So we replay first, corroborate second, and only request a fresh challenge
19
+ * when both agree the order does not exist.
20
+ */
21
+ import { randomBytes } from "node:crypto";
22
+ import { bindingFromExtensions, formatUsdc, paymentEchoExtensions, transferWithAuthorizationTypedData, validatePurchaseAuthorization, withPaymentIdentifier, } from "@daski/x402-scheme";
23
+ import { getAddress } from "viem";
24
+ import { CliError } from "../cli/errors.js";
25
+ import { findByIntent, updateOrder, upsertOrder, } from "../store/orders.js";
26
+ import { GatewayClient, } from "./client.js";
27
+ import { callWalletQuery } from "./lifecycle.js";
28
+ /** The spec-01 tool; absent on today's sandbox, where we fall back. */
29
+ export const CHALLENGE_TOOL = "daski_get_payment_challenge";
30
+ export const BUY_TOOL = "daski_buy_outcome";
31
+ /** A fresh reconciliation key. Also the idempotency key the gateway echoes. */
32
+ export function newIntentId() {
33
+ return `daski-${randomBytes(16).toString("hex")}`;
34
+ }
35
+ /**
36
+ * Step 1: obtain a payment challenge. Prefers `daski_get_payment_challenge`
37
+ * and falls back to an unpaid `daski_buy_outcome`, which is the same challenge
38
+ * by a longer road.
39
+ */
40
+ export async function requestChallenge(options) {
41
+ const { client, providerAgentId, outcomeId, request, payerAddress } = options;
42
+ const viaChallengeTool = await client.hasTool(CHALLENGE_TOOL);
43
+ const result = viaChallengeTool
44
+ ? await client.callTool(CHALLENGE_TOOL, {
45
+ providerAgentId, outcomeId, request, payerAddress,
46
+ })
47
+ : await client.callTool(BUY_TOOL, { providerAgentId, outcomeId, request });
48
+ const challenge = GatewayClient.challenge(result);
49
+ if (!challenge)
50
+ throw purchaseFailure(result);
51
+ const requirement = challenge.accepts[0];
52
+ if (!requirement) {
53
+ throw new CliError({
54
+ code: "DASKI_CHALLENGE_NO_REQUIREMENTS",
55
+ message: "The gateway returned a challenge with no payment requirements.",
56
+ remediation: "Retry; if it persists, report it to the gateway operator.",
57
+ });
58
+ }
59
+ return {
60
+ challenge,
61
+ requirement,
62
+ binding: bindingFromExtensions(challenge.extensions),
63
+ viaChallengeTool,
64
+ };
65
+ }
66
+ /**
67
+ * Steps 3 and 4: validate, recompute, sign. The authorization is built here
68
+ * rather than accepted, and the §4 validator sees it before the wallet does.
69
+ */
70
+ export async function authorizePayment(options) {
71
+ const { policy, challenge, signer } = options;
72
+ const requirement = challenge.requirement;
73
+ const now = options.nowSeconds ?? Math.floor(Date.now() / 1_000);
74
+ const binding = challenge.binding;
75
+ const payer = getAddress(policy.payerAddress);
76
+ const splitter = getAddress(requirement.payTo);
77
+ const amount = BigInt(requirement.amount);
78
+ if (!binding) {
79
+ throw new CliError({
80
+ code: "DASKI_CHALLENGE_NOT_RECIPE_BOUND",
81
+ message: "This challenge carries no daski-order-binding, so its authorization " +
82
+ "nonce cannot be recomputed.",
83
+ remediation: "Only recipe-bound Daski challenges are signable here. Use " +
84
+ "`daski sign-payment` documentation to see the accepted shapes.",
85
+ });
86
+ }
87
+ const validAfter = BigInt(Math.max(0, now - 30));
88
+ const validBefore = BigInt(Math.min(now + requirement.maxTimeoutSeconds, binding.expiresAt));
89
+ const { deriveBindingNonce } = await import("@daski/x402-scheme");
90
+ const nonce = deriveBindingNonce(binding, {
91
+ chainId: policy.chainId,
92
+ canonicalToken: getAddress(policy.canonicalToken),
93
+ payer,
94
+ splitter,
95
+ grossAmount: amount,
96
+ });
97
+ const domain = {
98
+ name: requirement.extra.name,
99
+ version: requirement.extra.version,
100
+ chainId: policy.chainId,
101
+ verifyingContract: getAddress(requirement.asset),
102
+ };
103
+ const proposal = transferWithAuthorizationTypedData(domain, {
104
+ from: payer,
105
+ to: splitter,
106
+ value: amount.toString(),
107
+ validAfter: validAfter.toString(),
108
+ validBefore: validBefore.toString(),
109
+ nonce,
110
+ });
111
+ const validated = await validatePurchaseAuthorization(policy, proposal, {
112
+ providerAgentId: options.providerAgentId,
113
+ outcomeId: options.outcomeId,
114
+ challengeAmountAtomic: amount,
115
+ challengeAsset: getAddress(requirement.asset),
116
+ challengePayTo: splitter,
117
+ challengeNetwork: requirement.network,
118
+ approvedQuoteAtomic: options.approvedQuoteAtomic,
119
+ paymentIdentifier: options.intentId,
120
+ binding,
121
+ nowSeconds: now,
122
+ });
123
+ const signature = await signer.signTypedData(transferWithAuthorizationTypedData(domain, validated.authorization));
124
+ return {
125
+ submission: {
126
+ x402Version: challenge.challenge.x402Version,
127
+ resource: challenge.challenge.resource,
128
+ accepted: requirement,
129
+ payload: { authorization: validated.authorization, signature },
130
+ extensions: withPaymentIdentifier(paymentEchoExtensions(challenge.challenge.extensions), options.intentId),
131
+ },
132
+ amountAtomic: validated.amountAtomic,
133
+ nonce: validated.recomputedNonce,
134
+ };
135
+ }
136
+ /**
137
+ * Step 5: the paid retry. The payload rides in `_meta["x402/payment"]` unless
138
+ * `--legacy-arg` asks for the argument form.
139
+ */
140
+ export async function submitPayment(options) {
141
+ const args = {
142
+ providerAgentId: options.providerAgentId,
143
+ outcomeId: options.outcomeId,
144
+ request: options.request,
145
+ };
146
+ if (options.legacyArg) {
147
+ args.paymentPayload = options.submission;
148
+ return options.client.callTool(BUY_TOOL, args);
149
+ }
150
+ return options.client.callTool(BUY_TOOL, args, {
151
+ "x402/payment": options.submission,
152
+ });
153
+ }
154
+ /**
155
+ * The ambiguous-outcome path. Never signs anything: it replays what was
156
+ * already signed, then corroborates against the payer's own history.
157
+ */
158
+ export async function reconcileAmbiguousPurchase(options) {
159
+ const { client, record } = options;
160
+ // 1. Replay the identical authorization. Idempotent by the gateway's own
161
+ // published retry policy, so this cannot create a second order.
162
+ const replay = await submitPayment({
163
+ client,
164
+ providerAgentId: record.providerAgentId,
165
+ outcomeId: record.outcomeId,
166
+ request: options.request,
167
+ submission: options.submission,
168
+ ...(options.legacyArg === undefined ? {} : { legacyArg: options.legacyArg }),
169
+ });
170
+ const replayBody = GatewayClient.json(replay);
171
+ if (!replay.isError && typeof replayBody?.orderHandle === "string") {
172
+ return {
173
+ status: "settled",
174
+ orderHandle: replayBody.orderHandle,
175
+ body: replayBody,
176
+ evidence: "identical signed authorization replayed to the same order",
177
+ };
178
+ }
179
+ // 2. Corroborate independently against the payer's own order history.
180
+ const listed = await listPayerOrders(options);
181
+ const match = listed.find((order) => order.providerAgentId === record.providerAgentId &&
182
+ order.outcomeId === record.outcomeId &&
183
+ order.grossAmount === record.amount &&
184
+ Date.parse(order.createdAt) >= Date.parse(record.createdAt) - 60_000);
185
+ if (match) {
186
+ return {
187
+ status: "settled",
188
+ orderHandle: match.orderHandle,
189
+ evidence: "matched an order in the payer's own history",
190
+ };
191
+ }
192
+ return {
193
+ status: "absent",
194
+ evidence: "the identical replay produced no order and the payer's history contains none",
195
+ };
196
+ }
197
+ /**
198
+ * The payer's order history. When the gateway echoes `paymentIdentifier` on a
199
+ * row, we filter by it exactly as §2 specifies; until then the rows carry no
200
+ * such field and the caller matches on the intent's other invariants.
201
+ */
202
+ export async function listPayerOrders(options) {
203
+ const body = await callWalletQuery({
204
+ client: options.client,
205
+ signer: options.signer,
206
+ toolName: "daski_list_my_orders",
207
+ action: "list-orders",
208
+ payer: options.payer,
209
+ request: { limit: 25, cursor: null },
210
+ chainId: options.chainId,
211
+ gatewayUrl: options.gatewayUrl,
212
+ });
213
+ const rows = Array.isArray(body.orders) ? body.orders : [];
214
+ if (!options.intentId)
215
+ return rows;
216
+ const filtered = rows.filter((row) => row.paymentIdentifier === options.intentId);
217
+ // Only narrow when the gateway actually echoes the key; an empty result from
218
+ // a field that does not exist is not evidence of absence.
219
+ return filtered.length > 0 || rows.some((row) => row.paymentIdentifier !== undefined)
220
+ ? filtered
221
+ : rows;
222
+ }
223
+ /** Records the intent before signing, so an interruption is recoverable. */
224
+ export function recordIntent(record) {
225
+ const existing = findByIntent(record.intentId);
226
+ if (existing)
227
+ return existing;
228
+ const now = new Date().toISOString();
229
+ return upsertOrder({ ...record, createdAt: now, updatedAt: now });
230
+ }
231
+ export { updateOrder };
232
+ export function purchaseFailure(result) {
233
+ const body = GatewayClient.json(result);
234
+ const code = typeof body?.code === "string" ? body.code : "DASKI_PURCHASE_FAILED";
235
+ return new CliError({
236
+ code,
237
+ message: typeof body?.message === "string"
238
+ ? body.message
239
+ : "The gateway rejected the purchase.",
240
+ remediation: typeof body?.next_action === "string"
241
+ ? body.next_action
242
+ : "Re-run with --json to see the gateway's full response.",
243
+ details: { gateway: body ?? null },
244
+ });
245
+ }
246
+ /** Human-readable price, for approval prompts and receipts. */
247
+ export function priceLine(amountAtomic) {
248
+ return formatUsdc(amountAtomic);
249
+ }
250
+ //# sourceMappingURL=purchase.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"purchase.js","sourceRoot":"","sources":["../../src/gateway/purchase.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * `@daski/pay` as a library.
3
+ *
4
+ * The CLI is the product; this surface exists so a host application can reuse
5
+ * the same validated flows without shelling out. Everything exported here
6
+ * still signs only through the §4 validator.
7
+ */
8
+ export { runBuy, type BuyOptions } from "./commands/buy.js";
9
+ export { runDoctor, type DoctorIssue, type DoctorOptions, type DoctorReport } from "./commands/doctor.js";
10
+ export { orderArtifact, orderCancel, orderConfirm, orderInput, orderStatus, type OrderArtifactOptions, type OrderInputOptions, type OrderOptions, } from "./commands/order.js";
11
+ export { runSignPayment, type SignPaymentOptions } from "./commands/signPayment.js";
12
+ export { createWallet, walletAddress, walletBalance, type WalletOptions } from "./commands/wallet.js";
13
+ export { CliError, type CliErrorOptions } from "./cli/errors.js";
14
+ export { redactText, redactValue } from "./cli/redact.js";
15
+ export { applyCapOverrides, atomicUsdc, ensureConfig, loadConfig, permissionWarnings, type DaskiConfig, type LoadedConfig, type ProfileConfig, type SignerKind, } from "./config.js";
16
+ export { createContext, type CommandContext, type ContextOptions } from "./context.js";
17
+ export { Catalog, CATALOG_TTL_SECONDS, type OutcomeSummary } from "./gateway/catalog.js";
18
+ export { GatewayClient, readiness, type GatewayCallLog, type PaymentChallenge, type PaymentRequirement, type PaymentSubmission, } from "./gateway/client.js";
19
+ export { callAuthorizedLifecycleTool, callWalletQuery } from "./gateway/lifecycle.js";
20
+ export { authorizePayment, listPayerOrders, newIntentId, reconcileAmbiguousPurchase, recordIntent, requestChallenge, submitPayment, type AuthorizedPayment, type ChallengeResult, type ReconcileOutcome, } from "./gateway/purchase.js";
21
+ export { createSigner, type SignerSelection } from "./signers/index.js";
22
+ export { runSignerSelfTest, selfTestVector, type SignerSelfTestResult } from "./signers/selfTest.js";
23
+ export { activeReadCapability, authorizedTotalAtomic, findByIntent, findOrder, listOrders, updateOrder, upsertOrder, type OrderRecord, type OrderState, } from "./store/orders.js";
24
+ export { hasKey, locateKey, type KeyLocation, type KeySource } from "./store/keystore.js";
25
+ export { CLI_VERSION } from "./version.js";
26
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,MAAM,EAAE,KAAK,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,KAAK,WAAW,EAAE,KAAK,aAAa,EAAE,KAAK,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAC1G,OAAO,EACL,aAAa,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,WAAW,EACjE,KAAK,oBAAoB,EAAE,KAAK,iBAAiB,EAAE,KAAK,YAAY,GACrE,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,cAAc,EAAE,KAAK,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACpF,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,KAAK,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAEtG,OAAO,EAAE,QAAQ,EAAE,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE1D,OAAO,EACL,iBAAiB,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,kBAAkB,EAC3E,KAAK,WAAW,EAAE,KAAK,YAAY,EAAE,KAAK,aAAa,EAAE,KAAK,UAAU,GACzE,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,aAAa,EAAE,KAAK,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AAEvF,OAAO,EAAE,OAAO,EAAE,mBAAmB,EAAE,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACzF,OAAO,EACL,aAAa,EAAE,SAAS,EACxB,KAAK,cAAc,EAAE,KAAK,gBAAgB,EAAE,KAAK,kBAAkB,EAAE,KAAK,iBAAiB,GAC5F,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,2BAA2B,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACtF,OAAO,EACL,gBAAgB,EAAE,eAAe,EAAE,WAAW,EAAE,0BAA0B,EAC1E,YAAY,EAAE,gBAAgB,EAAE,aAAa,EAC7C,KAAK,iBAAiB,EAAE,KAAK,eAAe,EAAE,KAAK,gBAAgB,GACpE,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,YAAY,EAAE,KAAK,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,KAAK,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AACrG,OAAO,EACL,oBAAoB,EAAE,qBAAqB,EAAE,YAAY,EAAE,SAAS,EACpE,UAAU,EAAE,WAAW,EAAE,WAAW,EAAE,KAAK,WAAW,EAAE,KAAK,UAAU,GACxE,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,WAAW,EAAE,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAC1F,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,26 @@
1
+ /**
2
+ * `@daski/pay` as a library.
3
+ *
4
+ * The CLI is the product; this surface exists so a host application can reuse
5
+ * the same validated flows without shelling out. Everything exported here
6
+ * still signs only through the §4 validator.
7
+ */
8
+ export { runBuy } from "./commands/buy.js";
9
+ export { runDoctor } from "./commands/doctor.js";
10
+ export { orderArtifact, orderCancel, orderConfirm, orderInput, orderStatus, } from "./commands/order.js";
11
+ export { runSignPayment } from "./commands/signPayment.js";
12
+ export { createWallet, walletAddress, walletBalance } from "./commands/wallet.js";
13
+ export { CliError } from "./cli/errors.js";
14
+ export { redactText, redactValue } from "./cli/redact.js";
15
+ export { applyCapOverrides, atomicUsdc, ensureConfig, loadConfig, permissionWarnings, } from "./config.js";
16
+ export { createContext } from "./context.js";
17
+ export { Catalog, CATALOG_TTL_SECONDS } from "./gateway/catalog.js";
18
+ export { GatewayClient, readiness, } from "./gateway/client.js";
19
+ export { callAuthorizedLifecycleTool, callWalletQuery } from "./gateway/lifecycle.js";
20
+ export { authorizePayment, listPayerOrders, newIntentId, reconcileAmbiguousPurchase, recordIntent, requestChallenge, submitPayment, } from "./gateway/purchase.js";
21
+ export { createSigner } from "./signers/index.js";
22
+ export { runSignerSelfTest, selfTestVector } from "./signers/selfTest.js";
23
+ export { activeReadCapability, authorizedTotalAtomic, findByIntent, findOrder, listOrders, updateOrder, upsertOrder, } from "./store/orders.js";
24
+ export { hasKey, locateKey } from "./store/keystore.js";
25
+ export { CLI_VERSION } from "./version.js";
26
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,MAAM,EAAmB,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,SAAS,EAA2D,MAAM,sBAAsB,CAAC;AAC1G,OAAO,EACL,aAAa,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,WAAW,GAElE,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,cAAc,EAA2B,MAAM,2BAA2B,CAAC;AACpF,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAsB,MAAM,sBAAsB,CAAC;AAEtG,OAAO,EAAE,QAAQ,EAAwB,MAAM,iBAAiB,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE1D,OAAO,EACL,iBAAiB,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,kBAAkB,GAE5E,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,aAAa,EAA4C,MAAM,cAAc,CAAC;AAEvF,OAAO,EAAE,OAAO,EAAE,mBAAmB,EAAuB,MAAM,sBAAsB,CAAC;AACzF,OAAO,EACL,aAAa,EAAE,SAAS,GAEzB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,2BAA2B,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACtF,OAAO,EACL,gBAAgB,EAAE,eAAe,EAAE,WAAW,EAAE,0BAA0B,EAC1E,YAAY,EAAE,gBAAgB,EAAE,aAAa,GAE9C,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,YAAY,EAAwB,MAAM,oBAAoB,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAA6B,MAAM,uBAAuB,CAAC;AACrG,OAAO,EACL,oBAAoB,EAAE,qBAAqB,EAAE,YAAY,EAAE,SAAS,EACpE,UAAU,EAAE,WAAW,EAAE,WAAW,GACrC,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,MAAM,EAAE,SAAS,EAAoC,MAAM,qBAAqB,CAAC;AAC1F,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,6 @@
1
+ /** `~/.daski`, or `$DASKI_HOME` when set (used by the conformance suite). */
2
+ export declare function daskiHome(): string;
3
+ export declare const configPath: () => string;
4
+ export declare const ordersPath: () => string;
5
+ export declare const keystorePath: () => string;
6
+ //# sourceMappingURL=paths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAIA,6EAA6E;AAC7E,wBAAgB,SAAS,IAAI,MAAM,CAElC;AAED,eAAO,MAAM,UAAU,QAAO,MAA0C,CAAC;AACzE,eAAO,MAAM,UAAU,QAAO,MAA0C,CAAC;AACzE,eAAO,MAAM,YAAY,QAAO,MAA4C,CAAC"}
package/dist/paths.js ADDED
@@ -0,0 +1,11 @@
1
+ /** Where the bridge keeps its state. One directory, three files, no surprises. */
2
+ import { homedir } from "node:os";
3
+ import { join } from "node:path";
4
+ /** `~/.daski`, or `$DASKI_HOME` when set (used by the conformance suite). */
5
+ export function daskiHome() {
6
+ return process.env.DASKI_HOME ?? join(homedir(), ".daski");
7
+ }
8
+ export const configPath = () => join(daskiHome(), "config.json");
9
+ export const ordersPath = () => join(daskiHome(), "orders.json");
10
+ export const keystorePath = () => join(daskiHome(), "keystore.json");
11
+ //# sourceMappingURL=paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAClF,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,6EAA6E;AAC7E,MAAM,UAAU,SAAS;IACvB,OAAO,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,CAAC,CAAC;AAC7D,CAAC;AAED,MAAM,CAAC,MAAM,UAAU,GAAG,GAAW,EAAE,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,aAAa,CAAC,CAAC;AACzE,MAAM,CAAC,MAAM,UAAU,GAAG,GAAW,EAAE,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,aAAa,CAAC,CAAC;AACzE,MAAM,CAAC,MAAM,YAAY,GAAG,GAAW,EAAE,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,eAAe,CAAC,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { SignerAdapter } from "@daski/x402-scheme";
2
+ export interface CdpSignerOptions {
3
+ /** CDP account name or address; defaults to `$DASKI_CDP_ACCOUNT`. */
4
+ account?: string | undefined;
5
+ }
6
+ export declare function createCdpSigner(options?: CdpSignerOptions): Promise<SignerAdapter>;
7
+ //# sourceMappingURL=cdp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cdp.d.ts","sourceRoot":"","sources":["../../src/signers/cdp.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,aAAa,EAAoB,MAAM,oBAAoB,CAAC;AAU1E,MAAM,WAAW,gBAAgB;IAC/B,qEAAqE;IACrE,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC9B;AAED,wBAAsB,eAAe,CAAC,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAAC,aAAa,CAAC,CAsB5F"}
@@ -0,0 +1,42 @@
1
+ import { CliError } from "../cli/errors.js";
2
+ const DOC = "https://github.com/daski-io/buyer/blob/main/docs/signers.md#cdp";
3
+ export async function createCdpSigner(options = {}) {
4
+ const accountName = options.account ?? process.env.DASKI_CDP_ACCOUNT;
5
+ if (!accountName) {
6
+ throw new CliError({
7
+ code: "DASKI_CDP_ACCOUNT_UNSET",
8
+ message: "The CDP signer needs an account name or address.",
9
+ remediation: `Set DASKI_CDP_ACCOUNT, or pass --cdp-account. See ${DOC}`,
10
+ });
11
+ }
12
+ const sdk = await importCdp();
13
+ const client = new sdk.CdpClient();
14
+ const account = await client.evm.getOrCreateAccount({ name: accountName });
15
+ return {
16
+ getAddress: async () => account.address,
17
+ signTypedData: (payload) => account.signTypedData(payload),
18
+ describe: () => ({
19
+ provider: "cdp",
20
+ // CDP can mint both; the conformance run is what pins this down per account.
21
+ accountType: "unknown",
22
+ conformance: "candidate-pending-conformance",
23
+ }),
24
+ };
25
+ }
26
+ /**
27
+ * `@coinbase/cdp-sdk` is not a dependency of this package: installing it is
28
+ * the operator's choice, and the local signer must not carry its weight.
29
+ */
30
+ async function importCdp() {
31
+ try {
32
+ return (await import("@coinbase/cdp-sdk"));
33
+ }
34
+ catch {
35
+ throw new CliError({
36
+ code: "DASKI_CDP_SDK_MISSING",
37
+ message: "The CDP signer requires @coinbase/cdp-sdk, which is not installed.",
38
+ remediation: `Run: npm install @coinbase/cdp-sdk — then see ${DOC}`,
39
+ });
40
+ }
41
+ }
42
+ //# sourceMappingURL=cdp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cdp.js","sourceRoot":"","sources":["../../src/signers/cdp.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,MAAM,GAAG,GAAG,iEAAiE,CAAC;AAY9E,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,UAA4B,EAAE;IAClE,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;IACrE,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,MAAM,IAAI,QAAQ,CAAC;YACjB,IAAI,EAAE,yBAAyB;YAC/B,OAAO,EAAE,kDAAkD;YAC3D,WAAW,EAAE,qDAAqD,GAAG,EAAE;SACxE,CAAC,CAAC;IACL,CAAC;IACD,MAAM,GAAG,GAAG,MAAM,SAAS,EAAE,CAAC;IAC9B,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,SAAS,EAAE,CAAC;IACnC,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,kBAAkB,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAmB,CAAC;IAC7F,OAAO;QACL,UAAU,EAAE,KAAK,IAAI,EAAE,CAAC,OAAO,CAAC,OAAO;QACvC,aAAa,EAAE,CAAC,OAAyB,EAAE,EAAE,CAAC,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC;QAC5E,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC;YACf,QAAQ,EAAE,KAAK;YACf,6EAA6E;YAC7E,WAAW,EAAE,SAAS;YACtB,WAAW,EAAE,+BAA+B;SAC7C,CAAC;KACH,CAAC;AACJ,CAAC;AAQD;;;GAGG;AACH,KAAK,UAAU,SAAS;IACtB,IAAI,CAAC;QACH,OAAO,CAAC,MAAM,MAAM,CAAC,mBAA6B,CAAC,CAAc,CAAC;IACpE,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,QAAQ,CAAC;YACjB,IAAI,EAAE,uBAAuB;YAC7B,OAAO,EAAE,oEAAoE;YAC7E,WAAW,EAAE,iDAAiD,GAAG,EAAE;SACpE,CAAC,CAAC;IACL,CAAC;AACH,CAAC"}
@@ -0,0 +1,53 @@
1
+ import type { SignerAdapter, TypedDataRequest } from "@daski/x402-scheme";
2
+ /** The slice of a Circle wallet record the adapter reads. */
3
+ export interface CircleWallet {
4
+ address: string;
5
+ /** `"EOA"` or `"SCA"`. */
6
+ accountType: string;
7
+ blockchain?: string;
8
+ }
9
+ /** The slice of the Circle client the adapter uses. */
10
+ export interface CircleClient {
11
+ getWallet(input: {
12
+ id: string;
13
+ }): Promise<{
14
+ data?: {
15
+ wallet: CircleWallet;
16
+ } | undefined;
17
+ }>;
18
+ signTypedData(input: {
19
+ walletId: string;
20
+ data: string;
21
+ memo?: string;
22
+ }): Promise<{
23
+ data?: {
24
+ signature: string;
25
+ } | undefined;
26
+ }>;
27
+ }
28
+ /** The slice of `@circle-fin/developer-controlled-wallets` the adapter imports. */
29
+ export interface CircleModule {
30
+ initiateDeveloperControlledWalletsClient(config: {
31
+ apiKey: string;
32
+ entitySecret: string;
33
+ }): CircleClient;
34
+ }
35
+ export interface CircleSignerOptions {
36
+ /** Circle wallet id; defaults to `$DASKI_CIRCLE_WALLET`. */
37
+ wallet?: string | undefined;
38
+ /**
39
+ * The SDK module, or a loader for it. Defaults to a dynamic import of the
40
+ * real package; injectable so unit tests can run without installing it.
41
+ */
42
+ sdk?: CircleModule | (() => Promise<CircleModule>) | undefined;
43
+ }
44
+ export declare function createCircleSigner(options?: CircleSignerOptions): Promise<SignerAdapter>;
45
+ /**
46
+ * Exactly the request the validator produced — domain, types, primaryType,
47
+ * message — as the JSON string Circle's `signTypedData` takes. `uint256`
48
+ * values arrive as bigints, which JSON cannot carry, so they go out as decimal
49
+ * strings: the same wire form the authorization itself uses. `EIP712Domain` is
50
+ * not added to `types`; it is derived from `domain`, as the validator does.
51
+ */
52
+ export declare function serializeTypedData(payload: TypedDataRequest): string;
53
+ //# sourceMappingURL=circle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"circle.d.ts","sourceRoot":"","sources":["../../src/signers/circle.ts"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAM1E,6DAA6D;AAC7D,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,0BAA0B;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,uDAAuD;AACvD,MAAM,WAAW,YAAY;IAC3B,SAAS,CAAC,KAAK,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,IAAI,CAAC,EAAE;YAAE,MAAM,EAAE,YAAY,CAAA;SAAE,GAAG,SAAS,CAAA;KAAE,CAAC,CAAC;IAC3F,aAAa,CAAC,KAAK,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QAC/E,IAAI,CAAC,EAAE;YAAE,SAAS,EAAE,MAAM,CAAA;SAAE,GAAG,SAAS,CAAC;KAC1C,CAAC,CAAC;CACJ;AAED,mFAAmF;AACnF,MAAM,WAAW,YAAY;IAC3B,wCAAwC,CAAC,MAAM,EAAE;QAC/C,MAAM,EAAE,MAAM,CAAC;QACf,YAAY,EAAE,MAAM,CAAC;KACtB,GAAG,YAAY,CAAC;CAClB;AAED,MAAM,WAAW,mBAAmB;IAClC,4DAA4D;IAC5D,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B;;;OAGG;IACH,GAAG,CAAC,EAAE,YAAY,GAAG,CAAC,MAAM,OAAO,CAAC,YAAY,CAAC,CAAC,GAAG,SAAS,CAAC;CAChE;AAED,wBAAsB,kBAAkB,CAAC,OAAO,GAAE,mBAAwB,GAAG,OAAO,CAAC,aAAa,CAAC,CA+ElG;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,gBAAgB,GAAG,MAAM,CAMpE"}