Skip to content

Commit 81bb7d7

Browse files
committed
Merge branch 'develop' into isabellewei/bernoulli-mainnet
2 parents 864755d + 5804681 commit 81bb7d7

35 files changed

+264
-78
lines changed

src/components/Tabs/TabsContent.tsx

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/** @jsxImportSource preact */
2+
import type { ComponentChild } from "preact"
3+
import { useRef } from "preact/hooks"
4+
import { useTabState } from "./useTabState"
5+
import styles from "./Tabs.module.css"
6+
import { clsx } from "~/lib"
7+
const tabSlotKey = "tab." as const
8+
const panelSlotKey = "panel." as const
9+
10+
type TabSlot = `${typeof tabSlotKey}${string}`
11+
type PanelSlot = `${typeof panelSlotKey}${string}`
12+
13+
function isTabSlotEntry(entry: [string, ComponentChild]): entry is [TabSlot, ComponentChild] {
14+
const [key] = entry
15+
return key.startsWith(tabSlotKey)
16+
}
17+
18+
function isPanelSlotEntry(entry: [string, ComponentChild]): entry is [PanelSlot, ComponentChild] {
19+
const [key] = entry
20+
return key.startsWith(panelSlotKey)
21+
}
22+
23+
function getBaseKeyFromTab(slot: TabSlot) {
24+
return slot.replace(new RegExp(`^${tabSlotKey}`), "")
25+
}
26+
27+
function getBaseKeyFromPanel(slot: PanelSlot) {
28+
return slot.replace(new RegExp(`^${panelSlotKey}`), "")
29+
}
30+
31+
type Props = {
32+
[key: TabSlot | PanelSlot]: ComponentChild
33+
sharedStore?: string
34+
}
35+
36+
export function TabsContent({ sharedStore, ...slots }: Props) {
37+
const tabs = Object.entries(slots).filter(isTabSlotEntry)
38+
const panels = Object.entries(slots).filter(isPanelSlotEntry)
39+
40+
/** Used to focus next and previous tab on arrow key press */
41+
const tabButtonRefs = useRef<Record<TabSlot, HTMLButtonElement | null>>({})
42+
43+
const firstPanelKey = panels[0] ? getBaseKeyFromPanel(panels[0][0]) : ""
44+
const [curr, setCurrStore] = useTabState(firstPanelKey, sharedStore)
45+
46+
function moveFocus(event: KeyboardEvent) {
47+
if (event.key === "ArrowLeft") {
48+
const currIdx = tabs.findIndex(([key]) => getBaseKeyFromTab(key) === curr)
49+
if (currIdx > 0) {
50+
const [prevTabKey] = tabs[currIdx - 1]
51+
setCurrStore(getBaseKeyFromTab(prevTabKey))
52+
tabButtonRefs.current[prevTabKey]?.focus()
53+
}
54+
}
55+
if (event.key === "ArrowRight") {
56+
const currIdx = tabs.findIndex(([key]) => getBaseKeyFromTab(key) === curr)
57+
if (currIdx < tabs.length - 1) {
58+
const [nextTabKey] = tabs[currIdx + 1]
59+
setCurrStore(getBaseKeyFromTab(nextTabKey))
60+
tabButtonRefs.current[nextTabKey]?.focus()
61+
}
62+
}
63+
}
64+
65+
return (
66+
<div className={styles.contentContainer}>
67+
<div role="tablist" onKeyDown={moveFocus}>
68+
{tabs.map(([key, content]) => (
69+
<button
70+
ref={(el) => (tabButtonRefs.current[key] = el)}
71+
onClick={() => {
72+
setCurrStore(getBaseKeyFromTab(key))
73+
}}
74+
aria-selected={curr === getBaseKeyFromTab(key)}
75+
tabIndex={curr === getBaseKeyFromTab(key) ? 0 : -1}
76+
role="tab"
77+
type="button"
78+
data-astro-tab
79+
id={key}
80+
key={key}
81+
class={clsx(
82+
curr === getBaseKeyFromTab(key) ? styles.contentTabPrimary : styles.contentTabSecondary,
83+
styles.contentTab
84+
)}
85+
>
86+
{content}
87+
</button>
88+
))}
89+
</div>
90+
{panels.map(([key, content]) => (
91+
<div
92+
hidden={curr !== getBaseKeyFromPanel(key)}
93+
role="tabpanel"
94+
aria-labelledby={`${tabSlotKey}${getBaseKeyFromPanel(key)}`}
95+
key={key}
96+
class={styles.panel}
97+
>
98+
{content}
99+
</div>
100+
))}
101+
</div>
102+
)
103+
}

