Skip to content

Commit

Permalink
Add options to override deployment transaction parameters (#10)
Browse files Browse the repository at this point in the history
  • Loading branch information
ericglau authored May 2, 2024
1 parent fafbbaa commit 39978a2
Show file tree
Hide file tree
Showing 8 changed files with 84 additions and 6 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## 0.0.1-alpha.7 (2024-05-02)

- Add options to enable overriding deployment transaction parameters.

## 0.0.1-alpha.6 (2024-04-16)

- Update documentation and error message about supported values for `--licenseType` option. ([#9](https://github.com/OpenZeppelin/defender-deploy-client-cli/pull/9))
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ Additional options:
--relayerId <RELAYER_ID> Relayer ID to use for deployment. Defaults to the relayer configured for your deployment environment on Defender.
--salt <SALT> Salt to use for CREATE2 deployment. Defaults to a random salt.
--createFactoryAddress <CREATE_FACTORY_ADDRESS> Address of the CREATE2 factory to use for deployment. Defaults to the factory provided by Defender.
--gasLimit <GAS_LIMIT> Maximum amount of gas to allow the deployment transaction to use.
--gasPrice <GAS_PRICE> Gas price for legacy transactions, in wei.
--maxFeePerGas <MAX_FEE_PER_GAS> Maximum total fee per gas, in wei.
--maxPriorityFeePerGas <MAX_PRIORITY_FEE_PER_GAS> Maximum priority fee per gas, in wei.
```

### Proposing an upgrade
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@openzeppelin/defender-deploy-client-cli",
"version": "0.0.1-alpha.6",
"version": "0.0.1-alpha.7",
"description": "CLI for deployments using OpenZeppelin Defender SDK",
"repository": "https://github.com/OpenZeppelin/defender-deploy-client-cli",
"license": "MIT",
Expand Down
43 changes: 40 additions & 3 deletions src/commands/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import minimist from 'minimist';
import { FunctionArgs, deployContract } from '../internal/deploy-contract';
import { getDeployClient } from '../internal/client';
import { USAGE_COMMAND_PREFIX, getAndValidateString, getNetwork } from '../internal/utils';
import { DeployClient } from '@openzeppelin/defender-sdk-deploy-client';
import { DeployClient, TxOverrides } from '@openzeppelin/defender-sdk-deploy-client';
import { NetworkClient } from '@openzeppelin/defender-sdk-network-client';

const USAGE = `${USAGE_COMMAND_PREFIX} deploy --contractName <CONTRACT_NAME> --contractPath <CONTRACT_PATH> --chainId <CHAIN_ID> --buildInfoFile <BUILD_INFO_FILE_PATH> [--constructorBytecode <CONSTRUCTOR_ARGS>] [--licenseType <LICENSE>] [--verifySourceCode <true|false>] [--relayerId <RELAYER_ID>] [--salt <SALT>] [--createFactoryAddress <CREATE_FACTORY_ADDRESS>]`;
Expand All @@ -22,6 +22,10 @@ Additional options:
--relayerId <RELAYER_ID> Relayer ID to use for deployment. Defaults to the relayer configured for your deployment environment on Defender.
--salt <SALT> Salt to use for CREATE2 deployment. Defaults to a random salt.
--createFactoryAddress <CREATE_FACTORY_ADDRESS> Address of the CREATE2 factory to use for deployment. Defaults to the factory provided by Defender.
--gasLimit <GAS_LIMIT> Maximum amount of gas to allow the deployment transaction to use.
--gasPrice <GAS_PRICE> Gas price for legacy transactions, in wei.
--maxFeePerGas <MAX_FEE_PER_GAS> Maximum total fee per gas, in wei.
--maxPriorityFeePerGas <MAX_PRIORITY_FEE_PER_GAS> Maximum priority fee per gas, in wei.
`;

export async function deploy(args: string[], deployClient?: DeployClient, networkClient?: NetworkClient): Promise<void> {
Expand All @@ -42,7 +46,8 @@ function parseArgs(args: string[]) {
'help',
'verifySourceCode',
],
string: ['contractName', 'contractPath', 'chainId', 'buildInfoFile', 'licenseType', 'constructorBytecode', 'relayerId', 'salt', 'createFactoryAddress'],
string: ['contractName', 'contractPath', 'chainId', 'buildInfoFile', 'licenseType', 'constructorBytecode', 'relayerId', 'salt', 'createFactoryAddress', 'gasLimit', 'gasPrice', 'maxFeePerGas', 'maxPriorityFeePerGas'],

alias: { h: 'help' },
default: { verifySourceCode: true },
});
Expand Down Expand Up @@ -86,9 +91,16 @@ async function getFunctionArgs(parsedArgs: minimist.ParsedArgs, extraArgs: strin
const salt = getAndValidateString(parsedArgs, 'salt');
const createFactoryAddress = getAndValidateString(parsedArgs, 'createFactoryAddress');

const txOverrides: TxOverrides = {
gasLimit: parseNumberOrUndefined(getAndValidateString(parsedArgs, 'gasLimit')),
gasPrice: parseHexOrUndefined(getAndValidateString(parsedArgs, 'gasPrice')),
maxFeePerGas: parseHexOrUndefined(getAndValidateString(parsedArgs, 'maxFeePerGas')),
maxPriorityFeePerGas: parseHexOrUndefined(getAndValidateString(parsedArgs, 'maxPriorityFeePerGas')),
};

checkInvalidArgs(parsedArgs);

return { contractName, contractPath, network, buildInfoFile, licenseType, constructorBytecode, verifySourceCode, relayerId, salt, createFactoryAddress };
return { contractName, contractPath, network, buildInfoFile, licenseType, constructorBytecode, verifySourceCode, relayerId, salt, createFactoryAddress, txOverrides };
}
}

Expand All @@ -109,9 +121,34 @@ function checkInvalidArgs(parsedArgs: minimist.ParsedArgs) {
'relayerId',
'salt',
'createFactoryAddress',
'gasLimit',
'gasPrice',
'maxFeePerGas',
'maxPriorityFeePerGas',
].includes(key),
);
if (invalidArgs.length > 0) {
throw new Error(`Invalid options: ${invalidArgs.join(', ')}`);
}
}

