PartyLayerDocs
Try Demo

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

typescript
import { createPartyLayer } from '@partylayer/sdk';

const client = createPartyLayer({
  network: 'mainnet',
  app: { name: 'My dApp' },
  telemetry: {
    enabled: true,
    endpoint: 'https://metrics.my-dapp.com/collect',
    sampleRate: 0.1,        // 10% sampling
    batchSize: 10,           // Send in batches of 10
    flushIntervalMs: 30000,  // Flush every 30s
  },
});

Telemetry Configuration

PropTypeDefaultDescription
enabledbooleanfalseEnable/disable telemetry collection.
endpointstringURL to send telemetry data to.
sampleRatenumber1.0Sampling rate (0.0 to 1.0).
appIdstringApp identifier (SHA-256 hashed before sending).
includeOriginbooleanfalseInclude dApp origin URL in metrics.
batchSizenumber10Number of events to batch before sending.
flushIntervalMsnumber30000Interval between flushes (ms).

Collected Metrics

The SDK collects 9 canonical metrics:

  • wallet_connect_attempts — Total connection attempts
  • wallet_connect_success — Successful connections
  • sessions_created — New sessions created
  • sessions_restored — Sessions restored from storage
  • restore_attempts — Session restore attempts
  • registry_fetch — Registry fetch operations
  • registry_cache_hit — Registry cache hits
  • registry_stale — Stale registry data usage
  • error_<CODE> — Error counts by error code
💡 Privacy
No PII is ever collected. App IDs are SHA-256 hashed before transmission. All payloads are validated before sending.

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 localStorage
  • Sessions are bound to the dApp origin — a session from app-a.com cannot be restored on app-b.com
  • Expired sessions (past expiresAt) are automatically pruned
  • On mount, PartyLayerKit attempts to restore the last session via the adapter's restore() method

Custom Storage

Provide a custom storage adapter for non-browser environments:

typescript
import { createPartyLayer } from '@partylayer/sdk';

const client = createPartyLayer({
  network: 'mainnet',
  app: { name: 'My dApp' },
  storage: {
    get: (key) => myCustomStorage.get(key),
    set: (key, value) => myCustomStorage.set(key, value),
    remove: (key) => myCustomStorage.delete(key),
    clear: () => myCustomStorage.clear(),
  },
});

Registry Internals

The PartyLayer wallet registry is a signed JSON manifest containing metadata for all verified Canton wallets.

How the Registry Works

  • Fetch — On init, the SDK fetches the registry from registry.partylayer.xyz
  • Verify — The registry payload is verified against embedded public keys
  • Cache — Verified data is cached with ETag support for efficient updates
  • Fallback — If the registry is unreachable, the SDK falls back to adapter-only discovery

Custom Registry

typescript
<PartyLayerKit
  network="mainnet"
  appName="My dApp"
  registryUrl="https://my-registry.example.com"
  channel="beta"
>

Registry Status

Monitor registry health with useRegistryStatus or the registry:status event:

typescript
client.on('registry:status', (event) => {
  const { status } = event;

  if (status.error) {
    console.warn('Registry error:', status.error.message);
    console.log('Using cached data:', status.source === 'cache');
  }

  console.log('Verified:', status.verified);
  console.log('Stale:', status.stale);
});

Security

Content Security Policy (CSP)

If your dApp uses CSP headers, ensure these are allowed:

text
connect-src 'self' https://registry.partylayer.xyz;
frame-src 'self';  /* For popup-based wallets */

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 network to "mainnet"
  • Use the "stable" registry channel (default)
  • Test with all supported wallets
  • Add error handling for all operations (connect, sign, submit)
  • Subscribe to the error event for global error reporting
  • Configure CSP headers for your domain
  • Call client.destroy() on app unmount (automatic with PartyLayerKit)
  • 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
⚠️ Warning
Never expose registry public keys or telemetry endpoints in client-side code if they contain sensitive information. Use environment variables and server-side configuration.

Lower-Level Provider (PartyLayerProvider)

If you need more control than PartyLayerKit provides, use the lower-level PartyLayerProvider directly:

tsx
import { PartyLayerProvider, ThemeProvider } from '@partylayer/react';
import { createPartyLayer } from '@partylayer/sdk';

// Create and configure the client manually
const client = createPartyLayer({
  network: 'mainnet',
  app: { name: 'My dApp', origin: 'https://my-dapp.com' },
  registryUrl: 'https://my-registry.example.com',
  storage: customStorageAdapter,
  telemetry: { enabled: true, endpoint: '...' },
  logger: customLogger,
});

function App() {
  return (
    <ThemeProvider theme="dark">
      <PartyLayerProvider client={client} network="mainnet">
        {/* Full manual control */}
      </PartyLayerProvider>
    </ThemeProvider>
  );
}
PreviousToken Transfers