From c403fa0da05a579028992672f7918bb7f0033033 Mon Sep 17 00:00:00 2001 From: RodrigoAD <15104916+RodrigoAD@users.noreply.github.com> Date: Fri, 14 Jan 2022 14:04:07 +0100 Subject: [PATCH] ownership commands for every program --- .../contracts/accessController/index.ts | 11 +++- .../src/commands/contracts/ocr2/index.ts | 5 ++ .../contracts/ownership/acceptOwnership.ts | 54 +++++++++++++++++ .../src/commands/contracts/ownership/index.ts | 7 +++ .../contracts/ownership/transferOwnership.ts | 60 +++++++++++++++++++ .../contracts/store/acceptOwnership.ts | 49 --------------- .../src/commands/contracts/store/index.ts | 9 +-- .../contracts/store/transferOwnership.ts | 53 ---------------- .../src/lib/types.ts | 4 ++ 9 files changed, 145 insertions(+), 107 deletions(-) create mode 100644 gauntlet/packages/gauntlet-solana-contracts/src/commands/contracts/ownership/acceptOwnership.ts create mode 100644 gauntlet/packages/gauntlet-solana-contracts/src/commands/contracts/ownership/index.ts create mode 100644 gauntlet/packages/gauntlet-solana-contracts/src/commands/contracts/ownership/transferOwnership.ts delete mode 100644 gauntlet/packages/gauntlet-solana-contracts/src/commands/contracts/store/acceptOwnership.ts delete mode 100644 gauntlet/packages/gauntlet-solana-contracts/src/commands/contracts/store/transferOwnership.ts diff --git a/gauntlet/packages/gauntlet-solana-contracts/src/commands/contracts/accessController/index.ts b/gauntlet/packages/gauntlet-solana-contracts/src/commands/contracts/accessController/index.ts index 8149b8e8e..22d90ae5b 100644 --- a/gauntlet/packages/gauntlet-solana-contracts/src/commands/contracts/accessController/index.ts +++ b/gauntlet/packages/gauntlet-solana-contracts/src/commands/contracts/accessController/index.ts @@ -1,5 +1,14 @@ import Initialize from './initialize' import AddAccess from './addAccess' import ReadState from './read' +import { makeAcceptOwnershipCommand } from '../ownership/acceptOwnership' +import { makeTransferOwnershipCommand } from '../ownership/transferOwnership' +import { CONTRACT_LIST } from '../../../lib/contracts' -export default [Initialize, AddAccess, ReadState] +export default [ + Initialize, + AddAccess, + ReadState, + makeAcceptOwnershipCommand(CONTRACT_LIST.ACCESS_CONTROLLER), + makeTransferOwnershipCommand(CONTRACT_LIST.ACCESS_CONTROLLER), +] diff --git a/gauntlet/packages/gauntlet-solana-contracts/src/commands/contracts/ocr2/index.ts b/gauntlet/packages/gauntlet-solana-contracts/src/commands/contracts/ocr2/index.ts index d98b6cbb1..603f4358c 100644 --- a/gauntlet/packages/gauntlet-solana-contracts/src/commands/contracts/ocr2/index.ts +++ b/gauntlet/packages/gauntlet-solana-contracts/src/commands/contracts/ocr2/index.ts @@ -15,6 +15,9 @@ import SetupFlow from './setup.dev.flow' import SetupRDDFlow from './setup.dev.rdd.flow' import Transmit from './transmit.dev' import Inspection from './inspection' +import { makeAcceptOwnershipCommand } from '../ownership/acceptOwnership' +import { CONTRACT_LIST } from '../../../lib/contracts' +import { makeTransferOwnershipCommand } from '../ownership/transferOwnership' export default [ Initialize, @@ -36,4 +39,6 @@ export default [ Transmit, SetupFlow, SetupRDDFlow, + makeAcceptOwnershipCommand(CONTRACT_LIST.OCR_2), + makeTransferOwnershipCommand(CONTRACT_LIST.OCR_2), ] diff --git a/gauntlet/packages/gauntlet-solana-contracts/src/commands/contracts/ownership/acceptOwnership.ts b/gauntlet/packages/gauntlet-solana-contracts/src/commands/contracts/ownership/acceptOwnership.ts new file mode 100644 index 000000000..a0bd7849e --- /dev/null +++ b/gauntlet/packages/gauntlet-solana-contracts/src/commands/contracts/ownership/acceptOwnership.ts @@ -0,0 +1,54 @@ +import { Result } from '@chainlink/gauntlet-core' +import { logger, prompt } from '@chainlink/gauntlet-core/dist/utils' +import { SolanaCommand, TransactionResponse } from '@chainlink/gauntlet-solana' +import { PublicKey } from '@solana/web3.js' +import { CONTRACT_LIST, getContract } from '../../../lib/contracts' +import { SolanaConstructor } from '../../../lib/types' + +export const makeAcceptOwnershipCommand = (contractId: CONTRACT_LIST): SolanaConstructor => { + return class AcceptOwnership extends SolanaCommand { + static id = `${contractId}:accept_ownership` + static category = contractId + + static examples = [`yarn gauntlet ${contractId}:accept_ownership --network=devnet --state=[PROGRAM_STATE]`] + + constructor(flags, args) { + super(flags, args) + + this.require(!!this.flags.state, 'Please provide flags with "state"') + } + + execute = async () => { + const contract = getContract(contractId, '') + const address = contract.programId.toString() + const program = this.loadProgram(contract.idl, address) + + const owner = this.wallet.payer + + const state = new PublicKey(this.flags.state) + + await prompt(`Accepting ownership of ${contractId} state (${state.toString()}). Continue?`) + + const tx = await program.rpc.acceptOwnership({ + accounts: { + // Store contract expects an store account instead of a state acc + ...(contractId === CONTRACT_LIST.STORE && { store: state }), + ...(contractId !== CONTRACT_LIST.STORE && { state }), + authority: owner.publicKey, + }, + signers: [owner], + }) + + logger.success(`Accepted ownership on tx ${tx}`) + + return { + responses: [ + { + tx: this.wrapResponse(tx, state.toString(), { state: state.toString() }), + contract: state.toString(), + }, + ], + } as Result + } + } +} diff --git a/gauntlet/packages/gauntlet-solana-contracts/src/commands/contracts/ownership/index.ts b/gauntlet/packages/gauntlet-solana-contracts/src/commands/contracts/ownership/index.ts new file mode 100644 index 000000000..ec33d0e10 --- /dev/null +++ b/gauntlet/packages/gauntlet-solana-contracts/src/commands/contracts/ownership/index.ts @@ -0,0 +1,7 @@ +import { makeTransferOwnershipCommand } from './transferOwnership' +import { makeAcceptOwnershipCommand } from './acceptOwnership' + +export default { + makeTransferOwnershipCommand, + makeAcceptOwnershipCommand, +} diff --git a/gauntlet/packages/gauntlet-solana-contracts/src/commands/contracts/ownership/transferOwnership.ts b/gauntlet/packages/gauntlet-solana-contracts/src/commands/contracts/ownership/transferOwnership.ts new file mode 100644 index 000000000..df9cf62c0 --- /dev/null +++ b/gauntlet/packages/gauntlet-solana-contracts/src/commands/contracts/ownership/transferOwnership.ts @@ -0,0 +1,60 @@ +import { Result } from '@chainlink/gauntlet-core' +import { logger, prompt } from '@chainlink/gauntlet-core/dist/utils' +import { SolanaCommand, TransactionResponse } from '@chainlink/gauntlet-solana' +import { PublicKey } from '@solana/web3.js' +import { CONTRACT_LIST, getContract } from '../../../lib/contracts' +import { SolanaConstructor } from '../../../lib/types' + +export const makeTransferOwnershipCommand = (contractId: CONTRACT_LIST): SolanaConstructor => { + return class TransferOwnership extends SolanaCommand { + static id = `${contractId}:transfer_ownership` + static category = contractId + + static examples = [ + `yarn gauntlet ${contractId}:transfer_ownership --network=devnet --state=[PROGRAM_STATE] --to=[PROPOSED_OWNER]`, + ] + + constructor(flags, args) { + super(flags, args) + + this.require(!!this.flags.state, 'Please provide flags with "state"') + this.require(!!this.flags.to, 'Please provide flags with "to"') + } + + execute = async () => { + const contract = getContract(contractId, '') + const address = contract.programId.toString() + const program = this.loadProgram(contract.idl, address) + + const owner = this.wallet.payer + + const state = new PublicKey(this.flags.state) + const proposedOwner = new PublicKey(this.flags.to) + + await prompt( + `Transfering ownership of ${contractId} state (${state.toString()}) to: (${proposedOwner.toString()}). Continue?`, + ) + + const tx = await program.rpc.transferOwnership(proposedOwner, { + accounts: { + // Store contract expects an store account instead of a state acc + ...(contractId === CONTRACT_LIST.STORE && { store: state }), + ...(contractId !== CONTRACT_LIST.STORE && { state }), + authority: owner.publicKey, + }, + signers: [owner], + }) + + logger.success(`Ownership transferred to ${proposedOwner.toString()} on tx ${tx}`) + + return { + responses: [ + { + tx: this.wrapResponse(tx, state.toString(), { state: state.toString() }), + contract: state.toString(), + }, + ], + } as Result + } + } +} diff --git a/gauntlet/packages/gauntlet-solana-contracts/src/commands/contracts/store/acceptOwnership.ts b/gauntlet/packages/gauntlet-solana-contracts/src/commands/contracts/store/acceptOwnership.ts deleted file mode 100644 index cd6316243..000000000 --- a/gauntlet/packages/gauntlet-solana-contracts/src/commands/contracts/store/acceptOwnership.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { Result } from '@chainlink/gauntlet-core' -import { logger, prompt } from '@chainlink/gauntlet-core/dist/utils' -import { SolanaCommand, TransactionResponse } from '@chainlink/gauntlet-solana' -import { PublicKey } from '@solana/web3.js' -import { CONTRACT_LIST, getContract } from '../../../lib/contracts' - -export default class AcceptOwnership extends SolanaCommand { - static id = 'store:accept_ownership' - static category = CONTRACT_LIST.STORE - - static examples = ['yarn gauntlet store:accept_ownership --network=devnet --state=[STORE_STATE]'] - - constructor(flags, args) { - super(flags, args) - - this.require(!!this.flags.state, 'Please provide flags with "state"') - } - - execute = async () => { - const store = getContract(CONTRACT_LIST.STORE, '') - const storeAddress = store.programId.toString() - const storeProgram = this.loadProgram(store.idl, storeAddress) - - const owner = this.wallet.payer - - const storeState = new PublicKey(this.flags.state) - - await prompt(`Accepting ownership of store state (${storeState.toString()}). Continue?`) - - const tx = await storeProgram.rpc.acceptOwnership({ - accounts: { - store: storeState, - authority: owner.publicKey, - }, - signers: [owner], - }) - - logger.success(`Accepted ownership on tx ${tx}`) - - return { - responses: [ - { - tx: this.wrapResponse(tx, storeState.toString(), { state: storeState.toString() }), - contract: storeState.toString(), - }, - ], - } as Result - } -} diff --git a/gauntlet/packages/gauntlet-solana-contracts/src/commands/contracts/store/index.ts b/gauntlet/packages/gauntlet-solana-contracts/src/commands/contracts/store/index.ts index 793adc9ba..ab725763d 100644 --- a/gauntlet/packages/gauntlet-solana-contracts/src/commands/contracts/store/index.ts +++ b/gauntlet/packages/gauntlet-solana-contracts/src/commands/contracts/store/index.ts @@ -2,16 +2,17 @@ import Initialize from './initialize' import CreateFeed from './createFeed' import SetValidatorConfig from './setValidatorConfig' import SetWriter from './setWriter' -import TransferOwnership from './transferOwnership' -import AcceptOwnership from './acceptOwnership' import SetLoweringAccessController from './setLoweringAccessController' +import { makeAcceptOwnershipCommand } from '../ownership/acceptOwnership' +import { makeTransferOwnershipCommand } from '../ownership/transferOwnership' +import { CONTRACT_LIST } from '../../../lib/contracts' export default [ Initialize, CreateFeed, SetValidatorConfig, SetWriter, - TransferOwnership, - AcceptOwnership, SetLoweringAccessController, + makeAcceptOwnershipCommand(CONTRACT_LIST.STORE), + makeTransferOwnershipCommand(CONTRACT_LIST.STORE), ] diff --git a/gauntlet/packages/gauntlet-solana-contracts/src/commands/contracts/store/transferOwnership.ts b/gauntlet/packages/gauntlet-solana-contracts/src/commands/contracts/store/transferOwnership.ts deleted file mode 100644 index 331aa9690..000000000 --- a/gauntlet/packages/gauntlet-solana-contracts/src/commands/contracts/store/transferOwnership.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { Result } from '@chainlink/gauntlet-core' -import { prompt } from '@chainlink/gauntlet-core/dist/utils' -import { SolanaCommand, TransactionResponse } from '@chainlink/gauntlet-solana' -import { PublicKey } from '@solana/web3.js' -import { CONTRACT_LIST, getContract } from '../../../lib/contracts' - -export default class TransferWwnership extends SolanaCommand { - static id = 'store:transfer_ownership' - static category = CONTRACT_LIST.STORE - - static examples = [ - 'yarn gauntlet store:transfer_ownership --network=devnet --state=[STORE_STATE] --to=[PROPOSED_OWNER]', - ] - - constructor(flags, args) { - super(flags, args) - - this.require(!!this.flags.state, 'Please provide flags with "state"') - this.require(!!this.flags.to, 'Please provide flags with "to"') - } - - execute = async () => { - const store = getContract(CONTRACT_LIST.STORE, '') - const storeAddress = store.programId.toString() - const storeProgram = this.loadProgram(store.idl, storeAddress) - - const owner = this.wallet.payer - - const storeState = new PublicKey(this.flags.state) - const proposedOwner = new PublicKey(this.flags.to) - - await prompt( - `Transfering ownership of store state (${storeState.toString()}) to: (${proposedOwner.toString()}). Continue?`, - ) - - const tx = await storeProgram.rpc.transferOwnership(proposedOwner, { - accounts: { - store: storeState, - authority: owner.publicKey, - }, - signers: [owner], - }) - - return { - responses: [ - { - tx: this.wrapResponse(tx, storeState.toString(), { state: storeState.toString() }), - contract: storeState.toString(), - }, - ], - } as Result - } -} diff --git a/gauntlet/packages/gauntlet-solana-contracts/src/lib/types.ts b/gauntlet/packages/gauntlet-solana-contracts/src/lib/types.ts index 6b6338b56..cff8bcb89 100644 --- a/gauntlet/packages/gauntlet-solana-contracts/src/lib/types.ts +++ b/gauntlet/packages/gauntlet-solana-contracts/src/lib/types.ts @@ -1,3 +1,5 @@ +import { SolanaCommand } from '@chainlink/gauntlet-solana' + interface Oracle { signer: Buffer transmitter: Buffer @@ -10,3 +12,5 @@ export interface OCR2Config { offchainConfig: Buffer offchainConfigVersion: number } + +export type SolanaConstructor = new (flags, args) => SolanaCommand