[contract-manager] Cosmwasm contracts (#986)

* Add stable testnet contracts

* Fix bug in creating InjectiveExecutor from mnemonic

* Import only from root library

* Code verification on proposals for cosmwasm

* Minimal script to upload wasm codes

* Use the netwrok parameter for InjectiveChain executor instead of endpoints
This commit is contained in:
Mohammad Amin Khashkhashi Moghaddam 2023-07-27 14:36:16 +02:00 committed by GitHub
parent c1517349f8
commit 92b295bd7a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 303 additions and 57 deletions

View File

@ -18,6 +18,7 @@
"@certusone/wormhole-sdk": "^0.9.8", "@certusone/wormhole-sdk": "^0.9.8",
"@pythnetwork/cosmwasm-deploy-tools": "*", "@pythnetwork/cosmwasm-deploy-tools": "*",
"@pythnetwork/price-service-client": "*", "@pythnetwork/price-service-client": "*",
"@injectivelabs/networks": "1.0.68",
"bs58": "^5.0.0", "bs58": "^5.0.0",
"ts-node": "^10.9.1", "ts-node": "^10.9.1",
"typescript": "^4.9.3" "typescript": "^4.9.3"

View File

@ -1,8 +1,10 @@
import yargs from "yargs"; import yargs from "yargs";
import { hideBin } from "yargs/helpers"; import { hideBin } from "yargs/helpers";
import { EvmChain } from "../src/chains"; import { CosmWasmChain, EvmChain } from "../src/chains";
import { createHash } from "crypto";
import { DefaultStore } from "../src/store"; import { DefaultStore } from "../src/store";
import { import {
CosmosUpgradeContract,
EvmUpgradeContract, EvmUpgradeContract,
getProposalInstructions, getProposalInstructions,
MultisigParser, MultisigParser,
@ -72,6 +74,28 @@ async function main() {
} }
} }
} }
if (instruction.governanceAction instanceof CosmosUpgradeContract) {
console.log(
`Verifying Cosmos Upgrade Contract on ${instruction.governanceAction.targetChainId}`
);
for (const chain of Object.values(DefaultStore.chains)) {
if (
chain instanceof CosmWasmChain &&
chain.isMainnet() === (cluster === "mainnet-beta") &&
chain.wormholeChainName ===
instruction.governanceAction.targetChainId
) {
const codeId = instruction.governanceAction.codeId;
const code = await chain.getCode(Number(codeId));
// this should be the same checksums.txt in our release file
console.log(
`Code Id:${codeId} digest:${createHash("sha256")
.update(code)
.digest("hex")}`
);
}
}
}
} }
} }
} }

View File

