@thru/embedded-provider 0.2.6 → 0.2.8

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.
package/README.md CHANGED
@@ -14,7 +14,7 @@ npm install @thru/embedded-provider
14
14
  import { EmbeddedProvider } from '@thru/embedded-provider';
15
15
 
16
16
  const provider = new EmbeddedProvider({
17
- iframeUrl: 'https://wallet.thru.io',
17
+ iframeUrl: 'https://wallet.thru.org',
18
18
  });
19
19
 
20
20
  // Initialize iframe (must be called before any other operation)
@@ -112,9 +112,7 @@ await provider.mountInline(container);
112
112
 
113
113
  The `IframeManager` validates that the iframe URL belongs to a set of trusted origins before loading it. Allowed origins:
114
114
 
115
- - `https://wallet.thru.io`
116
115
  - `https://wallet.thru.org`
117
- - `https://thru-wallet.up.railway.app`
118
116
  - `http://localhost` (any port, for development)
119
117
 
120
118
  Messages are sent with a strict `targetOrigin` and each iframe instance is tagged with a unique frame ID to prevent cross-talk.
package/dist/index.js CHANGED
@@ -48,8 +48,6 @@ var EmbeddedThruChain = class {
48
48
 
49
49
  // src/IframeManager.ts
50
50
  var ALLOWED_IFRAME_ORIGINS = [
51
- "https://thru-wallet.up.railway.app",
52
- "https://wallet.thru.io",
53
51
  "https://wallet.thru.org",
54
52
  // Allow localhost for development (any port)
55
53
  "http://localhost"
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../../chain-interfaces/src/types.ts","../src/chains/ThruChain.ts","../src/IframeManager.ts","../src/EmbeddedProvider.ts"],"names":["createRequestId","POST_MESSAGE_REQUEST_TYPES","DEFAULT_IFRAME_URL","EMBEDDED_PROVIDER_EVENTS"],"mappings":"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","file":"index.js","sourcesContent":["export const AddressType = {\n THRU: 'thru',\n} as const;\n\nexport type AddressType = typeof AddressType[keyof typeof AddressType];\n\nexport interface WalletAccount {\n accountType: AddressType;\n address: string;\n label: string;\n}\n\nexport interface AppMetadata {\n appId: string;\n appName: string;\n appUrl: string;\n imageUrl?: string;\n}\n\nexport interface ConnectResult {\n walletId?: string;\n accounts: WalletAccount[];\n status?: 'pending' | 'completed';\n metadata?: AppMetadata;\n}\n\nexport interface ConnectedApp {\n accountId: number;\n appId: string;\n origin: string;\n metadata: AppMetadata;\n connectedAt: number;\n updatedAt: number;\n}\n\nexport interface SignMessageParams {\n message: string | Uint8Array;\n networkId: string;\n}\n\nexport interface SignMessageResult {\n signature: Uint8Array;\n publicKey: string;\n}\n","import { AddressType, type IThruChain } from '@thru/chain-interfaces';\nimport { POST_MESSAGE_REQUEST_TYPES, createRequestId } from '@thru/protocol';\nimport type { EmbeddedProvider } from '../EmbeddedProvider';\nimport type { IframeManager } from '../IframeManager';\n\n/**\n * EmbeddedThruChain - postMessage-backed Thru chain adapter.\n */\nexport class EmbeddedThruChain implements IThruChain {\n private readonly iframeManager: IframeManager;\n private readonly provider: EmbeddedProvider;\n\n constructor(iframeManager: IframeManager, provider: EmbeddedProvider) {\n this.iframeManager = iframeManager;\n this.provider = provider;\n }\n\n get connected(): boolean {\n return this.provider.isConnected();\n }\n\n async connect(): Promise<{ publicKey: string }> {\n const result = await this.provider.connect();\n const thruAccount = result.accounts.find((addr) => addr.accountType === AddressType.THRU);\n\n if (!thruAccount) {\n throw new Error('Thru address not found in connection result');\n }\n\n return { publicKey: thruAccount.address };\n }\n\n async disconnect(): Promise<void> {\n await this.provider.disconnect();\n }\n\n async signTransaction(serializedTransaction: string): Promise<string> {\n if (!this.provider.isConnected()) {\n throw new Error('Wallet not connected');\n }\n if (typeof serializedTransaction !== 'string' || serializedTransaction.length === 0) {\n throw new Error('Transaction payload must be a base64 encoded string');\n }\n\n this.iframeManager.show();\n\n try {\n const response = await this.iframeManager.sendMessage({\n id: createRequestId(),\n type: POST_MESSAGE_REQUEST_TYPES.SIGN_TRANSACTION,\n payload: { transaction: serializedTransaction },\n origin: window.location.origin,\n });\n return response.result.signedTransaction;\n } finally {\n this.iframeManager.hide();\n }\n }\n}\n","import type {\n InferSuccessfulPostMessageResponse,\n PostMessageEvent,\n PostMessageRequest,\n PostMessageResponse,\n} from './types/messages';\nimport {\n IFRAME_READY_EVENT,\n POST_MESSAGE_EVENT_TYPE,\n POST_MESSAGE_REQUEST_TYPES,\n createRequestId,\n} from './types/messages';\n\n/**\n * Allowed origins for wallet iframe URLs\n * Only iframes from these origins can be loaded for security\n */\nconst ALLOWED_IFRAME_ORIGINS = [\n 'https://thru-wallet.up.railway.app',\n 'https://wallet.thru.io',\n 'https://wallet.thru.org',\n // Allow localhost for development (any port)\n 'http://localhost',\n];\n\n/**\n * Validates that the iframe URL is from a trusted origin\n * @throws Error if the origin is not allowed\n */\nfunction validateIframeOrigin(iframeUrl: string): void {\n let url: URL;\n try {\n url = new URL(iframeUrl);\n } catch (error) {\n throw new Error(\n `Invalid iframe URL: ${iframeUrl}. URL must be a valid absolute URL.`\n );\n }\n\n const origin = url.origin;\n\n // Check if origin matches any allowed origin\n // For localhost, we allow any port (e.g., http://localhost:3000)\n const isAllowed = ALLOWED_IFRAME_ORIGINS.some((allowedOrigin) => {\n if (allowedOrigin === 'http://localhost') {\n // Match exactly http://localhost or http://localhost:port\n return origin === 'http://localhost' || origin.match(/^http:\\/\\/localhost:\\d+$/);\n }\n return origin === allowedOrigin;\n });\n\n if (!isAllowed) {\n throw new Error(\n `Untrusted iframe origin: ${origin}. ` +\n `Only trusted wallet origins are allowed: ${ALLOWED_IFRAME_ORIGINS.join(', ')}. ` +\n `This security check prevents malicious websites from loading unauthorized wallet iframes.`\n );\n }\n}\n\n/**\n * Manages iframe lifecycle and postMessage communication\n * Handles creating, showing/hiding iframe, and message passing\n */\nexport class IframeManager {\n private iframe: HTMLIFrameElement | null = null;\n private iframeUrl: string;\n private iframeOrigin: string;\n private frameId: string;\n private messageHandlers = new Map<string, (response: PostMessageResponse) => void>();\n private messageListener: ((event: MessageEvent) => void) | null = null;\n private readyPromise: Promise<void> | null = null;\n private displayMode: 'modal' | 'inline' = 'modal';\n private inlineContainer: HTMLElement | null = null;\n private visible = false;\n\n /**\n * Callback for event broadcasts from iframe (no request id)\n */\n public onEvent?: (eventType: string, payload: any) => void;\n\n constructor(iframeUrl: string) {\n // Validate origin before accepting the URL\n validateIframeOrigin(iframeUrl);\n\n this.iframeUrl = iframeUrl;\n this.iframeOrigin = new URL(iframeUrl).origin;\n /* Used to correlate postMessage traffic with the correct iframe instance.\n Important in dev (React Strict Mode) where iframes can be created twice. */\n this.frameId = createRequestId('frame');\n }\n\n private getIframeSrc(): string {\n const url = new URL(this.iframeUrl);\n url.searchParams.set('tn_frame_id', this.frameId);\n return url.toString();\n }\n\n /**\n * Create and inject iframe into DOM\n * Returns a promise that resolves when iframe is ready\n */\n async createIframe(): Promise<void> {\n if (this.readyPromise) {\n return this.readyPromise;\n }\n\n this.readyPromise = (async () => {\n if (!this.iframe) {\n this.iframe = document.createElement('iframe');\n this.iframe.src = this.getIframeSrc();\n /* Allow WebAuthn in cross-origin iframe for passkey auth. */\n this.iframe.allow = 'publickey-credentials-get; publickey-credentials-create';\n this.applyIframeStyles();\n /* Keep hidden (but still load) until the wallet asks to show UI. */\n this.setVisibility(false);\n\n if (this.displayMode === 'inline' && this.inlineContainer) {\n this.inlineContainer.appendChild(this.iframe);\n } else {\n document.body.appendChild(this.iframe);\n }\n\n // Set up message listener\n this.messageListener = this.handleMessage.bind(this);\n window.addEventListener('message', this.messageListener);\n }\n\n await this.waitForReady();\n })().catch((error) => {\n this.readyPromise = null;\n throw error;\n });\n\n return this.readyPromise;\n }\n\n /**\n * Wait for iframe to send 'ready' signal\n */\n private waitForReady(): Promise<void> {\n return new Promise((resolve, reject) => {\n let resolved = false;\n let readyHandler: (event: MessageEvent) => void;\n const cleanup = () => {\n if (resolved) {\n return;\n }\n resolved = true;\n window.removeEventListener('message', readyHandler);\n clearTimeout(timeout);\n };\n\n const timeout = setTimeout(() => {\n cleanup();\n reject(new Error('Iframe ready timeout - wallet failed to load'));\n }, 10000);\n\n readyHandler = (event: MessageEvent) => {\n if (!this.isMessageFromIframe(event)) {\n return;\n }\n\n if (event.data?.type === IFRAME_READY_EVENT) {\n cleanup();\n resolve();\n }\n };\n\n window.addEventListener('message', readyHandler);\n });\n }\n\n /**\n * Mount iframe inline inside the provided container.\n */\n async mountInline(container: HTMLElement): Promise<void> {\n this.inlineContainer = container;\n this.displayMode = 'inline';\n await this.createIframe();\n this.showInline();\n }\n\n /**\n * Show iframe inline (embedded in container).\n */\n showInline(): void {\n if (!this.iframe) {\n return;\n }\n this.displayMode = 'inline';\n if (this.inlineContainer && this.iframe.parentElement !== this.inlineContainer) {\n this.inlineContainer.appendChild(this.iframe);\n }\n this.applyIframeStyles();\n this.setVisibility(true);\n }\n\n /**\n * Show iframe as a full-screen modal.\n */\n showModal(): void {\n if (!this.iframe) {\n return;\n }\n this.displayMode = 'modal';\n if (this.iframe.parentElement !== document.body) {\n document.body.appendChild(this.iframe);\n }\n this.applyIframeStyles();\n this.setVisibility(true);\n }\n\n /**\n * Show iframe modal\n */\n show(): void {\n this.showModal();\n }\n\n /**\n * Hide iframe modal\n */\n hide(): void {\n this.setVisibility(false);\n }\n\n isInline(): boolean {\n return this.displayMode === 'inline';\n }\n\n private applyIframeStyles(): void {\n if (!this.iframe) {\n return;\n }\n\n if (this.displayMode === 'inline') {\n this.iframe.style.cssText = `\n position: relative;\n width: 100%;\n height: 100%;\n border: none;\n z-index: 1;\n display: block;\n background: transparent;\n `;\n return;\n }\n\n this.iframe.style.cssText = `\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n border: none;\n z-index: 999999;\n display: block;\n background: rgba(0, 0, 0, 0.5);\n `;\n }\n\n private setVisibility(visible: boolean): void {\n if (!this.iframe) {\n return;\n }\n this.visible = visible;\n this.iframe.style.opacity = visible ? '1' : '0';\n this.iframe.style.pointerEvents = visible ? 'auto' : 'none';\n this.iframe.style.visibility = visible ? 'visible' : 'hidden';\n }\n\n /**\n * Send message to iframe and wait for response\n */\n async sendMessage<TRequest extends PostMessageRequest>(\n request: TRequest\n ): Promise<InferSuccessfulPostMessageResponse<TRequest>> {\n /* Ensure the iframe has navigated to the wallet origin before we try to\n postMessage to a strict targetOrigin. Otherwise the iframe can still be\n about:blank (same-origin with the dapp) and postMessage will throw. */\n if (this.readyPromise) {\n await this.readyPromise;\n } else {\n await this.createIframe();\n }\n\n if (!this.iframe?.contentWindow) {\n throw new Error('Iframe not initialized - call createIframe() first');\n }\n\n return new Promise<InferSuccessfulPostMessageResponse<TRequest>>((resolve, reject) => {\n /* CONNECT/SIGN_* requests require a human click and can take minutes.\n Keep a longer timeout to avoid breaking \"inline connect button\" flows. */\n const timeoutMs =\n request.type === POST_MESSAGE_REQUEST_TYPES.CONNECT ||\n request.type === POST_MESSAGE_REQUEST_TYPES.SIGN_MESSAGE ||\n request.type === POST_MESSAGE_REQUEST_TYPES.SIGN_TRANSACTION\n ? 5 * 60 * 1000 /* 5 minutes */\n : 30 * 1000; /* 30 seconds */\n\n const timeout = setTimeout(() => {\n this.messageHandlers.delete(request.id);\n reject(new Error('Request timeout - wallet did not respond'));\n }, timeoutMs);\n\n // Store handler for this request\n this.messageHandlers.set(request.id, (response: PostMessageResponse) => {\n clearTimeout(timeout);\n this.messageHandlers.delete(request.id);\n\n if (response.success) {\n resolve(response as InferSuccessfulPostMessageResponse<TRequest>);\n } else {\n const error = new Error(response.error?.message || 'Unknown error');\n (error as any).code = response.error?.code;\n reject(error);\n }\n });\n\n // Send message to iframe\n this.iframe!.contentWindow!.postMessage(request, this.iframeOrigin);\n });\n }\n\n /**\n * Handle incoming messages from iframe\n */\n private handleMessage(event: MessageEvent): void {\n if (!this.isMessageFromIframe(event)) {\n return; // Ignore messages from other origins\n }\n\n const data = event.data;\n\n // Handle response to a specific request (has id)\n if (data.id && this.messageHandlers.has(data.id)) {\n const handler = this.messageHandlers.get(data.id);\n if (handler) {\n handler(data as PostMessageResponse);\n }\n return;\n }\n\n // Handle event broadcasts (type === 'event')\n if (data.type === POST_MESSAGE_EVENT_TYPE) {\n this.handleEvent(data as PostMessageEvent);\n }\n }\n\n /**\n * Handle event broadcasts from iframe\n */\n private handleEvent(data: PostMessageEvent): void {\n // Forward to EmbeddedProvider via callback\n if (this.onEvent) {\n this.onEvent(data.event, data.data);\n }\n }\n\n private isMessageFromIframe(event: MessageEvent): boolean {\n if (event.origin !== this.iframeOrigin) {\n return false;\n }\n\n const data = event.data as any;\n if (!data || data.frameId !== this.frameId) {\n return false;\n }\n\n /* Some browsers (notably Safari) can provide a null `event.source` for\n cross-origin postMessage events. Frame id + origin is sufficient. */\n if (!event.source) {\n return true;\n }\n\n if (this.iframe?.contentWindow && event.source !== this.iframe.contentWindow) {\n return false;\n }\n\n return true;\n }\n\n /**\n * Destroy iframe and cleanup\n */\n destroy(): void {\n if (this.iframe) {\n this.iframe.remove();\n this.iframe = null;\n }\n\n this.readyPromise = null;\n\n if (this.messageListener) {\n window.removeEventListener('message', this.messageListener);\n this.messageListener = null;\n }\n\n this.messageHandlers.clear();\n }\n}\n","import type {\n AddressType as AddressTypeValue,\n ConnectResult,\n IThruChain,\n WalletAccount,\n} from '@thru/chain-interfaces';\nimport { AddressType } from '@thru/chain-interfaces';\nimport {\n DEFAULT_IFRAME_URL,\n EMBEDDED_PROVIDER_EVENTS,\n POST_MESSAGE_REQUEST_TYPES,\n createRequestId,\n type ConnectMetadataInput,\n type ConnectRequestPayload,\n type SelectAccountPayload\n} from '@thru/protocol';\nimport { IframeManager } from './IframeManager';\nimport { EmbeddedThruChain } from './chains/ThruChain';\n\nexport interface EmbeddedProviderConfig {\n iframeUrl?: string;\n addressTypes?: AddressTypeValue[];\n}\n\nexport interface ConnectOptions {\n metadata?: ConnectMetadataInput;\n}\n\n/**\n * Main embedded provider class\n * Manages iframe lifecycle, connection state, and chain-specific interfaces\n */\nexport class EmbeddedProvider {\n private iframeManager: IframeManager;\n private _thruChain?: IThruChain;\n private connected = false;\n private accounts: WalletAccount[] = [];\n private selectedAccount: WalletAccount | null = null;\n private eventListeners = new Map<string, Set<Function>>();\n private inlineMode = false;\n constructor(config: EmbeddedProviderConfig) {\n const iframeUrl = config.iframeUrl || DEFAULT_IFRAME_URL;\n this.iframeManager = new IframeManager(iframeUrl);\n\n // Set up event forwarding from iframe\n this.iframeManager.onEvent = (eventType: string, payload: any) => {\n this.emit(eventType, payload);\n\n if (eventType === EMBEDDED_PROVIDER_EVENTS.UI_SHOW) {\n if (this.inlineMode) {\n this.iframeManager.showInline();\n } else {\n this.iframeManager.showModal();\n }\n return;\n }\n\n if (\n eventType === EMBEDDED_PROVIDER_EVENTS.DISCONNECT ||\n eventType === EMBEDDED_PROVIDER_EVENTS.LOCK\n ) {\n this.connected = false;\n this.accounts = [];\n this.selectedAccount = null;\n return;\n }\n\n if (eventType === EMBEDDED_PROVIDER_EVENTS.ACCOUNT_CHANGED) {\n const account = (payload && (payload.account as WalletAccount | undefined)) || null;\n this.refreshAccountCache(account ?? null);\n }\n };\n\n // Create chain instances\n const addressTypes = config.addressTypes || [AddressType.THRU];\n if (addressTypes.includes(AddressType.THRU)) {\n this._thruChain = new EmbeddedThruChain(this.iframeManager, this);\n }\n }\n\n /**\n * Initialize the provider (must be called before use)\n * Creates iframe and waits for it to be ready\n */\n async initialize(): Promise<void> {\n await this.iframeManager.createIframe();\n }\n\n /**\n * Mount the wallet iframe inline in a container (for inline connect button).\n */\n async mountInline(container: HTMLElement): Promise<void> {\n this.inlineMode = true;\n await this.iframeManager.mountInline(container);\n }\n\n /**\n * Connect to wallet\n * Shows iframe modal and requests connection\n */\n async connect(options?: ConnectOptions): Promise<ConnectResult> {\n // Emit connecting event\n this.emit(EMBEDDED_PROVIDER_EVENTS.CONNECT_START, {});\n\n try {\n if (this.inlineMode) {\n this.iframeManager.showInline();\n } else {\n this.iframeManager.showModal();\n }\n\n const payload: ConnectRequestPayload = {};\n\n if (options?.metadata) {\n payload.metadata = options.metadata;\n }\n\n const response = await this.iframeManager.sendMessage({\n id: createRequestId(),\n type: POST_MESSAGE_REQUEST_TYPES.CONNECT,\n payload,\n origin: window.location.origin,\n });\n\n this.connected = true;\n this.accounts = response.result.accounts;\n this.selectedAccount = response.result.accounts[0] ?? null;\n\n // Emit success event\n this.emit(EMBEDDED_PROVIDER_EVENTS.CONNECT, response.result);\n\n // Hide iframe after successful connection\n if (!this.inlineMode) {\n this.iframeManager.hide();\n }\n\n return response.result;\n } catch (error) {\n if (!this.inlineMode) {\n this.iframeManager.hide();\n }\n this.emit(EMBEDDED_PROVIDER_EVENTS.CONNECT_ERROR, { error });\n throw error;\n }\n }\n\n /**\n * Disconnect from wallet\n */\n async disconnect(): Promise<void> {\n try {\n await this.iframeManager.sendMessage({\n id: createRequestId(),\n type: POST_MESSAGE_REQUEST_TYPES.DISCONNECT,\n origin: window.location.origin,\n });\n\n this.emit(EMBEDDED_PROVIDER_EVENTS.DISCONNECT, {});\n } catch (error) {\n this.emit(EMBEDDED_PROVIDER_EVENTS.ERROR, { error });\n throw error;\n } finally {\n this.connected = false;\n this.accounts = [];\n this.selectedAccount = null;\n if (!this.inlineMode) {\n this.iframeManager.hide();\n }\n }\n }\n\n /**\n * Check if connected\n */\n isConnected(): boolean {\n return this.connected;\n }\n\n /**\n * Get accounts\n */\n getAccounts(): WalletAccount[] {\n return this.accounts;\n }\n\n getSelectedAccount(): WalletAccount | null {\n return this.selectedAccount;\n }\n\n async selectAccount(publicKey: string): Promise<WalletAccount> {\n if (!this.connected) {\n throw new Error('Wallet not connected');\n }\n\n const knownAccount = this.accounts.find(acc => acc.address === publicKey) ?? null;\n if (!knownAccount) {\n console.warn('[EmbeddedProvider] Selecting account not present in local cache');\n }\n const payload: SelectAccountPayload = { publicKey };\n\n const response = await this.iframeManager.sendMessage({\n id: createRequestId(),\n type: POST_MESSAGE_REQUEST_TYPES.SELECT_ACCOUNT,\n payload,\n origin: window.location.origin,\n });\n\n const account = response.result.account;\n\n this.refreshAccountCache(account);\n return account;\n }\n\n /**\n * Get Thru chain API\n */\n get thru(): IThruChain {\n if (!this._thruChain) {\n throw new Error('Thru chain not enabled in provider config');\n }\n return this._thruChain;\n }\n\n /**\n * Event emitter: on\n */\n on(event: string, callback: Function): void {\n if (!this.eventListeners.has(event)) {\n this.eventListeners.set(event, new Set());\n }\n this.eventListeners.get(event)!.add(callback);\n }\n\n /**\n * Event emitter: off\n */\n off(event: string, callback: Function): void {\n this.eventListeners.get(event)?.delete(callback);\n }\n\n /**\n * Emit event to all listeners\n */\n private emit(event: string, data?: any): void {\n this.eventListeners.get(event)?.forEach(callback => {\n try {\n callback(data);\n } catch (error) {\n console.error(`Error in event listener for ${event}:`, error);\n }\n });\n }\n\n /**\n * Get iframe manager (for chain implementations)\n * @internal\n */\n getIframeManager(): IframeManager {\n return this.iframeManager;\n }\n\n /**\n * Destroy provider and cleanup\n */\n destroy(): void {\n this.iframeManager.destroy();\n this.eventListeners.clear();\n this.connected = false;\n this.accounts = [];\n this.selectedAccount = null;\n }\n\n private refreshAccountCache(account: WalletAccount | null): void {\n if (!account) {\n this.selectedAccount = null;\n return;\n }\n\n const existingIdx = this.accounts.findIndex(acc => acc.address === account.address);\n if (existingIdx >= 0) {\n this.accounts[existingIdx] = account;\n } else {\n this.accounts = [...this.accounts, account];\n }\n this.selectedAccount = account;\n }\n}\n"]}
1
+ {"version":3,"sources":["../../chain-interfaces/src/types.ts","../src/chains/ThruChain.ts","../src/IframeManager.ts","../src/EmbeddedProvider.ts"],"names":["createRequestId","POST_MESSAGE_REQUEST_TYPES","DEFAULT_IFRAME_URL","EMBEDDED_PROVIDER_EVENTS"],"mappings":"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","file":"index.js","sourcesContent":["export const AddressType = {\n THRU: 'thru',\n} as const;\n\nexport type AddressType = typeof AddressType[keyof typeof AddressType];\n\nexport interface WalletAccount {\n accountType: AddressType;\n address: string;\n label: string;\n}\n\nexport interface AppMetadata {\n appId: string;\n appName: string;\n appUrl: string;\n imageUrl?: string;\n}\n\nexport interface ConnectResult {\n walletId?: string;\n accounts: WalletAccount[];\n status?: 'pending' | 'completed';\n metadata?: AppMetadata;\n}\n\nexport interface ConnectedApp {\n accountId: number;\n appId: string;\n origin: string;\n metadata: AppMetadata;\n connectedAt: number;\n updatedAt: number;\n}\n\nexport interface SignMessageParams {\n message: string | Uint8Array;\n networkId: string;\n}\n\nexport interface SignMessageResult {\n signature: Uint8Array;\n publicKey: string;\n}\n","import { AddressType, type IThruChain } from '@thru/chain-interfaces';\nimport { POST_MESSAGE_REQUEST_TYPES, createRequestId } from '@thru/protocol';\nimport type { EmbeddedProvider } from '../EmbeddedProvider';\nimport type { IframeManager } from '../IframeManager';\n\n/**\n * EmbeddedThruChain - postMessage-backed Thru chain adapter.\n */\nexport class EmbeddedThruChain implements IThruChain {\n private readonly iframeManager: IframeManager;\n private readonly provider: EmbeddedProvider;\n\n constructor(iframeManager: IframeManager, provider: EmbeddedProvider) {\n this.iframeManager = iframeManager;\n this.provider = provider;\n }\n\n get connected(): boolean {\n return this.provider.isConnected();\n }\n\n async connect(): Promise<{ publicKey: string }> {\n const result = await this.provider.connect();\n const thruAccount = result.accounts.find((addr) => addr.accountType === AddressType.THRU);\n\n if (!thruAccount) {\n throw new Error('Thru address not found in connection result');\n }\n\n return { publicKey: thruAccount.address };\n }\n\n async disconnect(): Promise<void> {\n await this.provider.disconnect();\n }\n\n async signTransaction(serializedTransaction: string): Promise<string> {\n if (!this.provider.isConnected()) {\n throw new Error('Wallet not connected');\n }\n if (typeof serializedTransaction !== 'string' || serializedTransaction.length === 0) {\n throw new Error('Transaction payload must be a base64 encoded string');\n }\n\n this.iframeManager.show();\n\n try {\n const response = await this.iframeManager.sendMessage({\n id: createRequestId(),\n type: POST_MESSAGE_REQUEST_TYPES.SIGN_TRANSACTION,\n payload: { transaction: serializedTransaction },\n origin: window.location.origin,\n });\n return response.result.signedTransaction;\n } finally {\n this.iframeManager.hide();\n }\n }\n}\n","import type {\n InferSuccessfulPostMessageResponse,\n PostMessageEvent,\n PostMessageRequest,\n PostMessageResponse,\n} from './types/messages';\nimport {\n IFRAME_READY_EVENT,\n POST_MESSAGE_EVENT_TYPE,\n POST_MESSAGE_REQUEST_TYPES,\n createRequestId,\n} from './types/messages';\n\n/**\n * Allowed origins for wallet iframe URLs\n * Only iframes from these origins can be loaded for security\n */\nconst ALLOWED_IFRAME_ORIGINS = [\n 'https://wallet.thru.org',\n // Allow localhost for development (any port)\n 'http://localhost',\n];\n\n/**\n * Validates that the iframe URL is from a trusted origin\n * @throws Error if the origin is not allowed\n */\nfunction validateIframeOrigin(iframeUrl: string): void {\n let url: URL;\n try {\n url = new URL(iframeUrl);\n } catch (error) {\n throw new Error(\n `Invalid iframe URL: ${iframeUrl}. URL must be a valid absolute URL.`\n );\n }\n\n const origin = url.origin;\n\n // Check if origin matches any allowed origin\n // For localhost, we allow any port (e.g., http://localhost:3000)\n const isAllowed = ALLOWED_IFRAME_ORIGINS.some((allowedOrigin) => {\n if (allowedOrigin === 'http://localhost') {\n // Match exactly http://localhost or http://localhost:port\n return origin === 'http://localhost' || origin.match(/^http:\\/\\/localhost:\\d+$/);\n }\n return origin === allowedOrigin;\n });\n\n if (!isAllowed) {\n throw new Error(\n `Untrusted iframe origin: ${origin}. ` +\n `Only trusted wallet origins are allowed: ${ALLOWED_IFRAME_ORIGINS.join(', ')}. ` +\n `This security check prevents malicious websites from loading unauthorized wallet iframes.`\n );\n }\n}\n\n/**\n * Manages iframe lifecycle and postMessage communication\n * Handles creating, showing/hiding iframe, and message passing\n */\nexport class IframeManager {\n private iframe: HTMLIFrameElement | null = null;\n private iframeUrl: string;\n private iframeOrigin: string;\n private frameId: string;\n private messageHandlers = new Map<string, (response: PostMessageResponse) => void>();\n private messageListener: ((event: MessageEvent) => void) | null = null;\n private readyPromise: Promise<void> | null = null;\n private displayMode: 'modal' | 'inline' = 'modal';\n private inlineContainer: HTMLElement | null = null;\n private visible = false;\n\n /**\n * Callback for event broadcasts from iframe (no request id)\n */\n public onEvent?: (eventType: string, payload: any) => void;\n\n constructor(iframeUrl: string) {\n // Validate origin before accepting the URL\n validateIframeOrigin(iframeUrl);\n\n this.iframeUrl = iframeUrl;\n this.iframeOrigin = new URL(iframeUrl).origin;\n /* Used to correlate postMessage traffic with the correct iframe instance.\n Important in dev (React Strict Mode) where iframes can be created twice. */\n this.frameId = createRequestId('frame');\n }\n\n private getIframeSrc(): string {\n const url = new URL(this.iframeUrl);\n url.searchParams.set('tn_frame_id', this.frameId);\n return url.toString();\n }\n\n /**\n * Create and inject iframe into DOM\n * Returns a promise that resolves when iframe is ready\n */\n async createIframe(): Promise<void> {\n if (this.readyPromise) {\n return this.readyPromise;\n }\n\n this.readyPromise = (async () => {\n if (!this.iframe) {\n this.iframe = document.createElement('iframe');\n this.iframe.src = this.getIframeSrc();\n /* Allow WebAuthn in cross-origin iframe for passkey auth. */\n this.iframe.allow = 'publickey-credentials-get; publickey-credentials-create';\n this.applyIframeStyles();\n /* Keep hidden (but still load) until the wallet asks to show UI. */\n this.setVisibility(false);\n\n if (this.displayMode === 'inline' && this.inlineContainer) {\n this.inlineContainer.appendChild(this.iframe);\n } else {\n document.body.appendChild(this.iframe);\n }\n\n // Set up message listener\n this.messageListener = this.handleMessage.bind(this);\n window.addEventListener('message', this.messageListener);\n }\n\n await this.waitForReady();\n })().catch((error) => {\n this.readyPromise = null;\n throw error;\n });\n\n return this.readyPromise;\n }\n\n /**\n * Wait for iframe to send 'ready' signal\n */\n private waitForReady(): Promise<void> {\n return new Promise((resolve, reject) => {\n let resolved = false;\n let readyHandler: (event: MessageEvent) => void;\n const cleanup = () => {\n if (resolved) {\n return;\n }\n resolved = true;\n window.removeEventListener('message', readyHandler);\n clearTimeout(timeout);\n };\n\n const timeout = setTimeout(() => {\n cleanup();\n reject(new Error('Iframe ready timeout - wallet failed to load'));\n }, 10000);\n\n readyHandler = (event: MessageEvent) => {\n if (!this.isMessageFromIframe(event)) {\n return;\n }\n\n if (event.data?.type === IFRAME_READY_EVENT) {\n cleanup();\n resolve();\n }\n };\n\n window.addEventListener('message', readyHandler);\n });\n }\n\n /**\n * Mount iframe inline inside the provided container.\n */\n async mountInline(container: HTMLElement): Promise<void> {\n this.inlineContainer = container;\n this.displayMode = 'inline';\n await this.createIframe();\n this.showInline();\n }\n\n /**\n * Show iframe inline (embedded in container).\n */\n showInline(): void {\n if (!this.iframe) {\n return;\n }\n this.displayMode = 'inline';\n if (this.inlineContainer && this.iframe.parentElement !== this.inlineContainer) {\n this.inlineContainer.appendChild(this.iframe);\n }\n this.applyIframeStyles();\n this.setVisibility(true);\n }\n\n /**\n * Show iframe as a full-screen modal.\n */\n showModal(): void {\n if (!this.iframe) {\n return;\n }\n this.displayMode = 'modal';\n if (this.iframe.parentElement !== document.body) {\n document.body.appendChild(this.iframe);\n }\n this.applyIframeStyles();\n this.setVisibility(true);\n }\n\n /**\n * Show iframe modal\n */\n show(): void {\n this.showModal();\n }\n\n /**\n * Hide iframe modal\n */\n hide(): void {\n this.setVisibility(false);\n }\n\n isInline(): boolean {\n return this.displayMode === 'inline';\n }\n\n private applyIframeStyles(): void {\n if (!this.iframe) {\n return;\n }\n\n if (this.displayMode === 'inline') {\n this.iframe.style.cssText = `\n position: relative;\n width: 100%;\n height: 100%;\n border: none;\n z-index: 1;\n display: block;\n background: transparent;\n `;\n return;\n }\n\n this.iframe.style.cssText = `\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n border: none;\n z-index: 999999;\n display: block;\n background: rgba(0, 0, 0, 0.5);\n `;\n }\n\n private setVisibility(visible: boolean): void {\n if (!this.iframe) {\n return;\n }\n this.visible = visible;\n this.iframe.style.opacity = visible ? '1' : '0';\n this.iframe.style.pointerEvents = visible ? 'auto' : 'none';\n this.iframe.style.visibility = visible ? 'visible' : 'hidden';\n }\n\n /**\n * Send message to iframe and wait for response\n */\n async sendMessage<TRequest extends PostMessageRequest>(\n request: TRequest\n ): Promise<InferSuccessfulPostMessageResponse<TRequest>> {\n /* Ensure the iframe has navigated to the wallet origin before we try to\n postMessage to a strict targetOrigin. Otherwise the iframe can still be\n about:blank (same-origin with the dapp) and postMessage will throw. */\n if (this.readyPromise) {\n await this.readyPromise;\n } else {\n await this.createIframe();\n }\n\n if (!this.iframe?.contentWindow) {\n throw new Error('Iframe not initialized - call createIframe() first');\n }\n\n return new Promise<InferSuccessfulPostMessageResponse<TRequest>>((resolve, reject) => {\n /* CONNECT/SIGN_* requests require a human click and can take minutes.\n Keep a longer timeout to avoid breaking \"inline connect button\" flows. */\n const timeoutMs =\n request.type === POST_MESSAGE_REQUEST_TYPES.CONNECT ||\n request.type === POST_MESSAGE_REQUEST_TYPES.SIGN_MESSAGE ||\n request.type === POST_MESSAGE_REQUEST_TYPES.SIGN_TRANSACTION\n ? 5 * 60 * 1000 /* 5 minutes */\n : 30 * 1000; /* 30 seconds */\n\n const timeout = setTimeout(() => {\n this.messageHandlers.delete(request.id);\n reject(new Error('Request timeout - wallet did not respond'));\n }, timeoutMs);\n\n // Store handler for this request\n this.messageHandlers.set(request.id, (response: PostMessageResponse) => {\n clearTimeout(timeout);\n this.messageHandlers.delete(request.id);\n\n if (response.success) {\n resolve(response as InferSuccessfulPostMessageResponse<TRequest>);\n } else {\n const error = new Error(response.error?.message || 'Unknown error');\n (error as any).code = response.error?.code;\n reject(error);\n }\n });\n\n // Send message to iframe\n this.iframe!.contentWindow!.postMessage(request, this.iframeOrigin);\n });\n }\n\n /**\n * Handle incoming messages from iframe\n */\n private handleMessage(event: MessageEvent): void {\n if (!this.isMessageFromIframe(event)) {\n return; // Ignore messages from other origins\n }\n\n const data = event.data;\n\n // Handle response to a specific request (has id)\n if (data.id && this.messageHandlers.has(data.id)) {\n const handler = this.messageHandlers.get(data.id);\n if (handler) {\n handler(data as PostMessageResponse);\n }\n return;\n }\n\n // Handle event broadcasts (type === 'event')\n if (data.type === POST_MESSAGE_EVENT_TYPE) {\n this.handleEvent(data as PostMessageEvent);\n }\n }\n\n /**\n * Handle event broadcasts from iframe\n */\n private handleEvent(data: PostMessageEvent): void {\n // Forward to EmbeddedProvider via callback\n if (this.onEvent) {\n this.onEvent(data.event, data.data);\n }\n }\n\n private isMessageFromIframe(event: MessageEvent): boolean {\n if (event.origin !== this.iframeOrigin) {\n return false;\n }\n\n const data = event.data as any;\n if (!data || data.frameId !== this.frameId) {\n return false;\n }\n\n /* Some browsers (notably Safari) can provide a null `event.source` for\n cross-origin postMessage events. Frame id + origin is sufficient. */\n if (!event.source) {\n return true;\n }\n\n if (this.iframe?.contentWindow && event.source !== this.iframe.contentWindow) {\n return false;\n }\n\n return true;\n }\n\n /**\n * Destroy iframe and cleanup\n */\n destroy(): void {\n if (this.iframe) {\n this.iframe.remove();\n this.iframe = null;\n }\n\n this.readyPromise = null;\n\n if (this.messageListener) {\n window.removeEventListener('message', this.messageListener);\n this.messageListener = null;\n }\n\n this.messageHandlers.clear();\n }\n}\n","import type {\n AddressType as AddressTypeValue,\n ConnectResult,\n IThruChain,\n WalletAccount,\n} from '@thru/chain-interfaces';\nimport { AddressType } from '@thru/chain-interfaces';\nimport {\n DEFAULT_IFRAME_URL,\n EMBEDDED_PROVIDER_EVENTS,\n POST_MESSAGE_REQUEST_TYPES,\n createRequestId,\n type ConnectMetadataInput,\n type ConnectRequestPayload,\n type SelectAccountPayload\n} from '@thru/protocol';\nimport { IframeManager } from './IframeManager';\nimport { EmbeddedThruChain } from './chains/ThruChain';\n\nexport interface EmbeddedProviderConfig {\n iframeUrl?: string;\n addressTypes?: AddressTypeValue[];\n}\n\nexport interface ConnectOptions {\n metadata?: ConnectMetadataInput;\n}\n\n/**\n * Main embedded provider class\n * Manages iframe lifecycle, connection state, and chain-specific interfaces\n */\nexport class EmbeddedProvider {\n private iframeManager: IframeManager;\n private _thruChain?: IThruChain;\n private connected = false;\n private accounts: WalletAccount[] = [];\n private selectedAccount: WalletAccount | null = null;\n private eventListeners = new Map<string, Set<Function>>();\n private inlineMode = false;\n constructor(config: EmbeddedProviderConfig) {\n const iframeUrl = config.iframeUrl || DEFAULT_IFRAME_URL;\n this.iframeManager = new IframeManager(iframeUrl);\n\n // Set up event forwarding from iframe\n this.iframeManager.onEvent = (eventType: string, payload: any) => {\n this.emit(eventType, payload);\n\n if (eventType === EMBEDDED_PROVIDER_EVENTS.UI_SHOW) {\n if (this.inlineMode) {\n this.iframeManager.showInline();\n } else {\n this.iframeManager.showModal();\n }\n return;\n }\n\n if (\n eventType === EMBEDDED_PROVIDER_EVENTS.DISCONNECT ||\n eventType === EMBEDDED_PROVIDER_EVENTS.LOCK\n ) {\n this.connected = false;\n this.accounts = [];\n this.selectedAccount = null;\n return;\n }\n\n if (eventType === EMBEDDED_PROVIDER_EVENTS.ACCOUNT_CHANGED) {\n const account = (payload && (payload.account as WalletAccount | undefined)) || null;\n this.refreshAccountCache(account ?? null);\n }\n };\n\n // Create chain instances\n const addressTypes = config.addressTypes || [AddressType.THRU];\n if (addressTypes.includes(AddressType.THRU)) {\n this._thruChain = new EmbeddedThruChain(this.iframeManager, this);\n }\n }\n\n /**\n * Initialize the provider (must be called before use)\n * Creates iframe and waits for it to be ready\n */\n async initialize(): Promise<void> {\n await this.iframeManager.createIframe();\n }\n\n /**\n * Mount the wallet iframe inline in a container (for inline connect button).\n */\n async mountInline(container: HTMLElement): Promise<void> {\n this.inlineMode = true;\n await this.iframeManager.mountInline(container);\n }\n\n /**\n * Connect to wallet\n * Shows iframe modal and requests connection\n */\n async connect(options?: ConnectOptions): Promise<ConnectResult> {\n // Emit connecting event\n this.emit(EMBEDDED_PROVIDER_EVENTS.CONNECT_START, {});\n\n try {\n if (this.inlineMode) {\n this.iframeManager.showInline();\n } else {\n this.iframeManager.showModal();\n }\n\n const payload: ConnectRequestPayload = {};\n\n if (options?.metadata) {\n payload.metadata = options.metadata;\n }\n\n const response = await this.iframeManager.sendMessage({\n id: createRequestId(),\n type: POST_MESSAGE_REQUEST_TYPES.CONNECT,\n payload,\n origin: window.location.origin,\n });\n\n this.connected = true;\n this.accounts = response.result.accounts;\n this.selectedAccount = response.result.accounts[0] ?? null;\n\n // Emit success event\n this.emit(EMBEDDED_PROVIDER_EVENTS.CONNECT, response.result);\n\n // Hide iframe after successful connection\n if (!this.inlineMode) {\n this.iframeManager.hide();\n }\n\n return response.result;\n } catch (error) {\n if (!this.inlineMode) {\n this.iframeManager.hide();\n }\n this.emit(EMBEDDED_PROVIDER_EVENTS.CONNECT_ERROR, { error });\n throw error;\n }\n }\n\n /**\n * Disconnect from wallet\n */\n async disconnect(): Promise<void> {\n try {\n await this.iframeManager.sendMessage({\n id: createRequestId(),\n type: POST_MESSAGE_REQUEST_TYPES.DISCONNECT,\n origin: window.location.origin,\n });\n\n this.emit(EMBEDDED_PROVIDER_EVENTS.DISCONNECT, {});\n } catch (error) {\n this.emit(EMBEDDED_PROVIDER_EVENTS.ERROR, { error });\n throw error;\n } finally {\n this.connected = false;\n this.accounts = [];\n this.selectedAccount = null;\n if (!this.inlineMode) {\n this.iframeManager.hide();\n }\n }\n }\n\n /**\n * Check if connected\n */\n isConnected(): boolean {\n return this.connected;\n }\n\n /**\n * Get accounts\n */\n getAccounts(): WalletAccount[] {\n return this.accounts;\n }\n\n getSelectedAccount(): WalletAccount | null {\n return this.selectedAccount;\n }\n\n async selectAccount(publicKey: string): Promise<WalletAccount> {\n if (!this.connected) {\n throw new Error('Wallet not connected');\n }\n\n const knownAccount = this.accounts.find(acc => acc.address === publicKey) ?? null;\n if (!knownAccount) {\n console.warn('[EmbeddedProvider] Selecting account not present in local cache');\n }\n const payload: SelectAccountPayload = { publicKey };\n\n const response = await this.iframeManager.sendMessage({\n id: createRequestId(),\n type: POST_MESSAGE_REQUEST_TYPES.SELECT_ACCOUNT,\n payload,\n origin: window.location.origin,\n });\n\n const account = response.result.account;\n\n this.refreshAccountCache(account);\n return account;\n }\n\n /**\n * Get Thru chain API\n */\n get thru(): IThruChain {\n if (!this._thruChain) {\n throw new Error('Thru chain not enabled in provider config');\n }\n return this._thruChain;\n }\n\n /**\n * Event emitter: on\n */\n on(event: string, callback: Function): void {\n if (!this.eventListeners.has(event)) {\n this.eventListeners.set(event, new Set());\n }\n this.eventListeners.get(event)!.add(callback);\n }\n\n /**\n * Event emitter: off\n */\n off(event: string, callback: Function): void {\n this.eventListeners.get(event)?.delete(callback);\n }\n\n /**\n * Emit event to all listeners\n */\n private emit(event: string, data?: any): void {\n this.eventListeners.get(event)?.forEach(callback => {\n try {\n callback(data);\n } catch (error) {\n console.error(`Error in event listener for ${event}:`, error);\n }\n });\n }\n\n /**\n * Get iframe manager (for chain implementations)\n * @internal\n */\n getIframeManager(): IframeManager {\n return this.iframeManager;\n }\n\n /**\n * Destroy provider and cleanup\n */\n destroy(): void {\n this.iframeManager.destroy();\n this.eventListeners.clear();\n this.connected = false;\n this.accounts = [];\n this.selectedAccount = null;\n }\n\n private refreshAccountCache(account: WalletAccount | null): void {\n if (!account) {\n this.selectedAccount = null;\n return;\n }\n\n const existingIdx = this.accounts.findIndex(acc => acc.address === account.address);\n if (existingIdx >= 0) {\n this.accounts[existingIdx] = account;\n } else {\n this.accounts = [...this.accounts, account];\n }\n this.selectedAccount = account;\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thru/embedded-provider",
3
- "version": "0.2.6",
3
+ "version": "0.2.8",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -11,8 +11,8 @@
11
11
  }
12
12
  },
13
13
  "dependencies": {
14
- "@thru/protocol": "0.2.6",
15
- "@thru/chain-interfaces": "0.2.6"
14
+ "@thru/protocol": "0.2.8",
15
+ "@thru/chain-interfaces": "0.2.8"
16
16
  },
17
17
  "devDependencies": {
18
18
  "@types/node": "^24.7.0"
@@ -16,8 +16,6 @@ import {
16
16
  * Only iframes from these origins can be loaded for security
17
17
  */
18
18
  const ALLOWED_IFRAME_ORIGINS = [
19
- 'https://thru-wallet.up.railway.app',
20
- 'https://wallet.thru.io',
21
19
  'https://wallet.thru.org',
22
20
  // Allow localhost for development (any port)
23
21
  'http://localhost',