Skip to content

Commit 72778b4

Browse files
committed
feat: query cw20 token metadata
1 parent ad18bd9 commit 72778b4

File tree

5 files changed

+113
-1
lines changed

5 files changed

+113
-1
lines changed

typescript-sdk/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@unionlabs/client",
3-
"version": "0.0.58",
3+
"version": "0.0.59",
44
"homepage": "https://union.build",
55
"description": "Union Labs cross-chain transfers client",
66
"type": "module",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { queryCosmosCW20AddressBalance } from "#mod.ts"
2+
3+
const balance = await queryCosmosCW20AddressBalance({
4+
address: "bbn1xe0rnlh3u05qkwytkwmyzl86a0mvpwfxgf2t7u",
5+
contractAddress: "bbn192gwgengt32um4qshvhg5f3prtey2g6xmyrmkd87xvy59elaw5vs504zeg",
6+
chainId: "bbn-test-5"
7+
})
8+
9+
if (balance.isErr()) {
10+
console.error(balance.error)
11+
} else {
12+
console.info(balance.value)
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { queryCosmosC20TokenMetadata } from "#mod.ts"
2+
3+
const metadata = await queryCosmosC20TokenMetadata({
4+
contractAddress: "bbn192gwgengt32um4qshvhg5f3prtey2g6xmyrmkd87xvy59elaw5vs504zeg",
5+
chainId: "bbn-test-5"
6+
})
7+
8+
if (metadata.isErr()) {
9+
console.error(metadata.error)
10+
} else {
11+
console.info(metadata.value)
12+
}

typescript-sdk/src/mod.ts

+2
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ export {
4545
export {
4646
getCosmosHeight,
4747
queryContractState,
48+
queryCosmosCW20AddressBalance,
49+
queryCosmosC20TokenMetadata,
4850
getCosmosTransactionReceipt,
4951
getAptosAccountTransactions,
5052
getCosmosAccountTransactions

typescript-sdk/src/query/on-chain.ts

+85
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import { ofetch } from "ofetch"
22
import type { Prettify } from "../types.ts"
33
import { Base64, Hex, Json } from "ox"
4+
import { ResultAsync, err, ok, type Result } from "neverthrow"
5+
import { CosmWasmClient } from "@cosmjs/cosmwasm-stargate"
6+
import { cosmosRpcs, type CosmosChainId } from "#cosmos/client.ts"
47

58
type rpcUrlArgument = { rpcUrl: string }
69
export type RpcQueryPath = "height" | "block" | "transaction" | "net_info" | "health"
@@ -36,6 +39,88 @@ type CosmosTransactionReceipt = {
3639
}
3740
}
3841

42+
/**
43+
* get the balance of a given address for a given cw20 contract
44+
* @example
45+
* ```ts
46+
* const balance = await getCosmosCW20AddressBalance({
47+
* chainId: "bbn-test-5",
48+
* address: "bbn1xe0rnlh3u05qkwytkwmyzl86a0mvpwfxgf2t7u",
49+
* contractAddress: "bbn192gwgengt32um4qshvhg5f3prtey2g6xmyrmkd87xvy59elaw5vs504zeg",
50+
* })
51+
*/
52+
export async function queryCosmosCW20AddressBalance({
53+
address,
54+
contractAddress,
55+
chainId
56+
}: {
57+
address: string
58+
contractAddress: string
59+
chainId: CosmosChainId
60+
}): Promise<Result<string, Error>> {
61+
let rpc = cosmosRpcs[chainId] // as is valid bc of the check in the if statement.
62+
let publicClient = await ResultAsync.fromPromise(CosmWasmClient.connect(rpc), error => {
63+
return new Error(`failed to create public cosmwasm client with rpc ${rpc}`, { cause: error })
64+
})
65+
if (publicClient.isErr()) return err(publicClient.error)
66+
67+
let client = publicClient.value
68+
const balance = ResultAsync.fromPromise(
69+
client.queryContractSmart(contractAddress, { balance: { address } }),
70+
error => {
71+
return new Error(`failed to query balance for contract ${contractAddress}`, { cause: error })
72+
}
73+
)
74+
75+
return balance.andThen(balance => ok(balance.balance))
76+
}
77+
78+
/**
79+
* get the metadata of a given cw20 contract
80+
* @example
81+
* ```ts
82+
* const metadata = await queryCosmosC20TokenMetadata({
83+
* contractAddress: "bbn192gwgengt32um4qshvhg5f3prtey2g6xmyrmkd87xvy59elaw5vs504zeg",
84+
* chainId: "bbn-test-5"
85+
* })
86+
* ```
87+
*/
88+
export async function queryCosmosC20TokenMetadata({
89+
contractAddress,
90+
chainId
91+
}: {
92+
contractAddress: string
93+
chainId: CosmosChainId
94+
}): Promise<
95+
Result<
96+
{
97+
name: string
98+
symbol: string
99+
decimals: number
100+
total_supply: string
101+
},
102+
Error
103+
>
104+
> {
105+
let rpc = cosmosRpcs[chainId] // as is valid bc of the check in the if statement.
106+
let publicClient = await ResultAsync.fromPromise(CosmWasmClient.connect(rpc), error => {
107+
return new Error(`failed to create public cosmwasm client with rpc ${rpc}`, { cause: error })
108+
})
109+
if (publicClient.isErr()) return err(publicClient.error)
110+
let client = publicClient.value
111+
const response = ResultAsync.fromPromise(
112+
client.queryContractSmart(contractAddress, {
113+
token_info: {}
114+
}),
115+
error => {
116+
return new Error(`failed to query token info for contract ${contractAddress}`, {
117+
cause: error
118+
})
119+
}
120+
)
121+
return response
122+
}
123+
39124
const CW20_PREFIXES = [
40125
"\u0000\x07",
41126
"\u0000\x08",

0 commit comments

Comments
 (0)