Skip to content

Commit

Permalink
Merge pull request #6216 from Agoric/6211-cli-provision
Browse files Browse the repository at this point in the history
6211 cli provision
  • Loading branch information
mergify[bot] authored Sep 15, 2022
2 parents dd2e2b9 + e442fe7 commit eb3eb6e
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 46 deletions.
10 changes: 3 additions & 7 deletions packages/agoric-cli/src/commands/perf.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,11 @@ import {
makeFollower,
makeLeaderFromRpcAddresses,
} from '@agoric/casting';
import { execSync } from 'child_process';
import { Command } from 'commander';
import fs from 'fs';
import { exit } from 'process';
import { makeLeaderOptions } from '../lib/casting.js';
import { normalizeAddress } from '../lib/keys.js';
import { execSwingsetTransaction, normalizeAddress } from '../lib/chain.js';
import { networkConfig } from '../lib/rpc.js';

// tight for perf testing but less than this tends to hang.
Expand Down Expand Up @@ -52,8 +51,6 @@ export const makePerfCommand = async logger => {
const { offer } = JSON.parse(JSON.parse(payloadStr).body);
const { id: offerId } = offer;

const { chainName, rpcAddrs } = networkConfig;

const spec = `:published.wallet.${opts.from}`;

const leaderOptions = makeLeaderOptions({
Expand Down Expand Up @@ -88,15 +85,14 @@ export const makePerfCommand = async logger => {
void watchForSatisfied();

// now execute
let cmd = `agd --node=${rpcAddrs[0]} --chain-id=${chainName} --from=${opts.from} tx swingset wallet-action --allow-spend "$(cat ${opts.executeOffer})" --yes`;
let cmd = `wallet-action --allow-spend "$(cat ${opts.executeOffer})"`;
if (opts.keyringBackend) {
cmd = cmd.concat(' --keyring-backend ', opts.keyringBackend);
}
if (opts.home) {
cmd = cmd.concat(' --home ', opts.home);
}
console.warn('Executing in shell:', cmd);
execSync(cmd);
execSwingsetTransaction(cmd, networkConfig, opts.from);
});

return perf;
Expand Down
58 changes: 44 additions & 14 deletions packages/agoric-cli/src/commands/wallet.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// @ts-check
/* eslint-disable func-names */
/* global fetch, process */
import { execSync } from 'child_process';
import {
iterateLatest,
makeCastingSpec,
Expand All @@ -15,13 +14,50 @@ import { makeRpcUtils, networkConfig } from '../lib/rpc.js';
import { getWalletState } from '../lib/wallet.js';

import { makeLeaderOptions } from '../lib/casting.js';
import { normalizeAddress } from '../lib/keys.js';
import {
execSwingsetTransaction,
fetchSwingsetParams,
normalizeAddress,
} from '../lib/chain.js';

const SLEEP_SECONDS = 3;

export const makeWalletCommand = async () => {
const wallet = new Command('wallet').description('wallet commands');

wallet
.command('provision')
.description('provision a Smart Wallet')
.requiredOption(
'--account [address]',
'address literal or name',
normalizeAddress,
)
.option('--spend', 'confirm you want to spend')
.option('--nickname [string]', 'nickname to use', 'my-wallet')
.action(function () {
const { account, nickname, spend } = this.opts();
if (spend) {
const tx = `provision-one ${nickname} ${account} SMART_WALLET`;
execSwingsetTransaction(tx, networkConfig, account);
} else {
const params = fetchSwingsetParams(networkConfig);
assert(
params.power_flag_fees.length === 1,
'multiple power_flag_fees not supported',
);
const { fee: fees } = params.power_flag_fees[0];
const nf = new Intl.NumberFormat('en-US');
const costs = fees
.map(f => `${nf.format(Number(f.amount))} ${f.denom}`)
.join(' + ');
process.stdout.write(`Provisioning a wallet costs ${costs}\n`);
process.stdout.write(
`To really provision, repeat this command with --spend\n`,
);
}
});

wallet
.command('send')
.description('send a prepared offer')
Expand All @@ -34,19 +70,13 @@ export const makeWalletCommand = async () => {
.option('--dry-run', 'spit out the command instead of running it')
.action(function () {
const { dryRun, from, offer } = this.opts();
const { chainName, rpcAddrs } = networkConfig;

const cmd = `agd --node=${rpcAddrs[0]} --chain-id=${chainName} --from=${from} tx swingset wallet-action --allow-spend "$(cat ${offer})"`;

if (dryRun) {
process.stdout.write('Run this interactive command in shell:\n\n');
process.stdout.write(cmd);
process.stdout.write('\n');
} else {
const yesCmd = `${cmd} --yes`;
console.log('Executing ', yesCmd);
execSync(yesCmd);
}
execSwingsetTransaction(
`wallet-action --allow-spend "$(cat ${offer})"`,
networkConfig,
from,
dryRun,
);
});

wallet
Expand Down
54 changes: 54 additions & 0 deletions packages/agoric-cli/src/lib/chain.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// @ts-check
/* global process */
import { normalizeBech32 } from '@cosmjs/encoding';
import { execSync } from 'child_process';

export const normalizeAddress = literalOrName => {
try {
return normalizeBech32(literalOrName);
} catch (_) {
// not an address so try as a key
const buff = execSync(`agd keys show --address ${literalOrName}`);
return normalizeBech32(buff.toString().trim());
}
};
harden(normalizeAddress);

/**
* SECURITY: closes over process and child_process
*
* @param {string} swingsetArgs
* @param {import('./rpc').MinimalNetworkConfig} net
* @param {string} from
* @param {boolean} [dryRun]
*/
export const execSwingsetTransaction = (
swingsetArgs,
net,
from,
dryRun = false,
) => {
const { chainName, rpcAddrs } = net;

const cmd = `agd --node=${rpcAddrs[0]} --chain-id=${chainName} --from=${from} tx swingset ${swingsetArgs}`;

if (dryRun) {
process.stdout.write('Run this interactive command in shell:\n\n');
process.stdout.write(cmd);
process.stdout.write('\n');
} else {
const yesCmd = `${cmd} --yes`;
console.log('Executing ', yesCmd);
execSync(yesCmd);
}
};
harden(execSwingsetTransaction);

// xxx rpc should be able to query this by HTTP without shelling out
export const fetchSwingsetParams = net => {
const { chainName, rpcAddrs } = net;
const cmd = `agd --node=${rpcAddrs[0]} --chain-id=${chainName} query swingset params --output --json`;
const buffer = execSync(cmd);
return JSON.parse(buffer.toString());
};
harden(fetchSwingsetParams);
14 changes: 0 additions & 14 deletions packages/agoric-cli/src/lib/keys.js

This file was deleted.

6 changes: 2 additions & 4 deletions packages/agoric-cli/test/agops-governance-smoketest.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,11 @@ make scenario2-setup scenario2-run-chain-psm
cd packages/cosmic-swingset
# Fund the pool
make fund-provision-pool
# Copy the agoric address from your keplr wallet or 'agd keys list', starts with 'agoric1'
KEY=<yoursBech32>
# Provision your wallet
make ACCT_ADDR=$KEY AGORIC_POWERS=SMART_WALLET fund-acct provision-acct
agoric wallet provision --account <key-name>
# verify
agoric wallet list
agoric wallet show --from \$KEY
agoric wallet show --from <key-name>
"
exit 1
fi
Expand Down
12 changes: 5 additions & 7 deletions packages/agoric-cli/test/agops-perf-smoketest.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,14 @@ cd packages/cosmic-swingset
make scenario2-setup scenario2-run-chain-psm
# (new tab)
# Fund the pool (addr is a magic string)
make SOLO_COINS=1234000000ibc/usdc1234 ACCT_ADDR=agoric1megzytg65cyrgzs6fvzxgrcqvwwl7ugpt62346 fund-acct
# Provision your wallet
cd packages/cosmic-swingset
# Copy the agoric address from your keplr wallet or 'agd keys list', starts with 'agoric1'
WALLET_ADDR=<yours>
make ACCT_ADDR=$WALLET_ADDR AGORIC_POWERS=SMART_WALLET fund-acct provision-acct
# Fund the pool
make fund-provision-pool
# Provision your wallet
agoric wallet provision --account <key-name>
# verify
agoric wallet list
agoric wallet show --from $WALLET_ADDR
agoric wallet show --from <key-name>
"
exit 1
fi
Expand Down

0 comments on commit eb3eb6e

Please sign in to comment.