src/components/Tabs/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
export { Tabs } from "./Tabs"
2+
3+
export { TabsContent } from "./TabsContent"

src/content/docs/en/article-components.mdx

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import ToggleElement from "../../../components/ToggleElement.astro"
1414
import Aside from "../../../components/Aside.astro"
1515
import MarkmapView from "../../../components/MarkmapView/index.astro"
1616
import RPCTable from "../../../components/RPCTable/RPCTable.astro"
17+
import { Tabs, TabsContent } from "../../../components/Tabs"
1718

1819
This is body text right under the article title. It typically is just paragraph text that's pretty straightforward. Then there's **bold text**, and _italic text_, and **_bold-italic text_**, and `inline-code` and **`bold inline code`** and even _`italic inline code`_ and **_`bold italic inline code`_**. And of course don't forget [links](#), and [**bold links**](#), and [_italic links_](#), and [**_bold-italic links_**](#).
1920

@@ -164,6 +165,59 @@ stateDiagram
164165
step_context --> ConstraintBuilder
165166
```
166167

168+
### Tabs
169+
170+
<Tabs client:visible>
171+
<Fragment slot="tab.1">npm</Fragment>
172+
<Fragment slot="tab.2">yarn</Fragment>
173+
<Fragment slot="panel.1">```console npm install @chainlink/hardhat-chainlink ```</Fragment>
174+
<Fragment slot="panel.2">```console yarn add @chainlink/hardhat-chainlink ```</Fragment>
175+
</Tabs>
176+
177+
### TabsContent
178+
179+
<TabsContent sharedStore="vrfMethod" client:visible>
180+
<Fragment slot="tab.1">Subscription</Fragment>
181+
<Fragment slot="tab.2">Direct funding</Fragment>
182+
<Fragment slot="panel.1">
183+
184+
For Chainlink VRF v2 to fulfill your requests, you must maintain a sufficient amount of LINK in your subscription balance. Gas cost calculation includes the following variables:
185+
186+
- **Gas price:** The current gas price, which fluctuates depending on network conditions.
187+
188+
- **Callback gas:** The amount of gas used for the callback request that returns your requested random values.
189+
190+
- **Verification gas:** The amount of gas used to verify randomness on-chain.
191+
192+
The gas price depends on current network conditions. The callback gas depends on your callback function, and the number of random values in your request. The cost of each request is final only after the transaction is complete, but you define the limits you are willing to spend for the request with the following variables:
193+
194+
- **Gas lane:** The maximum gas price you are willing to pay for a request in wei. Define this limit by specifying the appropriate `keyHash` in your request. The limits of each gas lane are important for handling gas price spikes when Chainlink VRF bumps the gas price to fulfill your request quickly.
195+
196+
- **Callback gas limit:** Specifies the maximum amount of gas you are willing to spend on the callback request. Define this limit by specifying the `callbackGasLimit` value in your request.
197+
198+
</Fragment>
199+
<Fragment slot="panel.2">
200+
201+
For Chainlink VRF v2 to fulfill your requests, you must have a sufficient amount of LINK in your consuming contract. Gas cost calculation includes the following variables:
202+
203+
- **Gas price:** The current gas price, which fluctuates depending on network conditions.
204+
205+
- **Callback gas:** The amount of gas used for the callback request that returns your requested random values. The callback gas depends on your callback function and the number of random values in your request. Set the **callback gas limit** to specify the maximum amount of gas you are willing to spend on the callback request.
206+
207+
- **Verification gas:** The amount of gas used to verify randomness on-chain.
208+
209+
- **Wrapper overhead gas:** The amount of gas used by the VRF Wrapper contract. See the [Request and Receive Data](/vrf/v2/direct-funding#request-and-receive-data) section for details about the VRF v2 Wrapper contract design.
210+
211+
Because the consuming contract directly pays the LINK for the request, the cost is calculated during the request and not during the callback when the randomness is fulfilled. Test your callback function to learn how to correctly estimate the callback gas limit.
212+
213+
- If the gas limit is underestimated, the callback fails and the consuming contract is still charged for the work done to generate the requested random values.
214+
- If the gas limit is overestimated, the callback function will be executed but your contract is not refunded for the excess gas amount that you paid.
215+
216+
Make sure that your consuming contracts are funded with enough LINK tokens to cover the transaction costs. If the consuming contract doesn't have enough LINK tokens, your request will revert.
217+
218+
</Fragment>
219+
</TabsContent>
220+
167221
### RPC Table
168222

169223
<RPCTable />

src/content/docs/en/developers/guides/running-a-scroll-node.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ date: Last Modified
44
title: "Running a Scroll L2geth Node"
55
lang: "en"
66
permalink: "developers/guides/running-a-scroll-node"
7-
excerpt: "This guide contains instructions on how to to run your own node on the Scroll network."
7+
excerpt: "This guide contains instructions on how to run your own node on the Scroll network."
88
---
99

1010
import Aside from "../../../../../components/Aside.astro"
1111
import ToggleElement from "../../../../../components/ToggleElement.astro"
1212

13-
For most developers, using [our official RPC endpoint](../developer-quickstart#network-configuration) or one offered by other RPC providers in the ecosystem is the easiest way to get started on Scroll. For those looking to maintain their own node, this guide provides instructions on how to run a "follower node" that participates in the public mempool of transactions, but does not participate in consensus or block building. Scroll nodes are a fork of geth, using the clique protocol for consensus, which we call l2geth.
13+
For most developers, using [our official RPC endpoint](/en/developers/developer-quickstart#network-configuration) or one offered by other RPC providers in the ecosystem is the easiest way to get started on Scroll. For those looking to maintain their own node, this guide provides instructions on how to run a "follower node" that participates in the public mempool of transactions, but does not participate in consensus or block building. Scroll nodes are a fork of geth, using the clique protocol for consensus, which we call l2geth.
1414

1515
## Prerequisites
1616

src/content/docs/en/developers/index.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ ensuring that all code executed on the Scroll Layer 2 behaves just as if it were
8080
<p>
8181
We know the challenges of building in the open and getting user engagement! Scroll has a blossoming community of
8282
users and builders, and with a Discord community of over 500,000 members eager to try out applications on our
83-
testnet or mainnet, we’re excited to connect builders with users that can provide real-world feedback.
83+
testnet or mainnet, we’re excited to connect builders with users who can provide real-world feedback.
8484
</p>
8585
</ToggleElement>
8686

src/content/docs/en/developers/l1-and-l2-bridging.mdx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,12 @@ In addition to token transfers, the Scroll Messenger contract enables cross-chai
2626

2727
<ClickToZoom src={L1GatewayWHITE} />
2828

29-
There are many entry points from the user to the Scroll bridge. This will depend on what you want to do and how you want to do it. If you want to send ETH or ERC20 tokens, you should use the `GatewayRouter` . If you want to send NFTs, you should use the `L1ERC721Gateway` or `L1ERC1155Gateway`. If you want to send arbitrary data, you should use the `L1ScrollMessenger`. All Gateway transfers use the Scroll Messenger to send assets cross-chain, whose job is to append the transactions to the Message Queue for L2 inclusion.
29+
There are many entry points from the user to the Scroll bridge. This will depend on what you want to do and how you want to do it. If you want to send ETH or ERC20 tokens, you should use the `GatewayRouter`. If you want to send NFTs, you should use the `L1ERC721Gateway` or `L1ERC1155Gateway`. If you want to send arbitrary data, you should use the `L1ScrollMessenger`. All Gateway transfers use the Scroll Messenger to send assets cross-chain, whose job is to append the transactions to the Message Queue for L2 inclusion.
3030

3131
## L2 Gateway architecture
3232

3333
<ClickToZoom src={withdrawWHITE} />
3434

35-
Regarding possible permissionlessly callable entry points, the L2 Gateway Architecture is very similar to L1. The difference is that when sending a message from L2, calling the `appendMessage` function will store the message in an append-only binary merkle tree (aka withdraw tree) in the `L2MessageQueue`. When a new message is sent to the `L2MessageQueue`, the relayer will detect it and store it in the database. When the block is finalized, it will generate a proof of the new merkle path and pass it to the L1geth node to execute on `L1ScrollMessenger` . All finalized withdraw roots will be stored in the rollup contract so we can verify the proof against them. In the next Scroll versions, the Relayer won't be needed since all users will be able to finalize the transaction on L1.
35+
Regarding possible permissionlessly callable entry points, the L2 Gateway Architecture is very similar to L1. The difference is that when sending a message from L2, calling the `appendMessage` function will store the message in an append-only binary merkle tree (aka withdraw tree) in the `L2MessageQueue`. When a new message is sent to the `L2MessageQueue`, the relayer will detect it and store it in the database. When the block is finalized, it will generate a proof of the new merkle path and pass it to the L1geth node to execute on `L1ScrollMessenger`. All finalized withdraw roots will be stored in the rollup contract so we can verify the proof against them. In the next Scroll versions, the Relayer won't be needed since all users will be able to finalize the transaction on L1.
3636

37-
In the upcoming sections, we will explore the technical aspects of the bridge, including the smart contract API required to utilize its capabilities. Detailed guides with code examples are provided in the Developer Guides section to assist developers and users in understanding and implementing these functionalities.
37+
In the upcoming sections, we will explore the technical aspects of the bridge, including the smart contract API required to utilize its capabilities. Detailed guides with code examples are provided in the Developer Guides section to assist developers and users in understanding and implementing these functionalities.

src/content/docs/en/developers/l1-and-l2-bridging/erc1155-token-bridge.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ interface IScrollERC1155 {
5252
/// @notice Batch mint some token to recipient's account.
5353
/// @dev Gateway Utilities, only gateway contract can call
5454
/// @param _to The address of recipient.
55-
/// @param _tokenIds The token id to mint.
55+
/// @param _tokenIds The list of token ids to mint.
5656
/// @param _amounts The list of corresponding amount of token to mint.
5757
/// @param _data The data passed to recipient
5858
function batchMint(
@@ -158,5 +158,5 @@ Update the mapping that connects an ERC1155 token contract from L2 to L1.
158158

159159
| Parameter | Description |
160160
| --------- | ------------------------------------------------- |
161-
| \_l1Token | The address of th ERC1155 token in L1. |
161+
| \_l1Token | The address of the ERC1155 token in L1. |
162162
| \_l2Token | The address of corresponding ERC1155 token in L2. |

src/content/docs/en/developers/l1-and-l2-bridging/eth-and-erc20-token-bridge.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ All Gateway contracts will form the message and send it to the `L1ScrollMessenge
3333
address of the `L1ScrollMessenger`.
3434
</Aside>
3535

