UNPKG

@metamask/providers

Version:

A JavaScript Ethereum provider that connects to the wallet over a stream

1 lines 9.96 kB
{"version":3,"file":"CAIP294.mjs","sourceRoot":"","sources":["../src/CAIP294.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,wBAAwB;AAG3C,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,oBAAgB;AAEpD;;GAEG;AACH,MAAM,CAAN,IAAY,iBAGX;AAHD,WAAY,iBAAiB;IAC3B,yDAAoC,CAAA;IACpC,qDAAgC,CAAA;AAClC,CAAC,EAHW,iBAAiB,KAAjB,iBAAiB,QAG5B;AAyDD;;;;;GAKG;AACH,SAAS,yBAAyB,CAChC,KAAc;IAEd,OAAO,CACL,KAAK,YAAY,WAAW;QAC5B,KAAK,CAAC,IAAI,KAAK,iBAAiB,CAAC,MAAM;QACvC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC;QACtB,KAAK,CAAC,MAAM,CAAC,MAAM,KAAK,eAAe;QACvC,yBAAyB,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAC/C,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,SAAS,yBAAyB,CAAC,MAAW;IAC5C,MAAM,aAAa,GACjB,MAAM,CAAC,MAAM,KAAK,SAAS;QAC3B,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC;YAC3B,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAU,EAAE,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC;IAEpE,MAAM,eAAe,GACnB,MAAM,CAAC,QAAQ,KAAK,SAAS,IAAI,OAAO,MAAM,CAAC,QAAQ,KAAK,QAAQ,CAAC;IAEvE,OAAO,aAAa,IAAI,eAAe,CAAC;AAC1C,CAAC;AAED;;;;;GAKG;AACH,SAAS,0BAA0B,CACjC,KAAc;IAEd,OAAO,CACL,KAAK,YAAY,WAAW;QAC5B,KAAK,CAAC,IAAI,KAAK,iBAAiB,CAAC,QAAQ;QACzC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC;QACtB,KAAK,CAAC,MAAM,CAAC,MAAM,KAAK,iBAAiB;QACzC,iBAAiB,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CACvC,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,SAAS,iBAAiB,CAAC,IAAa;IACtC,OAAO,CACL,QAAQ,CAAC,IAAI,CAAC;QACd,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ;QAC7B,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;QAC7B,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ;QAC7B,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;QAClB,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ;QAC7B,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC;QAClC,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ;QAC7B,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;QAC1B,CAAC,IAAI,CAAC,WAAW,KAAK,SAAS;YAC7B,CAAC,OAAO,IAAI,CAAC,WAAW,KAAK,QAAQ,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CACzE,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAAC,UAA6B;IAC1D,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC,EAAE,CAAC;QACnC,iBAAiB,CACf,oDAAoD,iBAAiB,CAAC,MAAM,GAAG,CAChF,CAAC;IACJ,CAAC;IAED,MAAM,eAAe,GAAG,GAAG,EAAE,CAC3B,MAAM,CAAC,aAAa,CAClB,IAAI,WAAW,CAAC,iBAAiB,CAAC,QAAQ,EAAE;QAC1C,MAAM,EAAE;YACN,EAAE,EAAE,CAAC;YACL,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,iBAAiB;YACzB,MAAM,EAAE,UAAU;SACnB;KACF,CAAC,CACH,CAAC;IAEJ,eAAe,EAAE,CAAC;IAClB,MAAM,CAAC,gBAAgB,CACrB,iBAAiB,CAAC,MAAM,EACxB,CAAC,KAAgC,EAAE,EAAE;QACnC,IAAI,CAAC,yBAAyB,CAAC,KAAK,CAAC,EAAE,CAAC;YACtC,iBAAiB,CACf,4DAA4D,iBAAiB,CAAC,MAAM,GAAG,CACxF,CAAC;QACJ,CAAC;QACD,eAAe,EAAE,CAAC;IACpB,CAAC,CACF,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAC3B,YAAkE;IAElE,MAAM,CAAC,gBAAgB,CACrB,iBAAiB,CAAC,QAAQ,EAC1B,CAAC,KAAiC,EAAE,EAAE;QACpC,IAAI,CAAC,0BAA0B,CAAC,KAAK,CAAC,EAAE,CAAC;YACvC,iBAAiB,CACf,oDAAoD,iBAAiB,CAAC,QAAQ,GAAG,CAClF,CAAC;QACJ,CAAC;QACD,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAC7B,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,aAAa,CAClB,IAAI,WAAW,CAAC,iBAAiB,CAAC,MAAM,EAAE;QACxC,MAAM,EAAE;YACN,EAAE,EAAE,CAAC;YACL,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,eAAe;YACvB,MAAM,EAAE,EAAE;SACX;KACF,CAAC,CACH,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,SAAS,iBAAiB,CAAC,OAAe;IACxC,MAAM,IAAI,KAAK,CACb,GAAG,OAAO,+HAA+H,CAC1I,CAAC;AACJ,CAAC","sourcesContent":["import { isObject } from '@metamask/utils';\n\nimport type { BaseProviderInfo } from './types';\nimport { FQDN_REGEX, UUID_V4_REGEX } from './utils';\n\n/**\n * Describes the possible CAIP-294 event names\n */\nexport enum CAIP294EventNames {\n Announce = 'caip294:wallet_announce',\n Prompt = 'caip294:wallet_prompt',\n}\n\ndeclare global {\n // eslint-disable-next-line @typescript-eslint/consistent-type-definitions\n interface WindowEventMap {\n [CAIP294EventNames.Prompt]: CAIP294RequestWalletEvent;\n [CAIP294EventNames.Announce]: CAIP294AnnounceWalletEvent;\n }\n}\n\n/**\n * Represents the assets needed to display and identify a wallet.\n * @type CAIP294WalletData\n * @property uuid - A locally unique identifier for the wallet. MUST be a v4 UUID.\n * @property name - The name of the wallet.\n * @property icon - The icon for the wallet. MUST be data URI.\n * @property rdns - The reverse syntax domain name identifier for the wallet.\n * @property extensionId - The canonical extension ID of the wallet provider for the active browser.\n */\nexport type CAIP294WalletData = BaseProviderInfo & {\n extensionId?: string | undefined;\n};\n\n/**\n * Event for requesting a wallet.\n *\n * @type CAIP294RequestWalletEvent\n * @property detail - The detail object of the event.\n * @property type - The name of the event.\n */\nexport type CAIP294RequestWalletEvent = CustomEvent & {\n detail: {\n id: number;\n jsonrpc: '2.0';\n method: 'wallet_prompt';\n params: Record<string, any>;\n };\n type: CAIP294EventNames.Prompt;\n};\n\n/**\n * Event for announcing a wallet.\n *\n * @type CAIP294AnnounceWalletEvent\n * @property detail - The detail object of the event.\n * @property type - The name of the event.\n */\nexport type CAIP294AnnounceWalletEvent = CustomEvent & {\n detail: {\n id: number;\n jsonrpc: '2.0';\n method: 'wallet_announce';\n params: CAIP294WalletData;\n };\n type: CAIP294EventNames.Announce;\n};\n\n/**\n * Validates an {@link CAIP294RequestWalletEvent} object.\n *\n * @param event - The {@link CAIP294RequestWalletEvent} to validate.\n * @returns Whether the {@link CAIP294RequestWalletEvent} is valid.\n */\nfunction isValidRequestWalletEvent(\n event: unknown,\n): event is CAIP294RequestWalletEvent {\n return (\n event instanceof CustomEvent &&\n event.type === CAIP294EventNames.Prompt &&\n isObject(event.detail) &&\n event.detail.method === 'wallet_prompt' &&\n isValidWalletPromptParams(event.detail.params)\n );\n}\n\n/**\n * Validates a {@link CAIP294RequestWalletEvent} params field.\n *\n * @param params - The parameters to validate.\n * @returns Whether the parameters are valid.\n */\nfunction isValidWalletPromptParams(params: any): params is Record<string, any> {\n const isValidChains =\n params.chains === undefined ||\n (Array.isArray(params.chains) &&\n params.chains.every((chain: any) => typeof chain === 'string'));\n\n const isValidAuthName =\n params.authName === undefined || typeof params.authName === 'string';\n\n return isValidChains && isValidAuthName;\n}\n\n/**\n * Validates an {@link CAIP294AnnounceWalletEvent} object.\n *\n * @param event - The {@link CAIP294AnnounceWalletEvent} to validate.\n * @returns Whether the {@link CAIP294AnnounceWalletEvent} is valid.\n */\nfunction isValidAnnounceWalletEvent(\n event: unknown,\n): event is CAIP294AnnounceWalletEvent {\n return (\n event instanceof CustomEvent &&\n event.type === CAIP294EventNames.Announce &&\n isObject(event.detail) &&\n event.detail.method === 'wallet_announce' &&\n isValidWalletData(event.detail.params)\n );\n}\n\n/**\n * Validates an {@link CAIP294WalletData} object.\n *\n * @param data - The {@link CAIP294WalletData} to validate.\n * @returns Whether the {@link CAIP294WalletData} is valid.\n */\nfunction isValidWalletData(data: unknown): data is CAIP294WalletData {\n return (\n isObject(data) &&\n typeof data.uuid === 'string' &&\n UUID_V4_REGEX.test(data.uuid) &&\n typeof data.name === 'string' &&\n Boolean(data.name) &&\n typeof data.icon === 'string' &&\n data.icon.startsWith('data:image') &&\n typeof data.rdns === 'string' &&\n FQDN_REGEX.test(data.rdns) &&\n (data.extensionId === undefined ||\n (typeof data.extensionId === 'string' && data.extensionId.length > 0))\n );\n}\n\n/**\n * Intended to be used by a wallet. Announces a wallet by dispatching\n * an {@link CAIP294AnnounceWalletEvent}, and listening for\n * {@link CAIP294RequestWalletEvent} to re-announce.\n *\n * @throws If the {@link CAIP294WalletData} is invalid.\n * @param walletData - The {@link CAIP294WalletData} to announce.\n */\nexport function announceWallet(walletData: CAIP294WalletData): void {\n if (!isValidWalletData(walletData)) {\n throwErrorCAIP294(\n `Invalid CAIP-294 WalletData object received from ${CAIP294EventNames.Prompt}.`,\n );\n }\n\n const _announceWallet = () =>\n window.dispatchEvent(\n new CustomEvent(CAIP294EventNames.Announce, {\n detail: {\n id: 1,\n jsonrpc: '2.0',\n method: 'wallet_announce',\n params: walletData,\n },\n }),\n );\n\n _announceWallet();\n window.addEventListener(\n CAIP294EventNames.Prompt,\n (event: CAIP294RequestWalletEvent) => {\n if (!isValidRequestWalletEvent(event)) {\n throwErrorCAIP294(\n `Invalid CAIP-294 RequestWalletEvent object received from ${CAIP294EventNames.Prompt}.`,\n );\n }\n _announceWallet();\n },\n );\n}\n\n/**\n * Intended to be used by a dapp. Forwards announced wallet to the\n * provided handler by listening for * {@link CAIP294AnnounceWalletEvent},\n * and dispatches an {@link CAIP294RequestWalletEvent}.\n *\n * @param handleWallet - A function that handles an announced wallet.\n */\nexport function requestWallet<HandlerReturnType>(\n handleWallet: (walletData: CAIP294WalletData) => HandlerReturnType,\n): void {\n window.addEventListener(\n CAIP294EventNames.Announce,\n (event: CAIP294AnnounceWalletEvent) => {\n if (!isValidAnnounceWalletEvent(event)) {\n throwErrorCAIP294(\n `Invalid CAIP-294 WalletData object received from ${CAIP294EventNames.Announce}.`,\n );\n }\n handleWallet(event.detail);\n },\n );\n\n window.dispatchEvent(\n new CustomEvent(CAIP294EventNames.Prompt, {\n detail: {\n id: 1,\n jsonrpc: '2.0',\n method: 'wallet_prompt',\n params: {},\n },\n }),\n );\n}\n\n/**\n * Throws an error with link to CAIP-294 specifications.\n *\n * @param message - The message to include.\n * @throws a friendly error with a link to CAIP-294.\n */\nfunction throwErrorCAIP294(message: string) {\n throw new Error(\n `${message} See https://github.com/ChainAgnostic/CAIPs/blob/bc4942857a8e04593ed92f7dc66653577a1c4435/CAIPs/caip-294.md for requirements.`,\n );\n}\n"]}