Gas API (gas.cashmere.exchange)
Purpose
The Gas API prices cross-chain burns and returns ready-to-submit signatures for smart contract calls. It is stateless; all pricing data comes from Redis keys populated by internal daemons.
REST Endpoints
| Endpoint | Description |
|---|
GET /getEcdsaSig_native | Generate an ECDSA signature for EVM transfers (Transfer / TransferV2). |
GET /getEd25519Sig_native | Generate an Ed25519 signature for Solana, Aptos, or Sui flows. |
GET /tokenPrices | Fetch the latest token price cache (forwarded from Redis). |
GET /health | Lightweight readiness probe. |
GET /getEcdsaSig_native
| Query | Type | Notes |
|---|
localDomain | number | Origin chain domain ID (e.g., 0 for Ethereum). |
destinationDomain | number | Target chain domain ID. |
isV2 | boolean | true to request CCTP v2 (transferV2*), false for v1 (transfer*). |
isNative | boolean | true if the user will pay relayer fee + gas drop in native currency. |
GET https://gas.cashmere.exchange/getEcdsaSig_native?localDomain=0&destinationDomain=3&isV2=true&isNative=false
{
"fee": "1350000",
"deadline": "1729281534",
"signature": "0x8ab3…1f",
"isNative": false,
"cctpVersion": 2
}
fee is the relayer fee expressed in the bridge asset’s smallest unit (USDC = 6 decimals) unless isNative=true, where it represents native token units (18 decimals on EVM chains).
Fee logic
- Pulls
gas-api:gas-price:{destinationDomain} and gas-api:token-price:{localDomain} plus REDEEM_GAS_USAGES and ADJUSTMENT_FACTOR constants.
- Returns
fee as a string in the smallest USDC unit (6 decimals) or native token units when isNative=true.
- Applies per-chain minimums (e.g., Solana ≥ 0.59 USDC, Ethereum ≥ 0.20 USDC).
- When
isNative=true, the minimum is converted to native units using the source price feed.
gasDropAmount must mirror the fee currency: 6-decimal USDC when isNative=false, 18-decimal native token units when isNative=true.
maxFee (for v2 requests) is always quoted in 6-decimal USDC, regardless of isNative.
Signature payload
- Hash schema:
keccak256(abi.encodePacked(uint32(localDomain), uint32(destinationDomain), uint256(fee), uint256(deadline), bool(isNative), uint8(cctpVersion)));.
cctpVersion is 1 for transfer / transferWithPermit, 2 for the v2 variants.
GET /getEd25519Sig_native
| Query | Type | Notes |
|---|
localDomain | number | Origin chain domain ID. |
destinationDomain | number | Target domain. |
isNative | boolean | Native fee flag (true/false). |
version | number (optional) | Pass 2 to tag v2 payloads (Solana transfer_v2). |
GET https://gas.cashmere.exchange/getEd25519Sig_native?localDomain=5&destinationDomain=0&isNative=false&version=2
{
"signature": "0x6b8f…c2",
"message": "0x0200000000000000000000000000000030801e000000000001000000",
"publicKey": "0x93ab…af",
"destinationDomain": "0",
"fee": "590000",
"deadline": "1729281534",
"isNative": false,
"version": 2
}
fee is returned in the smallest USDC unit (6 decimals) when isNative=false. If isNative=true, the value is quoted in the native token denomination (e.g., 18 decimals for EVM-origin chains).
Message encoding
- Optional
version (u8) prefix.
localDomain (u32) only when the quote payload includes the isNative flag (for source-specific conversions).
destinationDomain (u32), fee (u64 representing 6-dec USDC when isNative=false, native token decimals when isNative=true), deadline (u64).
- Optional
isNative (bool) suffix.
The on-chain programs reproduce the same BCS byte order before verifying Ed25519 signatures.
WebSocket Broadcast
- Connect to
wss://gas.cashmere.exchange/subscribe for live fee and price updates.
- Payloads:
{ "type": "fees", "data": { <sourceChain>: { fee: { <destChain>: { native, usd } }, gas: { native, usd } } } }
{ "type": "tokenPrices", "data": { <domain>: "<price>" } }
- Clients can push these updates into their own caches to avoid repeated REST calls.
Operational Notes
- Redis key prefixes:
gas-api:transfer-fee-{native|usd}:{domain}, gas-api:token-price:{domain}, gas-api:gas-price:{domain}.
- Minimum USDC fees (6 decimals): default
80,000, Solana 590,000, Linea 100,000, HyperEVM 100,000, Ethereum 200,000.
- Deadline = current UNIX timestamp + 100 seconds (signatures expire after this window; relayers tolerate ≤5 seconds of clock drift before rejecting).
Points & Leaderboard API (kapi.cashmere.exchange)
All endpoints use JSON over HTTPS and rely on internal Postgres materialized views. They are unauthenticated but monitored; aggressive polling should be avoided.
Numeric fields are returned as floats to reflect Postgres aggregates; round as needed for UI display. Rate limit: 60 requests per minute per IP (check X-RateLimit-Remaining headers for real-time budget).
/stats/mainnet/wallets
Returns cached distinct sender counts on mainnet:
{
"unique_senders_count": 18342
}
- Backed by Redis (
mainnet_wallet_stats) with default TTL.
- Falls back to direct SQL if the cache miss occurs.
/stats/wallets
Devnet/testnet unique sender count (same schema as mainnet):
{
"unique_senders_count": 5120
}
/users/leaderboard
| Query | Default | Notes |
|---|
network | mainnet | Use devnet for the testnet leaderboard. |
limit | 50 | Maximum of 100. |
offset | 0 | Pagination offset. |
search | empty | Optional case-insensitive username filter (truncated to 100 chars). |
{
"leaderboard": [
{
"user_id": 42,
"username": "cashmerefan",
"ref_code": "CASHFAN",
"total_base_points": 5320.5,
"domain_multiplier": 2.5,
"domain_total_multiplied_points": 13301.25,
"referral_points": 1200,
"total_points_with_referrals": 14501.25,
"staked_op_nfts": 3,
"staked_eth_nfts": 1,
"wallet_count": 4,
"domain_rank": 128
}
],
"total_count": 4827,
"limit": 50,
"offset": 0,
"has_more": true
}
- Ranks read from
user_ranks / user_ranks_mainnet.
- Entries without a stored rank return
null and are ordered after ranked users.
/users
Two production query patterns:
GET /users?wallets=0xabc_evm,So111_solana — wallet-level points and multipliers.
GET /users?domains=username.csm — domain aggregates and per-chain breakdowns.
Wallet query
{
"username": "cashmerefan",
"ref_code": "CASHFAN",
"users": [
{
"user_id": 42,
"username": "cashmerefan",
"ref_code": "CASHFAN",
"wallets": [
{
"address": "0xabc...",
"chain_type": "evm",
"swap_points": 1200,
"swap_points_mainnet": 400,
"points_multiplier": 2.5,
"total_points_multiplied": 3500,
"total_points_multiplied_mainnet": 2600
}
],
"max_multiplier": 2.5,
"testnet_points": 800,
"nft_points": 120,
"swap_points": 1200
}
]
}
Domain query
{
"username": "builder.csm",
"ref_code": "BUILD",
"binded_wallets": {
"evm": "0xabc...",
"sol": "So111...",
"apt": "",
"sui": ""
},
"leaderboard_rank_mainnet": 128,
"leaderboard_rank_devnet": 54,
"domain_total_multiplied_points_mainnet": 4600,
"domain_total_multiplied_points": 13301.25,
"evm": {
"address": "0xabc...",
"chain_type": "evm",
"swap_points": 1200,
"swap_points_mainnet": 400,
"testnet_points": 800,
"points_multiplier": 2.5,
"total_points_multiplied": 3500,
"total_points_multiplied_mainnet": 2600,
"staked_eth_nfts": 1,
"staked_op_nfts": 3,
"nft_points": 120
},
"sol": {
"address": "So111...",
"chain_type": "solana",
"swap_points": 210,
"points_multiplier": 1.8,
"testnet_points": 420,
"total_points_multiplied": 378
}
}
All payloads retain snake_case keys.
/users/messages
Nonce helper for wallet binding flows:
GET https://kapi.cashmere.exchange/users/messages?username=builder.csm&address=0xabc...&chain_type=evm
{
"nonce": "1700000000",
"expires_at": "2024-09-18T12:35:56Z"
}
POST /users/verify
Submit the signed message to bind or unbind a wallet.
{
"username": "builder.csm",
"address": "0xabc...",
"chain_type": "evm",
"type": "bind",
"signature": "base64-or-hex",
"public_key": "",
"message": "Wallet binding request: builder.csm\nNonce: 1700000000"
}
chain_type: evm, solana, sui, or aptos.
type: bind or unbind.
- Always call
GET /users/messages immediately before signing.
- Aptos bindings must include
public_key (base64).
Successful calls return:
{
"success": true,
"username": "builder.csm"
}
/stats/mainnet/volumes
Volume aggregates. Raw amounts (without _usd) are 6-decimal USDC integers.
GET /stats/mainnet/volumes – lifetime volume (total_volume).
GET /stats/mainnet/volumes?senders=wallets – wallet-level totals (user_volume).
GET /stats/mainnet/volumes/hourly?limit=24 – hourly buckets (total_volume_usd).
GET /stats/mainnet/volumes/daily?limit=30 – daily buckets (total_volume_usd).
/stats/mainnet/fees
GET /stats/mainnet/fees?period=hourly|daily&limit=N — hourly/daily fee buckets (USD floats). Response includes fees[], period_type, limit, offset.
/stats/mainnet/transactions
GET /stats/mainnet/transactions — returns { "total_transactions": number }.
/stats/mainnet/chain-shares
GET /stats/mainnet/chain-shares — volume split per Circle domain (domain, amount, total_amount).
Transaction APIs (kapi.cashmere.exchange)
/transactions
Testnet + staging records backed by the default repository.
| Query | Description |
|---|
senders | Comma-separated addresses (optional). |
addr_or_tx_hash | Address, ENS (.eth), SNS (.sol), or tx hash. |
source_domain / destination_domain | Filter by Circle domain IDs (uint32). |
limit | Page size (default 10). |
cursor | Pagination cursor (<unix_ts>_<id>). |
Response:
{
"transactions": [
{
"id": 12345,
"source_tx_hash": "0xabc...",
"source_domain": 0,
"destination_domain": 3,
"sender": "0xabc...",
"recipient": "0xdef...",
"deposit_amount": 100000000,
"receive_amount": 99500000,
"max_fee": 2000000,
"relayer_fee": 1500000,
"gas_drop_amount": 5000000,
"is_gas_drop_in_native": false,
"confirmed": true,
"created_at": "2024-09-18T12:34:56Z"
}
],
"next_cursor": "1726666496_12345",
"has_more": true
}
Amounts are expressed in the bridge asset’s smallest unit (USDC = 6 decimals). gas_drop_amount is denominated in native units when is_gas_drop_in_native = true. The API currently returns snake_case fields for backward compatibility with internal services.
/transactionsmainnet
Same schema, but queries the mainnet replica. Additional filters:
| Query | Description |
|---|
start_time | UNIX timestamp (UTC) lower bound. |
end_time | UNIX timestamp upper bound. |
- Timestamp filters allow bridges to backfill historical windows efficiently (
created_at DESC order).
- ENS/SNS lookups are resolved before querying; invalid names return
400.
Smart Contract Integration (Quick Ref)
These APIs abstract away real-time fee estimation and attestation retrieval for EVM and non-EVM integrations.
- Call the Gas API to obtain
fee / deadline / signature.
- EVM:
/getEcdsaSig_native with isV2=true for TransferV2/V2Permit.
- Solana/Aptos/Sui:
/getEd25519Sig_native with version=2 when targeting v2 entrypoints.
- Use the returned
fee values to populate smart contract params:
TransferParams.fee or TransferV2Params.fee.
gasDropAmount should mirror the live quote when isNative=false (use the bridge token’s decimals, e.g., 6 for USDC); for native gas drops, include the quoted value in the transaction value.
- Submit the transaction before
deadline (signatures revert if block.timestamp > deadline; relayers tolerate ≤5 seconds of clock drift).
- Monitor
/transactionsmainnet (or WebSocket fees) to reconcile executed transfers and track relayer performance.
Gas and price feeds are cached in Redis. If any key is missing, the Gas API returns HTTP 500. Ensure Redis daemons are healthy and synchronized across shards before relying on quotes.