diff --git a/examples/README.md b/examples/README.md index c9ef27ff..b1618434 100644 --- a/examples/README.md +++ b/examples/README.md @@ -17,19 +17,19 @@ To run an example: 1. How to deploy an account via `DEPLOY_TRANSACTION`? R: See [deployAccount](./deployAccount/main.go) 1. How to estimate fees? - R: See [deployAccount](./deployAccount/main.go), line 87. + R: See [deployAccount](./deployAccount/main.go), line 89. 1. How to generate random public and private keys? - R: See [deployAccount](./deployAccount/main.go), line 45. + R: See [deployAccount](./deployAccount/main.go), line 46. 1. How to use my existing account importing my account address, and public and private keys? - R: See [deployContractUDC](./deployContractUDC/main.go), lines 53 and 69. + R: See [deployContractUDC](./deployContractUDC/main.go), lines 54 and 64. 1. How to get my nonce? - R: See [deployContractUDC](./deployContractUDC/main.go), line 75. + R: See [deployContractUDC](./deployContractUDC/main.go), line 70. 1. How to deploy a smart contract using UDC? R: See [deployContractUDC](./deployContractUDC/main.go). 1. How to send an invoke transaction? R: See [simpleInvoke](./simpleInvoke/main.go). 1. How to get the transaction status? - R: See [simpleInvoke](./simpleInvoke/main.go), line 115. + R: See [simpleInvoke](./simpleInvoke/main.go), line 131. 1. How to deploy an ERC20 token? R: See [deployContractUDC](./deployContractUDC/main.go). 1. How to get the balance of a ERC20 token? diff --git a/examples/deployAccount/main.go b/examples/deployAccount/main.go index 1e01a329..88ee2ff1 100644 --- a/examples/deployAccount/main.go +++ b/examples/deployAccount/main.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "math" + "strconv" "github.com/NethermindEth/juno/core/felt" "github.com/NethermindEth/starknet.go/account" @@ -48,7 +49,7 @@ func main() { // Set up the account passing random values to 'accountAddress' and 'cairoVersion' variables, // as for this case we only need the 'ks' to sign the deploy transaction. - acnt, err := account.NewAccount(client, pub, pub.String(), ks, 2) + accnt, err := account.NewAccount(client, pub, pub.String(), ks, 2) if err != nil { panic(err) } @@ -72,37 +73,55 @@ func main() { }, } - precomputedAddress, err := acnt.PrecomputeAddress(&felt.Zero, pub, classHash, tx.ConstructorCalldata) + precomputedAddress, err := accnt.PrecomputeAddress(&felt.Zero, pub, classHash, tx.ConstructorCalldata) if err != nil { panic(err) } fmt.Println("PrecomputedAddress:", precomputedAddress) // Sign the transaction - err = acnt.SignDeployAccountTransaction(context.Background(), &tx.DeployAccountTxn, precomputedAddress) + err = accnt.SignDeployAccountTransaction(context.Background(), &tx.DeployAccountTxn, precomputedAddress) if err != nil { - setup.PanicRPC(err) + panic(err) } - //estimate the transaction fee - feeRes, err := acnt.EstimateFee(context.Background(), []rpc.BroadcastTxn{tx}, []rpc.SimulationFlag{}, rpc.WithBlockTag("latest")) + // Estimate the transaction fee + feeRes, err := accnt.EstimateFee(context.Background(), []rpc.BroadcastTxn{tx}, []rpc.SimulationFlag{}, rpc.WithBlockTag("latest")) if err != nil { setup.PanicRPC(err) } + estimatedFee := feeRes[0].OverallFee + var feeInETH float64 + // If the estimated fee is higher than the current fee, let's override it and sign again + if estimatedFee.Cmp(tx.MaxFee) == 1 { + newFee, err := strconv.ParseUint(estimatedFee.String(), 0, 64) + if err != nil { + panic(err) + } + tx.MaxFee = new(felt.Felt).SetUint64(newFee + newFee/5) // fee + 20% to be sure + // Signing the transaction again + err = accnt.SignDeployAccountTransaction(context.Background(), &tx.DeployAccountTxn, precomputedAddress) + if err != nil { + panic(err) + } + feeInETH, _ = utils.FeltToBigInt(tx.MaxFee).Float64() + } else { + feeInETH, _ = utils.FeltToBigInt(estimatedFee).Float64() + feeInETH += feeInETH / 5 // fee + 20% to be sure + } //converts fee value from WEI to ETH - fee, _ := utils.FeltToBigInt(feeRes[0].OverallFee).Float64() - fee = fee / (math.Pow(10, 18)) + feeInETH = feeInETH / (math.Pow(10, 18)) // At this point you need to add funds to precomputed address to use it. var input string fmt.Println("The `precomputedAddress` account needs to have enough ETH to perform a transaction.") - fmt.Printf("Use the starknet faucet to send ETH to your `precomputedAddress`. You need aproximately %f ETH. \n", fee+fee/5) + fmt.Printf("Use the starknet faucet to send ETH to your `precomputedAddress`. You need aproximately %f ETH. \n", feeInETH) fmt.Println("When your account has been funded by the faucet, press any key, then `enter` to continue : ") fmt.Scan(&input) // Send transaction to the network - resp, err := acnt.AddDeployAccountTransaction(context.Background(), tx) + resp, err := accnt.AddDeployAccountTransaction(context.Background(), tx) if err != nil { fmt.Println("Error returned from AddDeployAccountTransaction: ") setup.PanicRPC(err) diff --git a/examples/deployContractUDC/main.go b/examples/deployContractUDC/main.go index 26b70b35..54d0d58c 100644 --- a/examples/deployContractUDC/main.go +++ b/examples/deployContractUDC/main.go @@ -60,12 +60,6 @@ func main() { fmt.Println("Established connection with the client") - // Set maxFee - maxfee, err := utils.HexToFelt("0x9184e72a000") - if err != nil { - panic(err) - } - // Initialize the account accnt, err := account.NewAccount(client, accountAddressInFelt, publicKey, ks, accountCairoVersion) if err != nil { @@ -80,7 +74,7 @@ func main() { // Build the InvokeTx struct InvokeTx := rpc.InvokeTxnV1{ - MaxFee: maxfee, + MaxFee: new(felt.Felt).SetUint64(100000000000000), Version: rpc.TransactionV1, Nonce: nonce, Type: rpc.TransactionType_Invoke, @@ -112,6 +106,26 @@ func main() { panic(err) } + // Estimate the transaction fee + feeRes, err := accnt.EstimateFee(context.Background(), []rpc.BroadcastTxn{InvokeTx}, []rpc.SimulationFlag{}, rpc.WithBlockTag("latest")) + if err != nil { + setup.PanicRPC(err) + } + estimatedFee := feeRes[0].OverallFee + // If the estimated fee is higher than the current fee, let's override it and sign again + if estimatedFee.Cmp(InvokeTx.MaxFee) == 1 { + newFee, err := strconv.ParseUint(estimatedFee.String(), 0, 64) + if err != nil { + panic(err) + } + InvokeTx.MaxFee = new(felt.Felt).SetUint64(newFee + newFee/5) // fee + 20% to be sure + // Signing the transaction again + err = accnt.SignInvokeTransaction(context.Background(), &InvokeTx) + if err != nil { + panic(err) + } + } + // After the signing we finally call the AddInvokeTransaction in order to invoke the contract function resp, err := accnt.AddInvokeTransaction(context.Background(), InvokeTx) if err != nil { @@ -128,9 +142,9 @@ func main() { } // This returns us with the transaction hash and status - fmt.Println("Transaction hash response : ", resp.TransactionHash) - fmt.Println("Transaction execution status : ", txStatus.ExecutionStatus) - fmt.Println("Transaction status : ", txStatus.FinalityStatus) + fmt.Printf("Transaction hash response: %v\n", resp.TransactionHash) + fmt.Printf("Transaction execution status: %s\n", txStatus.ExecutionStatus) + fmt.Printf("Transaction status: %s\n", txStatus.FinalityStatus) } // getUDCCalldata is a simple helper to set the call data required by the UDCs deployContract function. Update as needed. diff --git a/examples/simpleInvoke/main.go b/examples/simpleInvoke/main.go index 9da8e43f..37749e74 100644 --- a/examples/simpleInvoke/main.go +++ b/examples/simpleInvoke/main.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "math/big" + "strconv" "time" "github.com/NethermindEth/juno/core/felt" @@ -56,12 +57,6 @@ func main() { fmt.Println("Established connection with the client") - // Here we are setting the maxFee - maxfee, err := utils.HexToFelt("0x9184e72a000") - if err != nil { - panic(err) - } - // Getting the nonce from the account nonce, err := accnt.Nonce(context.Background(), rpc.BlockID{Tag: "latest"}, accnt.AccountAddress) if err != nil { @@ -70,7 +65,7 @@ func main() { // Building the InvokeTx struct InvokeTx := rpc.InvokeTxnV1{ - MaxFee: maxfee, + MaxFee: new(felt.Felt).SetUint64(100000000000000), Version: rpc.TransactionV1, Nonce: nonce, Type: rpc.TransactionType_Invoke, @@ -103,12 +98,33 @@ func main() { panic(err) } + // Estimate the transaction fee + feeRes, err := accnt.EstimateFee(context.Background(), []rpc.BroadcastTxn{InvokeTx}, []rpc.SimulationFlag{}, rpc.WithBlockTag("latest")) + if err != nil { + setup.PanicRPC(err) + } + estimatedFee := feeRes[0].OverallFee + // If the estimated fee is higher than the current fee, let's override it and sign again + if estimatedFee.Cmp(InvokeTx.MaxFee) == 1 { + newFee, err := strconv.ParseUint(estimatedFee.String(), 0, 64) + if err != nil { + panic(err) + } + InvokeTx.MaxFee = new(felt.Felt).SetUint64(newFee + newFee/5) // fee + 20% to be sure + // Signing the transaction again + err = accnt.SignInvokeTransaction(context.Background(), &InvokeTx) + if err != nil { + panic(err) + } + } + // After the signing we finally call the AddInvokeTransaction in order to invoke the contract function resp, err := accnt.AddInvokeTransaction(context.Background(), InvokeTx) if err != nil { setup.PanicRPC(err) } + fmt.Println("Waiting for the transaction status...") time.Sleep(time.Second * 3) // Waiting 3 seconds //Getting the transaction status @@ -118,8 +134,8 @@ func main() { } // This returns us with the transaction hash and status - fmt.Println("Transaction hash response : ", resp.TransactionHash) - fmt.Println("Transaction execution status : ", txStatus.ExecutionStatus) - fmt.Println("Transaction status : ", txStatus.FinalityStatus) + fmt.Printf("Transaction hash response: %v\n", resp.TransactionHash) + fmt.Printf("Transaction execution status: %s\n", txStatus.ExecutionStatus) + fmt.Printf("Transaction status: %s\n", txStatus.FinalityStatus) }