Skip to content

Commit 207f884

Browse files
committed
feat(wallet-vat,autoswap-vat): Create wallet & autoswap backend
1 parent 6317d24 commit 207f884

10 files changed

+695
-44
lines changed

go.mod

-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,5 @@ require (
1313
github.com/tendermint/tendermint v0.32.6
1414
github.com/tendermint/tm-db v0.2.0
1515
golang.org/x/sys v0.0.0-20190329044733-9eb1bfa1ce65 // indirect
16-
google.golang.org/appengine v1.4.0 // indirect
1716
google.golang.org/genproto v0.0.0-20190327125643-d831d65fe17d // indirect
1817
)

lib/ag-solo/init-autoswap.js

+82-33
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,91 @@
11
import harden from '@agoric/harden';
2+
import { makeMint } from '@agoric/ertp/core/mint';
23
import { upload } from './upload-contract';
34

5+
const CONTRACT_NAME = 'zoe:autoswap'
6+
47
// Usage:
58
// ag-solo bundle -e init-autoswap zoe:autoswap=../node_modules/@agoric/ertp/core/zoe/contracts/autoswap.js
69

710
export default async ({ home, bundle }) => {
8-
// Install all the bundle entries that have a TARGET:NAME.
9-
// TARGET may be 'zoe' or 'contractHost' for example.
10-
const keyNames = Object.keys(bundle).sort().reduce((prior, key) => {
11-
const match = key.match(/^[^:]+:(.*)/);
12-
if (match) {
13-
prior.push([key, match[1]]);
14-
}
15-
return prior;
16-
}, []);
17-
await upload(home, bundle, keyNames.map(([k, n]) => k));
18-
19-
// Register the installations.
20-
const nameIds = {};
21-
let autoswapKey;
22-
await Promise.all(keyNames.map(([k, n]) =>
23-
n === 'autoswap' ? autoswapKey = k : home~.uploads~.get(k).then(u => home~.registrar~.register(n, u))
24-
.then(id => nameIds[n] = id)));
25-
26-
// TODO: This is just a sketch of how we might convert home.moolaMint into
27-
// funds for the autoswap instance.
28-
29-
// Instantiate autoswap with some fresh moola and register the instance.
30-
if (autoswapKey) {
31-
const installHandle = await home~.uploads~.get(autoswapKey);
32-
const options = {
33-
assays: await Promise.all([home~.moolaMint~.getAssay()]),
34-
purses: await Promise.all([home~.moolaMint~.mint(100000)]),
35-
};
36-
const instance = home~.zoe~.makeInstance(installHandle, harden(options));
37-
nameIds['autoswap'] = await home~.registrar~.register('autoswap', instance);
11+
12+
console.log('*** AUTOSWAP');
13+
14+
// AUTOSWAP INSTALL
15+
16+
// 1. Load & install the autoswap contract.
17+
await upload(home, bundle, [ CONTRACT_NAME ]);
18+
19+
// 2. Get the autoswap contract installation.
20+
const installationHandle = await home~.uploads~.get(CONTRACT_NAME);
21+
22+
// 3. Store the contract installation in the registry.
23+
const installationId = await home~.registrar~.register(CONTRACT_NAME, installationHandle);
24+
25+
console.log('- Autoswap intallation', CONTRACT_NAME, '=>', installationId);
26+
27+
// AUTOSWAP INSTANCE
28+
29+
// 1. Assays
30+
const assays = await Promise.all([
31+
home~.moolaMint~.getAssay(),
32+
home~.simoleanMint~.getAssay(),
33+
]);
34+
35+
// 2. Contract instrance.
36+
try {
37+
await home~.zoe~.makeInstance(installationHandle, { assays });
38+
} catch(e) {}
39+
const { instance, instanceHandle, terms } = await home~.zoe~.makeInstance(installationHandle, { assays });
40+
41+
// 3. Offer rules
42+
const units = await Promise.all([
43+
terms~.assays~.[0]~.makeUnits(10000),
44+
terms~.assays~.[1]~.makeUnits(10000),
45+
terms~.assays~.[2]~.makeUnits(0),
46+
]);
47+
48+
const offerRules = harden({
49+
payoutRules: [
50+
{
51+
kind: 'offerExactly',
52+
units: units[0],
53+
},
54+
{
55+
kind: 'offerExactly',
56+
units: units[1],
57+
},
58+
{
59+
kind: 'wantAtLeast',
60+
units: units[2],
61+
},
62+
],
63+
exitRule: {
64+
kind: 'onDemand',
65+
},
66+
});
67+
68+
// 4. Payments (from mint, not from purse)
69+
70+
const faucets = await Promise.all([
71+
home~.moolaMint~.mint(units[0]),
72+
home~.simoleanMint~.mint(units[1]),
73+
]);
74+
75+
const payments = await Promise.all([
76+
faucets[0]~.withdrawAll(),
77+
faucets[1]~.withdrawAll(),
78+
]);
79+
80+
// 5. Liquidities.
81+
const { escrowReceipt } = await home~.zoe~.escrow(offerRules, payments);
82+
const liquidityOk = await instance~.addLiquidity(escrowReceipt);
83+
console.log(liquidityOk);
84+
85+
if (liquidityOk) {
86+
// Only store if the contract instance has liquidities.
87+
const instanceId = await home~.registrar~.register(CONTRACT_NAME, instanceHandle);
88+
console.log('- Autoswap instance', CONTRACT_NAME, '=>', instanceId);
3889
}
3990

40-
// Output the record from contract IDs to registered names to stdout.
41-
console.log(JSON.stringify(nameIds, undefined, 2));
42-
};
91+
}

