|
| 1 | +import { Account, Network } from '@provablehq/aleo-types'; |
| 2 | +import { WalletName, WalletReadyState } from '@provablehq/aleo-wallet-standard'; |
| 3 | +import { |
| 4 | + BaseAleoWalletAdapter, |
| 5 | + WalletConnectionError, |
| 6 | + WalletDisconnectionError, |
| 7 | +} from '@provablehq/aleo-wallet-adaptor-core'; |
| 8 | +import { GalileoWallet, GalileoWalletAdapterConfig, GalileoWindow } from './types'; |
| 9 | + |
| 10 | +/** |
| 11 | + * Galileo wallet adapter |
| 12 | + */ |
| 13 | +export class GalileoWalletAdapter extends BaseAleoWalletAdapter { |
| 14 | + /** |
| 15 | + * The wallet name |
| 16 | + */ |
| 17 | + readonly name = 'Galileo Wallet' as WalletName<'Galileo Wallet'>; |
| 18 | + |
| 19 | + /** |
| 20 | + * The wallet URL |
| 21 | + */ |
| 22 | + url = 'https://provable.com/'; |
| 23 | + |
| 24 | + /** |
| 25 | + * The wallet icon (base64-encoded SVG) |
| 26 | + */ |
| 27 | + readonly icon = |
| 28 | + 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAyNCIgaGVpZ2h0PSIxMDI0IiB2aWV3Qm94PSIwIDAgMTAyNCAxMDI0IiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgo8cmVjdCB3aWR0aD0iMTAyNCIgaGVpZ2h0PSIxMDI0IiBmaWxsPSIjMDkwNzA3Ii8+CjxwYXRoIGQ9Ik01MTIgODcxQzcxMC4yNyA4NzEgODcxIDcxMC4yNyA4NzEgNTEyQzg3MSA1MDUuMTI0IDg3MC44MDcgNDk4LjI5MyA4NzAuNDI1IDQ5MS41MTJDNzQ2LjQzIDYyNy4wNTggNDYxLjk5NCA3NjIuNDcgMzE0LjM5OSA4MTAuNjY0TDMxMi42ODQgODEwLjYzM0MzNjkuNzA0IDg0OC43NjUgNDM4LjI1NSA4NzEgNTEyIDg3MVoiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik0yNTAuNDA4IDc1Ny44NjhDMTkwLjAwNiA2OTMuNjI4IDE1MyA2MDcuMTM2IDE1MyA1MTJDMTUzIDMxMy43MyAzMTMuNzMgMTUzIDUxMiAxNTNDNjkyLjk5MyAxNTMgODQyLjcwMyAyODYuOTM4IDg2Ny40MiA0NjEuMTA1QzYxMS4yMTIgNjM4LjgyMyAzNzcuNjU5IDcxOC42OCAyNTEuMDQ2IDc1Ny44NjhIMjUwLjQwOFoiIGZpbGw9IndoaXRlIi8+Cjwvc3ZnPgo='; |
| 29 | + |
| 30 | + /** |
| 31 | + * The window object |
| 32 | + */ |
| 33 | + private _window: GalileoWindow | undefined; |
| 34 | + |
| 35 | + /** |
| 36 | + * Current network |
| 37 | + */ |
| 38 | + private _network: Network; |
| 39 | + |
| 40 | + /** |
| 41 | + * Public key |
| 42 | + */ |
| 43 | + private _publicKey: string = ''; |
| 44 | + |
| 45 | + _readyState: WalletReadyState = |
| 46 | + typeof window === 'undefined' || typeof document === 'undefined' |
| 47 | + ? WalletReadyState.UNSUPPORTED |
| 48 | + : WalletReadyState.NOT_DETECTED; |
| 49 | + |
| 50 | + /** |
| 51 | + * Galileo wallet instance |
| 52 | + */ |
| 53 | + private _galileoWallet: GalileoWallet | undefined; |
| 54 | + |
| 55 | + /** |
| 56 | + * Create a new Galileo wallet adapter |
| 57 | + * @param config Adapter configuration |
| 58 | + */ |
| 59 | + constructor(config?: GalileoWalletAdapterConfig) { |
| 60 | + super(); |
| 61 | + console.debug('GalileoWalletAdapter constructor', config); |
| 62 | + this._network = Network.TESTNET3; |
| 63 | + this._checkAvailability(); |
| 64 | + } |
| 65 | + |
| 66 | + /** |
| 67 | + * Check if Galileo wallet is available |
| 68 | + */ |
| 69 | + private _checkAvailability(): void { |
| 70 | + if (typeof window === 'undefined' || typeof document === 'undefined') { |
| 71 | + this.readyState = WalletReadyState.UNSUPPORTED; |
| 72 | + return; |
| 73 | + } |
| 74 | + |
| 75 | + this._window = window as GalileoWindow; |
| 76 | + |
| 77 | + if (this._window.galileo) { |
| 78 | + this.readyState = WalletReadyState.INSTALLED; |
| 79 | + this._galileoWallet = this._window?.galileo; |
| 80 | + } else { |
| 81 | + // Check if user is on a mobile device |
| 82 | + const isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent); |
| 83 | + if (isMobile) { |
| 84 | + this.readyState = WalletReadyState.LOADABLE; |
| 85 | + } |
| 86 | + } |
| 87 | + } |
| 88 | + |
| 89 | + /** |
| 90 | + * Connect to Galileo wallet |
| 91 | + * @returns The connected account |
| 92 | + */ |
| 93 | + async connect(network: Network): Promise<Account> { |
| 94 | + try { |
| 95 | + if (this.readyState !== WalletReadyState.INSTALLED) { |
| 96 | + throw new WalletConnectionError('Galileo Wallet is not available'); |
| 97 | + } |
| 98 | + |
| 99 | + // Call connect and extract address safely |
| 100 | + try { |
| 101 | + const connectResult = await this._galileoWallet?.connect(network); |
| 102 | + this._publicKey = connectResult?.address || ''; |
| 103 | + this._network = network; |
| 104 | + console.log('Galileo Wallet connected to network: ', this._network); |
| 105 | + } catch (error: unknown) { |
| 106 | + throw new WalletConnectionError( |
| 107 | + error instanceof Error ? error.message : 'Connection failed', |
| 108 | + ); |
| 109 | + } |
| 110 | + |
| 111 | + if (!this._publicKey) { |
| 112 | + throw new WalletConnectionError('No address returned from wallet'); |
| 113 | + } |
| 114 | + |
| 115 | + const account: Account = { |
| 116 | + address: this._publicKey, |
| 117 | + }; |
| 118 | + |
| 119 | + this.account = account; |
| 120 | + this.emit('connect', account); |
| 121 | + |
| 122 | + return account; |
| 123 | + } catch (err: Error | unknown) { |
| 124 | + this.emit('error', err instanceof Error ? err : new Error(String(err))); |
| 125 | + throw new WalletConnectionError(err instanceof Error ? err.message : 'Connection failed'); |
| 126 | + } |
| 127 | + } |
| 128 | + |
| 129 | + /** |
| 130 | + * Disconnect from Galileo wallet |
| 131 | + */ |
| 132 | + async disconnect(): Promise<void> { |
| 133 | + try { |
| 134 | + await this._galileoWallet?.disconnect(); |
| 135 | + this._publicKey = ''; |
| 136 | + this.account = undefined; |
| 137 | + this.emit('disconnect'); |
| 138 | + } catch (err: Error | unknown) { |
| 139 | + this.emit('error', err instanceof Error ? err : new Error(String(err))); |
| 140 | + throw new WalletDisconnectionError( |
| 141 | + err instanceof Error ? err.message : 'Disconnection failed', |
| 142 | + ); |
| 143 | + } |
| 144 | + } |
| 145 | +} |
0 commit comments