2022-03-28 20:39:08 -07:00
|
|
|
import {
|
|
|
|
ChainId,
|
|
|
|
CHAIN_ID_SOLANA,
|
2022-08-11 14:47:50 -07:00
|
|
|
isTerraChain,
|
2022-03-28 20:39:08 -07:00
|
|
|
nativeToHexString,
|
|
|
|
} from "@certusone/wormhole-sdk";
|
|
|
|
import { getLogger } from "./helpers/logHelper";
|
|
|
|
|
|
|
|
export type SupportedToken = {
|
|
|
|
chainId: ChainId;
|
|
|
|
address: string;
|
|
|
|
};
|
|
|
|
|
|
|
|
export type CommonEnvironment = {
|
|
|
|
logLevel: string;
|
|
|
|
promPort: number;
|
|
|
|
readinessPort?: number;
|
|
|
|
logDir?: string;
|
|
|
|
redisHost: string;
|
|
|
|
redisPort: number;
|
|
|
|
};
|
|
|
|
|
|
|
|
let loggingEnv: CommonEnvironment | undefined = undefined;
|
|
|
|
|
|
|
|
export const getCommonEnvironment: () => CommonEnvironment = () => {
|
|
|
|
if (loggingEnv) {
|
|
|
|
return loggingEnv;
|
|
|
|
} else {
|
|
|
|
const env = createCommonEnvironment();
|
|
|
|
loggingEnv = env;
|
|
|
|
return loggingEnv;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
function createCommonEnvironment(): CommonEnvironment {
|
|
|
|
let logLevel;
|
|
|
|
let promPort;
|
|
|
|
let readinessPort;
|
|
|
|
let logDir;
|
|
|
|
let redisHost;
|
|
|
|
let redisPort;
|
|
|
|
|
|
|
|
if (!process.env.LOG_LEVEL) {
|
|
|
|
throw new Error("Missing required environment variable: LOG_LEVEL");
|
|
|
|
} else {
|
|
|
|
logLevel = process.env.LOG_LEVEL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!process.env.LOG_DIR) {
|
|
|
|
//Not mandatory
|
|
|
|
} else {
|
|
|
|
logDir = process.env.LOG_DIR;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!process.env.PROM_PORT) {
|
|
|
|
throw new Error("Missing required environment variable: PROM_PORT");
|
|
|
|
} else {
|
|
|
|
promPort = parseInt(process.env.PROM_PORT);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!process.env.READINESS_PORT) {
|
|
|
|
//do nothing
|
|
|
|
} else {
|
|
|
|
readinessPort = parseInt(process.env.READINESS_PORT);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!process.env.REDIS_HOST) {
|
|
|
|
throw new Error("Missing required environment variable: REDIS_HOST");
|
|
|
|
} else {
|
|
|
|
redisHost = process.env.REDIS_HOST;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!process.env.REDIS_PORT) {
|
|
|
|
throw new Error("Missing required environment variable: REDIS_PORT");
|
|
|
|
} else {
|
|
|
|
redisPort = parseInt(process.env.REDIS_PORT);
|
|
|
|
}
|
|
|
|
|
|
|
|
return { logLevel, promPort, readinessPort, logDir, redisHost, redisPort };
|
|
|
|
}
|
|
|
|
|
|
|
|
export type RelayerEnvironment = {
|
|
|
|
supportedChains: ChainConfigInfo[];
|
|
|
|
redisHost: string;
|
|
|
|
redisPort: number;
|
|
|
|
clearRedisOnInit: boolean;
|
|
|
|
demoteWorkingOnInit: boolean;
|
|
|
|
supportedTokens: { chainId: ChainId; address: string }[];
|
|
|
|
};
|
|
|
|
|
|
|
|
export type ChainConfigInfo = {
|
|
|
|
chainId: ChainId;
|
|
|
|
chainName: string;
|
|
|
|
nativeCurrencySymbol: string;
|
|
|
|
nodeUrl: string;
|
|
|
|
tokenBridgeAddress: string;
|
|
|
|
walletPrivateKey?: string[];
|
|
|
|
solanaPrivateKey?: Uint8Array[];
|
|
|
|
bridgeAddress?: string;
|
|
|
|
terraName?: string;
|
|
|
|
terraChainId?: string;
|
|
|
|
terraCoin?: string;
|
|
|
|
terraGasPriceUrl?: string;
|
|
|
|
wrappedAsset?: string | null;
|
2022-08-05 07:20:36 -07:00
|
|
|
isTerraClassic?: boolean;
|
2022-03-28 20:39:08 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
export type ListenerEnvironment = {
|
|
|
|
spyServiceHost: string;
|
|
|
|
spyServiceFilters: { chainId: ChainId; emitterAddress: string }[];
|
|
|
|
restPort: number;
|
|
|
|
numSpyWorkers: number;
|
|
|
|
supportedTokens: { chainId: ChainId; address: string }[];
|
|
|
|
};
|
|
|
|
|
|
|
|
let listenerEnv: ListenerEnvironment | undefined = undefined;
|
|
|
|
|
|
|
|
export const getListenerEnvironment: () => ListenerEnvironment = () => {
|
|
|
|
if (listenerEnv) {
|
|
|
|
return listenerEnv;
|
|
|
|
} else {
|
|
|
|
const env = createListenerEnvironment();
|
|
|
|
listenerEnv = env;
|
|
|
|
return listenerEnv;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
const createListenerEnvironment: () => ListenerEnvironment = () => {
|
|
|
|
let spyServiceHost: string;
|
|
|
|
let spyServiceFilters: { chainId: ChainId; emitterAddress: string }[] = [];
|
|
|
|
let restPort: number;
|
|
|
|
let numSpyWorkers: number;
|
|
|
|
let supportedTokens: { chainId: ChainId; address: string }[] = [];
|
|
|
|
const logger = getLogger();
|
|
|
|
|
|
|
|
if (!process.env.SPY_SERVICE_HOST) {
|
|
|
|
throw new Error("Missing required environment variable: SPY_SERVICE_HOST");
|
|
|
|
} else {
|
|
|
|
spyServiceHost = process.env.SPY_SERVICE_HOST;
|
|
|
|
}
|
|
|
|
|
|
|
|
logger.info("Getting SPY_SERVICE_FILTERS...");
|
|
|
|
if (!process.env.SPY_SERVICE_FILTERS) {
|
|
|
|
throw new Error(
|
|
|
|
"Missing required environment variable: SPY_SERVICE_FILTERS"
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
const array = JSON.parse(process.env.SPY_SERVICE_FILTERS);
|
|
|
|
// if (!array.foreach) {
|
|
|
|
if (!array || !Array.isArray(array)) {
|
|
|
|
throw new Error("Spy service filters is not an array.");
|
|
|
|
} else {
|
|
|
|
array.forEach((filter: any) => {
|
|
|
|
if (filter.chainId && filter.emitterAddress) {
|
|
|
|
logger.info(
|
|
|
|
"nativeToHexString: " +
|
|
|
|
nativeToHexString(filter.emitterAddress, filter.chainId)
|
|
|
|
);
|
|
|
|
spyServiceFilters.push({
|
|
|
|
chainId: filter.chainId as ChainId,
|
|
|
|
emitterAddress: filter.emitterAddress,
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
throw new Error("Invalid filter record. " + filter.toString());
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
logger.info("Getting REST_PORT...");
|
|
|
|
if (!process.env.REST_PORT) {
|
|
|
|
throw new Error("Missing required environment variable: REST_PORT");
|
|
|
|
} else {
|
|
|
|
restPort = parseInt(process.env.REST_PORT);
|
|
|
|
}
|
|
|
|
|
|
|
|
logger.info("Getting SPY_NUM_WORKERS...");
|
|
|
|
if (!process.env.SPY_NUM_WORKERS) {
|
|
|
|
throw new Error("Missing required environment variable: SPY_NUM_WORKERS");
|
|
|
|
} else {
|
|
|
|
numSpyWorkers = parseInt(process.env.SPY_NUM_WORKERS);
|
|
|
|
}
|
|
|
|
|
|
|
|
logger.info("Getting SUPPORTED_TOKENS...");
|
|
|
|
if (!process.env.SUPPORTED_TOKENS) {
|
|
|
|
throw new Error("Missing required environment variable: SUPPORTED_TOKENS");
|
|
|
|
} else {
|
|
|
|
// const array = JSON.parse(process.env.SUPPORTED_TOKENS);
|
|
|
|
const array = eval(process.env.SUPPORTED_TOKENS);
|
|
|
|
if (!array || !Array.isArray(array)) {
|
|
|
|
throw new Error("SUPPORTED_TOKENS is not an array.");
|
|
|
|
} else {
|
|
|
|
array.forEach((token: any) => {
|
|
|
|
if (token.chainId && token.address) {
|
|
|
|
supportedTokens.push({
|
|
|
|
chainId: token.chainId,
|
|
|
|
address: token.address,
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
throw new Error("Invalid token record. " + token.toString());
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-05 07:20:36 -07:00
|
|
|
logger.info("Setting the listener backend...");
|
|
|
|
|
2022-03-28 20:39:08 -07:00
|
|
|
return {
|
|
|
|
spyServiceHost,
|
|
|
|
spyServiceFilters,
|
|
|
|
restPort,
|
|
|
|
numSpyWorkers,
|
|
|
|
supportedTokens,
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
let relayerEnv: RelayerEnvironment | undefined = undefined;
|
|
|
|
|
|
|
|
export const getRelayerEnvironment: () => RelayerEnvironment = () => {
|
|
|
|
if (relayerEnv) {
|
|
|
|
return relayerEnv;
|
|
|
|
} else {
|
|
|
|
const env = createRelayerEnvironment();
|
|
|
|
relayerEnv = env;
|
|
|
|
return relayerEnv;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
const createRelayerEnvironment: () => RelayerEnvironment = () => {
|
|
|
|
let supportedChains: ChainConfigInfo[] = [];
|
|
|
|
let redisHost: string;
|
|
|
|
let redisPort: number;
|
|
|
|
let clearRedisOnInit: boolean;
|
|
|
|
let demoteWorkingOnInit: boolean;
|
|
|
|
let supportedTokens: { chainId: ChainId; address: string }[] = [];
|
2022-08-05 07:20:36 -07:00
|
|
|
const logger = getLogger();
|
2022-03-28 20:39:08 -07:00
|
|
|
|
|
|
|
if (!process.env.REDIS_HOST) {
|
|
|
|
throw new Error("Missing required environment variable: REDIS_HOST");
|
|
|
|
} else {
|
|
|
|
redisHost = process.env.REDIS_HOST;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!process.env.REDIS_PORT) {
|
|
|
|
throw new Error("Missing required environment variable: REDIS_PORT");
|
|
|
|
} else {
|
|
|
|
redisPort = parseInt(process.env.REDIS_PORT);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (process.env.CLEAR_REDIS_ON_INIT === undefined) {
|
|
|
|
throw new Error(
|
|
|
|
"Missing required environment variable: CLEAR_REDIS_ON_INIT"
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
if (process.env.CLEAR_REDIS_ON_INIT.toLowerCase() === "true") {
|
|
|
|
clearRedisOnInit = true;
|
|
|
|
} else {
|
|
|
|
clearRedisOnInit = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (process.env.DEMOTE_WORKING_ON_INIT === undefined) {
|
|
|
|
throw new Error(
|
|
|
|
"Missing required environment variable: DEMOTE_WORKING_ON_INIT"
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
if (process.env.DEMOTE_WORKING_ON_INIT.toLowerCase() === "true") {
|
|
|
|
demoteWorkingOnInit = true;
|
|
|
|
} else {
|
|
|
|
demoteWorkingOnInit = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
supportedChains = loadChainConfig();
|
|
|
|
|
|
|
|
if (!process.env.SUPPORTED_TOKENS) {
|
|
|
|
throw new Error("Missing required environment variable: SUPPORTED_TOKENS");
|
|
|
|
} else {
|
|
|
|
// const array = JSON.parse(process.env.SUPPORTED_TOKENS);
|
|
|
|
const array = eval(process.env.SUPPORTED_TOKENS);
|
|
|
|
if (!array || !Array.isArray(array)) {
|
|
|
|
throw new Error("SUPPORTED_TOKENS is not an array.");
|
|
|
|
} else {
|
|
|
|
array.forEach((token: any) => {
|
|
|
|
if (token.chainId && token.address) {
|
|
|
|
supportedTokens.push({
|
|
|
|
chainId: token.chainId,
|
|
|
|
address: token.address,
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
throw new Error("Invalid token record. " + token.toString());
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-05 07:20:36 -07:00
|
|
|
logger.info("Setting the relayer backend...");
|
|
|
|
|
2022-03-28 20:39:08 -07:00
|
|
|
return {
|
|
|
|
supportedChains,
|
|
|
|
redisHost,
|
|
|
|
redisPort,
|
|
|
|
clearRedisOnInit,
|
|
|
|
demoteWorkingOnInit,
|
|
|
|
supportedTokens,
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
//Polygon is not supported on local Tilt network atm.
|
|
|
|
export function loadChainConfig(): ChainConfigInfo[] {
|
|
|
|
if (!process.env.SUPPORTED_CHAINS) {
|
|
|
|
throw new Error("Missing required environment variable: SUPPORTED_CHAINS");
|
|
|
|
}
|
|
|
|
if (!process.env.PRIVATE_KEYS) {
|
|
|
|
throw new Error("Missing required environment variable: PRIVATE_KEYS");
|
|
|
|
}
|
|
|
|
|
|
|
|
const unformattedChains = JSON.parse(process.env.SUPPORTED_CHAINS);
|
|
|
|
const unformattedPrivateKeys = JSON.parse(process.env.PRIVATE_KEYS);
|
|
|
|
const supportedChains: ChainConfigInfo[] = [];
|
|
|
|
|
|
|
|
if (!unformattedChains.forEach) {
|
|
|
|
throw new Error("SUPPORTED_CHAINS arg was not an array.");
|
|
|
|
}
|
|
|
|
if (!unformattedPrivateKeys.forEach) {
|
|
|
|
throw new Error("PRIVATE_KEYS arg was not an array.");
|
|
|
|
}
|
|
|
|
|
|
|
|
unformattedChains.forEach((element: any) => {
|
|
|
|
if (!element.chainId) {
|
|
|
|
throw new Error("Invalid chain config: " + element);
|
|
|
|
}
|
|
|
|
|
|
|
|
const privateKeyObj = unformattedPrivateKeys.find(
|
|
|
|
(x: any) => x.chainId === element.chainId
|
|
|
|
);
|
|
|
|
if (!privateKeyObj) {
|
|
|
|
throw new Error(
|
|
|
|
"Failed to find private key object for configured chain ID: " +
|
|
|
|
element.chainId
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (element.chainId === CHAIN_ID_SOLANA) {
|
|
|
|
supportedChains.push(
|
|
|
|
createSolanaChainConfig(element, privateKeyObj.privateKeys)
|
|
|
|
);
|
2022-08-11 14:47:50 -07:00
|
|
|
} else if (isTerraChain(element.chainId)) {
|
2022-03-28 20:39:08 -07:00
|
|
|
supportedChains.push(
|
|
|
|
createTerraChainConfig(element, privateKeyObj.privateKeys)
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
supportedChains.push(
|
|
|
|
createEvmChainConfig(element, privateKeyObj.privateKeys)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
return supportedChains;
|
|
|
|
}
|
|
|
|
|
|
|
|
function createSolanaChainConfig(
|
|
|
|
config: any,
|
|
|
|
privateKeys: any[]
|
|
|
|
): ChainConfigInfo {
|
|
|
|
let chainId: ChainId;
|
|
|
|
let chainName: string;
|
|
|
|
let nativeCurrencySymbol: string;
|
|
|
|
let nodeUrl: string;
|
|
|
|
let tokenBridgeAddress: string;
|
|
|
|
let solanaPrivateKey: Uint8Array[] = [];
|
|
|
|
let bridgeAddress: string;
|
|
|
|
let wrappedAsset: string | null;
|
|
|
|
|
|
|
|
if (!config.chainId) {
|
|
|
|
throw new Error("Missing required field in chain config: chainId");
|
|
|
|
}
|
|
|
|
if (!config.chainName) {
|
|
|
|
throw new Error("Missing required field in chain config: chainName");
|
|
|
|
}
|
|
|
|
if (!config.nativeCurrencySymbol) {
|
|
|
|
throw new Error(
|
|
|
|
"Missing required field in chain config: nativeCurrencySymbol"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
if (!config.nodeUrl) {
|
|
|
|
throw new Error("Missing required field in chain config: nodeUrl");
|
|
|
|
}
|
|
|
|
if (!config.tokenBridgeAddress) {
|
|
|
|
throw new Error(
|
|
|
|
"Missing required field in chain config: tokenBridgeAddress"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
if (!(privateKeys && privateKeys.length && privateKeys.forEach)) {
|
|
|
|
throw new Error(
|
|
|
|
"Ill formatted object received as private keys for Solana."
|
|
|
|
);
|
|
|
|
}
|
|
|
|
if (!config.bridgeAddress) {
|
|
|
|
throw new Error("Missing required field in chain config: bridgeAddress");
|
|
|
|
}
|
|
|
|
if (!config.wrappedAsset) {
|
|
|
|
throw new Error("Missing required field in chain config: wrappedAsset");
|
|
|
|
}
|
|
|
|
|
|
|
|
chainId = config.chainId;
|
|
|
|
chainName = config.chainName;
|
|
|
|
nativeCurrencySymbol = config.nativeCurrencySymbol;
|
|
|
|
nodeUrl = config.nodeUrl;
|
|
|
|
tokenBridgeAddress = config.tokenBridgeAddress;
|
|
|
|
bridgeAddress = config.bridgeAddress;
|
|
|
|
wrappedAsset = config.wrappedAsset;
|
|
|
|
|
|
|
|
privateKeys.forEach((item: any) => {
|
|
|
|
try {
|
|
|
|
const uint = Uint8Array.from(item);
|
|
|
|
solanaPrivateKey.push(uint);
|
|
|
|
} catch (e) {
|
|
|
|
throw new Error(
|
|
|
|
"Failed to coerce Solana private keys into a uint array. ENV JSON is possibly incorrect."
|
|
|
|
);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
return {
|
|
|
|
chainId,
|
|
|
|
chainName,
|
|
|
|
nativeCurrencySymbol,
|
|
|
|
nodeUrl,
|
|
|
|
tokenBridgeAddress,
|
|
|
|
bridgeAddress,
|
|
|
|
solanaPrivateKey,
|
|
|
|
wrappedAsset,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
function createTerraChainConfig(
|
|
|
|
config: any,
|
|
|
|
privateKeys: any[]
|
|
|
|
): ChainConfigInfo {
|
|
|
|
let chainId: ChainId;
|
|
|
|
let chainName: string;
|
|
|
|
let nativeCurrencySymbol: string;
|
|
|
|
let nodeUrl: string;
|
|
|
|
let tokenBridgeAddress: string;
|
|
|
|
let walletPrivateKey: string[];
|
|
|
|
let terraName: string;
|
|
|
|
let terraChainId: string;
|
|
|
|
let terraCoin: string;
|
|
|
|
let terraGasPriceUrl: string;
|
2022-08-05 07:20:36 -07:00
|
|
|
let isTerraClassic = false;
|
2022-03-28 20:39:08 -07:00
|
|
|
|
|
|
|
if (!config.chainId) {
|
|
|
|
throw new Error("Missing required field in chain config: chainId");
|
|
|
|
}
|
|
|
|
if (!config.chainName) {
|
|
|
|
throw new Error("Missing required field in chain config: chainName");
|
|
|
|
}
|
|
|
|
if (!config.nativeCurrencySymbol) {
|
|
|
|
throw new Error(
|
|
|
|
"Missing required field in chain config: nativeCurrencySymbol"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
if (!config.nodeUrl) {
|
|
|
|
throw new Error("Missing required field in chain config: nodeUrl");
|
|
|
|
}
|
|
|
|
if (!config.tokenBridgeAddress) {
|
|
|
|
throw new Error(
|
|
|
|
"Missing required field in chain config: tokenBridgeAddress"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
if (!(privateKeys && privateKeys.length && privateKeys.forEach)) {
|
|
|
|
throw new Error("Private keys for Terra are length zero or not an array.");
|
|
|
|
}
|
|
|
|
if (!config.terraName) {
|
|
|
|
throw new Error("Missing required field in chain config: terraName");
|
|
|
|
}
|
|
|
|
if (!config.terraChainId) {
|
|
|
|
throw new Error("Missing required field in chain config: terraChainId");
|
|
|
|
}
|
|
|
|
if (!config.terraCoin) {
|
|
|
|
throw new Error("Missing required field in chain config: terraCoin");
|
|
|
|
}
|
|
|
|
if (!config.terraGasPriceUrl) {
|
|
|
|
throw new Error("Missing required field in chain config: terraGasPriceUrl");
|
|
|
|
}
|
|
|
|
|
|
|
|
chainId = config.chainId;
|
|
|
|
chainName = config.chainName;
|
|
|
|
nativeCurrencySymbol = config.nativeCurrencySymbol;
|
|
|
|
nodeUrl = config.nodeUrl;
|
|
|
|
tokenBridgeAddress = config.tokenBridgeAddress;
|
|
|
|
walletPrivateKey = privateKeys;
|
|
|
|
terraName = config.terraName;
|
|
|
|
terraChainId = config.terraChainId;
|
|
|
|
terraCoin = config.terraCoin;
|
|
|
|
terraGasPriceUrl = config.terraGasPriceUrl;
|
2022-08-05 07:20:36 -07:00
|
|
|
isTerraClassic = config.isTerraClassic || false;
|
2022-03-28 20:39:08 -07:00
|
|
|
|
|
|
|
return {
|
|
|
|
chainId,
|
|
|
|
chainName,
|
|
|
|
nativeCurrencySymbol,
|
|
|
|
nodeUrl,
|
|
|
|
tokenBridgeAddress,
|
|
|
|
walletPrivateKey,
|
|
|
|
terraName,
|
|
|
|
terraChainId,
|
|
|
|
terraCoin,
|
|
|
|
terraGasPriceUrl,
|
2022-08-05 07:20:36 -07:00
|
|
|
isTerraClassic,
|
2022-03-28 20:39:08 -07:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
function createEvmChainConfig(
|
|
|
|
config: any,
|
|
|
|
privateKeys: any[]
|
|
|
|
): ChainConfigInfo {
|
|
|
|
let chainId: ChainId;
|
|
|
|
let chainName: string;
|
|
|
|
let nativeCurrencySymbol: string;
|
|
|
|
let nodeUrl: string;
|
|
|
|
let tokenBridgeAddress: string;
|
|
|
|
let walletPrivateKey: string[];
|
|
|
|
let wrappedAsset: string;
|
|
|
|
|
|
|
|
if (!config.chainId) {
|
|
|
|
throw new Error("Missing required field in chain config: chainId");
|
|
|
|
}
|
|
|
|
if (!config.chainName) {
|
|
|
|
throw new Error("Missing required field in chain config: chainName");
|
|
|
|
}
|
|
|
|
if (!config.nativeCurrencySymbol) {
|
|
|
|
throw new Error(
|
|
|
|
"Missing required field in chain config: nativeCurrencySymbol"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
if (!config.nodeUrl) {
|
|
|
|
throw new Error("Missing required field in chain config: nodeUrl");
|
|
|
|
}
|
|
|
|
if (!config.tokenBridgeAddress) {
|
|
|
|
throw new Error(
|
|
|
|
"Missing required field in chain config: tokenBridgeAddress"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
if (!(privateKeys && privateKeys.length && privateKeys.forEach)) {
|
|
|
|
throw new Error(
|
|
|
|
`Private keys for chain id ${config.chainId} are length zero or not an array.`
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!config.wrappedAsset) {
|
|
|
|
throw new Error("Missing required field in chain config: wrappedAsset");
|
|
|
|
}
|
|
|
|
chainId = config.chainId;
|
|
|
|
chainName = config.chainName;
|
|
|
|
nativeCurrencySymbol = config.nativeCurrencySymbol;
|
|
|
|
nodeUrl = config.nodeUrl;
|
|
|
|
tokenBridgeAddress = config.tokenBridgeAddress;
|
|
|
|
walletPrivateKey = privateKeys;
|
|
|
|
wrappedAsset = config.wrappedAsset;
|
|
|
|
|
|
|
|
return {
|
|
|
|
chainId,
|
|
|
|
chainName,
|
|
|
|
nativeCurrencySymbol,
|
|
|
|
nodeUrl,
|
|
|
|
tokenBridgeAddress,
|
|
|
|
walletPrivateKey,
|
|
|
|
wrappedAsset,
|
|
|
|
};
|
|
|
|
}
|