@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.
- package/LICENSE +21 -0
- package/README.md +102 -0
- package/dist/bin/daski.d.ts +3 -0
- package/dist/bin/daski.d.ts.map +1 -0
- package/dist/bin/daski.js +187 -0
- package/dist/bin/daski.js.map +1 -0
- package/dist/cli/args.d.ts +11 -0
- package/dist/cli/args.d.ts.map +1 -0
- package/dist/cli/args.js +82 -0
- package/dist/cli/args.js.map +1 -0
- package/dist/cli/errors.d.ts +24 -0
- package/dist/cli/errors.d.ts.map +1 -0
- package/dist/cli/errors.js +23 -0
- package/dist/cli/errors.js.map +1 -0
- package/dist/cli/output.d.ts +8 -0
- package/dist/cli/output.d.ts.map +1 -0
- package/dist/cli/output.js +76 -0
- package/dist/cli/output.js.map +1 -0
- package/dist/cli/prompt.d.ts +12 -0
- package/dist/cli/prompt.d.ts.map +1 -0
- package/dist/cli/prompt.js +101 -0
- package/dist/cli/prompt.js.map +1 -0
- package/dist/cli/redact.d.ts +26 -0
- package/dist/cli/redact.d.ts.map +1 -0
- package/dist/cli/redact.js +55 -0
- package/dist/cli/redact.js.map +1 -0
- package/dist/commands/buy.d.ts +15 -0
- package/dist/commands/buy.d.ts.map +1 -0
- package/dist/commands/buy.js +276 -0
- package/dist/commands/buy.js.map +1 -0
- package/dist/commands/doctor.d.ts +29 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +173 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/order.d.ts +18 -0
- package/dist/commands/order.d.ts.map +1 -0
- package/dist/commands/order.js +256 -0
- package/dist/commands/order.js.map +1 -0
- package/dist/commands/signPayment.d.ts +10 -0
- package/dist/commands/signPayment.d.ts.map +1 -0
- package/dist/commands/signPayment.js +162 -0
- package/dist/commands/signPayment.js.map +1 -0
- package/dist/commands/wallet.d.ts +11 -0
- package/dist/commands/wallet.d.ts.map +1 -0
- package/dist/commands/wallet.js +104 -0
- package/dist/commands/wallet.js.map +1 -0
- package/dist/config.d.ts +64 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +200 -0
- package/dist/config.js.map +1 -0
- package/dist/context.d.ts +36 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +54 -0
- package/dist/context.js.map +1 -0
- package/dist/gateway/balance.d.ts +16 -0
- package/dist/gateway/balance.d.ts.map +1 -0
- package/dist/gateway/balance.js +23 -0
- package/dist/gateway/balance.js.map +1 -0
- package/dist/gateway/catalog.d.ts +49 -0
- package/dist/gateway/catalog.d.ts.map +1 -0
- package/dist/gateway/catalog.js +161 -0
- package/dist/gateway/catalog.js.map +1 -0
- package/dist/gateway/client.d.ts +80 -0
- package/dist/gateway/client.d.ts.map +1 -0
- package/dist/gateway/client.js +128 -0
- package/dist/gateway/client.js.map +1 -0
- package/dist/gateway/lifecycle.d.ts +45 -0
- package/dist/gateway/lifecycle.d.ts.map +1 -0
- package/dist/gateway/lifecycle.js +96 -0
- package/dist/gateway/lifecycle.js.map +1 -0
- package/dist/gateway/purchase.d.ts +119 -0
- package/dist/gateway/purchase.d.ts.map +1 -0
- package/dist/gateway/purchase.js +250 -0
- package/dist/gateway/purchase.js.map +1 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -0
- package/dist/paths.d.ts +6 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +11 -0
- package/dist/paths.js.map +1 -0
- package/dist/signers/cdp.d.ts +7 -0
- package/dist/signers/cdp.d.ts.map +1 -0
- package/dist/signers/cdp.js +42 -0
- package/dist/signers/cdp.js.map +1 -0
- package/dist/signers/circle.d.ts +53 -0
- package/dist/signers/circle.d.ts.map +1 -0
- package/dist/signers/circle.js +136 -0
- package/dist/signers/circle.js.map +1 -0
- package/dist/signers/index.d.ts +23 -0
- package/dist/signers/index.d.ts.map +1 -0
- package/dist/signers/index.js +22 -0
- package/dist/signers/index.js.map +1 -0
- package/dist/signers/local.d.ts +3 -0
- package/dist/signers/local.d.ts.map +1 -0
- package/dist/signers/local.js +24 -0
- package/dist/signers/local.js.map +1 -0
- package/dist/signers/selfTest.d.ts +46 -0
- package/dist/signers/selfTest.d.ts.map +1 -0
- package/dist/signers/selfTest.js +113 -0
- package/dist/signers/selfTest.js.map +1 -0
- package/dist/store/keystore.d.ts +19 -0
- package/dist/store/keystore.d.ts.map +1 -0
- package/dist/store/keystore.js +226 -0
- package/dist/store/keystore.js.map +1 -0
- package/dist/store/orders.d.ts +39 -0
- package/dist/store/orders.d.ts.map +1 -0
- package/dist/store/orders.js +91 -0
- package/dist/store/orders.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +21 -0
- package/dist/version.js.map +1 -0
- package/package.json +59 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interactive prompts.
|
|
3
|
+
*
|
|
4
|
+
* Two rules the CLI never bends: a non-TTY session cannot answer a human
|
|
5
|
+
* question, and refusing is always the safe default. Every prompt here fails
|
|
6
|
+
* closed.
|
|
7
|
+
*/
|
|
8
|
+
import { createInterface } from "node:readline/promises";
|
|
9
|
+
import { CliError } from "./errors.js";
|
|
10
|
+
const ETX = String.fromCharCode(3); // Ctrl-C
|
|
11
|
+
const BACKSPACE = String.fromCharCode(127);
|
|
12
|
+
const BS = String.fromCharCode(8);
|
|
13
|
+
export function isInteractive() {
|
|
14
|
+
return Boolean(process.stdin.isTTY && process.stdout.isTTY);
|
|
15
|
+
}
|
|
16
|
+
/** Asks a yes/no question. Anything but an explicit yes is a no. */
|
|
17
|
+
export async function confirm(question) {
|
|
18
|
+
if (!isInteractive())
|
|
19
|
+
return false;
|
|
20
|
+
const rl = createInterface({ input: process.stdin, output: process.stderr });
|
|
21
|
+
try {
|
|
22
|
+
const answer = await rl.question(`${question} [y/N] `);
|
|
23
|
+
return /^y(es)?$/i.test(answer.trim());
|
|
24
|
+
}
|
|
25
|
+
finally {
|
|
26
|
+
rl.close();
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/** Requires the operator to retype an exact phrase. Used for key creation. */
|
|
30
|
+
export async function confirmPhrase(question, phrase) {
|
|
31
|
+
if (!isInteractive())
|
|
32
|
+
return false;
|
|
33
|
+
const rl = createInterface({ input: process.stdin, output: process.stderr });
|
|
34
|
+
try {
|
|
35
|
+
const answer = await rl.question(`${question}\nType "${phrase}" to continue: `);
|
|
36
|
+
return answer.trim() === phrase;
|
|
37
|
+
}
|
|
38
|
+
finally {
|
|
39
|
+
rl.close();
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Reads a passphrase without echoing it. The typed characters are never
|
|
44
|
+
* written back to the terminal and never leave this function except as the
|
|
45
|
+
* return value.
|
|
46
|
+
*/
|
|
47
|
+
export async function readPassphrase(prompt) {
|
|
48
|
+
if (!isInteractive()) {
|
|
49
|
+
throw new CliError({
|
|
50
|
+
code: "DASKI_PASSPHRASE_REQUIRES_TTY",
|
|
51
|
+
message: "A passphrase is required, but this session has no terminal.",
|
|
52
|
+
remediation: "Run the command from an interactive terminal, or configure an OS " +
|
|
53
|
+
"keychain so no passphrase is needed.",
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
process.stderr.write(prompt);
|
|
57
|
+
const stdin = process.stdin;
|
|
58
|
+
const wasRaw = stdin.isRaw ?? false;
|
|
59
|
+
stdin.setRawMode(true);
|
|
60
|
+
stdin.resume();
|
|
61
|
+
try {
|
|
62
|
+
return await new Promise((resolve, reject) => {
|
|
63
|
+
let value = "";
|
|
64
|
+
const cleanup = () => {
|
|
65
|
+
stdin.removeListener("data", onData);
|
|
66
|
+
stdin.setRawMode(wasRaw);
|
|
67
|
+
stdin.pause();
|
|
68
|
+
};
|
|
69
|
+
const onData = (chunk) => {
|
|
70
|
+
for (const char of chunk.toString("utf8")) {
|
|
71
|
+
if (char === "\r" || char === "\n") {
|
|
72
|
+
cleanup();
|
|
73
|
+
process.stderr.write("\n");
|
|
74
|
+
resolve(value);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
if (char === ETX) {
|
|
78
|
+
cleanup();
|
|
79
|
+
process.stderr.write("\n");
|
|
80
|
+
reject(new CliError({
|
|
81
|
+
code: "DASKI_PASSPHRASE_CANCELLED",
|
|
82
|
+
message: "Passphrase entry cancelled.",
|
|
83
|
+
remediation: "Re-run the command when ready.",
|
|
84
|
+
}));
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
if (char === BACKSPACE || char === BS) {
|
|
88
|
+
value = value.slice(0, -1);
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
value += char;
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
stdin.on("data", onData);
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
finally {
|
|
98
|
+
stdin.setRawMode(wasRaw);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=prompt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../src/cli/prompt.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A last line of defence on the way out.
|
|
3
|
+
*
|
|
4
|
+
* Keys are never *supposed* to reach output — no code path passes one to a
|
|
5
|
+
* printer — but "supposed to" is not a guarantee, and a leaked key is
|
|
6
|
+
* unrecoverable. Everything the CLI prints goes through here first.
|
|
7
|
+
*
|
|
8
|
+
* What this deliberately does **not** do is redact by hex shape. A 32-byte
|
|
9
|
+
* private key and a 32-byte hash are the same shape, and this CLI's whole job
|
|
10
|
+
* involves printing hashes: authorization nonces, request hashes, order keys.
|
|
11
|
+
* Blanking them all would corrupt the tool's own output — an operator could no
|
|
12
|
+
* longer check the nonce their wallet signed — while an attacker who can
|
|
13
|
+
* already get a key into a printed field can trivially reshape it.
|
|
14
|
+
*
|
|
15
|
+
* So the signals used here are the ones that actually discriminate: the field
|
|
16
|
+
* name a value arrived under, and the unmistakable shape of a seed phrase.
|
|
17
|
+
*/
|
|
18
|
+
export interface RedactOptions {
|
|
19
|
+
/** Also blank signatures. Optional for run logs; keys are never optional. */
|
|
20
|
+
signatures?: boolean;
|
|
21
|
+
/** Internal: the field name the current value was found under. */
|
|
22
|
+
fieldName?: string | undefined;
|
|
23
|
+
}
|
|
24
|
+
export declare function redactValue(value: unknown, options?: RedactOptions): unknown;
|
|
25
|
+
export declare function redactText(text: string): string;
|
|
26
|
+
//# sourceMappingURL=redact.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redact.d.ts","sourceRoot":"","sources":["../../src/cli/redact.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAqBH,MAAM,WAAW,aAAa;IAC5B,6EAA6E;IAC7E,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,kEAAkE;IAClE,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAChC;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,GAAE,aAAkB,GAAG,OAAO,CAgBhF;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE/C"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A last line of defence on the way out.
|
|
3
|
+
*
|
|
4
|
+
* Keys are never *supposed* to reach output — no code path passes one to a
|
|
5
|
+
* printer — but "supposed to" is not a guarantee, and a leaked key is
|
|
6
|
+
* unrecoverable. Everything the CLI prints goes through here first.
|
|
7
|
+
*
|
|
8
|
+
* What this deliberately does **not** do is redact by hex shape. A 32-byte
|
|
9
|
+
* private key and a 32-byte hash are the same shape, and this CLI's whole job
|
|
10
|
+
* involves printing hashes: authorization nonces, request hashes, order keys.
|
|
11
|
+
* Blanking them all would corrupt the tool's own output — an operator could no
|
|
12
|
+
* longer check the nonce their wallet signed — while an attacker who can
|
|
13
|
+
* already get a key into a printed field can trivially reshape it.
|
|
14
|
+
*
|
|
15
|
+
* So the signals used here are the ones that actually discriminate: the field
|
|
16
|
+
* name a value arrived under, and the unmistakable shape of a seed phrase.
|
|
17
|
+
*/
|
|
18
|
+
/** BIP-39 style phrases: twelve or more lowercase words in a row. */
|
|
19
|
+
const MNEMONIC_PATTERN = /\b(?:[a-z]{3,8}\s+){11,23}[a-z]{3,8}\b/g;
|
|
20
|
+
/**
|
|
21
|
+
* Field names whose contents are secret whatever they look like.
|
|
22
|
+
*
|
|
23
|
+
* Kept narrow on purpose. `authorization` and `token` are *not* here: in this
|
|
24
|
+
* domain an "authorization" is the EIP-3009 transfer authorization that
|
|
25
|
+
* `daski sign-payment` exists to print, and a "token" is an ERC-20 contract
|
|
26
|
+
* address. Redacting a field because its name sounds sensitive elsewhere
|
|
27
|
+
* would blank the tool's own output while protecting nothing.
|
|
28
|
+
*/
|
|
29
|
+
const KEYLIKE_FIELDS = new Set([
|
|
30
|
+
"privatekey", "private_key", "privkey", "secret", "secretkey", "secret_key",
|
|
31
|
+
"mnemonic", "seed", "seedphrase", "seed_phrase", "passphrase", "password",
|
|
32
|
+
"keystore", "keymaterial", "key_material", "daski_payer_private_key",
|
|
33
|
+
"apikey", "api_key",
|
|
34
|
+
]);
|
|
35
|
+
export function redactValue(value, options = {}) {
|
|
36
|
+
const { fieldName } = options;
|
|
37
|
+
if (fieldName && KEYLIKE_FIELDS.has(fieldName.toLowerCase()))
|
|
38
|
+
return "[redacted]";
|
|
39
|
+
if (options.signatures && fieldName?.toLowerCase() === "signature")
|
|
40
|
+
return "[redacted]";
|
|
41
|
+
if (typeof value === "string")
|
|
42
|
+
return value.replace(MNEMONIC_PATTERN, "[redacted]");
|
|
43
|
+
if (Array.isArray(value)) {
|
|
44
|
+
return value.map((item) => redactValue(item, { ...options, fieldName: undefined }));
|
|
45
|
+
}
|
|
46
|
+
if (value && typeof value === "object") {
|
|
47
|
+
return Object.fromEntries(Object.entries(value)
|
|
48
|
+
.map(([key, item]) => [key, redactValue(item, { ...options, fieldName: key })]));
|
|
49
|
+
}
|
|
50
|
+
return value;
|
|
51
|
+
}
|
|
52
|
+
export function redactText(text) {
|
|
53
|
+
return String(redactValue(text));
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=redact.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redact.js","sourceRoot":"","sources":["../../src/cli/redact.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,qEAAqE;AACrE,MAAM,gBAAgB,GAAG,yCAAyC,CAAC;AAEnE;;;;;;;;GAQG;AACH,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC;IAC7B,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW,EAAE,YAAY;IAC3E,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,UAAU;IACzE,UAAU,EAAE,aAAa,EAAE,cAAc,EAAE,yBAAyB;IACpE,QAAQ,EAAE,SAAS;CACpB,CAAC,CAAC;AASH,MAAM,UAAU,WAAW,CAAC,KAAc,EAAE,UAAyB,EAAE;IACrE,MAAM,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC;IAC9B,IAAI,SAAS,IAAI,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC;QAAE,OAAO,YAAY,CAAC;IAClF,IAAI,OAAO,CAAC,UAAU,IAAI,SAAS,EAAE,WAAW,EAAE,KAAK,WAAW;QAAE,OAAO,YAAY,CAAC;IAExF,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC,OAAO,CAAC,gBAAgB,EAAE,YAAY,CAAC,CAAC;IACpF,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,WAAW,CAAC,IAAI,EAAE,EAAE,GAAG,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC;IACtF,CAAC;IACD,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvC,OAAO,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,OAAO,CAAC,KAAgC,CAAC;aAC7C,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,WAAW,CAAC,IAAI,EAAE,EAAE,GAAG,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAClF,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,OAAO,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC;AACnC,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { PolicyRefusal } from "@daski/x402-scheme";
|
|
2
|
+
import { type ContextOptions } from "../context.js";
|
|
3
|
+
export interface BuyOptions extends ContextOptions {
|
|
4
|
+
providerAgentId: string;
|
|
5
|
+
outcomeId: string;
|
|
6
|
+
requestFile: string;
|
|
7
|
+
payer?: string | undefined;
|
|
8
|
+
json: boolean;
|
|
9
|
+
legacyArg?: boolean;
|
|
10
|
+
/** Skips only the interactive prompt, never the policy validator. */
|
|
11
|
+
yes?: boolean;
|
|
12
|
+
}
|
|
13
|
+
export declare function runBuy(options: BuyOptions): Promise<Record<string, unknown>>;
|
|
14
|
+
export { PolicyRefusal };
|
|
15
|
+
//# sourceMappingURL=buy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buy.d.ts","sourceRoot":"","sources":["../../src/commands/buy.ts"],"names":[],"mappings":"AAQA,OAAO,EAAc,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAK/D,OAAO,EAAiB,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AAYnE,MAAM,WAAW,UAAW,SAAQ,cAAc;IAChD,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,IAAI,EAAE,OAAO,CAAC;IACd,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,qEAAqE;IACrE,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAQD,wBAAsB,MAAM,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAgJlF;AAsID,OAAO,EAAE,aAAa,EAAE,CAAC"}
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `daski buy` — the full purchase.
|
|
3
|
+
*
|
|
4
|
+
* The seven steps of §2, in order, with the approval gate between the quote
|
|
5
|
+
* and the signature and the reconciliation gate between an ambiguous outcome
|
|
6
|
+
* and any re-sign.
|
|
7
|
+
*/
|
|
8
|
+
import { readFileSync } from "node:fs";
|
|
9
|
+
import { formatUsdc, PolicyRefusal } from "@daski/x402-scheme";
|
|
10
|
+
import { CliError } from "../cli/errors.js";
|
|
11
|
+
import { confirm, isInteractive } from "../cli/prompt.js";
|
|
12
|
+
import { note } from "../cli/output.js";
|
|
13
|
+
import { atomicUsdc } from "../config.js";
|
|
14
|
+
import { createContext } from "../context.js";
|
|
15
|
+
import { GatewayClient } from "../gateway/client.js";
|
|
16
|
+
import { authorizePayment, newIntentId, reconcileAmbiguousPurchase, recordIntent, requestChallenge, submitPayment, } from "../gateway/purchase.js";
|
|
17
|
+
import { updateOrder } from "../store/orders.js";
|
|
18
|
+
/** Gateway states that mean "authorized, outcome unknown" rather than "failed". */
|
|
19
|
+
const AMBIGUOUS_CODES = new Set([
|
|
20
|
+
"PAYMENT_PENDING_RECONCILIATION",
|
|
21
|
+
"PAYMENT_OUTCOME_PENDING",
|
|
22
|
+
]);
|
|
23
|
+
export async function runBuy(options) {
|
|
24
|
+
const request = readRequestFile(options.requestFile);
|
|
25
|
+
const context = await createContext(options);
|
|
26
|
+
try {
|
|
27
|
+
if (options.payer && options.payer.toLowerCase() !== context.payerAddress.toLowerCase()) {
|
|
28
|
+
throw new CliError({
|
|
29
|
+
code: "DASKI_PAYER_NOT_THIS_SIGNER",
|
|
30
|
+
message: `--payer ${options.payer} is not the address this profile signs with ` +
|
|
31
|
+
`(${context.payerAddress}).`,
|
|
32
|
+
remediation: "The bridge can only authorize payments from the key it holds. Switch " +
|
|
33
|
+
"profiles, or drop --payer.",
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
// -- 1. challenge ------------------------------------------------------
|
|
37
|
+
const challenge = await requestChallenge({
|
|
38
|
+
client: context.client,
|
|
39
|
+
providerAgentId: options.providerAgentId,
|
|
40
|
+
outcomeId: options.outcomeId,
|
|
41
|
+
request,
|
|
42
|
+
payerAddress: context.payerAddress,
|
|
43
|
+
});
|
|
44
|
+
const amountAtomic = BigInt(challenge.requirement.amount);
|
|
45
|
+
// -- 2. approval -------------------------------------------------------
|
|
46
|
+
const outcome = await context.catalog.getOutcome(options.providerAgentId, options.outcomeId);
|
|
47
|
+
const summary = approvalSummary(challenge.challenge.extensions, outcome, amountAtomic);
|
|
48
|
+
const threshold = atomicUsdc(context.profile.requireApprovalAboveUsdc);
|
|
49
|
+
if (amountAtomic > threshold && !options.yes) {
|
|
50
|
+
if (options.json || !isInteractive()) {
|
|
51
|
+
throw new CliError({
|
|
52
|
+
code: "DASKI_HUMAN_APPROVAL_REQUIRED",
|
|
53
|
+
message: `${formatUsdc(amountAtomic)} is above this profile's ` +
|
|
54
|
+
`requireApprovalAboveUsdc of ${context.profile.requireApprovalAboveUsdc} USDC, ` +
|
|
55
|
+
"and this session cannot ask a human.",
|
|
56
|
+
remediation: "Have a human run this command in an interactive terminal and confirm " +
|
|
57
|
+
"the prompt, or — if a human has already approved this exact purchase " +
|
|
58
|
+
"— re-run with --yes. Raising the threshold is a manual config edit.",
|
|
59
|
+
details: { approvalSummary: summary, priceUsdc: formatUsdc(amountAtomic) },
|
|
60
|
+
exitCode: 2,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
note(renderApproval(summary, amountAtomic));
|
|
64
|
+
if (!await confirm("Authorize this payment?")) {
|
|
65
|
+
throw new CliError({
|
|
66
|
+
code: "DASKI_PURCHASE_DECLINED",
|
|
67
|
+
message: "The purchase was not approved.",
|
|
68
|
+
remediation: "Nothing was signed and no money moved. Re-run when ready.",
|
|
69
|
+
exitCode: 2,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
// -- 3 & 4. validate, recompute, sign ----------------------------------
|
|
74
|
+
const intentId = newIntentId();
|
|
75
|
+
// Recorded before the signature so an interruption is recoverable.
|
|
76
|
+
recordIntent({
|
|
77
|
+
intentId,
|
|
78
|
+
profile: context.profileName,
|
|
79
|
+
providerAgentId: options.providerAgentId,
|
|
80
|
+
outcomeId: options.outcomeId,
|
|
81
|
+
payer: context.payerAddress,
|
|
82
|
+
amount: amountAtomic.toString(),
|
|
83
|
+
state: "INTENT_RECORDED",
|
|
84
|
+
request,
|
|
85
|
+
});
|
|
86
|
+
const authorized = await authorizePayment({
|
|
87
|
+
policy: context.policy,
|
|
88
|
+
signer: context.signer,
|
|
89
|
+
challenge,
|
|
90
|
+
providerAgentId: options.providerAgentId,
|
|
91
|
+
outcomeId: options.outcomeId,
|
|
92
|
+
approvedQuoteAtomic: amountAtomic,
|
|
93
|
+
intentId,
|
|
94
|
+
});
|
|
95
|
+
updateOrder(intentId, {
|
|
96
|
+
state: "AUTHORIZED",
|
|
97
|
+
authorizationNonce: authorized.nonce,
|
|
98
|
+
});
|
|
99
|
+
// -- 5. paid retry -----------------------------------------------------
|
|
100
|
+
let result;
|
|
101
|
+
try {
|
|
102
|
+
result = await submitPayment({
|
|
103
|
+
client: context.client,
|
|
104
|
+
providerAgentId: options.providerAgentId,
|
|
105
|
+
outcomeId: options.outcomeId,
|
|
106
|
+
request,
|
|
107
|
+
submission: authorized.submission,
|
|
108
|
+
...(options.legacyArg === undefined ? {} : { legacyArg: options.legacyArg }),
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
// The signature left the process and the answer did not come back. This
|
|
113
|
+
// is the ambiguous case: reconcile, never re-sign.
|
|
114
|
+
return await reconcile(context, {
|
|
115
|
+
intentId, options, request, authorized,
|
|
116
|
+
cause: `transport failure after submit: ${error.message}`,
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
const body = GatewayClient.json(result);
|
|
120
|
+
const code = typeof body?.code === "string" ? body.code : undefined;
|
|
121
|
+
if (result.isError && code && AMBIGUOUS_CODES.has(code)) {
|
|
122
|
+
return await reconcile(context, {
|
|
123
|
+
intentId, options, request, authorized,
|
|
124
|
+
cause: `gateway reported ${code}`,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
if (result.isError || !body || typeof body.orderHandle !== "string") {
|
|
128
|
+
updateOrder(intentId, { state: "PENDING_RECONCILIATION" });
|
|
129
|
+
const { purchaseFailure } = await import("../gateway/purchase.js");
|
|
130
|
+
throw purchaseFailure(result);
|
|
131
|
+
}
|
|
132
|
+
// -- 6 & 7. persist and report ----------------------------------------
|
|
133
|
+
const record = updateOrder(intentId, {
|
|
134
|
+
handle: body.orderHandle,
|
|
135
|
+
state: normalizeState(body.status),
|
|
136
|
+
});
|
|
137
|
+
return {
|
|
138
|
+
purchased: true,
|
|
139
|
+
orderHandle: body.orderHandle,
|
|
140
|
+
intentId,
|
|
141
|
+
profile: context.profileName,
|
|
142
|
+
provider: options.providerAgentId,
|
|
143
|
+
outcome: options.outcomeId,
|
|
144
|
+
price: formatUsdc(amountAtomic),
|
|
145
|
+
state: record?.state ?? String(body.status ?? "unknown"),
|
|
146
|
+
payer: context.payerAddress,
|
|
147
|
+
authorizationNonce: authorized.nonce,
|
|
148
|
+
challengeSource: challenge.viaChallengeTool
|
|
149
|
+
? "daski_get_payment_challenge"
|
|
150
|
+
: "daski_buy_outcome (unpaid challenge fallback)",
|
|
151
|
+
receipt: body.receipt ?? null,
|
|
152
|
+
gatewayCalls: context.client.callCount,
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
finally {
|
|
156
|
+
await context.close();
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
async function reconcile(context, args) {
|
|
160
|
+
updateOrder(args.intentId, { state: "PENDING_RECONCILIATION" });
|
|
161
|
+
note(`payment outcome unclear (${args.cause}); reconciling before any re-sign...`);
|
|
162
|
+
const record = updateOrder(args.intentId, {});
|
|
163
|
+
const outcome = await reconcileAmbiguousPurchase({
|
|
164
|
+
client: context.client,
|
|
165
|
+
signer: context.signer,
|
|
166
|
+
record,
|
|
167
|
+
payer: context.payerAddress,
|
|
168
|
+
chainId: context.profile.chainId,
|
|
169
|
+
gatewayUrl: context.profile.gatewayUrl,
|
|
170
|
+
submission: args.authorized.submission,
|
|
171
|
+
request: args.request,
|
|
172
|
+
...(args.options.legacyArg === undefined ? {} : { legacyArg: args.options.legacyArg }),
|
|
173
|
+
});
|
|
174
|
+
if (outcome.status === "settled") {
|
|
175
|
+
const settled = updateOrder(args.intentId, {
|
|
176
|
+
handle: outcome.orderHandle,
|
|
177
|
+
state: normalizeState(outcome.body?.status),
|
|
178
|
+
});
|
|
179
|
+
return {
|
|
180
|
+
purchased: true,
|
|
181
|
+
recovered: true,
|
|
182
|
+
orderHandle: outcome.orderHandle,
|
|
183
|
+
intentId: args.intentId,
|
|
184
|
+
state: settled?.state ?? "unknown",
|
|
185
|
+
price: formatUsdc(BigInt(record.amount)),
|
|
186
|
+
reconciliation: outcome.evidence,
|
|
187
|
+
cause: args.cause,
|
|
188
|
+
gatewayCalls: context.client.callCount,
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
// Provably absent: the caller may safely start over with a fresh challenge.
|
|
192
|
+
throw new CliError({
|
|
193
|
+
code: "DASKI_PAYMENT_UNRESOLVED_NO_ORDER",
|
|
194
|
+
message: `The purchase was interrupted (${args.cause}) and no order exists for it: ` +
|
|
195
|
+
`${outcome.evidence}.`,
|
|
196
|
+
remediation: "Nothing settled, so a fresh purchase is safe: re-run the same `daski buy` " +
|
|
197
|
+
`command. The unsettled intent is recorded as ${args.intentId}.`,
|
|
198
|
+
details: { intentId: args.intentId, reconciliation: outcome.evidence },
|
|
199
|
+
exitCode: 3,
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
function normalizeState(status) {
|
|
203
|
+
const value = String(status ?? "").toLowerCase();
|
|
204
|
+
if (["completed", "fulfilled"].includes(value))
|
|
205
|
+
return "FULFILLED";
|
|
206
|
+
if (["input-required", "input_required"].includes(value))
|
|
207
|
+
return "INPUT_REQUIRED";
|
|
208
|
+
if (["failed", "canceled", "provider_failed"].includes(value))
|
|
209
|
+
return "PROVIDER_FAILED";
|
|
210
|
+
return "SUBMITTED";
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* The human-facing summary. Prefers the gateway's `approvalSummary` when it
|
|
214
|
+
* ships one; otherwise it is assembled from the order terms and the catalog,
|
|
215
|
+
* so the operator sees who is being paid and under whose terms either way.
|
|
216
|
+
*/
|
|
217
|
+
function approvalSummary(extensions, outcome, amountAtomic) {
|
|
218
|
+
const supplied = extensions?.approvalSummary;
|
|
219
|
+
if (supplied && typeof supplied === "object")
|
|
220
|
+
return supplied;
|
|
221
|
+
const terms = extensions?.["daski-order-terms"];
|
|
222
|
+
return {
|
|
223
|
+
what: [outcome.serviceName, outcome.skillName].filter(Boolean).join(" / ") || "Daski outcome",
|
|
224
|
+
price: formatUsdc(amountAtomic),
|
|
225
|
+
paysTo: outcome.payTo,
|
|
226
|
+
provider: terms?.providerLegalName ?? outcome.providerAudience ?? "unknown",
|
|
227
|
+
commissionBps: terms?.commissionBps ?? outcome.commissionBps ?? null,
|
|
228
|
+
providerTerms: terms?.providerTermsUrl ?? null,
|
|
229
|
+
marketplaceTerms: terms?.marketplaceTermsUrl ?? null,
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
function renderApproval(summary, amountAtomic) {
|
|
233
|
+
const lines = ["", " ─ Purchase approval ─────────────────────────────"];
|
|
234
|
+
for (const [key, value] of Object.entries(summary)) {
|
|
235
|
+
if (value === null || value === undefined)
|
|
236
|
+
continue;
|
|
237
|
+
lines.push(` ${key.padEnd(18)} ${String(value)}`);
|
|
238
|
+
}
|
|
239
|
+
lines.push(` ${"you will pay".padEnd(18)} ${formatUsdc(amountAtomic)}`);
|
|
240
|
+
lines.push(" ─────────────────────────────────────────────────", "");
|
|
241
|
+
return lines.join("\n");
|
|
242
|
+
}
|
|
243
|
+
function readRequestFile(path) {
|
|
244
|
+
let raw;
|
|
245
|
+
try {
|
|
246
|
+
raw = readFileSync(path, "utf8");
|
|
247
|
+
}
|
|
248
|
+
catch (error) {
|
|
249
|
+
throw new CliError({
|
|
250
|
+
code: "DASKI_REQUEST_FILE_UNREADABLE",
|
|
251
|
+
message: `Could not read the request file ${path}: ${error.message}`,
|
|
252
|
+
remediation: "Pass --request with a path to a JSON file containing the outcome's request body.",
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
let parsed;
|
|
256
|
+
try {
|
|
257
|
+
parsed = JSON.parse(raw);
|
|
258
|
+
}
|
|
259
|
+
catch (error) {
|
|
260
|
+
throw new CliError({
|
|
261
|
+
code: "DASKI_REQUEST_FILE_NOT_JSON",
|
|
262
|
+
message: `${path} is not valid JSON: ${error.message}`,
|
|
263
|
+
remediation: "Fix the file so it contains a single JSON object.",
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
267
|
+
throw new CliError({
|
|
268
|
+
code: "DASKI_REQUEST_FILE_NOT_OBJECT",
|
|
269
|
+
message: `${path} must contain a JSON object.`,
|
|
270
|
+
remediation: "Wrap the request in an object, e.g. {\"address\": \"...\"}",
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
return parsed;
|
|
274
|
+
}
|
|
275
|
+
export { PolicyRefusal };
|
|
276
|
+
//# sourceMappingURL=buy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buy.js","sourceRoot":"","sources":["../../src/commands/buy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export interface DoctorIssue {
|
|
2
|
+
severity: "blocking" | "warning";
|
|
3
|
+
code: string;
|
|
4
|
+
message: string;
|
|
5
|
+
remediation: string;
|
|
6
|
+
}
|
|
7
|
+
export interface DoctorOptions {
|
|
8
|
+
profile?: string | undefined;
|
|
9
|
+
maxPerOrderUsdc?: string | undefined;
|
|
10
|
+
sessionCapUsdc?: string | undefined;
|
|
11
|
+
signerOverride?: string | undefined;
|
|
12
|
+
cdpAccount?: string | undefined;
|
|
13
|
+
circleWallet?: string | undefined;
|
|
14
|
+
}
|
|
15
|
+
export interface DoctorReport {
|
|
16
|
+
cliVersion: string;
|
|
17
|
+
profile: string;
|
|
18
|
+
stateDirectory: string;
|
|
19
|
+
configFile: string;
|
|
20
|
+
signer: Record<string, unknown>;
|
|
21
|
+
chain: Record<string, unknown>;
|
|
22
|
+
balances: Record<string, unknown> | null;
|
|
23
|
+
caps: Record<string, unknown>;
|
|
24
|
+
gateway: Record<string, unknown>;
|
|
25
|
+
issues: DoctorIssue[];
|
|
26
|
+
ok: boolean;
|
|
27
|
+
}
|
|
28
|
+
export declare function runDoctor(options: DoctorOptions): Promise<DoctorReport>;
|
|
29
|
+
//# sourceMappingURL=doctor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAwBA,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,UAAU,GAAG,SAAS,CAAC;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACnC;AAED,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACzC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,EAAE,EAAE,OAAO,CAAC;CACb;AAED,wBAAsB,SAAS,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC,CAuK7E"}
|