Daejin Developers

Solana walkthrough

One complete Solana run — deposit, rest, cancel, trade against the AMM, resolve, claim, withdraw — as commands, with the arithmetic to check against.

Complete run

Market 880101 on devnet, funded and closed out through the Solana /tx/* calls. Check your own run against the arithmetic: when a step is silently doing nothing, the totals stop adding up long before anything throws.

StepCallWalletExchange balanceShares
start—$500.00——
depositPOST /tx/deposit$400.00$100.00—
rest an orderPOST /orders$400.00$100.00—
cancel itDELETE /orders/{id}$400.00$100.00—
buy 10 YES at 50¢POST /market-order$400.00$94.9510 YES
market resolves YES(an operator does this)$400.00$94.9510 YES
claimPOST /tx/claim$400.00$104.950
withdrawPOST /tx/withdraw$504.95$0.000

Net $4.95 = a $10 payout on 10 winning shares, less the $5 they cost at 50¢, less $0.05 of fee. The fee is 1% of the trade.

The same run, as commands

Paste them in order against a market of your own. The build steps never touch your private key; the signing pipe is the wallet side. Every write needs an API key with write — -H "X-API-Key: $KEY" below; see Authentication.

Setup

export ENGINE=https://app-staging.daejin.xyz/clob/v1
export BRIDGE=https://app-staging.daejin.xyz/clob-engine
export KEY=tp_test_…                 # your API key (write scope), from the keys page
export USER_PUB=<your base58 pubkey> # the wallet that signs and holds the collateral
export M=880201                      # the numeric on-chain market id, from GET /markets

Amounts below are raw units: USDC has 6 decimals, so 50000000 is $50. Prices are ticks: 1000 = $1.00.

1 — Look at the market

curl -s "$BRIDGE/quote?market=$M"
# {"market":880201,"yes":500,"no":500}

curl -s $ENGINE/markets/$M
curl -s $ENGINE/markets/$M/book
curl -s $ENGINE/markets/$M/ticker

A market published through the app is already live on chain by the time it appears in GET /markets; /quote answering with prices is the confirmation. Everything below needs nothing but your own wallet and key.

2 — Deposit (signs)

# build — see what comes back before piping it anywhere
curl -s -X POST $BRIDGE/tx/deposit -H "X-API-Key: $KEY" -H 'content-type: application/json' \
  -d "{\"marketId\":$M,\"user\":\"$USER_PUB\",\"amount\":\"50000000\"}"
# {"ok":true,"transaction":"<base64>","blockhash":"…","createsTokenAccount":false}

# build → sign → submit, in one pipe
curl -s -X POST $BRIDGE/tx/deposit -H "X-API-Key: $KEY" -H 'content-type: application/json' \
  -d "{\"marketId\":$M,\"user\":\"$USER_PUB\",\"amount\":\"50000000\"}" \
  | jq -r .transaction | node sign.mjs \
  | curl -s -X POST $BRIDGE/tx/submit -H "X-API-Key: $KEY" -H 'content-type: application/json' --data-binary @-
# {"ok":true,"signature":"…","confirmed":true}

sign.mjs is the whole of your side of this. It ships as scripts/sign.mjs in tokenplay-clob-bridge and is printed in full on Build Transaction. Run it as USER_KEY=<base58 secret key> node sign.mjs. A real integration signs with the user's wallet — Phantom, a Ledger, a custodial signer — and the code is the same three lines, Transaction.from, sign, serialize.

3 — Rest an order, then cancel it (signs)

npm run mm:solana -- place --action buy --outcome YES --price 400 --size 5000000
# HTTP 201  {"accepted":true,"order":{"id":"o2","status":"open",…}}

curl -s $ENGINE/markets/$M/book
curl -s -H "X-API-Key: $KEY" "$ENGINE/users/$USER_PUB/orders?market=$M"

export OID=$(curl -s $ENGINE/markets/$M/orders | jq -r '.orders[0].id')
curl -s -H "X-API-Key: $KEY" $ENGINE/orders/$OID
# {"order":{"id":"o2","status":"open","remaining":"5000000"}}   ← no salt, no signature

npm run mm:solana -- cancel --id $OID
curl -s -H "X-API-Key: $KEY" "$ENGINE/users/$USER_PUB/orders/closed?market=$M"

Swap place for message to print the signed string and the signature without sending anything — the fastest way to see why a signature is being rejected.

4 — Prove the signature is really checked

curl -s -X POST $ENGINE/orders -H "X-API-Key: $KEY" -H 'content-type: application/json' -d "{
  \"user\":\"$USER_PUB\",\"market\":\"$M\",\"action\":\"buy\",\"outcome\":\"YES\",
  \"price\":500,\"size\":\"1000000\",\"type\":\"GTC\",\"salt\":42,\"expiry\":0,
  \"signature\":\"<any other valid base58 signature>\"}"
# 422  {"accepted":false,"reason":"invalid signature"}

5 — Trade against the AMM (signs)

curl -s -X POST $BRIDGE/market-order -H "X-API-Key: $KEY" -H 'content-type: application/json' \
  -d '{"market":880201,"user":"<pubkey>","action":"buy","outcome":"yes",
       "price":700,"size":5000000,"salt":123,"expiry":0,"signature":"<base58>"}'
# {"ok":true,"sig":"…","execPrice":500}

curl -s "$BRIDGE/quote?market=$M"
# {"yes":667,"no":333}    ← the AMM sold YES, so YES got dearer

Your signed price is a limit, not a request: 700 here means "fill me at 70¢ or better", and it filled at 50¢. A 422 means the pool could not do it within your limit.

6 — Liquidity, resolution, payout (signs)

curl -s -X POST $BRIDGE/tx/add-liquidity -H "X-API-Key: $KEY" -H 'content-type: application/json' \
  -d "{\"marketId\":$M,\"user\":\"$USER_PUB\",\"amount\":\"25000000\"}" \
  | jq -r .transaction | node sign.mjs \
  | curl -s -X POST $BRIDGE/tx/submit -H "X-API-Key: $KEY" -H 'content-type: application/json' --data-binary @-

# … the market resolves YES. Resolution is an operator action, not an API you call;
# GET $ENGINE/markets/$M stops listing the book once it has closed.

for k in claim claim-lp-fees remove-liquidity; do
  curl -s -X POST $BRIDGE/tx/$k -H "X-API-Key: $KEY" -H 'content-type: application/json' \
    -d "{\"marketId\":$M,\"user\":\"$USER_PUB\"}" \
    | jq -r .transaction | node sign.mjs \
    | curl -s -X POST $BRIDGE/tx/submit -H "X-API-Key: $KEY" -H 'content-type: application/json' --data-binary @-
done

The three claims only succeed after resolution; before it they fail on chain rather than doing nothing, so a run that reaches step 7 has really been paid out.

7 — Withdraw (signs)

# the balance after a claim is never a round number — read it, do not guess
curl -s -X POST $BRIDGE/tx/withdraw -H "X-API-Key: $KEY" -H 'content-type: application/json' \
  -d "{\"marketId\":$M,\"user\":\"$USER_PUB\",\"amount\":\"76975000\"}" \
  | jq -r .transaction | node sign.mjs \
  | curl -s -X POST $BRIDGE/tx/submit -H "X-API-Key: $KEY" -H 'content-type: application/json' --data-binary @-

Leaving a placeholder in amount makes the build return an error, jq print null, and the signer choke on nothing. If a pipe dies oddly, run the /tx/ call alone and read its error.

Check the arithmetic, not just the status codes

Deposit $50, buy 5000000 at an exec price of 500, and the position should read $47.475: the trade cost $2.50 of notional and $0.025 of fee. After YES resolves, claim adds $5.00 — the shares are worth par — for $52.475. Removing $25 of liquidity returns $24.50, not $25: the pool sold shares for $2.50 that settled at $5.00, and your 25 of its 125 shares carry 20% of that $2.50 loss. A run where every call returns 200 and the totals do not close is a run that has quietly failed.

On this page