Skip to content

Commit

Permalink
feat: fee market change (eip-1559) (#284)
Browse files Browse the repository at this point in the history
* feat: fee market change
  • Loading branch information
osslgtm committed Sep 13, 2023
1 parent c087fba commit 30c3672
Show file tree
Hide file tree
Showing 49 changed files with 447 additions and 171 deletions.
58 changes: 58 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,63 @@ npx -p @govtechsg/open-attestation-cli open-attestation <arguments>

## Usage

### Network Fees

For information on how network fees work, please refer to the ethereum documentation: [https://ethereum.org/en/developers/docs/gas/](https://ethereum.org/en/developers/docs/gas/)

#### Adjusting preset gas price

To adjust transaction gas price, use the variable of `priority` to scale against the market price.

Calculation:
priority \* previous block priority fee

Example:

| Priority | Previous block priority fee | Priority Fee to use |
| -------- | --------------------------- | ------------------- |
| 1 | 1 | 1 \* 1 = 1 |
| 1.2 | 1 | 1.2 \* 1 = 1.2 |
| 2 | 1 | 2 \* 1 = 2 |
| 1 | 10 | 1 \* 10 = 10 |
| 1.2 | 10 | 1.2 \* 10 = 12 |
| 2 | 10 | 2 \* 10 = 20 |

#### Fee Information

To display an estimated price of a transaction use the option of `dry-run` on your command.

Example:

```bash
open-attestation deploy document-store "My Name" --network sepolia --dry-run

/!\ Welcome to the fee table. Please read the information below to understand the transaction fee

The table below display information about the cost of the transaction on the mainnet network, depending on the gas price selected. Multiple modes are displayed to help you better help you to choose a gas price depending on your needs:

Information about the network:
Costs based on block number: 4275264
┌─────────┬──────────────┬──────────────────┬─────────────────────────────────┬────────────────────────┐
│ (index) │ block number │ gas price (gwei) │ max priority fee per gas (gwei) │ max fee per gas (gwei) │
├─────────┼──────────────┼──────────────────┼─────────────────────────────────┼────────────────────────┤
│ current │ 4275264 │ '0.629067134''2.5''3.758131382'
└─────────┴──────────────┴──────────────────┴─────────────────────────────────┴────────────────────────┘
Information about the transaction:
Estimated gas required: 869810 gas, which will cost approximately US$0.86837 based on prevailing gas price.
┌──────────┬───────────────────────┬────────────────────┬───────────────────────┐
│ (index) │ gas cost │ priority fee price │ max fee price │
├──────────┼───────────────────────┼────────────────────┼───────────────────────┤
│ GWEI │ '547168.88382454''2174525.0''3268860.25737742'
│ ETH │ '0.00054716888382454''0.002174525''0.00326886025737742'
│ ETHUSD │ 0.86837 │ 3.45105 │ 5.18781 │
│ ETHSGD │ 1.18247 │ 4.69931 │ 7.06426 │
│ MATICUSD │ 0.00027 │ 0.00109 │ 0.00165 │
│ MATICSGD │ 0.00037 │ 0.00149 │ 0.00225 │
└──────────┴───────────────────────┴────────────────────┴───────────────────────┘
Please read the information above to understand the table
```

#### List of features with the required options

| | Private Key | Wallet | Aws Kms |
Expand Down Expand Up @@ -732,6 +789,7 @@ Example - with private key set in `OA_PRIVATE_KEY` environment variable (recomme
open-attestation title-escrow accept-surrendered --token-registry 0x4933e30eF8A083f49d14759b2eafC94E56F0b3A7 --tokenId 0x951b39bcaddc0e8882883db48ca258ca35ccb01fee328355f0dfda1ff9be9990 --network sepolia
✔ success Surrendered transferable record with hash 0x951b39bcaddc0e8882883db48ca258ca35ccb01fee328355f0dfda1ff9be9990 has been accepted.
```
## Help
Expand Down
3 changes: 2 additions & 1 deletion src/commands/deploy/document-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { getLogger } from "../../logger";
import { deployDocumentStore } from "../../implementations/deploy/document-store";
import { DeployDocumentStoreCommand } from "./deploy.types";
import { withGasPriceOption, withNetworkAndWalletSignerOption } from "../shared";
import { getErrorMessage, getEtherscanAddress, highlight } from "../../utils";
import { displayTransactionPrice, getErrorMessage, getEtherscanAddress, highlight } from "../../utils";

const { trace } = getLogger("deploy:document-store");

Expand Down Expand Up @@ -32,6 +32,7 @@ export const handler = async (args: DeployDocumentStoreCommand): Promise<string
try {
info(`Deploying document store ${args.storeName}`);
const documentStore = await deployDocumentStore(args);
displayTransactionPrice(documentStore);
success(`Document store ${args.storeName} deployed at ${highlight(documentStore.contractAddress)}`);
info(
`Find more details at ${getEtherscanAddress({ network: args.network })}/address/${documentStore.contractAddress}`
Expand Down
14 changes: 6 additions & 8 deletions src/commands/deploy/token-registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@ import { deployTokenRegistry } from "../../implementations/deploy/token-registry
import { error, info, success } from "signale";
import { getLogger } from "../../logger";
import { withGasPriceOption, withNetworkAndWalletSignerOption } from "../shared";
import { getErrorMessage, getEtherscanAddress } from "../../utils";
import { displayTransactionPrice, getErrorMessage, getEtherscanAddress } from "../../utils";
import { DeployTokenRegistryCommand } from "./deploy.types";

const { trace } = getLogger("deploy:token-registry");

export const command = "token-registry <registry-name> <registry-symbol> [options]";
Expand Down Expand Up @@ -55,14 +54,13 @@ export const handler = async (args: DeployTokenRegistryCommand): Promise<string
trace(`Args: ${JSON.stringify(args, null, 2)}`);
try {
info(`Deploying token registry ${args.registryName}`);
const tokenRegistryAddress = await deployTokenRegistry(args);
success(`Token registry deployed at ${tokenRegistryAddress.contractAddress}`);
const tokenRegistry = await deployTokenRegistry(args);
displayTransactionPrice(tokenRegistry.transaction);
success(`Token registry deployed at ${tokenRegistry.contractAddress}`);
info(
`Find more details at ${getEtherscanAddress({ network: args.network })}/address/${
tokenRegistryAddress.contractAddress
}`
`Find more details at ${getEtherscanAddress({ network: args.network })}/address/${tokenRegistry.contractAddress}`
);
return tokenRegistryAddress.contractAddress;
return tokenRegistry.contractAddress;
} catch (e) {
error(getErrorMessage(e));
}
Expand Down
3 changes: 1 addition & 2 deletions src/commands/dns/txt-record/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ import { Argv } from "yargs";
import signale, { error, success } from "signale";
import { getLogger } from "../../../logger";
import { DnsCreateTxtRecordCommand } from "./dns-command.type";
import { getErrorMessage, highlight } from "../../../utils";
import { request } from "../../../implementations/utils/web-request";
import { getErrorMessage, highlight, request } from "../../../utils";

const { trace } = getLogger("dns:txt-record");

Expand Down
25 changes: 18 additions & 7 deletions src/commands/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,10 @@ export const isWalletOption = (option: any): option is WalletOption => {

export type WalletOrSignerOption = Partial<PrivateKeyOption> | Partial<AwsKmsSignerOption> | Partial<WalletOption>;

export interface GasOption {
export interface GasPriceScale {
maxPriorityFeePerGasScale: number;
}
export interface GasOption extends GasPriceScale {
dryRun: boolean;
}

Expand All @@ -58,12 +61,20 @@ export const withNetworkOption = (yargs: Argv): Argv =>
description: "Ethereum network to deploy to",
});
export const withGasPriceOption = (yargs: Argv): Argv =>
yargs.option("dry-run", {
alias: "dr",
type: "boolean",
default: false,
description: "Dry run",
});
yargs
.option("priority", {
alias: "maxPriorityFeePerGasScale",
type: "number",
default: 1,
demandOption: false,
description: "Scale for estimated priority fees (maxPriorityFeePerGasScale * estimatedPriorityFeePerGas)",
})
.option("dry-run", {
alias: "dr",
type: "boolean",
default: false,
description: "Provide estimated MaxFeePerGas and PriorityFeePerGas",
});

export const withPrivateKeyOption = (yargs: Argv): Argv =>
yargs
Expand Down
6 changes: 4 additions & 2 deletions src/commands/title-escrow/accept-surrendered.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { getLogger } from "../../logger";
import { withGasPriceOption, withNetworkAndWalletSignerOption } from "../shared";
import { BaseTitleEscrowCommand as TitleEscrowSurrenderDocumentCommand } from "./title-escrow-command.type";
import { acceptSurrendered } from "../../implementations/title-escrow/acceptSurrendered";
import { getErrorMessage, getEtherscanAddress } from "../../utils";
import { displayTransactionPrice, getErrorMessage, getEtherscanAddress } from "../../utils";

const { trace } = getLogger("title-escrow:accept-surrendered");

Expand Down Expand Up @@ -35,8 +35,10 @@ export const handler = async (args: TitleEscrowSurrenderDocumentCommand): Promis
try {
info(`Accepting surrendered document`);
const transaction = await acceptSurrendered(args);
displayTransactionPrice(transaction);
const { transactionHash } = transaction;
success(`Surrendered transferable record with hash ${args.tokenId} has been accepted.`);
info(`Find more details at ${getEtherscanAddress({ network: args.network })}/tx/${transaction.transactionHash}`);
info(`Find more details at ${getEtherscanAddress({ network: args.network })}/tx/${transactionHash}`);
} catch (e) {
error(getErrorMessage(e));
}
Expand Down
6 changes: 4 additions & 2 deletions src/commands/title-escrow/change-holder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { getLogger } from "../../logger";
import { transferHolder } from "../../implementations/title-escrow/transferHolder";
import { TitleEscrowTransferHolderCommand } from "./title-escrow-command.type";
import { withGasPriceOption, withNetworkAndWalletSignerOption } from "../shared";
import { getErrorMessage, getEtherscanAddress } from "../../utils";
import { displayTransactionPrice, getErrorMessage, getEtherscanAddress } from "../../utils";

const { trace } = getLogger("title-escrow:change-holder");

Expand Down Expand Up @@ -45,7 +45,9 @@ export const handler = async (args: TitleEscrowTransferHolderCommand): Promise<v
warn(
`Please note that only current holders can change the holder of the transferable record, otherwise this command will fail.`
);
const { transactionHash } = await transferHolder(args);
const transaction = await transferHolder(args);
displayTransactionPrice(transaction);
const { transactionHash } = transaction;
success(
`Transferable record with hash ${args.tokenId}'s holder has been successfully changed to holder with address: ${args.newHolder}`
);
Expand Down
6 changes: 4 additions & 2 deletions src/commands/title-escrow/endorse-change-of-owner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { getLogger } from "../../logger";
import { transferOwners } from "../../implementations/title-escrow/transferOwners";
import { TitleEscrowEndorseTransferOfOwnersCommand } from "./title-escrow-command.type";
import { withGasPriceOption, withNetworkAndWalletSignerOption } from "../shared";
import { getErrorMessage, getEtherscanAddress } from "../../utils";
import { displayTransactionPrice, getErrorMessage, getEtherscanAddress } from "../../utils";

const { trace } = getLogger("title-escrow:endorse-change-of-owner");

Expand Down Expand Up @@ -50,7 +50,9 @@ export const handler = async (args: TitleEscrowEndorseTransferOfOwnersCommand):
warn(
`Please note that you have to be both the holder and owner of the transferable record, otherwise this command will fail.`
);
const { transactionHash } = await transferOwners(args);
const transaction = await transferOwners(args);
displayTransactionPrice(transaction);
const { transactionHash } = transaction;
success(
`Transferable record with hash ${args.tokenId}'s holder has been successfully endorsed to new owner with address ${args.newOwner} and new holder with address: ${args.newHolder}`
);
Expand Down
12 changes: 6 additions & 6 deletions src/commands/title-escrow/endorse-transfer-of-owner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { getLogger } from "../../logger";
import { endorseNominatedBeneficiary } from "../../implementations/title-escrow/endorseNominatedBeneficiary";
import { TitleEscrowNominateBeneficiaryCommand } from "../../commands/title-escrow/title-escrow-command.type";
import { withGasPriceOption, withNetworkAndWalletSignerOption } from "../shared";
import { getErrorMessage, getEtherscanAddress } from "../../utils";
import { displayTransactionPrice, getErrorMessage, getEtherscanAddress } from "../../utils";

const { trace } = getLogger("title-escrow:endorse-transfer-of-owner");

Expand Down Expand Up @@ -46,13 +46,13 @@ export const handler = async (args: TitleEscrowNominateBeneficiaryCommand): Prom
warn(
`Please note that if you do not have the correct privileges to the transferable record, then this command will fail.`
);
const { transactionReceipt, nominatedBeneficiary } = await endorseNominatedBeneficiary(args);
const { transactionReceipt } = await endorseNominatedBeneficiary(args);
displayTransactionPrice(transactionReceipt);
const { transactionHash } = transactionReceipt;
success(
`Transferable record with hash ${args.tokenId}'s holder has been successfully endorsed to approved beneficiary at ${nominatedBeneficiary}`
);
info(
`Find more details at ${getEtherscanAddress({ network: args.network })}/tx/${transactionReceipt.transactionHash}`
`Transferable record with hash ${args.tokenId}'s holder has been successfully endorsed to approved beneficiary at ${args.newBeneficiary}`
);
info(`Find more details at ${getEtherscanAddress({ network: args.network })}/tx/${transactionHash}`);
} catch (e) {
error(getErrorMessage(e));
}
Expand Down
6 changes: 4 additions & 2 deletions src/commands/title-escrow/nominate-change-of-owner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { getLogger } from "../../logger";
import { nominateBeneficiary } from "../../implementations/title-escrow/nominateBeneficiary";
import { TitleEscrowNominateBeneficiaryCommand } from "./title-escrow-command.type";
import { withGasPriceOption, withNetworkAndWalletSignerOption } from "../shared";
import { getErrorMessage, getEtherscanAddress } from "../../utils";
import { displayTransactionPrice, getErrorMessage, getEtherscanAddress } from "../../utils";

const { trace } = getLogger("title-escrow:nominate-change-of-owner");

Expand Down Expand Up @@ -45,7 +45,9 @@ export const handler = async (args: TitleEscrowNominateBeneficiaryCommand): Prom
warn(
`Please note that if you do not have the correct privileges to the transferable record, then this command will fail.`
);
const { transactionHash } = await nominateBeneficiary(args);
const transaction = await nominateBeneficiary(args);
displayTransactionPrice(transaction);
const { transactionHash } = transaction;
success(
`Transferable record with hash ${args.tokenId}'s holder has been successfully nominated to new owner with address ${args.newBeneficiary}`
);
Expand Down
6 changes: 4 additions & 2 deletions src/commands/title-escrow/reject-surrendered.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { getLogger } from "../../logger";
import { withGasPriceOption, withNetworkAndWalletSignerOption } from "../shared";
import { BaseTitleEscrowCommand as TitleEscrowSurrenderDocumentCommand } from "./title-escrow-command.type";
import { rejectSurrendered } from "../../implementations/title-escrow/rejectSurrendered";
import { getErrorMessage, getEtherscanAddress } from "../../utils";
import { displayTransactionPrice, getErrorMessage, getEtherscanAddress } from "../../utils";

const { trace } = getLogger("title-escrow:reject-surrendered");

Expand Down Expand Up @@ -35,8 +35,10 @@ export const handler = async (args: TitleEscrowSurrenderDocumentCommand): Promis
try {
info(`Rejecting surrendered document`);
const transaction = await rejectSurrendered(args);
displayTransactionPrice(transaction);
const { transactionHash } = transaction;
success(`Surrendered transferable record with hash ${args.tokenId} has been rejected.`);
info(`Find more details at ${getEtherscanAddress({ network: args.network })}/tx/${transaction.transactionHash}`);
info(`Find more details at ${getEtherscanAddress({ network: args.network })}/tx/${transactionHash}`);
} catch (e) {
error(getErrorMessage(e));
}
Expand Down
6 changes: 4 additions & 2 deletions src/commands/title-escrow/surrender-document.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { getLogger } from "../../logger";
import { withGasPriceOption, withNetworkAndWalletSignerOption } from "../shared";
import { BaseTitleEscrowCommand as TitleEscrowSurrenderDocumentCommand } from "./title-escrow-command.type";
import { surrenderDocument } from "../../implementations/title-escrow/surrenderDocument";
import { getErrorMessage, getEtherscanAddress } from "../../utils";
import { displayTransactionPrice, getErrorMessage, getEtherscanAddress } from "../../utils";

const { trace } = getLogger("title-escrow:surrender-document");

Expand Down Expand Up @@ -35,8 +35,10 @@ export const handler = async (args: TitleEscrowSurrenderDocumentCommand): Promis
try {
info(`Surrendering document`);
const transaction = await surrenderDocument(args);
displayTransactionPrice(transaction);
const { transactionHash } = transaction;
success(`Transferable record with hash ${args.tokenId} has been surrendered.`);
info(`Find more details at ${getEtherscanAddress({ network: args.network })}/tx/${transaction.transactionHash}`);
info(`Find more details at ${getEtherscanAddress({ network: args.network })}/tx/${transactionHash}`);
} catch (e) {
error(getErrorMessage(e));
}
Expand Down
6 changes: 4 additions & 2 deletions src/commands/token-registry/issue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { getLogger } from "../../logger";
import { issueToTokenRegistry } from "../../implementations/token-registry/issue";
import { TokenRegistryIssueCommand } from "./token-registry-command.type";
import { withGasPriceOption, withNetworkAndWalletSignerOption } from "../shared";
import { getErrorMessage, getEtherscanAddress, addAddressPrefix } from "../../utils";
import { getErrorMessage, getEtherscanAddress, addAddressPrefix, displayTransactionPrice } from "../../utils";

const { trace } = getLogger("token-registry:issue");

Expand Down Expand Up @@ -46,10 +46,12 @@ export const handler = async (args: TokenRegistryIssueCommand): Promise<string |
info(
`Issuing ${args.tokenId} to the initial recipient ${args.beneficiary} and initial holder ${args.holder} in the registry ${args.address}`
);
const { transactionHash } = await issueToTokenRegistry({
const transaction = await issueToTokenRegistry({
...args,
tokenId: addAddressPrefix(args.tokenId),
});
displayTransactionPrice(transaction);
const { transactionHash } = transaction;
success(
`Token with hash ${args.tokenId} has been issued on ${args.address} with the initial recipient being ${args.beneficiary} and initial holder ${args.holder}`
);
Expand Down
2 changes: 2 additions & 0 deletions src/implementations/config/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ export const getTokenRegistryAddress = async (
passedOnWallet,
network,
dryRun: false,
maxPriorityFeePerGasScale: 1,
registryName: "Token Registry",
registrySymbol: "TR",
});
Expand All @@ -136,6 +137,7 @@ export const getDocumentStoreAddress = async (
passedOnWallet,
network,
dryRun: false,
maxPriorityFeePerGasScale: 1,
storeName: "Document Store",
});
const { contractAddress } = documentStore;
Expand Down

0 comments on commit 30c3672

Please sign in to comment.