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

# TypeScript SDK

> TypeScript SDK for the Hypermid API — Node.js, browsers, edge runtimes

The official TypeScript SDK provides a fully typed, promise-based client for the Hypermid API. Ships as a **dual ESM + CJS build** — works in modern Node.js (18+), browsers, Bun, Deno, Next.js, Vite, AWS Lambda, and edge runtimes.

## Installation

<CodeGroup>
  ```bash npm theme={"system"}
  npm install @hypermid/sdk
  ```

  ```bash pnpm theme={"system"}
  pnpm add @hypermid/sdk
  ```

  ```bash yarn theme={"system"}
  yarn add @hypermid/sdk
  ```

  ```bash bun theme={"system"}
  bun add @hypermid/sdk
  ```
</CodeGroup>

## Configuration

```typescript theme={"system"}
import { Hypermid } from "@hypermid/sdk";

// Anonymous tier — works immediately, no signup
const client = new Hypermid();

// With a partner API key
const client = new Hypermid({
  apiKey: process.env.HYPERMID_API_KEY,
});

// Full custom config
const client = new Hypermid({
  apiKey: process.env.HYPERMID_API_KEY,
  baseUrl: "https://api.hypermid.io",  // optional, default shown
  timeout: 30_000,                      // optional, ms, default shown
  fetch: customFetch,                   // optional, custom fetch impl
});
```

### Configuration options

| Option    | Type           | Default                   | Description                                                            |
| --------- | -------------- | ------------------------- | ---------------------------------------------------------------------- |
| `apiKey`  | `string`       | —                         | Partner API key. Omit for anonymous tier.                              |
| `baseUrl` | `string`       | `https://api.hypermid.io` | API base URL                                                           |
| `timeout` | `number`       | `30_000`                  | Per-request timeout in milliseconds                                    |
| `fetch`   | `typeof fetch` | `globalThis.fetch`        | Custom fetch implementation (for testing, polyfills, or edge runtimes) |

## Methods

### Chains & tokens

```typescript theme={"system"}
const chains = await client.getChains();

const tokens = await client.getTokens({
  chains: "1,42161,137",
  keywords: "usdc",
});

const conns = await client.getConnections({
  fromChain: 1,
  toChain: 42161,
});

const tools = await client.getTools();

const gas = await client.getGasPrices({ chains: "1,42161" });
```

### Quote / Execute / Status

```typescript theme={"system"}
const quote = await client.getQuote({
  fromChain: 1,
  fromToken: "0x0000000000000000000000000000000000000000",
  fromAmount: "1000000000000000000",
  toChain: 42161,
  toToken: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
  fromAddress: "0xYourAddress",
});

const exec = await client.execute({
  fromChain: 1,
  fromToken: "0x0000000000000000000000000000000000000000",
  fromAmount: "1000000000000000000",
  toChain: 42161,
  toToken: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
  fromAddress: "0xYourAddress",
  toAddress: "0xYourAddress",
});

// EVM swaps return a transactionRequest to sign and broadcast.
// Non-EVM (NEAR Intents) return a depositAddress to send tokens to.

const status = await client.getStatus({
  txHash: "0xTxHash",
  fromChain: 1,
  toChain: 42161,
});

// Or get multiple routes for comparison
const routes = await client.getRoutes({
  fromChain: 1,
  fromToken: "0x0000000000000000000000000000000000000000",
  fromAmount: "1000000000000000000",
  toChain: 42161,
  toToken: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
  fromAddress: "0xYourAddress",
});
```

### Balances

```typescript theme={"system"}
const balances = await client.getBalances({
  address: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
  chainIds: [1, 42161, 137],  // optional — restrict EVM coverage
});

console.log(
  `Total: $${balances.totalBalanceUSD} across ${Object.keys(balances.balances).length} chains`,
);
```

`getBalances` auto-detects the address ecosystem (EVM, Solana, Bitcoin, NEAR, Sui, Tron) and returns priced holdings plus dust classification.

### NEAR Intents deposits

For non-EVM destinations, `execute` returns a deposit address. After the user sends funds:

```typescript theme={"system"}
// Tell the backend you submitted the deposit
await client.submitDeposit({
  depositAddress: exec.depositAddress,
  txHash: "depositTxHash",
});

// Poll deposit status
const status = await client.getDepositStatus({
  depositAddress: exec.depositAddress,
});
```

### Webhooks

```typescript theme={"system"}
const created = await client.createWebhook({
  url: "https://yourapp.com/webhooks",
  events: ["swap.completed", "swap.failed", "onramp.completed"],
});
console.log("Webhook secret (store it):", created.secret);

const webhooks = await client.listWebhooks();

await client.deleteWebhook("whk_abc123");
```

Verify incoming webhook deliveries:

```typescript theme={"system"}
import { verifyWebhookSignature } from "@hypermid/sdk";

const ok = verifyWebhookSignature({
  body: rawRequestBody,
  signature: req.headers["x-hypermid-signature"],
  secret: process.env.HYPERMID_WEBHOOK_SECRET,
});
if (!ok) return new Response("invalid signature", { status: 401 });
```

### Fiat on-ramp (RampNow)

```typescript theme={"system"}
const config = await client.getOnrampConfig();
const assets = await client.getOnrampAssets({ country: "US" });

const quote = await client.getOnrampQuote({
  fiatCurrency: "USD",
  cryptoAsset: "ETH",
  chainId: 1,
  fiatAmount: 100,
  paymentMethod: "credit_card",
  walletAddress: "0xYourAddress",
});

const checkout = await client.createOnrampCheckout({
  fiatCurrency: "USD",
  cryptoAsset: "ETH",
  chainId: 1,
  fiatAmount: 100,
  paymentMethod: "credit_card",
  walletAddress: "0xYourAddress",
  redirectUrl: "https://yourapp.com/callback",
});
console.log("Send user to:", checkout.checkoutUrl);

const orderStatus = await client.getOnrampStatus("ord_abc123");
```

### Partner endpoints (require API key)

```typescript theme={"system"}
const info  = await client.getPartnerInfo();
const stats = await client.getPartnerStats({ period: "30d" });
const txns  = await client.getPartnerTransactions({ page: 1, limit: 50 });
```

### SuperSwap inbound receiver

For SuperSwap V2 inbound deposits (PulseChain-side outputs):

```typescript theme={"system"}
const res = await client.registerInboundReceiver({
  txHash: "0xDepositTxHash",
  fromAddress: "0xSender",
  toAddress: "0xPulseChainRecipient",
  outputToken: "0xOutputTokenOnPulse",
  destinationDomain: 369,
  signature: "0xEIP712Signature",
});
```

### Telemetry

```typescript theme={"system"}
await client.recordSwapEvent({
  eventType: "swap.viewed",
  metadata: { sessionId, walletConnected: true },
});

const ping = await client.ping();
```

## ExecuteSwap helper

For the full swap lifecycle in one call, use `executeSwap` (a top-level function, not a class method). It runs `execute`, calls back to you for signing, then polls until completion:

```typescript theme={"system"}
import { Hypermid, executeSwap } from "@hypermid/sdk";

const client = new Hypermid();

const result = await executeSwap(
  client,
  {
    fromChain: 1,
    fromToken: "0x0000000000000000000000000000000000000000",
    fromAmount: "1000000000000000000",
    toChain: 42161,
    toToken: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
    fromAddress: "0xYourAddress",
    toAddress: "0xYourAddress",
  },
  {
    onStatusChange: (update) => console.log("Status:", update.status),
    onTransactionRequest: async (resp) => {
      // Sign and broadcast resp.transactionRequest via your wallet.
      // Return the on-chain tx hash.
      return await wallet.sendTransaction(resp.transactionRequest);
    },
    onDepositRequired: async (resp) => {
      // Send tokens to resp.depositAddress.
      // Return the on-chain tx hash.
      return await wallet.send(resp.depositAddress, resp.expectedAmount);
    },
  },
  { pollInterval: 5_000, pollTimeout: 600_000 },
);
```

If you only need polling, use the wait helpers directly:

```typescript theme={"system"}
import { waitForDepositCompletion, waitForLiFiCompletion } from "@hypermid/sdk";

const result = await waitForDepositCompletion(client, { depositAddress }, {
  pollInterval: 5_000,
  pollTimeout: 600_000,
});

const result = await waitForLiFiCompletion(client, { txHash, fromChain, toChain }, {
  pollInterval: 10_000,
  pollTimeout: 1_800_000,
});
```

For dry-running quotes without signing, use `quoteAndPrepare(client, params)`.

## Type guards

Use these to branch on the provider/mode of an `ExecuteResponse` without checking response shape manually:

```typescript theme={"system"}
import {
  isLiFiRoute,
  isNearIntentsRoute,
  isSuperSwapRoute,
  isManualDeposit,
  isWalletDeposit,
} from "@hypermid/sdk";

const exec = await client.execute({ /* ... */ });

if (isLiFiRoute(exec)) {
  // EVM swap via LI.FI — sign exec.transactionRequest
}
if (isNearIntentsRoute(exec)) {
  // NEAR Intents — send tokens to exec.depositAddress
}
if (isSuperSwapRoute(exec)) {
  // SuperSwap (PulseChain-native) route
}
if (isWalletDeposit(exec)) {
  // Wallet-style deposit (sign + broadcast)
}
if (isManualDeposit(exec)) {
  // Manual deposit (show address + memo to user)
}
```

