Skip to content

Commit 24cc4d4

Browse files
committed
docs: generate documentation version
1 parent 7d11bee commit 24cc4d4

39 files changed

+4430
-1
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
---
2+
sidebar_position: 14
3+
---
4+
5+
# Messages with L1 network
6+
7+
You can exchange messages between L1 & L2 networks:
8+
9+
- L2 Starknet mainnet ↔️ L1 Ethereum.
10+
- L2 Starknet testnet ↔️ L1 Sepolia ETH testnet.
11+
- L2 local Starknet devnet ↔️ L1 local ETH testnet (anvil, ...).
12+
13+
You can find an explanation of the global mechanism [here](https://docs.starknet.io/documentation/architecture_and_concepts/L1-L2_Communication/messaging-mechanism/).
14+
15+
Most of the code for this messaging process will be written in Cairo, but Starknet.js provides some functionalities for this subject.
16+
17+
## L1 ➡️ L2 messages
18+
19+
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.
20+
The interface of this function:
21+
22+
```solidity
23+
/**
24+
Sends a message to an L2 contract.
25+
This function is payable, the paid amount is the message fee.
26+
Returns the hash of the message and the nonce of the message.
27+
*/
28+
function sendMessageToL2(
29+
uint256 toAddress,
30+
uint256 selector,
31+
uint256[] calldata payload
32+
) external payable returns (bytes32, uint256);
33+
```
34+
35+
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:
36+
37+
```typescript
38+
import { RpcProvider, constants } from 'starknet';
39+
const provider = new RpcProvider({ nodeUrl: constants.NetworkName.SN_SEPOLIA }); // for testnet
40+
41+
const responseEstimateMessageFee = await provider.estimateMessageFee({
42+
from_address: L1address,
43+
to_address: L2address,
44+
entry_point_selector: 'handle_l1_mess',
45+
payload: ['1234567890123456789', '200'], // without from_address
46+
});
47+
```
48+
49+
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 a first parameter called `from_address: felt252`). The payload shall not include the `from_address` parameter.
50+
51+
### L1 ➡️ L2 hashes
52+
53+
Starknet.js proposes 2 functions to calculate hashes related to a L1 ➡️ L2 message :
54+
55+
- The L2 message hash:
56+
For a L1 tx requesting a message L1->L2, some data extracted from etherscan : https://sepolia.etherscan.io/tx/0xd82ce7dd9f3964d89d2eb9d555e1460fb7792be274950abe578d610f95cc40f5
57+
58+
```typescript
59+
const l1FromAddress = '0x0000000000000000000000008453fc6cd1bcfe8d4dfc069c400b433054d47bdc';
60+
const l2ToAddress = 2158142789748719025684046545159279785659305214176670733242887773692203401023n;
61+
const l2Selector = 774397379524139446221206168840917193112228400237242521560346153613428128537n;
62+
const payload = [
63+
4543560n,
64+
829565602143178078434185452406102222830667255948n,
65+
3461886633118033953192540141609307739580461579986333346825796013261542798665n,
66+
9000000000000000n,
67+
0n,
68+
];
69+
const l1Nonce = 8288n;
70+
const l1ToL2MessageHash = hash.getL2MessageHash(
71+
l1FromAddress,
72+
l2ToAddress,
73+
l2Selector,
74+
payload,
75+
l1Nonce
76+
);
77+
// l1ToL2MessageHash = '0x2e350fa9d830482605cb68be4fdb9f0cb3e1f95a0c51623ac1a5d1bd997c2090'
78+
```
79+
80+
Can be verified here : https://sepolia.starkscan.co/message/0x2e350fa9d830482605cb68be4fdb9f0cb3e1f95a0c51623ac1a5d1bd997c2090#messagelogs
81+
82+
- The L2 transaction hash:
83+
For the same message:
84+
```typescript
85+
const l1ToL2TransactionHash = hash.calculateL2MessageTxHash(
86+
l1FromAddress,
87+
l2ToAddress,
88+
l2Selector,
89+
payload,
90+
constants.StarknetChainId.SN_SEPOLIA,
91+
l1Nonce
92+
);
93+
// l1ToL2TransactionHash = '0x67d959200d65d4ad293aa4b0da21bb050a1f669bce37d215c6edbf041269c07'
94+
```
95+
Can be verified here : https://sepolia.starkscan.co/tx/0x067d959200d65d4ad293aa4b0da21bb050a1f669bce37d215c6edbf041269c07
96+
97+
## L2 ➡️ L1 messages
98+
99+
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).
100+
101+
If necessary you can estimate this fee with the generic `estimateInvokeFee` function:
102+
103+
```typescript
104+
const { suggestedMaxFee: estimatedFee1 } = await account0.estimateInvokeFee({
105+
contractAddress: testAddress,
106+
entrypoint: 'withdraw_to_L1',
107+
calldata: ['123456789', '30'],
108+
});
109+
```
110+
111+
The result is in `estimatedFee1`, of type BN.
112+
113+
### L2 ➡️ L1 hash
114+
115+
Starknet.js proposes a function to calculate the L1 ➡️ L2 message hash :
116+
117+
```typescript
118+
const l2TransactionHash = '0x28dfc05eb4f261b37ddad451ff22f1d08d4e3c24dc646af0ec69fa20e096819';
119+
const l1MessageHash = await provider.getL1MessageHash(l2TransactionHash);
120+
// l1MessageHash = '0x55b3f8b6e607fffd9b4d843dfe8f9b5c05822cd94fcad8797deb01d77805532a'
121+
```
122+
123+
Can be verified here : https://sepolia.voyager.online/tx/0x28dfc05eb4f261b37ddad451ff22f1d08d4e3c24dc646af0ec69fa20e096819#messages
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"label": "Guides",
3+
"position": 2,
4+
"collapsed": false
5+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
---
2+
sidebar_position: 18
3+
---
4+
5+
# Automatic TypeScript parsing of Cairo ABI-s
6+
7+
Starknet.js has integrated [Abi-Wan-Kanabi](https://github.com/keep-starknet-strange/abi-wan-kanabi), the standalone TypeScript parser for Cairo smart contracts.
8+
9+
It enables on-the-fly typechecking and autocompletion for contract calls directly in TypeScript. Developers can now catch typing mistakes early, prior to executing a call on-chain, thus enhancing the overall DAPP development experience.
10+
11+
## Supported Cairo ABI-s
12+
13+
Please take a look on the Abi-Wan [documentation](https://github.com/keep-starknet-strange/abi-wan-kanabi#cairo-versions) for a list of supported Cairo ABI-s.
14+
15+
## Usage
16+
17+
First, you need to wrap your ABI in an array and export it as a `const`.
18+
19+
Example:
20+
21+
```js
22+
export const ABI = [
23+
{
24+
type: 'function',
25+
name: 'increase_balance',
26+
inputs: [
27+
{
28+
name: 'amount',
29+
type: 'core::felt252',
30+
},
31+
],
32+
outputs: [],
33+
state_mutability: 'external',
34+
},
35+
] as const;
36+
```
37+
38+
Later on, to use it in our code:
39+
40+
```js
41+
import { Contract, RpcProvider, constants } from 'starknet';
42+
43+
const address = 'YOUR_ADDRESS_HERE';
44+
const provider = new RpcProvider({ nodeUrl: `${yourNodeUrl}` });
45+
const contract = new Contract(ABI, address, provider).typedv2(ABI);
46+
47+
// Notice the autocompletion and typechecking in your editor
48+
const result = await contract.increase_balance(100);
49+
```
50+
51+
After that, you can use `contract` in your code as you would before, but with autocompletion and typechecking!
52+
53+
### Generate `abi.ts` from the contract class
54+
55+
If you have your contract class in a Json file, you can use the abiwan CLI to generate the `abi.ts` typescript file
56+
57+
```bash
58+
npx abi-wan-kanabi --input /path/to/contract_class.json --output /path/to/abi.ts
59+
```
60+
61+
### Usage for deployed contracts
62+
63+
Let's say you want to interact with the [Ekubo: Core](https://starkscan.co/contract/0x00000005dd3d2f4429af886cd1a3b08289dbcea99a294197e9eb43b0e0325b4b) contract
64+
65+
You need to first get the **ABI** of the contract and export it in a typescript file, you can do so using one command combining both [`starkli`](https://github.com/xJonathanLEI/starkli) (tested with version 0.2.3) and `npx abi-wan-kanabi`:
66+
67+
```bash
68+
starkli class-at "0x00000005dd3d2f4429af886cd1a3b08289dbcea99a294197e9eb43b0e0325b4b" --network mainnet | npx abi-wan-kanabi --input /dev/stdin --output abi.ts
69+
```
70+
71+
```typescript
72+
import { Contract, RpcProvider, constants } from 'starknet';
73+
import { ABI } from './abi';
74+
75+
const address = '0x00000005dd3d2f4429af886cd1a3b08289dbcea99a294197e9eb43b0e0325b4b';
76+
const provider = new RpcProvider({ nodeUrl: constants.NetworkName.SN_MAIN });
77+
const contract = new Contract(ABI, address, provider).typedv2(ABI);
78+
79+
// Notice the types inferred for the parameter and the returned value
80+
const primary_interface_id = contract.get_primary_interface_id();
81+
const protocol_fees_collected = contract.get_protocol_fees_collected('0x1');
82+
```

0 commit comments

Comments
 (0)