Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 86 additions & 0 deletions .claude/commands/lint.md
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like the direction here, but we should consider what of this could be implemented with a deterministic linter that is run by a script.

We should be able to put instructions to run the linting script in this command or we could create a Skill to do this. This will help preserve context and improve linting outcomes (in the traditional sense of linting)

Then anything that can't be done by a traditional linter could be done by the LLM

Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# Lint MDX Documentation

Check MDX files for formatting, structure, and Mintlify component usage.

Reference `mintlify-reference.md` for correct component syntax.

## Scope

**By default, only check changed files:**
1. Run `git diff --name-only HEAD` to get uncommitted changes
2. Run `git diff --name-only master...HEAD` to include committed changes on this branch
3. Filter to only `.mdx` files in `docs/`

**If `$ARGUMENTS` is provided:**
- `all` — check all MDX files in `docs/`
- A specific path — check only that file/folder (e.g., `docs/api`)

## Steps

1. Determine which files to check (changed files, all, or specific path)
2. Check each file for the issues below
3. Report issues with file path and line number
4. Suggest fixes for each issue

## Checks to perform

### Frontmatter
- Every MDX file should have frontmatter with at least `title` and `description`
- Frontmatter must be valid YAML between `---` fences

### Heading structure
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It may also be good as a basic lint to include a check if no headers exist at all as header tags help SEO/LLM-SEO optimize so we should have at least one on every page, even if it is <h1 (ie, h3).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could also be a warning that we can choose not to enforce

- No skipped heading levels (e.g., h1 → h3)
- Only one h1 per page (or none if title is in frontmatter)

