diff --git a/.gitignore b/.gitignore index e70ecd7f0..aabd02c8e 100644 --- a/.gitignore +++ b/.gitignore @@ -38,4 +38,6 @@ yarn-error.log* *.pem # Husky -.husky/ \ No newline at end of file +.husky/ +/lib/signals-implicit-mode/Counter +/lib/signals-implicit-mode/lib/signals-implicit-mode diff --git a/packages/wallet/dapp-client/src/ChainSessionManager.ts b/packages/wallet/dapp-client/src/ChainSessionManager.ts index 76b62a3f3..f8f56d916 100644 --- a/packages/wallet/dapp-client/src/ChainSessionManager.ts +++ b/packages/wallet/dapp-client/src/ChainSessionManager.ts @@ -69,6 +69,11 @@ export class ChainSessionManager { public loginMethod: LoginMethod | null = null public userEmail: string | null = null private guard?: GuardConfig + private lastSignedCallCache?: { + fingerprint: string + signedCall: { to: Address.Address; data: Hex.Hex } + createdAtMs: number + } /** * @param chainId The ID of the chain this manager is responsible for. @@ -753,6 +758,14 @@ export class ChainSessionManager { })) try { const signedCall = await this._buildAndSignCalls(callsToSend) + const fingerprint = this._fingerprintCalls(callsToSend) + if (fingerprint) { + this.lastSignedCallCache = { + fingerprint, + signedCall, + createdAtMs: Date.now(), + } + } const feeOptions = await this.relayer.feeOptions(signedCall.to, this.chainId, callsToSend) return feeOptions.options } catch (err) { @@ -809,7 +822,7 @@ export class ChainSessionManager { callsToSend.unshift(transferCall) } } - const signedCalls = await this._buildAndSignCalls(callsToSend) + const signedCalls = this._getCachedSignedCall(callsToSend) ?? (await this._buildAndSignCalls(callsToSend)) const hash = await this.relayer.relay(signedCalls.to, signedCalls.data, this.chainId) const status = await this._waitForTransactionReceipt(hash.opHash, this.chainId) if (status.status === 'confirmed') { @@ -988,4 +1001,42 @@ export class ChainSessionManager { await this.sequenceStorage.clearImplicitSession() await this.sequenceStorage.clearExplicitSessions() } + + private _getCachedSignedCall(calls: Payload.Call[]): { to: Address.Address; data: Hex.Hex } | null { + if (!this.lastSignedCallCache) { + return null + } + const ttlMs = 30_000 + if (Date.now() - this.lastSignedCallCache.createdAtMs > ttlMs) { + this.lastSignedCallCache = undefined + return null + } + const fingerprint = this._fingerprintCalls(calls) + if (!fingerprint) { + return null + } + if (fingerprint !== this.lastSignedCallCache.fingerprint) { + return null + } + return this.lastSignedCallCache.signedCall + } + + private _fingerprintCalls(calls: Payload.Call[]): string | null { + try { + return JSON.stringify( + calls.map((call) => ({ + to: call.to, + value: call.value?.toString() ?? '0', + data: call.data ?? '0x', + gasLimit: call.gasLimit?.toString() ?? '0', + delegateCall: call.delegateCall ?? false, + onlyFallback: call.onlyFallback ?? false, + behaviorOnError: call.behaviorOnError ?? 'revert', + })), + ) + } catch (error) { + console.warn('ChainSessionManager._fingerprintCalls failed:', error) + return null + } + } } diff --git a/packages/wallet/dapp-client/src/DappTransport.ts b/packages/wallet/dapp-client/src/DappTransport.ts index 0eb0804ae..c0c032453 100644 --- a/packages/wallet/dapp-client/src/DappTransport.ts +++ b/packages/wallet/dapp-client/src/DappTransport.ts @@ -328,10 +328,7 @@ export class DappTransport { return } - const isPotentiallyValidSource = - this.walletWindow && (event.source === this.walletWindow || !this.walletWindow.closed) - - if (!isPotentiallyValidSource && event.data?.type !== MessageType.WALLET_OPENED) { + if (!this.walletWindow || event.source !== this.walletWindow) { return }