@visa/cli 4.1.0-rc.120 → 4.1.0-rc.122
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 +13 -7
- package/dist/checkout-engine/live-fill-approval.d.ts +0 -11
- package/dist/checkout-engine/live-fill-approval.js +12 -31
- package/dist/checkout-engine/repo-env.d.ts +1 -1
- package/dist/checkout-engine/repo-env.js +1 -1
- package/dist/cli.js +323 -321
- package/dist/mcp-server/index.js +253 -251
- package/dist/skills/pair-visa-agent/SKILL.md +2 -3
- package/native/bin/win32-x64/visa-keychain-win.exe +0 -0
- package/package.json +1 -1
- package/server.json +2 -2
package/README.md
CHANGED
|
@@ -128,9 +128,9 @@ receives a delegated, capped, revocable signer (it can never mint one itself).
|
|
|
128
128
|
With a wallet delegated, set caps before funding:
|
|
129
129
|
|
|
130
130
|
```bash
|
|
131
|
-
visa wallet limits --per-transaction 0.25 --daily 2.00
|
|
132
|
-
visa wallet show
|
|
133
|
-
visa wallet fund
|
|
131
|
+
visa wallet limits --agent <agent-id> --per-transaction 0.25 --daily 2.00
|
|
132
|
+
visa wallet show --agent <agent-id> # address, network, policy
|
|
133
|
+
visa wallet fund --agent <agent-id> # funding instructions
|
|
134
134
|
```
|
|
135
135
|
|
|
136
136
|
Fund the wallet with USDC only after limits are set. Payments are gasless — no ETH is ever needed. Mainnet (Base) is the production default; set `VISA_V4_NETWORK=base-sepolia` for testnet, where `visa wallet fund` points at the faucet.
|
|
@@ -140,9 +140,9 @@ Fund the wallet with USDC only after limits are set. Payments are gasless — no
|
|
|
140
140
|
```bash
|
|
141
141
|
visa find "current weather by city" --max 0.10 # discovery; spends nothing
|
|
142
142
|
visa inspect <listing-id> # fetches the live 402 challenge; spends nothing
|
|
143
|
-
visa pay <listing-id> --max 0.05
|
|
144
|
-
visa activity
|
|
145
|
-
visa receipt <receipt-id>
|
|
143
|
+
visa pay <listing-id> --agent <agent-id> --max 0.05 # policy check → sign → settle
|
|
144
|
+
visa activity --agent <agent-id> # recent payments
|
|
145
|
+
visa receipt <receipt-id> --agent <agent-id> # journaled proof with on-chain tx
|
|
146
146
|
|
|
147
147
|
# Advanced direct-URL mode uses the same probe, policy, and receipt path.
|
|
148
148
|
visa inspect --url https://provider.example/paid
|
|
@@ -156,6 +156,11 @@ owned by `apps/mpp`, and VIC uses the checkout/mandate surface. Unsupported
|
|
|
156
156
|
rails are refused before signing. The wallet exposes no agent key-export
|
|
157
157
|
command.
|
|
158
158
|
|
|
159
|
+
Each wallet-enabled agent has an isolated Turnkey credential, policy, journal,
|
|
160
|
+
receipts, and paid-response directory. `--agent` / the MCP `agent` field may be
|
|
161
|
+
omitted while exactly one wallet authority exists; with multiple authorities it
|
|
162
|
+
is required so the CLI never guesses which agent can spend.
|
|
163
|
+
|
|
159
164
|
## MCP tools (v4 surface)
|
|
160
165
|
|
|
161
166
|
| Tool | Description |
|
|
@@ -256,8 +261,9 @@ visa-cli feedback # submit feedback
|
|
|
256
261
|
| `~/.visa-cli/pairings/` | Pending ceremony verifier or runtime identity key (owner-only mode 0600 on macOS/Linux; v2 pairing currently disabled on Windows) |
|
|
257
262
|
| `~/.visa-cli/agents/` | Activated agent identity, runtime private key, and signed activation credentials (owner-only mode 0600 on macOS/Linux; v2 pairing currently disabled on Windows) |
|
|
258
263
|
| `~/.visa-cli/session-recovery/` | Pending login-only PKCE verifier and pinned web origin (owner-only mode 0600 on macOS/Linux) |
|
|
264
|
+
| `~/.visa-cli/removed-agents/` | Records of agents deleted on the server, kept 30 days then dropped. Written automatically; nothing reads it |
|
|
259
265
|
| `~/.visa-mcp/agent-credential.json` | Legacy checkout-credential compatibility record (mode 0600) |
|
|
260
|
-
| `~/.visa-v4/
|
|
266
|
+
| `~/.visa-v4/agents/<agentId>/` | Per-agent Turnkey credential, spend policy, reservation journal, receipts, and paid responses — never edit by hand |
|
|
261
267
|
|
|
262
268
|
## Troubleshooting
|
|
263
269
|
|
|
@@ -1,21 +1,10 @@
|
|
|
1
1
|
import type { CheckoutMode, CheckoutOutcome, CheckoutResult } from './executor.js';
|
|
2
|
-
export declare const SUBMIT_ENV_FLAG = "CHECKOUT_AGENT_ALLOW_SUBMIT";
|
|
3
2
|
export declare const MODE_ENV_FLAG = "CHECKOUT_AGENT_MODE";
|
|
4
3
|
/**
|
|
5
4
|
* `--mode` values map 1:1 onto CheckoutMode; an absent flag falls back to the
|
|
6
5
|
* CHECKOUT_AGENT_MODE environment default, then to the safe dry-run default.
|
|
7
6
|
*/
|
|
8
7
|
export declare function parseCheckoutMode(value: string | undefined, env?: Record<string, string | undefined>): CheckoutMode;
|
|
9
|
-
/**
|
|
10
|
-
* Fail fast (before any file read or browser launch) when submit lacks an
|
|
11
|
-
* enablement. The env arm exists to stop AUTOMATION from reaching a live
|
|
12
|
-
* charge by accident — so it is required only when stdin is not a real TTY
|
|
13
|
-
* (scripts, agents, pipes). An interactive human needs no standing config:
|
|
14
|
-
* their per-run consent is the typed PAY phrase plus the passkey tap, both of
|
|
15
|
-
* which a non-interactive caller cannot fake (the phrase names the exact
|
|
16
|
-
* review id; the passkey is a FIDO ceremony on the verify site).
|
|
17
|
-
*/
|
|
18
|
-
export declare function assertSubmitAllowed(mode: CheckoutMode, env?: Record<string, string | undefined>, isInteractive?: boolean): void;
|
|
19
8
|
/** Distinct phrases per mode so dry-run muscle memory can never authorize a payment. */
|
|
20
9
|
export declare function approvalPhrase(mode: CheckoutMode, reviewId: string): string;
|
|
21
10
|
/** Integer-only minor→display formatting (two-decimal currencies, the same assumption as decimalToMinor). */
|
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
// Deliberate-enablement seam for run-live-fill's submit mode. A real submit
|
|
2
2
|
// moves real money, so it requires:
|
|
3
|
-
// 1.
|
|
4
|
-
// the explicit CHECKOUT_AGENT_ALLOW_SUBMIT=1 environment arm,
|
|
5
|
-
// 2. the invocation opts in (--mode submit, or the CHECKOUT_AGENT_MODE
|
|
3
|
+
// 1. the invocation opts in (--mode submit, or the CHECKOUT_AGENT_MODE
|
|
6
4
|
// environment default for operators who always run one mode),
|
|
7
|
-
//
|
|
5
|
+
// 2. the operator types the PAY phrase against the exact review id (and a
|
|
8
6
|
// hosted run additionally requires the passkey tap on the verify site).
|
|
9
|
-
// The
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
//
|
|
15
|
-
|
|
7
|
+
// The PAY phrase differs from dry-run's FILL phrase and names the exact review
|
|
8
|
+
// id, so a muscle-memory rerun of the dry-run procedure cannot drift into
|
|
9
|
+
// charging a card. Fresh checkouts need ZERO persisted config.
|
|
10
|
+
//
|
|
11
|
+
// There was a third requirement — a CHECKOUT_AGENT_ALLOW_SUBMIT=1 environment
|
|
12
|
+
// arm, exempted for interactive TTYs — meant to stop AUTOMATION reaching a live
|
|
13
|
+
// charge. It never ran: nothing in the product ever called `assertSubmitAllowed`.
|
|
14
|
+
// The same flag DID gate `pay_merchant`, where being default-off with no
|
|
15
|
+
// in-product way to set it meant a real install could not complete a purchase at
|
|
16
|
+
// all. Both are gone; the phrase and the mandate caps are the gates.
|
|
16
17
|
export const MODE_ENV_FLAG = 'CHECKOUT_AGENT_MODE';
|
|
17
18
|
/**
|
|
18
19
|
* `--mode` values map 1:1 onto CheckoutMode; an absent flag falls back to the
|
|
@@ -26,26 +27,6 @@ export function parseCheckoutMode(value, env = process.env) {
|
|
|
26
27
|
return 'submit';
|
|
27
28
|
throw new Error(`--mode (or ${MODE_ENV_FLAG}) must be dry-run or submit (got ${JSON.stringify(effective)})`);
|
|
28
29
|
}
|
|
29
|
-
/**
|
|
30
|
-
* Fail fast (before any file read or browser launch) when submit lacks an
|
|
31
|
-
* enablement. The env arm exists to stop AUTOMATION from reaching a live
|
|
32
|
-
* charge by accident — so it is required only when stdin is not a real TTY
|
|
33
|
-
* (scripts, agents, pipes). An interactive human needs no standing config:
|
|
34
|
-
* their per-run consent is the typed PAY phrase plus the passkey tap, both of
|
|
35
|
-
* which a non-interactive caller cannot fake (the phrase names the exact
|
|
36
|
-
* review id; the passkey is a FIDO ceremony on the verify site).
|
|
37
|
-
*/
|
|
38
|
-
export function assertSubmitAllowed(mode, env = process.env, isInteractive = process.stdin.isTTY === true) {
|
|
39
|
-
if (mode !== 'submit')
|
|
40
|
-
return;
|
|
41
|
-
if (env[SUBMIT_ENV_FLAG] === '1')
|
|
42
|
-
return;
|
|
43
|
-
if (isInteractive)
|
|
44
|
-
return;
|
|
45
|
-
throw new Error(`--mode submit refused: this is not an interactive terminal, and scripted submits ` +
|
|
46
|
-
`require ${SUBMIT_ENV_FLAG}=1. The gate is default-off so automation cannot ` +
|
|
47
|
-
'reach a live charge by accident.');
|
|
48
|
-
}
|
|
49
30
|
/** Distinct phrases per mode so dry-run muscle memory can never authorize a payment. */
|
|
50
31
|
export function approvalPhrase(mode, reviewId) {
|
|
51
32
|
return `${mode === 'submit' ? 'PAY' : 'CHECK'} ${reviewId}`;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Load the monorepo root `.env` as DEFAULTS for the runner, so stable
|
|
3
3
|
* per-machine config (VGS credentials, CHECKOUT_APPROVAL_BASE_URL,
|
|
4
|
-
*
|
|
4
|
+
* CHECKOUT_AGENT_MODE) is set once instead of
|
|
5
5
|
* retyped on every invocation. `process.loadEnvFile` never overrides
|
|
6
6
|
* variables already present in the environment (verified: shell always wins),
|
|
7
7
|
* so an explicit `FOO=x pnpm pay …` still beats the file. A missing file is
|
|
@@ -2,7 +2,7 @@ import { fileURLToPath } from 'node:url';
|
|
|
2
2
|
/**
|
|
3
3
|
* Load the monorepo root `.env` as DEFAULTS for the runner, so stable
|
|
4
4
|
* per-machine config (VGS credentials, CHECKOUT_APPROVAL_BASE_URL,
|
|
5
|
-
*
|
|
5
|
+
* CHECKOUT_AGENT_MODE) is set once instead of
|
|
6
6
|
* retyped on every invocation. `process.loadEnvFile` never overrides
|
|
7
7
|
* variables already present in the environment (verified: shell always wins),
|
|
8
8
|
* so an explicit `FOO=x pnpm pay …` still beats the file. A missing file is
|