@absol-labs/agent 0.11.0 → 0.12.0-rc.2
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 +43 -51
- package/dist/capability/invocation-capability.d.ts +2 -2
- package/dist/capability/probe-capability.d.ts +225 -0
- package/dist/capability/probe-capability.d.ts.map +1 -0
- package/dist/capability/probe-capability.js +248 -0
- package/dist/capability/probe-capability.js.map +1 -0
- package/dist/cli/args.d.ts +11 -0
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +23 -0
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/commands/claim.d.ts +32 -0
- package/dist/cli/commands/claim.d.ts.map +1 -1
- package/dist/cli/commands/claim.js +116 -28
- package/dist/cli/commands/claim.js.map +1 -1
- package/dist/cli/commands/close.d.ts.map +1 -1
- package/dist/cli/commands/close.js +35 -3
- package/dist/cli/commands/close.js.map +1 -1
- package/dist/cli/commands/invoke.d.ts +2 -0
- package/dist/cli/commands/invoke.d.ts.map +1 -1
- package/dist/cli/commands/invoke.js +2 -2
- package/dist/cli/commands/invoke.js.map +1 -1
- package/dist/cli/commands/mcp.d.ts.map +1 -1
- package/dist/cli/commands/mcp.js +15 -2
- package/dist/cli/commands/mcp.js.map +1 -1
- package/dist/cli/commands/open.d.ts.map +1 -1
- package/dist/cli/commands/open.js +58 -4
- package/dist/cli/commands/open.js.map +1 -1
- package/dist/cli/commands/pay.d.ts +34 -0
- package/dist/cli/commands/pay.d.ts.map +1 -0
- package/dist/cli/commands/pay.js +479 -0
- package/dist/cli/commands/pay.js.map +1 -0
- package/dist/cli/commands/reclaim-unverified.d.ts.map +1 -1
- package/dist/cli/commands/reclaim-unverified.js +3 -2
- package/dist/cli/commands/reclaim-unverified.js.map +1 -1
- package/dist/cli/commands/reclaim.d.ts +23 -2
- package/dist/cli/commands/reclaim.d.ts.map +1 -1
- package/dist/cli/commands/reclaim.js +204 -20
- package/dist/cli/commands/reclaim.js.map +1 -1
- package/dist/cli/commands/refund.d.ts +31 -0
- package/dist/cli/commands/refund.d.ts.map +1 -0
- package/dist/cli/commands/refund.js +397 -0
- package/dist/cli/commands/refund.js.map +1 -0
- package/dist/cli/commands/status.d.ts.map +1 -1
- package/dist/cli/commands/status.js +21 -2
- package/dist/cli/commands/status.js.map +1 -1
- package/dist/cli/commands/streams.js +8 -12
- package/dist/cli/commands/streams.js.map +1 -1
- package/dist/cli/commands/watch.d.ts.map +1 -1
- package/dist/cli/commands/watch.js +4 -1
- package/dist/cli/commands/watch.js.map +1 -1
- package/dist/cli/config.d.ts +44 -26
- package/dist/cli/config.d.ts.map +1 -1
- package/dist/cli/config.js +88 -38
- package/dist/cli/config.js.map +1 -1
- package/dist/cli/context.d.ts +19 -0
- package/dist/cli/context.d.ts.map +1 -1
- package/dist/cli/deps.d.ts +53 -0
- package/dist/cli/deps.d.ts.map +1 -1
- package/dist/cli/deps.js +51 -1
- package/dist/cli/deps.js.map +1 -1
- package/dist/cli/errors.d.ts.map +1 -1
- package/dist/cli/errors.js +21 -1
- package/dist/cli/errors.js.map +1 -1
- package/dist/cli/escape-hatch.d.ts +6 -4
- package/dist/cli/escape-hatch.d.ts.map +1 -1
- package/dist/cli/escape-hatch.js +6 -2
- package/dist/cli/escape-hatch.js.map +1 -1
- package/dist/cli/listings.d.ts +18 -0
- package/dist/cli/listings.d.ts.map +1 -1
- package/dist/cli/listings.js +22 -12
- package/dist/cli/listings.js.map +1 -1
- package/dist/cli/preflight.d.ts +20 -14
- package/dist/cli/preflight.d.ts.map +1 -1
- package/dist/cli/preflight.js +34 -20
- package/dist/cli/preflight.js.map +1 -1
- package/dist/cli/privy.d.ts.map +1 -1
- package/dist/cli/privy.js +4 -2
- package/dist/cli/privy.js.map +1 -1
- package/dist/cli/progress.d.ts +13 -1
- package/dist/cli/progress.d.ts.map +1 -1
- package/dist/cli/progress.js +7 -1
- package/dist/cli/progress.js.map +1 -1
- package/dist/cli/reclaimability.d.ts +82 -0
- package/dist/cli/reclaimability.d.ts.map +1 -0
- package/dist/cli/reclaimability.js +80 -0
- package/dist/cli/reclaimability.js.map +1 -0
- package/dist/cli/run.d.ts +2 -1
- package/dist/cli/run.d.ts.map +1 -1
- package/dist/cli/run.js +62 -21
- package/dist/cli/run.js.map +1 -1
- package/dist/cli/scan-range.d.ts +2 -2
- package/dist/cli/scan-range.js +2 -2
- package/dist/cli/status.d.ts +106 -1
- package/dist/cli/status.d.ts.map +1 -1
- package/dist/cli/status.js +325 -44
- package/dist/cli/status.js.map +1 -1
- package/dist/cli/wallet.d.ts +2 -2
- package/dist/cli/wallet.d.ts.map +1 -1
- package/dist/cli/wallet.js +29 -5
- package/dist/cli/wallet.js.map +1 -1
- package/dist/discovery/rate-band.d.ts +74 -0
- package/dist/discovery/rate-band.d.ts.map +1 -0
- package/dist/discovery/rate-band.js +114 -0
- package/dist/discovery/rate-band.js.map +1 -0
- package/dist/escrow-generation.d.ts +81 -0
- package/dist/escrow-generation.d.ts.map +1 -0
- package/dist/escrow-generation.js +76 -0
- package/dist/escrow-generation.js.map +1 -0
- package/dist/frameworks/agentkit.d.ts +8 -4
- package/dist/frameworks/agentkit.d.ts.map +1 -1
- package/dist/frameworks/agentkit.js +27 -10
- package/dist/frameworks/agentkit.js.map +1 -1
- package/dist/frameworks/eliza.d.ts +3 -3
- package/dist/frameworks/eliza.d.ts.map +1 -1
- package/dist/frameworks/eliza.js +15 -6
- package/dist/frameworks/eliza.js.map +1 -1
- package/dist/frameworks/langchain.d.ts.map +1 -1
- package/dist/frameworks/langchain.js +8 -0
- package/dist/frameworks/langchain.js.map +1 -1
- package/dist/gateway/caller-auth-gateway.d.ts +83 -31
- package/dist/gateway/caller-auth-gateway.d.ts.map +1 -1
- package/dist/gateway/caller-auth-gateway.js +180 -27
- package/dist/gateway/caller-auth-gateway.js.map +1 -1
- package/dist/gateway/http-server.d.ts +128 -44
- package/dist/gateway/http-server.d.ts.map +1 -1
- package/dist/gateway/http-server.js +506 -155
- package/dist/gateway/http-server.js.map +1 -1
- package/dist/gateway/probe-auth.d.ts +112 -0
- package/dist/gateway/probe-auth.d.ts.map +1 -0
- package/dist/gateway/probe-auth.js +127 -0
- package/dist/gateway/probe-auth.js.map +1 -0
- package/dist/gateway/signed-rate-bounds.d.ts +51 -0
- package/dist/gateway/signed-rate-bounds.d.ts.map +1 -0
- package/dist/gateway/signed-rate-bounds.js +94 -0
- package/dist/gateway/signed-rate-bounds.js.map +1 -0
- package/dist/gateway/x402-opener-mode.d.ts +252 -0
- package/dist/gateway/x402-opener-mode.d.ts.map +1 -0
- package/dist/gateway/x402-opener-mode.js +772 -0
- package/dist/gateway/x402-opener-mode.js.map +1 -0
- package/dist/index.d.ts +6 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -5
- package/dist/index.js.map +1 -1
- package/dist/mcp/server.d.ts +64 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +247 -37
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/x402-tools.d.ts +109 -0
- package/dist/mcp/x402-tools.d.ts.map +1 -0
- package/dist/mcp/x402-tools.js +554 -0
- package/dist/mcp/x402-tools.js.map +1 -0
- package/dist/network.d.ts +119 -0
- package/dist/network.d.ts.map +1 -0
- package/dist/network.js +199 -0
- package/dist/network.js.map +1 -0
- package/dist/sdk/client.d.ts +13 -0
- package/dist/sdk/client.d.ts.map +1 -1
- package/dist/sdk/client.js +15 -0
- package/dist/sdk/client.js.map +1 -1
- package/dist/sdk/invoke.d.ts +4 -0
- package/dist/sdk/invoke.d.ts.map +1 -1
- package/dist/sdk/invoke.js +2 -5
- package/dist/sdk/invoke.js.map +1 -1
- package/dist/wallet/autonomous-wallet-broker.d.ts +3 -0
- package/dist/wallet/autonomous-wallet-broker.d.ts.map +1 -1
- package/dist/wallet/autonomous-wallet-broker.js +27 -23
- package/dist/wallet/autonomous-wallet-broker.js.map +1 -1
- package/dist/wallet/autonomous-wallet-protocol.d.ts +8 -2
- package/dist/wallet/autonomous-wallet-protocol.d.ts.map +1 -1
- package/dist/wallet/autonomous-wallet-protocol.js +9 -2
- package/dist/wallet/autonomous-wallet-protocol.js.map +1 -1
- package/dist/wallet/autonomous-wallet.d.ts.map +1 -1
- package/dist/wallet/autonomous-wallet.js +3 -2
- package/dist/wallet/autonomous-wallet.js.map +1 -1
- package/dist/wallet/broker-escrows.d.ts +222 -0
- package/dist/wallet/broker-escrows.d.ts.map +1 -0
- package/dist/wallet/broker-escrows.js +36 -0
- package/dist/wallet/broker-escrows.js.map +1 -0
- package/dist/wallet/lifecycle.d.ts +21 -5
- package/dist/wallet/lifecycle.d.ts.map +1 -1
- package/dist/wallet/lifecycle.js +32 -12
- package/dist/wallet/lifecycle.js.map +1 -1
- package/dist/wallet/privy-broker-server.d.ts.map +1 -1
- package/dist/wallet/privy-broker-server.js +31 -26
- package/dist/wallet/privy-broker-server.js.map +1 -1
- package/dist/wallet/privy-session-broker.d.ts +14 -5
- package/dist/wallet/privy-session-broker.d.ts.map +1 -1
- package/dist/wallet/privy-session-broker.js +29 -17
- package/dist/wallet/privy-session-broker.js.map +1 -1
- package/dist/wallet/privy-session-provider.d.ts +3 -1
- package/dist/wallet/privy-session-provider.d.ts.map +1 -1
- package/dist/wallet/privy-session-provider.js +5 -3
- package/dist/wallet/privy-session-provider.js.map +1 -1
- package/dist/wallet/provider.d.ts.map +1 -1
- package/dist/wallet/provider.js +15 -8
- package/dist/wallet/provider.js.map +1 -1
- package/dist/x402/facilitator.d.ts +3 -30
- package/dist/x402/facilitator.d.ts.map +1 -1
- package/dist/x402/facilitator.js +0 -27
- package/dist/x402/facilitator.js.map +1 -1
- package/dist/x402-buyer/guarded-fetch.d.ts +51 -0
- package/dist/x402-buyer/guarded-fetch.d.ts.map +1 -0
- package/dist/x402-buyer/guarded-fetch.js +147 -0
- package/dist/x402-buyer/guarded-fetch.js.map +1 -0
- package/dist/x402-buyer/index.d.ts +10 -0
- package/dist/x402-buyer/index.d.ts.map +1 -0
- package/dist/x402-buyer/index.js +10 -0
- package/dist/x402-buyer/index.js.map +1 -0
- package/dist/x402-buyer/pay.d.ts +157 -0
- package/dist/x402-buyer/pay.d.ts.map +1 -0
- package/dist/x402-buyer/pay.js +366 -0
- package/dist/x402-buyer/pay.js.map +1 -0
- package/dist/x402-opener/abi.d.ts +684 -0
- package/dist/x402-opener/abi.d.ts.map +1 -0
- package/dist/x402-opener/abi.js +880 -0
- package/dist/x402-opener/abi.js.map +1 -0
- package/dist/x402-opener/facilitator-entry.d.ts +3 -0
- package/dist/x402-opener/facilitator-entry.d.ts.map +1 -0
- package/dist/x402-opener/facilitator-entry.js +40 -0
- package/dist/x402-opener/facilitator-entry.js.map +1 -0
- package/dist/x402-opener/facilitator-server.d.ts +209 -0
- package/dist/x402-opener/facilitator-server.d.ts.map +1 -0
- package/dist/x402-opener/facilitator-server.js +762 -0
- package/dist/x402-opener/facilitator-server.js.map +1 -0
- package/dist/x402-opener/index.d.ts +14 -0
- package/dist/x402-opener/index.d.ts.map +1 -0
- package/dist/x402-opener/index.js +14 -0
- package/dist/x402-opener/index.js.map +1 -0
- package/dist/x402-opener/listing-resolver.d.ts +55 -0
- package/dist/x402-opener/listing-resolver.d.ts.map +1 -0
- package/dist/x402-opener/listing-resolver.js +125 -0
- package/dist/x402-opener/listing-resolver.js.map +1 -0
- package/dist/x402-opener/refund-relay.d.ts +266 -0
- package/dist/x402-opener/refund-relay.d.ts.map +1 -0
- package/dist/x402-opener/refund-relay.js +1341 -0
- package/dist/x402-opener/refund-relay.js.map +1 -0
- package/dist/x402-opener/relayer-queue.d.ts +14 -0
- package/dist/x402-opener/relayer-queue.d.ts.map +1 -0
- package/dist/x402-opener/relayer-queue.js +18 -0
- package/dist/x402-opener/relayer-queue.js.map +1 -0
- package/dist/x402-opener/scheme.d.ts +296 -0
- package/dist/x402-opener/scheme.d.ts.map +1 -0
- package/dist/x402-opener/scheme.js +1035 -0
- package/dist/x402-opener/scheme.js.map +1 -0
- package/dist/x402-opener/terms.d.ts +165 -0
- package/dist/x402-opener/terms.d.ts.map +1 -0
- package/dist/x402-opener/terms.js +304 -0
- package/dist/x402-opener/terms.js.map +1 -0
- package/dist/zktls/reclaim.d.ts +2 -2
- package/dist/zktls/t2-delivery-proof.d.ts +6 -6
- package/docs/agent-layer.md +3 -2
- package/docs/autonomous-privy-wallet.md +188 -0
- package/docs/cli.md +265 -34
- package/docs/langchain.md +5 -0
- package/docs/mcp-reference.md +91 -5
- package/docs/probe-capability.md +191 -0
- package/docs/quickstart.md +39 -4
- package/docs/threat-model.md +20 -0
- package/docs/x402.md +766 -593
- package/package.json +19 -17
- package/src/capability/probe-capability.ts +355 -0
- package/src/cli/args.ts +29 -0
- package/src/cli/commands/claim.ts +168 -33
- package/src/cli/commands/close.ts +36 -3
- package/src/cli/commands/invoke.ts +5 -2
- package/src/cli/commands/mcp.ts +18 -2
- package/src/cli/commands/open.ts +75 -4
- package/src/cli/commands/pay.ts +584 -0
- package/src/cli/commands/reclaim-unverified.ts +8 -2
- package/src/cli/commands/reclaim.ts +277 -19
- package/src/cli/commands/refund.ts +475 -0
- package/src/cli/commands/status.ts +28 -2
- package/src/cli/commands/streams.ts +10 -14
- package/src/cli/commands/watch.ts +11 -1
- package/src/cli/config.ts +139 -52
- package/src/cli/context.ts +16 -0
- package/src/cli/deps.ts +111 -1
- package/src/cli/errors.ts +24 -1
- package/src/cli/escape-hatch.ts +19 -5
- package/src/cli/listings.ts +43 -10
- package/src/cli/preflight.ts +36 -21
- package/src/cli/privy.ts +4 -2
- package/src/cli/progress.ts +21 -2
- package/src/cli/reclaimability.ts +154 -0
- package/src/cli/run.ts +77 -21
- package/src/cli/scan-range.ts +2 -2
- package/src/cli/status.ts +454 -44
- package/src/cli/wallet.ts +45 -8
- package/src/discovery/rate-band.ts +172 -0
- package/src/escrow-generation.ts +135 -0
- package/src/frameworks/agentkit.ts +45 -11
- package/src/frameworks/eliza.ts +27 -5
- package/src/frameworks/langchain.ts +14 -0
- package/src/gateway/caller-auth-gateway.ts +320 -68
- package/src/gateway/http-server.ts +717 -220
- package/src/gateway/probe-auth.ts +191 -0
- package/src/gateway/signed-rate-bounds.ts +164 -0
- package/src/gateway/x402-opener-mode.ts +1171 -0
- package/src/index.ts +82 -19
- package/src/mcp/server.ts +351 -42
- package/src/mcp/x402-tools.ts +785 -0
- package/src/network.ts +302 -0
- package/src/sdk/client.ts +25 -0
- package/src/sdk/invoke.ts +6 -5
- package/src/wallet/autonomous-wallet-broker.ts +46 -20
- package/src/wallet/autonomous-wallet-protocol.ts +11 -2
- package/src/wallet/autonomous-wallet.ts +4 -2
- package/src/wallet/broker-escrows.ts +66 -0
- package/src/wallet/lifecycle.ts +53 -18
- package/src/wallet/privy-broker-server.ts +35 -25
- package/src/wallet/privy-session-broker.ts +58 -25
- package/src/wallet/privy-session-provider.ts +7 -3
- package/src/wallet/provider.ts +20 -15
- package/src/x402/facilitator.ts +3 -43
- package/src/x402-buyer/guarded-fetch.ts +213 -0
- package/src/x402-buyer/index.ts +9 -0
- package/src/x402-buyer/pay.ts +555 -0
- package/src/x402-opener/abi.ts +881 -0
- package/src/x402-opener/facilitator-entry.ts +48 -0
- package/src/x402-opener/facilitator-server.ts +1114 -0
- package/src/x402-opener/index.ts +13 -0
- package/src/x402-opener/listing-resolver.ts +202 -0
- package/src/x402-opener/refund-relay.ts +1873 -0
- package/src/x402-opener/relayer-queue.ts +18 -0
- package/src/x402-opener/scheme.ts +1551 -0
- package/src/x402-opener/terms.ts +453 -0
- package/dist/gateway/x402-mode.d.ts +0 -123
- package/dist/gateway/x402-mode.d.ts.map +0 -1
- package/dist/gateway/x402-mode.js +0 -212
- package/dist/gateway/x402-mode.js.map +0 -1
- package/dist/x402/delivery-oracle.d.ts +0 -108
- package/dist/x402/delivery-oracle.d.ts.map +0 -1
- package/dist/x402/delivery-oracle.js +0 -174
- package/dist/x402/delivery-oracle.js.map +0 -1
- package/dist/x402/facilitator-server-entry.d.ts +0 -3
- package/dist/x402/facilitator-server-entry.d.ts.map +0 -1
- package/dist/x402/facilitator-server-entry.js +0 -27
- package/dist/x402/facilitator-server-entry.js.map +0 -1
- package/dist/x402/facilitator-server.d.ts +0 -73
- package/dist/x402/facilitator-server.d.ts.map +0 -1
- package/dist/x402/facilitator-server.js +0 -305
- package/dist/x402/facilitator-server.js.map +0 -1
- package/dist/x402/payment-requirements.d.ts +0 -106
- package/dist/x402/payment-requirements.d.ts.map +0 -1
- package/dist/x402/payment-requirements.js +0 -138
- package/dist/x402/payment-requirements.js.map +0 -1
- package/dist/x402/relayer.d.ts +0 -41
- package/dist/x402/relayer.d.ts.map +0 -1
- package/dist/x402/relayer.js +0 -64
- package/dist/x402/relayer.js.map +0 -1
- package/dist/x402/resource-index.d.ts +0 -75
- package/dist/x402/resource-index.d.ts.map +0 -1
- package/dist/x402/resource-index.js +0 -126
- package/dist/x402/resource-index.js.map +0 -1
- package/dist/x402/verified-delivery-facilitator.d.ts +0 -285
- package/dist/x402/verified-delivery-facilitator.d.ts.map +0 -1
- package/dist/x402/verified-delivery-facilitator.js +0 -423
- package/dist/x402/verified-delivery-facilitator.js.map +0 -1
- package/src/gateway/x402-mode.ts +0 -350
- package/src/x402/delivery-oracle.ts +0 -285
- package/src/x402/facilitator-server-entry.ts +0 -35
- package/src/x402/facilitator-server.ts +0 -445
- package/src/x402/payment-requirements.ts +0 -231
- package/src/x402/relayer.ts +0 -122
- package/src/x402/resource-index.ts +0 -228
- package/src/x402/verified-delivery-facilitator.ts +0 -744
|
@@ -10,6 +10,9 @@ import {
|
|
|
10
10
|
resolveCliWallet,
|
|
11
11
|
} from "../wallet.js";
|
|
12
12
|
import type { CommandContext, CommandSpec } from "../context.js";
|
|
13
|
+
import type { CliReadClient } from "../deps.js";
|
|
14
|
+
import { escrowGenerationFor } from "../../escrow-generation.js";
|
|
15
|
+
import type { StreamV2 } from "@absol-labs/sdk";
|
|
13
16
|
|
|
14
17
|
/**
|
|
15
18
|
* The seller's side of the loop.
|
|
@@ -52,7 +55,7 @@ export const claimCommand: CommandSpec = {
|
|
|
52
55
|
}
|
|
53
56
|
const read = deps.createReadClient(config);
|
|
54
57
|
await assertTestnetRpc(config, () => read.getChainId());
|
|
55
|
-
await assertCanPayGas(read, account.address);
|
|
58
|
+
await assertCanPayGas(read, account.address, config.network);
|
|
56
59
|
|
|
57
60
|
const stream = await read.getStreamV2(streamId);
|
|
58
61
|
if (stream.operator.toLowerCase() !== account.address.toLowerCase()) {
|
|
@@ -65,40 +68,20 @@ export const claimCommand: CommandSpec = {
|
|
|
65
68
|
);
|
|
66
69
|
}
|
|
67
70
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
} catch (error) {
|
|
76
|
-
throw new CliError(
|
|
77
|
-
"no checkpoint covers this stream yet, so there is nothing provable to claim",
|
|
78
|
-
{
|
|
79
|
-
exitCode: 4,
|
|
80
|
-
hint: `the oracle publishes roughly every 15-22s and pays only for intervals that verified; ${describeError(
|
|
81
|
-
error,
|
|
82
|
-
)}`,
|
|
83
|
-
cause: error,
|
|
84
|
-
},
|
|
85
|
-
);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
const claimable = await read.claimableForV2(streamId, cumulativeAmount);
|
|
89
|
-
if (claimable === 0n) {
|
|
90
|
-
throw new CliError("this stream has nothing claimable right now", {
|
|
91
|
-
exitCode: 4,
|
|
92
|
-
hint: `everything checkpointed so far has already been claimed. See where it stands: metrik status ${streamId}`,
|
|
93
|
-
});
|
|
94
|
-
}
|
|
71
|
+
const plan = await planClaim(
|
|
72
|
+
read,
|
|
73
|
+
streamId,
|
|
74
|
+
stream,
|
|
75
|
+
escrowGenerationFor(config.chainId, config.escrow),
|
|
76
|
+
);
|
|
77
|
+
if (plan.kind === "nothing") throw plan.error;
|
|
95
78
|
|
|
96
79
|
const write = deps.createWriteClient(
|
|
97
80
|
config,
|
|
98
81
|
account,
|
|
99
82
|
writeClientOptions(wallet),
|
|
100
83
|
);
|
|
101
|
-
const
|
|
84
|
+
const action = {
|
|
102
85
|
streamId,
|
|
103
86
|
// `null` for a policy-enforced wallet — see `../spend-policy.ts`.
|
|
104
87
|
signedMandate: isPolicyEnforced(wallet)
|
|
@@ -106,21 +89,173 @@ export const claimCommand: CommandSpec = {
|
|
|
106
89
|
: await signClaimMandate(account, config.chainId),
|
|
107
90
|
spentSoFarUsdc: 0n,
|
|
108
91
|
nowSeconds: deps.nowSeconds(),
|
|
109
|
-
}
|
|
92
|
+
};
|
|
93
|
+
let result: { readonly txHash: `0x${string}` };
|
|
94
|
+
if (plan.kind === "claimWithProof") {
|
|
95
|
+
result = await write.claimStream(action);
|
|
96
|
+
} else {
|
|
97
|
+
if (write.claimProvenStream === undefined) {
|
|
98
|
+
throw new CliError(
|
|
99
|
+
"this write client cannot send claimProven, which is the only way to collect this stream's proven value",
|
|
100
|
+
{
|
|
101
|
+
exitCode: 3,
|
|
102
|
+
hint: "no current checkpoint proof pays it, so a proof claim would revert NothingToClaim",
|
|
103
|
+
},
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
result = await write.claimProvenStream(action);
|
|
107
|
+
}
|
|
110
108
|
|
|
111
109
|
out.result({
|
|
112
110
|
streamId,
|
|
113
111
|
txHash: result.txHash,
|
|
114
112
|
operator: stream.operator,
|
|
115
|
-
claimed: claimable,
|
|
116
|
-
|
|
113
|
+
claimed: plan.claimable,
|
|
114
|
+
method: plan.kind,
|
|
115
|
+
verifiedCumulative: plan.verifiedCumulative,
|
|
116
|
+
provenCumulative: plan.provenCumulative,
|
|
117
117
|
});
|
|
118
118
|
out.print("Claimed.");
|
|
119
119
|
out.table([
|
|
120
120
|
["streamId", streamId],
|
|
121
121
|
["tx", result.txHash],
|
|
122
122
|
["operator", stream.operator],
|
|
123
|
-
["claimed", `${formatUsdc(claimable)} (net of protocol fee)`],
|
|
123
|
+
["claimed", `${formatUsdc(plan.claimable)} (net of protocol fee)`],
|
|
124
|
+
[
|
|
125
|
+
"via",
|
|
126
|
+
plan.kind === "claimWithProof"
|
|
127
|
+
? "claimWithProof (the oracle's current checkpoint proof)"
|
|
128
|
+
: `claimProven (the on-chain proven high-water, ${formatUsdc(plan.provenCumulative ?? 0n)} gross — no current checkpoint proof pays more)`,
|
|
129
|
+
],
|
|
124
130
|
]);
|
|
125
131
|
},
|
|
126
132
|
};
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Which claim, if any, `metrik claim` would send. Reads only, so it is
|
|
136
|
+
* testable (and checkable against a live stream) without a key.
|
|
137
|
+
*
|
|
138
|
+
* - `claimWithProof` pays `min(proofCumulative, deposit) − claimed` against ANY
|
|
139
|
+
* retained checkpoint root.
|
|
140
|
+
* - `claimProven` (StreamEscrowV3) pays `min(provenCumulative, deposit) −
|
|
141
|
+
* claimed` with NO proof: the high-water was itself proven against a signed
|
|
142
|
+
* root when it was recorded. It is the only way to collect proven value whose
|
|
143
|
+
* root has rotated out of the retained set, or that a later root regressed.
|
|
144
|
+
*
|
|
145
|
+
* Both are asked of the escrow (`claimableFor` at each cumulative; the escrow
|
|
146
|
+
* pays a claim with exactly that math), and the larger is chosen. A proof
|
|
147
|
+
* claim wins a tie, because it also raises the proven high-water. Nothing is
|
|
148
|
+
* chosen when both pay zero, so no gas is spent to learn `NothingToClaim`.
|
|
149
|
+
*/
|
|
150
|
+
export type ClaimPlan =
|
|
151
|
+
| {
|
|
152
|
+
readonly kind: "claimWithProof" | "claimProven";
|
|
153
|
+
/** What the operator receives, net of the protocol fee. */
|
|
154
|
+
readonly claimable: bigint;
|
|
155
|
+
/** The current proof's cumulative; `null` when no proof was available. */
|
|
156
|
+
readonly verifiedCumulative: bigint | null;
|
|
157
|
+
/** V3 proven high-water; `null` on V2 or when unreadable. */
|
|
158
|
+
readonly provenCumulative: bigint | null;
|
|
159
|
+
}
|
|
160
|
+
| { readonly kind: "nothing"; readonly error: CliError };
|
|
161
|
+
|
|
162
|
+
export async function planClaim(
|
|
163
|
+
read: CliReadClient,
|
|
164
|
+
streamId: `0x${string}`,
|
|
165
|
+
stream: Pick<StreamV2, "claimedCumulative">,
|
|
166
|
+
escrowGeneration: string,
|
|
167
|
+
): Promise<ClaimPlan> {
|
|
168
|
+
let verifiedCumulative: bigint | null = null;
|
|
169
|
+
let proofError: unknown = null;
|
|
170
|
+
try {
|
|
171
|
+
verifiedCumulative = (await read.checkpointProof(streamId))
|
|
172
|
+
.cumulativeAmount;
|
|
173
|
+
} catch (error) {
|
|
174
|
+
proofError = error;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
let provenCumulative: bigint | null = null;
|
|
178
|
+
let provenError: string | null = null;
|
|
179
|
+
if (escrowGeneration === "v3") {
|
|
180
|
+
if (read.provenCumulativeOf === undefined) {
|
|
181
|
+
provenError = "this read client cannot read provenCumulativeOf";
|
|
182
|
+
} else {
|
|
183
|
+
try {
|
|
184
|
+
provenCumulative = await read.provenCumulativeOf(streamId);
|
|
185
|
+
} catch (error) {
|
|
186
|
+
provenError = describeError(error);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
const [proofClaimable, provenClaimable] = await Promise.all([
|
|
192
|
+
verifiedCumulative === null
|
|
193
|
+
? 0n
|
|
194
|
+
: read.claimableForV2(streamId, verifiedCumulative),
|
|
195
|
+
// `claimProven` pays at the high-water, so it is worth asking only when
|
|
196
|
+
// the high-water is above what has already been claimed.
|
|
197
|
+
provenCumulative === null || provenCumulative <= stream.claimedCumulative
|
|
198
|
+
? 0n
|
|
199
|
+
: read.claimableForV2(streamId, provenCumulative),
|
|
200
|
+
]);
|
|
201
|
+
|
|
202
|
+
if (proofClaimable > 0n && proofClaimable >= provenClaimable) {
|
|
203
|
+
return {
|
|
204
|
+
kind: "claimWithProof",
|
|
205
|
+
claimable: proofClaimable,
|
|
206
|
+
verifiedCumulative,
|
|
207
|
+
provenCumulative,
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
if (provenClaimable > 0n) {
|
|
211
|
+
return {
|
|
212
|
+
kind: "claimProven",
|
|
213
|
+
claimable: provenClaimable,
|
|
214
|
+
verifiedCumulative,
|
|
215
|
+
provenCumulative,
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
if (provenCumulative !== null && provenCumulative > 0n) {
|
|
220
|
+
return {
|
|
221
|
+
kind: "nothing",
|
|
222
|
+
error: new CliError("this stream has nothing to claim", {
|
|
223
|
+
exitCode: 4,
|
|
224
|
+
hint: `everything proven on-chain for it (${formatUsdc(provenCumulative)} gross) has already been claimed${
|
|
225
|
+
verifiedCumulative === null
|
|
226
|
+
? ", and the latest checkpoint no longer contains it"
|
|
227
|
+
: ""
|
|
228
|
+
}. See where it stands: metrik status ${streamId}`,
|
|
229
|
+
}),
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
if (verifiedCumulative === null) {
|
|
233
|
+
// Accrual lives in the oracle's checkpoint proof (and, on V3, the proven
|
|
234
|
+
// high-water), never in the stream tuple. Saying so is better than paying
|
|
235
|
+
// gas for a `NothingToClaim()` revert.
|
|
236
|
+
return {
|
|
237
|
+
kind: "nothing",
|
|
238
|
+
error: new CliError(
|
|
239
|
+
"no checkpoint covers this stream yet, so there is nothing provable to claim",
|
|
240
|
+
{
|
|
241
|
+
exitCode: 4,
|
|
242
|
+
hint: `the oracle publishes roughly every 15-22s and pays only for intervals that verified; ${describeError(
|
|
243
|
+
proofError,
|
|
244
|
+
)}${
|
|
245
|
+
provenError === null
|
|
246
|
+
? ""
|
|
247
|
+
: `; the on-chain proven high-water could not be read either (${provenError})`
|
|
248
|
+
}`,
|
|
249
|
+
cause: proofError,
|
|
250
|
+
},
|
|
251
|
+
),
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
return {
|
|
255
|
+
kind: "nothing",
|
|
256
|
+
error: new CliError("this stream has nothing claimable right now", {
|
|
257
|
+
exitCode: 4,
|
|
258
|
+
hint: `everything checkpointed so far has already been claimed. See where it stands: metrik status ${streamId}`,
|
|
259
|
+
}),
|
|
260
|
+
};
|
|
261
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { assertTestnetRpc, parseBytes32 } from "../config.js";
|
|
2
|
-
import { usageError } from "../errors.js";
|
|
2
|
+
import { CliError, usageError } from "../errors.js";
|
|
3
3
|
import { signRecoveryMandate } from "../mandate.js";
|
|
4
4
|
import { assertCanPayGas } from "../preflight.js";
|
|
5
5
|
import { writeClientOptions } from "../deps.js";
|
|
@@ -27,7 +27,28 @@ export const closeCommand: CommandSpec = {
|
|
|
27
27
|
const { account } = wallet;
|
|
28
28
|
const read = deps.createReadClient(config);
|
|
29
29
|
await assertTestnetRpc(config, () => read.getChainId());
|
|
30
|
-
|
|
30
|
+
// An x402 opener stream is closed through the opener, by its PAYER. Say so
|
|
31
|
+
// up front: the escrow would answer anyone else with NotBuyer, and the SDK
|
|
32
|
+
// refuses a non-payer before anything is sent.
|
|
33
|
+
const stream = await read.getStreamV2(streamId).catch(() => null);
|
|
34
|
+
const opener = stream?.opener ?? null;
|
|
35
|
+
if (opener !== null && stream !== null) {
|
|
36
|
+
out.note(
|
|
37
|
+
`x402 stream: closing through the opener ${opener}; only its payer ${stream.payer} may close it.`,
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
try {
|
|
41
|
+
await assertCanPayGas(read, account.address, config.network);
|
|
42
|
+
} catch (error) {
|
|
43
|
+
if (opener !== null && error instanceof CliError) {
|
|
44
|
+
throw new CliError(error.message, {
|
|
45
|
+
exitCode: error.exitCode,
|
|
46
|
+
hint: `${error.hint ?? ""} This stream was bought over x402: a payer with no gas can close it through the seller's refund relay instead — \`metrik refund ${streamId} --refund-url <url> --close\`.`.trim(),
|
|
47
|
+
cause: error,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
throw error;
|
|
51
|
+
}
|
|
31
52
|
|
|
32
53
|
// A policy-enforced wallet signs no mandate of its own: this is a
|
|
33
54
|
// buyer-recovery action, the escrow gates it on the buyer address and the
|
|
@@ -49,11 +70,23 @@ export const closeCommand: CommandSpec = {
|
|
|
49
70
|
nowSeconds: deps.nowSeconds(),
|
|
50
71
|
});
|
|
51
72
|
|
|
52
|
-
out.result({
|
|
73
|
+
out.result({
|
|
74
|
+
streamId,
|
|
75
|
+
txHash: result.txHash,
|
|
76
|
+
closed: true,
|
|
77
|
+
opener,
|
|
78
|
+
payer: stream?.payer ?? null,
|
|
79
|
+
});
|
|
53
80
|
out.print("Stream closed.");
|
|
54
81
|
out.table([
|
|
55
82
|
["streamId", streamId],
|
|
56
83
|
["tx", result.txHash],
|
|
84
|
+
...(opener === null
|
|
85
|
+
? []
|
|
86
|
+
: ([
|
|
87
|
+
["via opener", opener],
|
|
88
|
+
["payer", stream?.payer ?? "-"],
|
|
89
|
+
] as const)),
|
|
57
90
|
]);
|
|
58
91
|
out.print("");
|
|
59
92
|
out.print(
|
|
@@ -157,7 +157,7 @@ function explainInvokeFailure(error: unknown, signer: string): unknown {
|
|
|
157
157
|
return error;
|
|
158
158
|
}
|
|
159
159
|
|
|
160
|
-
function parseHeaders(raw: readonly string[]): Record<string, string> {
|
|
160
|
+
export function parseHeaders(raw: readonly string[]): Record<string, string> {
|
|
161
161
|
const headers: Record<string, string> = {};
|
|
162
162
|
for (const entry of raw) {
|
|
163
163
|
const separator = entry.indexOf(":");
|
|
@@ -171,7 +171,10 @@ function parseHeaders(raw: readonly string[]): Record<string, string> {
|
|
|
171
171
|
return headers;
|
|
172
172
|
}
|
|
173
173
|
|
|
174
|
-
function hasHeader(
|
|
174
|
+
export function hasHeader(
|
|
175
|
+
headers: Record<string, string>,
|
|
176
|
+
name: string,
|
|
177
|
+
): boolean {
|
|
175
178
|
return Object.keys(headers).some(
|
|
176
179
|
(key) => key.toLowerCase() === name.toLowerCase(),
|
|
177
180
|
);
|
package/src/cli/commands/mcp.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { booleanFlag, stringFlag } from "../args.js";
|
|
2
2
|
import { packageVersion } from "../version.js";
|
|
3
|
-
import { CDP_ENV_VARS, PRIVATE_KEY_ENV } from "../wallet.js";
|
|
3
|
+
import { CDP_ENV_VARS, PRIVATE_KEY_ENV, PRIVY_ENV_VARS } from "../wallet.js";
|
|
4
4
|
import type { CommandContext, CommandSpec } from "../context.js";
|
|
5
5
|
|
|
6
6
|
/** The published executable an MCP host starts. Declared in `package.json#bin`. */
|
|
@@ -82,6 +82,17 @@ export const mcpCommand: CommandSpec = {
|
|
|
82
82
|
},
|
|
83
83
|
};
|
|
84
84
|
|
|
85
|
+
// Honesty about the one wallet source this block cannot carry. The CLI
|
|
86
|
+
// resolves a Privy wallet (step 3), but the MCP server's own resolver,
|
|
87
|
+
// `parseAgentWalletEnv()`, reads a raw key or CDP and nothing else — there
|
|
88
|
+
// is no Privy path from the environment there. Printing Privy variables
|
|
89
|
+
// into a config the server would ignore is the failure this says out loud.
|
|
90
|
+
if (PRIVY_ENV_VARS.some((variable) => (env[variable] ?? "").length > 0)) {
|
|
91
|
+
out.note(
|
|
92
|
+
`note: this environment configures a Privy wallet, which the CLI can use but \`${MCP_BIN}\` cannot — its wallet resolver reads ${PRIVATE_KEY_ENV} or the CDP variables only. The block below therefore carries a key placeholder; give the MCP server a raw key or a CDP account.`,
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
85
96
|
out.result(document);
|
|
86
97
|
out.print(
|
|
87
98
|
`Paste this into your MCP client's config (Claude Desktop: claude_desktop_config.json), then replace every <…> placeholder:`,
|
|
@@ -102,6 +113,11 @@ export const mcpCommand: CommandSpec = {
|
|
|
102
113
|
* Wallet variables, shaped to match how the environment running this command is
|
|
103
114
|
* already configured — CDP if that is what is set, a raw key otherwise.
|
|
104
115
|
*
|
|
116
|
+
* Privy is deliberately absent: `parseAgentWalletEnv()`, which is what the MCP
|
|
117
|
+
* server resolves its wallet with, has no Privy branch. A Privy block here
|
|
118
|
+
* would print a config that cannot start the server. The command says so on
|
|
119
|
+
* stderr instead.
|
|
120
|
+
*
|
|
105
121
|
* Values are ALWAYS placeholders. `metrik` prints derived addresses and never
|
|
106
122
|
* echoes a credential, and a config block is the single most likely thing to be
|
|
107
123
|
* pasted into a chat window or an issue.
|
|
@@ -116,7 +132,7 @@ function walletEnv(env: NodeJS.ProcessEnv): Record<string, string> {
|
|
|
116
132
|
);
|
|
117
133
|
}
|
|
118
134
|
return {
|
|
119
|
-
[PRIVATE_KEY_ENV]: "<0x… a funded
|
|
135
|
+
[PRIVATE_KEY_ENV]: "<0x… a funded testnet key>",
|
|
120
136
|
};
|
|
121
137
|
}
|
|
122
138
|
|
package/src/cli/commands/open.ts
CHANGED
|
@@ -23,7 +23,12 @@ import {
|
|
|
23
23
|
resolveCliWallet,
|
|
24
24
|
PRIVATE_KEY_ENV,
|
|
25
25
|
} from "../wallet.js";
|
|
26
|
-
import {
|
|
26
|
+
import { resolveListingRecord } from "../listings.js";
|
|
27
|
+
import {
|
|
28
|
+
listingRateBand,
|
|
29
|
+
rateBandRefusal,
|
|
30
|
+
SignedRateBoundsError,
|
|
31
|
+
} from "../../discovery/rate-band.js";
|
|
27
32
|
import type { CommandContext, CommandSpec } from "../context.js";
|
|
28
33
|
|
|
29
34
|
export const openCommand: CommandSpec = {
|
|
@@ -89,14 +94,21 @@ export const openCommand: CommandSpec = {
|
|
|
89
94
|
if (account !== null && !dryRun) {
|
|
90
95
|
// Both balances, before anything is signed. Gas first: a wallet with no
|
|
91
96
|
// ETH cannot send the approval that the USDC check exists to protect.
|
|
92
|
-
await assertCanPayGas(read, account.address);
|
|
93
|
-
await assertCanFundStream(
|
|
97
|
+
await assertCanPayGas(read, account.address, config.network);
|
|
98
|
+
await assertCanFundStream(
|
|
99
|
+
read,
|
|
100
|
+
account.address,
|
|
101
|
+
budgetUsdc,
|
|
102
|
+
config.network,
|
|
103
|
+
);
|
|
94
104
|
}
|
|
95
105
|
|
|
96
106
|
const operatorOverride = stringFlag(args, "operator");
|
|
97
|
-
const
|
|
107
|
+
const resolution = await resolveListingRecord(context, serviceRef, {
|
|
98
108
|
required: operatorOverride === undefined,
|
|
99
109
|
});
|
|
110
|
+
const listing = resolution.listing;
|
|
111
|
+
await assertRateInSignedBand(context, resolution, ratePerSecondUsdc);
|
|
100
112
|
const operator = (operatorOverride ?? listing?.operator) as
|
|
101
113
|
| `0x${string}`
|
|
102
114
|
| undefined;
|
|
@@ -348,6 +360,65 @@ export const openCommand: CommandSpec = {
|
|
|
348
360
|
},
|
|
349
361
|
};
|
|
350
362
|
|
|
363
|
+
/**
|
|
364
|
+
* Refuse a `--rate` outside the band the operator SIGNED, before anything is
|
|
365
|
+
* signed or broadcast — dry run included, because the rate is an invalid input
|
|
366
|
+
* for this service exactly like `--rate 0` is.
|
|
367
|
+
*
|
|
368
|
+
* The escrow accepts any non-zero rate; the seller's capability gateway does
|
|
369
|
+
* not, and answers every request on an out-of-band stream with
|
|
370
|
+
* `403 stream-rate-out-of-bounds`. Without this check the CLI locked a buyer's
|
|
371
|
+
* deposit in a stream that could never be served, and said nothing.
|
|
372
|
+
*
|
|
373
|
+
* - Listing found: its signed descriptor is re-verified and the band enforced.
|
|
374
|
+
* A descriptor that does not verify is a refusal (exit 4), never "no band".
|
|
375
|
+
* A legacy binding signs no commercial terms, so there is nothing to enforce.
|
|
376
|
+
* - No listing: only reachable with `--operator`, the CLI's existing,
|
|
377
|
+
* explicit escape hatch for a service the registry cannot vouch for. The
|
|
378
|
+
* check cannot run, so it is skipped LOUDLY rather than silently. Without
|
|
379
|
+
* `--operator` an unreachable registry or a missing listing has already
|
|
380
|
+
* failed the command before this point (`resolveListingRecord`).
|
|
381
|
+
*/
|
|
382
|
+
async function assertRateInSignedBand(
|
|
383
|
+
context: CommandContext,
|
|
384
|
+
resolution: Awaited<ReturnType<typeof resolveListingRecord>>,
|
|
385
|
+
ratePerSecondUsdc: bigint,
|
|
386
|
+
): Promise<void> {
|
|
387
|
+
const { out } = context;
|
|
388
|
+
if (resolution.record === null) {
|
|
389
|
+
out.note(
|
|
390
|
+
resolution.registryUnreachable
|
|
391
|
+
? "warning: the operator-signed rate band could NOT be checked because the registry is unreachable. If --rate is outside the band the operator signed, the service's gateway will refuse every request while the deposit stays escrowed. Re-run when the registry answers to have it checked."
|
|
392
|
+
: "note: this serviceRef has no verified listing, so there is no operator-signed rate band to check --rate against.",
|
|
393
|
+
);
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
let bounds;
|
|
397
|
+
try {
|
|
398
|
+
bounds = await listingRateBand(resolution.record);
|
|
399
|
+
} catch (error) {
|
|
400
|
+
if (error instanceof SignedRateBoundsError) {
|
|
401
|
+
throw new CliError(
|
|
402
|
+
`the listing's operator-signed rate band could not be verified: ${error.message}`,
|
|
403
|
+
{
|
|
404
|
+
exitCode: 4,
|
|
405
|
+
hint: "nothing was broadcast. The CLI will not open a stream against a rate band it cannot verify.",
|
|
406
|
+
cause: error,
|
|
407
|
+
},
|
|
408
|
+
);
|
|
409
|
+
}
|
|
410
|
+
throw error;
|
|
411
|
+
}
|
|
412
|
+
if (bounds === null) return;
|
|
413
|
+
const refusal = rateBandRefusal(ratePerSecondUsdc, bounds, "--rate");
|
|
414
|
+
if (refusal !== undefined) {
|
|
415
|
+
throw new CliError(refusal, {
|
|
416
|
+
exitCode: 2,
|
|
417
|
+
hint: "pick a --rate inside the signed band (`--units atomic` takes base units; see `metrik discover` for each listing's band).",
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
|
|
351
422
|
/**
|
|
352
423
|
* What the buyer is actually paying for.
|
|
353
424
|
*
|