How I would test Bitget Wallet's swap and pay flows, and a working bench that checks live quotes and payment links against the chain.
eth_callA self-custody wallet that is becoming a payments app: swap, cross-chain, gas paid in the input token, national QR pay, a card and a merchant gateway. In the partner API a PayFi payment is a swap order with a merchant on the other end.
The confirmation screen. The user signs once against a quote, a fee, a min received and a spender. Every one of those numbers needs an oracle that is independent of the code that produced it.
A bench that reads Bitget Wallet's public quote endpoint, compares it with KyberSwap at the same moment, replays routes on chain, and parses real payment links. JUnit out, exit code for CI.
| Takeaway | Why it matters for testing |
|---|---|
| A quote is a promise; the chain decides | A 30,000 ETH route on Base quoted 71M USDC and reverted on replay. Simulation before signing is a test oracle and a product guard at the same time. |
| Decimals come from the token | USDT is 6 decimals on Ethereum and 18 on BNB Chain. The same payment link asks for 10 USDT on one and 0.00000000001 USDT on the other. |
| Money maths is integer maths | At 18 decimals, floating point is off by 153 base units on a RM 100 payment. Rounding direction is a product decision to test, and so is the arithmetic. |
| Quality moves left | Most of these are cheaper to catch in requirement review (质量左移): state the oracle for each number on the screen before a line of code exists. |
PayFi was named the 2025 focus. By 2026 the surface under test spans six product areas, each with its own failure states.
| Area | What is public | Test read |
|---|---|---|
| Swap | Multi-market quotes (in-house "Bitget Wallet X" plus DEX and aggregator routes), MEV protection on by default, 10-second quote expiry, dynamic fees; live tiers 0% wrap, 0.1% stablecoin pairs, 0.3% other. | Every number on the confirm screen has an independent oracle: chain decimals, reference price, replay, a second aggregator. |
| Cross-chain | Super DEX cross-chain routing (launched Mar 2025); zero-slippage routes for USDT, USDC and BGB; per-chain minimum order sizes in the partner docs. | Partial states are the risk: sent and not received, refunded in another asset. |
| Gas abstraction | GetGas (Dec 2024); gas paid in the input token through an EIP-7702 delegation and a typed-data signature. | What the user sees must match what they sign, including the delegation target. |
| QR pay | National QR schemes from 2025 (VietQR, QR Ph, Pix via a licensed partner), an APAC release in Apr 2026 and Latin American markets after it; USDT and USDC settle. | Rate lock, rounding, idempotent pay, refunds, network loss after broadcast. |
| Card | Mastercard with Immersve (UK and EU first, Jul 2025), then APAC and 50+ markets; fee-free quota then 1% to 2.2%; daily and annual limits. | Two ledgers meet at top-up: the self-custody wallet and the card account. |
| Merchant and partner APIs | Paydify merchant gateway partnership (May 2025), Pay SDK, HMAC-signed partner API with signed responses, and a public agent quote endpoint documented in an open-source wallet skill. | Contract tests below the UI: signatures, idempotency, timestamps, error codes. |
Security context: the Bitget exchange lost about $387.5M to an attack on 24 Sep 2026; Bitget states the wallet runs on separate infrastructure and was unaffected (BleepingComputer). For a wallet team this raises the bar on proving isolation and on release discipline.
Consumer wallets now compete on swap cost, spend options and safety. Few combine a card with QR pay. Data from my Wallet Stack Compare (56 wallets, sourced per cell).
| Wallet | Swap fee | Card | QR pay | Gap vs Bitget Wallet, and the test angle |
|---|---|---|---|---|
| Bitget Wallet | 0 / 0.1 / 0.3% | Yes, Mastercard with Immersve, 50+ markets | Yes, national QR | Benchmark. The widest spend surface means the most cross-system states to test. |
| MetaMask | 0.875% | Yes, Mastercard (Baanx, Monavate) | Unknown | Higher fee, no QR pay. Its 7702 smart accounts set the bar for clear signing prompts. |
| Phantom | 0.85% | Yes, Visa (US) | No | US-first spend. Strong transaction simulation UX to match. |
| OKX Wallet | 0% to 0.5% | Partial, inside OKX Pay (EEA) | Partial (SGQR) | Closest rival in Asia; exchange-linked pay. Fee-tier parity is a regression risk for both. |
| Trust Wallet | Varies by provider | No (lookalike card scams reported) | No | No first-party spend. Phishing around cards makes in-app domain trust a test area. |
| Binance Wallet | 0% to 0.5% | No (exchange card) | No (Binance Pay is exchange-side) | Spend lives in the exchange account. Bitget Wallet tests a self-custody to custodial handover the others avoid. |
| imToken | 0.3%, 0.04% stable | Yes, Fiat24 Mastercard | Unknown | Same tier shape at a lower stable rate. Fee display needs exact tests per pair class. |
| SafePal | 0.2% | Yes, Fiat24 Mastercard | Unknown | Hardware plus app. Its card ran through a third-party bank account model. |
| Rabby | 0.25% | No | No | Desktop power users; pre-sign simulation is its brand. A good benchmark for warning copy. |
Fees and features as published by each wallet, checked October 2026; sources per row on the Wallet Stack Compare pages. Bitget Wallet tiers from its live quote endpoint.
Each row reproduces from the demo with one click. Bitget Wallet rows come from its public quote endpoint, read only; nothing was ordered or signed.
| Case | Observation | Evidence | Severity | Owner |
|---|---|---|---|---|
| BG-01..05 | Bitget Wallet fee tiers and pricing hold | Fee matched the pair class in 5 of 5 quotes (0% ETH to WETH, 0.10% USDC to USDT, 0.30% others). The gap to KyberSwap at the same moment equalled the disclosed fee within 0.5%. MEV flag on for Ethereum, BNB Chain and Base. Price impact is graded in levels: a warning from about 5% loss, a required confirm for heavy losses (a 59% route on Arbitrum). Every route losing over 5% carried a level. Failed cases are retried once, and a clean second attempt is labelled flaky. | pass | Regression |
| BG-03 | Min received on one route sits slightly below the slippage setting | USDC to USDT on Base, in-house route: min received is 0.0005% of output below out × (1 − 0.5%), on every run. Other routes in the same response match exactly. | low | Swap backend |
| BG-03 | Route list sometimes out of sort order | About one response in four appends a late route after a forbidden one. Harmless if the client re-sorts; worth one assertion in the client test. | low | Client |
| SW-08 | A large quote that cannot fill | 30,000 ETH to USDC on Base (KyberSwap route): quoted 71M USDC with 7.5% impact; replay reverts "Return amount is not enough". A full-mode simulation step catches this before signing. | high if unguarded | Swap, client |
| PF-03 | Same payment link, a trillionth of the amount | uint256=1e7 is 10 USDT on Ethereum and 0.00000000001 USDT on BNB Chain. The bench renders from decimals() on chain and warns on sub-cent stablecoin requests. | high | Pay |
| PF-05 | The EIP-681 spec's own example fails checksum | The example address in the EIP-681 text is mixed case and fails EIP-55. Test vectors copied from a spec need validating too. | info | QA |
| PF-15 | Float maths drifts at 18 decimals | RM 100 at 4.2135 MYR per USDT: exact owed 23733238400379731815 base units; Number() maths gives ...968. | medium | Pay |
Demo: bitget-wallet-qa.leverlabs.workers.dev (Suite tab, Run all; expand a row for evidence and a ready bug report).
| JD line | How I would do it | Shown in |
|---|---|---|
| Test Bitget Wallet Swap and PayFi: test plans, case writing, execution (负责测试方案设计、用例编写和执行) | Risk-ranked plan per flow: P0 is anything that moves the wrong amount or sends to the wrong place. Each case names its oracle. Automated where an oracle exists off-device; manual on device with small real balances on mainnet. | Demo, Test plan tab |
| Requirement reviews with product and dev; find test points; drive issue localisation (参与需求评审, 推动问题定位) | Bring a one-page oracle sheet to each review: for every number on the new screen, where it comes from and how a test will check it. Bug reports carry the request, response and on-chain replay so engineers start from the failing layer. | Bug report export in the demo |
| Automated test scripts for efficiency and coverage (设计和实现自动化测试脚本) | One core module for browser and Node; JUnit for the pipeline; exit code gates the release; a six-hourly run against live routes catches upstream changes between releases. | Run in CI tab |
| Web3 swap, DeFi and bridge testing experience | Route build checks, spender allow-list, recipient in calldata, replay with state override, cross-chain min received and fee lines. | SW and BG cases |
| Smart contract principles on Ethereum, BSC, Polygon; read Solidity | Decode router returns, read approval and delegation targets, verify the spender has code, check 7702 delegation targets against the docs. | BG spender check |
| PayFi or payments testing (具备Web3 payfi或支付相关业务测试经验) | Payment-link parsing to spec, decimals per chain, integer rounding, idempotent pay, refunds, rate locks, card ledger reconciliation. | PF cases, Test plan |
| JavaScript, Python or Go | The bench is plain JavaScript with no dependencies; Python for data checks; I read Go well enough to trace a backend error. | Demo source |
Four layers, cheapest first. A defect found in a lower layer never needs a device.
| Layer | What runs there | Oracle |
|---|---|---|
| Requirement review | Oracle sheet per screen; edge-case list (dust, whale, stale quote, wrong chain, double tap, network loss after broadcast). | Agreed numbers and rounding rules, written before build. |
| API contract | Quote, confirm and order endpoints; signatures and timestamps; idempotency keys; error codes per chain. | Schema plus invariants (min ≤ out, fee tier per pair class, expiry present). |
| Chain replay | Built transactions replayed with eth_call and state overrides; spender code checks; decimals from chain. | What the chain returns at the current block. |
| Device and mainnet | iOS, Android (store and APK), extension, Telegram mini-app, dApp browser; small real balances for P0 flows. | Mined transaction and ledger entries match the confirm screen. |
An unreadable source is an error, never a pass. A green run means every oracle answered.
P0 cases pass on every client before release. A new P0 failure blocks; a P1 needs a named owner and date.
Routes and pools change daily without a release. A scheduled run against live quotes opens a ticket with the JSON evidence attached.
| When | Work | Output |
|---|---|---|
| Days 1 to 30 | Learn the swap and pay flows end to end on every client; read the last quarter of incidents and support tickets; map existing cases and tools. | Risk map of Swap and PayFi with current coverage per area. |
| Days 31 to 60 | Contract tests for quote and order APIs; chain replay for EVM swaps; payment-link and rounding suites; join every requirement review with an oracle sheet. | Automated P0 suite in CI with JUnit and a release gate. |
| Days 61 to 90 | Scheduled live regression; cross-chain and gas-abstraction cases; card top-up reconciliation checks; device matrix for the P0 set. | Escaped-defect rate tracked per release; regression time per release down. |
The demo is my own work, built for this application. It is not Bitget Wallet code and holds no keys.
Independent homework for the Bitget Wallet PayFi Test Engineer role · 2026 · edwardtay.com