03
Architecture
This reflects actual runtime behavior in deposit-widget-backend and deposit-service-processor , including retries, short-circuit paths, dedupe keys, and failure semantics.
flowchart TB
subgraph Client["Client (deposit-modal / host app)"]
A1["User connects EOA or host app passes owner address"]
A2["Create/load local browser session owner key"]
A3["POST /setup-account to backend"]
A4{"needsRegistration?"}
A5["Sign EIP-712 session typed data"]
A6["POST /register to backend"]
A7["User transfer to smart account"]
A8["POST /process/:address with deposit txHash"]
A9["Poll GET /status/:address?txHash=..."]
A10{"Terminal event received?"}
A11["bridge-complete => success"]
A12["bridge-failed or error => fail state"]
A13["No terminal event for 10m => timeout UI"]
end
subgraph Backend["deposit-widget-backend"]
B1["Validate transfer (native ETH direct or Safe execTransaction)"]
B2["Dedupe key: deposit-processed:<chainId>:<txHash>"]
B3["Proxy /process to deposit-service-processor"]
B4["Receive processor webhook at POST /notify"]
B5["Store webhook payload in Redis (tx + last)"]
B6["Update dedupe state: submitted / processed / failed"]
end
subgraph Processor["deposit-service-processor"]
C1["Dedupe key: deposit-dedupe:<chainId>:<txHash>"]
C2{"sameChain && sameToken?"}
C3["Emit deposit-received + bridge-complete (short-circuit)"]
C4["Emit deposit-received"]
C5["Enable source/target sessions when needed"]
C6["Build + submit intent with Rhinestone SDK"]
C7["waitForExecution => bridge-complete"]
C8["Retry up to 10 attempts with 1.2^n backoff"]
C9["Emit bridge-failed (DEP-1/2/3) or error"]
end
subgraph Orchestrator["Rhinestone Orchestrator"]
D1["Route swaps + bridge + settlement"]
D2["Return execution/claim/fill tx hashes"]
end
A3 --> B1
A4 -- yes --> A5 --> A6
A4 -- no --> A7
A6 --> A7
A7 --> A8
A8 --> B1
B1 --> B2 --> B3 --> C1 --> C2
C2 -- yes --> C3 --> B4
C2 -- no --> C4 --> C5 --> C6 --> D1 --> D2 --> C7 --> B4
C6 --> C8
C8 --> C6
C8 --> C9 --> B4
B4 --> B5 --> B6
B5 --> A9 --> A10
A10 -- bridge-complete --> A11
A10 -- bridge-failed or error --> A12
A10 -- no event yet --> A13End-to-end sequence (after transfer)
1. Account + session setup
Client calls /setup-account. If registration is needed, it signs session typed data and calls /register.
2. Deposit submission
After user transfer, client calls /process/:address with chainId/token/amount/txHash/sender.
3. Backend validation + dedupe
Backend validates native ETH transfers via RPC (including Safe forwarding path), acquires dedupe lock, and forwards to processor.
4. Processor execution
Processor dedupes again, emits deposit-received, optionally enables sessions, and submits bridging intent through Rhinestone SDK.
5. Webhook + status
Processor emits events to backend /notify. Backend stores them in Redis and modal polls /status by txHash until terminal event.
Failure and stuck-transfer handling
Processor retry loop: bridge submission and enable-session steps retry up to 10 attempts with exponential backoff (1.2^attempt).
Processor failure events: bridge-failed is emitted with error codes DEP-1 (insufficient route value), DEP-2 (session/bridge failure), or DEP-3 (missing session details). Unknown exceptions emit error .
Backend dedupe state transitions:processing -> submitted -> processed/failed. Failed state uses short retry TTL so the same tx can be retried.
Modal behavior: polling uses backoff up to 30s interval. If no terminal event is found in 10 minutes, modal enters timeout state and surfaces a support message.
sameChain && sameToken), processor short-circuits by emitting deposit-received thenbridge-complete without launching a bridge intent.