Skip to content

Latest commit

Β 

History

History
432 lines (403 loc) Β· 23.4 KB

File metadata and controls

432 lines (403 loc) Β· 23.4 KB

Streaming Payments Architecture Diagram

System Overview

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                         USER INTERFACE                          β”‚
β”‚                    (Frontend / API Client)                      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                             β”‚
                             β”‚ HTTP/REST
                             β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                      BACKEND API SERVER                         β”‚
β”‚                      (Express.js / Node)                        β”‚
β”‚                                                                 β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚              API Routes Layer                            β”‚  β”‚
β”‚  β”‚  /api/v1/streams (streaming-routes.js)                  β”‚  β”‚
β”‚  β”‚  - POST   /streams              Create stream           β”‚  β”‚
β”‚  β”‚  - POST   /streams/:id/withdraw Withdraw funds          β”‚  β”‚
β”‚  β”‚  - DELETE /streams/:id          Cancel stream           β”‚  β”‚
β”‚  β”‚  - GET    /streams/:id          Get details             β”‚  β”‚
β”‚  β”‚  - GET    /streams/:id/balance  Check balance           β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚                             β”‚                                   β”‚
β”‚                             β–Ό                                   β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚           Service Layer                                  β”‚  β”‚
β”‚  β”‚  streaming-service.js                                    β”‚  β”‚
β”‚  β”‚  - Transaction building                                  β”‚  β”‚
β”‚  β”‚  - Contract invocation                                   β”‚  β”‚
β”‚  β”‚  - Result parsing                                        β”‚  β”‚
β”‚  β”‚  - Transaction polling                                   β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚                             β”‚                                   β”‚
β”‚                             β–Ό                                   β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚           Database Layer                                 β”‚  β”‚
β”‚  β”‚  Stream.js (MongoDB Model)                               β”‚  β”‚
β”‚  β”‚  - Stream metadata                                       β”‚  β”‚
β”‚  β”‚  - Status tracking                                       β”‚  β”‚
β”‚  β”‚  - Transaction history                                   β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                             β”‚
                             β”‚ Soroban RPC
                             β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                      SOROBAN RPC SERVER                         β”‚
β”‚                   (Stellar Network Node)                        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                             β”‚
                             β”‚ Contract Calls
                             β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                  STREAMING PAYMENTS CONTRACT                    β”‚
