Skip to content

Commit 549871b

Browse files
feat(dapp-client): cache signed calls from fee options
1 parent 221699f commit 549871b

1 file changed

Lines changed: 49 additions & 1 deletion

File tree

packages/wallet/dapp-client/src/ChainSessionManager.ts

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,11 @@ export class ChainSessionManager {
8484
public loginMethod: LoginMethod | null = null
8585
public userEmail: string | null = null
8686
private guard?: GuardConfig
87+
private lastSignedCallCache?: {
88+
fingerprint: string
89+
signedCall: { to: Address.Address; data: Hex.Hex }
90+
createdAtMs: number
91+
}
8792

8893
/**
8994
* @param chainId The ID of the chain this manager is responsible for.
@@ -851,6 +856,11 @@ export class ChainSessionManager {
851856
}))
852857
try {
853858
const signedCall = await this._buildAndSignCalls(callsToSend)
859+
this.lastSignedCallCache = {
860+
fingerprint: this._fingerprintCalls(callsToSend),
861+
signedCall,
862+
createdAtMs: Date.now(),
863+
}
854864
const feeOptions = await this.relayer.feeOptions(signedCall.to, this.chainId, callsToSend)
855865
return feeOptions.options
856866
} catch (err) {
@@ -907,7 +917,7 @@ export class ChainSessionManager {
907917
callsToSend.unshift(transferCall)
908918
}
909919
}
910-
const signedCalls = await this._buildAndSignCalls(callsToSend)
920+
const signedCalls = this._getCachedSignedCall(callsToSend) ?? (await this._buildAndSignCalls(callsToSend))
911921
const hash = await this.relayer.relay(signedCalls.to, signedCalls.data, this.chainId)
912922
const status = await this._waitForTransactionReceipt(hash.opHash, this.chainId)
913923
if (status.status === 'confirmed') {
@@ -1101,4 +1111,42 @@ export class ChainSessionManager {
11011111
await this.sequenceStorage.clearExplicitSessions()
11021112
await this.sequenceStorage.clearSessionlessConnection()
11031113
}
1114+
1115+
private _getCachedSignedCall(calls: Payload.Call[]): { to: Address.Address; data: Hex.Hex } | null {
1116+
if (!this.lastSignedCallCache) {
1117+
return null
1118+
}
1119+
const ttlMs = 30_000
1120+
if (Date.now() - this.lastSignedCallCache.createdAtMs > ttlMs) {
1121+
this.lastSignedCallCache = undefined
1122+
return null
1123+
}
1124+
const fingerprint = this._fingerprintCalls(calls)
1125+
if (!fingerprint) {
1126+
return null
1127+
}
1128+
if (fingerprint !== this.lastSignedCallCache.fingerprint) {
1129+
return null
1130+
}
1131+
return this.lastSignedCallCache.signedCall
1132+
}
1133+
1134+
private _fingerprintCalls(calls: Payload.Call[]): string | null {
1135+
try {
1136+
return JSON.stringify(
1137+
calls.map((call) => ({
1138+
to: call.to,
1139+
value: call.value?.toString() ?? '0',
1140+
data: call.data ?? '0x',
1141+
gasLimit: call.gasLimit?.toString() ?? '0',
1142+
delegateCall: call.delegateCall ?? false,
1143+
onlyFallback: call.onlyFallback ?? false,
1144+
behaviorOnError: call.behaviorOnError ?? 'revert',
1145+
})),
1146+
)
1147+
} catch (error) {
1148+
console.warn('ChainSessionManager._fingerprintCalls failed:', error)
1149+
return null
1150+
}
1151+
}
11041152
}

0 commit comments

Comments
 (0)