Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(inter-protocol): psm-tool CLI, Google Sheets support #6015

Closed
wants to merge 11 commits into from

Conversation

dckc
Copy link
Member

@dckc dckc commented Aug 20, 2022

fixes: #5119
refs: #3628

todo:

  • move to its own package
  • bug: supported networks don't include mainnet
  • bug: only 1 reference asset supported
  • review git history; consider cleaning it up

Description

The tool describes itself as follows:

agoric-sdk/packages/inter-protocol$ node scripts/psm-tool.js

Usage:
to get contract instance boardId and, optionally, fees
  psm-tool --contract [--verbose]
to write an offer to stdout
  psm-tool --wantStable ANCHOR_TOKENS --boardId BOARD_ID [--feePct PCT]
  psm-tool --giveStable IST_TOKENS --boardId BOARD_ID [--feePct PCT]
to get succinct offer status and purse balances
  psm-tool --wallet AGORIC_ADDRESS

NOTE: --contract and --wallet may need --experimental-fetch node option.

For example:

psmInstance=$(psm-tool --contract)
psm-tool --contract --verbose # to get fees
psm-tool --wantStable 100 --boardId $psmInstance --feePct 0.01 >,psm-offer-action.json

# sign and send
agd --node=https://xnet.rpc.agoric.net/ --chain-id=agoricxnet-13   --from=LEDGER_KEY_NAME --sign-mode=amino-json   tx swingset wallet-action --allow-spend "$(cat ,psm-offer-action.json)"    

# check results
psm-tool --wallet agoric1....

Security Considerations

This tool only reads the chain and formats offers; it relies on agd for key management, signing, and broadcasting.

Documentation Considerations

???

Testing Considerations

I tested it on xnet manually with a ledger hardware signer (details to appear in subsequent comments).

I'd like someone to reproduce my results.

@dckc
Copy link
Member Author

dckc commented Aug 20, 2022

notes, in progress

Set up psm-tool

cp scripts/psm-tool.js ~/bin/psm-tool
chmod +x ~/bin/psm-tool

TODO: get yarn to do this

node fetch

export NODE_OPTIONS=--experimental-fetch
export NODE_NO_WARNINGS=1

node 14 is too old; try nvm?

Format your offer

Look up the PSM instance boardId

and check fees:

psmInstance=$(psm-tool --contract --verbose)
vstorage published.* [ 'agoricNames', 'psm', 'wallet' ]
psm { boardId: 'board00917', iface: 'Alleged: InstanceHandle' } [ 'Electorate', 'GiveStableFee', 'MintLimit', 'WantStableFee' ]
WantStableFee 0.01 % GiveStableFee 0.03 %

Format your offer

I had to bump the fees up by a tiny bit to get it to work.

psm-tool --boardId $psmInstance --wantStable 100 --feePct 0.011 >,psm-offer-action.json
cat ,psm-offer-action.json
{
  "type": "acceptOffer",
  "data": {
    "id": "1661232028916",
    "instancePetname": "instance@board00917",
    "requestContext": {
      "dappOrigin": "unknown",
      "origin": "unknown"
    },
    "meta": {
      "id": "1661232028916",
      "creationStamp": 1661232028916
    },
    "status": "proposed",
    "invitationMaker": {
      "method": "makeSwapInvitation"
    },
    "instanceHandleBoardId": "board00917",
    "proposalTemplate": {
      "give": {
        "In": {
          "pursePetname": "AUSD",
          "value": 100011000
        }
      },
      "want": {
        "Out": {
          "pursePetname": "Agoric stable local currency",
          "value": 100000000
        }
      }
    }
  }
}

Send the offer using agd

add a key using agd as usual for comsos-sdk CLI usage

using a ledger is optional

  1. connect your ledger and open the cosmos app
  2. agd keys add lx --ledger --coin-type=118
  3. approve on the ledger
  4. verify the results:
$ agd keys list
- name: lx
  type: ledger
  address: agoric168rp3ugmpu0jtla5wjkdlqg20rpv65xxzkh8yp
  pubkey: '{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"AptBUYCTVohDY5+iUqVZ+1If3NhuMMrKfzDUORV74Q6b"}'
  mnemonic: ""

provision a smart-wallet account using the xnet faucet

confirm:

$ chain_opts="--node=https://xnet.rpc.agoric.net:443 --chain-id=agoricxnet-13"
$ agd query bank balances agoric168rp3ugmpu0jtla5wjkdlqg20rpv65xxzkh8yp $chain_opts
balances:
- amount: "25000000"
  denom: uist

$ agd $chain_opts query vstorage children published.wallet.agoric168rp3ugmpu0jtla5wjkdlqg20rpv65xxzkh8yp
children: []
pagination: null

Get a whale to send you some ibc/toyusdc

The whale does something like:

# agd tx bank send self $dc_8yp 500000000ibc/toyusdc $chain_opts $keyring $tx_opts
txhash: 4BC13A7C210549B34168B16E31C94C79FB0D692512AC91C83401CAD0245E2EFE

# echo $dc_8yp
agoric168rp3ugmpu0jtla5wjkdlqg20rpv65xxzkh8yp
# echo $keyring
--keyring-backend=test --home=/state/...
# echo $tx_opts
--gas=auto --gas-adjustment=1.2 --broadcast-mode=block

Then you can confirm with agd query bank balances as above.

send it

agd --from=lx --sign-mode=amino-json tx swingset wallet-action --allow-spend "$(cat ,psm-offer-action.json)"  --node=https://xnet.rpc.agoric.net:443 --chain-id=agoricxnet-13

check the results in your wallet

psm-tool --wallet agoric168rp3ugmpu0jtla5wjkdlqg20rpv65xxzkh8yp

it may take a few seconds for the offer to show up as pending and a minute or two for it to get to accept.

@dckc
Copy link
Member Author

dckc commented Aug 21, 2022

handles both --giveStable and --wantStable

balances before this trade:

  balances: [
    '[null,"zoe invite"]',
    '[0,"BLD"]',
    '[125.000998,"IST"]',
    '[399.989,"AUSD"]',
    '[0,"IbcATOM"]'
  ],

then:

$ node scripts/psm-tool.js --giveStable 45 --boardId $psmInstance --feePct 0.031 >,psm-offer-action.json 

