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 paid

After 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.