diff --git a/packages/vats/src/bootstrap.js b/packages/vats/src/bootstrap.js index 86f13385718..5b51f5c09d7 100644 --- a/packages/vats/src/bootstrap.js +++ b/packages/vats/src/bootstrap.js @@ -9,6 +9,8 @@ import { E, Far } from '@agoric/far'; import { makeStore } from '@agoric/store'; import { installOnChain as installVaultFactoryOnChain } from '@agoric/run-protocol/bundles/install-on-chain.js'; import { installOnChain as installPegasusOnChain } from '@agoric/pegasus/bundles/install-on-chain.js'; +import attestationBundle from '@agoric/zoe/src/contracts/attestation/install-on-chain.js'; +import { bootstrapAttestation } from '@agoric/zoe/src/contracts/attestation/bootstrapAttestation.js'; import { makePluginManager } from '@agoric/swingset-vat/src/vats/plugin-manager.js'; import { assert, details as X } from '@agoric/assert'; @@ -27,6 +29,7 @@ import { BLD_ISSUER_ENTRY, } from './issuers'; import { feeIssuerConfig } from './core/behaviors.js'; +import { makeStakeReporter } from './my-lien.js'; const { multiply, floorDivide } = natSafeMath; @@ -578,6 +581,35 @@ export function buildRootObject(vatPowers, vatParameters) { }), ); + let attMakerFor; + if (bridgeManager) { + const [_n, bldRec] = + issuerEntries.find(([n, _r]) => n === BLD_ISSUER_ENTRY[0]) || + assert.fail('need @@bLD!'); + // start attestation contract + assert( + bridgeManager, + X`@@TODO: handle lack of bridge manager for attestations`, + ); + const { + // brand: attBrand, // TODO: runLoC will want these + // issuer: attIssuer, + creatorFacet: attestationCreatorFacet, + } = await bootstrapAttestation( + attestationBundle, + zoeWUnlimitedPurse, + bldRec.issuer || assert.fail('bld issuer!?!@@'), + makeStakeReporter( + bridgeManager, + bldRec.brand || assert.fail('bld brand!?!@@'), + ), + { expiringAttName: 'BldAttGov', returnableAttName: 'BldAttLoC' }, + ); + attMakerFor = address => E(attestationCreatorFacet).getAttMaker(address); + } else { + attMakerFor = a => assert.fail(X`no bridge manager@@@ ${a}`); + } + // This needs to happen after creating all the services. // eslint-disable-next-line no-use-before-define await registerNetworkProtocols( @@ -767,8 +799,12 @@ export function buildRootObject(vatPowers, vatParameters) { }), ); + const attestationMaker = attMakerFor(address); + const bundle = harden({ ...additionalPowers, + bridgeManager, // @@@@for experimenting with lien / attestation + attestationMaker, agoricNames, bank, chainTimerService, diff --git a/packages/vats/src/my-lien.js b/packages/vats/src/my-lien.js new file mode 100644 index 00000000000..9474ec95ce6 --- /dev/null +++ b/packages/vats/src/my-lien.js @@ -0,0 +1,61 @@ +// @ts-check +import { AmountMath } from '@agoric/ertp'; +import { E, Far } from '@agoric/far'; + +const { details: X } = assert; + +/** + * per golang/cosmos/x/lien/lien.go + * + * @typedef { 'bonded' | 'liened' | 'locked' | 'total' | 'unbonding' } AccountProperty + */ +const XLien = { + name: 'lien', + LIEN_GET_ACCOUNT_STATE: 'LIEN_GET_ACCOUNT_STATE', + denom: 'ubld', // @@err... +}; + +/** + * @typedef { Record & { currentTime: bigint } } AccountState + * @template T + */ + +/** + * @param {import('./bridge').BridgeManager} bridgeManager + * @param {Brand} stake + * @returns {StakingAuthority} + */ +export const makeStakeReporter = (bridgeManager, stake) => { + const { make: makeAmt } = AmountMath; + /** @param {string} numeral */ + const toStake = numeral => makeAmt(stake, BigInt(numeral)); + + /** @type {StakingAuthority} */ + const stakeReporter = Far('stakeReporter', { + getAccountState: async (address, wantedBrand) => { + assert( + wantedBrand === stake, + X`Cannot getAccountState for ${wantedBrand}. Expected ${stake}.`, + ); + /** @type { AccountState } */ + const { currentTime, bonded, liened, locked, total, unbonding } = await E( + bridgeManager, + ).toBridge(XLien.name, { + type: XLien.LIEN_GET_ACCOUNT_STATE, + address, + denom: XLien.denom, + amount: '0', + }); + return harden({ + bonded: toStake(bonded), + liened: toStake(liened), + locked: toStake(locked), + total: toStake(total), + unbonding: toStake(unbonding), + currentTime: BigInt(currentTime), + }); + }, + }); + + return stakeReporter; +};