@agenttech/tpay-cli 0.0.1 → 0.0.3

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.
Files changed (3) hide show
  1. package/README.md +145 -62
  2. package/dist/index.js +79 -3
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -1,87 +1,170 @@
1
- # @agentpay/tpay-cli
1
+ # @agenttech/tpay-cli
2
2
 
3
- A CLI for AI agents to send USDC/USDT via the T402 x402 v2 payment protocol.
4
- Output defaults to structured JSON. Use `--format text` for human-readable output. Logs go to stderr.
3
+ Send USDT payments on Solana via the T402 x402 v2 protocol. Designed for AI agents all output is structured JSON on stdout, logs go to stderr.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install -g @agenttech/tpay-cli
9
+ ```
10
+
11
+ Verify:
12
+
13
+ ```bash
14
+ tpay version
15
+ ```
16
+
17
+ ## Setup
18
+
19
+ The CLI needs a BIP-39 seed phrase to sign transactions. Two setup paths:
20
+
21
+ ### Non-interactive (recommended for agents)
22
+
23
+ ```bash
24
+ WALLET_SEED_PHRASE="your twelve or twenty four word seed phrase here" \
25
+ TPAY_PASSPHRASE="encryption-password" \
26
+ tpay setup
27
+ ```
28
+
29
+ This encrypts and saves the seed phrase to `~/.config/tpay/.env`.
30
+
31
+ ### From env file
32
+
33
+ ```bash
34
+ tpay setup --from-env /path/to/.env
35
+ ```
36
+
37
+ The file must contain `WALLET_SEED_PHRASE=...`.
38
+
39
+ ### Skip setup (inline seed phrase)
40
+
41
+ You can skip `tpay setup` entirely by passing the seed phrase as an environment variable on every call:
42
+
43
+ ```bash
44
+ WALLET_SEED_PHRASE="your seed phrase" tpay send --to <address> --amount 10
45
+ ```
46
+
47
+ ### Setup output
48
+
49
+ ```json
50
+ {"status":"success","saved":true}
51
+ ```
5
52
 
6
53
  ## Commands
7
54
 
8
- | Command | Description |
9
- |---|---|
10
- | `tpay setup` | Configure wallet keys interactively |
11
- | `tpay setup --from-env <file>` | Import keys from an env file |
12
- | `tpay send --to <addr> --amount <n> --chain <chain>` | Send payment |
13
- | `tpay intent status <intent_id>` | Check payment status |
14
- | `tpay version` | Print version |
15
- | `tpay help` / `tpay --help` | Show all commands |
16
- | `tpay send --help` | Show send args |
17
-
18
- Global flags:
19
- - `--verbose` — debug output to stderr
20
- - `--format text|json` — output format (default: `json`)
55
+ ### `tpay send`
56
+
57
+ Send a USDT payment.
21
58
 
22
59
  ```bash
