Skip to content

Commit

Permalink
chore: add makeFeePurse method
Browse files Browse the repository at this point in the history
  • Loading branch information
katelynsills committed Aug 12, 2021
1 parent 8af66c9 commit 45439ab
Show file tree
Hide file tree
Showing 6 changed files with 135 additions and 2 deletions.
41 changes: 41 additions & 0 deletions packages/zoe/src/zoeService/feePurse.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// @ts-check

import { Far } from '@agoric/marshal';

/**
*
* @param {Issuer} feeIssuer
* @returns {{
* makeFeePurse: MakeFeePurse
* isFeePurse: (feePurse: Purse) => boolean
* }}
*/
const setupMakeFeePurse = feeIssuer => {
const feePurses = new WeakSet();

/** @type {MakeFeePurse} */
const makeFeePurse = () => {
const purse = feeIssuer.makeEmptyPurse();
/** @type {FeePurse} */
const feePurse = Far('feePurse', {
...purse,
});
feePurses.add(feePurse);

// After keeping the purse methods, we throw away the purse
return feePurse;
};

/**
* @param {Purse} feePurse
*/
const isFeePurse = feePurse => feePurses.has(feePurse);

return {
makeFeePurse,
isFeePurse,
};
};

harden(setupMakeFeePurse);
export { setupMakeFeePurse };
10 changes: 10 additions & 0 deletions packages/zoe/src/zoeService/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,23 @@
* object with the instance, installation, description, invitation
* handle, and any custom properties specific to the contract.
* @property {GetFeeIssuer} getFeeIssuer
* @property {MakeFeePurse} makeFeePurse
*/

/**
* @callback GetFeeIssuer
* @returns {Issuer}
*/

/**
* @typedef {Purse} FeePurse
*/

/**
* @callback MakeFeePurse
* @returns {FeePurse}
*/

/**
* @callback GetPublicFacet
* @param {Instance} instance
Expand Down
4 changes: 4 additions & 0 deletions packages/zoe/src/zoeService/zoe.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { makeOffer } from './offer/offer.js';
import { makeInvitationQueryFns } from './invitationQueries.js';
import { setupCreateZCFVat } from './createZCFVat.js';
import { createFeeMint } from './feeMint.js';
import { setupMakeFeePurse } from './feePurse.js';

/**
* Create an instance of Zoe.
Expand Down Expand Up @@ -53,6 +54,8 @@ const makeZoe = (
feeIssuerConfig,
);

const { makeFeePurse } = setupMakeFeePurse(feeIssuer);

// This method contains the power to create a new ZCF Vat, and must
// be closely held. vatAdminSvc is even more powerful - any vat can
// be created. We severely restrict access to vatAdminSvc for this reason.
Expand Down Expand Up @@ -103,6 +106,7 @@ const makeZoe = (
install,
startInstance,
offer,
makeFeePurse,

// The functions below are getters only and have no impact on
// state within Zoe
Expand Down
25 changes: 25 additions & 0 deletions packages/zoe/test/unitTests/test-zoe.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { test } from '@agoric/zoe/tools/prepare-test-env-ava.js';

import path from 'path';

import { AmountMath } from '@agoric/ertp';
import { E } from '@agoric/eventual-send';
import { makePromiseKit } from '@agoric/promise-kit';
import { passStyleOf } from '@agoric/marshal';
Expand Down Expand Up @@ -371,3 +372,27 @@ test(`zoe.getInvitationDetails - no invitation`, async t => {
message: /A Zoe invitation is required, not "\[undefined\]"/,
});
});

test(`zoe.makeFeePurse`, async t => {
const { zoe, zcf, feeMintAccess } = await setupZCFTest();

const feePurse = E(zoe).makeFeePurse();
const feeIssuer = E(zoe).getFeeIssuer();
const feeBrand = await E(feeIssuer).getBrand();

const zcfMint = await zcf.registerFeeMint('RUN', feeMintAccess);
const { zcfSeat, userSeat } = zcf.makeEmptySeatKit();

const fee1000 = AmountMath.make(feeBrand, 1000n);
zcfMint.mintGains({ Fee: fee1000 }, zcfSeat);

zcfSeat.exit();
const payment = await E(userSeat).getPayout('Fee');
await E(feePurse).deposit(payment);

t.true(AmountMath.isEqual(await E(feePurse).getCurrentAmount(), fee1000));

await E(feePurse).withdraw(fee1000);

t.true(AmountMath.isEmpty(await E(feePurse).getCurrentAmount()));
});
12 changes: 10 additions & 2 deletions packages/zoe/test/unitTests/zcf/setupZcfTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export const setupZCFTest = async (issuerKeywordRecord, terms) => {
};
// The contract provides the `zcf` via `setTestJig` upon `start`.
const fakeVatAdmin = makeFakeVatAdmin(setZCF);
const { zoeService: zoe } = makeZoe(fakeVatAdmin.admin);
const { zoeService: zoe, feeMintAccess } = makeZoe(fakeVatAdmin.admin);
const bundle = await bundleSource(contractRoot);
const installation = await E(zoe).install(bundle);
const { creatorFacet, instance } = await E(zoe).startInstance(
Expand All @@ -34,5 +34,13 @@ export const setupZCFTest = async (issuerKeywordRecord, terms) => {
const { vatAdminState } = fakeVatAdmin;
// @ts-ignore fix types to understand that zcf is always defined
assert(zcf !== undefined);
return { zoe, zcf, instance, installation, creatorFacet, vatAdminState };
return {
zoe,
zcf,
instance,
installation,
creatorFacet,
vatAdminState,
feeMintAccess,
};
};
45 changes: 45 additions & 0 deletions packages/zoe/test/unitTests/zoe/test-feePurse.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// @ts-check

// eslint-disable-next-line import/no-extraneous-dependencies
import { test } from '@agoric/zoe/tools/prepare-test-env-ava.js';

import { makeIssuerKit, AssetKind, AmountMath } from '@agoric/ertp';

import { setupMakeFeePurse } from '../../../src/zoeService/feePurse.js';

const setup = () => {
const runIssuerKit = makeIssuerKit('RUN', AssetKind.NAT, {
decimalPlaces: 6,
});
const { makeFeePurse, isFeePurse } = setupMakeFeePurse(runIssuerKit.issuer);
return { makeFeePurse, isFeePurse, runIssuerKit };
};

test('feePurse starts empty', async t => {
const { makeFeePurse } = setup();
const feePurse = makeFeePurse();

t.true(AmountMath.isEmpty(feePurse.getCurrentAmount()));
});

test('depositing into and withdrawing from feePurse', async t => {
const { makeFeePurse, runIssuerKit } = setup();
const feePurse = makeFeePurse();

const run1000 = AmountMath.make(runIssuerKit.brand, 1000n);
const payment = runIssuerKit.mint.mintPayment(run1000);
feePurse.deposit(payment);

t.true(AmountMath.isEqual(feePurse.getCurrentAmount(), run1000));

feePurse.withdraw(run1000);

t.true(AmountMath.isEmpty(feePurse.getCurrentAmount()));
});

test('isFeePurse', async t => {
const { makeFeePurse, isFeePurse } = setup();
const feePurse = makeFeePurse();

t.true(isFeePurse(feePurse));
});

0 comments on commit 45439ab

Please sign in to comment.