diff --git a/.yarn/versions/b7e895ef.yml b/.yarn/versions/b7e895ef.yml new file mode 100644 index 00000000..2bce1205 --- /dev/null +++ b/.yarn/versions/b7e895ef.yml @@ -0,0 +1,6 @@ +releases: + browser-extension: patch + helios-inpage: patch + +declined: + - helios diff --git a/packages/inpage/eip-6963.js b/packages/inpage/eip-6963.js new file mode 100644 index 00000000..20db045b --- /dev/null +++ b/packages/inpage/eip-6963.js @@ -0,0 +1,18 @@ +export const EIP6963EventNames = { + Announce: 'eip6963:announceProvider', + Request: 'eip6963:requestProvider', +} + +export function announceProvider(providerDetail) { + const _announceProvider = () => + window.dispatchEvent( + new CustomEvent(EIP6963EventNames.Announce, { + detail: Object.freeze(providerDetail), + }), + ) + + _announceProvider() + window.addEventListener(EIP6963EventNames.Request, _announceProvider) + return () => + window.removeEventListener(EIP6963EventNames.Request, _announceProvider) +} diff --git a/packages/inpage/package.json b/packages/inpage/package.json index 5e4111f8..a950f128 100644 --- a/packages/inpage/package.json +++ b/packages/inpage/package.json @@ -10,6 +10,7 @@ "@fluent-wallet/extension-runtime": "workspace:packages/extension-runtime", "@fluent-wallet/provider-api": "workspace:packages/ui/provider-api", "@thi.ng/rstream": "6.0.21", + "uuid": "^8.3.2", "webextension-polyfill": "0.8.0" } } diff --git a/packages/inpage/setup-inpage-provider.js b/packages/inpage/setup-inpage-provider.js index fdb6d4d4..f9475aae 100644 --- a/packages/inpage/setup-inpage-provider.js +++ b/packages/inpage/setup-inpage-provider.js @@ -1,6 +1,11 @@ import {rpcStream} from '@fluent-wallet/extension-runtime/rpc-stream.js' import {initProvider} from '@fluent-wallet/provider-api' import {takeOver} from './take-over-portal' +import {announceProvider} from './eip-6963' +import {v4 as uuid} from 'uuid' + +const FLUENT_SVG = + 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iOTYiIGhlaWdodD0iOTYiIHZpZXdCb3g9IjAgMCA5NiA5NiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBjbGlwLXBhdGg9InVybCgjY2xpcDBfMTAwMV8yKSI+PHBhdGggZmlsbD0iI0YwRjBGMCIgZD0iTTAgMGg5NnY5NkgweiIvPjxwYXRoIGQ9Ik03NSAyMXY4LjY4OGMwIDEwLTguMDMyIDE4LjEyNS0xOC4wMDIgMTguMjg3bC0uMzAzLjAwMkg0OHY4LjcxQzQ4IDY2Ljk3NSAzOS44MzIgNzUgMjkuNzcgNzVIMjF2LTguOTQ1LTE5LjQ1QzIxIDMyLjQ2NCAzMi40NzQgMjEgNDYuNjI3IDIxSDc1eiIgZmlsbD0iI2ZmZiIvPjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNNjMuNDA4IDIxSDc1djguNjg3Qzc1IDM5Ljk3NSA2Ni44MzIgNDggNTYuNzcgNDhINDh2LTguOTM4QzQ4IDI5Ljk0NiA1NC42NzUgMjIuMzg4IDYzLjQwOCAyMXoiIGZpbGw9IiMyNDIyNjUiIGZpbGwtb3BhY2l0eT0iLjgiLz48cGF0aCBkPSJNNzUgMjF2OC42ODhjMCAxMC04LjAzMiAxOC4xMjUtMTguMDAyIDE4LjI4N2wtLjMwMy4wMDJINDh2OC43MUM0OCA2Ni45NzUgMzkuODMyIDc1IDI5Ljc3IDc1SDIxdi04Ljk0NS0xOS40NUMyMSAzMi40NjQgMzIuNDc0IDIxIDQ2LjYyNyAyMUg3NXoiIGZpbGw9IiM2MTZFRTEiIGZpbGwtb3BhY2l0eT0iLjgiLz48L2c+PGRlZnM+PGNsaXBQYXRoIGlkPSJjbGlwMF8xMDAxXzIiPjxwYXRoIGZpbGw9IiNmZmYiIGQ9Ik0wIDBoOTZ2OTZIMHoiLz48L2NsaXBQYXRoPjwvZGVmcz48L3N2Zz4=' let PROVIDER = null @@ -74,6 +79,15 @@ function setupProvider() { }) PROVIDER = initProvider(stream, sendToBg) + announceProvider({ + info: { + uuid: uuid(), + name: 'Fluent', + icon: FLUENT_SVG, + rdns: 'com.fluentwallet', + }, + provider: PROVIDER, + }) window.fluent = PROVIDER if (!window.ethereum) window.ethereum = PROVIDER @@ -81,11 +95,15 @@ function setupProvider() { takeOver(PROVIDER, 'cfx') if (window.localStorage.getItem(FLUENT_OVERRIDE_WINDOW_DOT_ETHEREUM)) { - Object.defineProperty(window, 'ethereum', { - value: PROVIDER, - writable: false, - }) - takeOver(PROVIDER, 'eth') + try { + Object.defineProperty(window, 'ethereum', { + value: PROVIDER, + writable: false, + }) + takeOver(PROVIDER, 'eth') + } catch (error) { + console.log('Failed to override window.ethereum', error) + } } return PROVIDER } diff --git a/packages/inpage/setup-inpage-provider.test.js b/packages/inpage/setup-inpage-provider.test.js index 39a028de..68ea03a8 100644 --- a/packages/inpage/setup-inpage-provider.test.js +++ b/packages/inpage/setup-inpage-provider.test.js @@ -1,16 +1,19 @@ import {expect, describe, it, vi} from 'vitest' +import {EIP6963EventNames} from './eip-6963.js' describe('inpage', () => { describe('setupProvider', () => { it('should setup the provider on window.conflux', async () => { - let listener, eventName + let listeners = [], + eventNames = [] window.addEventListener = vi.fn((e, l) => { - eventName = e - listener = l + eventNames.push(e) + listeners.push(l) }) expect(window.conflux).toBe(undefined) await import('./index.js') - expect(typeof listener).toBe('function') - expect(eventName).toBe('message') + listeners.forEach(l => expect(typeof l).toBe('function')) + expect(eventNames[0]).toBe('message') + expect(eventNames[1]).toBe(EIP6963EventNames.Request) expect(window.conflux).toBeDefined() }) diff --git a/yarn.lock b/yarn.lock index b3734a00..10e892a4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18252,6 +18252,7 @@ __metadata: "@fluent-wallet/extension-runtime": "workspace:packages/extension-runtime" "@fluent-wallet/provider-api": "workspace:packages/ui/provider-api" "@thi.ng/rstream": "npm:6.0.21" + uuid: "npm:^8.3.2" webextension-polyfill: "npm:0.8.0" languageName: unknown linkType: soft