Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 20 additions & 18 deletions packages/internal/src/action-types.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
// @jessie-check

import { keyMirror } from './keyMirror.js';

/**
* Types of messages used for communication between a cosmos-sdk blockchain node
* and its paired swingset VM, especially for the ABCI lifecycle. See:
Expand All @@ -14,13 +16,13 @@
*
* @enum {(typeof SwingsetMessageType)[keyof typeof SwingsetMessageType]}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if this expression could be simplified with this approach.

*/
export const SwingsetMessageType = /** @type {const} */ ({
AG_COSMOS_INIT: 'AG_COSMOS_INIT', // used to synchronize at process launch
BEGIN_BLOCK: 'BEGIN_BLOCK',
END_BLOCK: 'END_BLOCK',
COMMIT_BLOCK: 'COMMIT_BLOCK',
AFTER_COMMIT_BLOCK: 'AFTER_COMMIT_BLOCK',
SWING_STORE_EXPORT: 'SWING_STORE_EXPORT', // used to synchronize data export
export const SwingsetMessageType = keyMirror({
AG_COSMOS_INIT: null, // used to synchronize at process launch
BEGIN_BLOCK: null,
END_BLOCK: null,
COMMIT_BLOCK: null,
AFTER_COMMIT_BLOCK: null,
SWING_STORE_EXPORT: null, // used to synchronize data export
});
harden(SwingsetMessageType);

Expand All @@ -47,17 +49,17 @@ export const {
*
* @enum {(typeof QueuedActionType)[keyof typeof QueuedActionType]}
*/
export const QueuedActionType = /** @type {const} */ ({
CORE_EVAL: 'CORE_EVAL',
DELIVER_INBOUND: 'DELIVER_INBOUND',
IBC_EVENT: 'IBC_EVENT',
INSTALL_BUNDLE: 'INSTALL_BUNDLE',
PLEASE_PROVISION: 'PLEASE_PROVISION',
VBANK_BALANCE_UPDATE: 'VBANK_BALANCE_UPDATE',
WALLET_ACTION: 'WALLET_ACTION',
WALLET_SPEND_ACTION: 'WALLET_SPEND_ACTION',
VTRANSFER_IBC_EVENT: 'VTRANSFER_IBC_EVENT',
KERNEL_UPGRADE_EVENTS: 'KERNEL_UPGRADE_EVENTS',
export const QueuedActionType = keyMirror({
CORE_EVAL: null,
DELIVER_INBOUND: null,
IBC_EVENT: null,
INSTALL_BUNDLE: null,
PLEASE_PROVISION: null,
VBANK_BALANCE_UPDATE: null,
WALLET_ACTION: null,
WALLET_SPEND_ACTION: null,
VTRANSFER_IBC_EVENT: null,
KERNEL_UPGRADE_EVENTS: null,
});
harden(QueuedActionType);

Expand Down
6 changes: 4 additions & 2 deletions packages/internal/src/config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// @ts-check
// @jessie-check

import { keyMirror } from './keyMirror.js';

/**
* @file
*
Expand Down Expand Up @@ -38,8 +40,8 @@ export const CosmosInitKeyToBridgeId = {
};
harden(CosmosInitKeyToBridgeId);

export const WalletName = /** @type {const} */ ({
depositFacet: 'depositFacet',
export const WalletName = keyMirror({
depositFacet: null,
});
harden(WalletName);

Expand Down
1 change: 1 addition & 0 deletions packages/internal/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export * from './config.js';
export * from './debug.js';
export * from './errors.js';
export * from './js-utils.js';
export * from './keyMirror.js';
export { pureDataMarshaller } from './marshal.js';
export * from './method-tools.js';
export * from './metrics.js';
Expand Down
45 changes: 45 additions & 0 deletions packages/internal/src/keyMirror.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// @ts-check
// @jessie-check

const { freeze, keys } = Object;

/**
* @template {Record<string, string | null>} Init
* @typedef {{ readonly [K in keyof Init]: K }} KeyMirrorResult
*/

/**

Check warning on line 11 in packages/internal/src/keyMirror.js

View workflow job for this annotation

GitHub Actions / lint-primary

Missing JSDoc @param "record" declaration
* Mirror the keys of an object to string values that match the key names.
*
* The provided record must only map property names to either `null` or the
* property name itself. The returned object has identical keys whose values are
* the string form of the key.
*
* @template {Record<string, string | null>} Init
* @param {Init & { readonly [K in keyof Init]: Init[K] extends null ? null : K }}

Check warning on line 19 in packages/internal/src/keyMirror.js

View workflow job for this annotation

GitHub Actions / lint-primary

There must be an identifier after @param tag

Check failure on line 19 in packages/internal/src/keyMirror.js

View workflow job for this annotation

GitHub Actions / lint-primary

Expected @param names to be "record". Got ""
* record
* @returns {KeyMirrorResult<Init>}
*/
export const keyMirror = record => {
if (record === null || typeof record !== 'object') {
throw TypeError('keyMirror expects a record of string keys.');
}

/** @type {Record<string, string>} */
const mirrored = {};
for (const key of keys(record)) {
const typedKey = /** @type {keyof Init & string} */ (key);
const value = record[typedKey];

Check failure on line 32 in packages/internal/src/keyMirror.js

View workflow job for this annotation

GitHub Actions / lint-primary

arbitrary computed property names are not allowed in Jessie; use leading '+'
const stringValue = /** @type {string | null} */ (value);
if (stringValue !== null && stringValue !== typedKey) {
throw TypeError(
`Value for key "${typedKey}" must be null or the key string; got ${String(value)}.`,
);
}
mirrored[typedKey] = typedKey;

Check failure on line 39 in packages/internal/src/keyMirror.js

View workflow job for this annotation

GitHub Actions / lint-primary

arbitrary computed property names are not allowed in Jessie; use leading '+'
}

return /** @type {KeyMirrorResult<Init>} */ (freeze(mirrored));
};

freeze(keyMirror);
9 changes: 5 additions & 4 deletions packages/orchestration/src/chain-info.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import { E } from '@endo/far';
import { M, mustMatch } from '@endo/patterns';
import { keyMirror } from '@agoric/internal';
import cctpChainInfo from './cctp-chain-info.js';
import { withChainCapabilities } from './chain-capabilities.js';
import { HubName, normalizeConnectionInfo } from './exos/chain-hub.js';
Expand All @@ -25,10 +26,10 @@ import { ChainInfoShape, CosmosAssetInfoShape } from './typeGuards.js';
* @enum {(typeof KnownNamespace)[keyof typeof KnownNamespace]}
* @see {@link https://github.com/ChainAgnostic/CAIPs/blob/c599f7601d0ce83e6dd9f350c6c21d158d56fd6d/CAIPs/caip-2.md}
*/
export const KnownNamespace = /** @type {const} */ ({
cosmos: 'cosmos',
eip155: 'eip155',
solana: 'solana',
export const KnownNamespace = keyMirror({
cosmos: null,
eip155: null,
solana: null,
});
harden(KnownNamespace);

Expand Down
36 changes: 20 additions & 16 deletions packages/portfolio-api/src/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,44 @@

/// <reference types="ses" />

import { keyMirror } from '@agoric/internal';

/**
* Yield protocols for Proof of Concept.
*
* @enum {(typeof YieldProtocol)[keyof typeof YieldProtocol]}
*/
export const YieldProtocol = /** @type {const} */ ({
Aave: 'Aave',
Compound: 'Compound',
USDN: 'USDN',
Beefy: 'Beefy',
export const YieldProtocol = keyMirror({
Aave: null,
Compound: null,
USDN: null,
Beefy: null,
});
harden(YieldProtocol);

/**
* @enum {(typeof AxelarChain)[keyof typeof AxelarChain]}
*/
export const AxelarChain = /** @type {const} */ ({
Arbitrum: 'Arbitrum',
Avalanche: 'Avalanche',
Base: 'Base',
Ethereum: 'Ethereum',
Optimism: 'Optimism',
export const AxelarChain = keyMirror({
Arbitrum: null,
Avalanche: null,
Base: null,
Ethereum: null,
Optimism: null,
});
harden(AxelarChain);

/**
* @enum {(typeof SupportedChain)[keyof typeof SupportedChain]}
*/
export const SupportedChain = /** @type {const} */ ({
export const SupportedChain = {
...AxelarChain,
agoric: 'agoric',
noble: 'noble',
// XXX: check privateArgs for chainInfo for all of these
});
...keyMirror({
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this could be pulled to the enclosing expression. though it would repeat the traversal of AxelarChain

agoric: null,
noble: null,
// XXX: check privateArgs for chainInfo for all of these
}),
};
harden(SupportedChain);

/**
Expand Down
12 changes: 7 additions & 5 deletions packages/portfolio-contract/src/resolver/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

/// <reference types="ses" />

import { keyMirror } from '@agoric/internal';

/**
* Tx statuses for published transactions. Exhaustive state machine flows:
* - pending -> success (when cross-chain operation completes successfully)
Expand All @@ -21,11 +23,11 @@ harden(TxStatus);
*
* @enum {(typeof TxType)[keyof typeof TxType]}
*/
export const TxType = /** @type {const} */ ({
CCTP_TO_EVM: 'CCTP_TO_EVM',
GMP: 'GMP',
CCTP_TO_AGORIC: 'CCTP_TO_AGORIC',
export const TxType = keyMirror({
CCTP_TO_EVM: null,
GMP: null,
CCTP_TO_AGORIC: null,
/** @deprecated - only supports 20 byte addresses */
CCTP_TO_NOBLE: 'CCTP_TO_NOBLE',
CCTP_TO_NOBLE: null,
});
harden(TxType);
8 changes: 5 additions & 3 deletions packages/vats/src/walletFlags.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
// XXX domain of @agoric/cosmic-proto
import { keyMirror } from '@agoric/internal';

/**
* non-exhaustive list of powerFlags REMOTE_WALLET is currently a default.
*
* See also MsgProvision in golang/cosmos/proto/agoric/swingset/msgs.proto
*/
export const PowerFlags = /** @type {const} */ ({
SMART_WALLET: 'SMART_WALLET',
export const PowerFlags = keyMirror({
SMART_WALLET: null,
/** The ag-solo wallet is remote. */
REMOTE_WALLET: 'REMOTE_WALLET',
REMOTE_WALLET: null,
});
Loading