Skip to content
LogoLogo

Clients

A client holds a transport (URL, fetch, headers) and the network. Actions take the client as their first argument.

createClient

import { createClient } from 'arrekta-sdk'
 
const client = createClient({
  url: 'http://127.0.0.1:28332', // node REST API: /v1 and /rpc
  network: 'regtest',            // optional; otherwise learned from GET /v1/chain
  fetch: globalThis.fetch,       // optional custom fetch (proxies, tests)
})

createGatewayClient

The platform gateway fronts the node (/v1 proxied), its own routes (/gateway/v1) and the wallet and issuer services (/wallet/v1, /issuer/v1). Every request carries the API key.

import { createGatewayClient } from 'arrekta-sdk'
 
const gateway = createGatewayClient({ url: 'http://localhost:3000', apiKey: process.env.ARREKTA_API_KEY! })

Keep API keys server-side. For browsers, exchange the key for a short-lived stream token (POST /gateway/v1/stream/tokens); see Live event streams.

Signed requests (partners)

When the gateway admin registers your signing key on the API key, every request must be signed. Pass the private key and the client signs each request as it is sent:

import { createGatewayClient, privateKeyFromSeed, toHex } from 'arrekta-sdk'
 
const key = privateKeyFromSeed(signingSeed)          // ML-DSA-65 by default; keep the seed secret
console.log(toHex(key.publicKeyBytes))               // give this to the gateway admin once
const gateway = createGatewayClient({ url, apiKey, signingKey: key })

For another HTTP stack, signRequest({ key, apiKey, method, pathAndQuery, body }) returns the three headers (x-arrk-timestamp, x-arrk-nonce, x-arrk-signature).

Signed-in users (OAuth)

If the gateway is set up for your identity provider (OpenID Connect), a signed-in user's access token works instead of an API key:

const gateway = createGatewayClient({ url, headers: { authorization: `Bearer ${accessToken}` } })

Conditional reads (cache)

Every GET /v1/… answer carries an ETag. With cache: true the client remembers each response and sends If-None-Match the next time; when nothing changed the node answers 304 Not Modified with no body and the client returns the remembered result. Polling a transaction's confirmations or an address costs almost nothing while it is unchanged.

const client = createClient({ url: 'http://127.0.0.1:28332', cache: true }) // up to 500 responses
const polling = createClient({ url, cache: { maxEntries: 50 } })

It works the same through the gateway, which passes If-None-Match and ETag through.

Networks

NetworkAddress prefixDefault API port
mainnetarrk8332
testnettarrk18332
regtestrarrk28332

The network matters for signing: the signature hash commits to the network magic, so a transaction signed for regtest is invalid on testnet.