What Bursar is
An AI treasurer for small companies that pays invoices within limits it cannot change.
Every company pays invoices. Two things go wrong, often: someone pays a fake invoice (the "please note our new bank details" fraud, the most common business scam in the world), and someone pays the same invoice twice. Letting an AI do the work makes both worse, unless the AI never holds the keys.
Bursar splits the job in three. The AI reads the invoice inside a trusted execution environment on NEAR AI Cloud and reports what it says. The contract decides: a NEAR smart contract owned by the company checks the vendor, the payout, the amounts, the orders, and pays or refuses by itself. A dumb executor moves the money, and only to the destination the owner recorded. Nobody in the loop can both decide and move money, and the AI cannot choose an address.
Bursar is software, not a payment service. The USDC stays in the company's own contract, with the company's keys. Nothing passes through Bursar.
How a payment flows
- An invoice PDF arrives: dropped in the console, posted in a Telegram chat connected to the treasury (it shows up in Inbox, unread, until a person presses Read), or in the inbox folder the agent watches.
- The agent rasterizes it and sends the page to a model running in a TEE on NEAR AI Cloud. First it fetches an attestation for a fresh nonce; the answer comes back as structured JSON with an ECDSA signature over the exact bytes.
- The agent turns the answer into a claim (vendor, invoice number, amount, payout printed on the invoice, order reference, flags) and calls
request_paymenton the policy contract. Its only key can call that one method on that one contract. - The contract decides, deterministically and on chain, in the same transaction.
- A vendor on NEAR is paid in that transaction. A vendor on Base, Arbitrum, Solana or Sui is queued for the executor, which settles through NEAR Intents to the address on record, verified by the contract before any USDC leaves (mainnet only).
- Every decision is an on-chain event and carries a reference to the signed receipt of the reading. There is no database.
The rules the contract enforces
The owner sets them; the AI cannot touch them. Each refusal has a reason code you see in the console, the dashboard and the explorer.
Reading errors made harmless
The model can misread a number. Five checks that do not trust the model run on every reading, and each failure is a flag the contract holds on: the total must appear in the PDF's text layer; no larger amount may appear in the document (a subtotal taken for the total is caught); subtotal plus tax must equal the total when the invoice shows them; the model's confidence must be at least 0.6; the currency must be USDC. A scan without a text layer is always held. What remains possible is paying less than the invoice says, to the right account, within the orders and caps: the vendor will say so.
Withholding tax, set by your accountant
Bursar knows no tax rules and does not try to. Many countries make the payer keep back part of what it pays certain vendors, typically freelancers, and remit it to the state: ritenuta d'acconto in Italy, TDS in India, retencion in Spain and Latin America, with rates and bases that differ and change. So the rule lives where it belongs: whoever keeps the company's books sets, per vendor, a country and a withholding percentage (0 for companies and most foreign vendors). The contract then pays the vendor the net, keeps the withheld share in the treasury, earmarked, and shows in Analytics what is due. Remitting it is the company's job; afterwards the owner marks it remitted and the counter goes down. An invoice whose own withholding line disagrees with the rate set waits for a person.
Two things to be clear about. The withheld share is the vendor's money, not the company's: on a 1,000 invoice with 20% withholding the vendor receives 800 and the state 200 on the vendor's behalf, which the vendor later deducts from its own taxes; the company's cost is 1,000 either way. And the company still remits and files exactly as it does today, with its accountant: in Italy the F24 by the 16th of the following month, the Certificazione Unica and the 770; in India the TDS deposit by the 7th and the quarterly certificate; in Spain the modelo 111 each quarter. Bursar does not talk to any tax authority and will not; it keeps the amounts right and visible, per vendor and per month, so the filing is a copy, not a reconstruction.
Who is who: tax ids
Every vendor record can carry the identifier the vendor prints on its invoices: a VAT number in Europe, an EIN in the United States, a CNPJ in Brazil, a GSTIN in India, an ABN in Australia, or, for a freelancer with none, a supplier code the company assigns and asks them to print. The company records its own in Settings. Spaces and punctuation do not matter. Both checks are optional and both hold rather than block, so a tax id read wrong never refuses a real invoice.
Only the owner changes a vendor's payout. The executor cannot redirect funds: the contract compares the recipient it reports with the vendor record before releasing USDC. A transfer that fails on the token contract is rolled back in the callback: balance restored, payment marked transfer_failed.
Orders and holds
A registered vendor with the right account could still invent invoices under every cap. Bursar pays only what the company agreed to buy.
- Purchase order: a reference (PO-2026-118), a total, an optional expiry. Invoices that print the reference consume it until it is spent.
- Standing order: an amount per period (500 USDC every 30 days). One invoice per period, up to the amount.
- An invoice that no order covers is held, not blocked: a person sees it in Attention and approves or cancels it. By default only vendors that have orders are held to them;
set_order_policy truemakes every invoice need an order.
A hold is never silent. The Overview shows what waits for a person, and the hold's reasons are written on the payment: over_threshold, no_order, flagged, or a combination.
People, roles, DAO
Owner
The NEAR account that owns the contract: your wallet. It sets limits, vendors, orders and the company name, approves held payments, invites and removes collaborators.
Operators
Collaborators get an on-chain role with three permissions: approve, manage vendors, manage orders. An invite creates an account for them with a single key limited to exactly the methods their role allows, records the role in the contract, and gives you a link that carries the key after the hash sign, so it never reaches a server. Whoever opens it is signed in as that account with that role and nothing else. Remove revokes it on chain.
DAO
From Settings the owner creates a Sputnik DAO with the council of their choice. From then on every held payment opens a proposal that the council votes on, in the console or in Trezu on mainnet. A rejected or expired proposal cancels the payment and releases its budget; the contract reads the verdict back from the DAO itself.
The reading and its receipt
The invoice is read by a model running in a TEE on NEAR AI Cloud. The invoice never leaves the enclave in clear text. The answer comes with a receipt anyone can verify, without the API key and without trusting the agent:
- the exact request and response bytes, and their hashes;
- the enclave's ECDSA signature over
model:sha256(request):sha256(response); - the attestation report with the Intel TDX quote, bound to the signer and to the fresh nonce the agent chose;
- the quote checked against Intel's collateral (TCB status).
Change one byte and the signature fails. The contract stores a compact reference to the receipt next to the payment, so a decision can always be traced to exactly the model output it was made on. The console runs the same checks in the browser; bursar verify runs them from the terminal.
Invoices by Telegram
Vendors send invoices the way they already do; nobody at the company uploads anything. In Settings the owner connects a Telegram chat and says who it is for: one vendor, or the whole company. The bot gives a link; the vendor (or a colleague) presses Start once, and from then on every PDF posted in that chat lands in the console's Inbox, under that vendor. A person presses Read: the enclave reads it, the contract decides, and the bot tells that chat, and only that chat, what was decided. Nothing is paid from Telegram. A chat linked to one vendor is also a check the AI cannot talk its way around: an invoice from Acme's chat that names another vendor carries the flag chat_vendor_mismatch, and the contract holds it for a person. Connect as many chats as you like, change what a chat is for, or disconnect it, all from Settings. Bursar keeps only the sender, the file name and the vendor; the PDF stays on Telegram until someone presses Read.
Who holds the NEAR AI Cloud key
Two plans. Bursar reading, used for this hackathon demo: the browser goes through Bursar's relay, a Cloudflare Worker that holds a key paid by the team and forwards the bytes untouched, with daily caps. Own key: a company using Bursar brings its own NEAR AI Cloud key, and the invoice goes from the browser straight to the enclave, never through Bursar.
Signing in
No password, no server. Three doors on the sign-in page:
- NEAR wallet. The wallet tells the console who you are. If your account owns a treasury (the registry lists it, the contract confirms it), you pick it and the wallet adds a key limited to that contract to your browser: it signs vendors, orders, limits and approvals, never a transfer. If your account owns none, the console creates one at this first sign-in: a payer account from the testnet faucet, the policy contract deployed with your wallet as owner, test USDC, three demo vendors and their orders, an agent with one key. Bursar pays for the accounts and the contract storage; you pay nothing.
- Invite link. A colleague's link signs you in with exactly the role they chose.
- Keys file. For a treasury created with throwaway keys ("Download the keys"), when there is no wallet at all.
Several treasuries live side by side in the console's switcher. "Switch account" takes you back to the door.
The vault: lose the browser, keep the company
Everything that matters is on the contract and comes back at every sign-in: vendors, limits, payments, roles. What lives only in a browser is secret by nature: the agent key, the Telegram inbox token, the labels. A wallet owner keeps them in the vault: the wallet signs one fixed message (no transaction, no cost), the signature becomes an encryption key, the secrets are encrypted in the browser and stored on the contract with set_vault, owner only. A new browser, after signing in with the same wallet, presses "Unlock with the wallet" and gets them back. Nobody can open the vault without that wallet, Bursar included. The contract never reads it. If the wallet's key changes, the vault stays shut: keep the keys backup file too.
A person in the console can also ask the contract directly: request_payment accepts the agent, the owner and the operators. The decision is the same whoever asks; only the contract decides.
The console
A static page: nothing to install, every number read from the contract over RPC, every change signed in the browser.
Explorer and registry
The explorer shows the whole network: how many companies, the USDC their contracts hold, what was paid out today, this month and all time, how many decisions, blocked, waiting for a person, and the last decisions across every company. Nothing private: amounts and decisions are on-chain events. Vendor names and invoice numbers appear only on each company's own dashboard.
It reads a small public contract, the registry, where every treasury lists itself when it is created (the console does it; bursar setup too). Entries are hints, not proof: the explorer and the sign-in page read get_roles on each treasury and drop entries whose owner does not match.
Run it yourself
The README is a walkthrough in "do X, see Y" form; the short version:
The agent sends its claims as meta transactions (NEP-366) through a relayer that only forwards request_payment, so the agent owns no NEAR. An MCP server (bursar mcp) lets any assistant drive it with exactly the agent's powers: submit an invoice, list payments, explain a decision, verify a receipt.
Custody and limits
- Software, not a payment service. You run it on your own accounts with your own keys; nothing passes through Bursar. USDC only.
- The AI never chooses an address. The executor cannot redirect funds. Only the owner changes a payout, and a changed payout on an invoice is a block.
- Cross-chain payouts through NEAR Intents are mainnet only; on testnet the Base vendor stops at Queued.
- The verifier checks the signature, the nonce, the quote's binding and the quote against Intel collateral. It does not yet replay the RTMR3 event log or check GPU evidence; the receipt keeps both.
- The wallet sign-in adds a function-call key. Creating the DAO and inviting collaborators need NEAR deposits, which the payer account kept from creation funds on testnet.
- Sample invoices are fictional. Nothing in the demo is a real person or company.
- Paying vendors in a stablecoin is regulated differently from country to country: in some it is unrestricted, in some it must be reported, in a few it is not allowed for businesses. Bursar does not check this and cannot: the company runs the contract on its own accounts, with its own keys, under its own law. Check your jurisdiction before you fund a treasury.
Where invoices are already structured
More and more countries mandate electronic invoices in a fixed format: SDI and FatturaPA in Italy, Peppol across much of Europe and in Singapore, Australia and New Zealand, Factur-X and ZUGFeRD in France and Germany, Verifactu in Spain, KSeF in Poland, CFDI in Mexico, NF-e in Brazil, DTE in Chile, the GST e-invoice in India, Fatoora in Saudi Arabia, e-Fatura in Turkey. The United States has no mandate; PDFs by email are the norm, with Peppol-style exchange only starting. Where a structured format exists, the vendor, the amount, the tax ids and the payment details come as fields, not as a picture. Bursar's reading step is built for the PDF that still dominates everywhere else; where a structured invoice exists, that step becomes optional: a deterministic parser builds the claim, and the contract decides exactly as it does today. This is the direction after the hackathon, not something the demo does.