Skip to content

Commit

Permalink
feat(smart-wallet): publish pending offers before completion
Browse files Browse the repository at this point in the history
  • Loading branch information
samsiegart committed Feb 17, 2023
1 parent 0de845d commit 638c2b6
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 15 deletions.
28 changes: 23 additions & 5 deletions packages/inter-protocol/test/smartWallet/test-psm-integration.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ import { eventLoopIteration } from '@agoric/zoe/tools/eventLoopIteration.js';
import { E } from '@endo/far';
import { NonNullish } from '@agoric/assert';

import { coalesceUpdates } from '@agoric/smart-wallet/src/utils.js';
import {
coalesceUpdates,
sequenceUpdates,
} from '@agoric/smart-wallet/src/utils.js';
import { INVITATION_MAKERS_DESC } from '../../src/econCommitteeCharter.js';
import {
currentPurseBalance,
Expand Down Expand Up @@ -63,7 +66,7 @@ test('null swap', async t => {
const { getBalanceFor, wallet } = await t.context.provideWalletAndBalances(
'agoric1nullswap',
);
const computedState = coalesceUpdates(E(wallet).getUpdatesSubscriber());
const updates = sequenceUpdates(E(wallet).getUpdatesSubscriber());

/** @type {import('@agoric/smart-wallet/src/invitations').AgoricContractInvitationSpec} */
const invitationSpec = {
Expand All @@ -81,13 +84,28 @@ test('null swap', async t => {
want: { Out: anchor.makeEmpty() },
},
});

await eventLoopIteration();

t.like(updates[0], {
updated: 'balance',
});

const statusUpdateHasKeys = (updateIndex, result, numWants, payouts) => {
const { status } = updates[updateIndex];
t.is('result' in status, result, 'result');
t.is('numWantsSatisfied' in status, numWants, 'numWantsSatisfied');
t.is('payouts' in status, payouts, 'payouts');
t.false('error' in status);
};

statusUpdateHasKeys(1, false, false, false);
statusUpdateHasKeys(2, true, false, false);
statusUpdateHasKeys(3, true, true, false);
statusUpdateHasKeys(4, true, true, true);

t.is(await E.get(getBalanceFor(anchor.brand)).value, 0n);
t.is(await E.get(getBalanceFor(mintedBrand)).value, 0n);
const status = computedState.offerStatuses.get('nullSwap');
t.is(status?.id, 'nullSwap');
t.false('error' in NonNullish(status), 'should not have an error');
});

// we test this direciton of swap because wanting anchor would require the PSM to have anchor in it first
Expand Down
1 change: 1 addition & 0 deletions packages/smart-wallet/src/offers.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ export const makeOfferExecutor = ({
offerArgs,
);
logger.info(id, 'seated');
updateStatus({});

// publish 'result'
void E.when(
Expand Down
25 changes: 15 additions & 10 deletions packages/smart-wallet/src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,19 +98,24 @@ export const coalesceUpdates = (updates, invitationBrand) => {
};

/**
* Sequence updates from a wallet UpdateRecord publication feed. Note that local
* state may not reflect the wallet's state if the initial updates are missed.
*
* If this proves to be a problem we can add an option to this or a related
* utility to reset state from RPC.
*
* @param {import('@agoric/casting').Follower<any>} follower
* @throws if there is no first height
* @param {ERef<Subscriber<import('./smartWallet').UpdateRecord>>} updates
*/
export const assertHasData = async follower => {
const eachIterable = E(follower).getReverseIterable();
const iterator = await E(eachIterable)[Symbol.asyncIterator]();
const el = await iterator.next();
export const sequenceUpdates = updates => {
const sequence = [];

// done before we started
if (el.done && !el.value) {
assert.fail(NO_SMART_WALLET_ERROR);
}
void observeIteration(subscribeEach(updates), {
updateState: updateRecord => {
sequence.push(updateRecord);
},
});

return sequence;
};

/**
Expand Down

0 comments on commit 638c2b6

Please sign in to comment.