23
- # JSON output (default, for programmatic use)
24
- tpay send --to 0x... --amount 10 --chain base
25
- {"status":"success","intent_id":"...","tx_hash":"...","explorer_url":"..."}
60
+ tpay send --to <solana-address> --amount <number>
61
+ ```
26
62
 
27
- # Text output (human-readable)
28
- tpay send --to 0x... --amount 10 --chain base --format text
29
- status: success
30
- intent_id: abc123
31
- tx_hash: 0x...
32
- explorer_url: https://...
63
+ Or pipe JSON via stdin:
64
+
65
+ ```bash
66
+ echo '{"to":"<solana-address>","amount":"10"}' | tpay send
33
67
  ```
34
68
 
35
- Stdin JSON mode: pipe `{"to":"...","amount":"...","chain":"..."}` to `tpay send`.
69
+ **Success output:**
36
70
 
37
- ## Supported Chains
71
+ ```json
72
+ {"status":"success","intent_id":"intent_abc123","tx_hash":"5xY...","explorer_url":"https://..."}
73
+ ```
38
74
 
39
- | `--chain` value | Network |
40
- |---|---|
41
- | `base` | Base Mainnet (EVM) |
42
- | `bsc` | BSC Mainnet (EVM) |
43
- | `base-sepolia` | Base Sepolia (EVM testnet) |
44
- | `solana` | Solana Mainnet |
45
- | `solana-devnet` | Solana Devnet |
75
+ **Error output:**
76
+
77
+ ```json
78
+ {"status":"error","error_type":"payment_error","message":"Payment failed","intent_id":"intent_abc123"}
79
+ ```
46
80
 
47
- ## Runtime Environment Variables
81
+ ### `tpay balance`
48
82
 
49
- | Variable | Required | Description |
50
- |---|---|---|
51
- | `WALLET_PROVIDER` | No (default: `env`) | Wallet plugin name |
52
- | `WALLET_SEED_PHRASE` | Yes (for Solana) | BIP-39 mnemonic seed phrase |
53
- | `WALLET_EVM_PRIVATE_KEY` | For EVM chains | Hex private key (`0x...`) |
83
+ Check SOL and USDT balances for any address. No wallet keys required.
84
+
85
+ ```bash
86
+ tpay balance --address <solana-address>
87
+ ```
88
+
89
+ **Output:**
90
+
91
+ ```json
92
+ {"status":"ok","address":"<solana-address>","sol":"1.5","usdt":"100.0"}
93
+ ```
94
+
95
+ ### `tpay intent status`
54
96
 
55
- ## Build
97
+ Check the status of a payment intent.
56
98
 
57
99
  ```bash
58
- T402_API_URL=https://api.example.com \
59
- SOLANA_RPC_URL=https://your-rpc.example.com \
60
- SOLANA_FEE_PAYER=<base58> \
61
- bun build --compile src/index.ts --outfile tpay
100
+ tpay intent status <intent_id>
62
101
  ```
63
102
 
64
- ## Development
103
+ Or via stdin:
65
104
 
66
105
  ```bash