lib/ag-solo/vats/bootstrap.js

+26-2
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@ export default function setup(syscall, state, helpers) {
4343
async function createPrivateBundle(vats, exposeMint) {
4444
return harden({
4545
uploads: await E(vats.uploads).getUploads(),
46-
moolaMint: await E(vats.moola).getMint(),
46+
moolaMint: await E(vats.mints).getMint('moola'),
47+
simoleanMint: await E(vats.mints).getMint('simolean'),
48+
wallet: await E(vats.wallet).getWallet(),
4749
});
4850
}
4951

@@ -64,15 +66,19 @@ export default function setup(syscall, state, helpers) {
6466
const registrar = await E(vats.registrar).getSharedRegistrar();
6567
const chainTimerService = await E(vats.timer).createTimerService();
6668
const pixelBundle = await E(vats.pixel).createPixelBundle(nickname);
67-
const moola = await E(vats.moola).getSomeMoola(nickname, jackpot);
69+
const moola = await E(vats.mints).getNewPurse('moola', 'Moola purse');
70+
const simolean = await E(vats.mints).getNewPurse('simolean', 'Simolean purse');
71+
const exchange = await E(vats.exchange).getExchange();
6872
const zoe = await E(vats.zoe).getZoe();
6973
return harden({
7074
...pixelBundle,
7175
chainTimerService,
7276
sharingService,
7377
moola,
78+
simolean,
7479
contractHost,
7580
registrar,
81+
exchange,
7682
zoe,
7783
});
7884
},
@@ -209,11 +215,29 @@ export default function setup(syscall, state, helpers) {
209215
await E(vats.pixel).startup(host);
210216
await E(vats.timer).registerTimerDevice(devices.timer);
211217
const bundle = await makeBundler(host, vats).createDemoBundle('localuser');
218+
// fixme
219+
await E(vats.exchange).startup(host, bundle.zoe, bundle.registrar);
220+
await E(vats.wallet).startup(host, bundle.zoe, bundle.registrar);
221+
222+
const wallet = await E(vats.wallet).getWallet();
223+
224+
const moola = await E(vats.mints).getNewPurse('moola', 'Marketing');
225+
const simolean = await E(vats.mints).getNewPurse('simolean', 'Operating Account');
226+
await E(wallet).addPurse(moola);
227+
await E(wallet).addPurse(simolean);
228+
212229
await setupCommandDevice(vats, devices, { client: true });
230+
// fixme
231+
await E(vats.http).registerCommandHandler(vats.exchange);
232+
await E(vats.http).registerCommandHandler(vats.wallet);
233+
213234
await E(vats.http).setPresences(
214235
bundle,
215236
await createPrivateBundle(vats, true),
216237
);
238+
239+
await E(vats.wallet).setCommandDevice(devices.command);
240+
await E(vats.wallet).setPresences();
217241
} else {
218242
throw new Error(`ROLES was not recognized: ${ROLES}`);
219243
}

lib/ag-solo/vats/lib-exchange.js

+120
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
import harden from '@agoric/harden';
2+
3+
function checkOrder(a0, a1, b0, b1) {
4+
if (a0 === b0 && a1 === b1) {
5+
return true;
6+
}
7+
8+
if (a0 === b1 && a1 === b0) {
9+
return false;
10+
}
11+
12+
throw new TypeError('Canot resove asset ordering');
13+
}
14+
15+
export async function makeExchange(E, log, host, zoe, registrar) {
16+
// === API
17+
18+
async function getPrice(instanceId, extent0, assayId0, assayId1) {
19+
const instanceHandle = await E(registrar).get(instanceId);
20+
21+
// Find the assays in the registrar
22+
const registrarAssays = await Promise.all([
23+
E(registrar).get(assayId0),
24+
E(registrar).get(assayId1),
25+
]);
26+
27+
// Get the assays in the contract.
28+
// Get the contract instance.
29+
const {
30+
terms: { assays: contractAssays },
31+
instance,
32+
} = await E(zoe).getInstance(instanceHandle);
33+
34+
// Check whether we sell on contract assay 0 or 1.
35+
const normal = checkOrder(
36+
registrarAssays[0],
37+
registrarAssays[1],
38+
contractAssays[0],
39+
contractAssays[1],
40+
);
41+
42+
// Units of the input amount.
43+
const unit0 = await E(registrarAssays[0]).makeUnits(extent0);
44+
45+
// Order the units accordingly.
46+
const units = [
47+
normal ? unit0 : undefined,
48+
normal ? undefined : unit0,
49+
undefined,
50+
];
51+
52+
// Extract the price (multi steps for debugging).
53+
const unit1 = await E(instance).getPrice(units);
54+
const { extent } = unit1;
55+
return extent;
56+
}
57+
58+
async function getOfferRules(instanceId, extent, assayId0, assayId1) {
59+
const instanceHandle = await E(registrar).get(instanceId);
60+
61+
// Find the assays by id in the registrar.
62+
const registrarAssays = await Promise.all([
63+
E(registrar).get(assayId0),
64+
E(registrar).get(assayId1),
65+
]);
66+
67+
// Get the assays in the contract.
68+
const {
69+
terms: { assays: contractAssays },
70+
} = await E(zoe).getInstance(instanceHandle);
71+
72+
// Check whether we sell on contract assay 0 or 1.
73+
const normal = checkOrder(
74+
registrarAssays[0],
75+
registrarAssays[1],
76+
contractAssays[0],
77+
contractAssays[1],
78+
);
79+
80+
// Contrust the rules for serialization (no instance).
81+
// This rule is the payment
82+
const rule0 = {
83+
kind: 'offerExactly',
84+
units: { assayId: assayId0, extent },
85+
};
86+
// This rule is the payout
87+
const rule1 = {
88+
kind: 'wantAtLeast',
89+
units: { assayId: assayId1 },
90+
};
91+
92+
// Order the rules accordingly.
93+
const offerRules = harden({
94+
payoutRules: [
95+
normal ? rule0 : rule1,
96+
normal ? rule1 : rule0,
97+
{
98+
kind: 'wantAtLeast',
99+
units: {},
100+
},
101+
],
102+
exitRule: {
103+
kind: 'onDemand',
104+
},
105+
});
106+
107+
return offerRules;
108+
}
109+
110+
const autoswap = harden({
111+
userFacet: {
112+
getPrice,
113+
getOfferRules,
114+
},
115+
adminFacet: {},
116+
readFacet: {},
117+
});
118+
119+
return autoswap;
120+
}

0 commit comments

Comments
 (0)