And on statuses:

```typescript theme={"system"}
import {
  isLiFiStatusTerminal,
  isNIStatusTerminal,
  isDepositSuccess,
  isDepositRefunded,
  isDepositFailed,
} from "@hypermid/sdk";

if (isLiFiStatusTerminal(status.status))      { /* done or failed */ }
if (isNIStatusTerminal(depositStatus.status)) { /* done or failed */ }
if (isDepositSuccess(depositStatus))          { /* user got funds */ }
if (isDepositRefunded(depositStatus))         { /* refunded */ }
if (isDepositFailed(depositStatus))           { /* failed */ }
```

Chain helpers:

```typescript theme={"system"}
import { isNearIntentsChain, supportsWalletDeposit, ChainId } from "@hypermid/sdk";

isNearIntentsChain(ChainId.NEAR);     // true
supportsWalletDeposit(ChainId.ETH);   // true (user can sign on this chain)
```

For the full chain registry (`CHAIN_REGISTRY`, `resolveChain`, `toLifiChainId`, etc.), see the [chains module exports](https://github.com/Hypermid/hypermid-sdk/blob/main/src/chain-registry.ts).

## Error handling

```typescript theme={"system"}
import {
  HypermidError,
  HypermidTimeoutError,
  HypermidNetworkError,
} from "@hypermid/sdk";

try {
  const quote = await client.getQuote({ /* ... */ });
} catch (err) {
  if (err instanceof HypermidError) {
    console.error(`API error ${err.status}: [${err.code}] ${err.message}`);
    console.error("Request ID:", err.requestId);
  } else if (err instanceof HypermidTimeoutError) {
    console.error(`Request timed out after ${err.timeoutMs}ms`);
  } else if (err instanceof HypermidNetworkError) {
    console.error("Network error:", err.cause);
  } else {
    throw err;
  }
}
```

| Class                  | Raised when                                          |
| ---------------------- | ---------------------------------------------------- |
| `HypermidError`        | API returned a non-2xx error response                |
| `HypermidTimeoutError` | A single request exceeded `config.timeout`           |
| `HypermidNetworkError` | Transport-level failure (DNS, TLS, connection reset) |

## TypeScript types

All request/response types are exported from the package root:

```typescript theme={"system"}
import type {
  HypermidConfig,
  ApiResponse,
  ApiMeta,
  RateLimitInfo,

  // Chains / tokens
  Chain,
  ChainsResponse,
  Token,
  TokensParams,
  TokensResponse,

  // Quote / execute / status
  QuoteParams,
  QuoteResponse,
  ExecuteParams,
  ExecuteResponse,
  LiFiExecuteResponse,
  NIExecuteResponse,
  SuperSwapExecuteResponse,
  TransactionRequest,
  StatusParams,
  LiFiStatusParams,
  NIStatusParams,
  StatusResponse,

  // Balances
  BalancesParams,
  BalancesResponse,
  TokenBalance,

  // Webhooks
  WebhookEvent,
  CreateWebhookParams,
  WebhookCreated,
  WebhooksListResponse,

  // On-ramp
  OnrampQuoteParams,
  OnrampCheckoutParams,
  OnrampCheckoutResponse,
  OnrampStatusResponse,

  // SuperSwap
  InboundReceiverParams,
  InboundReceiverResponse,
} from "@hypermid/sdk";
```

## End-to-end example

A complete EVM swap from Ethereum to Arbitrum, anonymous tier:

```typescript theme={"system"}
import { Hypermid } from "@hypermid/sdk";

const client = new Hypermid();

const quote = await client.getQuote({
  fromChain: 1,
  fromToken: "0x0000000000000000000000000000000000000000",
  fromAmount: "1000000000000000000",
  toChain: 42161,
  toToken: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
  fromAddress: "0xYourAddress",
});
console.log("Provider:", quote.provider, "feeBps:", quote.feeBps);

const exec = await client.execute({
  fromChain: 1,
  fromToken: "0x0000000000000000000000000000000000000000",
  fromAmount: "1000000000000000000",
  toChain: 42161,
  toToken: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
  fromAddress: "0xYourAddress",
  toAddress: "0xYourAddress",
});

if ("transactionRequest" in exec) {
  console.log("Sign and broadcast tx to:", exec.transactionRequest.to);
}
```