@ -7,7 +7,7 @@ import { DefaultStore } from "../src/store";
const parser = yargs(hideBin(process.argv)) const parser = yargs(hideBin(process.argv))
.scriptName("deploy_cosmwasm.ts") .scriptName("deploy_cosmwasm.ts")
.usage( .usage(
"Usage: $0 --code <path/to/artifact.wasm> --mnemonic <mnemonic> --chain <chain>" "Usage: $0 --code <path/to/artifact.wasm> --private-key <private-key> --chain <chain>"
) )
.options({ .options({
code: { code: {
@ -15,10 +15,10 @@ const parser = yargs(hideBin(process.argv))
demandOption: true, demandOption: true,
desc: "Path to the artifact .wasm file", desc: "Path to the artifact .wasm file",
}, },
mnemonic: { "private-key": {
type: "string", type: "string",
demandOption: true, demandOption: true,
desc: "Mnemonic to use for the deployment", desc: "Private key to use for the deployment",
}, },
chain: { chain: {
type: "string", type: "string",
@ -39,7 +39,7 @@ async function main() {
await CosmWasmContract.deploy( await CosmWasmContract.deploy(
DefaultStore.chains[argv.chain] as CosmWasmChain, DefaultStore.chains[argv.chain] as CosmWasmChain,
wormholeContract, wormholeContract,
argv.mnemonic, argv["private-key"],
code code
) )
); );

View File

@ -0,0 +1,41 @@
import yargs from "yargs";
import { hideBin } from "yargs/helpers";
import { CosmWasmChain } from "../src/chains";
import { CosmWasmContract } from "../src/contracts/cosmwasm";
import { DefaultStore } from "../src/store";
const parser = yargs(hideBin(process.argv))
.scriptName("upload_cosmwasm.ts")
.usage(
"Usage: $0 --code <path/to/artifact.wasm> --private-key <private-key> --chain <chain>"
)
.options({
code: {
type: "string",
demandOption: true,
desc: "Path to the artifact .wasm file",
},
"private-key": {
type: "string",
demandOption: true,
desc: "Private key to use for the deployment",
},
chain: {
type: "string",
demandOption: true,
desc: "Chain to upload the code on. Can be one of the chains available in the store",
},
});
async function main() {
const argv = await parser.argv;
const { code } = argv;
const { codeId } = await CosmWasmContract.storeCode(
DefaultStore.chains[argv.chain] as CosmWasmChain,
argv["private-key"],
code
);
console.log(`Successfully uploaded code with id ${codeId}`);
}
main();

View File

@ -13,6 +13,7 @@ import {
} from "xc_admin_common"; } from "xc_admin_common";
import { AptosClient } from "aptos"; import { AptosClient } from "aptos";
import Web3 from "web3"; import Web3 from "web3";
import { CosmwasmQuerier } from "@pythnetwork/cosmwasm-deploy-tools";
export abstract class Chain extends Storable { export abstract class Chain extends Storable {
public wormholeChainName: ChainName; public wormholeChainName: ChainName;
@ -145,6 +146,11 @@ export class CosmWasmChain extends Chain {
return CosmWasmChain.type; return CosmWasmChain.type;
} }
async getCode(codeId: number): Promise<Buffer> {
const chainQuerier = await CosmwasmQuerier.connect(this.querierEndpoint);
return await chainQuerier.getCode({ codeId });
}
generateGovernanceUpgradePayload(codeId: bigint): Buffer { generateGovernanceUpgradePayload(codeId: bigint): Buffer {
return new CosmosUpgradeContract(this.wormholeChainName, codeId).encode(); return new CosmosUpgradeContract(this.wormholeChainName, codeId).encode();
} }

View File

@ -1,20 +1,18 @@
import { Chain, CosmWasmChain } from "../chains"; import { Chain, CosmWasmChain } from "../chains";
import { readFileSync } from "fs"; import { readFileSync } from "fs";
import { getPythConfig } from "@pythnetwork/cosmwasm-deploy-tools/lib/configs";
import { CHAINS, DataSource } from "xc_admin_common";
import { DeploymentType } from "@pythnetwork/cosmwasm-deploy-tools/lib/helper";
import { import {
ContractInfoResponse,
CosmwasmExecutor, CosmwasmExecutor,
CosmwasmQuerier,
DeploymentType,
getPythConfig,
InjectiveExecutor, InjectiveExecutor,
Price, Price,
PythWrapperExecutor, PythWrapperExecutor,
PythWrapperQuerier, PythWrapperQuerier,
} from "@pythnetwork/cosmwasm-deploy-tools/lib"; } from "@pythnetwork/cosmwasm-deploy-tools";
import { import { CHAINS, DataSource } from "xc_admin_common";
ContractInfoResponse, import { Network } from "@injectivelabs/networks";
CosmwasmQuerier,
} from "@pythnetwork/cosmwasm-deploy-tools/lib/chains-manager/chain-querier";
import { PriceServiceConnection } from "@pythnetwork/price-service-client";
import { CosmWasmClient } from "@cosmjs/cosmwasm-stargate"; import { CosmWasmClient } from "@cosmjs/cosmwasm-stargate";
import { Contract } from "../base"; import { Contract } from "../base";
@ -92,7 +90,7 @@ export class CosmWasmContract extends Contract {
} }
/** /**
* Stores the wasm code on the specified chain using the provided mnemonic as the signer * Stores the wasm code on the specified chain using the provided private key as the signer
* You can find the wasm artifacts from the repo releases * You can find the wasm artifacts from the repo releases
* @param chain chain to store the code on * @param chain chain to store the code on
* @param privateKey private key to use for signing the transaction in hex format without 0x prefix * @param privateKey private key to use for signing the transaction in hex format without 0x prefix
@ -158,7 +156,10 @@ export class CosmWasmContract extends Contract {
private static async getExecutor(chain: CosmWasmChain, privateKey: string) { private static async getExecutor(chain: CosmWasmChain, privateKey: string) {
if (chain.getId().indexOf("injective") > -1) { if (chain.getId().indexOf("injective") > -1) {
return new InjectiveExecutor(chain.executorEndpoint, privateKey); return InjectiveExecutor.fromPrivateKey(
chain.isMainnet() ? Network.Mainnet : Network.Testnet,
privateKey
);
} }
return new CosmwasmExecutor( return new CosmwasmExecutor(
chain.executorEndpoint, chain.executorEndpoint,

View File

@ -5,12 +5,12 @@ const service = tsNode.create({ ...repl.evalAwarePartialHost });
repl.setService(service); repl.setService(service);
repl.start(); repl.start();
repl.evalCode( repl.evalCode(
"import { loadHotWallet, Vault } from './src/entities';" + "import { loadHotWallet, Vault } from './src/governance';" +
"import { SuiChain, CosmWasmChain, AptosChain, EvmChain } from './src/chains';" + "import { SuiChain, CosmWasmChain, AptosChain, EvmChain } from './src/chains';" +
"import { SuiContract } from './src/sui';" + "import { SuiContract } from './src/contracts/sui';" +
"import { CosmWasmContract } from './src/cosmwasm';" + "import { CosmWasmContract } from './src/contracts/cosmwasm';" +
"import { EvmContract } from './src/evm';" + "import { EvmContract } from './src/contracts/evm';" +
"import { AptosContract } from './src/aptos';" + "import { AptosContract } from './src/contracts/aptos';" +
"import { DefaultStore } from './src/store';" + "import { DefaultStore } from './src/store';" +
"DefaultStore" "DefaultStore"
); );

View File

@ -1,5 +1,3 @@
querierEndpoint: https://injective-rpc.quickapi.com:443
executorEndpoint: https://k8s.global.mainnet.chain.grpc-web.injective.network:443
id: injective id: injective
wormholeChainName: injective wormholeChainName: injective
mainnet: true mainnet: true

View File

@ -1,5 +1,3 @@
querierEndpoint: https://k8s.testnet.tm.injective.network:443
executorEndpoint: https://k8s.testnet.chain.grpc-web.injective.network
id: injective_testnet id: injective_testnet
wormholeChainName: injective_testnet wormholeChainName: injective_testnet
mainnet: false mainnet: false

View File

@ -0,0 +1,3 @@
chain: injective_testnet
address: inj18hckkzqf47mdhd734g6papk6wj20y24rm43sk9
type: CosmWasmContract

View File

@ -0,0 +1,3 @@
chain: juno_testnet
address: juno1eacsrua27njc35pxz37y97gmcjs899t59f8pf0rkejjyvtmhws5q6lxsdd
type: CosmWasmContract

View File

@ -0,0 +1,3 @@
chain: neutron_testnet_pion_1
address: neutron15ldst8t80982akgr8w8ekcytejzkmfpgdkeq4xgtge48qs7435jqp87u3t
type: CosmWasmContract

View File

@ -0,0 +1,3 @@
chain: osmosis_testnet_5
address: osmo1hpdzqku55lmfmptpyj6wdlugqs5etr6teqf7r4yqjjrxjznjhtuqqu5kdh
type: CosmWasmContract

View File

@ -0,0 +1,3 @@
chain: sei_testnet_atlantic_2
address: sei1w2rxq6eckak47s25crxlhmq96fzjwdtjgdwavn56ggc0qvxvw7rqczxyfy
type: CosmWasmContract

168
package-lock.json generated
View File

@ -38,6 +38,7 @@
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"@certusone/wormhole-sdk": "^0.9.8", "@certusone/wormhole-sdk": "^0.9.8",
"@injectivelabs/networks": "1.0.68",
"@mysten/sui.js": "^0.37.1", "@mysten/sui.js": "^0.37.1",
"@pythnetwork/cosmwasm-deploy-tools": "*", "@pythnetwork/cosmwasm-deploy-tools": "*",
"@pythnetwork/price-service-client": "*", "@pythnetwork/price-service-client": "*",
@ -79,6 +80,20 @@
"@injectivelabs/utils": "1.10.12" "@injectivelabs/utils": "1.10.12"
} }
}, },
"contract_manager/node_modules/@certusone/wormhole-sdk/node_modules/@injectivelabs/networks": {
"version": "1.10.12",
"resolved": "https://registry.npmjs.org/@injectivelabs/networks/-/networks-1.10.12.tgz",
"integrity": "sha512-tTHyLls1Nik5QTs/S03qqG2y/ITvNwI8CJOQbMmmsr1CL2CdjJBtzRYn9Dyx2p8XgzRFf9hmlybpe20tq9O3SA==",
"hasInstallScript": true,
"optional": true,
"dependencies": {
"@injectivelabs/exceptions": "^1.10.12",
"@injectivelabs/ts-types": "^1.10.12",
"@injectivelabs/utils": "^1.10.12",
"link-module-alias": "^1.2.0",
"shx": "^0.3.2"
}
},
"contract_manager/node_modules/@certusone/wormhole-sdk/node_modules/@mysten/sui.js": { "contract_manager/node_modules/@certusone/wormhole-sdk/node_modules/@mysten/sui.js": {
"version": "0.32.2", "version": "0.32.2",
"resolved": "https://registry.npmjs.org/@mysten/sui.js/-/sui.js-0.32.2.tgz", "resolved": "https://registry.npmjs.org/@mysten/sui.js/-/sui.js-0.32.2.tgz",
@ -271,6 +286,19 @@
"integrity": "sha512-KvvX58MGMWh7xA+N+deCfunkA/ZNDvFLw4YbOmX3f/XBIkqrVY7qlotfy2aNb1kgp6h4B6Yc8YawJPDTfvWX7g==", "integrity": "sha512-KvvX58MGMWh7xA+N+deCfunkA/ZNDvFLw4YbOmX3f/XBIkqrVY7qlotfy2aNb1kgp6h4B6Yc8YawJPDTfvWX7g==",
"optional": true "optional": true
}, },
"contract_manager/node_modules/@injectivelabs/networks": {
"version": "1.0.68",
"resolved": "https://registry.npmjs.org/@injectivelabs/networks/-/networks-1.0.68.tgz",
"integrity": "sha512-CcWcLaRX1lJQyYs97+PPDmMaEFcXQgt/WjQ5raamcbQugJwMa/byC4eS18DZ0tIIZ24CoD+79zbgHDzfoe6/qg==",
"hasInstallScript": true,
"dependencies": {
"@injectivelabs/exceptions": "^1.0.42",
"@injectivelabs/ts-types": "^1.0.27",
"@injectivelabs/utils": "^1.0.59",
"link-module-alias": "^1.2.0",
"shx": "^0.3.2"
}
},
"contract_manager/node_modules/@injectivelabs/sdk-ts": { "contract_manager/node_modules/@injectivelabs/sdk-ts": {
"version": "1.10.72", "version": "1.10.72",
"resolved": "https://registry.npmjs.org/@injectivelabs/sdk-ts/-/sdk-ts-1.10.72.tgz", "resolved": "https://registry.npmjs.org/@injectivelabs/sdk-ts/-/sdk-ts-1.10.72.tgz",
@ -316,6 +344,47 @@
"snakecase-keys": "^5.4.1" "snakecase-keys": "^5.4.1"
} }
}, },
"contract_manager/node_modules/@injectivelabs/sdk-ts/node_modules/@injectivelabs/networks": {
"version": "1.11.0",
"resolved": "https://registry.npmjs.org/@injectivelabs/networks/-/networks-1.11.0.tgz",
"integrity": "sha512-0dtO/zZ8AzsxGInEWZ7tpOA0Q++M3FhAFxOWzhYC39ZeJlwHhEcYmvmhrGG5gRdus29XfFysRlaz3hyT3XH1Jg==",
"hasInstallScript": true,
"optional": true,
"dependencies": {
"@injectivelabs/exceptions": "^1.11.0",
"@injectivelabs/ts-types": "^1.11.0",
"@injectivelabs/utils": "^1.11.0",
"link-module-alias": "^1.2.0",
"shx": "^0.3.2"
}
},
"contract_manager/node_modules/@injectivelabs/sdk-ts/node_modules/@injectivelabs/utils": {
"version": "1.11.0",
"resolved": "https://registry.npmjs.org/@injectivelabs/utils/-/utils-1.11.0.tgz",
"integrity": "sha512-KnUmt4vIvoBz6F3mQomy4GeTkpcHMYwju2AgiqzARrrqgF/2p1ZHfKBpr1ksj/jkl5X+irh3JVfbd/dFjwKi1g==",
"hasInstallScript": true,
"optional": true,
"dependencies": {
"@injectivelabs/exceptions": "^1.11.0",
"@injectivelabs/ts-types": "^1.11.0",
"axios": "^0.21.1",
"bignumber.js": "^9.0.1",
"http-status-codes": "^2.2.0",
"link-module-alias": "^1.2.0",
"shx": "^0.3.2",
"snakecase-keys": "^5.1.2",
"store2": "^2.12.0"
}
},
"contract_manager/node_modules/@injectivelabs/sdk-ts/node_modules/@injectivelabs/utils/node_modules/axios": {
"version": "0.21.4",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz",
"integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==",
"optional": true,
"dependencies": {
"follow-redirects": "^1.14.0"
}
},
"contract_manager/node_modules/@injectivelabs/sdk-ts/node_modules/axios": { "contract_manager/node_modules/@injectivelabs/sdk-ts/node_modules/axios": {
"version": "0.27.2", "version": "0.27.2",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz",
@ -331,7 +400,6 @@
"resolved": "https://registry.npmjs.org/@injectivelabs/utils/-/utils-1.10.12.tgz", "resolved": "https://registry.npmjs.org/@injectivelabs/utils/-/utils-1.10.12.tgz",
"integrity": "sha512-c8al79nxIJgV1cBAdW2TPDGldj/8gm5k0h5TIN/AJs8/AeIjpTwwVGfLY3QvPOpRsxuQ9CjBkTXrAcSL1wwkcw==", "integrity": "sha512-c8al79nxIJgV1cBAdW2TPDGldj/8gm5k0h5TIN/AJs8/AeIjpTwwVGfLY3QvPOpRsxuQ9CjBkTXrAcSL1wwkcw==",
"hasInstallScript": true, "hasInstallScript": true,
"optional": true,
"dependencies": { "dependencies": {
"@injectivelabs/exceptions": "^1.10.12", "@injectivelabs/exceptions": "^1.10.12",
"@injectivelabs/ts-types": "^1.10.12", "@injectivelabs/ts-types": "^1.10.12",
@ -348,7 +416,6 @@
"version": "0.21.4", "version": "0.21.4",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz",
"integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==",
"optional": true,
"dependencies": { "dependencies": {
"follow-redirects": "^1.14.0" "follow-redirects": "^1.14.0"
} }
@ -7045,13 +7112,13 @@
} }
}, },
"node_modules/@injectivelabs/exceptions": { "node_modules/@injectivelabs/exceptions": {
"version": "1.10.12", "version": "1.11.0",
"resolved": "https://registry.npmjs.org/@injectivelabs/exceptions/-/exceptions-1.10.12.tgz", "resolved": "https://registry.npmjs.org/@injectivelabs/exceptions/-/exceptions-1.11.0.tgz",
"integrity": "sha512-9x8WDRi/K6JRMRAGJblbS0wQKckIX69CPU61ea22RprkO0sPazxpzp56txgHj0uHYkq2bg/exrX8N6UxdrNCMg==", "integrity": "sha512-jZ0N4cP1KCyErNEiCARaKt70E8KMTNa9R4a5FrCERX4cFKPxdbWpoQ8Lqga2jfHAgiFcChRJ5JmaSYclFtKf9w==",
"hasInstallScript": true, "hasInstallScript": true,
"dependencies": { "dependencies": {
"@injectivelabs/grpc-web": "^0.0.1", "@injectivelabs/grpc-web": "^0.0.1",
"@injectivelabs/ts-types": "^1.10.12", "@injectivelabs/ts-types": "^1.11.0",
"http-status-codes": "^2.2.0", "http-status-codes": "^2.2.0",
"link-module-alias": "^1.2.0", "link-module-alias": "^1.2.0",
"shx": "^0.3.2" "shx": "^0.3.2"
@ -7292,9 +7359,9 @@
} }
}, },
"node_modules/@injectivelabs/ts-types": { "node_modules/@injectivelabs/ts-types": {
"version": "1.10.12", "version": "1.11.0",
"resolved": "https://registry.npmjs.org/@injectivelabs/ts-types/-/ts-types-1.10.12.tgz", "resolved": "https://registry.npmjs.org/@injectivelabs/ts-types/-/ts-types-1.11.0.tgz",
"integrity": "sha512-Z/qeZ9jwhqpreXFNiox6NrXLiMyhvMEd79RWMZ9lVOLjTeXRTUh/Vl7ry7KBE2OypsPPTMUP+k7Dhsn0ufFwgw==", "integrity": "sha512-3ZVRW1xMe3RHOxFblRC0LgQcU/rpxgZQZ+sISyRKFGcS/m2ApkdmcPvjMgd5TQe9AXW/6nnvmul3mST8iAaUJg==",
"hasInstallScript": true, "hasInstallScript": true,
"dependencies": { "dependencies": {
"link-module-alias": "^1.2.0", "link-module-alias": "^1.2.0",
@ -63639,12 +63706,12 @@
} }
}, },
"@injectivelabs/exceptions": { "@injectivelabs/exceptions": {
"version": "1.10.12", "version": "1.11.0",
"resolved": "https://registry.npmjs.org/@injectivelabs/exceptions/-/exceptions-1.10.12.tgz", "resolved": "https://registry.npmjs.org/@injectivelabs/exceptions/-/exceptions-1.11.0.tgz",
"integrity": "sha512-9x8WDRi/K6JRMRAGJblbS0wQKckIX69CPU61ea22RprkO0sPazxpzp56txgHj0uHYkq2bg/exrX8N6UxdrNCMg==", "integrity": "sha512-jZ0N4cP1KCyErNEiCARaKt70E8KMTNa9R4a5FrCERX4cFKPxdbWpoQ8Lqga2jfHAgiFcChRJ5JmaSYclFtKf9w==",
"requires": { "requires": {
"@injectivelabs/grpc-web": "^0.0.1", "@injectivelabs/grpc-web": "^0.0.1",
"@injectivelabs/ts-types": "^1.10.12", "@injectivelabs/ts-types": "^1.11.0",
"http-status-codes": "^2.2.0", "http-status-codes": "^2.2.0",
"link-module-alias": "^1.2.0", "link-module-alias": "^1.2.0",
"shx": "^0.3.2" "shx": "^0.3.2"
@ -63879,9 +63946,9 @@
} }
}, },
"@injectivelabs/ts-types": { "@injectivelabs/ts-types": {
"version": "1.10.12", "version": "1.11.0",
"resolved": "https://registry.npmjs.org/@injectivelabs/ts-types/-/ts-types-1.10.12.tgz", "resolved": "https://registry.npmjs.org/@injectivelabs/ts-types/-/ts-types-1.11.0.tgz",
"integrity": "sha512-Z/qeZ9jwhqpreXFNiox6NrXLiMyhvMEd79RWMZ9lVOLjTeXRTUh/Vl7ry7KBE2OypsPPTMUP+k7Dhsn0ufFwgw==", "integrity": "sha512-3ZVRW1xMe3RHOxFblRC0LgQcU/rpxgZQZ+sISyRKFGcS/m2ApkdmcPvjMgd5TQe9AXW/6nnvmul3mST8iAaUJg==",
"requires": { "requires": {
"link-module-alias": "^1.2.0", "link-module-alias": "^1.2.0",
"shx": "^0.3.2" "shx": "^0.3.2"
@ -69501,6 +69568,7 @@
"version": "file:contract_manager", "version": "file:contract_manager",
"requires": { "requires": {
"@certusone/wormhole-sdk": "^0.9.8", "@certusone/wormhole-sdk": "^0.9.8",
"@injectivelabs/networks": "1.0.68",
"@mysten/sui.js": "^0.37.1", "@mysten/sui.js": "^0.37.1",
"@pythnetwork/cosmwasm-deploy-tools": "*", "@pythnetwork/cosmwasm-deploy-tools": "*",
"@pythnetwork/price-service-client": "*", "@pythnetwork/price-service-client": "*",
@ -69538,6 +69606,19 @@
"near-api-js": "^1.0.0" "near-api-js": "^1.0.0"
}, },
"dependencies": { "dependencies": {
"@injectivelabs/networks": {
"version": "1.10.12",
"resolved": "https://registry.npmjs.org/@injectivelabs/networks/-/networks-1.10.12.tgz",
"integrity": "sha512-tTHyLls1Nik5QTs/S03qqG2y/ITvNwI8CJOQbMmmsr1CL2CdjJBtzRYn9Dyx2p8XgzRFf9hmlybpe20tq9O3SA==",
"optional": true,
"requires": {
"@injectivelabs/exceptions": "^1.10.12",
"@injectivelabs/ts-types": "^1.10.12",
"@injectivelabs/utils": "^1.10.12",
"link-module-alias": "^1.2.0",
"shx": "^0.3.2"
}
},
"@mysten/sui.js": { "@mysten/sui.js": {
"version": "0.32.2", "version": "0.32.2",
"resolved": "https://registry.npmjs.org/@mysten/sui.js/-/sui.js-0.32.2.tgz", "resolved": "https://registry.npmjs.org/@mysten/sui.js/-/sui.js-0.32.2.tgz",
@ -69730,6 +69811,18 @@
"integrity": "sha512-KvvX58MGMWh7xA+N+deCfunkA/ZNDvFLw4YbOmX3f/XBIkqrVY7qlotfy2aNb1kgp6h4B6Yc8YawJPDTfvWX7g==", "integrity": "sha512-KvvX58MGMWh7xA+N+deCfunkA/ZNDvFLw4YbOmX3f/XBIkqrVY7qlotfy2aNb1kgp6h4B6Yc8YawJPDTfvWX7g==",
"optional": true "optional": true
}, },
"@injectivelabs/networks": {
"version": "1.0.68",
"resolved": "https://registry.npmjs.org/@injectivelabs/networks/-/networks-1.0.68.tgz",
"integrity": "sha512-CcWcLaRX1lJQyYs97+PPDmMaEFcXQgt/WjQ5raamcbQugJwMa/byC4eS18DZ0tIIZ24CoD+79zbgHDzfoe6/qg==",
"requires": {
"@injectivelabs/exceptions": "^1.0.42",
"@injectivelabs/ts-types": "^1.0.27",
"@injectivelabs/utils": "^1.0.59",
"link-module-alias": "^1.2.0",
"shx": "^0.3.2"
}
},
"@injectivelabs/sdk-ts": { "@injectivelabs/sdk-ts": {
"version": "1.10.72", "version": "1.10.72",
"resolved": "https://registry.npmjs.org/@injectivelabs/sdk-ts/-/sdk-ts-1.10.72.tgz", "resolved": "https://registry.npmjs.org/@injectivelabs/sdk-ts/-/sdk-ts-1.10.72.tgz",
@ -69774,6 +69867,47 @@
"snakecase-keys": "^5.4.1" "snakecase-keys": "^5.4.1"
}, },
"dependencies": { "dependencies": {
"@injectivelabs/networks": {
"version": "1.11.0",
"resolved": "https://registry.npmjs.org/@injectivelabs/networks/-/networks-1.11.0.tgz",
"integrity": "sha512-0dtO/zZ8AzsxGInEWZ7tpOA0Q++M3FhAFxOWzhYC39ZeJlwHhEcYmvmhrGG5gRdus29XfFysRlaz3hyT3XH1Jg==",
"optional": true,
"requires": {
"@injectivelabs/exceptions": "^1.11.0",
"@injectivelabs/ts-types": "^1.11.0",
"@injectivelabs/utils": "^1.11.0",
"link-module-alias": "^1.2.0",
"shx": "^0.3.2"
}
},
"@injectivelabs/utils": {
"version": "1.11.0",
"resolved": "https://registry.npmjs.org/@injectivelabs/utils/-/utils-1.11.0.tgz",
"integrity": "sha512-KnUmt4vIvoBz6F3mQomy4GeTkpcHMYwju2AgiqzARrrqgF/2p1ZHfKBpr1ksj/jkl5X+irh3JVfbd/dFjwKi1g==",
"optional": true,
"requires": {
"@injectivelabs/exceptions": "^1.11.0",
"@injectivelabs/ts-types": "^1.11.0",
"axios": "^0.21.1",
"bignumber.js": "^9.0.1",
"http-status-codes": "^2.2.0",
"link-module-alias": "^1.2.0",
"shx": "^0.3.2",
"snakecase-keys": "^5.1.2",
"store2": "^2.12.0"
},
"dependencies": {
"axios": {
"version": "0.21.4",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz",
"integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==",
"optional": true,
"requires": {
"follow-redirects": "^1.14.0"
}
}
}
},
"axios": { "axios": {
"version": "0.27.2", "version": "0.27.2",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz",
@ -69790,7 +69924,6 @@
"version": "1.10.12", "version": "1.10.12",
"resolved": "https://registry.npmjs.org/@injectivelabs/utils/-/utils-1.10.12.tgz", "resolved": "https://registry.npmjs.org/@injectivelabs/utils/-/utils-1.10.12.tgz",
"integrity": "sha512-c8al79nxIJgV1cBAdW2TPDGldj/8gm5k0h5TIN/AJs8/AeIjpTwwVGfLY3QvPOpRsxuQ9CjBkTXrAcSL1wwkcw==", "integrity": "sha512-c8al79nxIJgV1cBAdW2TPDGldj/8gm5k0h5TIN/AJs8/AeIjpTwwVGfLY3QvPOpRsxuQ9CjBkTXrAcSL1wwkcw==",
"optional": true,
"requires": { "requires": {
"@injectivelabs/exceptions": "^1.10.12", "@injectivelabs/exceptions": "^1.10.12",
"@injectivelabs/ts-types": "^1.10.12", "@injectivelabs/ts-types": "^1.10.12",
@ -69807,7 +69940,6 @@
"version": "0.21.4", "version": "0.21.4",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz",
"integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==",
"optional": true,
"requires": { "requires": {
"follow-redirects": "^1.14.0" "follow-redirects": "^1.14.0"
} }

View File

@ -86,12 +86,17 @@ export type RawContractStateRequest = {
key: Buffer; key: Buffer;
}; };
export type GetCodeRequest = {
codeId: number;
};
export type AllContractStateRequest = { export type AllContractStateRequest = {
contractAddr: string; contractAddr: string;
}; };
export class CosmwasmQuerier implements ChainQuerier { export class CosmwasmQuerier implements ChainQuerier {
private readonly wasmQueryClient: WasmExtension; private readonly wasmQueryClient: WasmExtension;
private constructor(readonly tendermintClient: Tendermint34Client) { private constructor(readonly tendermintClient: Tendermint34Client) {
this.wasmQueryClient = setupWasmExtension( this.wasmQueryClient = setupWasmExtension(
new QueryClient(tendermintClient) new QueryClient(tendermintClient)
@ -136,6 +141,15 @@ export class CosmwasmQuerier implements ChainQuerier {
return JSON.parse(Buffer.from(data).toString()); return JSON.parse(Buffer.from(data).toString());
} }
async getCode(req: GetCodeRequest): Promise<Buffer> {
const { codeId } = req;
const { wasm: wasmQueryClient } = this.wasmQueryClient;
const { data } = await wasmQueryClient.getCode(codeId);
return Buffer.from(data);
}
async getAllContractState(req: AllContractStateRequest): Promise<Object> { async getAllContractState(req: AllContractStateRequest): Promise<Object> {
const { contractAddr } = req; const { contractAddr } = req;

View File

@ -1,6 +1,7 @@
import { ChainExecutor } from "./chain-executor"; import { ChainExecutor } from "./chain-executor";
import { CosmwasmExecutor } from "./cosmwasm"; import { CosmwasmExecutor } from "./cosmwasm";
import { InjectiveExecutor } from "./injective"; import { InjectiveExecutor } from "./injective";
import { Network } from "@injectivelabs/networks";
export enum ChainType { export enum ChainType {
INJECTIVE = "injective", INJECTIVE = "injective",
@ -142,7 +143,9 @@ export async function createExecutorForChain(
if (chainType === ChainType.INJECTIVE) { if (chainType === ChainType.INJECTIVE) {
return InjectiveExecutor.fromMnemonic( return InjectiveExecutor.fromMnemonic(
chainConfig.executorEndpoint, chainConfig.chainId === ChainId.INJECTIVE_TESTNET
? Network.Testnet
: Network.Mainnet,
mnemonic mnemonic
); );
} else } else

View File

@ -1,2 +1,3 @@
export * from "./cosmwasm"; export * from "./cosmwasm";
export * from "./injective"; export * from "./injective";
export * from "./chain-querier";

View File

@ -25,25 +25,32 @@ import {
UpdateContractAdminResponse, UpdateContractAdminResponse,
} from "./chain-executor"; } from "./chain-executor";
import assert from "assert"; import assert from "assert";
import {
getNetworkEndpoints,
getNetworkInfo,
Network,
} from "@injectivelabs/networks";
import * as net from "net";
const DEFAULT_GAS_PRICE = 500000000; const DEFAULT_GAS_PRICE = 500000000;
export class InjectiveExecutor implements ChainExecutor { export class InjectiveExecutor implements ChainExecutor {
private readonly wallet: PrivateKey;
private readonly chainId = "injective-888";
private readonly gasMultiplier = 2; private readonly gasMultiplier = 2;
private readonly gasPrice = DEFAULT_GAS_PRICE; private readonly gasPrice = DEFAULT_GAS_PRICE;
constructor( constructor(
private readonly grpcEndpoint: string, private readonly network: Network,
readonly privateKey: string private readonly wallet: PrivateKey
) { ) {}
this.wallet = PrivateKey.fromHex(privateKey);
static fromMnemonic(network: Network, mnemonic: string) {
const wallet = PrivateKey.fromMnemonic(mnemonic);
return new InjectiveExecutor(network, wallet);
} }
static fromMnemonic(grpcEndpoint: string, mnemonic: string) { static fromPrivateKey(network: Network, privateKey: string) {
const wallet = PrivateKey.fromMnemonic(mnemonic); const wallet = PrivateKey.fromHex(privateKey);
return new InjectiveExecutor(grpcEndpoint, wallet.toHex()); return new InjectiveExecutor(network, wallet);
} }
private getAddress(): string { private getAddress(): string {
@ -51,17 +58,20 @@ export class InjectiveExecutor implements ChainExecutor {
} }
private async signAndBroadcastMsg(msg: Msgs): Promise<TxResponse> { private async signAndBroadcastMsg(msg: Msgs): Promise<TxResponse> {
const chainGrpcAuthApi = new ChainGrpcAuthApi(this.grpcEndpoint); const networkInfo = getNetworkInfo(this.network);
const endpoints = getNetworkEndpoints(this.network);
const chainGrpcAuthApi = new ChainGrpcAuthApi(endpoints.grpc);
const account = await chainGrpcAuthApi.fetchAccount(this.getAddress()); const account = await chainGrpcAuthApi.fetchAccount(this.getAddress());
const { txRaw: simulateTxRaw } = createTransactionFromMsg({ const { txRaw: simulateTxRaw } = createTransactionFromMsg({
sequence: account.baseAccount.sequence, sequence: account.baseAccount.sequence,
accountNumber: account.baseAccount.accountNumber, accountNumber: account.baseAccount.accountNumber,
message: msg, message: msg,
chainId: this.chainId, chainId: networkInfo.chainId,
pubKey: this.wallet.toPublicKey().toBase64(), pubKey: this.wallet.toPublicKey().toBase64(),
}); });
const txService = new TxGrpcClient(this.grpcEndpoint); const txService = new TxGrpcClient(endpoints.grpc);
// simulation // simulation
const { const {
gasInfo: { gasUsed }, gasInfo: { gasUsed },
@ -85,7 +95,7 @@ export class InjectiveExecutor implements ChainExecutor {
sequence: account.baseAccount.sequence, sequence: account.baseAccount.sequence,
accountNumber: account.baseAccount.accountNumber, accountNumber: account.baseAccount.accountNumber,
message: msg, message: msg,
chainId: this.chainId, chainId: networkInfo.chainId,
fee, fee,
pubKey: this.wallet.toPublicKey().toBase64(), pubKey: this.wallet.toPublicKey().toBase64(),
}); });

View File

@ -1,3 +1,5 @@
export * from "./deployer"; export * from "./deployer";
export * from "./chains-manager"; export * from "./chains-manager";
export * from "./pyth-wrapper"; export * from "./pyth-wrapper";
export * from "./configs";
export * from "./helper";