Skip to content

Commit 87264a3

Browse files
committed
feat(typescript-sdk): unwrap cw20s
1 parent 965f79d commit 87264a3

File tree

5 files changed

+135
-4
lines changed

5 files changed

+135
-4
lines changed
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
import { fromHex, http, toHex } from "viem"
2+
import { parseArgs } from "node:util"
3+
import { consola } from "scripts/logger"
4+
import { createUnionClient, hexToBytes } from "#mod.ts"
5+
import {
6+
getChannelInfo,
7+
getQuoteToken,
8+
getRecommendedChannels
9+
} from "#query/offchain/ucs03-channels"
10+
import { DirectSecp256k1Wallet } from "@cosmjs/proto-signing"
11+
import { queryContractState } from "#query/on-chain"
12+
import { SiweInvalidMessageFieldError } from "viem/siwe"
13+
14+
// hack to encode bigints to json
15+
declare global {
16+
interface BigInt {
17+
toJSON: () => string
18+
}
19+
}
20+
21+
if (!BigInt.prototype.toJSON) {
22+
Object.defineProperty(BigInt.prototype, "toJSON", {
23+
value: function () {
24+
return this.toString()
25+
},
26+
writable: true,
27+
configurable: true
28+
})
29+
}
30+
// end hack
31+
32+
const cliArgs = parseArgs({
33+
args: process.argv.slice(2),
34+
options: {
35+
"private-key": { type: "string" },
36+
"estimate-gas": { type: "boolean", default: false }
37+
}
38+
})
39+
40+
const PRIVATE_KEY = cliArgs.values["private-key"]
41+
const WRASPPED_MUNO_DENOM_CW20 = "bbn1e9ycc775kxv7klq5eh9vznjslps3tqt3f2ttku8ptky9qqt6ecjqn570rp"
42+
const AMOUNT = 12n
43+
const RECEIVER = toHex("union1qcvavxpxw3t8d9j7mwaeq9wgytkf5vwpzq6pr4")
44+
const SOURCE_CHAIN_ID = "bbn-test-5"
45+
const DESTINATION_CHAIN_ID = "union-testnet-9"
46+
47+
const baseToken = toHex(WRASPPED_MUNO_DENOM_CW20)
48+
49+
const channels = await getRecommendedChannels()
50+
51+
const channel = getChannelInfo(SOURCE_CHAIN_ID, DESTINATION_CHAIN_ID, channels)
52+
if (channel === null) {
53+
consola.info("no channel found")
54+
process.exit(1)
55+
}
56+
57+
consola.info("channel", channel)
58+
59+
consola.info("base token", baseToken)
60+
61+
const quoteToken = await getQuoteToken(SOURCE_CHAIN_ID, baseToken, channel)
62+
if (quoteToken.isErr()) {
63+
consola.info("could not get quote token")
64+
consola.error(quoteToken.error)
65+
process.exit(1)
66+
}
67+
68+
if (quoteToken.value.type === "NO_QUOTE_AVAILABLE") {
69+
consola.error("No quote token available")
70+
process.exit(1)
71+
}
72+
consola.info("quote token", quoteToken.value)
73+
74+
if (!PRIVATE_KEY) {
75+
consola.error("no private key provided")
76+
process.exit(1)
77+
}
78+
79+
const unionClient = createUnionClient({
80+
chainId: SOURCE_CHAIN_ID,
81+
account: await DirectSecp256k1Wallet.fromKey(Uint8Array.from(hexToBytes(PRIVATE_KEY)), "bbn"),
82+
gasPrice: { amount: "0.025", denom: "ubbn" },
83+
transport: http("https://rpc.bbn-test-5.babylon.chain.kitchen")
84+
})
85+
86+
const CW20_TOKEN_MINTER = "bbn143365ksyxj0zxj26djqsjltscty75qdlpwry6yxhr8ckzhq92xas8pz8sn"
87+
88+
const allowanceParams = {
89+
contractAddress: WRASPPED_MUNO_DENOM_CW20,
90+
amount: AMOUNT,
91+
spender: CW20_TOKEN_MINTER
92+
}
93+
consola.info("allowance params", allowanceParams)
94+
95+
const approveResponse = await unionClient.cw20IncreaseAllowance(allowanceParams)
96+
consola.info("approval", approveResponse)
97+
98+
let contractSTate = await queryContractState({
99+
restUrl: "https://rest.bbn-test-5.babylon.chain.kitchen",
100+
contractAddress: WRASPPED_MUNO_DENOM_CW20
101+
})
102+
consola.log("contract state", contractSTate)
103+
104+
if (approveResponse.isErr()) {
105+
consola.error(approveResponse.error)
106+
process.exit(1)
107+
}
108+
109+
consola.info("approval tx hash", approveResponse.value)
110+
111+
const transfer = await unionClient.transferAsset({
112+
baseToken: WRASPPED_MUNO_DENOM_CW20,
113+
baseAmount: AMOUNT,
114+
quoteToken: quoteToken.value.quote_token,
115+
quoteAmount: AMOUNT,
116+
receiver: RECEIVER,
117+
sourceChannelId: channel.source_channel_id,
118+
ucs03address: fromHex(`0x${channel.source_port_id}`, "string")
119+
})
120+
121+
if (transfer.isErr()) {
122+
consola.error("transfer submission failed:", transfer.error)
123+
process.exit(1)
124+
}
125+
126+
consola.info("transfer tx hash", transfer.value)

typescript-sdk/playground/union-to-babylon.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ const cliArgs = parseArgs({
3838
const PRIVATE_KEY = cliArgs.values["private-key"]
3939
const MUNO_DENOM = "muno"
4040
const AMOUNT = 12n
41-
const RECEIVER = toHex("bbn1xe0rnlh3u05qkwytkwmyzl86a0mvpwfxgf2t7u")
41+
const RECEIVER = toHex("bbn1qcvavxpxw3t8d9j7mwaeq9wgytkf5vwplf2cja")
4242
const SOURCE_CHAIN_ID = "union-testnet-9"
4343
const DESTINATION_CHAIN_ID = "bbn-test-5"
4444

typescript-sdk/src/cosmos/client.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import type {
1414
TransferAssetParameters,
1515
TransferAssetsParametersLegacy
1616
} from "../types.ts"
17+
import { isValidBech32ContractAddress } from "#mod.ts"
1718

1819
export const cosmosChainId = [
1920
"elgafar-1",
@@ -82,7 +83,10 @@ export const createCosmosClient = (parameters: CosmosClientParameters) =>
8283
salt: generateSalt()
8384
}
8485
},
85-
funds: [{ amount: baseAmount.toString(), denom: baseToken }]
86+
// If we are sending a CW20 (which is a valid bech32 address), then we do not need to attach native funds
87+
funds: isValidBech32ContractAddress(baseToken)
88+
? []
89+
: [{ amount: baseAmount.toString(), denom: baseToken }]
8690
}
8791
]
8892
})

typescript-sdk/src/generated/graphql-env.d.ts

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

typescript-sdk/src/mod.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ export {
3939
isValidEvmAddress,
4040
isValidCosmosTxHash,
4141
isValidBech32Address,
42+
isValidBech32ContractAddress,
4243
extractBech32AddressPrefix
4344
} from "./utilities/address.ts"
4445
export {

0 commit comments

Comments
 (0)