End point APIs

Description of End point APIs required for project setup

APIs

Description of End point APIs required for project setup.

Access Links

Description of URLs for loading RAMP F/E in Webview (mobile) and system browser (desktop) environments.
When creating a project, a RAMP access URL including the projectID is generated.

https://ramp.crosstoken.io/catalog?projectId={{projectID}}&sessionId={{sessionId}}&accessToken={{accessToken}}&platform=web&network=testnet


Parameter Description

Parameter Name

Description

Required

projectId

Project ID issued by Nexauth

Required

sessionId

User's game character identification ID

Required

accessToken

In-game user authentication token Used when RAMP B/E requests game asset inquiry from the developer's server.

Required

network

Mainnet, Testnet distinction

Required

lang

Language selection (zh, en, zh-Hant)

Optional

platform

web

Optional


User's Game Asset Inquiry API

API implementation is required to query the game assets owned by users for token issuance. The queried game assets are displayed on the RAMP F/E page.

When RAMP B/E calls the game asset inquiry API, it includes the accessToken and sessionId values from the query parameters of the RAMP F/E URL loaded for token issuance or burning in the game in the Request Header.
Therefore, the developer's server must verify the accessToken and return an appropriate response based on the verification result.

Requests will be made to the Get Assets endpoint set in the CROSS-RAMP Console project.


Request / Response

RAMP B/E to developer-implemented endpoint

Request Sample

GET /api/assets
Host: https://your-server.com
Content-Type: application/json
X-Dapp-Authorization: Bearer {{accessToken}}
X-Dapp-SessionID: {{sessionId}}

Request Header Field Description

Field Name

Description

X-Dapp-Authorization

accessToken generated by the developer's server. Uses the accessToken value added to the Query when loading RAMP F/E.

X-Dapp-SessionID

User's character identification ID managed by the developer. Uses the sessionId value added to the Query when loading RAMP F/E.


Response Sample

Success Response (200 OK)

{
  "success": true,
  "errorCode": null,
  "data": {
    "v1": {
      "player_id": "player_id_allen",
      "name": "name_allen",
      "wallet_address": "0x62c5a30a90d3c3032dfb0fe4ea05e9c454c56707",
      "server": "test",
      "assets": [
        {
          "id": "item_gold",
          "balance": "1000.123"
        }
      ]
    }
  }
}

Response Field Description

Field Name

Type

Description

success

boolean

Request success status

errorCode

string

Error code (null on success)

data

object

Response data (null on failure)

data.v1

object

API version 1 data

data.v1.player_id

string

User character unique ID

data.v1.name

string

User character name

data.v1.wallet_address

string

User wallet address

data.v1.server

string

User character's connected server information

data.v1.assets

array

List of user's game asset holdings

data.v1.assets[].id

string

Game asset unique identifier
Must input the game asset ID set in the RAMP console.

data.v1.assets[].balance

string

User's game asset holding quantity
Must input the user's asset holding quantity in the game.




User's Signature Verification Inquiry API

During the token issuance process, API implementation is required to verify whether the user's signature value matches the transaction request data sent by the developer.

For data integrity verification, requests are made with HMAC-SHA256 signed data generated in the CROSS-RAMP Console included in the Request Header.
Therefore, the developer's server must perform integrity verification using the HMAC value from the CROSS-RAMP Console.


After verifying whether the user's token issuance/burning request violates developer policies (authentication, game asset quantity, etc.), a response is required.

Requests will be made to the Validate Order endpoint set in the CROSS-RAMP Console project.


Request / Response

Request Sample

POST /api/validate
Host: https://your-server.com
Content-Type: application/json
x-dapp-authorization: Bearer {{accessToken}}
x-dapp-sessionid: {{sessionId}}
x-hmac-signature: {{hmac_signature}}

