run402 4.93.2 → 4.95.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 +61 -59
- package/cli.mjs +40 -47
- package/core-dist/config.js +52 -18
- package/core-dist/control-plane-session.js +31 -6
- package/core-dist/keystore.js +7 -7
- package/core-dist/profiles.js +9 -7
- package/core-dist/{allowance-auth.js → wallet-auth.js} +15 -15
- package/{sdk/core-dist/allowance.js → core-dist/wallet.js} +20 -20
- package/{sdk/core-dist/write-auth-session.js → core-dist/write-approvals.js} +19 -19
- package/gitvault-surface.json +2 -2
- package/lib/admin.mjs +6 -6
- package/lib/agent.mjs +20 -18
- package/lib/ai.mjs +5 -5
- package/lib/approve.mjs +81 -0
- package/lib/apps.mjs +12 -12
- package/lib/archives.mjs +371 -8
- package/lib/argparse.mjs +5 -5
- package/lib/assets.mjs +14 -14
- package/lib/auth.mjs +34 -34
- package/lib/billing.mjs +6 -6
- package/lib/branches.mjs +7 -7
- package/lib/buzz-doctor.mjs +2 -2
- package/lib/buzz-notifications.mjs +5 -5
- package/lib/buzz.mjs +3 -3
- package/lib/buzz.test.mjs +1 -1
- package/lib/cache.mjs +1 -1
- package/lib/cdn.mjs +2 -2
- package/lib/ci.mjs +12 -12
- package/lib/claims.mjs +2 -2
- package/lib/cold-start.mjs +21 -21
- package/lib/command-manifest.mjs +55 -70
- package/lib/config.mjs +28 -28
- package/lib/contacts.mjs +16 -16
- package/lib/contracts.mjs +12 -12
- package/lib/credentials.mjs +33 -33
- package/lib/daemon-path.mjs +1 -1
- package/lib/delegates.mjs +14 -14
- package/lib/deliveries.mjs +6 -6
- package/lib/deploy-rehearse-discovery.test.mjs +7 -7
- package/lib/deploy-v2.mjs +241 -193
- package/lib/deploy.mjs +21 -53
- package/lib/dev.mjs +3 -3
- package/lib/doctor-source-scan.mjs +1 -1
- package/lib/doctor.mjs +63 -63
- package/lib/domains.mjs +27 -27
- package/lib/email.mjs +38 -38
- package/lib/errors.mjs +40 -24
- package/lib/escalations.mjs +5 -5
- package/lib/events.mjs +32 -25
- package/lib/feedback.mjs +12 -12
- package/lib/functions.mjs +34 -34
- package/lib/gitvault-daemon.mjs +1 -1
- package/lib/gitvault-scaffold.mjs +2 -2
- package/lib/gitvault.mjs +2 -2
- package/lib/grants.mjs +7 -7
- package/lib/image.mjs +10 -10
- package/lib/init.mjs +69 -69
- package/lib/jobs.mjs +15 -15
- package/lib/lightning-wallet.mjs +28 -28
- package/lib/live.mjs +1 -1
- package/lib/login.mjs +207 -0
- package/lib/logout.mjs +53 -0
- package/lib/logs.mjs +8 -8
- package/lib/messages.mjs +5 -5
- package/lib/next-actions.mjs +16 -16
- package/lib/org-context.mjs +13 -13
- package/lib/{org.mjs → orgs.mjs} +215 -167
- package/lib/pay.mjs +1 -1
- package/lib/projects.mjs +70 -84
- package/lib/redeem.mjs +7 -8
- package/lib/remote-helper-session.mjs +12 -12
- package/lib/repos.mjs +83 -83
- package/lib/rooms.mjs +105 -69
- package/lib/sdk-errors.mjs +10 -5
- package/lib/sdk.mjs +3 -3
- package/lib/secrets.mjs +13 -13
- package/lib/service.mjs +5 -5
- package/lib/session-proofs.mjs +21 -0
- package/lib/sign-in.mjs +296 -0
- package/lib/sites.mjs +22 -22
- package/lib/snapshots.mjs +10 -10
- package/lib/stats.mjs +2 -2
- package/lib/status.mjs +25 -25
- package/lib/subdomains.mjs +30 -30
- package/lib/subscriptions.mjs +10 -10
- package/lib/tier.mjs +29 -22
- package/lib/transfer.mjs +59 -86
- package/lib/up.mjs +14 -14
- package/lib/wallet-context.mjs +4 -4
- package/lib/wallet-context.test.mjs +3 -3
- package/lib/wallets.mjs +197 -32
- package/lib/webhook-secret.mjs +6 -6
- package/lib/webhooks.mjs +8 -8
- package/lib/whoami.mjs +102 -0
- package/package.json +1 -1
- package/sdk/core-dist/config.js +52 -18
- package/sdk/core-dist/control-plane-session.js +31 -6
- package/sdk/core-dist/keystore.js +7 -7
- package/sdk/core-dist/profiles.js +9 -7
- package/sdk/core-dist/{allowance-auth.js → wallet-auth.js} +15 -15
- package/{core-dist/allowance.js → sdk/core-dist/wallet.js} +20 -20
- package/{core-dist/write-auth-session.js → sdk/core-dist/write-approvals.js} +19 -19
- package/sdk/dist/actions.d.ts +4 -4
- package/sdk/dist/actions.d.ts.map +1 -1
- package/sdk/dist/app-up.d.ts +2 -2
- package/sdk/dist/app-up.d.ts.map +1 -1
- package/sdk/dist/config.d.ts +1 -2
- package/sdk/dist/config.d.ts.map +1 -1
- package/sdk/dist/config.js.map +1 -1
- package/sdk/dist/control-plane-credentials.d.ts +8 -8
- package/sdk/dist/control-plane-credentials.js +7 -7
- package/sdk/dist/credentials.d.ts +20 -20
- package/sdk/dist/credentials.d.ts.map +1 -1
- package/sdk/dist/credentials.js +1 -1
- package/sdk/dist/errors.d.ts +26 -28
- package/sdk/dist/errors.d.ts.map +1 -1
- package/sdk/dist/errors.js +35 -38
- package/sdk/dist/errors.js.map +1 -1
- package/sdk/dist/index.d.ts +29 -16
- package/sdk/dist/index.d.ts.map +1 -1
- package/sdk/dist/index.js +30 -17
- package/sdk/dist/index.js.map +1 -1
- package/sdk/dist/kernel.d.ts +1 -1
- package/sdk/dist/kernel.d.ts.map +1 -1
- package/sdk/dist/kernel.js +10 -9
- package/sdk/dist/kernel.js.map +1 -1
- package/sdk/dist/namespaces/admin.d.ts +52 -121
- package/sdk/dist/namespaces/admin.d.ts.map +1 -1
- package/sdk/dist/namespaces/admin.js +41 -45
- package/sdk/dist/namespaces/admin.js.map +1 -1
- package/sdk/dist/namespaces/agent.d.ts +2 -2
- package/sdk/dist/namespaces/agent.d.ts.map +1 -1
- package/sdk/dist/namespaces/agent.js +2 -2
- package/sdk/dist/namespaces/agent.js.map +1 -1
- package/sdk/dist/namespaces/ai.d.ts +2 -2
- package/sdk/dist/namespaces/ai.js +3 -3
- package/sdk/dist/namespaces/ai.js.map +1 -1
- package/sdk/dist/namespaces/assets.js +1 -1
- package/sdk/dist/namespaces/assets.js.map +1 -1
- package/sdk/dist/namespaces/billing.d.ts +6 -3
- package/sdk/dist/namespaces/billing.d.ts.map +1 -1
- package/sdk/dist/namespaces/billing.js.map +1 -1
- package/sdk/dist/namespaces/buzz-notifications.types.d.ts +1 -1
- package/sdk/dist/namespaces/buzz.d.ts +2 -2
- package/sdk/dist/namespaces/buzz.d.ts.map +1 -1
- package/sdk/dist/namespaces/buzz.js +2 -2
- package/sdk/dist/namespaces/buzz.js.map +1 -1
- package/sdk/dist/namespaces/buzz.types.d.ts +2 -2
- package/sdk/dist/namespaces/buzz.types.d.ts.map +1 -1
- package/sdk/dist/namespaces/ci.js +3 -3
- package/sdk/dist/namespaces/ci.js.map +1 -1
- package/sdk/dist/namespaces/credentials.types.d.ts +1 -1
- package/sdk/dist/namespaces/deploy.d.ts +1 -1
- package/sdk/dist/namespaces/deploy.d.ts.map +1 -1
- package/sdk/dist/namespaces/deploy.js +31 -32
- package/sdk/dist/namespaces/deploy.js.map +1 -1
- package/sdk/dist/namespaces/deploy.types.d.ts +6 -6
- package/sdk/dist/namespaces/deploy.types.d.ts.map +1 -1
- package/sdk/dist/namespaces/domains.d.ts +10 -2
- package/sdk/dist/namespaces/domains.d.ts.map +1 -1
- package/sdk/dist/namespaces/domains.js +10 -5
- package/sdk/dist/namespaces/domains.js.map +1 -1
- package/sdk/dist/namespaces/errors.js +1 -1
- package/sdk/dist/namespaces/escalations.d.ts +1 -1
- package/sdk/dist/namespaces/escalations.js +1 -1
- package/sdk/dist/namespaces/escalations.types.d.ts +2 -2
- package/sdk/dist/namespaces/escalations.types.d.ts.map +1 -1
- package/sdk/dist/namespaces/events.types.d.ts +1 -1
- package/sdk/dist/namespaces/functions.d.ts +1 -1
- package/sdk/dist/namespaces/functions.js +2 -2
- package/sdk/dist/namespaces/functions.js.map +1 -1
- package/sdk/dist/namespaces/gitvault.crypto.d.ts +1 -1
- package/sdk/dist/namespaces/gitvault.d.ts +26 -26
- package/sdk/dist/namespaces/gitvault.d.ts.map +1 -1
- package/sdk/dist/namespaces/gitvault.js +113 -113
- package/sdk/dist/namespaces/gitvault.js.map +1 -1
- package/sdk/dist/namespaces/me.d.ts +120 -0
- package/sdk/dist/namespaces/me.d.ts.map +1 -0
- package/sdk/dist/namespaces/me.js +34 -0
- package/sdk/dist/namespaces/me.js.map +1 -0
- package/sdk/dist/namespaces/org.d.ts +108 -6
- package/sdk/dist/namespaces/org.d.ts.map +1 -1
- package/sdk/dist/namespaces/org.js +63 -7
- package/sdk/dist/namespaces/org.js.map +1 -1
- package/sdk/dist/namespaces/org.types.d.ts +29 -9
- package/sdk/dist/namespaces/org.types.d.ts.map +1 -1
- package/sdk/dist/namespaces/pay.js +3 -3
- package/sdk/dist/namespaces/pay.js.map +1 -1
- package/sdk/dist/namespaces/projects.d.ts +9 -9
- package/sdk/dist/namespaces/projects.js +15 -15
- package/sdk/dist/namespaces/projects.js.map +1 -1
- package/sdk/dist/namespaces/projects.types.d.ts +28 -12
- package/sdk/dist/namespaces/projects.types.d.ts.map +1 -1
- package/sdk/dist/namespaces/rooms.d.ts +7 -7
- package/sdk/dist/namespaces/rooms.js +17 -17
- package/sdk/dist/namespaces/rooms.js.map +1 -1
- package/sdk/dist/namespaces/rooms.types.d.ts +9 -9
- package/sdk/dist/namespaces/rooms.types.d.ts.map +1 -1
- package/sdk/dist/namespaces/service.d.ts +1 -1
- package/sdk/dist/namespaces/service.js +1 -1
- package/sdk/dist/namespaces/{operator-session.d.ts → session.d.ts} +135 -51
- package/sdk/dist/namespaces/session.d.ts.map +1 -0
- package/sdk/dist/namespaces/{operator-session.js → session.js} +118 -30
- package/sdk/dist/namespaces/session.js.map +1 -0
- package/sdk/dist/namespaces/subdomains.d.ts +5 -5
- package/sdk/dist/namespaces/subdomains.d.ts.map +1 -1
- package/sdk/dist/namespaces/subdomains.js +6 -6
- package/sdk/dist/namespaces/subdomains.js.map +1 -1
- package/sdk/dist/namespaces/tier.d.ts +44 -21
- package/sdk/dist/namespaces/tier.d.ts.map +1 -1
- package/sdk/dist/namespaces/tier.js +7 -7
- package/sdk/dist/namespaces/tier.js.map +1 -1
- package/sdk/dist/namespaces/transfers.d.ts +119 -85
- package/sdk/dist/namespaces/transfers.d.ts.map +1 -1
- package/sdk/dist/namespaces/transfers.js +31 -38
- package/sdk/dist/namespaces/transfers.js.map +1 -1
- package/sdk/dist/namespaces/vouchers.d.ts +9 -10
- package/sdk/dist/namespaces/vouchers.d.ts.map +1 -1
- package/sdk/dist/namespaces/vouchers.js +4 -5
- package/sdk/dist/namespaces/vouchers.js.map +1 -1
- package/sdk/dist/namespaces/wallets.d.ts +72 -3
- package/sdk/dist/namespaces/wallets.d.ts.map +1 -1
- package/sdk/dist/namespaces/wallets.js +141 -3
- package/sdk/dist/namespaces/wallets.js.map +1 -1
- package/sdk/dist/namespaces/write-approval.d.ts +101 -0
- package/sdk/dist/namespaces/write-approval.d.ts.map +1 -0
- package/sdk/dist/namespaces/write-approval.js +62 -0
- package/sdk/dist/namespaces/write-approval.js.map +1 -0
- package/sdk/dist/node/actions-node.d.ts +3 -3
- package/sdk/dist/node/actions-node.d.ts.map +1 -1
- package/sdk/dist/node/actions-node.js +44 -44
- package/sdk/dist/node/actions-node.js.map +1 -1
- package/sdk/dist/node/assets-node.js +6 -6
- package/sdk/dist/node/assets-node.js.map +1 -1
- package/sdk/dist/node/{bearer-claim-key.d.ts → bearer-redeem-key.d.ts} +12 -12
- package/sdk/dist/node/bearer-redeem-key.d.ts.map +1 -0
- package/sdk/dist/node/{bearer-claim-key.js → bearer-redeem-key.js} +21 -21
- package/sdk/dist/node/bearer-redeem-key.js.map +1 -0
- package/sdk/dist/node/ci.d.ts +1 -1
- package/sdk/dist/node/ci.d.ts.map +1 -1
- package/sdk/dist/node/ci.js +6 -6
- package/sdk/dist/node/ci.js.map +1 -1
- package/sdk/dist/node/credentials.d.ts +18 -17
- package/sdk/dist/node/credentials.d.ts.map +1 -1
- package/sdk/dist/node/credentials.js +29 -28
- package/sdk/dist/node/credentials.js.map +1 -1
- package/sdk/dist/node/deploy-manifest.d.ts +3 -5
- package/sdk/dist/node/deploy-manifest.d.ts.map +1 -1
- package/sdk/dist/node/deploy-manifest.js +3 -12
- package/sdk/dist/node/deploy-manifest.js.map +1 -1
- package/sdk/dist/node/funding-recovery.d.ts +1 -1
- package/sdk/dist/node/funding-recovery.d.ts.map +1 -1
- package/sdk/dist/node/funding-recovery.js +1 -1
- package/sdk/dist/node/funding-recovery.js.map +1 -1
- package/sdk/dist/node/gitvault-apply.d.ts +1 -1
- package/sdk/dist/node/gitvault-apply.d.ts.map +1 -1
- package/sdk/dist/node/gitvault-apply.js +1 -1
- package/sdk/dist/node/gitvault-apply.js.map +1 -1
- package/sdk/dist/node/gitvault-handoff.d.ts +22 -22
- package/sdk/dist/node/gitvault-handoff.d.ts.map +1 -1
- package/sdk/dist/node/gitvault-handoff.js +45 -45
- package/sdk/dist/node/gitvault-handoff.js.map +1 -1
- package/sdk/dist/node/gitvault-prewarm.js +7 -7
- package/sdk/dist/node/gitvault-prewarm.js.map +1 -1
- package/sdk/dist/node/gitvault-restore.d.ts +1 -1
- package/sdk/dist/node/gitvault-restore.js +1 -1
- package/sdk/dist/node/index.d.ts +16 -16
- package/sdk/dist/node/index.d.ts.map +1 -1
- package/sdk/dist/node/index.js +15 -15
- package/sdk/dist/node/index.js.map +1 -1
- package/sdk/dist/node/manifest-export.js +2 -2
- package/sdk/dist/node/manifest-export.js.map +1 -1
- package/sdk/dist/node/org-adopt.d.ts +49 -0
- package/sdk/dist/node/org-adopt.d.ts.map +1 -0
- package/sdk/dist/node/org-adopt.js +77 -0
- package/sdk/dist/node/org-adopt.js.map +1 -0
- package/sdk/dist/node/paid-fetch.d.ts +7 -7
- package/sdk/dist/node/paid-fetch.d.ts.map +1 -1
- package/sdk/dist/node/paid-fetch.js +54 -54
- package/sdk/dist/node/paid-fetch.js.map +1 -1
- package/sdk/dist/node/preflight.d.ts +1 -1
- package/sdk/dist/node/preflight.d.ts.map +1 -1
- package/sdk/dist/node/preflight.js +1 -1
- package/sdk/dist/node/preflight.js.map +1 -1
- package/sdk/dist/node/sites-node.js +1 -1
- package/sdk/dist/node/sites-node.js.map +1 -1
- package/sdk/dist/node/source-scan.d.ts +1 -1
- package/sdk/dist/node/source-scan.js +2 -2
- package/sdk/dist/node/source-scan.js.map +1 -1
- package/sdk/dist/scoped.d.ts +11 -11
- package/sdk/dist/scoped.d.ts.map +1 -1
- package/sdk/dist/scoped.js +5 -5
- package/sdk/dist/scoped.js.map +1 -1
- package/core-dist/operator-session.js +0 -154
- package/lib/allowance.mjs +0 -355
- package/lib/cloud.mjs +0 -256
- package/lib/core.mjs +0 -123
- package/lib/operator-proofs.mjs +0 -22
- package/lib/operator.mjs +0 -771
- package/sdk/core-dist/operator-session.js +0 -154
- package/sdk/dist/namespaces/allowance.d.ts +0 -79
- package/sdk/dist/namespaces/allowance.d.ts.map +0 -1
- package/sdk/dist/namespaces/allowance.js +0 -149
- package/sdk/dist/namespaces/allowance.js.map +0 -1
- package/sdk/dist/namespaces/operator-session.d.ts.map +0 -1
- package/sdk/dist/namespaces/operator-session.js.map +0 -1
- package/sdk/dist/namespaces/operator.d.ts +0 -359
- package/sdk/dist/namespaces/operator.d.ts.map +0 -1
- package/sdk/dist/namespaces/operator.js +0 -272
- package/sdk/dist/namespaces/operator.js.map +0 -1
- package/sdk/dist/node/bearer-claim-key.d.ts.map +0 -1
- package/sdk/dist/node/bearer-claim-key.js.map +0 -1
- package/sdk/dist/node/operator-claim.d.ts +0 -49
- package/sdk/dist/node/operator-claim.d.ts.map +0 -1
- package/sdk/dist/node/operator-claim.js +0 -77
- package/sdk/dist/node/operator-claim.js.map +0 -1
package/lib/up.mjs
CHANGED
|
@@ -7,27 +7,27 @@ import { getSdk } from "./sdk.mjs";
|
|
|
7
7
|
import { reportSdkError, fail } from "./sdk-errors.mjs";
|
|
8
8
|
import { assertKnownFlags, flagValue, normalizeArgv, positionalArgs } from "./argparse.mjs";
|
|
9
9
|
import { createUpdateCheckScheduler, emitUpdateNotice } from "./update-check.mjs";
|
|
10
|
-
import {
|
|
10
|
+
import { walletAuthHeaders, isCoreApiTarget, updateProject } from "./config.mjs";
|
|
11
11
|
import { loadLiveControlPlaneSession } from "../core-dist/control-plane-session.js";
|
|
12
12
|
|
|
13
13
|
const HELP = `run402 up — Provision/link/deploy the current app
|
|
14
14
|
|
|
15
15
|
Usage:
|
|
16
|
-
run402 up [repo-or-path] [--name <name>] [--project <
|
|
17
|
-
run402 up verify [repo-or-path] [--project <
|
|
16
|
+
run402 up [repo-or-path] [--name <name>] [--project <project_id>] [--manifest <path>] [--dir <path>] [--tier <tier>] [-y|--yes] [--check|--print-spec|--print-manifest|--plan|--require-plan <plan_id>|--repo-only] [--nested] [--verify] [--human|--json-stream] [--quiet]
|
|
17
|
+
run402 up verify [repo-or-path] [--project <project_id>] [--manifest <path>] [--dir <path>] [--human|--json-stream]
|
|
18
18
|
|
|
19
19
|
Options:
|
|
20
20
|
repo-or-path Local app directory or public Git repository URL. Defaults
|
|
21
21
|
to the current directory.
|
|
22
22
|
--name <name> Project display name when up needs to create a project.
|
|
23
23
|
Not a deploy manifest field and never renames a project.
|
|
24
|
-
--project <
|
|
24
|
+
--project <project_id> Explicit project id. All supplied selectors must agree.
|
|
25
25
|
--manifest <path> Manifest path. Defaults to run402.json, then
|
|
26
26
|
run402.deploy.json, then app.json in --dir/current directory.
|
|
27
27
|
--dir <path> Workspace directory to inspect (default: current dir).
|
|
28
28
|
--tier <tier> Bootstrap tier if no active Cloud tier exists
|
|
29
29
|
(prototype, hobby, team; default prototype).
|
|
30
|
-
-y, --yes Approve recursive prerequisites/local writes (
|
|
30
|
+
-y, --yes Approve recursive prerequisites/local writes (wallet,
|
|
31
31
|
tier, project creation, workspace link) for non-interactive runs.
|
|
32
32
|
--check Validate the manifest/config locally and print the
|
|
33
33
|
preflight, including the site inventory by content type
|
|
@@ -39,7 +39,7 @@ Options:
|
|
|
39
39
|
uploads, or local writes.
|
|
40
40
|
--plan Ask the gateway for a reviewed deploy plan. No upload,
|
|
41
41
|
commit, project provisioning, or workspace link write.
|
|
42
|
-
--require-plan <
|
|
42
|
+
--require-plan <plan_id> Apply only if this reviewed plan still matches.
|
|
43
43
|
--plan-fingerprint <fingerprint>
|
|
44
44
|
Optional fingerprint returned by --plan. Only valid
|
|
45
45
|
with --require-plan.
|
|
@@ -53,7 +53,7 @@ Options:
|
|
|
53
53
|
--propagation-budget-s <n>
|
|
54
54
|
Maximum wall-clock seconds to wait for fresh edge
|
|
55
55
|
propagation during app HTTP verification (default 120).
|
|
56
|
-
--verify After
|
|
56
|
+
--verify After the deploy, wait for gateway/edge release
|
|
57
57
|
coherence and attach the report to the final result.
|
|
58
58
|
--no-propagation-wait
|
|
59
59
|
Return propagation_pending immediately when the edge is
|
|
@@ -104,7 +104,7 @@ coordination only. RUN402_AGENT_NAME=<name> sets the name, overriding an
|
|
|
104
104
|
existing one; RUN402_CLIENT=<name> declares the client when it is not
|
|
105
105
|
auto-detected. A detected client that was not applied (the principal is
|
|
106
106
|
already named) is still reported. Change the name any time with
|
|
107
|
-
'run402
|
|
107
|
+
'run402 whoami --set-name <name>'. Reported under result.identity
|
|
108
108
|
(source, detected, detection).
|
|
109
109
|
--json Emit one final JSON object on stdout (default; compatibility no-op).
|
|
110
110
|
--human Emit the legacy human success/blocking summary on stdout.
|
|
@@ -138,12 +138,12 @@ Works for both app manifests (run402.json) and deploy manifests
|
|
|
138
138
|
(run402.deploy.json / app.json) that declare a top-level verify block.
|
|
139
139
|
|
|
140
140
|
Usage:
|
|
141
|
-
run402 up verify [repo-or-path] [--project <
|
|
141
|
+
run402 up verify [repo-or-path] [--project <project_id>] [--manifest <path>] [--dir <path>] [--name <name>] [--human|--json-stream]
|
|
142
142
|
|
|
143
143
|
Options:
|
|
144
144
|
repo-or-path Local app directory or public Git repository URL. Defaults
|
|
145
145
|
to the current directory.
|
|
146
|
-
--project <
|
|
146
|
+
--project <project_id> Existing project id. Defaults to .run402/project.json,
|
|
147
147
|
manifest project id, then active project.
|
|
148
148
|
--manifest <path> Manifest path. Defaults to run402.json, then
|
|
149
149
|
run402.deploy.json, then app.json.
|
|
@@ -373,7 +373,7 @@ export async function run(args = []) {
|
|
|
373
373
|
? undefined
|
|
374
374
|
: undefined,
|
|
375
375
|
});
|
|
376
|
-
// Cache the activated deployment id so `run402 subdomains
|
|
376
|
+
// Cache the activated deployment id so `run402 subdomains add` can
|
|
377
377
|
// pass it as an optimization (the gateway binds the live release
|
|
378
378
|
// without it). Best-effort: a keystore hiccup never fails `up`.
|
|
379
379
|
{
|
|
@@ -773,12 +773,12 @@ async function readLocalGitState(workDir) {
|
|
|
773
773
|
* inside `up`'s mental model" entry point to the same outcome.
|
|
774
774
|
*/
|
|
775
775
|
async function runRepoOnly({ sdk, workDir, createdRepository, nested = false, opts, tier, idempotencyKey }) {
|
|
776
|
-
// `sdk.up()`'s action graph auto-approves prerequisites (
|
|
776
|
+
// `sdk.up()`'s action graph auto-approves prerequisites (wallet, tier)
|
|
777
777
|
// for a cold start; calling projects.provision directly bypasses that, so
|
|
778
778
|
// this mirrors the SAME gate `run402 projects provision` itself uses —
|
|
779
|
-
// fail with the actionable
|
|
779
|
+
// fail with the actionable NO_WALLET guidance rather than an opaque
|
|
780
780
|
// auth error from the gateway.
|
|
781
|
-
if (!isCoreApiTarget() && !loadLiveControlPlaneSession())
|
|
781
|
+
if (!isCoreApiTarget() && !loadLiveControlPlaneSession()) walletAuthHeaders("/projects/v1");
|
|
782
782
|
const name = flagValue(opts, "--name") ?? undefined;
|
|
783
783
|
const provisioned = await sdk.projects.provision({ tier, name, idempotencyKey });
|
|
784
784
|
createdRepository = await gitInitIfNeeded(workDir);
|
package/lib/wallet-context.mjs
CHANGED
|
@@ -25,7 +25,7 @@ import { join } from "node:path";
|
|
|
25
25
|
import { fail } from "./sdk-errors.mjs";
|
|
26
26
|
import { isValidProfileName } from "../core-dist/config.js";
|
|
27
27
|
import { getDefaultWallet, profileExists, readMeta, profileDir } from "../core-dist/profiles.js";
|
|
28
|
-
import {
|
|
28
|
+
import { readWallet } from "../core-dist/wallet.js";
|
|
29
29
|
import { describeRejectedValue } from "../core-dist/redact.js";
|
|
30
30
|
// The binding file is a CHECKOUT-LEVEL CONTRACT read by more than one surface,
|
|
31
31
|
// so its reader lives in core — `run402-mcp` ships core/dist but not cli/, and
|
|
@@ -104,7 +104,7 @@ export function splitWalletFlag(rawArgv = []) {
|
|
|
104
104
|
* a file left with no keys is deleted rather than committed empty.
|
|
105
105
|
*
|
|
106
106
|
* The file is shared by tiers (`wallet` from `wallets bind`, `org`/`room` from
|
|
107
|
-
* `
|
|
107
|
+
* `orgs bind`) and unknown keys are preserved, so one tier can never clobber
|
|
108
108
|
* another's binding — which a whole-file write did until this existed.
|
|
109
109
|
*/
|
|
110
110
|
export function updateBindingFile(dir, patch) {
|
|
@@ -301,12 +301,12 @@ function shortAddr(a) {
|
|
|
301
301
|
return typeof a === "string" && a.length >= 12 ? `${a.slice(0, 6)}…${a.slice(-4)}` : a;
|
|
302
302
|
}
|
|
303
303
|
|
|
304
|
-
/** Best-effort address for display: meta.json (no key) first,
|
|
304
|
+
/** Best-effort address for display: meta.json (no key) first, wallet second. */
|
|
305
305
|
function walletAddress(name) {
|
|
306
306
|
const meta = readMeta(name);
|
|
307
307
|
if (meta?.address) return meta.address;
|
|
308
308
|
try {
|
|
309
|
-
return
|
|
309
|
+
return readWallet(join(profileDir(name), "wallet.json"))?.address ?? null;
|
|
310
310
|
} catch {
|
|
311
311
|
return null;
|
|
312
312
|
}
|
|
@@ -67,8 +67,8 @@ describe("splitWalletFlag", () => {
|
|
|
67
67
|
assert.deepEqual(r.walletFlag, { flag: "--wallet", value: "kychon" });
|
|
68
68
|
});
|
|
69
69
|
it("strips --wallet=<value> mid-args", () => {
|
|
70
|
-
const r = splitWalletFlag(["deploy", "
|
|
71
|
-
assert.deepEqual(r.argv, ["deploy", "
|
|
70
|
+
const r = splitWalletFlag(["deploy", "--wallet=foo", "--manifest", "x"]);
|
|
71
|
+
assert.deepEqual(r.argv, ["deploy", "--manifest", "x"]);
|
|
72
72
|
assert.equal(r.walletFlag.value, "foo");
|
|
73
73
|
});
|
|
74
74
|
it("leaves --profile to `repos`, which owns it as the AWS credential profile", () => {
|
|
@@ -238,7 +238,7 @@ describe("enforceWalletExists — fail closed", () => {
|
|
|
238
238
|
});
|
|
239
239
|
it("no-op for an existing wallet", () => {
|
|
240
240
|
ensureProfileDir("client-a");
|
|
241
|
-
writeFileSync(join(tmp, "profiles", "client-a", "
|
|
241
|
+
writeFileSync(join(tmp, "profiles", "client-a", "wallet.json"), "{}");
|
|
242
242
|
assert.doesNotThrow(() => enforceWalletExists({ name: "client-a", source: "binding" }, "deploy"));
|
|
243
243
|
});
|
|
244
244
|
it("fails closed for a missing wallet on a normal command", () => {
|
package/lib/wallets.mjs
CHANGED
|
@@ -17,6 +17,7 @@ import { writeFileSync, readFileSync, existsSync, rmSync } from "node:fs";
|
|
|
17
17
|
import { failUnknownSubcommand } from "./argparse.mjs";
|
|
18
18
|
import { join } from "node:path";
|
|
19
19
|
import { fail, reportSdkError } from "./sdk-errors.mjs";
|
|
20
|
+
import { walletFile, readWallet as readActiveWallet, saveWallet as saveActiveWallet } from "./config.mjs";
|
|
20
21
|
import { isValidProfileName, getActiveProfile } from "../core-dist/config.js";
|
|
21
22
|
import {
|
|
22
23
|
listProfileNames,
|
|
@@ -30,10 +31,11 @@ import {
|
|
|
30
31
|
getDefaultWallet,
|
|
31
32
|
setDefaultWallet,
|
|
32
33
|
} from "../core-dist/profiles.js";
|
|
33
|
-
import {
|
|
34
|
+
import { readWallet, saveWallet } from "../core-dist/wallet.js";
|
|
34
35
|
import { describeRejectedValue } from "../core-dist/redact.js";
|
|
35
36
|
import { getSdk } from "./sdk.mjs";
|
|
36
37
|
import { readBindingFile, updateBindingFile } from "./wallet-context.mjs";
|
|
38
|
+
import { initializeWalletAction } from "./next-actions.mjs";
|
|
37
39
|
|
|
38
40
|
const DEFAULT = "default";
|
|
39
41
|
const PRIVATE_KEY_RE = /^0x[0-9a-fA-F]{64}$/;
|
|
@@ -42,16 +44,18 @@ const HELP = `run402 wallets — manage named wallets (profiles)
|
|
|
42
44
|
|
|
43
45
|
Usage:
|
|
44
46
|
run402 wallets list List all wallets (local_label, server_label, address, rail, active)
|
|
45
|
-
run402 wallets current Show the
|
|
46
|
-
run402 wallets
|
|
47
|
+
run402 wallets current Show the active wallet: how it was selected, address, rail, file path, faucet use
|
|
48
|
+
run402 wallets fund Request testnet funds from the faucet into the active wallet (Base Sepolia or Tempo)
|
|
49
|
+
run402 wallets balance The active wallet's on-chain balances, plus its organization's allowance
|
|
50
|
+
run402 wallets new <name> Create a new wallet (key stays local); 'default' creates the root wallet
|
|
47
51
|
run402 wallets use <name> Set the global default wallet
|
|
48
52
|
run402 wallets rename <old> --to <new> Rename a wallet (legacy: rename <old> <new>)
|
|
49
53
|
run402 wallets bind [<name>] Write ./.run402.json binding this directory to a wallet
|
|
50
54
|
run402 wallets unbind Remove ./.run402.json
|
|
51
55
|
run402 wallets import <name> --key <path|-> Adopt an existing private key as a named wallet
|
|
52
56
|
run402 wallets rm <name> --yes Delete a wallet and its keys (requires --yes)
|
|
53
|
-
run402 wallets lightning status The active wallet's Lightning
|
|
54
|
-
run402 wallets lightning mint Mint the Lightning
|
|
57
|
+
run402 wallets lightning status The active wallet's Lightning wallet (balance, budget, custody)
|
|
58
|
+
run402 wallets lightning mint Mint the Lightning wallet for the active wallet (same as init lightning)
|
|
55
59
|
run402 wallets lightning revoke Revoke it: the sub-wallet is deleted on Run402's Hub; the rail returns to x402
|
|
56
60
|
|
|
57
61
|
Selection precedence for normal commands:
|
|
@@ -102,7 +106,7 @@ function walletInfo(name, active) {
|
|
|
102
106
|
const label = meta?.label ?? null;
|
|
103
107
|
if (!address) {
|
|
104
108
|
try {
|
|
105
|
-
const a =
|
|
109
|
+
const a = readWallet(join(profileDir(name), "wallet.json"));
|
|
106
110
|
address = a?.address ?? null;
|
|
107
111
|
rail = rail ?? a?.rail ?? null;
|
|
108
112
|
} catch {
|
|
@@ -127,7 +131,7 @@ function cmdList() {
|
|
|
127
131
|
out(listProfileNames().map((n) => walletInfo(n, active)));
|
|
128
132
|
}
|
|
129
133
|
|
|
130
|
-
function cmdCurrent() {
|
|
134
|
+
async function cmdCurrent() {
|
|
131
135
|
const ctx = activeContext();
|
|
132
136
|
const name = ctx?.name ?? getActiveProfile();
|
|
133
137
|
const info = walletInfo(name, name);
|
|
@@ -146,21 +150,33 @@ function cmdCurrent() {
|
|
|
146
150
|
hint: "Run 'run402 wallets rename' to reconcile.",
|
|
147
151
|
});
|
|
148
152
|
}
|
|
153
|
+
// The active wallet's own file: when it was created, its persisted rail, and
|
|
154
|
+
// whether the faucet has been used on it. `faucet_used` tracks faucet
|
|
155
|
+
// invocation, not pay-readiness — `run402 wallets balance` reads real funds.
|
|
156
|
+
let local = null;
|
|
157
|
+
try {
|
|
158
|
+
local = await getSdk().wallets.status();
|
|
159
|
+
} catch (err) {
|
|
160
|
+
reportSdkError(err);
|
|
161
|
+
}
|
|
149
162
|
out({
|
|
150
163
|
local_label: name,
|
|
151
164
|
source: ctx?.source ?? "unknown",
|
|
152
165
|
source_detail: ctx?.sourceDetail ?? null,
|
|
153
|
-
address: info.address,
|
|
166
|
+
address: local?.configured ? local.address : info.address,
|
|
154
167
|
server_label: info.server_label,
|
|
168
|
+
configured: !!local?.configured,
|
|
169
|
+
created: local?.created ?? null,
|
|
170
|
+
rail: local?.configured ? local.rail ?? "x402" : info.rail,
|
|
171
|
+
faucet_used: !!local?.faucet_used,
|
|
172
|
+
path: local?.path ?? walletFile(),
|
|
173
|
+
...(local?.configured ? {} : { next_actions: [initializeWalletAction()] }),
|
|
155
174
|
warnings,
|
|
156
175
|
});
|
|
157
176
|
}
|
|
158
177
|
|
|
159
178
|
async function cmdNew(args) {
|
|
160
179
|
const name = requireName(args.find((a) => a && !a.startsWith("-")));
|
|
161
|
-
if (name === DEFAULT) {
|
|
162
|
-
fail({ code: "BAD_WALLET_NAME", message: "'default' is reserved. Use 'run402 init' for the default wallet.", details: { name } });
|
|
163
|
-
}
|
|
164
180
|
if (profileExists(name)) {
|
|
165
181
|
fail({ code: "WALLET_EXISTS", message: `A wallet named '${name}' already exists.`, hint: "run402 wallets list", details: { name } });
|
|
166
182
|
}
|
|
@@ -175,12 +191,23 @@ async function cmdNew(args) {
|
|
|
175
191
|
const address = privateKeyToAccount(privateKey).address;
|
|
176
192
|
const created = new Date().toISOString();
|
|
177
193
|
ensureProfileDir(name);
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
194
|
+
saveWallet({ address, privateKey, created, funded: false, rail }, join(profileDir(name), "wallet.json"));
|
|
195
|
+
// The reserved `default` wallet lives at the config-dir root and carries no
|
|
196
|
+
// server label; a named wallet mirrors its name as the label.
|
|
197
|
+
if (name === DEFAULT) {
|
|
198
|
+
writeMeta(name, { name, address, rail, created });
|
|
199
|
+
} else {
|
|
200
|
+
writeMeta(name, { name, address, label: name, rail, created });
|
|
201
|
+
await maybePushLabel(name, name, address);
|
|
202
|
+
}
|
|
181
203
|
// requireName constrains aliases to shell-safe lowercase identifiers.
|
|
182
|
-
const command = rail === "lightning"
|
|
183
|
-
|
|
204
|
+
const command = rail === "lightning"
|
|
205
|
+
? `run402 --wallet ${name} init lightning`
|
|
206
|
+
: name === DEFAULT ? "run402 wallets fund" : `run402 wallets use ${name}`;
|
|
207
|
+
const why = rail === "lightning"
|
|
208
|
+
? "Initialize this Lightning wallet."
|
|
209
|
+
: name === DEFAULT ? "Fund the wallet you just created from the testnet faucet." : "Select the wallet you just created.";
|
|
210
|
+
out({ local_label: name, address, rail, created: true, next: command, next_actions: [{ type: "run_command", command, why }] });
|
|
184
211
|
}
|
|
185
212
|
|
|
186
213
|
function cmdUse(args) {
|
|
@@ -216,7 +243,7 @@ async function cmdRename(args) {
|
|
|
216
243
|
let address = meta.address ?? null;
|
|
217
244
|
if (!address) {
|
|
218
245
|
try {
|
|
219
|
-
address =
|
|
246
|
+
address = readWallet(join(profileDir(newName), "wallet.json"))?.address ?? null;
|
|
220
247
|
} catch {
|
|
221
248
|
/* best-effort */
|
|
222
249
|
}
|
|
@@ -229,7 +256,7 @@ async function cmdRename(args) {
|
|
|
229
256
|
function cmdBind(args) {
|
|
230
257
|
let name = args.find((a) => a && !a.startsWith("-"));
|
|
231
258
|
name = name ? requireName(name) : getActiveProfile();
|
|
232
|
-
// MERGE, never clobber: the same file carries `org`/`room` from `
|
|
259
|
+
// MERGE, never clobber: the same file carries `org`/`room` from `orgs bind`.
|
|
233
260
|
const { contents } = updateBindingFile(process.cwd(), { wallet: name });
|
|
234
261
|
const result = {
|
|
235
262
|
wallet: name,
|
|
@@ -285,7 +312,7 @@ async function cmdImport(args) {
|
|
|
285
312
|
}
|
|
286
313
|
const created = new Date().toISOString();
|
|
287
314
|
ensureProfileDir(name);
|
|
288
|
-
|
|
315
|
+
saveWallet({ address, privateKey, created, funded: false, rail: "x402" }, join(profileDir(name), "wallet.json"));
|
|
289
316
|
writeMeta(name, { name, address, label: name, rail: "x402", created });
|
|
290
317
|
await maybePushLabel(name, name, address);
|
|
291
318
|
out({ local_label: name, address, imported: true });
|
|
@@ -323,11 +350,11 @@ function flagVal(args, flag) {
|
|
|
323
350
|
}
|
|
324
351
|
|
|
325
352
|
/**
|
|
326
|
-
* Best-effort server-side label push. Signs with the TARGET wallet's
|
|
353
|
+
* Best-effort server-side label push. Signs with the TARGET wallet's key
|
|
327
354
|
* (not the active one) so a just-created/renamed wallet can set its own label.
|
|
328
355
|
*
|
|
329
356
|
* ON by default — the gateway label endpoint is live, and the display label is
|
|
330
|
-
* what makes the wallet name show up cross-machine and in the
|
|
357
|
+
* what makes the wallet name show up cross-machine and in the console
|
|
331
358
|
* (WEB). Set `RUN402_WALLET_LABEL_SYNC=0` to disable (fully-offline wallet ops,
|
|
332
359
|
* or hermetic tests). The local folder name is always the source of truth; this
|
|
333
360
|
* only mirrors the display label to the server. Always best-effort — `setLabel`
|
|
@@ -339,7 +366,7 @@ async function maybePushLabel(name, label, address) {
|
|
|
339
366
|
if (!address) return;
|
|
340
367
|
try {
|
|
341
368
|
const sdk = getSdk({
|
|
342
|
-
|
|
369
|
+
walletPath: join(profileDir(name), "wallet.json"),
|
|
343
370
|
keystorePath: join(profileDir(name), "projects.json"),
|
|
344
371
|
});
|
|
345
372
|
await sdk.wallet(address).setLabel(label);
|
|
@@ -364,6 +391,8 @@ export async function run(sub, args = []) {
|
|
|
364
391
|
case "unbind": return cmdUnbind();
|
|
365
392
|
case "import": return cmdImport(rest);
|
|
366
393
|
case "rm": return cmdRm(rest);
|
|
394
|
+
case "fund": return cmdFund();
|
|
395
|
+
case "balance": return cmdBalance();
|
|
367
396
|
case "lightning": return cmdLightning(rest);
|
|
368
397
|
default:
|
|
369
398
|
failUnknownSubcommand("wallets", sub);
|
|
@@ -371,30 +400,30 @@ export async function run(sub, args = []) {
|
|
|
371
400
|
}
|
|
372
401
|
|
|
373
402
|
// ── lightning ────────────────────────────────────────────────────────────────
|
|
374
|
-
// The Lightning
|
|
375
|
-
// The pairing secret stays in
|
|
403
|
+
// The Lightning wallet of the ACTIVE wallet (mpp-lightning-over-nwc).
|
|
404
|
+
// The pairing secret stays in wallet.json and is never printed.
|
|
376
405
|
async function cmdLightning(args) {
|
|
377
406
|
const action = args.find((a) => a && !a.startsWith("-")) ?? "status";
|
|
378
407
|
const { ensureLightningWallet, revokeLightningWallet, describeLightning, readLightningBalance } = await import("./lightning-wallet.mjs");
|
|
379
|
-
const {
|
|
408
|
+
const { readWallet } = await import("../core-dist/wallet.js");
|
|
380
409
|
try {
|
|
381
410
|
if (action === "status") {
|
|
382
|
-
const
|
|
383
|
-
if (!
|
|
411
|
+
const localWallet = readWallet();
|
|
412
|
+
if (!localWallet) fail({ code: "NO_WALLET", message: "No local wallet configured for this wallet.", hint: "run402 init lightning" });
|
|
384
413
|
let wallet = null;
|
|
385
414
|
try { wallet = await getSdk().agent.lightningWallet.get(); } catch (err) {
|
|
386
415
|
const code = err?.body?.code ?? err?.code;
|
|
387
416
|
if (code !== "LIGHTNING_WALLET_NOT_FOUND") throw err;
|
|
388
417
|
}
|
|
389
|
-
const balance = await readLightningBalance(
|
|
390
|
-
const lightning = describeLightning(
|
|
391
|
-
out({ rail:
|
|
418
|
+
const balance = await readLightningBalance(localWallet);
|
|
419
|
+
const lightning = describeLightning(localWallet, wallet, balance);
|
|
420
|
+
out({ rail: localWallet.rail ?? "x402", lightning, ...(lightning ? {} : { hint: "run402 init lightning" }) });
|
|
392
421
|
return;
|
|
393
422
|
}
|
|
394
423
|
if (action === "mint") {
|
|
395
424
|
const result = await ensureLightningWallet();
|
|
396
|
-
const balance = result.outcome === "stored" || result.outcome === "present" ? await readLightningBalance(result.
|
|
397
|
-
out({ outcome: result.outcome, rail: result.
|
|
425
|
+
const balance = result.outcome === "stored" || result.outcome === "present" ? await readLightningBalance(result.localWallet) : null;
|
|
426
|
+
out({ outcome: result.outcome, rail: result.localWallet.rail ?? "x402", lightning: describeLightning(result.localWallet, result.wallet, balance) });
|
|
398
427
|
return;
|
|
399
428
|
}
|
|
400
429
|
if (action === "revoke") {
|
|
@@ -407,3 +436,139 @@ async function cmdLightning(args) {
|
|
|
407
436
|
reportSdkError(err);
|
|
408
437
|
}
|
|
409
438
|
}
|
|
439
|
+
|
|
440
|
+
// ── fund / balance (the ACTIVE wallet) ─────────────────────────────────────
|
|
441
|
+
|
|
442
|
+
const USDC_ABI = [{ name: "balanceOf", type: "function", stateMutability: "view", inputs: [{ name: "account", type: "address" }], outputs: [{ name: "", type: "uint256" }] }];
|
|
443
|
+
const USDC_MAINNET = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
|
|
444
|
+
const USDC_SEPOLIA = "0x036CbD53842c5426634e7929541eC2318f3dCF7e";
|
|
445
|
+
const PATH_USD = "0x20c0000000000000000000000000000000000000";
|
|
446
|
+
const TEMPO_RPC = "https://rpc.moderato.tempo.xyz/";
|
|
447
|
+
|
|
448
|
+
async function loadDeps() {
|
|
449
|
+
const { generatePrivateKey, privateKeyToAccount } = await import("viem/accounts");
|
|
450
|
+
const { createPublicClient, http, defineChain } = await import("viem");
|
|
451
|
+
const { base, baseSepolia } = await import("viem/chains");
|
|
452
|
+
const tempoModerato = defineChain({
|
|
453
|
+
id: 42431,
|
|
454
|
+
name: "Tempo Moderato",
|
|
455
|
+
nativeCurrency: { name: "pathUSD", symbol: "pathUSD", decimals: 6 },
|
|
456
|
+
rpcUrls: { default: { http: [TEMPO_RPC] } },
|
|
457
|
+
});
|
|
458
|
+
return { generatePrivateKey, privateKeyToAccount, createPublicClient, http, base, baseSepolia, tempoModerato };
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
async function cmdFund() {
|
|
462
|
+
const w = readActiveWallet();
|
|
463
|
+
if (!w) {
|
|
464
|
+
fail({
|
|
465
|
+
code: "NO_WALLET",
|
|
466
|
+
message: "No local wallet.",
|
|
467
|
+
hint: "Run: run402 init",
|
|
468
|
+
});
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
if (w.rail === "mpp") {
|
|
472
|
+
// Tempo Moderato faucet — instant, no polling needed
|
|
473
|
+
const { createPublicClient, http, tempoModerato } = await loadDeps();
|
|
474
|
+
const client = createPublicClient({ chain: tempoModerato, transport: http() });
|
|
475
|
+
const before = await readUsdcBalance(client, PATH_USD, w.address).catch(() => 0);
|
|
476
|
+
|
|
477
|
+
const res = await fetch(TEMPO_RPC, {
|
|
478
|
+
method: "POST",
|
|
479
|
+
headers: { "Content-Type": "application/json" },
|
|
480
|
+
body: JSON.stringify({ jsonrpc: "2.0", method: "tempo_fundAddress", params: [w.address], id: 1 }),
|
|
481
|
+
});
|
|
482
|
+
const data = await res.json();
|
|
483
|
+
if (data.error) {
|
|
484
|
+
fail({
|
|
485
|
+
code: "FAUCET_FAILED",
|
|
486
|
+
message: data.error.message || "Tempo faucet failed",
|
|
487
|
+
details: { rail: "mpp" },
|
|
488
|
+
});
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
// Re-read balance once (instant confirmation)
|
|
492
|
+
const now = await readUsdcBalance(client, PATH_USD, w.address).catch(() => before);
|
|
493
|
+
saveActiveWallet({ ...w, funded: true, lastFaucet: new Date().toISOString() });
|
|
494
|
+
console.log(JSON.stringify({
|
|
495
|
+
address: w.address,
|
|
496
|
+
rail: "mpp",
|
|
497
|
+
onchain: {
|
|
498
|
+
"tempo-moderato_pathusd_micros": now,
|
|
499
|
+
},
|
|
500
|
+
}, null, 2));
|
|
501
|
+
return;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
// Default: Base Sepolia faucet (existing behavior)
|
|
505
|
+
const { createPublicClient, http, baseSepolia } = await loadDeps();
|
|
506
|
+
const client = createPublicClient({ chain: baseSepolia, transport: http() });
|
|
507
|
+
const before = await readUsdcBalance(client, USDC_SEPOLIA, w.address).catch(() => 0);
|
|
508
|
+
|
|
509
|
+
let data;
|
|
510
|
+
try {
|
|
511
|
+
data = await getSdk().wallets.faucet(w.address);
|
|
512
|
+
} catch (err) {
|
|
513
|
+
reportSdkError(err);
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
const MAX_WAIT = 30;
|
|
517
|
+
for (let i = 0; i < MAX_WAIT; i++) {
|
|
518
|
+
await new Promise(r => setTimeout(r, 1000));
|
|
519
|
+
const now = await readUsdcBalance(client, USDC_SEPOLIA, w.address).catch(() => before);
|
|
520
|
+
if (now > before) {
|
|
521
|
+
saveActiveWallet({ ...w, funded: true, lastFaucet: new Date().toISOString() });
|
|
522
|
+
console.log(JSON.stringify({
|
|
523
|
+
address: w.address,
|
|
524
|
+
rail: w.rail || "x402",
|
|
525
|
+
onchain: {
|
|
526
|
+
"base-sepolia_usd_micros": now,
|
|
527
|
+
},
|
|
528
|
+
}, null, 2));
|
|
529
|
+
return;
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
saveActiveWallet({ ...w, funded: true, lastFaucet: new Date().toISOString() });
|
|
534
|
+
console.log(JSON.stringify({ ...data, balance_confirmed: false, hint: "Faucet request sent but on-chain balance not yet confirmed" }));
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
async function readUsdcBalance(client, usdc, address) {
|
|
538
|
+
const raw = await client.readContract({ address: usdc, abi: USDC_ABI, functionName: "balanceOf", args: [address] });
|
|
539
|
+
return Number(raw);
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
async function cmdBalance() {
|
|
543
|
+
const w = readActiveWallet();
|
|
544
|
+
if (!w) {
|
|
545
|
+
fail({
|
|
546
|
+
code: "NO_WALLET",
|
|
547
|
+
message: "No local wallet.",
|
|
548
|
+
hint: "Run: run402 init",
|
|
549
|
+
});
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
const { createPublicClient, http, base, baseSepolia, tempoModerato } = await loadDeps();
|
|
553
|
+
const mainnetClient = createPublicClient({ chain: base, transport: http() });
|
|
554
|
+
const sepoliaClient = createPublicClient({ chain: baseSepolia, transport: http() });
|
|
555
|
+
const tempoClient = createPublicClient({ chain: tempoModerato, transport: http() });
|
|
556
|
+
|
|
557
|
+
const [mainnetUsdc, sepoliaUsdc, tempoPathUsd, billingRes] = await Promise.all([
|
|
558
|
+
readUsdcBalance(mainnetClient, USDC_MAINNET, w.address).catch(() => null),
|
|
559
|
+
readUsdcBalance(sepoliaClient, USDC_SEPOLIA, w.address).catch(() => null),
|
|
560
|
+
readUsdcBalance(tempoClient, PATH_USD, w.address).catch(() => null),
|
|
561
|
+
getSdk().billing.checkBalance(w.address).catch(() => null),
|
|
562
|
+
]);
|
|
563
|
+
|
|
564
|
+
console.log(JSON.stringify({
|
|
565
|
+
address: w.address,
|
|
566
|
+
rail: w.rail || "x402",
|
|
567
|
+
onchain: {
|
|
568
|
+
"base-mainnet_usd_micros": mainnetUsdc,
|
|
569
|
+
"base-sepolia_usd_micros": sepoliaUsdc,
|
|
570
|
+
"tempo-moderato_pathusd_micros": tempoPathUsd,
|
|
571
|
+
},
|
|
572
|
+
allowance_usd_micros: billingRes ? billingRes.allowance_usd_micros : null,
|
|
573
|
+
}, null, 2));
|
|
574
|
+
}
|
package/lib/webhook-secret.mjs
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* run402 webhook-secret — Manage
|
|
2
|
+
* run402 webhook-secret — Manage your webhook signing secret.
|
|
3
3
|
*
|
|
4
4
|
* Split out from notifications.mjs so the SURFACE inventory parser sees
|
|
5
5
|
* `webhook-secret:rotate` as its own command, separate from the
|
|
6
6
|
* `notifications:*` group.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
9
|
+
import { walletAuthHeaders } from "./config.mjs";
|
|
10
|
+
import { sessionProofs } from "./session-proofs.mjs";
|
|
11
11
|
import { getSdk } from "./sdk.mjs";
|
|
12
12
|
import { reportSdkError } from "./sdk-errors.mjs";
|
|
13
13
|
import { assertKnownFlags, normalizeArgv, failUnknownSubcommand } from "./argparse.mjs";
|
|
14
14
|
|
|
15
|
-
const HELP = `run402 webhook-secret — Manage
|
|
15
|
+
const HELP = `run402 webhook-secret — Manage your webhook signing secret
|
|
16
16
|
|
|
17
17
|
Usage:
|
|
18
18
|
run402 webhook-secret rotate
|
|
@@ -20,7 +20,7 @@ Usage:
|
|
|
20
20
|
Notes:
|
|
21
21
|
- Returns the new plaintext secret EXACTLY once. Store it immediately.
|
|
22
22
|
- Previous secret remains valid for 24 hours after rotation.
|
|
23
|
-
- Requires
|
|
23
|
+
- Requires passkey assurance ('run402 login', or 'run402 agent passkey enroll').
|
|
24
24
|
`;
|
|
25
25
|
|
|
26
26
|
export async function run(sub, args = []) {
|
|
@@ -39,7 +39,7 @@ export async function run(sub, args = []) {
|
|
|
39
39
|
}
|
|
40
40
|
const parsedArgs = normalizeArgv(args);
|
|
41
41
|
assertKnownFlags(parsedArgs, ["--help", "-h"]);
|
|
42
|
-
const proofs =
|
|
42
|
+
const proofs = sessionProofs("/agent/v1/webhook-secret/rotate");
|
|
43
43
|
try {
|
|
44
44
|
const data = await getSdk().admin.rotateWebhookSecret(proofs);
|
|
45
45
|
console.log(JSON.stringify(data, null, 2));
|
package/lib/webhooks.mjs
CHANGED
|
@@ -9,13 +9,13 @@ Usage:
|
|
|
9
9
|
run402 email webhooks <action> [args...]
|
|
10
10
|
|
|
11
11
|
Actions:
|
|
12
|
-
list [--mailbox <slug|id>] [--project <
|
|
13
|
-
get <webhook_id> [--mailbox <slug|id>] [--project <
|
|
14
|
-
delete <webhook_id> [--mailbox <slug|id>] [--project <
|
|
12
|
+
list [--mailbox <slug|id>] [--project <project_id>] List webhooks
|
|
13
|
+
get <webhook_id> [--mailbox <slug|id>] [--project <project_id>] Get a webhook
|
|
14
|
+
delete <webhook_id> [--mailbox <slug|id>] [--project <project_id>] Delete a webhook
|
|
15
15
|
update <webhook_id> [--url <url>] [--events <e1,e2>] [--mailbox <slug|id>] Update a webhook
|
|
16
|
-
register --url <url> --events <e1,e2> [--mailbox <slug|id>] [--project <
|
|
17
|
-
deliveries [--status <s>] [--mailbox <slug|id>] [--project <
|
|
18
|
-
redrive <delivery_id> [--mailbox <slug|id>] [--project <
|
|
16
|
+
register --url <url> --events <e1,e2> [--mailbox <slug|id>] [--project <project_id>] Register a new webhook
|
|
17
|
+
deliveries [--status <s>] [--mailbox <slug|id>] [--project <project_id>] List durable delivery rows (DLQ visibility)
|
|
18
|
+
redrive <delivery_id> [--mailbox <slug|id>] [--project <project_id>] Re-queue a dead-lettered delivery
|
|
19
19
|
|
|
20
20
|
Valid events: delivery, bounced, complained, reply_received, mailbox_suspended
|
|
21
21
|
Delivery statuses: pending, in_flight, delivered, failed_permanent (the DLQ)
|
|
@@ -41,12 +41,12 @@ const SUB_HELP = {
|
|
|
41
41
|
update: `run402 email webhooks update — Update an existing webhook
|
|
42
42
|
|
|
43
43
|
Usage:
|
|
44
|
-
run402 email webhooks update <webhook_id> [--url <url>] [--events <e1,e2>] [--mailbox <slug|id>] [--project <
|
|
44
|
+
run402 email webhooks update <webhook_id> [--url <url>] [--events <e1,e2>] [--mailbox <slug|id>] [--project <project_id>]
|
|
45
45
|
`,
|
|
46
46
|
register: `run402 email webhooks register — Register a new webhook
|
|
47
47
|
|
|
48
48
|
Usage:
|
|
49
|
-
run402 email webhooks register --url <url> --events <e1,e2> [--mailbox <slug|id>] [--project <
|
|
49
|
+
run402 email webhooks register --url <url> --events <e1,e2> [--mailbox <slug|id>] [--project <project_id>]
|
|
50
50
|
`,
|
|
51
51
|
};
|
|
52
52
|
|