UNPKG

@upbond/upbond-embed

Version:
1,331 lines (1,317 loc) 113 kB
import _objectWithoutProperties from '@babel/runtime/helpers/objectWithoutProperties'; import _defineProperty from '@babel/runtime/helpers/defineProperty'; import { setAPIKey, get } from '@toruslabs/http-helpers'; import { SafeEventEmitter, ObjectMultiplex, createStreamMiddleware, JRPCEngine, createIdRemapMiddleware, BasePostMessageStream, setupMultiplex } from '@toruslabs/openlogin-jrpc'; import deepmerge from 'lodash.merge'; import timingSafeEqual from '@ansugroup/timing-safe-equal'; import * as crypto from 'crypto-browserify'; import { ObservableStore, storeAsStream } from '@metamask/obs-store'; import { ethErrors, EthereumRpcError } from 'eth-rpc-errors'; import dequal from 'fast-deep-equal'; import { duplex } from 'is-stream'; import pump from 'pump'; import loglevel from 'loglevel'; import createHash from 'create-hash'; import { EventEmitter } from 'events'; const LOGIN_PROVIDER = { GOOGLE: "google", FACEBOOK: "facebook", TWITCH: "twitch", REDDIT: "reddit", DISCORD: "discord" }; const WALLET_VERIFIERS = { GOOGLE: "google", FACEBOOK: "facebook", TWITCH: "twitch", REDDIT: "reddit", DISCORD: "discord", EMAIL_PASSWORDLESS: "torus-auth0-email-passwordless" }; const WALLET_OPENLOGIN_VERIFIER_MAP = { [WALLET_VERIFIERS.GOOGLE]: "tkey-google", [WALLET_VERIFIERS.FACEBOOK]: "tkey-facebook", [WALLET_VERIFIERS.TWITCH]: "tkey-twitch", [WALLET_VERIFIERS.REDDIT]: "tkey-reddit", [WALLET_VERIFIERS.DISCORD]: "tkey-discord", [WALLET_VERIFIERS.EMAIL_PASSWORDLESS]: "tkey-auth0-email-passwordless" }; const PAYMENT_PROVIDER = { MOONPAY: "moonpay", WYRE: "wyre", RAMPNETWORK: "rampnetwork", XANPOOL: "xanpool", MERCURYO: "mercuryo", TRANSAK: "transak" }; const SUPPORTED_PAYMENT_NETWORK = { MAINNET: "mainnet", MATIC: "matic", BSC_MAINNET: "bsc_mainnet", AVALANCHE_MAINNET: "avalanche_mainnet", XDAI: "xdai" }; const UPBOND_BUILD_ENV = { PRODUCTION: "production", STAGING: "staging", DEVELOPMENT: "development", TESTING: "testing", LOCAL: "local", V1_DEBUG: "v1_debug", V1_LOCAL: "v1_local", V1_DEVELOPMENT: "v1_development", V1_STAGING: "v1_staging", V1_PRODUCTION: "v1_production", V2_DEBUG: "v2_debug", V2_LOCAL: "v2_local", V2_DEVELOPMENT: "v2_development", V2_STAGING: "v2_staging", V2_PRODUCTION: "v2_production", V3_DEVELOPMENT: "v3_development", V3_STAGING: "v3_staging", V3_PRODUCTION: "v3_production", DEBUG: "debug", WALLET_DID: "wallet-did", MPC_DEV: "mpc-dev" }; const BUTTON_POSITION = { BOTTOM_LEFT: "bottom-left", TOP_LEFT: "top-left", BOTTOM_RIGHT: "bottom-right", TOP_RIGHT: "top-right" }; /** * From https://min-api.cryptocompare.com/data/v2/pair/mapping/fsym?fsym=BTC&extraParams=YourSite * GET https://min-api.cryptocompare.com/data/v2/pair/mapping/fsym?fsym=BTC * Then map over returned entries, picking tsym * * Last updated: Date of commit */ const CRYPTO_COMPARE_CURRENCIES = ["ETH", "USDT", "USDC", "TUSD", "EOSDT", "USD", "DAI", "GUSD", "DKKT", "PAX", "ILS", "RUB", "BYN", "EUR", "GBP", "JPY", "KRW", "PLN", "MXN", "AUD", "BRL", "CAD", "CHF", "KPW", "LAK", "LBP", "LKR", "XOF", "CNHT", "DOGE", "UAH", "TRY", "HKD", "XJP", "SGD", "USC", "NZD", "NGN", "RUR", "COP", "GHS", "EGP", "IDR", "BHD", "CRC", "PEN", "AED", "DOP", "PKR", "HUF", "VND", "XAR", "LTC", "RON", "OMR", "MYR", "DKK", "UGX", "ZMW", "SAR", "SEK", "GEL", "RWF", "IRR", "TZS", "CNY", "VEF", "BDT", "HRK", "CLP", "THB", "XAF", "ARS", "UYU", "SZL", "KZT", "NOK", "KES", "PAB", "INR", "CZK", "MAD", "TWD", "PHP", "ZAR", "BOB", "CDF", "DASH", "VES", "ISK", "MWK", "BAM", "TTD", "XRP", "JOD", "RSD", "HNL", "BGN", "GTQ", "BWP", "XMR", "MMK", "QAR", "AOA", "KWD", "MUR", "WUSD", "WEUR", "WAVES", "WTRY", "LRD", "LSL", "LYD", "AWG", "MDL", "BTO", "EURS", "CHFT", "MKD", "MNT", "MOP", "MRO", "MVR", "VOLLAR", "CKUSD", "KHR", "VUV", "BITCNY", "QC", "BBD", "NAD", "NPR", "PGK", "PYG", "BIF", "BMD", "BND", "XLM", "BNB", "SCR", "BAT", "CRO", "HT", "KCS", "LEO", "LINK", "MKR", "NPXS", "OMG", "REP", "ZB", "ZIL", "ZRX", "BCH", "BZD", "CUP", "CVE", "DJF", "DZD", "ERN", "ETB", "FJD", "FKP", "BUSD", "ANCT", "ALL", "AMD", "ANG", "CNYX", "IQD", "UZS", "TND", "GGP", "XAU", "KGS", "GIP", "JMD", "ZEC", "USDP", "BSV", "EMC2", "SNT", "GTO", "POWR", "EUSD", "EURT", "BCY", "BTS", "ATM", "BLOCKPAY", "ARDR", "AMP", "B2X", "BITGOLD", "BITEUR", "ATB", "BITUSD", "AGRS", "DFXT", "HIKEN", "BIX", "KNC", "EOS", "COB", "COSS", "BMH", "NANO", "BDG", "BNT", "XVG", "LKK1Y", "LKK", "USDK", "EURN", "NZDT", "JSE", "GMD", "GNF", "GYD", "YER", "XPF", "HTG", "SLL", "SOS", "WST", "SVC", "SYP", "NEO", "KMF", "JUMP", "AYA", "BLAST", "WGR", "BCN", "BTG", "URALS", "INN", "USDQ", "CNH", "HUSD", "BKRW", "NZDX", "EURX", "CADX", "USDEX", "JPYX", "AUDX", "VNDC", "EON", "GBPX", "CHFX", "USDJ", "IDRT", "USDS", "USDN", "BIDR", "IDK", "BSD", "BTN", "KYD", "NIO", "SBD", "SDG", "SHP", "TOP", "XCD", "XCHF", "CNYT", "GYEN", "ZUSD", "GOLD", "TRX", "TRYB", "PLATC", "STRAX", "UST", "GLM", "VAI", "BRZ", "DDRST", "XAUT", "MIM"]; /** * currencies supported by the payment provider * Last updated: Date of commit */ const PROVIDER_SUPPORTED_FIAT_CURRENCIES = { // https://integrations.simplex.com/supported_currencies // https://support.moonpay.com/hc/en-gb/articles/360011931457-Which-fiat-currencies-are-supported- [PAYMENT_PROVIDER.MOONPAY]: ["AUD", "BGN", "BRL", "CAD", "CHF", "CNY", "COP", "CZK", "DKK", "DOP", "EGP", "EUR", "GBP", "HKD", "HRK", "IDR", "ILS", "JPY", "JOD", "KES", "KRW", "KWD", "LKR", "MAD", "MXN", "MYR", "NGN", "NOK", "NZD", "OMR", "PEN", "PKR", "PLN", "RON", "RUB", "SEK", "SGD", "THB", "TRY", "TWD", "USD", "VND", "ZAR"], /** * https://docs.sendwyre.com/docs/supported-currencies#fiat * The ones where credit card is supported */ [PAYMENT_PROVIDER.WYRE]: ["USD", "EUR", "GBP", "AUD", "CAD", "NZD", "ARS", "BRL", "CHF", "CLP", "COP", "CZK", "DKK", "HKD", "ILS", "INR", "ISK", "JPY", "KRW", "MXN", "MYR", "NOK", "PHP", "PLN", "SEK", "THB", "VND", "ZAR"], // https://support.ramp.network/en/articles/471-why-am-i-paying-in-usd-eur-gbp [PAYMENT_PROVIDER.RAMPNETWORK]: ["USD", "EUR", "GBP"], // From https://xanpool.com/ fiat select dropdown [PAYMENT_PROVIDER.XANPOOL]: ["SGD", "HKD", "THB", "PHP", "INR", "IDR", "MYR", "AUD", "NZD", "KRW"], // https://support.aax.com/en/articles/5295762-mercuryo // RUB / UAH currently not supported [PAYMENT_PROVIDER.MERCURYO]: ["EUR", "USD", "GBP", "TRY", "JPY", "BRL", "NGN", "VND", "MXN", "KRW"], /** * https://support.transak.com/hc/en-us/articles/360020615578-Credit-and-Debit-Card-Payments-through-Transak * or * https://transak.stoplight.io/docs/transak-docs/b3A6OTk1ODQ0-2-get-fiat-currencies */ [PAYMENT_PROVIDER.TRANSAK]: ["ARS", "AUD", "BBD", "BGN", "BMD", "BRL", "CAD", "CHF", "CLP", "CRC", "CZK", "DKK", "DOP", "EUR", "FJD", "FKP", "GBP", "GIP", "HRK", "HUF", "IDR", "ILS", "ISK", "JMD", "JPY", "KES", "KRW", "MDL", "MXN", "MYR", "NOK", "NZD", "PEN", "PHP", "PLN", "PYG", "RON", "SEK", "SGD", "THB", "TRY", "TZS", "USD", "ZAR"] }; const cryptoCompareCurrenciesSet = new Set(CRYPTO_COMPARE_CURRENCIES); /** * Fiat currencies that we support */ function supportedFiatCurrencies(provider) { const providerSupportedFiatCurrencies = PROVIDER_SUPPORTED_FIAT_CURRENCIES[provider]; return providerSupportedFiatCurrencies.filter(currency => cryptoCompareCurrenciesSet.has(currency)); } const paymentProviders$1 = { [PAYMENT_PROVIDER.MOONPAY]: { line1: "Credit/ Debit Card/ Apple Pay", line2: "4.5% or 5 USD", line3: "2,000€/day, 10,000€/mo", supportPage: "https://help.moonpay.io/en/", minOrderValue: 24.99, maxOrderValue: 50000, validCurrencies: supportedFiatCurrencies(PAYMENT_PROVIDER.MOONPAY), validCryptoCurrenciesByChain: { [SUPPORTED_PAYMENT_NETWORK.MAINNET]: [{ value: "aave", display: "AAVE" }, { value: "bat", display: "BAT" }, { value: "dai", display: "DAI" }, { value: "eth", display: "ETH" }, { value: "mkr", display: "MKR" }, { value: "matic", display: "MATIC" }, { value: "usdt", display: "USDT" }, { value: "usdc", display: "USDC" }], [SUPPORTED_PAYMENT_NETWORK.MATIC]: [{ value: "eth_polygon", display: "ETH" }, { value: "matic_polygon", display: "MATIC" }, { value: "usdc_polygon", display: "USDC" }], [SUPPORTED_PAYMENT_NETWORK.BSC_MAINNET]: [{ value: "bnb_bsc", display: "BNB" }, { value: "busd_bsc", display: "BUSD" }], [SUPPORTED_PAYMENT_NETWORK.AVALANCHE_MAINNET]: [{ value: "avax_cchain", display: "AVAX" }] }, includeFees: true, api: true, enforceMax: false }, [PAYMENT_PROVIDER.WYRE]: { line1: "Apple Pay/ Debit/ Credit Card", line2: "4.9% + 30¢ or 5 USD", line3: "$250/day", supportPage: "https://support.sendwyre.com/en/", minOrderValue: 5, maxOrderValue: 500, validCurrencies: supportedFiatCurrencies(PAYMENT_PROVIDER.WYRE), validCryptoCurrenciesByChain: { [SUPPORTED_PAYMENT_NETWORK.MAINNET]: [{ value: "AAVE", display: "AAVE" }, { value: "BAT", display: "BAT" }, { value: "BUSD", display: "BUSD" }, { value: "DAI", display: "DAI" }, { value: "ETH", display: "ETH" }, { value: "MKR", display: "MKR" }, { value: "UNI", display: "UNI" }, { value: "USDC", display: "USDC" }, { value: "USDT", display: "USDT" }], [SUPPORTED_PAYMENT_NETWORK.MATIC]: [{ value: "MUSDC", display: "USDC" }], // AVAXC? or AVAX? [SUPPORTED_PAYMENT_NETWORK.AVALANCHE_MAINNET]: [{ value: "AVAXC", display: "AVAXC" }] }, includeFees: false, api: true, enforceMax: false }, [PAYMENT_PROVIDER.RAMPNETWORK]: { line1: "Debit Card/ <br>Apple Pay/ Bank transfer", line2: "0.49% - 2.9%", line3: "5,000€/purchase, 20,000€/mo", supportPage: "https://instant.ramp.network/", minOrderValue: 50, maxOrderValue: 20000, validCurrencies: supportedFiatCurrencies(PAYMENT_PROVIDER.RAMPNETWORK), validCryptoCurrenciesByChain: { [SUPPORTED_PAYMENT_NETWORK.MAINNET]: [{ value: "ETH", display: "ETH" }, { value: "DAI", display: "DAI" }, { value: "USDC", display: "USDC" }, { value: "USDT", display: "USDT" }], [SUPPORTED_PAYMENT_NETWORK.MATIC]: [{ value: "MATIC_DAI", display: "DAI" }, { value: "MATIC_MATIC", display: "MATIC" }, { value: "MATIC_USDC", display: "USDC" }], // what about AVAXC? [SUPPORTED_PAYMENT_NETWORK.AVALANCHE_MAINNET]: [{ value: "AVAX", display: "AVAX" }] // Temporary unavailable // [SUPPORTED_PAYMENT_NETWORK.XDAI]: [{ value: 'XDAI_XDAI', display: 'XDAI' }], }, includeFees: true, api: true, receiveHint: "walletTopUp.receiveHintRamp", enforceMax: false }, [PAYMENT_PROVIDER.XANPOOL]: { line1: "PayNow/ InstaPay/ FPS/ GoJekPay/ UPI/ PromptPay/ <br>ViettelPay/ DuitNow", line2: "2.5% buying, 3% selling", line3: "$2,500 / day", supportPage: "mailto:support@xanpool.com", minOrderValue: 100, maxOrderValue: 2500, validCurrencies: supportedFiatCurrencies(PAYMENT_PROVIDER.XANPOOL), validCryptoCurrenciesByChain: { [SUPPORTED_PAYMENT_NETWORK.MAINNET]: [{ value: "ETH", display: "ETH" }, { value: "USDT", display: "USDT" }] }, includeFees: true, api: true, sell: true, enforceMax: false }, [PAYMENT_PROVIDER.MERCURYO]: { line1: "Credit/ Debit Card/ Apple Pay", line2: "3.95% or 4 USD", line3: "10,000€/day, 25,000€/mo", supportPage: "mailto:support@mercuryo.io", minOrderValue: 30, maxOrderValue: 5000, validCurrencies: supportedFiatCurrencies(PAYMENT_PROVIDER.MERCURYO), validCryptoCurrenciesByChain: { [SUPPORTED_PAYMENT_NETWORK.MAINNET]: [{ value: "ETH", display: "ETH" }, { value: "BAT", display: "BAT" }, { value: "USDT", display: "USDT" }, { value: "DAI", display: "DAI" }], [SUPPORTED_PAYMENT_NETWORK.BSC_MAINNET]: [{ value: "BNB", display: "BNB" }, { value: "BUSD", display: "BUSD" }, { value: "1INCH", display: "1INCH" }] }, includeFees: true, api: true, enforceMax: false }, [PAYMENT_PROVIDER.TRANSAK]: { line1: "Apple & Google Pay / Credit/Debit Card<br/>Bangkok Bank Mobile & iPay<br/>Bank Transfer (sepa/gbp) / SCB Mobile & Easy", line2: "0.99% - 5.5% or 5 USD", line3: "$5,000/day, $28,000/mo", supportPage: "https://support.transak.com/hc/en-US", minOrderValue: 30, maxOrderValue: 500, validCurrencies: supportedFiatCurrencies(PAYMENT_PROVIDER.TRANSAK), validCryptoCurrenciesByChain: { [SUPPORTED_PAYMENT_NETWORK.MAINNET]: [{ value: "AAVE", display: "AAVE" }, { value: "DAI", display: "DAI" }, { value: "ETH", display: "ETH" }, { value: "USDC", display: "USDC" }, { value: "USDT", display: "USDT" }], [SUPPORTED_PAYMENT_NETWORK.MATIC]: [{ value: "AAVE", display: "AAVE" }, { value: "DAI", display: "DAI" }, { value: "MATIC", display: "MATIC" }, { value: "USDC", display: "USDC" }, { value: "USDT", display: "USDT" }, { value: "WETH", display: "WETH" }], [SUPPORTED_PAYMENT_NETWORK.BSC_MAINNET]: [{ value: "BNB", display: "BNB" }, { value: "BUSD", display: "BUSD" }], [SUPPORTED_PAYMENT_NETWORK.AVALANCHE_MAINNET]: [{ value: "AVAX", display: "AVAX" }] }, includeFees: true, enforceMax: true } }; const translations = { en: { embed: { continue: "Continue", actionRequired: "Authorization required", pendingAction: "Click continue to proceed with your request in a popup", cookiesRequired: "Cookies Required", enableCookies: "Please enable cookies in your browser preferences to access Upbond", clickHere: "More Info" } }, de: { embed: { continue: "Fortsetzen", actionRequired: "Autorisierung erforderlich", pendingAction: "Klicken Sie in einem Popup auf Weiter, um mit Ihrer Anfrage fortzufahren", cookiesRequired: "Cookies benötigt", enableCookies: "Bitte aktivieren Sie Cookies in Ihren Browsereinstellungen, um auf Upbond zuzugreifen", clickHere: "Mehr Info" } }, ja: { embed: { continue: "継続する", actionRequired: "認証が必要です", pendingAction: "続行をクリックして、ポップアップでリクエストを続行します", cookiesRequired: "必要なクッキー", enableCookies: "Upbondにアクセスするには、ブラウザの設定でCookieを有効にしてください。", clickHere: "詳しくは" } }, ko: { embed: { continue: "계속하다", actionRequired: "승인 필요", pendingAction: "팝업에서 요청을 진행하려면 계속을 클릭하십시오.", cookiesRequired: "쿠키 필요", enableCookies: "브라우저 환경 설정에서 쿠키를 활성화하여 Upbond에 액세스하십시오.", clickHere: "더 많은 정보" } }, zh: { embed: { continue: "继续", actionRequired: "需要授权", pendingAction: "单击继续以在弹出窗口中继续您的请求", cookiesRequired: "必填Cookie", enableCookies: "请在您的浏览器首选项中启用cookie以访问Torus。", clickHere: "更多信息" } } }; const DID_STREAM_NAME = { RESULT: "did_listen_result", REQUEST: "did_listen_request" }; var configuration = { supportedVerifierList: Object.values(WALLET_VERIFIERS), paymentProviders: paymentProviders$1, api: "https://api.tor.us", translations, prodTorusUrl: "", localStorageKeyPrefix: `torus-`, DID_STREAM_NAME }; // import { ConsentDidResponse } from "./interfaces"; class Consent { constructor(_ref) { let { publicKey, scope, consentStream, provider, isLoggedIn = false, didIntervalRequest = 5000 } = _ref; _defineProperty(this, "communicationMux", void 0); _defineProperty(this, "provider", void 0); _defineProperty(this, "consentConfigurations", void 0); _defineProperty(this, "flowConfig", void 0); _defineProperty(this, "publicKey", void 0); _defineProperty(this, "isLoggedIn", void 0); _defineProperty(this, "didIntervalRequest", void 0); _defineProperty(this, "isDidDeployed", void 0); _defineProperty(this, "consentStreamName", void 0); _defineProperty(this, "didCreationCb", void 0); if (publicKey) { this.didIntervalRequest = didIntervalRequest; this.isLoggedIn = isLoggedIn; this.consentConfigurations = { enabled: false, scopes: scope }; this.flowConfig = "normal"; this.publicKey = publicKey; this.communicationMux = consentStream; this.provider = provider; this.isDidDeployed = false; this.consentStreamName = { consent: "consent", listenerStream: "did_listener_stream", getConsentData: "did_get_consent_data" }; this.didCreationCb = {}; this.listenDidCreation(); } } init() { if (!this.publicKey) { throw new Error(`Missing secret public key`); } if (!this.consentConfigurations.scopes || this.consentConfigurations.scopes.length === 0) { throw new Error(`Missing scope`); } console.log(`Consent management ready to go`); this.consentConfigurations.enabled = true; const stream = this.communicationMux.getStream(this.consentStreamName.consent); stream.write({ name: "init", data: { scope: this.consentConfigurations.scopes, publicKey: this.publicKey, host: window.location.host } }); } getDid() { return new Promise((resolve, reject) => { const stream = this.communicationMux.getStream(this.consentStreamName.consent); stream.write({ name: "request", data: { scope: this.consentConfigurations.scopes, publicKey: this.publicKey, host: window.location.host } }); stream.on("data", data => { if (data.name === "error") { if (data.data.code && data.data.code === 401) { this.isDidDeployed = false; this.didCreationCb = data.data.params; resolve({ jwt: "", jwtPresentation: "" }); } reject(new Error(data.data.msg)); } else { this.isDidDeployed = true; resolve(data.data); } }); }); } // requestDIDCreationOrFilledForm(clientId: string, params: { [x: string]: any }, secKey: string): Promise<ConsentDidResponse> { // return new Promise((resolve, reject) => { // try { // const ethProvider = new ethers.providers.Web3Provider(this.provider); // const signer = ethProvider.getSigner(); // Web3Token.sign( // async (msg: string) => { // const data = { // domain: "example.com", // scope: this.consentConfigurations.scopes, // type: "did_creation_request", // data: { // clientId, // clientSecret: secKey, // params, // }, // expires_in: "3 days", // msg, // }; // const tx = await signer.signMessage(JSON.stringify(data)); // return tx; // }, // { // domain: "example.com", // expires_in: "3 days", // } // ); // const stream = this.communicationMux.getStream("consent") as Substream; // stream.on("data", (data) => { // if (data.name === "consent_response") { // resolve(data.data); // } else if (data.name === "consent_error") { // reject(data.data.msg); // } // }); // stream.on("error", (err) => { // reject(err); // }); // } catch (error) { // if (error.message && error.message.includes("user rejected signing")) { // reject(new Error("User rejected your request")); // } // reject(error); // } // }); // } // requestUserData(did: { jwt: string; jwtPresentation: string }, cb?: (stream: Substream) => void): Promise<ConsentDidResponse> { // return new Promise((resolve, reject) => { // if (!this.isDidDeployed || (did.jwt === "" && did.jwtPresentation === "")) { // const data = this.requestDIDCreationOrFilledForm( // this.consentApiKey, // Object.keys(this.didCreationCb).length > 0 ? this.didCreationCb : {}, // this.key // ); // resolve(data); // return; // } // if (cb && typeof cb !== "function") { // reject(new Error(`Callback must be a function`)); // } // if (!did || !did.jwt || !did.jwtPresentation) { // reject(new Error(`Missing did object`)); // } // const { jwt, jwtPresentation } = did; // const stream = this.communicationMux.getStream("consent") as Substream; // try { // const ethProvider = new ethers.providers.Web3Provider(this.provider); // const signer = ethProvider.getSigner(); // Web3Token.sign( // async (msg: string) => { // const data = { // domain: this.isLocalhost() ? "example.com" : new URL(window.location.origin).hostname, // scope: this.consentConfigurations.scopes, // type: "consent_request", // data: { // vc: jwt, // vp: jwtPresentation, // }, // expires_in: "3 days", // msg, // }; // const tx = await signer.signMessage(JSON.stringify(data)); // return tx; // }, // { // domain: this.isLocalhost() ? "example.com" : new URL(window.location.origin).hostname, // expires_in: "3 days", // } // ); // if (cb) { // const consentStream = this.communicationMux.getStream("consent_stream") as Substream; // cb(consentStream); // } // stream.on("data", (data) => { // if (data.name === "consent_response") { // resolve(data.data); // stream.destroy(); // } else if (data.name === "consent_error") { // reject(data.data.msg); // stream.destroy(); // } // }); // stream.on("error", (err) => { // reject(err); // stream.destroy(); // }); // } catch (error) { // if (error.message && error.message.includes("user rejected signing")) { // reject(new Error("User rejected your request")); // stream.destroy(); // } // reject(error); // stream.destroy(); // } // }); // } // getUserData(): Promise<ConsentDidResponse> { // return new Promise((resolve, reject) => { // const stream = this.communicationMux.getStream(this.consentStreamName.getConsentData) as Substream; // stream.write({ // name: this.consentStreamName.getConsentData, // data: { // clientId: this.consentApiKey, // secretKey: this.key, // origin: window.location.origin, // }, // }); // stream.on("data", (ev) => { // if (ev.name === "result") { // resolve(ev.data); // } // reject(new Error("Consent does not exist")); // }); // }); // } listenDidCreation() { const stream = this.communicationMux.getStream(this.consentStreamName.listenerStream); stream.write({ name: configuration.DID_STREAM_NAME.REQUEST, data: { interval: this.didIntervalRequest } }); stream.on("data", ev => { if (ev.name && ev.name === configuration.DID_STREAM_NAME.RESULT) { if (ev.data) { this.isDidDeployed = true; } else { this.isDidDeployed = false; } } }); } isLocalhost() { return new URL(window.location.origin).hostname === "localhost"; } _createDigest(encodedData, format) { return crypto.createHmac("sha256", this.publicKey).update(encodedData).digest(format); } _decode(value) { let [encodedData, sourceDigest] = value.split("!"); if (!encodedData || !sourceDigest) throw new Error("invalid value(s)"); const json = Buffer.from(encodedData, "base64").toString("utf8"); const decodedData = JSON.parse(json); const checkDigest = this._createDigest(encodedData, "base64"); const digestsEqual = timingSafeEqual(sourceDigest, checkDigest); if (!digestsEqual) throw new Error("invalid value(s)"); return decodedData; } } const runOnLoad = fn => new Promise((resolve, reject) => { if (window.document.body != null) { Promise.resolve(fn()).then(resolve).catch(reject); } else { window.document.addEventListener("DOMContentLoaded", () => { Promise.resolve(fn()).then(resolve).catch(reject); }); } }); const htmlToElement = html => { const template = window.document.createElement("template"); const trimmedHtml = html.trim(); // Never return a text node of whitespace as the result template.innerHTML = trimmedHtml; return template.content.firstChild; }; const handleEvent = function (handle, eventName, handler) { for (var _len = arguments.length, handlerArgs = new Array(_len > 3 ? _len - 3 : 0), _key = 3; _key < _len; _key++) { handlerArgs[_key - 3] = arguments[_key]; } const handlerWrapper = () => { handler(...handlerArgs); handle.removeEventListener(eventName, handlerWrapper); }; handle.addEventListener(eventName, handlerWrapper); }; const handleStream = (handle, eventName, handler) => { const handlerWrapper = chunk => { handler(chunk); handle.removeListener(eventName, handlerWrapper); }; handle.on(eventName, handlerWrapper); }; async function documentReady() { return new Promise(resolve => { if (document.readyState !== "loading") { resolve(); } else { handleEvent(document, "DOMContentLoaded", resolve); } }); } var log = loglevel.getLogger("torus-embed"); var messages = { errors: { disconnected: () => "Upbond: Lost connection to Upbond.", permanentlyDisconnected: () => "Upbond: Disconnected from iframe. Page reload required.", sendSiteMetadata: () => "Upbond: Failed to send site metadata. This is an internal error, please report this bug.", unsupportedSync: method => `Upbond: The Upbond Ethereum provider does not support synchronous methods like ${method} without a callback parameter.`, invalidDuplexStream: () => "Must provide a Node.js-style duplex stream.", invalidOptions: (maxEventListeners, shouldSendMetadata) => `Invalid options. Received: { maxEventListeners: ${maxEventListeners}, shouldSendMetadata: ${shouldSendMetadata} }`, invalidRequestArgs: () => `Expected a single, non-array, object argument.`, invalidRequestMethod: () => `'args.method' must be a non-empty string.`, invalidRequestParams: () => `'args.params' must be an object or array if provided.`, invalidLoggerObject: () => `'args.logger' must be an object if provided.`, invalidLoggerMethod: method => `'args.logger' must include required method '${method}'.` }, info: { connected: chainId => `Upbond: Connected to chain with ID "${chainId}".` }, warnings: { // deprecated methods enableDeprecation: 'Upbond: ""ethereum.enable()" is deprecated and may be removed in the future. ' + 'Please use "ethereum.send("eth_requestAccounts")" instead. For more information, see: https://eips.ethereum.org/EIPS/eip-1102', sendDeprecation: 'Upbond: "ethereum.send(...)" is deprecated and may be removed in the future.' + ' Please use "ethereum.sendAsync(...)" or "ethereum.request(...)" instead.\nFor more information, see: https://eips.ethereum.org/EIPS/eip-1193', events: { close: 'Upbond: The event "close" is deprecated and may be removed in the future. Please use "disconnect" instead.' + "\nFor more information, see: https://eips.ethereum.org/EIPS/eip-1193", data: 'Upbond: The event "data" is deprecated and will be removed in the future.' + 'Use "message" instead.\nFor more information, see: https://eips.ethereum.org/EIPS/eip-1193#message', networkChanged: 'Upbond: The event "networkChanged" is deprecated and may be removed in the future.' + ' Please use "chainChanged" instead.\nFor more information, see: https://eips.ethereum.org/EIPS/eip-1193', notification: 'Upbond: The event "notification" is deprecated and may be removed in the future. ' + 'Please use "message" instead.\nFor more information, see: https://eips.ethereum.org/EIPS/eip-1193' }, publicConfigStore: 'Upbond: The property "publicConfigStore" is deprecated and WILL be removed in the future.' } }; const { paymentProviders } = configuration; const defaultLoginParam = { "upbond-line": { name: "LINE", description: "LINE", typeOfLogin: "line", loginProvider: "upbond-line", jwtParameters: { domain: "https://lzg2dndj.auth.dev.upbond.io", connection: "line", clientId: "FoQ_Ri8rKSXkHf82GRzZK", scope: "openid email profile offline_access" }, clientId: "BGbtA2oA0SYvm1fipIPaSgSTPfGJG8Q6Ep_XHuZY9qQVW5jUXTMd0l8xVtXPx91aCmFfuVqTZt9CK79BgHTNanU", showOnModal: true, showOnDesktop: true, showOnMobile: true, mainOption: true, priority: 1, customLogo: "line", logo: "https://elvira.co.th/wp-content/uploads/2016/02/line-icon.png", buttonBgColor: "#289B2A", buttonTextColor: "#f3f3f3" }, "upbond-google": { name: "Google", description: "Google", typeOfLogin: "jwt", loginProvider: "upbond-google", jwtParameters: { domain: "https://lzg2dndj.auth.dev.upbond.io", connection: "line", clientId: "hxFv4SaQVXv3tE_rhe5u9", scope: "openid email profile offline_access" }, clientId: "BGbtA2oA0SYvm1fipIPaSgSTPfGJG8Q6Ep_XHuZY9qQVW5jUXTMd0l8xVtXPx91aCmFfuVqTZt9CK79BgHTNanU", showOnModal: true, showOnDesktop: true, showOnMobile: true, mainOption: true, priority: 2, customLogo: "google", logo: "https://www.seekpng.com/png/full/788-7887426_google-g-png-google-logo-white-png.png", buttonBgColor: "#4B68AE", buttonTextColor: "#FFF" } }; const defaultLoginParamStg = { "upbond-line": { name: "LINE", description: "LINE", typeOfLogin: "line", loginProvider: "upbond-line", jwtParameters: { domain: "https://6a8e4595.auth.stg.upbond.io", connection: "line", clientId: "YQvxSsSNOIFgoEwZoiPdm", scope: "openid email profile offline_access" }, clientId: "BGbtA2oA0SYvm1fipIPaSgSTPfGJG8Q6Ep_XHuZY9qQVW5jUXTMd0l8xVtXPx91aCmFfuVqTZt9CK79BgHTNanU", showOnModal: true, showOnDesktop: true, showOnMobile: true, mainOption: true, priority: 1, customLogo: "line", logo: "https://elvira.co.th/wp-content/uploads/2016/02/line-icon.png", buttonBgColor: "#289B2A", buttonTextColor: "#f3f3f3" }, "upbond-google": { name: "Google", description: "Google", typeOfLogin: "jwt", loginProvider: "upbond-google", jwtParameters: { domain: "https://6a8e4595.auth.stg.upbond.io", connection: "line", clientId: "zYvDxb22eVYLqDMAp_ql9", scope: "openid email profile offline_access" }, clientId: "BGbtA2oA0SYvm1fipIPaSgSTPfGJG8Q6Ep_XHuZY9qQVW5jUXTMd0l8xVtXPx91aCmFfuVqTZt9CK79BgHTNanU", showOnModal: true, showOnDesktop: true, showOnMobile: true, mainOption: true, priority: 2, customLogo: "google", logo: "https://www.seekpng.com/png/full/788-7887426_google-g-png-google-logo-white-png.png", buttonBgColor: "#4B68AE", buttonTextColor: "#FFF" } }; const defaultLoginParamProd = { "upbond-line": { name: "LINE", description: "LINE", typeOfLogin: "line", loginProvider: "upbond-line", jwtParameters: { domain: "https://auth.upbond.io", connection: "line", clientId: "wa3wjaB0dx0RO9AgzngM-", scope: "openid email profile offline_access" }, clientId: "BKmNTSQ7y8yWyhNT_W5BobaAu7Re-zLW6fzK0bzdvjP9a-G4OP8ajriQJHFOH3ypvRIJeEp_O40aag-7iNTyp-s", showOnModal: true, showOnDesktop: true, showOnMobile: true, mainOption: true, priority: 1, customLogo: "line", logo: "https://elvira.co.th/wp-content/uploads/2016/02/line-icon.png", buttonBgColor: "#289B2A", buttonTextColor: "#f3f3f3" }, "upbond-google": { name: "Google", description: "Google", typeOfLogin: "jwt", loginProvider: "upbond-google", jwtParameters: { domain: "https://auth.upbond.io", connection: "line", clientId: "hxFv4SaQVXv3tE_rhe5u9", scope: "openid email profile offline_access" }, clientId: "BKmNTSQ7y8yWyhNT_W5BobaAu7Re-zLW6fzK0bzdvjP9a-G4OP8ajriQJHFOH3ypvRIJeEp_O40aag-7iNTyp-s", showOnModal: true, showOnDesktop: true, showOnMobile: true, mainOption: true, priority: 2, customLogo: "google", logo: "https://www.seekpng.com/png/full/788-7887426_google-g-png-google-logo-white-png.png", buttonBgColor: "#4B68AE", buttonTextColor: "#FFF" } }; const validatePaymentProvider = (provider, params) => { const errors = {}; if (!provider) { return { errors, isValid: true }; } if (provider && !paymentProviders[provider]) { errors.provider = "Invalid Provider"; return { errors, isValid: Object.keys(errors).length === 0 }; } const selectedProvider = paymentProviders[provider]; const selectedParams = params || {}; // set default values // if (!selectedParams.selectedCurrency) [selectedParams.selectedCurrency] = selectedProvider.validCurrencies // if (!selectedParams.fiatValue) selectedParams.fiatValue = selectedProvider.minOrderValue // if (!selectedParams.selectedCryptoCurrency) [selectedParams.selectedCryptoCurrency] = selectedProvider.validCryptoCurrencies // validations if (selectedParams.fiatValue) { const requestedOrderAmount = +parseFloat(selectedParams.fiatValue.toString()) || 0; if (requestedOrderAmount < selectedProvider.minOrderValue) errors.fiatValue = "Requested amount is lower than supported"; if (requestedOrderAmount > selectedProvider.maxOrderValue && selectedProvider.enforceMax) errors.fiatValue = "Requested amount is higher than supported"; } if (selectedParams.selectedCurrency && !selectedProvider.validCurrencies.includes(selectedParams.selectedCurrency)) { errors.selectedCurrency = "Unsupported currency"; } if (selectedParams.selectedCryptoCurrency) { const validCryptoCurrenciesByChain = Object.values(selectedProvider.validCryptoCurrenciesByChain).flat().map(currency => currency.value); const finalCryptoCurrency = provider === PAYMENT_PROVIDER.MOONPAY ? selectedParams.selectedCryptoCurrency.toLowerCase() : selectedParams.selectedCryptoCurrency; if (validCryptoCurrenciesByChain && !validCryptoCurrenciesByChain.includes(finalCryptoCurrency)) errors.selectedCryptoCurrency = "Unsupported cryptoCurrency"; } return { errors, isValid: Object.keys(errors).length === 0 }; }; // utility functions /** * json-rpc-engine middleware that logs RPC errors and and validates req.method. * * @param log - The logging API to use. * @returns json-rpc-engine middleware function */ function createErrorMiddleware() { return (req, res, next) => { // json-rpc-engine will terminate the request when it notices this error if (typeof req.method !== "string" || !req.method) { res.error = ethErrors.rpc.invalidRequest({ message: `The request 'method' must be a non-empty string.`, data: req }); } next(done => { const { error } = res; if (!error) { return done(); } log.error(`MetaMask - RPC Error: ${error.message}`, error); return done(); }); }; } /** * Logs a stream disconnection error. Emits an 'error' if given an * EventEmitter that has listeners for the 'error' event. * * @param log - The logging API to use. * @param remoteLabel - The label of the disconnected stream. * @param error - The associated error to log. * @param emitter - The logging API to use. */ function logStreamDisconnectWarning(remoteLabel, error, emitter) { let warningMsg = `MetaMask: Lost connection to "${remoteLabel}".`; if (error?.stack) { warningMsg += `\n${error.stack}`; } log.warn(warningMsg); if (emitter && emitter.listenerCount("error") > 0) { emitter.emit("error", warningMsg); } } const getPreopenInstanceId = () => Math.random().toString(36).slice(2); const getUpbondWalletUrl = async (buildEnv, // eslint-disable-next-line @typescript-eslint/no-unused-vars integrity) => { log.info("Opening torus URL!"); let torusUrl; let logLevel; // log.info("version used: ", versionUsed); switch (buildEnv) { /* Default the default to v2 */ case "production": case "v1_production": case "v2_production": torusUrl = `https://login.upbond.io`; logLevel = "info"; break; case "staging": case "v1_staging": case "v2_staging": torusUrl = "https://login.stg.upbond.io"; logLevel = "info"; break; case "development": case "v1_development": case "v2_development": case "testing": torusUrl = "https:/login.dev.upbond.io"; logLevel = "debug"; break; case "local": case "v2_local": torusUrl = "http://localhost:3002"; logLevel = "debug"; break; case "wallet-did": torusUrl = "https://wallet-did.dev.upbond.io"; logLevel = "debug"; break; case "mpc-dev": case "v3_development": torusUrl = "https://login-mpc.dev.upbond.io"; logLevel = "debug"; break; case "v3_staging": torusUrl = "https://login-mpc.stg.upbond.io"; logLevel = "debug"; break; case "v3_production": torusUrl = "https://login3.upbond.io"; logLevel = "info"; break; default: torusUrl = `https://login.upbond.io`; logLevel = "info"; break; } return { torusUrl, logLevel }; }; const getUserLanguage = () => { let userLanguage = window.navigator.language || "en-US"; const userLanguages = userLanguage.split("-"); userLanguage = Object.prototype.hasOwnProperty.call(configuration.translations, userLanguages[0]) ? userLanguages[0] : "en"; return userLanguage; }; const EMITTED_NOTIFICATIONS = ["eth_subscription" // per eth-json-rpc-filters/subscriptionManager ]; const NOOP = () => { // empty function }; const FEATURES_PROVIDER_CHANGE_WINDOW = "directories=0,titlebar=0,toolbar=0,status=0,location=0,menubar=0,height=660,width=375"; const FEATURES_DEFAULT_WALLET_WINDOW = "directories=0,titlebar=0,toolbar=0,status=0,location=0,menubar=0,height=740,width=1315"; const FEATURES_CONFIRM_WINDOW = "directories=0,titlebar=0,toolbar=0,status=0,location=0,menubar=0,height=700,width=450"; function getPopupFeatures() { // Fixes dual-screen position Most browsers Firefox const dualScreenLeft = window.screenLeft !== undefined ? window.screenLeft : window.screenX; const dualScreenTop = window.screenTop !== undefined ? window.screenTop : window.screenY; const w = 1200; const h = 700; const width = window.innerWidth ? window.innerWidth : document.documentElement.clientWidth ? document.documentElement.clientWidth : window.screen.width; const height = window.innerHeight ? window.innerHeight : document.documentElement.clientHeight ? document.documentElement.clientHeight : window.screen.height; const systemZoom = 1; // No reliable estimate const left = Math.abs((width - w) / 2 / systemZoom + dualScreenLeft); const top = Math.abs((height - h) / 2 / systemZoom + dualScreenTop); const features = `titlebar=0,toolbar=0,status=0,location=0,menubar=0,height=${h / systemZoom},width=${w / systemZoom},top=${top},left=${left}`; return features; } const searchToObject = search => { return search.substring(1).split("&").reduce(function (result, value) { const parts = value.split("="); if (parts[0]) result[decodeURIComponent(parts[0])] = decodeURIComponent(parts[1]); return result; }, {}); }; const parseIdToken = function (token) { let pureJwt = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; if (pureJwt) { const json = decodeURIComponent(window.atob(token).split("").map(c => { return `%${`00${c.charCodeAt(0).toString(16)}`.slice(-2)}`; }).join("")); return JSON.parse(json); } const base64Url = token.split(".")[1]; const base64 = base64Url.replace(/-/g, "+").replace(/_/g, "/"); const jsonPayload = decodeURIComponent(window.atob(base64).split("").map(c => { return `%${`00${c.charCodeAt(0).toString(16)}`.slice(-2)}`; }).join("")); return JSON.parse(jsonPayload); }; function ownKeys$1(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } function _objectSpread$1(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys$1(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys$1(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } SafeEventEmitter.defaultMaxListeners = 100; // resolve response.result, reject errors const getRpcPromiseCallback = function (resolve, reject) { let unwrapResult = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; return (error, response) => { if (error || response.error) { return reject(error || response.error); } return !unwrapResult || Array.isArray(response) ? resolve(response) : resolve(response.result); }; }; class UpbondInpageProvider extends SafeEventEmitter { /** * The chain ID of the currently connected Ethereum chain. * See [chainId.network]{@link https://chainid.network} for more information. */ /** * The user's currently selected Ethereum address. * If null, MetaMask is either locked or the user has not permitted any * addresses to be viewed. */ /** * Indicating that this provider is a MetaMask provider. */ constructor(connectionStream) { let { maxEventListeners = 100, shouldSendMetadata = true, jsonRpcStreamName = "provider" } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; super(); _defineProperty(this, "chainId", void 0); _defineProperty(this, "selectedAddress", void 0); _defineProperty(this, "_rpcEngine", void 0); _defineProperty(this, "networkVersion", void 0); _defineProperty(this, "shouldSendMetadata", void 0); _defineProperty(this, "isUpbond", void 0); _defineProperty(this, "_publicConfigStore", void 0); _defineProperty(this, "tryPreopenHandle", void 0); _defineProperty(this, "enable", void 0); _defineProperty(this, "_state", void 0); _defineProperty(this, "_jsonRpcConnection", void 0); _defineProperty(this, "_sentWarnings", { // methods enable: false, experimentalMethods: false, send: false, publicConfigStore: false, // events events: { close: false, data: false, networkChanged: false, notification: false } }); if (!duplex(connectionStream)) { throw new Error(messages.errors.invalidDuplexStream()); } this.isUpbond = true; this.setMaxListeners(maxEventListeners); // private state this._state = _objectSpread$1({}, UpbondInpageProvider._defaultState); // public state this.selectedAddress = null; this.networkVersion = null; this.chainId = null; this.shouldSendMetadata = shouldSendMetadata; // bind functions (to prevent e.g. web3@1.x from making unbound calls) this._handleAccountsChanged = this._handleAccountsChanged.bind(this); this._handleChainChanged = this._handleChainChanged.bind(this); this._handleUnlockStateChanged = this._handleUnlockStateChanged.bind(this); this._handleConnect = this._handleConnect.bind(this); this._handleDisconnect = this._handleDisconnect.bind(this); this._handleStreamDisconnect = this._handleStreamDisconnect.bind(this); this._sendSync = this._sendSync.bind(this); this._rpcRequest = this._rpcRequest.bind(this); this._warnOfDeprecation = this._warnOfDeprecation.bind(this); this._initializeState = this._initializeState.bind(this); this.request = this.request.bind(this); this.send = this.send.bind(this); this.sendAsync = this.sendAsync.bind(this); // this.enable = this.enable.bind(this); // setup connectionStream multiplexing const mux = new ObjectMultiplex(); pump(connectionStream, mux, connectionStream, this._handleStreamDisconnect.bind(this, "MetaMask")); // subscribe to metamask public config (one-way) this._publicConfigStore = new ObservableStore({ storageKey: "Metamask-Config" }); // handle isUnlocked changes, and chainChanged and networkChanged events // this._publicConfigStore.subscribe((stringifiedState) => { // // This is because we are using store as string // const state = JSON.parse(stringifiedState as unknown as string); // if ("isUnlocked" in state && state.isUnlocked !== this._state.isUnlocked) { // this._state.isUnlocked = state.isUnlocked; // if (!this._state.isUnlocked) { // // accounts are never exposed when the extension is locked // this._handleAccountsChanged([]); // } else { // // this will get the exposed accounts, if any // try { // this._rpcRequest( // { method: "eth_accounts", params: [] }, // NOOP, // true // indicating that eth_accounts _should_ update accounts // ); // } catch (_) { // // Swallow error // } // } // } // if ("selectedAddress" in state && this.selectedAddress !== state.selectedAddress) { // try { // this._rpcRequest( // { method: "eth_accounts", params: [] }, // NOOP, // true // indicating that eth_accounts _should_ update accounts // ); // } catch (_) { // // Swallow error // } // } // // Emit chainChanged event on chain change // if ("chainId" in state && state.chainId !== this.chainId) { // this.chainId = state.chainId || null; // this.emit("chainChanged", this.chainId); // // indicate that we've connected, for EIP-1193 compliance // // we do this here so that iframe can initialize // if (!this._state.hasEmittedConnection) { // this._handleConnect(this.chainId); // this._state.hasEmittedConnection = true; // } // } pump(mux.createStream("publicConfig"), storeAsStream(this._publicConfigStore), // RPC requests should still work if only this stream fails logStreamDisconnectWarning.bind(this, "MetaMask PublicConfigStore")); // ignore phishing warning message (handled elsewhere) mux.ignoreStream("phishing"); // setup own event listeners // EIP-1193 connect this.on("connect", () => { this._state.isConnected = true; }); // connect to async provider const jsonRpcConnection = createStreamMiddleware(); pump(jsonRpcConnection.stream, mux.createStream(jsonRpcStreamName), jsonRpcConnection.stream, this._handleStreamDisconnect.bind(this, "MetaMask RpcProvider")); // handle RPC requests via dapp-side rpc engine const rpcEngine = new JRPCEngine(); rpcEngine.push(createIdRemapMiddleware()); rpcEngine.push(createErrorMiddleware()); rpcEngine.push(jsonRpcConnection.middleware); this._rpcEngine = rpcEngine; // json rpc notification listener jsonRpcConnection.events.on("notification", payload => { const { method, params } = payload; if (method === "wallet_accountsChanged") { this._handleAccountsChanged(params); } else if (method === "wallet_unlockStateChanged") { this._handleUnlockStateChanged(params); } else if (method === "wallet_chainChanged") { this._handleChainChanged(params); } else if (EMITTED_NOTIFICATIONS.includes(payload.method)) { // EIP 1193 subscriptions, per eth-json-rpc-filters/subscriptionManager this.emit("data", payload); // deprecated this.emit("notification", params.result); this.emit("message", { type: method, data: params }); } // Backward compatibility for older non EIP 1193 subscriptions // t