@palmyr/cli 1.7.0 → 1.8.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/dist/cli.js +70 -0
- package/dist/cli.js.map +1 -1
- package/dist/pay-preflight.d.ts +54 -0
- package/dist/pay-preflight.js +202 -0
- package/dist/pay-preflight.js.map +1 -0
- package/dist/pay.js +45 -4
- package/dist/pay.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -376,6 +376,15 @@ const WALLET_HELP = {
|
|
|
376
376
|
{ flag: '--src-decimals <n>', desc: 'Source token decimals', hint: 'default 18' },
|
|
377
377
|
{ flag: '--dst-decimals <n>', desc: 'Dest token decimals', hint: 'default 6 (USDC-like)' },
|
|
378
378
|
],
|
|
379
|
+
'pay-preflight': [
|
|
380
|
+
{ flag: '--chain <c>', desc: 'Override the default pay chain', hint: 'solana | base (default: config.defaultPayChain)' },
|
|
381
|
+
{ flag: '--wallet <ID>', desc: 'Override the wallet to check', hint: 'default: config.defaultPayWalletId / PALMYR_PAY_WALLET / auto-pick' },
|
|
382
|
+
{ flag: '--min-usdc <N>', desc: 'Required USDC balance to pass (default 0 — just check the wallet exists)' },
|
|
383
|
+
{ flag: '--passphrase <p>', desc: 'Wallet passphrase if no OS-keychain session secret', hint: 'or PALMYR_WALLET_PASSPHRASE env' },
|
|
384
|
+
{ flag: '(price)', desc: 'Free — one RPC call to read USDC balance' },
|
|
385
|
+
{ flag: '(example)', desc: 'palmyr wallet pay-preflight --chain base --min-usdc 3 --json' },
|
|
386
|
+
{ flag: '(note)', desc: 'Local-only version runs automatically before every paid command (set PALMYR_NO_PREFLIGHT=1 to disable)' },
|
|
387
|
+
],
|
|
379
388
|
};
|
|
380
389
|
const PHONE_HELP = {
|
|
381
390
|
search: [
|
|
@@ -1032,6 +1041,13 @@ async function main() {
|
|
|
1032
1041
|
case 'search': {
|
|
1033
1042
|
const country = flags.country || 'US';
|
|
1034
1043
|
const data = await ao.phoneSearch(country, flags.limit ? parseInt(flags.limit) : undefined);
|
|
1044
|
+
// Empty result is a valid response but `{numbers: []}` alone made it
|
|
1045
|
+
// ambiguous whether the API failed or the country has no inventory.
|
|
1046
|
+
// Add a non-breaking `note` field — agents that already key off
|
|
1047
|
+
// `.numbers.length` keep working; new readers get a clear signal.
|
|
1048
|
+
if (data && Array.isArray(data.numbers) && data.numbers.length === 0 && !data.note) {
|
|
1049
|
+
data.note = `No numbers available for ${country}. Try a different country code (US, GB, CA, DE, etc.).`;
|
|
1050
|
+
}
|
|
1035
1051
|
return print(data);
|
|
1036
1052
|
render(React.createElement(RecordsScreen, {
|
|
1037
1053
|
version: VERSION,
|
|
@@ -2153,6 +2169,7 @@ async function main() {
|
|
|
2153
2169
|
{ name: 'watch', description: 'Maintain a watchlist of CAs to monitor', hint: 'add <CA> --trigger "..." | list' },
|
|
2154
2170
|
{ name: 'brief', description: 'Show thesis + PnL brief for a position', hint: '<CA>' },
|
|
2155
2171
|
{ name: 'doctor', description: 'Health check for the wallet-trading subsystem', hint: '[--wallet <ref>]' },
|
|
2172
|
+
{ name: 'pay-preflight', description: 'Check the x402 pay flow is ready (chain, wallet, signing, USDC balance)', hint: '[--chain solana|base] [--min-usdc N]' },
|
|
2156
2173
|
{ name: 'smoke-test', description: 'End-to-end validation of wallet trading on Solana + Base', hint: '--wallet <ref> [--chain solana|base|all]' },
|
|
2157
2174
|
{ name: 'readiness', description: 'Go/no-go autonomous-trading readiness — sign, gas, quotes, daemon, open positions', hint: '--wallet <ref>' },
|
|
2158
2175
|
{ name: 'live-test', description: 'Execute tiny real round trips on Solana + Base, verify no leftover positions', hint: '--wallet <ref> --budget Nusdc [--chain ...]' },
|
|
@@ -3806,6 +3823,59 @@ async function main() {
|
|
|
3806
3823
|
process.exit(EXIT.GENERAL);
|
|
3807
3824
|
break;
|
|
3808
3825
|
}
|
|
3826
|
+
case 'pay-preflight': {
|
|
3827
|
+
// Five-question readiness check for the x402 pay flow. Local-only
|
|
3828
|
+
// siblings of this same module run automatically before every paid
|
|
3829
|
+
// command (see paidRequest/paidStreamRequest); this command is the
|
|
3830
|
+
// explicit, full-fat version with the RPC USDC balance check.
|
|
3831
|
+
const ppChain = flags.chain?.toLowerCase();
|
|
3832
|
+
if (ppChain && ppChain !== 'solana' && ppChain !== 'base') {
|
|
3833
|
+
err(`--chain must be solana or base (got ${ppChain})`, EXIT.BAD_INPUT);
|
|
3834
|
+
}
|
|
3835
|
+
const ppWallet = flags.wallet || undefined;
|
|
3836
|
+
const ppMinUsdcRaw = flags['min-usdc'];
|
|
3837
|
+
const ppMinUsdc = typeof ppMinUsdcRaw === 'string' ? Number(ppMinUsdcRaw) : undefined;
|
|
3838
|
+
if (ppMinUsdc !== undefined && (!Number.isFinite(ppMinUsdc) || ppMinUsdc < 0)) {
|
|
3839
|
+
err(`--min-usdc must be a non-negative number (got ${String(ppMinUsdcRaw)})`, EXIT.BAD_INPUT);
|
|
3840
|
+
}
|
|
3841
|
+
const { fullPreflight } = await import('./pay-preflight.js');
|
|
3842
|
+
const report = await fullPreflight({
|
|
3843
|
+
...(ppChain ? { chain: ppChain } : {}),
|
|
3844
|
+
...(ppWallet ? { walletRef: ppWallet } : {}),
|
|
3845
|
+
...(ppMinUsdc !== undefined ? { minUsdc: ppMinUsdc } : {}),
|
|
3846
|
+
...(passphrase ? { passphrase } : {}),
|
|
3847
|
+
});
|
|
3848
|
+
if (AGENT_MODE) {
|
|
3849
|
+
print(report);
|
|
3850
|
+
if (!report.ok)
|
|
3851
|
+
process.exit(EXIT.GENERAL);
|
|
3852
|
+
break;
|
|
3853
|
+
}
|
|
3854
|
+
// TTY rendering — mirrors the doctor command's layout.
|
|
3855
|
+
console.log();
|
|
3856
|
+
section('Pay preflight');
|
|
3857
|
+
kv('Verdict', report.ok ? `${t.success}ready${t.reset}` : `${t.error}not ready${t.reset}`);
|
|
3858
|
+
kv('Pay chain', report.payChain);
|
|
3859
|
+
kv('Wallet ID', report.walletId || `${t.muted}(none)${t.reset}`);
|
|
3860
|
+
kv('Address', report.walletAddress || `${t.muted}(unknown)${t.reset}`);
|
|
3861
|
+
kv('Can sign', report.canSign ? `${t.success}yes${t.reset}` : `${t.error}no${t.reset}`);
|
|
3862
|
+
if (report.usdc) {
|
|
3863
|
+
const bal = report.usdc.balance;
|
|
3864
|
+
kv('USDC balance', bal === null ? `${t.muted}(unknown)${t.reset}` : `${bal.toFixed(6)} USDC`);
|
|
3865
|
+
if (report.usdc.requiredMin > 0)
|
|
3866
|
+
kv('Required min', `${report.usdc.requiredMin.toFixed(6)} USDC`);
|
|
3867
|
+
if (report.usdc.ataStatus)
|
|
3868
|
+
kv('Solana ATA', report.usdc.ataStatus);
|
|
3869
|
+
}
|
|
3870
|
+
if (report.fix) {
|
|
3871
|
+
console.log();
|
|
3872
|
+
console.log(` ${t.warn}Fix:${t.reset} ${report.fix}`);
|
|
3873
|
+
}
|
|
3874
|
+
console.log();
|
|
3875
|
+
if (!report.ok)
|
|
3876
|
+
process.exit(EXIT.GENERAL);
|
|
3877
|
+
break;
|
|
3878
|
+
}
|
|
3809
3879
|
case 'smoke-test': {
|
|
3810
3880
|
const smokeWalletRef = flags.wallet || undefined;
|
|
3811
3881
|
if (!smokeWalletRef)
|