Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
5642c69
feat: add configurable replacements
ericnordelo Sep 19, 2025
7b24bbe
Merge branch 'main' of https://github.com/OpenZeppelin/docs
ericnordelo Sep 19, 2025
8b87d1e
feat: add scripts
ericnordelo Sep 19, 2025
cd47e49
feat: add EOF
ericnordelo Sep 19, 2025
9a12d9e
feat: more fixes
ericnordelo Sep 19, 2025
6ab9c0c
fix: links in components
ericnordelo Sep 19, 2025
d14a3ab
feat: add a component for github link headers
ericnordelo Sep 19, 2025
046c616
feat: format files
ericnordelo Sep 19, 2025
2aa2899
fix: components
ericnordelo Sep 19, 2025
fc66940
fix: presets
ericnordelo Sep 19, 2025
532fa66
fix: interfaces and dispatchers
ericnordelo Sep 19, 2025
e87ddd3
fix: snip12 guide
ericnordelo Sep 19, 2025
3b7fb0a
remove: src5-migration guide
ericnordelo Sep 19, 2025
dd253a7
fix: erc20-permit
ericnordelo Sep 19, 2025
18c4aae
fix: links
ericnordelo Sep 19, 2025
cee85c5
fix: interfaces page
ericnordelo Sep 19, 2025
1f015a1
feat: set learn folder opened by default
ericnordelo Sep 19, 2025
383aaaa
fix: update pnpm yaml
ericnordelo Sep 22, 2025
b922ce7
fix: underscore
ericnordelo Sep 22, 2025
e087b59
feat: add dependency
ericnordelo Sep 22, 2025
e9ef093
fix: linter
ericnordelo Sep 22, 2025
2b0f83e
fix: access
ericnordelo Sep 22, 2025
f76bcbc
fix: account
ericnordelo Sep 22, 2025
b367a88
fix: code segments
ericnordelo Sep 22, 2025
b0166a8
fix: finance
ericnordelo Sep 22, 2025
4a9769e
fix: governor
ericnordelo Sep 22, 2025
f9bb9f0
fix: multisig
ericnordelo Sep 22, 2025
4d791b5
fix: timelock
ericnordelo Sep 22, 2025
cc6377e
fix: votes
ericnordelo Sep 22, 2025
b637749
fix: introspection
ericnordelo Sep 22, 2025
4311de9
fix: macros
ericnordelo Sep 22, 2025
b9b8b11
fix: erc20
ericnordelo Sep 22, 2025
65f6606
fix: erc721
ericnordelo Sep 22, 2025
af20fb9
fix: erc1155
ericnordelo Sep 22, 2025
0f1a99d
fix: erc4626
ericnordelo Sep 22, 2025
b109032
fix: math
ericnordelo Sep 22, 2025
8405129
fix: udc
ericnordelo Sep 22, 2025
5aef9e7
fix: upgrades
ericnordelo Sep 22, 2025
0f31b6f
fix: bc
ericnordelo Sep 22, 2025
442a28b
fix: account api
ericnordelo Sep 22, 2025
4d4a60c
fix: erc20 api
ericnordelo Sep 22, 2025
b829985
fix: erc721
ericnordelo Sep 22, 2025
793abfc
fix: finance api
ericnordelo Sep 22, 2025
e7aec49
fix: governance api
ericnordelo Sep 22, 2025
c4c4b32
fix: merkle-tree
ericnordelo Sep 22, 2025
fcc7965
fix: token common
ericnordelo Sep 22, 2025
ea97298
fix: udc
ericnordelo Sep 22, 2025
11c6f98
fix: utilities
ericnordelo Sep 22, 2025
6b424f4
fix: utilities
ericnordelo Sep 22, 2025
2cbe7ac
fix: broken links
ericnordelo Sep 22, 2025
4567300
chore: bumped action checkout verison
stevedylandev Sep 22, 2025
b8c16d4
chore: updated constants.ts to use .js file extension, updates file r…
stevedylandev Sep 22, 2025
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
4 changes: 0 additions & 4 deletions content/contracts-cairo/1.0.0/utils/_class_hashes.mdx

This file was deleted.

4 changes: 0 additions & 4 deletions content/contracts-cairo/1.0.0/utils/_common.mdx

This file was deleted.

