Overview

Axiom is an AI research agent for US stocks. After each market close it scans a watchlist for a few named, backtested setups, gathers evidence (technicals, market regime, SEC filings, news) and writes a cited bull/bear report for every hit. It never places trades.

Axiom Pay is the NEAR smart contract and tooling that turn that research into a product other agents can buy, and can check before buying:

  • Axiom commits a SHA-256 of every signal on-chain before the next open.
  • It sells fresh signals and reports per call, behind HTTP 402, settled on NEAR.
  • Once a signal's entry is known it's published free, so buyers can verify the whole record against the chain.
  • Buyer agents spend from wallets their humans control: budget, per-call cap, daily cap, approved sellers at approved prices.
Live deployment: contract axiom-market-33945.testnet on NEAR testnet, seller axiom-agent-33945.testnet. The market page reads both directly from the chain.

Quickstart

You need Rust. No near-cli: the axiom binary signs NEAR transactions itself. Steps 1–4 and 6 need no market-data keys; step 5 (a real scan) needs the free Alpaca keys described in the README.

cargo build --release && ./contract/build.sh
A=./target/release/axiom; S=$RANDOM

# 1. Testnet accounts from the faucet (keys saved to ~/.near-credentials/testnet/)
for r in market axiom owner sec buyer bot; do $A near create-account ax-$r-$S.testnet; done
export AXIOM_PAY_CONTRACT=ax-market-$S.testnet
$A near deploy --as ax-market-$S.testnet

# 2. Sellers register services
$A near register --service axiom-signals --price 0.02 --as ax-axiom-$S.testnet
$A near register --service axiom-report  --price 0.05 --as ax-axiom-$S.testnet
$A near register --service sec-red-flags --price 0.01 --as ax-sec-$S.testnet

# 3. Owners open wallets for their agents and approve services
$A near open-wallet --agent ax-bot-$S.testnet --budget 1 --max-per-call 0.1 --daily-cap 0.5 --as ax-buyer-$S.testnet
$A near approve axiom-signals --as ax-buyer-$S.testnet
$A near approve axiom-report  --as ax-buyer-$S.testnet
$A near open-wallet --agent ax-axiom-$S.testnet --budget 1 --as ax-owner-$S.testnet
$A near approve sec-red-flags --as ax-owner-$S.testnet

# 4. Run the sellers (two terminals)
$A near serve --port 8787 --as ax-axiom-$S.testnet
SEC_USER_AGENT="axiom-demo you@example.com" $A near serve --port 8788 --as ax-sec-$S.testnet

# 5. Axiom researches: buys SEC evidence, writes reports, commits each signal
NEAR_ACCOUNT_ID=ax-axiom-$S.testnet AXIOM_SEC_PROVIDER_URL=http://127.0.0.1:8788 \
  $A scan --near --no-llm --no-telegram

# 6. The buyer agent shops
$A near shop --as ax-bot-$S.testnet                              # refuses: no verified history yet
$A near shop --min-verified 0 --reports --as ax-bot-$S.testnet   # buys signals and reports

Expected: the first shop prints DECISION: not buying. Only 0 signal(s) verified on-chain. The second pays twice or more, marks each signal committed on-chain, and saves reports under purchased/<date>/. After the next open, axiom near check-seller shows those signals as verified, and the default policy buys.

Concepts

Wallet

Opened by a human owner for one agent account. Holds a budget (deposited NEAR) and a policy: max_per_call and daily_cap. An agent spends from exactly one wallet; the day rolls over at 00:00 UTC.

Service

A priced thing a seller sells, identified by a service_id. Payment goes straight to the seller's account. Only the seller who registered an id can reprice it.

Approval

An owner approves a service at a price. If the seller changes the price, the approval no longer matches and the agent can't pay until the owner approves the new price.

Receipt

Created by every payment: service, seller, payer, owner, amount, time and the request_hash, a SHA-256 of the exact request being paid for. The seller serves only that request, once, within 15 minutes.

Commitment

A SHA-256 recorded by any account, keyed by (committer, hash). Its block time proves the underlying record existed then. Nobody can commit on another account's behalf.

Agent key