67
- bun install
68
- bun test
69
- T402_API_URL=https://... WALLET_EVM_PRIVATE_KEY=0x... bun run src/index.ts send --to 0x... --amount 1 --chain base
106
+ echo '{"intent_id":"intent_abc123"}' | tpay intent status
70
107
  ```
71
108
 
72
- ## Adding a New Chain Plugin
109
+ **Output:**
73
110
 
74
- - [ ] Create `src/plugins/chains/<name>.ts`
75
- - [ ] Implement `ChainPlugin` interface (`name`, `chains[]`, `sign()`)
76
- - [ ] Add to `CHAIN_PLUGIN_LOADERS` in `src/loader.ts`
77
- - [ ] Add to Supported Chains table above
78
- - [ ] Test: verify x402 payload structure matches T402 backend
111
+ ```json
112
+ {"status":"ok","intent_id":"intent_abc123","payment_status":"BASE_SETTLED","sending_amount":"10","receiving_amount":"10","payer_chain":"solana","created_at":"...","expires_at":"...","tx_hash":"5xY...","explorer_url":"https://..."}
113
+ ```
114
+
115
+ ### `tpay version`
116
+
117
+ ```bash
118
+ tpay version
119
+ ```
120
+
121
+ ### `tpay help`
122
+
123
+ ```bash
124
+ tpay help
125
+ ```
126
+
127
+ ## Global Flags
128
+
129
+ | Flag | Description |
130
+ |---|---|
131
+ | `--verbose` | Debug logs to stderr |
132
+ | `--format json\|text` | Output format (default: `json`) |
133
+
134
+ ## Environment Variables
135
+
136
+ | Variable | Required | Description |
137
+ |---|---|---|
138
+ | `WALLET_SEED_PHRASE` | Yes (if no config file) | BIP-39 mnemonic (12–24 words) |
139
+ | `TPAY_PASSPHRASE` | No | Decrypts saved config at `~/.config/tpay/.env` |
140
+ | `SOLANA_FEE_PAYER` | No | Override fee payer address |
141
+
142
+ If both `WALLET_SEED_PHRASE` env var and an encrypted config file exist, the env var takes precedence.
143
+
144
+ ## Exit Codes
145
+
146
+ | Code | Type | Meaning |
147
+ |---|---|---|
148
+ | 0 | — | Success |
149
+ | 1 | `validation_error` | Invalid arguments or input |
150
+ | 2 | `runtime_error` | Unexpected runtime failure |
151
+ | 3 | `configuration_error` | Missing or invalid config |
152
+ | 4 | `network_error` | API or RPC failure |
153
+ | 5 | `payment_error` | Payment-specific failure |
154
+
155
+ All errors output JSON to stdout:
156
+
157
+ ```json
158
+ {"status":"error","error_type":"<type>","message":"<description>"}
159
+ ```
160
+
161
+ ## Supported Chains
162
+
163
+ | Chain | Network ID |
164
+ |---|---|
165
+ | Solana Mainnet | `solana` |
166
+ | Solana Devnet | `solana-devnet` |
79
167
 
80
- ## Adding a New Wallet Plugin
168
+ ## License
81
169
 
82
- - [ ] Create `src/plugins/wallets/<name>.ts`
83
- - [ ] Implement `WalletPlugin` interface (`name`, `getEvmPrivateKey()`, `getSolanaSeed()`)
84
- - [ ] Add to `WALLET_PLUGINS` map in `src/loader.ts`
85
- - [ ] Document required env vars above
86
- - [ ] Ensure key/seed return values are never logged
87
- - [ ] Test: verify loads when `WALLET_PROVIDER=<name>` is set
170
+ ISC
package/dist/index.js CHANGED
@@ -64009,6 +64009,7 @@ async function runHelp(ctx) {
64009
64009
  commands: {
64010
64010
  setup: 'Configure wallet keys with encryption. Use --from-env <file> to import. Non-interactive: WALLET_SEED_PHRASE="..." TPAY_PASSPHRASE="..." tpay setup',
64011
64011
  send: "Send USDC/USDT via T402. Args: --to, --amount",
64012
+ balance: "Show wallet SOL and USDT balances",
64012
64013
  "intent status <intent_id>": "Fetch current status of a payment intent",
64013
64014
  version: "Print CLI version",
64014
64015
  help: "Show this help"
@@ -64036,7 +64037,7 @@ async function runHelp(ctx) {
64036
64037
  async function runVersion(ctx) {
64037
64038
  output(ctx.format, {
64038
64039
  name: "@agenttech/tpay-cli",
64039
- version: "0.0.1"
64040
+ version: "0.0.3"
64040
64041
  });
64041
64042
  return 0;
64042
64043
  }
@@ -64236,7 +64237,6 @@ var CONFIG = {
64236
64237
  feePayer: ""
64237
64238
  }
64238
64239
  };
64239
- console.log("CONFIG", CONFIG);
64240
64240
 
64241
64241
  class SendCommand extends BaseCommand {
64242
64242
  async execute(opts) {
@@ -64344,12 +64344,85 @@ async function runIntentStatus(ctx, intentId) {
64344
64344
  return command.execute(intentId);
64345
64345
  }
64346
64346
 
64347
+ // src/cli/commands/balance.ts
64348
+ init_index_cjs();
64349
+ var CONFIG3 = {
64350
+ apiUrl: "https://api-staging-t402-pay.agent.tech",
64351
+ solana: {
64352
+ rpcUrl: "https://api.mainnet-beta.solana.com",
64353
+ feePayer: ""
64354
+ }
64355
+ };
64356
+ var USDT_MINT = new $PublicKey("Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB");
64357
+ var TOKEN_PROGRAM_ID2 = new $PublicKey("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA");
64358
+ var LAMPORTS_PER_SOL = 1000000000n;
64359
+ var USDT_DECIMALS = 6;
64360
+
64361
+ class BalanceCommand extends BaseCommand {
64362
+ async execute(opts) {
64363
+ const address3 = this.requireArg(opts.address, "address");
64364
+ let pubkey;
64365
+ try {
64366
+ pubkey = new $PublicKey(address3);
64367
+ } catch {
64368
+ throw new ValidationError(`Invalid Solana address: ${address3}`);
64369
+ }
64370
+ const connection = new $Connection(CONFIG3.solana.rpcUrl);
64371
+ try {
64372
+ this.ctx.logger.debug("Fetching balances", { address: address3 });
64373
+ const [solLamports, tokenAccounts] = await Promise.all([
64374
+ connection.getBalance(pubkey),
64375
+ connection.getParsedTokenAccountsByOwner(pubkey, { mint: USDT_MINT, programId: TOKEN_PROGRAM_ID2 })
64376
+ ]);
64377
+ let usdtRaw = 0n;
64378
+ for (const { account } of tokenAccounts.value) {
64379
+ const amount = account.data.parsed?.info?.tokenAmount?.amount;
64380
+ if (amount)
64381
+ usdtRaw += BigInt(amount);
64382
+ }
64383
+ output(this.ctx.format, {
64384
+ status: "ok",
64385
+ address: address3,
64386
+ sol: formatLamports(BigInt(solLamports)),
64387
+ usdt: formatToken(usdtRaw, USDT_DECIMALS)
64388
+ });
64389
+ return 0;
64390
+ } catch (error) {
64391
+ if (error instanceof ValidationError)
64392
+ throw error;
64393
+ if (error instanceof Error && error.message.includes("Server error")) {
64394
+ throw new NetworkError(error.message, error);
64395
+ }
64396
+ throw error;
64397
+ }
64398
+ }
64399
+ }
64400
+ function formatLamports(lamports) {
64401
+ const whole = lamports / LAMPORTS_PER_SOL;
64402
+ const frac = lamports % LAMPORTS_PER_SOL;
64403
+ if (frac === 0n)
64404
+ return whole.toString();
64405
+ return `${whole}.${frac.toString().padStart(9, "0").replace(/0+$/, "")}`;
64406
+ }
64407
+ function formatToken(raw, decimals) {
64408
+ const divisor = 10n ** BigInt(decimals);
64409
+ const whole = raw / divisor;
64410
+ const frac = raw % divisor;
64411
+ if (frac === 0n)
64412
+ return whole.toString();
64413
+ return `${whole}.${frac.toString().padStart(decimals, "0").replace(/0+$/, "")}`;
64414
+ }
64415
+ async function runBalance(ctx, opts) {
64416
+ const command = new BalanceCommand(ctx);
64417
+ return command.execute(opts);
64418
+ }
64419
+
64347
64420
  // src/cli/program.ts
64348
64421
  function createProgram() {
64349
64422
  const program2 = new Command;
64350
64423
  const versionInfo = {
64351
64424
  name: "@agenttech/tpay-cli",
64352
- version: "0.0.1"
64425
+ version: "0.0.3"
64353
64426
  };
64354
64427
  const versionString = typeof versionInfo === "string" ? versionInfo : versionInfo.version;
64355
64428
  program2.name("tpay").version(versionString, "-v, --version", "Show version").option("--verbose", "Enable debug logging to stderr").option("--format <fmt>", "Output format: json | text", "json");
@@ -64389,6 +64462,9 @@ function registerCommands(program2) {
64389
64462
  await loadEnv();
64390
64463
  process.exitCode = await runSend(getContext(), opts);
64391
64464
  });
64465
+ program2.command("balance").description("Show wallet SOL and USDT balances").option("--address <addr>", "Solana wallet address to query").action(async (opts) => {
64466
+ process.exitCode = await runBalance(getContext(), opts);
64467
+ });
64392
64468
  const intentCmd = program2.command("intent").description("Payment intent operations");
64393
64469
  intentCmd.command("status [intentId]").description("Check payment intent status").action(async (intentId) => {
64394
64470
  process.exitCode = await runIntentStatus(getContext(), intentId);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agenttech/tpay-cli",
3
- "version": "0.0.1",
3
+ "version": "0.0.3",
4
4
  "description": "T402 CLI for agent automation",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",