@agoric/deploy-script-support 0.10.4-u17.0 → 0.10.4-u18.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/README.md CHANGED
@@ -1,107 +1,100 @@
1
1
  # Deploy Script Support
2
2
 
3
3
  To install code on chain or in the a3p-integration environment, you'll have to
4
- generate a proposal, and write a script to build the core proposal. The
5
- proposals have limited access to bootstrap powers, described by their manifests.
4
+ write a script to build the core proposal. The proposals' access to bootstrap
5
+ powers is limited by their manifests.
6
6
 
7
- There are collections of proposals in .../vats/src/proposals,
8
- smart-wallet/src/proposals, orchestration/src/proposals, pegasus/src/proposals.
7
+ There are collections of proposals in /vats/src/proposals,
8
+ smart-wallet/src/proposals, orchestration/src/proposals, pegasus/src/proposals,
9
+ and inter-protocol/src/proposals.
9
10
 
10
11
  The overall format is a proposalBuilder script (There are several in
11
12
  .../builders/scripts/vats/) which has a default export that passes resources to
12
13
  the proposal. The resources include bundled source code and string-value
13
- parameters. The ProposalBuilder specifies (as an import string) the proposal
14
- it uses, identifies the "manifest", (which associates permissions to access
15
- powers in the bootstrap space with functions to be called), and builds bundles
16
- of source code needed by the proposal.
14
+ parameters. The script exports a CoreEvalBuilder named `defaultProposalBuilder`
15
+ that specifies (as an import string) the proposal it uses, identifies the
16
+ "manifest", (which associates permissions to access powers in the bootstrap
17
+ space with functions to be called), and builds bundles of source code needed by
18
+ the proposal.
17
19
 
18
- `.../builders/scripts/vats/upgradeVaults.js` is a canonical example. It says the
19
- proposal to run is '@agoric/inter-protocol/src/proposals/upgrade-vaults.js',
20
- lists the manifest there as `'getManifestForUpgradeVaults'`, and directs the
21
- creation of a bundle from
22
- '@agoric/inter-protocol/src/vaultFactory/vaultFactory.js', which will be made
23
- available to the proposal as `vaultsRef` in options.
20
+ Here's a simple example:
24
21
 
25
- `upgrade-vaults.js` defines `getManifestForUpgradeVaults()`, which returns a
26
- `manifest` that says `upgradeVaults()` should be executed, and specifies what
27
- powers it should have access to.
28
-
29
- ### Proposal
30
-
31
- The proposal is called with `(powers, options)` available. The manifest
32
- detailing the powers that will be used is usually in the same file, and
33
- conventionally provided by a function named `getManifestForFoo`. The manifest
34
- needs to have a unique name, since it will be referenced by name from the
35
- script. The usual format is
36
- ```js
37
- export const foo = async (
38
- {
39
- consume: {
40
- ...
41
- },
42
- brands: {
43
- ...
44
- }
45
- },
46
- options,
47
- ) => {
48
- const { fooRef } = options;
49
- // do the things using powers and options
50
- };
51
-
52
- export const getManifestForFoo = (powers, options) => {
53
- manifest: {
54
- [foo.name]: {
55
- consume: {
56
- ...
57
- },
58
- options,
59
- )};
60
22
  ```