An agent account <name>.<owner> whose key NEAR itself restricts to the marketplace methods of its role. It cannot attach NEAR, send NEAR anywhere, or call set_policy, so it can never raise its own limits.

Job

A request posted by a buyer agent with a max_price and a deadline. Seller agents bid; the buyer awards one bid. The receipt is bound to sha256("axiom-job/v1|<id>|<topic>").

Escrow

On award the price leaves the buyer's wallet and the contract holds it. confirm(delivered=true) pays the seller, confirm(delivered=false) refunds the wallet, and after a day of silence the winner may claim it.

Pool

Agents of different owners split one purchase. Each share waits in escrow; the last share pays the seller and every member can redeem the same receipt once. An unfilled pool refunds after its deadline.

Buying as an agent

Purchases follow an HTTP 402 handshake. The buyer never trusts the seller's numbers: it recomputes the request hash itself.

  1. GET /v1/<service>?… without a receipt. The seller answers 402 with its terms.
  2. Recompute request_hash; check the contract matches yours, and that your owner approved this service at its current price (get_wallet_of_agent, get_approval).
  3. Call pay(service_id, request_hash, memo). The contract enforces approval, caps and budget, pays the seller and returns a receipt.
  4. Repeat the request with &receipt=<id>. Retry on 5xx: the seller releases the receipt when its own upstream fails.
HTTP/1.1 402 Payment Required
{
  "error": "payment required",
  "network": "testnet",
  "contract": "axiom-market-33945.testnet",
  "method": "pay",
  "service_id": "axiom-signals",
  "price": "20000000000000000000000",
  "seller": "axiom-agent-33945.testnet",
  "request": "axiom-pay/v1|axiom-signals|2026-11-09",
  "request_hash": "1b9fe78e5d55…",
  "track_record": "/v1/track-record"
}

axiom near shop does all of this, after first verifying the seller's record (see verification) against its policy flags --min-verified and --max-unverified-share.

Selling a service

  1. axiom near register --service <id> --price <NEAR> --as <seller>. Attaches 0.01 NEAR for storage; the unused part is refunded.
  2. axiom near serve --as <seller> serves every service that account registered.
  3. A paid request is served only if the receipt names this seller and service, its request_hash matches this exact request, it is under 15 minutes old, and it hasn't been redeemed before.
  4. The server checks it has something to sell before quoting a price, so buyers are never charged for an empty answer.

Agent wallets

axiom near agent-create <name> --role buyer|seller --max-per-call <NEAR> --daily-cap <NEAR> --as <owner> creates the agent account, gives it a function-call key and adds your own key as its recovery key. Buyers are added to your wallet; storage credit is prepaid for them because their key cannot attach NEAR.

$ axiom near policy --max-per-call 100 --daily-cap 1000 --as nova.<owner>
RPC send_tx error: InvalidTxError -> InvalidAccessKeyError -> MethodNameMismatch { method_name: "set_policy" }

That is the agent trying to raise its own limits: the transaction never reaches the contract. A seller agent's earnings stay on its account until the owner moves them with axiom near agent-sweep.

Jobs, escrow and pools

  1. Post. axiom near hire "meme-risk|wyrm.nearlytrade.near" --max-price 0.01 --as <buyer agent> posts the job.
  2. Bid. Sellers running axiom near serve --bid meme-risk=0.006 watch the board and bid on topics they can deliver.
  3. Award. The buyer takes the cheapest bid from a seller whose disputes don't outnumber its deliveries. The price moves into escrow, under the wallet's caps.
  4. Deliver. The seller answers GET <endpoint>/v1/jobs/<id>?receipt=<n>.
  5. Settle. The buyer confirms (seller paid) or disputes (buyer refunded). Either way it goes on the seller's public record. A seller whose buyer goes silent runs axiom near claim <job> after a day.

axiom near swarm runs the whole economy on testnet: several sellers bid on several buyers' jobs, then the buyers pool one purchase. axiom near jobs and axiom near pools list the boards.

Memecoin research

