agoric 0.18.4 → 0.18.5-dev-800c2bb.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/src/start.js CHANGED
@@ -2,8 +2,10 @@
2
2
  import chalk from 'chalk';
3
3
  import { createHash } from 'crypto';
4
4
  import path from 'path';
5
+ import { createRequire } from 'module';
5
6
 
6
- import { Nat, isNat } from '@agoric/nat';
7
+ import { Nat, isNat } from '@endo/nat';
8
+ import { untilTrue } from '@agoric/internal';
7
9
 
8
10
  import {
9
11
  CENTRAL_DENOM,
@@ -15,6 +17,8 @@ import {
15
17
 
16
18
  import { makePspawn, getSDKBinaries } from './helpers.js';
17
19
 
20
+ const require = createRequire(import.meta.url);
21
+
18
22
  const terminalOnlyFlags = (...flags) => {
19
23
  if (process.stdout.isTTY && process.stdin.isTTY) {
20
24
  return flags;
@@ -27,10 +31,10 @@ const PROVISION_COINS = [
27
31
  `5000000000000000${CENTRAL_DENOM}`,
28
32
  `100provisionpass`,
29
33
  `100sendpacketpass`,
30
- `1000000000000ibc/0123456789abcdef`, // IbcATOM
31
- `1000000000000ibc/123456789abcdef0`, // AUSD
32
- `1000000000000ibc/23456789abcdef01`,
33
- `1000000000000ibc/3456789abcdef012`,
34
+ `1000000000000ibc/toyatom`, // ATOM
35
+ `1000000000000ibc/toyellie`, // AUSD
36
+ `1000000000000ibc/toyusdc`, // USDC
37
+ `1000000000000ibc/toyollie`, // USDT
34
38
  ].join(',');
35
39
  const DELEGATE0_COINS = `50000000${STAKING_DENOM}`;
36
40
  const SOLO_COINS = `13000000${STAKING_DENOM},500000000${CENTRAL_DENOM}`;
@@ -56,11 +60,11 @@ const GAS_ADJUSTMENT = '1.2';
56
60
  const delay = ms => new Promise(resolve => setTimeout(() => resolve(), ms));
57
61
 
58
62
  export default async function startMain(progname, rawArgs, powers, opts) {
59
- const { anylogger, fs, spawn, process } = powers;
63
+ const { anylogger, fs, spawn, now, process } = powers;
60
64
  const log = anylogger('agoric:start');
61
65
 
62
- const SDK_IMAGE = `agoric/agoric-sdk:${opts.dockerTag}`;
63
- const SOLO_IMAGE = `agoric/cosmic-swingset-solo:${opts.dockerTag}`;
66
+ const SDK_IMAGE = `ghcr.io/agoric/agoric-sdk:${opts.dockerTag}`;
67
+ const SOLO_IMAGE = `ghcr.io/agoric/cosmic-swingset-solo:${opts.dockerTag}`;
64
68
 
65
69
  const pspawnEnv = { ...process.env };
66
70
  if (opts.verbose > 1) {
@@ -124,17 +128,17 @@ export default async function startMain(progname, rawArgs, powers, opts) {
124
128
  }
125
129
 
126
130
  const capture = (spawner, args, show = false) => {
127
- const capret = [
131
+ const statusOut = [
128
132
  spawner(args, { stdio: ['inherit', 'pipe', 'inherit'] }),
129
133
  '',
130
134
  ];
131
- capret[0].childProcess.stdout.on('data', chunk => {
135
+ statusOut[0].childProcess.stdout.on('data', chunk => {
132
136
  if (show) {
133
137
  process.stdout.write(chunk);
134
138
  }
135
- capret[1] += chunk.toString('utf-8');
139
+ statusOut[1] += chunk.toString('utf-8');
136
140
  });
137
- return capret;
141
+ return statusOut;
138
142
  };
139
143
 
140
144
  const showKey = keyName =>
@@ -176,7 +180,8 @@ export default async function startMain(progname, rawArgs, powers, opts) {
176
180
  }
177
181
 
178
182
  if (!opts.dockerTag) {
179
- if (!(await exists('node_modules/@agoric/solo'))) {
183
+ const soloExists = await exists('node_modules/@agoric/solo');
184
+ if (!soloExists) {
180
185
  log.error(`you must first run '${progname} install'`);
181
186
  return 1;
182
187
  }
@@ -192,7 +197,8 @@ export default async function startMain(progname, rawArgs, powers, opts) {
192
197
  }
193
198
 
194
199
  const fakeGCI = 'sim-chain';
195
- if (!(await exists(agServer))) {
200
+ const serverExists = await exists(agServer);
201
+ if (!serverExists) {
196
202
  log(chalk.yellow(`initializing ${profileName}`));
197
203
  await pspawn(
198
204
  agSolo,
@@ -287,7 +293,8 @@ export default async function startMain(progname, rawArgs, powers, opts) {
287
293
  );
288
294
  }
289
295
 
290
- if (!(await exists(agServer))) {
296
+ const serverExists = await exists(agServer);
297
+ if (!serverExists) {
291
298
  const exitStatus = await chainSpawn([
292
299
  'init',
293
300
  'local-chain',
@@ -302,8 +309,9 @@ export default async function startMain(progname, rawArgs, powers, opts) {
302
309
  const addrs = {};
303
310
  for (const keyName of ['provision', 'delegate0']) {
304
311
  /* eslint-disable no-await-in-loop */
305
- let capret = showKey(keyName);
306
- if (await capret[0]) {
312
+ let statusOut = showKey(keyName);
313
+ const exitStatusOut = await statusOut[0];
314
+ if (exitStatusOut) {
307
315
  const exitStatus = await keysSpawn([
308
316
  'keys',
309
317
  'add',
@@ -313,18 +321,19 @@ export default async function startMain(progname, rawArgs, powers, opts) {
313
321
  if (exitStatus) {
314
322
  return exitStatus;
315
323
  }
316
- capret = showKey(keyName);
317
- const status2 = await capret[0];
324
+ statusOut = showKey(keyName);
325
+ const status2 = await statusOut[0];
318
326
  if (status2) {
319
327
  return status2;
320
328
  }
321
329
  }
322
- addrs[keyName] = capret[1].trimRight();
330
+ addrs[keyName] = statusOut[1].trimRight();
323
331
  /* eslint-enable no-await-in-loop */
324
332
  }
325
333
 
326
334
  const genesisFile = `${agServer}/config/genesis.json`;
327
- if (!(await exists(`${genesisFile}.stamp`))) {
335
+ const stampExists = await exists(`${genesisFile}.stamp`);
336
+ if (!stampExists) {
328
337
  let exitStatus;
329
338
  exitStatus = await chainSpawn([
330
339
  'add-genesis-account',
@@ -365,7 +374,7 @@ export default async function startMain(progname, rawArgs, powers, opts) {
365
374
  if (exitStatus) {
366
375
  return exitStatus;
367
376
  }
368
- exitStatus = await fs.writeFile(`${genesisFile}.stamp`, `${Date.now()}`);
377
+ exitStatus = await fs.writeFile(`${genesisFile}.stamp`, `${now()}`);
369
378
  if (exitStatus) {
370
379
  return exitStatus;
371
380
  }
@@ -494,8 +503,9 @@ export default async function startMain(progname, rawArgs, powers, opts) {
494
503
  );
495
504
  }
496
505
 
506
+ const serverExists = await exists(agServer);
497
507
  // Initialise the solo directory and key.
498
- if (!(await exists(agServer))) {
508
+ if (!serverExists) {
499
509
  const initArgs = [`--webport=${portNum}`];
500
510
  if (opts.dockerTag) {
501
511
  initArgs.push(`--webhost=0.0.0.0`);
@@ -509,6 +519,32 @@ export default async function startMain(progname, rawArgs, powers, opts) {
509
519
  return exitStatus;
510
520
  }
511
521
  }
522
+
523
+ // Create the full economy chain config.
524
+ const agServerResolve = spec =>
525
+ require.resolve(spec, { paths: [agServer] });
526
+ const coreConfigPath = agServerResolve(
527
+ '@agoric/vats/decentral-core-config.json',
528
+ );
529
+ const economyTemplPath = agServerResolve(
530
+ '@agoric/cosmic-swingset/economy-template.json',
531
+ );
532
+ const [rawSoloAddr, coreConfigJson, economyTemplJson] = await Promise.all([
533
+ fs.readFile(`${agServer}/ag-cosmos-helper-address`, 'utf-8'),
534
+ fs.readFile(coreConfigPath, 'utf-8'),
535
+ fs.readFile(economyTemplPath, 'utf-8'),
536
+ ]);
537
+ const soloAddr = rawSoloAddr.trimRight();
538
+ const economyProposals = JSON.parse(
539
+ economyTemplJson.replace(/@PRIMARY_ADDRESS@/g, soloAddr),
540
+ );
541
+ const economyConfig = JSON.parse(coreConfigJson);
542
+ economyConfig.coreProposals = economyProposals;
543
+ await fs.writeFile(
544
+ `${agServer}/decentral-economy-config.json`,
545
+ JSON.stringify(economyConfig, null, 2),
546
+ );
547
+
512
548
  if (!opts.restart) {
513
549
  return 0;
514
550
  }
@@ -516,13 +552,13 @@ export default async function startMain(progname, rawArgs, powers, opts) {
516
552
  const gciFile = `_agstate/agoric-servers/local-chain-${CHAIN_PORT}/config/genesis.json.sha256`;
517
553
  process.stdout.write(`Waiting for local-chain-${CHAIN_PORT} to start...`);
518
554
  let hasGci = false;
519
- while (!hasGci) {
555
+ for await (const _ of untilTrue(() => hasGci)) {
520
556
  process.stdout.write('.');
521
557
 
522
558
  // eslint-disable-next-line no-await-in-loop
523
559
  await new Promise((resolve, reject) => {
524
560
  fs.stat(gciFile).then(
525
- _ => {
561
+ _2 => {
526
562
  hasGci = true;
527
563
  resolve(true);
528
564
  },
@@ -551,12 +587,9 @@ export default async function startMain(progname, rawArgs, powers, opts) {
551
587
  let exitStatus;
552
588
 
553
589
  // Provision the ag-solo, if necessary.
554
- const soloAddr = (
555
- await fs.readFile(`${agServer}/ag-cosmos-helper-address`, 'utf-8')
556
- ).trimRight();
557
590
  let bestRpcAddr;
558
- while (!bestRpcAddr) {
559
- for (const rpcAddr of rpcAddrs) {
591
+ for await (const _ of untilTrue(() => bestRpcAddr)) {
592
+ for await (const rpcAddr of rpcAddrs) {
560
593
  // eslint-disable-next-line no-await-in-loop
561
594
  exitStatus = await keysSpawn([
562
595
  'query',
@@ -604,12 +637,12 @@ export default async function startMain(progname, rawArgs, powers, opts) {
604
637
  SOLO_COINS,
605
638
  ],
606
639
  ];
607
- for (const cmd of provCmds) {
608
- const capret = capture(keysSpawn, cmd, true);
640
+ for (/* await */ const cmd of provCmds) {
641
+ const statusOut = capture(keysSpawn, cmd, true);
609
642
  // eslint-disable-next-line no-await-in-loop
610
- exitStatus = await capret[0];
643
+ exitStatus = await statusOut[0];
611
644
  if (!exitStatus) {
612
- const json = capret[1].replace(/^gas estimate: \d+$/m, '');
645
+ const json = statusOut[1].replace(/^gas estimate: \d+$/m, '');
613
646
  try {
614
647
  const ret = JSON.parse(json);
615
648
  if (ret.code !== 0) {
@@ -639,8 +672,9 @@ export default async function startMain(progname, rawArgs, powers, opts) {
639
672
  return exitStatus;
640
673
  }
641
674
 
675
+ const file = await fs.readFile(gciFile, 'utf-8');
642
676
  // Connect to the chain.
643
- const gci = (await fs.readFile(gciFile, 'utf-8')).trimRight();
677
+ const gci = file.trimRight();
644
678
  exitStatus = await soloSpawn(
645
679
  ['set-gci-ingress', `--chainID=${CHAIN_ID}`, gci, bestRpcAddr],
646
680
  spawnOpts,
package/src/lib/psm.js DELETED
@@ -1,82 +0,0 @@
1
- // @ts-check
2
-
3
- import { COSMOS_UNIT } from './format.js';
4
-
5
- /** @typedef {import('@agoric/smart-wallet/src/offers').OfferSpec} OfferSpec */
6
- /** @typedef {import('@agoric/smart-wallet/src/offers').OfferStatus} OfferStatus */
7
- /** @typedef {import('@agoric/smart-wallet/src/smartWallet').BridgeAction} BridgeAction */
8
-
9
- /**
10
- * @param {Record<string, Brand>} brands
11
- * @param {({ wantMinted: number | undefined, giveMinted: number | undefined })} opts
12
- * @param {number} [fee=0]
13
- * @param {string} [anchor]
14
- * @returns {Proposal}
15
- */
16
- export const makePSMProposal = (brands, opts, fee = 0, anchor = 'AUSD') => {
17
- const giving = opts.giveMinted ? 'minted' : 'anchor';
18
- const brand =
19
- giving === 'anchor'
20
- ? { in: brands[anchor], out: brands.IST }
21
- : { in: brands.IST, out: brands[anchor] };
22
- const value =
23
- Number(giving === 'anchor' ? opts.wantMinted : opts.giveMinted) *
24
- Number(COSMOS_UNIT);
25
- const adjusted = {
26
- in: BigInt(Math.ceil(giving === 'anchor' ? value / (1 - fee) : value)),
27
- out: BigInt(Math.ceil(giving === 'minted' ? value * (1 - fee) : value)),
28
- };
29
- return {
30
- give: {
31
- In: { brand: brand.in, value: adjusted.in },
32
- },
33
- want: {
34
- Out: { brand: brand.out, value: adjusted.out },
35
- },
36
- };
37
- };
38
-
39
- /**
40
- * @param {Instance} instance
41
- * @param {Record<string, Brand>} brands
42
- * @param {{ offerId: number, feePct?: number } &
43
- * ({ wantMinted: number | undefined, giveMinted: number | undefined })} opts
44
- * @returns {BridgeAction}
45
- */
46
- export const makePSMSpendAction = (instance, brands, opts) => {
47
- const method = opts.wantMinted
48
- ? 'makeWantMintedInvitation'
49
- : 'makeGiveMintedInvitation'; // ref psm.js
50
- const proposal = makePSMProposal(
51
- brands,
52
- opts,
53
- opts.feePct ? opts.feePct / 100 : undefined,
54
- // @ts-expect-error please update types. Not sure where pair goees.
55
- opts.pair[1],
56
- );
57
-
58
- console.warn('psm spend give', proposal.give);
59
- console.warn('psm spend want', proposal.want);
60
-
61
- // NB: not really a Proposal because the brands are not remotes
62
- // Instead they're copyRecord like "{"boardId":"board0257","iface":"Alleged: IST brand"}" to pass through the boardId
63
- // fit(harden(proposal), ProposalShape);
64
-
65
- /** @type {OfferSpec} */
66
- const offer = {
67
- id: opts.offerId,
68
- invitationSpec: {
69
- source: 'contract',
70
- instance,
71
- publicInvitationMaker: method,
72
- },
73
- proposal,
74
- };
75
-
76
- /** @type {BridgeAction} */
77
- const spendAction = {
78
- method: 'executeOffer',
79
- offer,
80
- };
81
- return harden(spendAction);
82
- };