Skip to content

Commit

Permalink
test: faucetTools.fundFaucet
Browse files Browse the repository at this point in the history
- adds helper to fund agoric faucet with interchain tokens
- allows callers to request `OSMO`, `ATOM`, etc, via `provisionSmartWallet`
  • Loading branch information
0xpatrickdev committed Dec 2, 2024
1 parent 4e7cbf2 commit fd9cb7d
Show file tree
Hide file tree
Showing 7 changed files with 138 additions and 57 deletions.
60 changes: 7 additions & 53 deletions multichain-testing/test/auto-stake-it.test.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
import { type CosmosChainInfo } from '@agoric/orchestration';
import anyTest from '@endo/ses-ava/prepare-endo.js';
import type { ExecutionContext, TestFn } from 'ava';
import type { TestFn } from 'ava';
import starshipChainInfo from '../starship-chain-info.js';
import { makeDoOffer } from '../tools/e2e-tools.js';
import {
createFundedWalletAndClient,
makeIBCTransferMsg,
} from '../tools/ibc-transfer.js';
import { makeFundAndTransfer } from '../tools/ibc-transfer.js';
import { makeQueryClient } from '../tools/query.js';
import type { SetupContextWithWallets } from './support.js';
import { chainConfig, commonSetup } from './support.js';
Expand Down Expand Up @@ -38,53 +35,6 @@ test.after(async t => {
deleteTestKeys(accounts);
});

const makeFundAndTransfer = (t: ExecutionContext<SetupContextWithWallets>) => {
const { retryUntilCondition, useChain } = t.context;
return async (chainName: string, agoricAddr: string, amount = 100n) => {
const { staking } = useChain(chainName).chainInfo.chain;
const denom = staking?.staking_tokens?.[0].denom;
if (!denom) throw Error(`no denom for ${chainName}`);

const { client, address, wallet } = await createFundedWalletAndClient(
t,
chainName,
useChain,
);
const balancesResult = await retryUntilCondition(
() => client.getAllBalances(address),
coins => !!coins?.length,
`Faucet balances found for ${address}`,
);

console.log('Balances:', balancesResult);

const transferArgs = makeIBCTransferMsg(
{ denom, value: amount },
{ address: agoricAddr, chainName: 'agoric' },
{ address: address, chainName },
Date.now(),
useChain,
);
console.log('Transfer Args:', transferArgs);
// TODO #9200 `sendIbcTokens` does not support `memo`
// @ts-expect-error spread argument for concise code
const txRes = await client.sendIbcTokens(...transferArgs);
if (txRes && txRes.code !== 0) {
console.error(txRes);
throw Error(`failed to ibc transfer funds to ${chainName}`);
}
const { events: _events, ...txRest } = txRes;
console.log(txRest);
t.is(txRes.code, 0, `Transaction succeeded`);
t.log(`Funds transferred to ${agoricAddr}`);
return {
client,
address,
wallet,
};
};
};

