Skip to main content

Deposit

DF deposits are credited to the spot wallet by a backend listener that tails the BSC vault contract for SpotDeposit events. There is no deposit-initiation API — the user transacts directly with the vault, and the backend reconciles asynchronously.

Deposit Flow

1. approve() 2. deposit() 3. SpotDeposit event
──────────▶ ──────────▶ │
DF token ERC-20 Vault contract ▼
(0x4Fe0...664a) Backend listener

≥ 20 confirmations (~40s)


spot_balances.available += amount
INSERT spot_deposits row

Step 1 — Approve

The user approves the vault contract to pull amount of DF.

DF.approve(vaultAddress, amount);

Step 2 — Deposit

The user calls the vault's deposit method.

ZtdxSpotVault.deposit(address token, uint256 amount);
// token = DF token address (0x8063a4...)
// amount = wei (DF has 18 decimals, so 1 DF = 10**18)

The vault accepts the transfer and emits:

event SpotDeposit(address indexed account, address indexed token, uint256 amount);

Step 3 — Backend credits

The deposit poller observes the event after SPOT_BSC_CONFIRMATION_DEPTH blocks (currently 20). At that point:

  • A new row is inserted into spot_deposits with status = "confirmed".
  • spot_balances.available for the user is incremented.

Idempotency is guaranteed by a (chain_id, tx_hash, log_index) unique key — replays of the same event are no-ops.

List My Deposits

Returns the user's recent confirmed deposits.

Authentication Required
Authorization: Bearer <JWT> # or X-API-Key
GET /spot/deposits

Query Parameters

ParameterTypeDefaultDescription
limitnumber501–200; clamped server-side.

Response — 200 OK

[
{
"id": "5af0c1a2-...",
"token": "DF",
"amount": "100",
"chain_id": 97,
"tx_hash": "0xabc...",
"block_number": 106384180,
"status": "confirmed",
"created_at": 1778315530,
"confirmed_at": 1778315570
}
]
FieldTypeDescription
idstringUUID of the deposit row.
tokenstringAlways DF in MVP.
amountstringDecimal amount credited.
chain_idnumberSource chain (97 = BSC Testnet).
tx_hashstringOn-chain transaction hash.
block_numbernumberBlock where the event was emitted.
statusstringCurrently always confirmed — pending deposits are not surfaced.
created_atnumberUnix seconds — DB insert time.
confirmed_atnumberUnix seconds — when the listener credited the balance.

The list returns only confirmed entries; sub-confirmation deposits aren't visible here yet. To surface progress, the frontend can match the user's wallet TX hash against this endpoint by polling.

Code Example

import requests

BASE = "https://api-sepolia.p99.world/api/v1"
JWT = "your_jwt_token"

deposits = requests.get(
f"{BASE}/spot/deposits?limit=20",
headers={"Authorization": f"Bearer {JWT}"},
).json()
for d in deposits:
print(f" {d['token']:5} {d['amount']:>14} tx={d['tx_hash'][:10]}… block={d['block_number']}")

Operational Notes

  • The deposit poller runs every SPOT_BSC_POLL_INTERVAL_MS (currently 2000 ms) and processes up to 100 blocks per call.
  • Cold-start catch-up rate is ~30 blocks/second; in steady state the lag is ≤ 40 seconds (20 confirmations × ~2s/block on BSC Testnet).
  • Native-token (BNB) deposits are not supported in MVP.