β”‚                      (Soroban Smart Contract)                   β”‚
β”‚                                                                 β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚                  Contract Functions                      β”‚  β”‚
β”‚  β”‚                                                          β”‚  β”‚
β”‚  β”‚  create_stream(sender, recipient, token, amount, ...)   β”‚  β”‚
β”‚  β”‚  β”œβ”€ Validate parameters                                 β”‚  β”‚
β”‚  β”‚  β”œβ”€ Calculate rate_per_ledger                           β”‚  β”‚
β”‚  β”‚  β”œβ”€ Transfer tokens to contract                         β”‚  β”‚
β”‚  β”‚  β”œβ”€ Store stream data                                   β”‚  β”‚
β”‚  β”‚  └─ Emit "created" event                                β”‚  β”‚
β”‚  β”‚                                                          β”‚  β”‚
β”‚  β”‚  withdraw(stream_id, amount)                            β”‚  β”‚
β”‚  β”‚  β”œβ”€ Verify recipient authorization                      β”‚  β”‚
β”‚  β”‚  β”œβ”€ Calculate available balance                         β”‚  β”‚
β”‚  β”‚  β”œβ”€ Transfer tokens to recipient                        β”‚  β”‚
β”‚  β”‚  β”œβ”€ Update withdrawn amount                             β”‚  β”‚
β”‚  β”‚  └─ Emit "withdraw" event                               β”‚  β”‚
β”‚  β”‚                                                          β”‚  β”‚
β”‚  β”‚  cancel_stream(stream_id)                               β”‚  β”‚
β”‚  β”‚  β”œβ”€ Verify sender authorization                         β”‚  β”‚
β”‚  β”‚  β”œβ”€ Calculate recipient balance                         β”‚  β”‚
β”‚  β”‚  β”œβ”€ Transfer balance to recipient                       β”‚  β”‚
β”‚  β”‚  β”œβ”€ Calculate and refund unstreamed                     β”‚  β”‚
β”‚  β”‚  β”œβ”€ Remove stream from storage                          β”‚  β”‚
β”‚  β”‚  └─ Emit "canceled" event                               β”‚  β”‚
β”‚  β”‚                                                          β”‚  β”‚
β”‚  β”‚  balance_of(stream_id) -> i128                          β”‚  β”‚
β”‚  β”‚  β”œβ”€ Get stream data                                     β”‚  β”‚
β”‚  β”‚  β”œβ”€ Calculate elapsed ledgers                           β”‚  β”‚
β”‚  β”‚  β”œβ”€ Calculate streamed amount                           β”‚  β”‚
β”‚  β”‚  └─ Return (streamed - withdrawn)                       β”‚  β”‚
β”‚  β”‚                                                          β”‚  β”‚
β”‚  β”‚  get_stream(stream_id) -> Stream                        β”‚  β”‚
β”‚  β”‚  └─ Return stream data from storage                     β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚                                                                 β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚                  Storage Layer                           β”‚  β”‚
β”‚  β”‚                                                          β”‚  β”‚
β”‚  β”‚  DataKey::Stream(stream_id) -> Stream {                 β”‚  β”‚
β”‚  β”‚    sender: Address,                                     β”‚  β”‚
β”‚  β”‚    recipient: Address,                                  β”‚  β”‚
β”‚  β”‚    token: Address,                                      β”‚  β”‚
β”‚  β”‚    rate_per_ledger: i128,                               β”‚  β”‚
β”‚  β”‚    start_ledger: u32,                                   β”‚  β”‚
β”‚  β”‚    stop_ledger: u32,                                    β”‚  β”‚
β”‚  β”‚    withdrawn: i128                                      β”‚  β”‚
β”‚  β”‚  }                                                       β”‚  β”‚
β”‚  β”‚                                                          β”‚  β”‚
β”‚  β”‚  DataKey::NextStreamId -> u64                           β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                             β”‚
                             β”‚ Token Transfers
                             β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                      TOKEN CONTRACT                             β”‚
β”‚                   (Soroban Token / SAC)                         β”‚
β”‚                                                                 β”‚
β”‚  - Holds streamed tokens                                        β”‚
β”‚  - Transfers on create_stream                                   β”‚
β”‚  - Transfers on withdraw                                        β”‚
β”‚  - Transfers on cancel_stream                                   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Data Flow Diagrams

1. Create Stream Flow

User/Sender
    β”‚
    β”‚ 1. POST /api/v1/streams
    β”‚    {sender, recipient, token, amount, start, stop}
    β–Ό
Backend API
    β”‚
    β”‚ 2. Validate input
    β”‚ 3. Build transaction
    β–Ό
Streaming Contract
    β”‚
    β”‚ 4. Validate parameters
    β”‚ 5. Calculate rate_per_ledger = amount / (stop - start)
    β”‚ 6. Call token.transfer(sender -> contract, amount)
    β–Ό
Token Contract
    β”‚
    β”‚ 7. Transfer tokens
    β—„β”€β”€β”€β”˜
    β”‚
    β”‚ 8. Store stream data
    β”‚ 9. Emit "created" event
    β–Ό
Backend API
    β”‚
    β”‚ 10. Save to MongoDB
    β”‚ 11. Return stream_id
    β–Ό
User/Sender
    β”‚
    └─ Stream created! βœ…

2. Withdraw Flow

User/Recipient
    β”‚
    β”‚ 1. POST /api/v1/streams/:id/withdraw
    β”‚    {amount}
    β–Ό
Backend API
    β”‚
    β”‚ 2. Validate input
    β”‚ 3. Build transaction
    β–Ό
Streaming Contract
    β”‚
    β”‚ 4. Verify recipient authorization
    β”‚ 5. Calculate available = (rate Γ— elapsed) - withdrawn
    β”‚ 6. Validate amount <= available
    β”‚ 7. Call token.transfer(contract -> recipient, amount)
    β–Ό
Token Contract
    β”‚
    β”‚ 8. Transfer tokens
    β—„β”€β”€β”€β”˜
    β”‚
    β”‚ 9. Update withdrawn += amount
    β”‚ 10. Emit "withdraw" event
    β–Ό
Backend API
    β”‚
    β”‚ 11. Update MongoDB
    β”‚ 12. Return success
    β–Ό
User/Recipient
    β”‚
    └─ Tokens received! βœ…

3. Cancel Stream Flow

User/Sender
    β”‚
    β”‚ 1. DELETE /api/v1/streams/:id
    β–Ό
Backend API
    β”‚
    β”‚ 2. Build transaction
    β–Ό
Streaming Contract
    β”‚
    β”‚ 3. Verify sender authorization
    β”‚ 4. Calculate recipient_balance = streamed - withdrawn
    β”‚ 5. Calculate refund = total - streamed
    β”‚
    β”‚ 6. If recipient_balance > 0:
    β”‚    Call token.transfer(contract -> recipient, recipient_balance)
    β–Ό
Token Contract
    β”‚
    β”‚ 7. Transfer to recipient
    β—„β”€β”€β”€β”˜
    β”‚
    β”‚ 8. If refund > 0:
    β”‚    Call token.transfer(contract -> sender, refund)
    β–Ό
Token Contract
    β”‚
    β”‚ 9. Transfer refund to sender
    β—„β”€β”€β”€β”˜
    β”‚
    β”‚ 10. Remove stream from storage
    β”‚ 11. Emit "canceled" event
    β–Ό
Backend API
    β”‚
    β”‚ 12. Update MongoDB (status = canceled)
    β”‚ 13. Return success
    β–Ό
User/Sender
    β”‚
    └─ Stream canceled! Refund received! βœ…

4. Balance Query Flow

User/Anyone
    β”‚
    β”‚ 1. GET /api/v1/streams/:id/balance
    β–Ό
Backend API
    β”‚
    β”‚ 2. Build read transaction
    β–Ό
Streaming Contract
    β”‚
    β”‚ 3. Get stream data
    β”‚ 4. Get current ledger
    β”‚ 5. Calculate elapsed = current - start
    β”‚ 6. Calculate streamed = rate Γ— elapsed
    β”‚ 7. Calculate available = streamed - withdrawn
    β”‚ 8. Return available
    β–Ό
Backend API
    β”‚
    β”‚ 9. Return balance
    β–Ό
User/Anyone
    β”‚
    └─ Balance: X tokens βœ…

Component Interaction Matrix

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚              β”‚ Frontend β”‚ Backend  β”‚ Contract β”‚  Token   β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Frontend     β”‚    -     β”‚   HTTP   β”‚    -     β”‚    -     β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Backend      β”‚   HTTP   β”‚    -     β”‚   RPC    β”‚    -     β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Contract     β”‚    -     β”‚   RPC    β”‚    -     β”‚  Invoke  β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Token        β”‚    -     β”‚    -     β”‚  Invoke  β”‚    -     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Storage Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚              PERSISTENT STORAGE (On-Chain)              β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                         β”‚
β”‚  Stream(0) -> {                                         β”‚
β”‚    sender: GABC...,                                     β”‚
β”‚    recipient: GDEF...,                                  β”‚
β”‚    token: CXYZ...,                                      β”‚
β”‚    rate_per_ledger: 10,                                 β”‚
β”‚    start_ledger: 1000,                                  β”‚
β”‚    stop_ledger: 2000,                                   β”‚
β”‚    withdrawn: 5000                                      β”‚
β”‚  }                                                      β”‚
β”‚                                                         β”‚
β”‚  Stream(1) -> { ... }                                   β”‚
β”‚  Stream(2) -> { ... }                                   β”‚
β”‚                                                         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚             INSTANCE STORAGE (On-Chain)                 β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                         β”‚
β”‚  NextStreamId -> 3                                      β”‚
β”‚                                                         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚              MONGODB (Off-Chain)                        β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                         β”‚
β”‚  streams: [                                             β”‚
β”‚    {                                                    β”‚
β”‚      streamId: "0",                                     β”‚
β”‚      contractId: "C...",                                β”‚
β”‚      sender: "GABC...",                                 β”‚
β”‚      recipient: "GDEF...",                              β”‚
β”‚      tokenAddress: "CXYZ...",                           β”‚
β”‚      totalAmount: "10000",                              β”‚
β”‚      status: "active",                                  β”‚
β”‚      createdTxHash: "abc123...",                        β”‚
β”‚      createdAt: "2025-01-15T10:00:00Z"                  β”‚
β”‚    },                                                   β”‚
β”‚    ...                                                  β”‚
β”‚  ]                                                      β”‚
β”‚                                                         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Event Flow

Contract Events                Backend Processing
─────────────────             ──────────────────

created(stream_id)    ──────>  Save to MongoDB
  β”œβ”€ sender                     Update status: active
  β”œβ”€ recipient                  Store tx hash
  └─ total_amount               Index by sender/recipient

withdraw(stream_id)   ──────>  Update MongoDB
  β”œβ”€ recipient                  Update withdrawn amount
  └─ amount                     Log transaction

canceled(stream_id)   ──────>  Update MongoDB
  β”œβ”€ recipient_balance          Update status: canceled
  └─ refund_amount              Store cancel tx hash
                                Archive stream

Security Layers

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    USER LAYER                           β”‚
β”‚  - Wallet signature required                            β”‚
β”‚  - Private key never leaves wallet                      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                     β”‚
                     β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                   API LAYER                             β”‚
β”‚  - Input validation (express-validator)                 β”‚
β”‚  - Rate limiting                                        β”‚
β”‚  - CORS protection                                      β”‚
β”‚  - HTTPS only                                           β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                     β”‚
                     β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                 CONTRACT LAYER                          β”‚
β”‚  - Authorization checks (require_auth)                  β”‚
β”‚  - Balance validation                                   β”‚
β”‚  - Parameter validation                                 β”‚
β”‚  - Integer overflow protection                          β”‚
β”‚  - Atomic operations                                    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                     β”‚
                     β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                 NETWORK LAYER                           β”‚
β”‚  - Stellar consensus                                    β”‚
β”‚  - Transaction fees                                     β”‚
β”‚  - Ledger finality                                      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Deployment Architecture

Development          Testing              Production
───────────          ───────              ──────────

Local Testnet   ->   Stellar Testnet ->   Stellar Mainnet
    β”‚                     β”‚                     β”‚
    β”‚                     β”‚                     β”‚
    β–Ό                     β–Ό                     β–Ό
Local MongoDB       Test MongoDB         Production MongoDB
    β”‚                     β”‚                     β”‚
    β”‚                     β”‚                     β”‚
    β–Ό                     β–Ό                     β–Ό
Local Backend       Test Backend         Production Backend
    β”‚                     β”‚                     β”‚
    β”‚                     β”‚                     β”‚
    β–Ό                     β–Ό                     β–Ό
Local Frontend      Test Frontend        Production Frontend

This architecture provides:

  • βœ… Clear separation of concerns
  • βœ… Scalable design
  • βœ… Security at every layer
  • βœ… Event-driven updates
  • βœ… Efficient data flow
  • βœ… Production-ready structure