From a41cfa8a4e10ee1f1e9052b8b4aa9cb06007eecc Mon Sep 17 00:00:00 2001 From: Aaron Choo Date: Wed, 20 Dec 2023 22:23:19 +0800 Subject: [PATCH] fix: extract correct account sequence for injective --- CHANGELOG.md | 6 ++++++ package.json | 2 +- src/wallet/utils/sequence.test.ts | 25 +++++++++++++++++++++++++ src/wallet/utils/sequence.ts | 14 ++++++++++++++ src/wallet/wallets/ConnectedWallet.ts | 20 ++++++++------------ 5 files changed, 54 insertions(+), 13 deletions(-) create mode 100644 src/wallet/utils/sequence.test.ts create mode 100644 src/wallet/utils/sequence.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 23bcfac0..1693bd6a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## `v0.0.46` + +### Fixes + +- Fixed `ConnectedWallet.estimateFee` to properly extract account sequences from errors thrown by Injective RPCs + ## `v0.0.45` ### Improvements diff --git a/package.json b/package.json index 7ed7095b..7fdc9e13 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cosmes", - "version": "0.0.45", + "version": "0.0.46", "private": false, "packageManager": "pnpm@8.3.0", "sideEffects": false, diff --git a/src/wallet/utils/sequence.test.ts b/src/wallet/utils/sequence.test.ts new file mode 100644 index 00000000..c9daaf94 --- /dev/null +++ b/src/wallet/utils/sequence.test.ts @@ -0,0 +1,25 @@ +import { describe, expect, it } from "vitest"; + +import { extractExpectedAccountSequence } from "./sequence"; + +describe("extractExpectedAccountSequence", () => { + it("should extract expected account sequence numbers from valid errors", () => { + // Older cosmos sdk chains + const err1 = new Error( + `account sequence mismatch, expected 10, got 11: incorrect account sequence: invalid request` + ); + expect(extractExpectedAccountSequence(err1)).toBe(10n); + + // Newer cosmos sdk chains (0.45+) + const err2 = new Error( + `rpc error: code = Unknown desc = account sequence mismatch, expected 10, got 11: ......` + ); + expect(extractExpectedAccountSequence(err2)).toBe(10n); + + // Injective + const err3 = new Error( + `[reason]:"incorrect account sequence" metadata:{key:"ABCICode" value:"32"} ...... rpc error: code = Unknown desc = account sequence mismatch, expected 10, got 11: ......` + ); + expect(extractExpectedAccountSequence(err3)).toBe(10n); + }); +}); diff --git a/src/wallet/utils/sequence.ts b/src/wallet/utils/sequence.ts new file mode 100644 index 00000000..0e5777a8 --- /dev/null +++ b/src/wallet/utils/sequence.ts @@ -0,0 +1,14 @@ +/** + * Extracts and returns the expected account sequence number from an error. If + * the error is not related to an account sequence mismatch, `null` is returned. + */ +export function extractExpectedAccountSequence(err: Error): bigint | null { + const matches = err.message.match( + // This regex is intentionally kept as strict as possible + /account sequence mismatch, expected (\d+), got (\d+):/ + ); + if (!matches || matches.length < 3) { + return null; + } + return BigInt(matches[1]); +} diff --git a/src/wallet/wallets/ConnectedWallet.ts b/src/wallet/wallets/ConnectedWallet.ts index 074c7323..710187ef 100644 --- a/src/wallet/wallets/ConnectedWallet.ts +++ b/src/wallet/wallets/ConnectedWallet.ts @@ -18,6 +18,7 @@ import { import type { WalletName } from "../constants/WalletName"; import type { WalletType } from "../constants/WalletType"; +import { extractExpectedAccountSequence } from "../utils/sequence"; export type UnsignedTx = { msgs: Adapter[]; @@ -125,22 +126,17 @@ export abstract class ConnectedWallet { try { return await estimate(); } catch (err) { - if ( - !(err instanceof Error) || - !err.message.includes("account sequence mismatch") - ) { - // Rethrow if the error is not related to account sequence + if (!(err instanceof Error)) { + // Rethrow non-errors throw err; } - // Possible messages: - // "account sequence mismatch, expected 10, got 11: incorrect account sequence: invalid request" - // "rpc error: code = Unknown desc = account sequence mismatch, expected 10, got 11: ..." - const matches = err.message.match(/(\d+)/g); - if (!matches || matches.length < 2) { - throw new Error("Failed to parse account sequence"); + const expectedSequence = extractExpectedAccountSequence(err); + if (!expectedSequence) { + // Rethrow errors not related to account sequence mismatch + throw err; } // Set the cached sequence to the one from the error message - this.sequence = BigInt(matches[0]); + this.sequence = expectedSequence; return estimate(); } }