Skip to content

Commit

Permalink
feat: inter auction list (bids)
Browse files Browse the repository at this point in the history
  • Loading branch information
dckc committed Mar 16, 2023
1 parent 5383e27 commit 54c7318
Show file tree
Hide file tree
Showing 3 changed files with 171 additions and 11 deletions.
97 changes: 90 additions & 7 deletions packages/agoric-cli/src/inter.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,19 @@
import '@endo/init';
import { makeRatioFromAmounts } from '@agoric/zoe/src/contractSupport/ratio.js';
import { createCommand } from 'commander';
import { getNetworkConfig, makeRpcUtils } from './lib/rpc.js';
import { outputExecuteOfferAction } from './lib/wallet.js';
import { makeFollower, makeLeader } from '@agoric/casting';
import { M, matches } from '@agoric/store';
import {
boardSlottingMarshaller,
getNetworkConfig,
makeRpcUtils,
} from './lib/rpc.js';
import { coalesceWalletState, outputExecuteOfferAction } from './lib/wallet.js';
import { normalizeAddressWithOptions } from './lib/chain.js';
import { makeAmountFormatter } from './lib/format.js';

const { Fail } = assert;
const { entries, fromEntries, values } = Object;

const Offers = {
auction: {
Expand Down Expand Up @@ -45,7 +54,7 @@ const Offers = {
});
const wantCollateral = collateral.make(opts.wantCollateral);
const offerArgs = harden({
want: wantCollateral,
want: { Collateral: wantCollateral },
offerPrice: makeRatioFromAmounts(
proposal.give.Currency,
wantCollateral,
Expand All @@ -55,8 +64,8 @@ const Offers = {
id: opts.offerId,
invitationSpec: {
source: 'agoricContract',
instancePath: ['auction'],
callPipe: [['getBidInvitation', [collateral.brand]]],
instancePath: ['auctioneer'],
callPipe: [['makeBidInvitation', [collateral.brand]]],
},
proposal,
offerArgs,
Expand All @@ -65,6 +74,32 @@ const Offers = {
},
};

const mapValues = (obj, fn) =>
fromEntries(entries(obj).map(([prop, val]) => [prop, fn(val)]));

export const fmtBid = (bid, assets) => {
const fmtAmtTuple = makeAmountFormatter(assets);
const fmtAmt = amt => (([l, m]) => `${m}${l}`)(fmtAmtTuple(amt));
const fmtRecord = r => (r ? mapValues(r, fmtAmt) : undefined);

const {
id,
error,
proposal: { give },
offerArgs: { want, offerPrice }, // TODO: other kind of bid
payouts,
} = bid;
const amounts = {
give: give ? fmtRecord(give) : undefined,
want: want ? fmtRecord(want) : undefined,
price: offerPrice
? `${fmtAmt(offerPrice.numerator)}/${fmtAmt(offerPrice.denominator)}}`
: undefined,
payouts: fmtRecord(payouts),
};
return harden({ id, ...amounts, error });
};

/**
* @param {{ argv: string[], env: Partial<Record<string, string>>,
* stdout: typeof process.stdout, clock: () => number,
Expand All @@ -81,9 +116,12 @@ export const main = async ({ argv, env, stdout, clock }, { fetch }) => {
);

const config = await getNetworkConfig(env);
const { agoricNames } = await makeRpcUtils({ fetch }, config);
const { agoricNames, fromBoard } = await makeRpcUtils({ fetch }, config);

const auctionCmd = interCmd
.command('auction')
.description('auction commands');

const auctionCmd = interCmd.command('auction');
auctionCmd
.command('bid')
.description('bid on collateral')
Expand All @@ -96,5 +134,50 @@ export const main = async ({ argv, env, stdout, clock }, { fetch }) => {
outputExecuteOfferAction(offer, stdout);
}); // TODO: discount

const normalizeAddress = literalOrName =>
normalizeAddressWithOptions(literalOrName, auctionCmd.opts());

auctionCmd
.command('list')
.description('list bids')
.requiredOption(
'--from <address>',
'wallet address literal or name',
normalizeAddress,
)
.action(async opts => {
const unserializer = boardSlottingMarshaller(fromBoard.convertSlotToVal);

const networkConfig = await getNetworkConfig(env);
const leader = makeLeader(networkConfig.rpcAddrs[0]);
const follower = await makeFollower(
`:published.wallet.${opts.from}`,
leader,
{
// @ts-expect-error xxx
unserializer,
},
);

const coalesced = await coalesceWalletState(
follower,
agoricNames.brand.Invitation,
);
const bidInvitationShape = harden({
source: 'agoricContract',
instancePath: ['auctioneer'],
callPipe: [['makeBidInvitation', M.any()]],
});
for (const offerStatus of coalesced.offerStatuses.values()) {
harden(offerStatus); // coalesceWalletState should do this
// console.debug(offerStatus.invitationSpec);
if (!matches(offerStatus.invitationSpec, bidInvitationShape)) continue;

const info = fmtBid(offerStatus, values(agoricNames.vbankAsset));
stdout.write(JSON.stringify(info));
stdout.write('\n');
}
}); // TODO: discount

interCmd.parse(argv);
};
6 changes: 2 additions & 4 deletions packages/agoric-cli/src/lib/format.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,8 @@ const exampleAsset = {

/** @param {AssetDescriptor[]} assets */
export const makeAmountFormatter = assets => amt => {
const {
brand: { boardId },
value,
} = amt;
const { brand, value } = amt;
const boardId = brand.getBoardId();
const asset = assets.find(a => a.brand.getBoardId() === boardId);
if (!asset) return [NaN, boardId];
const {
Expand Down
79 changes: 79 additions & 0 deletions packages/agoric-cli/test/test-inter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import '@endo/init';
import test from 'ava';
import { fmtBid } from '../src/inter.js';

const brand = {
IbcATOM: { getBoardId: () => 'board00848' },
IST: { getBoardId: () => 'board0566' },
};

const agoricNames = {
brand,

vbankAsset: {
uist: {
brand: brand.IST,
denom: 'uist',
displayInfo: {
assetKind: 'nat',
decimalPlaces: 6,
},
issuer: {},
issuerName: 'IST',
proposedName: 'Agoric stable local currency',
},

'ibc/toyatom': {
brand: brand.IbcATOM,
denom: 'ibc/toyatom',
displayInfo: {
assetKind: 'nat',
decimalPlaces: 6,
},
issuer: {},
issuerName: 'IbcATOM',
proposedName: 'ATOM',
},
},
};

const offerStatus1 = {
error: 'Error: "nameKey" not found: (a string)',
id: 1678990150266,
invitationSpec: {
callPipe: [['getBidInvitation', [brand.IbcATOM]]],
instancePath: ['auctioneer'],
source: 'agoricContract',
},
offerArgs: {
offerPrice: {
denominator: { brand: brand.IbcATOM, value: 2000000n },
numerator: { brand: brand.IST, value: 20000000n },
},
want: {
Collateral: { brand: brand.IbcATOM, value: 2000000n },
},
},
proposal: {
give: {
Currency: { brand: brand.IbcATOM, value: 20000000n },
},
},
};

test('formatBid', t => {
const { values } = Object;
const actual = fmtBid(offerStatus1, values(agoricNames.vbankAsset));
t.deepEqual(actual, {
id: 1678990150266,
error: 'Error: "nameKey" not found: (a string)',
give: {
Currency: '20IbcATOM',
},
payouts: undefined,
price: '20IST/2IbcATOM}',
want: {
Collateral: '2IbcATOM',
},
});
});

0 comments on commit 54c7318

Please sign in to comment.