@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.
@@ -1,4 +1,4 @@
1
1
  export namespace shape {
2
- const WalletBridgeMsg: import("@endo/patterns").Matcher;
2
+ let WalletBridgeMsg: import("@endo/patterns").Matcher;
3
3
  }
4
4
  //# sourceMappingURL=typeGuards.d.ts.map
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, FarRef } from '@endo/far';
8
+ import type { ERef } from '@endo/far';
9
9
  import type { CapData } from '@endo/marshal';
10
- import type { MsgWalletSpendAction } from '@agoric/cosmic-proto/swingset/msgs';
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 RemotePurse<T = unknown> = FarRef<Purse<T>>;
23
-
24
- export type RemoteInvitationMakers = FarRef<
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 {MsgWalletSpendAction} and walletSpendAction in msg_server.go
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 BridgeActionCapData */
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<import("./offers").OfferId, {
5
- acceptedIn: import('./offers').OfferId;
5
+ invitationsReceived: Map<OfferId, {
6
+ acceptedIn: OfferId;
6
7
  description: string;
7
8
  instance: Instance;
8
9
  }>;
9
- offerStatuses: Map<import("./offers").OfferId, import("./offers").OfferStatus>;
10
- balances: Map<Brand<AssetKind>, Amount<AssetKind>>;
10
+ offerStatuses: Map<OfferId, OfferStatus>;
11
+ balances: Map<globalThis.Brand, globalThis.Amount>;
11
12
  };
12
- update: (updateRecord: import('./smartWallet').UpdateRecord | {}) => void;
13
+ update: (updateRecord: import("./smartWallet.js").UpdateRecord | {}) => void;
13
14
  };
