> For the complete documentation index, see [llms.txt](https://docs.anchored.finance/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.anchored.finance/trading-api/authentication/examples.md).

# Examples

Node.js HMAC authentication snippets. For a full integration sample with **viem** (self-submit tx, ERC-20 approve, One Click `signTypedData`), see [guides/demo-code.md](/trading-api/guides/demo-code.md).

## HMAC helper

```js
import crypto from "node:crypto";

function canonicalUri(path, query = {}) {
  const pairs = [];
  for (const key of Object.keys(query).sort()) {
    const value = query[key];
    if (Array.isArray(value)) {
      for (const item of value) pairs.push(`${key}=${item}`);
    } else if (value !== undefined && value !== null) {
      pairs.push(`${key}=${value}`);
    }
  }
  return pairs.length === 0 ? path : `${path}?${pairs.join("&")}`;
}

function signTradingApi({ method, path, query, timestamp, nonce, rawBody, apiSecret }) {
  const uri = canonicalUri(path, query);
  const payload = [
    method.toUpperCase(),
    uri,
    String(timestamp),
    nonce,
    rawBody ?? ""
  ].join("\n");

  return crypto
    .createHmac("sha256", apiSecret)
    .update(payload, "utf8")
    .digest("hex");
}
```

## Signed POST example

```js
const body = JSON.stringify({
  stockAddress: "0x0000000000000000000000000000000000000001",
  side: "Buy",
  type: "Market",
  notional: "10",
  deadline: 1893456000
});

const timestamp = Date.now();
const nonce = crypto.randomUUID();
const hmacAuth = signTradingApi({
  method: "POST",
  path: "/api/v1/orders/calldata",
  query: {},
  timestamp,
  nonce,
  rawBody: body,
  apiSecret: process.env.TRADING_API_SECRET
});

const headers = {
  "content-type": "application/json",
  "x-api-key": process.env.TRADING_API_KEY,
  "x-api-ts": String(timestamp),
  "x-api-nonce": nonce,
  "x-api-sign": hmacAuth,
  "x-api-chain-id": "8453",
  "x-api-p": "Anchored"
};

const response = await fetch(
  "https://rwa-api.anchored.finance/rwa/trading/api/v1/orders/calldata",
  { method: "POST", headers, body }
);
```

## cURL with HMAC

```bash
API_KEY="your-api-key"
API_SECRET='your-api-secret'   # single-quote it: a secret containing shell metacharacters breaks when double-quoted or sourced
METHOD="POST"
URI="/api/v1/orders/calldata"   # do NOT name this variable PATH — it clobbers the shell's $PATH
# Unix milliseconds. GNU date works directly; BSD (macOS) date emits a literal "N",
# so fall back based on whether the output is all digits (do NOT rely on exit code —
# BSD date exits 0 even for %3N).
TIMESTAMP=$(date +%s%3N)
case "$TIMESTAMP" in
  ''|*[!0-9]*)
    if command -v gdate >/dev/null 2>&1; then TIMESTAMP=$(gdate +%s%3N)
    else TIMESTAMP=$(python3 -c 'import time; print(int(time.time()*1000))'); fi ;;
esac
NONCE=$(uuidgen | tr '[:upper:]' '[:lower:]')
BODY='{"stockAddress":"0x0000000000000000000000000000000000000001","side":"Buy","type":"Market","notional":"10","deadline":1893456000}'

# Pipe printf STRAIGHT into openssl. Gotchas this avoids:
#  1) Join with REAL newlines (printf format), not the two-character "\n".
#  2) PAYLOAD=$(printf ...) would strip the trailing newline (breaks empty-body GET/DELETE).
#  3) -macopt "key:..." (not -hmac "...") so a secret starting with "-" isn't parsed as an option.
HMAC_AUTH=$(printf '%s\n%s\n%s\n%s\n%s' "$METHOD" "$URI" "$TIMESTAMP" "$NONCE" "$BODY" \
  | openssl dgst -sha256 -mac HMAC -macopt "key:$API_SECRET" -hex | awk '{print $NF}')

curl -X ${METHOD} "https://rwa-api.anchored.finance/rwa/trading${URI}" \
  -H "Content-Type: application/json" \
  -H "x-api-key: ${API_KEY}" \
  -H "x-api-ts: ${TIMESTAMP}" \
  -H "x-api-nonce: ${NONCE}" \
  -H "x-api-sign: ${HMAC_AUTH}" \
  -H "x-api-chain-id: 143" \
  -H "x-api-p: Anchored" \
  -d "${BODY}"
```

See also [signature.md](/trading-api/authentication/signature.md) for Python and HMAC authentication details, and [guides/demo-code.md](/trading-api/guides/demo-code.md) for viem integration.
