@cashie/ethereum-provider 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/provider/types.ts", "../src/ecdh/ecdh-manager.ts", "../src/utils/validate.ts", "../src/iframe/iframe.ts", "../src/iframe/iframe-handler.ts", "../src/utils/random.ts", "../src/provider/transeptor-ethereum-provider.ts", "../src/provider/errors.ts", "../src/provider/eip-1193-bridge.ts", "../src/provider/eip-6963/types.ts", "../src/provider/eip-6963/icon.ts", "../src/provider/eip-6963/announce-provider.ts"],
4
+ "sourcesContent": ["export class ProviderRpcError extends Error {\n /**\n * MUST be an integer number\n * SHOULD adhere to the specifications in the Error Standards section below\n *\n * @see https://eips.ethereum.org/EIPS/eip-1193#error-standards\n */\n code: number\n\n /**\n * SHOULD contain any other useful information about the error\n */\n data?: unknown\n\n constructor({\n message,\n code,\n data,\n }: {\n message: string\n code: number\n data?: unknown\n }) {\n super(message)\n this.code = code\n this.data = data\n }\n}\n\n/**\n * The Eip1193 error types\n *\n * @see https://eips.ethereum.org/EIPS/eip-1193#rpc-errors\n */\nexport type Eip1193Error =\n | 'userRejectedRequest'\n | 'unauthorized'\n | 'unsupportedMethod'\n | 'disconnected'\n | 'chainDisconnected'\n\nexport type Eip1193RequestArguments = {\n method: string\n params?: readonly unknown[] | object\n}\n\nexport interface Eip1193Provider {\n /**\n * Request a method from the Eip1193 provider\n *\n * @param request - the request to be sent to the Eip1193 provider\n * @returns the response from the Eip1193 provider\n *\n * @throws If the returned Promise rejects, it MUST reject with a ProviderRpcError as specified in the [EIP-1193](https://eips.ethereum.org/EIPS/eip-1193#rpc-errors) section below.\n */\n request: (request: Eip1193RequestArguments) => Promise<unknown>\n}\n\n/**\n * The message event is intended for arbitrary notifications not covered by other events.\n *\n * @see https://eips.ethereum.org/EIPS/eip-1193#message-event\n */\nexport type Eip1193ProviderMessage = {\n readonly type: string\n readonly data: unknown\n}\n\n/**\n * Specify the integer ID of the connected chain as a hexadecimal string, per the eth_chainId Ethereum RPC method.\n *\n * @see https://eips.ethereum.org/EIPS/eip-1193#provider_connect\n */\nexport type Eip1193ProviderConnectInfo = {\n readonly chainId: `0x${string}`\n}\n", "/* eslint-disable no-console */\nimport { SecureMessageType, SecureMessage } from './ecdh.types.js'\nimport {\n JsonRpcRequest,\n OutboundJsonRpcEventRequest,\n OutboundRpcRequestEventsMethodNames,\n JsonRpcResponse,\n JsonRpcErrorResponse,\n InboundJsonRpcEventRequest,\n InboundRpcRequestEventsMethodNames,\n} from '../types/index.js'\n\n/**\n * Ephemeral ECDH key pair(private key, public key), public key(public key in jwk format), and nonce\n */\nexport type EphemeralEcdh = {\n keyPair: CryptoKeyPair | null\n pubJwk: JsonWebKey | null\n nonce: Uint8Array | null\n}\n\n/**\n * Create a new ephemeral ECDH manager\n * The ECDH(Elliptic Curve Diffie\u2013Hellman) key exchange manager is used to generate a shared secret key to encrypt and decrypt secure messages between the two parties on an untrusted channel.\n */\nexport class EphemeralEcdhManager {\n private readonly ALGO = { name: 'ECDH', namedCurve: 'P-256' }\n #isInitialized = false\n #ephemeralEcdh: EphemeralEcdh = {\n keyPair: null,\n pubJwk: null,\n nonce: null,\n }\n #isKeyExchangeDone: {\n role: 'parent' | 'iframe' | null\n ok: boolean\n } = {\n role: null,\n ok: false,\n }\n #sequence = 0\n #aeadKey: CryptoKey | null = null\n\n constructor() {\n // empty constructor\n }\n\n /**\n * Assert that the ECDH is initialized\n *\n * @throws an error if the ECDH is not initialized\n */\n #assertInitialized(): void {\n if (!this.#isInitialized) {\n throw new Error('ECDH not initialized')\n }\n }\n\n /**\n * Assert that the secure connection is established\n *\n * @throws an error if the secure connection is not established\n */\n #assertSecureConnectionEstablished(): void {\n if (!this.#isKeyExchangeDone.ok) {\n throw new Error('Secure connection not established')\n }\n }\n\n /**\n * Check if Web Crypto API is available and properly configured\n *\n * @throws an error if Web Crypto API is not available\n */\n #assertWebCryptoAvailable(): void {\n try {\n if (\n typeof crypto !== 'undefined' &&\n typeof crypto.subtle !== 'undefined' &&\n typeof crypto.getRandomValues !== 'undefined' &&\n typeof crypto.subtle.generateKey !== 'undefined' &&\n typeof crypto.subtle.encrypt !== 'undefined' &&\n typeof crypto.subtle.decrypt !== 'undefined'\n ) {\n return\n }\n throw new Error('Web Crypto API not available')\n } catch (error) {\n throw new Error('Web Crypto API not available')\n }\n }\n\n /**\n * Check if the secure connection is established\n *\n * @returns true if the secure connection is established, false otherwise\n */\n get isSecureConnectionEstablished(): boolean {\n return this.#isKeyExchangeDone.ok\n }\n\n /**\n * Initialize the ECDH\n *\n * @returns void\n */\n async initializeEcdh(): Promise<void> {\n this.#assertWebCryptoAvailable()\n const keyPair = await crypto.subtle.generateKey(this.ALGO, true, [\n 'deriveBits',\n ])\n const pubJwk = await crypto.subtle.exportKey('jwk', keyPair.publicKey)\n const nonce = crypto.getRandomValues(new Uint8Array(16))\n\n this.#ephemeralEcdh = {\n keyPair,\n pubJwk,\n nonce,\n } as EphemeralEcdh\n this.#isInitialized = true\n }\n\n /**\n * Parse a key exchange message to generate a shared secret\n *\n * @param message - the key exchange response message\n * @returns void\n */\n async parseKeyExchangeMessage(\n message: SecureMessage<SecureMessageType.KeyExchangeResponse>,\n ): Promise<void> {\n this.#assertInitialized()\n if (!this.#ephemeralEcdh.keyPair) {\n throw new Error('Ephemeral keys not initialized')\n }\n if (!this.#ephemeralEcdh.nonce) {\n throw new Error('Ephemeral nonce not initialized')\n }\n\n // Extract the public key and nonce from the message\n const { pub, nonce } = message.payload\n const recipientPub = await crypto.subtle.importKey(\n 'jwk',\n pub,\n this.ALGO,\n false,\n [],\n )\n\n // Compute a shared secret using the recipient's public key and the ephemeral private key pair\n const bits = await crypto.subtle.deriveBits(\n { name: this.ALGO.name, public: recipientPub },\n this.#ephemeralEcdh.keyPair.privateKey,\n 256,\n )\n const baseKey = await crypto.subtle.importKey('raw', bits, 'HKDF', false, [\n 'deriveKey',\n ])\n\n // Derive the salt with format <parent-nonce,child-nonce>\n // Note: This must match the iframe's salt ordering for consistent key derivation\n const salt = new Uint8Array([\n ...this.#ephemeralEcdh.nonce,\n ...new Uint8Array(nonce),\n ])\n\n // Derive the AEAD key from the base key and the salt that will be used to encrypt/decrypt the messages between the both parties\n this.#aeadKey = await crypto.subtle.deriveKey(\n {\n name: 'HKDF',\n hash: 'SHA-256',\n salt,\n info: new TextEncoder().encode('transeptor-pay-v1'),\n },\n baseKey,\n { name: 'AES-GCM', length: 256 },\n false,\n ['encrypt', 'decrypt'],\n )\n }\n\n /**\n * Generate a key exchange message\n *\n * @returns the key exchange message\n */\n async generateKeyExchangeMessage(): Promise<\n SecureMessage<SecureMessageType.KeyExchangeInit>\n > {\n this.#assertInitialized()\n if (!this.#ephemeralEcdh.pubJwk) {\n throw new Error('Ephemeral public key not initialized')\n }\n if (!this.#ephemeralEcdh.nonce) {\n throw new Error('Ephemeral nonce not initialized')\n }\n if (!this.#ephemeralEcdh.keyPair) {\n throw new Error('Ephemeral keys not initialized')\n }\n\n return {\n type: SecureMessageType.KeyExchangeInit,\n payload: {\n pub: this.#ephemeralEcdh.pubJwk,\n nonce: Array.from<number>(this.#ephemeralEcdh.nonce),\n },\n }\n }\n\n /**\n * Prepare a secure message\n *\n * @param data - the data to be prepared\n * @returns the secure message\n */\n async prepareSecureMessage(\n data:\n | JsonRpcRequest\n | OutboundJsonRpcEventRequest<OutboundRpcRequestEventsMethodNames>,\n ): Promise<SecureMessage<SecureMessageType.Encrypted>> {\n this.#assertInitialized()\n this.#assertSecureConnectionEstablished()\n if (!this.#aeadKey) {\n throw new Error('AEAD key not initialized')\n }\n // Increment the sequence number\n this.#sequence++\n\n // Encrypt the data with the AEAD key given by the child iframe to ensure only the child iframe can decrypt the message\n const iv = crypto.getRandomValues(new Uint8Array(12))\n const additionalData = new TextEncoder().encode(`seq:${this.#sequence}`)\n const dataBytes = new TextEncoder().encode(JSON.stringify(data))\n const cipherText = new Uint8Array(\n await crypto.subtle.encrypt(\n { name: 'AES-GCM', iv, additionalData },\n this.#aeadKey,\n dataBytes,\n ),\n )\n\n return {\n type: SecureMessageType.Encrypted,\n payload: {\n iv: Array.from<number>(iv),\n cipherText: Array.from<number>(cipherText),\n additionalData: Array.from<number>(additionalData),\n },\n }\n }\n\n /**\n * Decrypt a secure message sent by the child iframe\n *\n * @param message - the secure message to be decrypted\n * @returns the decrypted data\n */\n async decryptSecureMessage(\n message: SecureMessage<SecureMessageType.Encrypted>,\n ): Promise<{\n decryptedMessage:\n | JsonRpcResponse\n | JsonRpcErrorResponse\n | InboundJsonRpcEventRequest<InboundRpcRequestEventsMethodNames>\n | null\n passedDecryption: boolean\n }> {\n try {\n this.#assertInitialized()\n this.#assertSecureConnectionEstablished()\n if (!this.#aeadKey) {\n throw new Error('AEAD key not initialized')\n }\n\n const { iv, cipherText, additionalData } = message.payload\n\n if (!iv || !cipherText || !additionalData) {\n throw new Error('Invalid message payload: missing required fields')\n }\n\n if (\n !Array.isArray(iv) ||\n !Array.isArray(cipherText) ||\n !Array.isArray(additionalData)\n ) {\n throw new Error('Invalid message payload: fields must be arrays')\n }\n\n const dataBytes = await crypto.subtle.decrypt(\n {\n name: 'AES-GCM',\n iv: new Uint8Array(iv),\n additionalData: new Uint8Array(additionalData),\n },\n this.#aeadKey,\n new Uint8Array(cipherText),\n )\n const decryptedMessage = JSON.parse(new TextDecoder().decode(dataBytes))\n return {\n decryptedMessage,\n passedDecryption: true,\n }\n } catch (error) {\n console.error('Error decrypting secure message from iframe', error)\n return {\n decryptedMessage: null,\n passedDecryption: false,\n }\n }\n }\n\n /**\n * Parse a key exchange done message\n *\n * @param message - the key exchange done message\n */\n parseKeyExchangeDoneMessage(\n message: SecureMessage<SecureMessageType.KeyExchangeDone>,\n ): void {\n this.#assertInitialized()\n const { ok, role } = message.payload\n if (ok) {\n this.#isKeyExchangeDone = {\n role,\n ok,\n }\n }\n }\n\n /**\n * Generate a key exchange done message\n *\n * @returns the key exchange done message\n */\n generateKeyExchangeDoneMessage(): SecureMessage<SecureMessageType.KeyExchangeDone> {\n return {\n type: SecureMessageType.KeyExchangeDone,\n payload: {\n ok: true,\n role: 'parent',\n },\n }\n }\n\n /**\n * Close the secure connection\n *\n */\n closeSecureConnection(): void {\n this.#isKeyExchangeDone = {\n role: null,\n ok: false,\n }\n this.#aeadKey = null\n }\n}\n", "import {\n InboundJsonRpcEventRequest,\n InboundRpcRequestEventsMethodNames,\n JsonRpcResponse,\n FatalError,\n} from '../types/index.js'\nimport { SecureMessage, SecureMessageType } from '../ecdh/ecdh.types.js'\n\ntype JsonRpcResponseValidator = {\n isValid: boolean\n response: JsonRpcResponse | null\n}\n\ntype JsonRpcEventRequestValidator = {\n isValid: boolean\n eventRequest: InboundJsonRpcEventRequest<InboundRpcRequestEventsMethodNames> | null\n}\n\ntype JsonRpcKeyExchangeResponseValidator = {\n isValid: boolean\n keyExchangeResponse: SecureMessage<SecureMessageType.KeyExchangeResponse> | null\n}\n\ntype JsonRpcKeyExchangeDoneValidator = {\n isValid: boolean\n keyExchangeDone: SecureMessage<SecureMessageType.KeyExchangeDone> | null\n}\n\ntype EncryptedRequestValidator = {\n isValid: boolean\n encryptedRequest: SecureMessage<SecureMessageType.Encrypted> | null\n}\n\ntype FatalErrorValidator = {\n isValid: boolean\n fatalError: FatalError | null\n}\n\n/**\n * Validate a JSON-RPC response\n *\n * @param message - The message to be validated\n * @returns The validated request\n */\nexport const jsonRpcResponseValidator = (\n message: unknown,\n): JsonRpcResponseValidator => {\n if (typeof message !== 'object' || message === null) {\n return { isValid: false, response: null }\n }\n const response = message as JsonRpcResponse\n if (response.jsonrpc !== '2.0') {\n return { isValid: false, response: null }\n }\n\n if (response.id === null || response.id === undefined) {\n return { isValid: false, response: null }\n }\n\n if (response && ('result' in response || 'error' in response)) {\n return { isValid: true, response: response as JsonRpcResponse }\n }\n\n return {\n isValid: true,\n response: response as JsonRpcResponse,\n }\n}\n\n/**\n * Validate a JSON-RPC event request\n *\n * @param message - The message to be validated\n * @returns The validated request\n */\nexport const inboundJsonRpcEventRequestValidator = (\n message: unknown,\n): JsonRpcEventRequestValidator => {\n if (typeof message !== 'object' || message === null) {\n return { isValid: false, eventRequest: null }\n }\n const eventRequest =\n message as InboundJsonRpcEventRequest<InboundRpcRequestEventsMethodNames>\n if (eventRequest.jsonrpc !== '2.0') {\n return { isValid: false, eventRequest: null }\n }\n if (!eventRequest.method) {\n return { isValid: false, eventRequest: null }\n }\n\n if (!('params' in eventRequest)) {\n return {\n isValid: false,\n eventRequest: null,\n }\n }\n\n return {\n isValid: true,\n eventRequest:\n eventRequest as InboundJsonRpcEventRequest<InboundRpcRequestEventsMethodNames>,\n }\n}\n\n/**\n * Validate a JSON-RPC key exchange response request\n *\n * @param message - The message to be validated\n * @returns The validated request\n */\nexport const jsonRpcKeyExchangeResponseValidator = (\n message: unknown,\n): JsonRpcKeyExchangeResponseValidator => {\n if (typeof message !== 'object' || message === null) {\n return { isValid: false, keyExchangeResponse: null }\n }\n const keyExchangeResponse =\n message as SecureMessage<SecureMessageType.KeyExchangeResponse>\n if (keyExchangeResponse.type !== SecureMessageType.KeyExchangeResponse) {\n return { isValid: false, keyExchangeResponse: null }\n }\n if (!keyExchangeResponse.payload.pub) {\n return { isValid: false, keyExchangeResponse: null }\n }\n if (!keyExchangeResponse.payload.nonce) {\n return { isValid: false, keyExchangeResponse: null }\n }\n return {\n isValid: true,\n keyExchangeResponse:\n keyExchangeResponse as SecureMessage<SecureMessageType.KeyExchangeResponse>,\n }\n}\n\n/**\n * Validate a JSON-RPC key exchange done request\n *\n * @param message - The message to be validated\n * @returns The validated request\n */\nexport const jsonRpcKeyExchangeDoneValidator = (\n message: unknown,\n): JsonRpcKeyExchangeDoneValidator => {\n if (typeof message !== 'object' || message === null) {\n return { isValid: false, keyExchangeDone: null }\n }\n const keyExchangeDone =\n message as SecureMessage<SecureMessageType.KeyExchangeDone>\n if (keyExchangeDone.type !== SecureMessageType.KeyExchangeDone) {\n return { isValid: false, keyExchangeDone: null }\n }\n if (!keyExchangeDone.payload.ok) {\n return { isValid: false, keyExchangeDone: null }\n }\n if (!keyExchangeDone.payload.role) {\n return { isValid: false, keyExchangeDone: null }\n }\n\n return {\n isValid: true,\n keyExchangeDone:\n keyExchangeDone as SecureMessage<SecureMessageType.KeyExchangeDone>,\n }\n}\n\n/**\n * Validate a JSON-RPC encrypted message\n *\n * @param message - The message to be validated\n * @returns The validated request\n */\nexport const encryptedMessageValidator = (\n message: unknown,\n): EncryptedRequestValidator => {\n if (typeof message !== 'object' || message === null) {\n return { isValid: false, encryptedRequest: null }\n }\n const encryptedRequest = message as SecureMessage<SecureMessageType.Encrypted>\n if (encryptedRequest.type !== SecureMessageType.Encrypted) {\n return { isValid: false, encryptedRequest: null }\n }\n if (!encryptedRequest.payload.iv) {\n return { isValid: false, encryptedRequest: null }\n }\n if (!encryptedRequest.payload.cipherText) {\n return { isValid: false, encryptedRequest: null }\n }\n if (!encryptedRequest.payload.additionalData) {\n return { isValid: false, encryptedRequest: null }\n }\n return {\n isValid: true,\n encryptedRequest:\n encryptedRequest as SecureMessage<SecureMessageType.Encrypted>,\n }\n}\n\n/**\n * Validate a fatal error\n *\n * @param message - The message to be validated\n * @returns The validated request\n */\nexport const fatalErrorValidator = (message: unknown): FatalErrorValidator => {\n if (typeof message !== 'object' || message === null) {\n return { isValid: false, fatalError: null }\n }\n const fatalError = message as FatalError\n if (!fatalError.code) {\n return { isValid: false, fatalError: null }\n }\n if (!fatalError.message) {\n return { isValid: false, fatalError: null }\n }\n return { isValid: true, fatalError: fatalError as FatalError }\n}\n", "/**\n * Frame width enum\n */\nexport enum FrameWidth {\n Default = '412px',\n Full = '100%',\n}\n\nexport enum FrameHeight {\n Default = '640px',\n Full = '100%',\n}\n\n/**\n * Check if the device is mobile\n *\n * @returns true if the device is mobile, false otherwise\n */\nexport const isMobile = () => {\n return window.innerWidth < 768\n}\n\n/**\n * Resize the iframe container and iframe element width\n *\n * @param iframeId - the id of the iframe\n * @param frameWidth - the width of the iframe\n * @param frameHeight - the height of the iframe\n */\nexport const resizeFrameWidth = (\n iframeId: string,\n frameWidth: FrameWidth,\n frameHeight: FrameHeight,\n) => {\n const iframe = document.getElementById(iframeId)\n\n if (iframe) {\n iframe.style.width = frameWidth\n iframe.style.height = frameHeight\n }\n}\n\n/**\n * Show the iframe\n *\n * @param overlay - the overlay element\n * @param iframe - the iframe element\n */\nconst showIframe = (overlay: HTMLElement, iframe: HTMLElement) => {\n overlay.style.opacity = '1'\n overlay.style.pointerEvents = 'auto'\n iframe.style.opacity = '1'\n iframe.style.transform = 'scale(1)' // Scale in\n}\n\n/**\n * Hide the iframe\n *\n * @param overlay - the overlay element\n * @param iframe - the iframe element\n */\nconst hideIframe = (overlay: HTMLElement, iframe: HTMLElement) => {\n overlay.style.opacity = '0'\n overlay.style.pointerEvents = 'none'\n iframe.style.opacity = '0'\n iframe.style.transform = 'scale(0.8)' // Scale out\n}\n\n/**\n * Toggle the visibility of the iframe\n *\n * @param iframeId - the id of the iframe\n * @param overlayId - the id of the overlay container\n * @param isVisible - the visibility of the iframe\n */\nexport const doToggleIframeVisibility = (\n iframeId: string,\n overlayId: string,\n isVisible: boolean,\n) => {\n const iframe = document.getElementById(iframeId)\n const overlay = document.getElementById(overlayId)\n if (!iframe || !overlay) {\n return\n }\n\n document.body.style.overflow = isVisible ? 'hidden' : 'auto'\n isVisible ? showIframe(overlay, iframe) : hideIframe(overlay, iframe)\n}\n\n/**\n * Append the iframe to the container div\n *\n * @param iframeId - the id of the iframe\n * @param overlayId - the id of the overlay container\n * @param url - the url of the iframe\n * @param frameWidth - the width of the iframe\n * @param frameHeight - the height of the iframe\n */\nexport const appendIframeWithContainer = (\n iframeId: string,\n overlayId: string,\n url: string,\n frameWidth: FrameWidth,\n frameHeight: FrameHeight,\n) => {\n // Create overlay container\n const overlay = document.createElement('div')\n overlay.id = overlayId\n Object.assign(overlay.style, {\n position: 'fixed',\n top: '0',\n left: '0',\n width: '100%',\n height: '100%',\n background: 'rgba(0, 0, 0, 0.4)',\n backdropFilter: 'blur(4px)',\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n zIndex: '9999',\n opacity: '1',\n pointerEvents: 'none', // Disable interactions when hidden\n cursor: 'default', // Default cursor for overlay background\n transition: 'opacity 0.3s ease-in-out',\n })\n\n const iframe = document.createElement('iframe')\n iframe.id = iframeId\n iframe.src = url\n iframe.allow = 'publickey-credentials-get *; publickey-credentials-create *'\n Object.assign(iframe.style, {\n height: frameHeight,\n width: frameWidth,\n position: 'relative',\n borderRadius: '0.75rem',\n boxShadow:\n '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -2px rgba(0, 0, 0, 0.1)',\n overflowY: 'auto',\n zIndex: '1000',\n opacity: '1',\n transform: 'scale(0.8)',\n transition: 'opacity 0.3s ease-in-out, transform 0.3s ease-in-out',\n })\n\n overlay.appendChild(iframe)\n document.body.appendChild(overlay)\n\n // Ensure styles are applied after DOM insertion\n setTimeout(() => {\n overlay.style.opacity = '1'\n overlay.style.pointerEvents = 'auto'\n iframe.style.opacity = '1'\n iframe.style.transform = 'scale(1)'\n }, 100) // Small delay to trigger transition\n\n // Prevent scrolling while overlay is open\n document.body.style.overflow = 'hidden'\n}\n\n/**\n * Destroy the iframe element and remove it from the DOM\n *\n * @param iframeId - the id of the iframe to be destroyed\n * @param overlayId - the id of the overlay container\n */\nexport const destroyIframeWithContainer = (\n iframeId: string,\n overlayId: string,\n) => {\n const overlay = document.getElementById(overlayId)\n if (overlay) {\n overlay.parentNode?.removeChild(overlay)\n document.body.style.overflow = 'auto' // Restore scrolling\n }\n const iframe = document.getElementById(iframeId)\n if (iframe) {\n if (iframe.parentNode) {\n iframe.parentNode.removeChild(iframe)\n }\n }\n}\n", "/* eslint-disable no-console */\nimport {\n EphemeralEcdhManager,\n SecureMessage,\n SecureMessageType,\n} from '../ecdh/index.js'\nimport {\n JsonRpcRequest,\n OutboundJsonRpcEventRequest,\n OutboundRpcRequestEventsMethodNames,\n InboundJsonRpcEventRequest,\n InboundRpcRequestEventsMethodNames,\n JsonRpcErrorResponse,\n JsonRpcResponse,\n} from '../types/index.js'\nimport {\n jsonRpcKeyExchangeResponseValidator,\n jsonRpcKeyExchangeDoneValidator,\n} from '../utils/validate.js'\nimport {\n appendIframeWithContainer,\n destroyIframeWithContainer,\n doToggleIframeVisibility,\n FrameHeight,\n FrameWidth,\n isMobile,\n resizeFrameWidth,\n} from './iframe.js'\n\n/**\n * Iframe handler interface\n */\nexport type IframeHandler = {\n /**\n * Create a new iframe element and append it to the container div if it is not already created\n * Establish a secure connection with the iframe\n *\n * @returns void\n */\n prepareIframe: () => Promise<void>\n\n /**\n * Disconnect the iframe by closing the secure connection and destroying the iframe container and iframe element\n *\n */\n disconnectIframe: () => void\n\n /**\n * Toggle the visibility of the iframe\n *\n * @param isVisible - the visibility of the iframe\n * @returns void\n */\n toggleFrameVisibility: (isVisible: boolean) => void\n\n /**\n * Send a message to the iframe\n *\n * @param request - the request to be sent to the iframe\n */\n sendMessageToIframe: (\n request:\n | JsonRpcRequest\n | OutboundJsonRpcEventRequest<OutboundRpcRequestEventsMethodNames>,\n ) => Promise<void>\n\n /**\n * Resize the iframe\n *\n * @param size - the size of the iframe\n * @returns void\n */\n resizeIframe: (size?: FrameWidth) => void\n\n /**\n * Get the origin of the iframe\n *\n * @returns the origin of the iframe\n */\n getIframeOrigin: () => string\n\n /**\n * Decrypt a secure message\n *\n * @param message - the secure message to be decrypted\n * @returns the decrypted message\n */\n decryptSecureMessage: (\n message: SecureMessage<SecureMessageType.Encrypted>,\n ) => Promise<\n | JsonRpcResponse\n | JsonRpcErrorResponse\n | InboundJsonRpcEventRequest<InboundRpcRequestEventsMethodNames>\n >\n}\n\ntype IframeHandlerConfig = {\n /**\n * The origin of the parent window\n */\n parentOrigin: string\n\n /**\n * The development wallet url to be used for the iframe when in dev mode\n */\n devWalletUrl?: string | undefined\n}\n\n/**\n * Create a new iframe handler\n *\n * @param config - the iframe handler config\n * @returns the iframe handler\n */\nexport const createIframeHandler = (\n config: IframeHandlerConfig,\n): IframeHandler => {\n const ecdhManager = new EphemeralEcdhManager()\n const { devWalletUrl } = config\n const IFRAME_ORIGIN = devWalletUrl || 'https://pay.transeptorlabs.io'\n const params = new URLSearchParams({ embedded: 'true' }).toString()\n const walletUrl = devWalletUrl\n ? `${devWalletUrl}?${params}`\n : `https://pay.transeptorlabs.io/?${params}`\n const DAPP_IFRAME_ID = 'dapp:iframe-embedded-payment'\n const OVERLAY_CONTAINER_ID = 'dapp:iframe-container'\n\n let activeFrameWidth = FrameWidth.Default\n let activeFrameHeight = FrameHeight.Default\n let isIframeCreated = false\n\n /**\n * Handle the overlay click event\n *\n * @param event - the mouse event\n */\n const handleOverlayClick = (event: MouseEvent) => {\n const overlay = document.getElementById(OVERLAY_CONTAINER_ID)\n if (overlay) {\n if (event.target === overlay) {\n doToggleIframeVisibility(DAPP_IFRAME_ID, OVERLAY_CONTAINER_ID, false)\n }\n }\n }\n\n /**\n * Get the content window of the iframe\n *\n * @returns the content window of the iframe\n */\n const getIframeContentWindow = (): Window | null => {\n const iframe = document.getElementById(DAPP_IFRAME_ID)\n if (!iframe) {\n throw new Error('Iframe not found')\n }\n const hasContentWindow = 'contentWindow' in iframe\n if (hasContentWindow) {\n const childWindow = iframe.contentWindow as Window\n return childWindow\n }\n return null\n }\n\n /**\n * Send a post message to the IFrame window to check if it is ready and to inform the iframe of the parent origin extracted from message event\n * Waits for the frame to be ready before sending the message.\n * max attempts is 600\n *\n * @param attempts - the number of attempts to wait for a response\n * @returns true if the frame is ready, false otherwise will reject with an error\n */\n const checkIframeReady = async (attempts = 600) => {\n const childWindow = getIframeContentWindow()\n if (!childWindow) {\n throw new Error('Iframe not found')\n }\n\n let isFrameReady = false\n\n const handleReady = (event: MessageEvent) => {\n if (!event.isTrusted) {\n return\n }\n\n if (event.origin !== IFRAME_ORIGIN) {\n return\n }\n\n const message = event.data\n if (message === 'pong') {\n isFrameReady = true\n return\n }\n }\n\n window.addEventListener('message', handleReady.bind(this))\n\n return new Promise<boolean>((_resolve, _reject) => {\n let counter = 0\n const intervalId = setInterval(() => {\n counter++\n // reject if more than the specified attempts\n if (counter >= attempts) {\n clearInterval(intervalId)\n window.removeEventListener('message', handleReady.bind(this))\n _reject(\n new Error(\n 'Max ping attempts reached to establish connection with the iframe',\n ),\n )\n }\n\n // resolve if the frame is ready\n if (isFrameReady) {\n clearInterval(intervalId)\n window.removeEventListener('message', handleReady.bind(this))\n console.log('Iframe is ready to receive messages')\n _resolve(true)\n } else {\n console.log('Sending ping to the iframe to check if it is ready')\n childWindow.postMessage('ping', IFRAME_ORIGIN)\n }\n }, 500) // 500ms\n })\n }\n\n /**\n * Establish a secure connection with the iframe\n *\n * @param attempts - the number of attempts to wait for a response\n * @returns the key exchange response message if the secure connection is established, null otherwise will reject with an error\n */\n const establishSecureConnectionWithIframe = async (attempts = 600) => {\n console.log('Establishing secure connection with the iframe')\n const childWindow = getIframeContentWindow()\n if (!childWindow) {\n throw new Error('Iframe not found')\n }\n\n // Generate key exchange messages\n const keyExchangeMessage = await ecdhManager.generateKeyExchangeMessage()\n let keyExchangeResponseMessage: SecureMessage<SecureMessageType.KeyExchangeResponse> | null =\n null\n let keyExchangeDoneMessage: SecureMessage<SecureMessageType.KeyExchangeDone> | null =\n null\n\n const handleReady = (event: MessageEvent) => {\n if (!event.isTrusted) {\n return\n }\n\n if (event.origin !== IFRAME_ORIGIN) {\n return\n }\n\n const message = event.data\n const { isValid: isValidKeyExchangeResponse, keyExchangeResponse } =\n jsonRpcKeyExchangeResponseValidator(message)\n if (isValidKeyExchangeResponse && keyExchangeResponse) {\n childWindow.postMessage(\n ecdhManager.generateKeyExchangeDoneMessage(),\n IFRAME_ORIGIN,\n )\n keyExchangeResponseMessage = message\n return\n }\n\n const { isValid: isValidKeyExchangeDone, keyExchangeDone } =\n jsonRpcKeyExchangeDoneValidator(message)\n if (isValidKeyExchangeDone && keyExchangeDone) {\n keyExchangeDoneMessage = message\n return\n }\n }\n\n window.addEventListener('message', handleReady.bind(this))\n\n childWindow.postMessage(keyExchangeMessage, IFRAME_ORIGIN)\n\n return new Promise<SecureMessage<SecureMessageType.KeyExchangeResponse>>(\n (_resolve, _reject) => {\n let counter = 0\n const intervalId = setInterval(() => {\n counter++\n // reject if more than the specified attempts\n if (counter >= attempts) {\n clearInterval(intervalId)\n window.removeEventListener('message', handleReady.bind(this))\n _reject(\n new Error(\n 'Max secure connection attempts reached to establish secure connection with the iframe',\n ),\n )\n }\n\n // resolve if the secure connection is established\n if (keyExchangeResponseMessage && keyExchangeDoneMessage) {\n clearInterval(intervalId)\n window.removeEventListener('message', handleReady.bind(this))\n ecdhManager.parseKeyExchangeDoneMessage(keyExchangeDoneMessage)\n _resolve(keyExchangeResponseMessage)\n }\n }, 200) // 200ms\n },\n )\n }\n\n return {\n getIframeOrigin: () => IFRAME_ORIGIN,\n\n prepareIframe: async () => {\n // Append the iframe to the DOM and add event listener to close overlay when clicking outside the iframe\n if (!isIframeCreated) {\n console.log('Appending iframe to the DOM')\n activeFrameWidth = isMobile() ? FrameWidth.Full : FrameWidth.Default\n activeFrameHeight = isMobile() ? FrameHeight.Full : FrameHeight.Default\n appendIframeWithContainer(\n DAPP_IFRAME_ID,\n OVERLAY_CONTAINER_ID,\n walletUrl,\n activeFrameWidth,\n activeFrameHeight,\n )\n\n const overlay = document.getElementById(OVERLAY_CONTAINER_ID)\n if (overlay) {\n overlay.addEventListener('click', handleOverlayClick)\n }\n isIframeCreated = true\n }\n\n // Establish connection and start key exchange\n if (!ecdhManager.isSecureConnectionEstablished) {\n const isIframeReady = await checkIframeReady()\n const childWindow = getIframeContentWindow()\n if (!childWindow && !isIframeReady) {\n throw new Error(\n 'Iframe content window not found, cannot start key exchange',\n )\n }\n // Initialize the ECDH manager\n await ecdhManager.initializeEcdh()\n\n // Establish secure connection with the iframe\n const keyExchangeResponseMessage =\n await establishSecureConnectionWithIframe()\n\n // Parse the key exchange response message from the iframe\n await ecdhManager.parseKeyExchangeMessage(keyExchangeResponseMessage)\n }\n },\n\n disconnectIframe: () => {\n if (!isIframeCreated) {\n return\n }\n\n if (!ecdhManager.isSecureConnectionEstablished) {\n return\n }\n\n ecdhManager.closeSecureConnection()\n destroyIframeWithContainer(DAPP_IFRAME_ID, OVERLAY_CONTAINER_ID)\n const overlay = document.getElementById(OVERLAY_CONTAINER_ID)\n if (overlay) {\n overlay.removeEventListener('click', handleOverlayClick)\n }\n isIframeCreated = false\n\n console.log(\n 'Secure connection closed with the iframe removed from the DOM',\n {\n isSecureConnectionEstablished:\n ecdhManager.isSecureConnectionEstablished,\n isIframeCreated: isIframeCreated,\n },\n )\n },\n\n toggleFrameVisibility: (isVisible) => {\n if (!isIframeCreated) {\n return\n }\n\n doToggleIframeVisibility(DAPP_IFRAME_ID, OVERLAY_CONTAINER_ID, isVisible)\n\n activeFrameWidth = isMobile() ? FrameWidth.Full : FrameWidth.Default\n activeFrameHeight = isMobile() ? FrameHeight.Full : FrameHeight.Default\n resizeFrameWidth(DAPP_IFRAME_ID, activeFrameWidth, activeFrameHeight)\n },\n\n resizeIframe: (size?: FrameWidth) => {\n if (!isIframeCreated) {\n return\n }\n\n activeFrameWidth = isMobile()\n ? FrameWidth.Full\n : size || FrameWidth.Default\n activeFrameHeight = isMobile() ? FrameHeight.Full : FrameHeight.Default\n resizeFrameWidth(DAPP_IFRAME_ID, activeFrameWidth, activeFrameHeight)\n },\n\n sendMessageToIframe: async (\n request:\n | JsonRpcRequest\n | OutboundJsonRpcEventRequest<OutboundRpcRequestEventsMethodNames>,\n ) => {\n if (!ecdhManager.isSecureConnectionEstablished) {\n throw new Error('Secure channel not established with the iframe')\n }\n\n const childWindow = getIframeContentWindow()\n if (childWindow) {\n const encryptedRequest = await ecdhManager.prepareSecureMessage(request)\n childWindow.postMessage(encryptedRequest, IFRAME_ORIGIN)\n } else {\n throw new Error('Iframe content window not found')\n }\n },\n\n decryptSecureMessage: async (\n message: SecureMessage<SecureMessageType.Encrypted>,\n ) => {\n if (!ecdhManager.isSecureConnectionEstablished) {\n throw new Error('Secure channel not established with the iframe')\n }\n const { decryptedMessage, passedDecryption } =\n await ecdhManager.decryptSecureMessage(message)\n if (!passedDecryption || !decryptedMessage) {\n throw new Error('Failed to decrypt secure message')\n }\n return decryptedMessage\n },\n }\n}\n", "/**\n * Returns a random number between 0 and maxRange\n *\n * @param maxRange - the maximum range for the random number\n * @returns a random number between 0 and maxRange\n */\nexport const getRandomNum = (maxRange: number) => {\n const rand: () => number = Math.random\n const rn = rand()\n return Math.floor(rn * maxRange)\n}\n", "/* eslint-disable @typescript-eslint/no-explicit-any */\nimport {\n createIframeHandler,\n FrameWidth,\n IframeHandler,\n} from '../iframe/index.js'\n\nimport {\n getRandomNum,\n inboundJsonRpcEventRequestValidator,\n jsonRpcResponseValidator,\n encryptedMessageValidator,\n fatalErrorValidator,\n} from '../utils/index.js'\n\nimport {\n InboundJsonRpcEventRequest,\n JsonRpcResponse,\n InboundRpcRequestEventsMethodNames,\n FatalError,\n JsonRpcRequest,\n} from '../types/index.js'\nimport { SecureMessage, SecureMessageType } from '../ecdh/index.js'\nimport { Eip1193RequestArguments, ProviderRpcError } from './types.js'\n\n// JSON-RPC types\nexport type Message = unknown\n\nexport type AcceptedChainConfig = {\n /**\n * The chain ID of the blockchain network to be used\n * It should be a valid Ethereum chain ID in hex format\n */\n chainId: `0x${string}`\n\n /**\n * The treasury address to receive the payments\n * It should be a valid Ethereum address in hex format\n */\n treasuryAddress: `0x${string}`\n}\n\n/**\n * The configuration for the EmbeddedPayment\n */\nexport type TranseptorEthereumProviderConfig = {\n /**\n * The development wallet url to be used for the iframe when in dev mode\n */\n devWalletUrl?: string\n\n /**\n * The accepted chain configurations to be used to accept payments\n */\n // acceptedChainConfig: AcceptedChainConfig[]\n\n /**\n * Callback function to handle incoming payment events that emit when the user completes a payment\n */\n // onPaymentEvent: (checkoutResponse: CheckoutResponse) => void\n}\n\n/**\n * We use a singleton class maintains a single instance across a web application, and to ensure\n * the post message listener is only added once, allowing that web application to access wallet globally.\n *\n * The TranseptorEthereumProvider target environment is the browser, and it is designed to be used in web applications.\n */\nexport class TranseptorEthereumProvider {\n static #instance: TranseptorEthereumProvider\n readonly #localWindow: Window\n readonly #boundMessageHandler: (event: MessageEvent<Message>) => void\n readonly FATAL_ERROR_MESSAGE = 'fatal: internal error'\n\n readonly #rpcMethodsThatRequireUserConsent: string[] = [\n 'wallet_requestExecutionPermissions',\n 'wallet_revokeExecutionPermission',\n ]\n\n #iframeHandler: IframeHandler\n #responseQueue: Map<\n number,\n {\n status: 'pending' | 'fulfilled' | 'failed'\n response: JsonRpcResponse | undefined\n fatalError?: FatalError\n }\n > = new Map()\n\n private constructor(iframeHandler: IframeHandler) {\n this.#localWindow = window\n this.#iframeHandler = iframeHandler\n\n this.#boundMessageHandler = this.#handleIncomingMessage.bind(this)\n this.#localWindow.addEventListener('message', this.#boundMessageHandler)\n }\n\n /**\n * Create a messageId to be used in a JSONRPC message and ensure it is unique.\n *\n * @returns A JsonRpcId\n */\n #getJsonRpcId(): number {\n const potentialId = getRandomNum(10000000000) + Date.now()\n\n // Ensure the id is unique and not already in the responseQueue or activeRequestId\n if (this.#responseQueue.has(potentialId)) {\n return this.#getJsonRpcId()\n }\n return potentialId\n }\n\n /**\n * close the TranseptorEthereumProvider\n */\n #close() {\n this.#iframeHandler.toggleFrameVisibility(false)\n }\n\n /**\n * resize the TranseptorEthereumProvider\n *\n * @param size - the size of the frame\n */\n #resize(size: FrameWidth) {\n this.#iframeHandler.resizeIframe(size)\n }\n\n /**\n * Handle incoming Post messages\n * Since the iframe is create locally, it will have the same origin as the dapp\n *\n * @param event - the PostMessageEvent sent from the iframe\n */\n async #handleIncomingMessage(event: MessageEvent<Message>) {\n if (!event.isTrusted) {\n return\n }\n\n if (event.origin !== this.#iframeHandler.getIframeOrigin()) {\n return\n }\n\n const message = event.data\n if (typeof message !== 'object') {\n return\n }\n\n const { isValid: isValidFatalError, fatalError } =\n fatalErrorValidator(message)\n if (isValidFatalError && fatalError) {\n this.#handleFatalError(fatalError)\n return\n }\n\n const { isValid: isValidEncryptedRequest, encryptedRequest } =\n encryptedMessageValidator(message)\n if (isValidEncryptedRequest && encryptedRequest) {\n await this.#handleIncomingEncryptedMessage(encryptedRequest)\n return\n }\n }\n\n /**\n * Handle a JsonRpcResponse and store it in the responseQueue\n *\n * @param response - the JsonRpcResponse to be handled\n */\n #handleJsonRpcResponse(response: JsonRpcResponse) {\n const { id } = response\n if (this.#responseQueue.has(Number(id))) {\n this.#responseQueue.set(Number(id), {\n status: 'fulfilled',\n response,\n })\n }\n }\n\n /**\n * Handle a InboundJsonRpcEventRequest and handle the event\n *\n * @param eventRequest - the JsonRpcEventRequest to be handled\n */\n #handleJsonRpcEvent(\n eventRequest: InboundJsonRpcEventRequest<InboundRpcRequestEventsMethodNames>,\n ) {\n const { method } = eventRequest\n switch (method) {\n case 'wallet_paymentEvent':\n break\n case 'wallet_closeFrame':\n this.#close()\n break\n case 'wallet_disconnect':\n this.#disconnect()\n break\n case 'wallet_resizeFrameFull':\n this.#resize(FrameWidth.Full)\n break\n case 'wallet_resizeFrameDefault':\n this.#resize(FrameWidth.Default)\n break\n }\n }\n\n /**\n * Handle a SecureMessage and handle the message\n *\n * @param encryptedRequest - the SecureMessage to be handled\n */\n async #handleIncomingEncryptedMessage(\n encryptedRequest: SecureMessage<SecureMessageType.Encrypted>,\n ) {\n const decryptedMessage =\n await this.#iframeHandler.decryptSecureMessage(encryptedRequest)\n\n const { isValid: isValidResponse, response } =\n jsonRpcResponseValidator(decryptedMessage)\n if (isValidResponse && response) {\n this.#handleJsonRpcResponse(response)\n return\n }\n\n const { isValid: isValidEventRequest, eventRequest } =\n inboundJsonRpcEventRequestValidator(decryptedMessage)\n if (isValidEventRequest && eventRequest) {\n this.#handleJsonRpcEvent(eventRequest)\n return\n }\n }\n\n /**\n * Handle a fatal error\n *\n * @param fatalError - the fatal error to be handled\n */\n #handleFatalError(fatalError: FatalError) {\n if (this.#responseQueue.size) {\n // loop through the responseQueue and set the status to failed\n this.#responseQueue.forEach((response) => {\n if (response.status === 'pending') {\n response.status = 'failed'\n response.fatalError = fatalError\n }\n })\n }\n }\n\n /**\n * Handles a JsonRpcRequest coming from the dapp\n * Request are handled synchronously(blocking) and requires immediate response from the user\n *\n * @param request - the JsonRpcRequest to be handled\n * @param requiresUserConsent - whether the user consent is required to show the iframe\n * @returns the response from the blobUrl IFrame\n */\n async #sendRequestToIframe(\n request: JsonRpcRequest,\n requiresUserConsent: boolean,\n ): Promise<JsonRpcResponse> {\n try {\n await this.#iframeHandler.prepareIframe()\n\n // show the iframe if the user consent is required otherwise the iframe will be hidden but can still response to requests\n if (requiresUserConsent) {\n this.#iframeHandler.toggleFrameVisibility(true)\n }\n\n const { id } = request\n this.#responseQueue.set(Number(id), {\n status: 'pending',\n response: undefined,\n })\n await this.#iframeHandler.sendMessageToIframe(request)\n\n // Wait for the user to respond from the IFrame\n return await this.#waitForResponse(Number(id))\n } catch (error: any) {\n if (error.message === this.FATAL_ERROR_MESSAGE) {\n this.#close()\n }\n return {\n jsonrpc: '2.0',\n id: request.id,\n error: {\n message: error.message,\n code: -32000,\n },\n }\n }\n }\n\n /**\n * Wait for a response from the user to be added to the responseQueue every second\n * max attempts is 300 or 5 minutes\n *\n * @param requestId - the id of the request\n * @param attempts - the number of attempts to wait for a response\n * @returns the response from the blobUrl IFrame\n */\n #waitForResponse(requestId: number, attempts = 300) {\n return new Promise<JsonRpcResponse>((_resolve, _reject) => {\n let counter = 0\n\n const intervalId = setInterval(() => {\n counter++\n\n // reject if more than the specified attempts\n if (counter >= attempts) {\n clearInterval(intervalId)\n _reject(new Error('Max attempts reached waiting for response'))\n }\n\n // remove the response from the queue and resolve the promise\n const result = this.#responseQueue.get(requestId)\n if (result) {\n if (result.status === 'failed' && result.fatalError) {\n clearInterval(intervalId)\n this.#responseQueue.delete(requestId)\n _reject(new Error(result.fatalError.message))\n }\n\n if (result.status === 'fulfilled') {\n clearInterval(intervalId)\n this.#responseQueue.delete(requestId)\n _resolve(result.response as JsonRpcResponse)\n }\n }\n }, 1000) // 1 second\n })\n }\n\n /**\n * Disconnect the TranseptorEthereumProvider\n *\n * @returns true if the TranseptorEthereumProvider is disconnected successfully, false otherwise\n */\n #disconnect() {\n this.#iframeHandler.toggleFrameVisibility(false)\n this.#iframeHandler.disconnectIframe()\n this.#responseQueue = new Map()\n return true\n }\n\n /**\n * Generic request to the TranseptorEthereumProvider\n *\n * @param request - the request to be sent to the TranseptorEthereumProvider\n * @returns the response from the TranseptorEthereumProvider\n */\n async sendRequest(request: Eip1193RequestArguments): Promise<unknown> {\n const requestId = this.#getJsonRpcId()\n const requiresUserConsent = this.#rpcMethodsThatRequireUserConsent.includes(\n request.method,\n )\n\n switch (request.method) {\n case 'wallet_disconnect':\n this.#disconnect()\n return true\n case 'wallet_openHomePage':\n await this.#iframeHandler.prepareIframe()\n this.#iframeHandler.toggleFrameVisibility(true)\n await this.#iframeHandler.sendMessageToIframe({\n jsonrpc: '2.0',\n method: 'wallet_navigateToDashboardEvent',\n params: [],\n })\n return true\n default: {\n const result = await this.#sendRequestToIframe(\n {\n jsonrpc: '2.0',\n id: requestId,\n method: request.method,\n params: request.params || [],\n },\n requiresUserConsent,\n )\n if ('error' in result) {\n throw new ProviderRpcError({\n message: result.error.message,\n code: result.error.code,\n data: result.error.data,\n })\n }\n return result.result\n }\n }\n }\n\n /**\n * Create a new instance of the TranseptorEthereumProvider\n *\n * @param config - the configuration for the TranseptorEthereumProvider\n * @returns the TranseptorEthereumProvider instance\n */\n static Create(\n config: TranseptorEthereumProviderConfig,\n ): TranseptorEthereumProvider {\n if (!TranseptorEthereumProvider.#instance) {\n const iframeHandler = createIframeHandler({\n parentOrigin: window.location.origin,\n devWalletUrl: config.devWalletUrl,\n })\n TranseptorEthereumProvider.#instance = new TranseptorEthereumProvider(\n iframeHandler,\n )\n }\n return TranseptorEthereumProvider.#instance\n }\n}\n", "export type ErrorDetails = {\n code: number\n message: string\n}\n\n/**\n * The EIP1193 error code enum\n */\nexport enum EIP1193_ERROR_CODES {\n /**\n * The user rejected the request.\n */\n USER_REJECTED_REQUEST = 4001,\n\n /**\n * The specified address is not connected or not in the wallet\n */\n UNAUTHORIZED = 4100,\n\n /**\n * The Provider does not support the requested method.\n */\n UNSUPPORTED_METHOD = 4200,\n\n /**\n * The Provider is disconnected from all chains.\n */\n DISCONNECTED = 4900,\n\n /**\n * The Provider is not connected to the requested chain.\n */\n CHAIN_DISCONNECTED = 4901,\n}\n\n/**\n * The ERC-7715 error code enum\n */\nexport enum ERC7715_ERROR_CODES {\n /**\n * The specified method is not authorized for the given origin\n * Related RPCs: wallet_requestConnection\n */\n UNAUTHORIZED_ACCESS_RESTRICTED_METHOD = 4101,\n}\n\n/**\n * The EIP5792 error code enum\n */\nexport enum EIP5792_ERROR_CODES {\n /**\n * This wallet does not support a capability that was not marked as optional\n * Related RPCs: wallet_sendCalls\n */\n UNSUPPORTED_NON_OPTIONAL_CAPABILITY = 5700,\n\n /**\n * This wallet does not support the specified chain id\n * Related RPCs: wallet_sendCalls\n */\n UNSUPPORTED_CHAIN_ID = 5710,\n\n /**\n * There is already a bundle submitted with this id\n * Related RPCs: wallet_sendCalls\n */\n DUPLICATE_BUNDLE_ID = 5720,\n\n /**\n * This bundle id is unknown / has not been submitted\n * Related RPCs: wallet_getCallsStatus, wallet_showCallsStatus\n */\n UNKNOWN_BUNDLE_ID = 5730,\n\n /**\n * The call bundle is too large for the wallet to process\n * Related RPCs: wallet_sendCalls\n */\n BUNDLE_TOO_LARGE = 5740,\n\n /**\n * The wallet can support atomicity after an upgrade, but the user rejected the upgrade\n * Related RPCs: wallet_sendCalls\n */\n ATOMIC_READY_WALLET_REJECTED_UPGRADE = 5750,\n\n /**\n * The wallet does not support atomic execution but the request requires it\n * Related RPCs: wallet_sendCalls\n */\n ATOMICITY_NOT_SUPPORTED = 5760,\n}\n\n/**\n * The fatal error code enum\n */\nexport enum FATAL_ERROR_CODES {\n INTERNAL_ERROR = -32001,\n}\n\nexport enum COMMON_ERROR_CODES {\n INVALID_PARAMS = -32602,\n}\n\n/**\n * The error code map\n */\nexport const ERROR_CODES_MAP: Record<\n | EIP1193_ERROR_CODES\n | EIP5792_ERROR_CODES\n | ERC7715_ERROR_CODES\n | FATAL_ERROR_CODES\n | COMMON_ERROR_CODES,\n ErrorDetails\n> = {\n // EIP1193 errors\n [EIP1193_ERROR_CODES.USER_REJECTED_REQUEST]: {\n code: 4001,\n message: 'User rejected the request.',\n },\n [EIP1193_ERROR_CODES.UNAUTHORIZED]: {\n code: 4100,\n message:\n 'The requested method and/or account has not been authorized by the user.',\n },\n [EIP1193_ERROR_CODES.UNSUPPORTED_METHOD]: {\n code: 4200,\n message: 'The Provider does not support the requested method.',\n },\n [EIP1193_ERROR_CODES.DISCONNECTED]: {\n code: 4900,\n message: 'The Provider is disconnected from all chains.',\n },\n [EIP1193_ERROR_CODES.CHAIN_DISCONNECTED]: {\n code: 4901,\n message: 'The Provider is not connected to the requested chain.',\n },\n\n //ERC-7715 errors\n [ERC7715_ERROR_CODES.UNAUTHORIZED_ACCESS_RESTRICTED_METHOD]: {\n code: 4101,\n message:\n 'The specified method is not authorized for the given origin. Please call wallet_requestConnection to authorize the method.',\n },\n\n // EIP5792 errors\n [EIP5792_ERROR_CODES.UNSUPPORTED_NON_OPTIONAL_CAPABILITY]: {\n code: 5700,\n message:\n 'This wallet does not support a capability that was not marked as optional.',\n },\n [EIP5792_ERROR_CODES.UNSUPPORTED_CHAIN_ID]: {\n code: 5710,\n message: 'This wallet does not support the specified chain id.',\n },\n [EIP5792_ERROR_CODES.DUPLICATE_BUNDLE_ID]: {\n code: 5720,\n message: 'There is already a bundle submitted with this id.',\n },\n [EIP5792_ERROR_CODES.UNKNOWN_BUNDLE_ID]: {\n code: 5730,\n message: 'This bundle id is unknown / has not been submitted.',\n },\n [EIP5792_ERROR_CODES.BUNDLE_TOO_LARGE]: {\n code: 5740,\n message: 'The call bundle is too large for the wallet to process.',\n },\n [EIP5792_ERROR_CODES.ATOMIC_READY_WALLET_REJECTED_UPGRADE]: {\n code: 5750,\n message:\n 'The wallet can support atomicity after an upgrade, but the user rejected the upgrade.',\n },\n [EIP5792_ERROR_CODES.ATOMICITY_NOT_SUPPORTED]: {\n code: 5760,\n message:\n 'The wallet does not support atomic execution but the request requires it.',\n },\n\n // Fatal/Common errors\n [FATAL_ERROR_CODES.INTERNAL_ERROR]: {\n code: -32001,\n message: 'fatal: internal error',\n },\n [COMMON_ERROR_CODES.INVALID_PARAMS]: {\n code: 4002,\n message: 'Invalid parameters.',\n },\n}\n\n/**\n * Get the error message for a given error code\n *\n * @param code - The error code\n * @returns The error message\n * @throws An error if the error code is not found\n */\nexport const getErrorMessage = (\n code:\n | EIP1193_ERROR_CODES\n | EIP5792_ERROR_CODES\n | ERC7715_ERROR_CODES\n | FATAL_ERROR_CODES\n | COMMON_ERROR_CODES,\n): ErrorDetails => {\n const details = ERROR_CODES_MAP[code]\n if (!details) {\n return {\n code,\n message: `Unknown error code: ${code}`,\n }\n }\n return details\n}\n", "import {\n Eip1193RequestArguments,\n Eip1193Provider,\n ProviderRpcError,\n} from './types.js'\nimport {\n TranseptorEthereumProvider,\n TranseptorEthereumProviderConfig,\n} from './transeptor-ethereum-provider.js'\nimport { getErrorMessage } from './errors.js'\n\nexport class Eip1193Bridge implements Eip1193Provider {\n #transeptorEthereumProvider: TranseptorEthereumProvider\n constructor(config: TranseptorEthereumProviderConfig) {\n this.#transeptorEthereumProvider = TranseptorEthereumProvider.Create(config)\n }\n\n async request(request: Eip1193RequestArguments) {\n try {\n return await this.#transeptorEthereumProvider.sendRequest(request)\n } catch (error: unknown) {\n if (error instanceof ProviderRpcError) {\n const errorDetails = getErrorMessage(error.code)\n if (errorDetails) {\n throw new ProviderRpcError(errorDetails)\n }\n }\n throw new ProviderRpcError({\n code: -32000,\n message: 'Unknown internal error',\n data: error,\n })\n }\n }\n}\n\n/**\n * Create a new Eip1193 provider\n *\n * @param config - the configuration for the TranseptorEthereumProvider\n * @returns the Eip1193 provider\n */\nexport function createEip1193Provider(\n config: TranseptorEthereumProviderConfig,\n): Eip1193Provider {\n return new Eip1193Bridge(config)\n}\n", "import { Eip1193Provider } from '../index.js'\n\nexport const enum ProviderEvent {\n AnnounceProvider = 'eip6963:announceProvider',\n RequestProvider = 'eip6963:requestProvider',\n}\n\n/**\n * Provider Detail defined by eip-6963\n */\nexport type EIP6963ProviderDetail = {\n info: {\n uuid: string\n name: string\n icon: string\n rdns: string\n }\n provider: Eip1193Provider\n}\n\n/**\n * Announce Event dispatched by a Wallet\n */\nexport interface EIP6963AnnounceProviderEvent extends CustomEvent {\n type: ProviderEvent.AnnounceProvider\n detail: EIP6963ProviderDetail\n}\n\n/**\n * Request Event dispatched by a DApp\n */\nexport interface EIP6963RequestProviderEvent extends Event {\n type: ProviderEvent.RequestProvider\n}\n", "/**\n * The icon of the Transeptor Pay wallet\n */\nexport const TRANSEPTOR_WALLET_ICON =\n 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAACXBIWXMAAC4jAAAuIwF4pT92AAAChklEQVR4nO2YTW/TMBjHs7Jpm4QK34BLJSSkldieugiGwho7y41TvwInPgCX6dEktqKWVSoXhDjssFtL7JTDruPEie9U5KQvaZd2DWVEiZ6f9FSW3+3/300cw0AQBEEQBEEQBEEQBEEQ5J7YuKe6eWAYLoixr1tP7Mudine9vSwMA0oF2gTQizGYG7wnXF4yoU6ICM6oUB/mgwh1ylzVJVy+i7fNvfJ7R8FTItRP4g5atn2z+fyNelzzrsrzwXjvked1twmX3arTJ/E+cgqECppCfqRHiplCnTARHMTLZquP3CK+vyRcncfzcghEizn2KeWyo9Omq14QEbTD4kbjweicz0XUjgj5qeoEeXYBRAvhfpNxeTjOZUK2mStr8TpJ7XSbHLsAwgnvHfvU5P6FTjcaPa24QfnAIq5qLV9YpHiOXQAJ6kNpesaDIrsAbqk/VS8qK7gLIFn9SXGhXQAj9X8kqD9bh3oDi/DCuQBG6qtk9ZNcUC+MC2AF9QvtAlhN/WK6AFKoX0gXQDr1i+UCWPLcX61tGhdQri5Y3afpxsnyuX8Xad8LPHmob5fxtjlVf0z6t8NZF2S6CTA5+9WJ+ouuuUsiuhob+qrMRP9gcT9RPVpXr+jYBdltAIQD7zt9QrjfWu9Mjj+byRoTqhnPW/JEaE+/GmWyCRB97XFlh3Dl6HTFuyo/s3sP/yYq3nVZ90l58Jk56rVOV2q3+9Nj6LH2nYBTV3Wy2oAN/WNZvV0m5Dd9BIiQZ2sFV+dE+KemUF/0x1OdjvIW1m/qsfUc4nP6/8CwpCdh2zc764Zl/dplb39v2fZw864+w4Vn/xRAjNT/+P8+EARBEARBEARBEARBEMRYnT/136hHs8p9dgAAAABJRU5ErkJggg=='\n", "import { TranseptorEthereumProviderConfig } from '../transeptor-ethereum-provider.js'\nimport { createEip1193Provider } from '../eip-1193-bridge.js'\nimport { EIP6963ProviderDetail, ProviderEvent } from './types.js'\nimport { TRANSEPTOR_WALLET_ICON } from './icon.js'\n\n/**\n * Announce the Transeptor Pay provider to the dapp\n *\n * @param config - the configuration for the TranseptorEthereumProvider\n */\nexport const announceProvider = (config: TranseptorEthereumProviderConfig) => {\n const provider = createEip1193Provider(config)\n const detail = Object.freeze({\n info: Object.freeze({\n uuid: '2d1e5f4d-8b8a-48bb-8d0a-7d6f8f2fa9a1',\n name: 'Transeptor',\n icon: TRANSEPTOR_WALLET_ICON,\n rdns: 'io.transeptor.pay',\n }),\n provider,\n } as EIP6963ProviderDetail)\n const announceEvent = new CustomEvent(ProviderEvent.AnnounceProvider, {\n detail,\n })\n\n // The Wallet dispatches an announce event which is heard by\n // the DApp code that had run earlier\n window.addEventListener(ProviderEvent.RequestProvider, () => {\n window.dispatchEvent(announceEvent)\n })\n\n // The Wallet listens to the request events which may be\n // dispatched later and re-dispatches the `EIP6963AnnounceProviderEvent`\n window.dispatchEvent(announceEvent)\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["ProviderRpcError", "message", "code", "data", "EphemeralEcdhManager", "#isInitialized", "#ephemeralEcdh", "#isKeyExchangeDone", "#sequence", "#aeadKey", "#assertInitialized", "#assertSecureConnectionEstablished", "#assertWebCryptoAvailable", "keyPair", "pubJwk", "nonce", "message", "pub", "recipientPub", "bits", "baseKey", "salt", "data", "iv", "additionalData", "dataBytes", "cipherText", "error", "ok", "role", "jsonRpcResponseValidator", "message", "response", "inboundJsonRpcEventRequestValidator", "eventRequest", "jsonRpcKeyExchangeResponseValidator", "keyExchangeResponse", "jsonRpcKeyExchangeDoneValidator", "keyExchangeDone", "encryptedMessageValidator", "encryptedRequest", "fatalErrorValidator", "fatalError", "isMobile", "resizeFrameWidth", "iframeId", "frameWidth", "frameHeight", "iframe", "showIframe", "overlay", "hideIframe", "doToggleIframeVisibility", "overlayId", "isVisible", "appendIframeWithContainer", "url", "destroyIframeWithContainer", "createIframeHandler", "config", "ecdhManager", "EphemeralEcdhManager", "devWalletUrl", "IFRAME_ORIGIN", "params", "walletUrl", "DAPP_IFRAME_ID", "OVERLAY_CONTAINER_ID", "activeFrameWidth", "activeFrameHeight", "isIframeCreated", "handleOverlayClick", "event", "overlay", "doToggleIframeVisibility", "getIframeContentWindow", "iframe", "checkIframeReady", "attempts", "childWindow", "isFrameReady", "handleReady", "_resolve", "_reject", "counter", "intervalId", "establishSecureConnectionWithIframe", "keyExchangeMessage", "keyExchangeResponseMessage", "keyExchangeDoneMessage", "message", "isValidKeyExchangeResponse", "keyExchangeResponse", "jsonRpcKeyExchangeResponseValidator", "isValidKeyExchangeDone", "keyExchangeDone", "jsonRpcKeyExchangeDoneValidator", "isMobile", "appendIframeWithContainer", "isIframeReady", "destroyIframeWithContainer", "isVisible", "resizeFrameWidth", "size", "request", "encryptedRequest", "decryptedMessage", "passedDecryption", "getRandomNum", "maxRange", "rand", "rn", "TranseptorEthereumProvider", "_TranseptorEthereumProvider", "#instance", "#localWindow", "#boundMessageHandler", "#rpcMethodsThatRequireUserConsent", "#iframeHandler", "#responseQueue", "iframeHandler", "#handleIncomingMessage", "#getJsonRpcId", "potentialId", "getRandomNum", "#close", "#resize", "size", "event", "message", "isValidFatalError", "fatalError", "fatalErrorValidator", "#handleFatalError", "isValidEncryptedRequest", "encryptedRequest", "encryptedMessageValidator", "#handleIncomingEncryptedMessage", "#handleJsonRpcResponse", "response", "id", "#handleJsonRpcEvent", "eventRequest", "method", "#disconnect", "decryptedMessage", "isValidResponse", "jsonRpcResponseValidator", "isValidEventRequest", "inboundJsonRpcEventRequestValidator", "#sendRequestToIframe", "request", "requiresUserConsent", "#waitForResponse", "error", "requestId", "attempts", "_resolve", "_reject", "counter", "intervalId", "result", "ProviderRpcError", "config", "createIframeHandler", "ERROR_CODES_MAP", "getErrorMessage", "code", "details", "Eip1193Bridge", "#transeptorEthereumProvider", "config", "TranseptorEthereumProvider", "request", "error", "ProviderRpcError", "errorDetails", "getErrorMessage", "createEip1193Provider", "ProviderEvent", "TRANSEPTOR_WALLET_ICON", "announceProvider", "config", "provider", "createEip1193Provider", "detail", "TRANSEPTOR_WALLET_ICON", "announceEvent"]
7
+ }
@@ -0,0 +1,14 @@
1
+ import { Eip1193RequestArguments, Eip1193Provider } from './types.js';
2
+ import { TranseptorEthereumProviderConfig } from './transeptor-ethereum-provider.js';
3
+ export declare class Eip1193Bridge implements Eip1193Provider {
4
+ #private;
5
+ constructor(config: TranseptorEthereumProviderConfig);
6
+ request(request: Eip1193RequestArguments): Promise<unknown>;
7
+ }
8
+ /**
9
+ * Create a new Eip1193 provider
10
+ *
11
+ * @param config - the configuration for the TranseptorEthereumProvider
12
+ * @returns the Eip1193 provider
13
+ */
14
+ export declare function createEip1193Provider(config: TranseptorEthereumProviderConfig): Eip1193Provider;
@@ -0,0 +1,7 @@
1
+ import { TranseptorEthereumProviderConfig } from '../transeptor-ethereum-provider.js';
2
+ /**
3
+ * Announce the Transeptor Pay provider to the dapp
4
+ *
5
+ * @param config - the configuration for the TranseptorEthereumProvider
6
+ */
7
+ export declare const announceProvider: (config: TranseptorEthereumProviderConfig) => void;
@@ -0,0 +1,4 @@
1
+ /**
2
+ * The icon of the Transeptor Pay wallet
3
+ */
4
+ export declare const TRANSEPTOR_WALLET_ICON = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAACXBIWXMAAC4jAAAuIwF4pT92AAAChklEQVR4nO2YTW/TMBjHs7Jpm4QK34BLJSSkldieugiGwho7y41TvwInPgCX6dEktqKWVSoXhDjssFtL7JTDruPEie9U5KQvaZd2DWVEiZ6f9FSW3+3/300cw0AQBEEQBEEQBEEQBEEQ5J7YuKe6eWAYLoixr1tP7Mudine9vSwMA0oF2gTQizGYG7wnXF4yoU6ICM6oUB/mgwh1ylzVJVy+i7fNvfJ7R8FTItRP4g5atn2z+fyNelzzrsrzwXjvked1twmX3arTJ/E+cgqECppCfqRHiplCnTARHMTLZquP3CK+vyRcncfzcghEizn2KeWyo9Omq14QEbTD4kbjweicz0XUjgj5qeoEeXYBRAvhfpNxeTjOZUK2mStr8TpJ7XSbHLsAwgnvHfvU5P6FTjcaPa24QfnAIq5qLV9YpHiOXQAJ6kNpesaDIrsAbqk/VS8qK7gLIFn9SXGhXQAj9X8kqD9bh3oDi/DCuQBG6qtk9ZNcUC+MC2AF9QvtAlhN/WK6AFKoX0gXQDr1i+UCWPLcX61tGhdQri5Y3afpxsnyuX8Xad8LPHmob5fxtjlVf0z6t8NZF2S6CTA5+9WJ+ouuuUsiuhob+qrMRP9gcT9RPVpXr+jYBdltAIQD7zt9QrjfWu9Mjj+byRoTqhnPW/JEaE+/GmWyCRB97XFlh3Dl6HTFuyo/s3sP/yYq3nVZ90l58Jk56rVOV2q3+9Nj6LH2nYBTV3Wy2oAN/WNZvV0m5Dd9BIiQZ2sFV+dE+KemUF/0x1OdjvIW1m/qsfUc4nP6/8CwpCdh2zc764Zl/dplb39v2fZw864+w4Vn/xRAjNT/+P8+EARBEARBEARBEARBEMRYnT/136hHs8p9dgAAAABJRU5ErkJggg==";
@@ -0,0 +1,2 @@
1
+ export { announceProvider } from './announce-provider.js';
2
+ export * from './types.js';
@@ -0,0 +1,30 @@
1
+ import { Eip1193Provider } from '../index.js';
2
+ export declare const enum ProviderEvent {
3
+ AnnounceProvider = "eip6963:announceProvider",
4
+ RequestProvider = "eip6963:requestProvider"
5
+ }
6
+ /**
7
+ * Provider Detail defined by eip-6963
8
+ */
9
+ export type EIP6963ProviderDetail = {
10
+ info: {
11
+ uuid: string;
12
+ name: string;
13
+ icon: string;
14
+ rdns: string;
15
+ };
16
+ provider: Eip1193Provider;
17
+ };
18
+ /**
19
+ * Announce Event dispatched by a Wallet
20
+ */
21
+ export interface EIP6963AnnounceProviderEvent extends CustomEvent {
22
+ type: ProviderEvent.AnnounceProvider;
23
+ detail: EIP6963ProviderDetail;
24
+ }
25
+ /**
26
+ * Request Event dispatched by a DApp
27
+ */
28
+ export interface EIP6963RequestProviderEvent extends Event {
29
+ type: ProviderEvent.RequestProvider;
30
+ }
@@ -0,0 +1,100 @@
1
+ export type ErrorDetails = {
2
+ code: number;
3
+ message: string;
4
+ };
5
+ /**
6
+ * The EIP1193 error code enum
7
+ */
8
+ export declare enum EIP1193_ERROR_CODES {
9
+ /**
10
+ * The user rejected the request.
11
+ */
12
+ USER_REJECTED_REQUEST = 4001,
13
+ /**
14
+ * The specified address is not connected or not in the wallet
15
+ */
16
+ UNAUTHORIZED = 4100,
17
+ /**
18
+ * The Provider does not support the requested method.
19
+ */
20
+ UNSUPPORTED_METHOD = 4200,
21
+ /**
22
+ * The Provider is disconnected from all chains.
23
+ */
24
+ DISCONNECTED = 4900,
25
+ /**
26
+ * The Provider is not connected to the requested chain.
27
+ */
28
+ CHAIN_DISCONNECTED = 4901
29
+ }
30
+ /**
31
+ * The ERC-7715 error code enum
32
+ */
33
+ export declare enum ERC7715_ERROR_CODES {
34
+ /**
35
+ * The specified method is not authorized for the given origin
36
+ * Related RPCs: wallet_requestConnection
37
+ */
38
+ UNAUTHORIZED_ACCESS_RESTRICTED_METHOD = 4101
39
+ }
40
+ /**
41
+ * The EIP5792 error code enum
42
+ */
43
+ export declare enum EIP5792_ERROR_CODES {
44
+ /**
45
+ * This wallet does not support a capability that was not marked as optional
46
+ * Related RPCs: wallet_sendCalls
47
+ */
48
+ UNSUPPORTED_NON_OPTIONAL_CAPABILITY = 5700,
49
+ /**
50
+ * This wallet does not support the specified chain id
51
+ * Related RPCs: wallet_sendCalls
52
+ */
53
+ UNSUPPORTED_CHAIN_ID = 5710,
54
+ /**
55
+ * There is already a bundle submitted with this id
56
+ * Related RPCs: wallet_sendCalls
57
+ */
58
+ DUPLICATE_BUNDLE_ID = 5720,
59
+ /**
60
+ * This bundle id is unknown / has not been submitted
61
+ * Related RPCs: wallet_getCallsStatus, wallet_showCallsStatus
62
+ */
63
+ UNKNOWN_BUNDLE_ID = 5730,
64
+ /**
65
+ * The call bundle is too large for the wallet to process
66
+ * Related RPCs: wallet_sendCalls
67
+ */
68
+ BUNDLE_TOO_LARGE = 5740,
69
+ /**
70
+ * The wallet can support atomicity after an upgrade, but the user rejected the upgrade
71
+ * Related RPCs: wallet_sendCalls
72
+ */
73
+ ATOMIC_READY_WALLET_REJECTED_UPGRADE = 5750,
74
+ /**
75
+ * The wallet does not support atomic execution but the request requires it
76
+ * Related RPCs: wallet_sendCalls
77
+ */
78
+ ATOMICITY_NOT_SUPPORTED = 5760
79
+ }
80
+ /**
81
+ * The fatal error code enum
82
+ */
83
+ export declare enum FATAL_ERROR_CODES {
84
+ INTERNAL_ERROR = -32001
85
+ }
86
+ export declare enum COMMON_ERROR_CODES {
87
+ INVALID_PARAMS = -32602
88
+ }
89
+ /**
90
+ * The error code map
91
+ */
92
+ export declare const ERROR_CODES_MAP: Record<EIP1193_ERROR_CODES | EIP5792_ERROR_CODES | ERC7715_ERROR_CODES | FATAL_ERROR_CODES | COMMON_ERROR_CODES, ErrorDetails>;
93
+ /**
94
+ * Get the error message for a given error code
95
+ *
96
+ * @param code - The error code
97
+ * @returns The error message
98
+ * @throws An error if the error code is not found
99
+ */
100
+ export declare const getErrorMessage: (code: EIP1193_ERROR_CODES | EIP5792_ERROR_CODES | ERC7715_ERROR_CODES | FATAL_ERROR_CODES | COMMON_ERROR_CODES) => ErrorDetails;
@@ -0,0 +1,5 @@
1
+ export { createEip1193Provider } from './eip-1193-bridge.js';
2
+ export { TranseptorEthereumProvider } from './transeptor-ethereum-provider.js';
3
+ export type { TranseptorEthereumProviderConfig } from './transeptor-ethereum-provider.js';
4
+ export * from './eip-6963/index.js';
5
+ export * from './types.js';
@@ -0,0 +1,48 @@
1
+ import { Eip1193RequestArguments } from './types.js';
2
+ export type Message = unknown;
3
+ export type AcceptedChainConfig = {
4
+ /**
5
+ * The chain ID of the blockchain network to be used
6
+ * It should be a valid Ethereum chain ID in hex format
7
+ */
8
+ chainId: `0x${string}`;
9
+ /**
10
+ * The treasury address to receive the payments
11
+ * It should be a valid Ethereum address in hex format
12
+ */
13
+ treasuryAddress: `0x${string}`;
14
+ };
15
+ /**
16
+ * The configuration for the EmbeddedPayment
17
+ */
18
+ export type TranseptorEthereumProviderConfig = {
19
+ /**
20
+ * The development wallet url to be used for the iframe when in dev mode
21
+ */
22
+ devWalletUrl?: string;
23
+ };
24
+ /**
25
+ * We use a singleton class maintains a single instance across a web application, and to ensure
26
+ * the post message listener is only added once, allowing that web application to access wallet globally.
27
+ *
28
+ * The TranseptorEthereumProvider target environment is the browser, and it is designed to be used in web applications.
29
+ */
30
+ export declare class TranseptorEthereumProvider {
31
+ #private;
32
+ readonly FATAL_ERROR_MESSAGE = "fatal: internal error";
33
+ private constructor();
34
+ /**
35
+ * Generic request to the TranseptorEthereumProvider
36
+ *
37
+ * @param request - the request to be sent to the TranseptorEthereumProvider
38
+ * @returns the response from the TranseptorEthereumProvider
39
+ */
40
+ sendRequest(request: Eip1193RequestArguments): Promise<unknown>;
41
+ /**
42
+ * Create a new instance of the TranseptorEthereumProvider
43
+ *
44
+ * @param config - the configuration for the TranseptorEthereumProvider
45
+ * @returns the TranseptorEthereumProvider instance
46
+ */
47
+ static Create(config: TranseptorEthereumProviderConfig): TranseptorEthereumProvider;
48
+ }
@@ -0,0 +1,56 @@
1
+ export declare class ProviderRpcError extends Error {
2
+ /**
3
+ * MUST be an integer number
4
+ * SHOULD adhere to the specifications in the Error Standards section below
5
+ *
6
+ * @see https://eips.ethereum.org/EIPS/eip-1193#error-standards
7
+ */
8
+ code: number;
9
+ /**
10
+ * SHOULD contain any other useful information about the error
11
+ */
12
+ data?: unknown;
13
+ constructor({ message, code, data, }: {
14
+ message: string;
15
+ code: number;
16
+ data?: unknown;
17
+ });
18
+ }
19
+ /**
20
+ * The Eip1193 error types
21
+ *
22
+ * @see https://eips.ethereum.org/EIPS/eip-1193#rpc-errors
23
+ */
24
+ export type Eip1193Error = 'userRejectedRequest' | 'unauthorized' | 'unsupportedMethod' | 'disconnected' | 'chainDisconnected';
25
+ export type Eip1193RequestArguments = {
26
+ method: string;
27
+ params?: readonly unknown[] | object;
28
+ };
29
+ export interface Eip1193Provider {
30
+ /**
31
+ * Request a method from the Eip1193 provider
32
+ *
33
+ * @param request - the request to be sent to the Eip1193 provider
34
+ * @returns the response from the Eip1193 provider
35
+ *
36
+ * @throws If the returned Promise rejects, it MUST reject with a ProviderRpcError as specified in the [EIP-1193](https://eips.ethereum.org/EIPS/eip-1193#rpc-errors) section below.
37
+ */
38
+ request: (request: Eip1193RequestArguments) => Promise<unknown>;
39
+ }
40
+ /**
41
+ * The message event is intended for arbitrary notifications not covered by other events.
42
+ *
43
+ * @see https://eips.ethereum.org/EIPS/eip-1193#message-event
44
+ */
45
+ export type Eip1193ProviderMessage = {
46
+ readonly type: string;
47
+ readonly data: unknown;
48
+ };
49
+ /**
50
+ * Specify the integer ID of the connected chain as a hexadecimal string, per the eth_chainId Ethereum RPC method.
51
+ *
52
+ * @see https://eips.ethereum.org/EIPS/eip-1193#provider_connect
53
+ */
54
+ export type Eip1193ProviderConnectInfo = {
55
+ readonly chainId: `0x${string}`;
56
+ };
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Represents the response from a checkout operation.
3
+ */
4
+ export type CheckoutResponse = {
5
+ checkoutId: string;
6
+ isSuccess: boolean;
7
+ } | {
8
+ isSuccess: boolean;
9
+ error: string;
10
+ };
@@ -0,0 +1,8 @@
1
+ /**
2
+ * The fatal error type to send to the child iframe
3
+ */
4
+ export type FatalError = {
5
+ isFatalError: true;
6
+ code: number;
7
+ message: string;
8
+ };
@@ -0,0 +1,3 @@
1
+ export * from './json-rpc.types.js';
2
+ export * from './checkout.types.js';
3
+ export * from './error.types.js';
@@ -0,0 +1,76 @@
1
+ import { CheckoutResponse } from './checkout.types.js';
2
+ /**
3
+ * The mapping of inbound events to their corresponding methods.
4
+ */
5
+ export interface InboundRpcRequestEventMethodMapping {
6
+ wallet_paymentEvent: CheckoutResponse;
7
+ wallet_closeFrame: {
8
+ reason?: string;
9
+ };
10
+ wallet_resizeFrameFull: void;
11
+ wallet_resizeFrameDefault: void;
12
+ wallet_disconnect: void;
13
+ }
14
+ /**
15
+ * The method names for the inbound events.
16
+ */
17
+ export type InboundRpcRequestEventsMethodNames = keyof InboundRpcRequestEventMethodMapping;
18
+ /**
19
+ * The mapping of outbound events to their corresponding methods.
20
+ */
21
+ export interface OutboundRpcRequestEventMethodMapping {
22
+ wallet_navigateToDashboardEvent: [];
23
+ }
24
+ /**
25
+ * The method names for the outbound events.
26
+ */
27
+ export type OutboundRpcRequestEventsMethodNames = keyof OutboundRpcRequestEventMethodMapping;
28
+ /**
29
+ * The JSON-RPC request object for inbound events.
30
+ */
31
+ export type InboundJsonRpcEventRequest<M extends InboundRpcRequestEventsMethodNames> = {
32
+ jsonrpc: '2.0';
33
+ method: M;
34
+ params: InboundRpcRequestEventMethodMapping[M];
35
+ };
36
+ /**
37
+ * The JSON-RPC request object for outbound events.
38
+ */
39
+ export type OutboundJsonRpcEventRequest<M extends OutboundRpcRequestEventsMethodNames> = {
40
+ jsonrpc: '2.0';
41
+ method: M;
42
+ params: OutboundRpcRequestEventMethodMapping[M];
43
+ };
44
+ /**
45
+ * The JSON-RPC request object.
46
+ */
47
+ export type JsonRpcRequest = {
48
+ jsonrpc: '2.0';
49
+ method: string;
50
+ params: readonly unknown[] | object;
51
+ id: number | string;
52
+ };
53
+ /**
54
+ * The JSON-RPC success response object.
55
+ */
56
+ export type JsonRpcSuccessResponse = {
57
+ jsonrpc: '2.0';
58
+ result: any;
59
+ id: number | string;
60
+ };
61
+ /**
62
+ * The JSON-RPC error response object.
63
+ */
64
+ export type JsonRpcErrorResponse = {
65
+ jsonrpc: '2.0';
66
+ error: {
67
+ code: number;
68
+ message: string;
69
+ data?: any;
70
+ };
71
+ id: number | string;
72
+ };
73
+ /**
74
+ * The JSON-RPC response object.
75
+ */
76
+ export type JsonRpcResponse = JsonRpcSuccessResponse | JsonRpcErrorResponse;
@@ -0,0 +1,4 @@
1
+ export * from './random.js';
2
+ export * from './time.js';
3
+ export * from './payment.js';
4
+ export * from './validate.js';
@@ -0,0 +1,3 @@
1
+ export declare const calculateInitialAmount: (total: number) => number;
2
+ export declare const calculateMaxAmount: (total: number) => number;
3
+ export declare const calculateAmountPerPayment: (total: number, numberOfPayments: number) => number;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Returns a random number between 0 and maxRange
3
+ *
4
+ * @param maxRange - the maximum range for the random number
5
+ * @returns a random number between 0 and maxRange
6
+ */
7
+ export declare const getRandomNum: (maxRange: number) => number;
@@ -0,0 +1,30 @@
1
+ export declare const SECONDS_IN_WEEK: number;
2
+ export declare const SECONDS_IN_DAY: number;
3
+ /**
4
+ * This function returns the current time in seconds as 12:00:00 AM UTC on the current day.
5
+ *
6
+ * @returns The current time in seconds since the Unix epoch, adjusted to the start of today in UTC.
7
+ */
8
+ export declare const getStartOfToday: () => number;
9
+ /**
10
+ * This function computes the expiry time as one day after the last payment at 12:00:00 AM UTC,
11
+ * which is determined by the number of payments and the start of today.
12
+ *
13
+ * @param numberOfPayments - The total number of payments to be made.
14
+ * @returns The expiry time in seconds since the Unix epoch, adjusted to the start of today plus the duration of the payments.
15
+ */
16
+ export declare const getExpiry: (numberOfPayments: number) => number;
17
+ /**
18
+ * Formats an epoch timestamp in seconds to a date string in MM/DD/YYYY format.
19
+ *
20
+ * @param epochSeconds - epoch timestamp in seconds
21
+ * @returns formatted date string in MM/DD/YYYY format
22
+ */
23
+ export declare function formatDate(epochSeconds: number): string;
24
+ /**
25
+ * Formats an epoch timestamp in seconds to a relative time string.
26
+ *
27
+ * @param epochSeconds - epoch timestamp in seconds
28
+ * @returns relative time string (e.g., "Today", "In 1 week", "In 2 weeks 3 days")
29
+ */
30
+ export declare function formatRelative(epochSeconds: number): string;