Skip to content

Instantly share code, notes, and snippets.

@katelynsills
Last active May 18, 2020 08:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save katelynsills/3eb9ff3fd461fcac9760a6fcf2f51a9b to your computer and use it in GitHub Desktop.
Save katelynsills/3eb9ff3fd461fcac9760a6fcf2f51a9b to your computer and use it in GitHub Desktop.
Give a freebie to both participants while swapping
/* eslint-disable no-use-before-define */
import harden from '@agoric/harden';
import produceIssuer from '@agoric/ertp';
//import { makeZoeHelpers } from './contractSupport';
import { makeZoeHelpers, defaultAcceptanceMsg } from '@agoric/zoe/src/contractSupport';
// zcf is the Zoe Contract Facet, i.e. the contract-facing API of Zoe
export const makeContract = harden(zcf => {
const helpers = makeZoeHelpers(zcf);
const { assertKeywords, checkHook, swap } = helpers;
const swapKeywords = harden(['Asset', 'Price'])
assertKeywords(swapKeywords);
const { issuer: goodwillIssuer, mint: goodwillMint, amountMath: goodwillAmountMath } = produceIssuer('goodwill');
const goodwill1000 = goodwillAmountMath.make(1000);
const giveGoodwill = (amount, recipientHandle) => {
const payment = goodwillMint.mintPayment(amount);
return helpers
.escrowAndAllocateTo({
amount,
payment,
keyword: 'Goodwill',
recipientHandle,
});
};
return zcf.addNewIssuer(goodwillIssuer, 'Goodwill').then(() => {
const makeMatchingInvite = firstOfferHandle => {
const {
proposal: { want, give },
} = zcf.getOffer(firstOfferHandle);
return giveGoodwill(goodwill1000, firstOfferHandle).then(() => {
return zcf.makeInvitation(
offerHandle => {
return giveGoodwill(goodwill1000, offerHandle)
.then(() => swap(firstOfferHandle, offerHandle));
},
'matchOffer',
harden({
customProperties: {
asset: give.Asset,
price: want.Price,
},
}),
);
});
};
const firstOfferExpected = harden({
give: { Asset: null },
want: { Price: null },
});
return harden({
invite: zcf.makeInvitation(
checkHook(makeMatchingInvite, firstOfferExpected),
'firstOffer',
),
publicAPI: {
getGoodwillIssuer: () => goodwillIssuer,
}
});
});
});
import { test } from 'tape-promise/tape';
import { makeZoe } from '@agoric/zoe';
import bundleSource from '@agoric/bundle-source';
// Import of agoric's harden capability
import harden from '@agoric/harden';
import { E } from '@agoric/eventual-send';
import { makeGetInstanceHandle } from '@agoric/zoe/src/clientSupport';
const goodwillContractRoot = `${__dirname}/../src/contract`;
import { setup } from '../src/setupBasicMints';
test('Testing the goodwill exchange setup....', async (t) => {
const {
moolaIssuer,
simoleanIssuer,
moolaMint,
simoleanMint,
moola,
simoleans,
} = setup();
const zoe = makeZoe({ require });
const inviteIssuer = zoe.getInviteIssuer();
// pack the contract
const { source, moduleFormat } = await bundleSource(goodwillContractRoot);
// install the contract
const installationHandle = zoe.install(source, moduleFormat);
// Setup Alice
const aliceMoolaPayment = moolaMint.mintPayment(moola(3));
const aliceMoolaPurse = moolaIssuer.makeEmptyPurse();
const aliceSimoleanPurse = simoleanIssuer.makeEmptyPurse();
// Setup Bob
const bobSimoleanPayment = simoleanMint.mintPayment(simoleans(7));
const bobMoolaPurse = moolaIssuer.makeEmptyPurse();
const bobSimoleanPurse = simoleanIssuer.makeEmptyPurse();
// 1: Alice creates an atomicSwap instance
const issuerKeywordRecord = harden({
Asset: moolaIssuer,
Price: simoleanIssuer,
});
const aliceInvite = await zoe.makeInstance(
installationHandle,
issuerKeywordRecord,
);
// 2: Alice escrows with zoe
const aliceProposal = harden({
give: { Asset: moola(3) },
want: { Price: simoleans(7) },
exit: { onDemand: null },
});
const alicePayments = { Asset: aliceMoolaPayment };
// 3: Alice makes the first offer in the swap.
const { payout: alicePayoutP, outcome: bobInviteP } = await zoe.offer(
aliceInvite,
aliceProposal,
alicePayments,
);
// 4: Alice spreads the invite far and wide with instructions
// on how to use it and Bob decides he wants to be the
// counter-party.
const bobExclusiveInvite = await inviteIssuer.claim(bobInviteP);
const {
extent: [bobInviteExtent],
} = await inviteIssuer.getAmountOf(bobExclusiveInvite);
const {
installationHandle: bobInstallationId,
issuerKeywordRecord: bobIssuers,
publicAPI,
} = zoe.getInstanceRecord(bobInviteExtent.instanceHandle);
const goodwillIssuer = publicAPI.getGoodwillIssuer();
const goodwillAmountMath = goodwillIssuer.getAmountMath();
const goodwill = goodwillAmountMath.make;
t.equals(bobInstallationId, installationHandle, 'bobInstallationId');
t.deepEquals(bobIssuers, { Asset: moolaIssuer, Price: simoleanIssuer, Goodwill: goodwillIssuer });
t.deepEquals(bobInviteExtent.asset, moola(3));
t.deepEquals(bobInviteExtent.price, simoleans(7));
const bobProposal = harden({
give: { Price: simoleans(7) },
want: { Asset: moola(3) },
exit: { onDemand: null },
});
const bobPayments = { Price: bobSimoleanPayment };
// 5: Bob makes an offer
const { payout: bobPayoutP, outcome: bobOutcomeP } = await zoe.offer(
bobExclusiveInvite,
bobProposal,
bobPayments,
);
t.equals(
await bobOutcomeP,
'The offer has been accepted. Once the contract has been completed, please check your payout',
);
const bobPayout = await bobPayoutP;
const alicePayout = await alicePayoutP;
const bobMoolaPayout = await bobPayout.Asset;
const bobSimoleanPayout = await bobPayout.Price;
const bobGoodwillPayout = await bobPayout.Goodwill;
const aliceMoolaPayout = await alicePayout.Asset;
const aliceSimoleanPayout = await alicePayout.Price;
const aliceGoodwillPayout = await alicePayout.Goodwill;
// Alice gets what Alice wanted
t.deepEquals(
await simoleanIssuer.getAmountOf(aliceSimoleanPayout),
aliceProposal.want.Price,
);
// Alice didn't get any of what Alice put in
t.deepEquals(await moolaIssuer.getAmountOf(aliceMoolaPayout), moola(0));
// Alice gets a goodwill payout of 1000
t.deepEquals(await E(goodwillIssuer).getAmountOf(aliceGoodwillPayout), goodwill(1000));
// Bob gets a goodwill payout of 1000
t.deepEquals(await E(goodwillIssuer).getAmountOf(bobGoodwillPayout), goodwill(1000));
// Alice deposits her payout to ensure she can
await aliceMoolaPurse.deposit(aliceMoolaPayout);
await aliceSimoleanPurse.deposit(aliceSimoleanPayout);
// Bob deposits his original payments to ensure he can
await bobMoolaPurse.deposit(bobMoolaPayout);
await bobSimoleanPurse.deposit(bobSimoleanPayout);
// Assert that the correct payouts were received.
// Alice had 3 moola and 0 simoleans.
// Bob had 0 moola and 7 simoleans.
t.equals(aliceMoolaPurse.getCurrentAmount().extent, 0);
t.equals(aliceSimoleanPurse.getCurrentAmount().extent, 7);
t.equals(bobMoolaPurse.getCurrentAmount().extent, 3);
t.equals(bobSimoleanPurse.getCurrentAmount().extent, 0);
t.end();
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment