@agoric/deploy-script-support 0.11.0 → 0.11.1-upgrade-23-dev-bd79330.0.bd79330
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/README.md +4 -4
- package/package.json +22 -14
- package/src/assertOfferResult.js +1 -0
- package/src/cachedBundleSpec.js +16 -8
- package/src/control/attenuated-deposit.core.js +55 -0
- package/src/control/chain-info.core.js +187 -0
- package/src/control/contract-control.build.js +27 -0
- package/src/control/contract-control.contract.js +386 -0
- package/src/control/contract-control.core.js +138 -0
- package/src/control/get-upgrade-kit.build.js +28 -0
- package/src/control/get-upgrade-kit.core.js +83 -0
- package/src/control/postal-service.core.js +59 -0
- package/src/coreProposalBehavior.js +7 -12
- package/src/depositInvitation.js +2 -1
- package/src/endo-pieces-contract.js +5 -0
- package/src/externalTypes.js +18 -6
- package/src/extract-proposal.js +10 -5
- package/src/getBundlerMaker.js +6 -2
- package/src/helpers.js +21 -7
- package/src/install.js +7 -2
- package/src/installInPieces.js +1 -1
- package/src/offer.js +18 -11
- package/src/parseCoreEvalArgs.js +5 -1
- package/src/saveIssuer.js +3 -1
- package/src/startInstance.js +5 -8
- package/src/wallet-utils.js +150 -0
- package/src/writeCoreEvalParts.js +34 -10
|
@@ -3,17 +3,12 @@ const t = 'makeCoreProposalBehavior';
|
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* @import {Installation} from '@agoric/zoe/src/zoeService/utils.js';
|
|
6
|
+
* @import {E} from '@endo/far';
|
|
7
|
+
* @import {ManifestBundleRef} from './externalTypes.js';
|
|
8
|
+
* @import {BootstrapPowers, ChainBootstrapSpace} from '@agoric/vats/src/core/types.js';
|
|
6
9
|
*/
|
|
7
10
|
|
|
8
11
|
/**
|
|
9
|
-
* TODO import these from @agoric/vats when the types are better managed
|
|
10
|
-
*
|
|
11
|
-
* @typedef {*} ChainBootstrapSpace
|
|
12
|
-
* @typedef {*} BootstrapPowers
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* @import {ManifestBundleRef} from './externalTypes.js'
|
|
17
12
|
* @typedef {[methodName: string, ...args: unknown[]]} FlatMethargs
|
|
18
13
|
* @typedef {Record<string, Record<string, unknown>>} Manifest
|
|
19
14
|
*/
|
|
@@ -44,9 +39,9 @@ export const permits = {
|
|
|
44
39
|
* @param {ManifestBundleRef} inputs.manifestBundleRef
|
|
45
40
|
* @param {FlatMethargs} inputs.getManifestCall
|
|
46
41
|
* @param {Manifest} [inputs.customManifest]
|
|
47
|
-
* @param {typeof
|
|
42
|
+
* @param {typeof E} inputs.E
|
|
48
43
|
* @param {(...args: unknown[]) => void} [inputs.log]
|
|
49
|
-
* @param {(ref:
|
|
44
|
+
* @param {(ref: ManifestBundleRef) => Promise<Installation<unknown>>} [inputs.customRestoreRef]
|
|
50
45
|
* @returns {(vatPowers: unknown) => Promise<unknown>}
|
|
51
46
|
*/
|
|
52
47
|
export const makeCoreProposalBehavior = ({
|
|
@@ -83,7 +78,7 @@ export const makeCoreProposalBehavior = ({
|
|
|
83
78
|
};
|
|
84
79
|
|
|
85
80
|
const makeRestoreRef = (vatAdminSvc, zoe) => {
|
|
86
|
-
/** @type {(ref:
|
|
81
|
+
/** @type {(ref: ManifestBundleRef) => Promise<Installation<unknown>>} */
|
|
87
82
|
const defaultRestoreRef = async bundleRef => {
|
|
88
83
|
// extract-proposal.js creates these records, and bundleName is
|
|
89
84
|
// the optional name under which the bundle was installed into
|
|
@@ -193,7 +188,7 @@ export const makeCoreProposalBehavior = ({
|
|
|
193
188
|
/**
|
|
194
189
|
* @param {object} inputs
|
|
195
190
|
* @param {Array<{ ref: ManifestBundleRef, call: FlatMethargs, customManifest?: Manifest }>} inputs.metadataRecords
|
|
196
|
-
* @param {typeof
|
|
191
|
+
* @param {typeof E} inputs.E
|
|
197
192
|
*/
|
|
198
193
|
export const makeEnactCoreProposalsFromBundleRef = ({ metadataRecords, E }) => {
|
|
199
194
|
/**
|
package/src/depositInvitation.js
CHANGED
|
@@ -3,7 +3,8 @@ import { E } from '@endo/far';
|
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* @import {Amount, Brand, Issuer, Payment, Purse} from '@agoric/ertp';
|
|
6
|
-
* @import {InvitationDetails} from '@agoric/zoe';
|
|
6
|
+
* @import {Invitation, InvitationDetails} from '@agoric/zoe';
|
|
7
|
+
* @import {ERef} from '@agoric/vow';
|
|
7
8
|
*/
|
|
8
9
|
|
|
9
10
|
/**
|
|
@@ -4,6 +4,11 @@ import { E, Far } from '@endo/far';
|
|
|
4
4
|
import { encodeBase64, decodeBase64 } from '@endo/base64';
|
|
5
5
|
import { ZipWriter } from '@endo/zip';
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* @import {ZoeService} from '@agoric/zoe';
|
|
9
|
+
* @import {ERef} from '@agoric/vow';
|
|
10
|
+
*/
|
|
11
|
+
|
|
7
12
|
export const start = () => {
|
|
8
13
|
/** @type { Map<string, [string, Uint8Array]>} */
|
|
9
14
|
const hashToEntry = new Map();
|
package/src/externalTypes.js
CHANGED
|
@@ -3,6 +3,15 @@ export {};
|
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* @import {NameHub} from '@agoric/vats';
|
|
6
|
+
* @import {ZoeService} from '@agoric/zoe';
|
|
7
|
+
* @import {BundleSource} from '@endo/bundle-source';
|
|
8
|
+
* @import {writeFile as WriteFile} from 'node:fs/promises';
|
|
9
|
+
* @import {ERef} from '@agoric/vow';
|
|
10
|
+
* @import {ScratchPad} from '@agoric/internal/src/scratch.js';
|
|
11
|
+
* @import {CoreEvalMaterialRecord} from './writeCoreEvalParts.js';
|
|
12
|
+
* @import {Bank} from '@agoric/vats/src/vat-bank.js';
|
|
13
|
+
* @import {Board} from '@agoric/vats';
|
|
14
|
+
* @import {NameAdmin} from '@agoric/vats';
|
|
6
15
|
*/
|
|
7
16
|
|
|
8
17
|
// TODO move this type somewhere better
|
|
@@ -54,30 +63,33 @@ export {};
|
|
|
54
63
|
|
|
55
64
|
/**
|
|
56
65
|
* @typedef {{
|
|
57
|
-
* bundleSource:
|
|
66
|
+
* bundleSource: BundleSource,
|
|
58
67
|
* cacheDir: string,
|
|
59
68
|
* lookup: (...path: string[]) => unknown,
|
|
69
|
+
* log?: typeof console.log,
|
|
60
70
|
* now: () => number,
|
|
71
|
+
* onWriteCoreEval?: (record: CoreEvalMaterialRecord) => void | Promise<void>,
|
|
61
72
|
* pathResolve: (...path: string[]) => string,
|
|
62
73
|
* publishBundle: PublishBundleRef,
|
|
63
74
|
* scriptArgs?: string[],
|
|
75
|
+
* writeFile?: WriteFile,
|
|
64
76
|
* }} DeployScriptEndownments
|
|
65
77
|
*/
|
|
66
78
|
|
|
67
79
|
/**
|
|
68
80
|
* @typedef {{
|
|
69
|
-
* scratch: ERef<
|
|
81
|
+
* scratch: ERef<ScratchPad>,
|
|
70
82
|
* }} CommonHome
|
|
71
83
|
*/
|
|
72
84
|
|
|
73
|
-
// TODO wallet as import('@agoric/wallet-backend/src/types').WalletAdmin once it's a module
|
|
85
|
+
// TODO wallet as import('@agoric/wallet-backend/src/types.js').WalletAdmin once it's a module
|
|
74
86
|
/**
|
|
75
87
|
* @typedef {CommonHome & {
|
|
76
88
|
* agoricNames: ERef<NameHub>,
|
|
77
|
-
* bank: ERef<
|
|
78
|
-
* board: ERef<
|
|
89
|
+
* bank: ERef<Bank>,
|
|
90
|
+
* board: ERef<Board>,
|
|
79
91
|
* faucet: unknown,
|
|
80
|
-
* myAddressNameAdmin: ERef<
|
|
92
|
+
* myAddressNameAdmin: ERef<NameAdmin>,
|
|
81
93
|
* namesByAddress: ERef<NameHub>,
|
|
82
94
|
* wallet: any,
|
|
83
95
|
* zoe: ERef<ZoeService>,
|
package/src/extract-proposal.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
import { Fail } from '@endo/errors';
|
|
3
3
|
import { deeplyFulfilledObject } from '@agoric/internal';
|
|
4
|
-
import fs from 'fs';
|
|
5
|
-
import { createRequire } from 'module';
|
|
6
|
-
import path from 'path';
|
|
4
|
+
import fs from 'node:fs';
|
|
5
|
+
import { createRequire } from 'node:module';
|
|
6
|
+
import path from 'node:path';
|
|
7
7
|
|
|
8
8
|
import { defangAndTrim, stringify } from './code-gen.js';
|
|
9
9
|
import {
|
|
@@ -11,6 +11,11 @@ import {
|
|
|
11
11
|
makeEnactCoreProposalsFromBundleRef,
|
|
12
12
|
} from './coreProposalBehavior.js';
|
|
13
13
|
|
|
14
|
+
/**
|
|
15
|
+
* @import {CoreEvalBuilder} from './externalTypes.js';
|
|
16
|
+
* @import {PublishBundleRef} from './externalTypes.js';
|
|
17
|
+
*/
|
|
18
|
+
|
|
14
19
|
/**
|
|
15
20
|
* @typedef {string | {module: string, entrypoint?: string, args?: Array<unknown>}} ConfigProposal
|
|
16
21
|
*/
|
|
@@ -155,7 +160,7 @@ export const extractCoreProposalBundles = async (
|
|
|
155
160
|
const thisProposalSequence = getSequenceForProposal(key);
|
|
156
161
|
const initPath = findModule(dirname, module);
|
|
157
162
|
const initDir = path.dirname(initPath);
|
|
158
|
-
/** @type {Record<string,
|
|
163
|
+
/** @type {Record<string, CoreEvalBuilder>} */
|
|
159
164
|
const ns = await import(initPath);
|
|
160
165
|
const install = (srcSpec, bundlePath) => {
|
|
161
166
|
const absoluteSrc = findModule(initDir, srcSpec);
|
|
@@ -181,7 +186,7 @@ export const extractCoreProposalBundles = async (
|
|
|
181
186
|
);
|
|
182
187
|
return bundleHandle;
|
|
183
188
|
};
|
|
184
|
-
/** @type {
|
|
189
|
+
/** @type {PublishBundleRef} */
|
|
185
190
|
const publishRef = async handleP => {
|
|
186
191
|
const handle = await handleP;
|
|
187
192
|
bundleHandleToAbsolutePaths.has(handle) ||
|
package/src/getBundlerMaker.js
CHANGED
|
@@ -11,9 +11,13 @@
|
|
|
11
11
|
* linked with https://github.com/agoric/agoric-sdk/issues/4564
|
|
12
12
|
*/
|
|
13
13
|
import { E } from '@endo/far';
|
|
14
|
-
import url from 'url';
|
|
14
|
+
import url from 'node:url';
|
|
15
15
|
|
|
16
|
-
/**
|
|
16
|
+
/**
|
|
17
|
+
* @import {start} from './endo-pieces-contract.js';
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/** @typedef {ReturnType<typeof start>['publicFacet']} BundleMaker */
|
|
17
21
|
/** @typedef {ReturnType<BundleMaker['makeBundler']>} Bundler */
|
|
18
22
|
|
|
19
23
|
export const makeGetBundlerMaker =
|
package/src/helpers.js
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
|
|
3
|
-
/// <reference path="../../zoe/exported.js" />
|
|
4
|
-
|
|
5
3
|
import { E } from '@endo/far';
|
|
6
4
|
import bundleSource from '@endo/bundle-source';
|
|
7
5
|
|
|
8
|
-
import fs from 'fs/promises';
|
|
9
|
-
import os from 'os';
|
|
6
|
+
import fs from 'node:fs/promises';
|
|
7
|
+
import os from 'node:os';
|
|
10
8
|
|
|
11
9
|
import { makeInstall } from './install.js';
|
|
12
10
|
import { makeOfferAndFindInvitationAmount } from './offer.js';
|
|
@@ -19,6 +17,13 @@ import { assertOfferResult } from './assertOfferResult.js';
|
|
|
19
17
|
import { installInPieces } from './installInPieces.js';
|
|
20
18
|
import { makeWriteCoreEval } from './writeCoreEvalParts.js';
|
|
21
19
|
|
|
20
|
+
/**
|
|
21
|
+
* @import {CommonHome} from './externalTypes.js';
|
|
22
|
+
* @import {AgSoloHome} from './externalTypes.js';
|
|
23
|
+
* @import {DeployScriptEndownments} from './externalTypes.js';
|
|
24
|
+
* @import {WriteCoreEval} from './writeCoreEvalParts.js';
|
|
25
|
+
*/
|
|
26
|
+
|
|
22
27
|
export * from '@agoric/internal/src/node/createBundles.js';
|
|
23
28
|
export { parseScriptArgs } from './parseCoreEvalArgs.js';
|
|
24
29
|
|
|
@@ -54,8 +59,8 @@ const makeLazyObject = sourceObject => {
|
|
|
54
59
|
};
|
|
55
60
|
|
|
56
61
|
/**
|
|
57
|
-
* @param {Promise<
|
|
58
|
-
* @param {
|
|
62
|
+
* @param {Promise<CommonHome | AgSoloHome>} homePromise
|
|
63
|
+
* @param {DeployScriptEndownments} endowments
|
|
59
64
|
*/
|
|
60
65
|
export const makeHelpers = async (homePromise, endowments) => {
|
|
61
66
|
// Endowments provided via `agoric run` or `agoric deploy`.
|
|
@@ -65,6 +70,9 @@ export const makeHelpers = async (homePromise, endowments) => {
|
|
|
65
70
|
publishBundle,
|
|
66
71
|
pathResolve,
|
|
67
72
|
cacheDir = pathResolve(os.homedir(), '.agoric/cache'),
|
|
73
|
+
onWriteCoreEval,
|
|
74
|
+
writeFile,
|
|
75
|
+
log,
|
|
68
76
|
} = endowments;
|
|
69
77
|
|
|
70
78
|
// Internal-to-this-function lazy dependencies.
|
|
@@ -146,11 +154,14 @@ export const makeHelpers = async (homePromise, endowments) => {
|
|
|
146
154
|
get getBundlerMaker() {
|
|
147
155
|
return makeGetBundlerMaker(homePromise, { bundleSource, lookup });
|
|
148
156
|
},
|
|
149
|
-
/** @returns {
|
|
157
|
+
/** @returns {WriteCoreEval} */
|
|
150
158
|
get writeCoreEval() {
|
|
151
159
|
return makeWriteCoreEval(homePromise, endowments, {
|
|
152
160
|
getBundleSpec: deps.cacheAndGetBundleSpec,
|
|
153
161
|
getBundlerMaker: helpers.getBundlerMaker,
|
|
162
|
+
...(onWriteCoreEval && { onWriteCoreEval }),
|
|
163
|
+
...(log && { log }),
|
|
164
|
+
...(writeFile && { writeFile }),
|
|
154
165
|
});
|
|
155
166
|
},
|
|
156
167
|
/** @deprecated use writeCoreEval */
|
|
@@ -158,6 +169,9 @@ export const makeHelpers = async (homePromise, endowments) => {
|
|
|
158
169
|
return makeWriteCoreEval(homePromise, endowments, {
|
|
159
170
|
getBundleSpec: deps.cacheAndGetBundleSpec,
|
|
160
171
|
getBundlerMaker: helpers.getBundlerMaker,
|
|
172
|
+
...(onWriteCoreEval && { onWriteCoreEval }),
|
|
173
|
+
...(log && { log }),
|
|
174
|
+
...(writeFile && { writeFile }),
|
|
161
175
|
});
|
|
162
176
|
},
|
|
163
177
|
});
|
package/src/install.js
CHANGED
|
@@ -3,13 +3,18 @@ import './externalTypes.js';
|
|
|
3
3
|
|
|
4
4
|
import { E } from '@endo/far';
|
|
5
5
|
|
|
6
|
-
/**
|
|
6
|
+
/**
|
|
7
|
+
* @import {Petname} from '@agoric/deploy-script-support/src/externalTypes.js'
|
|
8
|
+
* @import {Installation, ZoeService} from '@agoric/zoe';
|
|
9
|
+
* @import {InstallationManager} from './startInstance.js';
|
|
10
|
+
* @import {ERef} from '@agoric/vow';
|
|
11
|
+
*/
|
|
7
12
|
|
|
8
13
|
// XXX board is Board but specifying that leads to type errors with imports which aren't worth fixing right now
|
|
9
14
|
/**
|
|
10
15
|
* @param {typeof import('@endo/bundle-source')['default']} bundleSource
|
|
11
16
|
* @param {ERef<ZoeService>} zoe
|
|
12
|
-
* @param {ERef<
|
|
17
|
+
* @param {ERef<InstallationManager>} installationManager
|
|
13
18
|
* @param {ERef<any>} board
|
|
14
19
|
* @param {(bundle: any) => any} [publishBundle]
|
|
15
20
|
* @param {(path: string) => string} [pathResolve]
|
package/src/installInPieces.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { E } from '@endo/far';
|
|
3
3
|
import { ZipReader } from '@endo/zip';
|
|
4
4
|
import { encodeBase64, decodeBase64 } from '@endo/base64';
|
|
5
|
-
import crypto from 'crypto';
|
|
5
|
+
import crypto from 'node:crypto';
|
|
6
6
|
|
|
7
7
|
const computeSha512 = bytes => {
|
|
8
8
|
const hash = crypto.createHash('sha512');
|
package/src/offer.js
CHANGED
|
@@ -3,11 +3,13 @@ import { assert } from '@endo/errors';
|
|
|
3
3
|
import { E } from '@endo/far';
|
|
4
4
|
// Avoid pulling in too many dependencies like notifiers
|
|
5
5
|
import { AmountMath } from '@agoric/ertp/src/amountMath.js';
|
|
6
|
+
import { objectMap } from '@agoric/internal';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* @import {Petname} from '@agoric/deploy-script-support/src/externalTypes.js';
|
|
9
10
|
* @import {Amount, Brand, Issuer, Payment, Purse} from '@agoric/ertp';
|
|
10
|
-
* @import {InvitationDetails, Keyword, Proposal} from '@agoric/zoe';
|
|
11
|
+
* @import {Invitation, InvitationAmount, InvitationDetails, Keyword, Proposal, ProposalRecord, ZoeService} from '@agoric/zoe';
|
|
12
|
+
* @import {ERef} from '@agoric/vow';
|
|
11
13
|
*/
|
|
12
14
|
|
|
13
15
|
/**
|
|
@@ -53,17 +55,22 @@ export const makeOfferAndFindInvitationAmount = (
|
|
|
53
55
|
return AmountMath.make(invitationAmount.brand, value);
|
|
54
56
|
};
|
|
55
57
|
|
|
58
|
+
/**
|
|
59
|
+
* @param {Partial<ProposalRecord>} proposal
|
|
60
|
+
* @param {Record<Keyword, Petname>} paymentsWithPursePetnames
|
|
61
|
+
* @returns {Record<Keyword, ERef<Payment>>} payments
|
|
62
|
+
*/
|
|
56
63
|
const withdrawPayments = (proposal, paymentsWithPursePetnames) => {
|
|
57
|
-
return
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
);
|
|
64
|
+
return objectMap(paymentsWithPursePetnames, (pursePetname, keyword) => {
|
|
65
|
+
const purse = E(walletAdmin).getPurse(pursePetname);
|
|
66
|
+
assert(
|
|
67
|
+
'give' in proposal && proposal.give,
|
|
68
|
+
`proposal.give is required to withdraw`,
|
|
69
|
+
);
|
|
70
|
+
const amountToWithdraw = proposal.give[keyword];
|
|
71
|
+
const paymentP = E(purse).withdraw(amountToWithdraw);
|
|
72
|
+
return paymentP;
|
|
73
|
+
});
|
|
67
74
|
};
|
|
68
75
|
|
|
69
76
|
const withdrawInvitation = async invitationDetails => {
|
package/src/parseCoreEvalArgs.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* To customize proposals for multiple environments, we pass the "variant"
|
|
3
3
|
* identifier in scriptArgs. The variant must match a knownVariant.
|
|
4
4
|
*
|
|
5
|
-
* @param {
|
|
5
|
+
* @param {DeployScriptEndownments} endowments
|
|
6
6
|
* @param {string} name a name to use in error messages or Usage suggestions.
|
|
7
7
|
* @param {string[]} knownVariants
|
|
8
8
|
*/
|
|
@@ -12,6 +12,10 @@ export const parseScriptArgs = async (endowments, name, knownVariants) => {
|
|
|
12
12
|
const variantOrConfig =
|
|
13
13
|
scriptArgs && scriptArgs.length > 0 ? scriptArgs : undefined;
|
|
14
14
|
|
|
15
|
+
/**
|
|
16
|
+
* @import {DeployScriptEndownments} from './externalTypes.js';
|
|
17
|
+
*/
|
|
18
|
+
|
|
15
19
|
console.log(`${name}`, variantOrConfig);
|
|
16
20
|
|
|
17
21
|
const Usage = `agoric run ${name}.js ${[...knownVariants, '<json-config>'].join(' | ')}`;
|
package/src/saveIssuer.js
CHANGED
|
@@ -4,12 +4,14 @@ import { E } from '@endo/far';
|
|
|
4
4
|
/**
|
|
5
5
|
* @import {Petname} from '@agoric/deploy-script-support/src/externalTypes.js';
|
|
6
6
|
* @import {Amount, Brand, Issuer, Payment} from '@agoric/ertp';
|
|
7
|
+
* @import {IssuerManager} from './startInstance.js';
|
|
8
|
+
* @import {ERef} from '@agoric/vow';
|
|
7
9
|
*/
|
|
8
10
|
|
|
9
11
|
/**
|
|
10
12
|
* @param {ERef<any>} walletAdmin - an internal type of the
|
|
11
13
|
* wallet, not defined here
|
|
12
|
-
* @param {ERef<
|
|
14
|
+
* @param {ERef<IssuerManager>} issuerManager
|
|
13
15
|
*/
|
|
14
16
|
export const makeSaveIssuer = (walletAdmin, issuerManager) => {
|
|
15
17
|
/**
|
package/src/startInstance.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
// @ts-check
|
|
2
|
+
import { objectMap } from '@agoric/internal';
|
|
2
3
|
import { assert } from '@endo/errors';
|
|
3
4
|
import { E, passStyleOf } from '@endo/far';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* @import {Petname} from '@agoric/deploy-script-support/src/externalTypes.js';
|
|
7
8
|
* @import {Amount, Brand, Issuer, Payment, Purse} from '@agoric/ertp';
|
|
8
|
-
* @import {IssuerKeywordRecord, Keyword} from '@agoric/zoe';
|
|
9
|
+
* @import {Instance, Installation, IssuerKeywordRecord, Keyword, ZoeService} from '@agoric/zoe';
|
|
10
|
+
* @import {ERef} from '@agoric/vow';
|
|
9
11
|
*/
|
|
10
12
|
|
|
11
13
|
/**
|
|
@@ -36,13 +38,8 @@ export const makeStartInstance = (
|
|
|
36
38
|
zoeInvitationPurse,
|
|
37
39
|
) => {
|
|
38
40
|
const makeIssuerKeywordRecord = issuerPetnameKeywordRecord => {
|
|
39
|
-
return
|
|
40
|
-
|
|
41
|
-
([keyword, issuerPetname]) => {
|
|
42
|
-
const issuerP = E(issuerManager).get(issuerPetname);
|
|
43
|
-
return [keyword, issuerP];
|
|
44
|
-
},
|
|
45
|
-
),
|
|
41
|
+
return objectMap(issuerPetnameKeywordRecord, issuerPetname =>
|
|
42
|
+
E(issuerManager).get(issuerPetname),
|
|
46
43
|
);
|
|
47
44
|
};
|
|
48
45
|
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/* global globalThis */
|
|
2
|
+
/**
|
|
3
|
+
* @file Reusable wallet utilities for portfolio contract testing and operations
|
|
4
|
+
*
|
|
5
|
+
* This module consolidates wallet-related utilities that were previously
|
|
6
|
+
* duplicated across multichain-testing and a3p-integration.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { retryUntilCondition } from '@agoric/client-utils';
|
|
10
|
+
import { YMAX_CONTROL_WALLET_KEY } from '@agoric/portfolio-api/src/portfolio-constants.js';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @import {UpdateRecord} from '@agoric/smart-wallet/src/smartWallet.js';
|
|
14
|
+
* @import {RetryOptions} from '@agoric/client-utils';
|
|
15
|
+
* @import {SigningSmartWalletKit} from '@agoric/client-utils';
|
|
16
|
+
* @import {Instance} from '@agoric/zoe';
|
|
17
|
+
* @import {BridgeAction} from '@agoric/smart-wallet/src/smartWallet.js';
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Helper to wait for specific wallet updates
|
|
22
|
+
*
|
|
23
|
+
* This provides a higher-level API over retryUntilCondition for common
|
|
24
|
+
* wallet update patterns.
|
|
25
|
+
*
|
|
26
|
+
* @param {() => Promise<UpdateRecord>} getLastUpdate
|
|
27
|
+
* @param {RetryOptions & {
|
|
28
|
+
* log: (...args: unknown[]) => void;
|
|
29
|
+
* setTimeout: typeof globalThis.setTimeout;
|
|
30
|
+
* }} retryOpts
|
|
31
|
+
*/
|
|
32
|
+
export const walletUpdates = (getLastUpdate, retryOpts) => {
|
|
33
|
+
return harden({
|
|
34
|
+
/**
|
|
35
|
+
* Wait for an invocation to complete
|
|
36
|
+
* @param {string | number} id
|
|
37
|
+
*/
|
|
38
|
+
invocation: async id => {
|
|
39
|
+
const done = /** @type {UpdateRecord & { updated: 'invocation' }} */ (
|
|
40
|
+
await retryUntilCondition(
|
|
41
|
+
getLastUpdate,
|
|
42
|
+
update =>
|
|
43
|
+
update.updated === 'invocation' &&
|
|
44
|
+
update.id === id &&
|
|
45
|
+
!!(update.result || update.error),
|
|
46
|
+
`${id}`,
|
|
47
|
+
retryOpts,
|
|
48
|
+
)
|
|
49
|
+
);
|
|
50
|
+
if (done.error) throw Error(done.error);
|
|
51
|
+
return done.result;
|
|
52
|
+
},
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Wait for an offer to complete
|
|
56
|
+
* @param {string | number} id
|
|
57
|
+
*/
|
|
58
|
+
offerResult: async id => {
|
|
59
|
+
const done = await retryUntilCondition(
|
|
60
|
+
getLastUpdate,
|
|
61
|
+
update =>
|
|
62
|
+
// walletAction implies an error, so also stop on that
|
|
63
|
+
update.updated === 'walletAction' ||
|
|
64
|
+
// if it's offerStatus, it can be in progress until result or error
|
|
65
|
+
(update.updated === 'offerStatus' &&
|
|
66
|
+
update.status.id === id &&
|
|
67
|
+
(!!update.status.result || !!update.status.error)),
|
|
68
|
+
`${id}`,
|
|
69
|
+
retryOpts,
|
|
70
|
+
);
|
|
71
|
+
switch (done.updated) {
|
|
72
|
+
case 'walletAction':
|
|
73
|
+
throw Error(`walletAction failure: ${done.status.error}`);
|
|
74
|
+
case 'offerStatus':
|
|
75
|
+
if (done.status.error) {
|
|
76
|
+
throw Error(`offerStatus failure: ${done.status.error}`);
|
|
77
|
+
}
|
|
78
|
+
if (!done.status.result) {
|
|
79
|
+
throw Error(`offerStatus missing result`);
|
|
80
|
+
}
|
|
81
|
+
return done.status.result;
|
|
82
|
+
default:
|
|
83
|
+
throw Error(`unexpected update type ${done.updated}`);
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
});
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Redeem the ymaxControl invitation from the postal service
|
|
91
|
+
*
|
|
92
|
+
* This is a common pattern in ymax testing where we need to redeem
|
|
93
|
+
* the control facet invitation delivered via postal service.
|
|
94
|
+
*
|
|
95
|
+
* @param {{
|
|
96
|
+
* sig: SigningSmartWalletKit;
|
|
97
|
+
* postalServiceInstance: Instance;
|
|
98
|
+
* fresh: () => string | number;
|
|
99
|
+
* log?: (...args: unknown[]) => void;
|
|
100
|
+
* }} options
|
|
101
|
+
* @returns {Promise<void>}
|
|
102
|
+
*/
|
|
103
|
+
export const redeemYmaxControlInvitation = async ({
|
|
104
|
+
sig,
|
|
105
|
+
postalServiceInstance,
|
|
106
|
+
fresh,
|
|
107
|
+
log = () => {},
|
|
108
|
+
}) => {
|
|
109
|
+
const id = `redeem-${YMAX_CONTROL_WALLET_KEY}-${fresh()}`;
|
|
110
|
+
log('Redeeming ymaxControl invitation', id);
|
|
111
|
+
|
|
112
|
+
/** @type {BridgeAction} */
|
|
113
|
+
const redeemAction = harden({
|
|
114
|
+
method: 'executeOffer',
|
|
115
|
+
offer: {
|
|
116
|
+
id,
|
|
117
|
+
invitationSpec: {
|
|
118
|
+
source: 'purse',
|
|
119
|
+
instance: postalServiceInstance,
|
|
120
|
+
description: `deliver ${YMAX_CONTROL_WALLET_KEY}`,
|
|
121
|
+
},
|
|
122
|
+
proposal: {},
|
|
123
|
+
saveResult: { name: YMAX_CONTROL_WALLET_KEY, overwrite: true },
|
|
124
|
+
},
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
const tx = await sig.sendBridgeAction(redeemAction);
|
|
128
|
+
if (tx.code !== 0) {
|
|
129
|
+
throw Error(`Failed to redeem invitation: ${tx.rawLog}`);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const wup = walletUpdates(sig.query.getLastUpdate, {
|
|
133
|
+
setTimeout: globalThis.setTimeout,
|
|
134
|
+
log,
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
await wup.offerResult(id);
|
|
138
|
+
log('ymaxControl invitation redeemed successfully');
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Helper to create action IDs with a consistent format
|
|
143
|
+
*
|
|
144
|
+
* @param {string} description
|
|
145
|
+
* @param {() => string | number} [fresh]
|
|
146
|
+
* @returns {string}
|
|
147
|
+
*/
|
|
148
|
+
export const makeActionId = (description, fresh = () => Date.now()) => {
|
|
149
|
+
return `${description}.${fresh()}`;
|
|
150
|
+
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @ts-check
|
|
2
|
-
import fs from 'fs';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
3
|
import { E } from '@endo/far';
|
|
4
4
|
import { deeplyFulfilled } from '@endo/marshal';
|
|
5
5
|
|
|
@@ -12,7 +12,9 @@ import {
|
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* @import {BundleSource, BundleSourceResult} from '@endo/bundle-source';
|
|
15
|
-
* @import {AgSoloHome,
|
|
15
|
+
* @import {AgSoloHome, CommonHome, CoreEvalBuilder, CoreEvalDescriptor, ManifestBundleRef} from './externalTypes.js';
|
|
16
|
+
* @import {BundleMaker} from './getBundlerMaker.js';
|
|
17
|
+
* @import {Bundler} from './getBundlerMaker.js';
|
|
16
18
|
*/
|
|
17
19
|
|
|
18
20
|
/**
|
|
@@ -20,7 +22,14 @@ import {
|
|
|
20
22
|
* @property {string} name
|
|
21
23
|
* @property {string} permit
|
|
22
24
|
* @property {string} script
|
|
23
|
-
* @property {{entrypoint: string, bundleID
|
|
25
|
+
* @property {{entrypoint: string, bundleID?: string, bundleName?: string, fileName?: string}[]} bundles
|
|
26
|
+
*/
|
|
27
|
+
/**
|
|
28
|
+
* @typedef {{
|
|
29
|
+
* plan: CoreEvalPlan,
|
|
30
|
+
* eval: { json_permits: string, js_code: string },
|
|
31
|
+
* bundles: { entrypoint: string, bundleID?: string, bundleName?: string, fileName?: string, bundle: BundleSourceResult<'endoZipBase64'> }[],
|
|
32
|
+
* }} CoreEvalMaterialRecord
|
|
24
33
|
*/
|
|
25
34
|
|
|
26
35
|
/**
|
|
@@ -40,9 +49,10 @@ import {
|
|
|
40
49
|
* pathResolve: (path: string) => string,
|
|
41
50
|
* }} endowments
|
|
42
51
|
* @param {{
|
|
43
|
-
* getBundlerMaker: () => Promise<
|
|
44
|
-
* getBundleSpec: (bundle: Promise<BundleSourceResult<'endoZipBase64'>>, getBundle: () =>
|
|
52
|
+
* getBundlerMaker: () => Promise<BundleMaker>,
|
|
53
|
+
* getBundleSpec: (bundle: Promise<BundleSourceResult<'endoZipBase64'>>, getBundle: () => Bundler, opts?: any) => Promise<ManifestBundleRef>,
|
|
45
54
|
* log?: typeof console.log,
|
|
55
|
+
* onWriteCoreEval?: (record: CoreEvalMaterialRecord) => void | Promise<void>,
|
|
46
56
|
* writeFile?: typeof fs.promises.writeFile
|
|
47
57
|
* }} io
|
|
48
58
|
* @returns {WriteCoreEval}
|
|
@@ -54,13 +64,14 @@ export const makeWriteCoreEval = (
|
|
|
54
64
|
getBundlerMaker,
|
|
55
65
|
getBundleSpec,
|
|
56
66
|
log = console.log,
|
|
67
|
+
onWriteCoreEval = () => {},
|
|
57
68
|
writeFile = fs.promises.writeFile,
|
|
58
69
|
},
|
|
59
70
|
) => {
|
|
60
71
|
const { bundleSource, pathResolve } = endowments;
|
|
61
72
|
|
|
62
73
|
let bundlerCache;
|
|
63
|
-
/** @returns {
|
|
74
|
+
/** @returns {Bundler} */
|
|
64
75
|
const getBundler = () => {
|
|
65
76
|
if (!bundlerCache) {
|
|
66
77
|
bundlerCache = E(getBundlerMaker()).makeBundler({
|
|
@@ -118,7 +129,8 @@ export const makeWriteCoreEval = (
|
|
|
118
129
|
return ns.default;
|
|
119
130
|
};
|
|
120
131
|
|
|
121
|
-
|
|
132
|
+
/** @type {CoreEvalMaterialRecord['bundles']} */
|
|
133
|
+
const bundleRecords = [];
|
|
122
134
|
|
|
123
135
|
/**
|
|
124
136
|
* Install an entrypoint.
|
|
@@ -134,9 +146,13 @@ export const makeWriteCoreEval = (
|
|
|
134
146
|
// Serialise the installations.
|
|
135
147
|
mutex = E.when(mutex, async () => {
|
|
136
148
|
// console.log('installing', { filePrefix, entrypoint, bundlePath });
|
|
137
|
-
const spec = await
|
|
138
|
-
|
|
149
|
+
const [spec, builtBundle] = await Promise.all([
|
|
150
|
+
getBundleSpec(bundle, getBundler, opts),
|
|
151
|
+
bundle,
|
|
152
|
+
]);
|
|
153
|
+
bundleRecords.push({
|
|
139
154
|
entrypoint,
|
|
155
|
+
bundle: builtBundle,
|
|
140
156
|
...spec,
|
|
141
157
|
});
|
|
142
158
|
return spec;
|
|
@@ -203,13 +219,21 @@ behavior;
|
|
|
203
219
|
name: filePrefix,
|
|
204
220
|
script: codeFile,
|
|
205
221
|
permit: permitFile,
|
|
206
|
-
bundles,
|
|
222
|
+
bundles: bundleRecords.map(({ bundle: _bundle, ...spec }) => spec),
|
|
207
223
|
};
|
|
208
224
|
|
|
209
225
|
await writeFile(
|
|
210
226
|
`${filePrefix}-plan.json`,
|
|
211
227
|
`${JSON.stringify(plan, null, 2)}\n`,
|
|
212
228
|
);
|
|
229
|
+
await onWriteCoreEval({
|
|
230
|
+
plan,
|
|
231
|
+
eval: {
|
|
232
|
+
json_permits: JSON.stringify(evalPermits, null, 2),
|
|
233
|
+
js_code: trimmed,
|
|
234
|
+
},
|
|
235
|
+
bundles: bundleRecords,
|
|
236
|
+
});
|
|
213
237
|
|
|
214
238
|
log(`\
|
|
215
239
|
You can now run a governance submission command like:
|