Skip to content

Commit

Permalink
adds option to sign&execute now and allows to call without privKey pa…
Browse files Browse the repository at this point in the history
…ram (#803)

* adds DOM lib to tsConfig and fixes path in script

* adds option to sign&execute now and allows to call without privKey param

* refactors code and adds missing network in exclude list

* code refactoring
  • Loading branch information
0xDEnYO authored Oct 1, 2024
1 parent 422364a commit 49cc9b5
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 8 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ensureSCCoreDevApproval.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# - Smart Contract Core Dev Approval checker
# - makes sure that every pull_request is at least reviewed by one Smart Contract Core Dev
# - makes sure that every pull_request is at least reviewed by one Smart Contract Core Developer
# (member of group https://github.com/orgs/lifinance/teams/smart-contract-core)

name: SC Core Dev Approval Check
Expand Down
68 changes: 61 additions & 7 deletions script/deploy/safe/confirm-safe-tx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ import consola from 'consola'
import * as chains from 'viem/chains'
import { getSafeUtilityContracts, safeAddresses, safeApiUrls } from './config'
import { getViemChainForNetworkName } from '../../utils/viemScriptHelpers'
import * as dotenv from 'dotenv'
import { SafeMultisigTransactionResponse } from '@safe-global/safe-core-sdk-types'
dotenv.config()

const ABI_LOOKUP_URL = `https://api.openchain.xyz/signature-database/v1/lookup?function=%SELECTOR%&filter=true`

Expand All @@ -29,6 +32,7 @@ const skipNetworks: string[] = [
// 'gnosis',
// 'gravity',
// 'immutablezkevm',
// 'kaia',
// 'linea',
// 'mantle',
// 'metis',
Expand All @@ -41,6 +45,7 @@ const skipNetworks: string[] = [
// 'rootstock',
// 'scroll',
// 'sei',
// 'taiko',
// 'zksync',
]
const defaultNetworks = allNetworks.filter(
Expand Down Expand Up @@ -92,6 +97,7 @@ const func = async (network: string, privateKey: string, rpcUrl?: string) => {

const signerAddress = await signer.getAddress()

consola.info('-'.repeat(80))
consola.info('Chain:', chain.name)
consola.info('Signer:', signerAddress)

Expand All @@ -110,6 +116,31 @@ const func = async (network: string, privateKey: string, rpcUrl?: string) => {
safeService.getPendingTransactions(safeAddress)
)

// Function to sign a transaction
const signTransaction = async (
txToConfirm: SafeMultisigTransactionResponse
) => {
consola.info('Signing transaction', txToConfirm.safeTxHash)
const signedTx = await protocolKit.signTransaction(txToConfirm)
const dataToBeSigned = signedTx.getSignature(signerAddress)?.data
if (!dataToBeSigned) throw Error(`error while preparing data to be signed)`)

await retry(() =>
safeService.confirmTransaction(txToConfirm.safeTxHash, dataToBeSigned)
)
consola.success('Transaction signed', txToConfirm.safeTxHash)
}

// Function to execute a transaction
async function executeTransaction(
txToConfirm: SafeMultisigTransactionResponse
) {
consola.info('Executing transaction', txToConfirm.safeTxHash)
const exec = await protocolKit.executeTransaction(txToConfirm)
await exec.transactionResponse?.wait()
consola.success('Transaction executed', txToConfirm.safeTxHash)
}

// only show transaction Signer has not confirmed yet
const txs = allTx.results.filter(
(tx) =>
Expand Down Expand Up @@ -177,7 +208,7 @@ const func = async (network: string, privateKey: string, rpcUrl?: string) => {
storedResponse ??
(await consola.prompt('Action', {
type: 'select',
options: ['Sign & Execute Later', 'Execute Now'],
options: ['Sign & Execute Now', 'Sign', 'Execute Now'],
}))
storedResponses[tx.data!] = action

Expand All @@ -198,11 +229,17 @@ const func = async (network: string, privateKey: string, rpcUrl?: string) => {
consola.success('Transaction signed', tx.safeTxHash)
}

if (action === 'Sign') {
await signTransaction(txToConfirm)
}

if (action === 'Sign & Execute Now') {
await signTransaction(txToConfirm)
await executeTransaction(txToConfirm)
}

if (action === 'Execute Now') {
consola.info('Executing transaction', tx.safeTxHash)
const exec = await protocolKit.executeTransaction(txToConfirm)
await exec.transactionResponse?.wait()
consola.success('Transaction executed', tx.safeTxHash)
await executeTransaction(txToConfirm)
}
}
}
Expand All @@ -224,14 +261,31 @@ const main = defineCommand({
privateKey: {
type: 'string',
description: 'Private key of the signer',
required: true,
required: false,
},
},
async run({ args }) {
const networks = args.network ? [args.network] : defaultNetworks

// if no privateKey was supplied, read directly from env
let privateKey = args.privateKey
if (!privateKey) {
const key = await consola.prompt(
'Which private key do you want to use from your .env file?',
{
type: 'select',
options: ['PRIVATE_KEY_PRODUCTION', 'SAFE_SIGNER_PRIVATE_KEY'],
}
)

privateKey = process.env[key] ?? ''

if (privateKey == '')
throw Error(`could not find a key named ${key} in your .env file`)
}

for (const network of networks) {
await func(network, args.privateKey, args.rpcUrl)
await func(network, privateKey, args.rpcUrl)
}
},
})
Expand Down

0 comments on commit 49cc9b5

Please sign in to comment.