|
1 | 1 | import { Decimal } from "@cosmjs/math"
|
2 | 2 | import { DirectSecp256k1HdWallet } from "@cosmjs/proto-signing"
|
3 |
| -import { Cosmos, Evm } from "@unionlabs/sdk" |
4 |
| -import { |
5 |
| - CosmWasmClientSource, |
6 |
| - createCosmWasmClient, |
7 |
| - createSigningCosmWasmClient, |
8 |
| - SigningCosmWasmClientContext, |
9 |
| -} from "@unionlabs/sdk/cosmos" |
10 |
| -import { CosmosChannelSource } from "@unionlabs/sdk/cosmos" |
11 |
| -import { |
12 |
| - createCosmosToEvmFungibleAssetOrder, |
13 |
| - Instruction, |
14 |
| - sendInstructionCosmos, |
15 |
| -} from "@unionlabs/sdk/ucs03" |
16 |
| -import { Effect } from "effect" |
17 |
| -import { http } from "viem" |
18 |
| -import { sepolia } from "viem/chains" |
19 |
| - |
20 |
| -// @ts-ignore |
21 |
| -BigInt["prototype"].toJSON = function() { |
22 |
| - return this.toString() |
23 |
| -} |
| 3 | +import { Cosmos, Evm, FungibleAssetOrder, Ucs03, Ucs05 } from "@unionlabs/sdk" |
| 4 | +import { UniversalChainId } from "@unionlabs/sdk/schema/chain" |
| 5 | +import { ChannelId } from "@unionlabs/sdk/schema/channel" |
| 6 | +import { Effect, Exit, pipe } from "effect" |
| 7 | +import { http, toHex } from "viem" |
| 8 | +import { bobSepolia } from "viem/chains" |
24 | 9 |
|
25 | 10 | const MNEMONIC = process.env.MNEMONIC || "memo memo memo"
|
26 | 11 |
|
27 |
| -const SENDER = "0x52a648ef2157fd3bafa90bbac510b9a4870fdf36" |
28 |
| -const RECEIVER = "0xfaebe5bf141cc04a3f0598062b98d2df01ab3c4d" |
29 |
| -const SOURCE_UCS03_ADDRESS = "bbn15zcptld878lux44lvc0chzhz7dcdh62nh0xehwa8y7czuz3yljlspm2re6" |
30 |
| - |
31 |
| -// toHex(intent.sender), |
32 |
| -// intent.receiver, |
33 |
| -// toHex(intent.baseToken), |
34 |
| - |
35 |
| -// Define token transfers |
36 |
| -const TRANSFERS = [ |
37 |
| - { |
38 |
| - sender: SENDER, |
39 |
| - receiver: RECEIVER, |
40 |
| - // baseToken: "bbn1nznl7srgmtx9juevnrasr2srslqzze3083g30w8ug96f96rjpeuqg8f6uw", |
41 |
| - baseToken: "ubbn", |
42 |
| - baseAmount: 100n, |
43 |
| - quoteAmount: 100n, |
44 |
| - }, |
45 |
| -] as const |
46 |
| - |
47 |
| -const createBatch = Effect.gen(function*() { |
48 |
| - yield* Effect.log("creating transfer 1") |
49 |
| - const transfer1 = yield* createCosmosToEvmFungibleAssetOrder(TRANSFERS[0]) |
50 |
| - |
51 |
| - console.log(JSON.stringify(transfer1, null, 2)) |
52 |
| - |
53 |
| - return Instruction.Batch.make({ operand: [transfer1] }) |
54 |
| -}).pipe(Effect.withLogSpan("batch creation")) |
55 |
| - |
56 |
| -// Check and increase allowances if needed |
57 |
| -const checkAndIncreaseAllowances = Effect.gen(function*() { |
58 |
| - const publicClient = (yield* ViemPublicClient).client |
59 |
| - |
60 |
| - yield* Effect.log("Checking token allowances...") |
61 |
| - |
62 |
| - // for (const transfer of TRANSFERS) { |
63 |
| - // yield* Effect.log(`checking ${transfer.baseToken} allowance...`) |
64 |
| - |
65 |
| - // // Check current allowance |
66 |
| - // const currentAllowance = yield* readErc20Allowance( |
67 |
| - // transfer.baseToken, |
68 |
| - // transfer.sender, |
69 |
| - // SOURCE_UCS03_ADDRESS |
70 |
| - // ) |
71 |
| - |
72 |
| - // yield* Effect.log(`current ${transfer.baseToken} allowance: ${currentAllowance}`) |
73 |
| - |
74 |
| - // // If allowance is insufficient, increase it |
75 |
| - // if (currentAllowance < transfer.baseAmount) { |
76 |
| - // yield* Effect.log(`increasing ${transfer.baseToken} allowance...`) |
77 |
| - |
78 |
| - // // Approve exact amount needed |
79 |
| - // const txHash = yield* increaseErc20Allowance( |
80 |
| - // transfer.baseToken, |
81 |
| - // SOURCE_UCS03_ADDRESS, |
82 |
| - // transfer.baseAmount |
83 |
| - // ) |
84 |
| - |
85 |
| - // yield* Effect.log(`approval transaction sent: ${txHash}`) |
86 |
| - |
87 |
| - // // Wait for transaction receipt |
88 |
| - // const receipt = yield* waitForTransactionReceipt(txHash) |
89 |
| - |
90 |
| - // yield* Effect.log(`approval confirmed in block: ${receipt.blockNumber}`) |
91 |
| - |
92 |
| - // // Verify new allowance |
93 |
| - // const newAllowance = yield* readErc20Allowance( |
94 |
| - // transfer.baseToken, |
95 |
| - // transfer.sender, |
96 |
| - // SOURCE_UCS03_ADDRESS |
97 |
| - // ) |
98 |
| - |
99 |
| - // yield* Effect.log(`new ${transfer.baseToken} allowance: ${newAllowance}`) |
100 |
| - // } else { |
101 |
| - // yield* Effect.log(`${transfer.baseToken} allowance is sufficient`) |
102 |
| - // } |
103 |
| - // } |
104 |
| - |
105 |
| - yield* Effect.log("All allowances checked and increased if needed") |
106 |
| -}).pipe(Effect.withLogSpan("allowance check and increase")) |
107 |
| - |
108 |
| -Effect.runPromiseExit( |
109 |
| - Effect.gen(function*() { |
110 |
| - // Create clients and setup |
111 |
| - yield* Effect.log("transferring from sepolia to stargaze") |
112 |
| - |
113 |
| - yield* Effect.log("creating clients") |
114 |
| - const cosmWasmClientSource = yield* createCosmWasmClient( |
115 |
| - "https://rpc.rpc-node.union-testnet-10.union.build", |
116 |
| - ) |
117 |
| - |
118 |
| - const publicDestinationClient = yield* createViemPublicClient({ |
119 |
| - chain: sepolia, |
120 |
| - transport: http(), |
121 |
| - }) |
122 |
| - |
123 |
| - // Create a wallet from mnemonic (in a real app, use a secure method to get this) |
124 |
| - const wallet = yield* Effect.tryPromise(() => |
125 |
| - DirectSecp256k1HdWallet.fromMnemonic(MNEMONIC, { prefix: "union" }) |
126 |
| - ) |
127 |
| - |
128 |
| - // Get the first account address |
129 |
| - const [firstAccount] = yield* Effect.tryPromise(() => wallet.getAccounts()) |
130 |
| - |
131 |
| - // Create a signing client |
132 |
| - const signingClient = yield* createSigningCosmWasmClient( |
133 |
| - "https://rpc.rpc-node.union-testnet-10.union.build", |
134 |
| - wallet, |
135 |
| - { |
136 |
| - gasPrice: { amount: Decimal.fromUserInput("1", 6), denom: "muno" }, |
137 |
| - }, |
138 |
| - ) |
139 |
| - |
140 |
| - yield* Effect.log("clients created") |
141 |
| - |
142 |
| - // Main effect: create the batch and send it |
143 |
| - return yield* Effect.gen(function*() { |
144 |
| - yield* Effect.log("creating batch") |
145 |
| - const batch = yield* createBatch |
146 |
| - yield* Effect.log("batch created", JSON.stringify(batch, null, 2)) |
147 |
| - yield* Effect.log("batch abi", Instruction.encodeAbi(batch)) |
148 |
| - |
149 |
| - // Check and increase allowances before sending the batch |
150 |
| - // yield* Effect.log("checking and increasing allowances if needed") |
151 |
| - // yield* checkAndIncreaseAllowances |
152 |
| - // yield* Effect.log("allowances verified") |
153 |
| - |
154 |
| - yield* Effect.log("sending batch") |
155 |
| - return yield* sendInstructionCosmos(batch) |
156 |
| - }).pipe( |
157 |
| - Effect.provideService(SigningCosmWasmClientContext, { |
158 |
| - client: signingClient, |
159 |
| - address: firstAccount.address, |
160 |
| - }), |
161 |
| - Effect.provideService(CosmWasmClientSource, { client: cosmWasmClientSource }), |
162 |
| - Effect.provideService(ViemPublicClientDestination, { client: publicDestinationClient }), |
163 |
| - Effect.provideService(EvmChannelDestination, { |
164 |
| - ucs03address: "0xe33534b7f8D38C6935a2F6Ad35E09228dA239962", |
165 |
| - channelId: 1, |
166 |
| - }), |
167 |
| - Effect.provideService(CosmosChannelSource, { |
168 |
| - ucs03address: SOURCE_UCS03_ADDRESS, |
169 |
| - channelId: 1, |
170 |
| - }), |
171 |
| - ) |
172 |
| - }), |
173 |
| -).then(e => { |
174 |
| - console.log(JSON.stringify(e, null, 2)) |
175 |
| - console.log(e) |
| 12 | +const SENDER = Ucs05.AddressCosmosZkgm.make(toHex("bbn122ny3mep2l7nhtafpwav2y9e5jrslhekrn8frh")) |
| 13 | +const RECEIVER = Ucs05.AddressEvmZkgm.make("0xfaebe5bf141cc04a3f0598062b98d2df01ab3c4d") |
| 14 | +const SOURCE_UCS03_ADDRESS = |
| 15 | + "bbn15zcptld878lux44lvc0chzhz7dcdh62nh0xehwa8y7czuz3yljlspm2re6" as const |
| 16 | + |
| 17 | +const main = Effect.gen(function*() { |
| 18 | + const sourceClient = Cosmos.ClientSource.Live( |
| 19 | + "https://rpc.bbn-1.babylon.chain.kitchen", |
| 20 | + ) |
| 21 | + const destinationClient = Evm.PublicClientDestination.Live({ |
| 22 | + chain: bobSepolia, |
| 23 | + transport: http(), |
| 24 | + }) |
| 25 | + const wallet = yield* Effect.tryPromise(() => |
| 26 | + DirectSecp256k1HdWallet.fromMnemonic(MNEMONIC, { prefix: "bbn" }) |
| 27 | + ) |
| 28 | + const signingClient = Cosmos.SigningClientContext.Live( |
| 29 | + "https://rest.bbn-1.babylon.chain.kitchen", |
| 30 | + wallet, |
| 31 | + { gasPrice: { amount: Decimal.fromUserInput("1", 6), denom: "ubbn" } }, |
| 32 | + ) |
| 33 | + |
| 34 | + return yield* pipe( |
| 35 | + FungibleAssetOrder.cosmosToEvm({ |
| 36 | + sender: SENDER, |
| 37 | + receiver: RECEIVER, |
| 38 | + baseToken: "ubbn", |
| 39 | + baseAmount: 100n, |
| 40 | + quoteAmount: 100n, |
| 41 | + sourceChainId: UniversalChainId.make("babylon.bbn-1"), |
| 42 | + sourceChannelId: ChannelId.make(1), |
| 43 | + }), |
| 44 | + Effect.map((intent) => Ucs03.Batch.make({ operand: [intent] })), |
| 45 | + Effect.andThen((instruction) => Cosmos.sendInstruction(instruction, SENDER)), |
| 46 | + Effect.provide(signingClient), |
| 47 | + Effect.provide(sourceClient), |
| 48 | + Effect.provide(destinationClient), |
| 49 | + Effect.provideService(Evm.ChannelDestination, { |
| 50 | + ucs03address: "0xe33534b7f8D38C6935a2F6Ad35E09228dA239962", |
| 51 | + channelId: 1, |
| 52 | + }), |
| 53 | + Effect.provideService(Cosmos.ChannelSource, { |
| 54 | + ucs03address: SOURCE_UCS03_ADDRESS, |
| 55 | + channelId: 1, |
| 56 | + }), |
| 57 | + ) |
176 | 58 | })
|
| 59 | + |
| 60 | +Effect.runPromiseExit(main).then(Exit.match({ |
| 61 | + onFailure: (cause) => console.error(JSON.stringify(cause, null, 2)), |
| 62 | + onSuccess: (result) => console.log(result), |
| 63 | +})) |
0 commit comments