Skip to content

Commit

Permalink
feat: cleanups and fixes to the wallet
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelfig committed Sep 30, 2020
1 parent 926fa48 commit db525f8
Show file tree
Hide file tree
Showing 6 changed files with 168 additions and 77 deletions.
31 changes: 18 additions & 13 deletions packages/cosmic-swingset/lib/ag-solo/html/wallet-bridge.html
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,16 @@

<button id="launchWallet">Agoric Wallet</button>
<script type="text/javascript">
launchWallet.addEventListener('click', ev => {
const popupWallet = () => {
launchWallet.classList.add('pulse');
};

const ackWallet = () => {
launchWallet.classList.remove('pulse');
};

launchWallet.addEventListener('click', ev => {
ackWallet();
alert(`\
Use the:
Expand All @@ -51,10 +59,6 @@
command-line request to open the Agoric wallet.`);
});

const popupWallet = () => {
launchWallet.classList.add('pulse');
};

const walletPublicURL = new URL(
`/private/wallet-bridge${location.search}`,
window.origin.replace(/^http/, 'ws'),
Expand All @@ -63,6 +67,7 @@
const wsQueue = [];
const dappQueue = [];
let origin;
let popped = false;
ws.addEventListener('message', ev => {
let obj;
try {
Expand All @@ -76,6 +81,14 @@
if (obj.type === 'walletNeedDappApproval') {
// Let them approve.
popupWallet();
popped = true;
} else if (popped && obj.type === 'walletHaveDappApproval') {
ackWallet();
popped = false;
} else if (obj.type === 'walletOfferAdded') {
popupWallet();
} else if (obj.type === 'walletOfferHandled') {
ackWallet();
}
if (origin === undefined) {
dappQueue.push(obj);
Expand All @@ -94,10 +107,6 @@
// The queued messages are raw objects, so JSONify.
const obj = wsQueue.shift();
ws.send(JSON.stringify(obj));
if (obj.type === 'walletAddOffer') {
// Just pop up our corresponding UI.
popupWallet();
}
}
});

Expand Down Expand Up @@ -127,10 +136,6 @@
} else {
// console.log('sending', obj);
ws.send(JSON.stringify(obj));
if (obj.type === 'walletAddOffer') {
// Just pop up our corresponding UI.
popupWallet();
}
}
});
</script>
Expand Down
113 changes: 71 additions & 42 deletions packages/dapp-svelte-wallet/api/src/lib-wallet.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ export async function makeWallet({
const idToCompiledOfferP = new Map();
const idToComplete = new Map();
const idToSeat = new Map();
const idToOutcome = new Map();

// Client-side representation of the purses inbox;
/** @type {Map<string, PursesJSONState>} */
Expand Down Expand Up @@ -182,7 +181,8 @@ export async function makeWallet({
throw e;
}
},
receive(payment) {
async receive(paymentP) {
const payment = await paymentP;
return E(purse).deposit(payment);
},
deposit(payment, amount = undefined) {
Expand Down Expand Up @@ -246,31 +246,28 @@ export async function makeWallet({

async function updateInboxState(id, offer) {
// Only sent the uncompiled offer to the client.
const {
instanceHandleBoardId,
installationHandleBoardId,
proposalTemplate,
} = offer;
const { instance, installation, proposalTemplate, ...rest } = offer;
if (!instance || !installation) {
return;
}
delete rest.actions;
// We could get the instanceHandle and installationHandle from the
// board and store them to prevent having to make this call each
// time, but if we want the offers to be able to sent to the
// frontend, we cannot store the instanceHandle and
// installationHandle in these offer objects because the handles
// are presences and we don't wish to send presences to the
// frontend.
const instanceHandle = await E(board).getValue(instanceHandleBoardId);
const installationHandle = await E(board).getValue(
installationHandleBoardId,
);
const instance = display(instanceHandle);
const installation = display(installationHandle);
const instanceDisplay = display(instance);
const installationDisplay = display(installation);
const alreadyDisplayed =
inboxState.has(id) && inboxState.get(id).proposalForDisplay;

const offerForDisplay = {
...offer,
instancePetname: instance.petname,
installationPetname: installation.petname,
...rest,
proposalTemplate,
instancePetname: instanceDisplay.petname,
installationPetname: installationDisplay.petname,
proposalForDisplay: displayProposal(alreadyDisplayed || proposalTemplate),
};

Expand Down Expand Up @@ -442,8 +439,10 @@ export async function makeWallet({

const addIssuer = async (petnameForBrand, issuerP, makePurse = false) => {
const { brand, issuer } = await brandTable.initIssuer(issuerP);
const issuerBoardId = await E(board).getId(issuer);
issuerToBoardId.init(issuer, issuerBoardId);
if (!issuerToBoardId.has(issuer)) {
const issuerBoardId = await E(board).getId(issuer);
issuerToBoardId.init(issuer, issuerBoardId);
}
const addBrandPetname = () => {
let p;
const already = brandMapping.valToPetname.has(brand);
Expand Down Expand Up @@ -486,8 +485,8 @@ export async function makeWallet({
depositFacet = actions;
} else {
depositFacet = harden({
receive(payment) {
return E(actions).receive(payment);
receive(paymentP) {
return E(actions).receive(paymentP);
},
});
}
Expand Down Expand Up @@ -620,6 +619,12 @@ export async function makeWallet({
inviteHandleBoardId, // Keep for backward-compatibility.
invitationHandleBoardId = inviteHandleBoardId,
} = offer;

assert.typeof(
invitationHandleBoardId,
'string',
details`invitationHandleBoardId must be a string`,
);
const { proposal, purseKeywordRecord } = compileProposal(
offer.proposalTemplate,
);
Expand All @@ -643,8 +648,17 @@ export async function makeWallet({
harden([inviteValueElems.find(matchInvite)]),
);
const inviteP = E(zoeInvitePurse).withdraw(inviteAmount);
const { installation, instance } = await E(zoe).getInvitationDetails(
inviteP,
);

return { proposal, inviteP, purseKeywordRecord };
return {
proposal,
inviteP,
purseKeywordRecord,
installation,
instance,
};
};

/** @type {Store<string, DappRecord>} */
Expand Down Expand Up @@ -747,20 +761,8 @@ export async function makeWallet({
async function addOffer(rawOffer, requestContext = {}) {
const dappOrigin =
requestContext.dappOrigin || requestContext.origin || 'unknown';
const {
id: rawId,
instanceHandleBoardId,
installationHandleBoardId,
} = rawOffer;
const { id: rawId } = rawOffer;
const id = `${dappOrigin}#${rawId}`;
assert(
typeof instanceHandleBoardId === 'string',
details`instanceHandleBoardId must be a string`,
);
assert(
typeof installationHandleBoardId === 'string',
details`installationHandleBoardId must be a string`,
);
const offer = harden({
...rawOffer,
id,
Expand All @@ -771,15 +773,35 @@ export async function makeWallet({
updateInboxState(id, offer);

// Compile the offer
idToCompiledOfferP.set(id, await compileOffer(offer));
const compiledOfferP = compileOffer(offer);
idToCompiledOfferP.set(id, compiledOfferP);

// Our inbox state may have an enriched offer.
updateInboxState(id, idToOffer.get(id));
const { installation, instance } = await compiledOfferP;

if (idToOffer.has(id)) {
idToOffer.set(
id,
harden({
...idToOffer.get(id),
installation,
instance,
}),
);
updateInboxState(id, idToOffer.get(id));
}
return id;
}

function consummated(offer) {
return offer.status !== undefined;
if (offer.status !== undefined) {
return true;
}
if (offer.actions) {
E(offer.actions).handled(offer);
}
return false;
}

function declineOffer(id) {
Expand Down Expand Up @@ -824,7 +846,7 @@ export async function makeWallet({
return undefined;
}

/** @type {{ outcome?: any, depositedP?: Promise<any[]> }} */
/** @type {{ outcome?: any, depositedP?: Promise<any[]>, outcomeDetails?: any }} */
let ret = {};
let alreadyResolved = false;
const rejected = e => {
Expand Down Expand Up @@ -870,9 +892,15 @@ export async function makeWallet({
// it could be an object. We don't do anything currently if it
// is an object, but we will store it here for future use.
const outcome = await E(seat).getOfferResult();
idToOutcome.set(id, outcome);
if (offer.actions) {
E(offer.actions).result(offer, outcome);
}

ret = { outcome, depositedP };
ret = {
outcome,
depositedP,
outcomeDetails: offer.outcomeDetails,
};

// Update status, drop the proposal
depositedP
Expand Down Expand Up @@ -922,11 +950,12 @@ export async function makeWallet({
};

/**
* @param {Payment} payment
* @param {ERef<Payment>} paymentP
* @param {Purse | Petname=} depositTo
*/
const addPayment = async (payment, depositTo = undefined) => {
// We don't even create the record until we get an alleged brand.
const addPayment = async (paymentP, depositTo = undefined) => {
// We don't even create the record until we resolve the payment.
const payment = await paymentP;
const brand = await E(payment).getAllegedBrand();
const depositedPK = makePromiseKit();

Expand Down
2 changes: 1 addition & 1 deletion packages/dapp-svelte-wallet/api/src/observable.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export default function makeObservablePurse(E, purse, onFulfilled) {
.then(depositOnlyFacet => {
return {
receive(...args) {
E(depositOnlyFacet)
return E(depositOnlyFacet)
.receive(...args)
.then(result => {
onFulfilled();
Expand Down
Loading

0 comments on commit db525f8

Please sign in to comment.