@phantom_protocol/sdk
v0.2.0
Published
PhantomPay SDK — private agent-to-agent payments on the Phantom shielded pool
Maintainers
Readme
@phantom_protocol/sdk
Private agent-to-agent payments on the Phantom shielded pool.
Drop it into an agent and it can pay another agent, check its balance, and call paid tools — with no wallet setup, no gas handling, and no key management inside your agent code.
Testnet. This runs against BSC testnet. The tokens have no real value.
npm install @phantom_protocol/sdkUse
import { PhantomPay } from '@phantom_protocol/sdk';
const pay = new PhantomPay({
apiKey: process.env.PHANTOMPAY_API_KEY!, // per-agent key, never commit it
});
// What can I spend?
const { balance, budget } = await pay.balance();
// Pay another agent
const payment = await pay.pay({
to: 'agent_researcher_01',
amount: '0.25',
memo: 'market sizing, Q3',
});
// What have I paid and been paid?
const history = await pay.payments();Paying for a tool that charges
If a tool answers HTTP 402, the facilitator settles it and retries, and you get the tool's real response back. Your agent never sees the payment step.
const res = await pay.call({
serviceId: 'some-paid-api',
request: { method: 'GET', path: '/v1/search?q=solar' },
});Funding — read this first
An agent cannot pay from nothing. Money has to be in the pool before pay() will do anything, and
there is no path that skips this — a payment moves ledger balance, and balance comes from a deposit.
balance() tells you where to send it:
const { balance, funding } = await pay.balance();
// funding.deposit_address → this agent's OWN permanent addressThree ways money gets in:
| Route | Cost |
|---|---|
| Your user deposits through the Phantom app | $2 flat, once |
| Anyone sends tokens straight to funding.deposit_address | $2 flat, once — no signup needed on their side |
| Your operator funds several agents from one deposit | $2 flat total, split between them |
The $2 is a deposit fee, not a payment fee. Pay it once on the way in; every agent-to-agent
payment after that is a free ledger move. It only stings on a tiny deposit — funding an agent with
$5 means 40% went to the fee, so fund in meaningful amounts.
Paying someone who is not on PhantomPay
| They are… | Use | Cost |
|---|---|---|
| A registered agent | pay() | 0.1%, no gas, instant |
| An external tool that answers HTTP 402 | call() | real on-chain transfer, gas |
| Neither | not payable here — withdraw on-chain instead | gas, and a public transfer |
The recipient does not need this SDK installed. They need to exist as an agent, so there is an
account to credit. call() is the path for everyone else.
Why payments are instant and effectively free
An agent-to-agent payment is a double-entry ledger move, not a transaction. That is what makes a $0.001 payment viable — there is no gas, no proof and no block to wait for on each one. Balances net down and are settled on-chain in batches.
The consequence is worth stating plainly: an individual payment has no transaction hash, because there is no individual transaction. The settlement batches do, and those are public.
Funding and withdrawal are real on-chain operations against the shielded pool, and those do have hashes.
API
| Method | Does |
|---|---|
| balance() | This agent's spendable balance and budget |
| pay({ to, amount, memo?, idempotencyKey? }) | Pay another agent; returns the receipt |
| payments() | This agent's history, sent and received |
| call({ serviceId, request? }) | Call an allowlisted tool, paying it if it asks (x402) |
pay() generates an idempotency key if you do not pass one, so a retried call cannot pay twice.
Pass your own when the retry happens in a different process.
Config
new PhantomPay({
apiKey: string, // required
baseUrl?: string, // defaults to the hosted facilitator
});Notes
- Zero runtime dependencies. It is
fetchand nothing else. - The API key identifies one agent. Give each agent its own; do not share one across agents, or their balances and histories become indistinguishable.
- Errors are thrown with the facilitator's message and HTTP status attached.
MIT
