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 11 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
58 changes: 29 additions & 29 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ name: "CodeQL"

on:
push:
branches: [ develop ]
branches: [develop]
pull_request:
# The branches below must be a subset of the branches above
branches: [ develop ]
branches: [develop]
schedule:
- cron: '28 23 * * 0'
- cron: "28 23 * * 0"

jobs:
analyze:
Expand All @@ -32,39 +32,39 @@ jobs:
strategy:
fail-fast: false
matrix:
language: [ 'go', 'javascript' ]
language: ["go", "javascript"]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
# Learn more about CodeQL language support at https://git.io/codeql-language-support

steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Checkout repository
uses: actions/checkout@v2

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main

# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v1
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v1

# ℹ️ Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# ℹ️ Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl

# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language

#- run: |
# make bootstrap
# make release
#- run: |
# make bootstrap
# make release

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1
1 change: 1 addition & 0 deletions gauntlet/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"bin": "packages/gauntlet-solana-contracts/dist/index.js",
"scripts": {
"gauntlet": "yarn build && node ./packages/gauntlet-solana-contracts/dist/index.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.
1 change: 1 addition & 0 deletions gauntlet/packages/gauntlet-serum-multisig/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Gauntlet Serum Multisig
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.6",
"@chainlink/gauntlet-solana": "*",
"@chainlink/gauntlet-solana-contracts": "*",
"@project-serum/anchor": "^0.18.0",
"@solana/web3.js": "^1.30.2"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { Result } from '@chainlink/gauntlet-core'
import { TransactionResponse, SolanaCommand, RawTransaction } from '@chainlink/gauntlet-solana'

enum ACTIONS {
create = 'create',
approve = 'approve',
execute = 'execute',
}

export const wrapCommand = (command) => {
return class Multisig extends SolanaCommand {
command: SolanaCommand

static id = `${command.id}`

constructor(flags, args) {
super(flags, args)

this.command = new command(flags, args)
this.command.invokeMiddlewares(this.command, this.command.middlewares)
}

createProposal = (tx: RawTransaction[]) => {
return {} as Result<TransactionResponse>
}
approveProposal = (tx: RawTransaction[]) => {
return {} as Result<TransactionResponse>
}
executeProposal = (tx: RawTransaction[]) => {
return {} as Result<TransactionResponse>
}

execute = async () => {
const rawTx: RawTransaction[] = await this.command.makeRawTransaction()

const actions = {
[ACTIONS.create]: this.createProposal,
[ACTIONS.approve]: this.approveProposal,
[ACTIONS.execute]: this.executeProposal,
}

return actions[this.flags.action](rawTx)
}
}
}
28 changes: 28 additions & 0 deletions gauntlet/packages/gauntlet-serum-multisig/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { commands } from '@chainlink/gauntlet-solana-contracts'
import { executeCLI } from '@chainlink/gauntlet-core'
import { existsSync } from 'fs'
import path from 'path'
import { io } from '@chainlink/gauntlet-core/dist/utils'
import { wrapCommand } from './commands/multisig'

export const multisigCommands = {
custom: commands.custom.map(wrapCommand),
loadDefaultFlags: () => ({}),
abstract: {
findPolymorphic: () => undefined,
makeCommand: () => undefined,
},
}
;(async () => {
try {
const networkPossiblePaths = ['./networks', './packages/gauntlet-serum-multisig/networks']
const networkPath = networkPossiblePaths.filter((networkPath) =>
existsSync(path.join(process.cwd(), networkPath)),
)[0]
const result = await executeCLI(multisigCommands, networkPath)
io.saveJSON(result, 'report')
} catch (e) {
console.log(e)
console.log('Solana Command execution error', e.message)
}
})()
9 changes: 9 additions & 0 deletions gauntlet/packages/gauntlet-serum-multisig/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"outDir": "dist",
"rootDir": "src"
},
"include": ["src/**/*"],
"exclude": ["dist", "**/*.spec.ts", "**/*.test.ts"]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
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 '../../../lib/contracts'

type Input = {
owners: string[]
threshold: number | string
}
export default class MultisigCreate extends SolanaCommand {
static id = 'multisig:create'
static category = CONTRACT_LIST.MULTISIG

static examples = ['yarn gauntlet multisig:create --network=local']
ebarakos marked this conversation as resolved.
Show resolved Hide resolved

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

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

return {
owners: [this.wallet.publicKey.toString()],
threshold: 1,
}
}

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 [_, nonce] = await PublicKey.findProgramAddress([multisig.publicKey.toBuffer()], program.programId)
const multisigSize = 200 // TODO: Come back here
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, multisigSize)],
})
logger.info(`Multisig address: ${multisig.publicKey}`)

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,3 @@
import MultisigCreate from './create'

export default [MultisigCreate]
Loading