61
-
62
- `manifest` contains descriptions of powers to be provided to the proposals.
63
-
64
- **TODO** what happens with the `installations` in [`startPsm.js`](https://github.com/Agoric/agoric-sdk/blob/b13743a2cccf0cb63a412b54384435596d4e81ea/packages/inter-protocol/src/proposals/startPSM.js#L496)?
65
-
66
- `options` allows the proposal to be provided with arbitray other powerful
67
- objects.
68
-
69
- ### proposalBuilder Script
70
-
71
- The script describes how to build the core proposal. For
72
- `agoric-3-proposals` and uploading to the chain, the script must be named in the
73
- `CoreProposalSteps` section in [`upgrade.go`](../../golang/cosmos/app/upgrade.go),
74
- and its `defaultProposalBuilder` will be invoked directly.
75
-
76
- Script files should export `defaultProposalBuilder` and a `default` function
77
- that invokes `writeCoreProposal` one or more times to generate sets of files
78
- describing the proposal.
79
-
80
- ```js
81
- export const defaultProposalBuilder = ({ publishRef, install }) => {
23
+ /** @type {import('@agoric/deploy-script-support/src/externalTypes.js').CoreEvalBuilder} */
24
+ const game1ProposalBuilder = async ({ publishRef, install }) => {
82
25
  return harden({
83
- sourceSpec: '@agoric/vats/src/proposals/foo.js',
26
+ sourceSpec: '@agoric/smart-wallet/test/start-game1-proposal.js',
84
27
  getManifestCall: [
85
- 'getManifestForFoo',
28
+ getManifestForGame1.name,
86
29
  {
87
- fooRef: publishRef(install('@agoric/...')),
88
- ...otherParams,
30
+ game1Ref: publishRef(
31
+ install(
32
+ '@agoric/smart-wallet/test/gameAssetContract.js',
33
+ '../bundles/bundle-game1.js',
34
+ { persist: true },
35
+ ),
36
+ ),
89
37
  },
90
38
  ],
91
39
  });
92
40
  };
93
- `
41
+
94
42
  export default async (homeP, endowments) => {
95
- const { writeCoreProposal } = await makeHelpers(homeP, endowments);
96
- await writeCoreProposal('proposalName', defaultProposalBuilder);
43
+ const { writeCoreEval } = await makeHelpers(homeP, endowments);
44
+ await writeCoreEval('start-game1', game1ProposalBuilder);
97
45
  };
98
46
  ```
99
47
 
100
- The first element of `getManifestCall` is interpreted as the name of a proposal.
101
- The second element of `getManifestCall` produces the `options` argument passed
102
- to the proposal. (`fooRef` in the example above). A common thing to want to pass
103
- in options is a reference to code to be installed on-chain. The `fooRef` example
104
- above shows how. `publishRef(install(<path>))` is built from sources in the
105
- sdk, and passed as a `bundleRef`, which contains a `bundleID` suitable for
106
- passing to Zoe (for contracts) or `vatAdminService` (for non-contract vat code).
48
+ The first element of `getManifestCall` is interpreted as the name of a function
49
+ defining a behavior. The second element of `getManifestCall` produces the
50
+ `options` argument passed to the function (`{ game1Red }` in the example
51
+ above). A common thing to want to pass in `options` is a reference to code to be
52
+ installed on-chain. The example above shows how. `publishRef(install(<path>))`
53
+ is built from sources in agoric-sdk, and passed as a `bundleRef`, which contains
54
+ a `bundleID` suitable for passing to Zoe (for contracts) or `vatAdminService`
55
+ (for non-contract vat code).
56
+
57
+ The CoreEvalBuilder says the proposal to run is
58
+ '@agoric/smart-wallet/test/start-game1-proposal.js'. It says the manifest can be
59
+ produced by running `getManifestForGame1`, and directs the creation of bundles
60
+ from `@agoric/smart-wallet/test/gameAssetContract.js` which will be made
61
+ available to the proposal as `game1Ref` in `options`.
62
+
63
+ The manifest gives permissions for accessing objects in promise space, and
64
+ passes installations to the proposalBuilder. Notice that `game1Ref` from the
65
+ proposalBuilder is passed to `getManifestForGame1`, which adds it to
66
+ `installations`, with the name `game1`. The name provided for installations will
67
+ also be used to register the installation in `agoricNames`.
68
+
69
+ ```
70
+ export const getManifestForGame1 = ({ restoreRef }, { game1Ref }) => {
71
+ return harden({
72
+ manifest: gameManifest,
73
+ installations: {
74
+ game1: restoreRef(game1Ref),
75
+ },
76
+ });
77
+ };
78
+ ```
79
+
80
+ ### Invoking the coreEval Behavior
81
+
82
+ The proposalBuilder script's default export is responsible for calling
83
+ `writeCoreEval()` to produce the scripts that will be evaluated by the chain.
84
+ These define behavior functions that will be invoked based on the keys in the
85
+ manifest and passed arguments declared in the manifest. The manifest is usually
86
+ in the same file, and conventionally provided by a function named
87
+ `getManifestForFoo`. The manifest needs to have a unique name, since it will be
88
+ referenced by name from the script.
89
+
90
+ ### proposalBuilder Script
91
+
92
+ The script describes how to build the core proposal. Script files should export
93
+ `defaultProposalBuilder` and a `default` function that invokes
94
+ `writeCoreProposal` one or more times to generate sets of files describing the
95
+ proposal.
107
96
 
97
+ Chain-halting SoftwareUpgrades can include coreEvals, by adding them to the
98
+ `CoreProposalSteps` section in [`upgrade.go`](../../golang/cosmos/app/upgrade.go). To execute a proposal via
99
+ CoreEval, follow [the instructions at
100
+ docs.agoric.com](https://docs.agoric.com/guides/coreeval/local-testnet.html).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agoric/deploy-script-support",
3
- "version": "0.10.4-u17.0",
3
+ "version": "0.10.4-u18.0",
4
4
  "description": "Helpers and other support for writing deploy scripts",
5
5
  "type": "module",
6
6
  "main": "src/helpers.js",
@@ -34,25 +34,25 @@
34
34
  },
35
35
  "homepage": "https://github.com/Agoric/agoric-sdk#readme",
36
36
  "dependencies": {
37
- "@agoric/ertp": "^0.16.3-u17.0",
38
- "@agoric/import-manager": "^0.3.12-u17.0",
39
- "@agoric/internal": "^0.4.0-u17.0",
40
- "@agoric/notifier": "^0.7.0-u17.0",
41
- "@agoric/store": "^0.9.3-u17.0",
42
- "@agoric/time": "^0.3.3-u17.0",
43
- "@agoric/zoe": "^0.26.3-u17.0",
44
- "@endo/base64": "^1.0.7",
45
- "@endo/bundle-source": "^3.4.0",
46
- "@endo/errors": "^1.2.5",
47
- "@endo/far": "^1.1.5",
48
- "@endo/marshal": "^1.5.3",
49
- "@endo/nat": "^5.0.10",
50
- "@endo/promise-kit": "^1.1.5",
51
- "@endo/zip": "^1.0.7"
37
+ "@agoric/ertp": "^0.16.3-u18.0",
38
+ "@agoric/import-manager": "^0.3.12-u18.0",
39
+ "@agoric/internal": "^0.4.0-u18.0",
40
+ "@agoric/notifier": "^0.7.0-u18.0",
41
+ "@agoric/store": "^0.9.3-u18.0",
42
+ "@agoric/time": "^0.3.3-u18.0",
43
+ "@agoric/zoe": "^0.26.3-u18.0",
44
+ "@endo/base64": "^1.0.8",
45
+ "@endo/bundle-source": "^3.4.2",
46
+ "@endo/errors": "^1.2.7",
47
+ "@endo/far": "^1.1.8",
48
+ "@endo/marshal": "^1.6.1",
49
+ "@endo/nat": "^5.0.12",
50
+ "@endo/promise-kit": "^1.1.7",
51
+ "@endo/zip": "^1.0.8"
52
52
  },
53
53
  "devDependencies": {
54
- "@agoric/vats": "^0.16.0-u17.0",
55
- "@endo/init": "^1.1.4",
54
+ "@agoric/vats": "^0.16.0-u18.0",
55
+ "@endo/init": "^1.1.6",
56
56
  "ava": "^5.3.0",
57
57
  "import-meta-resolve": "^2.2.1"
58
58
  },
@@ -74,5 +74,5 @@
74
74
  "typeCoverage": {
75
75
  "atLeast": 82.6
76
76
  },
77
- "gitHead": "515c4c0efccfc91b97da30037c10fc4b076851e2"
77
+ "gitHead": "c22e7250188bbdb07bc021dffdb88af0309a7aa8"
78
78
  }
@@ -6,6 +6,9 @@ import { Fail } from '@endo/errors';
6
6
  */
7
7
  export const makeCacheAndGetBundleSpec =
8
8
  (cacheDir, { now, fs, pathResolve }) =>
9
+ /**
10
+ * @param {Promise<import('@endo/bundle-source').BundleSourceResult<'endoZipBase64'>>} bundleP
11
+ */
9
12
  async bundleP => {
10
13
  const bundle = await bundleP;
11
14
  const { endoZipBase64Sha512: hash } = bundle;
@@ -167,6 +167,7 @@ export const makeCoreProposalBehavior = ({
167
167
  const installAdmin = E(agoricNamesAdmin).lookupAdmin('installation');
168
168
  await Promise.all(
169
169
  installationEntries.map(([key, value]) => {
170
+ produceInstallations[key].reset();
170
171
  produceInstallations[key].resolve(value);
171
172
  return E(installAdmin).update(key, value);
172
173
  }),
@@ -1,6 +1,10 @@
1
1
  // @ts-check
2
2
  export {};
3
3
 
4
+ /**
5
+ * @import {NameHub} from '@agoric/vats';
6
+ */
7
+
4
8
  // TODO move this type somewhere better
5
9
  /**
6
10
  * @typedef {string | string[]} Petname A petname can either be a plain string
@@ -47,3 +51,42 @@ export {};
47
51
  * @param {...any} args
48
52
  * @returns {Promise<CoreEvalDescriptor>}
49
53
  */
54
+
55
+ /**
56
+ * @typedef {{
57
+ * bundleSource: typeof import('@endo/bundle-source').default,
58
+ * cacheDir: string,
59
+ * lookup: (...path: string[]) => unknown,
60
+ * now: () => number,
61
+ * pathResolve: (...path: string[]) => string,
62
+ * publishBundle: PublishBundleRef,
63
+ * scriptArgs?: string[],
64
+ * }} DeployScriptEndownments
65
+ */
66
+
67
+ /**
68
+ * @typedef {{
69
+ * scratch: ERef<import('@agoric/internal/src/scratch.js').ScratchPad>,
70
+ * }} CommonHome
71
+ */
72
+
73
+ // TODO wallet as import('@agoric/wallet-backend/src/types').WalletAdmin once it's a module
74
+ /**
75
+ * @typedef {CommonHome & {
76
+ * agoricNames: ERef<NameHub>,
77
+ * bank: ERef<import("@agoric/vats/src/vat-bank.js").Bank>,
78
+ * board: ERef<import("@agoric/vats").Board>,
79
+ * faucet: unknown,
80
+ * myAddressNameAdmin: ERef<import("@agoric/vats").NameAdmin>,
81
+ * namesByAddress: ERef<NameHub>,
82
+ * wallet: any,
83
+ * zoe: ERef<ZoeService>,
84
+ * }} AgSoloHome
85
+ */
86
+
87
+ /**
88
+ * @callback DeployScriptFunction
89
+ * @param {Promise<CommonHome>} homeP
90
+ * @param {DeployScriptEndownments} endowments
91
+ * @returns {Promise<void>}
92
+ */
package/src/helpers.js CHANGED
@@ -52,6 +52,10 @@ const makeLazyObject = sourceObject => {
52
52
  return /** @type {T} */ (lazyObject);
53
53
  };
54
54
 
55
+ /**
56
+ * @param {Promise<import('./externalTypes.js').CommonHome | import('./externalTypes.js').AgSoloHome>} homePromise
57
+ * @param {import('./externalTypes.js').DeployScriptEndownments} endowments
58
+ */
55
59
  export const makeHelpers = async (homePromise, endowments) => {
56
60
  // Endowments provided via `agoric run` or `agoric deploy`.
57
61
  const {
@@ -84,6 +88,7 @@ export const makeHelpers = async (homePromise, endowments) => {
84
88
  return E(deps.walletAdmin).getIssuerManager();
85
89
  },
86
90
  get offerAndFind() {
91
+ assert('wallet' in deps.home, 'expected AgSolo home');
87
92
  return makeOfferAndFindInvitationAmount(
88
93
  deps.walletAdmin,
89
94
  deps.home.zoe,
@@ -91,6 +96,7 @@ export const makeHelpers = async (homePromise, endowments) => {
91
96
  );
92
97
  },
93
98
  get walletAdmin() {
99
+ assert('wallet' in deps.home, 'expected AgSolo home');
94
100
  return E(deps.home.wallet).getAdminFacet();
95
101
  },
96
102
  get zoeInvitationPurse() {
@@ -110,6 +116,7 @@ export const makeHelpers = async (homePromise, endowments) => {
110
116
  return deps.offerAndFind.findInvitationAmount;
111
117
  },
112
118
  get install() {
119
+ assert('wallet' in deps.home, 'expected AgSolo home');
113
120
  return makeInstall(
114
121
  bundleSource,
115
122
  deps.home.zoe,
@@ -127,6 +134,7 @@ export const makeHelpers = async (homePromise, endowments) => {
127
134
  return makeSaveIssuer(deps.walletAdmin, deps.issuerManager);
128
135
  },
129
136
  get startInstance() {
137
+ assert('wallet' in deps.home, 'expected AgSolo home');
130
138
  return makeStartInstance(
131
139
  deps.issuerManager,
132
140
  deps.instanceManager,
@@ -11,7 +11,8 @@ import {
11
11
  } from './coreProposalBehavior.js';
12
12
 
13
13
  /**
14
- * @import {CoreEvalDescriptor} from './externalTypes.js';
14
+ * @import {BundleSource, BundleSourceResult} from '@endo/bundle-source';
15
+ * @import {AgSoloHome, CanonicalHome, CommonHome, CoreEvalBuilder, CoreEvalDescriptor, ManifestBundleRef} from './externalTypes.js';
15
16
  */
16
17
 
17
18
  /**
@@ -27,20 +28,20 @@ import {
27
28
  * summary to `${filePrefix}-plan.json), plus whatever bundles bundles the code loads)
