@daski/pay 0.3.1 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -11
- package/dist/bin/daski.js +26 -11
- package/dist/bin/daski.js.map +1 -1
- package/dist/chain/reader.d.ts +92 -0
- package/dist/chain/reader.d.ts.map +1 -0
- package/dist/chain/reader.js +130 -0
- package/dist/chain/reader.js.map +1 -0
- package/dist/commands/approval.js +2 -2
- package/dist/commands/approval.js.map +1 -1
- package/dist/commands/buy.d.ts +0 -1
- package/dist/commands/buy.d.ts.map +1 -1
- package/dist/commands/buy.js +15 -22
- package/dist/commands/buy.js.map +1 -1
- package/dist/commands/confirmation.d.ts +322 -4
- package/dist/commands/confirmation.d.ts.map +1 -1
- package/dist/commands/confirmation.js +771 -60
- package/dist/commands/confirmation.js.map +1 -1
- package/dist/commands/doctor.d.ts +20 -0
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +204 -59
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/order.d.ts +37 -6
- package/dist/commands/order.d.ts.map +1 -1
- package/dist/commands/order.js +181 -103
- package/dist/commands/order.js.map +1 -1
- package/dist/commands/signPayment.d.ts.map +1 -1
- package/dist/commands/signPayment.js +8 -3
- package/dist/commands/signPayment.js.map +1 -1
- package/dist/commands/wallet.d.ts +3 -0
- package/dist/commands/wallet.d.ts.map +1 -1
- package/dist/commands/wallet.js +72 -16
- package/dist/commands/wallet.js.map +1 -1
- package/dist/config.d.ts +10 -2
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +41 -1
- package/dist/config.js.map +1 -1
- package/dist/context.d.ts +28 -3
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +72 -3
- package/dist/context.js.map +1 -1
- package/dist/gateway/client.d.ts +20 -17
- package/dist/gateway/client.d.ts.map +1 -1
- package/dist/gateway/client.js +62 -43
- package/dist/gateway/client.js.map +1 -1
- package/dist/gateway/lifecycle.d.ts +4 -1
- package/dist/gateway/lifecycle.d.ts.map +1 -1
- package/dist/gateway/lifecycle.js +10 -5
- package/dist/gateway/lifecycle.js.map +1 -1
- package/dist/gateway/metadata.d.ts +66 -0
- package/dist/gateway/metadata.d.ts.map +1 -0
- package/dist/gateway/metadata.js +152 -0
- package/dist/gateway/metadata.js.map +1 -0
- package/dist/gateway/purchase.d.ts +51 -67
- package/dist/gateway/purchase.d.ts.map +1 -1
- package/dist/gateway/purchase.js +153 -125
- package/dist/gateway/purchase.js.map +1 -1
- package/dist/host.d.ts +41 -0
- package/dist/host.d.ts.map +1 -0
- package/dist/host.js +112 -0
- package/dist/host.js.map +1 -0
- package/dist/index.d.ts +12 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -4
- package/dist/index.js.map +1 -1
- package/dist/signers/circleAgent.d.ts +37 -0
- package/dist/signers/circleAgent.d.ts.map +1 -0
- package/dist/signers/circleAgent.js +244 -0
- package/dist/signers/circleAgent.js.map +1 -0
- package/dist/signers/contract.d.ts +34 -0
- package/dist/signers/contract.d.ts.map +1 -0
- package/dist/signers/contract.js +47 -0
- package/dist/signers/contract.js.map +1 -0
- package/dist/signers/index.d.ts +16 -7
- package/dist/signers/index.d.ts.map +1 -1
- package/dist/signers/index.js +7 -3
- package/dist/signers/index.js.map +1 -1
- package/dist/signers/local.d.ts +5 -1
- package/dist/signers/local.d.ts.map +1 -1
- package/dist/signers/local.js +16 -3
- package/dist/signers/local.js.map +1 -1
- package/dist/signers/selfTest.d.ts +32 -12
- package/dist/signers/selfTest.d.ts.map +1 -1
- package/dist/signers/selfTest.js +85 -12
- package/dist/signers/selfTest.js.map +1 -1
- package/dist/signers/signature.d.ts +10 -0
- package/dist/signers/signature.d.ts.map +1 -0
- package/dist/signers/signature.js +11 -0
- package/dist/signers/signature.js.map +1 -0
- package/dist/store/keystore.d.ts +48 -6
- package/dist/store/keystore.d.ts.map +1 -1
- package/dist/store/keystore.js +414 -110
- package/dist/store/keystore.js.map +1 -1
- package/dist/store/lock.d.ts +59 -0
- package/dist/store/lock.d.ts.map +1 -0
- package/dist/store/lock.js +269 -0
- package/dist/store/lock.js.map +1 -0
- package/dist/store/orders.d.ts +49 -9
- package/dist/store/orders.d.ts.map +1 -1
- package/dist/store/orders.js +173 -37
- package/dist/store/orders.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -5,11 +5,12 @@ The Daski buyer CLI obtains a quote, validates and signs an approved payment, an
|
|
|
5
5
|
## Setup and purchase
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
npm install -g @daski/pay@0.
|
|
8
|
+
npm install -g @daski/pay@0.4.1
|
|
9
|
+
export DASKI_HOST_CLASS=durable # or ephemeral
|
|
9
10
|
daski doctor --json
|
|
10
11
|
```
|
|
11
12
|
|
|
12
|
-
Doctor reports the configured signer
|
|
13
|
+
Doctor reports the host class, key backend and key durability, the configured signer with its account type, self-test, and deployment, native state paths, network, balances, spending settings, and gateway compatibility including which payer account types the gateway verifies. Reuse a healthy signer. The Circle agent wallet (`--signer circle-agent`) is the default on every host. Create a local wallet only on the user's own durable machine and only when the user asks: `daski wallet create` prompts interactively; authorized agent setup uses `daski wallet create --yes-human-approved` with `DASKI_KEYSTORE_PASSPHRASE_FILE` when there is no terminal. No local key is created on an ephemeral host.
|
|
13
14
|
|
|
14
15
|
Complete the request using gateway discovery and `daski_get_outcome_requirements`, then run:
|
|
15
16
|
|
|
@@ -23,30 +24,36 @@ The command returns the actual quote and an approval identifier. After the user
|
|
|
23
24
|
|
|
24
25
|
| Command | Behavior |
|
|
25
26
|
|---|---|
|
|
26
|
-
| `doctor --json` | Diagnose signer, paths, settings, funds, and gateway |
|
|
27
|
-
| `wallet create` | Create a local signer when missing |
|
|
27
|
+
| `doctor --json` | Diagnose host, key durability, signer, paths, settings, funds, and gateway |
|
|
28
|
+
| `wallet create` | Create a local signer when missing, on a durable host with a local backend |
|
|
28
29
|
| `wallet address` / `wallet balance` | Read the active payer and balances |
|
|
29
30
|
| `budget [--per-order <usdc\|none>] [--total <usdc\|none>] [--approval-above <usdc>]` | View or explicitly change spending settings |
|
|
30
31
|
| `buy --provider <id> --outcome <id> --request <file.json>` | Quote, approve, validate, sign, submit, and record |
|
|
31
|
-
| `order status <handle>` | Read order state using cached read access or a fresh
|
|
32
|
+
| `order status <handle>` | Read the gateway's order state using cached read access or a fresh grant-read capability |
|
|
32
33
|
| `order artifact <handle> [--output <file>]` | Save the provider result to a file |
|
|
33
34
|
| `order input <handle> --request <file.json>` | Submit customer input |
|
|
34
35
|
| `order cancel <handle>` | Request cancellation |
|
|
35
|
-
| `order confirm <handle> --choice <Confirmed\|NotConfirmed
|
|
36
|
-
| `order revoke-confirmation <handle>` | Withdraw the active review |
|
|
37
|
-
| `order confirm <handle> --resume` | Reconcile
|
|
36
|
+
| `order confirm <handle> --choice <Confirmed\|NotConfirmed> [--submission <sponsored\|direct>]` | Prepare and validate the user's review; sponsored: sign and submit; direct: print the validated call |
|
|
37
|
+
| `order revoke-confirmation <handle>` | Withdraw the active review, in the same mode |
|
|
38
|
+
| `order confirm <handle> --resume` | Reconcile a stored sponsored submission without another EAS signature |
|
|
39
|
+
| `order confirm <handle> --tx <hash>` | Direct mode: record the hash the wallet's tool reported (unverified); replaces a final, provably unrelated one |
|
|
40
|
+
| `order confirm <handle> --check [--submission <sponsored\|direct>]` | Verify a pending direct record (the receipt, the EAS event, the attestation, and the gateway's final state at or past the receipt's block); otherwise report the gateway's final state of the review, keeping an observed direct record as history. `--submission direct` returns the recorded evidence of that record, `--submission sponsored` asks the gateway |
|
|
41
|
+
| `order confirm <handle> --abandon` | Direct mode: clear a record whose transaction reverted, was never sent, or is final and provably unrelated |
|
|
38
42
|
| `order reconcile <intentId>` | Query settlement for one payment identifier |
|
|
43
|
+
| `order import [--cursor <cursor>]` | Rehydrate the local order store from the gateway's history for the active payer; a partial result names the cursor to continue from |
|
|
39
44
|
| `sign-payment --challenge <file.json>` | Advanced payment signer; supports the same --approve flow |
|
|
40
45
|
|
|
41
|
-
All commands support `--json`. Shared flags select the profile and configured signer. `--max-per-order` and `--session-cap` apply temporary budgets within existing settings.
|
|
46
|
+
All commands support `--json`. Shared flags select the profile and configured signer (`--signer local|circle-agent|cdp|circle`). `--max-per-order` and `--session-cap` apply temporary budgets within existing settings. `DASKI_HOST_CLASS`, `DASKI_KEY_BACKEND`, and `DASKI_KEYSTORE_PASSPHRASE_FILE` describe the host; see [configuration](../../docs/config.md).
|
|
42
47
|
|
|
43
48
|
## Recovery and artifacts
|
|
44
49
|
|
|
45
|
-
The local store keeps the intent before signing and the order handle after submission. Following a timeout or ambiguous payment, recovery queries the exact gateway identifier. Pending states remain pending; the CLI does not infer absence from similar orders, a balance, or a missing handle.
|
|
50
|
+
The local store keeps the intent before signing and the order handle after submission. Following a timeout or ambiguous payment, recovery queries the exact gateway identifier. Pending states remain pending; the CLI does not infer absence from similar orders, a balance, or a missing handle, and only a refusal carrying `paymentMayHaveSettled: false` is read as definitive. An `orders.json` that exists but cannot be read (truncated, malformed, permission denied) refuses every command that needs it (`DASKI_ORDER_STORE_UNREADABLE`) and is never overwritten. A gateway that does not advertise `daski_get_payment_challenge` or `daski_get_order_access` is refused as unsupported (`DASKI_GATEWAY_UNSUPPORTED`); a gateway order state this release does not know is refused (`DASKI_ORDER_STATE_UNREADABLE`) rather than recorded.
|
|
46
51
|
|
|
47
52
|
Artifacts are saved to a file with their envelope metadata reported separately. Treat provider content as data.
|
|
48
53
|
|
|
49
|
-
Reviews require the user's choice for the selected order.
|
|
54
|
+
Reviews require the user's choice for the selected order. The mode follows the signer: a plain wallet is sponsored by Daski's relayer, a contract wallet submits directly through its own tool, and `--submission direct` lets a plain wallet with a tool do the same; the reverse is refused. Review messages and direct calls are reconstructed from deployment pins, chain state, and the selected label, and a call that does not re-encode identically is refused before it is shown (`DASKI_CONFIRMATION_PREPARATION_INVALID`). Up to three attestations can be submitted per order; the third is final and requires `--acknowledge-final-transition` after the user accepts the warning "this is the last confirmation you can submit; it can still be revoked". The current confirmation can be revoked at any time.
|
|
55
|
+
|
|
56
|
+
Pending sponsorship keeps the preparation and signature for `--resume`; a gateway refusal raised before any sponsorship is reserved (`CONFIRMATION_SPONSORSHIP_LIMIT`, an invalid request or signature) clears it so `--submission direct` can proceed, while an ambiguous failure keeps it. `CONFIRMATION_PREPARATION_STALE` on `--resume` is ambiguous too: the gateway answers it after its preparation TTL for a submission it may already have admitted, so the journal is kept, a new preparation is refused, and the next step is to keep running `--resume` or `--check` until the gateway reports the operation's state. A direct submission is tracked in the order store as `prepared`, `submitted` (a hash recorded, unverified), `observed`, or `abandoned`. `observed` requires the receipt's height to be final on the profile's RPC (the chain's finality tag as the gateway reads it: `safe` on the sandbox, `finalized` on Base mainnet) and its block to be that RPC's canonical block there, the pinned EAS to have emitted an event with the payer as attester whose attestation (read at that final height) binds to the prepared call (every event in a batched receipt is tried), and the gateway's final read to be at or past the receipt's block, canonical at its height on the same RPC, and to show the result. A final, bound receipt closes the record as `observed` even if the wallet revoked or replaced the review afterwards; `review: current` or `superseded` reports the review's effect separately. A new preparation in either mode is refused while a direct one is prepared or submitted. One order's record is updated under a per-order lock and every write to the order file under a store-wide lock; a lock is reclaimed only when its owner process is gone, never by age, and reclamation is serialized (a reclaim left by a dead process is reported for manual removal). A hash recorded by mistake is replaced (`--tx`) or cleared (`--abandon`) only once its transaction is final and canonical and no event in it binds to the prepared call (`DASKI_CONFIRMATION_TX_UNFINALIZED` until then); a reverted transaction is abandoned only once its block is final and canonical; a missing, pending, or matching receipt keeps the record. Neither cancels anything at the wallet. On the sandbox the `safe` tag lags the head by minutes; on mainnet `finalized` takes minutes to tens of minutes.
|
|
50
57
|
|
|
51
58
|
## Documentation
|
|
52
59
|
|
package/dist/bin/daski.js
CHANGED
|
@@ -11,7 +11,7 @@ import { CliError } from "../cli/errors.js";
|
|
|
11
11
|
import { emit, emitError } from "../cli/output.js";
|
|
12
12
|
import { runBuy } from "../commands/buy.js";
|
|
13
13
|
import { runDoctor } from "../commands/doctor.js";
|
|
14
|
-
import { orderArtifact, orderCancel, orderConfirm, orderInput, orderStatus, orderReconcile, } from "../commands/order.js";
|
|
14
|
+
import { orderArtifact, orderCancel, orderConfirm, orderImport, orderInput, orderStatus, orderReconcile, } from "../commands/order.js";
|
|
15
15
|
import { runSignPayment } from "../commands/signPayment.js";
|
|
16
16
|
import { createWallet, walletAddress, walletBalance } from "../commands/wallet.js";
|
|
17
17
|
import { CLI_VERSION } from "../version.js";
|
|
@@ -39,26 +39,34 @@ Commands
|
|
|
39
39
|
order status <handle> Read an order's state
|
|
40
40
|
order artifact <handle> [--output <file>]
|
|
41
41
|
Write the result bytes to a file (never to stdout)
|
|
42
|
-
order confirm <handle> --choice <Confirmed|NotConfirmed>
|
|
43
|
-
Record the user's delivery review
|
|
42
|
+
order confirm <handle> --choice <Confirmed|NotConfirmed> [--submission <sponsored|direct>]
|
|
43
|
+
Record the user's delivery review; the mode follows the signer
|
|
44
44
|
order revoke-confirmation <handle> Withdraw the active review
|
|
45
|
-
order confirm <handle> --resume Reconcile a pending
|
|
45
|
+
order confirm <handle> --resume Reconcile a pending sponsored submission
|
|
46
|
+
order confirm <handle> --tx <hash> Direct mode: record the hash the wallet's tool reported
|
|
47
|
+
order confirm <handle> --check Direct mode: verify the receipt, attestation and final state
|
|
48
|
+
order confirm <handle> --abandon Direct mode: drop a record with no executable transaction
|
|
46
49
|
order input <handle> --request <file.json>
|
|
47
50
|
Submit requested customer input
|
|
48
51
|
order cancel <handle> Request cancellation
|
|
49
52
|
order reconcile <handle|intentId> Ask the gateway whether a payment settled; never re-signs
|
|
53
|
+
order import Rehydrate the local order store from the gateway's history
|
|
50
54
|
sign-payment --challenge <file.json> [--provider <id> --outcome <id>]
|
|
51
55
|
Validate, recompute, sign; print the paymentPayload
|
|
52
56
|
|
|
53
57
|
Global flags
|
|
54
58
|
--json Machine-readable output
|
|
55
59
|
--profile <name> Config profile (default: sandbox)
|
|
56
|
-
--signer <local|cdp|circle>
|
|
60
|
+
--signer <local|circle-agent|cdp|circle>
|
|
61
|
+
Override the profile's signer
|
|
57
62
|
--cdp-account <name> CDP account for --signer cdp (or DASKI_CDP_ACCOUNT)
|
|
58
|
-
--circle-wallet <id>
|
|
63
|
+
--circle-wallet <id|address> Circle wallet id for --signer circle (or DASKI_CIRCLE_WALLET);
|
|
64
|
+
the agent wallet address to select for --signer circle-agent
|
|
59
65
|
--max-per-order <usdc> Apply a temporary per-order budget
|
|
60
66
|
--session-cap <usdc> Apply a temporary total budget
|
|
61
67
|
|
|
68
|
+
Environment: DASKI_HOST_CLASS (durable|ephemeral), DASKI_KEY_BACKEND
|
|
69
|
+
(keychain|file|circle-agent|cdp|none), DASKI_KEYSTORE_PASSPHRASE_FILE.
|
|
62
70
|
New profiles use quote approval, with optional budgets. Doctor reports the
|
|
63
71
|
active configuration path. See https://github.com/daski-io/buyer#readme
|
|
64
72
|
`;
|
|
@@ -119,14 +127,13 @@ async function main(argv) {
|
|
|
119
127
|
}
|
|
120
128
|
}
|
|
121
129
|
case "buy": {
|
|
122
|
-
assertKnownFlags(flags, [...GLOBAL_FLAGS, "provider", "outcome", "request", "payer", "
|
|
130
|
+
assertKnownFlags(flags, [...GLOBAL_FLAGS, "provider", "outcome", "request", "payer", "approve"]);
|
|
123
131
|
const result = await runBuy({
|
|
124
132
|
...shared,
|
|
125
133
|
providerAgentId: requireFlag(flags, "provider"),
|
|
126
134
|
outcomeId: requireFlag(flags, "outcome"),
|
|
127
135
|
requestFile: requireFlag(flags, "request"),
|
|
128
136
|
payer: stringFlag(flags, "payer"),
|
|
129
|
-
legacyArg: boolFlag(flags, "legacy-arg"),
|
|
130
137
|
approved: stringFlag(flags, "approve"),
|
|
131
138
|
json,
|
|
132
139
|
});
|
|
@@ -134,6 +141,11 @@ async function main(argv) {
|
|
|
134
141
|
return 0;
|
|
135
142
|
}
|
|
136
143
|
case "order": {
|
|
144
|
+
if (command[1] === "import") {
|
|
145
|
+
assertKnownFlags(flags, [...GLOBAL_FLAGS, "cursor"]);
|
|
146
|
+
emit(await orderImport({ ...shared, json, cursor: stringFlag(flags, "cursor") }), output);
|
|
147
|
+
return 0;
|
|
148
|
+
}
|
|
137
149
|
const handle = command[2];
|
|
138
150
|
if (!handle) {
|
|
139
151
|
throw new CliError({
|
|
@@ -154,10 +166,13 @@ async function main(argv) {
|
|
|
154
166
|
return 0;
|
|
155
167
|
case "confirm":
|
|
156
168
|
case "revoke-confirmation":
|
|
157
|
-
assertKnownFlags(flags, [...GLOBAL_FLAGS, "choice", "resume", "acknowledge-final-transition"
|
|
169
|
+
assertKnownFlags(flags, [...GLOBAL_FLAGS, "choice", "resume", "acknowledge-final-transition",
|
|
170
|
+
"submission", "tx", "check", "abandon"]);
|
|
158
171
|
emit(await orderConfirm({ ...base, confirmation: stringFlag(flags, "choice"),
|
|
159
172
|
revoke: command[1] === "revoke-confirmation", resume: boolFlag(flags, "resume"),
|
|
160
|
-
acknowledgeFinalTransition: boolFlag(flags, "acknowledge-final-transition")
|
|
173
|
+
acknowledgeFinalTransition: boolFlag(flags, "acknowledge-final-transition"),
|
|
174
|
+
submission: stringFlag(flags, "submission"), tx: stringFlag(flags, "tx"),
|
|
175
|
+
check: boolFlag(flags, "check"), abandon: boolFlag(flags, "abandon") }), output);
|
|
161
176
|
return 0;
|
|
162
177
|
case "cancel":
|
|
163
178
|
assertKnownFlags(flags, GLOBAL_FLAGS);
|
|
@@ -172,7 +187,7 @@ async function main(argv) {
|
|
|
172
187
|
emit(await orderReconcile(base), output);
|
|
173
188
|
return 0;
|
|
174
189
|
default:
|
|
175
|
-
throw unknownSubcommand("order", command[1], ["status", "artifact", "confirm", "revoke-confirmation", "input", "cancel", "reconcile"]);
|
|
190
|
+
throw unknownSubcommand("order", command[1], ["status", "artifact", "confirm", "revoke-confirmation", "input", "cancel", "reconcile", "import"]);
|
|
176
191
|
}
|
|
177
192
|
}
|
|
178
193
|
case "sign-payment": {
|
package/dist/bin/daski.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"daski.js","sourceRoot":"","sources":["../../src/bin/daski.ts"],"names":[],"mappings":";AACA;;;;;;GAMG;AACH,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAChG,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EACL,aAAa,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,WAAW,
|
|
1
|
+
{"version":3,"file":"daski.js","sourceRoot":"","sources":["../../src/bin/daski.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Read-only chain access.
|
|
3
|
+
*
|
|
4
|
+
* Everything this CLI learns from the chain — whether a contract account is
|
|
5
|
+
* deployed, whether it accepts a signature, what a receipt contains, what an
|
|
6
|
+
* attestation binds — comes through this one narrow reader. It has no
|
|
7
|
+
* account, no wallet client, and no way to send a transaction: the CLI never
|
|
8
|
+
* sends one (T9), and a sending client is not constructed anywhere.
|
|
9
|
+
*
|
|
10
|
+
* The reader is an interface so `doctor` and the confirmation flow can be
|
|
11
|
+
* exercised against a scripted chain in tests.
|
|
12
|
+
*/
|
|
13
|
+
import { type Abi, type Address, type Hex } from "viem";
|
|
14
|
+
/** The bound on one `eth_call` used to verify a contract signature. */
|
|
15
|
+
export declare const ERC1271_CALL_GAS = 1000000n;
|
|
16
|
+
/** One deadline covering the code lookup and the call. */
|
|
17
|
+
export declare const ERC1271_CALL_TIMEOUT_MS = 5000;
|
|
18
|
+
export interface ReceiptLog {
|
|
19
|
+
address: Address;
|
|
20
|
+
topics: readonly Hex[];
|
|
21
|
+
data: Hex;
|
|
22
|
+
}
|
|
23
|
+
export interface TransactionReceiptLike {
|
|
24
|
+
status: "success" | "reverted";
|
|
25
|
+
blockNumber: bigint;
|
|
26
|
+
/** The block that carried the transaction, compared with the canonical block at that height. */
|
|
27
|
+
blockHash: Hex;
|
|
28
|
+
from: Address;
|
|
29
|
+
logs: readonly ReceiptLog[];
|
|
30
|
+
}
|
|
31
|
+
export interface ChainCallResult {
|
|
32
|
+
/** The return data, or undefined when the call reverted or returned nothing. */
|
|
33
|
+
data: Hex | undefined;
|
|
34
|
+
reverted: boolean;
|
|
35
|
+
}
|
|
36
|
+
/** The block tag a profile's chain treats as final. */
|
|
37
|
+
export type FinalityTag = "safe" | "finalized";
|
|
38
|
+
/**
|
|
39
|
+
* Base mainnet waits for L1 finality; the sandbox (Base Sepolia) treats the
|
|
40
|
+
* `safe` tag (the batch is posted to L1) as final, the same rule the gateway
|
|
41
|
+
* applies through CHAIN_FINALITY_TAG (owner decision 2026-08-28).
|
|
42
|
+
*/
|
|
43
|
+
export declare function finalityTagFor(chainId: number): FinalityTag;
|
|
44
|
+
export interface ChainReader {
|
|
45
|
+
/** Code at `address` at the latest block; `undefined` or `0x` for an EOA. */
|
|
46
|
+
getCode(address: Address): Promise<Hex | undefined>;
|
|
47
|
+
/** A bounded, read-only `eth_call` at the latest block. */
|
|
48
|
+
call(args: {
|
|
49
|
+
to: Address;
|
|
50
|
+
data: Hex;
|
|
51
|
+
gas: bigint;
|
|
52
|
+
}): Promise<ChainCallResult>;
|
|
53
|
+
/** The receipt for a hash, or `null` while the transaction is not mined. */
|
|
54
|
+
getTransactionReceipt(hash: Hex): Promise<TransactionReceiptLike | null>;
|
|
55
|
+
/** The number of the newest block at the profile chain's finality tag. */
|
|
56
|
+
getFinalBlockNumber(): Promise<bigint>;
|
|
57
|
+
/** The hash of the canonical block at a height, as this RPC reports the chain now. */
|
|
58
|
+
getBlockHash(blockNumber: bigint): Promise<Hex>;
|
|
59
|
+
/** A contract read, at the latest state or pinned to a block number. */
|
|
60
|
+
readContract<T>(args: {
|
|
61
|
+
address: Address;
|
|
62
|
+
abi: Abi;
|
|
63
|
+
functionName: string;
|
|
64
|
+
args: readonly unknown[];
|
|
65
|
+
blockNumber?: bigint;
|
|
66
|
+
}): Promise<T>;
|
|
67
|
+
}
|
|
68
|
+
/** A viem-backed reader for one RPC endpoint, with one deadline per request. */
|
|
69
|
+
export declare function createChainReader(rpcUrl: string, finalityTag: FinalityTag, timeoutMs?: number): ChainReader;
|
|
70
|
+
/** The ERC-1271 magic value: the only return that verifies a contract signature. */
|
|
71
|
+
export declare const ERC1271_MAGIC = "0x1626ba7e";
|
|
72
|
+
export declare const ERC1271_ABI: readonly [{
|
|
73
|
+
readonly type: "function";
|
|
74
|
+
readonly name: "isValidSignature";
|
|
75
|
+
readonly stateMutability: "view";
|
|
76
|
+
readonly inputs: readonly [{
|
|
77
|
+
readonly name: "hash";
|
|
78
|
+
readonly type: "bytes32";
|
|
79
|
+
}, {
|
|
80
|
+
readonly name: "signature";
|
|
81
|
+
readonly type: "bytes";
|
|
82
|
+
}];
|
|
83
|
+
readonly outputs: readonly [{
|
|
84
|
+
readonly name: "magicValue";
|
|
85
|
+
readonly type: "bytes4";
|
|
86
|
+
}];
|
|
87
|
+
}];
|
|
88
|
+
/** True when `data` is exactly the 32-byte ABI encoding of the magic value. */
|
|
89
|
+
export declare function isErc1271Magic(data: Hex | undefined): boolean;
|
|
90
|
+
/** A deployed contract has non-empty code. */
|
|
91
|
+
export declare function isDeployedCode(code: Hex | undefined): boolean;
|
|
92
|
+
//# sourceMappingURL=reader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reader.d.ts","sourceRoot":"","sources":["../../src/chain/reader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAEL,KAAK,GAAG,EAAE,KAAK,OAAO,EAAE,KAAK,GAAG,EACjC,MAAM,MAAM,CAAC;AAGd,uEAAuE;AACvE,eAAO,MAAM,gBAAgB,WAAa,CAAC;AAC3C,0DAA0D;AAC1D,eAAO,MAAM,uBAAuB,OAAQ,CAAC;AAE7C,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,SAAS,GAAG,EAAE,CAAC;IACvB,IAAI,EAAE,GAAG,CAAC;CACX;AAED,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,SAAS,GAAG,UAAU,CAAC;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,gGAAgG;IAChG,SAAS,EAAE,GAAG,CAAC;IACf,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,SAAS,UAAU,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,eAAe;IAC9B,gFAAgF;IAChF,IAAI,EAAE,GAAG,GAAG,SAAS,CAAC;IACtB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,uDAAuD;AACvD,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,WAAW,CAAC;AAE/C;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,CAE3D;AAED,MAAM,WAAW,WAAW;IAC1B,6EAA6E;IAC7E,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,GAAG,GAAG,SAAS,CAAC,CAAC;IACpD,2DAA2D;IAC3D,IAAI,CAAC,IAAI,EAAE;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,IAAI,EAAE,GAAG,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IAC9E,4EAA4E;IAC5E,qBAAqB,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO,CAAC,sBAAsB,GAAG,IAAI,CAAC,CAAC;IACzE,0EAA0E;IAC1E,mBAAmB,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IACvC,sFAAsF;IACtF,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IAChD,wEAAwE;IACxE,YAAY,CAAC,CAAC,EAAE,IAAI,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,GAAG,EAAE,GAAG,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,SAAS,OAAO,EAAE,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CACzI;AAkBD,gFAAgF;AAChF,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,SAAS,SAA0B,GAAG,WAAW,CA2D5H;AAED,oFAAoF;AACpF,eAAO,MAAM,aAAa,eAAe,CAAC;AAE1C,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;EAQA,CAAC;AAEzB,+EAA+E;AAC/E,wBAAgB,cAAc,CAAC,IAAI,EAAE,GAAG,GAAG,SAAS,GAAG,OAAO,CAE7D;AAED,8CAA8C;AAC9C,wBAAgB,cAAc,CAAC,IAAI,EAAE,GAAG,GAAG,SAAS,GAAG,OAAO,CAE7D"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Read-only chain access.
|
|
3
|
+
*
|
|
4
|
+
* Everything this CLI learns from the chain — whether a contract account is
|
|
5
|
+
* deployed, whether it accepts a signature, what a receipt contains, what an
|
|
6
|
+
* attestation binds — comes through this one narrow reader. It has no
|
|
7
|
+
* account, no wallet client, and no way to send a transaction: the CLI never
|
|
8
|
+
* sends one (T9), and a sending client is not constructed anywhere.
|
|
9
|
+
*
|
|
10
|
+
* The reader is an interface so `doctor` and the confirmation flow can be
|
|
11
|
+
* exercised against a scripted chain in tests.
|
|
12
|
+
*/
|
|
13
|
+
import { createPublicClient, http, HttpRequestError, TimeoutError, BaseError, } from "viem";
|
|
14
|
+
import { CliError } from "../cli/errors.js";
|
|
15
|
+
/** The bound on one `eth_call` used to verify a contract signature. */
|
|
16
|
+
export const ERC1271_CALL_GAS = 1000000n;
|
|
17
|
+
/** One deadline covering the code lookup and the call. */
|
|
18
|
+
export const ERC1271_CALL_TIMEOUT_MS = 5_000;
|
|
19
|
+
/**
|
|
20
|
+
* Base mainnet waits for L1 finality; the sandbox (Base Sepolia) treats the
|
|
21
|
+
* `safe` tag (the batch is posted to L1) as final, the same rule the gateway
|
|
22
|
+
* applies through CHAIN_FINALITY_TAG (owner decision 2026-08-28).
|
|
23
|
+
*/
|
|
24
|
+
export function finalityTagFor(chainId) {
|
|
25
|
+
return chainId === 8453 ? "finalized" : "safe";
|
|
26
|
+
}
|
|
27
|
+
function rpcUnavailable(rpcUrl, error) {
|
|
28
|
+
return new CliError({
|
|
29
|
+
code: "DASKI_RPC_UNAVAILABLE",
|
|
30
|
+
message: `The RPC at ${rpcUrl} did not answer: ${error instanceof Error ? error.message.split("\n")[0] : String(error)}`,
|
|
31
|
+
remediation: "Nothing was decided from this read. Check connectivity or set a working rpcUrl for " +
|
|
32
|
+
"the profile, then re-run.",
|
|
33
|
+
details: { retryable: true },
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
function isTransportFailure(error) {
|
|
37
|
+
if (!(error instanceof BaseError))
|
|
38
|
+
return true;
|
|
39
|
+
return error.walk((cause) => cause instanceof HttpRequestError || cause instanceof TimeoutError) !== null;
|
|
40
|
+
}
|
|
41
|
+
/** A viem-backed reader for one RPC endpoint, with one deadline per request. */
|
|
42
|
+
export function createChainReader(rpcUrl, finalityTag, timeoutMs = ERC1271_CALL_TIMEOUT_MS) {
|
|
43
|
+
const client = createPublicClient({ transport: http(rpcUrl, { timeout: timeoutMs, retryCount: 0 }) });
|
|
44
|
+
return {
|
|
45
|
+
async getCode(address) {
|
|
46
|
+
try {
|
|
47
|
+
return await client.getCode({ address });
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
throw rpcUnavailable(rpcUrl, error);
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
async call({ to, data, gas }) {
|
|
54
|
+
try {
|
|
55
|
+
const result = await client.call({ to, data, gas });
|
|
56
|
+
return { data: result.data, reverted: false };
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
// A transport failure is unknown, never invalid; a revert is a final answer.
|
|
60
|
+
if (isTransportFailure(error))
|
|
61
|
+
throw rpcUnavailable(rpcUrl, error);
|
|
62
|
+
return { data: undefined, reverted: true };
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
async getTransactionReceipt(hash) {
|
|
66
|
+
try {
|
|
67
|
+
const receipt = await client.getTransactionReceipt({ hash });
|
|
68
|
+
return {
|
|
69
|
+
status: receipt.status,
|
|
70
|
+
blockNumber: receipt.blockNumber,
|
|
71
|
+
blockHash: receipt.blockHash,
|
|
72
|
+
from: receipt.from,
|
|
73
|
+
logs: receipt.logs.map((log) => ({ address: log.address, topics: log.topics, data: log.data })),
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
if (error instanceof BaseError && error.name === "TransactionReceiptNotFoundError")
|
|
78
|
+
return null;
|
|
79
|
+
if (error instanceof BaseError &&
|
|
80
|
+
error.walk((cause) => cause.name === "TransactionReceiptNotFoundError") !== null)
|
|
81
|
+
return null;
|
|
82
|
+
throw rpcUnavailable(rpcUrl, error);
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
async getFinalBlockNumber() {
|
|
86
|
+
try {
|
|
87
|
+
return (await client.getBlock({ blockTag: finalityTag })).number;
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
throw rpcUnavailable(rpcUrl, error);
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
async getBlockHash(blockNumber) {
|
|
94
|
+
try {
|
|
95
|
+
return (await client.getBlock({ blockNumber })).hash;
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
throw rpcUnavailable(rpcUrl, error);
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
async readContract(args) {
|
|
102
|
+
try {
|
|
103
|
+
return await client.readContract(args);
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
throw rpcUnavailable(rpcUrl, error);
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
/** The ERC-1271 magic value: the only return that verifies a contract signature. */
|
|
112
|
+
export const ERC1271_MAGIC = "0x1626ba7e";
|
|
113
|
+
export const ERC1271_ABI = [
|
|
114
|
+
{
|
|
115
|
+
type: "function",
|
|
116
|
+
name: "isValidSignature",
|
|
117
|
+
stateMutability: "view",
|
|
118
|
+
inputs: [{ name: "hash", type: "bytes32" }, { name: "signature", type: "bytes" }],
|
|
119
|
+
outputs: [{ name: "magicValue", type: "bytes4" }],
|
|
120
|
+
},
|
|
121
|
+
];
|
|
122
|
+
/** True when `data` is exactly the 32-byte ABI encoding of the magic value. */
|
|
123
|
+
export function isErc1271Magic(data) {
|
|
124
|
+
return typeof data === "string" && data.length === 66 && data.toLowerCase().startsWith(ERC1271_MAGIC);
|
|
125
|
+
}
|
|
126
|
+
/** A deployed contract has non-empty code. */
|
|
127
|
+
export function isDeployedCode(code) {
|
|
128
|
+
return typeof code === "string" && /^0x[0-9a-fA-F]+$/.test(code) && code.length > 2;
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=reader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reader.js","sourceRoot":"","sources":["../../src/chain/reader.ts"],"names":[],"mappings":"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"}
|
|
@@ -14,8 +14,8 @@ export function purchaseApproval(args) {
|
|
|
14
14
|
network: args.requirement.network, token: getAddress(args.requirement.asset),
|
|
15
15
|
payTo: getAddress(args.requirement.payTo), amount: BigInt(args.requirement.amount).toString(),
|
|
16
16
|
requestHash: binding.canonicalRequestHash,
|
|
17
|
-
listing: binding.
|
|
18
|
-
providerTerms: binding.
|
|
17
|
+
listing: binding.runtimeCommitmentHash,
|
|
18
|
+
providerTerms: binding.providerIntentHash,
|
|
19
19
|
};
|
|
20
20
|
const termsHash = canonicalHash(terms);
|
|
21
21
|
const purchaseNumber = args.purchaseNumber ?? 1;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"approval.js","sourceRoot":"","sources":["../../src/commands/approval.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAqB,MAAM,oBAAoB,CAAC;AAClF,OAAO,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAExC,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAE3D,kFAAkF;AAClF,MAAM,UAAU,gBAAgB,CAAC,IAIhC;IACC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;IAC7B,MAAM,KAAK,GAAG;QACZ,OAAO,EAAE,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,EAAE,KAAK,EAAE,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC;QAC1E,eAAe,EAAE,IAAI,CAAC,eAAe,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS;QAChE,OAAO,EAAE,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,KAAK,EAAE,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC;QAC5E,KAAK,EAAE,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE;QAC7F,WAAW,EAAE,OAAO,CAAC,oBAAoB;QACzC,OAAO,EAAE,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"approval.js","sourceRoot":"","sources":["../../src/commands/approval.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/buy.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"buy.d.ts","sourceRoot":"","sources":["../../src/commands/buy.ts"],"names":[],"mappings":"AAQA,OAAO,EAA6B,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAG9E,OAAO,EAAiB,KAAK,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"buy.d.ts","sourceRoot":"","sources":["../../src/commands/buy.ts"],"names":[],"mappings":"AAQA,OAAO,EAA6B,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAG9E,OAAO,EAAiB,KAAK,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AAgBxF,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,qDAAqD;IACrD,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC/B;AAED,wBAAsB,MAAM,CAAC,OAAO,EAAE,UAAU,EAAE,cAAc,GAAE,CAAC,OAAO,EAAE,cAAc,KAAK,OAAO,CAAC,cAAc,CAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CA2KxK;AAuHD,OAAO,EAAE,aAAa,EAAE,CAAC"}
|
package/dist/commands/buy.js
CHANGED
|
@@ -12,7 +12,8 @@ import { note } from "../cli/output.js";
|
|
|
12
12
|
import { createContext } from "../context.js";
|
|
13
13
|
import { approvePurchase, nextPurchaseApproval } from "./approval.js";
|
|
14
14
|
import { GatewayClient } from "../gateway/client.js";
|
|
15
|
-
import { authorizePayment, challengeIntentId, isAmbiguousPurchaseAnswer, reconcileByIdentifier, recordIntent, requestChallenge, submitPayment, } from "../gateway/purchase.js";
|
|
15
|
+
import { authorizePayment, challengeIntentId, isAmbiguousPurchaseAnswer, localOrderState, reconcileByIdentifier, recordIntent, requestChallenge, submitPayment, } from "../gateway/purchase.js";
|
|
16
|
+
import { assertContractSignerUsable } from "../signers/contract.js";
|
|
16
17
|
import { updateOrder } from "../store/orders.js";
|
|
17
18
|
export async function runBuy(options, contextFactory = createContext) {
|
|
18
19
|
const request = readRequestFile(options.requestFile);
|
|
@@ -27,6 +28,12 @@ export async function runBuy(options, contextFactory = createContext) {
|
|
|
27
28
|
"profiles, or drop --payer.",
|
|
28
29
|
});
|
|
29
30
|
}
|
|
31
|
+
// A contract wallet must be one the gateway verifies and the chain has
|
|
32
|
+
// seen deployed, or a refusal at settlement would be the first signal.
|
|
33
|
+
await assertContractSignerUsable({
|
|
34
|
+
signer: context.signer, chain: context.chain, metadata: context.metadata,
|
|
35
|
+
gatewayUrl: context.profile.gatewayUrl,
|
|
36
|
+
});
|
|
30
37
|
// -- 1. challenge ------------------------------------------------------
|
|
31
38
|
const challenge = await requestChallenge({
|
|
32
39
|
client: context.client,
|
|
@@ -109,7 +116,6 @@ export async function runBuy(options, contextFactory = createContext) {
|
|
|
109
116
|
outcomeId: options.outcomeId,
|
|
110
117
|
request,
|
|
111
118
|
submission: authorized.submission,
|
|
112
|
-
...(options.legacyArg === undefined ? {} : { legacyArg: options.legacyArg }),
|
|
113
119
|
});
|
|
114
120
|
}
|
|
115
121
|
catch (error) {
|
|
@@ -122,7 +128,7 @@ export async function runBuy(options, contextFactory = createContext) {
|
|
|
122
128
|
}
|
|
123
129
|
const body = GatewayClient.json(result);
|
|
124
130
|
const code = typeof body?.code === "string" ? body.code : undefined;
|
|
125
|
-
if (result.isError && isAmbiguousPurchaseAnswer(
|
|
131
|
+
if (result.isError && isAmbiguousPurchaseAnswer(body)) {
|
|
126
132
|
return await reconcile(context, {
|
|
127
133
|
intentId,
|
|
128
134
|
cause: `gateway reported ${code ?? "an error"} with the payment outcome unknown`,
|
|
@@ -148,10 +154,10 @@ export async function runBuy(options, contextFactory = createContext) {
|
|
|
148
154
|
throw purchaseFailure(result, { afterSubmit: true, refused });
|
|
149
155
|
}
|
|
150
156
|
// -- 6 & 7. persist and report ----------------------------------------
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
});
|
|
157
|
+
// The handle is recorded before the state is read: a state this release
|
|
158
|
+
// cannot map is refused, and the order must still be reachable by handle.
|
|
159
|
+
updateOrder(intentId, { handle: body.orderHandle });
|
|
160
|
+
const record = updateOrder(intentId, { state: localOrderState(body.status, body.orderHandle) });
|
|
155
161
|
return {
|
|
156
162
|
purchased: true,
|
|
157
163
|
orderHandle: body.orderHandle,
|
|
@@ -160,12 +166,9 @@ export async function runBuy(options, contextFactory = createContext) {
|
|
|
160
166
|
provider: options.providerAgentId,
|
|
161
167
|
outcome: options.outcomeId,
|
|
162
168
|
price: formatUsdc(amountAtomic),
|
|
163
|
-
state: record?.state ?? String(body.status
|
|
169
|
+
state: record?.state ?? String(body.status),
|
|
164
170
|
payer: context.payerAddress,
|
|
165
171
|
authorizationNonce: authorized.nonce,
|
|
166
|
-
challengeSource: challenge.viaChallengeTool
|
|
167
|
-
? "daski_get_payment_challenge"
|
|
168
|
-
: "daski_buy_outcome (unpaid challenge fallback)",
|
|
169
172
|
receipt: body.receipt ?? null,
|
|
170
173
|
gatewayCalls: context.client.callCount,
|
|
171
174
|
};
|
|
@@ -189,7 +192,7 @@ async function reconcile(context, args) {
|
|
|
189
192
|
if (outcome.status === "settled") {
|
|
190
193
|
const settled = updateOrder(args.intentId, {
|
|
191
194
|
handle: outcome.orderHandle,
|
|
192
|
-
state:
|
|
195
|
+
state: localOrderState(outcome.gatewayState, outcome.orderHandle),
|
|
193
196
|
});
|
|
194
197
|
return {
|
|
195
198
|
purchased: true,
|
|
@@ -220,16 +223,6 @@ async function reconcile(context, args) {
|
|
|
220
223
|
exitCode: 3,
|
|
221
224
|
});
|
|
222
225
|
}
|
|
223
|
-
function normalizeState(status) {
|
|
224
|
-
const value = String(status ?? "").toLowerCase();
|
|
225
|
-
if (["completed", "fulfilled"].includes(value))
|
|
226
|
-
return "FULFILLED";
|
|
227
|
-
if (["input-required", "input_required"].includes(value))
|
|
228
|
-
return "INPUT_REQUIRED";
|
|
229
|
-
if (["failed", "canceled", "provider_failed"].includes(value))
|
|
230
|
-
return "PROVIDER_FAILED";
|
|
231
|
-
return "SUBMITTED";
|
|
232
|
-
}
|
|
233
226
|
/**
|
|
234
227
|
* The human-facing summary. The gateway's prepare tool ships a one-sentence
|
|
235
228
|
* `approvalSummary` in its preflight; it leads when present, and the rest is
|