-
Notifications
You must be signed in to change notification settings - Fork 215
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #7256 from Agoric/dc-bid-cli
feat: more usable bidding CLI: integrated sign/broadcast
- Loading branch information
Showing
20 changed files
with
1,544 additions
and
456 deletions.
There are no files selected for viewing
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,166 @@ | ||
/* eslint-disable @jessie.js/no-nested-await */ | ||
// @ts-check | ||
/* eslint-disable func-names */ | ||
import { InvalidArgumentError } from 'commander'; | ||
import { makeRpcUtils } from '../lib/rpc.js'; | ||
import { outputActionAndHint } from '../lib/wallet.js'; | ||
|
||
const { Fail } = assert; | ||
|
||
/** @typedef {import('@agoric/governance/src/contractGovernance/typedParamManager.js').ParamTypesMap} ParamTypesMap */ | ||
/** @template M @typedef {import('@agoric/governance/src/contractGovernance/typedParamManager.js').ParamTypesMapFromRecord<M>} ParamTypesMapFromRecord */ | ||
|
||
/** | ||
* @template {ParamTypesMap} M | ||
* @typedef {{ | ||
* [K in keyof M]: ParamValueForType<M[K]> | ||
* }} ParamValues | ||
*/ | ||
|
||
/** @typedef {ReturnType<import('@agoric/inter-protocol/src/auction/params.js').makeAuctioneerParams>} AuctionParamRecord */ | ||
/** @typedef {ParamValues<ParamTypesMapFromRecord<AuctionParamRecord>>} AuctionParams */ | ||
|
||
/** | ||
* @param {import('anylogger').Logger} _logger | ||
* @param {{ | ||
* createCommand: typeof import('commander').createCommand, | ||
* fetch: typeof window.fetch, | ||
* stdout: Pick<import('stream').Writable, 'write'>, | ||
* stderr: Pick<import('stream').Writable, 'write'>, | ||
* now: () => number, | ||
* }} io | ||
*/ | ||
export const makeAuctionCommand = ( | ||
_logger, | ||
{ createCommand, stdout, stderr, fetch, now }, | ||
) => { | ||
const auctioneer = createCommand('auctioneer').description( | ||
'Auctioneer commands', | ||
); | ||
|
||
auctioneer | ||
.command('proposeParamChange') | ||
.description('propose a change to start frequency') | ||
.option( | ||
'--start-frequency <seconds>', | ||
'how often to start auctions', | ||
BigInt, | ||
) | ||
.option('--clock-step <seconds>', 'descending clock frequency', BigInt) | ||
.option( | ||
'--starting-rate <basis-points>', | ||
'relative to oracle: 999 = 1bp discount', | ||
BigInt, | ||
) | ||
.option('--lowest-rate <basis-points>', 'lower limit for discount', BigInt) | ||
.option( | ||
'--discount-step <basis-points>', | ||
'descending clock step size', | ||
BigInt, | ||
) | ||
.option( | ||
'--discount-step <integer>', | ||
'proposed value (basis points)', | ||
BigInt, | ||
) | ||
.requiredOption( | ||
'--charterAcceptOfferId <string>', | ||
'offer that had continuing invitation result', | ||
) | ||
.option('--offer-id <string>', 'Offer id', String, `propose-${Date.now()}`) | ||
.option( | ||
'--deadline [minutes]', | ||
'minutes from now to close the vote', | ||
Number, | ||
1, | ||
) | ||
.action( | ||
/** | ||
* | ||
* @param {{ | ||
* charterAcceptOfferId: string, | ||
* startFrequency?: bigint, | ||
* clockStep?: bigint, | ||
* startingRate?: bigint, | ||
* lowestRate?: bigint, | ||
* discountStep?: bigint, | ||
* offerId: string, | ||
* deadline: number, | ||
* }} opts | ||
*/ | ||
async opts => { | ||
const { agoricNames, readLatestHead } = await makeRpcUtils({ fetch }); | ||
|
||
/** @type {{ current: AuctionParamRecord }} */ | ||
// @ts-expect-error XXX should runtime check? | ||
const { current } = await readLatestHead( | ||
`published.auction.governance`, | ||
); | ||
|
||
const { | ||
AuctionStartDelay: { | ||
// @ts-expect-error XXX RelativeTime includes raw bigint | ||
value: { timerBrand }, | ||
}, | ||
} = current; | ||
timerBrand || Fail`no timer brand?`; | ||
|
||
/** | ||
* typed param manager requires RelativeTimeRecord | ||
* but TimeMath.toRel prodocues a RelativeTime (which may be a bare bigint). | ||
* | ||
* @param {bigint} relValue | ||
* @returns {import('@agoric/time/src/types').RelativeTimeRecord} | ||
*/ | ||
const toRel = relValue => ({ timerBrand, relValue }); | ||
|
||
/** @type {Partial<AuctionParams>} */ | ||
const params = { | ||
...(opts.startFrequency && { | ||
StartFrequency: toRel(opts.startFrequency), | ||
}), | ||
...(opts.clockStep && { ClockStep: toRel(opts.clockStep) }), | ||
...(opts.startingRate && { StartingRate: opts.startingRate }), | ||
...(opts.lowestRate && { LowestRate: opts.lowestRate }), | ||
...(opts.discountStep && { DiscountStep: opts.discountStep }), | ||
}; | ||
|
||
if (Object.keys(params).length === 0) { | ||
throw new InvalidArgumentError(`no parameters given`); | ||
} | ||
|
||
const instance = agoricNames.instance.auctioneer; | ||
instance || Fail`missing auctioneer in names`; | ||
|
||
const t0 = now(); | ||
const deadline = BigInt(Math.round(t0 / 1000) + 60 * opts.deadline); | ||
|
||
/** @type {import('@agoric/inter-protocol/src/econCommitteeCharter.js').ParamChangesOfferArgs} */ | ||
const offerArgs = { | ||
deadline, | ||
params, | ||
instance, | ||
path: { paramPath: { key: 'governedParams' } }, | ||
}; | ||
|
||
/** @type {import('@agoric/smart-wallet/src/offers.js').OfferSpec} */ | ||
const offer = { | ||
id: opts.offerId, | ||
invitationSpec: { | ||
source: 'continuing', | ||
previousOffer: opts.charterAcceptOfferId, | ||
invitationMakerName: 'VoteOnParamChange', | ||
}, | ||
offerArgs, | ||
proposal: {}, | ||
}; | ||
|
||
outputActionAndHint( | ||
{ method: 'executeOffer', offer }, | ||
{ stdout, stderr }, | ||
); | ||
}, | ||
); | ||
|
||
return auctioneer; | ||
}; |
Oops, something went wrong.