28
29
  * see CoreEval in {@link '/golang/cosmos/x/swingset/types/swingset.pb.go'}
29
30
  * @param {string} filePrefix name on disk
30
- * @param {import('./externalTypes.js').CoreEvalBuilder} builder
31
+ * @param {CoreEvalBuilder} builder
31
32
  * @returns {Promise<CoreEvalPlan>}
32
33
  */
33
34
 
34
35
  /**
35
36
  *
36
- * @param {*} homeP
37
+ * @param {Promise<CommonHome | AgSoloHome>} homeP
37
38
  * @param {{
38
- * bundleSource: (path: string) => Promise<NodeModule>,
39
+ * bundleSource: BundleSource,
39
40
  * pathResolve: (path: string) => string,
40
41
  * }} endowments
41
42
  * @param {{
42
43
  * getBundlerMaker: () => Promise<import('./getBundlerMaker.js').BundleMaker>,
43
- * getBundleSpec: (...args: *) => Promise<import('./externalTypes.js').ManifestBundleRef>,
44
+ * getBundleSpec: (bundle: Promise<BundleSourceResult<'endoZipBase64'>>, getBundle: () => import('./getBundlerMaker.js').Bundler, opts?: any) => Promise<ManifestBundleRef>,
44
45
  * log?: typeof console.log,
45
46
  * writeFile?: typeof fs.promises.writeFile
46
47
  * }} io
@@ -63,6 +64,7 @@ export const makeWriteCoreEval = (
63
64
  const getBundler = () => {
64
65
  if (!bundlerCache) {
65
66
  bundlerCache = E(getBundlerMaker()).makeBundler({
67
+ // @ts-expect-error lazily resolved for AgSoloHome
66
68
  zoe: E.get(homeP).zoe,
67
69
  });
68
70
  }
@@ -95,17 +97,16 @@ export const makeWriteCoreEval = (
95
97
  };
96
98
  };
97
99
 
98
- let mutex =
99
- /** @type {Promise<import('./externalTypes.js').ManifestBundleRef | undefined>} */ (
100
- Promise.resolve()
101
- );
100
+ let mutex = /** @type {Promise<ManifestBundleRef | undefined>} */ (
101
+ Promise.resolve()
102
+ );
102
103
  /** @type {WriteCoreEval} */
