Skip to content

Commit d7e324d

Browse files
CalicoNinocgilbe27k-yangsemantic-release-botUnique-Divine
authored
feat: account parser (#374)
* chore: develop -> main (#370) * revert: cosmos submodule only (#362) * revert: cosmos submodule only * fix: rem * fix: rem * fix: update * feat: add msg client * fix: paths * fix: try chaosnet ibc * fix: path again * fix: try hm * fix: fixes to pass * feat: eth protos (#366) * fix: eth protos * fix: client * fix: fixes * fix: try older nibiru * fix: index * fix: mainnet * fix: import * revert: build change * chore: tests (#367) * fix: all query tests * chore: final tests * fix: buf * fix: fix * fix: pull latest * fix: build * fix: build * refactor(faucet)!: set default tokens (#369) * chore: develop -> main (#368) * revert: cosmos submodule only (#362) * revert: cosmos submodule only * fix: rem * fix: rem * fix: update * feat: add msg client * fix: paths * fix: try chaosnet ibc * fix: path again * fix: try hm * fix: fixes to pass * feat: eth protos (#366) * fix: eth protos * fix: client * fix: fixes * fix: try older nibiru * fix: index * fix: mainnet * fix: import * revert: build change * chore: tests (#367) * fix: all query tests * chore: final tests * fix: buf * fix: fix * fix: pull latest * fix: build * fix: build * chore(release): 4.5.1 ### [4.5.1](v4.5.0...v4.5.1) (2024-08-09) ### Miscellaneous Chores * develop -> main ([#368](#368)) ([c6d6570](c6d6570)), closes [#362](#362) [#366](#366) [#367](#367) [skip ci] * fix(faucet): remove unused tokens from default faucet request * fix: bump test --------- Co-authored-by: Cameron Gilbert <[email protected]> Co-authored-by: semantic-release-bot <[email protected]> --------- Co-authored-by: Kevin Yang <[email protected]> Co-authored-by: semantic-release-bot <[email protected]> * chore(github): Add project automation for https://tinyurl.com/25uty9w5 * chore(release): 4.5.2 ### [4.5.2](v4.5.1...v4.5.2) (2024-09-24) ### Miscellaneous Chores * develop -> main ([#370](#370)) ([ec2a25b](ec2a25b)), closes [#362](#362) [#366](#366) [#367](#367) [#369](#369) [#368](#368) [#362](#362) [#366](#366) [#367](#367) [#362](#362) [#366](#366) [#367](#367) * **github:** Add project automation for https://tinyurl.com/25uty9w5 ([c2c27e5](c2c27e5)) [skip ci] * feat: nibiru account parser * refactor: throw if baseaccount is undefined * test: fixing tests * chore: removing unnecessary ? * refactor: matching cosmjs implementation * chore: removing t.json * chore: pr comments --------- Co-authored-by: Cameron Gilbert <[email protected]> Co-authored-by: Kevin Yang <[email protected]> Co-authored-by: semantic-release-bot <[email protected]> Co-authored-by: Unique Divine <[email protected]>
1 parent 49b0766 commit d7e324d

File tree

3 files changed

+149
-0
lines changed

3 files changed

+149
-0
lines changed

src/sdk/tx/account.test.ts

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
import { accountFromEthAccount, accountFromNibiru } from "./account"
2+
import { EthAccount } from "src/protojs/eth/types/v1/account"
3+
import { Any } from "src/protojs/google/protobuf/any"
4+
import Long from "long"
5+
import * as cosmjs from "@cosmjs/stargate"
6+
import { decodeOptionalPubkey } from "@cosmjs/proto-signing"
7+
import { BaseAccount } from "src/protojs/cosmos/auth/v1beta1/auth"
8+
9+
// Mock decodeOptionalPubkey
10+
jest.mock("@cosmjs/proto-signing", () => ({
11+
decodeOptionalPubkey: jest.fn(),
12+
}))
13+
14+
const mockedDecodeOptionalPubkey = decodeOptionalPubkey as jest.Mock
15+
16+
describe("accountFromEthAccount", () => {
17+
it("should throw an error if baseAccount is undefined", () => {
18+
const baseAccount: BaseAccount = undefined as unknown as BaseAccount
19+
20+
expect(() => accountFromEthAccount(baseAccount)).toThrow()
21+
})
22+
23+
it("should return a valid account when baseAccount is defined", () => {
24+
const baseAccount: BaseAccount = {
25+
address: "nibi1testaddress",
26+
pubKey: {
27+
typeUrl: "/cosmos.crypto.secp256k1.PubKey",
28+
value: new Uint8Array([1, 2, 3]),
29+
},
30+
accountNumber: Long.fromNumber(123),
31+
sequence: Long.fromNumber(1),
32+
}
33+
34+
mockedDecodeOptionalPubkey.mockReturnValue({
35+
typeUrl: "/cosmos.crypto.secp256k1.PubKey",
36+
value: new Uint8Array([1, 2, 3]),
37+
})
38+
39+
const account = accountFromEthAccount(baseAccount)
40+
41+
expect(account.address).toBe("nibi1testaddress")
42+
expect(account.pubkey).toEqual({
43+
typeUrl: "/cosmos.crypto.secp256k1.PubKey",
44+
value: new Uint8Array([1, 2, 3]),
45+
})
46+
expect(account.accountNumber).toEqual(123)
47+
expect(account.sequence).toEqual(1)
48+
})
49+
})
50+
51+
describe("accountFromNibiru", () => {
52+
it("should parse EthAccount typeUrl and return valid account", () => {
53+
const input: Any = {
54+
typeUrl: "/eth.types.v1.EthAccount",
55+
value: EthAccount.encode({
56+
baseAccount: {
57+
address: "nibi1testaddress",
58+
pubKey: {
59+
typeUrl: "/cosmos.crypto.secp256k1.PubKey",
60+
value: new Uint8Array([4, 5, 6]),
61+
},
62+
accountNumber: Long.fromNumber(456),
63+
sequence: Long.fromNumber(2),
64+
},
65+
codeHash: "",
66+
}).finish(),
67+
}
68+
69+
mockedDecodeOptionalPubkey.mockReturnValue({
70+
typeUrl: "/cosmos.crypto.secp256k1.PubKey",
71+
value: new Uint8Array([4, 5, 6]),
72+
})
73+
74+
const account = accountFromNibiru(input)
75+
76+
expect(account.address).toBe("nibi1testaddress")
77+
expect(account.pubkey).toEqual({
78+
typeUrl: "/cosmos.crypto.secp256k1.PubKey",
79+
value: new Uint8Array([4, 5, 6]),
80+
})
81+
expect(account.accountNumber).toEqual(456)
82+
expect(account.sequence).toEqual(2)
83+
})
84+
85+
it("should handle non-EthAccount typeUrl by calling accountFromAny", () => {
86+
const mockAccountFromAny = jest
87+
.spyOn(cosmjs, "accountFromAny")
88+
.mockReturnValue({
89+
address: "nibi1otheraddress",
90+
pubkey: null,
91+
accountNumber: 789,
92+
sequence: 3,
93+
})
94+
95+
const input: Any = {
96+
typeUrl: "/other.types.v1.Account",
97+
value: new Uint8Array([7, 8, 9]),
98+
}
99+
100+
const account = accountFromNibiru(input)
101+
102+
expect(account.address).toBe("nibi1otheraddress")
103+
expect(mockAccountFromAny).toHaveBeenCalledWith(input)
104+
})
105+
})

src/sdk/tx/account.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { decodeOptionalPubkey } from "@cosmjs/proto-signing"
2+
import { Account, accountFromAny, AccountParser } from "@cosmjs/stargate"
3+
import { EthAccount } from "src/protojs/eth/types/v1/account"
4+
import { Any } from "src/protojs/google/protobuf/any"
5+
import { assert } from "@cosmjs/utils"
6+
import { BaseAccount } from "src/protojs/cosmos/auth/v1beta1/auth"
7+
8+
/**
9+
* Converts an EthAccount to a general Cosmos Account object.
10+
*
11+
* @param {EthAccount} ethAccount - The EthAccount object containing the account's base information.
12+
* @returns {Account} The Cosmos account object.
13+
*/
14+
export const accountFromEthAccount = ({
15+
address,
16+
pubKey,
17+
accountNumber,
18+
sequence,
19+
}: BaseAccount): Account => ({
20+
address,
21+
pubkey: decodeOptionalPubkey(pubKey),
22+
accountNumber: accountNumber.toNumber(),
23+
sequence: sequence.toNumber(),
24+
})
25+
26+
/**
27+
* Parses an account input into a Cosmos account. Handles both EthAccount and other standard accounts.
28+
*
29+
* @param {Any} input - The input account information, containing the typeUrl and value.
30+
* @returns {Account} Parsed account object.
31+
*/
32+
export const accountFromNibiru: AccountParser = (input: Any): Account => {
33+
const { typeUrl, value } = input
34+
35+
if (typeUrl === "/eth.types.v1.EthAccount") {
36+
const baseAccount = EthAccount.decode(value).baseAccount
37+
assert(baseAccount)
38+
return accountFromEthAccount(baseAccount)
39+
}
40+
41+
return accountFromAny(input)
42+
}

src/sdk/tx/txClient.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
setupWasmExtension,
1919
} from "@cosmjs/cosmwasm-stargate"
2020
import { NibiruExtensions, setupNibiruExtension } from ".."
21+
import { accountFromNibiru } from "./account"
2122

2223
export const nibiruRegistryTypes: ReadonlyArray<[string, GeneratedType]> = [
2324
...defaultRegistryTypes,
@@ -69,6 +70,7 @@ export class NibiruTxClient extends SigningStargateClient {
6970
registry: new Registry(nibiruRegistryTypes),
7071
gasPrice: GasPrice.fromString("0.025unibi"),
7172
broadcastPollIntervalMs: 1_000, // 1 second poll times
73+
accountParser: accountFromNibiru,
7274
...options,
7375
},
7476
wasmClient

0 commit comments

Comments
 (0)