Bridge API
HTTP API for listing bridge configuration, reading token balances, syncing a wallet’s bridge transfers, recording a send, marking a claim, and requesting relayer signatures.
All routes below are relative to the bridge base URL. Requests and responses use JSON unless noted.
These routes require the API guard headers.
API guard
Every documented route is signed. The bridge rejects the request before the handler runs when the signature is missing, stale, or wrong.
To obtain a client, contact AssetChain. You will receive a client key
Do not request a client key from the bridge. AssetChain issues it.
Headers
x-client-name
yes
Client name issued by AssetChain.
x-timestamp
yes
Unix time in seconds or milliseconds. Must be within 60 seconds of the server clock.
x-signature
yes
Hex-encoded HMAC-SHA256 of the canonical string, using the client key as the secret.
Content-Type
for bodies
application/json when the request has a body.
Canonical string
Hash the JSON body with SHA-256 (hex). If the request has no body, hash the empty string.
Join these four lines with a newline (\n). The path is the request path only, with no query string.
x-signature is HMAC-SHA256(clientKey, canonicalString) encoded as hex.
Example for GET /bridges with timestamp 1710000000 and no body:
The last line is SHA-256 of an empty string. If you send a JSON body, hash that exact JSON string, not a re-serialized object.
Node.js:
Browsers and other web apps (TypeScript). crypto.subtle is async, so signRequest returns a Promise<string>:
Use the same timestamp string in x-timestamp and in the canonical string. JSON.stringify the same object you send as the body. Hash that exact string. The client key is the HMAC secret: a browser can read it, so do not ship it in a public web app.
Guard responses
Missing headers:
HTTP 401
Timestamp is not a number:
HTTP 401
Timestamp is older or newer than 60 seconds:
HTTP 401
Signature does not match:
HTTP 401
Errors from route handlers
Validation failures returned by a route use HTTP 400:
Thrown errors are passed through the error handler:
GET /tokens
Lists configured tokens.
Parameters
None.
Response
HTTP 200
decimal
Token decimals.
chainId
Chain id string, including Solana ids such as sol.devnet.
maxClaimAmount
Raw max claim amount for this token, or null when no limit is set.
GET /bridges
Lists bridge deployments, including fees and the linked token.
Parameters
None.
Response
HTTP 200
fees.feeSend
Fee taken on send, in protocol units.
fees.feeFulfill
Fee taken on fulfill, in protocol units.
limitPerSend
Raw maximum amount per send.
tokenDecimal
Decimals used for this bridge’s token on this chain.
GET /transactions
Returns stored bridge transfers for a wallet. On the first request for that wallet, or when forceSync=true, the bridge reads transfers from chain and writes them before responding.
Query parameters
userAddress
yes
EVM or Solana wallet.
secondaryAddress
no
Second wallet included in the same result.
chainIds
no
Comma-separated chain ids to filter, for example 84532,421614.
fulfilled
no
true or false. Omit to return both.
forceSync
no
true re-reads transfers from chain before returning the page.
symbol
no
Token symbol filter. XRWA is stored as RWA.
page
no
Page number. Default 1. Minimum 1.
limit
no
Page size. Default 10. Minimum 1, maximum 100.
Response
HTTP 200
amount, fulfillAmount, timestamp, and txBlock are strings. claimApproved is true after an admin approves a transfer that is above the token’s max claim amount.
Invalid query:
HTTP 400
POST /transactions
Records a transfer that already exists on the source chain. The bridge reads the on-chain send and stores it. If that index is already stored for the same wallet and bridge, the existing row is returned.
Body
bridgeId
string
yes
Bridge id from GET /bridges.
index
string
yes
Source-chain transaction index for this user.
userAddress
string
yes
EVM or Solana wallet that sent the transfer.
transactionHash
string
yes
Source-chain transaction hash.
Response
HTTP 201
If the row already exists, the HTTP status is still 201 and data.message is "Transaction already exists".
Missing fields:
HTTP 400
Unknown bridge (HTTP 400):
The on-chain send does not exist (HTTP 400):
PUT /transactions
Checks whether a stored transfer has been fulfilled on the destination chain. When the destination confirms fulfillment, the row is marked fulfilled and the claim hash is saved.
Body
transactionId
string
yes
Transaction id from GET /transactions.
claimTransactionHash
string
yes
Destination-chain claim transaction hash.
toBridgeId
string
yes
Destination bridge id from GET /bridges.
Response
HTTP 200
fulfilled stays false when the destination chain does not yet show the claim. If the row was already fulfilled, data.message is "Transaction already fulfilled".
Missing fields:
HTTP 400
Unknown transaction or bridge (HTTP 400):
GET /blockchain/sign
Returns the relayer signatures required to fulfill a transfer on the destination chain.
Query parameters
bridgeId
yes
Source bridge id from GET /bridges.
index
yes
Source-chain transaction index for fromUser.
fromUser
yes
EVM or Solana address that sent the transfer.
Response
HTTP 200
signature contains one signature string per destination relayer, in relayer index order.
Validation failure:
HTTP 400
Common thrown errors (HTTP 400, code INTERNAL_ERROR):
Last updated