103
104
  const writeCoreEval = async (filePrefix, builder) => {
104
105
  /**
105
106
  *
106
107
  * @param {string} entrypoint
107
108
  * @param {string} [bundlePath]
108
- * @returns {Promise<NodeModule>}
109
+ * @returns {Promise<BundleSourceResult<'endoZipBase64'>>}
109
110
  */
110
111
  const getBundle = async (entrypoint, bundlePath) => {
111
112
  if (!bundlePath) {
@@ -125,7 +126,7 @@ export const makeWriteCoreEval = (
125
126
  * @param {string} entrypoint
126
127
  * @param {string} [bundlePath]
127
128
  * @param {unknown} [opts]
128
- * @returns {Promise<import('./externalTypes.js').ManifestBundleRef>}
129
+ * @returns {Promise<ManifestBundleRef>}
129
130
  */
130
131
  const install = async (entrypoint, bundlePath, opts) => {
131
132
  const bundle = getBundle(entrypoint, bundlePath);
@@ -146,7 +147,7 @@ export const makeWriteCoreEval = (
146
147
 
147
148
  // Await a reference then publish to the board.
148
149
  const cmds = [];
149
- /** @param {Promise<import('./externalTypes.js').ManifestBundleRef>} refP */
150
+ /** @param {Promise<ManifestBundleRef>} refP */
150
151
  const publishRef = async refP => {
151
152
  const { fileName, ...ref } = await refP;
152
153
  if (fileName) {