@absol-labs/agent 0.9.1 → 0.11.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/README.md +184 -26
- package/dist/capability/invocation-capability.d.ts +18 -6
- package/dist/capability/invocation-capability.d.ts.map +1 -1
- package/dist/capability/invocation-capability.js.map +1 -1
- package/dist/cli/amounts.d.ts +26 -0
- package/dist/cli/amounts.d.ts.map +1 -0
- package/dist/cli/amounts.js +71 -0
- package/dist/cli/amounts.js.map +1 -0
- package/dist/cli/args.d.ts +32 -0
- package/dist/cli/args.d.ts.map +1 -0
- package/dist/cli/args.js +119 -0
- package/dist/cli/args.js.map +1 -0
- package/dist/cli/attesters.d.ts +51 -0
- package/dist/cli/attesters.d.ts.map +1 -0
- package/dist/cli/attesters.js +58 -0
- package/dist/cli/attesters.js.map +1 -0
- package/dist/cli/bin.d.ts +3 -0
- package/dist/cli/bin.d.ts.map +1 -0
- package/dist/cli/bin.js +5 -0
- package/dist/cli/bin.js.map +1 -0
- package/dist/cli/commands/claim.d.ts +13 -0
- package/dist/cli/commands/claim.d.ts.map +1 -0
- package/dist/cli/commands/claim.js +102 -0
- package/dist/cli/commands/claim.js.map +1 -0
- package/dist/cli/commands/close.d.ts +3 -0
- package/dist/cli/commands/close.d.ts.map +1 -0
- package/dist/cli/commands/close.js +55 -0
- package/dist/cli/commands/close.js.map +1 -0
- package/dist/cli/commands/discover.d.ts +3 -0
- package/dist/cli/commands/discover.d.ts.map +1 -0
- package/dist/cli/commands/discover.js +183 -0
- package/dist/cli/commands/discover.js.map +1 -0
- package/dist/cli/commands/invoke.d.ts +3 -0
- package/dist/cli/commands/invoke.d.ts.map +1 -0
- package/dist/cli/commands/invoke.js +142 -0
- package/dist/cli/commands/invoke.js.map +1 -0
- package/dist/cli/commands/mcp.d.ts +3 -0
- package/dist/cli/commands/mcp.d.ts.map +1 -0
- package/dist/cli/commands/mcp.js +113 -0
- package/dist/cli/commands/mcp.js.map +1 -0
- package/dist/cli/commands/open.d.ts +3 -0
- package/dist/cli/commands/open.d.ts.map +1 -0
- package/dist/cli/commands/open.js +331 -0
- package/dist/cli/commands/open.js.map +1 -0
- package/dist/cli/commands/reclaim-unverified.d.ts +3 -0
- package/dist/cli/commands/reclaim-unverified.d.ts.map +1 -0
- package/dist/cli/commands/reclaim-unverified.js +172 -0
- package/dist/cli/commands/reclaim-unverified.js.map +1 -0
- package/dist/cli/commands/reclaim.d.ts +33 -0
- package/dist/cli/commands/reclaim.d.ts.map +1 -0
- package/dist/cli/commands/reclaim.js +308 -0
- package/dist/cli/commands/reclaim.js.map +1 -0
- package/dist/cli/commands/status.d.ts +3 -0
- package/dist/cli/commands/status.d.ts.map +1 -0
- package/dist/cli/commands/status.js +43 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/commands/streams.d.ts +3 -0
- package/dist/cli/commands/streams.d.ts.map +1 -0
- package/dist/cli/commands/streams.js +257 -0
- package/dist/cli/commands/streams.js.map +1 -0
- package/dist/cli/commands/watch.d.ts +3 -0
- package/dist/cli/commands/watch.d.ts.map +1 -0
- package/dist/cli/commands/watch.js +55 -0
- package/dist/cli/commands/watch.js.map +1 -0
- package/dist/cli/config.d.ts +61 -0
- package/dist/cli/config.d.ts.map +1 -0
- package/dist/cli/config.js +140 -0
- package/dist/cli/config.js.map +1 -0
- package/dist/cli/context.d.ts +29 -0
- package/dist/cli/context.d.ts.map +1 -0
- package/dist/cli/context.js +2 -0
- package/dist/cli/context.js.map +1 -0
- package/dist/cli/deps.d.ts +191 -0
- package/dist/cli/deps.d.ts.map +1 -0
- package/dist/cli/deps.js +277 -0
- package/dist/cli/deps.js.map +1 -0
- package/dist/cli/descriptor.d.ts +61 -0
- package/dist/cli/descriptor.d.ts.map +1 -0
- package/dist/cli/descriptor.js +78 -0
- package/dist/cli/descriptor.js.map +1 -0
- package/dist/cli/errors.d.ts +48 -0
- package/dist/cli/errors.d.ts.map +1 -0
- package/dist/cli/errors.js +129 -0
- package/dist/cli/errors.js.map +1 -0
- package/dist/cli/escape-hatch.d.ts +50 -0
- package/dist/cli/escape-hatch.d.ts.map +1 -0
- package/dist/cli/escape-hatch.js +45 -0
- package/dist/cli/escape-hatch.js.map +1 -0
- package/dist/cli/index.d.ts +8 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +7 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/listings.d.ts +15 -0
- package/dist/cli/listings.d.ts.map +1 -0
- package/dist/cli/listings.js +56 -0
- package/dist/cli/listings.js.map +1 -0
- package/dist/cli/mandate.d.ts +66 -0
- package/dist/cli/mandate.d.ts.map +1 -0
- package/dist/cli/mandate.js +61 -0
- package/dist/cli/mandate.js.map +1 -0
- package/dist/cli/output.d.ts +33 -0
- package/dist/cli/output.d.ts.map +1 -0
- package/dist/cli/output.js +34 -0
- package/dist/cli/output.js.map +1 -0
- package/dist/cli/preflight.d.ts +38 -0
- package/dist/cli/preflight.d.ts.map +1 -0
- package/dist/cli/preflight.js +72 -0
- package/dist/cli/preflight.js.map +1 -0
- package/dist/cli/privy.d.ts +83 -0
- package/dist/cli/privy.d.ts.map +1 -0
- package/dist/cli/privy.js +230 -0
- package/dist/cli/privy.js.map +1 -0
- package/dist/cli/progress.d.ts +36 -0
- package/dist/cli/progress.d.ts.map +1 -0
- package/dist/cli/progress.js +40 -0
- package/dist/cli/progress.js.map +1 -0
- package/dist/cli/run.d.ts +25 -0
- package/dist/cli/run.d.ts.map +1 -0
- package/dist/cli/run.js +173 -0
- package/dist/cli/run.js.map +1 -0
- package/dist/cli/scan-range.d.ts +55 -0
- package/dist/cli/scan-range.d.ts.map +1 -0
- package/dist/cli/scan-range.js +57 -0
- package/dist/cli/scan-range.js.map +1 -0
- package/dist/cli/spend-policy.d.ts +60 -0
- package/dist/cli/spend-policy.d.ts.map +1 -0
- package/dist/cli/spend-policy.js +65 -0
- package/dist/cli/spend-policy.js.map +1 -0
- package/dist/cli/status.d.ts +90 -0
- package/dist/cli/status.d.ts.map +1 -0
- package/dist/cli/status.js +252 -0
- package/dist/cli/status.js.map +1 -0
- package/dist/cli/timeout.d.ts +30 -0
- package/dist/cli/timeout.d.ts.map +1 -0
- package/dist/cli/timeout.js +55 -0
- package/dist/cli/timeout.js.map +1 -0
- package/dist/cli/version.d.ts +12 -0
- package/dist/cli/version.d.ts.map +1 -0
- package/dist/cli/version.js +22 -0
- package/dist/cli/version.js.map +1 -0
- package/dist/cli/wallet.d.ts +164 -0
- package/dist/cli/wallet.d.ts.map +1 -0
- package/dist/cli/wallet.js +234 -0
- package/dist/cli/wallet.js.map +1 -0
- package/dist/frameworks/crewai.d.ts +10 -0
- package/dist/frameworks/crewai.d.ts.map +1 -1
- package/dist/frameworks/crewai.js +12 -2
- package/dist/frameworks/crewai.js.map +1 -1
- package/dist/gateway/caller-auth-gateway.d.ts +38 -3
- package/dist/gateway/caller-auth-gateway.d.ts.map +1 -1
- package/dist/gateway/caller-auth-gateway.js +25 -1
- package/dist/gateway/caller-auth-gateway.js.map +1 -1
- package/dist/gateway/http-server.d.ts +53 -0
- package/dist/gateway/http-server.d.ts.map +1 -1
- package/dist/gateway/http-server.js +189 -4
- package/dist/gateway/http-server.js.map +1 -1
- package/dist/gateway/server-entry.d.ts +1 -0
- package/dist/gateway/server-entry.js +1 -0
- package/dist/gateway/server-entry.js.map +1 -1
- package/dist/gateway/x402-mode.d.ts +123 -0
- package/dist/gateway/x402-mode.d.ts.map +1 -0
- package/dist/gateway/x402-mode.js +212 -0
- package/dist/gateway/x402-mode.js.map +1 -0
- package/dist/index.d.ts +6 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -3
- package/dist/index.js.map +1 -1
- package/dist/mandates/env.d.ts +3 -2
- package/dist/mandates/env.d.ts.map +1 -1
- package/dist/mandates/env.js +3 -2
- package/dist/mandates/env.js.map +1 -1
- package/dist/mcp/http-server.d.ts +1 -0
- package/dist/mcp/http-server.js +1 -0
- package/dist/mcp/http-server.js.map +1 -1
- package/dist/mcp/server.d.ts +49 -0
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +533 -25
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/service-invoker.d.ts +97 -0
- package/dist/mcp/service-invoker.d.ts.map +1 -0
- package/dist/mcp/service-invoker.js +167 -0
- package/dist/mcp/service-invoker.js.map +1 -0
- package/dist/mcp/stdio.d.ts +1 -0
- package/dist/mcp/stdio.js +1 -0
- package/dist/mcp/stdio.js.map +1 -1
- package/dist/sdk/client.d.ts +25 -1
- package/dist/sdk/client.d.ts.map +1 -1
- package/dist/sdk/client.js +20 -1
- package/dist/sdk/client.js.map +1 -1
- package/dist/sdk/invoke.d.ts +19 -4
- package/dist/sdk/invoke.d.ts.map +1 -1
- package/dist/sdk/invoke.js +69 -5
- package/dist/sdk/invoke.js.map +1 -1
- package/dist/x402/delivery-oracle.d.ts +108 -0
- package/dist/x402/delivery-oracle.d.ts.map +1 -0
- package/dist/x402/delivery-oracle.js +174 -0
- package/dist/x402/delivery-oracle.js.map +1 -0
- package/dist/x402/facilitator-server-entry.d.ts +3 -0
- package/dist/x402/facilitator-server-entry.d.ts.map +1 -0
- package/dist/x402/facilitator-server-entry.js +27 -0
- package/dist/x402/facilitator-server-entry.js.map +1 -0
- package/dist/x402/facilitator-server.d.ts +73 -0
- package/dist/x402/facilitator-server.d.ts.map +1 -0
- package/dist/x402/facilitator-server.js +305 -0
- package/dist/x402/facilitator-server.js.map +1 -0
- package/dist/x402/facilitator.d.ts +69 -17
- package/dist/x402/facilitator.d.ts.map +1 -1
- package/dist/x402/facilitator.js +76 -33
- package/dist/x402/facilitator.js.map +1 -1
- package/dist/x402/payment-requirements.d.ts +106 -0
- package/dist/x402/payment-requirements.d.ts.map +1 -0
- package/dist/x402/payment-requirements.js +138 -0
- package/dist/x402/payment-requirements.js.map +1 -0
- package/dist/x402/relayer.d.ts +41 -0
- package/dist/x402/relayer.d.ts.map +1 -0
- package/dist/x402/relayer.js +64 -0
- package/dist/x402/relayer.js.map +1 -0
- package/dist/x402/resource-index.d.ts +75 -0
- package/dist/x402/resource-index.d.ts.map +1 -0
- package/dist/x402/resource-index.js +126 -0
- package/dist/x402/resource-index.js.map +1 -0
- package/dist/x402/verified-delivery-facilitator.d.ts +285 -0
- package/dist/x402/verified-delivery-facilitator.d.ts.map +1 -0
- package/dist/x402/verified-delivery-facilitator.js +423 -0
- package/dist/x402/verified-delivery-facilitator.js.map +1 -0
- package/dist/zktls/t2-delivery-proof.d.ts +6 -6
- package/docs/agent-layer.md +14 -9
- package/docs/cli.md +705 -0
- package/docs/crewai.md +6 -2
- package/docs/eliza.md +6 -1
- package/docs/mcp-hosted.md +7 -5
- package/docs/mcp-reference.md +175 -0
- package/docs/quickstart.md +36 -9
- package/docs/threat-model.md +4 -3
- package/docs/x402.md +648 -0
- package/package.json +33 -10
- package/src/capability/invocation-capability.ts +17 -1
- package/src/cli/amounts.ts +102 -0
- package/src/cli/args.ts +150 -0
- package/src/cli/attesters.ts +86 -0
- package/src/cli/bin.ts +5 -0
- package/src/cli/commands/claim.ts +126 -0
- package/src/cli/commands/close.ts +69 -0
- package/src/cli/commands/discover.ts +228 -0
- package/src/cli/commands/invoke.ts +178 -0
- package/src/cli/commands/mcp.ts +135 -0
- package/src/cli/commands/open.ts +397 -0
- package/src/cli/commands/reclaim-unverified.ts +218 -0
- package/src/cli/commands/reclaim.ts +377 -0
- package/src/cli/commands/status.ts +56 -0
- package/src/cli/commands/streams.ts +344 -0
- package/src/cli/commands/watch.ts +70 -0
- package/src/cli/config.ts +208 -0
- package/src/cli/context.ts +30 -0
- package/src/cli/deps.ts +528 -0
- package/src/cli/descriptor.ts +133 -0
- package/src/cli/errors.ts +162 -0
- package/src/cli/escape-hatch.ts +92 -0
- package/src/cli/index.ts +27 -0
- package/src/cli/listings.ts +77 -0
- package/src/cli/mandate.ts +126 -0
- package/src/cli/output.ts +63 -0
- package/src/cli/preflight.ts +88 -0
- package/src/cli/privy.ts +396 -0
- package/src/cli/progress.ts +75 -0
- package/src/cli/run.ts +209 -0
- package/src/cli/scan-range.ts +76 -0
- package/src/cli/spend-policy.ts +139 -0
- package/src/cli/status.ts +381 -0
- package/src/cli/timeout.ts +64 -0
- package/src/cli/version.ts +21 -0
- package/src/cli/wallet.ts +372 -0
- package/src/frameworks/crewai.ts +13 -2
- package/src/gateway/caller-auth-gateway.ts +77 -6
- package/src/gateway/http-server.ts +280 -6
- package/src/gateway/server-entry.ts +1 -0
- package/src/gateway/x402-mode.ts +350 -0
- package/src/index.ts +40 -5
- package/src/mandates/env.ts +3 -2
- package/src/mcp/http-server.ts +1 -0
- package/src/mcp/server.ts +706 -30
- package/src/mcp/service-invoker.ts +285 -0
- package/src/mcp/stdio.ts +1 -0
- package/src/sdk/client.ts +33 -1
- package/src/sdk/invoke.ts +90 -12
- package/src/x402/delivery-oracle.ts +285 -0
- package/src/x402/facilitator-server-entry.ts +35 -0
- package/src/x402/facilitator-server.ts +445 -0
- package/src/x402/facilitator.ts +125 -46
- package/src/x402/payment-requirements.ts +231 -0
- package/src/x402/relayer.ts +122 -0
- package/src/x402/resource-index.ts +228 -0
- package/src/x402/verified-delivery-facilitator.ts +744 -0
package/dist/cli/deps.js
ADDED
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
import { streamEscrowV2Abi } from "@absol-labs/shared";
|
|
2
|
+
import { MetrikClient, } from "@absol-labs/sdk";
|
|
3
|
+
import { erc20Abi, getAbiItem, http } from "viem";
|
|
4
|
+
import { discoverServicesDetailed, } from "../discovery/registry.js";
|
|
5
|
+
import { invoke as sdkInvoke, } from "../sdk/invoke.js";
|
|
6
|
+
import { VerifiedStreamAgentClient, } from "../sdk/client.js";
|
|
7
|
+
import { RPC_RETRY_COUNT, RPC_TIMEOUT_MS, withReadTimeout } from "./timeout.js";
|
|
8
|
+
/**
|
|
9
|
+
* The `StreamOpened` ABI entry, resolved once. Taken from the shared V2 ABI
|
|
10
|
+
* rather than re-declared: a hand-written copy that drifted by one indexed
|
|
11
|
+
* argument would silently match nothing.
|
|
12
|
+
*/
|
|
13
|
+
const STREAM_OPENED_EVENT = getAbiItem({
|
|
14
|
+
abi: streamEscrowV2Abi,
|
|
15
|
+
name: "StreamOpened",
|
|
16
|
+
});
|
|
17
|
+
/**
|
|
18
|
+
* The RPC transport, with an explicit per-call budget.
|
|
19
|
+
*
|
|
20
|
+
* viem's defaults leave a single `eth_call` able to hang for a long time behind
|
|
21
|
+
* three backing-off retries, which is how a `status` run reached two minutes
|
|
22
|
+
* with nothing on screen. Bounding it here bounds every read and every
|
|
23
|
+
* simulation the SDK performs, in one place.
|
|
24
|
+
*/
|
|
25
|
+
function rpcTransport(config) {
|
|
26
|
+
return http(config.rpcUrl, {
|
|
27
|
+
timeout: RPC_TIMEOUT_MS,
|
|
28
|
+
retryCount: RPC_RETRY_COUNT,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
/** Shared `MetrikClient` construction: one escrow, declared as V2 on both keys. */
|
|
32
|
+
function createMetrikClient(config, account, transport) {
|
|
33
|
+
return new MetrikClient({
|
|
34
|
+
chain: config.chain,
|
|
35
|
+
transport: transport ?? rpcTransport(config),
|
|
36
|
+
escrow: config.escrow,
|
|
37
|
+
// Declared on BOTH keys: without `escrowV2` the SDK routes reads and
|
|
38
|
+
// settlement through the legacy V1 ABI, which reverts against
|
|
39
|
+
// StreamEscrowV2 (its one-argument views were replaced by proof-carrying
|
|
40
|
+
// ones, and `reclaim` becomes `reclaimWithProof`).
|
|
41
|
+
escrowV2: config.escrow,
|
|
42
|
+
usdc: config.usdc,
|
|
43
|
+
oracleBaseUrl: config.oracleBaseUrl,
|
|
44
|
+
settlementTarget: { chainId: config.chainId, escrow: config.escrow },
|
|
45
|
+
...(account === undefined ? {} : { account }),
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
export const defaultCliDependencies = {
|
|
49
|
+
createReadClient(config) {
|
|
50
|
+
const metrik = createMetrikClient(config);
|
|
51
|
+
return {
|
|
52
|
+
async getChainId() {
|
|
53
|
+
return await metrik.publicClient.getChainId();
|
|
54
|
+
},
|
|
55
|
+
async getStreamV2(streamId) {
|
|
56
|
+
return await metrik.getStreamV2(streamId);
|
|
57
|
+
},
|
|
58
|
+
async checkpointProof(streamId) {
|
|
59
|
+
// Not an RPC call: this is an HTTP fetch against the oracle, so the
|
|
60
|
+
// transport budget above does not cover it.
|
|
61
|
+
return await withReadTimeout(async () => await metrik.checkpointProof(streamId), `the oracle at ${config.oracleBaseUrl}`);
|
|
62
|
+
},
|
|
63
|
+
async claimableForV2(streamId, cumulativeAmount) {
|
|
64
|
+
return await metrik.claimableForV2(streamId, cumulativeAmount);
|
|
65
|
+
},
|
|
66
|
+
async reclaimableForV2(streamId, cumulativeAmount) {
|
|
67
|
+
return await metrik.reclaimableForV2(streamId, cumulativeAmount);
|
|
68
|
+
},
|
|
69
|
+
async nativeBalance(address) {
|
|
70
|
+
return await metrik.publicClient.getBalance({ address });
|
|
71
|
+
},
|
|
72
|
+
async usdcBalance(address) {
|
|
73
|
+
return await metrik.publicClient.readContract({
|
|
74
|
+
address: config.usdc,
|
|
75
|
+
abi: erc20Abi,
|
|
76
|
+
functionName: "balanceOf",
|
|
77
|
+
args: [address],
|
|
78
|
+
});
|
|
79
|
+
},
|
|
80
|
+
async blockNumber() {
|
|
81
|
+
return await metrik.publicClient.getBlockNumber();
|
|
82
|
+
},
|
|
83
|
+
async streamOpenedLogs({ role, address, fromBlock, toBlock }) {
|
|
84
|
+
const logs = await metrik.publicClient.getLogs({
|
|
85
|
+
address: config.escrow,
|
|
86
|
+
event: STREAM_OPENED_EVENT,
|
|
87
|
+
args: { [role]: address },
|
|
88
|
+
fromBlock,
|
|
89
|
+
toBlock,
|
|
90
|
+
});
|
|
91
|
+
// Returned as-is: the topic filter is evaluated by the node, so
|
|
92
|
+
// re-checking `log.args.buyer === address` here would imply the filter
|
|
93
|
+
// is decorative and would hide a mis-built filter behind a second pass.
|
|
94
|
+
// A wrong filter should produce a visibly wrong result, not a quietly
|
|
95
|
+
// correct one.
|
|
96
|
+
return logs.flatMap((log) => log.args.streamId === undefined ||
|
|
97
|
+
log.args.buyer === undefined ||
|
|
98
|
+
log.args.operator === undefined ||
|
|
99
|
+
log.args.serviceRef === undefined ||
|
|
100
|
+
log.args.deposit === undefined ||
|
|
101
|
+
log.args.ratePerSecond === undefined ||
|
|
102
|
+
log.args.expiresAt === undefined
|
|
103
|
+
? []
|
|
104
|
+
: [
|
|
105
|
+
{
|
|
106
|
+
streamId: log.args.streamId,
|
|
107
|
+
buyer: log.args.buyer,
|
|
108
|
+
operator: log.args.operator,
|
|
109
|
+
serviceRef: log.args.serviceRef,
|
|
110
|
+
deposit: log.args.deposit,
|
|
111
|
+
ratePerSecond: log.args.ratePerSecond,
|
|
112
|
+
expiresAt: Number(log.args.expiresAt),
|
|
113
|
+
blockNumber: log.blockNumber ?? 0n,
|
|
114
|
+
},
|
|
115
|
+
]);
|
|
116
|
+
},
|
|
117
|
+
async escrowLogCountAt(block) {
|
|
118
|
+
const logs = await metrik.publicClient.getLogs({
|
|
119
|
+
address: config.escrow,
|
|
120
|
+
fromBlock: block,
|
|
121
|
+
toBlock: block,
|
|
122
|
+
});
|
|
123
|
+
return logs.length;
|
|
124
|
+
},
|
|
125
|
+
async protocolFeeBps() {
|
|
126
|
+
const bps = await metrik.publicClient.readContract({
|
|
127
|
+
address: config.escrow,
|
|
128
|
+
abi: streamEscrowV2Abi,
|
|
129
|
+
functionName: "protocolFeeBps",
|
|
130
|
+
});
|
|
131
|
+
return Number(bps);
|
|
132
|
+
},
|
|
133
|
+
async escapeGraceSeconds() {
|
|
134
|
+
const seconds = await metrik.publicClient.readContract({
|
|
135
|
+
address: config.escrow,
|
|
136
|
+
abi: streamEscrowV2Abi,
|
|
137
|
+
functionName: "escapeGraceSeconds",
|
|
138
|
+
});
|
|
139
|
+
return Number(seconds);
|
|
140
|
+
},
|
|
141
|
+
async latestCheckpointCheckedAt() {
|
|
142
|
+
const checkedAt = await metrik.publicClient.readContract({
|
|
143
|
+
address: config.escrow,
|
|
144
|
+
abi: streamEscrowV2Abi,
|
|
145
|
+
functionName: "latestCheckpointCheckedAt",
|
|
146
|
+
});
|
|
147
|
+
return Number(checkedAt);
|
|
148
|
+
},
|
|
149
|
+
async latestBlockTimestamp() {
|
|
150
|
+
const block = await metrik.publicClient.getBlock();
|
|
151
|
+
return Number(block.timestamp);
|
|
152
|
+
},
|
|
153
|
+
async oracleSigners() {
|
|
154
|
+
return await metrik.publicClient.readContract({
|
|
155
|
+
address: config.escrow,
|
|
156
|
+
abi: streamEscrowV2Abi,
|
|
157
|
+
functionName: "getOracleSigners",
|
|
158
|
+
});
|
|
159
|
+
},
|
|
160
|
+
};
|
|
161
|
+
},
|
|
162
|
+
createWriteClient(config, account, options) {
|
|
163
|
+
// A Privy wallet's provider IS the transport (see CreateWriteClientOptions);
|
|
164
|
+
// every other wallet keeps the plain bounded HTTP transport.
|
|
165
|
+
const transport = options?.transport ?? rpcTransport(config);
|
|
166
|
+
const clientConfig = {
|
|
167
|
+
chain: config.chain,
|
|
168
|
+
transport,
|
|
169
|
+
escrow: config.escrow,
|
|
170
|
+
escrowV2: config.escrow,
|
|
171
|
+
usdc: config.usdc,
|
|
172
|
+
oracleBaseUrl: config.oracleBaseUrl,
|
|
173
|
+
settlementTarget: { chainId: config.chainId, escrow: config.escrow },
|
|
174
|
+
...(account === null ? {} : { account }),
|
|
175
|
+
};
|
|
176
|
+
// The mandate-gated agent client owns every fund-moving call; the raw SDK
|
|
177
|
+
// client is used only for the build-only `--dry-run` preview, which
|
|
178
|
+
// broadcasts nothing.
|
|
179
|
+
const agentClient = new VerifiedStreamAgentClient(clientConfig);
|
|
180
|
+
const metrik = createMetrikClient(config, account === null ? undefined : account, transport);
|
|
181
|
+
return {
|
|
182
|
+
async buildHireTx(input) {
|
|
183
|
+
return await metrik.buildHireTx(input);
|
|
184
|
+
},
|
|
185
|
+
async openVerifiedStream({ signedMandate, ...input }) {
|
|
186
|
+
// No mandate means a policy-enforced wallet: the ceiling was already
|
|
187
|
+
// checked against the broker's own `/v1/config` before we got here, and
|
|
188
|
+
// the broker checks it AGAIN server-side on the transaction it signs.
|
|
189
|
+
// Going straight at the SDK client is the same path the SDK-driven
|
|
190
|
+
// (non-CLI) flow has always used.
|
|
191
|
+
if (signedMandate === null) {
|
|
192
|
+
return await metrik.hireVerifiedService({
|
|
193
|
+
operator: input.operator,
|
|
194
|
+
serviceRef: input.serviceRef,
|
|
195
|
+
budgetUsdc: input.budgetUsdc,
|
|
196
|
+
ratePerSecond: input.ratePerSecondUsdc,
|
|
197
|
+
maxDurationSeconds: input.maxDurationSeconds,
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
return await agentClient.openVerifiedStream({
|
|
201
|
+
...input,
|
|
202
|
+
signedMandate,
|
|
203
|
+
});
|
|
204
|
+
},
|
|
205
|
+
async closeStream({ signedMandate, ...input }) {
|
|
206
|
+
if (signedMandate === null)
|
|
207
|
+
return await metrik.close(input.streamId);
|
|
208
|
+
return await agentClient.closeStream({ ...input, signedMandate });
|
|
209
|
+
},
|
|
210
|
+
async reclaimStream({ signedMandate, ...input }) {
|
|
211
|
+
if (signedMandate === null) {
|
|
212
|
+
const closeResult = input.closeFirst
|
|
213
|
+
? await metrik.close(input.streamId)
|
|
214
|
+
: null;
|
|
215
|
+
return {
|
|
216
|
+
closeResult,
|
|
217
|
+
reclaimResult: await metrik.reclaim(input.streamId),
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
return await agentClient.reclaimStream({ ...input, signedMandate });
|
|
221
|
+
},
|
|
222
|
+
async reclaimUnverifiedStream({ signedMandate, ...input }) {
|
|
223
|
+
if (signedMandate === null) {
|
|
224
|
+
return await metrik.reclaimUnverified(input.streamId);
|
|
225
|
+
}
|
|
226
|
+
return await agentClient.reclaimUnverifiedStream({
|
|
227
|
+
...input,
|
|
228
|
+
signedMandate,
|
|
229
|
+
});
|
|
230
|
+
},
|
|
231
|
+
async claimStream({ signedMandate, ...input }) {
|
|
232
|
+
if (signedMandate === null)
|
|
233
|
+
return await metrik.claim(input.streamId);
|
|
234
|
+
return await agentClient.claimStream({ ...input, signedMandate });
|
|
235
|
+
},
|
|
236
|
+
};
|
|
237
|
+
},
|
|
238
|
+
async discover(options) {
|
|
239
|
+
return await discoverServicesDetailed(options);
|
|
240
|
+
},
|
|
241
|
+
async invoke(streamId, request, options) {
|
|
242
|
+
return await sdkInvoke(streamId, request, options);
|
|
243
|
+
},
|
|
244
|
+
createInvokeStreamReader(config) {
|
|
245
|
+
const metrik = createMetrikClient(config);
|
|
246
|
+
return {
|
|
247
|
+
async getStreamV2(streamId) {
|
|
248
|
+
const stream = await metrik.getStreamV2(streamId);
|
|
249
|
+
return {
|
|
250
|
+
buyer: stream.buyer,
|
|
251
|
+
operator: stream.operator,
|
|
252
|
+
serviceRef: stream.serviceRef,
|
|
253
|
+
status: stream.status,
|
|
254
|
+
expiresAt: stream.expiresAt,
|
|
255
|
+
};
|
|
256
|
+
},
|
|
257
|
+
};
|
|
258
|
+
},
|
|
259
|
+
nowSeconds() {
|
|
260
|
+
return Math.floor(Date.now() / 1000);
|
|
261
|
+
},
|
|
262
|
+
async sleep(ms) {
|
|
263
|
+
await new Promise((resolve) => setTimeout(resolve, ms));
|
|
264
|
+
},
|
|
265
|
+
};
|
|
266
|
+
/**
|
|
267
|
+
* The write-client options a resolved wallet implies.
|
|
268
|
+
*
|
|
269
|
+
* Kept next to {@link CreateWriteClientOptions} so every fund-moving command
|
|
270
|
+
* spells the transport decision the same way, and so a wallet that needs a
|
|
271
|
+
* provider transport cannot be broadcast through a plain RPC by a command that
|
|
272
|
+
* simply forgot to pass it.
|
|
273
|
+
*/
|
|
274
|
+
export function writeClientOptions(wallet) {
|
|
275
|
+
return wallet?.transport === undefined ? {} : { transport: wallet.transport };
|
|
276
|
+
}
|
|
277
|
+
//# sourceMappingURL=deps.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deps.js","sourceRoot":"","sources":["../../src/cli/deps.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { SignedServiceBinding, SignedServiceDescriptor } from "@absol-labs/shared";
|
|
2
|
+
import type { DiscoveredService } from "../discovery/registry.js";
|
|
3
|
+
/**
|
|
4
|
+
* What a listing's SIGNED descriptor already tells a newcomer — surfaced rather
|
|
5
|
+
* than discarded.
|
|
6
|
+
*
|
|
7
|
+
* The registry's signed records carry the callable endpoints, one worked example
|
|
8
|
+
* call, and the operator's accepted rate band. `metrik discover` used to project
|
|
9
|
+
* them away, so the CLI could show a `serviceRef` but never what the service
|
|
10
|
+
* DOES, what path to call, or what `--rate` the operator will accept. Everything
|
|
11
|
+
* here is read from the record whose signature was already recovered and
|
|
12
|
+
* matched, so nothing unsigned is ever presented as fact.
|
|
13
|
+
*/
|
|
14
|
+
export interface ListingEndpoint {
|
|
15
|
+
readonly name: string;
|
|
16
|
+
readonly path: string;
|
|
17
|
+
readonly method: string;
|
|
18
|
+
readonly description: string | null;
|
|
19
|
+
}
|
|
20
|
+
export interface ListingExample {
|
|
21
|
+
readonly endpoint: string;
|
|
22
|
+
readonly description: string | null;
|
|
23
|
+
readonly request: unknown;
|
|
24
|
+
readonly response: unknown;
|
|
25
|
+
}
|
|
26
|
+
export interface ListingRates {
|
|
27
|
+
/** USDC base units per second, as signed (decimal strings, never floats). */
|
|
28
|
+
readonly minRatePerSecond: string | null;
|
|
29
|
+
readonly maxRatePerSecond: string | null;
|
|
30
|
+
readonly currency: string | null;
|
|
31
|
+
readonly slaDescription: string | null;
|
|
32
|
+
readonly refundPolicy: string | null;
|
|
33
|
+
}
|
|
34
|
+
export interface ListingDetail {
|
|
35
|
+
readonly endpoints: readonly ListingEndpoint[];
|
|
36
|
+
readonly example: ListingExample | null;
|
|
37
|
+
readonly rates: ListingRates | null;
|
|
38
|
+
readonly authModel: string | null;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Project the signed record onto the presentable detail. A legacy binding (which
|
|
42
|
+
* carries no interface at all) yields empty detail rather than an invented one.
|
|
43
|
+
*/
|
|
44
|
+
export declare function listingDetail(signed: SignedServiceBinding | SignedServiceDescriptor | undefined): ListingDetail;
|
|
45
|
+
/**
|
|
46
|
+
* How much verification a listing actually declares. Used to order `discover`
|
|
47
|
+
* strongest-first so `--limit 1` returns the best-attested listing rather than
|
|
48
|
+
* whatever the registry happened to serve first — which is how a newcomer's very
|
|
49
|
+
* first result ended up being a deliberately-failing test fixture.
|
|
50
|
+
*
|
|
51
|
+
* This ranks the DECLARED verification spec, which is the only thing the signed
|
|
52
|
+
* record can tell us. It is a presentation order, not a trust score.
|
|
53
|
+
*/
|
|
54
|
+
export declare function verificationStrength(service: DiscoveredService): number;
|
|
55
|
+
/**
|
|
56
|
+
* Deterministic, strongest-verification-first order. Ties break on `serviceRef`
|
|
57
|
+
* so the same registry always renders in the same order and `--limit N` is
|
|
58
|
+
* reproducible between runs.
|
|
59
|
+
*/
|
|
60
|
+
export declare function orderListings<T extends DiscoveredService>(services: readonly T[]): T[];
|
|
61
|
+
//# sourceMappingURL=descriptor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"descriptor.d.ts","sourceRoot":"","sources":["../../src/cli/descriptor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,oBAAoB,EACpB,uBAAuB,EACxB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAElE;;;;;;;;;;GAUG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,YAAY;IAC3B,6EAA6E;IAC7E,QAAQ,CAAC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IACzC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IACzC,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CACtC;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,SAAS,EAAE,SAAS,eAAe,EAAE,CAAC;IAC/C,QAAQ,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI,CAAC;IACxC,QAAQ,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAAC;IACpC,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;AASD;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,oBAAoB,GAAG,uBAAuB,GAAG,SAAS,GACjE,aAAa,CAmCf;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,iBAAiB,GAAG,MAAM,CASvE;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,iBAAiB,EACvD,QAAQ,EAAE,SAAS,CAAC,EAAE,GACrB,CAAC,EAAE,CAOL"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
const EMPTY_DETAIL = {
|
|
2
|
+
endpoints: [],
|
|
3
|
+
example: null,
|
|
4
|
+
rates: null,
|
|
5
|
+
authModel: null,
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Project the signed record onto the presentable detail. A legacy binding (which
|
|
9
|
+
* carries no interface at all) yields empty detail rather than an invented one.
|
|
10
|
+
*/
|
|
11
|
+
export function listingDetail(signed) {
|
|
12
|
+
const descriptor = signed
|
|
13
|
+
?.descriptor;
|
|
14
|
+
if (descriptor === undefined)
|
|
15
|
+
return EMPTY_DETAIL;
|
|
16
|
+
const iface = descriptor.interface;
|
|
17
|
+
const commercial = descriptor.commercial;
|
|
18
|
+
return {
|
|
19
|
+
endpoints: (iface?.endpoints ?? []).map((endpoint) => ({
|
|
20
|
+
name: endpoint.name,
|
|
21
|
+
path: endpoint.path,
|
|
22
|
+
method: endpoint.method,
|
|
23
|
+
description: endpoint.description ?? null,
|
|
24
|
+
})),
|
|
25
|
+
example: iface?.example === undefined
|
|
26
|
+
? null
|
|
27
|
+
: {
|
|
28
|
+
endpoint: iface.example.endpoint,
|
|
29
|
+
description: iface.example.description ?? null,
|
|
30
|
+
request: iface.example.request ?? null,
|
|
31
|
+
response: iface.example.response ?? null,
|
|
32
|
+
},
|
|
33
|
+
rates: commercial === undefined
|
|
34
|
+
? null
|
|
35
|
+
: {
|
|
36
|
+
minRatePerSecond: commercial.minRatePerSecond ?? null,
|
|
37
|
+
maxRatePerSecond: commercial.maxRatePerSecond ?? null,
|
|
38
|
+
currency: commercial.currency ?? null,
|
|
39
|
+
slaDescription: commercial.slaDescription ?? null,
|
|
40
|
+
refundPolicy: commercial.refundPolicy ?? null,
|
|
41
|
+
},
|
|
42
|
+
authModel: iface?.authModel ?? null,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* How much verification a listing actually declares. Used to order `discover`
|
|
47
|
+
* strongest-first so `--limit 1` returns the best-attested listing rather than
|
|
48
|
+
* whatever the registry happened to serve first — which is how a newcomer's very
|
|
49
|
+
* first result ended up being a deliberately-failing test fixture.
|
|
50
|
+
*
|
|
51
|
+
* This ranks the DECLARED verification spec, which is the only thing the signed
|
|
52
|
+
* record can tell us. It is a presentation order, not a trust score.
|
|
53
|
+
*/
|
|
54
|
+
export function verificationStrength(service) {
|
|
55
|
+
const summary = service.verification;
|
|
56
|
+
if (summary === null)
|
|
57
|
+
return 0;
|
|
58
|
+
return ((summary.hasReexec ? 8 : 0) +
|
|
59
|
+
(summary.hasSchema ? 4 : 0) +
|
|
60
|
+
(summary.hasSla ? 2 : 0) +
|
|
61
|
+
Math.min(summary.canaries, 1));
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Deterministic, strongest-verification-first order. Ties break on `serviceRef`
|
|
65
|
+
* so the same registry always renders in the same order and `--limit N` is
|
|
66
|
+
* reproducible between runs.
|
|
67
|
+
*/
|
|
68
|
+
export function orderListings(services) {
|
|
69
|
+
return [...services].sort((left, right) => {
|
|
70
|
+
if (left.tier !== right.tier)
|
|
71
|
+
return right.tier - left.tier;
|
|
72
|
+
const strength = verificationStrength(right) - verificationStrength(left);
|
|
73
|
+
if (strength !== 0)
|
|
74
|
+
return strength;
|
|
75
|
+
return left.serviceRef.localeCompare(right.serviceRef);
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=descriptor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"descriptor.js","sourceRoot":"","sources":["../../src/cli/descriptor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI error taxonomy. Every expected failure surfaces as a `CliError` so the
|
|
3
|
+
* runner can print one actionable line instead of a viem/zod stack dump, and so
|
|
4
|
+
* a script can branch on the exit code.
|
|
5
|
+
*/
|
|
6
|
+
export type CliExitCode =
|
|
7
|
+
/** Bad flags, missing arguments, unparseable amounts. */
|
|
8
|
+
2
|
|
9
|
+
/** Configuration refused: wrong chain, missing key, mainnet target. */
|
|
10
|
+
| 3
|
|
11
|
+
/** The operation itself failed (RPC, registry, escrow revert, HTTP). */
|
|
12
|
+
| 4;
|
|
13
|
+
export declare class CliError extends Error {
|
|
14
|
+
readonly exitCode: CliExitCode;
|
|
15
|
+
/** Optional next step printed under the message in human mode. */
|
|
16
|
+
readonly hint: string | undefined;
|
|
17
|
+
constructor(message: string, options?: {
|
|
18
|
+
readonly exitCode?: CliExitCode;
|
|
19
|
+
readonly hint?: string;
|
|
20
|
+
readonly cause?: unknown;
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
/** Usage error: the caller typed something the CLI cannot act on. */
|
|
24
|
+
export declare function usageError(message: string, hint?: string): CliError;
|
|
25
|
+
/** Configuration error: the environment/flags describe a target we refuse. */
|
|
26
|
+
export declare function configError(message: string, hint?: string): CliError;
|
|
27
|
+
/**
|
|
28
|
+
* Unwrap the most useful message from an arbitrary thrown value.
|
|
29
|
+
*
|
|
30
|
+
* Boilerplate links are dropped once something in the chain has already named
|
|
31
|
+
* the revert; when nothing has, ONE is kept, because "it reverted" is then the
|
|
32
|
+
* only fact available and losing it would leave a bare "close failed".
|
|
33
|
+
*/
|
|
34
|
+
export declare function describeError(error: unknown): string;
|
|
35
|
+
/** Exported for the test that pins the shape of the chain, not the wording. */
|
|
36
|
+
export declare function stripRedundantBoilerplate(chain: readonly string[]): readonly string[];
|
|
37
|
+
/**
|
|
38
|
+
* Tidy one message line for display.
|
|
39
|
+
*
|
|
40
|
+
* viem renders an undecodable revert payload as `Execution reverted with
|
|
41
|
+
* reason: <the raw bytes as text>`, which arrives as mojibake glued to the end
|
|
42
|
+
* of an otherwise excellent error ("… Execution reverted with reason: ׃.x."). A
|
|
43
|
+
* revert reason that is not printable ASCII carries no information for a reader,
|
|
44
|
+
* so the unreadable tail is dropped and the useful prefix kept. Legitimate
|
|
45
|
+
* reasons — which are ASCII strings the contract author wrote — are untouched.
|
|
46
|
+
*/
|
|
47
|
+
export declare function presentMessage(raw: string): string;
|
|
48
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/cli/errors.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,MAAM,WAAW;AACrB,yDAAyD;AACvD,CAAC;AACH,uEAAuE;GACrE,CAAC;AACH,wEAAwE;GACtE,CAAC,CAAC;AAEN,qBAAa,QAAS,SAAQ,KAAK;IACjC,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;IAC/B,kEAAkE;IAClE,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;gBAGhC,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;QACP,QAAQ,CAAC,QAAQ,CAAC,EAAE,WAAW,CAAC;QAChC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;KACrB;CAOT;AAED,qEAAqE;AACrE,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,QAAQ,CAKnE;AAED,8EAA8E;AAC9E,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,QAAQ,CAKpE;AAmCD;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAcpD;AAED,+EAA+E;AAC/E,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,SAAS,MAAM,EAAE,GACvB,SAAS,MAAM,EAAE,CAenB;AAaD;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAelD"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
export class CliError extends Error {
|
|
2
|
+
exitCode;
|
|
3
|
+
/** Optional next step printed under the message in human mode. */
|
|
4
|
+
hint;
|
|
5
|
+
constructor(message, options = {}) {
|
|
6
|
+
super(message, options.cause === undefined ? {} : { cause: options.cause });
|
|
7
|
+
this.name = "CliError";
|
|
8
|
+
this.exitCode = options.exitCode ?? 4;
|
|
9
|
+
this.hint = options.hint;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
/** Usage error: the caller typed something the CLI cannot act on. */
|
|
13
|
+
export function usageError(message, hint) {
|
|
14
|
+
return new CliError(message, {
|
|
15
|
+
exitCode: 2,
|
|
16
|
+
...(hint === undefined ? {} : { hint }),
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
/** Configuration error: the environment/flags describe a target we refuse. */
|
|
20
|
+
export function configError(message, hint) {
|
|
21
|
+
return new CliError(message, {
|
|
22
|
+
exitCode: 3,
|
|
23
|
+
...(hint === undefined ? {} : { hint }),
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* viem's generic tail. Each of these is true and each carries zero information
|
|
28
|
+
* once an outer link has already named the revert:
|
|
29
|
+
*
|
|
30
|
+
* NothingToReclaim() — …this will not change on retry:
|
|
31
|
+
* The contract function "reclaim" reverted.:
|
|
32
|
+
* Execution reverted for an unknown reason.
|
|
33
|
+
*
|
|
34
|
+
* The message names the reason and then says the reason is unknown. Matched
|
|
35
|
+
* against a WHOLE link, so a message that merely contains one of these phrases
|
|
36
|
+
* alongside real detail is never dropped.
|
|
37
|
+
*/
|
|
38
|
+
const VIEM_BOILERPLATE = [
|
|
39
|
+
/^The contract function "[^"]*" reverted\.?$/,
|
|
40
|
+
/^Execution reverted for an unknown reason\.?$/,
|
|
41
|
+
/^Execution reverted\.?$/,
|
|
42
|
+
/^Execution reverted\.? \(the revert payload is not a readable reason string\)$/,
|
|
43
|
+
/^An unknown RPC error occurred\.?$/,
|
|
44
|
+
];
|
|
45
|
+
/** Does this link name a concrete revert — a custom error, reason or panic? */
|
|
46
|
+
function namesTheRevert(line) {
|
|
47
|
+
return (/\b[A-Z][A-Za-z0-9]*\([^)]*\)/.test(line) ||
|
|
48
|
+
/\breverted:/.test(line) ||
|
|
49
|
+
/\bpanicked with code\b/.test(line));
|
|
50
|
+
}
|
|
51
|
+
function isBoilerplate(line) {
|
|
52
|
+
return VIEM_BOILERPLATE.some((pattern) => pattern.test(line));
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Unwrap the most useful message from an arbitrary thrown value.
|
|
56
|
+
*
|
|
57
|
+
* Boilerplate links are dropped once something in the chain has already named
|
|
58
|
+
* the revert; when nothing has, ONE is kept, because "it reverted" is then the
|
|
59
|
+
* only fact available and losing it would leave a bare "close failed".
|
|
60
|
+
*/
|
|
61
|
+
export function describeError(error) {
|
|
62
|
+
if (error instanceof Error) {
|
|
63
|
+
const chain = [];
|
|
64
|
+
for (let current = error, depth = 0; depth < 4; depth++) {
|
|
65
|
+
if (!(current instanceof Error))
|
|
66
|
+
break;
|
|
67
|
+
const line = presentMessage(current.message.split("\n")[0] ?? "");
|
|
68
|
+
if (line.length > 0 && !chain.includes(line)) {
|
|
69
|
+
chain.push(line);
|
|
70
|
+
}
|
|
71
|
+
current = current.cause;
|
|
72
|
+
}
|
|
73
|
+
return stripRedundantBoilerplate(chain).join(": ");
|
|
74
|
+
}
|
|
75
|
+
return presentMessage(String(error));
|
|
76
|
+
}
|
|
77
|
+
/** Exported for the test that pins the shape of the chain, not the wording. */
|
|
78
|
+
export function stripRedundantBoilerplate(chain) {
|
|
79
|
+
const decoded = chain.some((line) => namesTheRevert(line) && !isBoilerplate(line));
|
|
80
|
+
let keptBoilerplate = false;
|
|
81
|
+
const kept = chain.filter((line, index) => {
|
|
82
|
+
if (!isBoilerplate(line))
|
|
83
|
+
return true;
|
|
84
|
+
// The first link is the thrown error's own message: never dropped, or a
|
|
85
|
+
// failure whose entire message is boilerplate would print as nothing.
|
|
86
|
+
if (index === 0)
|
|
87
|
+
return true;
|
|
88
|
+
if (decoded || keptBoilerplate)
|
|
89
|
+
return false;
|
|
90
|
+
keptBoilerplate = true;
|
|
91
|
+
return true;
|
|
92
|
+
});
|
|
93
|
+
return kept.length > 0 ? kept : chain;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Internal SDK method names that mean nothing to someone running a CLI. The
|
|
97
|
+
* message is otherwise good, so the name is rewritten rather than the whole line
|
|
98
|
+
* discarded. `getStreamV2` in particular is an SDK METHOD, not a contract
|
|
99
|
+
* function — printing it invites a reader to go looking for it on the escrow.
|
|
100
|
+
*/
|
|
101
|
+
const INTERNAL_NAMES = [
|
|
102
|
+
[/\bgetStreamV2 failed for stream\b/g, "could not read stream"],
|
|
103
|
+
[/\bgetStream failed for stream\b/g, "could not read stream"],
|
|
104
|
+
];
|
|
105
|
+
/**
|
|
106
|
+
* Tidy one message line for display.
|
|
107
|
+
*
|
|
108
|
+
* viem renders an undecodable revert payload as `Execution reverted with
|
|
109
|
+
* reason: <the raw bytes as text>`, which arrives as mojibake glued to the end
|
|
110
|
+
* of an otherwise excellent error ("… Execution reverted with reason: ׃.x."). A
|
|
111
|
+
* revert reason that is not printable ASCII carries no information for a reader,
|
|
112
|
+
* so the unreadable tail is dropped and the useful prefix kept. Legitimate
|
|
113
|
+
* reasons — which are ASCII strings the contract author wrote — are untouched.
|
|
114
|
+
*/
|
|
115
|
+
export function presentMessage(raw) {
|
|
116
|
+
let message = raw.trim();
|
|
117
|
+
for (const [pattern, replacement] of INTERNAL_NAMES) {
|
|
118
|
+
message = message.replace(pattern, replacement);
|
|
119
|
+
}
|
|
120
|
+
message = message.replace(/(Execution reverted with reason:)\s*(.*)$/, (whole, prefix, reason) => {
|
|
121
|
+
const trimmed = reason.trim();
|
|
122
|
+
if (trimmed.length >= 3 && /^[\x20-\x7e]+$/.test(trimmed))
|
|
123
|
+
return whole;
|
|
124
|
+
return `${prefix.replace(/ with reason:$/, ".")} (the revert payload is not a readable reason string)`;
|
|
125
|
+
});
|
|
126
|
+
// Strip control characters wherever they survived: they corrupt a terminal.
|
|
127
|
+
return message.replace(/[\u0000-\u001f\u007f-\u009f]/g, "").trim();
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/cli/errors.ts"],"names":[],"mappings":"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"}
|