{
  "user_sig": "0x58ea88cc20a571d2bc4f4a7ab687158e1924887c005a8a2ccce9a7c8f669adbb222932f9e760b923b6f359870169d58a171d47516ee71167313d5068dbd84c631c",
  "user_address": "0x6de346a7333d97fe0d39a49178ac65918c257b28",
  "project_id": "3a4----------------------2d7",
  "digest": "0x6d196d0881bb8e322c194fbf53518089b240055134044491a78b14920098e395",
  "uuid": "86b555dd-e622-43fe-a799-c5c4536dd8c6",
  "intent": {
    "method": "mint",
    "type": "assemble",
    "from": [
      {
        "type": "asset",
        "id": "item_gold",
        "amount": 100
      }
    ],
    "to": [
      {
        "type": "ERC20",
        "id": "0x14f6f0057274c3519d6258EB66F5d01D79821D81",
        "amount": 1
      }
    ],
    "target_candidate": {}
  }
}
POST /api/validate
Host: https://your-server.com
Content-Type: application/json
x-dapp-authorization: Bearer {{accessToken}}
x-dapp-sessionid: {{sessionId}}
x-hmac-signature: {{hmac_signature}}

{
  "user_sig": "0xb1378a978b5e77d750c44d4b9bdf4d883d2e2bad8e09c8928e8d83176359cc9376a959c3576c82f2214c9fece66c73417669bf667734ec8f94880885c5d1b82a1c",
  "user_address": "0x6de346a7333d97fe0d39a49178ac65918c257b28",
  "project_id": "3a4f5838f7cdfe31873a43ca021a92d7",
  "digest": "0x7bd721630a8c7e6b1c1050934fc3bf69cadaef0253c46f92f1b03242c5f2e733",
  "uuid": "d7360515-8547-427e-acb5-6556c8376fd4",
  "intent": {
    "method": "burn-permit",
    "type": "disassemble",
    "from": [
      {
        "type": "ERC20",
        "id": "0x14f6f0057274c3519d6258EB66F5d01D79821D81",
        "amount": 1
      }
    ],
    "to": [
      {
        "type": "asset",
        "id": "item_gold",
        "amount": 50
      }
    ],
    "target_candidate": {}
  }
}

Request Header Field Description

Field Name

Description

X-Dapp-Authorization

accessToken generated by the developer's server. Uses the accessToken value added to the Query when loading RAMP F/E.

X-Dapp-SessionID

User's character identification ID managed by the developer. Uses the sessionId value added to the Query when loading RAMP F/E.


Request Body Field Description

Field Name

Type

Description

user_sig

string

Data signed through CROSSx by the user for token issuance/burning.

user_address

string

User's CROSSx address

project_id

string

Project ID created in RAMP console

digest

string

Hash digest of transaction data This is the original text to be signed using the Validator key generated by the developer.

uuid

string

Request unique identifier

intent

object

Token issuance/burning information

intent.method

string

Execution method (mint, burn)

intent.type

string

Transaction type (assemble, disassemble)

  • assemble : Token issuance
  • disassemble : Token burning

intent.from

array

Source asset information list

intent.from[].type

string

Asset type (asset, ERC20)

  • asset : Game asset
  • ERC20 : Game token

intent.from[].id

string

Game asset ID registered in CROSS-RAMP Console.

intent.from[].amount

number

Game asset quantity used for token issuance

intent.to

array

Target asset information list

intent.to[].type

string

Asset type (ERC20, NFT)

intent.to[].id

string

Token contract address

intent.to[].amount

number

Token quantity to be issued

intent.target_candidate

object

Target candidate information (additional options)


Response Sample

Success Response (200 OK)

{
  "success": true,
  "errorCode": null,
  "data": {
    "userSig": "0x58ea88cc20a571d2bc4f4a7ab687158e1924887c005a8a2ccce9a7c8f669adbb222932f9e760b923b6f359870169d58a171d47516ee71167313d5068dbd84c631c",
    "validatorSig": "0xfd7c12023378170c615bdd63be3e7aa195ff98b42fe84dad34348017fc1050db157e077dd5053328040b476479edebfe5d773bb8602de6bc088951de7b597fd31b"
  }
}