### Code blocks
- All code blocks must specify a language (```javascript not just ```)
- Code inside `<CodeGroup>` blocks should have both language AND label (```javascript Node.js)

### Mintlify components
Check for correct syntax on these components:

**Callouts** — must be self-closing or have content:
- `<Note>`, `<Tip>`, `<Warning>`, `<Info>`, `<Check>`

**Structural** — check for proper nesting:
- `<Steps>` must contain `<Step title="...">` children
- `<Tabs>` must contain `<Tab title="...">` children
- `<AccordionGroup>` must contain `<Accordion title="...">` children

**Cards** — check required attributes:
- `<Card>` should have `title` and `href`
- `<CardGroup>` should have `cols` attribute

**API docs** — check required attributes:
- `<ParamField>` needs `path|body|query|header`, `type`, and ideally `required` or `default`
- `<ResponseField>` needs `name` and `type`

**Media**:
- Images should be wrapped in `<Frame>`
- `<img>` tags should have `alt` attributes

### Common mistakes to flag
- Unclosed MDX components (e.g., `<Note>` without `</Note>`)
- Using HTML comments `<!-- -->` instead of MDX `{/* */}`
- Broken internal links (files that don't exist in docs/)
- Empty code blocks
- Components with typos (e.g., `<Warnings>` instead of `<Warning>`)

## Output format

```
## Lint Results

### Files checked
- 3 changed files (use `/lint all` to check entire docs/)

### ❌ Errors (must fix)
- `docs/getting-started.mdx:15` — Code block missing language specifier
- `docs/api/users.mdx:42` — Unclosed <Note> component

### ⚠️ Warnings (should fix)
- `docs/guides/auth.mdx:8` — Image not wrapped in <Frame>

### ✅ Summary
- 3 files checked, 2 errors, 1 warning
```
30 changes: 30 additions & 0 deletions claude.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Documentation Repository

## Stack
- Mintlify for documentation site
- MDX files in `docs/` folder
- Storybook for component demos

## Git
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this necessary? If I'm building a new page on a branch, does claude need to know the primary branch? I dont think so.

- Primary branch: `master`

## Key References
- `mintlify-reference.md` — Mintlify component syntax and usage
- `content-instructions.md` — Content guidelines
- `global-tone-voice.mdx` — Tone and voice standards
- `docs.json` — Site navigation and configuration

## Conventions
- Use American English spelling
- Sentence case for headings
- All images wrapped in `<Frame>`
- Code blocks must specify a language
- Use Mintlify callouts sparingly (`<Note>`, `<Tip>`, `<Warning>`, `<Info>`, `<Check>`)

## Commands
- `/lint` — Check MDX formatting and Mintlify component usage

## Before Committing
- Run `/lint` and fix any errors
- If removing docs, add redirects in `docs.json`
- Ensure all internal links are valid
4 changes: 2 additions & 2 deletions docs/base-chain/network-information/block-building.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ See the [Configuration Changelog](/base-chain/network-information/configuration-
Currently, blocks are built using [op-rbuilder](https://github.com/flashbots/op-rbuilder) and priority fee auctions occur
every 200ms. There are two changes from the vanilla ordering to be aware of:

##### Timing
#### Timing

Flashblocks are built every 200ms, each ordering a portion of the block. Unlike the current system where later-arriving transactions with higher priority fees can be placed at the top of the block, Flashblocks creates a time-based constraint. Once a Flashblock is built and broadcast, its transaction ordering is locked even if a transaction with a higher priority fee arrives later, it cannot be included in earlier, already built Flashblocks.

##### High Gas Limits
#### High Gas Limits

If your app creates transactions with large gas limits, we recommend monitoring to detect any changes in inclusion latency. Transactions with gas limits over 1/10 of the current block gas limit (currently 14 million gas), face additional constraints:

Expand Down
2 changes: 2 additions & 0 deletions docs/base-chain/network-information/transaction-finality.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ This describes finality for transactions on Base except withdrawal transactions

For transactions on Base, finality is not a single time to wait for. Instead, there are 4 stages in time that each provide increasing security guarantees.

<Frame>
![Diagram of transaction finality stages on Base](/images/transaction-finality/base-tx-finality.jpg)
</Frame>

<Steps>
<Step title="Flashblock Inclusion: ~200ms" titleSize="h3">
Expand Down
16 changes: 16 additions & 0 deletions docs/learn/hardhat/etherscan/etherscan-sbs.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ By the end of this lesson, you should be able to:

[Etherscan](https://etherscan.io) is a popular Blockchain explorer that works for several different networks. In it, you can explore the state and activity of a particular network.

<Frame>
![Etherscan](/images/learn/etherscan/etherscan-user-interface.png)
</Frame>

You can explore:

Expand All @@ -35,7 +37,9 @@ You can explore:

For instance, the following shows the details of a Block:

<Frame>
![Block](/images/learn/etherscan/blocks.png)
</Frame>

Where you see information such as:

Expand All @@ -56,7 +60,9 @@ One of the things you can do with Etherscan is interact with already-deployed co

For example, if you want to read information from a famous contract such as [BAYC](https://etherscan.io/token/0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d), you can simply go to Etherscan and explore the contract:

<Frame>
![BAYC](/images/learn/etherscan/bayc.png)
</Frame>

You are able to see information such as:

Expand All @@ -68,33 +74,43 @@ You are able to see information such as:

In the **Contract** tab, you can see the full source code of BAYC:

<Frame>
![BAYC Verified](/images/learn/etherscan/bayc-verified.png)
</Frame>

For a developer, verifying contracts is important since it gives transparency to your users. However, there are some risks because this means that bad actors can see the full source code and can try to exploit it.

In order to read the state of the BAYC, you can go to the main menu and select the option **Read Contract**:

<Frame>
![BAYC Read](/images/learn/etherscan/bayc-read.png)
</Frame>

After you select that option, you are able to see all of the read functions of the contract.

You can also query who is the owner of the BAYC with id 150:

<Frame>
![BAYC Query](/images/learn/etherscan/bayc-query.png)
</Frame>

## Writing data to smart contracts using Etherscan

In a similar fashion, you can read data from smart contracts using Etherscan. It is also possible to write data.

To write data, go to the **Write Contract** tab:

<Frame>
![Write Contract](/images/learn/etherscan/bayc-write.png)
</Frame>

From there, connect your wallet by clicking the **Connect with web3** button.

After you connect, the following UI appears:

<Frame>
![Write BAYC Connected](/images/learn/etherscan/bayc-write-connected.png)
</Frame>

You can then call the functions you wish to write to.

Expand Down
2 changes: 2 additions & 0 deletions docs/learn/hardhat/hardhat-deploy/hardhat-deploy-sbs.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,9 @@ npx hardhat deploy --network base_sepolia

After you run the command, a deployments folder appears with a newly-created deployment for `base_sepolia`:

<Frame>
![New deployment](/images/learn/hardhat-deploying/new-deploy.png)
</Frame>

If you want to deploy to another network, change the network name as follows:

Expand Down
2 changes: 2 additions & 0 deletions docs/learn/hardhat/hardhat-forking/hardhat-forking.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,9 @@ describe('BalanceReader tests', () => {

In this example, the [USDC address](https://etherscan.io/token/0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48) is used and since USDC is an ERC-20 token, you can explore the token holders of that particular token directly in Etherscan:

<Frame>
![Hardhat forking](/images/learn/hardhat-forking/hardhat-forking.png)
</Frame>

Or, visit https://etherscan.io/token/0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48#balances, where you can see, at the time or writing, Arbitrum ONE Gateway is the top token holder.

Expand Down
2 changes: 2 additions & 0 deletions docs/learn/hardhat/hardhat-testing/hardhat-testing-sbs.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,9 @@ it('should get the unlockTime value', async () => {

Notice how autocomplete appears after entering `lockInstance`:

<Frame>
![Auto complete](/images/learn/hardhat-testing/autocomplete-unlockTime.png)
</Frame>

You can simply run `npx hardhat test` and then get:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,9 @@ All files | 100 | 83.33 | 100 | 100 | |

Which then gives you a report of the test coverage of your test suite. Notice there is a new folder called `coverage`, which was generated by the `solidity-coverage` plugin. Inside the `coverage` folder there is a `index.html` file. Open it in a browser, you'll see a report similar to the following:

<Frame>
![Coverage report](/images/hardhat-test-coverage/coverage-report.png)
</Frame>

## Increasing test coverage

Expand Down
6 changes: 6 additions & 0 deletions docs/learn/hardhat/hardhat-verify/hardhat-verify-sbs.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ The way smart contracts are verified is by simply uploading the source code and

Once the contract is verified, the Etherscan explorer shows a status like the following image:

<Frame>
![Verified contract](https://github.com/base/web/blob/master/apps/base-docs/docs/public/images/learn/hardhat-verify/hardhat-verify.png)
</Frame>

Luckily, Hardhat and Hardhat-deploy already contain a built-in capability to do this task easily on your behalf.

Expand All @@ -44,7 +46,9 @@ In order to obtain an Etherscan API key, visit [Etherscan](https://etherscan.io/

Then, go to [https://etherscan.io/myapikey](https://etherscan.io/myapikey) and create an API key by clicking the **Add** button:

<Frame>
![Add key](https://github.com/base/web/blob/master/apps/base-docs/docs/public/images/learn/hardhat-verify/harhat-verify-create-key.png)
</Frame>

Bear in mind that different networks have other Blockchain explorers. For example:

Expand Down Expand Up @@ -96,7 +100,9 @@ waiting for result...

You can now go to Basescan and search for your contract address, where you'll see the following:

<Frame>
![Base scan success](/images/learn/hardhat-verify/hardhat-verify-success.png)
</Frame>

## Conclusion

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -229,21 +229,29 @@ Finally, run `yarn dev` and navigate to [http://localhost:3000] to see the start

Before exploring the code, test the app. First, you should see this login page:

<Frame>
![Privy Login Page](/images/account-abstraction/privy-login-page.png)
</Frame>

After clicking "Log in" you'll see the following modal:

<Frame>
![Privy Login Modal](/images/account-abstraction/privy-login-modal.png)
</Frame>

By default, you can login with a wallet, or email.

After logging in, you'll be redirected to the `/dashboard` page, where the demo app will allow you to connect a number of other accounts to your `user` object:

<Frame>
![Privy Dashboard Page](/images/account-abstraction/privy-dashboard-page.png)
</Frame>

If you navigate to [console.privy.io](https://console.privy.io/), you'll see that Privy stores all your users and their data here.

<Frame>
![Privy Console](/images/account-abstraction/privy-console.png)
</Frame>

### PrivyProvider

Expand Down Expand Up @@ -278,7 +286,9 @@ Add a `config` property to the `<PrivyProvider />` in `_app.jsx` with `'github'`

Refresh to see that authentication is only possible now through Github or SMS:

<Frame>
![Privy Login Methods](/images/account-abstraction/privy-login-methods.png)
</Frame>

You can find a full list of `loginMethods` in the docs for [`PrivyClientConfig`].

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,20 @@ In this section, you will configure a Paymaster to sponsor payments on behalf of

### Screenshots

- **Selecting your project**
- **Selecting your project**
<Frame>
![cdp-home.png](/images/gasless-transaction-on-base/cdp-select-project.png)
</Frame>

- **Navigating to the Paymaster tool**
- **Navigating to the Paymaster tool**
<Frame>
![cdp-paymaster-tool.png](/images/gasless-transaction-on-base/cdp-paymaster.png)
</Frame>

- **Configuration screen**
- **Configuration screen**
<Frame>
![cdp-paymaster-tool.png](/images/gasless-transaction-on-base/cdp-config.png)
</Frame>

### Allowlist a Sponsorable Contract

Expand All @@ -60,7 +66,9 @@ In this section, you will configure a Paymaster to sponsor payments on behalf of
3. Click **Add** to add an allowlisted contract.
4. For this example, add [`0x83bd615eb93eE1336acA53e185b03B54fF4A17e8`][simple NFT contract], and add the function `mintTo(address)`.

<Frame>
![cdp-allowlist-contracts.png](/images/gasless-transaction-on-base/cdp-allowlist-contract.png)
</Frame>

> **Use your own contract**
> We use a [simple NFT contract][simple NFT contract] on Base mainnet as an example. Feel free to substitute your own.
Expand All @@ -84,7 +92,9 @@ This means **each user** can only have \$0.05 in sponsored gas and **1** user op

Next, **Set the Global Limit**. For example, set this to `$0.07` so that once the entire paymaster has sponsored \$0.07 worth of gas (across all users), no more sponsorship occurs unless you raise the limit.

<Frame>
![cdp-global-user-limits.png](/images/gasless-transaction-on-base/cdp-global-user-limits.png)
</Frame>

## Test Your Paymaster Policy

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ You'll need to set up an account on with [Coinbase Developer Platform (CDP) Acco

If you see a "something went wrong" error message when navigating to pay.coinbase.com, make sure you have "enforce secure initialization" disabled on the [Onramp config page] in Coinbase Developer Platform Dashboard.

<Frame>
![fund-onramp-config](/images/onchainkit-tutorials/fund-onramp-config.png)
</Frame>
</Tip>

## Setting up the Project
Expand Down Expand Up @@ -113,7 +115,9 @@ Now that we know the user's balance, we can then have them mint an NFT or prompt

The end state is to show their balance along with the appropriate call to actions like so:

<Frame>
![fund-wallet](/images/onchainkit-tutorials/fund-wallet-balance.png)
</Frame>

Update your component's return statement with the following code:

Expand Down Expand Up @@ -146,7 +150,9 @@ return (

Sweet! Now our conditional rendering is in full force. If a user clicks on the `+ Add funds to transact` button they will be given three options for topping up their smart wallet:

<Frame>
![fund-wallet](/images/onchainkit-tutorials/fund-funding-options.png)
</Frame>

## Conclusion

Expand Down
Loading