const autoStakeItScenario = test.macro({
title: (_, chainName: string) => `auto-stake-it on ${chainName}`,
exec: async (t, chainName: string) => {
Expand All @@ -97,7 +47,11 @@ const autoStakeItScenario = test.macro({
useChain,
} = t.context;

const fundAndTransfer = makeFundAndTransfer(t);
const fundAndTransfer = makeFundAndTransfer(
t,
retryUntilCondition,
useChain,
);

// 2. Find 'stakingDenom' denom on agoric
const remoteChainInfo = (
Expand Down
8 changes: 8 additions & 0 deletions multichain-testing/test/support.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { makeHermes } from '../tools/hermes-tools.js';
import { makeNobleTools } from '../tools/noble-tools.js';
import { makeAssetInfo } from '../tools/asset-info.js';
import starshipChainInfo from '../starship-chain-info.js';
import { makeFaucetTools } from '../tools/faucet-tools.js';

export const FAUCET_POUR = 10_000n * 1_000_000n;

Expand Down Expand Up @@ -83,6 +84,12 @@ export const commonSetup = async (t: ExecutionContext) => {
const nobleTools = makeNobleTools(childProcess);
const assetInfo = makeAssetInfo(starshipChainInfo);
const chainInfo = withChainCapabilities(starshipChainInfo);
const faucetTools = makeFaucetTools(
t,
tools.agd,
retryUntilCondition,
useChain,
);

/**
* Starts a contract if instance not found. Takes care of installing
Expand Down Expand Up @@ -123,6 +130,7 @@ export const commonSetup = async (t: ExecutionContext) => {
startContract,
assetInfo,
chainInfo,
faucetTools,
};
};

Expand Down
15 changes: 14 additions & 1 deletion multichain-testing/tools/agd-lib.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,19 @@ export const makeAgd = ({ execFileSync }) => {
},
).toString();
},
/** @param {string} name key name in keyring */
showAddress: name => {
return execFileSync(
kubectlBinary,
[...binaryArgs, 'keys', 'show', name, '-a', ...keyringArgs],
{
encoding: 'utf-8',
stdio: ['pipe', 'pipe', 'ignore'],
},
)
.toString()
.trim();
},
/** @param {string} name */
delete: name => {
return exec([...keyringArgs, 'keys', 'delete', name, '-y'], {
Expand All @@ -181,7 +194,7 @@ export const makeAgd = ({ execFileSync }) => {
return make();
};

/** @typedef {ReturnType<makeAgd>} Agd */
/** @typedef {ReturnType<typeof makeAgd>} Agd */

/** @param {{ execFileSync: typeof import('child_process').execFileSync, log: typeof console.log }} powers */
export const makeCopyFiles = (
Expand Down
7 changes: 6 additions & 1 deletion multichain-testing/tools/e2e-tools.js
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,11 @@ export const provisionSmartWallet = async (
// TODO: skip this query if balances is {}
const vbankEntries = await q.queryData('published.agoricNames.vbankAsset');
const byName = Object.fromEntries(
vbankEntries.map(([_denom, info]) => [info.issuerName, info]),
vbankEntries.map(([denom, info]) => {
/// XXX better way to filter out old ATOM denom?
if (denom === 'ibc/toyatom') return [undefined, undefined];
return [info.issuerName, info];
}),
);
progress({ send: balances, to: address });

Expand Down Expand Up @@ -540,6 +544,7 @@ export const makeE2ETools = async (
/** @param {string} name */
deleteKey: async name => agd.keys.delete(name),
copyFiles,
agd,
};
};

Expand Down
44 changes: 44 additions & 0 deletions multichain-testing/tools/faucet-tools.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import type { ExecutionContext } from 'ava';
import type { Denom } from '@agoric/orchestration';
import { makeFundAndTransfer } from './ibc-transfer.js';
import type { MultichainRegistry } from './registry.js';
import type { RetryUntilCondition } from './sleep.js';
import type { AgdTools } from './agd-tools.js';

type ChainName = string;

// 90% of default faucet pour
const DEFAULT_QTY = (10_000_000_000n * 9n) / 10n;

/**
* Determines the agoric `faucet` address and sends funds to it.
*
* Allows use of brands like OSMO, ATOM, etc. with `provisionSmartWallet`.
*/
export const makeFaucetTools = (
t: ExecutionContext,
agd: AgdTools['agd'],
retryUntilCondition: RetryUntilCondition,
useChain: MultichainRegistry['useChain'],
) => {
return {
/**
* @param assets denom on the issuing chain
* @param [qty] number of tokens
*/
fundFaucet: async (assets: [ChainName, Denom][], qty = DEFAULT_QTY) => {
const faucetAddr = agd.keys.showAddress('faucet');
console.log(`Faucet address: ${faucetAddr}`);

const fundAndTransfer = makeFundAndTransfer(
t,
retryUntilCondition,
useChain,
);

for (const [chainName, denom] of assets) {
await fundAndTransfer(chainName, faucetAddr, qty, denom);
}
},
};
};
59 changes: 57 additions & 2 deletions multichain-testing/tools/ibc-transfer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { MsgTransfer } from '@agoric/cosmic-proto/ibc/applications/transfer/v1/t
import { createWallet } from './wallet.js';
import chainInfo from '../starship-chain-info.js';
import type { MultichainRegistry } from './registry.js';
import type { RetryUntilCondition } from './sleep.js';

interface MakeFeeObjectArgs {
denom?: string;
Expand Down Expand Up @@ -118,14 +119,14 @@ export const makeIBCTransferMsg = (
};

export const createFundedWalletAndClient = async (
t: ExecutionContext,
log: (...args: unknown[]) => void,
chainName: string,
useChain: MultichainRegistry['useChain'],
) => {
const { chain, creditFromFaucet, getRpcEndpoint } = useChain(chainName);
const wallet = await createWallet(chain.bech32_prefix);
const address = (await wallet.getAccounts())[0].address;
t.log(`Requesting faucet funds for ${address}`);
log(`Requesting faucet funds for ${address}`);
await creditFromFaucet(address);
// TODO use telescope generated rpc client from @agoric/cosmic-proto
// https://github.com/Agoric/agoric-sdk/issues/9200
Expand All @@ -135,3 +136,57 @@ export const createFundedWalletAndClient = async (
);
return { client, wallet, address };
};

export const makeFundAndTransfer = (
t: ExecutionContext,
retryUntilCondition: RetryUntilCondition,
useChain: MultichainRegistry['useChain'],
) => {
return async (
chainName: string,
agoricAddr: string,
amount = 100n,
denom?: string,
) => {
const { staking } = useChain(chainName).chainInfo.chain;
const denomToTransfer = denom || staking?.staking_tokens?.[0].denom;
if (!denomToTransfer) throw Error(`no denom for ${chainName}`);

const { client, address, wallet } = await createFundedWalletAndClient(
t.log,
chainName,
useChain,
);
const balancesResult = await retryUntilCondition(
() => client.getAllBalances(address),
coins => !!coins?.length,
`Faucet balances found for ${address}`,
);
console.log('Balances:', balancesResult);

const transferArgs = makeIBCTransferMsg(
{ denom: denomToTransfer, value: amount },
{ address: agoricAddr, chainName: 'agoric' },
{ address: address, chainName },
Date.now(),
useChain,
);
console.log('Transfer Args:', transferArgs);
// TODO #9200 `sendIbcTokens` does not support `memo`
// @ts-expect-error spread argument for concise code
const txRes = await client.sendIbcTokens(...transferArgs);
if (txRes && txRes.code !== 0) {
console.error(txRes);
throw Error(`failed to ibc transfer funds to ${chainName}`);
}
const { events: _events, ...txRest } = txRes;
console.log(txRest);
t.is(txRes.code, 0, `Transaction succeeded`);
t.log(`Funds transferred to ${agoricAddr}`);
return {
client,
address,
wallet,
};
};
};
2 changes: 2 additions & 0 deletions multichain-testing/tools/sleep.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,5 @@ export const makeRetryUntilCondition = (defaultOptions: RetryOptions = {}) => {
...options,
});
};

export type RetryUntilCondition = ReturnType<typeof makeRetryUntilCondition>;

0 comments on commit fd9cb7d

Please sign in to comment.