Skip to content

Commit

Permalink
feat: nibicosmwasmclient
Browse files Browse the repository at this point in the history
  • Loading branch information
CalicoNino committed Oct 15, 2024
1 parent d7e324d commit 240d4b8
Show file tree
Hide file tree
Showing 2 changed files with 188 additions and 0 deletions.
126 changes: 126 additions & 0 deletions src/sdk/core/cosmwasmclient.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import { CosmWasmClient } from "@cosmjs/cosmwasm-stargate"
import { Account, accountFromAny, SequenceResponse } from "@cosmjs/stargate"
import { NibiCosmWasmClient } from "./cosmwasmclient"
import { Any } from "cosmjs-types/google/protobuf/any"

// Mock dependencies
jest.mock("@cosmjs/cosmwasm-stargate")
jest.mock("@cosmjs/stargate")
jest.mock("@cosmjs/tendermint-rpc")

describe("NibiCosmWasmClient", () => {
const mockCosmWasmClient = {
forceGetQueryClient: jest.fn(),
connect: jest.fn(),
}

const mockQueryClient = {
auth: {
account: jest.fn(),
},
}

// Mock Any type (used for accountFromAny)
const mockAny: Any = {
typeUrl: "/cosmos.auth.v1beta1.BaseAccount",
value: new Uint8Array([10, 20, 30, 40]), // Example value
}

// Mock Account structure (returned from accountFromAny)
const mockAccount: Account = {
address: "nibi1234...",
pubkey: {
type: "tendermint/PubKeySecp256k1",
value: new Uint8Array([1, 2, 3, 4, 5]),
},
accountNumber: 1,
sequence: 1,
}

beforeEach(() => {
jest.clearAllMocks()
// Set up mock client
;(CosmWasmClient.connect as jest.Mock).mockResolvedValue(mockCosmWasmClient)
mockCosmWasmClient.forceGetQueryClient.mockReturnValue(mockQueryClient)
})

describe("connect", () => {
it("should create a new NibiCosmWasmClient", async () => {
const endpoint = "http://localhost:26657"
const client = await NibiCosmWasmClient.connect(endpoint)

expect(CosmWasmClient.connect).toHaveBeenCalledWith(endpoint)
expect(client).toBeInstanceOf(NibiCosmWasmClient)
})
})

describe("getAccount", () => {
it("should return parsed account if account exists", async () => {
mockQueryClient.auth.account.mockResolvedValue(mockAny)
// Mock accountFromAny to return the mockAccount when called with mockAny
;(accountFromAny as jest.Mock).mockReturnValue(mockAccount)

const client = await NibiCosmWasmClient.connect("http://localhost:26657")
const result = await client.getAccount("nibi1234...")

expect(mockQueryClient.auth.account).toHaveBeenCalledWith("nibi1234...")
expect(result).toEqual(mockAccount)
})

it("should return null if account does not exist", async () => {
mockQueryClient.auth.account.mockResolvedValue(null)

const client = await NibiCosmWasmClient.connect("http://localhost:26657")
const result = await client.getAccount("nibi1234...")

expect(mockQueryClient.auth.account).toHaveBeenCalledWith("nibi1234...")
expect(result).toBeNull()
})

it("should return null on 'NotFound' error", async () => {
mockQueryClient.auth.account.mockRejectedValue(
new Error("rpc error: code = NotFound")
)

const client = await NibiCosmWasmClient.connect("http://localhost:26657")
const result = await client.getAccount("nibi1234...")

expect(result).toBeNull()
})

it("should throw error on other errors", async () => {
const errorMessage = "Some other error"
mockQueryClient.auth.account.mockRejectedValue(new Error(errorMessage))

const client = await NibiCosmWasmClient.connect("http://localhost:26657")
await expect(client.getAccount("nibi1234...")).rejects.toThrow(
errorMessage
)
})
})

describe("getSequence", () => {
it("should return sequence and account number for valid account", async () => {
mockQueryClient.auth.account.mockResolvedValue(mockAny)
;(accountFromAny as jest.Mock).mockReturnValue(mockAccount)

const client = await NibiCosmWasmClient.connect("http://localhost:26657")
const result: SequenceResponse = await client.getSequence("nibi1234...")

expect(mockQueryClient.auth.account).toHaveBeenCalledWith("nibi1234...")
expect(result).toEqual({
accountNumber: mockAccount.accountNumber,
sequence: mockAccount.sequence,
})
})

it("should throw an error if the account does not exist", async () => {
mockQueryClient.auth.account.mockResolvedValue(null)

const client = await NibiCosmWasmClient.connect("http://localhost:26657")
await expect(client.getSequence("nibi1234...")).rejects.toThrow(
"Account 'nibi1234...' does not exist on chain. Send some tokens there before trying to query sequence."
)
})
})
})
62 changes: 62 additions & 0 deletions src/sdk/core/cosmwasmclient.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { CosmWasmClient } from "@cosmjs/cosmwasm-stargate"
import {
Account,
accountFromAny,
AccountParser,
HttpEndpoint,
SequenceResponse,
} from "@cosmjs/stargate"
import { CometClient } from "@cosmjs/tendermint-rpc"

export interface NibiCosmWasmClientOptions {
readonly accountParser?: AccountParser
}

export class NibiCosmWasmClient extends CosmWasmClient {
private readonly accountParser: AccountParser

protected constructor(
cometClient: CometClient | undefined,
options: NibiCosmWasmClientOptions = {}
) {
super(cometClient)
const { accountParser = accountFromAny } = options
this.accountParser = accountParser
}

public static async connect(
endpoint: string | HttpEndpoint,
options: NibiCosmWasmClientOptions = {}
): Promise<NibiCosmWasmClient> {
const cosmWasmClient = await CosmWasmClient.connect(endpoint)
return new NibiCosmWasmClient(cosmWasmClient["cometClient"], options)
}

public async getAccount(searchAddress: string): Promise<Account | null> {
try {
const account = await this.forceGetQueryClient().auth.account(
searchAddress
)
return account ? this.accountParser(account) : null
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (error: any) {
if (/rpc error: code = NotFound/i.test(error.toString())) {
return null
}
throw error
}
}

public async getSequence(address: string): Promise<SequenceResponse> {
const account = await this.getAccount(address)
if (!account) {
throw new Error(
`Account '${address}' does not exist on chain. Send some tokens there before trying to query sequence.`
)
}
return {
accountNumber: account.accountNumber,
sequence: account.sequence,
}
}
}

0 comments on commit 240d4b8

Please sign in to comment.