@kubiklabs/wasmkit
Version:
Wasmkit is a development environment to compile, deploy, test, run cosmwasm contracts on different networks.
183 lines (182 loc) • 9.17 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Contract = void 0;
const fs_extra_1 = __importDefault(require("fs-extra"));
const path_1 = __importDefault(require("path"));
const context_1 = require("../../internal/context");
const errors_1 = require("../../internal/core/errors");
const errors_list_1 = require("../../internal/core/errors-list");
const project_structure_1 = require("../../internal/core/project-structure");
const strings_1 = require("../../internal/util/strings");
const compress_1 = require("../../lib/deploy/compress");
const checkpoints_1 = require("../checkpoints");
const client_1 = require("../client");
class Contract {
constructor(contractName, instantiateTag) {
this.env = context_1.WasmkitContext.getWasmkitContext().getRuntimeEnv();
this.contractName = (0, strings_1.replaceAll)(contractName, "-", "_");
this.codeId = 0;
this.contractCodeHash = "mock_hash";
this.contractAddress = "mock_address";
this.contractPath = path_1.default.join(project_structure_1.ARTIFACTS_DIR, "contracts", `${this.contractName}_compressed.wasm`);
this.instantiateTag = instantiateTag ?? "default_instantiate";
// Load checkpoints
this.checkpointPath = path_1.default.join(project_structure_1.ARTIFACTS_DIR, "checkpoints", `${this.contractName}.yaml`);
// file exist load it else create new checkpoint
// skip checkpoints if test command is run, or skip-checkpoints is passed
if (fs_extra_1.default.existsSync(this.checkpointPath) && this.env.runtimeArgs.useCheckpoints === true) {
this.checkpointData = (0, checkpoints_1.loadCheckpoint)(this.checkpointPath);
const contractHash = this.checkpointData[this.env.network.name]?.deployInfo?.contractCodeHash;
const contractCodeId = this.checkpointData[this.env.network.name]?.deployInfo?.codeId;
let contractAddr;
// Load instantiate info for tag
for (const value of this.checkpointData[this.env.network.name]?.instantiateInfo ?? []) {
if (value.instantiateTag === this.instantiateTag) {
contractAddr = value.contractAddress;
}
}
this.contractCodeHash = contractHash ?? "mock_hash";
this.codeId = contractCodeId ?? 0;
this.contractAddress = contractAddr ?? "mock_address";
}
else {
this.checkpointData = {};
}
}
async setupClient() {
this.client = await (0, client_1.getClient)(this.env.network);
}
async deploy(account, customFees, source, builder) {
const accountVal = account.account !== undefined
? account.account
: account;
const info = this.checkpointData[this.env.network.name]?.deployInfo;
if (info) {
console.log("Warning: contract already deployed, using checkpoints");
return info;
}
await (0, compress_1.compress)(this.contractName, this.env);
const wasmFileContent = fs_extra_1.default.readFileSync(this.contractPath);
const signingClient = await (0, client_1.getSigningClient)(this.env.network, accountVal);
const { codeId, contractCodeHash } = await (0, client_1.storeCode)(this.env.network, signingClient, accountVal.address, this.contractName, wasmFileContent, customFees, source, builder);
this.codeId = codeId;
const deployInfo = {
codeId: codeId,
contractCodeHash: contractCodeHash.code_hash,
deployTimestamp: String(new Date())
};
if (this.env.runtimeArgs.useCheckpoints === true) {
this.checkpointData[this.env.network.name] = {
...this.checkpointData[this.env.network.name],
deployInfo
};
(0, checkpoints_1.persistCheckpoint)(this.checkpointPath, this.checkpointData);
}
this.contractCodeHash = contractCodeHash.code_hash;
return deployInfo;
}
instantiatedWithAddress(address, timestamp) {
const initTimestamp = timestamp !== undefined ? String(timestamp) : String(new Date());
// contract address already exists
if (this.contractAddress !== "mock_address") {
console.log(`Contract ${this.contractName} already has address: ${this.contractAddress}, skipping`);
return;
}
else {
this.contractAddress = address;
}
const instantiateInfo = {
instantiateTag: this.instantiateTag,
contractAddress: address,
instantiateTimestamp: initTimestamp
};
// set init data (contract address, init timestamp) in checkpoints
const instInfo = this.checkpointData[this.env.network.name].instantiateInfo;
if (instInfo) {
this.checkpointData[this.env.network.name].instantiateInfo?.push(instantiateInfo);
}
else {
this.checkpointData[this.env.network.name].instantiateInfo = [instantiateInfo];
}
(0, checkpoints_1.persistCheckpoint)(this.checkpointPath, this.checkpointData);
}
async instantiate(initArgs, label, account, transferAmount, customFees, contractAdmin) {
const accountVal = account.account !== undefined
? account.account
: account;
// if (this.contractCodeHash === "mock_hash") {
// throw new WasmkitError(ERRORS.GENERAL.CONTRACT_NOT_DEPLOYED, {
// param: this.contractName
// });
// }
let info;
// Load instantiate info for tag
if (this.checkpointData[this.env.network.name] !== undefined) {
for (const value of this.checkpointData[this.env.network.name].instantiateInfo ?? []) {
if (value.instantiateTag === this.instantiateTag) {
info = value;
}
}
}
if (info) {
console.log("Warning: contract already instantiated, using checkpoints");
return info;
}
const signingClient = await (0, client_1.getSigningClient)(this.env.network, accountVal);
const initTimestamp = String(new Date());
label =
this.env.runtimeArgs.command === "test"
? `deploy ${this.contractName} ${initTimestamp}`
: label;
console.log(`Instantiating with label: ${label}`);
this.contractAddress = await (0, client_1.instantiateContract)(this.env.network, signingClient, this.codeId, accountVal.address, this.contractName, this.contractCodeHash, initArgs, label, transferAmount, customFees, contractAdmin);
const instantiateInfo = {
instantiateTag: this.instantiateTag,
contractAddress: this.contractAddress,
instantiateTimestamp: initTimestamp
};
if (this.env.runtimeArgs.useCheckpoints === true) {
const instInfo = this.checkpointData[this.env.network.name].instantiateInfo;
if (instInfo) {
this.checkpointData[this.env.network.name].instantiateInfo?.push(instantiateInfo);
}
else {
this.checkpointData[this.env.network.name].instantiateInfo = [instantiateInfo];
}
(0, checkpoints_1.persistCheckpoint)(this.checkpointPath, this.checkpointData);
}
return instantiateInfo;
}
async queryMsg(msgData) {
if (this.contractAddress === "mock_address") {
throw new errors_1.WasmkitError(errors_list_1.ERRORS.GENERAL.CONTRACT_NOT_INSTANTIATED, {
param: this.contractName
});
}
// Query the contract
console.log("Querying", this.contractAddress, "=>", Object.keys(msgData)[0]);
console.log(this.contractAddress, msgData);
if (this.client === undefined) {
throw new errors_1.WasmkitError(errors_list_1.ERRORS.GENERAL.CLIENT_NOT_LOADED);
}
return await (0, client_1.sendQuery)(this.client, this.env.network, msgData, this.contractAddress, this.contractCodeHash);
}
async executeMsg(msgData, account, customFees, memo, transferAmount) {
const accountVal = account.account !== undefined
? account.account
: account;
if (this.contractAddress === "mock_address") {
throw new errors_1.WasmkitError(errors_list_1.ERRORS.GENERAL.CONTRACT_NOT_INSTANTIATED, {
param: this.contractName
});
}
// Send execute msg to the contract
const signingClient = await (0, client_1.getSigningClient)(this.env.network, accountVal);
console.log("Executing", this.contractAddress, msgData);
return await (0, client_1.executeTransaction)(this.env.network, signingClient, accountVal.address, this.contractAddress, this.contractCodeHash, msgData, transferAmount, customFees, memo);
}
}
exports.Contract = Contract;