axiom meme scan --near runs every hour over NEAR's most-traded and newest pools. Each token gets a rug-risk screen: thin liquidity, pool age, top-10 holder share, how few wallets hold it outside pools, churn, sell pressure, extreme moves and copycat tickers. A breakout (a close above the last 72 hours' high on more than twice the usual volume) becomes a signal only if the token isn't high risk.

Each signal is committed with a public teaser in its label, e.g. axiom-meme/v1 meme-breakout · risk low 20 · hold 72h · 2026-11-13. The market page shows those as the shelf: buy them all with one meme-signals call, no bidding. When a signal's window ends it is published, and axiom meme verify recomputes its outcome from public candles, scored from the first full hour after the commitment, and counts any commitment never revealed.

axiom-meme/v1|<token>|<pool>|<setup>|<YYYY-MM-DDTHH:MMZ>|<entry>|<stop>|<target>|<max_hold_h>   # prices as Rust {:.6e}
axiom meme risk <token> [--seller <url>]      # free locally, or buy the screen
axiom meme shop --seller <url>                # verify the record, then buy the shelf
axiom meme export-record --as <seller>        # the published record the website reads

Axiom's research loop

axiom scan --near runs after the close: it scans the watchlist, buys SEC evidence from an evidence seller when AXIOM_SEC_PROVIDER_URL is set, writes a cited report per hit, logs a paper trade, and commits each signal. The on-chain label names only the session (axiom-signal/v1 2026-11-09), never the symbol, so nothing being sold leaks early. axiom near export-record writes the free record the website reads.

Code computes, the model explains: entries, stops, targets and statistics come from deterministic Rust. The optional LLM only writes the bull and bear narrative, citing evidence IDs.

Verification spec

A signal's canonical line, with prices at exactly four decimals (ties rounded to even, as Rust formats them):

axiom-signal/v1|<SYMBOL>|<setup>|<YYYY-MM-DD>|<entry>|<stop>|<target>|<max_hold>
axiom-signal/v1|JPM|trend-pullback|2026-11-09|339.6900|323.9929|371.0841|20

To verify an entry from a seller's record:

  1. Rebuild the line from the entry's fields and take its SHA-256 (lowercase hex).
  2. Call find_commitment(committer = seller, hash).
  3. Compare the commitment's timestamp_ns with the deadline: 13:30 UTC on the fill day, or on the next weekday after the session if it hasn't filled. That is the earliest moment the entry price could be known.
ResultMeaning
✓ before openCounts toward the track record.
lateCommitted after the entry was knowable. Doesn't count.
not on-chainNever committed, or a field was changed after committing.

CLI

All commands take --as <account> (key from ~/.near-credentials/<network>/) and read AXIOM_PAY_CONTRACT, NEAR_NETWORK (default testnet) and NEAR_RPC_URL (default FastNEAR).

CommandWhoDoes
axiom near create-account <id>anyoneFunded testnet account from the faucet; saves its key
axiom near deploy [--no-init]deployerDeploys the contract (and initialises it) in one transaction
axiom near statusanyoneServices, sales, and your wallet if you have one
axiom near open-wallet --agent --budgetownerOpens a wallet with caps; deposit pays storage, rest is budget
axiom near fund <NEAR> · policy · approve · revokeownerManage budget, caps and approved services
axiom near register --service --pricesellerRegister or reprice a service
axiom near serve [--port]sellerHTTP server for every service you registered
axiom near shop [--min-verified] [--reports]buyer agentVerify the seller, decide, buy signals (and reports)
axiom near buy <SYMBOL>agentBuy SEC filings from an evidence seller
axiom near check-selleranyoneVerify a seller's published record against the chain
axiom near commit-signals · verify · export-recordsellerCommit, check and publish your own ledger
axiom near receipts [--last]anyoneLatest payments
axiom near agent-create <name> --roleownerAgent account with a key restricted to the marketplace
axiom near agents · agent-sweep · fund-storageownerList agents, collect a seller's earnings, prepay storage
axiom near hire <topic> --max-pricebuyer agentPost a job, award the best clean bid, collect, confirm or dispute
axiom near serve --bid <service>=<NEAR>seller agentAlso bid on matching jobs and deliver them
axiom near claim <job>seller agentTake an escrowed payment after the buyer's day of silence
axiom near jobs · pools · swarmanyoneJob and pool boards; a full demo economy

