From ff2cbd7fd3391cdeb11a69bbac513886b486e3d1 Mon Sep 17 00:00:00 2001 From: Nathan <102951164+Nathan-SL@users.noreply.github.com> Date: Thu, 25 Aug 2022 14:41:29 +0300 Subject: [PATCH 1/9] Make account-contract a flag in starknet-verify (#198) [skip ci] --- README.md | 2 +- src/index.ts | 5 +---- src/task-actions.ts | 9 +-------- test/general-tests/starknet-verify/check.sh | 2 +- 4 files changed, 4 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index a84f427a..189fb332 100644 --- a/README.md +++ b/README.md @@ -112,7 +112,7 @@ You would typically use the input feature when deploying a single contract requi ### `starknet-verify` ``` -npx hardhat starknet-verify [--starknet-network ] [--path ] [ ...] [--address ] [--compiler-version ] [--license ] [--contract-name ] [--acount-contract ] +npx hardhat starknet-verify [--starknet-network ] [--path ] [ ...] [--address ] [--compiler-version ] [--license ] [--contract-name ] [--acount-contract] ``` Queries [Voyager](https://voyager.online/) to [verify the contract](https://voyager.online/verifyContract) deployed at `` using the source files at `` and any number of ``. diff --git a/src/index.ts b/src/index.ts index d63a73f8..142dbca1 100644 --- a/src/index.ts +++ b/src/index.ts @@ -293,10 +293,7 @@ task("starknet-verify", "Verifies a contract on a Starknet network.") .addParam("path", "The path of the main cairo contract (e.g. contracts/contract.cairo)") .addParam("address", "The address where the contract is deployed") .addParam("compilerVersion", "The compiler version used to compile the cairo contract") - .addOptionalParam( - "accountContract", - "The contract type which specifies whether it's an account contract. Omitting it sets false." - ) + .addFlag("accountContract", "The contract type which specifies it's an account contract.") .addOptionalParam("license", "The licence of the contract (e.g No License (None))") .addOptionalVariadicPositionalParam( "paths", diff --git a/src/task-actions.ts b/src/task-actions.ts index c8bba8f0..7c39e2c4 100644 --- a/src/task-actions.ts +++ b/src/task-actions.ts @@ -343,14 +343,7 @@ async function handleContractVerification( const bodyFormData = new FormData(); bodyFormData.append("compiler-version", args.compilerVersion); - let accountContract; - if (args.accountContract === "true") { - accountContract = "true"; - } else if (!args.accountContract || args.accountContract === "false") { - accountContract = "false"; - } else { - throw new StarknetPluginError("--account-contract must be true or false"); - } + const accountContract = args.accountContract ? "true" : "false"; bodyFormData.append("account-contract", accountContract); bodyFormData.append("license", args.license || "No License (None)"); diff --git a/test/general-tests/starknet-verify/check.sh b/test/general-tests/starknet-verify/check.sh index 0202ab5c..4e0f1791 100755 --- a/test/general-tests/starknet-verify/check.sh +++ b/test/general-tests/starknet-verify/check.sh @@ -19,7 +19,7 @@ echo "Verifying contract at $address" echo "Sleeping to allow Voyager to index the deployment" sleep 1m -npx hardhat starknet-verify --starknet-network "$NETWORK" --path $MAIN_CONTRACT $UTIL_CONTRACT --address $address --compiler-version 0.9.0 --license "No License (None)" --account-contract false +npx hardhat starknet-verify --starknet-network "$NETWORK" --path $MAIN_CONTRACT $UTIL_CONTRACT --address $address --compiler-version 0.9.0 --license "No License (None)" echo "Sleeping to allow Voyager to register the verification" sleep 15s From 4781e7a3d0f04e3089f80f3092c7bf9f711b039e Mon Sep 17 00:00:00 2001 From: Nathan-SL Date: Mon, 29 Aug 2022 09:34:04 +0300 Subject: [PATCH 2/9] Use random port on integrated devnet --- src/external-server/create-devnet-wrapper.ts | 7 ++++--- src/task-actions.ts | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/external-server/create-devnet-wrapper.ts b/src/external-server/create-devnet-wrapper.ts index 5fb1dd56..b469078d 100644 --- a/src/external-server/create-devnet-wrapper.ts +++ b/src/external-server/create-devnet-wrapper.ts @@ -10,15 +10,16 @@ import { import { getImageTagByArch, getNetwork } from "../utils"; import { DockerDevnet } from "./docker-devnet"; import { VenvDevnet } from "./venv-devnet"; -import { ExternalServer } from "./external-server"; +import { ExternalServer, getFreePort } from "./external-server"; -export function createIntegratedDevnet(hre: HardhatRuntimeEnvironment): ExternalServer { +export async function createIntegratedDevnet(hre: HardhatRuntimeEnvironment): Promise { const devnetNetwork = getNetwork( INTEGRATED_DEVNET, hre.config.networks, `networks["${INTEGRATED_DEVNET}"]` ); - const { hostname, port } = new URL(devnetNetwork.url || INTEGRATED_DEVNET_URL); + const { hostname } = new URL(devnetNetwork.url || INTEGRATED_DEVNET_URL); + const port = await getFreePort(); if (hostname !== "localhost" && hostname !== "127.0.0.1") { throw new StarknetPluginError("Integrated devnet works only with localhost and 127.0.0.1"); diff --git a/src/task-actions.ts b/src/task-actions.ts index 7c39e2c4..af52069e 100644 --- a/src/task-actions.ts +++ b/src/task-actions.ts @@ -553,7 +553,7 @@ async function runWithDevnet(hre: HardhatRuntimeEnvironment, fn: () => Promise Date: Mon, 29 Aug 2022 09:40:09 +0300 Subject: [PATCH 3/9] Format code --- src/external-server/create-devnet-wrapper.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/external-server/create-devnet-wrapper.ts b/src/external-server/create-devnet-wrapper.ts index b469078d..63aacbe7 100644 --- a/src/external-server/create-devnet-wrapper.ts +++ b/src/external-server/create-devnet-wrapper.ts @@ -12,7 +12,9 @@ import { DockerDevnet } from "./docker-devnet"; import { VenvDevnet } from "./venv-devnet"; import { ExternalServer, getFreePort } from "./external-server"; -export async function createIntegratedDevnet(hre: HardhatRuntimeEnvironment): Promise { +export async function createIntegratedDevnet( + hre: HardhatRuntimeEnvironment +): Promise { const devnetNetwork = getNetwork( INTEGRATED_DEVNET, hre.config.networks, From abf2adabb169eeb234d9d81f8a234d27f9f0b03c Mon Sep 17 00:00:00 2001 From: Nathan-SL Date: Wed, 31 Aug 2022 18:41:53 +0300 Subject: [PATCH 4/9] Assign port to integrated devnet in hre --- src/external-server/create-devnet-wrapper.ts | 5 ++--- src/task-actions.ts | 4 ++++ .../with-docker-address-occupied/check.sh | 3 +-- .../with-venv-address-occupied/check.sh | 3 +-- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/external-server/create-devnet-wrapper.ts b/src/external-server/create-devnet-wrapper.ts index 63aacbe7..1ba6da24 100644 --- a/src/external-server/create-devnet-wrapper.ts +++ b/src/external-server/create-devnet-wrapper.ts @@ -10,7 +10,7 @@ import { import { getImageTagByArch, getNetwork } from "../utils"; import { DockerDevnet } from "./docker-devnet"; import { VenvDevnet } from "./venv-devnet"; -import { ExternalServer, getFreePort } from "./external-server"; +import { ExternalServer } from "./external-server"; export async function createIntegratedDevnet( hre: HardhatRuntimeEnvironment @@ -20,8 +20,7 @@ export async function createIntegratedDevnet( hre.config.networks, `networks["${INTEGRATED_DEVNET}"]` ); - const { hostname } = new URL(devnetNetwork.url || INTEGRATED_DEVNET_URL); - const port = await getFreePort(); + const { hostname, port } = new URL(devnetNetwork.url || INTEGRATED_DEVNET_URL); if (hostname !== "localhost" && hostname !== "127.0.0.1") { throw new StarknetPluginError("Integrated devnet works only with localhost and 127.0.0.1"); diff --git a/src/task-actions.ts b/src/task-actions.ts index af52069e..2e2b068d 100644 --- a/src/task-actions.ts +++ b/src/task-actions.ts @@ -26,6 +26,7 @@ import { getWalletUtil } from "./extend-utils"; import { createIntegratedDevnet } from "./external-server"; import { Recompiler } from "./recompiler"; import { version } from "../package.json"; +import { getFreePort } from "./external-server/external-server"; function checkSourceExists(sourcePath: string): void { if (!fs.existsSync(sourcePath)) { @@ -553,6 +554,9 @@ async function runWithDevnet(hre: HardhatRuntimeEnvironment, fn: () => Promise&1 | - ../scripts/assert-contains.py "127.0.0.1:5050 already occupied." +npx hardhat test --no-compile test/integrated-devnet.test.ts diff --git a/test/integrated-devnet-tests/with-venv-address-occupied/check.sh b/test/integrated-devnet-tests/with-venv-address-occupied/check.sh index 54e376dd..0e69d800 100755 --- a/test/integrated-devnet-tests/with-venv-address-occupied/check.sh +++ b/test/integrated-devnet-tests/with-venv-address-occupied/check.sh @@ -11,5 +11,4 @@ starknet-devnet --host 127.0.0.1 --port 5050 --accounts 0 & npx hardhat starknet-compile contracts/contract.cairo -npx hardhat test --no-compile test/integrated-devnet.test.ts 2>&1 | - ../scripts/assert-contains.py "127.0.0.1:5050 already occupied." +npx hardhat test --no-compile test/integrated-devnet.test.ts From 78ff511f4fa56e77271040ab4dac234435744208 Mon Sep 17 00:00:00 2001 From: Nathan-SL Date: Thu, 1 Sep 2022 11:21:03 +0300 Subject: [PATCH 5/9] Change target branch [skip ci] --- scripts/test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/test.sh b/scripts/test.sh index 792e9da6..b5470bc8 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -9,7 +9,7 @@ CONFIG_FILE_NAME="hardhat.config.ts" # setup example repo rm -rf starknet-hardhat-example -git clone -b plugin --single-branch git@github.com:Shard-Labs/starknet-hardhat-example.git +git clone -b release-0.7.0 --single-branch git@github.com:Shard-Labs/starknet-hardhat-example.git cd starknet-hardhat-example git log -n 1 npm install From af7b7fb1ae4b07ef5ca44cd0f04d259aa4a9864f Mon Sep 17 00:00:00 2001 From: Nathan <102951164+Nathan-SL@users.noreply.github.com> Date: Fri, 9 Sep 2022 18:29:29 +0300 Subject: [PATCH 6/9] Calculate estimateFee Implicitly (#206) [skip ci] --- README.md | 1 + src/account.ts | 17 +++++++++++++++++ src/types.ts | 1 + 3 files changed, 19 insertions(+) diff --git a/README.md b/README.md index 189fb332..48619655 100644 --- a/README.md +++ b/README.md @@ -344,6 +344,7 @@ More detailed documentation can be found [here](#account). const { res: currBalance } = await account.call(contract, "get_balance"); const amount = BigInt(10); // Passing max_fee is currently optional + // Invoke function will handle estimateFee calculation if maxFee is not provided await account.invoke(contract, "increase_balance", { amount }, { maxFee: BigInt("123") }); const { res: newBalance } = await account.call(contract, "get_balance"); diff --git a/src/account.ts b/src/account.ts index 1d9ab0a5..cc17ee8d 100644 --- a/src/account.ts +++ b/src/account.ts @@ -66,6 +66,23 @@ export abstract class Account { calldata?: StringMap, options?: InvokeOptions ): Promise { + if (options?.maxFee && options?.overhead) { + const msg = "Both maxFee and overhead cannot be specified"; + throw new StarknetPluginError(msg); + } + + if (options?.maxFee === undefined || options?.maxFee === null) { + let overhead = + options?.overhead === undefined || options?.overhead === null + ? 0.5 + : options?.overhead; + overhead = Math.round((1 + overhead) * 100); + const maxFee = await this.estimateFee(toContract, functionName, calldata, options); + options = { + ...options, + maxFee: (maxFee.amount * BigInt(overhead)) / BigInt(100) + }; + } return ( await this.interact(InteractChoice.INVOKE, toContract, functionName, calldata, options) ).toString(); diff --git a/src/types.ts b/src/types.ts index ca8c0539..15cdb2ce 100644 --- a/src/types.ts +++ b/src/types.ts @@ -306,6 +306,7 @@ export interface InvokeOptions { wallet?: Wallet; nonce?: Numeric; maxFee?: Numeric; + overhead?: number; } export interface CallOptions { From 77c1e37292b58ec3926c868017d72fcbdfce09a4 Mon Sep 17 00:00:00 2001 From: FabijanC Date: Fri, 9 Sep 2022 18:07:16 +0200 Subject: [PATCH 7/9] Update README.md [skip ci] --- README.md | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 48619655..ee473d85 100644 --- a/README.md +++ b/README.md @@ -343,9 +343,9 @@ More detailed documentation can be found [here](#account). const { res: currBalance } = await account.call(contract, "get_balance"); const amount = BigInt(10); - // Passing max_fee is currently optional - // Invoke function will handle estimateFee calculation if maxFee is not provided - await account.invoke(contract, "increase_balance", { amount }, { maxFee: BigInt("123") }); + + // Read more about max fee specification under # Funds and fees + await account.invoke(contract, "increase_balance", { amount }, { maxFee: BigInt("1000000000") }); const { res: newBalance } = await account.call(contract, "get_balance"); expect(newBalance).to.deep.equal(currBalance + amount); @@ -599,7 +599,7 @@ npm install --save-dev influenceth__cairo_math_64x61@npm:@influenceth/cairo-math ```typescript paths: { - cairoPaths: ["./node_modules"] + cairoPaths: ["./node_modules"]; } ``` @@ -679,11 +679,11 @@ await contract.invoke("increase_balance", { amount: 1 }, { wallet }); Recompilation is performed when contracts are updated or when artifacts are missing. A file will be created with the name `cairo-files-cache.json` to handle caching. Recompilation is handled before the following [CLI commands](#cli-commands) are executed. -- `npx hardhat starknet-deploy` -- `npx hardhat starknet-invoke` -- `npx hardhat starknet-call` -- `npx hardhat run` -- `npx hardhat test` +- `npx hardhat starknet-deploy` +- `npx hardhat starknet-invoke` +- `npx hardhat starknet-call` +- `npx hardhat run` +- `npx hardhat test` This feature is turned off by default and is specified in the `hardhat.config.ts` file. @@ -773,6 +773,13 @@ Once your account has funds, you can specify a max fee greater than zero: await account.invoke(contract, "foo", { arg1: ... }, { maxFee: BigInt(...) }); ``` +If you don't specify a `maxFee`, one will be calculated for you by applying an overhead of 50% to the result of fee estimation. You can also customize the overhead by providing a value for `overhead`: + +```typescript +// maxFee will be 40% of estimated fee; if overhead not provided, a default value is used. +await account.invoke(contract, "foo", { arg1: ... }, { overhead: 0.4 ); +``` + ### Multicalls You can also use the Account object to perform multi{calls, invokes, fee estimations}. From 25f19a6557ce30971314db235ecc1f6aa2348858 Mon Sep 17 00:00:00 2001 From: Nathan-SL Date: Tue, 20 Sep 2022 15:50:15 +0300 Subject: [PATCH 8/9] Add port to devnet on docker container args --- src/external-server/docker-devnet.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/external-server/docker-devnet.ts b/src/external-server/docker-devnet.ts index bd4b238a..31b7d42f 100644 --- a/src/external-server/docker-devnet.ts +++ b/src/external-server/docker-devnet.ts @@ -18,6 +18,7 @@ export class DockerDevnet extends DockerServer { } protected async getContainerArgs(): Promise { - return this.devnetArgs || []; + const containerArgs = this.devnetArgs || []; + return [...containerArgs, "--port", this.port]; } } From 42b9383cb538314a6f10b929a0102104bbeb84ee Mon Sep 17 00:00:00 2001 From: Nathan-SL Date: Thu, 22 Sep 2022 13:22:35 +0300 Subject: [PATCH 9/9] Set port to starknet networkUrl & check if port is free --- src/external-server/external-server.ts | 2 +- src/task-actions.ts | 13 +++++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/external-server/external-server.ts b/src/external-server/external-server.ts index ccdb16ae..2ff4f7f0 100644 --- a/src/external-server/external-server.ts +++ b/src/external-server/external-server.ts @@ -13,7 +13,7 @@ function sleep(amountMillis: number): Promise { }); } -function isFreePort(port: number): Promise { +export async function isFreePort(port: number): Promise { return new Promise((accept, reject) => { const sock = net.createConnection(port); sock.once("connect", () => { diff --git a/src/task-actions.ts b/src/task-actions.ts index 2e2b068d..6bec0abc 100644 --- a/src/task-actions.ts +++ b/src/task-actions.ts @@ -26,7 +26,7 @@ import { getWalletUtil } from "./extend-utils"; import { createIntegratedDevnet } from "./external-server"; import { Recompiler } from "./recompiler"; import { version } from "../package.json"; -import { getFreePort } from "./external-server/external-server"; +import { getFreePort, isFreePort } from "./external-server/external-server"; function checkSourceExists(sourcePath: string): void { if (!fs.existsSync(sourcePath)) { @@ -554,9 +554,14 @@ async function runWithDevnet(hre: HardhatRuntimeEnvironment, fn: () => Promise