1
1
import anyTest from '@endo/ses-ava/prepare-endo.js' ;
2
2
import type { TestFn } from 'ava' ;
3
3
import { AmountMath } from '@agoric/ertp' ;
4
+ import { encodeAddressHook } from '@agoric/cosmic-proto/address-hooks.js' ;
4
5
import { makeDoOffer } from '../../tools/e2e-tools.js' ;
5
6
import { commonSetup , type SetupContextWithWallets } from '../support.js' ;
6
7
import { makeQueryClient } from '../../tools/query.js' ;
7
8
import starshipChainInfo from '../../starship-chain-info.js' ;
9
+ import {
10
+ createFundedWalletAndClient ,
11
+ makeIBCTransferMsg ,
12
+ } from '../../tools/ibc-transfer.js' ;
8
13
9
14
const test = anyTest as TestFn < SetupContextWithWallets > ;
10
15
@@ -14,6 +19,69 @@ const contractName = 'swapAnything';
14
19
const contractBuilder =
15
20
'../packages/builders/scripts/testing/init-swap-anything.js' ;
16
21
22
+ const fundRemote = async (
23
+ t ,
24
+ destinationChain ,
25
+ denomToTransfer = 'ubld' ,
26
+ amount = 100000000n ,
27
+ ) => {
28
+ const { retryUntilCondition, useChain } = t . context ;
29
+
30
+ const { client, address, wallet } = await createFundedWalletAndClient (
31
+ t . log ,
32
+ destinationChain ,
33
+ useChain ,
34
+ ) ;
35
+ const balancesResult = await retryUntilCondition (
36
+ ( ) => client . getAllBalances ( address ) ,
37
+ coins => ! ! coins ?. length ,
38
+ `Faucet balances found for ${ address } ` ,
39
+ ) ;
40
+ console . log ( 'Balances:' , balancesResult ) ;
41
+
42
+ const { client : agoricClient , address : agoricAddress } =
43
+ await createFundedWalletAndClient ( t . log , 'agoric' , useChain ) ;
44
+
45
+ const balancesResultAg = await retryUntilCondition (
46
+ ( ) => agoricClient . getAllBalances ( agoricAddress ) ,
47
+ coins => ! ! coins ?. length ,
48
+ `Faucet balances found for ${ agoricAddress } ` ,
49
+ ) ;
50
+ console . log ( 'Balances AGORIC:' , balancesResultAg ) ;
51
+
52
+ const transferArgs = makeIBCTransferMsg (
53
+ { denom : denomToTransfer , value : amount } ,
54
+ { address, chainName : destinationChain } ,
55
+ { address : agoricAddress , chainName : 'agoric' } ,
56
+ Date . now ( ) ,
57
+ useChain ,
58
+ ) ;
59
+ console . log ( 'Transfer Args:' , transferArgs ) ;
60
+ // TODO #9200 `sendIbcTokens` does not support `memo`
61
+ // @ts -expect-error spread argument for concise code
62
+ const txRes = await agoricClient . sendIbcTokens ( ...transferArgs ) ;
63
+ if ( txRes && txRes . code !== 0 ) {
64
+ console . error ( txRes ) ;
65
+ throw Error ( `failed to ibc transfer funds to ${ denomToTransfer } ` ) ;
66
+ }
67
+ const { events : _events , ...txRest } = txRes ;
68
+ console . log ( txRest ) ;
69
+ t . is ( txRes . code , 0 , `Transaction succeeded` ) ;
70
+ t . log ( `Funds transferred to ${ agoricAddress } ` ) ;
71
+
72
+ await retryUntilCondition (
73
+ ( ) => client . getAllBalances ( address ) ,
74
+ coins => ! ! coins ?. length ,
75
+ `${ denomToTransfer } transferred to ${ address } ` ,
76
+ ) ;
77
+
78
+ return {
79
+ client,
80
+ address,
81
+ wallet,
82
+ } ;
83
+ } ;
84
+
17
85
test . before ( async t => {
18
86
const { setupTestKeys, ...common } = await commonSetup ( t ) ;
19
87
const { commonBuilderOpts, deleteTestKeys, startContract } = common ;
@@ -24,7 +92,7 @@ test.before(async t => {
24
92
await startContract ( contractName , contractBuilder , commonBuilderOpts ) ;
25
93
} ) ;
26
94
27
- test ( 'BLD for OSMO, receiver on Agoric' , async t => {
95
+ test . serial ( 'BLD for OSMO, receiver on Agoric' , async t => {
28
96
const {
29
97
wallets,
30
98
provisionSmartWallet,
@@ -103,6 +171,94 @@ test('BLD for OSMO, receiver on Agoric', async t => {
103
171
) ;
104
172
} ) ;
105
173
174
+ test . serial ( 'address hook - BLD for OSMO, receiver on Agoric' , async t => {
175
+ const { wallets, vstorageClient, retryUntilCondition, useChain } = t . context ;
176
+ const { getRestEndpoint, chain : cosmosChain } = useChain ( 'cosmoshub' ) ;
177
+
178
+ const { address : cosmosHubAddr , client : cosmosHubClient } = await fundRemote (
179
+ t ,
180
+ 'cosmoshub' ,
181
+ ) ;
182
+
183
+ const cosmosHubApiUrl = await getRestEndpoint ( ) ;
184
+ const cosmosHubQueryClient = makeQueryClient ( cosmosHubApiUrl ) ;
185
+
186
+ const {
187
+ transferChannel : { counterPartyChannelId } ,
188
+ } = starshipChainInfo . agoric . connections [ cosmosChain . chain_id ] ;
189
+
190
+ const apiUrl = await useChain ( 'agoric' ) . getRestEndpoint ( ) ;
191
+ const queryClient = makeQueryClient ( apiUrl ) ;
192
+
193
+ const { balances : balancesBefore } = await queryClient . queryBalances (
194
+ wallets . agoricReceiver ,
195
+ ) ;
196
+
197
+ const { hash : bldDenomOnHub } = await cosmosHubQueryClient . queryDenom (
198
+ `transfer/${ counterPartyChannelId } ` ,
199
+ 'ubld' ,
200
+ ) ;
201
+ t . log ( { bldDenomOnHub, counterPartyChannelId } ) ;
202
+
203
+ const {
204
+ sharedLocalAccount : { value : baseAddress } ,
205
+ } = await vstorageClient . queryData ( 'published.swap-anything' ) ;
206
+ t . log ( baseAddress ) ;
207
+
208
+ const orcContractReceiverAddress = encodeAddressHook ( baseAddress , {
209
+ destAddr : 'osmo17p9rzwnnfxcjp32un9ug7yhhzgtkhvl9jfksztgw5uh69wac2pgs5yczr8' ,
210
+ receiverAddr : wallets . agoricReceiver ,
211
+ outDenom : 'uosmo' ,
212
+ } ) ;
213
+
214
+ const transferArgs = makeIBCTransferMsg (
215
+ { denom : `ibc/${ bldDenomOnHub } ` , value : 125n } ,
216
+ { address : orcContractReceiverAddress , chainName : 'agoric' } ,
217
+ { address : cosmosHubAddr , chainName : 'cosmoshub' } ,
218
+ Date . now ( ) ,
219
+ useChain ,
220
+ ) ;
221
+ console . log ( 'Transfer Args:' , transferArgs ) ;
222
+ // TODO #9200 `sendIbcTokens` does not support `memo`
223
+ // @ts -expect-error spread argument for concise code
224
+ const txRes = await cosmosHubClient . sendIbcTokens ( ...transferArgs ) ;
225
+ if ( txRes && txRes . code !== 0 ) {
226
+ console . error ( txRes ) ;
227
+ throw Error ( `failed to ibc transfer funds to ibc/${ bldDenomOnHub } ` ) ;
228
+ }
229
+ const { events : _events , ...txRest } = txRes ;
230
+ console . log ( txRest ) ;
231
+ t . is ( txRes . code , 0 , `Transaction succeeded` ) ;
232
+ t . log ( `Funds transferred to ${ orcContractReceiverAddress } ` ) ;
233
+
234
+ const osmosisChainId = useChain ( 'osmosis' ) . chain . chain_id ;
235
+
236
+ const {
237
+ transferChannel : { channelId } ,
238
+ } = starshipChainInfo . agoric . connections [ osmosisChainId ] ;
239
+
240
+ const { balances : agoricReceiverBalances } = await retryUntilCondition (
241
+ ( ) => queryClient . queryBalances ( wallets . agoricReceiver ) ,
242
+ ( { balances } ) => balances . length > balancesBefore . length ,
243
+ 'Deposit reflected in localOrchAccount balance' ,
244
+ ) ;
245
+ t . log ( agoricReceiverBalances ) ;
246
+
247
+ const { hash : expectedHash } = await queryClient . queryDenom (
248
+ `transfer/${ channelId } ` ,
249
+ 'uosmo' ,
250
+ ) ;
251
+
252
+ t . log ( 'Expected denom hash:' , expectedHash ) ;
253
+
254
+ t . regex ( agoricReceiverBalances [ 0 ] ?. denom , / ^ i b c / ) ;
255
+ t . is (
256
+ agoricReceiverBalances [ 0 ] ?. denom . split ( 'ibc/' ) [ 1 ] ,
257
+ expectedHash ,
258
+ 'got expected ibc denom hash' ,
259
+ ) ;
260
+ } ) ;
261
+
106
262
test . after ( async t => {
107
263
const { deleteTestKeys } = t . context ;
108
264
deleteTestKeys ( accounts ) ;
0 commit comments