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 NameDescriptionRequired
projectIdProject ID issued by NexauthRequired
sessionIdUser's game character identification IDRequired
accessTokenIn-game user authentication token
Used when RAMP B/E requests game asset inquiry from the developer's server.
Required
networkMainnet, Testnet distinctionRequired
langLanguage selection (zh, en, zh-Hant)Optional
platformwebOptional

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 NameDescription
X-Dapp-AuthorizationaccessToken generated by the developer's server.
Uses the accessToken value added to the Query when loading RAMP F/E.
X-Dapp-SessionIDUser'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 NameTypeDescription
successbooleanRequest success status
errorCodestringError code (null on success)
dataobjectResponse data (null on failure)
data.v1objectAPI version 1 data
data.v1.player_idstringUser character unique ID
data.v1.namestringUser character name
data.v1.wallet_addressstringUser wallet address
data.v1.serverstringUser character's connected server information
data.v1.assetsarrayList of user's game asset holdings
data.v1.assets[].idstringGame asset unique identifier

Must input the game asset ID set in the RAMP console.
data.v1.assets[].balancestringUser'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 NameDescription
X-Dapp-AuthorizationaccessToken generated by the developer's server.
Uses the accessToken value added to the Query when loading RAMP F/E.
X-Dapp-SessionIDUser'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 NameTypeDescription
user_sigstringData signed through CROSSx by the user for token issuance/burning.
user_addressstringUser's CROSSx address
project_idstringProject ID created in RAMP console
digeststringHash digest of transaction data
This is the original text to be signed using the Validator key generated by the developer.
uuidstringRequest unique identifier
intentobjectToken issuance/burning information
intent.methodstringExecution method (mint, burn)
intent.typestringTransaction type (assemble, disassemble)
  • assemble : Token issuance
  • disassemble : Token burning
intent.fromarraySource asset information list
intent.from[].typestringAsset type (asset, ERC20)
  • asset : Game asset
  • ERC20 : Game token
intent.from[].idstringGame asset ID registered in CROSS-RAMP Console.
intent.from[].amountnumberGame asset quantity used for token issuance
intent.toarrayTarget asset information list
intent.to[].typestringAsset type (ERC20, NFT)
intent.to[].idstringToken contract address
intent.to[].amountnumberToken quantity to be issued
intent.target_candidateobjectTarget candidate information (additional options)

Response Sample

Success Response (200 OK)

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

Response Field Description

Field NameTypeDescription
successbooleanRequest success status
errorCodestringError code (null on success)
dataobjectResponse data (null on failure)
data.userSigstringData signed by the user through CROSSx for token issuance/burning.
data.validatorSigstringData 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,
       };
     }
   }