fix: use secret RPC urls in infra, apply environment-specific registry overrides (#3875)

### Description

A while back, it seems secret RPC URLs stopped being used by monorepo
services (see
https://github.com/hyperlane-xyz/hyperlane-monorepo/pull/3179/files#diff-ba3b7bea2b5c046acd88d25ed382df875b49d77e061f2ef8347ffcc741c0353eR34).
This adds them back.

Some things to note on the approach:
- Sadly, due to the way some of the infra config generation works, we're
forced to use synchronous interfaces for getting chain metadata in a
bunch of places. This is why `getRegistry` returns a
`FileSystemRegistry`, which is a `SynchronousRegistry`.
- Applying secrets / overrides requires us to do things async for two
reasons -- one is just that fetching from GCP secrets is an async
operation, the other is that a `MergedRegistry` is not a
`SynchronousRegistry`. The approach I've taken is that there are two
ways of getting a registry - using `getRegistry` will give the
synchronous version that can continue to be used by our sync config
generation, but it won't have any environment-specific overrides (tx
overrides or secrets). To get an async registry with
environment-specific overrides, the `getRegistry` function on the
EnvironmentConfig is used.
- Overrides are now more succinct as the merging happens later in the
pipeline

### Drive-by changes

- Started moving away from using the gcloud CLI under the hood for GCP
operations and toward using the GCP secret SDK
- Updated the mainnet3 key funder to fix an incident, but will follow up
with a fresh deploy once this is mergd

### Related issues

- These are the code changes for
https://github.com/hyperlane-xyz/hyperlane-monorepo/issues/3774, but
I'll follow up with fresh deploys for the monorepo services

### Backward compatibility

<!--
Are these changes backward compatible? Are there any infrastructure
implications, e.g. changes that would prohibit deploying older commits
using this infra tooling?

Yes/No
-->

### Testing

<!--
What kind of testing have these changes undergone?

None/Manual/Unit Tests
-->

---------

Co-authored-by: Connor McEwen <connor.mcewen@gmail.com>
Co-authored-by: Yorke Rhodes <yorke@hyperlane.xyz>
Co-authored-by: J M Rossy <jm.rossy@gmail.com>
noah/dr-fix
Trevor Porter 6 months ago committed by GitHub
parent 8a6654477e
commit db9f733e4f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 49
      rust/config/mainnet_config.json
  2. 28
      typescript/infra/config/environments/mainnet3/chains.ts
  3. 2
      typescript/infra/config/environments/mainnet3/funding.ts
  4. 48
      typescript/infra/config/environments/mainnet3/index.ts
  5. 9
      typescript/infra/config/environments/test/index.ts
  6. 15
      typescript/infra/config/environments/testnet4/chains.ts
  7. 33
      typescript/infra/config/environments/testnet4/index.ts
  8. 39
      typescript/infra/config/registry.ts
  9. 1
      typescript/infra/package.json
  10. 58
      typescript/infra/scripts/agent-utils.ts
  11. 8
      typescript/infra/scripts/agents/update-agent-config.ts
  12. 10
      typescript/infra/scripts/check-rpc-urls.ts
  13. 4
      typescript/infra/scripts/funding/fund-keys-from-deployer.ts
  14. 12
      typescript/infra/scripts/helloworld/kathy.ts
  15. 12
      typescript/infra/scripts/print-chain-metadatas.ts
  16. 88
      typescript/infra/scripts/print-gas-prices.ts
  17. 12
      typescript/infra/scripts/print-token-prices.ts
  18. 8
      typescript/infra/src/agents/index.ts
  19. 81
      typescript/infra/src/config/chain.ts
  20. 8
      typescript/infra/src/config/environment.ts
  21. 30
      typescript/infra/src/utils/gcloud.ts
  22. 4
      typescript/infra/src/utils/utils.ts
  23. 10
      typescript/sdk/src/metadata/agentConfig.ts
  24. 315
      yarn.lock

@ -634,13 +634,19 @@
}, },
"injective": { "injective": {
"bech32Prefix": "inj", "bech32Prefix": "inj",
"blockExplorers": [
],
"blocks": { "blocks": {
"confirmations": 1,
"estimateBlockTime": 1,
"reorgPeriod": 10 "reorgPeriod": 10
}, },
"canonicalAsset": "inj", "canonicalAsset": "inj",
"chainId": "injective-1", "chainId": "injective-1",
"contractAddressBytes": 20, "contractAddressBytes": 20,
"domainId": "6909546", "displayName": "Injective",
"domainId": 6909546,
"gasCurrencyCoinGeckoId": "injective-protocol",
"gasPrice": { "gasPrice": {
"amount": "700000000", "amount": "700000000",
"denom": "inj" "denom": "inj"
@ -658,12 +664,24 @@
"mailbox": "0x0f7fb53961d70687e352aa55cb329ca76edc0c19", "mailbox": "0x0f7fb53961d70687e352aa55cb329ca76edc0c19",
"merkleTreeHook": "0x568ad3638447f07def384969f4ea39fae3802962", "merkleTreeHook": "0x568ad3638447f07def384969f4ea39fae3802962",
"name": "injective", "name": "injective",
"nativeToken": {
"decimals": 18,
"denom": "inj",
"name": "Injective",
"symbol": "INJ"
},
"protocol": "cosmos", "protocol": "cosmos",
"restUrls": [
{
"http": "https://sentry.lcd.injective.network:443"
}
],
"rpcUrls": [ "rpcUrls": [
{ {
"http": "https://injective-rpc.polkachu.com" "http": "https://sentry.tm.injective.network:443"
} }
], ],
"slip44": 118,
"validatorAnnounce": "0x1fb225b2fcfbe75e614a1d627de97ff372242eed" "validatorAnnounce": "0x1fb225b2fcfbe75e614a1d627de97ff372242eed"
}, },
"mantapacific": { "mantapacific": {
@ -837,13 +855,25 @@
}, },
"neutron": { "neutron": {
"bech32Prefix": "neutron", "bech32Prefix": "neutron",
"blockExplorers": [
{
"apiUrl": "https://www.mintscan.io/neutron",
"family": "other",
"name": "Mintscan",
"url": "https://www.mintscan.io/neutron"
}
],
"blocks": { "blocks": {
"confirmations": 1,
"estimateBlockTime": 3,
"reorgPeriod": 1 "reorgPeriod": 1
}, },
"canonicalAsset": "untrn", "canonicalAsset": "untrn",
"chainId": "neutron-1", "chainId": "neutron-1",
"contractAddressBytes": 32, "contractAddressBytes": 32,
"domainId": "1853125230", "displayName": "Neutron",
"domainId": 1853125230,
"gasCurrencyCoinGeckoId": "neutron-3",
"gasPrice": { "gasPrice": {
"amount": "0.0053", "amount": "0.0053",
"denom": "untrn" "denom": "untrn"
@ -858,10 +888,22 @@
"from": 4000000 "from": 4000000
}, },
"interchainGasPaymaster": "0x504ee9ac43ec5814e00c7d21869a90ec52becb489636bdf893b7df9d606b5d67", "interchainGasPaymaster": "0x504ee9ac43ec5814e00c7d21869a90ec52becb489636bdf893b7df9d606b5d67",
"isTestnet": false,
"mailbox": "0x848426d50eb2104d5c6381ec63757930b1c14659c40db8b8081e516e7c5238fc", "mailbox": "0x848426d50eb2104d5c6381ec63757930b1c14659c40db8b8081e516e7c5238fc",
"merkleTreeHook": "0xcd30a0001cc1f436c41ef764a712ebabc5a144140e3fd03eafe64a9a24e4e27c", "merkleTreeHook": "0xcd30a0001cc1f436c41ef764a712ebabc5a144140e3fd03eafe64a9a24e4e27c",
"name": "neutron", "name": "neutron",
"nativeToken": {
"decimals": 6,
"denom": "untrn",
"name": "Neutron",
"symbol": "NTRN"
},
"protocol": "cosmos", "protocol": "cosmos",
"restUrls": [
{
"http": "https://rest-lb.neutron.org"
}
],
"rpcUrls": [ "rpcUrls": [
{ {
"http": "https://rpc-kralum.neutron-1.neutron.org" "http": "https://rpc-kralum.neutron-1.neutron.org"
@ -872,6 +914,7 @@
"prefix": "neutron", "prefix": "neutron",
"type": "cosmosKey" "type": "cosmosKey"
}, },
"slip44": 118,
"validatorAnnounce": "0xf3aa0d652226e21ae35cd9035c492ae41725edc9036edf0d6a48701b153b90a0" "validatorAnnounce": "0xf3aa0d652226e21ae35cd9035c492ae41725edc9036edf0d6a48701b153b90a0"
}, },
"optimism": { "optimism": {

@ -1,30 +1,23 @@
import { ChainMap, ChainMetadata } from '@hyperlane-xyz/sdk'; import { ChainMap, ChainMetadata } from '@hyperlane-xyz/sdk';
import { objKeys } from '@hyperlane-xyz/utils';
import { getChainMetadatas } from '../../../src/config/chain.js'; import { isEthereumProtocolChain } from '../../../src/utils/utils.js';
import { getChain } from '../../registry.js';
import { supportedChainNames } from './supportedChainNames.js'; import { supportedChainNames } from './supportedChainNames.js';
export const environment = 'mainnet3'; export const environment = 'mainnet3';
const { export const ethereumChainNames = supportedChainNames.filter(
ethereumMetadatas: defaultEthereumMainnetConfigs, isEthereumProtocolChain,
nonEthereumMetadatas: nonEthereumMainnetConfigs, );
} = getChainMetadatas(supportedChainNames);
export const ethereumMainnetConfigs: ChainMap<ChainMetadata> = { export const chainMetadataOverrides: ChainMap<Partial<ChainMetadata>> = {
...defaultEthereumMainnetConfigs,
bsc: { bsc: {
...getChain('bsc'),
transactionOverrides: { transactionOverrides: {
gasPrice: 3 * 10 ** 9, // 3 gwei gasPrice: 3 * 10 ** 9, // 3 gwei
}, },
}, },
polygon: { polygon: {
...getChain('polygon'),
blocks: { blocks: {
...getChain('polygon').blocks,
confirmations: 3, confirmations: 3,
}, },
transactionOverrides: { transactionOverrides: {
@ -35,9 +28,7 @@ export const ethereumMainnetConfigs: ChainMap<ChainMetadata> = {
}, },
}, },
ethereum: { ethereum: {
...getChain('ethereum'),
blocks: { blocks: {
...getChain('ethereum').blocks,
confirmations: 3, confirmations: 3,
}, },
transactionOverrides: { transactionOverrides: {
@ -46,7 +37,6 @@ export const ethereumMainnetConfigs: ChainMap<ChainMetadata> = {
}, },
}, },
scroll: { scroll: {
...getChain('scroll'),
transactionOverrides: { transactionOverrides: {
// Scroll doesn't use EIP 1559 and the gas price that's returned is sometimes // Scroll doesn't use EIP 1559 and the gas price that's returned is sometimes
// too low for the transaction to be included in a reasonable amount of time - // too low for the transaction to be included in a reasonable amount of time -
@ -55,17 +45,9 @@ export const ethereumMainnetConfigs: ChainMap<ChainMetadata> = {
}, },
}, },
moonbeam: { moonbeam: {
...getChain('moonbeam'),
transactionOverrides: { transactionOverrides: {
maxFeePerGas: 350 * 10 ** 9, // 350 gwei maxFeePerGas: 350 * 10 ** 9, // 350 gwei
maxPriorityFeePerGas: 50 * 10 ** 9, // 50 gwei maxPriorityFeePerGas: 50 * 10 ** 9, // 50 gwei
}, },
}, },
}; };
export const mainnetConfigs: ChainMap<ChainMetadata> = {
...ethereumMainnetConfigs,
...nonEthereumMainnetConfigs,
};
export const ethereumChainNames = objKeys(ethereumMainnetConfigs);

@ -9,7 +9,7 @@ import { environment } from './chains.js';
export const keyFunderConfig: KeyFunderConfig = { export const keyFunderConfig: KeyFunderConfig = {
docker: { docker: {
repo: 'gcr.io/abacus-labs-dev/hyperlane-monorepo', repo: 'gcr.io/abacus-labs-dev/hyperlane-monorepo',
tag: 'b22a0f4-20240523-140812', tag: '7720875-20240531-072251',
}, },
// We're currently using the same deployer/key funder key as mainnet2. // We're currently using the same deployer/key funder key as mainnet2.
// To minimize nonce clobbering we offset the key funder cron // To minimize nonce clobbering we offset the key funder cron

@ -1,16 +1,21 @@
import { ChainMetadata, RpcConsensusType } from '@hyperlane-xyz/sdk'; import { IRegistry } from '@hyperlane-xyz/registry';
import { ProtocolType, objFilter } from '@hyperlane-xyz/utils'; import { RpcConsensusType } from '@hyperlane-xyz/sdk';
import { import {
getKeysForRole, getKeysForRole,
getMultiProtocolProvider,
getMultiProviderForRole, getMultiProviderForRole,
} from '../../../scripts/agent-utils.js'; } from '../../../scripts/agent-utils.js';
import { getRegistryForEnvironment } from '../../../src/config/chain.js';
import { EnvironmentConfig } from '../../../src/config/environment.js'; import { EnvironmentConfig } from '../../../src/config/environment.js';
import { Role } from '../../../src/roles.js'; import { Role } from '../../../src/roles.js';
import { Contexts } from '../../contexts.js'; import { Contexts } from '../../contexts.js';
import { agents } from './agent.js'; import { agents } from './agent.js';
import { environment as environmentName, mainnetConfigs } from './chains.js'; import {
chainMetadataOverrides,
environment as environmentName,
} from './chains.js';
import { core } from './core.js'; import { core } from './core.js';
import { keyFunderConfig } from './funding.js'; import { keyFunderConfig } from './funding.js';
import { helloWorld } from './helloworld.js'; import { helloWorld } from './helloworld.js';
@ -18,34 +23,39 @@ import { igp } from './igp.js';
import { infrastructure } from './infrastructure.js'; import { infrastructure } from './infrastructure.js';
import { bridgeAdapterConfigs, relayerConfig } from './liquidityLayer.js'; import { bridgeAdapterConfigs, relayerConfig } from './liquidityLayer.js';
import { owners } from './owners.js'; import { owners } from './owners.js';
import { supportedChainNames } from './supportedChainNames.js';
const getRegistry = async (useSecrets = true): Promise<IRegistry> =>
getRegistryForEnvironment(
environmentName,
supportedChainNames,
chainMetadataOverrides,
useSecrets,
);
export const environment: EnvironmentConfig = { export const environment: EnvironmentConfig = {
environment: environmentName, environment: environmentName,
chainMetadataConfigs: mainnetConfigs, supportedChainNames,
getMultiProvider: ( getRegistry,
getMultiProtocolProvider: async () =>
getMultiProtocolProvider(await getRegistry()),
getMultiProvider: async (
context: Contexts = Contexts.Hyperlane, context: Contexts = Contexts.Hyperlane,
role: Role = Role.Deployer, role: Role = Role.Deployer,
connectionType?: RpcConsensusType, _connectionType?: RpcConsensusType,
) => { useSecrets?: boolean,
const config = objFilter( ) =>
mainnetConfigs, getMultiProviderForRole(
(_, chainMetadata): chainMetadata is ChainMetadata =>
chainMetadata.protocol === ProtocolType.Ethereum,
);
return getMultiProviderForRole(
config,
environmentName, environmentName,
await getRegistry(useSecrets),
context, context,
role, role,
undefined, undefined,
connectionType, ),
);
},
getKeys: ( getKeys: (
context: Contexts = Contexts.Hyperlane, context: Contexts = Contexts.Hyperlane,
role: Role = Role.Deployer, role: Role = Role.Deployer,
) => getKeysForRole(mainnetConfigs, environmentName, context, role), ) => getKeysForRole(environmentName, supportedChainNames, context, role),
agents, agents,
core, core,
igp, igp,

@ -5,6 +5,7 @@ import { MultiProvider, testChainMetadata } from '@hyperlane-xyz/sdk';
import { EnvironmentConfig } from '../../../src/config/environment.js'; import { EnvironmentConfig } from '../../../src/config/environment.js';
import { agents } from './agent.js'; import { agents } from './agent.js';
import { testChainNames } from './chains.js';
import { core } from './core.js'; import { core } from './core.js';
import { igp } from './igp.js'; import { igp } from './igp.js';
import { infra } from './infra.js'; import { infra } from './infra.js';
@ -12,7 +13,13 @@ import { owners } from './owners.js';
export const environment: EnvironmentConfig = { export const environment: EnvironmentConfig = {
environment: 'test', environment: 'test',
chainMetadataConfigs: testChainMetadata, supportedChainNames: testChainNames,
getRegistry: () => {
throw new Error('Not implemented');
},
getMultiProtocolProvider: () => {
throw new Error('Not implemented');
},
agents, agents,
core, core,
igp, igp,

@ -1,24 +1,19 @@
import { ChainMap, ChainMetadata } from '@hyperlane-xyz/sdk'; import { ChainMap, ChainMetadata } from '@hyperlane-xyz/sdk';
import { objKeys } from '@hyperlane-xyz/utils';
import { getChainMetadatas } from '../../../src/config/chain.js'; import { isEthereumProtocolChain } from '../../../src/utils/utils.js';
import { getChain } from '../../registry.js';
import { supportedChainNames } from './supportedChainNames.js'; import { supportedChainNames } from './supportedChainNames.js';
export const environment = 'testnet4'; export const environment = 'testnet4';
const { ethereumMetadatas: defaultEthereumMainnetConfigs } = export const ethereumChainNames = supportedChainNames.filter(
getChainMetadatas(supportedChainNames); isEthereumProtocolChain,
);
export const testnetConfigs: ChainMap<ChainMetadata> = { export const chainMetadataOverrides: ChainMap<Partial<ChainMetadata>> = {
...defaultEthereumMainnetConfigs,
bsctestnet: { bsctestnet: {
...getChain('bsctestnet'),
transactionOverrides: { transactionOverrides: {
gasPrice: 8 * 10 ** 9, // 8 gwei gasPrice: 8 * 10 ** 9, // 8 gwei
}, },
}, },
}; };
export const ethereumChainNames = objKeys(defaultEthereumMainnetConfigs);

@ -1,15 +1,22 @@
import { IRegistry } from '@hyperlane-xyz/registry';
import { RpcConsensusType } from '@hyperlane-xyz/sdk'; import { RpcConsensusType } from '@hyperlane-xyz/sdk';
import { objMerge } from '@hyperlane-xyz/utils';
import { import {
getKeysForRole, getKeysForRole,
getMultiProtocolProvider,
getMultiProviderForRole, getMultiProviderForRole,
} from '../../../scripts/agent-utils.js'; } from '../../../scripts/agent-utils.js';
import { getRegistryForEnvironment } from '../../../src/config/chain.js';
import { EnvironmentConfig } from '../../../src/config/environment.js'; import { EnvironmentConfig } from '../../../src/config/environment.js';
import { Role } from '../../../src/roles.js'; import { Role } from '../../../src/roles.js';
import { Contexts } from '../../contexts.js'; import { Contexts } from '../../contexts.js';
import { agents } from './agent.js'; import { agents } from './agent.js';
import { environment as environmentName, testnetConfigs } from './chains.js'; import {
chainMetadataOverrides,
environment as environmentName,
} from './chains.js';
import { core } from './core.js'; import { core } from './core.js';
import { keyFunderConfig } from './funding.js'; import { keyFunderConfig } from './funding.js';
import { helloWorld } from './helloworld.js'; import { helloWorld } from './helloworld.js';
@ -18,27 +25,39 @@ import { infrastructure } from './infrastructure.js';
import { bridgeAdapterConfigs } from './liquidityLayer.js'; import { bridgeAdapterConfigs } from './liquidityLayer.js';
import { liquidityLayerRelayerConfig } from './middleware.js'; import { liquidityLayerRelayerConfig } from './middleware.js';
import { owners } from './owners.js'; import { owners } from './owners.js';
import { supportedChainNames } from './supportedChainNames.js';
const getRegistry = async (useSecrets = true): Promise<IRegistry> =>
getRegistryForEnvironment(
environmentName,
supportedChainNames,
chainMetadataOverrides,
useSecrets,
);
export const environment: EnvironmentConfig = { export const environment: EnvironmentConfig = {
environment: environmentName, environment: environmentName,
chainMetadataConfigs: testnetConfigs, supportedChainNames,
getMultiProvider: ( getRegistry,
getMultiProtocolProvider: async () =>
getMultiProtocolProvider(await getRegistry()),
getMultiProvider: async (
context: Contexts = Contexts.Hyperlane, context: Contexts = Contexts.Hyperlane,
role: Role = Role.Deployer, role: Role = Role.Deployer,
connectionType?: RpcConsensusType, _connectionType?: RpcConsensusType,
useSecrets?: boolean,
) => ) =>
getMultiProviderForRole( getMultiProviderForRole(
testnetConfigs,
environmentName, environmentName,
await getRegistry(useSecrets),
context, context,
role, role,
undefined, undefined,
connectionType,
), ),
getKeys: ( getKeys: (
context: Contexts = Contexts.Hyperlane, context: Contexts = Contexts.Hyperlane,
role: Role = Role.Deployer, role: Role = Role.Deployer,
) => getKeysForRole(testnetConfigs, environmentName, context, role), ) => getKeysForRole(environmentName, supportedChainNames, context, role),
agents, agents,
core, core,
igp, igp,

@ -1,7 +1,11 @@
import { dirname, join } from 'path'; import { dirname, join } from 'path';
import { fileURLToPath } from 'url'; import { fileURLToPath } from 'url';
import { ChainAddresses } from '@hyperlane-xyz/registry'; import {
ChainAddresses,
MergedRegistry,
PartialRegistry,
} from '@hyperlane-xyz/registry';
import { FileSystemRegistry } from '@hyperlane-xyz/registry/fs'; import { FileSystemRegistry } from '@hyperlane-xyz/registry/fs';
import { import {
ChainMap, ChainMap,
@ -35,10 +39,18 @@ export function setRegistry(reg: FileSystemRegistry) {
registry = reg; registry = reg;
} }
/**
* Gets a FileSystemRegistry whose contents are found at the environment
* variable `REGISTRY_URI`, or `DEFAULT_REGISTRY_URI` if no env var is specified.
* This registry will not have any environment-specific overrides applied,
* and is useful for synchronous registry operations that do not require
* any overrides.
* @returns A FileSystemRegistry.
*/
export function getRegistry(): FileSystemRegistry { export function getRegistry(): FileSystemRegistry {
if (!registry) { if (!registry) {
const registryUri = process.env.REGISTRY_URI || DEFAULT_REGISTRY_URI; const registryUri = process.env.REGISTRY_URI || DEFAULT_REGISTRY_URI;
rootLogger.info('Using registry URI:', registryUri); rootLogger.info({ registryUri }, 'Using registry URI');
registry = new FileSystemRegistry({ registry = new FileSystemRegistry({
uri: registryUri, uri: registryUri,
logger: rootLogger.child({ module: 'infra-registry' }), logger: rootLogger.child({ module: 'infra-registry' }),
@ -111,3 +123,26 @@ export function getMainnetAddresses(): ChainMap<ChainAddresses> {
export function getTestnetAddresses(): ChainMap<ChainAddresses> { export function getTestnetAddresses(): ChainMap<ChainAddresses> {
return getEnvAddresses('testnet4'); return getEnvAddresses('testnet4');
} }
/**
* Gets a registry, applying the provided overrides. The base registry
* that the overrides are applied to is the registry returned by `getRegistry`.
* @param chainMetadataOverrides Chain metadata overrides.
* @param chainAddressesOverrides Chain address overrides.
* @returns A MergedRegistry merging the registry from `getRegistry` and the overrides.
*/
export function getRegistryWithOverrides(
chainMetadataOverrides: ChainMap<Partial<ChainMetadata>> = {},
chainAddressesOverrides: ChainMap<Partial<ChainAddresses>> = {},
): MergedRegistry {
const baseRegistry = getRegistry();
const overrideRegistry = new PartialRegistry({
chainMetadata: chainMetadataOverrides,
chainAddresses: chainAddressesOverrides,
});
return new MergedRegistry({
registries: [baseRegistry, overrideRegistry],
});
}

@ -12,6 +12,7 @@
"@ethersproject/experimental": "^5.7.0", "@ethersproject/experimental": "^5.7.0",
"@ethersproject/hardware-wallets": "^5.7.0", "@ethersproject/hardware-wallets": "^5.7.0",
"@ethersproject/providers": "^5.7.2", "@ethersproject/providers": "^5.7.2",
"@google-cloud/secret-manager": "^5.5.0",
"@hyperlane-xyz/helloworld": "3.13.0", "@hyperlane-xyz/helloworld": "3.13.0",
"@hyperlane-xyz/registry": "1.3.0", "@hyperlane-xyz/registry": "1.3.0",
"@hyperlane-xyz/sdk": "3.13.0", "@hyperlane-xyz/sdk": "3.13.0",

@ -1,12 +1,13 @@
import path, { join } from 'path'; import path, { join } from 'path';
import yargs, { Argv } from 'yargs'; import yargs, { Argv } from 'yargs';
import { ChainAddresses } from '@hyperlane-xyz/registry'; import { ChainAddresses, IRegistry } from '@hyperlane-xyz/registry';
import { import {
ChainMap, ChainMap,
ChainMetadata, ChainMetadata,
ChainName, ChainName,
CoreConfig, CoreConfig,
MultiProtocolProvider,
MultiProvider, MultiProvider,
RpcConsensusType, RpcConsensusType,
collectValidators, collectValidators,
@ -16,6 +17,7 @@ import {
ProtocolType, ProtocolType,
objFilter, objFilter,
objMap, objMap,
objMerge,
promiseObjAll, promiseObjAll,
rootLogger, rootLogger,
symmetricDifference, symmetricDifference,
@ -35,7 +37,10 @@ import { getCurrentKubernetesContext } from '../src/agents/index.js';
import { getCloudAgentKey } from '../src/agents/key-utils.js'; import { getCloudAgentKey } from '../src/agents/key-utils.js';
import { CloudAgentKey } from '../src/agents/keys.js'; import { CloudAgentKey } from '../src/agents/keys.js';
import { RootAgentConfig } from '../src/config/agent/agent.js'; import { RootAgentConfig } from '../src/config/agent/agent.js';
import { fetchProvider } from '../src/config/chain.js'; import {
fetchProvider,
getSecretMetadataOverrides,
} from '../src/config/chain.js';
import { import {
AgentEnvironment, AgentEnvironment,
DeployEnvironment, DeployEnvironment,
@ -47,6 +52,7 @@ import {
assertContext, assertContext,
assertRole, assertRole,
getInfraPath, getInfraPath,
inCIMode,
readJSONAtPath, readJSONAtPath,
writeMergedJSONAtPath, writeMergedJSONAtPath,
} from '../src/utils/utils.js'; } from '../src/utils/utils.js';
@ -283,8 +289,8 @@ export function ensureValidatorConfigConsistency(agentConfig: RootAgentConfig) {
export function getKeyForRole( export function getKeyForRole(
environment: DeployEnvironment, environment: DeployEnvironment,
context: Contexts, context: Contexts,
chain: ChainName,
role: Role, role: Role,
chain?: ChainName,
index?: number, index?: number,
): CloudAgentKey { ): CloudAgentKey {
debugLog(`Getting key for ${role} role`); debugLog(`Getting key for ${role} role`);
@ -292,33 +298,32 @@ export function getKeyForRole(
return getCloudAgentKey(agentConfig, role, chain, index); return getCloudAgentKey(agentConfig, role, chain, index);
} }
export async function getMultiProtocolProvider(
registry: IRegistry,
): Promise<MultiProtocolProvider> {
const chainMetadata = await registry.getMetadata();
return new MultiProtocolProvider(chainMetadata);
}
export async function getMultiProviderForRole( export async function getMultiProviderForRole(
txConfigs: ChainMap<ChainMetadata>,
environment: DeployEnvironment, environment: DeployEnvironment,
registry: IRegistry,
context: Contexts, context: Contexts,
role: Role, role: Role,
index?: number, index?: number,
// TODO: rename to consensusType?
connectionType?: RpcConsensusType,
): Promise<MultiProvider> { ): Promise<MultiProvider> {
const chainMetadata = await registry.getMetadata();
debugLog(`Getting multiprovider for ${role} role`); debugLog(`Getting multiprovider for ${role} role`);
const multiProvider = new MultiProvider(txConfigs); const multiProvider = new MultiProvider(chainMetadata);
if (process.env.CI === 'true') { if (inCIMode()) {
debugLog('Returning multiprovider with default RPCs in CI'); debugLog('Running in CI, returning multiprovider without secret keys');
// Return the multiProvider with default RPCs
return multiProvider; return multiProvider;
} }
await promiseObjAll( await promiseObjAll(
objMap(txConfigs, async (chain, _) => { objMap(chainMetadata, async (chain, _) => {
if (multiProvider.getProtocol(chain) === ProtocolType.Ethereum) { if (multiProvider.getProtocol(chain) === ProtocolType.Ethereum) {
const provider = await fetchProvider( const key = getKeyForRole(environment, context, role, chain, index);
environment, const signer = await key.getSigner();
chain,
connectionType,
);
const key = getKeyForRole(environment, context, chain, role, index);
const signer = await key.getSigner(provider);
multiProvider.setProvider(chain, provider);
multiProvider.setSigner(chain, signer); multiProvider.setSigner(chain, signer);
} }
}), }),
@ -330,23 +335,22 @@ export async function getMultiProviderForRole(
// Note: this will only work for keystores that allow key's to be extracted. // Note: this will only work for keystores that allow key's to be extracted.
// I.e. GCP will work but AWS HSMs will not. // I.e. GCP will work but AWS HSMs will not.
export async function getKeysForRole( export async function getKeysForRole(
txConfigs: ChainMap<ChainMetadata>,
environment: DeployEnvironment, environment: DeployEnvironment,
supportedChainNames: ChainName[],
context: Contexts, context: Contexts,
role: Role, role: Role,
index?: number, index?: number,
): Promise<ChainMap<CloudAgentKey>> { ): Promise<ChainMap<CloudAgentKey>> {
if (process.env.CI === 'true') { if (inCIMode()) {
debugLog('No keys to return in CI'); debugLog('No keys to return in CI');
return {}; return {};
} }
const keys = await promiseObjAll( const keyEntries = supportedChainNames.map((chain) => [
objMap(txConfigs, async (chain, _) => chain,
getKeyForRole(environment, context, chain, role, index), getKeyForRole(environment, context, role, chain, index),
), ]);
); return Object.fromEntries(keyEntries);
return keys;
} }
export function getEnvironmentDirectory(environment: DeployEnvironment) { export function getEnvironmentDirectory(environment: DeployEnvironment) {

@ -6,7 +6,13 @@ async function main() {
const { environment } = await getArgs().argv; const { environment } = await getArgs().argv;
const envConfig = getEnvironmentConfig(environment); const envConfig = getEnvironmentConfig(environment);
let multiProvider = await envConfig.getMultiProvider(); let multiProvider = await envConfig.getMultiProvider(
undefined,
undefined,
undefined,
// Don't use secrets
false,
);
await writeAgentConfig(multiProvider, environment); await writeAgentConfig(multiProvider, environment);
} }

@ -2,24 +2,22 @@ import { ethers } from 'ethers';
import { rootLogger } from '@hyperlane-xyz/utils'; import { rootLogger } from '@hyperlane-xyz/utils';
import { getSecretRpcEndpoint } from '../src/agents/index.js'; import { getSecretRpcEndpoints } from '../src/agents/index.js';
import { getArgs } from './agent-utils.js'; import { getArgs } from './agent-utils.js';
import { getEnvironmentConfig } from './core-utils.js'; import { getEnvironmentConfig } from './core-utils.js';
// TODO remove this script as part of migration to CLI
// It's redundant with metadata-check.ts in the SDK
async function main() { async function main() {
const { environment } = await getArgs().argv; const { environment } = await getArgs().argv;
const config = await getEnvironmentConfig(environment); const config = getEnvironmentConfig(environment);
const multiProvider = await config.getMultiProvider(); const multiProvider = await config.getMultiProvider();
const chains = multiProvider.getKnownChainNames(); const chains = multiProvider.getKnownChainNames();
const providers: [string, ethers.providers.JsonRpcProvider][] = []; const providers: [string, ethers.providers.JsonRpcProvider][] = [];
for (const chain of chains) { for (const chain of chains) {
rootLogger.debug(`Building providers for ${chain}`); rootLogger.debug(`Building providers for ${chain}`);
const rpcData = [ const rpcData = [
...(await getSecretRpcEndpoint(environment, chain, false)), ...(await getSecretRpcEndpoints(environment, chain, false)),
...(await getSecretRpcEndpoint(environment, chain, true)), ...(await getSecretRpcEndpoints(environment, chain, true)),
]; ];
for (const url of rpcData) for (const url of rpcData)
providers.push([chain, new ethers.providers.StaticJsonRpcProvider(url)]); providers.push([chain, new ethers.providers.StaticJsonRpcProvider(url)]);

@ -381,7 +381,7 @@ class ContextFunder {
[Role.Kathy]: '', [Role.Kathy]: '',
}; };
const roleKeysPerChain: ChainMap<Record<FundableRole, BaseAgentKey[]>> = {}; const roleKeysPerChain: ChainMap<Record<FundableRole, BaseAgentKey[]>> = {};
const chains = getEnvironmentConfig(environment).chainMetadataConfigs; const { supportedChainNames } = getEnvironmentConfig(environment);
for (const role of rolesToFund) { for (const role of rolesToFund) {
assertFundableRole(role); // only the relayer and kathy are fundable keys assertFundableRole(role); // only the relayer and kathy are fundable keys
const roleAddress = fetchLocalKeyAddresses(role)[environment][context]; const roleAddress = fetchLocalKeyAddresses(role)[environment][context];
@ -392,7 +392,7 @@ class ContextFunder {
} }
fundableRoleKeys[role] = roleAddress; fundableRoleKeys[role] = roleAddress;
for (const chain of Object.keys(chains)) { for (const chain of supportedChainNames) {
if (!roleKeysPerChain[chain as ChainName]) { if (!roleKeysPerChain[chain as ChainName]) {
roleKeysPerChain[chain as ChainName] = { roleKeysPerChain[chain as ChainName] = {
[Role.Relayer]: [], [Role.Relayer]: [],

@ -20,6 +20,7 @@ import {
ProtocolType, ProtocolType,
ensure0x, ensure0x,
objMap, objMap,
pick,
retryAsync, retryAsync,
rootLogger, rootLogger,
sleep, sleep,
@ -28,7 +29,6 @@ import {
} from '@hyperlane-xyz/utils'; } from '@hyperlane-xyz/utils';
import { Contexts } from '../../config/contexts.js'; import { Contexts } from '../../config/contexts.js';
import { testnetConfigs } from '../../config/environments/testnet4/chains.js';
import { import {
hyperlaneHelloworld, hyperlaneHelloworld,
releaseCandidateHelloworld, releaseCandidateHelloworld,
@ -166,7 +166,6 @@ async function main(): Promise<boolean> {
logger.debug('Starting up', { environment }); logger.debug('Starting up', { environment });
const coreConfig = getEnvironmentConfig(environment); const coreConfig = getEnvironmentConfig(environment);
// const coreConfig = getCoreConfigStub(environment);
const { app, core, igp, multiProvider, keys } = const { app, core, igp, multiProvider, keys } =
await getHelloWorldMultiProtocolApp( await getHelloWorldMultiProtocolApp(
@ -550,7 +549,14 @@ async function updateWalletBalanceMetricFor(
} }
// Get a core config intended for testing Kathy without secret access // Get a core config intended for testing Kathy without secret access
export function getCoreConfigStub(environment: DeployEnvironment) { export async function getCoreConfigStub(environment: DeployEnvironment) {
const environmentConfig = getEnvironmentConfig(environment);
// Don't fetch any secrets.
const registry = await environmentConfig.getRegistry(false);
const testnetConfigs = pick(
await registry.getMetadata(),
environmentConfig.supportedChainNames,
);
const multiProvider = new MultiProvider({ const multiProvider = new MultiProvider({
// Desired chains here. Key must have funds on these chains // Desired chains here. Key must have funds on these chains
...testnetConfigs, ...testnetConfigs,

@ -1,3 +1,5 @@
import { pick } from '@hyperlane-xyz/utils';
import { getArgs } from './agent-utils.js'; import { getArgs } from './agent-utils.js';
import { getEnvironmentConfig } from './core-utils.js'; import { getEnvironmentConfig } from './core-utils.js';
@ -9,7 +11,15 @@ async function main() {
const environmentConfig = getEnvironmentConfig(args.environment); const environmentConfig = getEnvironmentConfig(args.environment);
console.log(JSON.stringify(environmentConfig.chainMetadataConfigs, null, 2)); // Intentionally do not include any secrets in the output
const registry = await environmentConfig.getRegistry(false);
const allMetadata = await registry.getMetadata();
const environmentMetadata = pick(
allMetadata,
environmentConfig.supportedChainNames,
);
console.log(JSON.stringify(environmentMetadata, null, 2));
} }
main().catch((err) => { main().catch((err) => {

@ -1,47 +1,67 @@
import { ethers } from 'ethers'; import { ethers } from 'ethers';
import { MultiProtocolProvider, ProviderType } from '@hyperlane-xyz/sdk'; import {
import { objMap, promiseObjAll } from '@hyperlane-xyz/utils'; ChainMap,
MultiProtocolProvider,
ProviderType,
} from '@hyperlane-xyz/sdk';
import { mainnetConfigs } from '../config/environments/mainnet3/chains.js'; import {
import { getCosmosChainGasPrice } from '../src/config/gas-oracle.js'; GasPriceConfig,
getCosmosChainGasPrice,
} from '../src/config/gas-oracle.js';
import { getEnvironmentConfig } from './core-utils.js';
async function main() { async function main() {
const allMetadatas = mainnetConfigs; const environmentConfig = getEnvironmentConfig('mainnet3');
const mpp = new MultiProtocolProvider(allMetadatas); const mpp = await environmentConfig.getMultiProtocolProvider();
const prices = await promiseObjAll( const prices: ChainMap<GasPriceConfig> = Object.fromEntries(
objMap(allMetadatas, async (chain, metadata) => { await Promise.all(
const provider = mpp.getProvider(chain); environmentConfig.supportedChainNames.map(async (chain) => [
switch (provider.type) { chain,
case ProviderType.EthersV5: { await getGasPrice(mpp, chain),
const gasPrice = await provider.provider.getGasPrice(); ]),
return { ),
amount: ethers.utils.formatUnits(gasPrice, 'gwei'),
decimals: 9,
};
}
case ProviderType.CosmJsWasm: {
const { amount } = await getCosmosChainGasPrice(chain);
return {
amount,
decimals: 1,
};
}
case ProviderType.SolanaWeb3:
// TODO get a reasonable value
return '0.001';
default:
throw new Error(`Unsupported provider type: ${provider.type}`);
}
}),
); );
console.log(JSON.stringify(prices, null, 2)); console.log(JSON.stringify(prices, null, 2));
} }
async function getGasPrice(
mpp: MultiProtocolProvider,
chain: string,
): Promise<GasPriceConfig> {
const provider = mpp.getProvider(chain);
switch (provider.type) {
case ProviderType.EthersV5: {
const gasPrice = await provider.provider.getGasPrice();
return {
amount: ethers.utils.formatUnits(gasPrice, 'gwei'),
decimals: 9,
};
}
case ProviderType.CosmJsWasm: {
const { amount } = await getCosmosChainGasPrice(chain);
return {
amount,
decimals: 1,
};
}
case ProviderType.SolanaWeb3:
// TODO get a reasonable value
return {
amount: '0.001',
decimals: 9,
};
default:
throw new Error(`Unsupported provider type: ${provider.type}`);
}
}
main() main()
.then() .then()
.catch((err) => { .catch((err) => {

@ -1,11 +1,17 @@
import { objMap } from '@hyperlane-xyz/utils'; import { objMap, pick } from '@hyperlane-xyz/utils';
import { mainnetConfigs } from '../config/environments/mainnet3/chains.js'; import { getEnvironmentConfig } from './core-utils.js';
const CURRENCY = 'usd'; const CURRENCY = 'usd';
async function main() { async function main() {
const metadata = mainnetConfigs; const environmentConfig = getEnvironmentConfig('mainnet3');
const registry = await environmentConfig.getRegistry();
const metadata = pick(
await registry.getMetadata(),
environmentConfig.supportedChainNames,
);
const ids = objMap( const ids = objMap(
metadata, metadata,

@ -300,14 +300,14 @@ export async function getSecretAwsCredentials(agentConfig: AgentContextConfig) {
}; };
} }
export async function getSecretRpcEndpoint( export async function getSecretRpcEndpoints(
environment: string, environment: string,
chainName: ChainName, chainName: ChainName,
quorum = false, multipleEndpoints = false,
): Promise<string[]> { ): Promise<string[]> {
const secret = await fetchGCPSecret( const secret = await fetchGCPSecret(
`${environment}-rpc-endpoint${quorum ? 's' : ''}-${chainName}`, `${environment}-rpc-endpoint${multipleEndpoints ? 's' : ''}-${chainName}`,
quorum, multipleEndpoints,
); );
if (typeof secret != 'string' && !Array.isArray(secret)) { if (typeof secret != 'string' && !Array.isArray(secret)) {
throw Error(`Expected secret for ${chainName} rpc endpoint`); throw Error(`Expected secret for ${chainName} rpc endpoint`);

@ -1,16 +1,21 @@
import { SecretManagerServiceClient } from '@google-cloud/secret-manager';
import { providers } from 'ethers'; import { providers } from 'ethers';
import { IRegistry } from '@hyperlane-xyz/registry';
import { import {
ChainMap,
ChainMetadata, ChainMetadata,
ChainName, ChainName,
HyperlaneSmartProvider, HyperlaneSmartProvider,
ProviderRetryOptions, ProviderRetryOptions,
RpcConsensusType, RpcConsensusType,
RpcUrl,
} from '@hyperlane-xyz/sdk'; } from '@hyperlane-xyz/sdk';
import { ProtocolType, objFilter } from '@hyperlane-xyz/utils'; import { ProtocolType, objFilter, objMerge } from '@hyperlane-xyz/utils';
import { getChain } from '../../config/registry.js'; import { getChain, getRegistryWithOverrides } from '../../config/registry.js';
import { getSecretRpcEndpoint } from '../agents/index.js'; import { getSecretRpcEndpoints } from '../agents/index.js';
import { inCIMode } from '../utils/utils.js';
import { DeployEnvironment } from './environment.js'; import { DeployEnvironment } from './environment.js';
@ -20,7 +25,6 @@ export const defaultRetry: ProviderRetryOptions = {
}; };
export async function fetchProvider( export async function fetchProvider(
environment: DeployEnvironment,
chainName: ChainName, chainName: ChainName,
connectionType: RpcConsensusType = RpcConsensusType.Single, connectionType: RpcConsensusType = RpcConsensusType.Single,
): Promise<providers.Provider> { ): Promise<providers.Provider> {
@ -29,10 +33,9 @@ export async function fetchProvider(
throw Error(`Unsupported chain: ${chainName}`); throw Error(`Unsupported chain: ${chainName}`);
} }
const chainId = chainMetadata.chainId; const chainId = chainMetadata.chainId;
const single = connectionType === RpcConsensusType.Single;
let rpcData = chainMetadata.rpcUrls.map((url) => url.http); let rpcData = chainMetadata.rpcUrls.map((url) => url.http);
if (rpcData.length === 0) { if (rpcData.length === 0) {
rpcData = await getSecretRpcEndpoint(environment, chainName, !single); throw Error(`No RPC URLs found for chain: ${chainName}`);
} }
if (connectionType === RpcConsensusType.Single) { if (connectionType === RpcConsensusType.Single) {
@ -73,3 +76,69 @@ export function getChainMetadatas(chains: Array<ChainName>) {
return { ethereumMetadatas, nonEthereumMetadatas }; return { ethereumMetadatas, nonEthereumMetadatas };
} }
/**
* Gets the registry for the given environment, with optional overrides and
* the ability to get overrides from secrets.
* @param deployEnv The deploy environment.
* @param chains The chains to get metadata for.
* @param defaultChainMetadataOverrides The default chain metadata overrides. If
* secret overrides are used, the secret overrides will be merged with these and
* take precedence.
* @param useSecrets Whether to fetch metadata overrides from secrets.
* @returns A registry with overrides for the given environment.
*/
export async function getRegistryForEnvironment(
deployEnv: DeployEnvironment,
chains: ChainName[],
defaultChainMetadataOverrides: ChainMap<Partial<ChainMetadata>> = {},
useSecrets: boolean = true,
): Promise<IRegistry> {
let overrides = defaultChainMetadataOverrides;
if (useSecrets && !inCIMode()) {
overrides = objMerge(
overrides,
await getSecretMetadataOverrides(deployEnv, chains),
);
}
const registry = getRegistryWithOverrides(overrides);
return registry;
}
/**
* Gets chain metadata overrides from GCP secrets.
* @param deployEnv The deploy environment.
* @param chains The chains to get metadata overrides for.
* @returns A partial chain metadata map with the secret overrides.
*/
export async function getSecretMetadataOverrides(
deployEnv: DeployEnvironment,
chains: string[],
): Promise<ChainMap<Partial<ChainMetadata>>> {
const chainMetadataOverrides: ChainMap<Partial<ChainMetadata>> = {};
const secretRpcUrls = await Promise.all(
chains.map(async (chain) => {
const rpcUrls = await getSecretRpcEndpoints(deployEnv, chain, true);
return {
chain,
rpcUrls,
};
}),
);
for (const { chain, rpcUrls } of secretRpcUrls) {
if (rpcUrls.length === 0) {
throw Error(`No secret RPC URLs found for chain: ${chain}`);
}
// Need explicit casting here because Zod expects a non-empty array.
const metadataRpcUrls = rpcUrls.map((rpcUrl: string) => ({
http: rpcUrl,
})) as ChainMetadata['rpcUrls'];
chainMetadataOverrides[chain] = {
rpcUrls: metadataRpcUrls,
};
}
return chainMetadataOverrides;
}

@ -1,3 +1,4 @@
import { IRegistry } from '@hyperlane-xyz/registry';
import { import {
BridgeAdapterConfig, BridgeAdapterConfig,
ChainMap, ChainMap,
@ -5,6 +6,7 @@ import {
ChainName, ChainName,
CoreConfig, CoreConfig,
IgpConfig, IgpConfig,
MultiProtocolProvider,
MultiProvider, MultiProvider,
OwnableConfig, OwnableConfig,
RpcConsensusType, RpcConsensusType,
@ -39,17 +41,21 @@ export const envNameToAgentEnv: Record<DeployEnvironment, AgentEnvironment> = {
export type EnvironmentConfig = { export type EnvironmentConfig = {
environment: DeployEnvironment; environment: DeployEnvironment;
chainMetadataConfigs: ChainMap<ChainMetadata>; supportedChainNames: ChainName[];
// Get the registry with or without environment-specific secrets.
getRegistry: (useSecrets?: boolean) => Promise<IRegistry>;
// Each AgentConfig, keyed by the context // Each AgentConfig, keyed by the context
agents: Partial<Record<Contexts, RootAgentConfig>>; agents: Partial<Record<Contexts, RootAgentConfig>>;
core: ChainMap<CoreConfig>; core: ChainMap<CoreConfig>;
igp: ChainMap<IgpConfig>; igp: ChainMap<IgpConfig>;
owners: ChainMap<OwnableConfig>; owners: ChainMap<OwnableConfig>;
infra: InfrastructureConfig; infra: InfrastructureConfig;
getMultiProtocolProvider: () => Promise<MultiProtocolProvider>;
getMultiProvider: ( getMultiProvider: (
context?: Contexts, context?: Contexts,
role?: Role, role?: Role,
connectionType?: RpcConsensusType, connectionType?: RpcConsensusType,
useSecrets?: boolean,
) => Promise<MultiProvider>; ) => Promise<MultiProvider>;
getKeys: ( getKeys: (
context?: Contexts, context?: Contexts,

@ -1,3 +1,4 @@
import { SecretManagerServiceClient } from '@google-cloud/secret-manager';
import fs from 'fs'; import fs from 'fs';
import { rootLogger } from '@hyperlane-xyz/utils'; import { rootLogger } from '@hyperlane-xyz/utils';
@ -6,6 +7,8 @@ import { rm, writeFile } from 'fs/promises';
import { execCmd, execCmdAndParseJson } from './utils.js'; import { execCmd, execCmdAndParseJson } from './utils.js';
export const GCP_PROJECT_ID = 'abacus-labs-dev';
interface IamCondition { interface IamCondition {
title: string; title: string;
expression: string; expression: string;
@ -32,9 +35,7 @@ export async function fetchGCPSecret(
); );
output = envVarOverride; output = envVarOverride;
} else { } else {
[output] = await execCmd( output = await fetchLatestGCPSecret(secretName);
`gcloud secrets versions access latest --secret ${secretName}`,
);
} }
if (parseJson) { if (parseJson) {
@ -43,6 +44,29 @@ export async function fetchGCPSecret(
return output; return output;
} }
export async function fetchLatestGCPSecret(secretName: string) {
const client = new SecretManagerServiceClient({
projectId: GCP_PROJECT_ID,
});
const [secretVersion] = await client.accessSecretVersion({
name: `projects/${GCP_PROJECT_ID}/secrets/${secretName}/versions/latest`,
});
const secretData = secretVersion.payload?.data;
if (!secretData) {
throw new Error(`Secret ${secretName} missing payload`);
}
// Handle both string and Uint8Array
let dataStr: string;
if (typeof secretData === 'string') {
dataStr = secretData;
} else {
dataStr = new TextDecoder().decode(secretData);
}
return dataStr;
}
// If the environment variable GCP_SECRET_OVERRIDES_ENABLED is `true`, // If the environment variable GCP_SECRET_OVERRIDES_ENABLED is `true`,
// this will attempt to find an environment variable of the form: // this will attempt to find an environment variable of the form:
// `GCP_SECRET_OVERRIDE_${gcpSecretName.replaceAll('-', '_').toUpperCase()}` // `GCP_SECRET_OVERRIDE_${gcpSecretName.replaceAll('-', '_').toUpperCase()}`

@ -269,3 +269,7 @@ export function isEthereumProtocolChain(chainName: ChainName) {
export function getInfraPath() { export function getInfraPath() {
return join(dirname(fileURLToPath(import.meta.url)), '../../'); return join(dirname(fileURLToPath(import.meta.url)), '../../');
} }
export function inCIMode() {
return process.env.CI === 'true';
}

@ -399,6 +399,16 @@ export function buildAgentConfig(
const chainConfigs: ChainMap<AgentChainMetadata> = {}; const chainConfigs: ChainMap<AgentChainMetadata> = {};
for (const chain of [...chains].sort()) { for (const chain of [...chains].sort()) {
const metadata = multiProvider.tryGetChainMetadata(chain); const metadata = multiProvider.tryGetChainMetadata(chain);
if (metadata?.protocol === ProtocolType.Cosmos) {
// Note: the gRPC URL format in the registry lacks a correct http:// or https:// prefix at the moment,
// which is expected by the agents. For now, we intentionally skip this.
delete metadata.grpcUrls;
// The agents expect gasPrice.amount and gasPrice.denom and ignore the transaction overrides.
// To reduce confusion when looking at the config, we remove the transaction overrides.
delete metadata.transactionOverrides;
}
const chainConfig: AgentChainMetadata = { const chainConfig: AgentChainMetadata = {
...metadata, ...metadata,
...addresses[chain], ...addresses[chain],

@ -5608,6 +5608,39 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@google-cloud/secret-manager@npm:^5.5.0":
version: 5.5.0
resolution: "@google-cloud/secret-manager@npm:5.5.0"
dependencies:
google-gax: "npm:^4.0.3"
checksum: 487267dab1e260a0da79012194bb61c85f8b02b642330fdec32cac1fe37900f0fd6709ff4928fe631ab227b0d758bd3e59b1e3dc1d0682de566a64ef4fb42bba
languageName: node
linkType: hard
"@grpc/grpc-js@npm:~1.10.3":
version: 1.10.8
resolution: "@grpc/grpc-js@npm:1.10.8"
dependencies:
"@grpc/proto-loader": "npm:^0.7.13"
"@js-sdsl/ordered-map": "npm:^4.4.2"
checksum: cb7903e93db38a86bd2ddffb84313de78144454ad988801ede90f0c794d6a5f666a1b24f50e950b50d633b4bacc7416c7cabf4a6791b91c4fa89c001122edba8
languageName: node
linkType: hard
"@grpc/proto-loader@npm:^0.7.0, @grpc/proto-loader@npm:^0.7.13":
version: 0.7.13
resolution: "@grpc/proto-loader@npm:0.7.13"
dependencies:
lodash.camelcase: "npm:^4.3.0"
long: "npm:^5.0.0"
protobufjs: "npm:^7.2.5"
yargs: "npm:^17.7.2"
bin:
proto-loader-gen-types: build/bin/proto-loader-gen-types.js
checksum: 7e2d842c2061cbaf6450c71da0077263be3bab165454d5c8a3e1ae4d3c6d2915f02fd27da63ff01f05e127b1221acd40705273f5d29303901e60514e852992f4
languageName: node
linkType: hard
"@headlessui/react@npm:^1.7.17": "@headlessui/react@npm:^1.7.17":
version: 1.7.18 version: 1.7.18
resolution: "@headlessui/react@npm:1.7.18" resolution: "@headlessui/react@npm:1.7.18"
@ -5824,6 +5857,7 @@ __metadata:
"@ethersproject/experimental": "npm:^5.7.0" "@ethersproject/experimental": "npm:^5.7.0"
"@ethersproject/hardware-wallets": "npm:^5.7.0" "@ethersproject/hardware-wallets": "npm:^5.7.0"
"@ethersproject/providers": "npm:^5.7.2" "@ethersproject/providers": "npm:^5.7.2"
"@google-cloud/secret-manager": "npm:^5.5.0"
"@hyperlane-xyz/helloworld": "npm:3.13.0" "@hyperlane-xyz/helloworld": "npm:3.13.0"
"@hyperlane-xyz/registry": "npm:1.3.0" "@hyperlane-xyz/registry": "npm:1.3.0"
"@hyperlane-xyz/sdk": "npm:3.13.0" "@hyperlane-xyz/sdk": "npm:3.13.0"
@ -6501,6 +6535,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@js-sdsl/ordered-map@npm:^4.4.2":
version: 4.4.2
resolution: "@js-sdsl/ordered-map@npm:4.4.2"
checksum: ac64e3f0615ecc015461c9f527f124d2edaa9e68de153c1e270c627e01e83d046522d7e872692fd57a8c514578b539afceff75831c0d8b2a9a7a347fbed35af4
languageName: node
linkType: hard
"@layerzerolabs/lz-evm-messagelib-v2@npm:^2.0.2": "@layerzerolabs/lz-evm-messagelib-v2@npm:^2.0.2":
version: 2.0.6 version: 2.0.6
resolution: "@layerzerolabs/lz-evm-messagelib-v2@npm:2.0.6" resolution: "@layerzerolabs/lz-evm-messagelib-v2@npm:2.0.6"
@ -9439,6 +9480,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@types/caseless@npm:*":
version: 0.12.5
resolution: "@types/caseless@npm:0.12.5"
checksum: f6a3628add76d27005495914c9c3873a93536957edaa5b69c63b46fe10b4649a6fecf16b676c1695f46aab851da47ec6047dcf3570fa8d9b6883492ff6d074e0
languageName: node
linkType: hard
"@types/chai@npm:*, @types/chai@npm:^4.2.21": "@types/chai@npm:*, @types/chai@npm:^4.2.21":
version: 4.3.1 version: 4.3.1
resolution: "@types/chai@npm:4.3.1" resolution: "@types/chai@npm:4.3.1"
@ -9607,7 +9655,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@types/long@npm:^4.0.1": "@types/long@npm:^4.0.0, @types/long@npm:^4.0.1":
version: 4.0.2 version: 4.0.2
resolution: "@types/long@npm:4.0.2" resolution: "@types/long@npm:4.0.2"
checksum: 68afa05fb20949d88345876148a76f6ccff5433310e720db51ac5ca21cb8cc6714286dbe04713840ddbd25a8b56b7a23aa87d08472fabf06463a6f2ed4967707 checksum: 68afa05fb20949d88345876148a76f6ccff5433310e720db51ac5ca21cb8cc6714286dbe04713840ddbd25a8b56b7a23aa87d08472fabf06463a6f2ed4967707
@ -9814,6 +9862,18 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@types/request@npm:^2.48.8":
version: 2.48.12
resolution: "@types/request@npm:2.48.12"
dependencies:
"@types/caseless": "npm:*"
"@types/node": "npm:*"
"@types/tough-cookie": "npm:*"
form-data: "npm:^2.5.0"
checksum: a7b3f9f14cacc18fe235bb8e57eff1232a04bd3fa3dad29371f24a5d96db2cd295a0c8b6b34ed7efa3efbbcff845febb02c9635cd68c54811c947ea66ae22090
languageName: node
linkType: hard
"@types/resolve@npm:^0.0.8": "@types/resolve@npm:^0.0.8":
version: 0.0.8 version: 0.0.8
resolution: "@types/resolve@npm:0.0.8" resolution: "@types/resolve@npm:0.0.8"
@ -9904,6 +9964,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@types/tough-cookie@npm:*":
version: 4.0.5
resolution: "@types/tough-cookie@npm:4.0.5"
checksum: 01fd82efc8202670865928629697b62fe9bf0c0dcbc5b1c115831caeb073a2c0abb871ff393d7df1ae94ea41e256cb87d2a5a91fd03cdb1b0b4384e08d4ee482
languageName: node
linkType: hard
"@types/trusted-types@npm:^2.0.2": "@types/trusted-types@npm:^2.0.2":
version: 2.0.7 version: 2.0.7
resolution: "@types/trusted-types@npm:2.0.7" resolution: "@types/trusted-types@npm:2.0.7"
@ -10902,6 +10969,15 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"agent-base@npm:^7.0.2":
version: 7.1.1
resolution: "agent-base@npm:7.1.1"
dependencies:
debug: "npm:^4.3.4"
checksum: c478fec8f79953f118704d007a38f2a185458853f5c45579b9669372bd0e12602e88dc2ad0233077831504f7cd6fcc8251c383375bba5eaaf563b102938bda26
languageName: node
linkType: hard
"agentkeepalive@npm:^4.2.1": "agentkeepalive@npm:^4.2.1":
version: 4.2.1 version: 4.2.1
resolution: "agentkeepalive@npm:4.2.1" resolution: "agentkeepalive@npm:4.2.1"
@ -11956,6 +12032,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"buffer-equal-constant-time@npm:1.0.1":
version: 1.0.1
resolution: "buffer-equal-constant-time@npm:1.0.1"
checksum: 80bb945f5d782a56f374b292770901065bad21420e34936ecbe949e57724b4a13874f735850dd1cc61f078773c4fb5493a41391e7bda40d1fa388d6bd80daaab
languageName: node
linkType: hard
"buffer-from@npm:^1.0.0": "buffer-from@npm:^1.0.0":
version: 1.1.2 version: 1.1.2
resolution: "buffer-from@npm:1.1.2" resolution: "buffer-from@npm:1.1.2"
@ -13651,6 +13734,18 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"duplexify@npm:^4.0.0":
version: 4.1.3
resolution: "duplexify@npm:4.1.3"
dependencies:
end-of-stream: "npm:^1.4.1"
inherits: "npm:^2.0.3"
readable-stream: "npm:^3.1.1"
stream-shift: "npm:^1.0.2"
checksum: b44b98ba0ffac3a658b4b1bf877219e996db288c5ae6f3dc55ca9b2cbef7df60c10eabfdd947f3d73a623eb9975a74a66d6d61e6f26bff90155315adb362aa77
languageName: node
linkType: hard
"duplexify@npm:^4.1.2": "duplexify@npm:^4.1.2":
version: 4.1.2 version: 4.1.2
resolution: "duplexify@npm:4.1.2" resolution: "duplexify@npm:4.1.2"
@ -13680,6 +13775,15 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"ecdsa-sig-formatter@npm:1.0.11, ecdsa-sig-formatter@npm:^1.0.11":
version: 1.0.11
resolution: "ecdsa-sig-formatter@npm:1.0.11"
dependencies:
safe-buffer: "npm:^5.0.1"
checksum: 878e1aab8a42773320bc04c6de420bee21aebd71810e40b1799880a8a1c4594bcd6adc3d4213a0fb8147d4c3f529d8f9a618d7f59ad5a9a41b142058aceda23f
languageName: node
linkType: hard
"ee-first@npm:1.1.1": "ee-first@npm:1.1.1":
version: 1.1.1 version: 1.1.1
resolution: "ee-first@npm:1.1.1" resolution: "ee-first@npm:1.1.1"
@ -14912,7 +15016,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"extend@npm:~3.0.2": "extend@npm:^3.0.2, extend@npm:~3.0.2":
version: 3.0.2 version: 3.0.2
resolution: "extend@npm:3.0.2" resolution: "extend@npm:3.0.2"
checksum: 59e89e2dc798ec0f54b36d82f32a27d5f6472c53974f61ca098db5d4648430b725387b53449a34df38fd0392045434426b012f302b3cc049a6500ccf82877e4e checksum: 59e89e2dc798ec0f54b36d82f32a27d5f6472c53974f61ca098db5d4648430b725387b53449a34df38fd0392045434426b012f302b3cc049a6500ccf82877e4e
@ -15303,7 +15407,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"form-data@npm:^2.2.0": "form-data@npm:^2.2.0, form-data@npm:^2.5.0":
version: 2.5.1 version: 2.5.1
resolution: "form-data@npm:2.5.1" resolution: "form-data@npm:2.5.1"
dependencies: dependencies:
@ -15666,6 +15770,29 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"gaxios@npm:^6.0.0, gaxios@npm:^6.1.1":
version: 6.6.0
resolution: "gaxios@npm:6.6.0"
dependencies:
extend: "npm:^3.0.2"
https-proxy-agent: "npm:^7.0.1"
is-stream: "npm:^2.0.0"
node-fetch: "npm:^2.6.9"
uuid: "npm:^9.0.1"
checksum: 9f035590374fd168e7bb3ddda369fc8bd487f16a2308fde18284ccc0f685d0af4ac5e3e38d680a8c6342a9000fbf9d77ce691ee110dbed2feebb659e729c640a
languageName: node
linkType: hard
"gcp-metadata@npm:^6.1.0":
version: 6.1.0
resolution: "gcp-metadata@npm:6.1.0"
dependencies:
gaxios: "npm:^6.0.0"
json-bigint: "npm:^1.0.0"
checksum: a0d12a9cb7499fdb9de0fff5406aa220310c1326b80056be8d9b747aae26414f99d14bd795c0ec52ef7d0473eef9d61bb657b8cd3d8186c8a84c4ddbff025fe9
languageName: node
linkType: hard
"gensync@npm:^1.0.0-beta.2": "gensync@npm:^1.0.0-beta.2":
version: 1.0.0-beta.2 version: 1.0.0-beta.2
resolution: "gensync@npm:1.0.0-beta.2" resolution: "gensync@npm:1.0.0-beta.2"
@ -16034,6 +16161,40 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"google-auth-library@npm:^9.3.0":
version: 9.10.0
resolution: "google-auth-library@npm:9.10.0"
dependencies:
base64-js: "npm:^1.3.0"
ecdsa-sig-formatter: "npm:^1.0.11"
gaxios: "npm:^6.1.1"
gcp-metadata: "npm:^6.1.0"
gtoken: "npm:^7.0.0"
jws: "npm:^4.0.0"
checksum: 10d5863493f9426107b0f6c4df244b1413a2cacff9589076f906924336d894fe8bc4153d4a3756cebec8a58784ff1a3900c621924f75f004908611fa46d3caa6
languageName: node
linkType: hard
"google-gax@npm:^4.0.3":
version: 4.3.3
resolution: "google-gax@npm:4.3.3"
dependencies:
"@grpc/grpc-js": "npm:~1.10.3"
"@grpc/proto-loader": "npm:^0.7.0"
"@types/long": "npm:^4.0.0"
abort-controller: "npm:^3.0.0"
duplexify: "npm:^4.0.0"
google-auth-library: "npm:^9.3.0"
node-fetch: "npm:^2.6.1"
object-hash: "npm:^3.0.0"
proto3-json-serializer: "npm:^2.0.0"
protobufjs: "npm:7.2.6"
retry-request: "npm:^7.0.0"
uuid: "npm:^9.0.1"
checksum: 63335724e741737b90689e43f8ea5804d82b8f4eaa013ba07166bf6119ef7474d06682d580d72f6b708d6c55251204b1f05db615c3cd84abf2f8f295c50882ec
languageName: node
linkType: hard
"gopd@npm:^1.0.1": "gopd@npm:^1.0.1":
version: 1.0.1 version: 1.0.1
resolution: "gopd@npm:1.0.1" resolution: "gopd@npm:1.0.1"
@ -16166,6 +16327,16 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"gtoken@npm:^7.0.0":
version: 7.1.0
resolution: "gtoken@npm:7.1.0"
dependencies:
gaxios: "npm:^6.0.0"
jws: "npm:^4.0.0"
checksum: 640392261e55c9242137a81a4af8feb053b57061762cedddcbb6a0d62c2314316161808ac2529eea67d06d69fdc56d82361af50f2d840a04a87ea29e124d7382
languageName: node
linkType: hard
"h3@npm:^1.10.1, h3@npm:^1.8.2": "h3@npm:^1.10.1, h3@npm:^1.8.2":
version: 1.10.2 version: 1.10.2
resolution: "h3@npm:1.10.2" resolution: "h3@npm:1.10.2"
@ -16725,6 +16896,16 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"https-proxy-agent@npm:^7.0.1":
version: 7.0.4
resolution: "https-proxy-agent@npm:7.0.4"
dependencies:
agent-base: "npm:^7.0.2"
debug: "npm:4"
checksum: 405fe582bba461bfe5c7e2f8d752b384036854488b828ae6df6a587c654299cbb2c50df38c4b6ab303502c3c5e029a793fbaac965d1e86ee0be03faceb554d63
languageName: node
linkType: hard
"human-id@npm:^1.0.2": "human-id@npm:^1.0.2":
version: 1.0.2 version: 1.0.2
resolution: "human-id@npm:1.0.2" resolution: "human-id@npm:1.0.2"
@ -18336,6 +18517,27 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"jwa@npm:^2.0.0":
version: 2.0.0
resolution: "jwa@npm:2.0.0"
dependencies:
buffer-equal-constant-time: "npm:1.0.1"
ecdsa-sig-formatter: "npm:1.0.11"
safe-buffer: "npm:^5.0.1"
checksum: ab983f6685d99d13ddfbffef9b1c66309a536362a8412d49ba6e687d834a1240ce39290f30ac7dbe241e0ab6c76fee7ff795776ce534e11d148158c9b7193498
languageName: node
linkType: hard
"jws@npm:^4.0.0":
version: 4.0.0
resolution: "jws@npm:4.0.0"
dependencies:
jwa: "npm:^2.0.0"
safe-buffer: "npm:^5.0.1"
checksum: 1d15f4cdea376c6bd6a81002bd2cb0bf3d51d83da8f0727947b5ba3e10cf366721b8c0d099bf8c1eb99eb036e2c55e5fd5efd378ccff75a2b4e0bd10002348b9
languageName: node
linkType: hard
"keccak@npm:3.0.1": "keccak@npm:3.0.1":
version: 3.0.1 version: 3.0.1
resolution: "keccak@npm:3.0.1" resolution: "keccak@npm:3.0.1"
@ -18918,6 +19120,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"long@npm:^5.0.0":
version: 5.2.3
resolution: "long@npm:5.2.3"
checksum: 9167ec6947a825b827c30da169a7384eec6c0c9ec2f0b9c74da2e93d81159bbe39fb09c3f13dae9721d4b807ccfa09797a7dd1012f5d478e3e33ca3c78b608e6
languageName: node
linkType: hard
"loose-envify@npm:^1.0.0, loose-envify@npm:^1.1.0": "loose-envify@npm:^1.0.0, loose-envify@npm:^1.1.0":
version: 1.4.0 version: 1.4.0
resolution: "loose-envify@npm:1.4.0" resolution: "loose-envify@npm:1.4.0"
@ -20113,7 +20322,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"node-fetch@npm:^2.6.0, node-fetch@npm:^2.6.1, node-fetch@npm:^2.6.12": "node-fetch@npm:^2.6.0, node-fetch@npm:^2.6.1, node-fetch@npm:^2.6.12, node-fetch@npm:^2.6.9":
version: 2.7.0 version: 2.7.0
resolution: "node-fetch@npm:2.7.0" resolution: "node-fetch@npm:2.7.0"
dependencies: dependencies:
@ -20422,6 +20631,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"object-hash@npm:^3.0.0":
version: 3.0.0
resolution: "object-hash@npm:3.0.0"
checksum: f498d456a20512ba7be500cef4cf7b3c183cc72c65372a549c9a0e6dd78ce26f375e9b1315c07592d3fde8f10d5019986eba35970570d477ed9a2a702514432a
languageName: node
linkType: hard
"object-inspect@npm:^1.12.0, object-inspect@npm:^1.12.2, object-inspect@npm:^1.9.0": "object-inspect@npm:^1.12.0, object-inspect@npm:^1.12.2, object-inspect@npm:^1.9.0":
version: 1.12.2 version: 1.12.2
resolution: "object-inspect@npm:1.12.2" resolution: "object-inspect@npm:1.12.2"
@ -21344,6 +21560,35 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"proto3-json-serializer@npm:^2.0.0":
version: 2.0.1
resolution: "proto3-json-serializer@npm:2.0.1"
dependencies:
protobufjs: "npm:^7.2.5"
checksum: dc4319c90e2412b9647f13dd1df2a6338ee3a07e2fd693c5ce4d1728c3730d913ebdb6d656f400ae4214a70bf0791ca0bc04d53b2cbdd75394bf0b175898443b
languageName: node
linkType: hard
"protobufjs@npm:7.2.6":
version: 7.2.6
resolution: "protobufjs@npm:7.2.6"
dependencies:
"@protobufjs/aspromise": "npm:^1.1.2"
"@protobufjs/base64": "npm:^1.1.2"
"@protobufjs/codegen": "npm:^2.0.4"
"@protobufjs/eventemitter": "npm:^1.1.0"
"@protobufjs/fetch": "npm:^1.1.0"
"@protobufjs/float": "npm:^1.0.2"
"@protobufjs/inquire": "npm:^1.1.0"
"@protobufjs/path": "npm:^1.1.2"
"@protobufjs/pool": "npm:^1.1.0"
"@protobufjs/utf8": "npm:^1.1.0"
"@types/node": "npm:>=13.7.0"
long: "npm:^5.0.0"
checksum: 81ab853d28c71998d056d6b34f83c4bc5be40cb0b416585f99ed618aed833d64b2cf89359bad7474d345302f2b5e236c4519165f8483d7ece7fd5b0d9ac13f8b
languageName: node
linkType: hard
"protobufjs@npm:^6.8.8, protobufjs@npm:~6.11.2, protobufjs@npm:~6.11.3": "protobufjs@npm:^6.8.8, protobufjs@npm:~6.11.2, protobufjs@npm:~6.11.3":
version: 6.11.4 version: 6.11.4
resolution: "protobufjs@npm:6.11.4" resolution: "protobufjs@npm:6.11.4"
@ -21368,6 +21613,26 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"protobufjs@npm:^7.2.5":
version: 7.3.0
resolution: "protobufjs@npm:7.3.0"
dependencies:
"@protobufjs/aspromise": "npm:^1.1.2"
"@protobufjs/base64": "npm:^1.1.2"
"@protobufjs/codegen": "npm:^2.0.4"
"@protobufjs/eventemitter": "npm:^1.1.0"
"@protobufjs/fetch": "npm:^1.1.0"
"@protobufjs/float": "npm:^1.0.2"
"@protobufjs/inquire": "npm:^1.1.0"
"@protobufjs/path": "npm:^1.1.2"
"@protobufjs/pool": "npm:^1.1.0"
"@protobufjs/utf8": "npm:^1.1.0"
"@types/node": "npm:>=13.7.0"
long: "npm:^5.0.0"
checksum: aff4aa2a3a2f011accb51e23fcae122acbee35cb761abe51f799675a61ab39ad9a506911f307e0fdb9a1703bed1f522cfbdaafaeefd2b3aaca2ddc18f03029d9
languageName: node
linkType: hard
"proxy-addr@npm:~2.0.7": "proxy-addr@npm:~2.0.7":
version: 2.0.7 version: 2.0.7
resolution: "proxy-addr@npm:2.0.7" resolution: "proxy-addr@npm:2.0.7"
@ -22253,6 +22518,17 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"retry-request@npm:^7.0.0":
version: 7.0.2
resolution: "retry-request@npm:7.0.2"
dependencies:
"@types/request": "npm:^2.48.8"
extend: "npm:^3.0.2"
teeny-request: "npm:^9.0.0"
checksum: 8f4c927d41dd575fc460aad7b762fb0a33542097201c3c1a31529ad17fa8af3ac0d2a45bf4a2024d079913e9c2dd431566070fe33321c667ac87ebb400de5917
languageName: node
linkType: hard
"retry@npm:0.13.1": "retry@npm:0.13.1":
version: 0.13.1 version: 0.13.1
resolution: "retry@npm:0.13.1" resolution: "retry@npm:0.13.1"
@ -23390,7 +23666,16 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"stream-shift@npm:^1.0.0": "stream-events@npm:^1.0.5":
version: 1.0.5
resolution: "stream-events@npm:1.0.5"
dependencies:
stubs: "npm:^3.0.0"
checksum: 969ce82e34bfbef5734629cc06f9d7f3705a9ceb8fcd6a526332f9159f1f8bbfdb1a453f3ced0b728083454f7706adbbe8428bceb788a0287ca48ba2642dc3fc
languageName: node
linkType: hard
"stream-shift@npm:^1.0.0, stream-shift@npm:^1.0.2":
version: 1.0.3 version: 1.0.3
resolution: "stream-shift@npm:1.0.3" resolution: "stream-shift@npm:1.0.3"
checksum: a24c0a3f66a8f9024bd1d579a533a53be283b4475d4e6b4b3211b964031447bdf6532dd1f3c2b0ad66752554391b7c62bd7ca4559193381f766534e723d50242 checksum: a24c0a3f66a8f9024bd1d579a533a53be283b4475d4e6b4b3211b964031447bdf6532dd1f3c2b0ad66752554391b7c62bd7ca4559193381f766534e723d50242
@ -23690,6 +23975,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"stubs@npm:^3.0.0":
version: 3.0.0
resolution: "stubs@npm:3.0.0"
checksum: dec7b82186e3743317616235c59bfb53284acc312cb9f4c3e97e2205c67a5c158b0ca89db5927e52351582e90a2672822eeaec9db396e23e56893d2a8676e024
languageName: node
linkType: hard
"styled-jsx@npm:5.1.1": "styled-jsx@npm:5.1.1":
version: 5.1.1 version: 5.1.1
resolution: "styled-jsx@npm:5.1.1" resolution: "styled-jsx@npm:5.1.1"
@ -23943,6 +24235,19 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"teeny-request@npm:^9.0.0":
version: 9.0.0
resolution: "teeny-request@npm:9.0.0"
dependencies:
http-proxy-agent: "npm:^5.0.0"
https-proxy-agent: "npm:^5.0.0"
node-fetch: "npm:^2.6.9"
stream-events: "npm:^1.0.5"
uuid: "npm:^9.0.0"
checksum: 44daabb6c2e239c3daed0218ebdafb50c7141c16d7257a6cfef786dbff56d7853c2c02c97934f7ed57818ce5861ac16c5f52f3a16fa292bd4caf53483d386443
languageName: node
linkType: hard
"term-size@npm:^2.1.0": "term-size@npm:^2.1.0":
version: 2.2.1 version: 2.2.1
resolution: "term-size@npm:2.2.1" resolution: "term-size@npm:2.2.1"

Loading…
Cancel
Save