Response Field Description

Field Name

Type

Description

success

boolean

Request success status

errorCode

string

Error code (null on success)

data

object

Response data (null on failure)

data.userSig

string

Data signed by the user through CROSSx for token issuance/burning.

data.validatorSig

string

Data signed with ECDSA using the Validator key generated by the developer.
The Validator key address must be registered in the CROSS-RAMP Console.



User's Token Issuance/Burning Result API

Delivers blockchain transaction results for user's token issuance/burning requests to the game server via Webhook.

Transaction results are delivered to the endpoint registered in the CROSS-RAMP Console, and the developer's server must respond with HTTP status 200 after receiving the results.


If RAMP B/E does not receive a response or receives an HTTP 500 code, RAMP B/E will retry sending.
For proper processing, HTTP 200 code must be responded.

📘

Retry Information

After the first Webhook delivery attempt, up to 20 retries will be attempted for 12 hours.

  • 2 attempts at 5-minute intervals
  • 7 attempts at 15-minute intervals
  • 10 attempts at 60-minute intervals

Webhook request / response

If receipt.status is not 0x1, the blockchain network transaction request has failed, so game assets must be restored.

Request Sample

POST /api/result
Host: https://your-server.com
Content-Type: application/json
x-dapp-authorization: Bearer {{accessToken}}
x-dapp-sessionid: {{sessionId}}
x-hmac-signature: {{hmac_signature}}

{
    "session_id": "{{dappSessionId}}",
    "uuid": "b6d3976b-36b1-48d6-974b-da1471aa94de",
    "tx_hash": "0x17def972330f874dcfbc8099ada5da777c4273e3c0aa6faebb103e09615f5784",
    "receipt": {
        "type": "0x2",
        "root": "0x",
        "status": "0x1",
        "cumulativeGasUsed": "0x1f531",
        "logsBloom": "0x00000000080040000000200a00000000000000000000000000000000000000000000010000000000002000100000000000000000000000000000000000000000000000100820000400000008000000000000000000000000000000000000110000040000020000000000000000000800000040000000000000000010000000000000000008000000000000080000000000000000000000000000000000100000000000000000000000000400000002000000000000000000000000000000000000000002000000000000000000020800000002000000000000000000000020400000000000000000000200000000000000000000000000000800000000000000",
        "logs": [
            {
                "address": "0x14f6f0057274c3519d6258eb66f5d01d79821d81",
                "topics": [
                    "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
                    "0x0000000000000000000000000000000000000000000000000000000000000000",
                    "0x0000000000000000000000006de346a7333d97fe0d39a49178ac65918c257b28"
                ],
                "data": "0x0000000000000000000000000000000000000000000000003e73362871420000",
                "blockNumber": "0xaa3d8f",
                "transactionHash": "0x17def972330f874dcfbc8099ada5da777c4273e3c0aa6faebb103e09615f5784",
                "transactionIndex": "0x0",
                "blockHash": "0x5b62d0387e2f37ea7c76cde2b08b1a36648aca277c76152fdf0da59e6ee63733",
                "blockTimestamp": 0,
                "logIndex": "0x0",
                "removed": false
            },
            {
                "address": "0x7189d67b9ded72e9f1dcfce1c23ea3af418f4a57",
                "topics": [
                    "0x9612604afba70e4cf03261d7d86ca03d08911d9887aa41621dea929e34cfd7b1",
                    "0x3361346635383338663763646665333138373361343363613032316139326437",
                    "0x171ac396aacce04a8c32ecd6322f384796a2a5e15224316a78c9358a8cea809b",
                    "0x0000000000000000000000006de346a7333d97fe0d39a49178ac65918c257b28"
                ],
                "data": "0x00000000000000000000000014f6f0057274c3519d6258eb66f5d01d79821d810000000000000000000000000000000000000000000000004563918244f40000",
                "blockNumber": "0xaa3d8f",
                "transactionHash": "0x17def972330f874dcfbc8099ada5da777c4273e3c0aa6faebb103e09615f5784",
                "transactionIndex": "0x0",
                "blockHash": "0x5b62d0387e2f37ea7c76cde2b08b1a36648aca277c76152fdf0da59e6ee63733",
                "blockTimestamp": 0,
                "logIndex": "0x2",
                "removed": false
            }
        ],
        "transactionHash": "0x17def972330f874dcfbc8099ada5da777c4273e3c0aa6faebb103e09615f5784",
        "contractAddress": "0x0000000000000000000000000000000000000000",
        "gasUsed": "0x1f531",
        "effectiveGasPrice": "0xee6b2800",
        "blockHash": "0x5b62d0387e2f37ea7c76cde2b08b1a36648aca277c76152fdf0da59e6ee63733",
        "blockNumber": "0xaa3d8f",
        "transactionIndex": "0x0"
    },
    "intent": {
        "method": "mint",
        "type": "assemble",
        "from": [
            {
                "type": "asset",
                "id": "item_gold_n",
                "amount": 500
            }
        ],
        "to": [
            {
                "type": "ERC20",
                "id": "0x14f6f0057274c3519d6258EB66F5d01D79821D81",
                "amount": 5
            }
        ],
        "target_candidate": {}
    }
}

