Skip to content
LogoLogo

Clients

Both clients share one core and expose the same action names; pick sync or async.

from arrekta_sdk import Client, AsyncClient
 
client = Client("http://127.0.0.1:28332")                 # node REST API: /v1 and /rpc
client = Client("http://127.0.0.1:28332", network="regtest")  # optional; else learned from /v1/chain
 
async with AsyncClient("http://127.0.0.1:28332") as aclient:
    tip = await aclient.get_block(id="tip")

Use them as context managers (or call close()) to release the HTTP connection pool.

Gateway clients

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

import os
from arrekta_sdk import GatewayClient
 
gateway = GatewayClient("http://localhost:3000", api_key=os.environ["ARREKTA_API_KEY"])

An AsyncGatewayClient exists for asyncio code.

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:

from arrekta_sdk import GatewayClient, PrivateKey
 
key = PrivateKey(signing_seed)                      # ML-DSA-65 by default; keep the seed secret
print(key.public_key().to_bytes().hex())            # give this to the gateway admin once
gateway = GatewayClient(url, api_key=api_key, signing_key=key)

For another HTTP stack, sign_request(key, api_key, method, path_and_query, body) returns the three headers (X-ARRK-Timestamp, X-ARRK-Nonce, X-ARRK-Signature), and RequestSigner is a ready-made httpx auth hook.

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:

gateway = GatewayClient(url, headers={"authorization": f"Bearer {access_token}"})

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.

client = Client("http://127.0.0.1:28332", cache=True)    # up to 500 responses
polling = AsyncClient(url, cache=50)                     # at most 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 signature hash commits to the network magic, so a transaction signed for regtest is invalid on testnet.