$ agd --from=k1 tx swingset wallet-action --allow-spend "$(cat ,psm-offer-action.json)"  --node=[https://xnet.rpc.agoric.net:443](https://xnet.rpc.agoric.net/) --chain-id=agoricxnet-13 -y
...
txhash: 25AD7CA51B8078FC1CFD06009206B258802636B40D71AD6FBA9B57E4F7BBBCBC

$ node --experimental-fetch scripts/psm-tool.js --wallet agoric1gskrw4kzxrck2t4ywfra4ag6zvl855r0n2p8r8
{
  balances: [
    '[null,"zoe invite"]',
    '[0,"BLD"]',
    '[80.000998,"IST"]',
    '[399.989,"AUSD"]',
    '[0,"IbcATOM"]'
  ],
  offers: [
    '["2022-08-21T04:32:33.763Z","rejected","psm","swap",{"give":{"In":[100,"AUSD"]},"want":{"Out":[100,"IST"]}}]',
    '["2022-08-21T04:42:17.890Z","accept","psm","swap",{"give":{"In":[100,"AUSD"]},"want":{"Out":[100,"IST"]}}]',
    '["2022-08-21T04:45:46.093Z","accept","psm","swap",{"give":{"In":[100,"AUSD"]},"want":{"Out":[100,"IST"]}}]',
    '["2022-08-21T04:49:13.105Z","accept","psm","swap",{"give":{"In":[100.01,"AUSD"]},"want":{"Out":[100,"IST"]}}]',
    '["2022-08-21T04:54:54.602Z","accept","psm","swap",{"give":{"In":[100.011,"AUSD"]},"want":{"Out":[100,"IST"]}}]',
    '["2022-08-21T05:03:40.199Z","pending","psm","swap",{"give":{"In":[45,"IST"]},"want":{"Out":[45.01395,"AUSD"]}}]'
  ]
}

@dckc
Copy link
Member Author

dckc commented Aug 22, 2022

@dtribble suggested making 1000 trades with this tool.

I got as far as making 1 in psm-load.mjs in instagoric 46d29db.

@dckc dckc mentioned this pull request Aug 22, 2022
@dckc
Copy link
Member Author

dckc commented Aug 31, 2022

Managing this on an agoric-sdk branch is awkward because I want to use it to test other branches.

a recent version:
https://gist.github.com/dckc/dfc2182a59b11ec4527349afd5ca050f#file-psm-tool-js

cc @gibson042

@dckc
Copy link
Member Author

dckc commented Sep 2, 2022

Spreadsheet front-end for PSM / wallet

I made a spreadsheet that works like the psm-tool cli:

image

-- Agoric Fun - Google Sheets

cc @rowgraus @nalinbhatt @btulloh @samsiegart @Chris-Hibbert @kennyrowe @turadg

@dckc dckc changed the title feat(inter-protocol): cli for PSM can trade ibc/toyusdc for IST (with ledger) feat(inter-protocol): psm-tool CLI, Google Sheets support Sep 2, 2022
@dckc
Copy link
Member Author

dckc commented Sep 6, 2022

no longer aimed for the product
#5119 (comment)

@dckc dckc closed this Sep 6, 2022
@dckc dckc reopened this Sep 7, 2022
dckc added 11 commits September 7, 2022 00:26
refactor: use types of observedSpendAction

feat: miniMarshal

chore: separate flags from opts

fixup: typeof fetch comment

fixup: types for main

refactor: parseCapData

feat: getOfferState (WIP)

fixup: opts / flags
fixup: docs for --addr

feat(psm-tool): show purse balances scaled, with petnames

 - refactor: vstorage.read, storageNode.unserialize, fromBoard

feat(psm-tool): format offers nicely

fix!(psm-tool): --addr => --wallet, --lookup => --contract

 - format fee ratios with asPercent()

feat!(psm-tool): --wantStable, --giveStable, --feePct

fix(psm-tool): include Fee when showing WantStableFee

chore(psm-tool): updated PSM, vstorage APIs

 - PSM API:
   - split invitation making methods
   - published.psm.IST.AUSD.governance storage path
 - handle multi-valued vstorage
   - a bit of error handling in vstorage query
 - support local, ollinet, xnet networks
 - avoid assert module dependency
 - assert .at(-1) doesn't return undefined
chore(psm-tool): capData debugging

fix(psm-tool): fee handling
chore(psm-tool): sync with Google sheet

chore(psm-tool): move psm-tool.js to src/

chore(psm-tool): split between script and lib

chore(psm-tool): rename Code.js from google sheets

refactor(psm-tool): move CLI details out of src/psm-lib.js

chore(psm-tool): move Google apps scripts stuff to app/

fixup(psm-tool): duplicate assert in sheets-lib.js

feat(psm-tool): simpleWalletState for use in Google Sheets

 - theWeb

fix(psm-tool): avoid xs.last() in Google Apps Script

also:
 - 1_000_000
 - 123n

build(psm-tool): build, clasp:push

chore(psm-tool): ignore google apps scripts config
test(psm-tool): testFormatOffer apps script

style(psm-tool): lint

refactor(psm-tool): getContractState
feat(psm-tool): updateClock to trigger wallet update
@dckc
Copy link
Member Author

dckc commented Sep 7, 2022

@dckc dckc mentioned this pull request Sep 8, 2022
@dckc
Copy link
Member Author

dckc commented Sep 8, 2022

throw-away prototype (unless/until we reconsider)

@dckc dckc closed this Sep 8, 2022
@dckc
Copy link
Member Author

dckc commented Sep 10, 2022

@arirubinstein @turadg @dtribble @Hibbert I hacked together a quick update to psm-tool that supports setting the id in a trade and looking up an offer by id. Exactly how to tell that a trade is done isn't quite clear to me yet, but maybe numWantsSatisfied would work.

$ psm-tool --wantMinted 6 --feePct 0.01 --id 1662785326898|tee ,want.json
{"body":"{\"method\":\"executeOffer\",\"offer\":{\"id\":1662785326898,\"invitationSpec\":{\"source\":\"contract\",\"instance\":{\"@qclass\":\"slot\",\"index\":0},\"publicInvitationMaker\":\"makeWantMintedInvitation\"},\"proposal\":{\"give\":{\"In\":{\"brand\":{\"@qclass\":\"slot\",\"index\":1},\"value\":{\"@qclass\":\"bigint\",\"digits\":\"6000601\"}}},\"want\":{\"Out\":{\"brand\":{\"@qclass\":\"slot\",\"index\":2},\"value\":{\"@qclass\":\"bigint\",\"digits\":\"6000000\"}}}}}}","slots":["board05311","board0592","board0257"]}

as well as finding a trade by id:

$ node ./scripts/psm-tool.js --wallet $addr --offer 1662784949972
{
  numWantsSatisfied: 1,
  payouts: { In: [ 0, 'AUSD' ], Out: [ 6, 'Agoric stable local currency' ] }
}

I like to run it as watch "node ./scripts/psm-tool.js --wallet $addr --offer 1662784949972".

The single-file form is in a gist: psm-tool

@turadg turadg mentioned this pull request Sep 10, 2022
@Chris-Hibbert
Copy link
Contributor

In my copy of psm-tool, I added

const makePSMVoteProposal = (instance, brands, opts, timeStamp) => {
  /** @type {OfferSpec} */
  const offer = {
    id: timeStamp,
    invitationSpec: {
      source: 'purse',
      instance,
      publicInvitationMaker: 'VoteOnPauseOffers',
      description: 'PSM charter member invitation',
    },
    proposal: {},
  };

  /** @type {BridgeAction} */
  const spendAction = {
    method: 'executeOffer',
    offer,
  };
  return spendAction;
};

and then changed main to look like this:

const main = async (argv, { fetch, clock }) => {
  const { opts, flags } = parseArgs(argv, ['--contract', '--verbose']);

  if (flags.contract || opts.wallet) {
    assert(fetch, 'missing fetch API; try --experimental-fetch?');
    // @ts-expect-error what's up with typeof fetch???
    return online(opts, flags, { fetch });
  }

  if (!(opts.wantStable || opts.giveStable)) {
    console.error(USAGE);
    return 1;
  }

  const fromBoard = makeFromBoard();
  const net = networks[opts.net || 'local'];
  assert(net, opts.net);
  const getJSON = async url => (await fetch(log('url')(net.rpc + url))).json();
  const agoricNames = await makeAgoricNames(fromBoard, getJSON);
  const instance = agoricNames.instance.psmCharter;
  const spendAction = makePSMVoteProposal(
    instance,
    agoricNames.brand,
    // @ts-expect-error
    opts,
    clock().valueOf(),
  );
  console.log(JSON.stringify(miniMarshal().serialize(spendAction)));
  return 0;
};

We'll clearly need a main that discriminates more options, but this is sufficient to create requests that look like this for me:

{"body":"{\"method\":\"executeOffer\",\"offer\":{\"id\":1662759063666,\"invitationSpec\":{\"source\":\"purse\",\"instance\":{\"@qclass\":\"slot\",\"index\":0},\"publicInvitationMaker\":\"VoteOnPauseOffers\",\"description\":\"PSM charter member invitation\"},\"proposal\":{}}}","slots":["board0371"]}

Also, can we put psm-tool under source control somewhere?

@dckc
Copy link
Member Author

dckc commented Sep 10, 2022

can we put psm-tool under source control somewhere?

It's in the dc-psm-tool branch whence came this PR.

Meanwhile, we're garbage-collecting it in favor of #6176 .

@turadg
Copy link
Member

turadg commented Sep 11, 2022

@Chris-Hibbert thanks for the snippet. 8aaedcb incorporates it in 6176. One nice thing about having the code in the repo is type checking works, which errored on the publicInvitationMaker key (which is for source: 'contract').

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

CLI testing tools for PSM
3 participants