Wormhole stub (#789)
* add * add sei to wormhole chains * add wormhole code to the repo * add lib to gitignore * cosmwasm bug fix * add tmp to gitignore * no need for simulation * add wormhole deployment stuff * better comments * resolve build errors * trying a fix * fix * rename compiled code * address feedback * remove gitignore * sei deployment * complete sentences * address comments
This commit is contained in:
parent
f94dceb1bc
commit
079828f8ac
|
@ -14,6 +14,9 @@ export const RECEIVER_CHAINS = {
|
|||
meter: 60010,
|
||||
mantle: 60011,
|
||||
conflux_espace: 60012,
|
||||
sei: 60013,
|
||||
osmosis: 60014,
|
||||
neutron: 60015,
|
||||
};
|
||||
|
||||
// If there is any overlapping value the receiver chain will replace the wormhole
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -10,6 +10,7 @@
|
|||
"price_service/client/js",
|
||||
"target_chains/aptos/sdk/js",
|
||||
"target_chains/cosmwasm/sdk/js",
|
||||
"target_chains/cosmwasm/tools",
|
||||
"target_chains/ethereum/contracts",
|
||||
"target_chains/ethereum/sdk/js",
|
||||
"target_chains/ethereum/sdk/solidity",
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
"typescript": "^4.6.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@injectivelabs/sdk-ts": "^1.0.484",
|
||||
"@injectivelabs/sdk-ts": "1.10.72",
|
||||
"@pythnetwork/price-service-client": "*",
|
||||
"@pythnetwork/pyth-sdk-solidity": "*",
|
||||
"@truffle/hdwallet-provider": "^2.1.3",
|
||||
|
|
|
@ -20,7 +20,7 @@ import {
|
|||
createTransactionFromMsg,
|
||||
} from "@injectivelabs/sdk-ts";
|
||||
|
||||
import { DEFAULT_GAS_PRICE } from "@injectivelabs/utils";
|
||||
const DEFAULT_GAS_PRICE = 500000000;
|
||||
|
||||
type PriceQueryResponse = {
|
||||
price_feed: {
|
||||
|
@ -63,7 +63,7 @@ export class InjectivePriceListener extends ChainPriceListener {
|
|||
Buffer.from(`{"price_feed":{"id":"${priceId}"}}`).toString("base64")
|
||||
);
|
||||
|
||||
const json = Buffer.from(data as string, "base64").toString();
|
||||
const json = Buffer.from(data).toString();
|
||||
priceQueryResponse = JSON.parse(json);
|
||||
} catch (e) {
|
||||
console.error(`Polling on-chain price for ${priceId} failed. Error:`);
|
||||
|
@ -163,8 +163,7 @@ export class InjectivePricePusher implements IPricePusher {
|
|||
const sig = await this.wallet.sign(Buffer.from(signBytes));
|
||||
|
||||
/** Append Signatures */
|
||||
txRaw.setSignaturesList([sig]);
|
||||
|
||||
txRaw.signatures = [sig];
|
||||
const txResponse = await txService.broadcast(txRaw);
|
||||
|
||||
return txResponse;
|
||||
|
@ -215,7 +214,7 @@ export class InjectivePricePusher implements IPricePusher {
|
|||
).toString("base64")
|
||||
);
|
||||
|
||||
const json = Buffer.from(data as string, "base64").toString();
|
||||
const json = Buffer.from(data).toString();
|
||||
updateFeeQueryResponse = JSON.parse(json);
|
||||
} catch (e) {
|
||||
console.error("Error fetching update fee");
|
||||
|
|
|
@ -1,2 +1,5 @@
|
|||
artifacts/
|
||||
lib
|
||||
|
||||
!bin
|
||||
!wormhole-stub/artifacts
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -15,10 +15,10 @@
|
|||
"@cosmjs/cosmwasm-stargate": "^0.29.5",
|
||||
"@cosmjs/encoding": "^0.26.2",
|
||||
"@cosmjs/proto-signing": "^0.30.1",
|
||||
"@injectivelabs/networks": "^1.0.55",
|
||||
"@injectivelabs/sdk-ts": "^1.0.354",
|
||||
"@injectivelabs/utils": "^1.0.47",
|
||||
"@injectivelabs/networks": "1.0.68",
|
||||
"@injectivelabs/sdk-ts": "1.0.354",
|
||||
"@ltd/j-toml": "^1.38.0",
|
||||
"@pythnetwork/xc-governance-sdk": "*",
|
||||
"@terra-money/terra.js": "^3.1.3",
|
||||
"chain-registry": "^1.6.0",
|
||||
"cosmjs-utils": "^0.1.0",
|
||||
|
|
|
@ -0,0 +1,120 @@
|
|||
import { ChainExecutor } from "./chain-executor";
|
||||
import { CosmwasmExecutor } from "./cosmwasm";
|
||||
import { InjectiveExecutor } from "./injective";
|
||||
|
||||
export enum ChainType {
|
||||
INJECTIVE = "injective",
|
||||
COSMWASM = "cosmwasm",
|
||||
}
|
||||
|
||||
// GUIDELINES: to add new chains
|
||||
// ENUM Key should be of the form:
|
||||
// CHAINNAME{_OPTIONAL-IDENTIFIER}
|
||||
// ENUM Value should be of the form:
|
||||
// chainname{_optional-identifier}
|
||||
export enum ChainIdTestnet {
|
||||
INJECTIVE = "injective",
|
||||
OSMOSIS_4 = "osmosis_4",
|
||||
OSMOSIS_5 = "osmosis_5",
|
||||
SEI_ATLANTIC_2 = "sei_atlantic_2",
|
||||
NEUTRON_PION_1 = "neutron_pion_1",
|
||||
}
|
||||
|
||||
export const ChainIdsTestnet = Object.values(ChainIdTestnet);
|
||||
|
||||
// TODO: ADD MAINNET IDs IN FUTURE
|
||||
// export enum ChainIdMainnet {
|
||||
// INJECTIVE = "injective",
|
||||
// }
|
||||
|
||||
export type ChainConfig =
|
||||
| {
|
||||
// usually the chain name
|
||||
// osmosis, injective
|
||||
chainId: ChainIdTestnet;
|
||||
chainType: ChainType.INJECTIVE;
|
||||
|
||||
// endpoints to create executor and querier for a particular chain
|
||||
querierEndpoint: string;
|
||||
executorEndpoint: string;
|
||||
}
|
||||
| {
|
||||
// usually the chain name
|
||||
// osmosis, injective
|
||||
chainId: ChainIdTestnet;
|
||||
chainType: ChainType.COSMWASM;
|
||||
|
||||
// endpoints to create executor and querier for a particular chain
|
||||
querierEndpoint: string;
|
||||
executorEndpoint: string;
|
||||
|
||||
// some extra fields
|
||||
// prefix of the particular cosmwasm chain
|
||||
// eg "osmo"
|
||||
prefix: string;
|
||||
// gas price for that chain
|
||||
// eg "0.025 uosmo"
|
||||
gasPrice: string;
|
||||
};
|
||||
|
||||
export const ChainsConfigTestnet: Record<ChainIdTestnet, ChainConfig> = {
|
||||
[ChainIdTestnet.INJECTIVE]: {
|
||||
chainId: ChainIdTestnet.INJECTIVE,
|
||||
chainType: ChainType.INJECTIVE,
|
||||
querierEndpoint: "https://k8s.testnet.tm.injective.network:443",
|
||||
executorEndpoint: "https://k8s.testnet.chain.grpc-web.injective.network",
|
||||
},
|
||||
[ChainIdTestnet.OSMOSIS_5]: {
|
||||
chainId: ChainIdTestnet.OSMOSIS_5,
|
||||
chainType: ChainType.COSMWASM,
|
||||
executorEndpoint: "https://rpc.osmotest5.osmosis.zone/",
|
||||
querierEndpoint: "https://rpc.osmotest5.osmosis.zone/",
|
||||
prefix: "osmo",
|
||||
gasPrice: "0.025uosmo",
|
||||
},
|
||||
[ChainIdTestnet.OSMOSIS_4]: {
|
||||
chainId: ChainIdTestnet.OSMOSIS_4,
|
||||
chainType: ChainType.COSMWASM,
|
||||
executorEndpoint: "https://rpc-test.osmosis.zone:443",
|
||||
querierEndpoint: "https://rpc-test.osmosis.zone:443",
|
||||
prefix: "osmo",
|
||||
gasPrice: "0.025uosmo",
|
||||
},
|
||||
[ChainIdTestnet.SEI_ATLANTIC_2]: {
|
||||
chainId: ChainIdTestnet.SEI_ATLANTIC_2,
|
||||
chainType: ChainType.COSMWASM,
|
||||
executorEndpoint: "https://rpc.atlantic-2.seinetwork.io/",
|
||||
querierEndpoint: "https://rpc.atlantic-2.seinetwork.io/",
|
||||
prefix: "sei",
|
||||
gasPrice: "0.1usei",
|
||||
},
|
||||
[ChainIdTestnet.NEUTRON_PION_1]: {
|
||||
chainId: ChainIdTestnet.NEUTRON_PION_1,
|
||||
chainType: ChainType.COSMWASM,
|
||||
executorEndpoint: "https://rpc.pion.rs-testnet.polypore.xyz/",
|
||||
querierEndpoint: "https://rpc.pion.rs-testnet.polypore.xyz/",
|
||||
prefix: "neutron",
|
||||
gasPrice: "0.025untrn",
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* This method will return an executor for that corresponding chainType for given chainId.
|
||||
*/
|
||||
export function createExecutorForChain(
|
||||
chainId: ChainIdTestnet,
|
||||
mnemonic: string
|
||||
): ChainExecutor {
|
||||
const chainConfig = ChainsConfigTestnet[chainId];
|
||||
const chainType = chainConfig.chainType;
|
||||
|
||||
if (chainType === ChainType.INJECTIVE) {
|
||||
return new InjectiveExecutor(chainConfig.executorEndpoint, mnemonic);
|
||||
} else
|
||||
return new CosmwasmExecutor(
|
||||
chainConfig.executorEndpoint,
|
||||
mnemonic,
|
||||
chainConfig.prefix,
|
||||
chainConfig.gasPrice
|
||||
);
|
||||
}
|
|
@ -63,16 +63,10 @@ export class CosmwasmExecutor implements ChainExecutor {
|
|||
}
|
||||
);
|
||||
|
||||
const gasUsed = await cosmwasmClient.simulate(
|
||||
address,
|
||||
[encodedMsgObject],
|
||||
"auto"
|
||||
);
|
||||
|
||||
const txResponse = await cosmwasmClient.signAndBroadcast(
|
||||
address,
|
||||
[encodedMsgObject],
|
||||
calculateFee(gasUsed * 1.5, this.gasPrice)
|
||||
1.5
|
||||
);
|
||||
|
||||
if (txResponse.code !== 0) {
|
||||
|
|
|
@ -24,9 +24,10 @@ import {
|
|||
UpdateContractAdminRequest,
|
||||
UpdateContractAdminResponse,
|
||||
} from "./chain-executor";
|
||||
import { DEFAULT_GAS_PRICE } from "@injectivelabs/utils";
|
||||
import assert from "assert";
|
||||
|
||||
const DEFAULT_GAS_PRICE = 500000000;
|
||||
|
||||
export class InjectiveExecutor implements ChainExecutor {
|
||||
private readonly wallet: PrivateKey;
|
||||
private readonly chainId = "injective-888";
|
||||
|
@ -131,6 +132,7 @@ export class InjectiveExecutor implements ChainExecutor {
|
|||
admin: this.getAddress(),
|
||||
codeId,
|
||||
label,
|
||||
// @ts-ignore: bug in the injective's sdk
|
||||
msg: instMsg,
|
||||
});
|
||||
|
||||
|
|
|
@ -35,6 +35,12 @@ export const CONFIG: Config = {
|
|||
name: "localterra",
|
||||
},
|
||||
},
|
||||
[NETWORKS.INJECTIVE_MAINNET]: {
|
||||
type: CONFIG_TYPE.INJECTIVE,
|
||||
host: {
|
||||
network: Network.Mainnet,
|
||||
},
|
||||
},
|
||||
[NETWORKS.INJECTIVE_TESTNET]: {
|
||||
type: CONFIG_TYPE.INJECTIVE,
|
||||
host: {
|
||||
|
|
|
@ -120,6 +120,9 @@ export class OsmosisDeployer implements Deployer {
|
|||
cosmwasm.wasm.v1.MessageComposer.withTypeUrl.instantiateContract({
|
||||
sender: accAddress,
|
||||
admin: accAddress,
|
||||
// FIXME: soon this file will be removed
|
||||
// not spending any time on this bug
|
||||
// @ts-ignore
|
||||
codeId: Long.fromNumber(codeId),
|
||||
label,
|
||||
msg: Buffer.from(JSON.stringify(inst_msg)),
|
||||
|
@ -155,6 +158,7 @@ export class OsmosisDeployer implements Deployer {
|
|||
cosmwasm.wasm.v1.MessageComposer.withTypeUrl.migrateContract({
|
||||
sender: await this.getAccountAddress(),
|
||||
contract,
|
||||
// @ts-ignore
|
||||
codeId: Long.fromNumber(codeId),
|
||||
msg: Buffer.from(
|
||||
JSON.stringify({
|
||||
|
|
|
@ -0,0 +1,175 @@
|
|||
import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
|
||||
import { createInterface } from "readline";
|
||||
import path from "path";
|
||||
|
||||
// This function lets you write a question to the terminal
|
||||
// And returns the response of the user
|
||||
function readLineAsync(msg: string) {
|
||||
const readline = createInterface({
|
||||
input: process.stdin,
|
||||
output: process.stdout,
|
||||
});
|
||||
|
||||
return new Promise((resolve) => {
|
||||
readline.question(msg, (userRes) => {
|
||||
resolve(userRes);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// The stage executor is where the stage functionality is defined
|
||||
// Optionally it can take in a method `getResultOfPastStage` as a parameter
|
||||
// if it wants to access the result of the previous stages
|
||||
|
||||
// Each stage should have exactly one atomic operation (like sending a transaction),
|
||||
// The pipeline doesn't enforce atomicity. So if you have 2 atomic operations in
|
||||
// one stage, then you could end up fulfilling one and failing the other.
|
||||
export type StageExecutor =
|
||||
| ((
|
||||
// get the result of a past stage using it's id
|
||||
// It will return the result for the same step id
|
||||
// It will return undefined if the previous stage data has not been stored locally
|
||||
// or if a future stage data is being asked
|
||||
getResultOfPastStage: <Y>(stageId: string) => Y
|
||||
) => Promise<any>)
|
||||
| (() => Promise<any>);
|
||||
|
||||
export type Stage = {
|
||||
id: string;
|
||||
executor: StageExecutor;
|
||||
};
|
||||
|
||||
type StageResult<T = any> =
|
||||
| {
|
||||
status: "rejected";
|
||||
reason: any;
|
||||
}
|
||||
| {
|
||||
status: "fulfilled";
|
||||
result: T;
|
||||
};
|
||||
|
||||
export class Pipeline {
|
||||
private stages: Stage[] = [];
|
||||
private readonly pipelineStore: PipelineStore;
|
||||
|
||||
constructor(
|
||||
// osmosis_testnet_4
|
||||
private readonly id: string,
|
||||
readonly storageFilePath: string
|
||||
) {
|
||||
this.pipelineStore = new PipelineStore(storageFilePath);
|
||||
}
|
||||
|
||||
addStage(stage: Stage) {
|
||||
this.stages.push(stage);
|
||||
}
|
||||
|
||||
private stageExecutorWrapper(executor: StageExecutor) {
|
||||
// We want to wrap the executor provided by the pipeline consumer
|
||||
// In order to wrap the response of the executor in the StageResult
|
||||
// also in this method we inject the `getResultOfPastStage` to the stage executor
|
||||
return async (): Promise<StageResult> => {
|
||||
// method to inject
|
||||
const getResultOfPastStage = <Y>(stageId: string): Y => {
|
||||
let result = this.pipelineStore.getStageState<StageResult<Y>>(stageId);
|
||||
|
||||
// This if condition will execute only if the stage executor is
|
||||
// trying to reading a stage's state with stage id that doesn't exist
|
||||
// past results will all be fulfilled and the pipeline will make sure of that
|
||||
if (
|
||||
result === undefined ||
|
||||
(result !== undefined && result.status === "rejected")
|
||||
) {
|
||||
throw new Error(
|
||||
`${this.id}: Stage id seems to be invalid: ${stageId}`
|
||||
);
|
||||
}
|
||||
return result.result;
|
||||
};
|
||||
try {
|
||||
// wrapping result
|
||||
const result = await executor(getResultOfPastStage);
|
||||
return {
|
||||
status: "fulfilled",
|
||||
result,
|
||||
};
|
||||
} catch (e) {
|
||||
return {
|
||||
status: "rejected",
|
||||
reason: e,
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private async processStage(stage: Stage): Promise<boolean> {
|
||||
// Here we will check if there is a past result that has been fulfilled
|
||||
// If yes, we are not going to process any further
|
||||
let currentResult = this.pipelineStore.getStageState<StageResult>(stage.id);
|
||||
if (currentResult !== undefined && currentResult.status === "fulfilled")
|
||||
return true;
|
||||
|
||||
// Else we will process the new stage and store the result
|
||||
const newResult = await this.stageExecutorWrapper(stage.executor)();
|
||||
this.pipelineStore.setStageState(stage.id, newResult);
|
||||
|
||||
if (newResult.status === "fulfilled") return true;
|
||||
|
||||
console.log(`${this.id}: Stage with id: ${stage.id} failed.`);
|
||||
console.log(`Please fix the error and re run the pipeline`);
|
||||
return false;
|
||||
}
|
||||
|
||||
async run() {
|
||||
console.log("Running pipeline with id: ", this.id);
|
||||
for (let stage of this.stages) {
|
||||
console.log(`${this.id}: Running stage with id: ${stage.id}`);
|
||||
|
||||
// This method is only going to process stage if all the past ones have been fulfilled
|
||||
let fulfilled = await this.processStage(stage);
|
||||
|
||||
// store the whole processing locally after every stage
|
||||
this.pipelineStore.commit();
|
||||
if (fulfilled === false) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PipelineStore helps in getting and setting the state locally
|
||||
// It manipulates data in-memory and once the consumer has finished manipulating it
|
||||
// They need to commit the data to permanent storage using the commit method
|
||||
class PipelineStore {
|
||||
private readonly store: {
|
||||
[stageId: string]: any;
|
||||
};
|
||||
|
||||
constructor(private readonly filePath: string) {
|
||||
if (!existsSync(this.filePath)) {
|
||||
this.store = {};
|
||||
return;
|
||||
}
|
||||
|
||||
this.store = JSON.parse(readFileSync(this.filePath).toString());
|
||||
}
|
||||
|
||||
// It gets the latest state for the given stage
|
||||
// the state after the last operation
|
||||
// if there is no stage state, in case it was no process it will return undefined.
|
||||
// the caller can provide the T and this method will cast the result into it.
|
||||
getStageState<T = any>(stageId: string): T | undefined {
|
||||
return this.store[stageId];
|
||||
}
|
||||
|
||||
// It sets the latest state for the given step
|
||||
setStageState(stageId: string, state: any) {
|
||||
this.store[stageId] = state;
|
||||
}
|
||||
|
||||
// After all the in memory operations one can commit to the local file
|
||||
// for permanent storage
|
||||
commit() {
|
||||
mkdirSync(path.dirname(this.filePath), { recursive: true });
|
||||
writeFileSync(this.filePath, JSON.stringify(this.store, null, 4));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,150 @@
|
|||
import {
|
||||
ChainIdTestnet,
|
||||
ChainIdsTestnet,
|
||||
createExecutorForChain,
|
||||
} from "./chains-manager/chains";
|
||||
import yargs from "yargs";
|
||||
import { hideBin } from "yargs/helpers";
|
||||
import { readFileSync } from "fs";
|
||||
import {
|
||||
InstantiateContractResponse,
|
||||
StoreCodeResponse,
|
||||
} from "./chains-manager/chain-executor";
|
||||
import { Pipeline } from "./pipeline";
|
||||
import { CHAINS } from "@pythnetwork/xc-governance-sdk";
|
||||
const argv = yargs(hideBin(process.argv))
|
||||
.usage("USAGE: npm run wormhole-stub -- <command>")
|
||||
.option("mnemonic", {
|
||||
type: "string",
|
||||
demandOption: "Please provide the mnemonic",
|
||||
})
|
||||
.option("contract-version", {
|
||||
type: "string",
|
||||
demandOption: `Please input the contract-version of the wormhole contract.
|
||||
There should be a compiled code at the path - "../wormhole-stub/artifacts/wormhole-\${contract-version}.wasm"`,
|
||||
})
|
||||
.option("chain-id", {
|
||||
type: "string",
|
||||
choices: ChainIdsTestnet,
|
||||
})
|
||||
.option("mainnet", {
|
||||
type: "boolean",
|
||||
desc: "Execute this script for mainnet networks. THIS WILL BE ADDED IN FUTURE",
|
||||
})
|
||||
.help()
|
||||
.alias("help", "h")
|
||||
.wrap(yargs.terminalWidth())
|
||||
.parseSync();
|
||||
|
||||
// IMPORTANT: IN ORDER TO RUN THIS SCRIPT FOR CHAINS
|
||||
// WE NEED SOME METADATA
|
||||
// HERE IS WHERE WE WILL BE ADDING THAT
|
||||
|
||||
// The type definition here make sure that the chain is added to xc_governance_sdk_js before this script was executed
|
||||
type WormholeConfig = Record<
|
||||
ChainIdTestnet,
|
||||
{ feeDenom: string; chainId: number }
|
||||
>;
|
||||
const wormholeConfig: WormholeConfig = {
|
||||
[ChainIdTestnet.INJECTIVE]: {
|
||||
feeDenom: "inj",
|
||||
chainId: CHAINS.injective,
|
||||
},
|
||||
[ChainIdTestnet.OSMOSIS_4]: {
|
||||
feeDenom: "uosmo",
|
||||
chainId: CHAINS.osmosis,
|
||||
},
|
||||
[ChainIdTestnet.OSMOSIS_5]: {
|
||||
feeDenom: "uosmo",
|
||||
chainId: CHAINS.osmosis,
|
||||
},
|
||||
[ChainIdTestnet.SEI_ATLANTIC_2]: {
|
||||
feeDenom: "usei",
|
||||
chainId: CHAINS.sei,
|
||||
},
|
||||
[ChainIdTestnet.NEUTRON_PION_1]: {
|
||||
feeDenom: "untrn",
|
||||
chainId: CHAINS.neutron,
|
||||
},
|
||||
};
|
||||
|
||||
async function run() {
|
||||
const STORAGE_DIR = "../wormhole-stub/testnet";
|
||||
let wasmFilePath = `../wormhole-stub/artifacts/wormhole-${argv.contractVersion}.wasm`;
|
||||
|
||||
// get the wormhole code
|
||||
const contractBytes = readFileSync(wasmFilePath);
|
||||
|
||||
let chainIds = argv.chainId === undefined ? ChainIdsTestnet : [argv.chainId];
|
||||
for (let chainId of chainIds) {
|
||||
let pipelineStoreFilePath = `${STORAGE_DIR}/${chainId}-${argv.contractVersion}.json`;
|
||||
const pipeline = new Pipeline(chainId, pipelineStoreFilePath);
|
||||
|
||||
const chainExecutor = createExecutorForChain(chainId, argv.mnemonic);
|
||||
|
||||
// add stages
|
||||
// 1 deploy artifact
|
||||
pipeline.addStage({
|
||||
id: "deploy-wormhole-code",
|
||||
executor: async () => {
|
||||
return chainExecutor.storeCode({
|
||||
contractBytes,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
// 2 instantiate contract
|
||||
pipeline.addStage({
|
||||
id: "instantiate-contract",
|
||||
executor: (getResultOfPastStage) => {
|
||||
const storeCodeRes: StoreCodeResponse = getResultOfPastStage(
|
||||
"deploy-wormhole-code"
|
||||
);
|
||||
|
||||
return chainExecutor.instantiateContract({
|
||||
codeId: storeCodeRes.codeId,
|
||||
instMsg: getWormholeConfig(wormholeConfig[chainId]),
|
||||
label: "wormhole",
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
// 3 set its own admin
|
||||
pipeline.addStage({
|
||||
id: "set-own-admin",
|
||||
executor: (getResultOfPastStage) => {
|
||||
const instantiateContractRes: InstantiateContractResponse =
|
||||
getResultOfPastStage("instantiate-contract");
|
||||
|
||||
return chainExecutor.updateContractAdmin({
|
||||
newAdminAddr: instantiateContractRes.contractAddr,
|
||||
contractAddr: instantiateContractRes.contractAddr,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
await pipeline.run();
|
||||
}
|
||||
}
|
||||
|
||||
function getWormholeConfig({
|
||||
feeDenom,
|
||||
chainId,
|
||||
}: {
|
||||
feeDenom: string;
|
||||
chainId: number;
|
||||
}) {
|
||||
return {
|
||||
chain_id: chainId,
|
||||
fee_denom: feeDenom,
|
||||
gov_chain: 1,
|
||||
gov_address: "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQ=",
|
||||
guardian_set_expirity: 86400,
|
||||
initial_guardian_set: {
|
||||
addresses: [{ bytes: "WMw65cCXshPOPIGXnhuflXB0aqU=" }],
|
||||
expiration_time: 0,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
run();
|
|
@ -24,4 +24,4 @@ WORKDIR /code
|
|||
RUN --mount=type=cache,target=/code/target,id=cosmwasm_wormhole_target --mount=type=cache,target=/usr/local/cargo/registry optimize_workspace.sh
|
||||
|
||||
FROM scratch AS export-stage
|
||||
COPY --from=builder /code/artifacts/wormhole* /
|
||||
COPY --from=builder /code/artifacts/ /
|
||||
|
|
Binary file not shown.
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"deploy-wormhole-code": {
|
||||
"status": "fulfilled",
|
||||
"result": {
|
||||
"txHash": "609E6EFFD1C191FA69157BC124CD15B0448E30A11AA65D36CF8BE66666127828",
|
||||
"codeId": 1116
|
||||
}
|
||||
},
|
||||
"instantiate-contract": {
|
||||
"status": "fulfilled",
|
||||
"result": {
|
||||
"txHash": "6408D6691CF40E3C13062F12FD65E3599722A8FDBD3664852BB44DC739C57B9A",
|
||||
"contractAddr": "inj1ks8v2tvx2vsqxx7sgckl9h7rxga60tuvgezpps"
|
||||
}
|
||||
},
|
||||
"set-own-admin": {
|
||||
"status": "fulfilled",
|
||||
"result": {
|
||||
"txHash": "5B31A48AEF4250FAA09117EF63E49E81B6EFBFAC1B1C6AEFF80265434A70DD7D"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"deploy-wormhole-code": {
|
||||
"status": "fulfilled",
|
||||
"result": {
|
||||
"codeId": 244,
|
||||
"txHash": "C8F04CFACC75C28862F3E2A6D08F5F9B869268F09B9D792EBD6C4EC8BC8F36DE"
|
||||
}
|
||||
},
|
||||
"instantiate-contract": {
|
||||
"status": "fulfilled",
|
||||
"result": {
|
||||
"contractAddr": "neutron17xlvf3f82tklvzpveam56n96520pdrxfgpralyhf3nq7f33uvgzqrgegc7",
|
||||
"txHash": "8456CC89F7253998E0A22AD5F037574682315F332C661AC357AF927FDFF489B0"
|
||||
}
|
||||
},
|
||||
"set-own-admin": {
|
||||
"status": "fulfilled",
|
||||
"result": {
|
||||
"txHash": "B9188160725B5282D11DB83F1AC28F88879A4C03AF7B6F178EA44BD07BB76805"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"deploy-wormhole-code": {
|
||||
"status": "fulfilled",
|
||||
"result": {
|
||||
"codeId": 6949,
|
||||
"txHash": "504970A0B21933FCE9BA22E2819AEEC643E7DBFA230C7BEA2E8A068522605E65"
|
||||
}
|
||||
},
|
||||
"instantiate-contract": {
|
||||
"status": "fulfilled",
|
||||
"result": {
|
||||
"contractAddr": "osmo18njur8dzzq6lm5dd6n2td94jgmnywt0j9es2ymxpa0zyy7jrwwuq4v8arc",
|
||||
"txHash": "E8B11F851BF79448129D1F75D67B9020A794E9DA9686B56EDC458FFC338D69B1"
|
||||
}
|
||||
},
|
||||
"set-own-admin": {
|
||||
"status": "fulfilled",
|
||||
"result": {
|
||||
"txHash": "CACD7F3608E915AC629B399C63EE2C595583AE76418949847B43795208F656EE"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"deploy-wormhole-code": {
|
||||
"status": "fulfilled",
|
||||
"result": {
|
||||
"codeId": 58,
|
||||
"txHash": "48375A885AE7047D38C4001C4F16F8852E4971F7E761108075AC4BD447A05AFB"
|
||||
}
|
||||
},
|
||||
"instantiate-contract": {
|
||||
"status": "fulfilled",
|
||||
"result": {
|
||||
"contractAddr": "osmo1224ksv5ckfcuz2geeqfpdu2u3uf706y5fx8frtgz6egmgy0hkxxqtgad95",
|
||||
"txHash": "B5A7FDC5220C05D446BBB9207F0DDA8C8C7FEB1DBF11127993D014C20FAF0CFA"
|
||||
}
|
||||
},
|
||||
"set-own-admin": {
|
||||
"status": "fulfilled",
|
||||
"result": {
|
||||
"txHash": "E4CA160348165532DBE7B43C116A801E78FE77122928DB9F9D4DB41514F53F53"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"deploy-wormhole-code": {
|
||||
"status": "fulfilled",
|
||||
"result": {
|
||||
"codeId": 369,
|
||||
"txHash": "240C71EE74A1C676A054FD6F6E81CC46701103EF8CAB3A431ACFC18042B0AC09"
|
||||
}
|
||||
},
|
||||
"instantiate-contract": {
|
||||
"status": "fulfilled",
|
||||
"result": {
|
||||
"contractAddr": "sei1tu7w5lxsckpa4ahd4umra0k02zyd7eq79j7zxk8e3ds8evlejywqrtsl6a",
|
||||
"txHash": "72FA96116275D66D8CF83BCD955E837FDB9CBA085CF0D57EC6FA30C20F106E0B"
|
||||
}
|
||||
},
|
||||
"set-own-admin": {
|
||||
"status": "fulfilled",
|
||||
"result": {
|
||||
"txHash": "3BFF9026BCAF0B08C1A6FDE3F26D051860D21CCCC1DF28D9A09D0C9F570815A0"
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue