Skip to content

Architecture

SIP Protocol operates as an application layer between user applications and the NEAR Intents settlement system.

flowchart TB
    subgraph APP["Application Layer"]
        direction LR
        DApps["DApps"]
        Wallets["Wallets"]
        DAOs["DAOs"]
    end

    subgraph SDK["@sip-protocol/sdk"]
        direction LR
        IB["Intent Builder"]
        SA["Stealth Address"]
        PM["Privacy Manager"]
        WA["Wallet Adapters"]
    end

    subgraph PRIVACY["Privacy Layer (SIP)"]
        direction TB
        subgraph Primitives["Cryptographic Primitives"]
            direction LR
            PC["Pedersen Commitments"]
            ST["Stealth Addresses"]
            VK["Viewing Keys"]
        end
        subgraph Proofs["ZK Proofs"]
            direction LR
            FP["Funding Proof"]
            VP["Validity Proof"]
            FFP["Fulfillment Proof"]
        end
    end

    subgraph SETTLE["Settlement Layer"]
        direction LR
        API["1Click API"]
        Solvers["Solvers"]
        CS["Chain Signatures"]
    end

    subgraph CHAINS["Blockchain Layer"]
        direction LR
        NEAR["NEAR"]
        ETH["Ethereum"]
        SOL["Solana"]
        ZEC["Zcash"]
        BTC["Bitcoin"]
    end

    APP --> SDK
    SDK --> PRIVACY
    PRIVACY --> SETTLE
    SETTLE --> CHAINS

    style APP fill:#1e1b4b,stroke:#8b5cf6,stroke-width:2px
    style SDK fill:#312e81,stroke:#8b5cf6,stroke-width:2px
    style PRIVACY fill:#4c1d95,stroke:#a78bfa,stroke-width:3px
    style SETTLE fill:#312e81,stroke:#8b5cf6,stroke-width:2px
    style CHAINS fill:#1e1b4b,stroke:#8b5cf6,stroke-width:2px

The main entry point that orchestrates all operations:

const sip = new SIP({
network: 'testnet',
proofProvider: new MockProofProvider(),
})

Fluent API for constructing shielded intents:

const intent = await sip
.intent()
.input('solana', 'SOL', amount)
.output('ethereum', 'ETH')
.privacy(PrivacyLevel.SHIELDED)
.build()

Chain-specific wallet integrations:

AdapterChainProvider
EthereumWalletAdapterEthereumMetaMask, WalletConnect
SolanaWalletAdapterSolanaPhantom, Solflare
MockWalletAdapterTestingMock provider

ZK proof generation interfaces:

ProviderStatusUse Case
MockProofProviderAvailableTesting, development
NoirProofProviderPlannedProduction
flowchart LR
    A["User Intent"] --> B["Standard Intent"] --> C["Solver"] --> D["Settlement"]
    style A fill:#1e1b4b,stroke:#8b5cf6
    style B fill:#1e1b4b,stroke:#8b5cf6
    style C fill:#1e1b4b,stroke:#8b5cf6
    style D fill:#1e1b4b,stroke:#8b5cf6

No privacy features. All data visible on-chain.

flowchart TB
    A["User Intent"] --> B["Generate Stealth Address"]
    B --> C["Create Pedersen Commitments"]
    C --> D["Generate ZK Proofs"]
    D --> E["Submit Shielded Intent"]
    E --> F["Solver Fulfills"]
    F --> G["Fulfillment Proof"]
    G --> H["Settlement to Stealth Address"]

    B -.- B1["Recipient Privacy"]
    C -.- C1["Amount Privacy"]
    D -.- D1["Funding + Validity"]
    F -.- F1["Only sees commitments"]

    style A fill:#4c1d95,stroke:#a78bfa,stroke-width:2px
    style B fill:#4c1d95,stroke:#a78bfa
    style C fill:#4c1d95,stroke:#a78bfa
    style D fill:#4c1d95,stroke:#a78bfa
    style E fill:#4c1d95,stroke:#a78bfa
    style F fill:#312e81,stroke:#8b5cf6
    style G fill:#312e81,stroke:#8b5cf6
    style H fill:#22c55e,stroke:#86efac,stroke-width:2px

Same as shielded, plus:

  • Encrypt transaction metadata with viewing key
  • Auditor can decrypt specific transactions
  • ViewingProof for audit reports
flowchart TB
    A["Shielded Intent"] --> B["Encrypt with Viewing Key"]
    B --> C["Store Encrypted Metadata"]
    C --> D["Auditor Requests Access"]
    D --> E["Decrypt with Viewing Key"]
    E --> F["Generate ViewingProof"]

    style A fill:#4c1d95,stroke:#a78bfa
    style B fill:#4c1d95,stroke:#a78bfa
    style C fill:#312e81,stroke:#8b5cf6
    style D fill:#312e81,stroke:#8b5cf6
    style E fill:#22c55e,stroke:#86efac
    style F fill:#22c55e,stroke:#86efac
C = value·G + blinding·H
  • Perfectly hiding: Cannot extract value from C
  • Computationally binding: Cannot change value after commit
  • Homomorphic: C₁ + C₂ commits to sum of values

Based on EIP-5564:

  1. Recipient publishes meta-address (P, Q)
  2. Sender generates ephemeral key r
  3. Sender computes stealth address A = Q + H(r·P)·G
  4. Recipient scans for R values, derives private key

Hierarchical key derivation:

Master Viewing Key
├── Full Viewing Key (all transactions)
├── Auditor Key (time-limited)
└── Transaction Key (single transaction)

Encryption: XChaCha20-Poly1305 with HKDF key derivation.

Connects to NEAR’s 1Click API for cross-chain settlement:

const adapter = new NEARIntentsAdapter({
network: 'testnet',
endpoint: 'https://1click.chaindefuser.com',
})

Handles Zcash-specific shielded transactions:

const zcash = new ZcashShieldedService({
rpcUrl: 'http://localhost:8232',
})
FilePurpose
packages/sdk/src/sip.tsMain SIP client
packages/sdk/src/intent.tsIntentBuilder
packages/sdk/src/stealth.tsStealth addresses
packages/sdk/src/crypto.tsPedersen commitments
packages/sdk/src/privacy.tsViewing keys
packages/sdk/src/proofs/Proof providers
packages/sdk/src/adapters/Network/wallet adapters
OperationTime (avg)
Generate meta-address0.9ms
Derive stealth address5.4ms
Create commitment7.2ms
Verify commitment6.6ms
Full shielded intent~25ms

Measured on Apple M1, Node.js 20.

  • Language: TypeScript (strict)
  • Monorepo: pnpm + Turborepo
  • Crypto: @noble/curves, @noble/hashes, @noble/ciphers
  • Testing: Vitest
  • CI/CD: GitHub Actions