Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: chain manager cron allow managing schedules #ntrn-387 #57

Merged
merged 11 commits into from
Sep 16, 2024
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"@cosmjs/cosmwasm-stargate": "^0.32.4",
"@cosmjs/proto-signing": "^0.32.4",
"@cosmjs/stargate": "0.32.4",
"@neutron-org/cosmjs-types": "0.9.2-rc1",
"@neutron-org/neutronjs": "https://github.com/neutron-org/neutronjs.git#7f45328320b53b4fa2b572bc25bb96bf80260181",
"axios": "1.6.0",
"bip39": "^3.1.0",
"long": "^5.2.1",
Expand Down Expand Up @@ -58,4 +58,4 @@
"engines": {
"node": ">=20.0"
}
}
}
2 changes: 1 addition & 1 deletion src/cosmos.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Event as CosmosEvent } from '@cosmjs/stargate';
import { IndexedTx } from '@cosmjs/stargate';
import crypto from "crypto";
import crypto from 'crypto';

export const getSequenceId = (tx: IndexedTx | undefined): number => {
if (!tx) {
Expand Down
60 changes: 37 additions & 23 deletions src/dao.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import {
VotingPowerAtHeightResponse,
} from './types';
import {
addSchedule,
addCronScheduleProposal,
addScheduleBindings,
AddSchedule,
chainManagerWrapper,
clearAdminProposal,
clientUpdateProposal,
Expand All @@ -25,7 +27,9 @@ import {
ParamsTransferInfo,
pinCodesCustomAuthorityProposal,
pinCodesProposal,
removeSchedule,
removeCronScheduleProposal,
removeScheduleBindings,
RemoveSchedule,
SendProposalInfo,
unpinCodesProposal,
updateAdminProposal,
Expand All @@ -38,8 +42,9 @@ import {
ExecuteResult,
SigningCosmWasmClient,
} from '@cosmjs/cosmwasm-stargate';
import { ClientState } from '@neutron-org/cosmjs-types/ibc/lightclients/tendermint/v1/tendermint';
import { QueryClientImpl as AdminQueryClient } from '@neutron-org/cosmjs-types/cosmos/adminmodule/adminmodule/query';
import { ClientState } from '@neutron-org/neutronjs/ibc/lightclients/tendermint/v1/tendermint';
import { MsgExecuteContract } from '@neutron-org/neutronjs/neutron/cron/schedule';
import { QueryClientImpl as AdminQueryClient } from '@neutron-org/neutronjs/cosmos/adminmodule/adminmodule/query.rpc.Query';
import { ADMIN_MODULE_ADDRESS } from './constants';
import { DynamicFeesParams, FeeMarketParams } from './proposal';
import { getWithAttempts } from './wait';
Expand Down Expand Up @@ -130,7 +135,7 @@ export const getProposalModules = async (
address: timelockAddr,
};
// eslint-disable-next-line no-empty
} catch (e) {}
} catch (e) { }

proposalsStructure[moduleType] = {
address: proposalModule.address,
Expand Down Expand Up @@ -208,7 +213,7 @@ export const getSubDaoContracts = async (
};

export class Dao {
constructor(private client: CosmWasmClient, public contracts: DaoContracts) {}
constructor(private client: CosmWasmClient, public contracts: DaoContracts) { }

async checkPassedProposal(proposalId: number) {
await getWithAttempts(
Expand Down Expand Up @@ -292,12 +297,12 @@ export class Dao {
voting_power_at_height:
typeof height === 'undefined'
? {
address: addr,
}
address: addr,
}
: {
address: addr,
height: height,
},
address: addr,
height: height,
},
});
}

Expand Down Expand Up @@ -379,7 +384,7 @@ export class DaoMember {
private client: SigningCosmWasmClient,
public user: string,
private denom: string,
) {}
) { }

/**
* voteYes vote 'yes' for given proposal.
Expand Down Expand Up @@ -527,7 +532,7 @@ export class DaoMember {
if (proposalId < 0) {
throw new Error(
'failed to get proposal ID from the proposal creation tx attributes: ' +
JSON.stringify(proposalTx.events),
JSON.stringify(proposalTx.events),
);
}
return proposalId;
Expand Down Expand Up @@ -747,7 +752,7 @@ export class DaoMember {
if (proposalId < 0) {
throw new Error(
'failed to get proposal ID from the proposal creation tx attributes: ' +
JSON.stringify(proposalTx.events),
JSON.stringify(proposalTx.events),
);
}
return proposalId;
Expand Down Expand Up @@ -1029,7 +1034,7 @@ export class DaoMember {
if (proposalId < 0) {
throw new Error(
'failed to get proposal ID from the proposal creation tx attributes: ' +
JSON.stringify(proposalTx.events),
JSON.stringify(proposalTx.events),
);
}
return proposalId1;
Expand Down Expand Up @@ -1687,13 +1692,14 @@ export class DaoMember {
title: string,
description: string,
amount: string,
name: string,
period: number,
msgs: any[],
info: AddSchedule,
bindings = false,
): Promise<number> {
const message = chainManagerWrapper(
chainManagerAddress,
addSchedule(name, period, msgs),
bindings
? addScheduleBindings(info.name, info.period, info.msgs)
: addCronScheduleProposal(info),
);
return await this.submitSingleChoiceProposal(
title,
Expand All @@ -1711,9 +1717,10 @@ export class DaoMember {
title: string,
description: string,
amount: string,
name: string,
info: RemoveSchedule,
customModule = 'single',
wrapForChainManager = true,
bindings = false,
): Promise<number> {
// This ugly piece of code is required because we are not going
// to remove the security address functionality from the cron module
Expand All @@ -1724,9 +1731,16 @@ export class DaoMember {
// TODO(pr0n00gler).
let message: any;
if (wrapForChainManager) {
message = chainManagerWrapper(chainManagerAddress, removeSchedule(name));
message = chainManagerWrapper(
chainManagerAddress,
bindings
? removeScheduleBindings(info.name)
: removeCronScheduleProposal(info),
);
} else {
message = removeSchedule(name);
message = bindings
? removeScheduleBindings(info.name)
: removeCronScheduleProposal(info);
}
return await this.submitSingleChoiceProposal(
title,
Expand Down Expand Up @@ -1852,7 +1866,7 @@ export const getNeutronDAOCore = async (
rpcClient: ProtobufRpcClient,
): Promise<string> => {
const queryClient = new AdminQueryClient(rpcClient);
const admins = await queryClient.Admins();
const admins = await queryClient.admins();
const chainManager = admins.admins[0];
const strategies = await client.queryContractSmart(chainManager, {
strategies: {},
Expand Down
62 changes: 53 additions & 9 deletions src/proposal.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Coin } from '@cosmjs/proto-signing';
import { ADMIN_MODULE_ADDRESS } from './constants';
import { MsgExecuteContract } from '@neutron-org/neutronjs/neutron/cron/schedule';

export type ParamChangeProposalInfo = {
title: string;
Expand Down Expand Up @@ -148,12 +149,12 @@ export type MultiChoiceProposal = {
readonly choices: CheckedMultipleChoiceOption[];
// Proposal status (Open, rejected, executed, execution failed, closed, passed)
readonly status:
| 'open'
| 'rejected'
| 'passed'
| 'executed'
| 'closed'
| 'execution_failed';
| 'open'
| 'rejected'
| 'passed'
| 'executed'
| 'closed'
| 'execution_failed';
// Voting settings (threshold, quorum, etc.)
readonly voting_strategy: VotingStrategy;
// The total power when the proposal started (used to calculate percentages)
Expand Down Expand Up @@ -689,10 +690,10 @@ export const sendProposal = (info: SendProposalInfo): any => ({
},
});

export const addSchedule = (
export const addScheduleBindings = (
name: string,
period: number,
msgs: string[],
msgs: MsgExecuteContract[],
): any => ({
custom: {
add_schedule: {
Expand All @@ -703,7 +704,7 @@ export const addSchedule = (
},
});

export const removeSchedule = (name: string): any => ({
export const removeScheduleBindings = (name: string): any => ({
custom: {
remove_schedule: {
name,
Expand Down Expand Up @@ -748,6 +749,49 @@ export const updateDynamicFeesParamsProposal = (
},
});

export interface AddSchedule {
name: string;
period: number;
msgs: MsgExecuteContract[];
execution_stage: string;
}

export interface RemoveSchedule {
name: string;
}

export const addCronScheduleProposal = (info: AddSchedule): any => ({
custom: {
submit_admin_proposal: {
admin_proposal: {
proposal_execute_message: {
message: JSON.stringify({
'@type': '/neutron.cron.MsgAddSchedule',
authority: ADMIN_MODULE_ADDRESS,
...info,
}),
},
},
},
},
});

export const removeCronScheduleProposal = (info: RemoveSchedule): any => ({
custom: {
submit_admin_proposal: {
admin_proposal: {
proposal_execute_message: {
message: JSON.stringify({
'@type': '/neutron.cron.MsgRemoveSchedule',
authority: ADMIN_MODULE_ADDRESS,
...info,
}),
},
},
},
},
});

export const updateConsensusParamsProposal = (
params: ConsensusParams,
): any => ({
Expand Down
38 changes: 6 additions & 32 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1184,10 +1184,9 @@
"@jridgewell/resolve-uri" "^3.1.0"
"@jridgewell/sourcemap-codec" "^1.4.14"

"@neutron-org/[email protected]":
version "0.9.2-rc1"
resolved "https://registry.yarnpkg.com/@neutron-org/cosmjs-types/-/cosmjs-types-0.9.2-rc1.tgz#ca1fc1dc9566858dbd765e8f82c8a70097bcc84b"
integrity sha512-ju2AqJ14yO4+JF8RwY4ZVy7f2HVjhdf66SfhS6y4ucBZm997/E/yYVMnpWmUncVg8ARooISOKaOYNagqz0am6Q==
"@neutron-org/neutronjs@https://github.com/neutron-org/neutronjs.git#7f45328320b53b4fa2b572bc25bb96bf80260181":
version "4.2.0"
resolved "https://github.com/neutron-org/neutronjs.git#7f45328320b53b4fa2b572bc25bb96bf80260181"

"@noble/[email protected]", "@noble/curves@~1.4.0":
version "1.4.2"
Expand Down Expand Up @@ -3176,16 +3175,7 @@ string-argv@^0.3.1:
resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.2.tgz#2b6d0ef24b656274d957d54e0a4bbf6153dc02b6"
integrity sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==

"string-width-cjs@npm:string-width@^4.2.0":
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
dependencies:
emoji-regex "^8.0.0"
is-fullwidth-code-point "^3.0.0"
strip-ansi "^6.0.1"

string-width@^4.1.0, string-width@^4.2.0:
"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0:
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
Expand All @@ -3203,14 +3193,7 @@ string-width@^5.0.0, string-width@^5.0.1, string-width@^5.1.2:
emoji-regex "^9.2.2"
strip-ansi "^7.0.1"

"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
dependencies:
ansi-regex "^5.0.1"

strip-ansi@^6.0.0, strip-ansi@^6.0.1:
"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
Expand Down Expand Up @@ -3446,7 +3429,7 @@ word-wrap@^1.2.5:
resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34"
integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==

"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
Expand All @@ -3464,15 +3447,6 @@ wrap-ansi@^6.2.0:
string-width "^4.1.0"
strip-ansi "^6.0.0"

wrap-ansi@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
dependencies:
ansi-styles "^4.0.0"
string-width "^4.1.0"
strip-ansi "^6.0.0"

wrap-ansi@^8.1.0:
version "8.1.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"
Expand Down