Skip to content

Commit

Permalink
docs: update guides to v5
Browse files Browse the repository at this point in the history
---------

Co-authored-by: Ivan Pavičić <[email protected]>
Co-authored-by: Petar Penovic <[email protected]>
  • Loading branch information
3 people authored Jun 14, 2023
1 parent b82d8e4 commit 724686f
Show file tree
Hide file tree
Showing 19 changed files with 956 additions and 411 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
node_modules/
dist/
www/
2 changes: 1 addition & 1 deletion www/docs/guides/L1message.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ You have to pay in the L1 an extra fee when invoking `sendMessageToL2` (of cours

```typescript
import { SequencerProvider } from "starknet";
const provider = new SequencerProvider({ baseUrl: BaseUrl.SN_GOERLI }); // for testnet 1
const provider = new SequencerProvider({ baseUrl: constants.BaseUrl.SN_GOERLI }); // for testnet 1

const responseEstimateMessageFee = await provider.estimateMessageFee({
from_address: L1address,
Expand Down
197 changes: 197 additions & 0 deletions www/docs/guides/compiled_contracts/deployBraavos.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
// Collection of functions for Braavos account creation
// coded with Starknet.js v5.11.1, 01/jun/2023

import {
BigNumberish,
CairoVersion,
CallData,
Calldata,
DeployAccountContractPayload,
DeployAccountContractTransaction,
DeployContractResponse,
EstimateFeeDetails,
InvocationsSignerDetails,
Provider,
RawCalldata,
constants,
ec,
hash,
num,
stark,
} from 'starknet';

const BraavosProxyClassHash: BigNumberish =
'0x03131fa018d520a037686ce3efddeab8f28895662f019ca3ca18a626650f7d1e';
const BraavosInitialClassHash = '0x5aa23d5bb71ddaa783da7ea79d405315bafa7cf0387a74f4593578c3e9e6570';
const BraavosAccountClassHash = '0x2c2b8f559e1221468140ad7b2352b1a5be32660d0bf1a3ae3a054a4ec5254e4'; // will probably change over time

export function getBraavosSignature(
BraavosProxyAddress: BigNumberish,
BraavosProxyConstructorCallData: RawCalldata,
starkKeyPubBraavos: BigNumberish,
version: bigint,
max_fee: BigNumberish,
chainId: constants.StarknetChainId,
nonce: bigint,
privateKeyBraavos: BigNumberish
): string[] {
const txnHash = hash.calculateDeployAccountTransactionHash(
BraavosProxyAddress,
BraavosProxyClassHash,
BraavosProxyConstructorCallData,
starkKeyPubBraavos,
version,
max_fee,
chainId,
nonce
);

const parsedOtherSigner = [0, 0, 0, 0, 0, 0, 0];
const { r, s } = ec.starkCurve.sign(
hash.computeHashOnElements([txnHash, BraavosAccountClassHash, ...parsedOtherSigner]),
num.toHex(privateKeyBraavos)
);
const signature = [
r.toString(),
s.toString(),
BraavosAccountClassHash.toString(),
...parsedOtherSigner.map((e) => e.toString()),
];
console.log('signature =', signature);
return signature;
}

const calcBraavosInit = (starkKeyPubBraavos: string) =>
CallData.compile({ public_key: starkKeyPubBraavos });
const BraavosProxyConstructor = (BraavosInitializer: Calldata) =>
CallData.compile({
implementation_address: BraavosInitialClassHash,
initializer_selector: hash.getSelectorFromName('initializer'),
calldata: [...BraavosInitializer],
});

export function calculateAddressBraavos(privateKeyBraavos: BigNumberish): string {
const starkKeyPubBraavos = ec.starkCurve.getStarkKey(num.toHex(privateKeyBraavos));
const BraavosInitializer = calcBraavosInit(starkKeyPubBraavos);
const BraavosProxyConstructorCallData = BraavosProxyConstructor(BraavosInitializer);

return hash.calculateContractAddressFromHash(
starkKeyPubBraavos,
BraavosProxyClassHash,
BraavosProxyConstructorCallData,
0
);
}

async function buildBraavosAccountDeployPayload(
privateKeyBraavos: BigNumberish,
{
classHash,
addressSalt,
constructorCalldata,
contractAddress: providedContractAddress,
}: DeployAccountContractPayload,
{ nonce, chainId, version, maxFee }: InvocationsSignerDetails
): Promise<DeployAccountContractTransaction> {
const compiledCalldata = CallData.compile(constructorCalldata ?? []);
const contractAddress = providedContractAddress ?? calculateAddressBraavos(privateKeyBraavos);
const starkKeyPubBraavos = ec.starkCurve.getStarkKey(num.toHex(privateKeyBraavos));
const signature = getBraavosSignature(
contractAddress,
compiledCalldata,
starkKeyPubBraavos,
BigInt(version),
maxFee,
chainId,
BigInt(nonce),
privateKeyBraavos
);
return {
classHash,
addressSalt,
constructorCalldata: compiledCalldata,
signature,
};
}

export async function estimateBraavosAccountDeployFee(
privateKeyBraavos: BigNumberish,
provider: Provider,
{ blockIdentifier, skipValidate }: EstimateFeeDetails = {}
): Promise<bigint> {
const version = hash.feeTransactionVersion;
const nonce = constants.ZERO;
const chainId = await provider.getChainId();
const cairoVersion: CairoVersion = '0';
const starkKeyPubBraavos = ec.starkCurve.getStarkKey(num.toHex(privateKeyBraavos));
const BraavosProxyAddress = calculateAddressBraavos(privateKeyBraavos);
const BraavosInitializer = calcBraavosInit(starkKeyPubBraavos);
const BraavosProxyConstructorCallData = BraavosProxyConstructor(BraavosInitializer);

const payload = await buildBraavosAccountDeployPayload(
privateKeyBraavos,
{
classHash: BraavosProxyClassHash.toString(),
addressSalt: starkKeyPubBraavos,
constructorCalldata: BraavosProxyConstructorCallData,
contractAddress: BraavosProxyAddress,
},
{
nonce,
chainId,
version,
walletAddress: BraavosProxyAddress,
maxFee: constants.ZERO,
cairoVersion,
}
);

const response = await provider.getDeployAccountEstimateFee(
{ ...payload },
{ version, nonce },
blockIdentifier,
skipValidate
);
const suggestedMaxFee = stark.estimatedFeeToMaxFee(response.overall_fee);

return suggestedMaxFee;
}

export async function deployBraavosAccount(
privateKeyBraavos: BigNumberish,
provider: Provider,
max_fee?: BigNumberish
): Promise<DeployContractResponse> {
const nonce = constants.ZERO;
const starkKeyPubBraavos = ec.starkCurve.getStarkKey(num.toHex(privateKeyBraavos));
console.log('pubkey =', starkKeyPubBraavos.toString());
const BraavosProxyAddress = calculateAddressBraavos(privateKeyBraavos);
const BraavosInitializer = calcBraavosInit(starkKeyPubBraavos);
const BraavosProxyConstructorCallData = BraavosProxyConstructor(BraavosInitializer);
max_fee ??= await estimateBraavosAccountDeployFee(privateKeyBraavos, provider);
const version = hash.transactionVersion;
const signatureBraavos = getBraavosSignature(
BraavosProxyAddress,
BraavosProxyConstructorCallData,
starkKeyPubBraavos,
version,
max_fee,
await provider.getChainId(),
nonce,
privateKeyBraavos
);

return provider.deployAccountContract(
{
classHash: BraavosProxyClassHash.toString(),
addressSalt: starkKeyPubBraavos,
constructorCalldata: BraavosProxyConstructorCallData,
signature: signatureBraavos,
},
{
nonce,
maxFee: max_fee,
version,
}
);
}
10 changes: 4 additions & 6 deletions www/docs/guides/connect_account.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ You need 2 data :
- the private key of this account

```typescript
import { Account, ec, Provider } from "starknet";
import { Account, Provider } from "starknet";
```

## Connect a predeployed account in Starknet-devnet
Expand All @@ -38,10 +38,9 @@ Then you can use this code :
const provider = new Provider({ sequencer: { baseUrl:"http://127.0.0.1:5050" } });
// initialize existing pre-deployed account 0 of Devnet
const privateKey = "0xe3e70682c2094cac629f6fbed82c07cd";
const starkKeyPair = ec.getKeyPair(privateKey);
const accountAddress = "0x7e00d496e324876bbc8531f2d9a82bf154d1a04a50218ee74cdd372f75a551a";

const account = new Account(provider, accountAddress, starkKeyPair);
const account = new Account(provider, accountAddress, privateKey);
```

Your account is now connected, and you can use it.
Expand All @@ -61,11 +60,10 @@ import * as dotenv from "dotenv";
dotenv.config();

// initialize provider
const provider = new Provider({ sequencer: { network: NetworkName.SN_GOERLI2 } });
const provider = new Provider({ sequencer: { network: constants.NetworkName.SN_GOERLI2 } });
// initialize existing account
const privateKey = process.env.OZ_NEW_ACCOUNT_PRIVKEY;
const starkKeyPair = ec.getKeyPair(privateKey);
const accountAddress = "0x051158d244c7636dde39ec822873b29e6c9a758c6a9812d005b6287564908667";

const account = new Account(provider, accountAddress, starkKeyPair);
const account = new Account(provider, accountAddress, privateKey);
```
16 changes: 11 additions & 5 deletions www/docs/guides/connect_contract.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,25 @@ Once your provider is initialized, you can connect a contract already deployed i
You need 2 data :

- the address of the contract
- the ABI file of the contract (or the compiled contract file, that includes the abi)
- 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()` command can help you.
> 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";
const compressedContract = await provider.getClassAt(addrContract);
fs.writeFileSync('./myAbi.json', json.stringify( compressedContract.abi, undefined, 2));
```

> When possible, prefer to read the compiled contract from a local Json file, as it's much more faster, using the `json.parse` util provided by Starknet.js, as shown below.
## Get the abi from a compiled file
## Get the abi from a compiled/compressed file

```typescript
import { Provider, Contract, json } from "starknet";
```

If you have the compiled 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 ABI :

```typescript
const compiledContract = json.parse(fs.readFileSync("./compiledContracts/test.json").toString("ascii"));
Expand All @@ -33,7 +39,7 @@ const compiledContract = json.parse(fs.readFileSync("./compiledContracts/test.js

```typescript
// initialize provider
const provider = new Provider({ sequencer: { network: NetworkName.SN_GOERLI } });
const provider = new Provider({ sequencer: { network: constants.NetworkName.SN_GOERLI } });

// initialize deployed contract
const testAddress = "0x7667469b8e93faa642573078b6bf8c790d3a6184b2a1bb39c5c923a732862e1";
Expand Down
29 changes: 21 additions & 8 deletions www/docs/guides/connect_network.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@ import {Provider} from 'starknet';
## Connect your DAPP to Starknet mainnet

```typescript
const provider = new Provider({ sequencer: { network: NetworkName.SN_MAIN } })
const provider = new Provider({ sequencer: { network: constants.NetworkName.SN_MAIN } })
```

## Connect your DAPP to Starknet testnet 1 & 2

```typescript
const provider = new Provider({ sequencer: { network: NetworkName.SN_GOERLI } }) // for testnet 1
const provider = new Provider({ sequencer: { network: NetworkName.SN_GOERLI2 } }) // for testnet 2
const provider = new Provider({ sequencer: { network: constants.NetworkName.SN_GOERLI } }) // for testnet 1
const provider = new Provider({ sequencer: { network: constants.NetworkName.SN_GOERLI2 } }) // for testnet 2
```

## Connect your DAPP to Starknet-devnet
Expand Down Expand Up @@ -55,6 +55,12 @@ 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 located in a computer of you network, launched with this additional option : `--http-rpc 0.0.0.0:9545`). You connect with :

```typescript
const provider = new Provider({ rpc: { nodeUrl: '192.168.1.99:9545' } })
```

## Specific methods

Some methods are available only if connected to a sequencer, and some others are available only if connected to a node (using RPC).
Expand All @@ -64,8 +70,8 @@ Some methods are available only if connected to a sequencer, and some others are
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 } from "starknet";
const provider = new SequencerProvider({ baseUrl: BaseUrl.SN_GOERLI2 }); // for testnet 2
import { SequencerProvider, constants } from "starknet";
const provider = new SequencerProvider({ baseUrl: constants.BaseUrl.SN_GOERLI2 }); // for testnet 2
const responseEstimateMessageFee = await provider.estimateMessageFee(.....)
```

Expand All @@ -76,12 +82,19 @@ For example, if you want to read the events recorded in a range of blocks, you n
```typescript
import { RpcProvider } from "starknet";
const providerRPC = new RpcProvider({ nodeUrl: "http://192.168.1.99:9545" }); // for a pathfinder node located in a PC in the local network
const lastBlock = await providerRPC.getBlock('latest');
let eventsList = await providerRPC.getEvents({
address: myContractAddress,
from_block: {block_number: block_number0},
to_block: {block_number: block_number1},
chunk_size: 1000
from_block: {block_number: lastBlock.block_number-2},
to_block: {block_number: lastBlock.block_number},
chunk_size: 400
});
```

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 :

```typescript
const providerRPC = new RpcProvider({ nodeUrl: 'https://starknet-mainnet.g.alchemy.com/v2/' + alchemyKey});
```
Loading

0 comments on commit 724686f

Please sign in to comment.