API

Integrate the Relayer REST API to easily build with or offer uAssets in your dApp.

The Relayer is a convenience service responsible for facilitating communication between users, and a network of Universal merchants. Integrating this API allows you to tap into the network of merchants to enable buying or selling uAssets in your application.

Please reach out to us via Partnerships to request an API key.

Basics

Base URL: https://relayer.universalassets.xyz/api

Authorization: Include an Authorization header with Bearer <YOUR_API_KEY> as the value.

Types
  • TokenName: BTC, SOL, XRP, DOGE, DOT, NEAR, LTC, ADA, BCH, ALGO

  • PairTokenName: USDC

  • BlockchainName: BASE

  • Quote

      type: "BUY" | "SELL";
      token: TokenName;
      token_amount: string; // wei
      pair_token: PairTokenName;
      slippage_bips: number; // 0-100
      blockchain: BlockchainName;
      deadline: string; // unix epoch
      pair_token_amount: string; // wei
      id: string;
      user_address: string; // 0x..
      merchant_address: string; // 0x..
      gas_fee_nominal: string; // wei
      gas_fee_dollars: number; // e.g. $1.23 = 1.23
      relayer_nonce: number;
      merchant_id: string; 
Requesting a Quote

POST /quote

Receive a quote for a uAsset order.

Body

{
  type: "BUY" | "SELL";
  token: TokenName;
  token_amount?: string;
  pair_token_amount?: string;
  pair_token: PairTokenName;
  slippage_bips: number;
  blockchain: BlockchainName;
  user_address: string;
}

Response 200

{
  ...Quote
}
Signing a Quote

The user must sign the UniswapX's Dutch Order compatible EIP-712 data for the received quote in order to submit the order.

Example:

import { DutchOrderBuilder } from "@uniswap/uniswapx-sdk";
import { BigNumber } from "ethers5"; // ethers v5

type TokenName = "BTC" | "SOL" | "XRP" | "DOGE" | "DOT" | "NEAR" | "LTC" | "ADA" | "BCH" | "ALGO";
type PairTokenName = "USDC";
type BlockchainName = "BASE";

interface Quote {
  type: "BUY" | "SELL";
  token: TokenName;
  token_amount: bigint;
  pair_token: PairTokenName;
  slippage_bips: number;
  blockchain: BlockchainName;
  deadline: bigint;
  pair_token_amount: bigint;
  id: string;
  user_address: string;
  merchant_address: string;
  gas_fee_nominal: bigint;
  gas_fee_dollars: number;
  relayer_nonce: number;
}

const CHAIN_ID: number = <CHAIN_ID>;
const REACTOR_ADDRESS: string = <REACTOR_ADDRESS>;
const PERMIT2_ADDRESS: string = <PERMIT2_ADDRESS>;

async function signTypedQuote(quote: Quote) {
  const builder = new DutchOrderBuilder(
    CHAIN_ID,
    REACTOR_ADDRESS,
    PERMIT2_ADDRESS
  );
  const TOKEN_ADDRESS = <TOKEN_ADDRESS>;
  const PAIR_TOKEN_ADDRESS = <PAIR_TOKEN_ADDRESS>;

  const order = builder
    .deadline(Number(quote.deadline))
    .decayEndTime(Number(quote.deadline))
    .decayStartTime(Number(quote.deadline) - 100)
    .nonce(BigNumber.from(quote.relayer_nonce))
    .input({
      token: quote.type == "BUY" ? PAIR_TOKEN_ADDRESS : TOKEN_ADDRESS,
      startAmount:
        quote.type == "BUY"
          ? BigNumber.from(quote.pair_token_amount.toString())
          : BigNumber.from(quote.token_amount.toString()),
      endAmount:
        quote.type == "BUY"
          ? BigNumber.from(quote.pair_token_amount.toString())
          : BigNumber.from(quote.token_amount.toString()),
    })
    .output({
      token: quote.type == "BUY" ? TOKEN_ADDRESS : PAIR_TOKEN_ADDRESS,
      startAmount:
        quote.type == "BUY"
          ? BigNumber.from(quote.token_amount.toString())
          : BigNumber.from(quote.pair_token_amount.toString()),
      endAmount:
        quote.type == "BUY"
          ? BigNumber.from(quote.token_amount.toString())
          : BigNumber.from(quote.pair_token_amount.toString()),
      recipient: quote.user_address,
    })
    .swapper(quote.user_address)
    .exclusiveFiller(quote.merchant_address, BigNumber.from(0))
    .build();

  const { domain, types, values } = order.permitData();
  const primaryType: "PermitWitnessTransferFrom" = "PermitWitnessTransferFrom";
  const typedData = {
    domain,
    types,
    primaryType,
    message: values,
  };
  const signer = <SIGNER>;
  const signature = await signer.signTypedData(typedData);
  return signature;
}
Submitting an Order

POST /order

Submits the user-signed order to be fulfilled.

Body

{
 ...Quote, 
 "signature": string, // Quote signed by the user
}

Response

{
  "transaction_hash": string // Transaction hash of the fulfillment
}

Last updated