Static wallets
A static wallet is a reusable deposit address scoped to one of your customers: one EVM address, valid across every supported EVM chain, that they can fund any number of times with any amount.
Use it where funding an account is a core feature — player balances, trading accounts, prepaid services. For one-off fixed-amount charges, use Payments instead.
Create a wallet per customer
curl -X POST https://api.suward.com/v1/static-wallets \
-H "X-Api-Key: $SUWARD_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"externalId": "customer-99",
"allowedAssets": ["USDT_ETHEREUM", "USDT_ARBITRUM"]
}'allowedAssetsis the wallet's accept-list. A deposit in any other asset is recorded with statusignored— visible for audit, never credited. Update the list any time withPATCH /v1/static-wallets/{staticWalletId}.externalIdis your customer reference: creation is idempotent by it (retries never create a duplicate wallet), and it is denormalized onto every deposit, so a webhook alone tells you whose money arrived.- Optional: a per-wallet
webhookUrloverride and arbitrarymetadata.
The response returns the wallet's address — hand it to the customer once; it stays theirs.
{
"id": "sw_71b0d4",
"projectId": "prj_1a2b",
"address": "0x7c31…be04",
"allowedAssets": ["USDT_ETHEREUM", "USDT_ARBITRUM"],
"externalId": "customer-99",
"createdAt": 1769000000000,
"updatedAt": 1769000000000
}Deposits: the lifecycle
Each incoming transfer is recorded as an individual deposit and moves through detected → accepted → confirmed as finality accrues; a chain reorganization rolls an unfinalized deposit back to invalidated. Credit your user at accepted (a static_deposit.accepted webhook fires), treat the funds as final at confirmed / static_deposit.success. Deposits that fail screening are held (complianceHold) or rejected (complianceRejected, which sends static_deposit.failed) before crediting. → Settlement & finality, Screening levels
| Status | Credited? | Meaning |
|---|---|---|
detected | No | Seen on-chain, awaiting confirmations. No webhook. |
accepted | Yes | Safe confirmations reached. Credit the user. static_deposit.accepted. |
confirmed | Yes — withdrawable | Irreversible; funds are withdrawable. static_deposit.success. |
ignored | No | The asset is not on the wallet's allow-list. Recorded for audit only; no webhook. |
invalidated | No | Rolled back before acceptance, e.g. by a chain reorganization. Nothing was credited. |
complianceHold | No | Held pending compliance review. No webhook. |
complianceRejected | No | Rejected by compliance; credit reversed. Terminal. static_deposit.failed. |
Every deposit records amount, fee, networkFee, and netAmount, plus txHash and transferIndex — enough to reconcile a single transfer inside a batched transaction. List them with GET /v1/static-wallets/{staticWalletId}/deposits, or fetch one by id.
curl "https://api.suward.com/v1/static-wallets/sw_71b0d4/deposits?limit=20" \
-H "X-Api-Key: $SUWARD_API_KEY"Crediting is by stage, not by arithmetic
The net amount — amount minus fee and networkFee, i.e. netAmount — is credited to your
project balance; each deposit reports all three figures individually. Balance updates are atomic and
reorg-safe — the deposit's stage and the balance move together or not at all.
Operate at scale
- Addresses don't expire; there is nothing to refresh or reissue.
- Deleting a wallet stops monitoring its address for new deposits; recorded deposits are unaffected.
- Funds land on the same project balance as payments; sweep them with Auto-withdrawals.
- Listing is cursor-paginated:
limitup to 100,lastIdfrom the previous page,orderasc or desc.
Test it
Drive a synthetic deposit through its lifecycle with POST /v1/static-wallets/{staticWalletId}/simulate (test assets only; no chain activity, no balance credit), or send real test tokens to the address and watch the full pipeline run. → Test payments
curl -X POST https://api.suward.com/v1/static-wallets/sw_71b0d4/simulate \
-H "X-Api-Key: $SUWARD_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"asset": "TESTSTABLECOIN_OPTIMISM",
"amount": "25000000",
"status": "accepted"
}'Next: Auto-withdrawals for treasury rules · Webhooks for crediting your users automatically.
Something unclear? payments@suward.com — we treat every integration question as a documentation defect.