# 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