182 lines
5.8 KiB
TypeScript
182 lines
5.8 KiB
TypeScript
import {
|
|
AptosChain,
|
|
Chain,
|
|
CosmWasmChain,
|
|
EvmChain,
|
|
GlobalChain,
|
|
SuiChain,
|
|
} from "./chains";
|
|
import {
|
|
AptosPriceFeedContract,
|
|
CosmWasmPriceFeedContract,
|
|
EvmEntropyContract,
|
|
EvmPriceFeedContract,
|
|
SuiPriceFeedContract,
|
|
} from "./contracts";
|
|
import { Token } from "./token";
|
|
import { PriceFeedContract, Storable } from "./base";
|
|
import { parse, stringify } from "yaml";
|
|
import { readdirSync, readFileSync, statSync, writeFileSync } from "fs";
|
|
import { Vault } from "./governance";
|
|
|
|
export class Store {
|
|
public chains: Record<string, Chain> = { global: new GlobalChain() };
|
|
public contracts: Record<string, PriceFeedContract> = {};
|
|
public entropy_contracts: Record<string, EvmEntropyContract> = {};
|
|
public tokens: Record<string, Token> = {};
|
|
public vaults: Record<string, Vault> = {};
|
|
|
|
constructor(public path: string) {
|
|
this.loadAllChains();
|
|
this.loadAllContracts();
|
|
this.loadAllTokens();
|
|
this.loadAllVaults();
|
|
}
|
|
|
|
static serialize(obj: Storable) {
|
|
return stringify([obj.toJson()]);
|
|
}
|
|
|
|
getYamlFiles(path: string) {
|
|
const walk = function (dir: string) {
|
|
let results: string[] = [];
|
|
const list = readdirSync(dir);
|
|
list.forEach(function (file) {
|
|
file = dir + "/" + file;
|
|
const stat = statSync(file);
|
|
if (stat && stat.isDirectory()) {
|
|
// Recurse into a subdirectory
|
|
results = results.concat(walk(file));
|
|
} else {
|
|
// Is a file
|
|
results.push(file);
|
|
}
|
|
});
|
|
return results;
|
|
};
|
|
return walk(path).filter((file) => file.endsWith(".yaml"));
|
|
}
|
|
|
|
loadAllChains() {
|
|
const allChainClasses = {
|
|
[CosmWasmChain.type]: CosmWasmChain,
|
|
[SuiChain.type]: SuiChain,
|
|
[EvmChain.type]: EvmChain,
|
|
[AptosChain.type]: AptosChain,
|
|
};
|
|
|
|
this.getYamlFiles(`${this.path}/chains/`).forEach((yamlFile) => {
|
|
const parsedArray = parse(readFileSync(yamlFile, "utf-8"));
|
|
for (const parsed of parsedArray) {
|
|
if (allChainClasses[parsed.type] === undefined) return;
|
|
const chain = allChainClasses[parsed.type].fromJson(parsed);
|
|
if (this.chains[chain.getId()])
|
|
throw new Error(`Multiple chains with id ${chain.getId()} found`);
|
|
this.chains[chain.getId()] = chain;
|
|
}
|
|
});
|
|
}
|
|
|
|
saveAllContracts() {
|
|
const contractsByType: Record<string, Storable[]> = {};
|
|
const contracts: Storable[] = Object.values(this.contracts);
|
|
contracts.push(...Object.values(this.entropy_contracts));
|
|
for (const contract of contracts) {
|
|
if (!contractsByType[contract.getType()]) {
|
|
contractsByType[contract.getType()] = [];
|
|
}
|
|
contractsByType[contract.getType()].push(contract);
|
|
}
|
|
for (const [type, contracts] of Object.entries(contractsByType)) {
|
|
writeFileSync(
|
|
`${this.path}/contracts/${type}s.yaml`,
|
|
stringify(contracts.map((c) => c.toJson()))
|
|
);
|
|
}
|
|
}
|
|
|
|
saveAllChains() {
|
|
const chainsByType: Record<string, Chain[]> = {};
|
|
for (const chain of Object.values(this.chains)) {
|
|
if (!chainsByType[chain.getType()]) {
|
|
chainsByType[chain.getType()] = [];
|
|
}
|
|
chainsByType[chain.getType()].push(chain);
|
|
}
|
|
for (const [type, chains] of Object.entries(chainsByType)) {
|
|
writeFileSync(
|
|
`${this.path}/chains/${type}s.yaml`,
|
|
stringify(chains.map((c) => c.toJson()))
|
|
);
|
|
}
|
|
}
|
|
|
|
loadAllContracts() {
|
|
const allContractClasses = {
|
|
[CosmWasmPriceFeedContract.type]: CosmWasmPriceFeedContract,
|
|
[SuiPriceFeedContract.type]: SuiPriceFeedContract,
|
|
[EvmPriceFeedContract.type]: EvmPriceFeedContract,
|
|
[AptosPriceFeedContract.type]: AptosPriceFeedContract,
|
|
[EvmEntropyContract.type]: EvmEntropyContract,
|
|
};
|
|
this.getYamlFiles(`${this.path}/contracts/`).forEach((yamlFile) => {
|
|
const parsedArray = parse(readFileSync(yamlFile, "utf-8"));
|
|
for (const parsed of parsedArray) {
|
|
if (allContractClasses[parsed.type] === undefined) return;
|
|
if (!this.chains[parsed.chain])
|
|
throw new Error(`Chain ${parsed.chain} not found`);
|
|
const chain = this.chains[parsed.chain];
|
|
const chainContract = allContractClasses[parsed.type].fromJson(
|
|
chain,
|
|
parsed
|
|
);
|
|
if (
|
|
this.contracts[chainContract.getId()] ||
|
|
this.entropy_contracts[chainContract.getId()]
|
|
)
|
|
throw new Error(
|
|
`Multiple contracts with id ${chainContract.getId()} found`
|
|
);
|
|
if (chainContract instanceof EvmEntropyContract) {
|
|
this.entropy_contracts[chainContract.getId()] = chainContract;
|
|
} else {
|
|
this.contracts[chainContract.getId()] = chainContract;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
loadAllTokens() {
|
|
this.getYamlFiles(`${this.path}/tokens/`).forEach((yamlFile) => {
|
|
const parsedArray = parse(readFileSync(yamlFile, "utf-8"));
|
|
for (const parsed of parsedArray) {
|
|
if (parsed.type !== Token.type) return;
|
|
|
|
const token = Token.fromJson(parsed);
|
|
if (this.tokens[token.getId()])
|
|
throw new Error(`Multiple tokens with id ${token.getId()} found`);
|
|
this.tokens[token.getId()] = token;
|
|
}
|
|
});
|
|
}
|
|
|
|
loadAllVaults() {
|
|
this.getYamlFiles(`${this.path}/vaults/`).forEach((yamlFile) => {
|
|
const parsedArray = parse(readFileSync(yamlFile, "utf-8"));
|
|
for (const parsed of parsedArray) {
|
|
if (parsed.type !== Vault.type) return;
|
|
|
|
const vault = Vault.fromJson(parsed);
|
|
if (this.vaults[vault.getId()])
|
|
throw new Error(`Multiple vaults with id ${vault.getId()} found`);
|
|
this.vaults[vault.getId()] = vault;
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* DefaultStore loads all the contracts and chains from the store directory and provides a single point of access to them.
|
|
*/
|
|
export const DefaultStore = new Store(`${__dirname}/../store`);
|