@agoric/smart-wallet 0.5.3 → 0.5.4-calypso-dev-84eb287.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +34 -24
- package/src/invitations.d.ts +14 -10
- package/src/invitations.d.ts.map +1 -1
- package/src/invitations.js +32 -28
- package/src/marshal-contexts.d.ts +44 -41
- package/src/marshal-contexts.d.ts.map +1 -1
- package/src/marshal-contexts.js +65 -58
- package/src/offerWatcher.d.ts +48 -0
- package/src/offerWatcher.d.ts.map +1 -0
- package/src/offerWatcher.js +311 -0
- package/src/offers.d.ts +7 -31
- package/src/offers.d.ts.map +1 -1
- package/src/offers.js +9 -182
- package/src/proposals/upgrade-wallet-factory2-proposal.d.ts +23 -0
- package/src/proposals/upgrade-wallet-factory2-proposal.d.ts.map +1 -0
- package/src/proposals/upgrade-wallet-factory2-proposal.js +60 -0
- package/src/proposals/upgrade-walletFactory-proposal.d.ts +17 -0
- package/src/proposals/upgrade-walletFactory-proposal.d.ts.map +1 -0
- package/src/proposals/upgrade-walletFactory-proposal.js +127 -0
- package/src/smartWallet.d.ts +116 -69
- package/src/smartWallet.d.ts.map +1 -1
- package/src/smartWallet.js +830 -202
- package/src/typeGuards.d.ts +1 -1
- package/src/types.d.ts +24 -13
- package/src/utils.d.ts +17 -14
- package/src/utils.d.ts.map +1 -1
- package/src/utils.js +18 -6
- package/src/walletFactory.d.ts +26 -79
- package/src/walletFactory.d.ts.map +1 -1
- package/src/walletFactory.js +103 -42
- package/CHANGELOG.md +0 -172
- package/src/payments.d.ts +0 -20
- package/src/payments.d.ts.map +0 -1
- package/src/payments.js +0 -89
package/src/typeGuards.d.ts
CHANGED
package/src/types.d.ts
CHANGED
|
@@ -5,9 +5,12 @@
|
|
|
5
5
|
* Downside is it can't reference any ambient types, which most of agoric-sdk type are presently.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import { ERef
|
|
8
|
+
import type { ERef } from '@endo/far';
|
|
9
9
|
import type { CapData } from '@endo/marshal';
|
|
10
|
-
import type {
|
|
10
|
+
import type { agoric } from '@agoric/cosmic-proto';
|
|
11
|
+
import type { AgoricNamesRemotes } from '@agoric/vats/tools/board-utils.js';
|
|
12
|
+
import type { StoredFacet } from '@agoric/internal/src/lib-chainStorage.js';
|
|
13
|
+
import type { OfferSpec } from './offers.js';
|
|
11
14
|
|
|
12
15
|
declare const CapDataShape: unique symbol;
|
|
13
16
|
|
|
@@ -19,33 +22,33 @@ declare const CapDataShape: unique symbol;
|
|
|
19
22
|
*/
|
|
20
23
|
export type Petname = string | string[];
|
|
21
24
|
|
|
22
|
-
export type
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
Record<string, (...args: any[]) => Promise<Invitation>>
|
|
25
|
+
export type InvitationMakers = Record<
|
|
26
|
+
string,
|
|
27
|
+
(...args: any[]) => Promise<Invitation>
|
|
26
28
|
>;
|
|
27
29
|
|
|
28
30
|
export type PublicSubscribers = Record<string, ERef<StoredFacet>>;
|
|
29
31
|
|
|
32
|
+
export interface ContinuingOfferResult {
|
|
33
|
+
invitationMakers: InvitationMakers;
|
|
34
|
+
publicSubscribers: PublicSubscribers;
|
|
35
|
+
}
|
|
36
|
+
|
|
30
37
|
export type Cell<T> = {
|
|
31
38
|
get: () => T;
|
|
32
39
|
set(val: T): void;
|
|
33
40
|
};
|
|
34
41
|
|
|
35
|
-
export type BridgeActionCapData = WalletCapData<
|
|
36
|
-
import('./smartWallet.js').BridgeAction
|
|
37
|
-
>;
|
|
38
|
-
|
|
39
42
|
/**
|
|
40
43
|
* Defined by walletAction struct in msg_server.go
|
|
41
44
|
*
|
|
42
|
-
* @see {
|
|
45
|
+
* @see {agoric.swingset.MsgWalletAction} and walletSpendAction in msg_server.go
|
|
43
46
|
*/
|
|
44
47
|
export type WalletActionMsg = {
|
|
45
48
|
type: 'WALLET_ACTION';
|
|
46
49
|
/** base64 of Uint8Array of bech32 data */
|
|
47
50
|
owner: string;
|
|
48
|
-
/** JSON of
|
|
51
|
+
/** JSON of marshalled BridgeAction */
|
|
49
52
|
action: string;
|
|
50
53
|
blockHeight: unknown; // int64
|
|
51
54
|
blockTime: unknown; // int64
|
|
@@ -54,7 +57,7 @@ export type WalletActionMsg = {
|
|
|
54
57
|
/**
|
|
55
58
|
* Defined by walletSpendAction struct in msg_server.go
|
|
56
59
|
*
|
|
57
|
-
* @see {MsgWalletSpendAction} and walletSpendAction in msg_server.go
|
|
60
|
+
* @see {agoric.swingset.MsgWalletSpendAction} and walletSpendAction in msg_server.go
|
|
58
61
|
*/
|
|
59
62
|
export type WalletSpendActionMsg = {
|
|
60
63
|
type: 'WALLET_SPEND_ACTION';
|
|
@@ -74,3 +77,11 @@ export type WalletSpendActionMsg = {
|
|
|
74
77
|
* the sending of the message (as is the case for WALLET_SPEND_ACTION).
|
|
75
78
|
*/
|
|
76
79
|
export type WalletBridgeMsg = WalletActionMsg | WalletSpendActionMsg;
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Used for clientSupport helpers
|
|
83
|
+
*/
|
|
84
|
+
export type OfferMaker = (
|
|
85
|
+
agoricNames: AgoricNamesRemotes,
|
|
86
|
+
...rest: any[]
|
|
87
|
+
) => OfferSpec;
|
package/src/utils.d.ts
CHANGED
|
@@ -1,26 +1,29 @@
|
|
|
1
|
+
/** @import {OfferId, OfferStatus} from './offers.js'; */
|
|
1
2
|
export const NO_SMART_WALLET_ERROR: "no smart wallet";
|
|
2
|
-
export function makeWalletStateCoalescer(invitationBrand?: Brand<"set"> | undefined): {
|
|
3
|
+
export function makeWalletStateCoalescer(invitationBrand?: globalThis.Brand<"set"> | undefined): {
|
|
3
4
|
state: {
|
|
4
|
-
invitationsReceived: Map<
|
|
5
|
-
acceptedIn:
|
|
5
|
+
invitationsReceived: Map<OfferId, {
|
|
6
|
+
acceptedIn: OfferId;
|
|
6
7
|
description: string;
|
|
7
8
|
instance: Instance;
|
|
8
9
|
}>;
|
|
9
|
-
offerStatuses: Map<
|
|
10
|
-
balances: Map<Brand
|
|
10
|
+
offerStatuses: Map<OfferId, OfferStatus>;
|
|
11
|
+
balances: Map<globalThis.Brand, globalThis.Amount>;
|
|
11
12
|
};
|
|
12
|
-
update: (updateRecord: import(
|
|
13
|
+
update: (updateRecord: import("./smartWallet.js").UpdateRecord | {}) => void;
|
|
13
14
|
};
|
|
14
|
-
export function coalesceUpdates(updates: ERef<Subscriber<import(
|
|
15
|
-
invitationsReceived: Map<
|
|
16
|
-
acceptedIn:
|
|
15
|
+
export function coalesceUpdates(updates: ERef<Subscriber<import("./smartWallet.js").UpdateRecord>>, invitationBrand?: globalThis.Brand<"set"> | undefined): {
|
|
16
|
+
invitationsReceived: Map<OfferId, {
|
|
17
|
+
acceptedIn: OfferId;
|
|
17
18
|
description: string;
|
|
18
19
|
instance: Instance;
|
|
19
20
|
}>;
|
|
20
|
-
offerStatuses: Map<
|
|
21
|
-
balances: Map<Brand
|
|
21
|
+
offerStatuses: Map<OfferId, OfferStatus>;
|
|
22
|
+
balances: Map<globalThis.Brand, globalThis.Amount>;
|
|
22
23
|
};
|
|
23
|
-
export function assertHasData(follower: import(
|
|
24
|
-
export function objectMapStoragePath(subscribers?: import("@agoric/zoe/src/contractSupport").TopicsRecord | import("./types.js").PublicSubscribers | undefined): ERef<Record<string, string>> | null;
|
|
25
|
-
export type CoalescedWalletState = ReturnType<typeof makeWalletStateCoalescer>[
|
|
24
|
+
export function assertHasData(follower: import("@agoric/casting").Follower<any>): Promise<void>;
|
|
25
|
+
export function objectMapStoragePath(subscribers?: import("@agoric/zoe/src/contractSupport/topics.js").TopicsRecord | import("./types.js").PublicSubscribers | undefined): ERef<Record<string, string>> | null;
|
|
26
|
+
export type CoalescedWalletState = ReturnType<typeof makeWalletStateCoalescer>["state"];
|
|
27
|
+
import type { OfferId } from './offers.js';
|
|
28
|
+
import type { OfferStatus } from './offers.js';
|
|
26
29
|
//# sourceMappingURL=utils.d.ts.map
|
package/src/utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["utils.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["utils.js"],"names":[],"mappings":"AAIA,yDAAyD;AAEzD,sDAAuD;AAKhD;;;wBAYc,OAAO;yBACN,MAAM;sBACT,QAAQ;;;;;2BAOd,OAAO,kBAAkB,EAAE,YAAY,GAAG,EAAE;EAgExD;AAaM,yCAHI,IAAI,CAAC,UAAU,CAAC,OAAO,kBAAkB,EAAE,YAAY,CAAC,CAAC;;oBAnF/C,OAAO;qBACN,MAAM;kBACT,QAAQ;;;;EA6F1B;AAMM,wCAHI,OAAO,iBAAiB,EAAE,QAAQ,CAAC,GAAG,CAAC,iBAYjD;AASM,2KAFM,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,IAAI,CAW/C;mCAtDa,UAAU,CAAC,OAAO,wBAAwB,CAAC,CAAC,OAAO,CAAC;6BA7F1B,aAAa;iCAAb,aAAa"}
|
package/src/utils.js
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
/* eslint-disable no-undef-init */
|
|
2
1
|
import { deeplyFulfilledObject, objectMap, makeTracer } from '@agoric/internal';
|
|
3
2
|
import { observeIteration, subscribeEach } from '@agoric/notifier';
|
|
4
3
|
import { E } from '@endo/far';
|
|
5
4
|
|
|
5
|
+
/** @import {OfferId, OfferStatus} from './offers.js'; */
|
|
6
|
+
|
|
6
7
|
export const NO_SMART_WALLET_ERROR = 'no smart wallet';
|
|
7
8
|
|
|
8
9
|
const trace = makeTracer('WUTIL', false);
|
|
9
10
|
|
|
10
11
|
/** @param {Brand<'set'>} [invitationBrand] */
|
|
11
12
|
export const makeWalletStateCoalescer = (invitationBrand = undefined) => {
|
|
12
|
-
/** @type {Map<
|
|
13
|
+
/** @type {Map<OfferId, OfferStatus>} */
|
|
13
14
|
const offerStatuses = new Map();
|
|
14
15
|
/** @type {Map<Brand, Amount>} */
|
|
15
16
|
const balances = new Map();
|
|
@@ -17,11 +18,21 @@ export const makeWalletStateCoalescer = (invitationBrand = undefined) => {
|
|
|
17
18
|
/**
|
|
18
19
|
* keyed by description; xxx assumes unique
|
|
19
20
|
*
|
|
20
|
-
* @type {Map<
|
|
21
|
+
* @type {Map<
|
|
22
|
+
* OfferId,
|
|
23
|
+
* {
|
|
24
|
+
* acceptedIn: OfferId;
|
|
25
|
+
* description: string;
|
|
26
|
+
* instance: Instance;
|
|
27
|
+
* }
|
|
28
|
+
* >}
|
|
21
29
|
*/
|
|
22
30
|
const invitationsReceived = new Map();
|
|
23
31
|
|
|
24
|
-
/**
|
|
32
|
+
/**
|
|
33
|
+
* @param {import('./smartWallet.js').UpdateRecord | {}} updateRecord newer
|
|
34
|
+
* than previous
|
|
35
|
+
*/
|
|
25
36
|
const update = updateRecord => {
|
|
26
37
|
if (!('updated' in updateRecord)) {
|
|
27
38
|
return;
|
|
@@ -93,7 +104,7 @@ export const makeWalletStateCoalescer = (invitationBrand = undefined) => {
|
|
|
93
104
|
* If this proves to be a problem we can add an option to this or a related
|
|
94
105
|
* utility to reset state from RPC.
|
|
95
106
|
*
|
|
96
|
-
* @param {ERef<Subscriber<import('./smartWallet').UpdateRecord>>} updates
|
|
107
|
+
* @param {ERef<Subscriber<import('./smartWallet.js').UpdateRecord>>} updates
|
|
97
108
|
* @param {Brand<'set'>} [invitationBrand]
|
|
98
109
|
*/
|
|
99
110
|
export const coalesceUpdates = (updates, invitationBrand) => {
|
|
@@ -125,7 +136,8 @@ export const assertHasData = async follower => {
|
|
|
125
136
|
/**
|
|
126
137
|
* Handles the case of falsy argument so the caller can consistently await.
|
|
127
138
|
*
|
|
128
|
-
* @param {import('./types.js').PublicSubscribers
|
|
139
|
+
* @param {import('./types.js').PublicSubscribers
|
|
140
|
+
* | import('@agoric/zoe/src/contractSupport/index.js').TopicsRecord} [subscribers]
|
|
129
141
|
* @returns {ERef<Record<string, string>> | null}
|
|
130
142
|
*/
|
|
131
143
|
export const objectMapStoragePath = subscribers => {
|
package/src/walletFactory.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
export const privateArgsShape: import("@endo/patterns").Matcher;
|
|
2
1
|
export namespace customTermsShape {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
let agoricNames: globalThis.Pattern;
|
|
3
|
+
let board: globalThis.Pattern;
|
|
4
|
+
let assetPublisher: globalThis.Pattern;
|
|
6
5
|
}
|
|
7
|
-
export
|
|
6
|
+
export const privateArgsShape: import("@endo/patterns").Matcher;
|
|
7
|
+
export function publishDepositFacet(address: string, wallet: import("./smartWallet.js").SmartWallet, namesByAddressAdmin: ERef<import("@agoric/vats").NameAdmin>): Promise<unknown>;
|
|
8
8
|
export function makeAssetRegistry(assetPublisher: AssetPublisher): {
|
|
9
9
|
/** @param {Brand} brand */
|
|
10
10
|
has: (brand: Brand) => boolean;
|
|
@@ -13,100 +13,47 @@ export function makeAssetRegistry(assetPublisher: AssetPublisher): {
|
|
|
13
13
|
brand: Brand;
|
|
14
14
|
displayInfo: DisplayInfo;
|
|
15
15
|
issuer: Issuer;
|
|
16
|
-
petname: import(
|
|
16
|
+
petname: import("./types.js").Petname;
|
|
17
17
|
};
|
|
18
18
|
values: () => Iterable<{
|
|
19
19
|
brand: Brand;
|
|
20
20
|
displayInfo: DisplayInfo;
|
|
21
21
|
issuer: Issuer;
|
|
22
|
-
petname: import(
|
|
22
|
+
petname: import("./types.js").Petname;
|
|
23
23
|
}>;
|
|
24
24
|
};
|
|
25
25
|
export function prepare(zcf: ZCF<SmartWalletContractTerms>, privateArgs: {
|
|
26
26
|
storageNode: ERef<StorageNode>;
|
|
27
|
-
walletBridgeManager?: ERef<import("@agoric/vats").ScopedBridgeManager
|
|
28
|
-
walletReviver?: ERef<WalletReviver
|
|
29
|
-
}, baggage:
|
|
30
|
-
creatorFacet: {
|
|
31
|
-
/**
|
|
32
|
-
* @param {string} address
|
|
33
|
-
* @param {ERef<import('@agoric/vats/src/vat-bank').Bank>} bank
|
|
34
|
-
* @param {ERef<import('@agoric/vats/').NameAdmin>} namesByAddressAdmin
|
|
35
|
-
* @returns {Promise<[wallet: import('./smartWallet').SmartWallet, isNew: boolean]>} wallet
|
|
36
|
-
* along with a flag to distinguish between looking up an existing wallet
|
|
37
|
-
* and creating a new one.
|
|
38
|
-
*/
|
|
39
|
-
provideSmartWallet(address: string, bank: ERef<import('@agoric/vats/src/vat-bank').Bank>, namesByAddressAdmin: ERef<import('@agoric/vats/').NameAdmin>): Promise<[wallet: {
|
|
40
|
-
handleBridgeAction(actionCapData: import("@endo/marshal").CapData<string>, canSpend?: boolean | undefined): Promise<void>;
|
|
41
|
-
getDepositFacet(): {
|
|
42
|
-
receive(payment: import("@endo/far").FarRef<Payment<AssetKind>, import("@endo/eventual-send").DataOnly<Payment<AssetKind>>>): Promise<Amount<AssetKind>>;
|
|
43
|
-
};
|
|
44
|
-
getOffersFacet(): {
|
|
45
|
-
executeOffer(offerSpec: import("./offers.js").OfferSpec): Promise<void>;
|
|
46
|
-
tryExitOffer(offerId: import("./offers.js").OfferId): Promise<void>;
|
|
47
|
-
};
|
|
48
|
-
getCurrentSubscriber(): Subscriber<import("./smartWallet.js").CurrentWalletRecord>;
|
|
49
|
-
getUpdatesSubscriber(): Subscriber<import("./smartWallet.js").UpdateRecord>;
|
|
50
|
-
getPublicTopics(): {
|
|
51
|
-
current: {
|
|
52
|
-
description: string;
|
|
53
|
-
subscriber: Subscriber<import("./smartWallet.js").CurrentWalletRecord>;
|
|
54
|
-
storagePath: Promise<string>;
|
|
55
|
-
};
|
|
56
|
-
updates: {
|
|
57
|
-
description: string;
|
|
58
|
-
subscriber: Subscriber<import("./smartWallet.js").UpdateRecord>;
|
|
59
|
-
storagePath: Promise<string>;
|
|
60
|
-
};
|
|
61
|
-
};
|
|
62
|
-
}, isNew: boolean]>;
|
|
63
|
-
} & import("@endo/eventual-send").RemotableBrand<{}, {
|
|
27
|
+
walletBridgeManager?: ERef<import("@agoric/vats").ScopedBridgeManager<"wallet">>;
|
|
28
|
+
walletReviver?: ERef<WalletReviver>;
|
|
29
|
+
}, baggage: import("@agoric/vat-data").Baggage): Promise<{
|
|
30
|
+
creatorFacet: import("@endo/exo").Guarded<{
|
|
64
31
|
/**
|
|
65
32
|
* @param {string} address
|
|
66
|
-
* @param {ERef<import('@agoric/vats/src/vat-bank').Bank>} bank
|
|
67
|
-
* @param {ERef<import('@agoric/vats/').NameAdmin>} namesByAddressAdmin
|
|
68
|
-
* @returns {Promise<
|
|
69
|
-
*
|
|
70
|
-
*
|
|
33
|
+
* @param {ERef<import('@agoric/vats/src/vat-bank.js').Bank>} bank
|
|
34
|
+
* @param {ERef<import('@agoric/vats/src/types.js').NameAdmin>} namesByAddressAdmin
|
|
35
|
+
* @returns {Promise<
|
|
36
|
+
* [wallet: import('./smartWallet.js').SmartWallet, isNew: boolean]
|
|
37
|
+
* >}
|
|
38
|
+
* wallet along with a flag to distinguish between looking up an existing
|
|
39
|
+
* wallet and creating a new one.
|
|
71
40
|
*/
|
|
72
|
-
provideSmartWallet(address: string, bank: ERef<import(
|
|
73
|
-
handleBridgeAction(actionCapData: import("@endo/marshal").CapData<string>, canSpend?: boolean | undefined): Promise<void>;
|
|
74
|
-
getDepositFacet(): {
|
|
75
|
-
receive(payment: import("@endo/far").FarRef<Payment<AssetKind>, import("@endo/eventual-send").DataOnly<Payment<AssetKind>>>): Promise<Amount<AssetKind>>;
|
|
76
|
-
};
|
|
77
|
-
getOffersFacet(): {
|
|
78
|
-
executeOffer(offerSpec: import("./offers.js").OfferSpec): Promise<void>;
|
|
79
|
-
tryExitOffer(offerId: import("./offers.js").OfferId): Promise<void>;
|
|
80
|
-
};
|
|
81
|
-
getCurrentSubscriber(): Subscriber<import("./smartWallet.js").CurrentWalletRecord>;
|
|
82
|
-
getUpdatesSubscriber(): Subscriber<import("./smartWallet.js").UpdateRecord>;
|
|
83
|
-
getPublicTopics(): {
|
|
84
|
-
current: {
|
|
85
|
-
description: string;
|
|
86
|
-
subscriber: Subscriber<import("./smartWallet.js").CurrentWalletRecord>;
|
|
87
|
-
storagePath: Promise<string>;
|
|
88
|
-
};
|
|
89
|
-
updates: {
|
|
90
|
-
description: string;
|
|
91
|
-
subscriber: Subscriber<import("./smartWallet.js").UpdateRecord>;
|
|
92
|
-
storagePath: Promise<string>;
|
|
93
|
-
};
|
|
94
|
-
};
|
|
95
|
-
}, isNew: boolean]>;
|
|
41
|
+
provideSmartWallet(address: string, bank: ERef<import("@agoric/vats/src/vat-bank.js").Bank>, namesByAddressAdmin: ERef<import("@agoric/vats/src/types.js").NameAdmin>): Promise<[wallet: import("./smartWallet.js").SmartWallet, isNew: boolean]>;
|
|
96
42
|
}>;
|
|
97
43
|
}>;
|
|
98
44
|
export type SmartWalletContractTerms = {
|
|
99
45
|
agoricNames: ERef<NameHub>;
|
|
100
|
-
board: ERef<import(
|
|
46
|
+
board: ERef<import("@agoric/vats").Board>;
|
|
101
47
|
assetPublisher: AssetPublisher;
|
|
102
48
|
};
|
|
103
|
-
export type NameHub = import('@agoric/vats').NameHub;
|
|
104
49
|
export type AssetPublisher = {
|
|
105
|
-
getAssetSubscription: () => ERef<IterableEachTopic<import(
|
|
50
|
+
getAssetSubscription: () => ERef<IterableEachTopic<import("@agoric/vats/src/vat-bank.js").AssetDescriptor>>;
|
|
106
51
|
};
|
|
107
|
-
export type
|
|
52
|
+
export type IsRevive = boolean;
|
|
108
53
|
export type WalletReviver = {
|
|
109
|
-
reviveWallet: (address: string) => Promise<import(
|
|
110
|
-
ackWallet: (address: string) =>
|
|
54
|
+
reviveWallet: (address: string) => Promise<import("./smartWallet.js").SmartWallet>;
|
|
55
|
+
ackWallet: (address: string) => IsRevive;
|
|
111
56
|
};
|
|
57
|
+
export type start = typeof prepare;
|
|
58
|
+
import type { NameHub } from '@agoric/vats';
|
|
112
59
|
//# sourceMappingURL=walletFactory.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"walletFactory.d.ts","sourceRoot":"","sources":["walletFactory.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"walletFactory.d.ts","sourceRoot":"","sources":["walletFactory.js"],"names":[],"mappings":";;;;;AA6BA,gEAKE;AAaK,6CAJI,MAAM,UACN,OAAO,kBAAkB,EAAE,WAAW,uBACtC,IAAI,CAAC,OAAO,cAAc,EAAE,SAAS,CAAC,oBAehD;AAWM,kDAFI,cAAc;IAyCrB,2BAA2B;iBAAf,KAAK;IAEjB,2BAA2B;iBAAf,KAAK;eArCP,KAAK;qBACC,WAAW;gBAChB,MAAM;iBACL,OAAO,YAAY,EAAE,OAAO;;;eAH9B,KAAK;qBACC,WAAW;gBAChB,MAAM;iBACL,OAAO,YAAY,EAAE,OAAO;;EAuC3C;AAyCM,6BAVI,GAAG,CAAC,wBAAwB,CAAC,eAC7B;IACV,WAAe,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IACnC,mBAAuB,CAAC,EAAE,IAAI,CAC9B,OAAa,cAAc,EAAE,mBAAmB,CAAC,QAAQ,CAAC,CACrD,CAAC;IACN,aAAiB,CAAC,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;CACrC,WACO,OAAO,kBAAkB,EAAE,OAAO;;QA2IvC;;;;;;;;;WASG;oCARQ,MAAM,QACN,IAAI,CAAC,OAAO,8BAA8B,EAAE,IAAI,CAAC,uBACjD,IAAI,CAAC,OAAO,2BAA2B,EAAE,SAAS,CAAC,GACjD,OAAO,CACnB,CAAK,MAAM,EAAE,OAAO,kBAAkB,EAAE,WAAW,EAAE,KAAK,EAAE,OAAO,CAAC,CACjE;;GAuDT;uCA5OY;IACZ,WAAe,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IAC/B,KAAS,EAAE,IAAI,CAAC,OAAO,cAAc,EAAE,KAAK,CAAC,CAAC;IAC9C,cAAkB,EAAE,cAAc,CAAC;CAChC;6BAGS;IACZ,oBAAwB,EAAE,MAAM,IAAI,CACpC,iBAAuB,CAAC,OAAO,8BAA8B,EAAE,eAAe,CAAC,CAC1E,CAAC;CACH;uBAGS,OAAO;4BAEP;IACZ,YAAgB,EAAE,CAClB,OAAa,EAAE,MAAM,KACZ,OAAO,CAAC,OAAO,kBAAkB,EAAE,WAAW,CAAC,CAAC;IACzD,SAAa,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,QAAQ,CAAC;CAC1C;oBA4NU,OAAO,OAAO;6BAtVD,cAAc"}
|
package/src/walletFactory.js
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @file Wallet Factory
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* Contract to make smart wallets.
|
|
5
|
+
*
|
|
6
|
+
* Note: The upgrade test uses a slightly modified copy of this file. When the
|
|
7
|
+
* interface changes here, that will also need to change.
|
|
5
8
|
*/
|
|
6
9
|
|
|
7
10
|
import { makeTracer, WalletName } from '@agoric/internal';
|
|
@@ -14,8 +17,16 @@ import { E } from '@endo/far';
|
|
|
14
17
|
import { prepareSmartWallet } from './smartWallet.js';
|
|
15
18
|
import { shape } from './typeGuards.js';
|
|
16
19
|
|
|
20
|
+
/** @import {NameHub} from '@agoric/vats'; */
|
|
21
|
+
|
|
17
22
|
const trace = makeTracer('WltFct');
|
|
18
23
|
|
|
24
|
+
export const customTermsShape = harden({
|
|
25
|
+
agoricNames: M.eref(M.remotable('agoricNames')),
|
|
26
|
+
board: M.eref(M.remotable('board')),
|
|
27
|
+
assetPublisher: M.eref(M.remotable('Bank')),
|
|
28
|
+
});
|
|
29
|
+
|
|
19
30
|
export const privateArgsShape = harden(
|
|
20
31
|
M.splitRecord(
|
|
21
32
|
{ storageNode: M.eref(M.remotable('StorageNode')) },
|
|
@@ -23,11 +34,8 @@ export const privateArgsShape = harden(
|
|
|
23
34
|
),
|
|
24
35
|
);
|
|
25
36
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
board: M.eref(M.remotable('board')),
|
|
29
|
-
assetPublisher: M.eref(M.remotable('Bank')),
|
|
30
|
-
});
|
|
37
|
+
const WALLETS_BY_ADDRESS = 'walletsByAddress';
|
|
38
|
+
const UPGRADE_TO_INCARNATION_TWO = 'upgrade to incarnation two';
|
|
31
39
|
|
|
32
40
|
/**
|
|
33
41
|
* Provide a NameHub for this address and insert depositFacet only if not
|
|
@@ -56,8 +64,8 @@ export const publishDepositFacet = async (
|
|
|
56
64
|
* Make a registry for use by the wallet instances.
|
|
57
65
|
*
|
|
58
66
|
* This doesn't need to persist durably because the `assetPublisher` has a
|
|
59
|
-
* "pinned" topic and call to getAssetSubscription gets a fresh stream of all
|
|
60
|
-
* assets that it knows of.
|
|
67
|
+
* "pinned" topic and call to getAssetSubscription gets a fresh stream of all
|
|
68
|
+
* the assets that it knows of.
|
|
61
69
|
*
|
|
62
70
|
* @param {AssetPublisher} assetPublisher
|
|
63
71
|
*/
|
|
@@ -65,12 +73,13 @@ export const makeAssetRegistry = assetPublisher => {
|
|
|
65
73
|
trace('makeAssetRegistry', assetPublisher);
|
|
66
74
|
/**
|
|
67
75
|
* @typedef {{
|
|
68
|
-
* brand: Brand
|
|
69
|
-
* displayInfo: DisplayInfo
|
|
70
|
-
* issuer: Issuer
|
|
71
|
-
* petname: import('./types').Petname
|
|
76
|
+
* brand: Brand;
|
|
77
|
+
* displayInfo: DisplayInfo;
|
|
78
|
+
* issuer: Issuer;
|
|
79
|
+
* petname: import('./types.js').Petname;
|
|
72
80
|
* }} BrandDescriptor
|
|
73
|
-
*
|
|
81
|
+
* For use by clients to describe brands to users. Includes `displayInfo` to
|
|
82
|
+
* save a remote call.
|
|
74
83
|
*/
|
|
75
84
|
/** @type {MapStore<Brand, BrandDescriptor>} */
|
|
76
85
|
const brandDescriptors = makeScalarMapStore();
|
|
@@ -110,45 +119,52 @@ export const makeAssetRegistry = assetPublisher => {
|
|
|
110
119
|
|
|
111
120
|
/**
|
|
112
121
|
* @typedef {{
|
|
113
|
-
* agoricNames: ERef<NameHub
|
|
114
|
-
* board: ERef<import('@agoric/vats').Board
|
|
115
|
-
* assetPublisher: AssetPublisher
|
|
122
|
+
* agoricNames: ERef<NameHub>;
|
|
123
|
+
* board: ERef<import('@agoric/vats').Board>;
|
|
124
|
+
* assetPublisher: AssetPublisher;
|
|
116
125
|
* }} SmartWalletContractTerms
|
|
117
126
|
*
|
|
118
|
-
* @typedef {import('@agoric/vats').NameHub} NameHub
|
|
119
127
|
*
|
|
120
128
|
* @typedef {{
|
|
121
129
|
* getAssetSubscription: () => ERef<
|
|
122
|
-
* IterableEachTopic<import('@agoric/vats/src/vat-bank').AssetDescriptor
|
|
130
|
+
* IterableEachTopic<import('@agoric/vats/src/vat-bank.js').AssetDescriptor>
|
|
131
|
+
* >;
|
|
123
132
|
* }} AssetPublisher
|
|
124
133
|
*
|
|
125
|
-
*
|
|
134
|
+
*
|
|
135
|
+
* @typedef {boolean} IsRevive
|
|
136
|
+
*
|
|
126
137
|
* @typedef {{
|
|
127
|
-
* reviveWallet: (
|
|
128
|
-
*
|
|
138
|
+
* reviveWallet: (
|
|
139
|
+
* address: string,
|
|
140
|
+
* ) => Promise<import('./smartWallet.js').SmartWallet>;
|
|
141
|
+
* ackWallet: (address: string) => IsRevive;
|
|
129
142
|
* }} WalletReviver
|
|
130
143
|
*/
|
|
131
144
|
|
|
132
|
-
// NB: even though all the wallets share this contract,
|
|
145
|
+
// NB: even though all the wallets share this contract,
|
|
133
146
|
// 1. they should not rely on that; they may be partitioned later
|
|
134
147
|
// 2. they should never be able to detect behaviors from another wallet
|
|
135
148
|
/**
|
|
136
149
|
* @param {ZCF<SmartWalletContractTerms>} zcf
|
|
137
150
|
* @param {{
|
|
138
|
-
* storageNode: ERef<StorageNode
|
|
139
|
-
* walletBridgeManager?: ERef<
|
|
140
|
-
*
|
|
151
|
+
* storageNode: ERef<StorageNode>;
|
|
152
|
+
* walletBridgeManager?: ERef<
|
|
153
|
+
* import('@agoric/vats').ScopedBridgeManager<'wallet'>
|
|
154
|
+
* >;
|
|
155
|
+
* walletReviver?: ERef<WalletReviver>;
|
|
141
156
|
* }} privateArgs
|
|
142
157
|
* @param {import('@agoric/vat-data').Baggage} baggage
|
|
143
158
|
*/
|
|
144
159
|
export const prepare = async (zcf, privateArgs, baggage) => {
|
|
160
|
+
const upgrading = baggage.has(WALLETS_BY_ADDRESS);
|
|
145
161
|
const { agoricNames, board, assetPublisher } = zcf.getTerms();
|
|
146
162
|
|
|
147
163
|
const zoe = zcf.getZoeService();
|
|
148
164
|
const { storageNode, walletBridgeManager, walletReviver } = privateArgs;
|
|
149
165
|
|
|
150
166
|
/** @type {MapStore<string, import('./smartWallet.js').SmartWallet>} */
|
|
151
|
-
const walletsByAddress = provideDurableMapStore(baggage,
|
|
167
|
+
const walletsByAddress = provideDurableMapStore(baggage, WALLETS_BY_ADDRESS);
|
|
152
168
|
const provider = makeAtomicProvider(walletsByAddress);
|
|
153
169
|
|
|
154
170
|
const handleWalletAction = makeExo(
|
|
@@ -160,17 +176,20 @@ export const prepare = async (zcf, privateArgs, baggage) => {
|
|
|
160
176
|
/**
|
|
161
177
|
* Designed to be called by the bridgeManager vat.
|
|
162
178
|
*
|
|
163
|
-
* If this errors before calling handleBridgeAction(), the failure will
|
|
164
|
-
* promise does reject, but as of now bridge
|
|
165
|
-
*
|
|
166
|
-
*
|
|
167
|
-
*
|
|
168
|
-
*
|
|
179
|
+
* If this errors before calling handleBridgeAction(), the failure will
|
|
180
|
+
* not be observable. The promise does reject, but as of now bridge
|
|
181
|
+
* manager drops instead of handling it. Eventually we'll make the bridge
|
|
182
|
+
* able to give feedback about the requesting transaction. Meanwhile we
|
|
183
|
+
* could write the error to chainStorage but we don't have a guarantee of
|
|
184
|
+
* the wallet owner to associate it with. (We could have a shared
|
|
185
|
+
* `lastError` node but it would be so noisy as to not provide much info
|
|
186
|
+
* to the end user.)
|
|
169
187
|
*
|
|
170
|
-
* Once the owner is known, this calls handleBridgeAction which ensures
|
|
171
|
-
* are published in the owner wallet's vstorage path.
|
|
188
|
+
* Once the owner is known, this calls handleBridgeAction which ensures
|
|
189
|
+
* that all errors are published in the owner wallet's vstorage path.
|
|
172
190
|
*
|
|
173
|
-
* @param {import('./types.js').WalletBridgeMsg} obj validated by
|
|
191
|
+
* @param {import('./types.js').WalletBridgeMsg} obj validated by
|
|
192
|
+
* shape.WalletBridgeMsg
|
|
174
193
|
* @returns {Promise<void>}
|
|
175
194
|
*/
|
|
176
195
|
fromBridge: async obj => {
|
|
@@ -219,6 +238,15 @@ export const prepare = async (zcf, privateArgs, baggage) => {
|
|
|
219
238
|
|
|
220
239
|
const registry = makeAssetRegistry(assetPublisher);
|
|
221
240
|
|
|
241
|
+
/**
|
|
242
|
+
* An object known only to walletFactory and smartWallets. The WalletFactory
|
|
243
|
+
* only has the self facet for the pre-existing wallets that must be repaired.
|
|
244
|
+
* Self is too accessible, so use of the repair function requires use of a
|
|
245
|
+
* secret that clients won't have. This can be removed once the upgrade has
|
|
246
|
+
* taken place.
|
|
247
|
+
*/
|
|
248
|
+
const upgradeToIncarnation2Key = harden({});
|
|
249
|
+
|
|
222
250
|
const shared = harden({
|
|
223
251
|
agoricNames,
|
|
224
252
|
invitationBrand,
|
|
@@ -227,15 +255,33 @@ export const prepare = async (zcf, privateArgs, baggage) => {
|
|
|
227
255
|
publicMarshaller,
|
|
228
256
|
registry,
|
|
229
257
|
zoe,
|
|
258
|
+
secretWalletFactoryKey: upgradeToIncarnation2Key,
|
|
230
259
|
});
|
|
231
260
|
|
|
232
261
|
/**
|
|
233
262
|
* Holders of this object:
|
|
263
|
+
*
|
|
234
264
|
* - vat (transitively from holding the wallet factory)
|
|
235
265
|
* - wallet-ui (which has key material; dapps use wallet-ui to propose actions)
|
|
236
266
|
*/
|
|
237
267
|
const makeSmartWallet = prepareSmartWallet(baggage, shared);
|
|
238
268
|
|
|
269
|
+
// One time repair for incarnation 2. We're adding WatchedPromises to allow
|
|
270
|
+
// wallets to durably monitor offer outcomes, but wallets that already exist
|
|
271
|
+
// need to be backfilled. This code needs to run once at the beginning of
|
|
272
|
+
// incarnation 2, and then shouldn't be needed again.
|
|
273
|
+
if (!baggage.has(UPGRADE_TO_INCARNATION_TWO)) {
|
|
274
|
+
trace('Wallet Factory upgrading to incarnation 2');
|
|
275
|
+
|
|
276
|
+
// This could take a while, depending on how many outstanding wallets exist.
|
|
277
|
+
// The current plan is that it will run exactly once, and inside an upgrade
|
|
278
|
+
// handler, between blocks.
|
|
279
|
+
for (const wallet of walletsByAddress.values()) {
|
|
280
|
+
wallet.repairWalletForIncarnation2(upgradeToIncarnation2Key);
|
|
281
|
+
}
|
|
282
|
+
baggage.init(UPGRADE_TO_INCARNATION_TWO, 'done');
|
|
283
|
+
}
|
|
284
|
+
|
|
239
285
|
const creatorFacet = prepareExo(
|
|
240
286
|
baggage,
|
|
241
287
|
'walletFactoryCreator',
|
|
@@ -249,16 +295,22 @@ export const prepare = async (zcf, privateArgs, baggage) => {
|
|
|
249
295
|
{
|
|
250
296
|
/**
|
|
251
297
|
* @param {string} address
|
|
252
|
-
* @param {ERef<import('@agoric/vats/src/vat-bank').Bank>} bank
|
|
253
|
-
* @param {ERef<import('@agoric/vats/').NameAdmin>} namesByAddressAdmin
|
|
254
|
-
* @returns {Promise<
|
|
255
|
-
*
|
|
256
|
-
*
|
|
298
|
+
* @param {ERef<import('@agoric/vats/src/vat-bank.js').Bank>} bank
|
|
299
|
+
* @param {ERef<import('@agoric/vats/src/types.js').NameAdmin>} namesByAddressAdmin
|
|
300
|
+
* @returns {Promise<
|
|
301
|
+
* [wallet: import('./smartWallet.js').SmartWallet, isNew: boolean]
|
|
302
|
+
* >}
|
|
303
|
+
* wallet along with a flag to distinguish between looking up an existing
|
|
304
|
+
* wallet and creating a new one.
|
|
257
305
|
*/
|
|
258
306
|
provideSmartWallet(address, bank, namesByAddressAdmin) {
|
|
259
307
|
let isNew = false;
|
|
260
308
|
|
|
261
|
-
/**
|
|
309
|
+
/**
|
|
310
|
+
* @type {(
|
|
311
|
+
* address: string,
|
|
312
|
+
* ) => Promise<import('./smartWallet.js').SmartWallet>}
|
|
313
|
+
*/
|
|
262
314
|
const maker = async _address => {
|
|
263
315
|
const invitationPurse = await E(invitationIssuer).makeEmptyPurse();
|
|
264
316
|
const walletStorageNode = E(storageNode).makeChildNode(address);
|
|
@@ -292,10 +344,19 @@ export const prepare = async (zcf, privateArgs, baggage) => {
|
|
|
292
344
|
if (walletBridgeManager) {
|
|
293
345
|
// NB: may not be in service when creatorFacet is used, or ever
|
|
294
346
|
// It can't be awaited because that fails vat restart
|
|
295
|
-
|
|
347
|
+
if (upgrading) {
|
|
348
|
+
void E(walletBridgeManager).setHandler(handleWalletAction);
|
|
349
|
+
} else {
|
|
350
|
+
void E(walletBridgeManager).initHandler(handleWalletAction);
|
|
351
|
+
}
|
|
296
352
|
}
|
|
297
353
|
|
|
298
354
|
return {
|
|
299
355
|
creatorFacet,
|
|
300
356
|
};
|
|
301
357
|
};
|
|
358
|
+
harden(prepare);
|
|
359
|
+
|
|
360
|
+
// So we can consistently import `start` from contracts.
|
|
361
|
+
// Can't be a value export because Zoe enforces that contracts export one or the other.
|
|
362
|
+
/** @typedef {typeof prepare} start */
|