@tonyboyle/solana-wallet-universal-links-generator
v2.0.1
Published
A minimal, stateless TypeScript SDK for generating deep links to mobile Solana wallets
Maintainers
Readme
@tonyboyle/solana-wallet-universal-links-generator
A stateless deep link generator and response decoder for mobile Solana wallets. This SDK provides utilities to generate universal links and deep links for wallet interactions and parse callback responses - you provide the storage and state management.
What This SDK Does
- Link Generation: Creates universal links and deep links for wallet operations (connect, sign, etc.)
- Response Parsing: Decodes and validates wallet callback responses
- End-to-End Encryption: Built-in encryption for sensitive data using x25519 key exchange
- Multi-Wallet Support: Works with Phantom, Solflare, and Backpack wallets
What You Need to Provide
- Session Storage: Store connection sessions, encryption keys, and user state
- State Management: Handle connection state, loading states, and user authentication
- Routing/Linking: Handle deep link callbacks in your app (React Native Linking, etc.)
- Persistence: Save wallet sessions across app restarts (AsyncStorage, SecureStore, etc.)
This SDK is intentionally stateless - it focuses on generating secure wallet links and parsing responses. You maintain control over how sessions and state are managed in your application.
Features
- Stateless: No session management or state storage - you control the data flow
- Type-safe: Full TypeScript support with typed parameters using generics
- Dual link format: Generate universal links or deep links via a single
linkTypeargument - Multi-wallet: Supports Phantom, Solflare, and Backpack
- Encrypted: Built-in encryption support using x25519 key exchange (TweetNaCl.js)
- Auto-encryption: Payloads are automatically encrypted when encryption parameters are provided
- Response Parsing: Type-safe response parsers for all wallet methods with automatic error handling
Installation
npm install @tonyboyle/solana-wallet-universal-links-generatorQuick Start
Using Individual Command Functions
import { connect, parseConnectResponse } from '@tonyboyle/solana-wallet-universal-links-generator';
// Connect to Phantom (keys are generated automatically)
const { url, dappPublicKey, dappPrivateKey } = connect('phantom', {
app_url: 'https://myapp.com',
redirect_link: 'myapp://wallet/callback',
cluster: 'mainnet-beta'
});
// Open url in the wallet app, then parse the callback it returns
const result = parseConnectResponse(callbackUrl, dappPrivateKey);
if ('errorCode' in result) {
console.error('Connection failed:', result.errorMessage);
} else {
console.log('Connected!', result.publicKey);
console.log('Session token:', result.session);
// Store this — needed for all subsequent signing operations
console.log('Wallet encryption key:', result.walletEncryptionPublicKey);
}Using the Class-based API
import { UniversalWalletAdapter } from '@tonyboyle/solana-wallet-universal-links-generator';
const adapter = new UniversalWalletAdapter();
const { url, dappPublicKey, dappPrivateKey } = adapter.connect('phantom', {
app_url: 'https://myapp.com',
redirect_link: 'myapp://wallet/callback',
cluster: 'mainnet-beta'
});Supported Wallets
| Wallet | Universal Link Base | Deep Link Base |
|--------|-------------------|----------------|
| Phantom | https://phantom.app/ul/v1 | phantom://v1 |
| Solflare | https://solflare.com/ul/v1 | solflare://ul/v1 |
| Backpack | https://backpack.app/ul/v1 | backpack://ul/v1 |
By default all methods generate universal links. Pass 'deeplink' as the third argument to generate deep links instead:
// Universal link (default)
const { url } = connect('phantom', params);
// → https://phantom.app/ul/v1/connect?...
// Deep link
const { url } = connect('phantom', params, 'deeplink');
// → phantom://v1/connect?...Documentation
Core Documentation
- Getting Started - Installation, quick start, and basic concepts
- API Reference - Complete method signatures and parameters
- Response Types - Response parsing and type definitions
- Encryption - Security features and best practices
Examples and Guides
- React Native + Expo Example - Complete implementation with Zustand
Supported Methods
- Connect: Establish wallet connection and get session token
- Disconnect: Terminate wallet session
- Sign Transaction: Sign a single transaction (wallet doesn't submit)
- Sign All Transactions: Sign multiple transactions (wallet doesn't submit)
- Sign and Send Transaction: Sign and submit transaction (deprecated in Phantom)
- Sign Message: Sign an arbitrary message
Security Notes
- This SDK is stateless - you control session storage and key management
- Store private keys securely - use SecureStore, not AsyncStorage
- Validate all responses - always check for errors and validate data
- Generate new keys per session - never reuse encryption keys
- Auto-encryption by default - payloads are encrypted when keys are provided
Dependencies
- tweetnacl: For x25519 key exchange and symmetric encryption
- tweetnacl-util: For base64 encoding/decoding utilities
- bs58: For base58 encoding/decoding
License
MIT
