Security architecture

Your keys. Your machine. Your call.

AES-256-GCM encrypted vault · scrypt key derivation · explicit approval at every financial edge · zero plaintext in logs or memory dumps.

The vault

API credentials live encrypted — per user, per session.

scrypt key derivation against a per-user salt means the same secret decrypts nothing across users. No shared-state attack surface.

CredentialVault.ts

Format: salt:iv:authTag:ciphertext · base64 · colon-separated

// Key derivation
derivedKey = scrypt(
  ENCRYPTION_SECRET + ':' + userId,
  salt,                 // 16 random bytes, per credential
  32                    // bytes = AES-256 key
)

// Encrypt
iv       = randomBytes(12)              // 96-bit IV, required for GCM
cipher   = createCipheriv('aes-256-gcm', derivedKey, iv)
ct       = cipher.update(plaintext) + cipher.final()
authTag  = cipher.getAuthTag()          // 16 bytes — tamper protection

// Storage
row = [salt, iv, authTag, ct]
        .map(b => b.toString('base64'))
        .join(':')
Supports rotating ENCRYPTION_SECRET — the vault tries each known secret on decrypt.

AES-256-GCM

Authenticated encryption — any tampering fails the auth tag check

Per-user salt

Compromising one user's key does not compromise anyone else's

Plaintext never logged

Scrubbed from Pino logs and Sentry breadcrumbs at the source

3-gate approval

Cross-exchange trades never fire without you.

Three explicit checkpoints — any of them you can walk away from. No auto-submit, no hidden defaults, no dark patterns.

1
User approval required

Gate 1 · Buy

User reviews price, fees, and balance, then approves the buy order on the source exchange.

Order placed · balance decremented · source exchange confirms fill

2
User approval required

Gate 2 · Withdraw

After buy fills, user enters the destination address, verifies the network, and approves withdrawal.

Address whitelist · network fee preview · 2FA at exchange edge

3
User approval required

Gate 3 · Sell

Once crypto lands on the destination exchange, user approves the final sell. Profit is realized.

Re-quote before execution · slippage check · predicted vs actual logged

Ghost liquidity defense

Four-layer suspended-coin filter

Delisted or frozen coins look liquid on the surface — they'll happily show a last price. We filter at every layer so you never try to route through them.

1

Gate.io public API

Every coin with deposit_disabled or withdraw_disabled is skipped at fetch time.

2

Graph route engine

Requires real bid AND ask to build an edge — no fallback to last price, no ghost liquidity.

3

Arbitrage scanner

Same bid/ask guard applies. Any pair missing real quotes is dropped from the scan window.

4

UI filter

Client-side spread sanity check (< 2%) removes the last stragglers before we ever offer them to you.

Risk manager

Seven defaults. Every one overridable.

Opinionated out of the box, adjustable to your mandate. Every threshold below applies before a trade is ever submitted.

ThresholdDefaultEffect
maxLossPerCyclePct2%Pre-trade rejection if projected loss exceeds 2% of the session balance.
maxDailyLossPct5%Hard stop for the day. Sessions auto-pause and require user reset.
maxPositionSizePct50%Single trade capped at half the current balance.
minProfitThresholdPct0.3%Trades below this expected edge never fire.
consecutiveLossLimit3Three losses in a row triggers an auto-pause.
cooldownAfterLossSeconds300sFive-minute wait after a losing cycle before the bot resumes.
maxOpenPositions1One concurrent position per session — no pyramiding.

Local-first

Keys never leave your machine. Full stop.

The Tauri desktop app runs the Node sidecar locally. API credentials are encrypted client-side and stored on your disk. The auth server sees user sessions — never exchange keys.

Desktop

Bundled Node sidecar handles every signed request. Exchange traffic goes direct from your IP — nothing transits our infrastructure.

Web

Encrypted vault syncs with your account, decryption happens on-device at trade time. Secret rotation means revoking a leaked vault secret is a one-click op.

Trust is a stack, not a slogan.

Every layer above is in production today. Ask hard questions — we ship the answers in code.