Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

omni-transfer TypeScript SDK

CI npm

Typed TypeScript client for the omni-transfer API — cross-chain swap and bridge infrastructure. Generated from the OpenAPI spec, so it always matches the live API surface.

npm install omni-transfer-sdk

Works in Node.js 20+ and modern browsers (fetch-based, ESM + CJS builds, full type declarations).


Client setup

import { createOmniTransferClient } from 'omni-transfer-sdk';

const client = createOmniTransferClient({
  baseUrl: 'https://api.example.com',
  apiKey: 'prefix.secret', // for swap / explorer endpoints
});

Prefer a global default? Call configureOmniTransfer({ baseUrl, apiKey }) once at startup and omit client from every call.


Swap: route → sign → execute → track

1. Get quotes

import { createRoute } from 'omni-transfer-sdk';

const route = await createRoute({
  client,
  body: {
    srcChainId: 'eip155:1',    // Ethereum mainnet (CAIP-2)
    dstChainId: 'eip155:8453', // Base
    srcToken: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', // USDC
    dstToken: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', // USDC on Base
    amountIn: '1000000',     // 1 USDC (6 decimals)
    sender: '0xYourAddress',
    recipient: '0xRecipient',
  },
  throwOnError: true,
});

const quote = route.data.quotes!.items![0]!;

quote.execution?.type tells you what to do next:

type What to do
evm_gasless Sign the EIP-712 digest, call executeQuote with signature
evm_deposit Broadcast the send tx, call lockDepositQuote — API auto-detects the deposit
solana_sponsored Sign the base64 message, call executeQuote with signature
btc_psbt Sign your inputs, call executeQuote with the signed tx as signature
deposit address Lock the quote, send BTC, call executeQuote with triggerTxHash

2. Sign & execute

EVM gasless

The relayer pays gas; you only sign a digest.

import { executeQuote, signEvmDigest } from 'omni-transfer-sdk';

const digest = quote.execution!.sign!.fields!['digest'] as string;
const signature = await signEvmDigest(digest, '0x<private-key>');

const exec = await executeQuote({
  client,
  body: { quoteId: quote.quoteId!, signature },
  throwOnError: true,
});

EVM deposit

Broadcast the transaction from your own wallet, then let auto-detection handle it or supply the hash yourself.

import { lockDepositQuote, executeQuote } from 'omni-transfer-sdk';

// 1. Lock the quote (activates the on-chain listener for 5 minutes)
await lockDepositQuote({
  client,
  path: { quoteId: quote.quoteId! },
  throwOnError: true,
});

// 2. Broadcast from your wallet using:
//    quote.execution!.send!.chainId  — chain
//    quote.execution!.send!.to       — destination
//    quote.execution!.send!.data     — calldata
//    quote.execution!.send!.value    — value in wei

// Option A — auto-detection (recommended): the API watches for the deposit
//             and starts execution automatically. No executeQuote call needed.

// Option B — supply the tx hash immediately after broadcasting:
const exec = await executeQuote({
  client,
  body: { quoteId: quote.quoteId!, triggerTxHash: '0x<your-tx-hash>' },
  throwOnError: true,
});

Solana sponsored

Fees are covered; you sign the serialized transaction message.

import { executeQuote, signSolanaMessage, solanaPrivateKeyFromBase58 } from 'omni-transfer-sdk';

const privKey = solanaPrivateKeyFromBase58('<base58-private-key>');
const message = quote.execution!.sign!.fields!['message'] as string; // base64
const signature = await signSolanaMessage(message, privKey);

const exec = await executeQuote({
  client,
  body: { quoteId: quote.quoteId!, signature },
  throwOnError: true,
});

Bitcoin PSBT

Sign your inputs with SIGHASH_SINGLE|ANYONECANPAY; the API appends the treasury leg and broadcasts.

import { executeQuote, signBtcUnsignedTx } from 'omni-transfer-sdk';

const fields = quote.execution!.sign!.fields as {
  unsignedTxHex: string;
  inputAmounts: number[];
  inputPkScripts: string[];
};
const signature = signBtcUnsignedTx(fields, '<WIF-key>');

const exec = await executeQuote({
  client,
  body: { quoteId: quote.quoteId!, signature },
  throwOnError: true,
});

Bitcoin deposit address

Send BTC to the deposit address returned in the route response, then report the tx hash.

import { lockDepositQuote, executeQuote } from 'omni-transfer-sdk';

// 1. Lock the quote
await lockDepositQuote({
  client,
  path: { quoteId: quote.quoteId! },
  throwOnError: true,
});

// 2. Send BTC to: route.data.depositAddress (from your wallet)

// 3. Execute with the broadcast tx hash
const exec = await executeQuote({
  client,
  body: { quoteId: quote.quoteId!, triggerTxHash: '<your-txid>' },
  throwOnError: true,
});

3. Track execution

import { getExecution } from 'omni-transfer-sdk';

// Poll until status is "completed" or "failed"
let status = await getExecution({
  client,
  path: { id: exec.data.executionId! },
  throwOnError: true,
});

while (status.data.status !== 'completed' && status.data.status !== 'failed') {
  await new Promise(r => setTimeout(r, 3000));
  status = await getExecution({ client, path: { id: exec.data.executionId! }, throwOnError: true });
}
console.log('final status:', status.data.status);