10 changes: 10 additions & 0 deletions content/contracts-cairo/api/testing.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
title: Testing
---

<Callout type='info'>
The `openzeppelin_testing` package version is now decoupled from the `cairo-contracts` version.
</Callout>

You can find the documentation for the `openzeppelin_testing` package in the README for the corresponding version in the
[scarb registry](https://scarbs.xyz/packages/openzeppelin_testing).
67 changes: 32 additions & 35 deletions content/contracts-cairo/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,23 @@
title: Contracts for Cairo
---

**A library for secure smart contract development** written in Cairo for [Starknet](https://starkware.co/product/starknet/). This library consists of a set of [reusable components](components) to build custom smart contracts, as well as
ready-to-deploy [presets](presets). You can also find other [utilities](/api/utilities) including [interfaces and dispatchers](interfaces) and [test utilities](/api/testing)
that facilitate testing with Starknet Foundry.
[starknet]:https://starkware.co/product/starknet/
[scarb]:https://docs.swmansion.com/scarb/
[scarb-install]:https://docs.swmansion.com/scarb/download.html

<Callout type='warn'>
This repo contains highly experimental code. Expect rapid iteration. **Use at your own risk.**
</Callout>

**A library for secure smart contract development** written in Cairo for [Starknet][starknet]. This library consists of a set of
[reusable components](/cairo-contracts/components) to build custom smart contracts, as well as ready-to-deploy [presets](/cairo-contracts/presets). You can also
find other [utilities](/cairo-contracts/api/utilities) including [interfaces and dispatchers](/cairo-contracts/interfaces) and [test utilities](/cairo-contracts/api/testing)
that facilitate testing with Starknet Foundry.

<Callout>
You can track our roadmap and future milestones in our [Github Project](https://github.com/orgs/OpenZeppelin/projects/29/).
</Callout>

## Installation

The library is available as a [Scarb](https://docs.swmansion.com/scarb) package. Follow [this guide](https://docs.swmansion.com/scarb/download.html) for installing Cairo and Scarb on your machine
The library is available as a [Scarb][scarb] package. Follow [this guide][scarb-install] for installing Cairo and Scarb on your machine
before proceeding, and run the following command to check that the installation was successful:

```bash
Expand Down Expand Up @@ -51,18 +53,13 @@ Scarb.toml src

### Install the library

<Callout type='warn'>
<Callout type='info'>

The `openzeppelin` package is an umbrella (meta) package that aggregates all library subpackages. Prior to v3.x, the umbrella and its subpackages were
versioned in lockstep—their versions always matched. Starting with v3.x, following the introduction of `openzeppelin_interfaces`, the umbrella is
versioned independently from some of the subpackages.

The `openzeppelin` package is an umbrella package that includes all the packages in the library.
Before version `3.x.x`, the `openzeppelin` and its sub-packages
were versioned together meaning that the version of the `openzeppelin`
package was the same as the version of the sub-packages.

Starting from version `3.x.x`, with the introduction of the `openzeppelin_interfaces` package,
the `openzeppelin` package is versioned independently from the sub-packages.

See the [Versioning of the sub-packages](index#versioning_of_the_sub_packages) section for more information.
See the [Versioning of the sub-packages](/cairo-contracts#versioning-of-the-sub-packages) section for more information.

</Callout>

Expand All @@ -76,11 +73,11 @@ openzeppelin = "3.0.0-alpha.2"
The previous example would import the entire library. We can also add each package as a separate dependency to
improve the building time by not including modules that won’t be used:

```javascript
```toml
[dependencies]
openzeppelin_access = "3.0.0-alpha.2"
openzeppelin_token = "3.0.0-alpha.2"
openzeppelin_interfaces = "1.0.0"
openzeppelin_access = "3.0.0-alpha.1"
openzeppelin_token = "3.0.0-alpha.1"
openzeppelin_interfaces = "{{openzeppelin_interfaces_version}}"
Comment thread
stevedylandev marked this conversation as resolved.
```

## Versioning of the sub-packages
Expand All @@ -89,20 +86,20 @@ Here you can find a reference of the versioning of the sub-packages for this umb

```javascript
[dependencies]
openzeppelin_access = "3.0.0-alpha.2"
openzeppelin_token = "3.0.0-alpha.2"
openzeppelin_access = "3.0.0-alpha.2"
openzeppelin_account = "3.0.0-alpha.2"
openzeppelin_finance = "3.0.0-alpha.2"
openzeppelin_interfaces = "1.0.0"
openzeppelin_governance = "3.0.0-alpha.2"
openzeppelin_introspection = "3.0.0-alpha.2"
openzeppelin_merkle_tree = "3.0.0-alpha.2"
openzeppelin_presets = "3.0.0-alpha.2"
openzeppelin_security = "3.0.0-alpha.2"
openzeppelin_token = "3.0.0-alpha.2"
openzeppelin_upgrades = "3.0.0-alpha.2"
openzeppelin_utils = "3.0.0-alpha.2"
openzeppelin_access = "3.0.0-alpha.1"
openzeppelin_token = "3.0.0-alpha.1"
openzeppelin_access = "3.0.0-alpha.1"
openzeppelin_account = "3.0.0-alpha.1"
openzeppelin_finance = "3.0.0-alpha.1"
openzeppelin_interfaces = "{{openzeppelin_interfaces_version}}"
openzeppelin_governance = "3.0.0-alpha.1"
openzeppelin_introspection = "3.0.0-alpha.1"
openzeppelin_merkle_tree = "3.0.0-alpha.1"
openzeppelin_presets = "3.0.0-alpha.1"
openzeppelin_security = "3.0.0-alpha.1"
openzeppelin_token = "3.0.0-alpha.1"
openzeppelin_upgrades = "3.0.0-alpha.1"
openzeppelin_utils = "{{openzeppelin_utils_version}}"
```

## Basic usage
Expand Down
4 changes: 0 additions & 4 deletions content/contracts-cairo/utils/_class_hashes.mdx

This file was deleted.

4 changes: 0 additions & 4 deletions content/contracts-cairo/utils/_common.mdx

This file was deleted.

3 changes: 3 additions & 0 deletions content/contracts-cairo/utils/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const OPENZEPPELIN_INTERFACES_VERSION = "2.1.0-alpha.0";
export const OPENZEPPELIN_UTILS_VERSION = "3.1.0-alpha.0";
export const UMBRELLA_VERSION = "3.0.0-alpha.2";
10 changes: 10 additions & 0 deletions content/contracts-cairo/utils/replacements.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { OPENZEPPELIN_INTERFACES_VERSION, OPENZEPPELIN_UTILS_VERSION, UMBRELLA_VERSION } from "./constants";

export const REPLACEMENTS = {
include: ['**/content/contracts-cairo/**/*.mdx'],
replacements: {
umbrella_version: UMBRELLA_VERSION,
openzeppelin_interfaces_version: OPENZEPPELIN_INTERFACES_VERSION,
openzeppelin_utils_version: OPENZEPPELIN_UTILS_VERSION,
}
}
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@
"katex": "^0.16.22",
"lucide-react": "^0.540.0",
"mermaid": "^11.11.0",
"next": "15.4.5",
"micromatch": "^4.0.8",
"next": "^15.5.3",
"next-themes": "^0.4.6",
"react": "^19.1.1",
"react-dom": "^19.1.1",
Expand All @@ -52,6 +53,7 @@
"@tailwindcss/postcss": "^4.1.13",
"@tanstack/react-query-devtools": "^5.89.0",
"@types/mdx": "^2.0.13",
"@types/micromatch": "^4.0.9",
"@types/node": "24.1.0",
"@types/react": "^19.1.12",
"@types/react-dom": "^19.1.9",
Expand Down
11 changes: 10 additions & 1 deletion source.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { defineConfig, defineDocs } from "fumadocs-mdx/config";
import remarkMath from "remark-math";
import rehypeKatex from "rehype-katex";
import { remarkMdxMermaid } from "fumadocs-core/mdx-plugins";
import remarkReplace from "@/lib/remark-replace";
import { REPLACEMENTS as cairoContractReplacements } from "content/contracts-cairo/utils/replacements";

// You can customise Zod schemas for frontmatter and `meta.json` here
// see https://fumadocs.vercel.app/docs/mdx/collections#define-docs
Expand All @@ -25,7 +27,14 @@ export default defineConfig({
dark: "github-dark",
},
},
remarkPlugins: [remarkMath, remarkMdxMermaid],
remarkPlugins: [remarkMath, remarkMdxMermaid,
[
remarkReplace,
[
cairoContractReplacements,
]
],
],
rehypePlugins: (v) => [rehypeKatex, ...v],
},
});
102 changes: 102 additions & 0 deletions src/lib/remark-replace.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import { visit } from "unist-util-visit";
import micromatch from "micromatch";

/**
* A replacement rule applied to MDX/Markdown files.
*
* - Use `include` to match files via glob(s).
* - Or use `includeFn` for custom logic (receives the normalized file path or undefined).
* - `replacements` maps placeholders like `{{key}}` → "value".
* - If `exclusive` is true, the first matching rule stops further replacements for that node.
*/
export type Rule = {
include?: string | string[];
includeFn?: (info: { path?: string }) => boolean;
replacements: Record<string, string>;
exclusive?: boolean;
};

/**
* Multi-rule remark plugin to replace placeholders in text, inlineCode and code blocks.
*
* Placeholders are written as `{{key}}` and replaced with the corresponding string
* from the active rule's `replacements` map.
*
* Safe defaults:
* - If `file.path` is missing (virtual content), rules are considered active unless
* their `includeFn` explicitly returns false.
* - Empty/whitespace patterns are ignored; if no valid patterns are left,
* the rule falls back to "match all".
*
* Example usage (Fumadocs / MDX config):
*
* import { defineConfig } from "fumadocs-mdx/config";
* import remarkReplaceMulti, { Rule } from "@/lib/remark-replace-multi";
*
* const rules: Rule[] = [
* { include: "content/docs/**", replacements: { version: "3.0.0", api: "/docs/api" }, exclusive: true },
* { include: "content/guides/**", replacements: { version: "2.2.0", api: "/guides/api" }, exclusive: true },
* ];
*
* export default defineConfig({
* mdxOptions: {
* remarkPlugins: (prev) => [[remarkReplaceMulti, rules], ...prev],
* },
* });
*/
export default function remarkReplaceMulti(rules: Rule[]) {
// --- helpers ---------------------------------------------------------------

/** Normalize vfile path (may be missing in virtual files). */
const getPath = (file?: any): string | undefined => {
const raw =
(typeof file?.path === "string" && file.path) ||
(Array.isArray(file?.history) && file.history[0]) ||
undefined;
return raw ? raw.replace(/\\/g, "/") : undefined;
};

/** Turn include into a clean, non-empty patterns array (or ["** /*"]). */
const toPatterns = (include?: string | string[]): string[] => {
const arr = Array.isArray(include) ? include : include ? [include] : [];
const cleaned = arr.map((p) => p.trim()).filter((p) => p.length > 0);
return cleaned.length ? cleaned : ["**/*"];
};

/** Does this rule apply to the given file path? */
const isRuleActive = (rule: Rule, path?: string): boolean => {
if (rule.includeFn) return rule.includeFn({ path });
// If we don't have a path, default to active (virtual files).
if (!path) return true;
return micromatch.isMatch(path, toPatterns(rule.include));
};

/** Replace all `{{key}}` with values from `map`. */
const replaceAll = (input: string, map: Record<string, string>): string => {
let out = input;
for (const [k, v] of Object.entries(map)) {
out = out.split(`{{${k}}}`).join(String(v));
}
return out;
};

// --- plugin ---------------------------------------------------------------

return (tree: any, file?: any) => {
const path = getPath(file);

// Collect rules that apply to this file.
const active = rules.filter((r) => isRuleActive(r, path));
if (active.length === 0) return;

// Apply replacements to text & code nodes.
visit(tree, ["text", "inlineCode", "code"], (node: any) => {
if (typeof node.value !== "string") return;

for (const rule of active) {
node.value = replaceAll(node.value, rule.replacements);
if (rule.exclusive) break; // stop after first exclusive rule
}
});
};
}
5 changes: 5 additions & 0 deletions src/navigation/starknet.json
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,11 @@
"name": "Token Common",
"url": "/contracts-cairo/api/token_common"
},
{
"type": "page",
"name": "Testing",
"url": "/contracts-cairo/api/testing"
},
{
"type": "page",
"name": "UDC",
Expand Down
Loading