diff --git a/.changeset/old-dragons-hear.md b/.changeset/old-dragons-hear.md new file mode 100644 index 000000000..8b46bc364 --- /dev/null +++ b/.changeset/old-dragons-hear.md @@ -0,0 +1,5 @@ +--- +'@ton/walletkit': patch +--- + +Make bridge SSE connection optional for sending messages diff --git a/.changeset/pre.json b/.changeset/pre.json index 81aa241fb..7c439f5b1 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -23,6 +23,7 @@ "fix-jetton-param-naming", "late-cups-argue", "move-domain-from-signer-to-wallets", + "old-dragons-hear", "rename-transaction-action-to-send", "short-kings-flow", "smart-toys-remain", diff --git a/packages/appkit-react/CHANGELOG.md b/packages/appkit-react/CHANGELOG.md index 9ce0c1e0d..cfee78f60 100644 --- a/packages/appkit-react/CHANGELOG.md +++ b/packages/appkit-react/CHANGELOG.md @@ -1,5 +1,11 @@ # @ton/appkit-react +## 0.0.6-alpha.3 + +### Patch Changes + +- @ton/appkit@0.0.5-alpha.3 + ## 0.0.6-alpha.2 ### Patch Changes diff --git a/packages/appkit-react/package.json b/packages/appkit-react/package.json index 7150b6542..329a1035e 100644 --- a/packages/appkit-react/package.json +++ b/packages/appkit-react/package.json @@ -1,6 +1,6 @@ { "name": "@ton/appkit-react", - "version": "0.0.6-alpha.2", + "version": "0.0.6-alpha.3", "type": "module", "scripts": { "build": "pnpm run build:esm && pnpm run copy:css", diff --git a/packages/appkit/CHANGELOG.md b/packages/appkit/CHANGELOG.md index 25912de44..f5e000a2c 100644 --- a/packages/appkit/CHANGELOG.md +++ b/packages/appkit/CHANGELOG.md @@ -1,5 +1,12 @@ # @ton/appkit +## 0.0.5-alpha.3 + +### Patch Changes + +- Updated dependencies [0042cc9] + - @ton/walletkit@0.0.12-alpha.3 + ## 0.0.5-alpha.2 ### Patch Changes diff --git a/packages/appkit/package.json b/packages/appkit/package.json index 8e7af5676..7170594f6 100644 --- a/packages/appkit/package.json +++ b/packages/appkit/package.json @@ -1,6 +1,6 @@ { "name": "@ton/appkit", - "version": "0.0.5-alpha.2", + "version": "0.0.5-alpha.3", "description": "", "repository": { "type": "git", diff --git a/packages/mcp/CHANGELOG.md b/packages/mcp/CHANGELOG.md index 96c4b5ca1..f46544390 100644 --- a/packages/mcp/CHANGELOG.md +++ b/packages/mcp/CHANGELOG.md @@ -1,5 +1,12 @@ # @ton/mcp +## 0.1.15-alpha.15 + +### Patch Changes + +- Updated dependencies [0042cc9] + - @ton/walletkit@0.0.12-alpha.3 + ## 0.1.15-alpha.14 ### Patch Changes diff --git a/packages/mcp/package.json b/packages/mcp/package.json index f03dbce05..88f145f3a 100644 --- a/packages/mcp/package.json +++ b/packages/mcp/package.json @@ -1,6 +1,6 @@ { "name": "@ton/mcp", - "version": "0.1.15-alpha.14", + "version": "0.1.15-alpha.15", "description": "TON MCP Server - Model Context Protocol server for TON blockchain wallet operations", "license": "MIT", "type": "module", diff --git a/packages/walletkit-ios-bridge/src/main.ts b/packages/walletkit-ios-bridge/src/main.ts index dd1247053..2dd2b4cc9 100644 --- a/packages/walletkit-ios-bridge/src/main.ts +++ b/packages/walletkit-ios-bridge/src/main.ts @@ -154,6 +154,7 @@ window.initWalletKit = async (configuration, storage, bridgeTransport, sessionMa eventProcessor: configuration.eventsConfiguration, storage: storage ? new SwiftStorageAdapter(storage) : new MemoryStorageAdapter({}), dev: configuration.dev, + analytics: configuration.analytics, }); console.log('🚀 WalletKit iOS Bridge starting...'); diff --git a/packages/walletkit-ios-bridge/src/types.ts b/packages/walletkit-ios-bridge/src/types.ts index c0a7cbb29..63a5e8a6f 100644 --- a/packages/walletkit-ios-bridge/src/types.ts +++ b/packages/walletkit-ios-bridge/src/types.ts @@ -48,7 +48,10 @@ export interface SwiftWalletSigner { publicKey: () => Hex; } -type ReusedTonWalletKitOptions = Pick; +type ReusedTonWalletKitOptions = Pick< + TonWalletKitOptions, + 'deviceInfo' | 'walletManifest' | 'bridge' | 'dev' | 'analytics' +>; export interface SwiftWalletKitConfiguration extends ReusedTonWalletKitOptions { networkConfigurations?: { diff --git a/packages/walletkit/CHANGELOG.md b/packages/walletkit/CHANGELOG.md index 098ae4650..fe8a8da57 100644 --- a/packages/walletkit/CHANGELOG.md +++ b/packages/walletkit/CHANGELOG.md @@ -1,5 +1,11 @@ # @ton/walletkit +## 0.0.12-alpha.3 + +### Patch Changes + +- 0042cc9: Make bridge SSE connection optional for sending messages + ## 0.0.12-alpha.2 ### Patch Changes diff --git a/packages/walletkit/package.json b/packages/walletkit/package.json index 0fcb2e3dc..c3f3efe9b 100644 --- a/packages/walletkit/package.json +++ b/packages/walletkit/package.json @@ -1,6 +1,6 @@ { "name": "@ton/walletkit", - "version": "0.0.12-alpha.2", + "version": "0.0.12-alpha.3", "description": "Wallet kit for TON Connect", "main": "dist/cjs/index.js", "module": "dist/esm/index.js", diff --git a/packages/walletkit/src/core/BridgeManager.ts b/packages/walletkit/src/core/BridgeManager.ts index 4044273f8..1684f1d88 100644 --- a/packages/walletkit/src/core/BridgeManager.ts +++ b/packages/walletkit/src/core/BridgeManager.ts @@ -50,6 +50,7 @@ export class BridgeManager { // eslint-disable-next-line @typescript-eslint/no-explicit-any private eventQueue: any[] = []; private isProcessing = false; + private isActive = false; // Durable events support private eventStore: EventStore; @@ -98,6 +99,23 @@ export class BridgeManager { this.walletKitConfig = walletKitConfig; this.jsBridgeTransport = config?.jsBridgeTransport; + if (this.config.bridgeUrl && !this.config.disableHttpConnection) { + this.bridgeProvider = new BridgeProvider( + this.config.bridgeUrl, + this.queueBridgeEvent.bind(this), + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (error: any) => { + log.error('Bridge listener error', { error: error.toString() }); + // Send bridge-client-connect-error event for listener errors + this.analytics?.emitBridgeClientConnectError({ + error_message: `${error?.toString() || 'Unknown error'}${error?.errorCode ? ` (Code: ${error?.errorCode})` : ''}`, + trace_id: error?.traceId, + client_id: error?.clientId, + }); + }, + ); + } + if (!this.jsBridgeTransport && config?.enableJsBridge) { throw new WalletKitError(ERROR_CODES.INVALID_CONFIG, 'JS Bridge transport is not configured'); } @@ -107,8 +125,15 @@ export class BridgeManager { * Initialize bridge connection */ async start(): Promise { - if (this.bridgeProvider) { - log.warn('Bridge already initialized'); + if (this.isActive === true) { + log.warn('Bridge already started'); + return; + } + + this.isActive = true; + + if (this.isConnected === true) { + log.warn('Bridge already connected'); return; } @@ -121,6 +146,7 @@ export class BridgeManager { this.reconnectAttempts = 0; } } catch (error) { + this.isActive = false; log.error('Failed to start bridge', { error }); throw error; } @@ -321,7 +347,6 @@ export class BridgeManager { async close(): Promise { if (this.bridgeProvider) { await this.bridgeProvider.close(); - this.bridgeProvider = undefined; } // Clear event queue and reset processing state @@ -329,6 +354,7 @@ export class BridgeManager { this.isProcessing = false; // this.sessions.clear(); + this.isActive = false; this.isConnected = false; this.reconnectAttempts = 0; if (this.requestProcessingTimeoutId) { @@ -365,8 +391,11 @@ export class BridgeManager { * Connect to TON Connect bridge */ private async connectToSSEBridge(): Promise { - if (!this.config.bridgeUrl) { - return; + if (!this.bridgeProvider) { + throw new WalletKitError( + ERROR_CODES.BRIDGE_NOT_INITIALIZED, + 'Bridge not initialized before connecting to SSE', + ); } const connectTraceId = uuidv7(); @@ -390,24 +419,8 @@ export class BridgeManager { }); } - this.bridgeProvider = await BridgeProvider.open({ - bridgeUrl: this.config.bridgeUrl, - clients, - listener: this.queueBridgeEvent.bind(this), - // eslint-disable-next-line @typescript-eslint/no-explicit-any - errorListener: (error: any) => { - log.error('Bridge listener error', { error: error.toString() }); - // Send bridge-client-connect-error event for listener errors - this.analytics?.emitBridgeClientConnectError({ - error_message: `${error?.toString() || 'Unknown error'}${error?.errorCode ? ` (Code: ${error?.errorCode})` : ''}`, - trace_id: error?.traceId ?? connectTraceId, - client_id: error?.clientId, - }); - }, - options: { - lastEventId: this.lastEventId, - // heartbeatReconnectIntervalMs: this.config.reconnectInterval, - }, + await this.bridgeProvider?.restoreConnection(clients, { + lastEventId: this.lastEventId, }); this.isConnected = true; this.reconnectAttempts = 0;