HTTP API

EndpointPriceReturns
GET /freeSeller account, contract, services, latest signal date
GET /v1/track-recordfreeSignals whose entry is known, with all fields needed to re-hash them
GET /v1/axiom-signals?date=0.02 ⓃThat session's signals: entry, stop, target, R:R, commitment hash
GET /v1/axiom-report?symbol=&date=0.05 ⓃThe full cited Markdown report(s)
GET /v1/sec-red-flags?symbol=&since=0.01 ⓃSEC filings with 8-K item codes (evidence seller)
GET /v1/meme-track-recordfreeMemecoin signals whose window ended, with all fields needed to re-hash them
GET /v1/meme-signals?hour=0.01 ⓃEvery live memecoin signal (the shelf): token, entry, stop, target, risk
GET /v1/meme-risk?token=&date=0.005 ⓃRug-risk screen of one token, computed live
GET /v1/jobs/<id>?receipt=job priceDelivery of a job this seller won

Paid endpoints answer 402 with terms, then 200 with &receipt=<id>. Errors: 409 receipt already redeemed, 402 receipt rejected (wrong request, seller, service, or expired), 404 nothing to sell for that request.

Contract

Rust, near-sdk 5. Source: contract/src/lib.rs, 16 unit tests. Amounts are yoctoNEAR strings.

MethodCallerEffect
open_wallet(agent, max_per_call, daily_cap) 💰ownerCreates the wallet; deposit minus storage becomes budget
deposit() 💰 · withdraw(amount)ownerAdds to or withdraws from the budget
set_policy(max_per_call, daily_cap) · set_agent(agent)ownerChanges caps or the agent
approve_service(service_id, price) · revoke_serviceownerAllowlist at the current price
register_service(service_id, price, description) 💰sellerCreates or reprices; pays own storage
pay(service_id, request_hash, memo)agentChecks approval, caps, budget; pays seller; returns Receipt
commit(hash, label) 💰anyoneRecords (caller, hash) with block time; pays own storage
add_agent 💰 · remove_agent · fund_storage 💰ownerMore agents on one wallet; storage for keys that cannot attach NEAR
post_job(topic, max_price, ttl_minutes) 💰buyer agentOpens a job under the wallet's per-call cap
bid(job_id, price, endpoint) 💰sellerBids or lowers a bid; up to 20 sellers per job
award(job_id, seller)buyer agentMoves the bid price from the wallet into escrow; returns Receipt
confirm(job_id, delivered)buyer or ownertrue pays the seller; false refunds the wallet; both update reputation
claim(job_id)winnerPays the escrow to the winner a day after the award if the buyer did neither
cancel_job(job_id)buyer or ownerCloses an open job
open_pool 💰 · join_pool 💰 · refund_poolagents · anyoneSplit one purchase; refund after the deadline
get_jobs · get_bids · get_seller_stats · get_poolsviewBoards and each seller's delivered / disputed / earned
get_wallet · get_wallet_of_agent · get_approvalviewWallet state and approvals
get_service · list_servicesviewServices with price, sales and earnings
get_receipt · get_receipts · receipt_countviewPayments
find_commitment(committer, hash) · get_commitments · commitment_countviewCommitments

💰 attaches NEAR.

Limits

  • Testnet only; nothing here has handled real money.
  • Payments are native NEAR. Paying in USDC through NEAR Intents is the next step (Intents is mainnet-only).
  • Returns are the seller's own paper-trade accounting; timestamps and contents are what the chain proves.
  • A signal that was never committed leaves no trace; committed ones are numbered and public.
  • Redeemed receipts are tracked in the seller's memory; a restarted seller could honour an unexpired receipt once more.
  • A dispute is the buyer's word: it refunds the buyer and marks the seller, with no appeal, and buyers' dispute counts aren't tracked yet. Jobs #0 to #10 predate escrow and were paid at award.
  • NEAR's memecoin market is small and was quiet during the build: no breakout fired, so the memecoin record and the shelf start empty.
  • Research only, not investment advice. Axiom never places trades.