diff --git a/packages/keychain/src/utils/connection/execute.ts b/packages/keychain/src/utils/connection/execute.ts index fd34ec065..f3c96648f 100644 --- a/packages/keychain/src/utils/connection/execute.ts +++ b/packages/keychain/src/utils/connection/execute.ts @@ -11,6 +11,7 @@ import { } from "starknet"; import { ConnectionCtx, ControllerError, ExecuteCtx } from "./types"; import { ErrorCode, JsCall } from "@cartridge/account-wasm/controller"; +import { mutex } from "./sync"; export const ESTIMATE_FEE_PERCENTAGE = 10; @@ -64,6 +65,7 @@ export function execute({ }); } + const release = await mutex.obtain(); return await new Promise( async (resolve, reject) => { if (!account) { @@ -158,7 +160,9 @@ export function execute({ }); } }, - ); + ).finally(() => { + release(); + }); }; } diff --git a/packages/keychain/src/utils/connection/sign.ts b/packages/keychain/src/utils/connection/sign.ts index 8e4a52a24..cc25df3d7 100644 --- a/packages/keychain/src/utils/connection/sign.ts +++ b/packages/keychain/src/utils/connection/sign.ts @@ -5,6 +5,7 @@ import { } from "@cartridge/controller"; import { Signature, TypedData } from "starknet"; import { ConnectionCtx, SignMessageCtx } from "./types"; +import { mutex } from "./sync"; import Controller from "utils/controller"; import { parseControllerError } from "./execute"; @@ -29,6 +30,7 @@ export function signMessageFactory(setContext: (ctx: ConnectionCtx) => void) { }); } + const release = await mutex.obtain(); return await new Promise( async (resolve, reject) => { // If a session call and there is no session available @@ -62,6 +64,8 @@ export function signMessageFactory(setContext: (ctx: ConnectionCtx) => void) { }); } }, - ); + ).finally(() => { + release(); + }); }; } diff --git a/packages/keychain/src/utils/connection/sync.ts b/packages/keychain/src/utils/connection/sync.ts new file mode 100644 index 000000000..12e1a009b --- /dev/null +++ b/packages/keychain/src/utils/connection/sync.ts @@ -0,0 +1,3 @@ +import { Mutex } from "utils/mutex"; + +export const mutex = new Mutex(); diff --git a/packages/keychain/src/utils/controller.ts b/packages/keychain/src/utils/controller.ts index 56e9f609e..84cc8a373 100644 --- a/packages/keychain/src/utils/controller.ts +++ b/packages/keychain/src/utils/controller.ts @@ -13,10 +13,8 @@ import { Call, CallData, } from "starknet"; -import { Mutex } from "utils/mutex"; -import { toWasmPolicies } from "@cartridge/controller"; -const mutex = new Mutex(); +import { toWasmPolicies } from "@cartridge/controller"; import { CartridgeAccount, @@ -103,12 +101,7 @@ export default class Controller extends Account { throw new Error("Account not found"); } - const release = await mutex.obtain(); - try { - await this.cartridge.createSession(toWasmPolicies(policies), expiresAt); - } finally { - release(); - } + await this.cartridge.createSession(toWasmPolicies(policies), expiresAt); } registerSessionCalldata( @@ -133,17 +126,12 @@ export default class Controller extends Account { throw new Error("Account not found"); } - const release = await mutex.obtain(); - try { - return await this.cartridge.registerSession( - toWasmPolicies(policies), - expiresAt, - publicKey, - num.toHex(maxFee), - ); - } finally { - release(); - } + return await this.cartridge.registerSession( + toWasmPolicies(policies), + expiresAt, + publicKey, + num.toHex(maxFee), + ); } upgrade(new_class_hash: JsFelt): JsCall { @@ -151,21 +139,11 @@ export default class Controller extends Account { } async executeFromOutsideV2(calls: Call[]): Promise { - const release = await mutex.obtain(); - try { - return await this.cartridge.executeFromOutsideV2(toJsCalls(calls)); - } finally { - release(); - } + return await this.cartridge.executeFromOutsideV2(toJsCalls(calls)); } async executeFromOutsideV3(calls: Call[]): Promise { - const release = await mutex.obtain(); - try { - return await this.cartridge.executeFromOutsideV3(toJsCalls(calls)); - } finally { - release(); - } + return await this.cartridge.executeFromOutsideV3(toJsCalls(calls)); } async execute( @@ -180,15 +158,10 @@ export default class Controller extends Account { executionDetails.maxFee = num.toHex(executionDetails.maxFee); } - const release = await mutex.obtain(); - try { - return await this.cartridge.execute( - toJsCalls(calls), - executionDetails as JsInvocationsDetails, - ); - } finally { - release(); - } + return await this.cartridge.execute( + toJsCalls(calls), + executionDetails as JsInvocationsDetails, + ); } hasSession(calls: Call[]): boolean { @@ -210,27 +183,22 @@ export default class Controller extends Account { calls: Call[], _: EstimateFeeDetails = {}, ): Promise { - const release = await mutex.obtain(); - try { - const res = await this.cartridge.estimateInvokeFee(toJsCalls(calls)); - - // The reason why we set the multiplier unseemingly high is to account - // for the fact that the estimation above is done without validation (ie SKIP_VALIDATE). - // - // Setting it lower might cause the actual transaction to fail due to - // insufficient max fee. - const MULTIPLIER_PERCENTAGE = 170; // x1.7 - - // This will essentially multiply the estimated fee by 1.7 - const suggestedMaxFee = num.addPercent( - BigInt(res.overall_fee), - MULTIPLIER_PERCENTAGE, - ); + const res = await this.cartridge.estimateInvokeFee(toJsCalls(calls)); + + // The reason why we set the multiplier unseemingly high is to account + // for the fact that the estimation above is done without validation (ie SKIP_VALIDATE). + // + // Setting it lower might cause the actual transaction to fail due to + // insufficient max fee. + const MULTIPLIER_PERCENTAGE = 170; // x1.7 + + // This will essentially multiply the estimated fee by 1.7 + const suggestedMaxFee = num.addPercent( + BigInt(res.overall_fee), + MULTIPLIER_PERCENTAGE, + ); - return { suggestedMaxFee, ...res }; - } finally { - release(); - } + return { suggestedMaxFee, ...res }; } async verifyMessageHash( @@ -252,39 +220,19 @@ export default class Controller extends Account { } async signMessage(typedData: TypedData): Promise { - const release = await mutex.obtain(); - try { - return await this.cartridge.signMessage(JSON.stringify(typedData)); - } finally { - release(); - } + return this.cartridge.signMessage(JSON.stringify(typedData)); } async getNonce(_?: any): Promise { - const release = await mutex.obtain(); - try { - return await this.cartridge.getNonce(); - } finally { - release(); - } + return await this.cartridge.getNonce(); } async selfDeploy(maxFee: BigNumberish): Promise { - const release = await mutex.obtain(); - try { - return await this.cartridge.deploySelf(num.toHex(maxFee)); - } finally { - release(); - } + return await this.cartridge.deploySelf(num.toHex(maxFee)); } async delegateAccount(): Promise { - const release = await mutex.obtain(); - try { - return await this.cartridge.delegateAccount(); - } finally { - release(); - } + return this.cartridge.delegateAccount(); } revoke(_origin: string) {