Get granular per-step progress (with live EVM confirmation counts):

import { getExecutionSteps } from 'omni-transfer-sdk';

const steps = await getExecutionSteps({
  client,
  path: { id: exec.data.executionId! },
  throwOnError: true,
});
for (const step of steps.data) {
  console.log(`[${step.status}] ${step.label} — tx: ${step.txHash}`);
}

Authentication (wallet login)

loginWithEvm runs the full challenge → EIP-191 sign → verify flow and sets the bearer token on the client automatically, so /v1/me calls authenticate without any extra wiring.

Accepts a raw private key or any viem account (privateKeyToAccount, mnemonicToAccount, hardware wallets, wallet adapters):

import { createOmniTransferClient, loginWithEvm, listApiKeys } from 'omni-transfer-sdk';
import { privateKeyToAccount } from 'viem/accounts';

const client = createOmniTransferClient({ baseUrl: 'https://api.example.com' });

// viem account:
const account = privateKeyToAccount('0x<private-key>');
await loginWithEvm(account, client);

// or raw private key string:
await loginWithEvm('0x<private-key>', client);

// All /v1/me calls are now authenticated:
const keys = await listApiKeys({ client, throwOnError: true });

You can also wire a pre-existing session token at construction time:

const client = createOmniTransferClient({
  baseUrl: 'https://api.example.com',
  sessionToken: 'existing-token',
});

Account management (/v1/me)

All endpoints require a session (see above).

List API keys

import { listApiKeys } from 'omni-transfer-sdk';

const { data: keys } = await listApiKeys({ client, throwOnError: true });
for (const k of keys) {
  console.log(k.keyPrefix, k.name, k.revokedAt ? '(revoked)' : '');
}

Create an API key

import { createApiKey } from 'omni-transfer-sdk';

const { data } = await createApiKey({
  client,
  body: {
    name: 'My integration',
    annotation: 'Used by my backend',
    partnerBps: 50, // 0.5% partner fee, up to root key's system fee
  },
  throwOnError: true,
});
// The full key is returned ONCE — store it immediately.
console.log('API key:', data.apiKey);

Store an encrypted blob on a key

import { updateApiKeyBlob } from 'omni-transfer-sdk';

await updateApiKeyBlob({
  client,
  path: { id: '<key-uuid>' },
  body: { encryptedBlob: '<client-encrypted payload>' },
  throwOnError: true,
});

Usage & revenue summaries (30d)

import { getUsageSummary, getRevenueSummary } from 'omni-transfer-sdk';

const { data: usage } = await getUsageSummary({ client, throwOnError: true });
console.log('tx count:', usage.txCount);

const { data: rev } = await getRevenueSummary({ client, throwOnError: true });
console.log('revenue:', rev.revenueUsd, 'USD');

Analytics

import { getCreatorAnalytics } from 'omni-transfer-sdk';

const { data } = await getCreatorAnalytics({
  client,
  query: { window: '30d' }, // '7d' (default) or '30d'
  throwOnError: true,
});
console.log(`success rate: ${data.txStats?.pctSuccess?.toFixed(1)}%`);

Explorer

No API key required.

Search by execution ID, tx hash, or wallet address

import { searchExplorerExecutions } from 'omni-transfer-sdk';

const { data } = await searchExplorerExecutions({
  client,
  query: { q: '0x<tx-hash-or-wallet>' },
  throwOnError: true,
});
if (data.execution) {
  console.log('found:', data.execution.executionId);
}

Execution details

import { getExplorerExecution } from 'omni-transfer-sdk';

const { data: ex } = await getExplorerExecution({
  client,
  path: { id: '<execution-id>' },
  throwOnError: true,
});
console.log(ex.status, ex.source?.token?.symbol, '→', ex.destination?.token?.symbol);

Error handling

Without throwOnError, calls return { data, error, response }:

const result = await createRoute({ client, body });
if (result.error) {
  // result.error is the typed error body, result.response.status is the HTTP code
  console.error(result.response.status, result.error.message);
} else {
  // result.data is the typed 200 response
}

With throwOnError: true, only the success type is returned — TypeScript narrows data accordingly.


Signing helpers reference

Helper Chain Purpose
signEvmDigest(digestHex, privKeyHex) EVM Sign a 32-byte execution digest (v = 27/28) — viem
personalSign(message, privKeyHex) EVM EIP-191 personal_sign (used internally by loginWithEvm)
signSolanaMessage(messageB64, privKey) Solana Sign raw transaction message bytes — @solana/kit
solanaPrivateKeyFromBase58(b58) Solana Decode a base58 64-byte keypair to Uint8Array
signBtcUnsignedTx(fields, wif) Bitcoin P2WPKH / P2SH-P2WPKH / legacy SIGHASH_SINGLE|ANYONECANPAY@scure/btc-signer
loginWithEvm(signer, client?) EVM Full challenge → sign → verify auth flow with automatic session population

All signing helpers are pure functions — no key material is transmitted. Outputs are verified byte-for-byte against the Go SDK with shared test vectors.


Changelog

See CHANGELOG.md.

Contributing

Source lives at github.com/omnes-tech/omni-transfer under sdk/typescript/. The client is generated from the API's OpenAPI spec — see the repo for development instructions.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages