# Parsec Connect — SDK Reference Browser SDK for connecting web dApps to **Parsec Wallet**, a sovereign Algorand desktop wallet. Parsec runs a local WebSocket server on `localhost:9876`. This SDK detects it, connects, and provides Pera-compatible transaction signing. ## Quick Start ```html ``` ## Installation Include the SDK from your server: ```html ``` Or import as a module: ```javascript const { ParsecConnect, ParsecError } = require('./modules/parsec-connect'); ``` ## Constructor ```javascript const parsec = new ParsecConnect({ port: 9876, // Parsec server port (default 9876) debug: false, // Enable console logging requestTimeout: 120000, // Sign request timeout in ms (default 120s) connectTimeout: 5000, // WebSocket connect timeout in ms autoReconnect: true, // Auto-reconnect on unexpected close maxReconnectAttempts: 3, // Max reconnect attempts onDisconnect: (info) => {}, // Called on disconnect onReconnect: () => {}, // Called on successful reconnect onSignRequest: (req) => {}, // Called when sign request is pending }); ``` ## API Reference ### `isAvailable()` → `Promise` Probe localhost to check if Parsec Wallet is running. ```javascript const status = await parsec.isAvailable(); // { // available: true, // unlocked: true, // hasAccount: true, // version: "0.1.0", // wallet: "parsec" // } ``` ### `poll(intervalMs, callback)` → `Function` Periodically check Parsec availability. Returns a stop function. ```javascript const stop = parsec.poll(3000, (status) => { btn.disabled = !status.available; btn.textContent = status.available ? 'Connect Parsec' : 'Parsec not detected'; }); // Later: stop(); ``` ### `connect()` → `Promise` Connect via WebSocket and retrieve accounts. ```javascript try { const accounts = await parsec.connect(); console.log('Address:', accounts[0]); } catch (e) { if (e.code === ParsecConnect.ERRORS.WALLET_LOCKED) { alert('Please unlock Parsec Wallet first'); } } ``` ### `signTransaction(txnGroups, message?)` → `Promise` Sign transactions. The user sees an approval dialog in Parsec. **Pera-compatible interface** — drop-in replacement: ```javascript // Same format as peraWallet.signTransaction() const signed = await parsec.signTransaction([[ { txn: paymentTxn, signers: [myAddress] }, { txn: appCallTxn, signers: [myAddress] }, ]], 'Verify chain #8453 (1 ALGO)'); ``` The `message` parameter is displayed to the user in Parsec's approval dialog. ### `getAccounts()` → `string[]` Get connected account addresses. ### `getAddress()` → `string | null` Get the primary connected address. ### `isConnected()` → `boolean` Check if WebSocket is currently open. ### `reconnect()` → `Promise` Disconnect and reconnect (e.g. after wallet unlock). ### `disconnect()` Close the WebSocket connection and clear state. ## Error Handling All errors are `ParsecError` instances with a `.code` property: ```javascript try { const signed = await parsec.signTransaction(txnGroups); } catch (e) { switch (e.code) { case ParsecConnect.ERRORS.USER_REJECTED: // 4001 — user clicked Reject console.log('User declined'); break; case ParsecConnect.ERRORS.WALLET_LOCKED: // 4100 — wallet locked console.log('Unlock Parsec first'); break; case ParsecConnect.ERRORS.TIMEOUT: // 4002 — approval timed out console.log('Request timed out'); break; case ParsecConnect.ERRORS.DISCONNECTED: // 4003 — connection lost console.log('Lost connection to Parsec'); break; } } ``` ### Error Codes | Code | Name | Meaning | |------|------|---------| | 4001 | USER_REJECTED | User rejected the sign request | | 4002 | TIMEOUT | Sign request timed out (120s default) | | 4003 | DISCONNECTED | WebSocket connection lost | | 4100 | WALLET_LOCKED | Wallet is locked or no account | | -32700 | PARSE_ERROR | Invalid JSON received | | -32601 | METHOD_NOT_FOUND | Unknown RPC method | | -32602 | INVALID_PARAMS | Invalid method parameters | ## Wallet Selector Pattern Support both Pera and Parsec in your dApp: ```javascript // Abstraction layer let wallet = { type: null, address: null }; async function connectPera() { const peraWallet = new PeraWalletConnect(); const accounts = await peraWallet.connect(); wallet = { type: 'pera', address: accounts[0], sign: (txns) => peraWallet.signTransaction(txns), disconnect: () => peraWallet.disconnect(), }; } async function connectParsec() { const parsec = new ParsecConnect(); const accounts = await parsec.connect(); wallet = { type: 'parsec', address: accounts[0], sign: (txns, msg) => parsec.signTransaction(txns, msg), disconnect: () => parsec.disconnect(), }; } // Same signing code for both: const signed = await wallet.sign([[{ txn, signers: [wallet.address] }]], 'My dApp action'); ``` ## How It Works ``` Web dApp (browser) Parsec Wallet (Tauri desktop) | | | 1. fetch /health ───────────────────> | HTTP health check | <──────────────────── { ok, unlocked} | | | | 2. WebSocket /ws ───────────────────> | WS upgrade | <──────────────────── connected | | | | 3. parsec_accounts ─────────────────> | JSON-RPC | <──── { accounts: [{ address }] } | | | | 4. parsec_signTransactions ─────────> | User sees approval dialog | { txns: [base64...], message } | ┌──────────────────┐ | | │ Sign Request │ | (user reviews in Parsec) | │ Origin: dapp.com │ | | │ 2 transactions │ | | │ [Reject] [Sign] │ | | └──────────────────┘ | <──── { signedTxns: [base64...] } | User approves | | | 5. sendRawTransaction ──────────────> | Algorand network ``` ## Protocol Reference The WebSocket protocol is JSON-RPC 2.0: ### `parsec_accounts` ```json → { "id": 1, "method": "parsec_accounts", "params": {} } ← { "id": 1, "result": { "accounts": [{ "address": "ALGO...", "label": "Parsec", "network": "mainnet" }] } } ``` ### `parsec_signTransactions` ```json → { "id": 2, "method": "parsec_signTransactions", "params": { "txns": ["base64-encoded-unsigned-txn-bytes", ...], "origin": "https://agenticplace.pythai.net", "message": "Mint aORC NFT (1 ALGO)" } } ← { "id": 2, "result": { "signedTxns": ["base64-signed-bytes", ...] } } ``` ### `parsec_network` ```json → { "id": 3, "method": "parsec_network", "params": {} } ← { "id": 3, "result": { "network": "mainnet", "algodUrl": "https://mainnet-api.4160.nodely.dev" } } ``` ### `ping` ```json → { "id": 0, "method": "ping", "params": {} } ← { "id": 0, "result": { "pong": true } } ``` ## HTTP Endpoints | Endpoint | Purpose | |----------|---------| | `GET /parsec/v1/connect/health` | Quick detection: `{ status, unlocked, hasAccount }` | | `GET /parsec/v1/connect/info` | Detailed: `{ network, capabilities, activeSessions }` | | `GET /parsec/v1/connect/ws` | WebSocket upgrade for JSON-RPC | ## Browser Compatibility - Chrome 80+, Firefox 78+, Safari 14+, Edge 80+ - Requires `localhost` access (not available in some restricted environments) - Desktop only — Parsec is a Tauri desktop app, not a mobile wallet - For mobile users, fall back to Pera Wallet ## Version ParsecConnect SDK v1.1.0 | Protocol parsec-connect/1.0