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

Multisig support #37

Merged
merged 37 commits into from
Jan 14, 2022
Merged
Show file tree
Hide file tree
Changes from 33 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
da5e79b
Create multisig command
ebarakos Dec 15, 2021
347448c
Prettier + example
ebarakos Dec 15, 2021
64d7a8f
Merged feature/relay and required changes for running the flow
ebarakos Dec 16, 2021
a386ca2
Merged example with raw transaction; removed log
ebarakos Dec 16, 2021
1682cc3
Change threshold working
ebarakos Dec 17, 2021
1090678
Abstract transaction working with JSON file
ebarakos Dec 17, 2021
595ccf2
Set owners, thredhold and able to run arbitrary transactions directly
ebarakos Dec 17, 2021
937fdf1
Formatting
ebarakos Dec 17, 2021
e949da4
moved multisig into its library
RodrigoAD Dec 21, 2021
06ac89a
fix rebase
RodrigoAD Dec 21, 2021
098f710
multisig command wrapper
RodrigoAD Dec 21, 2021
ba63154
moved cli script
RodrigoAD Jan 4, 2022
60f2f5c
Working, supporting setting threshold owners and example command setB…
ebarakos Jan 5, 2022
a7f8aaa
Prettier
ebarakos Jan 5, 2022
b9a09cc
Merged develop
ebarakos Jan 7, 2022
32f069c
Fixed develop merge
ebarakos Jan 10, 2022
b32a5f0
Merge remote-tracking branch 'origin/develop' into multisig
ebarakos Jan 10, 2022
7dee2c8
Prettier
ebarakos Jan 10, 2022
88d7df5
Addressing review comments, improving flow with single --proposal fla…
ebarakos Jan 11, 2022
0b13f58
Merge remote-tracking branch 'origin/develop' into multisig
ebarakos Jan 11, 2022
223315c
Fix run issue + fix approvals inspection
ebarakos Jan 12, 2022
8117b9c
Merge remote-tracking branch 'origin/develop' into multisig
ebarakos Jan 12, 2022
5ff900f
Merge remote-tracking branch 'origin/develop' into multisig
ebarakos Jan 13, 2022
39d2c10
Fix version issue
ebarakos Jan 13, 2022
f97a470
Moved multisig create to package, fixed creation parameters
ebarakos Jan 13, 2022
bee8977
Able to execute setBilling from any proposal address, on access given…
ebarakos Jan 13, 2022
59cfe46
Restructuring of multisig wrapper command + distint actions UX
ebarakos Jan 14, 2022
0c26070
Merge remote-tracking branch 'origin/develop' into multisig
ebarakos Jan 14, 2022
e77b88d
Small changes
ebarakos Jan 14, 2022
3d619fb
Added README
ebarakos Jan 14, 2022
57f6901
Revert BN imports
ebarakos Jan 14, 2022
bc44992
refactored multisig
RodrigoAD Jan 14, 2022
f6c7206
Fixes
ebarakos Jan 14, 2022
380b528
Revert .map
ebarakos Jan 14, 2022
ab4637a
Move multisigAddress to constructor
ebarakos Jan 14, 2022
3f17a04
remove set billing default value
RodrigoAD Jan 14, 2022
4f366d5
Merge branch 'multisig' of github.com:smartcontractkit/chainlink-sola…
RodrigoAD Jan 14, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion gauntlet/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
"main": "packages/gauntlet-solana-contracts/dist/index.js",
"bin": "packages/gauntlet-solana-contracts/dist/index.js",
"scripts": {
"gauntlet": "yarn build && node ./packages/gauntlet-solana-contracts/dist/index.js",
"gauntlet": "yarn build && node ./packages/gauntlet-solana-contracts/dist/cli.js",
"gauntlet-serum-multisig": "yarn build && node ./packages/gauntlet-serum-multisig/dist/index.js",
"lint": "tsc -b ./tsconfig.json",
"test": "yarn build && SKIP_PROMPTS=true jest --runInBand ./packages",
"test:coverage": "yarn test --collectCoverage",
Expand Down
21 changes: 21 additions & 0 deletions gauntlet/packages/gauntlet-serum-multisig/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2019 Khalid Zoabi

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
40 changes: 40 additions & 0 deletions gauntlet/packages/gauntlet-serum-multisig/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Gauntlet Serum Multisig

## Creating a Multisig

Example with 3 owners and threshold=2

`yarn gauntlet-serum-multisig create --network=local 3W37Aopzbtzczi8XWdkFTvBeSyYgXLuUkaodkq59xBCT ETqajtkz4xcsB397qTBPetprR8jMC3JszkjJJp3cjWJS QMaHW2Fpyet4ZVf7jgrGB6iirZLjwZUjN9vPKcpQrHs --threshold=2`

## Actions

Rest of the commands will adhere to the following flow:

### Create

You run a regular command, and you just replace `gauntlet` with `gauntlet-serum-multisig`.
For e.g if you have this command: `yarn gauntlet ocr2:set_billing --network=local --state=k91NrbTgTt4bo86fXN3SXqUzVvoDRiivxf2KcU1p5Gp`
it becomes:
`yarn gauntlet-serum-multisig ocr2:set_billing --network=local --state=k91NrbTgTt4bo86fXN3SXqUzVvoDRiivxf2KcU1p5Gp`

The creator automatically signs/approves the proposal.
You get a message on console with the proposal PublicKey that you need for continuing on next actions

### Approve/Execute

You run a previously created command and you just append `--proposal` flag,
For e.g for the above: `yarn gauntlet-serum-multisig ocr2:set_billing --network=local --state=k91NrbTgTt4bo86fXN3SXqUzVvoDRiivxf2KcU1p5Gp --proposal=CyU1HR7Ebs4aQVQVabT6KeNFusHqov1nwCpCDs9CRZhw`

If the threshold is met, the proposal is executed. Else, you need to repeat the action for the rest of the owners until the threshold is met.

### Setting owners

Example of setting one more owner to the above created multisig

`yarn gauntlet-serum-multisig set:owners --network=local QMaHW2Fpyet4ZVf7jgrGB6iirZLjwZUjN9vPKcpQrHs ETqajtkz4xcsB397qTBPetprR8jMC3JszkjJJp3cjWJS 3W37Aopzbtzczi8XWdkFTvBeSyYgXLuUkaodkq59xBCT 8i1ZbY9S7VPV4AKVEL1xewyYFvtkrjAnffqfsCf3FoRB`

### Setting threshold

Example of setting threshold to 3

`yarn gauntlet-serum-multisig set:threshold --network=local --threshold=1`
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
NODE_URL=https://api.devnet.solana.com

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
NODE_URL=http://127.0.0.1:8899
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
NODE_URL=https://api.testnet.solana.com
34 changes: 34 additions & 0 deletions gauntlet/packages/gauntlet-serum-multisig/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"name": "@chainlink/gauntlet-serum-multisig",
"version": "0.0.1",
"description": "Gauntlet Serum Multisig",
"keywords": [
"typescript",
"cli"
],
"main": "./dist/index.js",
"types": "dist/index.d.ts",
"files": [
"dist/**/*",
"!dist/**/*.test.js"
],
"scripts": {
"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-solana": "*",
"@chainlink/gauntlet-solana-contracts": "*",
"@project-serum/anchor": "^0.20.0",
"@solana/web3.js": "^1.30.2"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { Result } from '@chainlink/gauntlet-core'
import { logger } from '@chainlink/gauntlet-core/dist/utils'
import { SolanaCommand, TransactionResponse } from '@chainlink/gauntlet-solana'
import { PublicKey, SYSVAR_RENT_PUBKEY, Keypair } from '@solana/web3.js'
import BN from 'bn.js'
import { CONTRACT_LIST, getContract } from '@chainlink/gauntlet-solana-contracts'

type Input = {
owners: string[]
threshold: number | string
}

const DEFAULT_MAXIMUM_SIZE = 200

export default class MultisigCreate extends SolanaCommand {
static id = 'create'
static category = CONTRACT_LIST.MULTISIG

static examples = ['yarn gauntlet-serum-multisig create --network=local']

constructor(flags, args) {
super(flags, args)
this.requireFlag('threshold', 'Please provide multisig threshold')
}

makeInput = (userInput: any): Input => {
if (userInput) return userInput as Input

return {
//TODO: validate args. Maybe wrap them int PublicKey?
owners: this.args,
threshold: this.flags.threshold,
}
}

execute = async () => {
this.require(this.args.length > 0, 'Please provide at least one owner as an argument')
const contract = getContract(CONTRACT_LIST.MULTISIG, '')
const address = contract.programId.toString()
const program = this.loadProgram(contract.idl, address)

const input = this.makeInput(this.flags.input)

const multisig = Keypair.generate()

const [multisigSigner, nonce] = await PublicKey.findProgramAddress(
[multisig.publicKey.toBuffer()],
program.programId,
)
const maximumSize = this.flags.maximumSize || DEFAULT_MAXIMUM_SIZE
const owners = input.owners.map((key) => new PublicKey(key))

const tx = await program.rpc.createMultisig(owners, new BN(input.threshold), nonce, {
accounts: {
multisig: multisig.publicKey,
rent: SYSVAR_RENT_PUBKEY,
},
signers: [multisig],
instructions: [await program.account.multisig.createInstruction(multisig, maximumSize)],
})
logger.info(`Multisig address: ${multisig.publicKey}`)
logger.info(`Multisig Signer: ${multisigSigner.toString()}`)

return {
responses: [
{
tx: this.wrapResponse(tx, multisig.publicKey.toString()),
contract: multisig.publicKey.toString(),
},
],
} as Result<TransactionResponse>
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import SetOwners from './setOwners'
import SetThreshold from './setThreshold'

export default [SetOwners, SetThreshold]
Loading