@paybox-sh/sdk
v0.5.0
Published
Typed Node SDK + `paybox` CLI for the Paybox agent API. Mirrors the MCP tool surface (list_credentials, request_payment, request_wallet_sign, request_secret, request_swap, get_portfolio, get_request) over REST, with in-process non-custodial wallet signing
Readme
@paybox-sh/sdk
Typed Node SDK and paybox CLI for the Paybox agent API. It mirrors the MCP tool
surface — list_credentials, request_payment, request_wallet_sign,
request_secret, request_swap, discover_services, pay_x402, use_service,
get_portfolio, get_request — but talks to the REST API directly, with no MCP
host and no signing iframe.
Wallet signing is non-custodial and runs in-process: the SDK reuses the exact
signing core from the wallet-sign iframe (@paybox/mcp-app), builds the chain
digest, and ed25519-signs the MoonX envelope with your pbxk1. key. The MoonX
secret never reaches the client — the secret-gated /sign happens server-side.
Install
pnpm add @paybox-sh/sdk # library
npx @paybox-sh/sdk login # or use the CLI directlyCLI
# Authenticate: OAuth in the browser (approve with a passkey), or store a key.
# `paybox login` is a guided two-step: OAuth, then it opens the app to provision
# a wallet signing key and prompts you to paste the `pbxk1.` token back.
paybox login # OAuth 2.1 + PKCE, then provision a key
paybox login --no-provision # OAuth only, skip the key step
paybox login --key pbx_live_… # personal API key instead (no OAuth)
paybox login --signing-key pbxk1.… # supply the signing key non-interactively
paybox credentials # list usable credentials
paybox pay --credential <id> --merchant Acme --url https://acme.com --amount 1999
paybox secret --credential <id> --purpose "deploy" # one-time token
paybox secret --credential <id> --raw # raw value (grant-gated)
paybox sign --credential <id> --intent '{"op":"message","message":"gm"}'
paybox swap --credential <id> --src-chain eip155:8453 \
--src-token native --dst-token 0x… --amount 1000000000000000
paybox portfolio --address 0x… --networks 1,8453
paybox discover "weather api" # browse paid x402 services (Bazaar)
paybox pay-x402 --credential <id> --url https://svc/api --accepts @accepts.json
paybox use-service --credential <id> --url https://svc/api # paybox pays + fetches
paybox request <request_id> --wait # poll a pending request
paybox version # installed version (+ update check)
paybox update # update the global install to latest
paybox uninstall # clear stored config (prints npm rm)
paybox --json credentials # machine-readable output on any commandversion/update/uninstall are conveniences over npm: update runs
npm i -g @paybox-sh/sdk@latest (use --print to just show it); uninstall
clears ~/.config/paybox and prints the npm rm -g line (a package can't remove
its own binary). For project installs use pnpm up/pnpm rm, or npx
@paybox-sh/sdk@latest to always run the latest without installing.
sign, swap, pay-x402, and use-service complete in-process when a pbxk1.
signing key is configured and the operation clears immediately (autonomous
grant). When the grant requires approval, the command returns pending_approval;
approve in the app, then paybox request <id> --wait.
pay-x402 is header mode — on success output.value.x_payment is the X-PAYMENT
header to replay on the original request. use-service is gateway mode — paybox
makes the paid call for you and returns the resource's reply on
output.value.response. Pass --accepts from the resource's own 402 (browse the
catalog with paybox discover).
Library
import { PayboxClient } from "@paybox-sh/sdk";
const paybox = PayboxClient.fromConfig(); // reads ~/.config/paybox + env
// or: new PayboxClient({ apiKey: "pbx_live_…", signingKey: "pbxk1.…" });
const creds = await paybox.listCredentials();
const pay = await paybox.requestPayment({
credentialId: creds[0].credential.id,
merchant: "Acme",
merchantUrl: "https://acme.com",
amountCents: 1999,
});
const sig = await paybox.requestWalletSign({
credentialId: walletId,
chain: "eip155:8453",
intent: { op: "message", message: "gm" },
}); // signs in-process if a key is set
// x402: discover a paid endpoint, then pay it — header mode (you replay the
// X-PAYMENT header) or gateway mode (paybox fetches the paid content for you).
const services = await paybox.discoverServices("weather api");
const paid = await paybox.useService({ credentialId: walletId, url: services[0].resource });
// paid.response.output.value.response holds the resource's replyConfiguration
Resolution order: explicit constructor options → environment → stored config.
| Env | Meaning |
|-----|---------|
| PAYBOX_API_URL | API origin (default https://api.paybox.sh). |
| PAYBOX_API_KEY | A pbx_live_* personal API key. |
| PAYBOX_ACCESS_TOKEN | A raw OAuth access token. |
| PAYBOX_SIGNING_KEY | A pbxk1. wallet signing key (enables sign/swap). |
| PAYBOX_CONFIG_DIR | Override the config dir (default ~/.config/paybox). |
paybox login writes ~/.config/paybox/config.json (mode 0600 on
macOS/Linux). On Windows the POSIX mode bits don't restrict access — the file
is not access-protected there, so prefer PAYBOX_API_KEY / PAYBOX_SIGNING_KEY
env vars on shared Windows machines.
Develop
pnpm install
pnpm typecheck
pnpm build # tsup → dist/ (ESM + types + paybox bin)
# Refresh the generated tool types from a running server (the source of truth):
PAYBOX_MCP_URL=http://127.0.0.1:8080/mcp PAYBOX_API_KEY=pbx_live_… pnpm genThe argument and response types in src/generated.ts mirror the server's MCP
tool schemas (schemars-derived) and server/src/models.rs. pnpm gen reads the
live list_tools schemas so the client can't drift from the server contract.
