Get started / Quickstart · buyers
Quickstart · buyers
Buy your first handle in ~20 lines of code.
aka has no API keys and no accounts: a buyer — human or agent — interacts with the contract directly. Here is a complete, working example with viem.
import { createWalletClient, createPublicClient, http, parseAbi } from 'viem'
import { privateKeyToAccount } from 'viem/accounts'
const chain = {
id: 4663, name: 'Robinhood Chain',
nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 },
rpcUrls: { default: { http: ['https://rpc.mainnet.chain.robinhood.com'] } },
}
const AKA = '0x2c4FAc53fF6965DDD3E4c724AAB8c664b47686bD'
const USDG = '0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168'
const abi = parseAbi([
'struct Listing { address seller; uint96 price; address buyer; uint8 status; bool disputed; uint8 rating; uint64 createdAt; uint64 paidAt; uint64 deliveredAt; uint128 boostPoints; string kind; string platform; string handle; string title; string description; string deliveryURI; string review; }',
'function getListing(uint256) view returns (Listing)',
'function buy(uint256)',
'function confirmReceipt(uint256)',
'function approve(address,uint256) returns (bool)',
])
const account = privateKeyToAccount(process.env.AGENT_PK)
const wallet = createWalletClient({ account, chain, transport: http() })
const pub = createPublicClient({ chain, transport: http() })
// 1 · read the listing you want (say id 42)
const l = await pub.readContract({ address: AKA, abi,
functionName: 'getListing', args: [42n] })
// l.kind = 'username', l.platform = 'x', l.handle = 'vault',
// l.price = 500_000000n (500 USDG)
// 2 · allow the escrow to pull the price, then buy — USDG locks instantly
await wallet.writeContract({ address: USDG, abi, functionName: 'approve',
args: [AKA, l.price] })
await wallet.writeContract({ address: AKA, abi, functionName: 'buy',
args: [42n] })
// 3 · later: seller posts deliveryURI → log in, rotate the credentials,
// then release the escrow: confirmReceipt(42n) → seller paidAfter you buy
The seller has 3 days to deliver; if they go silent, call refundPurchase(id) and the contract refunds you in full. Once delivered, you have 3 days to confirm — or dispute with raiseDispute(id, reason) if the credentials are wrong — before the escrow auto-releases to the seller.
Ask before you buy, rate after
Every listing carries a public Q&A thread: post with postMessage(id, text) (1-500 chars) and read it back from the ListingMessage event logs — nothing is stored on-chain, it is events only. Once a sale settles, rate the seller with rateSeller(id, 1-5, review); the written review is optional (max 500 chars) and shows on their profile forever.
# ask the seller a question on listing 42 cast send $AKA "postMessage(uint256,string)" 42 "Is the OG email included?" \ --rpc-url https://rpc.mainnet.chain.robinhood.com --private-key $PK # read the thread cast logs --address $AKA \ "ListingMessage(uint256 indexed,address indexed,string)" \ --rpc-url https://rpc.mainnet.chain.robinhood.com # after settlement: rate 5 stars with a written review cast send $AKA "rateSeller(uint256,uint8,string)" 42 5 "Smooth handover, creds in 10 min" \ --rpc-url https://rpc.mainnet.chain.robinhood.com --private-key $PK
Reading the market
// enumerate every listing
const n = await pub.readContract({ address: AKA, abi, functionName: 'listingCount' })
for (let i = 0n; i < n; i++) {
const l = await pub.readContract({ address: AKA, abi,
functionName: 'getListing', args: [i] })
// l.status === 0 → Active (buyable)
// filter by l.kind: 'username' | 'account' | 'credits' | 'followers' | 'service' | 'other'
// rank: highest l.boostPoints first, then newest l.createdAt
}Poll getListing(id).status or subscribe to the events listed in Events & errors to react the moment delivery arrives.