diff --git a/packages/example/extension/src/background/index.ts b/packages/example/extension/src/background/index.ts index 800cd28c..4a17a00a 100644 --- a/packages/example/extension/src/background/index.ts +++ b/packages/example/extension/src/background/index.ts @@ -1,5 +1,5 @@ import { CONTENT_PORT_NAME, createChannel, createPortTransport, serializeMessage } from '../messages'; -import { generateMnemonic } from './wallet'; +import { deriveEthereumAccount, deriveSolanaAccount, generateMnemonic } from './wallet'; chrome.runtime.onInstalled.addListener((details) => { if (details.reason === chrome.runtime.OnInstalledReason.INSTALL) { @@ -13,5 +13,22 @@ chrome.runtime.onConnect.addListener((port) => { const transport = createPortTransport(port); const channel = createChannel(transport); + + const unsubscribe = channel.onMessage('connect', async (_params, sendResponse) => { + const { mnemonic } = await chrome.storage.local.get('mnemonic'); + const ethereumAccount = deriveEthereumAccount(mnemonic); + const solanaAccount = deriveSolanaAccount(mnemonic); + + // TODO: Open popup and allow user to select accounts. + const response = [ + { chain: 'ethereum', publicKey: serializeMessage(ethereumAccount.publicKey) }, + { chain: 'solana', publicKey: serializeMessage(solanaAccount.publicKey) }, + ]; + sendResponse(response); + }); + + port.onDisconnect.addListener(() => { + unsubscribe(); + }); } }); diff --git a/packages/example/extension/src/content/multiChainWallet.ts b/packages/example/extension/src/content/multiChainWallet.ts index a6a30430..019871f1 100644 --- a/packages/example/extension/src/content/multiChainWallet.ts +++ b/packages/example/extension/src/content/multiChainWallet.ts @@ -11,6 +11,13 @@ import type { } from '@wallet-standard/standard'; import { CHAIN_ETHEREUM, CHAIN_SOLANA_MAINNET } from '@wallet-standard/util'; +import type { Channel } from '../messages'; +import { deserializeMessage } from '../messages'; + +declare const window: { + _channel: Channel; +}; + export type EthereumChain = typeof CHAIN_ETHEREUM; export type EthereumWalletAccountFeature = SignTransactionFeature; @@ -146,14 +153,37 @@ export class MultiChainWallet implements Wallet { return this.#hasMoreAccounts; } + #request(method: string, params?: any[]) { + return window._channel.sendMessage(method, params); + } + async connect< Chain extends MultiChainWalletAccount['chain'], FeatureName extends WalletAccountFeatureName, ExtensionName extends WalletAccountExtensionName, Input extends ConnectInput >(input?: Input): Promise> { - // TODO - this.#accounts = []; + const accounts = await this.#request('connect'); + + if (accounts === null) { + // TODO: Use custom errors. + throw new Error('The user rejected the request.'); + } + + this.#accounts = accounts.map((account: { chain: string; publicKey: string }) => { + const { chain, publicKey: wirePublicKey } = account; + + const publicKey = deserializeMessage(wirePublicKey); + + switch (chain) { + case 'ethereum': + return new EthereumWalletAccount(publicKey); + case 'solana': + return new SolanaWalletAccount(publicKey); + default: + throw new Error(`Unknown chain: '${chain}'`); + } + }); return { accounts: this.accounts as any,