diff --git a/packages/treasury/test/test-runLoC.js b/packages/treasury/test/test-runLoC.js index 97de2033419c..9aa399e5d51f 100644 --- a/packages/treasury/test/test-runLoC.js +++ b/packages/treasury/test/test-runLoC.js @@ -4,13 +4,21 @@ import { test } from '@agoric/zoe/tools/prepare-test-env-ava.js'; import { makeFakeVatAdmin } from '@agoric/zoe/tools/fakeVatAdmin.js'; import { makeZoeKit } from '@agoric/zoe'; import { E } from '@agoric/eventual-send'; -import { makeLoopback } from '@agoric/captp'; +import { Far, makeLoopback } from '@agoric/captp'; import { resolve as metaResolve } from 'import-meta-resolve'; import bundleSource from '@agoric/bundle-source'; -import { AmountMath } from '@agoric/ertp'; +import { AmountMath, AssetKind, makeIssuerKit } from '@agoric/ertp'; // import { makeLoopback } from '@agoric/captp'; +/** + * @typedef { import('@agoric/eventual-send').Unpromise } Unpromise + * @template T + */ +/** @typedef {Unpromise>} StartAttestationResult */ +/** @typedef {Unpromise>} StartLineOfCredit */ + const { assign, entries, fromEntries, keys, values } = Object; +const { details: X } = assert; const mapValues = (obj, f) => fromEntries(entries(obj).map(([p, v]) => [p, f(v)])); @@ -23,12 +31,14 @@ const asset = async ref => const contractRoots = { runLoC: '../src/runLoC.js', + attestation: '@agoric/zoe/src/contracts/attestation/attestation.js', }; test.before(async t => { t.log('bundling...', contractRoots); const bundles = { runLoC: await bundleSource(await asset(contractRoots.runLoC)), + attestation: await bundleSource(await asset(contractRoots.attestation)), }; t.log( 'bundled:', @@ -60,11 +70,100 @@ test('RUN mint access', async t => { assert.typeof(t.context, 'object'); assert(t.context); + const { zoe, feeMintAccess } = await genesis(); + t.true(!!zoe); + t.true(!!feeMintAccess); +}); + +const startAttestation = async (t, zoe) => { + const installation = await E(zoe).install(t.context.bundles.attestation); + const bldIssuerKit = makeIssuerKit( + 'BLD', + AssetKind.NAT, + harden({ + decimalPlaces: 6, + }), + ); + + /** @type {StartAttestationResult} */ + const { publicFacet, creatorFacet } = await E(zoe).startInstance( + installation, + harden({ Underlying: bldIssuerKit.issuer }), + harden({ + expiringAttName: 'BldAttGov', + returnableAttName: 'BldAttLoc', + }), + ); + return { bldIssuerKit, publicFacet, creatorFacet }; +}; + +const chainState = harden({ + currentTime: 10n, + accounts: { + address1: { + total: 500n, + bonded: 200n, + locked: 10n, + }, + }, +}); + +/** + * @param {Brand} uBrand + */ +const makeStakeReporter = uBrand => { + const ubld = v => AmountMath.make(uBrand, v); + return Far('stakeReporter', { + /** + * @param { string } address + * @param { Brand } brand + */ + getAccountState: (address, brand) => { + assert(brand === uBrand, X`unexpected brand: ${brand}`); + const account = chainState.accounts[address]; + assert(account, X`no such account: ${address}`); + return harden({ + ...mapValues(account, ubld), + currentTime: chainState.currentTime, + }); + }, + }); +}; + +test('start attestation', async t => { + const { zoe } = await genesis(); + + const a = await startAttestation(t, zoe); + t.log('attestation start result', a); + const { brand: bldBrand } = a.bldIssuerKit; + const ubld = v => AmountMath.make(bldBrand, v); + + a.creatorFacet.addAuthority(makeStakeReporter(bldBrand)); + + const attMaker = await E(a.creatorFacet).getAttMaker( + keys(chainState.accounts)[0], + ); + const expiration = chainState.currentTime + 5n; + const att = await E(attMaker).makeAttestations(ubld(10n), expiration); + t.log('attestation', att); + const pmt = await att.returnable; + t.log({ pmt }); + t.pass(); +}); + +test('take out RUN line of credit', async t => { + assert.typeof(t.context, 'object'); + assert(t.context); + const { zoe, feeMintAccess, getJig } = await genesis(); t.true(!!zoe); t.true(!!feeMintAccess); + const a = await startAttestation(t, zoe); + const { brand: bldBrand } = a.bldIssuerKit; + a.creatorFacet.addAuthority(makeStakeReporter(bldBrand)); const installation = await E(zoe).install(t.context.bundles.runLoC); + /** @type {StartLineOfCredit} */ const { publicFacet } = await E(zoe).startInstance( installation, undefined, @@ -72,13 +171,25 @@ test('RUN mint access', async t => { harden({ feeMintAccess }), ); /** @type {{ runBrand: Brand, runIssuer: Issuer }} */ - const { runBrand, runIssuer } = getJig(); - const lineOfCreditInvitation = await E(publicFacet).getInvitation(); - + const { runBrand } = getJig(); /** @param { bigint } value */ const run = value => AmountMath.make(runBrand, value); - const attAmt = run(0n); // @@TODO - const attPmt = await E(E(runIssuer).makeEmptyPurse()).withdraw(attAmt); // @@TODO + + const lineOfCreditInvitation = await E(publicFacet).getInvitation(); + + /** @param { bigint } v */ + const ubld = v => AmountMath.make(bldBrand, v); + + const { returnable: attIssuer } = await E(a.publicFacet).getIssuers(); + const addr = keys(chainState.accounts)[0]; + const attMaker = await E(a.creatorFacet).getAttMaker(addr); + t.log({ addr, attMaker }); + + const expiration = chainState.currentTime + 1n; + const attPmt = await E.get(E(attMaker).makeAttestations(ubld(5n), expiration)) + .returnable; + t.log({ attPmt }); + const attAmt = await E(attIssuer).getAmountOf(attPmt); const seat = await E(zoe).offer( lineOfCreditInvitation,