From 7fc54bcd0ef4ceb11f207b521fe92a274bb20928 Mon Sep 17 00:00:00 2001 From: RodrigoAD <15104916+RodrigoAD@users.noreply.github.com> Date: Thu, 10 Feb 2022 17:27:14 +0100 Subject: [PATCH 1/7] commands export data raw tx on inspection command --- .../src/commands/abstract/executionWrapper.ts | 15 +++++++++++++-- .../src/commands/abstract/index.ts | 6 ++++++ .../src/commands/abstract/inspectionWrapper.ts | 4 ++++ .../src/commands/contracts/link/deploy.ts | 4 ++++ .../src/commands/contracts/link/transfer.ts | 4 ++++ .../src/commands/tooling/upload.ts | 4 ++++ .../gauntlet-terra/src/commands/internal/terra.ts | 1 + 7 files changed, 36 insertions(+), 2 deletions(-) diff --git a/packages-ts/gauntlet-terra-contracts/src/commands/abstract/executionWrapper.ts b/packages-ts/gauntlet-terra-contracts/src/commands/abstract/executionWrapper.ts index ca24ed2c..edbd6ac2 100644 --- a/packages-ts/gauntlet-terra-contracts/src/commands/abstract/executionWrapper.ts +++ b/packages-ts/gauntlet-terra-contracts/src/commands/abstract/executionWrapper.ts @@ -1,6 +1,7 @@ import AbstractCommand, { makeAbstractCommand } from '.' import { Result } from '@chainlink/gauntlet-core' import { TerraCommand, TransactionResponse } from '@chainlink/gauntlet-terra' +import { MsgExecuteContract } from '@terra-money/terra.js' export interface AbstractInstruction<Input, ContractInput> { instruction: { @@ -26,7 +27,7 @@ export const instructionToCommand = (instruction: AbstractInstruction<any, any>) super(flags, args) } - execute = async (): Promise<Result<TransactionResponse>> => { + buildCommand = async (): Promise<TerraCommand> => { const commandInput = await instruction.makeInput(this.flags, this.args) if (!instruction.validateInput(commandInput)) { throw new Error(`Invalid input params: ${JSON.stringify(commandInput)}`) @@ -34,7 +35,17 @@ export const instructionToCommand = (instruction: AbstractInstruction<any, any>) const input = await instruction.makeContractInput(commandInput) const abstractCommand = await makeAbstractCommand(id, this.flags, this.args, input) await abstractCommand.invokeMiddlewares(abstractCommand, abstractCommand.middlewares) - let response = await abstractCommand.execute() + return abstractCommand + } + + makeRawTransaction = async (): Promise<MsgExecuteContract> => { + const command = await this.buildCommand() + return command.makeRawTransaction() + } + + execute = async (): Promise<Result<TransactionResponse>> => { + const command = await this.buildCommand() + let response = await command.execute() if (instruction.afterExecute) { const data = instruction.afterExecute(response) response = { ...response, data: { ...data } } diff --git a/packages-ts/gauntlet-terra-contracts/src/commands/abstract/index.ts b/packages-ts/gauntlet-terra-contracts/src/commands/abstract/index.ts index 67e5370a..c4eb5340 100644 --- a/packages-ts/gauntlet-terra-contracts/src/commands/abstract/index.ts +++ b/packages-ts/gauntlet-terra-contracts/src/commands/abstract/index.ts @@ -1,4 +1,5 @@ import { Result } from '@chainlink/gauntlet-core' +import { MsgExecuteContract } from '@terra-money/terra.js' import { logger, prompt } from '@chainlink/gauntlet-core/dist/utils' import { TransactionResponse, TerraCommand } from '@chainlink/gauntlet-terra' import { Contract, CONTRACT_LIST, getContract, TerraABI, TERRA_OPERATIONS } from '../../lib/contracts' @@ -130,6 +131,11 @@ export default class AbstractCommand extends TerraCommand { this.contracts = [this.opts.contract.id] } + makeRawTransaction = async (): Promise<MsgExecuteContract> => { + const address = this.args[0] + return new MsgExecuteContract(this.wallet.key.accAddress, address, this.params) + } + abstractDeploy: AbstractExecute = async (params: any) => { logger.loading(`Deploying contract ${this.opts.contract.id}`) const codeId = this.codeIds[this.opts.contract.id] diff --git a/packages-ts/gauntlet-terra-contracts/src/commands/abstract/inspectionWrapper.ts b/packages-ts/gauntlet-terra-contracts/src/commands/abstract/inspectionWrapper.ts index af08a195..c58578da 100644 --- a/packages-ts/gauntlet-terra-contracts/src/commands/abstract/inspectionWrapper.ts +++ b/packages-ts/gauntlet-terra-contracts/src/commands/abstract/inspectionWrapper.ts @@ -47,6 +47,10 @@ export const instructionToInspectCommand = <CommandInput, Expected>( super(flags, args) } + makeRawTransaction = () => { + throw new Error('Inspection command does not involve any transaction') + } + execute = async (): Promise<Result<TransactionResponse>> => { const input = await inspectInstruction.makeInput(this.flags, this.args) const commands = await Promise.all( diff --git a/packages-ts/gauntlet-terra-contracts/src/commands/contracts/link/deploy.ts b/packages-ts/gauntlet-terra-contracts/src/commands/contracts/link/deploy.ts index c644a4e9..33fd1b45 100644 --- a/packages-ts/gauntlet-terra-contracts/src/commands/contracts/link/deploy.ts +++ b/packages-ts/gauntlet-terra-contracts/src/commands/contracts/link/deploy.ts @@ -19,6 +19,10 @@ export default class DeployLink extends TerraCommand { super(flags, args) } + makeRawTransaction = async () => { + throw new Error('Deploy LINK command: makeRawTransaction method not implemented') + } + execute = async () => { await prompt(`Begin deploying LINK Token?`) const deploy = await this.deploy(CW20_BASE_CODE_IDs[this.flags.network], { diff --git a/packages-ts/gauntlet-terra-contracts/src/commands/contracts/link/transfer.ts b/packages-ts/gauntlet-terra-contracts/src/commands/contracts/link/transfer.ts index 367a1ea2..fd2732f6 100644 --- a/packages-ts/gauntlet-terra-contracts/src/commands/contracts/link/transfer.ts +++ b/packages-ts/gauntlet-terra-contracts/src/commands/contracts/link/transfer.ts @@ -17,6 +17,10 @@ export default class TransferLink extends TerraCommand { super(flags, args) } + makeRawTransaction = async () => { + throw new Error('Transfer LINK command: makeRawTransaction method not implemented') + } + execute = async () => { const decimals = this.flags.decimals || 18 const link = this.flags.link || process.env.LINK diff --git a/packages-ts/gauntlet-terra-contracts/src/commands/tooling/upload.ts b/packages-ts/gauntlet-terra-contracts/src/commands/tooling/upload.ts index 3862513a..0840c116 100644 --- a/packages-ts/gauntlet-terra-contracts/src/commands/tooling/upload.ts +++ b/packages-ts/gauntlet-terra-contracts/src/commands/tooling/upload.ts @@ -23,6 +23,10 @@ export default class UploadContractCode extends TerraCommand { super(flags, args) } + makeRawTransaction = async () => { + throw new Error('Upload command: makeRawTransaction method not implemented') + } + getCodeId(response): number | undefined { return Number(this.parseResponseValue(response, 'store_code', 'code_id')) } diff --git a/packages-ts/gauntlet-terra/src/commands/internal/terra.ts b/packages-ts/gauntlet-terra/src/commands/internal/terra.ts index 72a140bf..a00f9162 100644 --- a/packages-ts/gauntlet-terra/src/commands/internal/terra.ts +++ b/packages-ts/gauntlet-terra/src/commands/internal/terra.ts @@ -23,6 +23,7 @@ export default abstract class TerraCommand extends WriteCommand<TransactionRespo contracts: string[] public codeIds: CodeIds abstract execute: () => Promise<Result<TransactionResponse>> + abstract makeRawTransaction: () => Promise<MsgExecuteContract> constructor(flags, args) { super(flags, args) From 74ec3cc22c3c0a5a4fb78b336e28e8112bb5d0fd Mon Sep 17 00:00:00 2001 From: RodrigoAD <15104916+RodrigoAD@users.noreply.github.com> Date: Mon, 14 Feb 2022 17:10:17 +0100 Subject: [PATCH 2/7] basic package and schema --- .../gauntlet-terra-contracts/src/index.ts | 3 +- .../gauntlet-terra-cw20-multisig/README.md | 1 + .../gauntlet-terra-cw20-multisig/package.json | 32 +++++++++++++++++++ .../src/commands/multisig.ts | 32 +++++++++++++++++++ .../gauntlet-terra-cw20-multisig/src/index.ts | 3 ++ .../tsconfig.json | 9 ++++++ tsconfig.json | 3 ++ 7 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 packages-ts/gauntlet-terra-cw20-multisig/README.md create mode 100644 packages-ts/gauntlet-terra-cw20-multisig/package.json create mode 100644 packages-ts/gauntlet-terra-cw20-multisig/src/commands/multisig.ts create mode 100644 packages-ts/gauntlet-terra-cw20-multisig/src/index.ts create mode 100644 packages-ts/gauntlet-terra-cw20-multisig/tsconfig.json diff --git a/packages-ts/gauntlet-terra-contracts/src/index.ts b/packages-ts/gauntlet-terra-contracts/src/index.ts index dcf0b1ba..adbb36dd 100644 --- a/packages-ts/gauntlet-terra-contracts/src/index.ts +++ b/packages-ts/gauntlet-terra-contracts/src/index.ts @@ -1,4 +1,5 @@ import { executeCLI } from '@chainlink/gauntlet-core' +import { multisigWrapCommand } from '@chainlink/gauntlet-terra-cw20-multisig' import { existsSync } from 'fs' import path from 'path' import { io } from '@chainlink/gauntlet-core/dist/utils' @@ -7,7 +8,7 @@ import { makeAbstractCommand } from './commands/abstract' import { defaultFlags } from './lib/args' const commands = { - custom: [...Terra], + custom: [...Terra, ...Terra.map(multisigWrapCommand)], loadDefaultFlags: () => defaultFlags, abstract: { findPolymorphic: () => undefined, diff --git a/packages-ts/gauntlet-terra-cw20-multisig/README.md b/packages-ts/gauntlet-terra-cw20-multisig/README.md new file mode 100644 index 00000000..e5c408c6 --- /dev/null +++ b/packages-ts/gauntlet-terra-cw20-multisig/README.md @@ -0,0 +1 @@ +# Gauntlet Terra CW20 Multisig \ No newline at end of file diff --git a/packages-ts/gauntlet-terra-cw20-multisig/package.json b/packages-ts/gauntlet-terra-cw20-multisig/package.json new file mode 100644 index 00000000..d50505f5 --- /dev/null +++ b/packages-ts/gauntlet-terra-cw20-multisig/package.json @@ -0,0 +1,32 @@ +{ + "name": "@chainlink/gauntlet-terra-cw20-multisig", + "version": "0.0.1", + "description": "Gauntlet Terra Cw20 Multisig", + "keywords": [ + "typescript", + "cli" + ], + "main": "./dist/index.js", + "types": "dist/index.d.ts", + "files": [ + "dist/**/*", + "!dist/**/*.test.js" + ], + "scripts": { + "preinstall": "node ../../scripts/require-yarn.js", + "gauntlet": "ts-node ./src/index.ts", + "lint": "tsc", + "test": "SKIP_PROMPTS=true jest --runInBand", + "test:coverage": "yarn test --collectCoverage", + "test:ci": "yarn test --ci", + "lint:format": "yarn prettier --check ./src", + "format": "yarn prettier --write ./src", + "clean": "rm -rf ./dist/ ./bin/", + "build": "yarn clean && tsc", + "bundle": "yarn build && pkg ." + }, + "dependencies": { + "@chainlink/gauntlet-core": "0.0.7", + "@chainlink/gauntlet-terra": "*" + } +} diff --git a/packages-ts/gauntlet-terra-cw20-multisig/src/commands/multisig.ts b/packages-ts/gauntlet-terra-cw20-multisig/src/commands/multisig.ts new file mode 100644 index 00000000..ff9690b1 --- /dev/null +++ b/packages-ts/gauntlet-terra-cw20-multisig/src/commands/multisig.ts @@ -0,0 +1,32 @@ +import { Result } from '@chainlink/gauntlet-core' +import { logger } from '@chainlink/gauntlet-core/dist/utils' +import { TerraCommand, TransactionResponse } from '@chainlink/gauntlet-terra' +import { MsgExecuteContract } from '@terra-money/terra.js' + +export const wrapCommand = (command) => { + return class Multisig extends TerraCommand { + command: TerraCommand + + static id = `${command.id}:multisig` + + constructor(flags, args) { + super(flags, args) + + this.command = new command(flags, args) + } + + makeRawTransaction = async () => { + // TODO: Replace with Mulstig tx message + return {} as MsgExecuteContract + } + + execute = async () => { + // If ID Proposal is provided, check the proposal status, and either approve or execute. + // If ID Proposal is not provided, create a new proposal + const message = await this.command.makeRawTransaction() + logger.log('Command data:', message) + + return {} as Result<TransactionResponse> + } + } +} diff --git a/packages-ts/gauntlet-terra-cw20-multisig/src/index.ts b/packages-ts/gauntlet-terra-cw20-multisig/src/index.ts new file mode 100644 index 00000000..08a5280c --- /dev/null +++ b/packages-ts/gauntlet-terra-cw20-multisig/src/index.ts @@ -0,0 +1,3 @@ +import { wrapCommand as multisigWrapCommand } from './commands/multisig' + +export { multisigWrapCommand } diff --git a/packages-ts/gauntlet-terra-cw20-multisig/tsconfig.json b/packages-ts/gauntlet-terra-cw20-multisig/tsconfig.json new file mode 100644 index 00000000..2c84c1fc --- /dev/null +++ b/packages-ts/gauntlet-terra-cw20-multisig/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "outDir": "dist", + "rootDir": "src" + }, + "include": ["src/**/*"], + "exclude": ["dist", "**/*.spec.ts", "**/*.test.ts"] +} diff --git a/tsconfig.json b/tsconfig.json index fb612e2a..a6bd767f 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,6 +6,9 @@ { "path": "./packages-ts/gauntlet-terra" }, + { + "path": "./packages-ts/gauntlet-terra-cw20-multisig" + }, { "path": "./packages-ts/gauntlet-terra-contracts" } From 242757138c696b0236b0e8700d0c10ab8275dd14 Mon Sep 17 00:00:00 2001 From: RodrigoAD <15104916+RodrigoAD@users.noreply.github.com> Date: Wed, 16 Feb 2022 13:25:36 +0100 Subject: [PATCH 3/7] multisig command --- .../src/commands/abstract/executionWrapper.ts | 6 +- .../src/commands/abstract/index.ts | 6 +- .../src/commands/multisig.ts | 152 +++++++++++++++++- .../src/commands/internal/terra.ts | 23 ++- 4 files changed, 172 insertions(+), 15 deletions(-) diff --git a/packages-ts/gauntlet-terra-contracts/src/commands/abstract/executionWrapper.ts b/packages-ts/gauntlet-terra-contracts/src/commands/abstract/executionWrapper.ts index edbd6ac2..00766832 100644 --- a/packages-ts/gauntlet-terra-contracts/src/commands/abstract/executionWrapper.ts +++ b/packages-ts/gauntlet-terra-contracts/src/commands/abstract/executionWrapper.ts @@ -1,7 +1,7 @@ import AbstractCommand, { makeAbstractCommand } from '.' import { Result } from '@chainlink/gauntlet-core' import { TerraCommand, TransactionResponse } from '@chainlink/gauntlet-terra' -import { MsgExecuteContract } from '@terra-money/terra.js' +import { AccAddress, MsgExecuteContract } from '@terra-money/terra.js' export interface AbstractInstruction<Input, ContractInput> { instruction: { @@ -38,9 +38,9 @@ export const instructionToCommand = (instruction: AbstractInstruction<any, any>) return abstractCommand } - makeRawTransaction = async (): Promise<MsgExecuteContract> => { + makeRawTransaction = async (signer: AccAddress): Promise<MsgExecuteContract> => { const command = await this.buildCommand() - return command.makeRawTransaction() + return command.makeRawTransaction(signer) } execute = async (): Promise<Result<TransactionResponse>> => { diff --git a/packages-ts/gauntlet-terra-contracts/src/commands/abstract/index.ts b/packages-ts/gauntlet-terra-contracts/src/commands/abstract/index.ts index c4eb5340..74b60a21 100644 --- a/packages-ts/gauntlet-terra-contracts/src/commands/abstract/index.ts +++ b/packages-ts/gauntlet-terra-contracts/src/commands/abstract/index.ts @@ -1,5 +1,5 @@ import { Result } from '@chainlink/gauntlet-core' -import { MsgExecuteContract } from '@terra-money/terra.js' +import { AccAddress, MsgExecuteContract } from '@terra-money/terra.js' import { logger, prompt } from '@chainlink/gauntlet-core/dist/utils' import { TransactionResponse, TerraCommand } from '@chainlink/gauntlet-terra' import { Contract, CONTRACT_LIST, getContract, TerraABI, TERRA_OPERATIONS } from '../../lib/contracts' @@ -131,9 +131,9 @@ export default class AbstractCommand extends TerraCommand { this.contracts = [this.opts.contract.id] } - makeRawTransaction = async (): Promise<MsgExecuteContract> => { + makeRawTransaction = async (signer: AccAddress): Promise<MsgExecuteContract> => { const address = this.args[0] - return new MsgExecuteContract(this.wallet.key.accAddress, address, this.params) + return new MsgExecuteContract(signer, address, this.params) } abstractDeploy: AbstractExecute = async (params: any) => { diff --git a/packages-ts/gauntlet-terra-cw20-multisig/src/commands/multisig.ts b/packages-ts/gauntlet-terra-cw20-multisig/src/commands/multisig.ts index ff9690b1..b8849254 100644 --- a/packages-ts/gauntlet-terra-cw20-multisig/src/commands/multisig.ts +++ b/packages-ts/gauntlet-terra-cw20-multisig/src/commands/multisig.ts @@ -1,11 +1,47 @@ import { Result } from '@chainlink/gauntlet-core' -import { logger } from '@chainlink/gauntlet-core/dist/utils' +import { logger, prompt } from '@chainlink/gauntlet-core/dist/utils' import { TerraCommand, TransactionResponse } from '@chainlink/gauntlet-terra' -import { MsgExecuteContract } from '@terra-money/terra.js' +import { AccAddress, MsgExecuteContract } from '@terra-money/terra.js' + +type ProposalAction = ( + signer: AccAddress, + proposalId: number, + message: MsgExecuteContract, +) => Promise<MsgExecuteContract> + +enum Vote { + YES = 'yes', + NO = 'no', + ABS = 'abstain', + VETO = 'veto', +} + +type WasmMsg = { + execute: { + contract_addr: string + funds: { + denom: string + amount: string + }[] + msg: string + } +} + +enum Action { + CREATE = 'create', + APPROVE = 'approve', + EXECUTE = 'execute', +} + +type State = { + threshold: number + proposalStatus: Action +} export const wrapCommand = (command) => { return class Multisig extends TerraCommand { command: TerraCommand + multisig: AccAddress static id = `${command.id}:multisig` @@ -13,18 +49,120 @@ export const wrapCommand = (command) => { super(flags, args) this.command = new command(flags, args) + + if (!AccAddress.validate(process.env.MULTISIG_ADDRESS)) throw new Error(`Invalid Multisig wallet address`) + this.multisig = process.env.MULTISIG_ADDRESS as AccAddress + } + + makeRawTransaction = async (signer: AccAddress, status?: Action) => { + const message = await this.command.makeRawTransaction(this.multisig) + + const operations = { + [Action.CREATE]: this.executePropose, + [Action.APPROVE]: this.executeApproval, + [Action.EXECUTE]: this.executeExecution, + } + + return operations[status](signer, Number(this.flags.proposal), message) + } + + toWasmMsg = (message: MsgExecuteContract): WasmMsg => { + return { + execute: { + contract_addr: message.contract, + funds: message.coins.toArray().map((c) => c.toData()), + msg: Buffer.from(message.toJSON()).toString('base64'), + }, + } + } + + executePropose: ProposalAction = async (signer, proposalId, message) => { + logger.info('Generating data for creating new proposal') + const proposeInput = { + propose: { + description: command.id, + msgs: [ + { + wasm: this.toWasmMsg(message), + }, + ], + title: command.id, + // latest: { + // never: {}, + // }, + }, + } + return new MsgExecuteContract(signer, this.multisig, proposeInput) + } + + executeApproval: ProposalAction = async (signer, proposalId) => { + logger.info(`Generating data for approving proposal ${proposalId}`) + const approvalInput = { + vote: { + vote: Vote.YES, + proposal_id: proposalId, + }, + } + return new MsgExecuteContract(signer, this.multisig, approvalInput) } - makeRawTransaction = async () => { - // TODO: Replace with Mulstig tx message - return {} as MsgExecuteContract + executeExecution: ProposalAction = async (signer, proposalId) => { + logger.info(`Generating data for executing proposal ${proposalId}`) + const executeInput = { + execute: { + proposal_id: proposalId, + }, + } + return new MsgExecuteContract(signer, this.multisig, executeInput) + } + + fetchState = async (proposalId?: number): Promise<State> => { + const threshold = await this.query(this.multisig, { + threshold: {}, + }) + if (!proposalId) + return { + threshold, + proposalStatus: Action.CREATE, + } + const proposalState = await this.query(this.multisig, { + proposal: { + proposal_id: proposalId, + }, + }) + console.log(proposalState) + + return { + threshold, + proposalStatus: Action.APPROVE, + } } execute = async () => { + let proposalId = !!this.flags.proposal && Number(this.flags.proposal) + const state = await this.fetchState(proposalId) + const rawTx = await this.makeRawTransaction(this.wallet.key.accAddress, state.proposalStatus) + + console.info(` + Proposal State: + - Threshold: ${state.threshold} + - Status: ${state.proposalStatus} + `) + + const actionMessage = { + [Action.CREATE]: 'CREATING', + [Action.APPROVE]: 'APPROVING', + [Action.EXECUTE]: 'EXECUTING', + } + await prompt(`Continue ${actionMessage[state.proposalStatus]} proposal?`) + const tx = await this.signAndSend([rawTx]) + + if (state.proposalStatus === Action.CREATE) { + // get proposal ID from logs + } + // If ID Proposal is provided, check the proposal status, and either approve or execute. // If ID Proposal is not provided, create a new proposal - const message = await this.command.makeRawTransaction() - logger.log('Command data:', message) return {} as Result<TransactionResponse> } diff --git a/packages-ts/gauntlet-terra/src/commands/internal/terra.ts b/packages-ts/gauntlet-terra/src/commands/internal/terra.ts index a00f9162..cbc5eb67 100644 --- a/packages-ts/gauntlet-terra/src/commands/internal/terra.ts +++ b/packages-ts/gauntlet-terra/src/commands/internal/terra.ts @@ -1,6 +1,6 @@ import { Result, WriteCommand } from '@chainlink/gauntlet-core' import { logger } from '@chainlink/gauntlet-core/dist/utils' -import { EventsByType, MsgStoreCode, TxLog } from '@terra-money/terra.js' +import { EventsByType, MsgStoreCode, AccAddress, TxLog } from '@terra-money/terra.js' import { SignMode } from '@terra-money/terra.proto/cosmos/tx/signing/v1beta1/signing' import { withProvider, withWallet, withCodeIds, withNetwork } from '../middlewares' @@ -23,7 +23,7 @@ export default abstract class TerraCommand extends WriteCommand<TransactionRespo contracts: string[] public codeIds: CodeIds abstract execute: () => Promise<Result<TransactionResponse>> - abstract makeRawTransaction: () => Promise<MsgExecuteContract> + abstract makeRawTransaction: (signer: AccAddress) => Promise<MsgExecuteContract> constructor(flags, args) { super(flags, args) @@ -64,6 +64,25 @@ export default abstract class TerraCommand extends WriteCommand<TransactionRespo return await this.provider.wasm.contractQuery(address, input, params) } + signAndSend = async (messages: MsgExecuteContract[]): Promise<TransactionResponse> => { + try { + const tx = await this.wallet.createAndSignTx({ + msgs: messages, + ...(this.wallet.key instanceof LedgerKey && { + signMode: SignMode.SIGN_MODE_LEGACY_AMINO_JSON, + }), + }) + + const res = await this.provider.tx.broadcast(tx) + + logger.debug(res) + return this.wrapResponse(res) + } catch (e) { + const details = e.response.data + throw new Error(details.message) + } + } + async call(address, input) { const msg = new MsgExecuteContract(this.wallet.key.accAddress, address, input) From bd956c829ef0cff5c69c1f3fbf859a5f875ac429 Mon Sep 17 00:00:00 2001 From: RodrigoAD <15104916+RodrigoAD@users.noreply.github.com> Date: Wed, 16 Feb 2022 14:31:05 +0100 Subject: [PATCH 4/7] multisig command improvements list some todos --- .../src/commands/multisig.ts | 137 +++++++++++++----- .../src/lib/utils.ts | 13 ++ 2 files changed, 114 insertions(+), 36 deletions(-) create mode 100644 packages-ts/gauntlet-terra-cw20-multisig/src/lib/utils.ts diff --git a/packages-ts/gauntlet-terra-cw20-multisig/src/commands/multisig.ts b/packages-ts/gauntlet-terra-cw20-multisig/src/commands/multisig.ts index b8849254..eaf97514 100644 --- a/packages-ts/gauntlet-terra-cw20-multisig/src/commands/multisig.ts +++ b/packages-ts/gauntlet-terra-cw20-multisig/src/commands/multisig.ts @@ -2,6 +2,7 @@ import { Result } from '@chainlink/gauntlet-core' import { logger, prompt } from '@chainlink/gauntlet-core/dist/utils' import { TerraCommand, TransactionResponse } from '@chainlink/gauntlet-terra' import { AccAddress, MsgExecuteContract } from '@terra-money/terra.js' +import { isDeepEqual } from '../lib/utils' type ProposalAction = ( signer: AccAddress, @@ -17,13 +18,15 @@ enum Vote { } type WasmMsg = { - execute: { - contract_addr: string - funds: { - denom: string - amount: string - }[] - msg: string + wasm: { + execute: { + contract_addr: string + funds: { + denom: string + amount: string + }[] + msg: string + } } } @@ -31,11 +34,15 @@ enum Action { CREATE = 'create', APPROVE = 'approve', EXECUTE = 'execute', + NONE = 'none', } type State = { threshold: number - proposalStatus: Action + nextAction: Action + // https://github.com/CosmWasm/cw-plus/blob/82138f9484e538913f7faf78bc292fb14407aae8/packages/cw3/src/query.rs#L75 + currentStatus?: 'pending' | 'open' | 'rejected' | 'passed' | 'executed' + data?: WasmMsg[] } export const wrapCommand = (command) => { @@ -54,42 +61,53 @@ export const wrapCommand = (command) => { this.multisig = process.env.MULTISIG_ADDRESS as AccAddress } - makeRawTransaction = async (signer: AccAddress, status?: Action) => { + makeRawTransaction = async (signer: AccAddress, state?: State) => { const message = await this.command.makeRawTransaction(this.multisig) const operations = { [Action.CREATE]: this.executePropose, [Action.APPROVE]: this.executeApproval, [Action.EXECUTE]: this.executeExecution, + [Action.NONE]: () => { + throw new Error('No action needed') + }, } - return operations[status](signer, Number(this.flags.proposal), message) + if (state.nextAction !== Action.CREATE) { + this.require( + await this.isSameProposal(state.data, [this.toWasmMsg(message)]), + 'The transaction generated is different from the proposal provided', + ) + } + + return operations[state.nextAction](signer, Number(this.flags.proposal), message) + } + + isSameProposal = (proposalMsgs: WasmMsg[], generatedMsgs: WasmMsg[]) => { + return isDeepEqual(proposalMsgs, generatedMsgs) } toWasmMsg = (message: MsgExecuteContract): WasmMsg => { return { - execute: { - contract_addr: message.contract, - funds: message.coins.toArray().map((c) => c.toData()), - msg: Buffer.from(message.toJSON()).toString('base64'), + wasm: { + execute: { + contract_addr: message.contract, + funds: message.coins.toArray().map((c) => c.toData()), + msg: Buffer.from(JSON.stringify(message.execute_msg)).toString('base64'), + }, }, } } - executePropose: ProposalAction = async (signer, proposalId, message) => { + executePropose: ProposalAction = async (signer, _, message) => { logger.info('Generating data for creating new proposal') const proposeInput = { propose: { description: command.id, - msgs: [ - { - wasm: this.toWasmMsg(message), - }, - ], + msgs: [this.toWasmMsg(message)], title: command.id, - // latest: { - // never: {}, - // }, + // TODO: Set expiration time + // latest: { never: {} } }, } return new MsgExecuteContract(signer, this.multisig, proposeInput) @@ -117,36 +135,72 @@ export const wrapCommand = (command) => { } fetchState = async (proposalId?: number): Promise<State> => { - const threshold = await this.query(this.multisig, { + const thresholdState = await this.query(this.multisig, { threshold: {}, }) - if (!proposalId) + const threshold = thresholdState.absolute_count.total_weight + if (!proposalId) { return { threshold, - proposalStatus: Action.CREATE, + nextAction: Action.CREATE, } + } + const proposalState = await this.query(this.multisig, { proposal: { proposal_id: proposalId, }, }) - console.log(proposalState) + // TODO: Fetch owners and add them to state + + const status = proposalState.status + const toNextAction = { + passed: Action.EXECUTE, + open: Action.APPROVE, + pending: Action.APPROVE, + rejected: Action.NONE, + executed: Action.NONE, + } return { threshold, - proposalStatus: Action.APPROVE, + nextAction: toNextAction[status], + currentStatus: status, + data: proposalState.msgs, + } + } + + printPostInstructions = async (proposalId: number) => { + const state = await this.fetchState(proposalId) + // TODO: Calculate approvals left + const approvalsLeft = state.threshold - 1 + const messages = { + [Action.APPROVE]: `The proposal needs ${approvalsLeft} more approvals. Run the same command with the flag --proposal=${proposalId}`, + [Action.EXECUTE]: `The proposal reached the threshold and can be executed. Run the same command with the flag --proposal=${proposalId}`, + [Action.NONE]: `The proposal has been executed. No more actions needed`, } + logger.line() + logger.info(`Next Actions: + ${messages[state.nextAction]} + `) + logger.line() } execute = async () => { let proposalId = !!this.flags.proposal && Number(this.flags.proposal) const state = await this.fetchState(proposalId) - const rawTx = await this.makeRawTransaction(this.wallet.key.accAddress, state.proposalStatus) + + if (state.nextAction === Action.NONE) { + await this.printPostInstructions(proposalId) + return + } + const rawTx = await this.makeRawTransaction(this.wallet.key.accAddress, state) console.info(` Proposal State: - Threshold: ${state.threshold} - - Status: ${state.proposalStatus} + - Next Action: ${state.nextAction.toUpperCase()} + - Owners: TODO `) const actionMessage = { @@ -154,17 +208,28 @@ export const wrapCommand = (command) => { [Action.APPROVE]: 'APPROVING', [Action.EXECUTE]: 'EXECUTING', } - await prompt(`Continue ${actionMessage[state.proposalStatus]} proposal?`) + await prompt(`Continue ${actionMessage[state.nextAction]} proposal?`) const tx = await this.signAndSend([rawTx]) - if (state.proposalStatus === Action.CREATE) { - // get proposal ID from logs + if (state.nextAction === Action.CREATE) { + const proposalFromEvent = tx.events[0].wasm.proposal_id[0] + logger.success(`New proposal created with ID: ${proposalFromEvent}`) + proposalId = Number(proposalFromEvent) } - // If ID Proposal is provided, check the proposal status, and either approve or execute. - // If ID Proposal is not provided, create a new proposal + await this.printPostInstructions(proposalId) - return {} as Result<TransactionResponse> + return { + responses: [ + { + tx, + contract: this.multisig, + }, + ], + data: { + proposalId, + }, + } as Result<TransactionResponse> } } } diff --git a/packages-ts/gauntlet-terra-cw20-multisig/src/lib/utils.ts b/packages-ts/gauntlet-terra-cw20-multisig/src/lib/utils.ts new file mode 100644 index 00000000..07401085 --- /dev/null +++ b/packages-ts/gauntlet-terra-cw20-multisig/src/lib/utils.ts @@ -0,0 +1,13 @@ +import assert from 'assert' + +export const isDeepEqual = (a: any, b: any) => { + try { + assert.deepStrictEqual(a, b) + } catch (error) { + if (error.name === 'AssertionError') { + return false + } + throw error + } + return true +} From be350c4e15dedd5daac26abc94dc702c69da21f2 Mon Sep 17 00:00:00 2001 From: RodrigoAD <15104916+RodrigoAD@users.noreply.github.com> Date: Wed, 16 Feb 2022 17:18:00 +0100 Subject: [PATCH 5/7] more detailed state --- .../src/commands/multisig.ts | 43 +++++++++++++------ 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/packages-ts/gauntlet-terra-cw20-multisig/src/commands/multisig.ts b/packages-ts/gauntlet-terra-cw20-multisig/src/commands/multisig.ts index eaf97514..a72f8195 100644 --- a/packages-ts/gauntlet-terra-cw20-multisig/src/commands/multisig.ts +++ b/packages-ts/gauntlet-terra-cw20-multisig/src/commands/multisig.ts @@ -40,6 +40,8 @@ enum Action { type State = { threshold: number nextAction: Action + owners: AccAddress[] + approvers: string[] // https://github.com/CosmWasm/cw-plus/blob/82138f9484e538913f7faf78bc292fb14407aae8/packages/cw3/src/query.rs#L75 currentStatus?: 'pending' | 'open' | 'rejected' | 'passed' | 'executed' data?: WasmMsg[] @@ -49,6 +51,7 @@ export const wrapCommand = (command) => { return class Multisig extends TerraCommand { command: TerraCommand multisig: AccAddress + multisigGroup: AccAddress static id = `${command.id}:multisig` @@ -58,7 +61,9 @@ export const wrapCommand = (command) => { this.command = new command(flags, args) if (!AccAddress.validate(process.env.MULTISIG_ADDRESS)) throw new Error(`Invalid Multisig wallet address`) + if (!AccAddress.validate(process.env.MULTISIG_GROUP)) throw new Error(`Invalid Multisig group address`) this.multisig = process.env.MULTISIG_ADDRESS as AccAddress + this.multisigGroup = process.env.MULTISIG_GROUP as AccAddress } makeRawTransaction = async (signer: AccAddress, state?: State) => { @@ -135,6 +140,10 @@ export const wrapCommand = (command) => { } fetchState = async (proposalId?: number): Promise<State> => { + const groupState = await this.query(this.multisigGroup, { + list_members: {}, + }) + const owners = groupState.members.map((m) => m.addr) const thresholdState = await this.query(this.multisig, { threshold: {}, }) @@ -143,17 +152,20 @@ export const wrapCommand = (command) => { return { threshold, nextAction: Action.CREATE, + owners, + approvers: [], } } - const proposalState = await this.query(this.multisig, { proposal: { proposal_id: proposalId, }, }) - - // TODO: Fetch owners and add them to state - + const votes = await this.query(this.multisig, { + list_votes: { + proposal_id: proposalId, + }, + }) const status = proposalState.status const toNextAction = { passed: Action.EXECUTE, @@ -165,24 +177,23 @@ export const wrapCommand = (command) => { return { threshold, nextAction: toNextAction[status], + owners, currentStatus: status, data: proposalState.msgs, + approvers: votes.votes.filter((v) => v.vote === Vote.YES).map((v) => v.voter), } } printPostInstructions = async (proposalId: number) => { const state = await this.fetchState(proposalId) - // TODO: Calculate approvals left - const approvalsLeft = state.threshold - 1 + const approvalsLeft = state.threshold - state.approvers.length const messages = { [Action.APPROVE]: `The proposal needs ${approvalsLeft} more approvals. Run the same command with the flag --proposal=${proposalId}`, [Action.EXECUTE]: `The proposal reached the threshold and can be executed. Run the same command with the flag --proposal=${proposalId}`, [Action.NONE]: `The proposal has been executed. No more actions needed`, } logger.line() - logger.info(`Next Actions: - ${messages[state.nextAction]} - `) + logger.info(`${messages[state.nextAction]}`) logger.line() } @@ -196,11 +207,15 @@ export const wrapCommand = (command) => { } const rawTx = await this.makeRawTransaction(this.wallet.key.accAddress, state) - console.info(` - Proposal State: - - Threshold: ${state.threshold} - - Next Action: ${state.nextAction.toUpperCase()} - - Owners: TODO + logger.info(`Proposal State: + - Total Owners: ${state.owners.length} + - Owners List: ${state.owners} + + - Threshold: ${state.threshold} + - Total Approvers: ${state.approvers.length} + - Approvers List: ${state.approvers} + + - Next Action: ${state.nextAction.toUpperCase()} `) const actionMessage = { From 076a163155a26776a9325dd70933cf7f53564949 Mon Sep 17 00:00:00 2001 From: RodrigoAD <15104916+RodrigoAD@users.noreply.github.com> Date: Thu, 17 Feb 2022 13:24:54 +0100 Subject: [PATCH 6/7] execute option on multisig --- .../src/commands/multisig.ts | 41 +++++++++++++++---- .../src/commands/internal/terra.ts | 2 + 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/packages-ts/gauntlet-terra-cw20-multisig/src/commands/multisig.ts b/packages-ts/gauntlet-terra-cw20-multisig/src/commands/multisig.ts index a72f8195..f0b16c0c 100644 --- a/packages-ts/gauntlet-terra-cw20-multisig/src/commands/multisig.ts +++ b/packages-ts/gauntlet-terra-cw20-multisig/src/commands/multisig.ts @@ -223,26 +223,51 @@ export const wrapCommand = (command) => { [Action.APPROVE]: 'APPROVING', [Action.EXECUTE]: 'EXECUTING', } - await prompt(`Continue ${actionMessage[state.nextAction]} proposal?`) - const tx = await this.signAndSend([rawTx]) - if (state.nextAction === Action.CREATE) { - const proposalFromEvent = tx.events[0].wasm.proposal_id[0] - logger.success(`New proposal created with ID: ${proposalFromEvent}`) - proposalId = Number(proposalFromEvent) + if (this.flags.execute) { + await prompt(`Continue ${actionMessage[state.nextAction]} proposal?`) + const tx = await this.signAndSend([rawTx]) + + if (state.nextAction === Action.CREATE) { + const proposalFromEvent = tx.events[0].wasm.proposal_id[0] + logger.success(`New proposal created with ID: ${proposalFromEvent}`) + proposalId = Number(proposalFromEvent) + } + + await this.printPostInstructions(proposalId) + + return { + responses: [ + { + tx, + contract: this.multisig, + }, + ], + data: { + proposalId, + }, + } as Result<TransactionResponse> } - await this.printPostInstructions(proposalId) + // TODO: Test raw message + const msgData = Buffer.from(JSON.stringify(rawTx.execute_msg)).toString('base64') + logger.line() + logger.success(`Message generated succesfully for ${actionMessage[state.nextAction]} proposal`) + logger.log() + logger.log(msgData) + logger.log() + logger.line() return { responses: [ { - tx, + tx: {}, contract: this.multisig, }, ], data: { proposalId, + message: msgData, }, } as Result<TransactionResponse> } diff --git a/packages-ts/gauntlet-terra/src/commands/internal/terra.ts b/packages-ts/gauntlet-terra/src/commands/internal/terra.ts index cbc5eb67..d62a3178 100644 --- a/packages-ts/gauntlet-terra/src/commands/internal/terra.ts +++ b/packages-ts/gauntlet-terra/src/commands/internal/terra.ts @@ -66,6 +66,7 @@ export default abstract class TerraCommand extends WriteCommand<TransactionRespo signAndSend = async (messages: MsgExecuteContract[]): Promise<TransactionResponse> => { try { + logger.loading('Signing transaction...') const tx = await this.wallet.createAndSignTx({ msgs: messages, ...(this.wallet.key instanceof LedgerKey && { @@ -73,6 +74,7 @@ export default abstract class TerraCommand extends WriteCommand<TransactionRespo }), }) + logger.loading('Sending transaction...') const res = await this.provider.tx.broadcast(tx) logger.debug(res) From 45a7bd08176895e935185659d2c4f6aa5041a3b6 Mon Sep 17 00:00:00 2001 From: RodrigoAD <15104916+RodrigoAD@users.noreply.github.com> Date: Fri, 18 Feb 2022 11:40:43 +0100 Subject: [PATCH 7/7] refactor --- .../networks/.env.bombay-testnet | 5 +++-- .../gauntlet-terra-contracts/src/index.ts | 2 +- .../src/lib/constants.ts | 2 +- packages-ts/gauntlet-terra-cw-plus/README.md | 1 + .../package.json | 4 ++-- .../src/commands/multisig.ts | 20 +++++++++---------- .../src/index.ts | 0 .../src/lib/utils.ts | 0 .../tsconfig.json | 0 .../gauntlet-terra-cw20-multisig/README.md | 1 - .../src/commands/internal/terra.ts | 8 ++------ tsconfig.json | 2 +- 12 files changed, 21 insertions(+), 24 deletions(-) create mode 100644 packages-ts/gauntlet-terra-cw-plus/README.md rename packages-ts/{gauntlet-terra-cw20-multisig => gauntlet-terra-cw-plus}/package.json (88%) rename packages-ts/{gauntlet-terra-cw20-multisig => gauntlet-terra-cw-plus}/src/commands/multisig.ts (91%) rename packages-ts/{gauntlet-terra-cw20-multisig => gauntlet-terra-cw-plus}/src/index.ts (100%) rename packages-ts/{gauntlet-terra-cw20-multisig => gauntlet-terra-cw-plus}/src/lib/utils.ts (100%) rename packages-ts/{gauntlet-terra-cw20-multisig => gauntlet-terra-cw-plus}/tsconfig.json (100%) delete mode 100644 packages-ts/gauntlet-terra-cw20-multisig/README.md diff --git a/packages-ts/gauntlet-terra-contracts/networks/.env.bombay-testnet b/packages-ts/gauntlet-terra-contracts/networks/.env.bombay-testnet index 15fc2f61..f659c2de 100644 --- a/packages-ts/gauntlet-terra-contracts/networks/.env.bombay-testnet +++ b/packages-ts/gauntlet-terra-contracts/networks/.env.bombay-testnet @@ -4,5 +4,6 @@ DEFAULT_GAS_PRICE=0.5 LINK=terra1fcksmfjncl6m7apvpalvhwv5jxd9djv5lwyu82 BILLING_ACCESS_CONTROLLER=terra1trcufj64y53hxk7g8cra33xw3jkyvlr9lu99eu REQUESTER_ACCESS_CONTROLLER=terra1s38kfu4qp0ttwxkka9zupaysefl5qruhv5rc0z -MULTISIG_GROUP=terra168lv95kfm49y9zu0409jmplj756ukxdrew7uta -MULTISIG_WALLET=terra1u89pduw4enewduy9qydj925738cyn9juszgj54 + +CW4_GROUP=terra1edk45cc6rckjszfmr87qfx50pfn2mnhg5mn3vd +CW3_FLEX_MULTISIG=terra1cql0r4csmce0ntf68dmkvu3negs7m662uyg90g diff --git a/packages-ts/gauntlet-terra-contracts/src/index.ts b/packages-ts/gauntlet-terra-contracts/src/index.ts index adbb36dd..ef5a87fa 100644 --- a/packages-ts/gauntlet-terra-contracts/src/index.ts +++ b/packages-ts/gauntlet-terra-contracts/src/index.ts @@ -1,5 +1,5 @@ import { executeCLI } from '@chainlink/gauntlet-core' -import { multisigWrapCommand } from '@chainlink/gauntlet-terra-cw20-multisig' +import { multisigWrapCommand } from '@chainlink/gauntlet-terra-cw-plus' import { existsSync } from 'fs' import path from 'path' import { io } from '@chainlink/gauntlet-core/dist/utils' diff --git a/packages-ts/gauntlet-terra-contracts/src/lib/constants.ts b/packages-ts/gauntlet-terra-contracts/src/lib/constants.ts index 20cb82fe..228a97ec 100644 --- a/packages-ts/gauntlet-terra-contracts/src/lib/constants.ts +++ b/packages-ts/gauntlet-terra-contracts/src/lib/constants.ts @@ -11,7 +11,7 @@ export const enum CATEGORIES { DEVIATION_FLAGGING_VALIDATOR = 'Devaiation Flagging Validator', } -export const DEFAULT_RELEASE_VERSION = 'v0.0.4' +export const DEFAULT_RELEASE_VERSION = 'local' export const DEFAULT_CWPLUS_VERSION = 'v0.9.1' export const ORACLES_MAX_LENGTH = 31 diff --git a/packages-ts/gauntlet-terra-cw-plus/README.md b/packages-ts/gauntlet-terra-cw-plus/README.md new file mode 100644 index 00000000..3c95c93f --- /dev/null +++ b/packages-ts/gauntlet-terra-cw-plus/README.md @@ -0,0 +1 @@ +# Gauntlet Terra CW Plus \ No newline at end of file diff --git a/packages-ts/gauntlet-terra-cw20-multisig/package.json b/packages-ts/gauntlet-terra-cw-plus/package.json similarity index 88% rename from packages-ts/gauntlet-terra-cw20-multisig/package.json rename to packages-ts/gauntlet-terra-cw-plus/package.json index d50505f5..c7f36436 100644 --- a/packages-ts/gauntlet-terra-cw20-multisig/package.json +++ b/packages-ts/gauntlet-terra-cw-plus/package.json @@ -1,7 +1,7 @@ { - "name": "@chainlink/gauntlet-terra-cw20-multisig", + "name": "@chainlink/gauntlet-terra-cw-plus", "version": "0.0.1", - "description": "Gauntlet Terra Cw20 Multisig", + "description": "Gauntlet Terra CW Plus contracts", "keywords": [ "typescript", "cli" diff --git a/packages-ts/gauntlet-terra-cw20-multisig/src/commands/multisig.ts b/packages-ts/gauntlet-terra-cw-plus/src/commands/multisig.ts similarity index 91% rename from packages-ts/gauntlet-terra-cw20-multisig/src/commands/multisig.ts rename to packages-ts/gauntlet-terra-cw-plus/src/commands/multisig.ts index f0b16c0c..c15d5ce0 100644 --- a/packages-ts/gauntlet-terra-cw20-multisig/src/commands/multisig.ts +++ b/packages-ts/gauntlet-terra-cw-plus/src/commands/multisig.ts @@ -60,19 +60,19 @@ export const wrapCommand = (command) => { this.command = new command(flags, args) - if (!AccAddress.validate(process.env.MULTISIG_ADDRESS)) throw new Error(`Invalid Multisig wallet address`) - if (!AccAddress.validate(process.env.MULTISIG_GROUP)) throw new Error(`Invalid Multisig group address`) - this.multisig = process.env.MULTISIG_ADDRESS as AccAddress - this.multisigGroup = process.env.MULTISIG_GROUP as AccAddress + if (!AccAddress.validate(process.env.CW3_FLEX_MULTISIG)) throw new Error(`Invalid Multisig wallet address`) + if (!AccAddress.validate(process.env.CW4_GROUP)) throw new Error(`Invalid Multisig group address`) + this.multisig = process.env.CW3_FLEX_MULTISIG as AccAddress + this.multisigGroup = process.env.CW4_GROUP as AccAddress } makeRawTransaction = async (signer: AccAddress, state?: State) => { const message = await this.command.makeRawTransaction(this.multisig) const operations = { - [Action.CREATE]: this.executePropose, - [Action.APPROVE]: this.executeApproval, - [Action.EXECUTE]: this.executeExecution, + [Action.CREATE]: this.makeProposeTransaction, + [Action.APPROVE]: this.makeAcceptTransaction, + [Action.EXECUTE]: this.makeExecuteTransaction, [Action.NONE]: () => { throw new Error('No action needed') }, @@ -104,7 +104,7 @@ export const wrapCommand = (command) => { } } - executePropose: ProposalAction = async (signer, _, message) => { + makeProposeTransaction: ProposalAction = async (signer, _, message) => { logger.info('Generating data for creating new proposal') const proposeInput = { propose: { @@ -118,7 +118,7 @@ export const wrapCommand = (command) => { return new MsgExecuteContract(signer, this.multisig, proposeInput) } - executeApproval: ProposalAction = async (signer, proposalId) => { + makeAcceptTransaction: ProposalAction = async (signer, proposalId) => { logger.info(`Generating data for approving proposal ${proposalId}`) const approvalInput = { vote: { @@ -129,7 +129,7 @@ export const wrapCommand = (command) => { return new MsgExecuteContract(signer, this.multisig, approvalInput) } - executeExecution: ProposalAction = async (signer, proposalId) => { + makeExecuteTransaction: ProposalAction = async (signer, proposalId) => { logger.info(`Generating data for executing proposal ${proposalId}`) const executeInput = { execute: { diff --git a/packages-ts/gauntlet-terra-cw20-multisig/src/index.ts b/packages-ts/gauntlet-terra-cw-plus/src/index.ts similarity index 100% rename from packages-ts/gauntlet-terra-cw20-multisig/src/index.ts rename to packages-ts/gauntlet-terra-cw-plus/src/index.ts diff --git a/packages-ts/gauntlet-terra-cw20-multisig/src/lib/utils.ts b/packages-ts/gauntlet-terra-cw-plus/src/lib/utils.ts similarity index 100% rename from packages-ts/gauntlet-terra-cw20-multisig/src/lib/utils.ts rename to packages-ts/gauntlet-terra-cw-plus/src/lib/utils.ts diff --git a/packages-ts/gauntlet-terra-cw20-multisig/tsconfig.json b/packages-ts/gauntlet-terra-cw-plus/tsconfig.json similarity index 100% rename from packages-ts/gauntlet-terra-cw20-multisig/tsconfig.json rename to packages-ts/gauntlet-terra-cw-plus/tsconfig.json diff --git a/packages-ts/gauntlet-terra-cw20-multisig/README.md b/packages-ts/gauntlet-terra-cw20-multisig/README.md deleted file mode 100644 index e5c408c6..00000000 --- a/packages-ts/gauntlet-terra-cw20-multisig/README.md +++ /dev/null @@ -1 +0,0 @@ -# Gauntlet Terra CW20 Multisig \ No newline at end of file diff --git a/packages-ts/gauntlet-terra/src/commands/internal/terra.ts b/packages-ts/gauntlet-terra/src/commands/internal/terra.ts index d62a3178..ee6298ee 100644 --- a/packages-ts/gauntlet-terra/src/commands/internal/terra.ts +++ b/packages-ts/gauntlet-terra/src/commands/internal/terra.ts @@ -76,12 +76,10 @@ export default abstract class TerraCommand extends WriteCommand<TransactionRespo logger.loading('Sending transaction...') const res = await this.provider.tx.broadcast(tx) - - logger.debug(res) return this.wrapResponse(res) } catch (e) { - const details = e.response.data - throw new Error(details.message) + const message = e?.response?.data?.message || e.message + throw new Error(message) } } @@ -96,8 +94,6 @@ export default abstract class TerraCommand extends WriteCommand<TransactionRespo }) const res = await this.provider.tx.broadcast(tx) - - logger.debug(res) return this.wrapResponse(res) } diff --git a/tsconfig.json b/tsconfig.json index a6bd767f..e99b113c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -7,7 +7,7 @@ "path": "./packages-ts/gauntlet-terra" }, { - "path": "./packages-ts/gauntlet-terra-cw20-multisig" + "path": "./packages-ts/gauntlet-terra-cw-plus" }, { "path": "./packages-ts/gauntlet-terra-contracts"