From 68b55481242245aac1c85f920ffdfe3acddf8619 Mon Sep 17 00:00:00 2001 From: Sahil Aujla Date: Fri, 6 Mar 2026 11:17:30 -0500 Subject: [PATCH 1/7] Rewrite docs style guide --- STYLE_RULES.md | 425 ++++++++++++++++++++++++++++++++++--------------- 1 file changed, 298 insertions(+), 127 deletions(-) diff --git a/STYLE_RULES.md b/STYLE_RULES.md index 0d6d03b38..cc2230c08 100644 --- a/STYLE_RULES.md +++ b/STYLE_RULES.md @@ -1,188 +1,359 @@ -# Alchemy docs style rules +# Alchemy docs style guide -These rules govern all written documentation in this repository — MDX pages, -API spec descriptions, changelog entries, and code sample comments. +This guide explains how we write docs in this repository. It covers MDX pages, API descriptions, changelog entries, and code sample comments. -Both human contributors and AI agents follow these rules. Each rule is a -pass/fail check. If a rule has an EXCEPTION, apply the exception only when -the stated condition is true. +Use it for editorial decisions: voice, structure, terminology, and examples. For MDX syntax and components, see [MDX_FEATURES.md](./MDX_FEATURES.md). For repo setup and contribution workflow, see [CONTRIBUTING.md](./CONTRIBUTING.md). -*** +## Agent quick rules -## VOICE +Use this section as the fast path when you are writing or editing docs with an AI agent. -RULE: Use "we" when referring to Alchemy. Never write "Alchemy" as a third-person subject. -✅ "We support 80+ chains" -❌ "Alchemy supports 80+ chains" -EXCEPTION: First sentence of a landing page or meta description may use "Alchemy" once for SEO, then switch to "we." +Required: -RULE: Use "you" when addressing the reader. Never use "the developer", "the user", "users", or "one." -✅ "You can create an API key from the dashboard" -❌ "The developer can create an API key from the dashboard" -❌ "Users should deploy their contract" +* Use `you` for the reader +* Prefer `we` for Alchemy in prose +* Use sentence case headings +* Prefer the `Steps` and `Step` components for ordered MDX procedures +* Use descriptive link text +* Use the preferred terminology table exactly +* Use JavaScript or TypeScript for authored examples unless the page has a stronger existing convention +* Put changelog updates under product-area headings and place `Node` after more user-facing sections when both are present +* Use `Updates` for launches, availability changes, deprecations, and behavior changes +* Use `Upgrades` for version bumps and maintenance entries +* Do not hand-edit generated API reference output; update the source specs instead -RULE: Use contractions. "you'll", "we've", "don't", "isn't." -❌ "You will need to configure" → ✅ "You'll need to configure" +Preferred: -RULE: Never use "simply", "just", "easy", "easily", or "obviously." -❌ "Simply call the endpoint" -✅ "Call the endpoint" +* Open with the reader outcome, not background context +* Keep procedural steps action-oriented and move explanation into separate sections +* Make examples copy-pasteable +* Show expected output when success is not obvious +* Use cURL when showing raw request structure or quick command-line testing +* Keep changelog bullets to one distinct change each -RULE: Cut filler phrases. -❌ "In order to" → ✅ "To" -❌ "It is important to note that" → DELETE -❌ "As a matter of fact" → DELETE -❌ "Basically" → DELETE +Avoid: -RULE: Do not over-explain general programming concepts (HTTP requests, loops, variables, JSON parsing). Do explain blockchain-specific and Alchemy-specific concepts. +* Writing in terms of "the user", "users", or "the developer" +* Promotional or filler-heavy phrasing +* Vague headings such as `Overview`, `Usage`, or `Details` +* Repeating the same link throughout a section without a reason +* Overusing callouts -*** +If a default conflicts with clarity, choose clarity and preserve the repo's existing patterns. -## FORMATTING +## What good docs do -RULE: Headings use sentence case. Capitalize only the first word and proper nouns. -✅ "Get started with the SDK" -✅ "Send your first transaction" -❌ "Get Started With The SDK" -❌ "Send Your First Transaction" +Good docs help a reader make progress without making them slow down to decode our writing. In practice, that means: -RULE: No emojis in headings. -❌ "📋 Steps to get started" -✅ "Steps to get started" +* They start with the outcome, not the background +* They sound direct and competent, not promotional +* They use product and protocol terms consistently +* They show working examples, not idealized pseudocode +* They make the next step obvious -RULE: Headings describe what the reader will DO, not just label a topic. -✅ "Send your first transaction" -❌ "Transactions" +## How to use this guide -RULE: Never skip heading levels. H2 → H3 → H4. Never H2 → H4. +Treat these as strong defaults, not blind rules. -RULE: Numbered lists ONLY for sequential steps. Use bullet lists for non-ordered items. +Interpret these labels consistently: -RULE: All list items in a single list must have parallel structure. If one starts with a verb, all start with a verb. -✅ "Create an app", "Configure the SDK", "Send a request" -❌ "Create an app", "SDK configuration", "Sending a request" +* `Required` means agents and contributors should follow the rule unless an existing repo constraint prevents it +* `Preferred` means use this by default, but it can be overridden for clarity or local context +* `Avoid` means do not do this unless there is a specific reason -*** +Some choices in this repo are enforced by tooling such as Prettier, ESLint, and markdown linting. This guide should not duplicate those checks. It should cover the places where judgment matters: what to say, how to organize it, and how much to explain. -## TERMINOLOGY +When a rule hurts clarity, choose clarity. When you break a default, do it intentionally. -These are the ONLY correct forms. Flag any deviation. +## Voice and tone -| Correct | Incorrect (flag these) | -|---------|----------------------| -| API key | api key, API Key, apikey, Api Key | -| Alchemy SDK | alchemy SDK, Alchemy sdk | -| Alchemy Dashboard | dashboard (as product name), the Dashboard | -| JSON-RPC | json-rpc, JSONRPC, Json-RPC | -| webhook | Webhook (mid-sentence), web hook, web-hook | -| smart contract | Smart Contract (mid-sentence) | -| dApp | dapp, Dapp, DApp | -| onchain | on-chain, on chain | -| offchain | off-chain, off chain | -| mainnet | Mainnet (mid-sentence), main net, main-net | -| testnet | Testnet (mid-sentence), test net, test-net | -| WebSocket | Websocket, websocketb Socket | -| ERC-20 | ERC20, erc-20 | -| ERC-721 | ERC721, erc-721 | -| ERC-4337 | ERC4337, erc-4337 | -| gas fees | Gas Fees, Gas fees (mid-sentence) | +Write like a capable teammate helping another developer ship. + +### Address the reader directly + +Use `you` for the reader. + +Prefer: + +* "You can create an API key in the Alchemy Dashboard." +* "If you already have a contract deployed, skip this step." + +Avoid: + +* "The developer can create an API key..." +* "Users should..." +* "One can..." + +### Refer to Alchemy consistently + +Use `we` when speaking on behalf of Alchemy in explanatory prose. + +Prefer: + +* "We support 80+ chains." +* "We recommend using webhooks when you need near real-time updates." + +Allow "Alchemy" as the subject when it improves scanning, branding, or SEO, especially in intros, titles, and overview copy. Do not force awkward rewrites to avoid the company name. + +### Keep the tone direct + +Prefer short, declarative sentences. Contractions are fine when they sound natural. + +Prefer: + +* "You'll need an API key before you can send requests." +* "This endpoint returns token balances for an address." + +Avoid filler and softening language that reduces precision: + +* `simply` +* `just` +* `easy` +* `easily` +* `obviously` +* `basically` +* `it is important to note` +* `in order to` + +### Explain the right things + +Explain what is specific to Alchemy, blockchain workflows, or the product surface the reader is using. + +Do not spend paragraphs reteaching general programming concepts unless the page is explicitly for beginners and the extra context is necessary to complete the task. + +## Structure pages around reader intent + +Organize content around what the reader is trying to do, not around how we think about the product internally. + +### Open with the outcome + +The first screen should answer at least one of these questions: + +* What will I do here? +* What will I get when I finish? +* Is this the right page for my problem? + +### Separate action from explanation + +Keep step-by-step instructions focused on actions. Put conceptual background in a separate section such as `How it works`, `Why this matters`, or `Before you begin`. + +This keeps procedural content scannable and makes conceptual sections easier to revisit later. + +### Write headings that help people scan + +Use sentence case. + +Prefer headings that describe an action, question, or concrete topic: + +* `Send your first request` +* `Check whether the webhook was delivered` +* `Choose a supported network` + +Avoid vague labels: + +* `Overview` +* `Usage` +* `Details` +* `Miscellaneous` -RULE: Capitalize chain names always: Ethereum, Solana, Polygon, Arbitrum, Base, Optimism. +Do not skip heading levels. -RULE: Use "endpoint" not "route" or "URL" for API endpoints. +## Content patterns by page type -RULE: Use "request" and "response" not "call" and "return" in API context. +### Tutorials and quickstarts -RULE: Use "parameter" not "param" in prose. "param" is acceptable only in code. +Tutorials should help the reader reach a concrete outcome with minimal ambiguity. -RULE: First use of any acronym must be spelled out: "Externally Owned Account (EOA)." After that, use the acronym only. +Default structure: -*** +1. What the reader will build, learn, or finish +2. Prerequisites +3. Ordered steps +4. Verification +5. Next steps -## CODE SAMPLES +Guidelines: -RULE: Every code sample must be runnable when the reader substitutes their own API key. No pseudocode in tutorials unless explicitly labeled "pseudocode." +* In MDX tutorials, prefer the `Steps` and `Step` components for ordered procedures +* Make each step produce a visible result +* Show expected output after commands when verification is not obvious +* Keep conceptual detours out of the main path -RULE: Every code sample must include error handling (try/catch or equivalent). -❌ Bare `fetch()` with no error handling -✅ `fetch()` wrapped in try/catch with response status check +### Changelog entries + +Changelog entries should answer three questions quickly: + +* What changed? +* Who does it matter to? +* What should the reader do next, if anything? + +Lead with the change, then the impact. + +Default structure: + +* Group updates under product-area headings such as `Developer Experience`, `Wallets`, `Rollups`, `Data`, and `Node` +* Skip sections that have no meaningful updates that week +* Put `Node` after product-facing sections when both are present, so infrastructure upgrades do not bury more user-visible changes +* Use short bolded subheads only when they improve scanability, such as `Docs`, `Dashboard`, `Updates`, and `Upgrades` + +Guidelines: + +* Keep one distinct change per bullet +* Start each bullet with the shipped change, then add the impact or context +* Use `Updates` for launches, availability changes, deprecations, or behavior changes +* Use `Upgrades` for version bumps and network-level maintenance +* In `Node` upgrade lists, use the pattern `Network: Component version, Component version` +* Link the first relevant product, doc page, or release note when it helps the reader verify the change +* Use a top-of-entry callout only for exceptional notices such as shutdowns, migrations, or time-sensitive deprecations +* Keep the tone factual. Changelog entries should read like release notes, not marketing copy + +## Formatting defaults + +These are editorial defaults for readability. Tooling may already enforce some of them. + +### Lists + +In MDX pages, prefer the `Steps` and `Step` components for step-by-step procedures. Use numbered lists when a lighter-weight ordered sequence is enough. + +Use bullets for sets, options, and grouped facts. + +Keep list items parallel. If one item starts with a verb, the others should too. + +### Code formatting + +Use inline code for: + +* Method names +* Parameter names +* File names and paths +* Commands +* Config values +* Technical identifiers + +Do not use inline code for normal prose or product names unless you are referring to a literal UI label or string value. + +### Links + +Write descriptive link text. The reader should know where a link goes before clicking it. + +Prefer: + +* "See the [Admin API overview](/docs/reference/admin-api/overview)." + +Avoid: + +* "Click [here](/docs/reference/admin-api/overview)." + +Link a repeated concept once per section unless the repeated link materially improves navigation. + +### Callouts + +Use callouts to highlight information the reader is likely to miss in body text. + +Preferred defaults: + +* `Note` for extra context +* `Tip` for shortcuts or best practices +* `Warning` for likely mistakes or surprising behavior +* `Check` or `Success` for verification and completion states + +Use callouts sparingly. If a page needs a warning box every few paragraphs, the body copy probably needs to be clearer. + +## Terminology and naming + +Use consistent terms across docs, code comments, and examples. + +### Preferred forms + +| Preferred | Avoid | +| --- | --- | +| API key | api key, apikey, API Key | +| Alchemy SDK | alchemy SDK, Alchemy sdk | +| Alchemy Dashboard | dashboard, Dashboard | +| JSON-RPC | JSONRPC, json-rpc | +| webhook | Webhook in the middle of a sentence | +| smart contract | Smart Contract in the middle of a sentence | +| dApp | dapp, DApp | +| onchain | on-chain, on chain | +| offchain | off-chain, off chain | +| mainnet | Mainnet in the middle of a sentence | +| testnet | Testnet in the middle of a sentence | +| WebSocket | websocket, Websocket | +| ERC-20 | ERC20 | +| ERC-721 | ERC721 | +| ERC-4337 | ERC4337 | -RULE: Use `{apiKey}` as the API key placeholder. -❌ YOUR\_API\_KEY, \, API\_KEY +Additional defaults: -RULE: Use realistic values in examples. Real block numbers, real testnet addresses, real method names. -❌ `0x0000000000000000000000000000000000000000` +* Capitalize chain and network names such as `Ethereum`, `Polygon`, `Solana`, `Arbitrum`, `Base`, and `Optimism` +* Use `parameter` in prose instead of `param` +* Spell out an acronym on first use when the audience might not know it -RULE: Every request example must be followed by an example response. +## Code samples and examples -RULE: Use fenced code blocks with language identifiers: \`\`\`javascript\`\`\`, \`\`\`bash\`\`\`, \`\`\`json\`\`\`, \`\`\`python\`\`\`, \`\`\`solidity\`\`\`. +Examples should help the reader succeed on the first attempt. -RULE: Use inline code for: method names, parameter names, file names, terminal commands, values, technical chain references. -✅ "Call `eth_getBlockByNumber`" -✅ "Set the `network` parameter" -❌ Do NOT use inline code for product names ("Alchemy SDK" not "`Alchemy SDK`") +### Make examples runnable -RULE: Multi-language code sample order: JavaScript/TypeScript → Python → cURL. Always include cURL on API reference pages. +Prefer examples that work when the reader swaps in their own credentials or addresses. -*** +If a sample is illustrative rather than runnable, label it clearly. -## LINKS +### Use realistic values -RULE: Link text must describe the destination. -✅ "See the [quickstart guide](/docs/alchemy-quickstart-guide)" -❌ "Click [here](/docs/alchemy-quickstart-guide)" +Use values that resemble real usage. Avoid placeholder data that teaches bad habits or hides important structure. -RULE: Internal docs links use relative paths: `/docs/...` not full URLs. -RULE: Link a term only on its first mention per section. Do not repeat-link the same destination within the same section. +Prefer: -*** +* Real method names +* Plausible addresses and block numbers +* Copy-pasteable commands -## API REFERENCE PAGE STRUCTURE +Be careful with secrets, costs, and destructive actions. In those cases, a placeholder is better than a misleading real value. -Every API endpoint page must contain these sections in this order: +### Show failure paths when they matter -1. Method name as title -2. One-line description of what it does -3. Parameters table (columns: Parameter, Type, Required, Description) -4. Request example (cURL + SDK) -5. Response example (full JSON, annotate non-obvious fields) -6. Error codes (common errors and causes) +Include error handling in tutorials and SDK examples when failures are part of the normal integration path. -Missing any section = flag as incomplete. +Not every short reference snippet needs full defensive scaffolding. Favor the amount of error handling that teaches the reader what they are likely to need in practice. -*** +### Choose language examples intentionally -## TUTORIAL STRUCTURE +Default to the language mix that matches the page type and audience. -Every tutorial must contain these sections in this order: +In most cases: -1. What you'll build/learn (1 paragraph, set expectations) -2. Prerequisites (tools, accounts, knowledge needed) -3. Numbered steps (each step produces a verifiable result) -4. Verify it works (concrete confirmation step) -5. Next steps (links to related guides) +* JavaScript or TypeScript works well for tutorials, SDK-led workflows, server-side examples, and data workflows +* cURL is useful when showing raw request structure or quick command-line testing -RULE: Do not mix conceptual explanation into step-by-step instructions. Use a separate "How it works" section or a callout. +Only include multiple languages when the extra examples add real value. Three shallow examples are often worse than one strong example. -RULE: Include expected output after every command or code execution step. +## Repo-specific notes -*** +This repo contains more than long-form docs. The same editorial standards apply across formats, but the implementation details differ: -## CALLOUTS +* `content/` contains MDX pages +* `src/openapi/` contains REST API definitions +* `src/openrpc/` contains JSON-RPC definitions -RULE: Use only these four callout types: +When writing MDX: -* **Note** — additional context, not critical -* **Tip** — shortcut or best practice -* **Warning** — could cause errors or unexpected behavior -* **Danger** — could cause data loss, security issues, or cost money +* Follow this guide for voice, structure, and examples +* Use [MDX_FEATURES.md](./MDX_FEATURES.md) for component syntax and supported patterns -RULE: Max 3 callouts per page. If you need more, the body text is missing information. +When writing API specs: -*** +* Keep descriptions concise and user-facing +* Use consistent terminology with the docs +* Avoid repeating the same explanation across every field when a higher-level description would be clearer -## DEPRECATION +## Review checklist -RULE: Never delete docs for deprecated features. Add a deprecation notice at the top with: date, what replaces it, and migration path. +Before publishing, check: -RULE: Changelog entries follow: **\[Product] — What changed — Why it matters to you.** +* Can the reader tell what this page helps them do within the first few lines? +* Are prerequisites explicit? +* Do the headings scan well on their own? +* Are examples copy-pasteable or clearly labeled when they are not? +* Are product names, protocols, and terms consistent with house style? +* Does the page show how to verify success or what to do next? From 51853be0d91a7a1780d039e589ead3a33b0368e1 Mon Sep 17 00:00:00 2001 From: Sahil Aujla Date: Fri, 6 Mar 2026 11:53:18 -0500 Subject: [PATCH 2/7] Add style guide eval set tutorials --- .../how-to-use-api-keys-in-http-headers.mdx | 311 ++++++------------ .../getting-started/create-an-api-key.mdx | 104 +++--- .../make-your-first-request.mdx | 68 ++-- ...status-of-a-transaction-using-its-hash.mdx | 247 +++++--------- 4 files changed, 276 insertions(+), 454 deletions(-) diff --git a/content/tutorials/getting-started/api-security-and-authentication/how-to-use-api-keys-in-http-headers.mdx b/content/tutorials/getting-started/api-security-and-authentication/how-to-use-api-keys-in-http-headers.mdx index bed5c28ce..9fca8957a 100644 --- a/content/tutorials/getting-started/api-security-and-authentication/how-to-use-api-keys-in-http-headers.mdx +++ b/content/tutorials/getting-started/api-security-and-authentication/how-to-use-api-keys-in-http-headers.mdx @@ -1,250 +1,135 @@ --- -title: How To Make HTTP Header-Based API Requests -description: Learn how to use your Alchemy API keys in HTTP headers for enhanced security when calling blockchain APIs -subtitle: Learn how to use your Alchemy API keys in HTTP headers for enhanced security when calling blockchain APIs +title: How to make HTTP header-based API requests +description: Send Alchemy API requests with your API key in the Authorization header instead of the URL. +subtitle: Send Alchemy API requests with your API key in the Authorization header instead of the URL. slug: docs/how-to-use-api-keys-in-http-headers --- -## Introduction +This guide shows you how to keep your Alchemy API key out of the request URL +and send it in the `Authorization` header instead. You will make one JSON-RPC +request and one NFT API request using Node.js. -When working with RPC providers, including API keys directly in the request URL is a common practice but this is a security risk as the keys are exposed in server logs, browser history, and cached data. This goes against the best practice of putting API keys in the request `Authorization` header where they can be properly secured and omitted from logs. +## Why use headers -In line with this best practice, we expanded our API key handling methods to accept API keys in request `Authorization` header, while still maintaining compatibility with the URL method. In this guide we'll discuss why this update was needed, its security benefits, and provide a detailed walkthrough on how to use your Alchemy API keys in HTTP headers for blockchain API requests. - -![](https://alchemyapi-res.cloudinary.com/image/upload/v1764180211/docs/tutorials/getting-started/api-security-and-authentication/03e9567-image.png) - -*** - -## Why HTTP Header Based Requests? - -HTTP requests consist of three parts: a request line, headers, and optionally a body. The request line specifies the method of the request (GET, POST, etc.), the request URI, and the HTTP version. Headers carry additional information like content type and authorization details. The body, which is optional and mostly used with methods like POST and PUT, contains the data that is intended to be sent. - -In a URL-based request approach, data like an API key is sent as a part of the URL itself. An example of this is the given request url: - - - ```text text - https://eth-mainnet.g.alchemy.com/v2/your_api_key - ``` - - -However, this approach can expose your API key to risks, such as being logged in server logs, appearing in browser history, or accidentally being exposed through sharing of URLs. - -HTTP header-based requests send the API key or Access key in HTTP `Authorization` header rather than in the URL. This method is generally safer because the header information isn't exposed in browser history or server logs by default. - -In the next two sections we will show you how you can get an Alchemy API key and setup a project to make header based requests. If you already have a project setup and an Alchemy API key, please skip to the [Implementation](#making-the-api-requests) section. +Putting your API key in the `Authorization` header keeps it out of request +URLs, which are more likely to appear in logs, browser history, and shared +screenshots. - You can make requests using either an Alchemy API Key or an Access Key in the Auth header. However, in this tutorial we will use API Key for simplicity. Check out the guide on [creating Access Keys](/docs/how-to-create-access-keys) ! + You can use either an API key or an access key in the + `Authorization` header. This guide uses an API key for simplicity. If you + need access keys, see [how to create access keys](/docs/how-to-create-access-keys). -*** - -## Getting Your API Key - -The first step to using HTTP header-based requests with Alchemy is to get your API key. Here's how to do it: - -1. Navigate to your Alchemy dashboard and click on the "Apps" tab. - -![](https://alchemyapi-res.cloudinary.com/image/upload/v1764180212/docs/tutorials/getting-started/api-security-and-authentication/4b53077-image.png) - -2. Grab the API from one of the existing apps by clicking the "API key" button or create a new app for your brand new project by clicking the "Create new app" button on the top-right. ![](https://alchemyapi-res.cloudinary.com/image/upload/v1764180214/docs/tutorials/getting-started/api-security-and-authentication/1a652f4-image.png) -3. Fill out the details for your new app, this includes the app name, description ( optional ) and network. The network will be the network on which you want to make the requests. ![](https://alchemyapi-res.cloudinary.com/image/upload/v1764180215/docs/tutorials/getting-started/api-security-and-authentication/6f2c7af-image.png) -4. Once the app is created, click on the "API key" button to get your API key for the given app. And that's it! You should now have an API key that you can use in your project. ![](https://alchemyapi-res.cloudinary.com/image/upload/v1764180221/docs/tutorials/getting-started/api-security-and-authentication/d473044-image.png) - -*** - -## Setting up the Project - -Before we proceed with making HTTP header-based requests using the API key, we need to set up a basic Node.js project where we can write and execute our code. Here's how you can do it: - -1. **Install Node.js**: If you haven't installed Node.js on your system, you can download and install it from the official [Node.js website](https://nodejs.org/en). - -2. **Create a new project**: Create a new directory for your project and initialize the project by running the following commands in your terminal: - - - ```bash bash - mkdir alchemy-tutorial - cd alchemy-tutorial - npm init -y - ``` - - - These commands will initialize a Node.js project and create a `package.json` file with default values. - -3. **Install necessary libraries**: To work with our HTTP header-based requests, we need a library to make those requests. In this tutorial we will show you how you can make requests using the two most popular libraries namely: axios and ethers.js. So install these libraries by running the command below: - - - ```bash bash - npm install axios ethers - ``` - - - This command adds Axios and Ethers.js to your project and updates the `package.json` file to include these dependencies. You'll see how we use these libraries in the next section. +## Prerequisites -4. **Create a new file for your code**: You can now create new JavaScript files in your project directory which will hold the actual code for making these requests. Create two new files called: `axiosScript.js` and ` ethersScript.js` ( or just a single file for the library you're interested in ). +* Node.js 18 or later +* An Alchemy API key +* A terminal you can run `node` from -You've now set up a simple Node.js project with the necessary dependencies installed. You're ready to start writing your code. + + + Export your API key as an environment variable: -Please note that while we're using a basic Node.js project here for demonstration purposes, you can certainly use this approach in other types of projects, such as those built with Next.js, React, etc. The method of making HTTP header-based requests using the API key remains the same; the project setup and configuration will differ based on the framework or library you're using. + ```bash + export ALCHEMY_API_KEY="YOUR_API_KEY" + ``` + -*** + + Create a file named `requests.mjs` and add this code: -## Making the API Requests + ```javascript title="requests.mjs" + const apiKey = process.env.ALCHEMY_API_KEY; -With your API key at hand and the project set up, you can now start making HTTP header-based requests. To demonstrate the process, we'll use two major JavaScript libraries: Axios and Ethers.js. We'll make requests to the [`eth_getBalance`](/docs/reference/eth-getbalance) method (JSON-RPC API) and [getNFTsForOwner](/docs/reference/nft-api-endpoints/nft-api-endpoints/nft-ownership-endpoints/get-nf-ts-for-owner-v-3) NFT API method (Enhanced API) for showcasing. + if (!apiKey) { + throw new Error("Set the ALCHEMY_API_KEY environment variable first."); + } -### Using Axios (JSON-RPC API) + async function fetchJson(url, init) { + const response = await fetch(url, init); -Axios is a widely adopted JavaScript library for HTTP requests. Below is how you would use your Alchemy API key/Access Key in an HTTP header with Axios: + if (!response.ok) { + throw new Error(`Request failed with status ${response.status}`); + } - - ```javascript javascript - const axios = require('axios'); // Import axios library + const payload = await response.json(); - // Set up data object for the request - const data = { - method: 'eth_getBalance', // Set request method - params: ['0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045'], // Insert the EVM address - id: 1, - jsonrpc: "2.0" - } + if (payload.error) { + throw new Error(payload.error.message); + } - // Set up headers object for the request - const headers = { - 'Authorization': `Bearer YOUR_API_KEY`, // Insert API key/Access Key in Authorization header - } + return payload; + } - // Send POST request using axios to base request url ( you can get the base request url from your Alchemy dashboard ) - axios.post('https://eth-mainnet.g.alchemy.com/v2', data, { headers: headers }) - .then(response => console.log(response.data.result)) // Log response data - .catch(error => console.error(error)); // Log any errors - ``` - - -Add the code given above to your `axiosScript.js` file and remember to replace `YOUR_API_KEY` with your actual Alchemy API key and `'0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045'` with the EVM address whose balance you want to check. - -This code: - -* Imports the Axios library. - -* Sets up a data object containing the JSON-RPC method to call and its params. - -* Creates a header object containing the authorization header for the request. This also includes the API key. This is used for authenticating the request. - -* Finally it sends the request through axios using the Alchemy base request url and the two objects ( header and data ) defined before. The base request url should correspond to the network you're making requests on. You can get this url from your app details in the Alchemy dashboard as shown below: - - ![](https://alchemyapi-res.cloudinary.com/image/upload/v1764180222/docs/tutorials/getting-started/api-security-and-authentication/fc9cad8-image.png) - -* If it's a successful response the result is logged to the console, if not, the errors are logged. - -### Using Axios (Enhanced API) - -Similarly for Enhanced APIs like NFT API, you can include the API Key/Access Key in the header and omit the `apiKey` from path: - -![](https://alchemyapi-res.cloudinary.com/image/upload/v1764180223/docs/tutorials/getting-started/api-security-and-authentication/011be99-image.png) - -Here's the code demonstrating this: - - - ```javascript javascript - const axios = require("axios"); // Import axios library - - // Set up headers object for the request - const headers = { - Authorization: `Bearer YOUR_API_KEY`, // Insert API key/Access Key in Authorization header - }; - - // Send GET request using axios to the request URL omitting api key from it - axios - .get( - "https://eth-mainnet.g.alchemy.com/nft/v3/getNFTsForOwner?owner=0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045&withMetadata=true&pageSize=1", - { headers: headers } - ) - .then((response) => console.log(response.data)) // Log response data - .catch((error) => console.error(error)); // Log any errors - ``` - - -We can make the same request using cURL as following: - - - ```shell shell - curl --location 'https://eth-mainnet.g.alchemy.com/nft/v3/getNFTsForOwner?owner=0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045' \ --header 'Authorization: Bearer YOUR_API_KEY' - ``` - - -Again, it's following the same principle of removing API Key/Access Key from path and including it in Auth header. - -### Using Ethers.js - -Ethers.js is a commonly used JavaScript library in blockchain development. Here's how to use your Alchemy API key in an HTTP header with Ethers.js: + async function getBalance(address) { + const payload = await fetchJson("https://eth-mainnet.g.alchemy.com/v2", { + method: "POST", + headers: { + Authorization: `Bearer ${apiKey}`, + "Content-Type": "application/json", + }, + body: JSON.stringify({ + jsonrpc: "2.0", + id: 1, + method: "eth_getBalance", + params: [address, "latest"], + }), + }); - - ```javascript javascript - // Import the FetchRequest class from ethers - const { FetchRequest } = require('ethers'); + console.log("Balance result:", payload.result); + } - // Define an asynchronous function to get the balance of EVM address - async function getBalance() { - // The base request URL ( you can get this from your app details in Alchemy dashboard ) - const url = 'https://eth-mainnet.g.alchemy.com/v2'; - // The EVM address that we want to get the balance of - const address = '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045'; // Replace with the address you're interested in - // Alchemy API Key - const apiKey = 'YOUR_API_KEY'; // Replace with your actual API key + async function getNftsForOwner(address) { + const url = + `https://eth-mainnet.g.alchemy.com/nft/v3/getNFTsForOwner` + + `?owner=${address}&withMetadata=false&pageSize=1`; - // Create a new FetchRequest instance with the specified URL - let req = new FetchRequest(url); - // Set the Content-Type header to 'application/json' - req.setHeader('Content-Type', 'application/json'); - // Set the Authorization header with the API key - req.setHeader('Authorization', `Bearer ${apiKey}`); - // Set the request body with a JSON string containing the JSON-RPC request - req.body = JSON.stringify({ - jsonrpc: '2.0', - id: 1, - method: 'eth_getBalance', - params: [address] + const payload = await fetchJson(url, { + headers: { + Authorization: `Bearer ${apiKey}`, + }, }); - // Set the HTTP method to POST - req.method = 'POST'; - // Send the request and wait for the response - let resp = await req.send(); + console.log("NFT API result:", JSON.stringify(payload, null, 2)); + } + + const address = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"; - // Parse the response body as JSON and extract the result field - let result = JSON.parse(resp.bodyText).result; + await getBalance(address); + await getNftsForOwner(address); + ``` + - // Log the result to the console - console.log(result); - } + + Run the file: - // Call the getBalance function and log any errors to the console - getBalance().catch(console.error); - ``` - + ```bash + node requests.mjs + ``` -Add the code given above to your `ethersScript.js` file and remember to replace `YOUR_API_KEY` with your actual Alchemy API key and `'0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045'` with the EVM address whose balance you want to check. + If the request succeeds, you should see a balance payload followed by an NFT + API response. If you get a `401` error, check that your API key is valid and + that you are sending it in the `Authorization` header. + + -This code: +## Quick cURL example -* Imports the `FetchRequest` class from the Ethers library that can be used for making custom HTTP requests. -* Defines an asynchronous function `getBalance` to handle the entire process of fetching balance. -* Specifies the base request URL, the EVM address whose balance needs to be fetched, and the Alchemy API key. The base request URL should correspond to the network you're making the requests on. You can get it from your app details in the Alchemy dashboard as shown below: ![](https://alchemyapi-res.cloudinary.com/image/upload/v1764180224/docs/tutorials/getting-started/api-security-and-authentication/261c5f7-image.png) -* Creates a new `FetchRequest` instance using the base request URL. -* Sets the 'Content-Type' header of the request to 'application/json' using the `setHeader` method. -* Sets the 'Authorization' header of the request to include the API key using the `setHeader` method. -* Specifies the body of the request with a stringified JSON object representing the JSON-RPC request for `eth_getBalance` method. -* Sets the HTTP method of the request to `'POST'`. -* Sends the request to the Alchemy endpoint using the `send` method and waits for the response. -* Parses the response body as a JSON object using `JSON.parse`, and retrieves the `result` field from the parsed object, which contains the hex formatted balance of the EVM address in Wei. -* Logs the result (the balance) to the console. -* Executes the `getBalance` function and provides error handling. If an error occurs during execution, it's caught and logged to the console. +If you want to inspect the raw HTTP request, run this command: -## Conclusion +```bash +curl "https://eth-mainnet.g.alchemy.com/v2" \ + -X POST \ + -H "Authorization: Bearer $ALCHEMY_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}' +``` -In this guide you learned how to make HTTP header-based API requests. +This uses the same authentication pattern: no API key in the URL, `Authorization` +header only. -We recommend moving your Alchemy API keys from the URL to HTTP headers as it enhances the security of your projects. With our support for header-based requests, this transition is seamless and easy. +## Next steps -If you have any questions or feedback, please contact us at support@alchemy.com or open a ticket in the dashboard. +* [Create access keys](/docs/how-to-create-access-keys) +* [Review request logs](/docs/alchemy-request-logs) diff --git a/content/tutorials/getting-started/create-an-api-key.mdx b/content/tutorials/getting-started/create-an-api-key.mdx index 29528de03..391d5f245 100644 --- a/content/tutorials/getting-started/create-an-api-key.mdx +++ b/content/tutorials/getting-started/create-an-api-key.mdx @@ -1,82 +1,72 @@ --- -title: Create an Alchemy API Key -description: Learn how to create an Alchemy API Key. -subtitle: Learn how to create an Alchemy API Key. +title: Create an Alchemy API key +description: Create an app in the Alchemy Dashboard and copy its API key. +subtitle: Create an app in the Alchemy Dashboard and copy its API key. slug: docs/create-an-api-key --- -> 👋 **New to Alchemy?** Start for free by creating an [Alchemy account](https://dashboard.alchemy.com/signup), then follow this guide to get your API Key! +This guide shows you how to create an app in the Alchemy Dashboard, copy its +API key, and find the endpoint URLs you will use in requests. -To use Alchemy's products, you need an API key to authenticate your requests. + + If you just created your Alchemy account, you already have a default app and + API key. Use that unless you need a separate app for a new project or + environment. + -With every app you create you get an API key on the dashboard. When you first signup for Alchemy, an app with an API key are created for you: +## Prerequisites -![](https://alchemyapi-res.cloudinary.com/image/upload/v1758730225/get-api-key_bn8zua.png) - -You can immediately start making requests with that API key! - -If you need to **create a new app for a new API key**, here are the steps to do so: +* An [Alchemy account](https://dashboard.alchemy.com/signup) + + Sign in to the [Alchemy Dashboard](https://dashboard.alchemy.com/) and open + **Team Overview** from your team menu. - - -First, navigate to your [Team Overview](https://dashboard.alchemy.com/) by clicking on your team name. - -![](https://alchemyapi-res.cloudinary.com/image/upload/v1758730581/navigate-overview_fwgrbb.png) - - - - - -Click on the "Apps" tab and then the "Create new app" button. - -![](https://alchemyapi-res.cloudinary.com/image/upload/v1758730226/create-new-app_fiqujs.png) - - - - + ![](https://alchemyapi-res.cloudinary.com/image/upload/v1758730581/navigate-overview_fwgrbb.png) + -Fill in the details for your new app, this includes specifying a name and description (optional) for it. Then click the "Next" button. + + Open the **Apps** tab, then select **Create new app**. -![](https://alchemyapi-res.cloudinary.com/image/upload/v1758730227/Screenshot_2025-09-24_at_11.48.08_AM_cyn4tx.png) + ![](https://alchemyapi-res.cloudinary.com/image/upload/v1758730226/create-new-app_fiqujs.png) + - + + Add an app name, an optional description, and the chains you want this app + to support. Then choose the services you want enabled and select + **Create App**. - + ![](https://alchemyapi-res.cloudinary.com/image/upload/v1758730227/Screenshot_2025-09-24_at_11.48.08_AM_cyn4tx.png) -Next, you can choose a chain or multiple chains to be supported on your app. + ![](https://alchemyapi-res.cloudinary.com/image/upload/v1758730226/Screenshot_2025-09-24_at_11.52.11_AM_xdtahy.png) -![](https://alchemyapi-res.cloudinary.com/image/upload/v1758730226/Screenshot_2025-09-24_at_11.52.11_AM_xdtahy.png) + ![](https://alchemyapi-res.cloudinary.com/image/upload/v1758730227/Screenshot_2025-09-24_at_11.51.22_AM_lx3qcu.png) + - + + After the app is created, you will land on the app details page. Copy the + API key shown in the top-right corner. - + ![](https://alchemyapi-res.cloudinary.com/image/upload/v1758730225/get-api-key_bn8zua.png) + -As the last step, you can select what services to activate on your application. You can come back and change these any time! Then select "Create App": + + Open the **Endpoints** tab to view the HTTP and WebSocket URLs for the + chains enabled on this app. -![](https://alchemyapi-res.cloudinary.com/image/upload/v1758730227/Screenshot_2025-09-24_at_11.51.22_AM_lx3qcu.png) - - - - - -Once your app is created, you will be redirected to the app details page, **here you will see your API key in the top right corner**: - -![](https://alchemyapi-res.cloudinary.com/image/upload/v1758730225/get-api-key_bn8zua.png) - - - - - -The API Key will be enabled on the chains you selected in the previous steps, switch to the "Endpoints" tab to toggle certain chains and view the request URLs (which contain your generated API key!). + ![](https://alchemyapi-res.cloudinary.com/image/upload/v1758730224/endpoints_gjlfrb.png) + + -![](https://alchemyapi-res.cloudinary.com/image/upload/v1758730224/endpoints_gjlfrb.png) +## Verify it works - +You are done when both of these are true: - +* You can see an API key on the app details page +* You can see at least one HTTP or WebSocket endpoint URL in the **Endpoints** tab -## 🔑 Next Steps +## Next steps -Now that you have your API Key, follow along to [making your first Alchemy request](/docs/make-your-first-request). +* [Make your first request](/docs/make-your-first-request) +* [Use API keys in HTTP headers](/docs/how-to-use-api-keys-in-http-headers) diff --git a/content/tutorials/getting-started/make-your-first-request.mdx b/content/tutorials/getting-started/make-your-first-request.mdx index d9f031d5a..571f10fba 100644 --- a/content/tutorials/getting-started/make-your-first-request.mdx +++ b/content/tutorials/getting-started/make-your-first-request.mdx @@ -1,39 +1,55 @@ --- -title: Make Your First Alchemy Request -description: Learn how to send a blockchain request using Alchemy. -subtitle: Learn how to send a blockchain request using Alchemy. +title: Make your first Alchemy request +description: Send your first JSON-RPC request to Alchemy with cURL. +subtitle: Send your first JSON-RPC request to Alchemy with cURL. slug: docs/make-your-first-request --- -> 👋 **Don't have an API Key?** [Start here](/docs/create-an-api-key) before making your first request! +This guide shows you how to send an `eth_gasPrice` request to Ethereum Mainnet +with cURL and verify the response. -You can interact with Alchemy's infrastructure provider using [JSON-RPC](https://www.alchemy.com/docs/how-to-read-data-with-json-rpc#how-to-read-ethereum-data) and your [command line](https://www.computerhope.com/jargon/c/commandi.htm). +## Prerequisites -Let's make a call to `eth_gasPrice`, so we'll fill this in as our `method`. +* An Alchemy API key. If you need one, [create an API key](/docs/create-an-api-key). +* A terminal with `curl` installed -Simply replace `demo` with your Alchemy API Key and you can run this from the command line to retrieve the current gas price: + + + Export your API key as an environment variable: - - ```shell shell - curl https://eth-mainnet.g.alchemy.com/v2/demo \ - -X POST \ - -H "Content-Type: application/json" \ - -d '{"jsonrpc":"2.0","method":"eth_gasPrice","params":[],"id":73}' - ``` - + ```bash + export ALCHEMY_API_KEY="YOUR_API_KEY" + ``` + -Results: + + Run this command: - - ```json Result - { "id": 73, - "jsonrpc": "2.0", - "result": "0x09184e72a000" // 10000000000000 } - ``` - + ```bash + curl "https://eth-mainnet.g.alchemy.com/v2/$ALCHEMY_API_KEY" \ + -X POST \ + -H "Content-Type: application/json" \ + -d '{"jsonrpc":"2.0","method":"eth_gasPrice","params":[],"id":1}' + ``` + -## Next Steps + + A successful response looks like this: -Congratulations on making your first Alchemy request! 🎉 + ```json + { + "jsonrpc": "2.0", + "id": 1, + "result": "0x09184e72a000" + } + ``` -Next, we recommend you check out setting up Alchemy [with Viem](docs/set-up-alchemy-with-viem) or [any web3 library using AI](docs/alchemy-via-libraries)! + The `result` value is the current gas price in wei, encoded as hex. + + + +## Next steps + +* [Set up Alchemy with Viem](/docs/set-up-alchemy-with-viem) +* [Use API keys in HTTP headers](/docs/how-to-use-api-keys-in-http-headers) +* [Review request logs in the Alchemy Dashboard](/docs/alchemy-request-logs) diff --git a/content/tutorials/transactions/sending-transactions/how-to-check-the-status-of-a-transaction-using-its-hash.mdx b/content/tutorials/transactions/sending-transactions/how-to-check-the-status-of-a-transaction-using-its-hash.mdx index f39073a92..d53675b2f 100644 --- a/content/tutorials/transactions/sending-transactions/how-to-check-the-status-of-a-transaction-using-its-hash.mdx +++ b/content/tutorials/transactions/sending-transactions/how-to-check-the-status-of-a-transaction-using-its-hash.mdx @@ -1,190 +1,121 @@ --- -title: How to Check the Status of a Transaction using its Hash -description: Learn how to check the status of a transaction using the transaction hash -subtitle: Learn how to check the status of a transaction using the transaction hash +title: How to check a transaction status from its hash +description: Use a transaction hash and eth_getTransactionReceipt to tell whether a transaction succeeded, reverted, or is still pending. +subtitle: Use a transaction hash and eth_getTransactionReceipt to tell whether a transaction succeeded, reverted, or is still pending. slug: docs/how-to-check-the-status-of-a-transaction-using-its-hash --- - - Start using this API in your app today. [Get started for free](https://dashboard.alchemy.com/signup) - +This guide shows you how to use a transaction hash and `eth_getTransactionReceipt` +to tell whether a transaction succeeded, reverted, or is still pending. - - This tutorial uses the **[getTransactionReceipt](/docs/chains/ethereum/ethereum-api-endpoints/eth-get-transaction-receipt)** endpoint. - +## Prerequisites -# Introduction +* Node.js 18 or later +* An Alchemy API key +* A transaction hash on Ethereum Mainnet -The transaction hash is a unique identifier that is assigned to every transaction on the blockchain network. In this article, we will explain how you can use Alchemy's [getTransactionReceipt](/docs/chains/ethereum/ethereum-api-endpoints/eth-get-transaction-receipt) API to check the status of a transaction using its transaction hash. + + A transaction receipt exists only after the transaction is mined. If the + method returns `null`, the transaction is still pending or the hash is + unknown. + -# Creating the Status Checker Script + + + Export your API key as an environment variable: -*** + ```bash + export ALCHEMY_API_KEY="YOUR_API_KEY" + ``` + -## Step 1: Install Node and npm + + Create a file named `check-status.mjs` and add this code: -In case you haven't already, [install node and npm](https://nodejs.org/en/download/) on your local machine. + ```javascript title="check-status.mjs" + const apiKey = process.env.ALCHEMY_API_KEY; -Make sure that node is at least **v14 or higher** by typing the following in your terminal: - - - ```shell shell - node -v - ``` - - -## Step 2: Create an Alchemy app - -*** - -In case you haven't already, [sign up for a free Alchemy account](https://dashboard.alchemy.com/signup). - -![2880](https://alchemyapi-res.cloudinary.com/image/upload/v1764192918/docs/tutorials/transactions/understanding-transactions/06c375a-Screenshot_2022-11-04_at_10.36.40_PM.png "Screenshot 2022-11-04 at 10.36.40 PM.png") - -Alchemy's account dashboard where developers can create a new app on the Ethereum blockchain. - -Next, navigate to the [Alchemy Dashboard](https://dashboard.alchemy.com/signup) and create a new app. - -Make sure you set the chain to Ethereum and the network to Mainnet. Once the app is created, click on your app's *View Key* button on the dashboard. - -Take note of the **HTTP URL**. - -The URL will be in this form: `https://eth-mainnet.g.alchemy.com/v2/xxxxxxxxx` - -You will need this later. - -*** - -## Step 3: Create a node project - -Let's now create an empty repository and install all node dependencies. - -Run the following commands in order to create your node project. - - - ```shell Viem - mkdir transaction-status-checker && cd transaction-status-checker - npm init -y - npm install --save viem - touch main.js - ``` - - ```shell Ethers.js - mkdir transaction-status-checker && cd transaction-status-checker - npm init -y - npm install --save ethers - touch main.js - ``` - - -This will create a repository named `transaction-status-checker` that holds all your files and dependencies. - -Next, open this repo in your favorite code editor. - -We will write all our code in the `main.js` file. - -## Step 4: Check the Transaction Status - -To check the status of the transaction using its transaction hash, we will use the [getTransactionReceipt](/docs/chains/ethereum/ethereum-api-endpoints/eth-get-transaction-receipt) method. - -* This method accepts a transaction hash and returns the transaction receipt, which is an object that contains the details about the transaction. The returned object has a property called `status`. -* If the value of the `status` property is `1`, it means that the transaction was successful, on the other hand, a value of `0` signifies that the transaction failed. -* If no object (transaction receipt) is returned from the `getTransactionReceipt` method, it means either the transaction is pending or the hash provided is an invalid/unknown transaction hash. - -Add the following code to the `main.js` file: - - - ```javascript Viem - import { createPublicClient, http } from 'viem' - import { mainnet } from 'viem/chains' + if (!apiKey) { + throw new Error("Set the ALCHEMY_API_KEY environment variable first."); + } - // Replace with your Alchemy API Key - const apiKey = "demo"; + const rpcUrl = `https://eth-mainnet.g.alchemy.com/v2/${apiKey}`; + const txHash = + "0xd488331be3a2f9cdd0f2b351f2b13f5151630aaafd2c2b246f7f3cd7fd0b1dfc"; + + async function checkTransactionStatus(hash) { + const response = await fetch(rpcUrl, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + jsonrpc: "2.0", + id: 1, + method: "eth_getTransactionReceipt", + params: [hash], + }), + }); + + if (!response.ok) { + throw new Error(`Request failed with status ${response.status}`); + } - const client = createPublicClient({ - chain: mainnet, - transport: http(`https://eth-mainnet.g.alchemy.com/v2/${apiKey}`) - }) + const payload = await response.json(); - // Transaction hash for the transaction whose status we want to check - const txHash = "0xd488331be3a2f9cdd0f2b351f2b13f5151630aaafd2c2b246f7f3cd7fd0b1dfc"; + if (payload.error) { + throw new Error(payload.error.message); + } - // Getting the status of the transaction using getTransactionReceipt and logging accordingly - const checkTransactionStatus = async () => { - try { - const receipt = await client.getTransactionReceipt({ hash: txHash }); + const receipt = payload.result; if (!receipt) { - console.log("Pending or Unknown Transaction"); - } else if (receipt.status === 'success') { - console.log("Transaction was successful!"); - } else { - console.log("Transaction failed!"); + console.log("Transaction is still pending or the hash is unknown."); + return; } - } catch (error) { - console.log("Pending or Unknown Transaction"); - } - }; - - checkTransactionStatus(); - ``` - - ```javascript Ethers.js - import { ethers } from 'ethers' - - // Replace with your Alchemy API Key - const apiKey = "demo"; - const provider = new ethers.JsonRpcProvider(`https://eth-mainnet.g.alchemy.com/v2/${apiKey}`); - - // Transaction hash for the transaction whose status we want to check - const txHash = "0xd488331be3a2f9cdd0f2b351f2b13f5151630aaafd2c2b246f7f3cd7fd0b1dfc"; - // Getting the status of the transaction using getTransactionReceipt and logging accordingly - const checkTransactionStatus = async () => { - try { - const receipt = await provider.getTransactionReceipt(txHash); - - if (!receipt) { - console.log("Pending or Unknown Transaction"); - } else if (receipt.status === 1) { - console.log("Transaction was successful!"); - } else { - console.log("Transaction failed!"); + if (receipt.status === "0x1") { + console.log("Transaction succeeded."); + return; } - } catch (error) { - console.log("Pending or Unknown Transaction"); + + console.log("Transaction reverted."); } - }; - checkTransactionStatus(); + await checkTransactionStatus(txHash); + ``` + + + + Run the file: - // Status is 1 for success, 0 for failure. - ``` - + ```bash + node check-status.mjs + ``` -Here's an explanation of what the code is doing: + A successful run prints one of these results: -* Imports either Viem or Ethers.js library to interact with Ethereum. -* Configures the client/provider with the Alchemy API key and Ethereum mainnet. -* Defines the transaction hash for the transaction whose status we want to check. -* Calls the `getTransactionReceipt` method, passing in the transaction hash as an argument. -* This returns the transaction receipt for the transaction, which contains the status of the transaction. -* It then logs the status of the transaction to the console according to the value of the `status` property. If the receipt is `null`, it means that the transaction is either pending or unknown. For Viem, the status is 'success' or 'reverted', while for Ethers.js the status is `1` for success and `0` for failure. + ```text + Transaction succeeded. + ``` -Run the script using: + ```text + Transaction reverted. + ``` - - ```shell shell - node main.js - ``` - + ```text + Transaction is still pending or the hash is unknown. + ``` + + -If all goes well, you should see an output with the status of the transaction: +## How to interpret the result -```shell -Transaction was successful! -``` +* `Transaction succeeded.` means the receipt exists and `status` is `0x1` +* `Transaction reverted.` means the receipt exists and `status` is `0x0` +* `Transaction is still pending or the hash is unknown.` means the receipt is `null` -# Conclusion +## Next steps -In conclusion, checking the status of a transaction using its hash is a simple process. By following the steps outlined in this article, you can easily track the status of your transaction. +* [Get transaction details](/docs/how-to-get-transaction-details) +* [Learn more about sending transactions](/docs/sending-transactions) From 5b438d8e7ea41dce38f78528dad65194afa98810 Mon Sep 17 00:00:00 2001 From: Sahil Aujla Date: Fri, 6 Mar 2026 12:28:57 -0500 Subject: [PATCH 3/7] Clarify style guide precedence for wallets docs --- STYLE_RULES.md | 5 +++++ content/wallets/CONTRIBUTING.md | 7 +++++++ 2 files changed, 12 insertions(+) diff --git a/STYLE_RULES.md b/STYLE_RULES.md index cc2230c08..ab284298d 100644 --- a/STYLE_RULES.md +++ b/STYLE_RULES.md @@ -61,6 +61,11 @@ Interpret these labels consistently: * `Preferred` means use this by default, but it can be overridden for clarity or local context * `Avoid` means do not do this unless there is a specific reason +Section-specific guides override this document when they are more specific. For +example, Wallets documentation has its own contributing guide at +`content/wallets/CONTRIBUTING.md`. In those docs, follow the Wallets-specific +rules first and use this guide as the fallback for anything not covered there. + Some choices in this repo are enforced by tooling such as Prettier, ESLint, and markdown linting. This guide should not duplicate those checks. It should cover the places where judgment matters: what to say, how to organize it, and how much to explain. When a rule hurts clarity, choose clarity. When you break a default, do it intentionally. diff --git a/content/wallets/CONTRIBUTING.md b/content/wallets/CONTRIBUTING.md index 8aad0d817..a3006e304 100644 --- a/content/wallets/CONTRIBUTING.md +++ b/content/wallets/CONTRIBUTING.md @@ -6,6 +6,9 @@ **ROLE**: You are helping write documentation for Alchemy's Smart Wallets product. Always follow these rules when generating or editing content. +**PRECEDENCE**: These rules override the repo-wide style guide in +[`STYLE_RULES.md`](../../STYLE_RULES.md) for content under `content/wallets/`. + **CORE PRINCIPLES**: * SIMPLIFY: Hide blockchain complexity, focus on developer outcomes @@ -31,6 +34,10 @@ When writing or editing documentation for Alchemy Smart Wallets, follow these comprehensive style guidelines. These rules ensure consistency, clarity, and developer-focused content that abstracts away blockchain complexity. +**Scope**: These guidelines extend the repo-wide style guide in +[`STYLE_RULES.md`](../../STYLE_RULES.md). If a Wallets-specific rule conflicts +with the repo-wide guide, follow this document for Wallets content. + **Foundation**: Follow the [Google Developer Documentation Style Guide](https://developers.google.com/style) as the base standard. *** From d5ca840926a0a9d6856a619155b1f3e7bc7f36d8 Mon Sep 17 00:00:00 2001 From: Sahil Aujla Date: Fri, 6 Mar 2026 12:31:45 -0500 Subject: [PATCH 4/7] format rules correctly --- STYLE_RULES.md | 5 +---- content/wallets/CONTRIBUTING.md | 7 ++----- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/STYLE_RULES.md b/STYLE_RULES.md index ab284298d..ef7f9bc4e 100644 --- a/STYLE_RULES.md +++ b/STYLE_RULES.md @@ -61,10 +61,7 @@ Interpret these labels consistently: * `Preferred` means use this by default, but it can be overridden for clarity or local context * `Avoid` means do not do this unless there is a specific reason -Section-specific guides override this document when they are more specific. For -example, Wallets documentation has its own contributing guide at -`content/wallets/CONTRIBUTING.md`. In those docs, follow the Wallets-specific -rules first and use this guide as the fallback for anything not covered there. +Section-specific guides override this document when they are more specific. For example, Wallets documentation has its own contributing guide at `content/wallets/CONTRIBUTING.md`. In those docs, follow the Wallets-specific rules first and use this guide as the fallback for anything not covered there. Some choices in this repo are enforced by tooling such as Prettier, ESLint, and markdown linting. This guide should not duplicate those checks. It should cover the places where judgment matters: what to say, how to organize it, and how much to explain. diff --git a/content/wallets/CONTRIBUTING.md b/content/wallets/CONTRIBUTING.md index a3006e304..675bb70aa 100644 --- a/content/wallets/CONTRIBUTING.md +++ b/content/wallets/CONTRIBUTING.md @@ -6,8 +6,7 @@ **ROLE**: You are helping write documentation for Alchemy's Smart Wallets product. Always follow these rules when generating or editing content. -**PRECEDENCE**: These rules override the repo-wide style guide in -[`STYLE_RULES.md`](../../STYLE_RULES.md) for content under `content/wallets/`. +**PRECEDENCE**: These rules override the repo-wide style guide in [`STYLE_RULES.md`](../../STYLE_RULES.md) for content under `content/wallets/`. **CORE PRINCIPLES**: @@ -34,9 +33,7 @@ When writing or editing documentation for Alchemy Smart Wallets, follow these comprehensive style guidelines. These rules ensure consistency, clarity, and developer-focused content that abstracts away blockchain complexity. -**Scope**: These guidelines extend the repo-wide style guide in -[`STYLE_RULES.md`](../../STYLE_RULES.md). If a Wallets-specific rule conflicts -with the repo-wide guide, follow this document for Wallets content. +**Scope**: These guidelines extend the repo-wide style guide in [`STYLE_RULES.md`](../../STYLE_RULES.md). If a Wallets-specific rule conflicts with the repo-wide guide, follow this document for Wallets content. **Foundation**: Follow the [Google Developer Documentation Style Guide](https://developers.google.com/style) as the base standard. From 67bb05db62175f6783520145654b05fffae907dc Mon Sep 17 00:00:00 2001 From: Sahil Aujla Date: Fri, 6 Mar 2026 12:37:52 -0500 Subject: [PATCH 5/7] add it to agent quick rules --- STYLE_RULES.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/STYLE_RULES.md b/STYLE_RULES.md index ef7f9bc4e..fd80c7e68 100644 --- a/STYLE_RULES.md +++ b/STYLE_RULES.md @@ -18,8 +18,9 @@ Required: * Use the preferred terminology table exactly * Use JavaScript or TypeScript for authored examples unless the page has a stronger existing convention * Put changelog updates under product-area headings and place `Node` after more user-facing sections when both are present -* Use `Updates` for launches, availability changes, deprecations, and behavior changes -* Use `Upgrades` for version bumps and maintenance entries +* * For files under `content/wallets/`, follow `content/wallets/CONTRIBUTING.md` before this guide +* In changelog, use `Updates` for launches, availability changes, deprecations, and behavior changes +* In changelog, Use `Upgrades` for version bumps and maintenance entries * Do not hand-edit generated API reference output; update the source specs instead Preferred: From c42fea1fbe96f64ba35ed7f6658186e2177f8d9e Mon Sep 17 00:00:00 2001 From: Sahil Aujla Date: Fri, 6 Mar 2026 12:39:17 -0500 Subject: [PATCH 6/7] fix --- STYLE_RULES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/STYLE_RULES.md b/STYLE_RULES.md index fd80c7e68..e234b809d 100644 --- a/STYLE_RULES.md +++ b/STYLE_RULES.md @@ -18,7 +18,7 @@ Required: * Use the preferred terminology table exactly * Use JavaScript or TypeScript for authored examples unless the page has a stronger existing convention * Put changelog updates under product-area headings and place `Node` after more user-facing sections when both are present -* * For files under `content/wallets/`, follow `content/wallets/CONTRIBUTING.md` before this guide +* For files under `content/wallets/`, follow `content/wallets/CONTRIBUTING.md` before this guide * In changelog, use `Updates` for launches, availability changes, deprecations, and behavior changes * In changelog, Use `Upgrades` for version bumps and maintenance entries * Do not hand-edit generated API reference output; update the source specs instead From 77fa01dc2f6ab9a8608302730b40d78b3ea6b745 Mon Sep 17 00:00:00 2001 From: Sahil Aujla Date: Fri, 6 Mar 2026 12:45:53 -0500 Subject: [PATCH 7/7] Rewrite wallets add-passkey guide --- content/wallets/pages/react/add-passkey.mdx | 50 ++++++++++++++------- 1 file changed, 34 insertions(+), 16 deletions(-) diff --git a/content/wallets/pages/react/add-passkey.mdx b/content/wallets/pages/react/add-passkey.mdx index 6d1a6e480..ae4882154 100644 --- a/content/wallets/pages/react/add-passkey.mdx +++ b/content/wallets/pages/react/add-passkey.mdx @@ -1,17 +1,24 @@ --- -title: Add Passkey -description: Learn how to add a passkey to your users' accounts with Smart Wallets. +title: Add a passkey +description: Add a passkey during sign-up or from your app settings. slug: wallets/react/add-passkey --- -You may have noticed in the [Demo App](https://demo.alchemy.com/) that you can allow a user to log in with an existing passkey, but there's no way to sign-up with a passkey. This guide will outline -how to add a passkey to a user's account after they've signed up. +Use this guide to add passkeys as an authentication method in your React app. +You can prompt for a passkey during sign-up or let a signed-in user add one +later from a settings screen. -If you're not sure how to authenticate your users, see [this guide](/docs/wallets/react/getting-started). +## Prerequisites -## Add a passkey on sign up +* A React app with Smart Wallets configured +* Authentication already set up in your app. If you still need that, start with + [React quickstart](/wallets/react/quickstart) and [environment setup](/wallets/react/setup). +* For the second example, a user must already be signed in -The easiest way to add a passkey to users is right when they signup! This can be done by updating your `ui` config in the `createConfig` call to enable the UI components to prompt the user for a passkey. +## Add a passkey during sign-up + +Enable `addPasskeyOnSignup` in your `createConfig` call to prompt for a passkey +as part of sign-up. ```ts twoslash config.ts // @noErrors @@ -33,33 +40,44 @@ export const config = createConfig( ); ``` -Now, when a user signs up, they will be prompted to create a passkey. +When sign-up starts, the UI prompts the user to create a passkey and attach it +to the account. -## Add a passkey later +## Add a passkey after sign-up -With the above config, the user will only be prompted when they first create their account in your app. If you want to add the ability to add a passkey elsewhere in your app, for example in a settings page, you can use the [`useAddPasskey`](/docs/wallets/reference/account-kit/react/hooks/useAddPasskey) hook. +Use `useAddPasskey` when you want to add passkeys from a settings page or any +other authenticated screen. - This hook requires that the user already be authenticated or else it will - throw an error! + `useAddPasskey` requires an authenticated user. Call it only after sign-in is + complete. ```tsx twoslash import React from "react"; import { useAddPasskey } from "@account-kit/react"; -export default function MyComponent() { +export default function SettingsPage() { const { addPasskey, isAddingPasskey } = useAddPasskey(); return ( ); } ``` + +When the button is clicked, the browser opens the passkey creation flow. After +the flow completes, the new passkey is available as a login method for that +account. + +## Next steps + +* [Sign in with a passkey](/wallets/react/login-methods/passkey-login) +* [Add and remove login methods](/wallets/signer/authentication/adding-and-removing-login-methods)