function parseHexOrUndefined(value?: string): string | undefined {
if (value !== undefined) {
// If not a hex string, convert from decimal to hex as a string
if (!value.startsWith('0x')) {
return '0x' + Number(value).toString(16);
} else {
return value;
}
} else {
return undefined;
}
}

function parseNumberOrUndefined(value?: string): number | undefined {
if (value !== undefined) {
return Number(value);
} else {
return undefined;
}
}
4 changes: 3 additions & 1 deletion src/internal/deploy-contract.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { promises as fs } from 'fs';

import { Network } from '@openzeppelin/defender-sdk-base-client';
import { DeployClient, DeployContractRequest, DeploymentResponse, SourceCodeLicense } from '@openzeppelin/defender-sdk-deploy-client';
import { DeployClient, DeployContractRequest, DeploymentResponse, SourceCodeLicense, TxOverrides } from '@openzeppelin/defender-sdk-deploy-client';

export interface FunctionArgs {
contractName: string;
Expand All @@ -14,6 +14,7 @@ export interface FunctionArgs {
relayerId?: string;
salt?: string;
createFactoryAddress?: string;
txOverrides?: TxOverrides;
}

export async function deployContract(args: FunctionArgs, client: DeployClient) {
Expand All @@ -30,6 +31,7 @@ export async function deployContract(args: FunctionArgs, client: DeployClient) {
relayerId: args.relayerId,
salt: args.salt,
createFactoryAddress: args.createFactoryAddress,
txOverrides: args.txOverrides,
};

let deployment: DeploymentResponse;
Expand Down
29 changes: 28 additions & 1 deletion test/deploy.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,32 @@ test('deploy required args', async t => {
relayerId: undefined,
salt: undefined,
createFactoryAddress: undefined,
txOverrides: {
gasLimit: undefined,
gasPrice: undefined,
maxFeePerGas: undefined,
maxPriorityFeePerGas: undefined
},
});
});

test('deploy all args', async t => {
const args = ['--contractName', 'MyContract', '--contractPath', 'contracts/MyContract.sol', '--chainId', FAKE_CHAIN_ID, '--buildInfoFile', 'test/input/build-info.json', '--constructorBytecode', '0x1234', '--licenseType', 'MIT', '--verifySourceCode', 'false', '--relayerId', 'my-relayer-id', '--salt', '0x4567', '--createFactoryAddress', '0x0000000000000000000000000000000000098765'];
const args = [
'--contractName', 'MyContract',
'--contractPath', 'contracts/MyContract.sol',
'--chainId', FAKE_CHAIN_ID,
'--buildInfoFile', 'test/input/build-info.json',
'--constructorBytecode', '0x1234',
'--licenseType', 'MIT',
'--verifySourceCode', 'false',
'--relayerId', 'my-relayer-id',
'--salt', '0x4567',
'--createFactoryAddress', '0x0000000000000000000000000000000000098765',
'--gasLimit', '1000000',
'--gasPrice', '1000000000', // 1 gwei
'--maxFeePerGas', '2000000000', // 2 gwei
'--maxPriorityFeePerGas', '500000000', // 0.5 gwei
];

await deploy(args, t.context.fakeDeployClient, t.context.fakeNetworkClient);

Expand All @@ -96,5 +117,11 @@ test('deploy all args', async t => {
relayerId: 'my-relayer-id',
salt: '0x4567',
createFactoryAddress: '0x0000000000000000000000000000000000098765',
txOverrides: {
gasLimit: 1000000,
gasPrice: '0x3b9aca00',
maxFeePerGas: '0x77359400',
maxPriorityFeePerGas: '0x1dcd6500',
}
});
});
4 changes: 4 additions & 0 deletions test/deploy.js.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,9 @@ Generated by [AVA](https://avajs.dev).
--relayerId <RELAYER_ID> Relayer ID to use for deployment. Defaults to the relayer configured for your deployment environment on Defender.␊
--salt <SALT> Salt to use for CREATE2 deployment. Defaults to a random salt.␊
--createFactoryAddress <CREATE_FACTORY_ADDRESS> Address of the CREATE2 factory to use for deployment. Defaults to the factory provided by Defender.␊
--gasLimit <GAS_LIMIT> Maximum amount of gas to allow the deployment transaction to use.␊
--gasPrice <GAS_PRICE> Gas price for legacy transactions, in wei.␊
--maxFeePerGas <MAX_FEE_PER_GAS> Maximum total fee per gas, in wei.␊
--maxPriorityFeePerGas <MAX_PRIORITY_FEE_PER_GAS> Maximum priority fee per gas, in wei.␊
`
Binary file modified test/deploy.js.snap
Binary file not shown.

0 comments on commit 39978a2

Please sign in to comment.