36-
When a new block gets created on L1, the Watcher will detect the message on the `L1MessageQueue` and will pass it to the Relayer service, which will submit the transaction to the L2 via the l2geth node. Finally, the l2geth node will pass the transaction to the `L2ScrollMessagner` contract for execution on L2.
36+
When a new block gets created on L1, the Watcher will detect the message on the `L1MessageQueue` and will pass it to the Relayer service, which will submit the transaction to the L2 via the l2geth node. Finally, the l2geth node will pass the transaction to the `L2ScrollMessenger` contract for execution on L2.
3737

3838
## Withdraw ETH and ERC20 tokens from L2
3939

@@ -76,7 +76,7 @@ interface IScrollStandardERC20 {
7676
/// @param _amount The amount of token to mint.
7777
function mint(address _to, uint256 _amount) external;
7878
79-
/// @notice Mint some token from account.
79+
/// @notice Burn some token from account.
8080
/// @dev Gateway Utilities, only gateway contract can call
8181
/// @param _from The address of account to burn token.
8282
/// @param _amount The amount of token to mint.

src/content/docs/en/developers/scroll-contracts.mdx

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,21 @@ Use the table below to configure your Ethereum tools to the Scroll mainnet.
100100
- v3StakerAddress: [`0xFdFbE973c9ecB036Ecfb7af697FcACe789D3f928`](https://scrollscan.com/address/0xFdFbE973c9ecB036Ecfb7af697FcACe789D3f928)
101101
- quoterV2Address: [`0x2566e082Cb1656d22BCbe5644F5b997D194b5299`](https://scrollscan.com/address/0x2566e082Cb1656d22BCbe5644F5b997D194b5299)
102102

103+
### Safe
104+
105+
You can access Safe on Scroll [here](https://safe.scroll.xyz/), and the transaction service API is at https://transaction.safe.scroll.xyz.
106+
107+
- CompatibilityFallbackHandler: [`0xf48f2B2d2a534e402487b3ee7C18c33Aec0Fe5e4`](https://scrollscan.com/address/0xf48f2B2d2a534e402487b3ee7C18c33Aec0Fe5e4)
108+
- CreateCall: [`0x7cbB62EaA69F79e6873cD1ecB2392971036cFAa4`](https://scrollscan.com/address/0x7cbB62EaA69F79e6873cD1ecB2392971036cFAa4)
109+
- DefaultCallbackHandler: [`0x1AC114C2099aFAf5261731655Dc6c306bFcd4Dbd`](https://scrollscan.com/address/0x1AC114C2099aFAf5261731655Dc6c306bFcd4Dbd)
110+
- GnosisSafe: [`0xd9Db270c1B5E3Bd161E8c8503c55cEABeE709552`](https://scrollscan.com/address/0xd9Db270c1B5E3Bd161E8c8503c55cEABeE709552)
111+
- GnosisSafeL2: [`0x3E5c63644E683549055b9Be8653de26E0B4CD36E`](https://scrollscan.com/address/0x3E5c63644E683549055b9Be8653de26E0B4CD36E)
112+
- GnosisSafeProxyFactory: [`0xa6B71E26C5e0845f74c812102Ca7114b6a896AB2`](https://scrollscan.com/address/0xa6B71E26C5e0845f74c812102Ca7114b6a896AB2)
113+
- MultiSend: [`0xA238CBeb142c10Ef7Ad8442C6D1f9E89e07e7761`](https://scrollscan.com/address/0xA238CBeb142c10Ef7Ad8442C6D1f9E89e07e7761)
114+
- MultiSendCallOnly: [`0x40A2aCCbd92BCA938b02010E17A5b8929b49130D`](https://scrollscan.com/address/0x40A2aCCbd92BCA938b02010E17A5b8929b49130D)
115+
- SignMessageLib: [`0xA65387F16B013cf2Af4605Ad8aA5ec25a2cbA3a2`](https://scrollscan.com/address/0xA65387F16B013cf2Af4605Ad8aA5ec25a2cbA3a2)
116+
- SimulateTxAccessor: [`0x59AD6735bCd8152B84860Cb256dD9e96b85F69Da`](https://scrollscan.com/address/0x59AD6735bCd8152B84860Cb256dD9e96b85F69Da)
117+
103118
#### Ethereum Attestation Service (EAS)
104119

105120
- EAS: [`0xC47300428b6AD2c7D03BB76D05A176058b47E6B0`](https://scrollscan.com/address/0xC47300428b6AD2c7D03BB76D05A176058b47E6B0)
@@ -224,6 +239,21 @@ See this [Github gist](https://gist.github.com/dghelm/7fe68f0a524f30846e1142721c
224239
- EIP712Proxy: [`0xB3574f76b1720E61FdA98702c7016674CD6Eaa7b`](https://sepolia.scrollscan.com/address/0xB3574f76b1720E61FdA98702c7016674CD6Eaa7b)
225240
- Indexer: [`0x7C2cb1eDC328491da52de2a0afc44D3B0Ae7ee17`](https://sepolia.scrollscan.com/address/0x7C2cb1eDC328491da52de2a0afc44D3B0Ae7ee17)
226241

242+
### Safe
243+
244+
You can access Safe on Scroll [here](https://safe.scroll.xyz/), and the transaction service API is at https://transaction-sepolia.safe.scroll.xyz.
245+
246+
- CompatibilityFallbackHandler: [`0xf48f2B2d2a534e402487b3ee7C18c33Aec0Fe5e4`](https://sepolia.scrollscan.com/address/0xf48f2B2d2a534e402487b3ee7C18c33Aec0Fe5e4)
247+
- CreateCall: [`0x7cbB62EaA69F79e6873cD1ecB2392971036cFAa4`](https://sepolia.scrollscan.com/address/0x7cbB62EaA69F79e6873cD1ecB2392971036cFAa4)
248+
- DefaultCallbackHandler: [`0x1AC114C2099aFAf5261731655Dc6c306bFcd4Dbd`](https://sepolia.scrollscan.com/address/0x1AC114C2099aFAf5261731655Dc6c306bFcd4Dbd)
249+
- GnosisSafe: [`0xd9Db270c1B5E3Bd161E8c8503c55cEABeE709552`](https://sepolia.scrollscan.com/address/0xd9Db270c1B5E3Bd161E8c8503c55cEABeE709552)
250+
- GnosisSafeL2: [`0x3E5c63644E683549055b9Be8653de26E0B4CD36E`](https://sepolia.scrollscan.com/address/0x3E5c63644E683549055b9Be8653de26E0B4CD36E)
251+
- GnosisSafeProxyFactory: [`0xa6B71E26C5e0845f74c812102Ca7114b6a896AB2`](https://sepolia.scrollscan.com/address/0xa6B71E26C5e0845f74c812102Ca7114b6a896AB2)
252+
- MultiSend: [`0xA238CBeb142c10Ef7Ad8442C6D1f9E89e07e7761`](https://sepolia.scrollscan.com/address/0xA238CBeb142c10Ef7Ad8442C6D1f9E89e07e7761)
253+
- MultiSendCallOnly: [`0x40A2aCCbd92BCA938b02010E17A5b8929b49130D`](https://sepolia.scrollscan.com/address/0x40A2aCCbd92BCA938b02010E17A5b8929b49130D)
254+
- SignMessageLib: [`0xA65387F16B013cf2Af4605Ad8aA5ec25a2cbA3a2`](https://sepolia.scrollscan.com/address/0xA65387F16B013cf2Af4605Ad8aA5ec25a2cbA3a2)
255+
- SimulateTxAccessor: [`0x59AD6735bCd8152B84860Cb256dD9e96b85F69Da`](https://sepolia.scrollscan.com/address/0x59AD6735bCd8152B84860Cb256dD9e96b85F69Da)
256+
227257
### Additional Useful Contracts
228258

229259
- Multicall3: [`0xcA11bde05977b3631167028862bE2a173976CA11`](https://sepolia.scrollscan.com/address/0xcA11bde05977b3631167028862bE2a173976CA11)

0 commit comments

Comments
 (0)