-
Notifications
You must be signed in to change notification settings - Fork 226
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(wallet-vat,autoswap-vat): Create wallet & autoswap backend
- Loading branch information
Showing
10 changed files
with
695 additions
and
44 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,42 +1,91 @@ | ||
import harden from '@agoric/harden'; | ||
import { makeMint } from '@agoric/ertp/core/mint'; | ||
import { upload } from './upload-contract'; | ||
|
||
const CONTRACT_NAME = 'zoe:autoswap' | ||
|
||
// Usage: | ||
// ag-solo bundle -e init-autoswap zoe:autoswap=../node_modules/@agoric/ertp/core/zoe/contracts/autoswap.js | ||
|
||
export default async ({ home, bundle }) => { | ||
// Install all the bundle entries that have a TARGET:NAME. | ||
// TARGET may be 'zoe' or 'contractHost' for example. | ||
const keyNames = Object.keys(bundle).sort().reduce((prior, key) => { | ||
const match = key.match(/^[^:]+:(.*)/); | ||
if (match) { | ||
prior.push([key, match[1]]); | ||
} | ||
return prior; | ||
}, []); | ||
await upload(home, bundle, keyNames.map(([k, n]) => k)); | ||
|
||
// Register the installations. | ||
const nameIds = {}; | ||
let autoswapKey; | ||
await Promise.all(keyNames.map(([k, n]) => | ||
n === 'autoswap' ? autoswapKey = k : home~.uploads~.get(k).then(u => home~.registrar~.register(n, u)) | ||
.then(id => nameIds[n] = id))); | ||
|
||
// TODO: This is just a sketch of how we might convert home.moolaMint into | ||
// funds for the autoswap instance. | ||
|
||
// Instantiate autoswap with some fresh moola and register the instance. | ||
if (autoswapKey) { | ||
const installHandle = await home~.uploads~.get(autoswapKey); | ||
const options = { | ||
assays: await Promise.all([home~.moolaMint~.getAssay()]), | ||
purses: await Promise.all([home~.moolaMint~.mint(100000)]), | ||
}; | ||
const instance = home~.zoe~.makeInstance(installHandle, harden(options)); | ||
nameIds['autoswap'] = await home~.registrar~.register('autoswap', instance); | ||
|
||
console.log('*** AUTOSWAP'); | ||
|
||
// AUTOSWAP INSTALL | ||
|
||
// 1. Load & install the autoswap contract. | ||
await upload(home, bundle, [ CONTRACT_NAME ]); | ||
|
||
// 2. Get the autoswap contract installation. | ||
const installationHandle = await home~.uploads~.get(CONTRACT_NAME); | ||
|
||
// 3. Store the contract installation in the registry. | ||
const installationId = await home~.registrar~.register(CONTRACT_NAME, installationHandle); | ||
|
||
console.log('- Autoswap intallation', CONTRACT_NAME, '=>', installationId); | ||
|
||
// AUTOSWAP INSTANCE | ||
|
||
// 1. Assays | ||
const assays = await Promise.all([ | ||
home~.moolaMint~.getAssay(), | ||
home~.simoleanMint~.getAssay(), | ||
]); | ||
|
||
// 2. Contract instrance. | ||
try { | ||
await home~.zoe~.makeInstance(installationHandle, { assays }); | ||
} catch(e) {} | ||
const { instance, instanceHandle, terms } = await home~.zoe~.makeInstance(installationHandle, { assays }); | ||
|
||
// 3. Offer rules | ||
const units = await Promise.all([ | ||
terms~.assays~.[0]~.makeUnits(10000), | ||
terms~.assays~.[1]~.makeUnits(10000), | ||
terms~.assays~.[2]~.makeUnits(0), | ||
]); | ||
|
||
const offerRules = harden({ | ||
payoutRules: [ | ||
{ | ||
kind: 'offerExactly', | ||
units: units[0], | ||
}, | ||
{ | ||
kind: 'offerExactly', | ||
units: units[1], | ||
}, | ||
{ | ||
kind: 'wantAtLeast', | ||
units: units[2], | ||
}, | ||
], | ||
exitRule: { | ||
kind: 'onDemand', | ||
}, | ||
}); | ||
|
||
// 4. Payments (from mint, not from purse) | ||
|
||
const faucets = await Promise.all([ | ||
home~.moolaMint~.mint(units[0]), | ||
home~.simoleanMint~.mint(units[1]), | ||
]); | ||
|
||
const payments = await Promise.all([ | ||
faucets[0]~.withdrawAll(), | ||
faucets[1]~.withdrawAll(), | ||
]); | ||
|
||
// 5. Liquidities. | ||
const { escrowReceipt } = await home~.zoe~.escrow(offerRules, payments); | ||
const liquidityOk = await instance~.addLiquidity(escrowReceipt); | ||
console.log(liquidityOk); | ||
|
||
if (liquidityOk) { | ||
// Only store if the contract instance has liquidities. | ||
const instanceId = await home~.registrar~.register(CONTRACT_NAME, instanceHandle); | ||
console.log('- Autoswap instance', CONTRACT_NAME, '=>', instanceId); | ||
} | ||
|
||
// Output the record from contract IDs to registered names to stdout. | ||
console.log(JSON.stringify(nameIds, undefined, 2)); | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
import harden from '@agoric/harden'; | ||
|
||
function checkOrder(a0, a1, b0, b1) { | ||
if (a0 === b0 && a1 === b1) { | ||
return true; | ||
} | ||
|
||
if (a0 === b1 && a1 === b0) { | ||
return false; | ||
} | ||
|
||
throw new TypeError('Canot resove asset ordering'); | ||
} | ||
|
||
export async function makeExchange(E, log, host, zoe, registrar) { | ||
// === API | ||
|
||
async function getPrice(instanceId, extent0, assayId0, assayId1) { | ||
const instanceHandle = await E(registrar).get(instanceId); | ||
|
||
// Find the assays in the registrar | ||
const registrarAssays = await Promise.all([ | ||
E(registrar).get(assayId0), | ||
E(registrar).get(assayId1), | ||
]); | ||
|
||
// Get the assays in the contract. | ||
// Get the contract instance. | ||
const { | ||
terms: { assays: contractAssays }, | ||
instance, | ||
} = await E(zoe).getInstance(instanceHandle); | ||
|
||
// Check whether we sell on contract assay 0 or 1. | ||
const normal = checkOrder( | ||
registrarAssays[0], | ||
registrarAssays[1], | ||
contractAssays[0], | ||
contractAssays[1], | ||
); | ||
|
||
// Units of the input amount. | ||
const unit0 = await E(registrarAssays[0]).makeUnits(extent0); | ||
|
||
// Order the units accordingly. | ||
const units = [ | ||
normal ? unit0 : undefined, | ||
normal ? undefined : unit0, | ||
undefined, | ||
]; | ||
|
||
// Extract the price (multi steps for debugging). | ||
const unit1 = await E(instance).getPrice(units); | ||
const { extent } = unit1; | ||
return extent; | ||
} | ||
|
||
async function getOfferRules(instanceId, extent, assayId0, assayId1) { | ||
const instanceHandle = await E(registrar).get(instanceId); | ||
|
||
// Find the assays by id in the registrar. | ||
const registrarAssays = await Promise.all([ | ||
E(registrar).get(assayId0), | ||
E(registrar).get(assayId1), | ||
]); | ||
|
||
// Get the assays in the contract. | ||
const { | ||
terms: { assays: contractAssays }, | ||
} = await E(zoe).getInstance(instanceHandle); | ||
|
||
// Check whether we sell on contract assay 0 or 1. | ||
const normal = checkOrder( | ||
registrarAssays[0], | ||
registrarAssays[1], | ||
contractAssays[0], | ||
contractAssays[1], | ||
); | ||
|
||
// Contrust the rules for serialization (no instance). | ||
// This rule is the payment | ||
const rule0 = { | ||
kind: 'offerExactly', | ||
units: { assayId: assayId0, extent }, | ||
}; | ||
// This rule is the payout | ||
const rule1 = { | ||
kind: 'wantAtLeast', | ||
units: { assayId: assayId1 }, | ||
}; | ||
|
||
// Order the rules accordingly. | ||
const offerRules = harden({ | ||
payoutRules: [ | ||
normal ? rule0 : rule1, | ||
normal ? rule1 : rule0, | ||
{ | ||
kind: 'wantAtLeast', | ||
units: {}, | ||
}, | ||
], | ||
exitRule: { | ||
kind: 'onDemand', | ||
}, | ||
}); | ||
|
||
return offerRules; | ||
} | ||
|
||
const autoswap = harden({ | ||
userFacet: { | ||
getPrice, | ||
getOfferRules, | ||
}, | ||
adminFacet: {}, | ||
readFacet: {}, | ||
}); | ||
|
||
return autoswap; | ||
} |
Oops, something went wrong.