// Copyright 2023 @soul-wallet/extension-base authors & contributors // SPDX-License-Identifier: Apache-2.0 import { MetadataRequest, Resolver } from '@soul-wallet/extension-base/background/types'; import RequestService from '@soul-wallet/extension-base/services/request-service'; import { extractMetadata } from '@soul-wallet/extension-base/services/request-service/helper'; import { MetaRequest } from '@soul-wallet/extension-base/services/request-service/types'; import { MetadataStore } from '@soul-wallet/extension-base/stores'; import { getId } from '@soul-wallet/extension-base/utils/getId'; import { addMetadata, knownMetadata } from '@soul-wallet/extension-chains'; import { MetadataDef } from '@soul-wallet/extension-inject/types'; import { BehaviorSubject } from 'rxjs'; export default class MetadataRequestHandler { readonly #requestService: RequestService; readonly #metaStore: MetadataStore = new MetadataStore(); readonly #metaRequests: Record = {}; public readonly metaSubject: BehaviorSubject = new BehaviorSubject([]); constructor (requestService: RequestService) { this.#requestService = requestService; extractMetadata(this.#metaStore); } public get knownMetadata (): MetadataDef[] { return knownMetadata(); } public get allMetaRequests (): MetadataRequest[] { return Object .values(this.#metaRequests) .map(({ id, request, url }): MetadataRequest => ({ id, request, url })); } public get numMetaRequests (): number { return Object.keys(this.#metaRequests).length; } public getMetaRequest (id: string): MetaRequest { return this.#metaRequests[id]; } public saveMetadata (meta: MetadataDef): void { this.#metaStore.set(meta.genesisHash, meta); addMetadata(meta); } private updateIconMeta (shouldClose?: boolean): void { this.metaSubject.next(this.allMetaRequests); this.#requestService.updateIconV2(shouldClose); } private metaComplete = (id: string, resolve: (result: boolean) => void, reject: (error: Error) => void): Resolver => { const complete = (): void => { delete this.#metaRequests[id]; this.updateIconMeta(true); }; return { reject: (error: Error): void => { complete(); reject(error); }, resolve: (result: boolean): void => { complete(); resolve(result); } }; }; public injectMetadata (url: string, request: MetadataDef): Promise { return new Promise((resolve, reject): void => { const id = getId(); this.#metaRequests[id] = { ...this.metaComplete(id, resolve, reject), id, request, url }; this.updateIconMeta(); this.#requestService.popupOpen(); }); } public resetWallet () { for (const request of Object.values(this.#metaRequests)) { request.reject(new Error('Reset wallet')); } this.metaSubject.next([]); } }