@partylayer/adapter-bron 0.6.0 → 0.7.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.
- package/README.md +46 -3
- package/dist/index.d.mts +12 -3
- package/dist/index.d.ts +12 -3
- package/dist/index.js +163 -77
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +163 -78
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/auth.ts","../src/api.ts","../src/bron-adapter.ts"],"names":["error","toPartyId","toWalletId","mapUnknownErrorToPartyLayerError","UserRejectedError","toSignature","signedTx","toTransactionHash","normalizeLedgerMethodUpper","ledgerApiBodyToString"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Bron OAuth2 Authentication Client\n * \n * Handles OAuth2 flows for Bron enterprise wallet.\n * \n * References:\n * - Bron developer portal: https://developer.bron.org/\n * - Bron ecosystem: https://www.canton.network/ecosystem/bron-wallet\n */\n\nimport type { StorageAdapter } from '@partylayer/core';\n\n/**\n * OAuth2 configuration\n */\nexport interface BronAuthConfig {\n /** Authorization server URL */\n authorizationUrl: string;\n /** Token endpoint URL */\n tokenUrl: string;\n /** Client ID */\n clientId: string;\n /** Client secret (for server-side flows) */\n clientSecret?: string;\n /** Redirect URI */\n redirectUri: string;\n /** Scopes */\n scopes?: string[];\n /** Use PKCE (recommended for browser) */\n usePKCE?: boolean;\n}\n\n/**\n * OAuth2 tokens\n */\nexport interface BronTokens {\n accessToken: string;\n refreshToken?: string;\n expiresAt: number;\n tokenType: string;\n}\n\n/**\n * Bron OAuth2 client\n */\nexport class BronAuthClient {\n private config: BronAuthConfig;\n private storage?: StorageAdapter;\n private tokens: BronTokens | null = null; // In-memory by default\n\n constructor(config: BronAuthConfig, storage?: StorageAdapter) {\n this.config = config;\n this.storage = storage;\n }\n\n /**\n * Generate PKCE code verifier and challenge\n */\n private async generatePKCE(): Promise<{ verifier: string; challenge: string }> {\n const verifier = this.generateRandomString(128);\n const encoder = new TextEncoder();\n const data = encoder.encode(verifier);\n const digest = await crypto.subtle.digest('SHA-256', data);\n const challenge = btoa(String.fromCharCode(...new Uint8Array(digest)))\n .replace(/\\+/g, '-')\n .replace(/\\//g, '_')\n .replace(/=/g, '');\n\n return { verifier, challenge };\n }\n\n /**\n * Generate random string\n */\n private generateRandomString(length: number): string {\n const array = new Uint8Array(length);\n crypto.getRandomValues(array);\n return Array.from(array, (byte) => byte.toString(16).padStart(2, '0')).join('');\n }\n\n /**\n * Start authorization flow\n */\n async startAuth(): Promise<string> {\n const state = this.generateRandomString(32);\n const params = new URLSearchParams({\n response_type: 'code',\n client_id: this.config.clientId,\n redirect_uri: this.config.redirectUri,\n state,\n scope: (this.config.scopes || ['openid', 'profile']).join(' '),\n });\n\n // Add PKCE if enabled\n if (this.config.usePKCE) {\n const pkce = await this.generatePKCE();\n params.set('code_challenge', pkce.challenge);\n params.set('code_challenge_method', 'S256');\n \n // Store verifier temporarily (in sessionStorage)\n if (typeof window !== 'undefined') {\n sessionStorage.setItem('bron_pkce_verifier', pkce.verifier);\n sessionStorage.setItem('bron_auth_state', state);\n }\n } else {\n // Store state\n if (typeof window !== 'undefined') {\n sessionStorage.setItem('bron_auth_state', state);\n }\n }\n\n const authUrl = `${this.config.authorizationUrl}?${params.toString()}`;\n return authUrl;\n }\n\n /**\n * Finish authorization flow with callback URL\n */\n async finishAuth(callbackUrl: string): Promise<BronTokens> {\n const url = new URL(callbackUrl);\n const code = url.searchParams.get('code');\n const state = url.searchParams.get('state');\n const error = url.searchParams.get('error');\n\n if (error) {\n throw new Error(`OAuth error: ${error}`);\n }\n\n if (!code) {\n throw new Error('No authorization code in callback');\n }\n\n // Validate state\n if (typeof window !== 'undefined') {\n const storedState = sessionStorage.getItem('bron_auth_state');\n if (state !== storedState) {\n throw new Error('State mismatch');\n }\n }\n\n // Exchange code for tokens\n const tokenParams = new URLSearchParams({\n grant_type: 'authorization_code',\n code,\n redirect_uri: this.config.redirectUri,\n client_id: this.config.clientId,\n });\n\n // Add PKCE verifier if used\n if (this.config.usePKCE && typeof window !== 'undefined') {\n const verifier = sessionStorage.getItem('bron_pkce_verifier');\n if (verifier) {\n tokenParams.set('code_verifier', verifier);\n sessionStorage.removeItem('bron_pkce_verifier');\n }\n }\n\n // Add client secret for server-side flow\n if (this.config.clientSecret) {\n tokenParams.set('client_secret', this.config.clientSecret);\n }\n\n // Request tokens\n const response = await fetch(this.config.tokenUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n },\n body: tokenParams.toString(),\n });\n\n if (!response.ok) {\n const error = await response.text();\n throw new Error(`Token exchange failed: ${error}`);\n }\n\n const tokenData = (await response.json()) as {\n access_token: string;\n refresh_token?: string;\n expires_in: number;\n token_type: string;\n };\n\n const tokens: BronTokens = {\n accessToken: tokenData.access_token,\n refreshToken: tokenData.refresh_token,\n expiresAt: Date.now() + tokenData.expires_in * 1000,\n tokenType: tokenData.token_type || 'Bearer',\n };\n\n // Store tokens (in memory by default, or encrypted storage if configured)\n this.tokens = tokens;\n if (this.storage) {\n // Store encrypted (implementation depends on storage adapter)\n await this.storage.set('bron_tokens', JSON.stringify(tokens));\n }\n\n // Clean up session storage\n if (typeof window !== 'undefined') {\n sessionStorage.removeItem('bron_auth_state');\n }\n\n return tokens;\n }\n\n /**\n * Get current access token\n */\n async getAccessToken(): Promise<string | null> {\n // Check if token exists and is not expired\n if (this.tokens && Date.now() < this.tokens.expiresAt) {\n return this.tokens.accessToken;\n }\n\n // Try to load from storage\n if (this.storage) {\n const stored = await this.storage.get('bron_tokens');\n if (stored) {\n this.tokens = JSON.parse(stored) as BronTokens;\n if (Date.now() < this.tokens.expiresAt) {\n return this.tokens.accessToken;\n }\n }\n }\n\n return null;\n }\n\n /**\n * Logout\n */\n async logout(): Promise<void> {\n this.tokens = null;\n if (this.storage) {\n await this.storage.remove('bron_tokens');\n }\n }\n}\n","/**\n * Bron API Client\n * \n * Typed client for Bron enterprise wallet API endpoints.\n * \n * References:\n * - Bron developer portal: https://developer.bron.org/\n */\n\nimport type { PartyId } from '@partylayer/core';\nimport { toPartyId } from '@partylayer/core';\n\n/**\n * Bron API configuration\n */\nexport interface BronApiConfig {\n /** Base API URL */\n baseUrl: string;\n /** Access token getter */\n getAccessToken: () => Promise<string | null>;\n}\n\n/**\n * Session/Party mapping\n */\nexport interface BronSession {\n sessionId: string;\n partyId: PartyId;\n expiresAt?: number;\n}\n\n/**\n * Signature request\n */\nexport interface BronSignRequest {\n message?: string;\n transaction?: unknown;\n sessionId: string;\n}\n\n/**\n * Signature response\n */\nexport interface BronSignResponse {\n requestId: string;\n status: 'pending' | 'approved' | 'denied';\n signature?: string;\n transactionHash?: string;\n}\n\n/**\n * Request status\n */\nexport interface BronRequestStatus {\n requestId: string;\n status: 'pending' | 'approved' | 'denied' | 'expired';\n signature?: string;\n transactionHash?: string;\n error?: {\n code: string;\n message: string;\n };\n}\n\n/**\n * Bron API client\n */\nexport class BronApiClient {\n private config: BronApiConfig;\n\n constructor(config: BronApiConfig) {\n this.config = config;\n }\n\n /**\n * Create authenticated request headers\n */\n private async getHeaders(): Promise<HeadersInit> {\n const token = await this.config.getAccessToken();\n if (!token) {\n throw new Error('No access token available');\n }\n\n return {\n 'Authorization': `Bearer ${token}`,\n 'Content-Type': 'application/json',\n };\n }\n\n /**\n * Create session / get party mapping\n */\n async createSession(): Promise<BronSession> {\n const headers = await this.getHeaders();\n const response = await fetch(`${this.config.baseUrl}/sessions`, {\n method: 'POST',\n headers,\n });\n\n if (!response.ok) {\n const error = await response.text();\n throw new Error(`Failed to create session: ${error}`);\n }\n\n const data = (await response.json()) as {\n sessionId: string;\n partyId: string;\n expiresAt?: number;\n };\n\n return {\n sessionId: data.sessionId,\n partyId: toPartyId(data.partyId),\n expiresAt: data.expiresAt,\n };\n }\n\n /**\n * Request signature\n */\n async requestSignature(request: BronSignRequest): Promise<BronSignResponse> {\n const headers = await this.getHeaders();\n const response = await fetch(`${this.config.baseUrl}/signatures`, {\n method: 'POST',\n headers,\n body: JSON.stringify(request),\n });\n\n if (!response.ok) {\n const error = await response.text();\n throw new Error(`Failed to request signature: ${error}`);\n }\n\n const data = (await response.json()) as {\n requestId: string;\n status: string;\n signature?: string;\n transactionHash?: string;\n };\n\n return {\n requestId: data.requestId,\n status: data.status as 'pending' | 'approved' | 'denied',\n signature: data.signature,\n transactionHash: data.transactionHash,\n };\n }\n\n /**\n * Get request status\n */\n async getRequestStatus(requestId: string): Promise<BronRequestStatus> {\n const headers = await this.getHeaders();\n const response = await fetch(`${this.config.baseUrl}/signatures/${requestId}`, {\n method: 'GET',\n headers,\n });\n\n if (!response.ok) {\n const error = await response.text();\n throw new Error(`Failed to get request status: ${error}`);\n }\n\n const data = (await response.json()) as {\n requestId: string;\n status: string;\n signature?: string;\n transactionHash?: string;\n error?: {\n code: string;\n message: string;\n };\n };\n\n return {\n requestId: data.requestId,\n status: data.status as 'pending' | 'approved' | 'denied' | 'expired',\n signature: data.signature,\n transactionHash: data.transactionHash,\n error: data.error,\n };\n }\n\n /**\n * Proxy a Canton Ledger API request through the Bron remote signer.\n *\n * Bron acts as an authenticated HTTP proxy — it forwards the request\n * to the Canton Ledger API on behalf of the connected party and returns\n * the raw JSON response.\n */\n async proxyLedgerApi(request: {\n requestMethod: string;\n resource: string;\n body?: string;\n sessionId: string;\n }): Promise<{ response: string }> {\n const headers = await this.getHeaders();\n const response = await fetch(`${this.config.baseUrl}/ledger-proxy`, {\n method: 'POST',\n headers,\n body: JSON.stringify(request),\n });\n\n if (!response.ok) {\n const error = await response.text();\n throw new Error(`Ledger API proxy failed: ${error}`);\n }\n\n const data = (await response.json()) as { response: string };\n return { response: data.response };\n }\n\n /**\n * Poll request status until complete\n */\n async pollRequestStatus(\n requestId: string,\n timeoutMs: number = 60000,\n intervalMs: number = 2000\n ): Promise<BronRequestStatus> {\n const startTime = Date.now();\n\n while (Date.now() - startTime < timeoutMs) {\n const status = await this.getRequestStatus(requestId);\n\n if (status.status === 'approved' || status.status === 'denied' || status.status === 'expired') {\n return status;\n }\n\n // Wait before next poll\n await new Promise((resolve) => setTimeout(resolve, intervalMs));\n }\n\n throw new Error('Polling timeout');\n }\n}\n","/**\n * Bron Wallet Adapter\n * \n * Enterprise remote signer adapter using OAuth2 + API client.\n * \n * References:\n * - Bron developer portal: https://developer.bron.org/\n * - Bron ecosystem: https://www.canton.network/ecosystem/bron-wallet\n * - Wallet Integration Guide: https://docs.digitalasset.com/integrate/devnet/index.html\n */\n\nimport type {\n WalletAdapter,\n AdapterContext,\n AdapterDetectResult,\n AdapterConnectResult,\n SignMessageParams,\n SignTransactionParams,\n LedgerApiParams,\n LedgerApiResult,\n} from '@partylayer/core';\nimport { normalizeLedgerMethodUpper, ledgerApiBodyToString } from '@partylayer/core';\nimport {\n toWalletId,\n toSignature,\n toTransactionHash,\n UserRejectedError,\n mapUnknownErrorToPartyLayerError,\n type CapabilityKey,\n} from '@partylayer/core';\nimport { BronAuthClient, type BronAuthConfig } from './auth';\nimport { BronApiClient } from './api';\n\n// Re-export types for convenience\nexport type { BronAuthConfig } from './auth';\nexport type { BronApiConfig } from './api';\n\n/**\n * API configuration for the Bron adapter. Only `baseUrl` is needed: the adapter\n * supplies its own access-token getter, wired to its OAuth client, so a caller\n * neither provides nor overrides one. This is deliberately narrower than the\n * internal BronApiConfig (which the API client uses and does carry a token getter).\n */\nexport interface BronAdapterApiConfig {\n /** Base URL of the Bron signer API. */\n baseUrl: string;\n}\n\n/**\n * Bron adapter configuration\n */\nexport interface BronAdapterConfig {\n /** OAuth2 configuration */\n auth: BronAuthConfig;\n /** API configuration */\n api: BronAdapterApiConfig;\n}\n\n/**\n * Bron Wallet Adapter\n */\nexport class BronAdapter implements WalletAdapter {\n readonly walletId = toWalletId('bron');\n readonly name = 'Bron';\n\n private authClient: BronAuthClient;\n private apiClient: BronApiClient;\n\n constructor(config: BronAdapterConfig) {\n // Initialize auth client\n // Tokens stored in memory by default (secure)\n // Can optionally use encrypted storage if provided\n this.authClient = new BronAuthClient(config.auth);\n\n // Initialize the real API client. There is no URL- or environment-inferred\n // mock: a mock, if wanted for a test, must be constructed explicitly by the\n // test, never triggered by a substring in a URL or by NODE_ENV.\n this.apiClient = new BronApiClient({\n baseUrl: config.api.baseUrl,\n getAccessToken: async () => {\n return await this.authClient.getAccessToken();\n },\n });\n }\n\n getCapabilities(): CapabilityKey[] {\n return [\n 'connect',\n 'disconnect',\n 'restore',\n 'remoteSigner',\n 'signMessage',\n 'signTransaction',\n 'ledgerApi',\n ];\n }\n\n detectInstalled(): Promise<AdapterDetectResult> {\n // Bron is an enterprise remote signer - no \"installation\" required\n // Availability depends on OAuth2 configuration\n // Bron is an enterprise remote signer: no local install, and unusable\n // without OAuth credentials the app supplies. `needs-config` lets the picker\n // hide it rather than show a tile whose click dead-ends at an OAuth error —\n // which is the behaviour the SDK already had, now stated in the data.\n return Promise.resolve({\n installed: false,\n // BronAdapterConfig requires `auth`, so an instance cannot exist without\n // credentials; the unconfigured case is handled a level up by not\n // registering the adapter, which is why Bron is absent from the picker\n // rather than present and broken.\n availability: { kind: 'no-local-install' },\n reason: 'Bron is a remote signer service',\n });\n }\n\n async connect(\n ctx: AdapterContext,\n _opts?: {\n timeoutMs?: number;\n requiredCapabilities?: CapabilityKey[];\n }\n ): Promise<AdapterConnectResult> {\n try {\n // Check if we have an access token\n const accessToken = await this.authClient.getAccessToken();\n\n // If no token, start OAuth flow\n if (!accessToken) {\n if (typeof window === 'undefined') {\n throw new Error('OAuth flow requires browser environment');\n }\n\n const authUrl = await this.authClient.startAuth();\n \n // Open auth URL (popup or redirect)\n const popup = window.open(\n authUrl,\n 'Bron Auth',\n 'width=500,height=600'\n );\n\n if (!popup) {\n throw new Error('Failed to open auth popup');\n }\n\n // The OAuth callback (finishAuth with the returned code) must be handled\n // by the app; the adapter has no redirect handler of its own. Fail loudly\n // rather than fabricating a token — there is no dev/mock shortcut.\n throw new Error('OAuth callback not implemented in adapter - handle in app');\n }\n\n // Create session with Bron API\n const session = await this.apiClient.createSession();\n\n return {\n partyId: session.partyId,\n session: {\n walletId: this.walletId,\n // Bron's API session does not report the connected network → not\n // wallet-reported, so network-mismatch detection is limited for this\n // adapter (echoes the requested ctx.network).\n network: ctx.network,\n createdAt: Date.now(),\n expiresAt: session.expiresAt,\n capabilitiesSnapshot: ['connect', 'signMessage', 'signTransaction', 'remoteSigner'],\n metadata: {\n sessionId: session.sessionId,\n },\n },\n capabilities: ['connect', 'signMessage', 'signTransaction', 'remoteSigner'],\n };\n } catch (err) {\n throw mapUnknownErrorToPartyLayerError(err, {\n walletId: this.walletId,\n phase: 'connect',\n transport: 'remote',\n });\n }\n }\n\n async disconnect(\n _ctx: AdapterContext,\n _session: import('@partylayer/core').Session\n ): Promise<void> {\n await this.authClient.logout();\n }\n\n async restore(\n _ctx: AdapterContext,\n persisted: import('@partylayer/core').PersistedSession\n ): Promise<import('@partylayer/core').Session | null> {\n // Check if we have a session ID and access token\n const sessionId = persisted.metadata?.sessionId;\n if (typeof sessionId !== 'string') {\n return null;\n }\n\n const accessToken = await this.authClient.getAccessToken();\n if (!accessToken) {\n return null; // No token to restore\n }\n\n // Check expiration\n if (persisted.expiresAt && Date.now() >= persisted.expiresAt) {\n return null;\n }\n\n // Restore session\n return {\n ...persisted,\n walletId: this.walletId,\n };\n }\n\n async signMessage(\n _ctx: AdapterContext,\n session: import('@partylayer/core').Session,\n params: SignMessageParams\n ): Promise<import('@partylayer/core').SignedMessage> {\n try {\n const sessionId = session.metadata?.sessionId;\n if (typeof sessionId !== 'string') {\n throw new Error('No session ID');\n }\n\n // Request signature\n const signResponse = await this.apiClient.requestSignature({\n message: params.message,\n sessionId,\n });\n\n // If pending, poll for status\n if (signResponse.status === 'pending') {\n const status = await this.apiClient.pollRequestStatus(signResponse.requestId);\n \n if (status.status === 'denied') {\n throw new UserRejectedError('Signature request denied');\n }\n\n if (status.status === 'approved' && status.signature) {\n return {\n message: params.message,\n signature: toSignature(status.signature),\n partyId: session.partyId,\n };\n }\n\n throw new Error('Signature request failed');\n }\n\n if (signResponse.status === 'denied') {\n throw new UserRejectedError('Signature request denied');\n }\n\n if (!signResponse.signature) {\n throw new Error('No signature in response');\n }\n\n return {\n message: params.message,\n signature: toSignature(signResponse.signature),\n partyId: session.partyId,\n };\n } catch (err) {\n throw mapUnknownErrorToPartyLayerError(err, {\n walletId: this.walletId,\n phase: 'signMessage',\n transport: 'remote',\n });\n }\n }\n\n async signTransaction(\n _ctx: AdapterContext,\n session: import('@partylayer/core').Session,\n params: SignTransactionParams\n ): Promise<import('@partylayer/core').SignedTransaction> {\n try {\n const sessionId = session.metadata?.sessionId;\n if (typeof sessionId !== 'string') {\n throw new Error('No session ID');\n }\n\n // Request signature\n const signResponse = await this.apiClient.requestSignature({\n transaction: params.tx,\n sessionId,\n });\n\n // If pending, poll for status\n if (signResponse.status === 'pending') {\n const status = await this.apiClient.pollRequestStatus(signResponse.requestId);\n \n if (status.status === 'denied') {\n throw new UserRejectedError('Transaction signing denied');\n }\n\n if (status.status === 'approved' && status.signature) {\n const signedTx = typeof params.tx === 'object' && params.tx !== null\n ? { ...params.tx as Record<string, unknown>, signature: status.signature }\n : { tx: params.tx, signature: status.signature };\n return {\n signedTx,\n // Was `toTransactionHash('pending')` when Bron reported no hash.\n // The field is optional now, so nothing is what gets reported.\n ...(status.transactionHash\n ? { transactionHash: toTransactionHash(status.transactionHash) }\n : {}),\n partyId: session.partyId,\n };\n }\n\n throw new Error('Transaction signing failed');\n }\n\n if (signResponse.status === 'denied') {\n throw new UserRejectedError('Transaction signing denied');\n }\n\n if (!signResponse.signature) {\n throw new Error('No signature in response');\n }\n\n const signedTx = typeof params.tx === 'object' && params.tx !== null\n ? { ...params.tx as Record<string, unknown>, signature: signResponse.signature }\n : { tx: params.tx, signature: signResponse.signature };\n return {\n signedTx,\n ...(signResponse.transactionHash\n ? { transactionHash: toTransactionHash(signResponse.transactionHash) }\n : {}),\n partyId: session.partyId,\n };\n } catch (err) {\n throw mapUnknownErrorToPartyLayerError(err, {\n walletId: this.walletId,\n phase: 'signTransaction',\n transport: 'remote',\n });\n }\n }\n\n /**\n * Proxy a Canton Ledger API request through the Bron enterprise API.\n *\n * Bron acts as an authenticated HTTP proxy — it forwards the request\n * to the Canton Ledger API using the enterprise session credentials.\n */\n async ledgerApi(\n ctx: AdapterContext,\n session: import('@partylayer/core').Session,\n params: LedgerApiParams,\n ): Promise<LedgerApiResult> {\n try {\n const sessionId = session.metadata?.sessionId;\n if (typeof sessionId !== 'string') {\n throw new Error('No session ID');\n }\n\n ctx.logger.debug('Proxying ledger API request via Bron', {\n sessionId,\n requestMethod: params.requestMethod,\n resource: params.resource,\n });\n\n const result = await this.apiClient.proxyLedgerApi({\n requestMethod: normalizeLedgerMethodUpper(params.requestMethod),\n resource: params.resource,\n body: ledgerApiBodyToString(params.body),\n sessionId,\n });\n\n return { response: result.response };\n } catch (err) {\n throw mapUnknownErrorToPartyLayerError(err, {\n walletId: this.walletId,\n phase: 'ledgerApi',\n transport: 'remote',\n });\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/auth.ts","../src/api.ts","../src/authorization.ts","../src/bron-adapter.ts"],"names":["toPartyId","UserRejectedError","toWalletId","mapUnknownErrorToPartyLayerError","toSignature","signedTx","toTransactionHash","normalizeLedgerMethodUpper","ledgerApiBodyToString"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Bron OAuth2 Authentication Client\n * \n * Handles OAuth2 flows for Bron enterprise wallet.\n * \n * References:\n * - Bron developer portal: https://developer.bron.org/\n * - Bron ecosystem: https://www.canton.network/ecosystem/bron-wallet\n */\n\nimport type { StorageAdapter } from '@partylayer/core';\n\n/**\n * OAuth2 configuration\n */\nexport interface BronAuthConfig {\n /** Authorization server URL */\n authorizationUrl: string;\n /** Token endpoint URL */\n tokenUrl: string;\n /** Client ID */\n clientId: string;\n /** Client secret (for server-side flows) */\n clientSecret?: string;\n /** Redirect URI */\n redirectUri: string;\n /** Scopes */\n scopes?: string[];\n /** PKCE defaults to true and is required in browsers. */\n usePKCE?: boolean;\n}\n\n/**\n * OAuth2 tokens\n */\nexport interface BronTokens {\n accessToken: string;\n refreshToken?: string;\n expiresAt: number;\n tokenType: string;\n}\n\n/**\n * Bron OAuth2 client\n */\nexport class BronAuthClient {\n private config: BronAuthConfig;\n private storage?: StorageAdapter;\n private tokens: BronTokens | null = null; // In-memory by default\n private pending: { state: string; verifier?: string; expiresAt: number } | null = null;\n private exchange: AbortController | null = null;\n private authorization = new AbortController();\n private epoch = 0;\n private storageWrites: Promise<void> = Promise.resolve();\n\n private persist(action: () => Promise<void>): Promise<void> {\n const write = this.storageWrites.catch(() => {}).then(action);\n this.storageWrites = write;\n return write;\n }\n\n constructor(config: BronAuthConfig, storage?: StorageAdapter) {\n for (const input of [config.authorizationUrl, config.tokenUrl, config.redirectUri]) {\n const url = new URL(input);\n if (url.username || url.password || url.hash || (url.protocol !== 'https:' &&\n !(url.protocol === 'http:' && ['localhost', '127.0.0.1', '[::1]'].includes(url.hostname)))) throw new Error('OAuth requires trusted HTTPS URLs');\n }\n if (!config.clientId?.trim()) throw new Error('OAuth clientId is required');\n if (typeof window !== 'undefined' && (config.clientSecret || config.usePKCE === false)) throw new Error('Browser OAuth requires PKCE and must not contain a client secret');\n this.config = { ...config, usePKCE: config.usePKCE ?? true };\n this.storage = storage;\n }\n\n /**\n * Generate PKCE code verifier and challenge\n */\n private async generatePKCE(): Promise<{ verifier: string; challenge: string }> {\n // 32 random bytes produce a 64-character RFC 7636 verifier (43–128 chars).\n const verifier = this.generateRandomString(32);\n const encoder = new TextEncoder();\n const data = encoder.encode(verifier);\n const digest = await crypto.subtle.digest('SHA-256', data);\n const challenge = btoa(String.fromCharCode(...new Uint8Array(digest)))\n .replace(/\\+/g, '-')\n .replace(/\\//g, '_')\n .replace(/=/g, '');\n\n return { verifier, challenge };\n }\n\n /**\n * Generate random string\n */\n private generateRandomString(length: number): string {\n const array = new Uint8Array(length);\n crypto.getRandomValues(array);\n return Array.from(array, (byte) => byte.toString(16).padStart(2, '0')).join('');\n }\n\n /**\n * Start authorization flow\n */\n async startAuth(): Promise<string> {\n this.cancelAuthorization();\n this.authorization = new AbortController();\n const epoch = this.epoch;\n const state = this.generateRandomString(32);\n const params = new URLSearchParams({\n response_type: 'code',\n client_id: this.config.clientId,\n redirect_uri: this.config.redirectUri,\n state,\n scope: (this.config.scopes || ['openid', 'profile']).join(' '),\n });\n\n // Add PKCE if enabled\n if (this.config.usePKCE) {\n const pkce = await this.generatePKCE();\n params.set('code_challenge', pkce.challenge);\n params.set('code_challenge_method', 'S256');\n \n if (epoch !== this.epoch) throw new Error('OAuth authorization cancelled');\n this.pending = { state, verifier: pkce.verifier, expiresAt: Date.now() + 300_000 };\n } else {\n this.pending = { state, expiresAt: Date.now() + 300_000 };\n }\n\n const url = new URL(this.config.authorizationUrl);\n for (const [key, value] of params) url.searchParams.set(key, value);\n return url.href;\n }\n\n /**\n * Finish authorization flow with callback URL\n */\n async finishAuth(callbackUrl: string): Promise<BronTokens> {\n const url = new URL(callbackUrl);\n const redirect = new URL(this.config.redirectUri);\n const pending = this.pending;\n if (url.origin !== redirect.origin || url.pathname !== redirect.pathname || url.hash || url.username || url.password ||\n [...redirect.searchParams].some(([key, value]) => url.searchParams.getAll(key).length !== 1 || url.searchParams.get(key) !== value) ||\n !pending || pending.expiresAt <= Date.now() || url.searchParams.getAll('state').length !== 1 ||\n url.searchParams.get('state') !== pending.state) throw new Error('Invalid or expired OAuth callback state');\n // Consume before the asynchronous token request, including provider errors.\n this.pending = null;\n if (url.searchParams.has('error')) throw new Error('OAuth authorization was declined or failed');\n const code = url.searchParams.get('code');\n if (!code || url.searchParams.getAll('code').length !== 1) throw new Error('No unique authorization code in callback');\n const tokenParams = new URLSearchParams({ grant_type: 'authorization_code', code,\n redirect_uri: this.config.redirectUri, client_id: this.config.clientId });\n if (this.config.usePKCE) {\n if (!pending.verifier) throw new Error('Missing PKCE verifier');\n tokenParams.set('code_verifier', pending.verifier);\n }\n if (this.config.clientSecret) tokenParams.set('client_secret', this.config.clientSecret);\n const epoch = this.epoch;\n const controller = new AbortController(); this.exchange = controller;\n const timer = setTimeout(() => controller.abort(), 15_000);\n try {\n const response = await fetch(this.config.tokenUrl, {\n method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', Accept: 'application/json' },\n body: tokenParams.toString(), credentials: 'omit', cache: 'no-store', redirect: 'error',\n referrerPolicy: 'no-referrer', signal: controller.signal,\n });\n if (!response.ok) throw new Error('OAuth token exchange failed');\n const raw = await response.text();\n if (raw.length > 256_000) throw new Error('OAuth token response is too large');\n const data = JSON.parse(raw);\n if (!data || typeof data.access_token !== 'string' || !data.access_token || data.access_token.length > 64_000 ||\n /[\\s\\p{Cc}]/u.test(data.access_token) || typeof data.token_type !== 'string' || data.token_type.toLowerCase() !== 'bearer' ||\n typeof data.expires_in !== 'number' || !Number.isFinite(data.expires_in) || data.expires_in <= 0 || data.expires_in > 31_536_000 ||\n (data.refresh_token !== undefined && (typeof data.refresh_token !== 'string' || !data.refresh_token || /\\p{Cc}/u.test(data.refresh_token)))) {\n throw new Error('Invalid OAuth token response');\n }\n if (controller.signal.aborted || epoch !== this.epoch) throw new Error('OAuth authorization cancelled');\n const tokens: BronTokens = { accessToken: data.access_token, expiresAt: Date.now() + data.expires_in * 1000,\n tokenType: 'Bearer', ...(data.refresh_token ? { refreshToken: data.refresh_token } : {}) };\n this.tokens = tokens;\n // A custom storage adapter is app-owned; it is not encrypted by this class.\n if (this.storage) await this.persist(async () => {\n if (epoch === this.epoch) await this.storage!.set('bron_tokens', JSON.stringify(tokens));\n });\n if (epoch !== this.epoch) throw new Error('OAuth authorization cancelled');\n return tokens;\n } finally {\n clearTimeout(timer); if (this.exchange === controller) this.exchange = null;\n }\n }\n\n /** Clear authorization state and abort only the in-flight token exchange. */\n cancelAuthorization(): void {\n this.authorization.abort();\n this.epoch++; this.pending = null; this.exchange?.abort(); this.exchange = null;\n }\n\n getAuthorizationSignal(): AbortSignal { return this.authorization.signal; }\n\n /**\n * Get current access token\n */\n async getAccessToken(): Promise<string | null> {\n const epoch = this.epoch;\n // Check if token exists and is not expired\n if (this.tokens && Date.now() < this.tokens.expiresAt) {\n return this.tokens.accessToken;\n }\n\n // Try to load from storage\n if (this.storage) {\n const stored = await this.storage.get('bron_tokens');\n if (epoch !== this.epoch) return null;\n if (stored) {\n try {\n const tokens = JSON.parse(stored) as BronTokens;\n if (typeof tokens.accessToken === 'string' && tokens.accessToken && !/[\\s\\p{Cc}]/u.test(tokens.accessToken) &&\n tokens.tokenType === 'Bearer' && Number.isFinite(tokens.expiresAt) && Date.now() < tokens.expiresAt) {\n this.tokens = tokens; return tokens.accessToken;\n }\n } catch { /* Invalid persisted data never establishes an authenticated session. */ }\n }\n }\n\n return null;\n }\n\n /**\n * Logout\n */\n async logout(): Promise<void> {\n this.cancelAuthorization();\n this.tokens = null;\n if (this.storage) {\n await this.persist(() => this.storage!.remove('bron_tokens'));\n }\n }\n}\n","/**\n * Bron API Client\n * \n * Typed client for Bron enterprise wallet API endpoints.\n * \n * References:\n * - Bron developer portal: https://developer.bron.org/\n */\n\nimport type { PartyId } from '@partylayer/core';\nimport { toPartyId } from '@partylayer/core';\n\n/**\n * Bron API configuration\n */\nexport interface BronApiConfig {\n /** Base API URL */\n baseUrl: string;\n /** Access token getter */\n getAccessToken: () => Promise<string | null>;\n}\n\n/**\n * Session/Party mapping\n */\nexport interface BronSession {\n sessionId: string;\n partyId: PartyId;\n expiresAt?: number;\n}\n\n/**\n * Signature request\n */\nexport interface BronSignRequest {\n message?: string;\n transaction?: unknown;\n sessionId: string;\n}\n\n/**\n * Signature response\n */\nexport interface BronSignResponse {\n requestId: string;\n status: 'pending' | 'approved' | 'denied';\n signature?: string;\n transactionHash?: string;\n}\n\n/**\n * Request status\n */\nexport interface BronRequestStatus {\n requestId: string;\n status: 'pending' | 'approved' | 'denied' | 'expired';\n signature?: string;\n transactionHash?: string;\n error?: {\n code: string;\n message: string;\n };\n}\n\n/**\n * Bron API client\n */\nexport class BronApiClient {\n private config: BronApiConfig;\n\n constructor(config: BronApiConfig) {\n this.config = config;\n }\n\n /**\n * Create authenticated request headers\n */\n private async getHeaders(): Promise<HeadersInit> {\n const token = await this.config.getAccessToken();\n if (!token) {\n throw new Error('No access token available');\n }\n\n return {\n 'Authorization': `Bearer ${token}`,\n 'Content-Type': 'application/json',\n };\n }\n\n /**\n * Create session / get party mapping\n */\n async createSession(): Promise<BronSession> {\n const headers = await this.getHeaders();\n const response = await fetch(`${this.config.baseUrl}/sessions`, {\n method: 'POST',\n headers,\n });\n\n if (!response.ok) {\n const error = await response.text();\n throw new Error(`Failed to create session: ${error}`);\n }\n\n const data = (await response.json()) as {\n sessionId: string;\n partyId: string;\n expiresAt?: number;\n };\n\n return {\n sessionId: data.sessionId,\n partyId: toPartyId(data.partyId),\n expiresAt: data.expiresAt,\n };\n }\n\n /**\n * Request signature\n */\n async requestSignature(request: BronSignRequest): Promise<BronSignResponse> {\n const headers = await this.getHeaders();\n const response = await fetch(`${this.config.baseUrl}/signatures`, {\n method: 'POST',\n headers,\n body: JSON.stringify(request),\n });\n\n if (!response.ok) {\n const error = await response.text();\n throw new Error(`Failed to request signature: ${error}`);\n }\n\n const data = (await response.json()) as {\n requestId: string;\n status: string;\n signature?: string;\n transactionHash?: string;\n };\n\n return {\n requestId: data.requestId,\n status: data.status as 'pending' | 'approved' | 'denied',\n signature: data.signature,\n transactionHash: data.transactionHash,\n };\n }\n\n /**\n * Get request status\n */\n async getRequestStatus(requestId: string): Promise<BronRequestStatus> {\n const headers = await this.getHeaders();\n const response = await fetch(`${this.config.baseUrl}/signatures/${requestId}`, {\n method: 'GET',\n headers,\n });\n\n if (!response.ok) {\n const error = await response.text();\n throw new Error(`Failed to get request status: ${error}`);\n }\n\n const data = (await response.json()) as {\n requestId: string;\n status: string;\n signature?: string;\n transactionHash?: string;\n error?: {\n code: string;\n message: string;\n };\n };\n\n return {\n requestId: data.requestId,\n status: data.status as 'pending' | 'approved' | 'denied' | 'expired',\n signature: data.signature,\n transactionHash: data.transactionHash,\n error: data.error,\n };\n }\n\n /**\n * Proxy a Canton Ledger API request through the Bron remote signer.\n *\n * Bron acts as an authenticated HTTP proxy — it forwards the request\n * to the Canton Ledger API on behalf of the connected party and returns\n * the raw JSON response.\n */\n async proxyLedgerApi(request: {\n requestMethod: string;\n resource: string;\n body?: string;\n sessionId: string;\n }): Promise<{ response: string }> {\n const headers = await this.getHeaders();\n const response = await fetch(`${this.config.baseUrl}/ledger-proxy`, {\n method: 'POST',\n headers,\n body: JSON.stringify(request),\n });\n\n if (!response.ok) {\n const error = await response.text();\n throw new Error(`Ledger API proxy failed: ${error}`);\n }\n\n const data = (await response.json()) as { response: string };\n return { response: data.response };\n }\n\n /**\n * Poll request status until complete\n */\n async pollRequestStatus(\n requestId: string,\n timeoutMs: number = 60000,\n intervalMs: number = 2000\n ): Promise<BronRequestStatus> {\n const startTime = Date.now();\n\n while (Date.now() - startTime < timeoutMs) {\n const status = await this.getRequestStatus(requestId);\n\n if (status.status === 'approved' || status.status === 'denied' || status.status === 'expired') {\n return status;\n }\n\n // Wait before next poll\n await new Promise((resolve) => setTimeout(resolve, intervalMs));\n }\n\n throw new Error('Polling timeout');\n }\n}\n","import { UserRejectedError } from '@partylayer/core';\nimport type { BronAuthClient } from './auth';\n\nconst CALLBACK = 'partylayer:bron:authorization-callback';\n\n/**\n * Call from the application's registered redirect page. The popup relays only\n * to its own origin; the opener verifies the source, path, state and PKCE.\n * This helper does not register a Bron OAuth client or define vendor endpoints.\n */\nexport function completeBronAuthorization(redirectUri: string): void {\n if (typeof window === 'undefined' || !window.opener) throw new Error('Open this OAuth callback from the connecting application');\n const expected = new URL(redirectUri);\n if (window.location.origin !== expected.origin || window.location.pathname !== expected.pathname) throw new Error('Unexpected OAuth redirect page');\n const callbackUrl = window.location.href;\n window.opener.postMessage({ type: CALLBACK, callbackUrl }, expected.origin);\n // Clear authorization codes from this page's address/history after relaying.\n window.history.replaceState(null, '', expected.pathname);\n window.close();\n}\n\n/** Internal bounded popup bridge for the legacy, explicitly configured OAuth integration. */\nexport async function authorizeBronPopup(auth: BronAuthClient, redirectUri: string, timeoutMs: number): Promise<void> {\n if (typeof window === 'undefined') throw new Error('OAuth flow requires a browser environment');\n if (!Number.isInteger(timeoutMs) || timeoutMs < 1 || timeoutMs > 300_000) throw new Error('Invalid OAuth timeout');\n const expected = new URL(redirectUri);\n if (expected.origin !== window.location.origin) throw new Error('Register a same-origin OAuth callback page');\n const url = await auth.startAuth();\n const popup = window.open(url, 'partylayer-bron-authorization', 'width=500,height=650');\n if (!popup) { auth.cancelAuthorization(); throw new Error('Allow the wallet authorization popup and try again'); }\n return new Promise<void>((resolve, reject) => {\n const signal = auth.getAuthorizationSignal();\n let callbackReceived = false;\n let finished = false;\n const finish = (error?: unknown) => {\n if (finished) return;\n finished = true;\n clearTimeout(timer); clearInterval(closed);\n window.removeEventListener('message', receive);\n signal.removeEventListener('abort', cancel);\n if (error) auth.cancelAuthorization();\n try { popup.close(); } catch { /* Window closure does not determine the auth result. */ }\n if (error) reject(error); else resolve();\n };\n const receive = (event: MessageEvent) => {\n if (finished || callbackReceived || event.source !== popup || event.origin !== expected.origin ||\n !event.data || event.data.type !== CALLBACK || typeof event.data.callbackUrl !== 'string') return;\n callbackReceived = true;\n void auth.finishAuth(event.data.callbackUrl).then(() => finish(), error => finish(error));\n };\n const cancel = () => finish(new Error('Wallet authorization cancelled'));\n const timer = setTimeout(() => finish(new Error('Wallet authorization timed out')), timeoutMs);\n const closed = setInterval(() => {\n if (!callbackReceived && popup.closed) finish(new UserRejectedError('Wallet authorization was closed'));\n }, 250);\n window.addEventListener('message', receive);\n signal.addEventListener('abort', cancel, { once: true });\n if (signal.aborted) cancel();\n });\n}\n","/**\n * Bron Wallet Adapter\n * \n * Enterprise remote signer adapter using OAuth2 + API client.\n * \n * References:\n * - Bron developer portal: https://developer.bron.org/\n * - Bron ecosystem: https://www.canton.network/ecosystem/bron-wallet\n * - Wallet Integration Guide: https://docs.digitalasset.com/integrate/devnet/index.html\n */\n\nimport type {\n WalletAdapter,\n AdapterContext,\n AdapterDetectResult,\n AdapterConnectResult,\n SignMessageParams,\n SignTransactionParams,\n LedgerApiParams,\n LedgerApiResult,\n} from '@partylayer/core';\nimport { normalizeLedgerMethodUpper, ledgerApiBodyToString } from '@partylayer/core';\nimport {\n toWalletId,\n toSignature,\n toTransactionHash,\n UserRejectedError,\n mapUnknownErrorToPartyLayerError,\n type CapabilityKey,\n} from '@partylayer/core';\nimport { BronAuthClient, type BronAuthConfig } from './auth';\nimport { BronApiClient } from './api';\nimport { authorizeBronPopup } from './authorization';\n\n// Re-export types for convenience\nexport type { BronAuthConfig } from './auth';\nexport type { BronApiConfig } from './api';\n\n/**\n * API configuration for the Bron adapter. Only `baseUrl` is needed: the adapter\n * supplies its own access-token getter, wired to its OAuth client, so a caller\n * neither provides nor overrides one. This is deliberately narrower than the\n * internal BronApiConfig (which the API client uses and does carry a token getter).\n */\nexport interface BronAdapterApiConfig {\n /** Base URL of the Bron signer API. */\n baseUrl: string;\n}\n\n/**\n * Bron adapter configuration\n */\nexport interface BronAdapterConfig {\n /** OAuth2 configuration */\n auth: BronAuthConfig;\n /** API configuration */\n api: BronAdapterApiConfig;\n}\n\n/**\n * Bron Wallet Adapter\n */\nexport class BronAdapter implements WalletAdapter {\n readonly walletId = toWalletId('bron');\n readonly name = 'Bron';\n\n private authClient: BronAuthClient;\n private apiClient: BronApiClient;\n private redirectUri: string;\n private connecting = false;\n\n constructor(config: BronAdapterConfig) {\n // Initialize auth client\n // Tokens stored in memory by default (secure)\n // Can optionally use encrypted storage if provided\n this.authClient = new BronAuthClient(config.auth);\n this.redirectUri = config.auth.redirectUri;\n\n // Initialize the real API client. There is no URL- or environment-inferred\n // mock: a mock, if wanted for a test, must be constructed explicitly by the\n // test, never triggered by a substring in a URL or by NODE_ENV.\n this.apiClient = new BronApiClient({\n baseUrl: config.api.baseUrl,\n getAccessToken: async () => {\n return await this.authClient.getAccessToken();\n },\n });\n }\n\n getCapabilities(): CapabilityKey[] {\n return [\n 'connect',\n 'disconnect',\n 'restore',\n 'remoteSigner',\n 'signMessage',\n 'signTransaction',\n 'ledgerApi',\n ];\n }\n\n detectInstalled(): Promise<AdapterDetectResult> {\n // Bron is an enterprise remote signer - no \"installation\" required\n // Availability depends on OAuth2 configuration\n // Bron is an enterprise remote signer: no local install, and unusable\n // without OAuth credentials the app supplies. `needs-config` lets the picker\n // hide it rather than show a tile whose click dead-ends at an OAuth error —\n // which is the behaviour the SDK already had, now stated in the data.\n return Promise.resolve({\n installed: false,\n // BronAdapterConfig requires `auth`, so an instance cannot exist without\n // credentials; the unconfigured case is handled a level up by not\n // registering the adapter, which is why Bron is absent from the picker\n // rather than present and broken.\n availability: { kind: 'no-local-install' },\n reason: 'Bron is a remote signer service',\n });\n }\n\n async connect(\n ctx: AdapterContext,\n opts?: {\n timeoutMs?: number;\n requiredCapabilities?: CapabilityKey[];\n }\n ): Promise<AdapterConnectResult> {\n if (this.connecting) throw new Error('A Bron connection is already pending');\n this.connecting = true;\n try {\n // Check if we have an access token\n const accessToken = await this.authClient.getAccessToken();\n\n // If no token, start OAuth flow\n if (!accessToken) {\n await authorizeBronPopup(this.authClient, this.redirectUri, opts?.timeoutMs ?? 120_000);\n }\n\n // Create session with Bron API\n const session = await this.apiClient.createSession();\n\n return {\n partyId: session.partyId,\n session: {\n walletId: this.walletId,\n // Bron's API session does not report the connected network → not\n // wallet-reported, so network-mismatch detection is limited for this\n // adapter (echoes the requested ctx.network).\n network: ctx.network,\n createdAt: Date.now(),\n expiresAt: session.expiresAt,\n capabilitiesSnapshot: ['connect', 'signMessage', 'signTransaction', 'remoteSigner'],\n metadata: {\n sessionId: session.sessionId,\n },\n },\n capabilities: ['connect', 'signMessage', 'signTransaction', 'remoteSigner'],\n };\n } catch (err) {\n throw mapUnknownErrorToPartyLayerError(err, {\n walletId: this.walletId,\n phase: 'connect',\n transport: 'remote',\n });\n } finally {\n this.connecting = false;\n }\n }\n\n async disconnect(\n _ctx: AdapterContext,\n _session: import('@partylayer/core').Session\n ): Promise<void> {\n await this.authClient.logout();\n }\n\n async restore(\n _ctx: AdapterContext,\n persisted: import('@partylayer/core').PersistedSession\n ): Promise<import('@partylayer/core').Session | null> {\n // Check if we have a session ID and access token\n const sessionId = persisted.metadata?.sessionId;\n if (typeof sessionId !== 'string') {\n return null;\n }\n\n const accessToken = await this.authClient.getAccessToken();\n if (!accessToken) {\n return null; // No token to restore\n }\n\n // Check expiration\n if (persisted.expiresAt && Date.now() >= persisted.expiresAt) {\n return null;\n }\n\n // Restore session\n return {\n ...persisted,\n walletId: this.walletId,\n };\n }\n\n async signMessage(\n _ctx: AdapterContext,\n session: import('@partylayer/core').Session,\n params: SignMessageParams\n ): Promise<import('@partylayer/core').SignedMessage> {\n try {\n const sessionId = session.metadata?.sessionId;\n if (typeof sessionId !== 'string') {\n throw new Error('No session ID');\n }\n\n // Request signature\n const signResponse = await this.apiClient.requestSignature({\n message: params.message,\n sessionId,\n });\n\n // If pending, poll for status\n if (signResponse.status === 'pending') {\n const status = await this.apiClient.pollRequestStatus(signResponse.requestId);\n \n if (status.status === 'denied') {\n throw new UserRejectedError('Signature request denied');\n }\n\n if (status.status === 'approved' && status.signature) {\n return {\n message: params.message,\n signature: toSignature(status.signature),\n partyId: session.partyId,\n };\n }\n\n throw new Error('Signature request failed');\n }\n\n if (signResponse.status === 'denied') {\n throw new UserRejectedError('Signature request denied');\n }\n\n if (!signResponse.signature) {\n throw new Error('No signature in response');\n }\n\n return {\n message: params.message,\n signature: toSignature(signResponse.signature),\n partyId: session.partyId,\n };\n } catch (err) {\n throw mapUnknownErrorToPartyLayerError(err, {\n walletId: this.walletId,\n phase: 'signMessage',\n transport: 'remote',\n });\n }\n }\n\n async signTransaction(\n _ctx: AdapterContext,\n session: import('@partylayer/core').Session,\n params: SignTransactionParams\n ): Promise<import('@partylayer/core').SignedTransaction> {\n try {\n const sessionId = session.metadata?.sessionId;\n if (typeof sessionId !== 'string') {\n throw new Error('No session ID');\n }\n\n // Request signature\n const signResponse = await this.apiClient.requestSignature({\n transaction: params.tx,\n sessionId,\n });\n\n // If pending, poll for status\n if (signResponse.status === 'pending') {\n const status = await this.apiClient.pollRequestStatus(signResponse.requestId);\n \n if (status.status === 'denied') {\n throw new UserRejectedError('Transaction signing denied');\n }\n\n if (status.status === 'approved' && status.signature) {\n const signedTx = typeof params.tx === 'object' && params.tx !== null\n ? { ...params.tx as Record<string, unknown>, signature: status.signature }\n : { tx: params.tx, signature: status.signature };\n return {\n signedTx,\n // Was `toTransactionHash('pending')` when Bron reported no hash.\n // The field is optional now, so nothing is what gets reported.\n ...(status.transactionHash\n ? { transactionHash: toTransactionHash(status.transactionHash) }\n : {}),\n partyId: session.partyId,\n };\n }\n\n throw new Error('Transaction signing failed');\n }\n\n if (signResponse.status === 'denied') {\n throw new UserRejectedError('Transaction signing denied');\n }\n\n if (!signResponse.signature) {\n throw new Error('No signature in response');\n }\n\n const signedTx = typeof params.tx === 'object' && params.tx !== null\n ? { ...params.tx as Record<string, unknown>, signature: signResponse.signature }\n : { tx: params.tx, signature: signResponse.signature };\n return {\n signedTx,\n ...(signResponse.transactionHash\n ? { transactionHash: toTransactionHash(signResponse.transactionHash) }\n : {}),\n partyId: session.partyId,\n };\n } catch (err) {\n throw mapUnknownErrorToPartyLayerError(err, {\n walletId: this.walletId,\n phase: 'signTransaction',\n transport: 'remote',\n });\n }\n }\n\n /**\n * Proxy a Canton Ledger API request through the Bron enterprise API.\n *\n * Bron acts as an authenticated HTTP proxy — it forwards the request\n * to the Canton Ledger API using the enterprise session credentials.\n */\n async ledgerApi(\n ctx: AdapterContext,\n session: import('@partylayer/core').Session,\n params: LedgerApiParams,\n ): Promise<LedgerApiResult> {\n try {\n const sessionId = session.metadata?.sessionId;\n if (typeof sessionId !== 'string') {\n throw new Error('No session ID');\n }\n\n ctx.logger.debug('Proxying ledger API request via Bron', {\n sessionId,\n requestMethod: params.requestMethod,\n resource: params.resource,\n });\n\n const result = await this.apiClient.proxyLedgerApi({\n requestMethod: normalizeLedgerMethodUpper(params.requestMethod),\n resource: params.resource,\n body: ledgerApiBodyToString(params.body),\n sessionId,\n });\n\n return { response: result.response };\n } catch (err) {\n throw mapUnknownErrorToPartyLayerError(err, {\n walletId: this.walletId,\n phase: 'ledgerApi',\n transport: 'remote',\n });\n }\n }\n}\n"]}
|
package/dist/index.mjs
CHANGED
|
@@ -8,15 +8,32 @@ var BronAuthClient = class {
|
|
|
8
8
|
storage;
|
|
9
9
|
tokens = null;
|
|
10
10
|
// In-memory by default
|
|
11
|
+
pending = null;
|
|
12
|
+
exchange = null;
|
|
13
|
+
authorization = new AbortController();
|
|
14
|
+
epoch = 0;
|
|
15
|
+
storageWrites = Promise.resolve();
|
|
16
|
+
persist(action) {
|
|
17
|
+
const write = this.storageWrites.catch(() => {
|
|
18
|
+
}).then(action);
|
|
19
|
+
this.storageWrites = write;
|
|
20
|
+
return write;
|
|
21
|
+
}
|
|
11
22
|
constructor(config, storage) {
|
|
12
|
-
|
|
23
|
+
for (const input of [config.authorizationUrl, config.tokenUrl, config.redirectUri]) {
|
|
24
|
+
const url = new URL(input);
|
|
25
|
+
if (url.username || url.password || url.hash || url.protocol !== "https:" && !(url.protocol === "http:" && ["localhost", "127.0.0.1", "[::1]"].includes(url.hostname))) throw new Error("OAuth requires trusted HTTPS URLs");
|
|
26
|
+
}
|
|
27
|
+
if (!config.clientId?.trim()) throw new Error("OAuth clientId is required");
|
|
28
|
+
if (typeof window !== "undefined" && (config.clientSecret || config.usePKCE === false)) throw new Error("Browser OAuth requires PKCE and must not contain a client secret");
|
|
29
|
+
this.config = { ...config, usePKCE: config.usePKCE ?? true };
|
|
13
30
|
this.storage = storage;
|
|
14
31
|
}
|
|
15
32
|
/**
|
|
16
33
|
* Generate PKCE code verifier and challenge
|
|
17
34
|
*/
|
|
18
35
|
async generatePKCE() {
|
|
19
|
-
const verifier = this.generateRandomString(
|
|
36
|
+
const verifier = this.generateRandomString(32);
|
|
20
37
|
const encoder = new TextEncoder();
|
|
21
38
|
const data = encoder.encode(verifier);
|
|
22
39
|
const digest = await crypto.subtle.digest("SHA-256", data);
|
|
@@ -35,6 +52,9 @@ var BronAuthClient = class {
|
|
|
35
52
|
* Start authorization flow
|
|
36
53
|
*/
|
|
37
54
|
async startAuth() {
|
|
55
|
+
this.cancelAuthorization();
|
|
56
|
+
this.authorization = new AbortController();
|
|
57
|
+
const epoch = this.epoch;
|
|
38
58
|
const state = this.generateRandomString(32);
|
|
39
59
|
const params = new URLSearchParams({
|
|
40
60
|
response_type: "code",
|
|
@@ -47,94 +67,108 @@ var BronAuthClient = class {
|
|
|
47
67
|
const pkce = await this.generatePKCE();
|
|
48
68
|
params.set("code_challenge", pkce.challenge);
|
|
49
69
|
params.set("code_challenge_method", "S256");
|
|
50
|
-
if (
|
|
51
|
-
|
|
52
|
-
sessionStorage.setItem("bron_auth_state", state);
|
|
53
|
-
}
|
|
70
|
+
if (epoch !== this.epoch) throw new Error("OAuth authorization cancelled");
|
|
71
|
+
this.pending = { state, verifier: pkce.verifier, expiresAt: Date.now() + 3e5 };
|
|
54
72
|
} else {
|
|
55
|
-
|
|
56
|
-
sessionStorage.setItem("bron_auth_state", state);
|
|
57
|
-
}
|
|
73
|
+
this.pending = { state, expiresAt: Date.now() + 3e5 };
|
|
58
74
|
}
|
|
59
|
-
const
|
|
60
|
-
|
|
75
|
+
const url = new URL(this.config.authorizationUrl);
|
|
76
|
+
for (const [key, value] of params) url.searchParams.set(key, value);
|
|
77
|
+
return url.href;
|
|
61
78
|
}
|
|
62
79
|
/**
|
|
63
80
|
* Finish authorization flow with callback URL
|
|
64
81
|
*/
|
|
65
82
|
async finishAuth(callbackUrl) {
|
|
66
83
|
const url = new URL(callbackUrl);
|
|
84
|
+
const redirect = new URL(this.config.redirectUri);
|
|
85
|
+
const pending = this.pending;
|
|
86
|
+
if (url.origin !== redirect.origin || url.pathname !== redirect.pathname || url.hash || url.username || url.password || [...redirect.searchParams].some(([key, value]) => url.searchParams.getAll(key).length !== 1 || url.searchParams.get(key) !== value) || !pending || pending.expiresAt <= Date.now() || url.searchParams.getAll("state").length !== 1 || url.searchParams.get("state") !== pending.state) throw new Error("Invalid or expired OAuth callback state");
|
|
87
|
+
this.pending = null;
|
|
88
|
+
if (url.searchParams.has("error")) throw new Error("OAuth authorization was declined or failed");
|
|
67
89
|
const code = url.searchParams.get("code");
|
|
68
|
-
|
|
69
|
-
const error = url.searchParams.get("error");
|
|
70
|
-
if (error) {
|
|
71
|
-
throw new Error(`OAuth error: ${error}`);
|
|
72
|
-
}
|
|
73
|
-
if (!code) {
|
|
74
|
-
throw new Error("No authorization code in callback");
|
|
75
|
-
}
|
|
76
|
-
if (typeof window !== "undefined") {
|
|
77
|
-
const storedState = sessionStorage.getItem("bron_auth_state");
|
|
78
|
-
if (state !== storedState) {
|
|
79
|
-
throw new Error("State mismatch");
|
|
80
|
-
}
|
|
81
|
-
}
|
|
90
|
+
if (!code || url.searchParams.getAll("code").length !== 1) throw new Error("No unique authorization code in callback");
|
|
82
91
|
const tokenParams = new URLSearchParams({
|
|
83
92
|
grant_type: "authorization_code",
|
|
84
93
|
code,
|
|
85
94
|
redirect_uri: this.config.redirectUri,
|
|
86
95
|
client_id: this.config.clientId
|
|
87
96
|
});
|
|
88
|
-
if (this.config.usePKCE
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
tokenParams.set("code_verifier", verifier);
|
|
92
|
-
sessionStorage.removeItem("bron_pkce_verifier");
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
if (this.config.clientSecret) {
|
|
96
|
-
tokenParams.set("client_secret", this.config.clientSecret);
|
|
97
|
-
}
|
|
98
|
-
const response = await fetch(this.config.tokenUrl, {
|
|
99
|
-
method: "POST",
|
|
100
|
-
headers: {
|
|
101
|
-
"Content-Type": "application/x-www-form-urlencoded"
|
|
102
|
-
},
|
|
103
|
-
body: tokenParams.toString()
|
|
104
|
-
});
|
|
105
|
-
if (!response.ok) {
|
|
106
|
-
const error2 = await response.text();
|
|
107
|
-
throw new Error(`Token exchange failed: ${error2}`);
|
|
108
|
-
}
|
|
109
|
-
const tokenData = await response.json();
|
|
110
|
-
const tokens = {
|
|
111
|
-
accessToken: tokenData.access_token,
|
|
112
|
-
refreshToken: tokenData.refresh_token,
|
|
113
|
-
expiresAt: Date.now() + tokenData.expires_in * 1e3,
|
|
114
|
-
tokenType: tokenData.token_type || "Bearer"
|
|
115
|
-
};
|
|
116
|
-
this.tokens = tokens;
|
|
117
|
-
if (this.storage) {
|
|
118
|
-
await this.storage.set("bron_tokens", JSON.stringify(tokens));
|
|
97
|
+
if (this.config.usePKCE) {
|
|
98
|
+
if (!pending.verifier) throw new Error("Missing PKCE verifier");
|
|
99
|
+
tokenParams.set("code_verifier", pending.verifier);
|
|
119
100
|
}
|
|
120
|
-
if (
|
|
121
|
-
|
|
101
|
+
if (this.config.clientSecret) tokenParams.set("client_secret", this.config.clientSecret);
|
|
102
|
+
const epoch = this.epoch;
|
|
103
|
+
const controller = new AbortController();
|
|
104
|
+
this.exchange = controller;
|
|
105
|
+
const timer = setTimeout(() => controller.abort(), 15e3);
|
|
106
|
+
try {
|
|
107
|
+
const response = await fetch(this.config.tokenUrl, {
|
|
108
|
+
method: "POST",
|
|
109
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded", Accept: "application/json" },
|
|
110
|
+
body: tokenParams.toString(),
|
|
111
|
+
credentials: "omit",
|
|
112
|
+
cache: "no-store",
|
|
113
|
+
redirect: "error",
|
|
114
|
+
referrerPolicy: "no-referrer",
|
|
115
|
+
signal: controller.signal
|
|
116
|
+
});
|
|
117
|
+
if (!response.ok) throw new Error("OAuth token exchange failed");
|
|
118
|
+
const raw = await response.text();
|
|
119
|
+
if (raw.length > 256e3) throw new Error("OAuth token response is too large");
|
|
120
|
+
const data = JSON.parse(raw);
|
|
121
|
+
if (!data || typeof data.access_token !== "string" || !data.access_token || data.access_token.length > 64e3 || /[\s\p{Cc}]/u.test(data.access_token) || typeof data.token_type !== "string" || data.token_type.toLowerCase() !== "bearer" || typeof data.expires_in !== "number" || !Number.isFinite(data.expires_in) || data.expires_in <= 0 || data.expires_in > 31536e3 || data.refresh_token !== void 0 && (typeof data.refresh_token !== "string" || !data.refresh_token || /\p{Cc}/u.test(data.refresh_token))) {
|
|
122
|
+
throw new Error("Invalid OAuth token response");
|
|
123
|
+
}
|
|
124
|
+
if (controller.signal.aborted || epoch !== this.epoch) throw new Error("OAuth authorization cancelled");
|
|
125
|
+
const tokens = {
|
|
126
|
+
accessToken: data.access_token,
|
|
127
|
+
expiresAt: Date.now() + data.expires_in * 1e3,
|
|
128
|
+
tokenType: "Bearer",
|
|
129
|
+
...data.refresh_token ? { refreshToken: data.refresh_token } : {}
|
|
130
|
+
};
|
|
131
|
+
this.tokens = tokens;
|
|
132
|
+
if (this.storage) await this.persist(async () => {
|
|
133
|
+
if (epoch === this.epoch) await this.storage.set("bron_tokens", JSON.stringify(tokens));
|
|
134
|
+
});
|
|
135
|
+
if (epoch !== this.epoch) throw new Error("OAuth authorization cancelled");
|
|
136
|
+
return tokens;
|
|
137
|
+
} finally {
|
|
138
|
+
clearTimeout(timer);
|
|
139
|
+
if (this.exchange === controller) this.exchange = null;
|
|
122
140
|
}
|
|
123
|
-
|
|
141
|
+
}
|
|
142
|
+
/** Clear authorization state and abort only the in-flight token exchange. */
|
|
143
|
+
cancelAuthorization() {
|
|
144
|
+
this.authorization.abort();
|
|
145
|
+
this.epoch++;
|
|
146
|
+
this.pending = null;
|
|
147
|
+
this.exchange?.abort();
|
|
148
|
+
this.exchange = null;
|
|
149
|
+
}
|
|
150
|
+
getAuthorizationSignal() {
|
|
151
|
+
return this.authorization.signal;
|
|
124
152
|
}
|
|
125
153
|
/**
|
|
126
154
|
* Get current access token
|
|
127
155
|
*/
|
|
128
156
|
async getAccessToken() {
|
|
157
|
+
const epoch = this.epoch;
|
|
129
158
|
if (this.tokens && Date.now() < this.tokens.expiresAt) {
|
|
130
159
|
return this.tokens.accessToken;
|
|
131
160
|
}
|
|
132
161
|
if (this.storage) {
|
|
133
162
|
const stored = await this.storage.get("bron_tokens");
|
|
163
|
+
if (epoch !== this.epoch) return null;
|
|
134
164
|
if (stored) {
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
165
|
+
try {
|
|
166
|
+
const tokens = JSON.parse(stored);
|
|
167
|
+
if (typeof tokens.accessToken === "string" && tokens.accessToken && !/[\s\p{Cc}]/u.test(tokens.accessToken) && tokens.tokenType === "Bearer" && Number.isFinite(tokens.expiresAt) && Date.now() < tokens.expiresAt) {
|
|
168
|
+
this.tokens = tokens;
|
|
169
|
+
return tokens.accessToken;
|
|
170
|
+
}
|
|
171
|
+
} catch {
|
|
138
172
|
}
|
|
139
173
|
}
|
|
140
174
|
}
|
|
@@ -144,9 +178,10 @@ var BronAuthClient = class {
|
|
|
144
178
|
* Logout
|
|
145
179
|
*/
|
|
146
180
|
async logout() {
|
|
181
|
+
this.cancelAuthorization();
|
|
147
182
|
this.tokens = null;
|
|
148
183
|
if (this.storage) {
|
|
149
|
-
await this.storage.remove("bron_tokens");
|
|
184
|
+
await this.persist(() => this.storage.remove("bron_tokens"));
|
|
150
185
|
}
|
|
151
186
|
}
|
|
152
187
|
};
|
|
@@ -268,6 +303,61 @@ var BronApiClient = class {
|
|
|
268
303
|
throw new Error("Polling timeout");
|
|
269
304
|
}
|
|
270
305
|
};
|
|
306
|
+
var CALLBACK = "partylayer:bron:authorization-callback";
|
|
307
|
+
function completeBronAuthorization(redirectUri) {
|
|
308
|
+
if (typeof window === "undefined" || !window.opener) throw new Error("Open this OAuth callback from the connecting application");
|
|
309
|
+
const expected = new URL(redirectUri);
|
|
310
|
+
if (window.location.origin !== expected.origin || window.location.pathname !== expected.pathname) throw new Error("Unexpected OAuth redirect page");
|
|
311
|
+
const callbackUrl = window.location.href;
|
|
312
|
+
window.opener.postMessage({ type: CALLBACK, callbackUrl }, expected.origin);
|
|
313
|
+
window.history.replaceState(null, "", expected.pathname);
|
|
314
|
+
window.close();
|
|
315
|
+
}
|
|
316
|
+
async function authorizeBronPopup(auth, redirectUri, timeoutMs) {
|
|
317
|
+
if (typeof window === "undefined") throw new Error("OAuth flow requires a browser environment");
|
|
318
|
+
if (!Number.isInteger(timeoutMs) || timeoutMs < 1 || timeoutMs > 3e5) throw new Error("Invalid OAuth timeout");
|
|
319
|
+
const expected = new URL(redirectUri);
|
|
320
|
+
if (expected.origin !== window.location.origin) throw new Error("Register a same-origin OAuth callback page");
|
|
321
|
+
const url = await auth.startAuth();
|
|
322
|
+
const popup = window.open(url, "partylayer-bron-authorization", "width=500,height=650");
|
|
323
|
+
if (!popup) {
|
|
324
|
+
auth.cancelAuthorization();
|
|
325
|
+
throw new Error("Allow the wallet authorization popup and try again");
|
|
326
|
+
}
|
|
327
|
+
return new Promise((resolve, reject) => {
|
|
328
|
+
const signal = auth.getAuthorizationSignal();
|
|
329
|
+
let callbackReceived = false;
|
|
330
|
+
let finished = false;
|
|
331
|
+
const finish = (error) => {
|
|
332
|
+
if (finished) return;
|
|
333
|
+
finished = true;
|
|
334
|
+
clearTimeout(timer);
|
|
335
|
+
clearInterval(closed);
|
|
336
|
+
window.removeEventListener("message", receive);
|
|
337
|
+
signal.removeEventListener("abort", cancel);
|
|
338
|
+
if (error) auth.cancelAuthorization();
|
|
339
|
+
try {
|
|
340
|
+
popup.close();
|
|
341
|
+
} catch {
|
|
342
|
+
}
|
|
343
|
+
if (error) reject(error);
|
|
344
|
+
else resolve();
|
|
345
|
+
};
|
|
346
|
+
const receive = (event) => {
|
|
347
|
+
if (finished || callbackReceived || event.source !== popup || event.origin !== expected.origin || !event.data || event.data.type !== CALLBACK || typeof event.data.callbackUrl !== "string") return;
|
|
348
|
+
callbackReceived = true;
|
|
349
|
+
void auth.finishAuth(event.data.callbackUrl).then(() => finish(), (error) => finish(error));
|
|
350
|
+
};
|
|
351
|
+
const cancel = () => finish(new Error("Wallet authorization cancelled"));
|
|
352
|
+
const timer = setTimeout(() => finish(new Error("Wallet authorization timed out")), timeoutMs);
|
|
353
|
+
const closed = setInterval(() => {
|
|
354
|
+
if (!callbackReceived && popup.closed) finish(new UserRejectedError("Wallet authorization was closed"));
|
|
355
|
+
}, 250);
|
|
356
|
+
window.addEventListener("message", receive);
|
|
357
|
+
signal.addEventListener("abort", cancel, { once: true });
|
|
358
|
+
if (signal.aborted) cancel();
|
|
359
|
+
});
|
|
360
|
+
}
|
|
271
361
|
|
|
272
362
|
// src/bron-adapter.ts
|
|
273
363
|
var BronAdapter = class {
|
|
@@ -275,8 +365,11 @@ var BronAdapter = class {
|
|
|
275
365
|
name = "Bron";
|
|
276
366
|
authClient;
|
|
277
367
|
apiClient;
|
|
368
|
+
redirectUri;
|
|
369
|
+
connecting = false;
|
|
278
370
|
constructor(config) {
|
|
279
371
|
this.authClient = new BronAuthClient(config.auth);
|
|
372
|
+
this.redirectUri = config.auth.redirectUri;
|
|
280
373
|
this.apiClient = new BronApiClient({
|
|
281
374
|
baseUrl: config.api.baseUrl,
|
|
282
375
|
getAccessToken: async () => {
|
|
@@ -306,23 +399,13 @@ var BronAdapter = class {
|
|
|
306
399
|
reason: "Bron is a remote signer service"
|
|
307
400
|
});
|
|
308
401
|
}
|
|
309
|
-
async connect(ctx,
|
|
402
|
+
async connect(ctx, opts) {
|
|
403
|
+
if (this.connecting) throw new Error("A Bron connection is already pending");
|
|
404
|
+
this.connecting = true;
|
|
310
405
|
try {
|
|
311
406
|
const accessToken = await this.authClient.getAccessToken();
|
|
312
407
|
if (!accessToken) {
|
|
313
|
-
|
|
314
|
-
throw new Error("OAuth flow requires browser environment");
|
|
315
|
-
}
|
|
316
|
-
const authUrl = await this.authClient.startAuth();
|
|
317
|
-
const popup = window.open(
|
|
318
|
-
authUrl,
|
|
319
|
-
"Bron Auth",
|
|
320
|
-
"width=500,height=600"
|
|
321
|
-
);
|
|
322
|
-
if (!popup) {
|
|
323
|
-
throw new Error("Failed to open auth popup");
|
|
324
|
-
}
|
|
325
|
-
throw new Error("OAuth callback not implemented in adapter - handle in app");
|
|
408
|
+
await authorizeBronPopup(this.authClient, this.redirectUri, opts?.timeoutMs ?? 12e4);
|
|
326
409
|
}
|
|
327
410
|
const session = await this.apiClient.createSession();
|
|
328
411
|
return {
|
|
@@ -348,6 +431,8 @@ var BronAdapter = class {
|
|
|
348
431
|
phase: "connect",
|
|
349
432
|
transport: "remote"
|
|
350
433
|
});
|
|
434
|
+
} finally {
|
|
435
|
+
this.connecting = false;
|
|
351
436
|
}
|
|
352
437
|
}
|
|
353
438
|
async disconnect(_ctx, _session) {
|
|
@@ -494,6 +579,6 @@ var BronAdapter = class {
|
|
|
494
579
|
}
|
|
495
580
|
};
|
|
496
581
|
|
|
497
|
-
export { BronAdapter };
|
|
582
|
+
export { BronAdapter, completeBronAuthorization };
|
|
498
583
|
//# sourceMappingURL=index.mjs.map
|
|
499
584
|
//# sourceMappingURL=index.mjs.map
|