Deep dive into API concepts

Deep dive into API concepts

This page provides information on how to generate the following API headers and params:

Header / Param
Used in:
  • IMX-Timestamp

  • IMX-Signature

  • createCollection

  • updateCollection

  • addMetadataSchemaToCollection

  • updateMetadataSchemaByName

  • createProject

  • x-imx-eth-signature

  • Get a list of metadata refreshes

  • Requesting a metadata refresh

  • Get metadata refresh results

  • Get metadata refresh errors

  • createOrder

  • cancelOrder

  • createTransferV1

  • createTransfer

  • createWithdrawal

  • createTrade

  • createExchangeTransfer

  • stark_signature

  • createOrder

  • cancelOrder

  • createTransferV1

  • createTransfer

  • createWithdrawal

  • createTrade

  • createExchangeTransfer

  • auth_signature

  • mintTokens

UPGRADE YOUR SDK TO AVOID GENERATING THESE HEADERS

If you are using the Core SDK or the JS SDK, you will generally not need to provide these headers as long as you upgrade to the following versions:

  • Core SDK: >= 1.0.0-beta.2

  • JS SDK: >= 1.17

IMX-Timestamp (string)

The IMX-Timestamp can be generated by this example Javascript function:

Javascript

const timestamp = Math.floor(Date.now() / 1000).toString();

x-imx-eth-address (string)

This is the public Ethereum address of the user executing the transaction.

IMX-Signature (string), x-imx-eth-signature (string), auth_signature (string)

💡STEPS:

  • Get Ethereum signer

  • Get message to be signed

  • Serialize the signature

1. Get Ethereum signer

Signers are abstractions of user accounts that can be used to sign transactions. A user's private key is required to generate them. Read more here.

In order to generate the IMX-Signature and x-imx-eth-signature headers, we need an Ethereum signer for the user.

See here on how to generate these signers.

2. Get message

Different messages are required by the different attributes:

Param
Message

IMX-Signature

IMX-Timestamp

x-imx-eth-signature

The message to be signed depends on each transaction. Typically, it contains information about the transaction that requires the user signature. The messages required for the following endpoints are:

  • Get a list of metadata refreshes - expects a message of IMX timestamp

  • Requesting a metadata refresh - expects a message of IMX timestamp

  • Get metadata refresh results - expects a message of IMX timestamp

  • Get metadata refresh errors - expects a message of IMX timestamp

  • createOrder - expects a message of getSignableOrder

  • cancelOrder - expects a message of getSignableOrder

  • createTransferV1 - expects a message of getSignableTransfer

  • createTransfer - expects a message of getSignableTransfer

  • createWithdrawal - expects a message of getSignableWithdrawal

  • createTrade - expects a message of getSignableTrade

  • createExchangeTransfer - expects a message of getExchangeSignableTransfer

auth_signature

See below

How to get the message for the auth_signature?

The auth_signature param is used in the mintTokens request.

  1. Put together an object like the following Javascript example:

Javascript

const object = {
  contract_address: "string",
  royalties: [ // Optional
    {
      recipient: "string",
      percentage: "string",
    },
  ]
  users: [
    {
      ether_key: "string",
      tokens: [
        {
          id: "string",
          blueprint: "string",
          royalties: [ // Optional
            {
              recipient: "string",
              percentage: "string",
            },
          ]
        }
      ]
    }
  ],
};
  1. Create a hash of that object that becomes the message to be signed to get the auth_signature:

Javascript

import { keccak256 } from '@ethersproject/keccak256';
import { toUtf8Bytes } from '@ethersproject/strings';

const message = keccak256(toUtf8Bytes(JSON.stringify(object)));

3. Serialize the signature

Implement a function using the signer and message obtained in the previous steps like the following Typescript example:

Typescript

export async function signRaw(
  message: string,
  signer: Signer
): Promise<string> {
  const signature = deserializeSignature(await signer.signMessage(message));
  return serializeEthSignature(signature);
}

Where deserializeSignature() looks like:

Typescript

import BN from 'bn.js'; // https://www.npmjs.com/package/bn.js
import * as encUtils from 'enc-utils'; // https://www.npmjs.com/package/enc-utils

type SignatureOptions = {
  r: BN;
  s: BN;
  recoveryParam: number | null | undefined;
};

function importRecoveryParam(v: string): number | undefined {
  return v.trim()
    ? new BN(v, 16).cmp(new BN(27)) !== -1
      ? new BN(v, 16).sub(new BN(27)).toNumber()
      : new BN(v, 16).toNumber()
    : undefined;
}

function deserializeSignature(sig: string, size = 64): SignatureOptions {
  sig = encUtils.removeHexPrefix(sig);
  return {
    r: new BN(sig.substring(0, size), 'hex'),
    s: new BN(sig.substring(size, size * 2), 'hex'),
    recoveryParam: importRecoveryParam(sig.substring(size * 2, size * 2 + 2)),
  };
}

and serializeEthSignature() looks like:

Typescript

function serializeEthSignature(sig: SignatureOptions): string {
  // This is because golang appends a recovery param
  // https://github.com/ethers-io/ethers.js/issues/823
  return encUtils.addHexPrefix(
    encUtils.padLeft(sig.r.toString(16), 64) +
      encUtils.padLeft(sig.s.toString(16), 64) +
      encUtils.padLeft(sig.recoveryParam?.toString(16) || '', 2)
  );
}

stark_signature (string)

The stark_signature is required in the request body params of certain endpoints. It is obtained by using a Stark signer to sign the payload_hash produced in the response of the following corresponding endpoints:

Action

Endpoint(s) requiring stark_signature

Endpoint(s) providing payload_hash to be signed

Create orders

createOrder

getSignableOrderV1 getSignableOrder

Cancel orders

cancelOrder

getSignableCancelOrder

Create transfers

createTransfer createTransferV1

getSignableTransfer getSignableTransferV1

Create withdrawals

createWithdrawal

getSignableWithdrawal

Create trades

createTrade

getSignableTrade

Create exchange transfers

createExchangeTransfer

getExchangeSignableTransfer

💡STEPS:

  • Get message to be signed

  • Generate StarkSigner and sign the message

1. Get message to be signed

Call the corresponding endpoint to the one requiring the stark_signature that gets the payload_hash to be signed (ie. the endpoint that provides the payload_hash for the createWithdrawal endpoint is the getSignableWithdrawal endpoint).

2. Generate Stark signer and sign the message

Use the Core SDK to generate the Stark signers. See instructions here.

Use the Stark signer to sign the payload_hash in Step 1:

  • Typescript Core SDK

  • Kotlin (JVM) Core SDK

  • Swift Core SDK

  • Golang Core SDK

const starkSignature = await starkSigner.signMessage(payloadHash);

Last updated