@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
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"privy.d.ts","sourceRoot":"","sources":["../../src/cli/privy.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,OAAO,EACZ,KAAK,SAAS,EACf,MAAM,MAAM,CAAC;AAEd,OAAO,EAQL,KAAK,+BAA+B,EAErC,MAAM,gCAAgC,CAAC;AAQxC;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,oBAAoB,GAAG,kBAAkB,GAAG,eAAe,CAAC;AAExE,gFAAgF;AAChF,eAAO,MAAM,oBAAoB,kCAAkC,CAAC;AACpE,0EAA0E;AAC1E,eAAO,MAAM,oBAAoB,kCAAkC,CAAC;AACpE,yEAAyE;AACzE,eAAO,MAAM,uBAAuB,qCAAqC,CAAC;AAC1E,2DAA2D;AAC3D,eAAO,MAAM,iBAAiB,+BAA+B,CAAC;AAC9D,oFAAoF;AACpF,eAAO,MAAM,gBAAgB,8BAA8B,CAAC;AAE5D,+EAA+E;AAC/E,eAAO,MAAM,cAAc,4KAMjB,CAAC;AAEX,qEAAqE;AACrE,eAAO,MAAM,sBAAsB,2IAKzB,CAAC;AAEX;;;;;;;;;;GAUG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;CACrC;AAED,uFAAuF;AACvF,wBAAsB,qBAAqB,CACzC,SAAS,EAAE,MAAM,EACjB,SAAS,GAAE,OAAO,KAAa,GAC9B,OAAO,CAAC,gBAAgB,CAAC,CAyC3B;AAUD,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,MAAM,EAAE,oBAAoB,CAAC;IACtC,mFAAmF;IACnF,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,yFAAyF;IACzF,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,+EAA+E;IAC/E,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,kFAAkF;IAClF,QAAQ,CAAC,eAAe,EAAE,MAAM,OAAO,CAAC,gBAAgB,CAAC,CAAC;CAC3D;AAED,MAAM,WAAW,4BAA4B;IAC3C,uFAAuF;IACvF,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,4EAA4E;IAC5E,QAAQ,CAAC,KAAK,CAAC,EAAE,+BAA+B,CAAC;IACjD,8CAA8C;IAC9C,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CACnC;AAED;;;;;;;;GAQG;AACH,wBAAsB,qBAAqB,CACzC,GAAG,EAAE,MAAM,CAAC,UAAU,EACtB,OAAO,GAAE,4BAAiC,GACzC,OAAO,CAAC,sBAAsB,GAAG,IAAI,CAAC,CA8CxC"}
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import { custom, isAddress, getAddress, } from "viem";
|
|
2
|
+
import { AutonomousWalletError, EncryptedFileCredentialStore, HttpAutonomousWalletBroker, METRIK_AUTONOMOUS_WALLET_BROKER_URL, METRIK_WALLET_ENCRYPTION_KEY_ENV, createAutonomousWalletProvider, createDefaultAutonomousWalletStore, } from "../wallet/autonomous-wallet.js";
|
|
3
|
+
import { createPrivySessionProvider } from "../wallet/privy-session-provider.js";
|
|
4
|
+
import { createPrivyEmbeddedAccount, } from "../wallet/provider.js";
|
|
5
|
+
import { configError } from "./errors.js";
|
|
6
|
+
/** The store key naming the agent-owned wallet in the host credential store. */
|
|
7
|
+
export const PRIVY_WALLET_KEY_ENV = "METRIK_AGENT_PRIVY_WALLET_KEY";
|
|
8
|
+
/** Broker base URL. Optional for `autonomous`, REQUIRED for `session`. */
|
|
9
|
+
export const PRIVY_BROKER_URL_ENV = "METRIK_AGENT_PRIVY_BROKER_URL";
|
|
10
|
+
/** A scoped session token minted by the broker's `POST /v1/sessions`. */
|
|
11
|
+
export const PRIVY_SESSION_TOKEN_ENV = "METRIK_AGENT_PRIVY_SESSION_TOKEN";
|
|
12
|
+
/** The embedded wallet address the session is bound to. */
|
|
13
|
+
export const PRIVY_ADDRESS_ENV = "METRIK_AGENT_PRIVY_ADDRESS";
|
|
14
|
+
/** The PUBLIC Privy app id. Not a secret — the broker serves it at `/v1/config`. */
|
|
15
|
+
export const PRIVY_APP_ID_ENV = "METRIK_AGENT_PRIVY_APP_ID";
|
|
16
|
+
/** Every variable either Privy shape reads. Named in errors, never printed. */
|
|
17
|
+
export const PRIVY_ENV_VARS = [
|
|
18
|
+
PRIVY_WALLET_KEY_ENV,
|
|
19
|
+
PRIVY_BROKER_URL_ENV,
|
|
20
|
+
PRIVY_SESSION_TOKEN_ENV,
|
|
21
|
+
PRIVY_ADDRESS_ENV,
|
|
22
|
+
PRIVY_APP_ID_ENV,
|
|
23
|
+
];
|
|
24
|
+
/** The variables the user-owned session shape needs, all of them. */
|
|
25
|
+
export const PRIVY_SESSION_ENV_VARS = [
|
|
26
|
+
PRIVY_BROKER_URL_ENV,
|
|
27
|
+
PRIVY_SESSION_TOKEN_ENV,
|
|
28
|
+
PRIVY_ADDRESS_ENV,
|
|
29
|
+
PRIVY_APP_ID_ENV,
|
|
30
|
+
];
|
|
31
|
+
/** Reads a broker's public policy. No credential is sent; nothing secret is served. */
|
|
32
|
+
export async function fetchPrivySpendPolicy(brokerUrl, fetchImpl = fetch) {
|
|
33
|
+
const base = brokerUrl.replace(/\/$/, "");
|
|
34
|
+
const response = await fetchImpl(`${base}/v1/config`, {
|
|
35
|
+
headers: { accept: "application/json" },
|
|
36
|
+
}).catch((error) => {
|
|
37
|
+
throw configError(`the Privy broker at ${base} did not answer its public policy`, `${describe(error)} The CLI reads GET /v1/config to know the ceiling your wallet is capped at; without it, it cannot tell you before broadcasting whether a hire fits.`);
|
|
38
|
+
});
|
|
39
|
+
const body = (await response.json().catch(() => null));
|
|
40
|
+
if (!response.ok || body === null) {
|
|
41
|
+
throw configError(`the Privy broker at ${base} rejected the public policy read (${response.status})`);
|
|
42
|
+
}
|
|
43
|
+
const chainId = Number(body.chainId);
|
|
44
|
+
const maxTotalUsdc = asBigint(body.maxTotalUsdcAtomic);
|
|
45
|
+
const maxRatePerSecondUsdc = asBigint(body.maxRatePerSecondAtomic);
|
|
46
|
+
const maxDurationSeconds = Number(body.maxDurationSeconds);
|
|
47
|
+
if (!Number.isSafeInteger(chainId) ||
|
|
48
|
+
maxTotalUsdc === null ||
|
|
49
|
+
maxRatePerSecondUsdc === null ||
|
|
50
|
+
!Number.isSafeInteger(maxDurationSeconds)) {
|
|
51
|
+
throw configError(`the Privy broker at ${base} returned a policy this CLI cannot read`, "expected chainId, maxTotalUsdcAtomic, maxRatePerSecondAtomic and maxDurationSeconds.");
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
brokerUrl: base,
|
|
55
|
+
chainId,
|
|
56
|
+
maxTotalUsdc,
|
|
57
|
+
maxRatePerSecondUsdc,
|
|
58
|
+
maxDurationSeconds,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
function asBigint(value) {
|
|
62
|
+
if (typeof value === "bigint")
|
|
63
|
+
return value;
|
|
64
|
+
if (typeof value === "number" && Number.isSafeInteger(value))
|
|
65
|
+
return BigInt(value);
|
|
66
|
+
if (typeof value === "string" && /^[0-9]+$/.test(value))
|
|
67
|
+
return BigInt(value);
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Resolves a Privy wallet from the environment, or `null` when no Privy
|
|
72
|
+
* variable is set at all.
|
|
73
|
+
*
|
|
74
|
+
* A PARTIALLY configured Privy setup is an error, not a `null` — "you set the
|
|
75
|
+
* session token but not the address" and "you configured no Privy wallet" are
|
|
76
|
+
* different facts, and rendering the first as the second sends the reader
|
|
77
|
+
* looking in the wrong place. This mirrors the CDP path exactly.
|
|
78
|
+
*/
|
|
79
|
+
export async function resolvePrivyCliWallet(env, options = {}) {
|
|
80
|
+
const walletKey = read(env, PRIVY_WALLET_KEY_ENV);
|
|
81
|
+
const brokerUrl = read(env, PRIVY_BROKER_URL_ENV);
|
|
82
|
+
const sessionToken = read(env, PRIVY_SESSION_TOKEN_ENV);
|
|
83
|
+
const address = read(env, PRIVY_ADDRESS_ENV);
|
|
84
|
+
const appId = read(env, PRIVY_APP_ID_ENV);
|
|
85
|
+
if (walletKey === null &&
|
|
86
|
+
brokerUrl === null &&
|
|
87
|
+
sessionToken === null &&
|
|
88
|
+
address === null &&
|
|
89
|
+
appId === null) {
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
if (walletKey !== null) {
|
|
93
|
+
if (sessionToken !== null) {
|
|
94
|
+
options.note?.(`warning: both ${PRIVY_WALLET_KEY_ENV} and ${PRIVY_SESSION_TOKEN_ENV} are set; using the agent-owned wallet named by ${PRIVY_WALLET_KEY_ENV}. Unset it to sign with the session token.`);
|
|
95
|
+
}
|
|
96
|
+
return await resolveAutonomous(walletKey, brokerUrl, env, options);
|
|
97
|
+
}
|
|
98
|
+
const missing = PRIVY_SESSION_ENV_VARS.filter((name) => read(env, name) === null);
|
|
99
|
+
if (missing.length > 0) {
|
|
100
|
+
throw configError(`the Privy wallet is partially configured: ${missing.join(", ")} ${missing.length === 1 ? "is" : "are"} not set`, `a Privy wallet is configured one of two ways: set ${PRIVY_WALLET_KEY_ENV} to the store key of an agent-owned wallet you provisioned with provisionMetrikAutonomousWallet(), or set all of ${PRIVY_SESSION_ENV_VARS.join(", ")} for a broker session. Set the missing one${missing.length === 1 ? "" : "s"}, or unset the others to use a different wallet.`);
|
|
101
|
+
}
|
|
102
|
+
return resolveSession({
|
|
103
|
+
brokerUrl: brokerUrl,
|
|
104
|
+
sessionToken: sessionToken,
|
|
105
|
+
address: address,
|
|
106
|
+
appId: appId,
|
|
107
|
+
...(options.rpcUrl === undefined ? {} : { rpcUrl: options.rpcUrl }),
|
|
108
|
+
...(options.fetchImpl === undefined
|
|
109
|
+
? {}
|
|
110
|
+
: { fetchImpl: options.fetchImpl }),
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
async function resolveAutonomous(walletKey, brokerUrlOverride, env, options) {
|
|
114
|
+
const store = options.store ?? selectCredentialStore(env);
|
|
115
|
+
let record;
|
|
116
|
+
try {
|
|
117
|
+
record = await store.load(walletKey);
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
throw configError(`could not read the agent-owned Privy wallet "${walletKey}" from the credential store`, `${describe(error)} On a headless host the OS credential store is often unavailable; set ${METRIK_WALLET_ENCRYPTION_KEY_ENV} to use the encrypted-file store instead.`);
|
|
121
|
+
}
|
|
122
|
+
if (record === null) {
|
|
123
|
+
throw configError(`no agent-owned Privy wallet is stored under the key "${walletKey}"`, `the CLI never provisions a wallet on your behalf — a fund-moving command is the wrong place to mint one. Provision it once with provisionMetrikAutonomousWallet({ storeKey: "${walletKey}" }) (see docs/autonomous-privy-wallet.md), then re-run this command.`);
|
|
124
|
+
}
|
|
125
|
+
if (record.walletId === undefined || record.address === undefined) {
|
|
126
|
+
throw configError(`the agent-owned Privy wallet "${walletKey}" was never finished provisioning`, "the local key exists but the broker never returned a wallet id and address. Re-run provisionMetrikAutonomousWallet() with the same store key — it retries with the same key and idempotency nonce.");
|
|
127
|
+
}
|
|
128
|
+
const brokerUrl = brokerUrlOverride ?? record.brokerUrl;
|
|
129
|
+
if (brokerUrlOverride !== null && brokerUrlOverride !== record.brokerUrl) {
|
|
130
|
+
options.note?.(`note: ${PRIVY_BROKER_URL_ENV} (${brokerUrlOverride}) overrides the broker this wallet was provisioned against (${record.brokerUrl}); only a broker holding this wallet's Privy authorization key can authorize it.`);
|
|
131
|
+
}
|
|
132
|
+
let broker;
|
|
133
|
+
try {
|
|
134
|
+
broker = new HttpAutonomousWalletBroker(brokerUrl, {
|
|
135
|
+
...(options.fetchImpl === undefined
|
|
136
|
+
? {}
|
|
137
|
+
: { fetchImpl: options.fetchImpl }),
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
throw configError(`the autonomous wallet broker URL is not usable: ${describe(error)}`, `set ${PRIVY_BROKER_URL_ENV} to an HTTPS broker you control (the default is ${METRIK_AUTONOMOUS_WALLET_BROKER_URL}).`);
|
|
142
|
+
}
|
|
143
|
+
const provider = createAutonomousWalletProvider({
|
|
144
|
+
wallet: record,
|
|
145
|
+
broker,
|
|
146
|
+
...(options.rpcUrl === undefined ? {} : { rpcUrl: options.rpcUrl }),
|
|
147
|
+
...(options.fetchImpl === undefined
|
|
148
|
+
? {}
|
|
149
|
+
: { fetchImpl: options.fetchImpl }),
|
|
150
|
+
});
|
|
151
|
+
const account = await embeddedAccount(provider, record.appId, record.address);
|
|
152
|
+
return {
|
|
153
|
+
source: "privy-autonomous",
|
|
154
|
+
account,
|
|
155
|
+
transport: custom(provider),
|
|
156
|
+
description: `${record.address} (agent-owned Privy wallet "${walletKey}" via ${brokerUrl})`,
|
|
157
|
+
readSpendPolicy: async () => await fetchPrivySpendPolicy(brokerUrl, options.fetchImpl ?? globalThis.fetch.bind(globalThis)),
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
function resolveSession(input) {
|
|
161
|
+
if (!isAddress(input.address)) {
|
|
162
|
+
throw configError(`${PRIVY_ADDRESS_ENV} must be a 0x-prefixed 20-byte address`);
|
|
163
|
+
}
|
|
164
|
+
const address = getAddress(input.address);
|
|
165
|
+
let provider;
|
|
166
|
+
try {
|
|
167
|
+
provider = createPrivySessionProvider({
|
|
168
|
+
brokerUrl: input.brokerUrl,
|
|
169
|
+
sessionToken: input.sessionToken,
|
|
170
|
+
address,
|
|
171
|
+
...(input.rpcUrl === undefined ? {} : { rpcUrl: input.rpcUrl }),
|
|
172
|
+
...(input.fetchImpl === undefined ? {} : { fetchImpl: input.fetchImpl }),
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
catch (error) {
|
|
176
|
+
throw configError(`the Privy session broker URL is not usable: ${describe(error)}`, `set ${PRIVY_BROKER_URL_ENV} to the HTTPS broker that minted ${PRIVY_SESSION_TOKEN_ENV}. A session token is only valid against the broker that issued it.`);
|
|
177
|
+
}
|
|
178
|
+
return embeddedAccount(provider, input.appId, address).then((account) => ({
|
|
179
|
+
source: "privy-session",
|
|
180
|
+
account,
|
|
181
|
+
transport: custom(provider),
|
|
182
|
+
description: `${address} (Privy broker session via ${input.brokerUrl})`,
|
|
183
|
+
readSpendPolicy: async () => await fetchPrivySpendPolicy(input.brokerUrl, input.fetchImpl ?? globalThis.fetch.bind(globalThis)),
|
|
184
|
+
}));
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Wraps a provider in the package's existing Privy EOA adapter.
|
|
188
|
+
*
|
|
189
|
+
* Both CLI providers answer `eth_chainId` and `eth_accounts` locally, so the
|
|
190
|
+
* adapter's session assertion is a pure local consistency check here — no
|
|
191
|
+
* network call happens while the wallet is being resolved.
|
|
192
|
+
*/
|
|
193
|
+
async function embeddedAccount(provider, appId, address) {
|
|
194
|
+
try {
|
|
195
|
+
return await createPrivyEmbeddedAccount({
|
|
196
|
+
appId,
|
|
197
|
+
address,
|
|
198
|
+
provider,
|
|
199
|
+
chainId: 84532,
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
catch (error) {
|
|
203
|
+
throw configError(`the Privy wallet could not be prepared: ${describe(error)}`, `check ${PRIVY_ENV_VARS.join(", ")}. Metrik Privy wallets are Base Sepolia (84532) only.`);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* The credential store the autonomous wallet was provisioned into.
|
|
208
|
+
*
|
|
209
|
+
* Selection mirrors `provisionMetrikAutonomousWallet`'s documented options:
|
|
210
|
+
* setting `METRIK_WALLET_ENCRYPTION_KEY` means the encrypted-file store (the
|
|
211
|
+
* durable option for a headless host), otherwise the host OS store. Picking a
|
|
212
|
+
* different store than provisioning used simply finds no record, and the
|
|
213
|
+
* "no wallet is stored under this key" error above says so.
|
|
214
|
+
*/
|
|
215
|
+
function selectCredentialStore(env) {
|
|
216
|
+
if (read(env, METRIK_WALLET_ENCRYPTION_KEY_ENV) !== null) {
|
|
217
|
+
return new EncryptedFileCredentialStore({ env });
|
|
218
|
+
}
|
|
219
|
+
return createDefaultAutonomousWalletStore();
|
|
220
|
+
}
|
|
221
|
+
function read(env, name) {
|
|
222
|
+
const value = env[name];
|
|
223
|
+
return value === undefined || value.length === 0 ? null : value;
|
|
224
|
+
}
|
|
225
|
+
function describe(error) {
|
|
226
|
+
if (error instanceof AutonomousWalletError)
|
|
227
|
+
return error.message;
|
|
228
|
+
return error instanceof Error ? error.message : String(error);
|
|
229
|
+
}
|
|
230
|
+
//# sourceMappingURL=privy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"privy.js","sourceRoot":"","sources":["../../src/cli/privy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A heartbeat on stderr for commands that can take a while.
|
|
3
|
+
*
|
|
4
|
+
* A live acceptance run saw `close` take 8s once and 142s the next time, and
|
|
5
|
+
* `status` calls run past two minutes with nothing on screen. With no output at
|
|
6
|
+
* all, a slow RPC and a wedged process look identical, and the only safe reading
|
|
7
|
+
* of that ambiguity — on a command that may have already broadcast a
|
|
8
|
+
* transaction — is the expensive one: wait, or kill it and risk double-sending.
|
|
9
|
+
*
|
|
10
|
+
* So the CLI narrates. Not progress towards a known total (there isn't one), but
|
|
11
|
+
* proof of life plus elapsed time, which is what distinguishes "slow" from
|
|
12
|
+
* "stuck". stderr in BOTH modes, so `--json` stdout stays a single parseable
|
|
13
|
+
* document.
|
|
14
|
+
*/
|
|
15
|
+
export interface Heartbeat {
|
|
16
|
+
/** Stops the ticker. Safe to call more than once. */
|
|
17
|
+
readonly stop: () => void;
|
|
18
|
+
}
|
|
19
|
+
/** Silence before the first tick — below this, a command is simply fast. */
|
|
20
|
+
export declare const HEARTBEAT_DELAY_MS = 8000;
|
|
21
|
+
/** Gap between ticks once it has started. */
|
|
22
|
+
export declare const HEARTBEAT_INTERVAL_MS = 10000;
|
|
23
|
+
export interface HeartbeatOptions {
|
|
24
|
+
readonly delayMs?: number;
|
|
25
|
+
readonly intervalMs?: number;
|
|
26
|
+
/** Injectable for tests; defaults to the global timers. */
|
|
27
|
+
readonly setTimer?: typeof setTimeout;
|
|
28
|
+
readonly clearTimer?: typeof clearTimeout;
|
|
29
|
+
readonly now?: () => number;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Start narrating `label`. Nothing is printed unless the work outlasts
|
|
33
|
+
* `delayMs`, so a fast command is silent and a slow one is legible.
|
|
34
|
+
*/
|
|
35
|
+
export declare function startHeartbeat(note: (line: string) => void, label: string, options?: HeartbeatOptions): Heartbeat;
|
|
36
|
+
//# sourceMappingURL=progress.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"progress.d.ts","sourceRoot":"","sources":["../../src/cli/progress.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,SAAS;IACxB,qDAAqD;IACrD,QAAQ,CAAC,IAAI,EAAE,MAAM,IAAI,CAAC;CAC3B;AAED,4EAA4E;AAC5E,eAAO,MAAM,kBAAkB,OAAQ,CAAC;AACxC,6CAA6C;AAC7C,eAAO,MAAM,qBAAqB,QAAS,CAAC;AAE5C,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,2DAA2D;IAC3D,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,UAAU,CAAC;IACtC,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,YAAY,CAAC;IAC1C,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CAC7B;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,EAC5B,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,gBAAqB,GAC7B,SAAS,CAiCX"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/** Silence before the first tick — below this, a command is simply fast. */
|
|
2
|
+
export const HEARTBEAT_DELAY_MS = 8_000;
|
|
3
|
+
/** Gap between ticks once it has started. */
|
|
4
|
+
export const HEARTBEAT_INTERVAL_MS = 10_000;
|
|
5
|
+
/**
|
|
6
|
+
* Start narrating `label`. Nothing is printed unless the work outlasts
|
|
7
|
+
* `delayMs`, so a fast command is silent and a slow one is legible.
|
|
8
|
+
*/
|
|
9
|
+
export function startHeartbeat(note, label, options = {}) {
|
|
10
|
+
const delayMs = options.delayMs ?? HEARTBEAT_DELAY_MS;
|
|
11
|
+
const intervalMs = options.intervalMs ?? HEARTBEAT_INTERVAL_MS;
|
|
12
|
+
const setTimer = options.setTimer ?? setTimeout;
|
|
13
|
+
const clearTimer = options.clearTimer ?? clearTimeout;
|
|
14
|
+
const now = options.now ?? Date.now;
|
|
15
|
+
const startedAt = now();
|
|
16
|
+
let timer;
|
|
17
|
+
let stopped = false;
|
|
18
|
+
const tick = () => {
|
|
19
|
+
if (stopped)
|
|
20
|
+
return;
|
|
21
|
+
const elapsed = Math.round((now() - startedAt) / 1000);
|
|
22
|
+
note(`… still working: ${label} (${elapsed}s elapsed). Slow RPC or oracle, not a hang — nothing is retried silently.`);
|
|
23
|
+
schedule(intervalMs);
|
|
24
|
+
};
|
|
25
|
+
const schedule = (ms) => {
|
|
26
|
+
timer = setTimer(tick, ms);
|
|
27
|
+
// Never hold the process open on account of the narration.
|
|
28
|
+
timer.unref?.();
|
|
29
|
+
};
|
|
30
|
+
schedule(delayMs);
|
|
31
|
+
return {
|
|
32
|
+
stop() {
|
|
33
|
+
stopped = true;
|
|
34
|
+
if (timer !== undefined)
|
|
35
|
+
clearTimer(timer);
|
|
36
|
+
timer = undefined;
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=progress.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"progress.js","sourceRoot":"","sources":["../../src/cli/progress.ts"],"names":[],"mappings":"AAmBA,4EAA4E;AAC5E,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,CAAC;AACxC,6CAA6C;AAC7C,MAAM,CAAC,MAAM,qBAAqB,GAAG,MAAM,CAAC;AAW5C;;;GAGG;AACH,MAAM,UAAU,cAAc,CAC5B,IAA4B,EAC5B,KAAa,EACb,UAA4B,EAAE;IAE9B,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,kBAAkB,CAAC;IACtD,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,qBAAqB,CAAC;IAC/D,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,UAAU,CAAC;IAChD,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,YAAY,CAAC;IACtD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;IAEpC,MAAM,SAAS,GAAG,GAAG,EAAE,CAAC;IACxB,IAAI,KAAgD,CAAC;IACrD,IAAI,OAAO,GAAG,KAAK,CAAC;IAEpB,MAAM,IAAI,GAAG,GAAS,EAAE;QACtB,IAAI,OAAO;YAAE,OAAO;QACpB,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,GAAG,IAAI,CAAC,CAAC;QACvD,IAAI,CACF,oBAAoB,KAAK,KAAK,OAAO,2EAA2E,CACjH,CAAC;QACF,QAAQ,CAAC,UAAU,CAAC,CAAC;IACvB,CAAC,CAAC;IACF,MAAM,QAAQ,GAAG,CAAC,EAAU,EAAQ,EAAE;QACpC,KAAK,GAAG,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC3B,2DAA2D;QAC1D,KAAgC,CAAC,KAAK,EAAE,EAAE,CAAC;IAC9C,CAAC,CAAC;IACF,QAAQ,CAAC,OAAO,CAAC,CAAC;IAElB,OAAO;QACL,IAAI;YACF,OAAO,GAAG,IAAI,CAAC;YACf,IAAI,KAAK,KAAK,SAAS;gBAAE,UAAU,CAAC,KAAK,CAAC,CAAC;YAC3C,KAAK,GAAG,SAAS,CAAC;QACpB,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type CliStreams } from "./output.js";
|
|
2
|
+
import { type CliDependencies } from "./deps.js";
|
|
3
|
+
import type { CommandSpec } from "./context.js";
|
|
4
|
+
/**
|
|
5
|
+
* The command surface, in the order the product loop runs:
|
|
6
|
+
* discover -> open -> invoke -> watch/status -> close -> reclaim, then the
|
|
7
|
+
* operator's own redemption (`claim`) and the buyer's last-resort exit
|
|
8
|
+
* (`reclaim-unverified`). `streams` (which of them are mine?) sits inside that
|
|
9
|
+
* loop; `mcp` (run the same loop from an MCP host) sits after it.
|
|
10
|
+
*/
|
|
11
|
+
export declare const COMMANDS: readonly CommandSpec[];
|
|
12
|
+
export interface RunCliOptions {
|
|
13
|
+
readonly argv: readonly string[];
|
|
14
|
+
readonly env?: NodeJS.ProcessEnv;
|
|
15
|
+
readonly streams?: CliStreams;
|
|
16
|
+
readonly deps?: CliDependencies;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Runs one CLI invocation and returns the process exit code. Pure in its
|
|
20
|
+
* inputs: argv, env, output sinks and side-effecting dependencies are all
|
|
21
|
+
* injected, so the whole surface is testable without a key or an RPC.
|
|
22
|
+
*/
|
|
23
|
+
export declare function runCli(options: RunCliOptions): Promise<number>;
|
|
24
|
+
export declare function renderHelp(commandName?: string): string;
|
|
25
|
+
//# sourceMappingURL=run.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/cli/run.ts"],"names":[],"mappings":"AAQA,OAAO,EAAiB,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAE7D,OAAO,EAA0B,KAAK,eAAe,EAAE,MAAM,WAAW,CAAC;AAGzE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAchD;;;;;;GAMG;AACH,eAAO,MAAM,QAAQ,EAAE,SAAS,WAAW,EAY1C,CAAC;AAEF,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACjC,QAAQ,CAAC,OAAO,CAAC,EAAE,UAAU,CAAC;IAC9B,QAAQ,CAAC,IAAI,CAAC,EAAE,eAAe,CAAC;CACjC;AAED;;;;GAIG;AACH,wBAAsB,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAiEpE;AAqBD,wBAAgB,UAAU,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CA8DvD"}
|
package/dist/cli/run.js
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import { assertKnownFlags, booleanFlag, parseArgs } from "./args.js";
|
|
2
|
+
import { CONFIG_FLAGS, GLOBAL_FLAGS, TESTNET_CHAIN_IDS, resolveConfig, } from "./config.js";
|
|
3
|
+
import { CliError, describeError, usageError } from "./errors.js";
|
|
4
|
+
import { createPrinter } from "./output.js";
|
|
5
|
+
import { startHeartbeat } from "./progress.js";
|
|
6
|
+
import { defaultCliDependencies } from "./deps.js";
|
|
7
|
+
import { packageVersion } from "./version.js";
|
|
8
|
+
import { CDP_ENV_VARS, PRIVATE_KEY_ENV } from "./wallet.js";
|
|
9
|
+
import { claimCommand } from "./commands/claim.js";
|
|
10
|
+
import { closeCommand } from "./commands/close.js";
|
|
11
|
+
import { discoverCommand } from "./commands/discover.js";
|
|
12
|
+
import { invokeCommand } from "./commands/invoke.js";
|
|
13
|
+
import { mcpCommand } from "./commands/mcp.js";
|
|
14
|
+
import { openCommand } from "./commands/open.js";
|
|
15
|
+
import { reclaimCommand } from "./commands/reclaim.js";
|
|
16
|
+
import { reclaimUnverifiedCommand } from "./commands/reclaim-unverified.js";
|
|
17
|
+
import { statusCommand } from "./commands/status.js";
|
|
18
|
+
import { streamsCommand } from "./commands/streams.js";
|
|
19
|
+
import { watchCommand } from "./commands/watch.js";
|
|
20
|
+
/**
|
|
21
|
+
* The command surface, in the order the product loop runs:
|
|
22
|
+
* discover -> open -> invoke -> watch/status -> close -> reclaim, then the
|
|
23
|
+
* operator's own redemption (`claim`) and the buyer's last-resort exit
|
|
24
|
+
* (`reclaim-unverified`). `streams` (which of them are mine?) sits inside that
|
|
25
|
+
* loop; `mcp` (run the same loop from an MCP host) sits after it.
|
|
26
|
+
*/
|
|
27
|
+
export const COMMANDS = [
|
|
28
|
+
discoverCommand,
|
|
29
|
+
openCommand,
|
|
30
|
+
statusCommand,
|
|
31
|
+
streamsCommand,
|
|
32
|
+
watchCommand,
|
|
33
|
+
invokeCommand,
|
|
34
|
+
closeCommand,
|
|
35
|
+
reclaimCommand,
|
|
36
|
+
reclaimUnverifiedCommand,
|
|
37
|
+
claimCommand,
|
|
38
|
+
mcpCommand,
|
|
39
|
+
];
|
|
40
|
+
/**
|
|
41
|
+
* Runs one CLI invocation and returns the process exit code. Pure in its
|
|
42
|
+
* inputs: argv, env, output sinks and side-effecting dependencies are all
|
|
43
|
+
* injected, so the whole surface is testable without a key or an RPC.
|
|
44
|
+
*/
|
|
45
|
+
export async function runCli(options) {
|
|
46
|
+
const env = options.env ?? process.env;
|
|
47
|
+
const streams = options.streams ?? {
|
|
48
|
+
stdout: (line) => process.stdout.write(`${line}\n`),
|
|
49
|
+
stderr: (line) => process.stderr.write(`${line}\n`),
|
|
50
|
+
};
|
|
51
|
+
const deps = options.deps ?? defaultCliDependencies;
|
|
52
|
+
let json = false;
|
|
53
|
+
try {
|
|
54
|
+
const args = parseArgs(options.argv);
|
|
55
|
+
json = booleanFlag(args, "json");
|
|
56
|
+
const out = createPrinter(streams, json);
|
|
57
|
+
// `--version` is checked before the bare-invocation help branch: `metrik
|
|
58
|
+
// --version` parses to no command at all.
|
|
59
|
+
if (args.command === "version" || booleanFlag(args, "version")) {
|
|
60
|
+
streams.stdout(packageVersion());
|
|
61
|
+
return 0;
|
|
62
|
+
}
|
|
63
|
+
if (args.command === null || args.command === "help") {
|
|
64
|
+
// A misspelled TOP-LEVEL flag must fail like a misspelled per-command one
|
|
65
|
+
// does. Printing help and exiting 0 tells a script the invocation
|
|
66
|
+
// succeeded, which is how a typo goes unnoticed.
|
|
67
|
+
assertKnownFlags(args, [...GLOBAL_FLAGS, "version"]);
|
|
68
|
+
streams.stdout(renderHelp(args.positionals[0]));
|
|
69
|
+
return 0;
|
|
70
|
+
}
|
|
71
|
+
const command = COMMANDS.find((spec) => spec.name === args.command);
|
|
72
|
+
if (command === undefined) {
|
|
73
|
+
throw usageError(`unknown command: ${args.command}`, `commands: ${COMMANDS.map((spec) => spec.name).join(", ")}`);
|
|
74
|
+
}
|
|
75
|
+
if (booleanFlag(args, "help")) {
|
|
76
|
+
streams.stdout(renderHelp(command.name));
|
|
77
|
+
return 0;
|
|
78
|
+
}
|
|
79
|
+
assertKnownFlags(args, [
|
|
80
|
+
...GLOBAL_FLAGS,
|
|
81
|
+
...CONFIG_FLAGS,
|
|
82
|
+
...command.flags,
|
|
83
|
+
]);
|
|
84
|
+
const config = resolveConfig(args, env);
|
|
85
|
+
// Every command gets the heartbeat, in one place rather than per command:
|
|
86
|
+
// any of them can be the one waiting on a slow endpoint, and a rule with an
|
|
87
|
+
// exception is a rule someone forgets to apply to the next command.
|
|
88
|
+
const heartbeat = startHeartbeat(out.note, `metrik ${command.name}`);
|
|
89
|
+
try {
|
|
90
|
+
await command.run({ args, config, env, out, deps });
|
|
91
|
+
}
|
|
92
|
+
finally {
|
|
93
|
+
heartbeat.stop();
|
|
94
|
+
}
|
|
95
|
+
return 0;
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
if (error instanceof CliError) {
|
|
99
|
+
emitFailure(streams, json, error.message, error.hint, error.exitCode);
|
|
100
|
+
return error.exitCode;
|
|
101
|
+
}
|
|
102
|
+
emitFailure(streams, json, describeError(error), undefined, 4);
|
|
103
|
+
return 4;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
function emitFailure(streams, json, message, hint, exitCode) {
|
|
107
|
+
if (json) {
|
|
108
|
+
// The failure goes to stderr even in --json mode so stdout stays either a
|
|
109
|
+
// result document or nothing at all.
|
|
110
|
+
streams.stderr(JSON.stringify({ error: message, hint: hint ?? null, exitCode }));
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
streams.stderr(`error: ${message}`);
|
|
114
|
+
if (hint !== undefined)
|
|
115
|
+
streams.stderr(` ${hint}`);
|
|
116
|
+
}
|
|
117
|
+
export function renderHelp(commandName) {
|
|
118
|
+
const command = COMMANDS.find((spec) => spec.name === commandName);
|
|
119
|
+
if (command !== undefined) {
|
|
120
|
+
return [
|
|
121
|
+
`metrik ${command.name} — ${command.summary}`,
|
|
122
|
+
"",
|
|
123
|
+
`Usage: ${command.usage}`,
|
|
124
|
+
"",
|
|
125
|
+
command.flags.length === 0
|
|
126
|
+
? "Command flags: (none)"
|
|
127
|
+
: `Command flags: ${command.flags.map((flag) => `--${flag}`).join(" ")}`,
|
|
128
|
+
`Settlement flags: ${CONFIG_FLAGS.map((flag) => `--${flag}`).join(" ")}`,
|
|
129
|
+
"Output flags: --json",
|
|
130
|
+
...(command.signs
|
|
131
|
+
? [
|
|
132
|
+
"",
|
|
133
|
+
`Broadcasts a transaction. Requires a wallet in the environment: ${PRIVATE_KEY_ENV}, or ${CDP_ENV_VARS.join(" + ")}.`,
|
|
134
|
+
]
|
|
135
|
+
: command.requiresKey === true
|
|
136
|
+
? [
|
|
137
|
+
"",
|
|
138
|
+
`Broadcasts nothing, but signs an off-chain EIP-712 capability, so it requires a wallet in the environment: ${PRIVATE_KEY_ENV}, or ${CDP_ENV_VARS.join(" + ")}.`,
|
|
139
|
+
]
|
|
140
|
+
: []),
|
|
141
|
+
].join("\n");
|
|
142
|
+
}
|
|
143
|
+
const width = COMMANDS.reduce((max, spec) => Math.max(max, spec.name.length), 0);
|
|
144
|
+
return [
|
|
145
|
+
`metrik ${packageVersion()} — pay for verified delivery, metered by the second`,
|
|
146
|
+
"",
|
|
147
|
+
"You rent a verified-live endpoint BY TIME, not per call: the oracle probes it and the",
|
|
148
|
+
"meter runs on availability that verified. One request and a thousand cost the same",
|
|
149
|
+
"second, and the clock keeps running while you send none. `metrik close` stops it.",
|
|
150
|
+
"",
|
|
151
|
+
"Usage: metrik <command> [options]",
|
|
152
|
+
"",
|
|
153
|
+
"Commands:",
|
|
154
|
+
...COMMANDS.map((spec) => ` ${spec.name.padEnd(width)} ${spec.summary}${spec.signs ? " [broadcasts a tx]" : spec.requiresKey === true ? " [needs a key]" : ""}`),
|
|
155
|
+
"",
|
|
156
|
+
"Global flags:",
|
|
157
|
+
" --json machine-readable output on stdout",
|
|
158
|
+
" --help this text, or `metrik <command> --help`",
|
|
159
|
+
"",
|
|
160
|
+
"Settlement flags (all default to Metrik's Base Sepolia deployment):",
|
|
161
|
+
" --chain-id --rpc-url --escrow --usdc --oracle-url --registry-url",
|
|
162
|
+
"",
|
|
163
|
+
"Wallet (read from the environment only; never accepted as a flag):",
|
|
164
|
+
` ${PRIVATE_KEY_ENV} a Base Sepolia test key. Checked first.`,
|
|
165
|
+
` ${CDP_ENV_VARS.join(", ")}`,
|
|
166
|
+
" a Coinbase CDP Server Wallet v2 account. Used when no private key is set.",
|
|
167
|
+
" A credential on the command line lands in shell history; these never are.",
|
|
168
|
+
"",
|
|
169
|
+
`TESTNET ONLY: this CLI refuses any chain outside ${TESTNET_CHAIN_IDS.join(", ")} (Base Sepolia),`,
|
|
170
|
+
"and re-checks the chain id the RPC actually serves before signing. There is no override.",
|
|
171
|
+
].join("\n");
|
|
172
|
+
}
|
|
173
|
+
//# sourceMappingURL=run.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/cli/run.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure block-range arithmetic for the escrow log scan behind `metrik streams`.
|
|
3
|
+
* No RPC, no clock, no env — so the coverage rules below are unit-testable
|
|
4
|
+
* without a network, which is the point: they decide when an empty result is
|
|
5
|
+
* allowed to be rendered as "you have no streams".
|
|
6
|
+
*
|
|
7
|
+
* ## Why the anchor is the deploy block
|
|
8
|
+
*
|
|
9
|
+
* A fixed lookback ("the last N blocks") cannot describe coverage: a wallet
|
|
10
|
+
* whose stream predates the window is shown an empty list with nothing to
|
|
11
|
+
* distinguish it from a wallet that never opened one. For a payments tool,
|
|
12
|
+
* telling someone their escrowed funds do not exist is the worst failure we
|
|
13
|
+
* have. The escrow has NO history before its deploy block, so that block is the
|
|
14
|
+
* honest anchor — and whether the budget reached it is then a fact the command
|
|
15
|
+
* can state.
|
|
16
|
+
*
|
|
17
|
+
* ## Why the window is 10 000 blocks
|
|
18
|
+
*
|
|
19
|
+
* `buyer` and `operator` are INDEXED on `StreamOpened`, so a per-wallet scan is
|
|
20
|
+
* a server-side topic filter whose response is tiny regardless of range. What
|
|
21
|
+
* public RPCs cap is the per-call BLOCK RANGE, and a topic filter does not lift
|
|
22
|
+
* it: `sepolia.base.org` answers a wider range with `-32614 "eth_getLogs is
|
|
23
|
+
* limited to a 10,000 range"`. So the page size is the cap, not a guess below
|
|
24
|
+
* it.
|
|
25
|
+
*/
|
|
26
|
+
/**
|
|
27
|
+
* getLogs page size. The window is `chunk + 1` blocks (bounds inclusive), so
|
|
28
|
+
* 9 999 is the largest page `sepolia.base.org` accepts.
|
|
29
|
+
*/
|
|
30
|
+
export declare const LOG_SCAN_CHUNK = 9999n;
|
|
31
|
+
/**
|
|
32
|
+
* Window budget for one scan. 400 x 10 000 = 4 000 000 blocks, comfortably more
|
|
33
|
+
* than the live escrow's history (~1.06M blocks on 2026-09-17), so the default
|
|
34
|
+
* scan is complete rather than merely large. It is a CEILING, not a fixed cost:
|
|
35
|
+
* windows are built for the actual anchor-to-head span. Exceeding it is not an
|
|
36
|
+
* error — it is reported as `degraded`.
|
|
37
|
+
*/
|
|
38
|
+
export declare const LOG_SCAN_MAX_WINDOWS = 400;
|
|
39
|
+
export interface ScanRange {
|
|
40
|
+
readonly fromBlock: bigint;
|
|
41
|
+
readonly toBlock: bigint;
|
|
42
|
+
/** Inclusive `[from, to]` windows, in ascending order. */
|
|
43
|
+
readonly windows: readonly (readonly [bigint, bigint])[];
|
|
44
|
+
/** True iff the budget could NOT reach `anchor`, i.e. the scan is partial. */
|
|
45
|
+
readonly degraded: boolean;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Page `[anchor, head]` into non-overlapping inclusive windows.
|
|
49
|
+
*
|
|
50
|
+
* An RPC that is behind the deployment yields an empty-but-valid range rather
|
|
51
|
+
* than a negative one, and an anchor past the head is clamped: a node still
|
|
52
|
+
* syncing must not produce a nonsense scan.
|
|
53
|
+
*/
|
|
54
|
+
export declare function escrowScanRange(head: bigint, anchorBlock: bigint, chunk?: bigint, maxWindows?: number): ScanRange;
|
|
55
|
+
//# sourceMappingURL=scan-range.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan-range.d.ts","sourceRoot":"","sources":["../../src/cli/scan-range.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH;;;GAGG;AACH,eAAO,MAAM,cAAc,QAAS,CAAC;AAErC;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,MAAM,CAAC;AAExC,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,0DAA0D;IAC1D,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC;IACzD,8EAA8E;IAC9E,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;CAC5B;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnB,KAAK,GAAE,MAAuB,EAC9B,UAAU,GAAE,MAA6B,GACxC,SAAS,CAaX"}
|