Response Sample

POST /api/result
Host: https://your-server.com
Content-Type: application/json

{
  "success": true,
  "errorCode": null,
  "data": null
}

HMAC Signature and Validator Signature Samples

HMAC Signature Sample

const crypto = require('crypto');

function generateHmacSignature(payload, secretKey) {
  // Convert JSON data to string
  const dataString = JSON.stringify(payload);
  
  // Generate signature with HMAC-SHA256
  const hmac = crypto.createHmac('sha256', secretKey);
  hmac.update(dataString);
  const signature = hmac.digest('hex');
  
  return signature;
}

// Signature verification function
function verifyHmacSignature(payload, receivedSignature, secretKey) {
  const expectedSignature = generateHmacSignature(payload, secretKey);
  
  // Safe comparison to prevent timing attacks
  return crypto.timingSafeEqual(
    Buffer.from(expectedSignature, 'hex'),
    Buffer.from(receivedSignature, 'hex')
  );
}

// Usage example
const secretKey = 'your_secret_key_from_console';
const requestData = {
  sessionId: 'player_12345',
  assetId: 'gold_coin',
  amount: '100.50'
};

// Generate signature
const signature = generateHmacSignature(requestData, secretKey);
console.log('Generated signature:', signature);

// Verify signature
const isValid = verifyHmacSignature(requestData, signature, secretKey);
console.log('Signature valid:', isValid);

Validator Signature Sample

import { ethers } from "ethers";

/**
 * generateValidatorSignature
 * 
 * Signs the given digest using the validator's private key.
 * The digest must be a 32-byte hash (e.g. "0xabc123...").
 * 
 * @param {string} userSig - (optional) user's signature
 * @param {string} digest  - 32-byte digest to sign
 * @returns {Promise<{ success: boolean, signature?: string, error?: string }>}
 */
export async function generateValidatorSignature(userSig, digest) {
  try {
    // Load validator private key (from env or default)
    const privateKey =
      process.env.VALIDATOR_PRIVATE_KEY;

    // Create an Ethers.js Wallet instance
    const wallet = new ethers.Wallet(privateKey);

    // Convert digest (hex) to byte array
    const digestBytes = ethers.getBytes(digest);

    // Sign the digest (must be 32 bytes)
    const rawSignature = await wallet.signingKey.sign(digestBytes);

    // Serialize signature (r + s + v)
    const signature = ethers.Signature.from(rawSignature).serialized;

    // Return success response
    return {
      success: true,
      signature,
    };
  } catch (error) {
    console.error("Error generating validator signature:", error);

    // Return failure response
    return {
      success: false,
      error: error.message,
    };
  }
}

© 2025 NEXUS Co., Ltd. All Rights Reserved.