From 5ec201e39999033ec6d0aa40f9414de2ecfdd7e9 Mon Sep 17 00:00:00 2001 From: ivpavici Date: Tue, 4 Jul 2023 14:50:26 +0200 Subject: [PATCH 1/2] docs: added waitForTransaction section and cleanups --- www/docs/guides/L1message.md | 9 ++- www/docs/guides/connect_account.md | 22 ++--- www/docs/guides/connect_contract.md | 8 +- www/docs/guides/connect_network.md | 13 +-- www/docs/guides/create_account.md | 48 +++++------ www/docs/guides/create_contract.md | 32 ++++---- www/docs/guides/define_call_message.md | 108 +++++++++++++------------ www/docs/guides/estimate_fees.md | 16 ++-- www/docs/guides/events.md | 9 ++- www/docs/guides/interact.md | 69 ++++++++++------ www/docs/guides/signature.md | 6 +- www/docs/guides/use_ERC20.md | 16 ++-- www/docs/guides/what_s_starknet.js.md | 6 +- 13 files changed, 195 insertions(+), 167 deletions(-) diff --git a/www/docs/guides/L1message.md b/www/docs/guides/L1message.md index b742b65e8..4d0bc962e 100644 --- a/www/docs/guides/L1message.md +++ b/www/docs/guides/L1message.md @@ -4,7 +4,7 @@ sidebar_position: 13 # Messages with L1 network -You can exchange messages between L1 & L2 networks : +You can exchange messages between L1 & L2 networks: - L2 Starknet mainnet ↔️ L1 Ethereum. - L2 Starknet testnet 1 & 2 ↔️ L1 Goerli ETH testnet. @@ -16,7 +16,8 @@ Most of the code for this message process will be written in Cairo, but Starknet ## L1 ➡️ L2 messages -To send a message from L1 to L2, you need a solidity smart contract in the L1 network, calling the `SendMessageToL2` function of the Starknet core contract. The interface of this function : +To send a message from L1 to L2, you need a solidity smart contract in the L1 network, calling the `SendMessageToL2` function of the Starknet core contract. +The interface of this function: ```solidity /** @@ -31,7 +32,7 @@ function sendMessageToL2( ) external payable returns (bytes32, uint256); ``` -You have to pay in the L1 an extra fee when invoking `sendMessageToL2` (of course paid with the L1 fee TOKEN), to pay the L2 part of the messaging mechanism. You can estimate this fee with this function : +You have to pay in the L1 an extra fee when invoking `sendMessageToL2` (of course paid with the L1 fee TOKEN), to pay the L2 part of the messaging mechanism. You can estimate this fee with this function: ```typescript import { SequencerProvider } from "starknet"; @@ -51,7 +52,7 @@ If the fee is paid in L1, the cairo contract at `to_Address` is automatically ex To send a message to L1, you will just invoke a cairo contract function, paying a fee that will pay all the process (in L1 & L2). -If necessary you can estimate this fee with the generic `estimateInvokeFee` function : +If necessary you can estimate this fee with the generic `estimateInvokeFee` function: ```typescript const { suggestedMaxFee: estimatedFee1 } = await account0.estimateInvokeFee({ diff --git a/www/docs/guides/connect_account.md b/www/docs/guides/connect_account.md index 9d3ab0022..2b3c9e8f5 100644 --- a/www/docs/guides/connect_account.md +++ b/www/docs/guides/connect_account.md @@ -2,11 +2,11 @@ sidebar_position: 4 --- -# 🔌 Connect an existing account +# 🔌 Connect to an existing account Once your provider is initialized, you can connect an existing account. -You need 2 data : +You need 2 data pieces of: - the address of the account - the private key of this account @@ -15,15 +15,15 @@ You need 2 data : import { Account, Provider } from "starknet"; ``` -## Connect a predeployed account in Starknet-devnet +## Connect to a pre-deployed account in Starknet-devnet -When you launch starknet-devnet, 10 accounts are predeployed with 100 dummy ETH in each. +When you launch starknet-devnet, 10 accounts are pre-deployed with 100 dummy ETH in each. Addresses and private keys are displayed on the console at initialization. -> This data will change at each launch, so to freeze them, launch with : `starknet-devnet --seed 0`. +> This data will change at each launch, so to freeze them, launch with: `starknet-devnet --seed 0`. -The result for `account #0` : +The result for `account #0`: ```bash Address: 0x7e00d496e324876bbc8531f2d9a82bf154d1a04a50218ee74cdd372f75a551a @@ -31,7 +31,7 @@ Public key: 0x7e52885445756b313ea16849145363ccb73fb4ab0440dbac333cf9d13de82b9 Private key: 0xe3e70682c2094cac629f6fbed82c07cd ``` -Then you can use this code : +Then you can use this code: ```typescript // initialize provider @@ -45,15 +45,15 @@ const account = new Account(provider, accountAddress, privateKey); Your account is now connected, and you can use it. -## 👛 Connect an existing account (in any network) +## 👛 Connect to a existing account (in any network) -The code is exactly the same, you just have to : +The code is exactly the same, you just have to: - connect to the appropriate network. - use the address of this account (public data). -- use the private key of this account (very sensitive data : your code MUST not disclose it). +- use the private key of this account (very sensitive data: your code MUST not disclose it). -For example, to connect an existing account to testnet, with a private key stored in .env non archived file : +For example, to connect an existing account to testnet, with a private key stored in .env non archived file: ```typescript import * as dotenv from "dotenv"; diff --git a/www/docs/guides/connect_contract.md b/www/docs/guides/connect_contract.md index a3246739a..0cda7d4b5 100644 --- a/www/docs/guides/connect_contract.md +++ b/www/docs/guides/connect_contract.md @@ -6,12 +6,12 @@ sidebar_position: 5 Once your provider is initialized, you can connect a contract already deployed in the network. -You need 2 data : +You need 2 pieces of data: - the address of the contract - the ABI file of the contract (or the compiled/compressed contract file, that includes the abi) -> If you don't have the abi file, the `provider.getClassAt()` and `provider.getClassByHash()` commands will recover the compressed contract file. As these methods generate a significant workload to the sequencer/node, it's recommended to store the result in your computer, to be able to reuse it later without using the provider : +> If you don't have the abi file, the `provider.getClassAt()` and `provider.getClassByHash()` commands will recover the compressed contract file. As these methods generate a significant workload to the sequencer/node, it's recommended to store the result in your computer, to be able to reuse it later without using the provider: ```typescript import fs from "fs"; @@ -27,7 +27,7 @@ fs.writeFileSync('./myAbi.json', json.stringify( compressedContract.abi, undefin import { Provider, Contract, json } from "starknet"; ``` -If you have the compiled/compressed file of the contract, use this code to recover all data, including ABI : +If you have the compiled/compressed file of the contract, use this code to recover all data, including the ABI: ```typescript const compiledContract = json.parse(fs.readFileSync("./compiledContracts/test.json").toString("ascii")); @@ -35,7 +35,7 @@ const compiledContract = json.parse(fs.readFileSync("./compiledContracts/test.js > Note the `json.parse` util provided by Starknet.js -## Connect the contract +## Connect to the contract ```typescript // initialize provider diff --git a/www/docs/guides/connect_network.md b/www/docs/guides/connect_network.md index bece4ba4a..91e7849de 100644 --- a/www/docs/guides/connect_network.md +++ b/www/docs/guides/connect_network.md @@ -35,7 +35,7 @@ const provider = new Provider({ sequencer: { baseUrl:"http://127.0.0.1:5050"} }) ## Connect your DAPP to a private Starknet network -If necessary you can have a full control on the network access (for example, for your company private test network) : +If necessary you can have a full control on the network access (for example, for your company private test network): ```typescript const provider = new Provider({ @@ -49,13 +49,14 @@ const provider = new Provider({ ## Connect your DAPP to a Starknet node -For a local [Pathfinder](https://github.com/eqlabs/pathfinder) node : +For a local [Pathfinder](https://github.com/eqlabs/pathfinder) node: ```typescript const provider = new Provider({ rpc: { nodeUrl: '127.0.0.1:9545' } }) ``` -Your node can be located in your local network (example : pathfinder node located in a computer of you network, launched with this additional option : `--http-rpc 0.0.0.0:9545`). You connect with : +Your node can be located in your local network (example: pathfinder node running nn a computer on your network, launched with this additional option: `--http-rpc 0.0.0.0:9545`). +You can connect with: ```typescript const provider = new Provider({ rpc: { nodeUrl: '192.168.1.99:9545' } }) @@ -67,7 +68,7 @@ Some methods are available only if connected to a sequencer, and some others are ### Specific sequencer methods -For example, if you want to estimate the fee of a L1 ➡️ L2 message, you need to use a method that is available only in the sequencer. The class `SequencerProvider` is available for this case : +For example, if you want to estimate the fee of a L1 ➡️ L2 message, you need to use a method that is available only in the sequencer. The class `SequencerProvider` is available for this case: ```typescript import { SequencerProvider, constants } from "starknet"; @@ -77,7 +78,7 @@ const responseEstimateMessageFee = await provider.estimateMessageFee(.....) ### Specific RPC methods -For example, if you want to read the events recorded in a range of blocks, you need to use a method available from a RPC node. The class `RpcProvider` is available for this case : +For example, if you want to read the events recorded in a range of blocks, you need to use a method available from a RPC node. The class `RpcProvider` is available for this case: ```typescript import { RpcProvider } from "starknet"; @@ -93,7 +94,7 @@ let eventsList = await providerRPC.getEvents({ RPC providers are for example Infura, Alchemy, Chainstack... Or you can spin up your own Pathfinder node! -For example, to connect to Alchemy with your personal API key : +For example, to connect to Alchemy with your personal API key: ```typescript const providerRPC = new RpcProvider({ nodeUrl: 'https://starknet-mainnet.g.alchemy.com/v2/' + alchemyKey}); diff --git a/www/docs/guides/create_account.md b/www/docs/guides/create_account.md index ffd6653fe..f775522c3 100644 --- a/www/docs/guides/create_account.md +++ b/www/docs/guides/create_account.md @@ -2,23 +2,23 @@ sidebar_position: 8 --- -# Create account +# Create an account Since there are no Externally Owned Accounts (EOA) in Starknet, all Accounts in Starknet are contracts. Unlike in Ethereum where a wallet is created with a public and private key pair, Starknet Accounts are the only way to sign transactions and messages, and verify signatures. Therefore a Account - Contract interface is needed. Account contracts on Starknet cannot be deployed without paying a fee. -Create an account is a bit tricky ; you have several steps : +Create an account is a bit tricky ; you have several steps: 1. Decide on your account type (OpenZeppelin, ArgentX, Braavos, ...). 2. Compute the address of your future account. 3. Send funds to this pre-computed address. The funds will be used to pay for the account contract deployment, and remains will fund the new account. 4. Actual deployment of the Account -## Create OZ (Open Zeppelin) account : +## Create an OZ (Open Zeppelin) account -> Level : easy. +> Level: easy. Here, we will create a wallet with the Open Zeppelin smart contract v0.5.1. The contract class is already implemented in both Testnet 1 & 2. This contract is coded in Cairo 0, so it will not survive to the upcoming regenesis of Starknet. @@ -27,16 +27,16 @@ This contract is coded in Cairo 0, so it will not survive to the upcoming regene import { Account, constants, ec, json, stark, Provider, hash, CallData } from "starknet"; ``` -### compute address : +### compute address ```typescript // connect provider const provider = new Provider({ sequencer: { network: constants.NetworkName.SN_GOERLI } }); -// new Open Zeppelin account v0.5.1 : - // Generate public and private key pair. +// new Open Zeppelin account v0.5.1 +// Generate public and private key pair. const privateKey = stark.randomAddress(); -console.log('New OZ account :\nprivateKey=', privateKey); +console.log('New OZ account:\nprivateKey=', privateKey); const starkKeyPub = ec.starkCurve.getStarkKey(privateKey); console.log('publicKey=', starkKeyPub); @@ -56,7 +56,7 @@ If you want a specific private key, replace `stark.randomAddress()` by your choi Then you have to fund this address! -How to proceed is out of the scope of this guide, but you can for example : +How to proceed is out of the scope of this guide, but you can for example: - Transfer ETH from another wallet. - Bridge ETH to this Starknet address. @@ -70,7 +70,7 @@ curl -X POST http://127.0.0.1:5050/mint -d '{"address":"0x04a093c37ab61065d00155 ### deployment of the new account -If you have sent enough fund to this new address, you can go forward to the final step : +If you have sent enough fund to this new address, you can go forward to the final step: ```typescript const OZaccount = new Account(provider, OZcontractAddress, privateKey); @@ -85,9 +85,9 @@ await provider.waitForTransaction(transaction_hash); console.log('✅ New OpenZeppelin account created.\n address =', contract_address); ``` -## Create Argent account +## Create an Argent account -> Level : medium. +> Level: medium. Here, we will create a wallet with the Argent smart contract v0.2.3. This case is more complicated, because we will have the account behind a proxy contract (this way, the wallet contract can be updated). The contract classes of both contracts are already implemented in both Testnet 1 & 2. @@ -103,7 +103,7 @@ import { Account, ec, json, stark, Provider, hash, CallData } from "starknet"; // connect provider const provider = new Provider({ sequencer: { network: constants.NetworkName.SN_GOERLI } }); -//new Argent X account v0.2.3 : +//new Argent X account v0.2.3 const argentXproxyClassHash = "0x25ec026985a3bf9d0cc1fe17326b245dfdc3ff89b8fde106542a3ea56c5a918"; const argentXaccountClassHash = "0x033434ad846cdd5f23eb73ff09fe6fddd568284a0fb7d1be20ee482f044dabe2"; @@ -134,7 +134,7 @@ Then you have to fund this address. ### deployment of the new account -If you have sent enough fund to this new address, you can go forward to the final step : +If you have sent enough fund to this new address, you can go forward to the final step: ```typescript const accountAX = new Account(provider, AXcontractAddress, privateKeyAX); @@ -146,22 +146,22 @@ const deployAccountPayload = { addressSalt: starkKeyPubAX }; const { transaction_hash: AXdAth, contract_address: AXcontractFinalAdress } = await accountAX.deployAccount(deployAccountPayload); -console.log('✅ ArgentX wallet deployed at :',AXcontractFinalAdress); +console.log('✅ ArgentX wallet deployed at:',AXcontractFinalAdress); ``` -## Create Braavos account +## Create a Braavos account -> Level : hard. +> Level: hard. Even more complicated, a Braavos account needs also a proxy, but needs in addition a specific signature. Starknet.js is handling only Starknet standard signatures ; so we needs extra code to handle this specific signature for account creation. These nearly 200 lines of code are not displayed here, but are available in a module [here](./compiled_contracts/deployBraavos.ts). -We will deploy hereunder a Braavos account in devnet. So launch starknet-devnet with these parameters : +We will deploy hereunder a Braavos account in devnet. So launch starknet-devnet with these parameters: ```bash starknet-devnet --seed 0 --fork-network alpha-goerli ``` -Initialization : +Initialization: ```typescript import { Provider, Account, num, stark } from "starknet"; @@ -172,7 +172,7 @@ import { calculateAddressBraavos, import axios from "axios"; ``` -If you want to create yourself the private key, for example with a random number : +If you want to create yourself the private key, for example with a random number: ```typescript const privateKeyBraavos = stark.randomAddress(); @@ -228,7 +228,7 @@ The computed address has been funded automatically by minting new dummy ETH in S You are not limited to these 3 contracts contracts. You can create your own contract for wallet. It's the concept of Account Abstraction. -You can customize entirely the wallet - for example : +You can customize entirely the wallet - for example: - use a different concept of keys. @@ -246,7 +246,7 @@ You can customize entirely the wallet - for example : The only limitation is your imagination... -Here is an example of a customized wallet, including super administrator management, on a local starknet-devnet : +Here is an example of a customized wallet, including super administrator management, on a local starknet-devnet: > launch `starknet-devnet --seed 0` before using this script @@ -265,10 +265,10 @@ const privateKey0 = "0xe3e70682c2094cac629f6fbed82c07cd"; const accountAddress0 = "0x7e00d496e324876bbc8531f2d9a82bf154d1a04a50218ee74cdd372f75a551a"; const account0 = new Account(provider, accountAddress0, privateKey0); -// new account abstraction : +// new account abstraction // Generate public and private key pair. const AAprivateKey = stark.randomAddress(); -console.log('New account :\nprivateKey=', AAprivateKey); +console.log('New account:\nprivateKey=', AAprivateKey); const AAstarkKeyPub = ec.starkCurve.getStarkKey(AAprivateKey); console.log('publicKey=', AAstarkKeyPub); diff --git a/www/docs/guides/create_contract.md b/www/docs/guides/create_contract.md index 84f8bb08b..2615b7f90 100644 --- a/www/docs/guides/create_contract.md +++ b/www/docs/guides/create_contract.md @@ -2,11 +2,11 @@ sidebar_position: 7 --- -# Create new contract +# Create a new contract When you have compiled your new Cairo contract, you can deploy it in the network. -In Starknet, a new contract has to be added in two phases : +In Starknet, a new contract has to be added in two phases: 1. Create the contract class. 2. Deploy an instance of the contract. @@ -24,7 +24,7 @@ You will have only one Class Hash for one contract code, but you can have as man Other users of the network can use your declared contract. It means that if somebody has already declared a contract class (and paid this declaration), and if you would like to have your own instance of this contract, you have only to deploy (and pay) a new instance. -Example : if you want an ERC20 contract, and somebody has already declared an ERC20 contract that conforms to your needs, you have just to deploy a new instance of this contract class. +Example: if you want an ERC20 contract, and somebody has already declared an ERC20 contract that conforms to your needs, you have just to deploy a new instance of this contract class. ```typescript import { Provider, Account, Contract, json, stark, uint256, shortString } from "starknet"; @@ -32,14 +32,14 @@ import { Provider, Account, Contract, json, stark, uint256, shortString } from " ## `declareAndDeploy()` your new contract -Starknet.js proposes a function to perform both operations in one step : `declareAndDeploy()`. +Starknet.js proposes a function to perform both operations in one step: `declareAndDeploy()`. -Here, to declare & deploy a `Test.cairo` smartcontract, in devnet : +Here, to declare & deploy a `Test.cairo` smart contract, in devnet: ```typescript // connect provider const provider = new Provider({ sequencer: { baseUrl: "http://127.0.0.1:5050" } }); -// connect your account. To adapt to your own account : +// connect your account. To adapt to your own account: const privateKey0 = process.env.OZ_ACCOUNT_PRIVATE_KEY; const account0Address: string = "0x123....789"; const account0 = new Account(provider, account0Address, privateKey0); @@ -49,7 +49,7 @@ const compiledTestSierra = json.parse(fs.readFileSync( "./compiledContracts/test const compiledTestCasm = json.parse(fs.readFileSync( "./compiledContracts/test.casm").toString( "ascii")); const deployResponse = await account0.declareAndDeploy({ contract: compiledTestSierra, casm: compiledTestCasm }); -// Connect the new contract instance : +// Connect the new contract instance: const myTestContract = new Contract(compiledTest.abi, deployResponse.deploy.contract_address, provider); console.log("Test Contract Class Hash =", deployResponse.declare.class_hash); console.log('✅ Test Contract connected at =', myTestContract.address); @@ -57,12 +57,12 @@ console.log('✅ Test Contract connected at =', myTestContract.address); ## `deployContract()` for a new instance -If the contract class is already declared, it's faster and cheaper : just use `deployContract()`. +If the contract class is already declared, it's faster and cheaper: just use `deployContract()`. ```typescript // connect provider const provider = new Provider({ sequencer: { baseUrl: "http://127.0.0.1:5050" } }); -// connect your account. To adapt to your own account : +// connect your account. To adapt to your own account: const privateKey0 = process.env.OZ_ACCOUNT_PRIVATE_KEY; const account0Address: string = "0x123....789"; @@ -79,7 +79,7 @@ await provider.waitForTransaction( deployResponse.transaction_hash); const { abi: testAbi } = await provider.getClassByHash( testClassHash); if (testAbi === undefined) { throw new Error("no abi.") }; -// Connect the new contract instance : +// Connect the new contract instance: const myTestContract = new Contract(testAbi, deployResponse.contract_address, provider); console.log('✅ Test Contract connected at =', myTestContract.address); ``` @@ -87,7 +87,7 @@ console.log('✅ Test Contract connected at =', myTestContract.address); ## Construct the constructor If your contract has a constructor with inputs, you have to provide these inputs in the `deployContract` or `declareAndDeploy` commands. -For example, with this contract constructor : +For example, with this contract constructor: ```json "name": "constructor", @@ -107,11 +107,11 @@ For example, with this contract constructor : ], ``` -You have several ways to define these inputs : +You have several ways to define these inputs: ### myCalldata.compile -This is the recommended way to proceed : +This is the recommended way to proceed: ```typescript const myArray1: RawCalldata = ["0x0a", 24, 36n]; @@ -131,7 +131,7 @@ Starknet.js will perform a full verification of conformity with the abi. Propert ### CallData.compile -For very simple constructors, you can use `CallData.compile` : +For very simple constructors, you can use `CallData.compile`: ```typescript const myArray1: RawCalldata = ["0x0a", 24, 36n]; @@ -161,7 +161,7 @@ If you want only declare a new Contract Class, use `declare()`. ```typescript // connect provider const provider = new Provider({ sequencer: { baseUrl: "http://127.0.0.1:5050" } }); -// connect your account. To adapt to your own account : +// connect your account. To adapt to your own account: const privateKey0 = process.env.OZ_ACCOUNT_PRIVATE_KEY; const account0Address: string = "0x123....789"; @@ -169,7 +169,7 @@ const account0 = new Account(provider, account0Address, starkKeyPair0); // Declare Test contract in devnet const compiledTestSierra = json.parse(fs.readFileSync( "./compiledContracts/test.sierra").toString("ascii")); -const compiledtestCasm = json.parse(fs.readFileSync( "./compiledContracts/test.casm").toString("ascii")); +const compiledTestCasm = json.parse(fs.readFileSync( "./compiledContracts/test.casm").toString("ascii")); const declareResponse = await account0.declare({ contract: compiledTestSierra, casm: compiledTestCasm }); console.log('Test Contract declared with classHash =', declareResponse.class_hash); await provider.waitForTransaction(declareResponse.transaction_hash); diff --git a/www/docs/guides/define_call_message.md b/www/docs/guides/define_call_message.md index 3df451528..1e8888323 100644 --- a/www/docs/guides/define_call_message.md +++ b/www/docs/guides/define_call_message.md @@ -17,12 +17,12 @@ In Starknet.js, you can perform these transformations manually, but you can take ### Cairo -Cairo has 2 versions, involving 2 types of data : +Cairo has 2 versions, involving 2 types of data: -- **Cairo 0** : here, everything is felt, an integer on 251 bits. - Available : array, struct, tuple, named tuple, a mix of these elements. -- **Cairo 1** : with plethora of literal types : u8, u16, u32, usize, u64, u128, felt252, u256, bool, address. - Available : array, struct, tuple, a mix of these elements. +- **Cairo 0**: here, everything is felt, an integer on 251 bits. + Available: array, struct, tuple, named tuple, a mix of these elements. +- **Cairo 1**: with plethora of literal types: u8, u16, u32, usize, u64, u128, felt252, u256, bool, address. + Available: array, struct, tuple, a mix of these elements. Starknet.js is compatible with both versions. @@ -34,10 +34,10 @@ Starknet is waiting a list of felts, and answers with the same format. These types does not exist in JS/TS - you have Number, bigInt, string, array, objects... and types defined in libraries. -In Starknet.js, it's a bit ... complicated : you have the BigNumberish type and it can include: +In Starknet.js, it's a bit ... complicated: you have the BigNumberish type and it can include: -- String representing a number : "123", "0xabc2" -- Number (max 53 bits) : 123 +- String representing a number: "123", "0xabc2" +- Number (max 53 bits): 123 - BigInt (max 255 bits): 12345612345n ```typescript @@ -47,12 +47,12 @@ const decimals: BigNumberish = 18; ## Preparation of data before delivery -If your Cairo smart-contract is waiting a : +If your Cairo smart-contract is waiting a: ### felt, u8, u16, u32, usize, u64, u128, felt252, address Starknet is waiting a felt. -You can send to Starknet.js methods : bigNumberish. +You can send to Starknet.js methods: bigNumberish. ```typescript await myContract.my_function(12,"13","0xe",15n); @@ -61,7 +61,7 @@ await myContract.my_function(12,"13","0xe",15n); ### bool Starknet is waiting a felt, containing 0 or 1. -You can send to Starknet.js methods : boolean, bigNumberish. +You can send to Starknet.js methods: boolean, bigNumberish. ```typescript await myContract.my_function(true,1); @@ -70,7 +70,7 @@ await myContract.my_function(true,1); ### u256 Starknet is waiting 2 felts, the first including the lowest 128 bits, the second including the 128 highest bits. -You can send to Starknet.js methods : bigNumberish (Cairo 1 only), Uint256 object (both Cairo 0 & 1). +You can send to Starknet.js methods: bigNumberish (Cairo 1 only), Uint256 object (both Cairo 0 & 1). ```typescript await myContract0.my_function({low: 100, high: 0}) // Cairo 0 & 1 contract @@ -78,7 +78,7 @@ await myContract1.my_function(cairo.uint256(100)) // Cairo 0 & 1 contract await myContract2.my_function(12345678, "13456789765", "0xe23a40b543f", 1534566734334n) // Cairo 1 contract ``` -In specific cases that we will see hereunder, you can use an object, with the following format : +In specific cases that we will see hereunder, you can use an object, with the following format: ```typescript const a1: Uint256 = cairo.uint256("0x05f7cd1fd465baff2ba9d2d1501ad0a2eb5337d9a885be319366b5205a414fdd") @@ -89,43 +89,43 @@ const a3: Uint256 = {low: a1.low,high: a1.high}; ### string Starknet is waiting a felt, including 31 ASCII characters max. -You can send to Starknet.js methods : string, bigNumberish. +You can send to Starknet.js methods: string, bigNumberish. ```typescript await myContract.my_function("Token","0x0x534e5f4d41494e") ``` -To encode yourself a string : +To encode yourself a string: ```typescript const encStr: string = shortString.encodeShortString("Stark"); ``` -To decode yourself a string : +To decode yourself a string: ```typescript const decStr: string = shortString.decodeShortString("0x7572692f706963742f7433382e6a7067"); ``` -the result is : "uri/pict/t38.jpg" +The result is: "uri/pict/t38.jpg" ### longString longString is a string that may contain more than 31 characters. Starknet is waiting an array of felt: string_len, string1, string2, ... -You can send to Starknet.js methods : string, bigNumberish[]. +You can send to Starknet.js methods: string, bigNumberish[]. ```typescript await myContract.my_function("http://addressOfMyERC721pictures/image1.jpg") ``` -If you want to split yourself your longString in 31 chars substrings : +If you want to split yourself your longString in 31 chars substrings: ```typescript const splitted: string[] = shortString.splitLongString("http://addressOfMyERC721pictures/image1.jpg") ``` -If you want to split yourself your longString in an array of felts : +If you want to split your longString in an array of felts: ```typescript const longString: string[] = shortString.splitLongString("http://addressOfMyERC721pictures/image1.jpg" ).map( str => shortString.encodeShortString( str)) @@ -134,14 +134,14 @@ const longString: string[] = shortString.splitLongString("http://addressOfMyERC7 ### tuple Starknet is waiting a list of felts. -You can send to Starknet.js methods : `cairo.tuple()`, object. +You can send to Starknet.js methods: `cairo.tuple()`, object. ```typescript const myTpl = cairo.tuple("0x0a", 200); await myContract.my_function(myTpl); ``` -To construct yourself your tuple : +To construct your tuple: ```typescript const myTpl = {"0": "0x0a", "1": 200}; @@ -152,8 +152,8 @@ const myTpl = {"0": "0x0a", "1": 200}; > Only for Cairo 0. Starknet is waiting a list of felts. -You can send to Starknet.js methods : an object, `cairo.tuple()`, list of bigNumberish. -From this ABI : +You can send to Starknet.js methods: an object, `cairo.tuple()`, list of bigNumberish. +From this ABI: ```json { @@ -162,7 +162,7 @@ From this ABI : } ``` -you can create this code : +You can create this code: ```typescript const namedTup = {min: "0x4e65ac6", max: 296735486n}; @@ -173,8 +173,8 @@ await myContract.my_function(namedTup); ### struct -Starknet is waiting a list of felts. -You can send to Starknet.js methods : an object. +Starknet is waiting for a list of felts. +You can send to Starknet.js methods: an object. ```typescript const myStruct = {type: "TR1POST", tries: 8, isBridged: true}; @@ -183,22 +183,22 @@ await myContract.my_function(myStruct); ### array -Starknet is waiting an array of felt: array_len, array1, array2, ... -You can send to Starknet.js methods : bigNumberish[]. +Starknet is waiting an array of felts: array_len, array1, array2, ... +You can send to Starknet.js methods: bigNumberish[]. ```typescript Const myArray = [10,"0xaa",567n]; await myContract.my_function(myArray); ``` -> Do not add the `array_len` parameter before your array ; Starknet.js will manage automatically this element. +> Do not add the `array_len` parameter before your array. Starknet.js will manage this element automatically. ### complex types You can mix and nest literals, arrays, structs and tuples. -Starknet is waiting a list of felt. -All these examples are valid : +Starknet is waiting a list of felts. +All these examples are valid: ```typescript type Order2 = { @@ -218,7 +218,7 @@ await myContract.my_function(param1, param2, param3, param4); ## Authorized types for Starknet.js methods -There are 12 methods using contract parameters. Some types are authorized for each method : +There are 12 methods using contract parameters. Some types are authorized for each method: ### list of parameters @@ -247,7 +247,7 @@ const txResp = await account0.execute({ calldata: myParams}); ``` -All Starknet.js methods accepts this type of input, except meta-class, that needs 3 dots prefix : +All Starknet.js methods accepts this type of input, except meta-class, that needs 3 dots prefix: ```typescript const myParams = ["TOKEN", "13", [10, 11, 12], 135438734812n]; @@ -261,7 +261,7 @@ await myContract[functionName](...myParams); ### Object (without ABI conformity check) -Use of objects allows a clear representation of the list of parameters : +Use of objects allows a clear representation of the list of parameters: ```typescript const myParams = { @@ -273,7 +273,7 @@ const deployResponse = await myAccount.deployContract({ constructorCalldata: myParams }); ``` -This type is available for : `CallData.compile(), hash.calculateContractAddressFromHash, account.deployContract, account.deployAccount, account.execute` +This type is available for: `CallData.compile(), hash.calculateContractAddressFromHash, account.deployContract, account.deployAccount, account.execute` > Objects properties have to be ordered in accordance with the ABI. @@ -297,7 +297,7 @@ const functionParameters: RawArgsObject = {//wrong order ; all properties are mi initial_supply: myFalseUint256, recipient: account0.address, decimals: 18, - tupoftup: cairo.tuple(cairo.tuple(34,"0x5e") ,myFalseUint256), + tupOfTup: cairo.tuple(cairo.tuple(34,"0x5e") ,myFalseUint256), card: myOrder2bis, longText: "Zorg is back, for ever, here and everywhere", array1: [100, 101, 102], @@ -321,15 +321,15 @@ const myCall: Call = myContract.populate("get_elements", functionParameters); const res = await myContract.get_elements(...myCall.calldata); ``` -It can be used only with methods that knows the abi : `Contract.populate, myCallData.compile`. +It can be used only with methods that knows the abi: `Contract.populate, myCallData.compile`. Starknet.js will perform a full check of conformity with the ABI of the contract, reorder the objects properties if necessary, stop if something is wrong or missing, remove not requested properties, convert everything to Starknet format. Starknet.js will alert earlier of errors in your parameters (with human comprehensible words), before call to Starknet. So, no more incomprehensible Starknet messages due to parameters construction. -If a property `array_len` has been added before an array , this property is ignored as it's automatically managed by Starknet.js. +If a property `array_len` has been added before an array, this property is ignored as it's automatically managed by Starknet.js. ### Call, or Call[] -A Call is an object with this format : +A Call is an object with this format: ```typescript type Call = { @@ -339,7 +339,7 @@ type Call = { } ``` -and is only authorized with `Account.execute `. It can be generated manually or by `Contract.populate()` : +...and is only authorized with `Account.execute `. It can be generated manually or by `Contract.populate()`: ```typescript const myCall: Call = myContract.populate("get_component", [100, recipient]); @@ -353,7 +353,7 @@ const myCall: Call = { const tx = await account0.execute(myCall); ``` -It's particularly interesting when you want to invoke a function several times in the same transaction : +It's particularly interesting when you want to invoke a function several times in the same transaction: ```typescript const myCall1: Call = myContract.populate("mint", {type: 7, qty: 10}); @@ -366,7 +366,7 @@ const tx = await account0.execute([myCall1, myCall2, myCall3]); This type is particularly useful when you need the maximum of performance and speed in your code ; You have no automatic transformation, no checks with ABI, no parsing. -You provide to starknet.js the low level data expected by Starknet : +You provide to starknet.js the low level data expected by Starknet: ```typescript const specialParameters: Calldata = [ @@ -408,16 +408,18 @@ These types of arguments can't be used at your convenience everywhere. Here is a ## Receive data from a Cairo contract -When you perform a call, the result depends of the contract language : +When you perform a call, the result depends of the contract language: + +- In Cairo 0, then answer is an object, with keys using the Cairo variables names. -- In Cairo 0, then answer is an object, with keys using the Cairo variables names. Example : +Example: ```typescript const res=myContract.call(...); const amount = res.amount; ``` -- In Cairo 1, the result is a variable : +- In Cairo 1, the result is a variable: ```typescript const amount = myContract.call(...); @@ -448,7 +450,7 @@ const isAbiCairo1: boolean = cairo.isCairo1Abi(myAbi); ### parseRequest -If for any reason (mainly for speed of processing), you want to define yourself the low level parameters to send to Starknet, you can use the parseRequest option. +If for any reason (mainly for speed of processing), you want to define yourself the low level parameters to send to Starknet, you can use the `parseRequest` option. Parameters are an array of strings (representing numbers). ```typescript @@ -468,20 +470,20 @@ If for any reason, you want to receive a low level answer from Starknet, you can const result = await myContract.call("get_bals",100n, {parseResponse: false}); ``` -answer is an array of strings (representing numbers). +Answer is an array of strings (representing numbers). ### formatResponse -As seen above, the strings returned by Starknet are not automatically parsed, because ABI do not inform when a contract returns a string. -But there is a way to have an automatic parse of a string : +As seen above, the strings returned by Starknet are not automatically parsed, because ABI does not inform when a contract returns a string. +But there is a way to have automatic parsing of a string. -As example, if a contract returns a struct containing a shortString and a longString : +As example, if a contract returns a struct containing a shortString and a longString: ```typescript { name: felt252, description: Array } ``` -You can automatize the strings parse with : +You can automate the string parsing with: ```typescript const formatAnswer = { name: 'string', description: 'string' } @@ -492,7 +494,7 @@ const result = await myContract.get_text(calldata, { }); ``` -The result will be an object, with 2 string : +The result will be an object, with 2 strings: ```typescript { name: "Organic", description: "The best way to read a long string!!!" } diff --git a/www/docs/guides/estimate_fees.md b/www/docs/guides/estimate_fees.md index 0c4bd5b8e..6ef9fb492 100644 --- a/www/docs/guides/estimate_fees.md +++ b/www/docs/guides/estimate_fees.md @@ -8,11 +8,11 @@ By default, all non free Starknet commands (declare, deploy, invoke) work withou Nevertheless, you might want to inform the DAPP user of the cost of the incoming transaction before proceeding, and request its validation. -Starknet.js proposes several functions to estimate the fees : +Starknet.js proposes several functions to estimate the fees: ## estimateDeclareFee -To estimate the cost to declare a contract in the network : +To estimate the cost to declare a contract in the network: ```typescript const { suggestedMaxFee: estimatedFee1 } = await account0.estimateDeclareFee({ @@ -25,7 +25,7 @@ The result is in `estimatedFee1`, of type BigInt. ## estimateDeployFee -To estimate the cost to deploy a contract in the network : +To estimate the cost to deploy a contract in the network: ```typescript const { suggestedMaxFee: estimatedFee1 } = await account0.estimateDeployFee({ classHash: testClassHash }); @@ -35,7 +35,7 @@ The result is in `estimatedFee1`, of type BigInt. ## estimateAccountDeployFee -To estimate the cost to deploy an account in the network : +To estimate the cost to deploy an account in the network: ```typescript const { suggestedMaxFee: estimatedFee1 } = await account0.estimateAccountDeployFee({ @@ -49,7 +49,7 @@ The result is in `estimatedFee1`, of type BigInt. ## estimateInvokeFee -To estimate the cost to invoke a contract in the network : +To estimate the cost to invoke a contract in the network: ```typescript const { suggestedMaxFee: estimatedFee1 } = await account0.estimateInvokeFee({ @@ -64,20 +64,20 @@ The result is in `estimatedFee1`, of type BigInt. ## Fee limitation In all non-free functions, you can add an optional parameter limiting the fee consumption. -If the fee has been previously estimated, you can use this value for this parameter, but sometimes this value is under-evaluated : **don't hesitate to add a margin of approximately 10%** : +If the fee has been previously estimated, you can use this value for this parameter, but sometimes this value is under-evaluated: **don't hesitate to add a margin of approximately 10%**: ```typescript estimatedFee1 * 11n / 10n ``` -You can also use the `stark.estimatedFeeToMaxFee` function : +You can also use the `stark.estimatedFeeToMaxFee` function: ```typescript import { stark } from "starknet"; stark.estimatedFeeToMaxFee(estimatedFee1, 0.1); ``` -Example for declare : +Example for declare: ```typescript const { suggestedMaxFee: estimatedFee1 } = await account0.estimateDeclareFee({ contract: compiledTest }); diff --git a/www/docs/guides/events.md b/www/docs/guides/events.md index d974bcf52..19d910264 100644 --- a/www/docs/guides/events.md +++ b/www/docs/guides/events.md @@ -16,7 +16,8 @@ The events are stored in a block on the blockchain. ## Events in the Cairo code -You have to analyze the Cairo code of your smart contract, to recover the list of data emitted by the event. An example in Cairo 0 : +You have to analyze the Cairo code of your smart contract, to recover the list of data emitted by the event. +An example in Cairo 0: ```cairo @event @@ -34,7 +35,7 @@ func my_func{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() Here, we can see that the event will store 3 felts. -Once compiled, this code will generate an abi file containing : +Once compiled, this code will generate an abi file containing: ```typescript { @@ -61,7 +62,7 @@ const txReceiptDeployTest: InvokeTransactionReceiptResponse = await provider.wai console.log("events =",txReceiptDeployTest.events); ``` -Now, you have all the events of the block. Here, we have 2 events - the last one contains our data : +Now, you have all the events of the block. Here, we have 2 events - the last one contains our data: ```typescript [ @@ -89,7 +90,7 @@ Now, you have all the events of the block. Here, we have 2 events - the last one ``` -Use the contract deployment address `testContractAddress`, to filter the events and read the data from your smart contract : +Use the contract deployment address `testContractAddress`, to filter the events and read the data from your smart contract: ```typescript const event = txReceiptDeployTest.events.find( diff --git a/www/docs/guides/interact.md b/www/docs/guides/interact.md index 83f1af4c0..0e5891c2b 100644 --- a/www/docs/guides/interact.md +++ b/www/docs/guides/interact.md @@ -4,7 +4,7 @@ sidebar_position: 6 # Interact with your contract -Once your provider, contract and account are connected, you can interact with the contract : +Once your provider, contract and account are connected, you can interact with the contract: - you can read the memory of the contract, without fees. - you can write to memory, but you have to pay fees. @@ -16,26 +16,26 @@ Your account should be funded enough to pay fees (0.01 ETH should be enough to s ![](./pictures/Interact_contract.png) -Here we will interact with a `test.cairo` contract (Cairo 0), already deployed in Testnet 1 and Tesnet 2, at addresses : +Here we will interact with a `test.cairo` contract (Cairo 0), already deployed in Testnet 1 and Tesnet 2, at addresses: -- testnet1 : [0x5f7cd1fd465baff2ba9d2d1501ad0a2eb5337d9a885be319366b5205a414fdd](https://testnet.starkscan.co/contract/0x5f7cd1fd465baff2ba9d2d1501ad0a2eb5337d9a885be319366b5205a414fdd#read-contract). -- testnet2 : [0x2367db6b0df07033d196dcd25961109d8fbc86227158343149742284c7582e](https://testnet-2.starkscan.co/contract/0x002367db6b0df07033d196dcd25961109d8fbc86227158343149742284c7582e#read-contract). +- testnet1: [0x5f7cd1fd465baff2ba9d2d1501ad0a2eb5337d9a885be319366b5205a414fdd](https://testnet.starkscan.co/contract/0x5f7cd1fd465baff2ba9d2d1501ad0a2eb5337d9a885be319366b5205a414fdd#read-contract). +- testnet2: [0x2367db6b0df07033d196dcd25961109d8fbc86227158343149742284c7582e](https://testnet-2.starkscan.co/contract/0x002367db6b0df07033d196dcd25961109d8fbc86227158343149742284c7582e#read-contract). We will use Testnet1, so you need a funded wallet in this network. -This contract contains a storage memory called `balance`. +This contract contains a storage variable called `balance`. -- It can be read with the `@view function : get_balance()` -- Balance can be modified with the `@external function : increase_balance(amount1: felt, amount2: felt)` +- It can be read with the `@view function: get_balance()` +- Balance can be modified with the `@external function: increase_balance(amount1: felt, amount2: felt)` ```typescript import { Provider, Contract, Account, ec, json } from "starknet"; ``` -## 🔍 Read contract memory, with meta-class +## 🔍 Read from contract memory, with meta-class -To read the balance, you need only to connect a Provider and a Contract. -You have to call Starknet, with use of the meta-class method : `contract.function_name(params)` (here `params` is not necessary, because there are no parameters for the `get_balance` function). +To read the balance, you need to connect a Provider and a Contract. +You have to call Starknet, with use of the meta-class method: `contract.function_name(params)` (here `params` is not necessary, because there are no parameters for the `get_balance` function). ```typescript //initialize Provider @@ -54,19 +54,20 @@ console.log("Initial balance =", bal1.res.toString()); // .res because the retur // With Cairo 1 contract, the result value is in bal1, as bigint. ``` -## ✍️ Write contract memory, with meta-class +## ✍️ Write to contract memory, with meta-class To increase the balance, you need in addition a connected and funded Account. -You have to invoke Starknet, with use of the meta-class method : `contract.function_name(params)` -After the invoke, you have to wait the incorporation of the modification of Balance in the network, with `await provider.waitForTransaction(transaction_hash)` +You have to invoke Starknet, with the use of the meta-class method: `contract.function_name(params)` -Here is an example to increase and check the balance : +> After the invoke, you have to wait the incorporation of the modification of Balance in the network, with `await provider.waitForTransaction(transaction_hash)` + +Here is an example on how to increase and check the balance: ```typescript //initialize Provider const provider = new Provider({ sequencer: { network: constants.NetworkName.SN_GOERLI } }); -// connect your account. To adapt to your own account : +// connect your account. To adapt to your own account: const privateKey0 = process.env.OZ_ACCOUNT_PRIVATE_KEY; const account0Address = "0x123....789"; @@ -97,11 +98,29 @@ console.log("Final balance =", bal2.res.toString()); `Contract.populate()` is the recommended method to define the parameters to call/invoke the Cairo functions. +## Sending sequential transactions + +If you intend to send sequential transactions through the contract object, like so: + +```typescript +const tx = await cairo1Contract.array2d_ex(data); +const tx1 = await cairo1Contract.array2d_ex(data); +``` + +Be sure to use `waitForTransaction` between the calls, because you may experience issues with the nonce not incrementing: + +```typescript +const tx = await cairo1Contract.array2d_ex(data); +await provider.waitForTransaction(tx.transaction_hash); +const tx1 = await cairo1Contract.array2d_ex(data); +await provider.waitForTransaction(tx1.transaction_hash); +``` + ## Write several operations, with Account.execute In a Starknet transaction, you can include several invoke operations. It will be performed with `account.execute`. -We will later see this case more in detail in this dedicated [guide](multiCall.md) , but in summary, you use this command with the following parameters: +We will later see this case more in detail in this dedicated [guide](multiCall.md), but in summary, you use this command with the following parameters: - address of the contract to invoke - name of the function to invoke @@ -123,11 +142,11 @@ await provider.waitForTransaction(result.transaction_hash); ## Other existing methods -Some other useful method to interact with Starknet : +Some other useful methods to interact with Starknet: ### Function name defined in the code -If you want to call a function with its name contained in a variable : +If you want to call a function with its name contained in a variable: ```typescript const listFn = ["calc-sum","calc-hash","calc-proof"]; @@ -137,15 +156,19 @@ const res = await myTestContract[listFn[fnChoice]](200, 234567897n, 865423); ### Light and fast call -If you want to have a very fast execution, with the minimum of resource usage : +If you want to have a very fast execution, with the minimum of resource usage: ```typescript const specialParameters: Calldata = [ '2036735872918048433518', '5130580', - '18']; -const getResponse = await myAccount.call("get_bal",specialParameters, - {parseRequest: false}); + '18' + ]; +const getResponse = await myAccount.call( + "get_bal", + specialParameters, + { parseRequest: false } +); ``` -You provide the low level numbers expected by Starknet, without any parsing or check. See more detail [here](define_call_message.md#parse-configuration) +You provide the low level numbers expected by Starknet, without any parsing or check. See more details [here](define_call_message.md#parse-configuration). diff --git a/www/docs/guides/signature.md b/www/docs/guides/signature.md index da6c379e2..9173da786 100644 --- a/www/docs/guides/signature.md +++ b/www/docs/guides/signature.md @@ -19,7 +19,7 @@ const privateKey = "0x1234567890987654321"; const starknetPublicKey = ec.starkCurve.getStarkKey(privateKey); const fullPublicKey = encode.addHexPrefix( encode.buf2hex( ec.starkCurve.getPublicKey( privateKey, false))); -const message : BigNumberish[] = [1, 128, 18, 14]; +const message: BigNumberish[] = [1, 128, 18, 14]; const msgHash = hash.computeHashOnElements(message); const signature: weierstrass.SignatureType = ec.starkCurve.sign(msgHash,privateKey); @@ -55,7 +55,7 @@ console.log("Result (boolean) =", result1); > The sender can also provide their account address. Then you can check that this full public key is linked to this account. The pubKey that you can read in the account contract is part (part X) of the full pubKey (parts X & Y): -Read the pubKey of the account : +Read the pubKey of the account: ```typescript const provider = new Provider({ sequencer: { baseUrl: "http://127.0.0.1:5050" } }); //devnet @@ -103,7 +103,7 @@ These items are designed to be able to be an interface with a wallet. At sign re - `message` will be displayed at the bottom of the wallet display, showing clearly (not in hex) the message to sign. Its structure has to be in accordance with the type listed in `primaryType`, defined in `types`. - `domain` will be shown above the message. Its structure has to be in accordance with `StarkNetDomain`. -The prefefined types that you can use : +The predefined types that you can use : - felt : for an integer on 251 bits. - felt\* : for an array of felt. diff --git a/www/docs/guides/use_ERC20.md b/www/docs/guides/use_ERC20.md index 0be2a7d76..81da1b019 100644 --- a/www/docs/guides/use_ERC20.md +++ b/www/docs/guides/use_ERC20.md @@ -8,7 +8,7 @@ Based on what has been seen in the previous pages of this guide, we will use an ## What's an ERC20 -As in Ethereum, a token has an ERC20 contract to manage it. This contract contains a table, that lists the quantity of tokens owned by each involved account : +As in Ethereum, a token has an ERC20 contract to manage it. This contract contains a table, that lists the quantity of tokens owned by each involved account: ![](./pictures/ERC20.png) For example, the Account address 2 owns 100 token of this ERC20 contract. @@ -27,7 +27,7 @@ This way, the ERC20 contract is absolutely sure that the caller of the transfer ## ETH token is an ERC20 in Starknet -In opposition with Ethereum, the ETH token is an ERC20 in Starknet, as all other tokens. In all networks, it's ERC20 contract address is : +In opposition with Ethereum, the ETH token is an ERC20 in Starknet, as all other tokens. In all networks, it's ERC20 contract address is: ```typescript const addrETH = "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7"; @@ -39,7 +39,7 @@ Lets dive down the rabbit hole! This example works with an ERC20 mintable (everybody can mint new tokens), that we will deploy on the devnet (launched with `starknet-devnet --seed 0`). -First, let's initialize an account : +First, let's initialize an account: ```typescript // initialize provider @@ -51,7 +51,7 @@ const accountAddress = "0x7e00d496e324876bbc8531f2d9a82bf154d1a04a50218ee74cdd37 const account0 = new Account(provider, accountAddress, privateKey); ``` -Declaration and deployment of the ERC20 contract : +Declaration and deployment of the ERC20 contract: ```typescript // Deploy an ERC20 contract @@ -85,13 +85,13 @@ erc20.connect(account0); ## Interact with an ERC20 -Here we will read the balance, mint new tokens, and transfer tokens : +Here we will read the balance, mint new tokens, and transfer tokens: ```typescript // Check balance - should be 100 console.log(`Calling Starknet for account balance...`); const balanceInitial = await erc20.balanceOf(account0.address); -console.log("account0 has a balance of :", uint256.uint256ToBN(balanceInitial.balance).toString()); // Cairo 0 response +console.log("account0 has a balance of:", uint256.uint256ToBN(balanceInitial.balance).toString()); // Cairo 0 response // Mint 1000 tokens to account address const amountToMint = cairo.uint256(1000); @@ -109,7 +109,7 @@ await provider.waitForTransaction(mintTxHash); // Check balance - should be 1100 console.log(`Calling Starknet for account balance...`); const balanceBeforeTransfer = await erc20.balanceOf(account0.address); -console.log("account0 has a balance of :", uint256.uint256ToBN(balanceBeforeTransfer.balance).toString()); // Cairo 0 response +console.log("account0 has a balance of:", uint256.uint256ToBN(balanceBeforeTransfer.balance).toString()); // Cairo 0 response // Execute tx transfer of 10 tokens console.log(`Invoke Tx - Transfer 10 tokens back to erc20 contract...`); @@ -127,6 +127,6 @@ await provider.waitForTransaction(transferTxHash); // Check balance after transfer - should be 1090 console.log(`Calling Starknet for account balance...`); const balanceAfterTransfer = await erc20.balanceOf(account0.address); -console.log("account0 has a balance of :", uint256.uint256ToBN(balanceAfterTransfer.balance).toString()); // Cairo 0 response +console.log("account0 has a balance of:", uint256.uint256ToBN(balanceAfterTransfer.balance).toString()); // Cairo 0 response console.log("✅ Script completed."); ``` diff --git a/www/docs/guides/what_s_starknet.js.md b/www/docs/guides/what_s_starknet.js.md index 899b958f9..763764805 100644 --- a/www/docs/guides/what_s_starknet.js.md +++ b/www/docs/guides/what_s_starknet.js.md @@ -12,13 +12,13 @@ Starknet.js is a library that helps to connect your website or your Decentralize Some important topics that have to be understood: -- You can connect your DAPP to several networks : +- You can connect your DAPP to several networks: - [Starknet mainnet](https://starkscan.co) (Layer 2 of [Ethereum network](https://etherscan.io/) ). - [Starknet testnet 1](https://testnet.starkscan.co/) & [testnet 2](https://testnet-2.starkscan.co/) (Layer 2 of [Goerli network](https://goerli.etherscan.io/) (testnet of Ethereum)). - [Starknet-devnet](https://shard-labs.github.io/starknet-devnet/docs/intro) (your local Starknet network, for developers). - and also to some more specific solutions : + and also to some more specific solutions: - private customized version of Starknet. - local Starknet node (connected to mainnet or testnet). @@ -28,6 +28,6 @@ Some important topics that have to be understood: - Only the `Provider` object is talking directly to the network - your DAPP will talk mainly to `Account` and `Contract` objects. You will define with the `Provider` with which network you want to work. You can ask the Provider some low level data of the network (block, timestamp, ...). - `Signer` and `Utils` objects contain many useful functions for the interaction with Starknet.js. - The `Contract` object is mainly used to read the memory of a blockchain contract. -- The `Account` object is the most useful : +- The `Account` object is the most useful: - as wallet, to store your tokens. - as a way to pay the fees to the network, to be able to write in its memory. From 8af9a909cf7c0be357b1104aec977d2b85e1aba9 Mon Sep 17 00:00:00 2001 From: Toni Tabak Date: Tue, 4 Jul 2023 16:27:54 +0200 Subject: [PATCH 2/2] docs: grammarly --- www/docs/guides/L1message.md | 8 +-- www/docs/guides/connect_account.md | 8 +-- www/docs/guides/connect_network.md | 10 ++-- www/docs/guides/create_account.md | 34 ++++++------- www/docs/guides/define_call_message.md | 70 +++++++++++++------------- www/docs/guides/estimate_fees.md | 6 +-- www/docs/guides/interact.md | 18 +++---- www/docs/guides/intro.md | 8 +-- www/docs/guides/multiCall.md | 2 +- www/docs/guides/signature.md | 36 ++++++------- www/docs/guides/use_ERC20.md | 14 +++--- www/docs/guides/what_s_starknet.js.md | 8 +-- 12 files changed, 111 insertions(+), 111 deletions(-) diff --git a/www/docs/guides/L1message.md b/www/docs/guides/L1message.md index 4d0bc962e..245340c31 100644 --- a/www/docs/guides/L1message.md +++ b/www/docs/guides/L1message.md @@ -10,9 +10,9 @@ You can exchange messages between L1 & L2 networks: - L2 Starknet testnet 1 & 2 ↔️ L1 Goerli ETH testnet. - L2 local Starknet devnet ↔️ L1 local ETH testnet (Ganache, ...). -You can find explanation of the global mechanism [here](https://docs.starknet.io/documentation/architecture_and_concepts/L1-L2_Communication/messaging-mechanism/). +You can find an explanation of the global mechanism [here](https://docs.starknet.io/documentation/architecture_and_concepts/L1-L2_Communication/messaging-mechanism/). -Most of the code for this message process will be written in Cairo, but Starknet.js provides some functionalities for this subject. +Most of the code for this messaging process will be written in Cairo, but Starknet.js provides some functionalities for this subject. ## L1 ➡️ L2 messages @@ -46,11 +46,11 @@ const responseEstimateMessageFee = await provider.estimateMessageFee({ }) ``` -If the fee is paid in L1, the cairo contract at `to_Address` is automatically executed, function `entry_point_selector` (the function shall have a decorator `@l1_handler` in the Cairo code), with parameters `payload`. +If the fee is paid in L1, the Cairo contract at `to_Address` is automatically executed, function `entry_point_selector` (the function shall have a decorator `@l1_handler` in the Cairo code), with parameters `payload`. ## L2 ➡️ L1 messages -To send a message to L1, you will just invoke a cairo contract function, paying a fee that will pay all the process (in L1 & L2). +To send a message to L1, you will just invoke a Cairo contract function, paying a fee that will pay all the processes (in L1 & L2). If necessary you can estimate this fee with the generic `estimateInvokeFee` function: diff --git a/www/docs/guides/connect_account.md b/www/docs/guides/connect_account.md index 2b3c9e8f5..717367d08 100644 --- a/www/docs/guides/connect_account.md +++ b/www/docs/guides/connect_account.md @@ -6,7 +6,7 @@ sidebar_position: 4 Once your provider is initialized, you can connect an existing account. -You need 2 data pieces of: +You need 2 pieces of data: - the address of the account - the private key of this account @@ -45,15 +45,15 @@ const account = new Account(provider, accountAddress, privateKey); Your account is now connected, and you can use it. -## 👛 Connect to a existing account (in any network) +## 👛 Connect to an existing account (in any network) -The code is exactly the same, you just have to: +The code is the same, you just have to: - connect to the appropriate network. - use the address of this account (public data). - use the private key of this account (very sensitive data: your code MUST not disclose it). -For example, to connect an existing account to testnet, with a private key stored in .env non archived file: +For example, to connect an existing account on testnet, with a private key stored in a .env non-archived file: ```typescript import * as dotenv from "dotenv"; diff --git a/www/docs/guides/connect_network.md b/www/docs/guides/connect_network.md index 91e7849de..839d967a9 100644 --- a/www/docs/guides/connect_network.md +++ b/www/docs/guides/connect_network.md @@ -4,7 +4,7 @@ sidebar_position: 3 # Provider object 🔌 connect to the network -First thing to do - define with which network you want to interact. +The first thing to do is to define with which network you want to interact. With the Provider object, you define which network to use. @@ -35,7 +35,7 @@ const provider = new Provider({ sequencer: { baseUrl:"http://127.0.0.1:5050"} }) ## Connect your DAPP to a private Starknet network -If necessary you can have a full control on the network access (for example, for your company private test network): +If necessary you can have full control of the network access (for example, for your company's private test network): ```typescript const provider = new Provider({ @@ -55,7 +55,7 @@ For a local [Pathfinder](https://github.com/eqlabs/pathfinder) node: const provider = new Provider({ rpc: { nodeUrl: '127.0.0.1:9545' } }) ``` -Your node can be located in your local network (example: pathfinder node running nn a computer on your network, launched with this additional option: `--http-rpc 0.0.0.0:9545`). +Your node can be located in your local network (example: pathfinder node running on a computer on your network, launched with this additional option: `--http-rpc 0.0.0.0:9545`). You can connect with: ```typescript @@ -68,7 +68,7 @@ Some methods are available only if connected to a sequencer, and some others are ### Specific sequencer methods -For example, if you want to estimate the fee of a L1 ➡️ L2 message, you need to use a method that is available only in the sequencer. The class `SequencerProvider` is available for this case: +For example, if you want to estimate the fee of an L1 ➡️ L2 message, you need to use a method that is available only in the sequencer. The class `SequencerProvider` is available for this case: ```typescript import { SequencerProvider, constants } from "starknet"; @@ -78,7 +78,7 @@ const responseEstimateMessageFee = await provider.estimateMessageFee(.....) ### Specific RPC methods -For example, if you want to read the events recorded in a range of blocks, you need to use a method available from a RPC node. The class `RpcProvider` is available for this case: +For example, if you want to read the events recorded in a range of blocks, you need to use a method available from an RPC node. The class `RpcProvider` is available for this case: ```typescript import { RpcProvider } from "starknet"; diff --git a/www/docs/guides/create_account.md b/www/docs/guides/create_account.md index f775522c3..be1b35d2c 100644 --- a/www/docs/guides/create_account.md +++ b/www/docs/guides/create_account.md @@ -6,14 +6,14 @@ sidebar_position: 8 Since there are no Externally Owned Accounts (EOA) in Starknet, all Accounts in Starknet are contracts. -Unlike in Ethereum where a wallet is created with a public and private key pair, Starknet Accounts are the only way to sign transactions and messages, and verify signatures. Therefore a Account - Contract interface is needed. +Unlike in Ethereum where a wallet is created with a public and private key pair, Starknet Accounts are the only way to sign transactions and messages and verify signatures. Therefore an Account - Contract interface is needed. Account contracts on Starknet cannot be deployed without paying a fee. -Create an account is a bit tricky ; you have several steps: +Creating an account is a bit tricky; you have several steps: 1. Decide on your account type (OpenZeppelin, ArgentX, Braavos, ...). 2. Compute the address of your future account. -3. Send funds to this pre-computed address. The funds will be used to pay for the account contract deployment, and remains will fund the new account. +3. Send funds to this pre-computed address. The funds will be used to pay for the account contract deployment and remains will fund the new account. 4. Actual deployment of the Account ## Create an OZ (Open Zeppelin) account @@ -21,7 +21,7 @@ Create an account is a bit tricky ; you have several steps: > Level: easy. Here, we will create a wallet with the Open Zeppelin smart contract v0.5.1. The contract class is already implemented in both Testnet 1 & 2. -This contract is coded in Cairo 0, so it will not survive to the upcoming regenesis of Starknet. +This contract is coded in Cairo 0, so it will not survive the upcoming re-genesis of Starknet. ```typescript import { Account, constants, ec, json, stark, Provider, hash, CallData } from "starknet"; @@ -52,7 +52,7 @@ const OZcontractAddress = hash.calculateContractAddressFromHash( console.log('Precalculated account address=', OZcontractAddress); ``` -If you want a specific private key, replace `stark.randomAddress()` by your choice. +If you want a specific private key, replace `stark.randomAddress`()` with your choice. Then you have to fund this address! @@ -70,7 +70,7 @@ curl -X POST http://127.0.0.1:5050/mint -d '{"address":"0x04a093c37ab61065d00155 ### deployment of the new account -If you have sent enough fund to this new address, you can go forward to the final step: +If you have sent enough funds to this new address, you can go forward to the final step: ```typescript const OZaccount = new Account(provider, OZcontractAddress, privateKey); @@ -89,7 +89,7 @@ console.log('✅ New OpenZeppelin account created.\n address =', contract_addr > Level: medium. -Here, we will create a wallet with the Argent smart contract v0.2.3. This case is more complicated, because we will have the account behind a proxy contract (this way, the wallet contract can be updated). The contract classes of both contracts are already implemented in both Testnet 1 & 2. +Here, we will create a wallet with the Argent smart contract v0.2.3. This case is more complicated because we will have the account behind a proxy contract (this way, the wallet contract can be updated). The contract classes of both contracts are already implemented in both Testnet 1 & 2. > If necessary OZ contracts can also be created with a proxy. @@ -128,13 +128,13 @@ const AXcontractAddress = hash.calculateContractAddressFromHash( console.log('Precalculated account address=', AXcontractAddress); ``` -If you want a specific private key, replace `stark.randomAddress()` by your choice. +If you want a specific private key, replace `stark.randomAddress`()` with your choice. Then you have to fund this address. ### deployment of the new account -If you have sent enough fund to this new address, you can go forward to the final step: +If you have sent enough funds to this new address, you can go forward to the final step: ```typescript const accountAX = new Account(provider, AXcontractAddress, privateKeyAX); @@ -153,7 +153,7 @@ console.log('✅ ArgentX wallet deployed at:',AXcontractFinalAdress); > Level: hard. -Even more complicated, a Braavos account needs also a proxy, but needs in addition a specific signature. Starknet.js is handling only Starknet standard signatures ; so we needs extra code to handle this specific signature for account creation. These nearly 200 lines of code are not displayed here, but are available in a module [here](./compiled_contracts/deployBraavos.ts). +Even more complicated, a Braavos account needs also a proxy but needs in addition a specific signature. Starknet.js is handling only Starknet standard signatures; so we need extra code to handle this specific signature for account creation. These nearly 200 lines of code are not displayed here but are available in a module [here](./compiled_contracts/deployBraavos.ts). We will deploy hereunder a Braavos account in devnet. So launch starknet-devnet with these parameters: @@ -172,7 +172,7 @@ import { calculateAddressBraavos, import axios from "axios"; ``` -If you want to create yourself the private key, for example with a random number: +If you want to create the private key, for example with a random number: ```typescript const privateKeyBraavos = stark.randomAddress(); @@ -222,11 +222,11 @@ await providerDevnet.waitForTransaction(transaction_hash); console.log('✅ Braavos wallet deployed at', BraavosAccountFinalAddress); ``` -The computed address has been funded automatically by minting new dummy ETH in Starknet devnet! +The computed address has been funded automatically by minting a new dummy ETH in Starknet devnet! ## Create your account abstraction -You are not limited to these 3 contracts contracts. You can create your own contract for wallet. It's the concept of Account Abstraction. +You are not limited to these 3 contracts. You can create your own contract for the wallet. It's the concept of Account Abstraction. You can customize entirely the wallet - for example: @@ -234,11 +234,11 @@ You can customize entirely the wallet - for example: - add a guardian to save your account. -- have the possibility to transfer the ownership of the wallet. +- have the possibility to transfer ownership of the wallet. - add some administrators or a super-administrator. -- whitelist of address for transfer. +- whitelist of addresses for transfer. - multisig. @@ -309,5 +309,5 @@ console.log('✅ New customized account created.\n address =', contract_addres ## Account update -For ArgentX and Braavos wallets, if you have created the privkey inside the browser wallet, necessary upgrades will be automatically managed in the wallet. -However, if you have created yourself the private key, it becomes your responsibility to update the account implementation class when it's necessary. It can be done with the `upgrade` function of the implementation class. +For ArgentX and Braavos wallets, if you have created the private key inside the browser wallet, necessary upgrades will be automatically managed in the wallet. +However, if you have created the private key by yourself, it becomes your responsibility to update the account implementation class when it's necessary. It can be done with the `upgrade` function of the implementation class. diff --git a/www/docs/guides/define_call_message.md b/www/docs/guides/define_call_message.md index 1e8888323..efc6a876e 100644 --- a/www/docs/guides/define_call_message.md +++ b/www/docs/guides/define_call_message.md @@ -9,9 +9,9 @@ This guide is the most important of all this documentation. Take your time, and Cairo contracts and Javascript/Typescript languages do not have the same types of data. To exchange data with Starknet, the data have to be transformed and formatted in a list of numbers. So, it's necessary to prepare the data before sending them to a contract. -On the other side, when a contract sends data to your DAPP (result of a call), you also have to transform them before using them in your code. +On the other side, when a contract sends data to your DAPP (the result of a call), you also have to transform them before using them in your code. -In Starknet.js, you can perform these transformations manually, but you can take advantage of methods that performs these transformations. +In Starknet.js, you can perform these transformations manually, but you can take advantage of methods that perform these transformations. ## Types of data @@ -20,23 +20,23 @@ In Starknet.js, you can perform these transformations manually, but you can take Cairo has 2 versions, involving 2 types of data: - **Cairo 0**: here, everything is felt, an integer on 251 bits. - Available: array, struct, tuple, named tuple, a mix of these elements. + Available: array, struct, tuple, named tuple, or a mix of these elements. - **Cairo 1**: with plethora of literal types: u8, u16, u32, usize, u64, u128, felt252, u256, bool, address. - Available: array, struct, tuple, a mix of these elements. + Available: array, struct, tuple, or a mix of these elements. Starknet.js is compatible with both versions. ### Starknet -Starknet is waiting a list of felts, and answers with the same format. +Starknet is waiting for a list of felts, and answers with the same format. ### Javascript / Typescript -These types does not exist in JS/TS - you have Number, bigInt, string, array, objects... and types defined in libraries. +These types do not exist in JS/TS - you have Number, bigInt, string, array, objects... and types defined in libraries. In Starknet.js, it's a bit ... complicated: you have the BigNumberish type and it can include: -- String representing a number: "123", "0xabc2" +- String (representing a number): "123", "0xabc2" - Number (max 53 bits): 123 - BigInt (max 255 bits): 12345612345n @@ -47,11 +47,11 @@ const decimals: BigNumberish = 18; ## Preparation of data before delivery -If your Cairo smart-contract is waiting a: +If your Cairo smart contract is waiting for a: ### felt, u8, u16, u32, usize, u64, u128, felt252, address -Starknet is waiting a felt. +Starknet is waiting for a felt. You can send to Starknet.js methods: bigNumberish. ```typescript @@ -60,7 +60,7 @@ await myContract.my_function(12,"13","0xe",15n); ### bool -Starknet is waiting a felt, containing 0 or 1. +Starknet is waiting for a felt, containing 0 or 1. You can send to Starknet.js methods: boolean, bigNumberish. ```typescript @@ -69,7 +69,7 @@ await myContract.my_function(true,1); ### u256 -Starknet is waiting 2 felts, the first including the lowest 128 bits, the second including the 128 highest bits. +Starknet is waiting for 2 felts, the first including the lowest 128 bits, the second including the 128 highest bits. You can send to Starknet.js methods: bigNumberish (Cairo 1 only), Uint256 object (both Cairo 0 & 1). ```typescript @@ -88,7 +88,7 @@ const a3: Uint256 = {low: a1.low,high: a1.high}; ### string -Starknet is waiting a felt, including 31 ASCII characters max. +Starknet is waiting for a felt, including 31 ASCII characters max. You can send to Starknet.js methods: string, bigNumberish. ```typescript @@ -112,7 +112,7 @@ The result is: "uri/pict/t38.jpg" ### longString longString is a string that may contain more than 31 characters. -Starknet is waiting an array of felt: string_len, string1, string2, ... +Starknet is waiting for an array of felt: string_len, string1, string2, ... You can send to Starknet.js methods: string, bigNumberish[]. ```typescript @@ -133,8 +133,8 @@ const longString: string[] = shortString.splitLongString("http://addressOfMyERC7 ### tuple -Starknet is waiting a list of felts. -You can send to Starknet.js methods: `cairo.tuple()`, object. +Starknet is waiting for a list of felts. +You can send it to Starknet.js methods: `cairo.tuple()`, object. ```typescript const myTpl = cairo.tuple("0x0a", 200); @@ -151,7 +151,7 @@ const myTpl = {"0": "0x0a", "1": 200}; > Only for Cairo 0. -Starknet is waiting a list of felts. +Starknet is waiting for a list of felts. You can send to Starknet.js methods: an object, `cairo.tuple()`, list of bigNumberish. From this ABI: @@ -183,8 +183,8 @@ await myContract.my_function(myStruct); ### array -Starknet is waiting an array of felts: array_len, array1, array2, ... -You can send to Starknet.js methods: bigNumberish[]. +Starknet is waiting for an array of felts: array_len, array1, array2, ... +You can send it to Starknet.js methods: bigNumberish[]. ```typescript Const myArray = [10,"0xaa",567n]; @@ -195,9 +195,9 @@ await myContract.my_function(myArray); ### complex types -You can mix and nest literals, arrays, structs and tuples. +You can mix and nest literals, arrays, structs, and tuples. -Starknet is waiting a list of felts. +Starknet is waiting for a list of felts. All these examples are valid: ```typescript @@ -223,7 +223,7 @@ There are 12 methods using contract parameters. Some types are authorized for ea ### list of parameters Only meta-class methods are using a list of parameters (as illustrated in the previous chapter). -A Meta-Class is a Class which has any of its properties determined at run-time. The Contract object uses a Contract's ABI to determine what methods are available. +A Meta-Class is a Class that has any of its properties determined at run-time. The Contract object uses a Contract's ABI to determine what methods are available. ```typescript await myContract.my_function("TOKEN", "13", [10, 11, 12], 135438734812n); @@ -247,7 +247,7 @@ const txResp = await account0.execute({ calldata: myParams}); ``` -All Starknet.js methods accepts this type of input, except meta-class, that needs 3 dots prefix: +All Starknet.js methods accept this type of input, except meta-class, which needs 3 dots prefix: ```typescript const myParams = ["TOKEN", "13", [10, 11, 12], 135438734812n]; @@ -261,7 +261,7 @@ await myContract[functionName](...myParams); ### Object (without ABI conformity check) -Use of objects allows a clear representation of the list of parameters: +The use of objects allows a clear representation of the list of parameters: ```typescript const myParams = { @@ -279,7 +279,7 @@ This type is available for: `CallData.compile(), hash.calculateContractAddressFr ### Object (with ABI conformity check) -This is the recommended type of inputs to use, especially for complex ABI. +This is the recommended type of input to use, especially for complex ABI. ```typescript const myFalseUint256 = { high: 1, low: 23456 }; // wrong order ; should be low first @@ -321,9 +321,9 @@ const myCall: Call = myContract.populate("get_elements", functionParameters); const res = await myContract.get_elements(...myCall.calldata); ``` -It can be used only with methods that knows the abi: `Contract.populate, myCallData.compile`. -Starknet.js will perform a full check of conformity with the ABI of the contract, reorder the objects properties if necessary, stop if something is wrong or missing, remove not requested properties, convert everything to Starknet format. -Starknet.js will alert earlier of errors in your parameters (with human comprehensible words), before call to Starknet. So, no more incomprehensible Starknet messages due to parameters construction. +It can be used only with methods that know the abi: `Contract.populate, myCallData.compile`. +Starknet.js will perform a full check of conformity with the ABI of the contract, reorder the object's properties if necessary, stop if something is wrong or missing, remove not requested properties, and convert everything to Starknet format. +Starknet.js will alert you earlier of errors in your parameters (with human comprehensible words), before the call to Starknet. So, no more incomprehensible Starknet messages due to parameters construction. If a property `array_len` has been added before an array, this property is ignored as it's automatically managed by Starknet.js. @@ -364,9 +364,9 @@ const tx = await account0.execute([myCall1, myCall2, myCall3]); ### Array of strings (representing numbers) -This type is particularly useful when you need the maximum of performance and speed in your code ; You have no automatic transformation, no checks with ABI, no parsing. +This type is particularly useful when you need the maximum performance and speed in your code; You have no automatic transformation, no checks with ABI, and no parsing. -You provide to starknet.js the low level data expected by Starknet: +You provide to starknet.js the low-level data expected by Starknet: ```typescript const specialParameters: Calldata = [ @@ -408,9 +408,9 @@ These types of arguments can't be used at your convenience everywhere. Here is a ## Receive data from a Cairo contract -When you perform a call, the result depends of the contract language: +When you perform a call, the result depends on the contract language: -- In Cairo 0, then answer is an object, with keys using the Cairo variables names. +- In Cairo 0, the answer is an object, with keys using the Cairo variable's names. Example: @@ -450,7 +450,7 @@ const isAbiCairo1: boolean = cairo.isCairo1Abi(myAbi); ### parseRequest -If for any reason (mainly for speed of processing), you want to define yourself the low level parameters to send to Starknet, you can use the `parseRequest` option. +If for any reason (mainly for speed of processing), you want to define yourself the low-level parameters to send to Starknet, you can use the `parseRequest` option. Parameters are an array of strings (representing numbers). ```typescript @@ -464,20 +464,20 @@ const txH = await myContract.send_tk([ ### parseResponse -If for any reason, you want to receive a low level answer from Starknet, you can use the parseResponse option. +If for any reason, you want to receive a low-level answer from Starknet, you can use the parseResponse option. ```typescript const result = await myContract.call("get_bals",100n, {parseResponse: false}); ``` -Answer is an array of strings (representing numbers). +The answer is an array of strings (representing numbers). ### formatResponse As seen above, the strings returned by Starknet are not automatically parsed, because ABI does not inform when a contract returns a string. But there is a way to have automatic parsing of a string. -As example, if a contract returns a struct containing a shortString and a longString: +For example, if a contract returns a struct containing a shortString and a longString: ```typescript { name: felt252, description: Array } diff --git a/www/docs/guides/estimate_fees.md b/www/docs/guides/estimate_fees.md index 6ef9fb492..3fe6e7069 100644 --- a/www/docs/guides/estimate_fees.md +++ b/www/docs/guides/estimate_fees.md @@ -4,9 +4,9 @@ sidebar_position: 10 # Estimate fees -By default, all non free Starknet commands (declare, deploy, invoke) work without any limitation of cost. +By default, all nonfree Starknet commands (declare, deploy, invoke) work without any limitation of cost. -Nevertheless, you might want to inform the DAPP user of the cost of the incoming transaction before proceeding, and request its validation. +Nevertheless, you might want to inform the DAPP user of the cost of the incoming transaction before proceeding and requesting its validation. Starknet.js proposes several functions to estimate the fees: @@ -77,7 +77,7 @@ import { stark } from "starknet"; stark.estimatedFeeToMaxFee(estimatedFee1, 0.1); ``` -Example for declare: +Example for declaring: ```typescript const { suggestedMaxFee: estimatedFee1 } = await account0.estimateDeclareFee({ contract: compiledTest }); diff --git a/www/docs/guides/interact.md b/www/docs/guides/interact.md index 0e5891c2b..8f99b5b84 100644 --- a/www/docs/guides/interact.md +++ b/www/docs/guides/interact.md @@ -4,13 +4,13 @@ sidebar_position: 6 # Interact with your contract -Once your provider, contract and account are connected, you can interact with the contract: +Once your provider, contract, and account are connected, you can interact with the contract: - you can read the memory of the contract, without fees. - you can write to memory, but you have to pay fees. - - On Mainnet, you have to pay fees with bridged ETH token. - - On Testnet 1 & 2, you have to pay with bridged Goerli ETH token. - - On devnet, you have to pay with dummy ETH token. + - On Mainnet, you have to pay fees with a bridged ETH token. + - On Testnet 1 & 2, you have to pay with a bridged Goerli ETH token. + - On devnet, you have to pay with a dummy ETH token. Your account should be funded enough to pay fees (0.01 ETH should be enough to start). @@ -35,7 +35,7 @@ import { Provider, Contract, Account, ec, json } from "starknet"; ## 🔍 Read from contract memory, with meta-class To read the balance, you need to connect a Provider and a Contract. -You have to call Starknet, with use of the meta-class method: `contract.function_name(params)` (here `params` is not necessary, because there are no parameters for the `get_balance` function). +You have to call Starknet, with the use of the meta-class method: `contract.function_name(params)` (here `params` is not necessary, because there are no parameters for the `get_balance` function). ```typescript //initialize Provider @@ -62,7 +62,7 @@ You have to invoke Starknet, with the use of the meta-class method: `contract.fu > After the invoke, you have to wait the incorporation of the modification of Balance in the network, with `await provider.waitForTransaction(transaction_hash)` -Here is an example on how to increase and check the balance: +Here is an example of how to increase and check the balance: ```typescript //initialize Provider @@ -124,7 +124,7 @@ We will later see this case more in detail in this dedicated [guide](multiCall.m - address of the contract to invoke - name of the function to invoke -- and array of parameters for this function +- and an array of parameters for this function ```typescript const result = await account.execute( @@ -156,7 +156,7 @@ const res = await myTestContract[listFn[fnChoice]](200, 234567897n, 865423); ### Light and fast call -If you want to have a very fast execution, with the minimum of resource usage: +If you want to have a very fast execution, with minimum resource usage: ```typescript const specialParameters: Calldata = [ @@ -171,4 +171,4 @@ const getResponse = await myAccount.call( ); ``` -You provide the low level numbers expected by Starknet, without any parsing or check. See more details [here](define_call_message.md#parse-configuration). +You provide the low-level numbers expected by Starknet, without any parsing or checking. See more details [here](define_call_message.md#parse-configuration). diff --git a/www/docs/guides/intro.md b/www/docs/guides/intro.md index 3486efb4b..c9e0e9bc2 100644 --- a/www/docs/guides/intro.md +++ b/www/docs/guides/intro.md @@ -20,7 +20,7 @@ npm install starknet@next ### With Devnet -Example devnet version is `0.5.3`. +The example devnet version is `0.5.3`. Get devnet with docker: @@ -29,14 +29,14 @@ docker pull shardlabs/starknet-devnet:0.5.3 docker run -p 5050:5050 shardlabs/starknet-devnet:0.5.3 --seed 0 ``` -Open new console tab, go to your starknet.js directory and run: +Open a new console tab, go to your starknet.js directory, and run: ```bash npm run test # all tests npm run test ./__tests__/contract.test.ts # just one test suite ``` -By default `defaultProvider` tests will be ran through the `Sequencer`. +By default, `defaultProvider` tests will be run through the `Sequencer`. If you want to run `defaultProvider` through the `RPC` run: @@ -67,7 +67,7 @@ Additional helpful resources can also be found at [OpenZeppelin](https://do Please take a look at our workshop using OpenZeppelin contracts [here](https://github.com/0xs34n/starknet.js-workshop). -Example with Argent contract [here](https://github.com/0xs34n/starknet.js-account). +Example with the Argent contract [here](https://github.com/0xs34n/starknet.js-account). ## Contracts used in the guides diff --git a/www/docs/guides/multiCall.md b/www/docs/guides/multiCall.md index d1bde9592..d103a8eb0 100644 --- a/www/docs/guides/multiCall.md +++ b/www/docs/guides/multiCall.md @@ -30,7 +30,7 @@ const account = new Account( ## Interact with contracts -Interact with more than one contract by using `account.execute([calls])`. Example is as follows. +Interact with more than one contract by using `account.execute([calls])`. The example is as follows. ```javascript const multiCall = await account.execute( diff --git a/www/docs/guides/signature.md b/www/docs/guides/signature.md index 9173da786..48bdd4c0c 100644 --- a/www/docs/guides/signature.md +++ b/www/docs/guides/signature.md @@ -8,7 +8,7 @@ You can use Starknet.js to sign a message outside of the network, using the stan ## Sign and send a message -Your message has to be an array of `BigNumberish`. First calculate the hash of this message, then calculate the signature. +Your message has to be an array of `BigNumberish`. First, calculate the hash of this message, then calculate the signature. > If the message does not respect some safety rules of composition, this method could be a way of attack of your smart contract. If you have any doubt, prefer the [EIP712 like method](#sign-and-verify-following-eip712), which is safe, but is also more complicated. @@ -33,7 +33,7 @@ Then you can send, by any means, to the recipient of the message: ## Receive and verify a message -On receiver side, you can verify that: +On the receiver side, you can verify that: - the message has not been modified, - the sender of this message owns the private key corresponding to the public key. @@ -45,7 +45,7 @@ On receiver side, you can verify that: ### Verify outside of Starknet: -The sender provides the message, the signature and the full public key. Verification: +The sender provides the message, the signature, and the full public key. Verification: ```typescript const msgHash1 = hash.computeHashOnElements(message); @@ -53,9 +53,9 @@ const result1 = ec.starkCurve.verify(signature, msgHash1, fullPublicKey); console.log("Result (boolean) =", result1); ``` -> The sender can also provide their account address. Then you can check that this full public key is linked to this account. The pubKey that you can read in the account contract is part (part X) of the full pubKey (parts X & Y): +> The sender can also provide their account address. Then you can check that this full public key is linked to this account. The public Key that you can read in the account contract is part (part X) of the full public Key (parts X & Y): -Read the pubKey of the account: +Read the Public Key of the account: ```typescript const provider = new Provider({ sequencer: { baseUrl: "http://127.0.0.1:5050" } }); //devnet @@ -65,7 +65,7 @@ const contractAccount = new Contract(compiledAccount.abi, accountAddress, provid const pubKey3 = await contractAccount.call("getPublicKey"); ``` -Check that the pubKey of the account is part of the full pubKey: +Check that the Public Key of the account is part of the full public Key: ```typescript const isFullPubKeyRelatedToAccount: boolean = @@ -73,9 +73,9 @@ const isFullPubKeyRelatedToAccount: boolean = console.log("Result (boolean)=", isFullPubKeyRelatedToAccount); ``` -### Verify in Starknet network, with the account: +### Verify in the Starknet network, with the account: -The sender can provide an account address, in spite of a full public key. +The sender can provide an account address, despite a full public key. ```typescript const provider = new Provider({ sequencer: { baseUrl: "http://127.0.0.1:5050" } }); //devnet @@ -95,21 +95,21 @@ const msgHash2 = hash.computeHashOnElements(message); console.log("Result (boolean) =", result2); ``` -## Sign and verify following EIP712 +## Sign and verify the following EIP712 -Previous examples are valid for an array of numbers. In case of more complex structure of object, you have to work in the spirit of [EIP 712](https://eips.ethereum.org/EIPS/eip-712). This json structure has 4 mandatory items: `types`, `primaryType`, `domain` and `message`. +Previous examples are valid for an array of numbers. In the case of a more complex structure of an object, you have to work in the spirit of [EIP 712](https://eips.ethereum.org/EIPS/eip-712). This JSON structure has 4 mandatory items: `types`, `primaryType`, `domain`, and `message`. These items are designed to be able to be an interface with a wallet. At sign request, the wallet will display: -- `message` will be displayed at the bottom of the wallet display, showing clearly (not in hex) the message to sign. Its structure has to be in accordance with the type listed in `primaryType`, defined in `types`. -- `domain` will be shown above the message. Its structure has to be in accordance with `StarkNetDomain`. +- the `message` will be displayed at the bottom of the wallet display, showing clearly (not in hex) the message to sign. Its structure has to be in accordance with the type listed in `primaryType`, defined in `types`. +- the `domain` will be shown above the message. Its structure has to be in accordance with `StarkNetDomain`. The predefined types that you can use : -- felt : for an integer on 251 bits. -- felt\* : for an array of felt. -- string : for a shortString of 31 ASCII characters max. -- selector : for a name of a smartcontract function. -- merkletree : for a Root of a Merkle tree. root is calculated with the provided data. +- felt: for an integer on 251 bits. +- felt\*: for an array of felt. +- string: for a shortString of 31 ASCII characters max. +- selector: for a name of a smart contract function. +- merkletree: for a Root of a Merkle tree. the root is calculated with the provided data. ```typescript const typedDataValidate: TypedData = { @@ -171,7 +171,7 @@ const signature2: weierstrass.SignatureType = await account.signMessage(typedDat ``` -On receiver side, you receive the json, the signature and the account address. To verify the message: +On the receiver side, you receive the JSON, the signature, and the account address. To verify the message: ```typescript const compiledAccount = json.parse(fs.readFileSync("./compiledContracts/Account_0_5_1.json").toString("ascii")); diff --git a/www/docs/guides/use_ERC20.md b/www/docs/guides/use_ERC20.md index 81da1b019..ca39177d7 100644 --- a/www/docs/guides/use_ERC20.md +++ b/www/docs/guides/use_ERC20.md @@ -11,23 +11,23 @@ Based on what has been seen in the previous pages of this guide, we will use an As in Ethereum, a token has an ERC20 contract to manage it. This contract contains a table, that lists the quantity of tokens owned by each involved account: ![](./pictures/ERC20.png) -For example, the Account address 2 owns 100 token of this ERC20 contract. +For example, Account address 2 owns 100 tokens of this ERC20 contract. -Users have the feeling that their tokens are stored in their wallet, but it's absolutely false. You have no list of assets stored in your account contract. In fact, a token has its own ERC20 contract, and the amount of token owned by your account address is stored in this contract. +Users have the feeling that their tokens are stored in their wallets, but it's absolutely false. You have no list of assets stored in your account contract. In fact, a token has its own ERC20 contract, and the amount of token owned by your account address is stored in this contract. -If you want to have your balance of a token, ask its ERC20 contract, with the function `ERC20contract.balanceOf(accountAddress)`. +If you want to have your balance of a token, ask for its ERC20 contract, with the function `ERC20contract.balanceOf(accountAddress)`. -When you want to transfer some tokens in you possession, you have to use the ERC20 contract function `transfer`, through the `account.execute` function (or meta-class methods). In this way, Starknet.js will send to the account contract a message signed with the private key. +When you want to transfer some tokens in your possession, you have to use the ERC20 contract function `transfer`, through the `account.execute` function (or meta-class methods). In this way, Starknet.js will send to the account contract a message signed with the private key. This message contains the name of the function to call in the ERC20 contract, with its optional parameters. -The account contract will use the public key to check that you have the private key, then will ask to the ERC20 contract to execute the requested function. +The account contract will use the public key to check that you have the private key, then will ask the ERC20 contract to execute the requested function. This way, the ERC20 contract is absolutely sure that the caller of the transfer function knows the private key of this account. ## ETH token is an ERC20 in Starknet -In opposition with Ethereum, the ETH token is an ERC20 in Starknet, as all other tokens. In all networks, it's ERC20 contract address is: +In opposition to Ethereum, the ETH token is an ERC20 in Starknet, like all other tokens. In all networks, its ERC20 contract address is: ```typescript const addrETH = "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7"; @@ -35,7 +35,7 @@ const addrETH = "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004 ## Deploy an ERC20 -Lets dive down the rabbit hole! +Let's dive down the rabbit hole! This example works with an ERC20 mintable (everybody can mint new tokens), that we will deploy on the devnet (launched with `starknet-devnet --seed 0`). diff --git a/www/docs/guides/what_s_starknet.js.md b/www/docs/guides/what_s_starknet.js.md index 763764805..7e6adfefa 100644 --- a/www/docs/guides/what_s_starknet.js.md +++ b/www/docs/guides/what_s_starknet.js.md @@ -25,9 +25,9 @@ Some important topics that have to be understood: > Understand what is Starknet and how it works is necessary. Then, you can learn how to interact with it using Starknet.js. So, at this stage, you should be aware of the content of the [Starknet official doc](https://docs.starknet.io/documentation/) and [the Starknet Book](https://book.starknet.io/). -- Only the `Provider` object is talking directly to the network - your DAPP will talk mainly to `Account` and `Contract` objects. You will define with the `Provider` with which network you want to work. You can ask the Provider some low level data of the network (block, timestamp, ...). -- `Signer` and `Utils` objects contain many useful functions for the interaction with Starknet.js. +- Only the `Provider` object is talking directly to the network - your DAPP will talk mainly to `Account` and `Contract` objects. You will define with the `Provider` with which network you want to work. You can ask the Provider for some low-level data of the network (block, timestamp, ...). +- `Signer` and `Utils` objects contain many useful functions for interaction with Starknet.js. - The `Contract` object is mainly used to read the memory of a blockchain contract. - The `Account` object is the most useful: - - as wallet, to store your tokens. - - as a way to pay the fees to the network, to be able to write in its memory. + - as a wallet, to store your tokens. + - as a way to pay the fees to the network, and to be able to write in its memory.