14
- export function coalesceUpdates(updates: ERef<Subscriber<import('./smartWallet').UpdateRecord>>, invitationBrand?: Brand<"set"> | undefined): {
15
- invitationsReceived: Map<import("./offers").OfferId, {
16
- acceptedIn: import('./offers').OfferId;
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<import("./offers").OfferId, import("./offers").OfferStatus>;
21
- balances: Map<Brand<AssetKind>, Amount<AssetKind>>;
21
+ offerStatuses: Map<OfferId, OfferStatus>;
22
+ balances: Map<globalThis.Brand, globalThis.Amount>;
22
23
  };
23
- export function assertHasData(follower: import('@agoric/casting').Follower<any>): Promise<void>;
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>['state'];
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
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["utils.js"],"names":[],"mappings":"AAKA,sDAAuD;AAKhD;;;wBASmD,OAAO,UAAU,EAAE,OAAO;yBAAe,MAAM;sBAAY,QAAQ;;;;;2BAI/G,OAAO,eAAe,EAAE,YAAY,GAAG,EAAE;EA8DtD;AAaM,yCAHI,KAAK,WAAW,OAAO,eAAe,EAAE,YAAY,CAAC,CAAC;;oBA5EP,OAAO,UAAU,EAAE,OAAO;qBAAe,MAAM;kBAAY,QAAQ;;;;EAwF5H;AAMM,wCAHI,OAAO,iBAAiB,EAAE,QAAQ,CAAC,GAAG,CAAC,iBAYjD;AAQM,iKAFM,KAAK,OAAO,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,IAAI,CAW/C;mCArDa,WAAW,+BAA+B,CAAC,CAAC,OAAO,CAAC"}
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<import('./offers').OfferId, import('./offers').OfferStatus>} */
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<import('./offers').OfferId, { acceptedIn: import('./offers').OfferId, description: string, instance: Instance }>}
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
- /** @param {import('./smartWallet').UpdateRecord | {}} updateRecord newer than previous */
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 | import('@agoric/zoe/src/contractSupport').TopicsRecord} [subscribers]
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 => {
@@ -1,10 +1,10 @@
1
- export const privateArgsShape: import("@endo/patterns").Matcher;
2
1
  export namespace customTermsShape {
3
- const agoricNames: any;
4
- const board: any;
5
- const assetPublisher: any;
2
+ let agoricNames: globalThis.Pattern;
3
+ let board: globalThis.Pattern;
4
+ let assetPublisher: globalThis.Pattern;
6
5
  }
7
- export function publishDepositFacet(address: string, wallet: import('./smartWallet.js').SmartWallet, namesByAddressAdmin: ERef<import('@agoric/vats').NameAdmin>): Promise<unknown>;
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('./types').Petname;
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('./types').Petname;
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> | undefined;
28
- walletReviver?: ERef<WalletReviver> | undefined;
29
- }, baggage: MapStore<string, unknown>): Promise<{
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<[wallet: import('./smartWallet').SmartWallet, isNew: boolean]>} wallet
69
- * along with a flag to distinguish between looking up an existing wallet
70
- * and creating a new one.
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('@agoric/vats/src/vat-bank').Bank>, namesByAddressAdmin: ERef<import('@agoric/vats/').NameAdmin>): Promise<[wallet: {
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('@agoric/vats').Board>;
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('@agoric/vats/src/vat-bank').AssetDescriptor>>;
50
+ getAssetSubscription: () => ERef<IterableEachTopic<import("@agoric/vats/src/vat-bank.js").AssetDescriptor>>;
106
51
  };
107
- export type isRevive = boolean;
52
+ export type IsRevive = boolean;
108
53
  export type WalletReviver = {
109
- reviveWallet: (address: string) => Promise<import('./smartWallet').SmartWallet>;
110
- ackWallet: (address: string) => isRevive;
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":"AAkBA,gEAKE;;;;;;AAgBK,6CAJI,MAAM,UACN,OAAO,kBAAkB,EAAE,WAAW,uBACtC,KAAK,OAAO,cAAc,EAAE,SAAS,CAAC,oBAehD;AAWM,kDAFI,cAAc;IAwCrB,2BAA2B;iBAAf,KAAK;IAEjB,2BAA2B;iBAAf,KAAK;eApCP,KAAK;qBACC,WAAW;gBAChB,MAAM;iBACL,OAAO,SAAS,EAAE,OAAO;;;eAH3B,KAAK;qBACC,WAAW;gBAChB,MAAM;iBACL,OAAO,SAAS,EAAE,OAAO;;EAsCxC;AAmCM,6BARI,IAAI,wBAAwB,CAAC;iBAEtB,KAAK,WAAW,CAAC;;;;;QAgH7B;;;;;;;WAOG;oCANQ,MAAM,QACN,KAAK,OAAO,2BAA2B,EAAE,IAAI,CAAC,uBAC9C,KAAK,OAAO,eAAe,EAAE,SAAS,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;QAHlD;;;;;;;WAOG;oCANQ,MAAM,QACN,KAAK,OAAO,2BAA2B,EAAE,IAAI,CAAC,uBAC9C,KAAK,OAAO,eAAe,EAAE,SAAS,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;GAgDvD;uCA7LY;IACZ,WAAe,EAAE,KAAK,OAAO,CAAC,CAAC;IAC/B,KAAS,EAAE,KAAK,OAAO,cAAc,EAAE,KAAK,CAAC,CAAC;IAC9C,cAAkB,EAAE,cAAc,CAAC;CAChC;sBAES,OAAO,cAAc,EAAE,OAAO;6BAE9B;IACZ,oBAAwB,EAAE,MAAM,KAChC,kBAAwB,OAAO,2BAA2B,EAAE,eAAe,CAAC,CAAC,CAAA;CAC1E;uBAES,OAAO;;4BAES,MAAM,KAAK,QAAQ,OAAO,eAAe,EAAE,WAAW,CAAC;yBAC1D,MAAM,KAAK,QAAQ"}
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"}
@@ -1,7 +1,10 @@
1
1
  /**
2
2
  * @file Wallet Factory
3
3
  *
4
- * Contract to make smart wallets.
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
- export const customTermsShape = harden({
27
- agoricNames: M.eref(M.remotable('agoricNames')),
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 the
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
- * For use by clients to describe brands to users. Includes `displayInfo` to save a remote call.
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
- * @typedef {boolean} isRevive
134
+ *
135
+ * @typedef {boolean} IsRevive
136
+ *
126
137
  * @typedef {{
127
- * reviveWallet: (address: string) => Promise<import('./smartWallet').SmartWallet>,
128
- * ackWallet: (address: string) => isRevive,
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, they
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<import('@agoric/vats').ScopedBridgeManager>,
140
- * walletReviver?: ERef<WalletReviver>,
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, 'walletsByAddress');
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 not be observable. The
164
- * promise does reject, but as of now bridge manager drops instead of handling it. Eventually
165
- * we'll make the bridge able to give feedback about the requesting transaction. Meanwhile we
166
- * could write the error to chainStorage but we don't have a guarantee of the wallet owner to
167
- * associate it with. (We could have a shared `lastError` node but it would be so noisy as to
168
- * not provide much info to the end user.)
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 that all errors
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 shape.WalletBridgeMsg
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<[wallet: import('./smartWallet').SmartWallet, isNew: boolean]>} wallet
255
- * along with a flag to distinguish between looking up an existing wallet
256
- * and creating a new one.
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
- /** @type {(address: string) => Promise<import('./smartWallet').SmartWallet>} */
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
- void E(walletBridgeManager).initHandler(handleWalletAction);
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 */