Advanced
This section covers advanced topics including telemetry, session persistence, registry internals, security best practices, and production deployment.
Telemetry & Metrics
PartyLayer includes an opt-in telemetry system for collecting anonymous usage metrics. Telemetry is disabled by default and respects user privacy.
Enabling Telemetry
Telemetry Configuration
Collected Metrics
The SDK collects 9 canonical metrics:
wallet_connect_attempts, Total connection attemptswallet_connect_success, Successful connectionssessions_created, New sessions createdsessions_restored, Sessions restored from storagerestore_attempts, Session restore attemptsregistry_fetch, Registry fetch operationsregistry_cache_hit, Registry cache hitsregistry_stale, Stale registry data usageerror_<CODE>, Error counts by error code
Session Persistence
PartyLayer automatically persists wallet sessions in localStorage so users don't need to reconnect on page reload.
How It Works
- Sessions are stored encrypted in
localStorageunder the keypartylayer_active_session - Sessions are bound to the dApp origin, a session from
app-a.comcannot be restored onapp-b.com - Expired sessions (past
expiresAt) are automatically pruned - On mount,
PartyLayerKitattempts to restore the last session via the adapter'srestore()method
Per-Wallet Restore Support
Each adapter implements its own restore() method. Behavior after a page reload depends on the wallet:
- Console, checks extension availability +
isConnected()state; restores if the wallet reports a live session - Loop, calls
loop.init()with a 5s auto-connect timeout; restores if the Loop auth token is still valid - Nightly, checks
window.nightly.cantonprovider is connected; restores if so - Cantor8, restores if the stored session token hasn't expired (pure metadata-based)
- Bron, requires a live OAuth access token; user must be signed in to Bron's auth provider
Handling Null Session
Restore is asynchronous. Your component may mount with session === null for a tick while restore runs, OR the user may have cleared their storage. Always guard:
Custom Storage
Provide a custom storage adapter for non-browser environments:
Registry Internals
The PartyLayer wallet registry is a JSON manifest of wallet metadata, published from a public repository and served from a single HTTPS origin. It is validated against a JSON Schema on every build. It is not signed today: see Integrity below.
How the Registry Works
- Fetch, On init, the SDK fetches the registry from
registry.partylayer.xyz - Validate, The payload is checked against the registry schema; entries that do not match are rejected
- Cache, Validated data is cached with ETag support for efficient updates
- Fallback, If the registry is unreachable, the SDK falls back to adapter-only discovery
Integrity
What protects the registry today is schema validation on every build, a gate that blocks the removal of a wallet's CIP-0103 native flag, a public commit history, and TLS to a single origin. Ed25519 signing is implemented in the client but is not enabled in production. Verification only runs when a consumer passes registryPublicKeys, and no signature is published for either channel, so the verification path does not execute. Do not treat registry contents as cryptographically attested.
Custom Registry
Registry Status
Monitor registry health with useRegistryStatus or the registry:status event:
Security
Content Security Policy (CSP)
If your dApp uses CSP headers, ensure these are allowed:
Origin Validation
PartyLayer validates the dApp origin during wallet connections. The origin is included in session metadata and verified by wallets. This prevents session hijacking across domains.
Transport Security
- PostMessage, Origin is validated on every message exchange
- Deep Links, HTTPS-only with app-link verification
- Injected, Direct in-process communication (no network)
- QR/Popup, Encrypted channel with session key exchange
Production Checklist
Before deploying to production:
- Set
networkto"mainnet" - Use the
"stable"registry channel (default) - Test with all supported wallets
- Add error handling for all operations (connect, sign, submit)
- Subscribe to the
errorevent for global error reporting - Configure CSP headers for your domain
- Call
client.destroy()on app unmount (automatic withPartyLayerKit) - Test session restoration (page reload should maintain connection)
- Verify registry fallback works (test with network offline)
- If using telemetry, configure your endpoint and sampling rate
Lower-Level Provider (PartyLayerProvider)
If you need more control than PartyLayerKit provides, use the lower-level PartyLayerProvider directly: