NEAR Integration Design
NEAR Intents Integration Design
Section titled “NEAR Intents Integration Design”Design document for integrating NEAR 1Click API with SIP Protocol SDK.
- Enable privacy-preserving cross-chain swaps via NEAR Intents
- Shield recipient identity using stealth addresses
- Support compliant mode with selective disclosure
- Provide seamless developer experience
Non-Goals
Section titled “Non-Goals”- Hiding input amounts (requires protocol-level changes)
- Solver-side privacy (out of scope for MVP)
- Custom solver implementation (use existing network)
Architecture
Section titled “Architecture”Component Overview
Section titled “Component Overview”┌──────────────────────────────────────────────────────────────────────────┐│ SIP SDK ││ ┌────────────────────────────────────────────────────────────────────┐ ││ │ Intent Layer │ ││ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────────────┐│ ││ │ │IntentBuilder│ │PrivacyLayer │ │ NEARIntentsAdapter ││ ││ │ │(existing) │──│(existing) │──│ (new) ││ ││ │ └─────────────┘ └─────────────┘ └─────────────────────────────┘│ ││ └────────────────────────────────────────────────────────────────────┘ ││ │ ││ ┌────────────────────────────────┼───────────────────────────────────┐ ││ │ Stealth & Commitment Layer │ ││ │ ┌─────────────┐ ┌─────────────┐ ┌──────────────────────────┐ │ ││ │ │ Stealth │ │ Pedersen │ │ Viewing Keys │ │ ││ │ │ Addresses │ │ Commitments │ │ │ │ ││ │ └─────────────┘ └─────────────┘ └──────────────────────────┘ │ ││ └────────────────────────────────────────────────────────────────────┘ ││ │ ││ ┌────────────────────────────────┼───────────────────────────────────┐ ││ │ Network Adapters │ ││ │ ┌─────────────┐ ┌─────────────┐ ┌──────────────────────────┐ │ ││ │ │ OneClick │ │ SolverRelay │ │ Status Tracker │ │ ││ │ │ Client │ │ Client │ │ │ │ ││ │ └─────────────┘ └─────────────┘ └──────────────────────────┘ │ ││ └────────────────────────────────────────────────────────────────────┘ │└──────────────────────────────────────────────────────────────────────────┘ │ ▼ ┌───────────────────────────┐ │ NEAR 1Click API │ │ (External Service) │ └───────────────────────────┘New Components
Section titled “New Components”1. NEARIntentsAdapter
Section titled “1. NEARIntentsAdapter”Purpose: Bridge between SIP intents and NEAR 1Click API
Responsibilities:
- Convert SIP ShieldedIntent to OneClickQuoteRequest
- Generate stealth addresses for recipients
- Handle quote lifecycle
- Track swap status
Interface:
interface NEARIntentsAdapter { // Convert SIP intent to 1Click quote request prepareQuote(intent: ShieldedIntent): Promise<OneClickQuoteRequest>
// Request quote from 1Click API getQuote(request: OneClickQuoteRequest): Promise<OneClickQuoteResponse>
// Submit deposit notification submitDeposit(deposit: OneClickDepositSubmit): Promise<void>
// Track swap status getStatus(depositAddress: string): Promise<OneClickStatusResponse>
// Full flow: intent → quote → deposit → status executeIntent(intent: ShieldedIntent): Promise<SwapResult>}2. OneClickClient
Section titled “2. OneClickClient”Purpose: HTTP client for 1Click API
Interface:
interface OneClickClient { // Get supported tokens getTokens(): Promise<OneClickToken[]>
// Request swap quote quote(request: OneClickQuoteRequest): Promise<OneClickQuoteResponse>
// Submit deposit transaction submitDeposit(deposit: OneClickDepositSubmit): Promise<OneClickQuoteResponse>
// Check swap status getStatus(depositAddress: string, memo?: string): Promise<OneClickStatusResponse>}3. SolverRelayClient (Optional)
Section titled “3. SolverRelayClient (Optional)”Purpose: Direct solver integration for advanced use cases
Interface:
interface SolverRelayClient { // Request quote directly from solvers quote(request: SolverQuoteRequest): Promise<SolverQuoteResponse[]>
// Publish signed intent publishIntent(intent: SolverPublishIntent): Promise<void>
// Get intent status getStatus(quoteHash: string): Promise<SolverStatusResponse>
// WebSocket for real-time updates subscribe(channel: 'quote' | 'quote_status'): AsyncIterator<SolverQuoteEvent>}Privacy Integration
Section titled “Privacy Integration”Stealth Address Flow
Section titled “Stealth Address Flow”┌─────────────────┐ ┌─────────────────┐│ Sender │ │ Recipient ││ │ │ ││ Has: meta addr │ │ Has: meta addr ││ of recipient │ │ + private keys │└────────┬────────┘ └────────┬────────┘ │ │ │ 1. Generate stealth address │ │ from recipient's meta addr │ ▼ │┌─────────────────┐ ││ Stealth Address │ ││ + Ephemeral Key │ │└────────┬────────┘ │ │ │ │ 2. Use stealth as recipient in │ │ OneClickQuoteRequest │ ▼ │┌─────────────────┐ ││ 1Click API │ ││ Quote + Deposit │ │└────────┬────────┘ │ │ │ │ 3. Funds sent to stealth addr │ │ on destination chain │ ▼ │┌─────────────────┐ ││ Destination │ ││ Chain │◀─────── 4. Recipient scans, derives ──┘│ (stealth addr) │ private key, claims funds└─────────────────┘Privacy Modes
Section titled “Privacy Modes”| Mode | Recipient | Amounts | Viewer Access |
|---|---|---|---|
transparent | Plain address | Visible | N/A |
shielded | Stealth address | Visible* | None |
compliant | Stealth address | Visible* | Viewing key holders |
*Amount visibility depends on destination chain capabilities
Integration with Viewing Keys
Section titled “Integration with Viewing Keys”For compliant mode, generate viewing keys that allow auditors to:
- Verify recipient: Derive public key from viewing key, confirm stealth address ownership
- Track history: Scan for all transactions to viewing key holder
- Audit amounts: Decrypt any encrypted metadata (future)
// Compliant mode flowconst viewingKey = generateViewingKey(derivationPath)
const intent = await new IntentBuilder() .input('near', 'NEAR', 100n) .output('eth', 'ETH', 0.03n) .privacy('compliant') .recipient(recipientMetaAddress) .viewingKey(viewingKey) .build()
// Auditor can verify with viewing keyconst isForRecipient = verifyWithViewingKey( stealthAddress, ephemeralPubKey, viewingKey)Data Flow
Section titled “Data Flow”Intent Creation to Swap Execution
Section titled “Intent Creation to Swap Execution”1. User creates intent via SDK ───────────────────────────────────────────────────────────────── const intent = await createShieldedIntent({ input: { chain: 'near', symbol: 'NEAR', amount: 100n }, output: { chain: 'eth', symbol: 'ETH', minAmount: 0.03n }, privacy: 'shielded', recipientMetaAddress: '...', })
2. NEARIntentsAdapter converts to 1Click request ───────────────────────────────────────────────────────────────── - Generate stealth address from recipientMetaAddress - Map SIP asset format to Defuse asset identifiers - Construct OneClickQuoteRequest
3. OneClickClient fetches quote ───────────────────────────────────────────────────────────────── POST /v0/quote → OneClickQuoteResponse - depositAddress: where to send input tokens - amountIn/amountOut: swap amounts - deadline: expiration
4. User deposits to depositAddress ───────────────────────────────────────────────────────────────── - On source chain (NEAR) - Transaction monitored by 1Click
5. 1Click executes swap ───────────────────────────────────────────────────────────────── - Solvers compete to fulfill - Winner executes on destination chain - Funds sent to stealth address
6. Recipient claims funds ───────────────────────────────────────────────────────────────── - Scans for stealth addresses - Derives private key - Spends from stealth addressAPI Design
Section titled “API Design”High-Level API (Recommended)
Section titled “High-Level API (Recommended)”import { SIPClient } from '@sip-protocol/sdk'
const client = new SIPClient({ nearIntents: { baseUrl: 'https://1click.chaindefuser.com', jwtToken: process.env.NEAR_INTENTS_JWT, },})
// Simple swap with privacyconst result = await client.swap({ from: { chain: 'near', amount: '100 NEAR' }, to: { chain: 'eth', asset: 'ETH' }, recipient: recipientMetaAddress, privacy: 'shielded',})
console.log(result.status) // 'SUCCESS'console.log(result.txHash) // destination chain txLow-Level API (Advanced)
Section titled “Low-Level API (Advanced)”import { NEARIntentsAdapter, OneClickClient} from '@sip-protocol/sdk'
const oneClick = new OneClickClient({ baseUrl: '...' })const adapter = new NEARIntentsAdapter({ oneClick })
// Manual control over each stepconst intent = await createShieldedIntent({ ... })const quote = await adapter.getQuote( await adapter.prepareQuote(intent))
// Deposit separatelyconst depositTx = await wallet.send(quote.depositAddress, quote.amountIn)
// Track statusconst status = await adapter.getStatus(quote.depositAddress)Error Handling
Section titled “Error Handling”Error Categories
Section titled “Error Categories”- Quote Errors: Invalid assets, insufficient liquidity, amount too low
- Network Errors: Timeout, rate limiting, server errors
- Deposit Errors: Wrong amount, expired quote, failed deposit
- Settlement Errors: Solver failure, chain issues
Error Mapping
Section titled “Error Mapping”enum SIPSwapError { // Quote phase INSUFFICIENT_LIQUIDITY = 'INSUFFICIENT_LIQUIDITY', UNSUPPORTED_PAIR = 'UNSUPPORTED_PAIR', AMOUNT_TOO_LOW = 'AMOUNT_TOO_LOW',
// Deposit phase QUOTE_EXPIRED = 'QUOTE_EXPIRED', DEPOSIT_FAILED = 'DEPOSIT_FAILED', AMOUNT_MISMATCH = 'AMOUNT_MISMATCH',
// Settlement phase SOLVER_FAILURE = 'SOLVER_FAILURE', SETTLEMENT_TIMEOUT = 'SETTLEMENT_TIMEOUT',
// Privacy INVALID_META_ADDRESS = 'INVALID_META_ADDRESS', STEALTH_GENERATION_FAILED = 'STEALTH_GENERATION_FAILED',}Testing Strategy
Section titled “Testing Strategy”Unit Tests
Section titled “Unit Tests”- Asset identifier mapping
- Stealth address generation for recipients
- Quote request construction
- Status parsing
Integration Tests
Section titled “Integration Tests”- Dry quote requests (no deposit address)
- Full quote lifecycle (with testnet)
- Error handling scenarios
Mocking
Section titled “Mocking”// MockOneClickClient for testingclass MockOneClickClient implements OneClickClient { async quote(request: OneClickQuoteRequest): Promise<OneClickQuoteResponse> { return { quoteId: 'mock_quote_123', depositAddress: '0xmock...', amountIn: request.amount, amountOut: calculateMockOutput(request), // ... } }}Implementation Plan
Section titled “Implementation Plan”Phase 1: Core Integration
Section titled “Phase 1: Core Integration”- Implement
OneClickClientHTTP client - Implement basic
NEARIntentsAdapter - Add stealth address integration
- Unit tests
Phase 2: Full Flow
Section titled “Phase 2: Full Flow”- End-to-end swap execution
- Status tracking and polling
- Error handling
- Integration tests with testnet
Phase 3: Advanced Features
Section titled “Phase 3: Advanced Features”- Viewing key integration for compliant mode
- Solver relay direct integration (optional)
- Batch swap support
- WebSocket status updates
Security Considerations
Section titled “Security Considerations”- API Keys: JWT tokens stored securely, never logged
- Deposit Addresses: Verify quote signature before depositing
- Stealth Keys: Generated client-side, never sent to API
- Amount Validation: Verify amountOut against expectations
- Deadline Handling: Refuse quotes with short deadlines
Open Questions
Section titled “Open Questions”-
Testnet: NEAR Intents has no testnet - how to test?
- Option A: Dry quotes only
- Option B: Minimal mainnet tests
- Option C: Mock server
-
Zcash Integration: How to bridge to Zcash shielded pools?
- Requires Zcash-specific adapter
- May need different swap path
-
Fee Handling: Where to apply SIP protocol fees?
- Option A: Add to appFees array
- Option B: Separate fee layer
References
Section titled “References”- NEAR 1Click API Reference - Full API documentation
- NEAR Privacy Analysis - Privacy threat model
- SIP Specification - Protocol specification