UNPKG

@cygnus-wealth/wallet-integration-system

Version:

Multi-chain wallet integration system for CygnusWealth

138 lines (137 loc) 5.09 kB
import { Chain, IntegrationSource } from '@cygnus-wealth/data-models'; export class SolanaWalletIntegration { chain; source; provider = null; connected = false; accounts = []; activeAccountIndex = 0; constructor(chain = Chain.SOLANA, source = IntegrationSource.PHANTOM, _config) { this.chain = chain; this.source = source; // Configuration can be used for future extensions if needed } async connect() { if (typeof window === 'undefined' || !window.solana) { throw new Error('Phantom wallet not found'); } try { this.provider = window.solana; const response = await this.provider.connect(); const publicKey = response.publicKey; // Create account for the connected wallet // Note: Phantom typically only exposes one account at a time this.accounts = [{ address: publicKey.toString(), index: 0, derivationPath: undefined, // Unknown - Phantom doesn't expose derivation paths label: 'Active Account' }]; // Try to get multiple accounts if supported if (this.provider.request) { try { const accountsResp = await this.provider.request({ method: 'getAccounts' }); if (Array.isArray(accountsResp) && accountsResp.length > 1) { this.accounts = accountsResp.map((acc, index) => ({ address: typeof acc === 'string' ? acc : (acc.publicKey || acc.address), index, derivationPath: undefined, // Unknown - wallets don't expose derivation paths label: index === 0 ? 'Active Account' : `Connected Account ${index}` })); } } catch { // Provider doesn't support multiple accounts } } this.activeAccountIndex = 0; this.connected = true; return { address: this.accounts[0].address, chain: this.chain, source: this.source, connected: true, connectedAt: new Date(), accounts: this.accounts, activeAccount: this.accounts[0] }; } catch (error) { this.connected = false; throw error; } } async disconnect() { if (this.provider) { await this.provider.disconnect(); this.connected = false; this.provider = null; this.accounts = []; this.activeAccountIndex = 0; } } async getAddress() { if (!this.connected || this.accounts.length === 0) { throw new Error('Wallet not connected'); } return this.accounts[this.activeAccountIndex].address; } async getAllAccounts() { if (!this.connected) { throw new Error('Wallet not connected'); } // Try to refresh accounts if provider supports it if (this.provider?.request) { try { const accountsResp = await this.provider.request({ method: 'getAccounts' }); if (Array.isArray(accountsResp) && accountsResp.length > 0) { this.accounts = accountsResp.map((acc, index) => ({ address: typeof acc === 'string' ? acc : (acc.publicKey || acc.address), index, derivationPath: `m/44'/501'/${index}'/0'`, label: `Account ${index + 1}` })); } } catch { // Keep existing accounts } } return [...this.accounts]; } async switchAccount(address) { if (!this.connected) { throw new Error('Wallet not connected'); } const accountIndex = this.accounts.findIndex(acc => acc.address === address); if (accountIndex === -1) { throw new Error(`Account ${address} not found`); } this.activeAccountIndex = accountIndex; // Try to switch account in provider if supported if (this.provider?.request) { try { await this.provider.request({ method: 'switchAccount', params: { address } }); } catch { // Provider doesn't support account switching } } } async getActiveAccount() { if (!this.connected || this.accounts.length === 0) { return null; } return this.accounts[this.activeAccountIndex]; } isConnected() { return this.connected && !!this.provider?.isConnected; } }