> ## Documentation Index
> Fetch the complete documentation index at: https://docs.kuru.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Relay

> Authenticate a trading wallet and submit signed Kuru actions through the TypeScript SDK.

`@toxicflow-labs/ts-sdk/relay` authenticates a secondary trading EOA with Relay and submits already signed trading-wallet or AccountCore payloads. It does not create wallet-intent signatures for you; use [Trading-wallet signing](/sdk/trading-wallet.md) first.

All testnet examples use Monad chain ID `10143` and the Relay testnet URL `https://relay.testnet.kuru.io`.

This SDK Relay client submits over REST. For direct WebSocket integration, connect to `wss://relay.testnet.kuru.io/relay/ws?account_id=<accountId>` (or `wss://relay.mainnet.kuru.io/relay/ws?account_id=<accountId>` on mainnet) with a wallet-bound JWT in the `Authorization` upgrade header. `account_id` is the Kuru trading account ID, not the signer address; see the [Relay WebSocket overview](/api/relay/rest.md#websocket) for its canonical format and outcome behavior. The SDK does not currently provide a Relay WebSocket transport.

## Authenticate

`authenticate()` requests Relay's one-time challenge, signs its exact UTF-8 message with `personal_sign`, exchanges it for a JWT, validates the wallet binding, and retains the token on the client.

```typescript theme={null}
import { privateKeyToAccount } from "viem/accounts";
import {
  createKuruRelayClient,
  createLocalAccountRelaySigner,
} from "@toxicflow-labs/ts-sdk/relay";

const tradingWallet = privateKeyToAccount(
  process.env.TRADING_WALLET_KEY as `0x${string}`,
);
const relay = createKuruRelayClient({
  baseUrl: "https://relay.testnet.kuru.io",
  signer: createLocalAccountRelaySigner(tradingWallet),
  timeoutMs: 5_000,
});

const session = await relay.authenticate();
console.log(session.wallet, session.expiresAt);
```

Use `createWalletClientRelaySigner(walletClient, tradingWalletAddress)` for an injected or embedded wallet. The SDK does not authenticate, refresh tokens, re-sign payloads, or retry state-changing submissions implicitly.

## Sign and submit

After the signed `intent` is ready, submission is one Relay REST request and no chain RPC. The client assigns a UUIDv7 request ID unless you provide one.

```typescript theme={null}
// intent is the SignedWalletIntent returned by signBatchIntent(...).
const broadcast = await relay.executeBatch({ intent });
console.log(broadcast.txHash, broadcast.transactionType);
```

> [!WARNING]
>
> `BROADCAST` means Relay accepted and scheduled the sponsored transaction for
> asynchronous RPC broadcast. It does not prove provider acceptance or that the
> target action executed. Wait for the transaction receipt and verify the
> expected event or state change.

## SDK method mapping

| Signed value | Relay client method | Relay API reference |
| - | - | - |
| AccountCore signer authorization, optionally plus EIP-7702 authorization | `authorizeAccountSigner` | [Authorize account signer](/api/relay/reference/authorize-account-signer.md) |
| `SignedWalletIntent<PreparedReplaceBySlotIntent>` | `executeReplaceBySlot` | [Execute packed replacement](/api/relay/reference/execute-replace-by-slot.md) |
| `SignedWalletIntent<PreparedBatchIntent>` | `executeBatch` | [Execute order batch](/api/relay/reference/execute-batch.md) |
| `SignedWalletIntent<PreparedCreateReplaceTriggerIntent>` | `createReplaceTrigger` | [Create packed trigger](/api/relay/reference/create-replace-trigger.md) |
| `SignedWalletIntent<PreparedCreateBatchTriggerIntent>` | `createBatchTrigger` | [Create batch trigger](/api/relay/reference/create-batch-trigger.md) |
| `SignedWalletIntent<PreparedCancelTriggerIntent>` | `cancelTrigger` | [Cancel conditional order](/api/relay/reference/cancel-trigger.md) |

Relay trigger creation (`createReplaceTrigger` and `createBatchTrigger`) is disabled. The SDK provides the corresponding signing interfaces for contract integrations.

Relay also defines nine [opt-in operational methods](/api/relay/operational.md), including cancel-by-ID, cancel-all, FOK, stored FOK trigger/TWAP actions, signer revocation, and subaccount creation. They use bounded RPC simulation and are slower than the batch/packed path. The SDK Relay client does **not** currently expose wrappers for these new methods; use the documented REST or authenticated WebSocket envelopes with separately prepared, exact EIP-712 signatures. In particular, AccountCore revocation and child creation use a separate owner/admin/TRADE authorizer signature with the AccountCore version-1 domain; the frontend trading-wallet JWT does not grant that authority.

## Runnable examples

The SDK repository has one runnable source file per Relay method. Each signs its payload first, authenticates the trading EOA, then sends the matching Relay request:

* [`authorize-account-signer.ts`](https://github.com/Kuru-Labs/ts-sdk/blob/main/examples/relay/authorize-account-signer.ts)
* [`execute-replace-by-slot.ts`](https://github.com/Kuru-Labs/ts-sdk/blob/main/examples/relay/execute-replace-by-slot.ts)
* [`execute-batch.ts`](https://github.com/Kuru-Labs/ts-sdk/blob/main/examples/relay/execute-batch.ts)
* [`create-replace-trigger.ts`](https://github.com/Kuru-Labs/ts-sdk/blob/main/examples/relay/create-replace-trigger.ts)
* [`create-batch-trigger.ts`](https://github.com/Kuru-Labs/ts-sdk/blob/main/examples/relay/create-batch-trigger.ts)
* [`cancel-trigger.ts`](https://github.com/Kuru-Labs/ts-sdk/blob/main/examples/relay/cancel-trigger.ts)

Set the current account and market inputs explicitly before running an example. The testnet deployment addresses and chain ID `10143` are listed in [Testnet Deployments](/deployments/testnet.md).

## Errors and retries

`KuruRelayError.kind` distinguishes input, authentication, HTTP, transport, timeout, cancellation, Relay rejection, and malformed-response failures. A Relay rejection includes safe response metadata such as `retryable`, `retryAfterMs`, and `candidateTxHash`.

Do not blindly retry a state-changing request. Reconcile the prior request ID and any candidate transaction hash, then use a fresh signature or consciously reuse the same request ID only when the Relay API's idempotency behavior is understood.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.