Wallets, payments, and Bitcoin finance for agents
Give your agent its own keys, USDT payments, and Bitcoin trading and lending. No separate gas coin to buy or maintain on Libre. Price work in dollars and pay in stablecoins: our two-wallet testnet prototype shows the flow.
RESTPOST https://mcp.libre.org/v1/tools/<tool>
OpenAPIhttps://mcp.libre.org/openapi.json
For agentshttps://mcp.libre.org/llms.txt
Verified on Libre testnet · September 12, 2026 UTC
Two agents. One task. Paid in USDT.
A buyer agent requested a data analysis. A seller agent quoted 19.99 USDT. The buyer signed with its own wallet; the seller confirmed the payment and returned the result with a signed receipt.
| Agent wallet | USDT before → after | LIBRE before → after |
|---|---|---|
| Buyerpaybuyuijv14 | 25.00 → 5.01 | 0 → 0 |
| Sellerpayseluijv14 | 0.05 → 20.04 | 0 → 0 |
Neither wallet needed LIBRE to pay gas. Both used normal new-account resources, with no extra resource grant. Libre still has CPU, NET, and RAM limits; external bridge fees and trading spreads can apply.
The seller waited for irreversible block 260263992 before delivering the result (about 2 minutes 56 seconds after inclusion in this run). A dropped response, seller restart, and concurrent retries recovered the same purchase with one payment and one fulfillment.
Inspect the proof or compose an example payment
# Read the recorded testnet evidence (requires jq)
curl -fsS https://www.libre.org/agents/payments/testnet-proof.json \
| jq '{network, buyer, seller, payment, before, after, checks}'
# Compose an unsigned testnet transfer; this does not send funds. # Replace the accounts with your own testnet wallets. curl -fsS https://mcp.libre.org/v1/tools/transfer \ -H 'content-type: application/json' \ -d '{"network":"testnet","from":"yourbuyer", "to":"yourseller","symbol":"USDT","amount":"19.99", "memo":"pay:example-invoice-001","permission":"active"}'
Your agent checks the network, recipient, amount, memo, and allowed actions before signing locally. A memo identifies the invoice; the seller must also verify the actual transfer and prevent transaction reuse. The full prototype adds a signed quote, spending budget, payment verification, and retry recovery.
Tested scope: two independent deterministic software agents with separate wallet keys. The adapter is an experimental x402-inspired implementation, not an upstream x402 integration or production payment service. Underpayment, overpayment, refunds, and optional USDT↔BTC conversion are illustrated in the walkthrough; they were not part of this test.
Don't take this page's word for it
Everything below is a public fact about a public chain. Each claim comes with the command that settles it, so you can check before you write a line of code.
Trading costs nothing
Not low fees — none. The exchange contract has no fee parameter, no fee recipient and no fee action. Its entire configuration is a pause switch.
# the whole config of the exchange contract curl -s -X POST $LIBRE/v1/chain/get_table_rows \ -d '{"json":true,"code":"dex.libre", "scope":"dex.libre","table":"config"}' {"rows":[{"paused":0}],"more":false}
Your program holds the keys
Nothing here custodies anything. Our server composes unsigned transactions; your code signs them. Give it a permission limited to the actions it needs, and revoke that permission in one transaction if it misbehaves.
# compose returns actions, never a signature curl -s -X POST https://mcp.libre.org/v1/tools/place_order \ -H 'content-type: application/json' \ -d '{"network":"testnet","account":"mybot", "pair":"btcusdt","side":"buy", "price":"1000","amount":"0.00001"}' {"actions":[…], "esr":"esr://…", "expires":"…"}
It can fund itself
The account asks a bridge for its own Bitcoin address and signs that request with its own key. Send Bitcoin to the address and the balance is spendable on Libre. No exchange account, no card, no person opening a wallet.
# register, sign, then poll — the bridge # signers assign the address shortly after POST /v1/tools/setup_deposit_address {"actions":[{"account":"x.libre", "name":"newaccount", …}]} POST /v1/tools/get_deposit_address {"btc_address":"tb1qnwqa25nmmpxj82rn…"}
It can borrow against that Bitcoin
Lock Bitcoin in a vault only that loan can draw on, borrow USDT up to 60% of its value, repay whenever. The rate follows demand — near 3% when the pool is idle. Nobody approves the loan.
# the terms the contract enforces curl -s -X POST $LIBRE/v1/chain/get_table_rows \ -d '{"json":true,"code":"loan","scope":"loan", "table":"globalparams"}' max_loan_to_value: 6000 // 60% liquidation_warning_threshold: 7000 liquidation_risk_threshold: 8000
The price comes from the chain
Loan health is decided by an on-chain oracle: several independent feeders publish a Bitcoin price, the contract averages a round of at least three that agree within 10%, and refuses anything older than five minutes.
# the same price the loan contract uses curl -s -X POST https://mcp.libre.org/v1/tools/get_btc_price \ -H 'content-type: application/json' -d '{}' {"price": 81207.7, "report_count": 4, "age_seconds": 1, "stale": false}
Getting an agent running
Five steps, none of which need our permission.
-
Create an account
Free, at accounts.libre.org. Libre accounts are human-readable names, and come with the resources to transact — there is no gas token to buy first.
-
Give the bot a key of its own
At tools.libre.org/bot-account, create a permission holding only your bot's public key, linked only to the actions you choose. It cannot change your keys, vote, or spend outside that list. One transaction revokes it.
-
Ask for a Bitcoin address
The bot signs
setup_deposit_addressitself, then pollsget_deposit_address. The bridge signers assign the address a short time later — about a minute — so poll rather than expecting it immediately. -
Send Bitcoin to it
Once confirmed, the balance is spendable on Libre: tradeable on the exchange, or usable as loan collateral through a vault.
-
Trade or borrow
Point the bot at mcp.libre.org — 28 tools over MCP or plain HTTP. Read state, compose a transaction, sign it, push it.
The whole loop
Read, compose, sign, push. WharfKit handles reference blocks, contract ABIs and serialization, so signing is one call.
npm i @wharfkit/session @wharfkit/wallet-plugin-privatekey import { Session } from '@wharfkit/session'; import { WalletPluginPrivateKey } from '@wharfkit/wallet-plugin-privatekey'; const session = new Session({ chain: { id: chainId, url: 'https://api.libre.cryptobloks.io' }, actor: 'mybot', permission: 'agent', // the restricted permission, not active walletPlugin: new WalletPluginPrivateKey(process.env.AGENT_KEY), }); // compose — unsigned, no key involved const res = await fetch('https://mcp.libre.org/v1/tools/place_order', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ account: 'mybot', pair: 'btcusdt', side: 'buy', price: '80000', amount: '0.0001', permission: 'agent' }), }); const { actions } = await res.json(); // sign locally and push await session.transact({ actions });
The five things an agent does
Each is one call that returns unsigned actions. Sign them with your key and push. The responses below are what the server actually returns today.
Buy Bitcoin
An order is a token transfer carrying its terms in the memo. Buying locks the USDT until the order fills or you cancel it.
POST /v1/tools/place_order {"account":"mybot","pair":"btcusdt","side":"buy", "price":"80000","amount":"0.001","permission":"agent"} usdt.libre::transfer to: dex.libre quantity: 80.00000000 USDT memo: buy:0.00100000 BTC:80000.00000000 USDT
Sell Bitcoin
The mirror image: the Bitcoin is what gets locked, and the memo names the price you are asking in USDT.
POST /v1/tools/place_order {"account":"mybot","pair":"btcusdt","side":"sell", "price":"90000","amount":"0.001","permission":"agent"} btc.libre::transfer to: dex.libre quantity: 0.00100000 BTC memo: sell:0.00100000 BTC:90000.00000000 USDT
Borrow and repay whenever
Keep the loan open as long as it is useful. Interest accrues while it runs, you can
repay part or all of it any time, and the one thing to watch is the value of your
collateral. max_apr_bps sets the highest rate you will accept; above
it the request waits until the rate comes back to you.
POST /v1/tools/borrow {"account":"mybot","amount_usdt":"500", "max_apr_bps":2000,"permission":"agent"} loan::borrowvar amount: 500.00000000 USDT pool_id: 6 max_apr_bps: 2000 loan::processqueue
Send Bitcoin out
Peg-out is a transfer to the bridge with the destination address as the memo. The bridge charges 50 basis points, capped at 0.005 BTC.
POST /v1/tools/withdraw_btc {"account":"mybot","amount":"0.005", "btc_address":"bc1qar0srrr7xfkvy5l643lydnw9re59gtzz…", "permission":"agent"} btc.libre::transfer to: x.libre quantity: 0.00500000 BTC memo: bc1qar0srrr7xfkvy5l643lydnw9re59gtzz…
Receive Bitcoin
Ask the bridge for an address once, then read it back. The signers assign it a short time after your transaction confirms, so poll rather than expecting it immediately. Bitcoin sent there becomes spendable on Libre.
POST /v1/tools/setup_deposit_address x.libre::newaccount account: mybot // sign, then poll POST /v1/tools/get_deposit_address {"btc_address":"bc1q…"}
What isn't true yet
You will check these within a minute of arriving, so here they are first.
- The order book is thin, and the spread is wide
-
Often several percent between the best bid and the best ask, with days passing
between fills. If you came to hit a tight market, you can't yet. If you came to make
one, there is no protocol fee to earn back and almost no competition — run
get_orderbookand judge for yourself. - Leverage is modest
- Borrow, buy, redeposit and repeat tops out near 2.5× in theory, closer to 1.5–2× before you are sitting on the liquidation threshold. And every turn of that loop crosses the spread above, which today can cost more than a year of borrow interest.
- "No fees" means trading
- The exchange takes nothing and ordinary transactions cost nothing. The bridges do charge to move Bitcoin and USDT out — 50 and 100 basis points — and a liquidation costs 5% of the outstanding debt plus a 1% sale discount.
- Settlement is fast, finality takes minutes
- Blocks are half a second, so orders land immediately. A block becomes irreversible once 15 of the 21 validators confirm it, which takes roughly three minutes. That matters for anything you settle on top of a trade.
Start with the read-only tools
No account, no key and no permission needed to look around. Every read tool is open, on mainnet and testnet.
curl -s -X POST https://mcp.libre.org/v1/tools/get_pool_stats \
-H 'content-type: application/json' -d '{}'