Developer Docs

Stash Integration Guide

How tienko.io (and other ecosystem exchanges) connect to The Stash fee pool on tienko.market.

Overview

Every completed trade on tienko.io contributes 1% of the trade value to The Stash — a shared prize pool distributed to eligible coin holders at the end of each season. This guide covers the two API calls your exchange backend must make after every trade settles.

Authentication

All Stash API calls require a Bearer token in the Authorization header. Use the LISTING_WEBHOOK_SECRET shared with you by the Tienko team. Keep this secret server-side — never expose it in frontend code or logs.

http
Authorization: Bearer <LISTING_WEBHOOK_SECRET>
Requests without a valid token return HTTP 401. Rotate the secret immediately if it is ever exposed.

Integration flow

Trade settles on tienko.io

Your exchange confirms the on-chain transaction is finalised.

POST /api/stash/fee

Send the trade amount, tx hash, and buyer wallet. Stash records the 1% fee and updates the season balance.

POST /api/stash/holding (acquire)

Send the buyer wallet + coin mint address with action: acquire. Stash records when this wallet started holding.

POST /api/stash/holding (release)

When the same wallet later sells or transfers, send action: release. Stash closes the holding window.

Season end — rewards distributed

Tienko.market calculates each eligible wallet's share based on fees contributed and holding duration.

POST/api/stash/ping

1. Connectivity test

Call this first to verify your credentials and confirm the Stash API is reachable. Returns the current Stash balance and active season.

When: During initial setup and after any credential rotation.

Request

http
POST https://tienko.market/api/stash/ping
Authorization: Bearer <LISTING_WEBHOOK_SECRET>
Content-Type: application/json

{}

Response (success)

json
{
  "ok": true,
  "message": "tienko.market Stash API is reachable.",
  "stash": {
    "totalEth": "12.45000000",
    "currentSeasonEth": "3.21000000"
  },
  "activeSeason": {
    "id": 1,
    "name": "Season 1 — July 2026",
    "endsAt": "2026-07-31T23:59:59.000Z"
  },
  "timestamp": "2026-07-30T09:00:00.000Z"
}
POST/api/stash/fee

2. Record a trade fee

Call this immediately after every trade settles on tienko.io. The endpoint calculates 1% of the trade amount, records it in the fee log, and increments the running Stash balance atomically.

When: After every completed trade — buy, sell, or swap.

Request

http
POST https://tienko.market/api/stash/fee
Authorization: Bearer <LISTING_WEBHOOK_SECRET>
Content-Type: application/json

{
  "tradeAmountEth": "1.5",
  "txHash": "0xabc123...",
  "fromWallet": "0xBuyerWalletAddress",
  "listingId": 42,
  "feePercent": 1.0
}

Response (success)

json
{
  "success": true,
  "feeAmountEth": "0.01500000",
  "seasonId": 1,
  "message": "Fee of 0.01500000 ETH added to The Stash."
}
POST/api/stash/holding

3. Record a holding change

Call this when a wallet acquires or releases a coin. The Stash uses 7-day holding data to determine season-end eligibility. Missing holding events means wallets may not qualify for rewards.

When: On every buy (action: acquire) and every sell or transfer (action: release).

Request

http
POST https://tienko.market/api/stash/holding
Authorization: Bearer <LISTING_WEBHOOK_SECRET>
Content-Type: application/json

{
  "walletAddress": "0xBuyerWalletAddress",
  "coinMintAddress": "0xCoinContractAddress",
  "action": "acquire"
}

Release example

http
POST https://tienko.market/api/stash/holding
Authorization: Bearer <LISTING_WEBHOOK_SECRET>
Content-Type: application/json

{
  "walletAddress": "0xSellerWalletAddress",
  "coinMintAddress": "0xCoinContractAddress",
  "action": "release"
}

Response (success)

json
{
  "success": true,
  "action": "acquire",
  "wallet": "0xbuyerwalletaddress",
  "coin": "0xcoincontractaddress"
}

Complete Node.js example

Drop this into your trade settlement handler. Call onTradeSettled after every confirmed on-chain transaction.

typescript
// Node.js / TypeScript integration example
const STASH_URL = 'https://tienko.market';
const STASH_SECRET = process.env.LISTING_WEBHOOK_SECRET;

async function onTradeSettled(trade: {
  txHash: string;
  buyerWallet: string;
  sellerWallet: string;
  coinMintAddress: string;
  tradeAmountEth: string;
  listingId: number;
}) {
  const headers = {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${STASH_SECRET}`,
  };

  // 1. Record the fee
  await fetch(`${STASH_URL}/api/stash/fee`, {
    method: 'POST',
    headers,
    body: JSON.stringify({
      tradeAmountEth: trade.tradeAmountEth,
      txHash: trade.txHash,
      fromWallet: trade.buyerWallet,
      listingId: trade.listingId,
      feePercent: 1.0,
    }),
  });

  // 2. Buyer acquires the coin
  await fetch(`${STASH_URL}/api/stash/holding`, {
    method: 'POST',
    headers,
    body: JSON.stringify({
      walletAddress: trade.buyerWallet,
      coinMintAddress: trade.coinMintAddress,
      action: 'acquire',
    }),
  });

  // 3. Seller releases the coin
  await fetch(`${STASH_URL}/api/stash/holding`, {
    method: 'POST',
    headers,
    body: JSON.stringify({
      walletAddress: trade.sellerWallet,
      coinMintAddress: trade.coinMintAddress,
      action: 'release',
    }),
  });
}

Error handling

All endpoints return JSON. On success: HTTP 200/201 with { success: true }. On failure: HTTP 4xx/5xx with { error: string, message: string }. Implement retry logic with exponential backoff for 5xx responses. Log all 4xx responses — they indicate a payload or auth issue that needs fixing.

201 Created

Fee or holding recorded successfully

401 Unauthorized

Invalid or missing Bearer token

400 Bad Request

Missing or invalid payload field

Ready to connect?

Contact the Tienko team to receive your LISTING_WEBHOOK_SECRET and confirm your integration is live.

View The Stash

Integration checklist

Received LISTING_WEBHOOK_SECRET from Tienko team
POST /api/stash/ping returns 200 with your credentials
POST /api/stash/fee called after every settled trade
POST /api/stash/holding (acquire) called on every buy
POST /api/stash/holding (release) called on every sell / transfer
Retry logic implemented for 5xx responses
Secret stored server-side only — not in frontend code or logs