-
Notifications
You must be signed in to change notification settings - Fork 231
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
a868412
commit f27ebfe
Showing
3 changed files
with
198 additions
and
1 deletion.
There are no files selected for viewing
90 changes: 90 additions & 0 deletions
90
multichain-testing/test/fast-usdc/noble-forwarding.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
import anyTest from '@endo/ses-ava/prepare-endo.js'; | ||
import type { TestFn } from 'ava'; | ||
import { commonSetup, type SetupContext } from '../support.js'; | ||
import { createWallet } from '../../tools/wallet.js'; | ||
import type { IBCConnectionInfo } from '@agoric/orchestration'; | ||
import { makeQueryClient } from '../../tools/query.js'; | ||
|
||
const test = anyTest as TestFn<SetupContext>; | ||
|
||
test('noble forwarding', async t => { | ||
const { nobleTools, retryUntilCondition, useChain, vstorageClient } = | ||
await commonSetup(t); | ||
|
||
const agoricWallet = await createWallet('agoric'); | ||
const agoricAddr = (await agoricWallet.getAccounts())[0].address; | ||
t.log('Made agoric wallet:', agoricAddr); | ||
|
||
const agoricChainId = useChain('agoric').chain.chain_id; | ||
// TODO registry 'name' doesn't work with `type: custom`? | ||
// const nobleChainId = useChain('noble').chain.chain_id; | ||
const nobleChainId = 'noblelocal'; | ||
|
||
const connInfoPath = `published.agoricNames.chainConnection.${agoricChainId}_${nobleChainId}`; | ||
const { | ||
transferChannel: { counterPartyChannelId, channelId }, | ||
}: IBCConnectionInfo = await vstorageClient.queryData(connInfoPath); | ||
|
||
t.regex( | ||
counterPartyChannelId, | ||
/^channel-/, | ||
'counterPartyChannelId retrieved from vstorage', | ||
); | ||
t.log(`Found noble->agoric channelId in vstorage: ${counterPartyChannelId}`); | ||
|
||
t.log( | ||
`Registering forwarding account for ${counterPartyChannelId} ${agoricAddr}...`, | ||
); | ||
const registerFwdAcctTx = nobleTools.registerForwardingAcct( | ||
counterPartyChannelId, | ||
agoricAddr, | ||
); | ||
t.is(registerFwdAcctTx?.code, 0, 'registered forwarding account'); | ||
t.log('Register forwarding account tx:', { | ||
code: registerFwdAcctTx?.code, | ||
height: registerFwdAcctTx?.height, | ||
txhash: registerFwdAcctTx?.txhash, | ||
}); | ||
|
||
const { address: nobleForwardingAddr, exists } = | ||
nobleTools.queryForwardingAddress(counterPartyChannelId, agoricAddr); | ||
t.regex(nobleForwardingAddr, /^noble1/, 'noble forwarding address'); | ||
t.is(exists, true, 'forwarding address exists'); | ||
t.log(`Got forwarding address: ${nobleForwardingAddr}`); | ||
|
||
const qty = 10_000_000n; | ||
t.log( | ||
`Initiating mock cctp mint for ${qty} uusdc to ${nobleForwardingAddr}...`, | ||
); | ||
const cctpMintTx = nobleTools.mockCctpMint(qty, nobleForwardingAddr); | ||
t.is(cctpMintTx?.code, 0, 'mocked cctp mint'); | ||
t.log('Mocked CCTP Mint tx:', { | ||
code: cctpMintTx?.code, | ||
height: cctpMintTx?.height, | ||
txhash: cctpMintTx?.txhash, | ||
}); | ||
|
||
const apiUrl = await useChain('agoric').getRestEndpoint(); | ||
const queryClient = makeQueryClient(apiUrl); | ||
|
||
const { balances } = await retryUntilCondition( | ||
() => queryClient.queryBalances(agoricAddr), | ||
({ balances }) => !!balances.length, | ||
`${agoricAddr} received forwarded funds from noble`, | ||
); | ||
t.is(BigInt(balances[0]?.amount), qty, 'got tokens'); | ||
t.log('Received forwarded funds from noble:', balances); | ||
|
||
const { hash: expectedHash } = await queryClient.queryDenom( | ||
`transfer/${channelId}`, | ||
'uusdc', | ||
); | ||
t.log('Expected denom hash:', expectedHash); | ||
|
||
t.regex(balances[0]?.denom, /^ibc/); | ||
t.is( | ||
balances[0]?.denom.split('ibc/')[1], | ||
expectedHash, | ||
'got expected ibc denom hash', | ||
); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
import type { IBCChannelID } from '@agoric/vats'; | ||
import type { ExecSync } from './agd-lib.js'; | ||
import type { ChainAddress } from '@agoric/orchestration'; | ||
|
||
const kubectlBinary = 'kubectl'; | ||
const noblePod = 'noblelocal-genesis-0'; | ||
const nobleBinary = 'nobled'; | ||
|
||
const makeKubeArgs = () => { | ||
return [ | ||
'exec', | ||
'-i', | ||
noblePod, | ||
'-c', | ||
'validator', | ||
'--tty=false', | ||
'--', | ||
nobleBinary, | ||
]; | ||
}; | ||
|
||
export const makeNobleTools = ({ | ||
execFileSync, | ||
}: { | ||
execFileSync: ExecSync; | ||
}) => { | ||
const exec = ( | ||
args: string[], | ||
opts = { encoding: 'utf-8' as const, stdio: ['ignore', 'pipe', 'ignore'] }, | ||
) => execFileSync(kubectlBinary, [...makeKubeArgs(), ...args], opts); | ||
|
||
const checkEnv = () => { | ||
if (process.env.FILE !== 'config.fusdc.yaml') { | ||
console.error('Warning: Noble chain must be running for this to work'); | ||
} | ||
}; | ||
|
||
const registerForwardingAcct = ( | ||
channelId: IBCChannelID, | ||
address: ChainAddress['value'], | ||
) => { | ||
checkEnv(); | ||
return JSON.parse( | ||
exec([ | ||
'tx', | ||
'forwarding', | ||
'register-account', | ||
channelId, | ||
address, | ||
'--from=genesis', | ||
'-y', | ||
'-b', | ||
'block', | ||
]), | ||
); | ||
}; | ||
|
||
const mockCctpMint = (amount: bigint, destination: ChainAddress['value']) => { | ||
checkEnv(); | ||
return JSON.parse( | ||
exec([ | ||
'tx', | ||
'bank', | ||
'send', | ||
'faucet', | ||
destination, | ||
`${Number(amount)}uusdc`, | ||
'--from=faucet', | ||
'-y', | ||
'-b', | ||
'block', | ||
]), | ||
); | ||
}; | ||
|
||
const queryForwardingAddress = ( | ||
channelId: IBCChannelID, | ||
address: ChainAddress['value'], | ||
) => { | ||
checkEnv(); | ||
return JSON.parse( | ||
exec([ | ||
'query', | ||
'forwarding', | ||
'address', | ||
channelId, | ||
address, | ||
'--output=json', | ||
]), | ||
); | ||
}; | ||
|
||
return { | ||
mockCctpMint, | ||
queryForwardingAddress, | ||
registerForwardingAcct, | ||
}; | ||
}; | ||
|
||
export type NobleTools = ReturnType<typeof makeNobleTools>; |