Skip to content

Conversation

@DannyFi
Copy link
Contributor

@DannyFi DannyFi commented Jan 23, 2026

Summary by CodeRabbit

  • New Features

    • Added three interactive Alt Fee demos: quick start, supported-tokens query, and chain configuration viewer.
  • Documentation

    • Updated SDK examples and API reference; adjusted example values, conversion utility names, and inserted demo components.
  • Bug Fixes

    • Updated RPC endpoints to the new domain across docs, configs, and examples.
  • Style

    • Added Alt Fee UI styles and fixed React attribute rendering; adjusted site SEO/meta tags.
  • Chores

    • Added viem-related dependencies and centralized SEO/site metadata.

✏️ Tip: You can customize this high-level summary in your review settings.

@DannyFi DannyFi requested a review from a team as a code owner January 23, 2026 11:31
@DannyFi DannyFi requested review from r3aker86 and removed request for a team January 23, 2026 11:31
@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Jan 23, 2026

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
❌ Deployment failed
View logs
pre-rail e91138b Jan 26 2026, 11:17 AM

@coderabbitai
Copy link

coderabbitai bot commented Jan 23, 2026

📝 Walkthrough

Walkthrough

Adds three Alt Fee demo React components and styles, updates RPC endpoints and docs, injects SEO metadata into Docusaurus config, adds viem dependencies, fixes a React SVG prop, and normalizes a trailing slash in config.json.

Changes

Cohort / File(s) Summary
Site config & SEO
config.json, docusaurus.config.js
Normalized start_urls in config.json; introduced SEO constants and injected Open Graph / Twitter / canonical / hreflang meta via docusaurus.config.js; replaced hard-coded title/URL with constants.
Alt Fee demo components
src/components/AltFee/AltFeeQuickStartDemo.tsx, src/components/AltFee/QuerySupportedTokensDemo.tsx, src/components/AltFee/ChainConfigDemo.tsx
Added three new React components: a local private-key transaction demo (uses viem public/wallet clients), a supported-token query UI (reads TokenRegistry), and a chain config viewer.
Docs & examples
docs/build-on-morph/sdk/js-sdk.mdx
Inserted demo imports/usages, replaced hard-coded private key with placeholder, switched numeric(...)numericCore(...), adjusted amounts and feeTokenID, and updated Hoodi RPC URL references.
Network & RPC endpoints
src/components/ApiExplorer/configs/networks.ts, src/components/ApiExplorer/supported.json
Switched RPC and WS endpoints from *.morphl2.io/rpc-hoodi.morphl2.io to *.morph.network for mainnet and Hoodi.
Dependencies
package.json
Added @morph-network/viem (^0.1.0) and viem (^2.44.4).
Styling
src/css/figma-overrides.scss
Added Alt Fee UI styles: responsive form grid, inputs/selects, card layout, toolbar/status/table styles, modal styling, and mobile adjustments.
Minor fixes
src/components/MarkdownActionsDropdown/index.js, src/theme/SearchBar/index.js
Fixed React SVG props (fillRule, className) and removed redundant social meta tags from SearchBar.

Sequence Diagram(s)

sequenceDiagram
  participant User as User
  participant UI as AltFeeQuickStartDemo (UI)
  participant Wallet as Viem WalletClient
  participant RPC as PublicClient / RPC
  participant TokenReg as TokenRegistry

  User->>UI: enter privateKey, recipient, amount, fee options
  UI->>Wallet: derive account (privateKeyToAccount)
  UI->>RPC: fetch nonce & gas hints
  UI->>TokenReg: (optional) query fee token info
  UI->>Wallet: sign & send transaction
  Wallet->>RPC: submit raw tx
  RPC-->>Wallet: return tx hash/receipt
  Wallet-->>UI: tx hash / status
  UI-->>User: display tx hash and explorer link
Loading
sequenceDiagram
  participant User as User
  participant UI2 as QuerySupportedTokensDemo (UI)
  participant RPC2 as PublicClient / RPC
  participant TokenReg2 as TokenRegistry Contract

  User->>UI2: click "Query supported tokens"
  UI2->>RPC2: call TokenRegistry.getSupportedTokenList()
  RPC2->>TokenReg2: execute read
  TokenReg2-->>RPC2: return token list
  RPC2-->>UI2: return token list
  UI2-->>User: render table + raw JSON
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • Playground #116 — Updates ApiExplorer network definitions and RPC endpoints (touches same network constants).
  • fix: fix code example error #128 — Modifies Alt Fee docs/examples (feeTokenID, amounts, numeric→numericCore) similar to this PR.
  • New doc style #109 — Overlaps site configuration and styling changes (docusaurus config, SCSS updates).

Suggested reviewers

  • MarvelFisher
  • tomatoishealthy

Poem

🐰 I hopped through code with nimble feet,

demos sprang up, and RPCs meet.
Tokens listed, chains in view,
a modal, styles, and fixes too —
carrots out: "Docs ready — take a seat!"

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title accurately summarizes the two main objectives: adding Alt Fee demo components and implementing SEO enhancements.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@DannyFi DannyFi self-assigned this Jan 23, 2026
@DannyFi DannyFi requested review from BTCB and MarvelFisher January 23, 2026 11:34
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
docs/build-on-morph/sdk/js-sdk.mdx (2)

288-291: Inconsistent tokenID value in comment.

The comment on line 290 shows tokenID: 6 but all other examples in this document now use feeTokenID: 4 for USDT. Update this for consistency.

Suggested fix
-  // => [{ tokenID: 6, tokenAddress: "0x..." }, ...]
+  // => [{ tokenID: 4, tokenAddress: "0x..." }, ...]

503-508: Inconsistent tokenID in example output.

The example output shows tx.feeTokenID as 6 but the documentation consistently uses 4 for USDT elsewhere. Update for consistency.

Suggested fix
 const tx = parseAltFeeTransaction("0x7f...");

-console.log(tx.feeTokenID);  // 6
+console.log(tx.feeTokenID);  // 4
 console.log(tx.feeLimit);    // 252637086960555000n
 console.log(tx.type);        // "altFee"
🤖 Fix all issues with AI agents
In `@docusaurus.config.js`:
- Around line 195-201: The static canonical link entry using tagName:'link' with
attributes.rel='canonical' and href=SITE_URL should be removed or replaced so
Docusaurus can generate per-page canonicals; locate the headTags (or similar
static head injection) where the object with attributes {rel: 'canonical', href:
SITE_URL} is added and either delete that object or change the logic to compute
the page-specific canonical (e.g., derive href from metadata/router) so the
canonical points to each page rather than SITE_URL.

In `@package.json`:
- Line 28: The package entry "@morph-network/viem" in package.json cannot be
resolved; either remove or replace that dependency with a publicly available
package (for example the upstream "viem" or another maintained fork), or change
the dependency value to a reachable source (a git URL or valid registry URL),
and if it's a private package configure the private registry in .npmrc/CI (or
add authentication) so npm install can fetch it; update package.json to the
chosen valid spec, regenerate package-lock.json/yarn.lock, and verify CI
installs succeed (refer to the dependency string "@morph-network/viem" when
editing).

In `@src/components/AltFee/AltFeeQuickStartDemo.tsx`:
- Around line 116-118: The hardcoded gas parameters in AltFeeQuickStartDemo
(gas: 100000n, maxFeePerGas: 15000000n, maxPriorityFeePerGas: 14000000n) can
underpay transactions; instead call the provider's estimateGas (or use
signer.estimateGas/populateTransaction then provider.estimateGas) to compute
gasLimit, fetch fee data via provider.getFeeData() to derive maxFeePerGas and
maxPriorityFeePerGas, and apply BigInt conversions; also include a sensible
fallback (larger constants) if estimation fails and ensure these computed values
are used when constructing the transaction before sending.

In `@src/components/AltFee/QuerySupportedTokensDemo.tsx`:
- Around line 4-8: The import list is missing morphMainnet which causes
incorrect chain selection; update the import statement that currently includes
morphHoodiTestnet, TOKEN_REGISTRY_PROXY_ADDRESS, and tokenRegistryAbi to also
import morphMainnet so the component can support mainnet selection (i.e., add
morphMainnet alongside morphHoodiTestnet in the same import).
- Around line 37-40: The chain passed to createPublicClient is hardcoded to
morphHoodiTestnet causing testnet to be used even when mainnet is selected;
update the createPublicClient call to pick the chain based on the current
network value (e.g., choose morphHoodiMainnet when network indicates mainnet and
morphHoodiTestnet for testnet) and keep rpcUrl(network) as-is; specifically
modify the createPublicClient invocation in QuerySupportedTokensDemo to use a
conditional or mapping (referencing createPublicClient, morphHoodiTestnet, and
the mainnet variant like morphHoodiMainnet) so the chain matches the selected
network.
🧹 Nitpick comments (1)
src/components/AltFee/AltFeeQuickStartDemo.tsx (1)

261-262: Remove empty <div> element.

This empty div serves no purpose and should be removed.

Suggested fix
         </div>
-        <div>
-        </div>
       </div>

Comment on lines +195 to +201
{
tagName: 'link',
attributes: {
rel: 'canonical',
href: SITE_URL,
},
},
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Static canonical URL may harm SEO.

This canonical link always points to the site root (SITE_URL) for every page. For proper SEO, each page should have a canonical URL pointing to itself to prevent duplicate content issues.

Docusaurus typically handles canonical URLs automatically per-page. This static headTags entry may override that behavior.

Consider removing this static canonical tag and letting Docusaurus handle canonicals dynamically, or verify this is intentional for your use case.

Suggested removal
-    {
-      tagName: 'link',
-      attributes: {
-        rel: 'canonical',
-        href: SITE_URL,
-      },
-    },
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{
tagName: 'link',
attributes: {
rel: 'canonical',
href: SITE_URL,
},
},
🤖 Prompt for AI Agents
In `@docusaurus.config.js` around lines 195 - 201, The static canonical link entry
using tagName:'link' with attributes.rel='canonical' and href=SITE_URL should be
removed or replaced so Docusaurus can generate per-page canonicals; locate the
headTags (or similar static head injection) where the object with attributes
{rel: 'canonical', href: SITE_URL} is added and either delete that object or
change the logic to compute the page-specific canonical (e.g., derive href from
metadata/router) so the canonical points to each page rather than SITE_URL.

"@docusaurus/theme-common": "3.1.1",
"@docusaurus/theme-search-algolia": "3.1.1",
"@mdx-js/react": "3.0.1",
"@morph-network/viem": "^0.1.0",
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check the latest version and metadata for `@morph-network/viem`
npm view `@morph-network/viem` versions --json 2>/dev/null | tail -10
npm view `@morph-network/viem` version 2>/dev/null
npm view `@morph-network/viem` dist-tags 2>/dev/null

Repository: morph-l2/morph-doc

Length of output: 343


🏁 Script executed:

#!/bin/bash
# Read the package.json to see the full dependency entry for `@morph-network/viem`
cat package.json | grep -A 2 -B 2 "@morph-network/viem"

Repository: morph-l2/morph-doc

Length of output: 239


🏁 Script executed:

#!/bin/bash
# Check for .npmrc or npm configuration
ls -la | grep -E "^\.|npmrc|yarnrc"
cat .npmrc 2>/dev/null
cat .yarn/config.cjs 2>/dev/null

# Search for references to morph-network/viem in the codebase
rg "@morph-network/viem" --type json --max-count 10

Repository: morph-l2/morph-doc

Length of output: 111


@morph-network/viem dependency cannot be resolved.

The package is not found in the public npm registry and no private registry or alternative source is configured. This dependency will fail during npm install. Either configure access to the registry where this package is published, or use a git URL if it's a private repository.

🤖 Prompt for AI Agents
In `@package.json` at line 28, The package entry "@morph-network/viem" in
package.json cannot be resolved; either remove or replace that dependency with a
publicly available package (for example the upstream "viem" or another
maintained fork), or change the dependency value to a reachable source (a git
URL or valid registry URL), and if it's a private package configure the private
registry in .npmrc/CI (or add authentication) so npm install can fetch it;
update package.json to the chosen valid spec, regenerate
package-lock.json/yarn.lock, and verify CI installs succeed (refer to the
dependency string "@morph-network/viem" when editing).

Comment on lines 116 to 118
gas: 100000n,
maxFeePerGas: 15000000n,
maxPriorityFeePerGas: 14000000n,
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Hardcoded gas parameters may cause transaction failures.

The fixed values (gas: 100000n, maxFeePerGas: 15000000n, maxPriorityFeePerGas: 14000000n) are quite low and could result in:

  • Insufficient gas for certain transfers
  • Transactions stuck in the mempool if network base fee exceeds 15 gwei

Consider estimating gas dynamically or using more generous defaults for a demo.

Suggested improvement using gas estimation
+      const gasEstimate = await publicClient.estimateGas({
+        account: account.address,
+        to: recipient,
+        value,
+      });
+
+      const feeData = await publicClient.estimateFeesPerGas();
+
       const hash = await walletClient.sendTransaction({
         account,
         to: recipient,
         value,
         nonce,
-        gas: 100000n,
-        maxFeePerGas: 15000000n,
-        maxPriorityFeePerGas: 14000000n,
+        gas: gasEstimate,
+        maxFeePerGas: feeData.maxFeePerGas,
+        maxPriorityFeePerGas: feeData.maxPriorityFeePerGas,
🤖 Prompt for AI Agents
In `@src/components/AltFee/AltFeeQuickStartDemo.tsx` around lines 116 - 118, The
hardcoded gas parameters in AltFeeQuickStartDemo (gas: 100000n, maxFeePerGas:
15000000n, maxPriorityFeePerGas: 14000000n) can underpay transactions; instead
call the provider's estimateGas (or use signer.estimateGas/populateTransaction
then provider.estimateGas) to compute gasLimit, fetch fee data via
provider.getFeeData() to derive maxFeePerGas and maxPriorityFeePerGas, and apply
BigInt conversions; also include a sensible fallback (larger constants) if
estimation fails and ensure these computed values are used when constructing the
transaction before sending.

Comment on lines +4 to +8
import {
morphHoodiTestnet,
TOKEN_REGISTRY_PROXY_ADDRESS,
tokenRegistryAbi,
} from "@morph-network/viem";
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add morphMainnet import to fix the chain selection issue.

The import needs to include morphMainnet to properly support the mainnet network option.

Suggested fix
 import {
   morphHoodiTestnet,
+  morphMainnet,
   TOKEN_REGISTRY_PROXY_ADDRESS,
   tokenRegistryAbi,
 } from "@morph-network/viem";
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import {
morphHoodiTestnet,
TOKEN_REGISTRY_PROXY_ADDRESS,
tokenRegistryAbi,
} from "@morph-network/viem";
import {
morphHoodiTestnet,
morphMainnet,
TOKEN_REGISTRY_PROXY_ADDRESS,
tokenRegistryAbi,
} from "@morph-network/viem";
🤖 Prompt for AI Agents
In `@src/components/AltFee/QuerySupportedTokensDemo.tsx` around lines 4 - 8, The
import list is missing morphMainnet which causes incorrect chain selection;
update the import statement that currently includes morphHoodiTestnet,
TOKEN_REGISTRY_PROXY_ADDRESS, and tokenRegistryAbi to also import morphMainnet
so the component can support mainnet selection (i.e., add morphMainnet alongside
morphHoodiTestnet in the same import).

Comment on lines +37 to +40
const publicClient = createPublicClient({
chain: morphHoodiTestnet,
transport: http(rpcUrl(network)),
});
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Chain configuration is hardcoded to testnet regardless of network selection.

The chain parameter always uses morphHoodiTestnet even when mainnet is selected. This could cause chain ID mismatches or unexpected behavior when querying the mainnet.

Suggested fix
+import {
+  morphHoodiTestnet,
+  morphMainnet,
+  TOKEN_REGISTRY_PROXY_ADDRESS,
+  tokenRegistryAbi,
+} from "@morph-network/viem";

+// Inside handleQuery:
       const publicClient = createPublicClient({
-        chain: morphHoodiTestnet,
+        chain: network === "mainnet" ? morphMainnet : morphHoodiTestnet,
         transport: http(rpcUrl(network)),
       });
🤖 Prompt for AI Agents
In `@src/components/AltFee/QuerySupportedTokensDemo.tsx` around lines 37 - 40, The
chain passed to createPublicClient is hardcoded to morphHoodiTestnet causing
testnet to be used even when mainnet is selected; update the createPublicClient
call to pick the chain based on the current network value (e.g., choose
morphHoodiMainnet when network indicates mainnet and morphHoodiTestnet for
testnet) and keep rpcUrl(network) as-is; specifically modify the
createPublicClient invocation in QuerySupportedTokensDemo to use a conditional
or mapping (referencing createPublicClient, morphHoodiTestnet, and the mainnet
variant like morphHoodiMainnet) so the chain matches the selected network.

@DannyFi DannyFi changed the title Alt fee Demo Alt fee Demo & SEO Jan 23, 2026
@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Jan 26, 2026

Deploying morph-doc with  Cloudflare Pages  Cloudflare Pages

Latest commit: e91138b
Status: ✅  Deploy successful!
Preview URL: https://eb329f91.morph-doc.pages.dev
Branch Preview URL: https://alt-fee.morph-doc.pages.dev

View logs

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@docs/build-on-morph/sdk/js-sdk.mdx`:
- Around line 188-189: Update the inconsistent token ID comments to match the
example's feeTokenID of 4: change the sample output comment that shows "tokenID:
6" to "tokenID: 4" (or explicitly state that tokenID 6 refers to a different
registry token), and change the console output comment for tx.feeTokenID to
reflect 4 instead of 6; search for occurrences of feeTokenID, tokenID and
tx.feeTokenID in this document and ensure output comments and explanatory text
consistently reference the same registry ID or call out when a different token
is being demonstrated.

Comment on lines +188 to 189
feeTokenID: 4, // Token Registry ID for USDT
feeLimit: 252637086960555000n, // Max token payment
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Inconsistent feeTokenID values in documentation.

The examples now consistently use feeTokenID: 4 (USDT), but there are inconsistencies in the output comments that were not updated:

  • Line 290: // => [{ tokenID: 6, tokenAddress: "0x..." }, ...]
  • Lines 505-506: console.log(tx.feeTokenID); // 6

Consider updating these output comments to maintain consistency, or clarify that tokenID: 6 represents a different token in the registry output.

🤖 Prompt for AI Agents
In `@docs/build-on-morph/sdk/js-sdk.mdx` around lines 188 - 189, Update the
inconsistent token ID comments to match the example's feeTokenID of 4: change
the sample output comment that shows "tokenID: 6" to "tokenID: 4" (or explicitly
state that tokenID 6 refers to a different registry token), and change the
console output comment for tx.feeTokenID to reflect 4 instead of 6; search for
occurrences of feeTokenID, tokenID and tx.feeTokenID in this document and ensure
output comments and explanatory text consistently reference the same registry ID
or call out when a different token is being demonstrated.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@src/components/AltFee/AltFeeQuickStartDemo.tsx`:
- Around line 48-55: The executeSend function currently re-derives the signing
account inside executeSend using privateKey, which can drift if the user edits
privateKey after confirming; modify the confirm flow so the account is derived
and captured at confirmation time and included in ConfirmPayload (e.g., add an
account or signer field to ConfirmPayload when opening the confirm modal), then
in executeSend use the passed payload.account for signing instead of re-reading
privateKey; ensure privateKeyToAccount(privateKey.trim() as `0x${string}`) is
called when building the confirm payload (not in executeSend) and that
executeSend only trusts payload.account for tx signing to prevent account drift.
- Around line 67-69: The call that computes the transaction nonce in
AltFeeQuickStartDemo.tsx uses publicClient.getTransactionCount({ address:
account.address }) which defaults to blockTag "latest" and can return a nonce
that's too low if there are pending transactions; update the call to include
blockTag: "pending" so the pending transaction count is considered (i.e., call
publicClient.getTransactionCount with address: account.address and blockTag:
"pending") to prevent "nonce too low" errors when transactions are queued.
🧹 Nitpick comments (1)
src/css/figma-overrides.scss (1)

957-959: Scope the card button padding override to Alt Fee only.

.card__body .button applies site‑wide and can unintentionally change other card button sizing. Prefer scoping to .alt-fee-card to avoid regressions.

♻️ Proposed fix
-.card__body .button {
+.alt-fee-card .card__body .button {
   padding: 10px 10px;
 }

Comment on lines +48 to +55
const executeSend = async (payload: ConfirmPayload) => {
setStatus("");
setTxHash("");

try {
setIsSending(true);
const account = privateKeyToAccount(privateKey.trim() as `0x${string}`);

Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Prevent confirm/send account drift.

executeSend re-derives the account from current privateKey state, so a user could change the key after the confirm modal appears and send from a different account than shown. Capture the account at confirmation time (or lock inputs while the modal is open) and reuse it for signing.

🐛 Suggested fix (capture account in confirm payload)
 type ConfirmPayload = {
+  account: ReturnType<typeof privateKeyToAccount>;
   accountAddress: `0x${string}`;
   recipient: `0x${string}`;
   amountEth: string;
   value: bigint;
   gasPayment: "token" | "native";
   feeTokenId?: number;
   feeLimit?: string;
 };

 const executeSend = async (payload: ConfirmPayload) => {
   setStatus("");
   setTxHash("");

   try {
     setIsSending(true);
-    const account = privateKeyToAccount(privateKey.trim() as `0x${string}`);
+    const account = payload.account;

     const publicClient = createPublicClient({
       chain: morphHoodiTestnet,
       transport: http(rpcUrl),
     });

 ...

-    const account = privateKeyToAccount(normalizedKey as `0x${string}`);
+    const account = privateKeyToAccount(normalizedKey as `0x${string}`);
     const recipient = (resolvedTo || account.address) as `0x${string}`;

     setConfirmData({
+      account,
       accountAddress: account.address,
       recipient,
       amountEth: trimmedAmount,
       value,
       gasPayment,
       feeTokenId: parsedFeeTokenId,
       feeLimit: gasPayment === "token" ? feeLimit.trim() : undefined,
     });
🤖 Prompt for AI Agents
In `@src/components/AltFee/AltFeeQuickStartDemo.tsx` around lines 48 - 55, The
executeSend function currently re-derives the signing account inside executeSend
using privateKey, which can drift if the user edits privateKey after confirming;
modify the confirm flow so the account is derived and captured at confirmation
time and included in ConfirmPayload (e.g., add an account or signer field to
ConfirmPayload when opening the confirm modal), then in executeSend use the
passed payload.account for signing instead of re-reading privateKey; ensure
privateKeyToAccount(privateKey.trim() as `0x${string}`) is called when building
the confirm payload (not in executeSend) and that executeSend only trusts
payload.account for tx signing to prevent account drift.

Comment on lines +67 to +69
const nonce = await publicClient.getTransactionCount({
address: account.address,
});
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# Find the viem version in the project
fd -t f "package.json" | head -5 | xargs cat | grep -A 2 -B 2 "viem"

Repository: morph-l2/morph-doc

Length of output: 344


🌐 Web query:

viem v2.44.4 getTransactionCount blockTag parameter API documentation

💡 Result:

In viem v2.x, publicClient.getTransactionCount accepts an optional blockTag to fetch an account’s transaction count (nonce) at a specific block tag (instead of a blockNumber).

Signature (relevant params):

  • address: Address (required)
  • blockNumber?: bigint (optional)
  • blockTag?: 'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' (optional) [1]

Example:

const nonce = await publicClient.getTransactionCount({
  address: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e',
  blockTag: 'safe',
})

[1]

Docs: getTransactionCount (JSON-RPC: eth_getTransactionCount) [1]

Sources


🏁 Script executed:

# Read the actual file to verify the code and context
wc -l "src/components/AltFee/AltFeeQuickStartDemo.tsx"

Repository: morph-l2/morph-doc

Length of output: 112


🏁 Script executed:

# Read lines 60-80 to get context around lines 67-69
sed -n '60,80p' "src/components/AltFee/AltFeeQuickStartDemo.tsx"

Repository: morph-l2/morph-doc

Length of output: 613


Use pending nonce to avoid "nonce too low" errors with queued transactions.

Without blockTag: "pending", getTransactionCount uses the default "latest" tag and only counts confirmed transactions. If a user has pending transactions, this can reuse a nonce and fail. Add blockTag: "pending" to account for pending transaction count.

♻️ Proposed fix
-      const nonce = await publicClient.getTransactionCount({
-        address: account.address,
-      });
+      const nonce = await publicClient.getTransactionCount({
+        address: account.address,
+        blockTag: "pending",
+      });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const nonce = await publicClient.getTransactionCount({
address: account.address,
});
const nonce = await publicClient.getTransactionCount({
address: account.address,
blockTag: "pending",
});
🤖 Prompt for AI Agents
In `@src/components/AltFee/AltFeeQuickStartDemo.tsx` around lines 67 - 69, The
call that computes the transaction nonce in AltFeeQuickStartDemo.tsx uses
publicClient.getTransactionCount({ address: account.address }) which defaults to
blockTag "latest" and can return a nonce that's too low if there are pending
transactions; update the call to include blockTag: "pending" so the pending
transaction count is considered (i.e., call publicClient.getTransactionCount
with address: account.address and blockTag: "pending") to prevent "nonce too
low" errors when transactions are queued.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@docs/build-on-morph/sdk/js-sdk.mdx`:
- Around line 885-889: The documentation example uses an outdated RPC URL in the
console output comment; update the comment that logs MORPH_HOODI_TESTNET.rpcUrl
to the current URL (`https://rpc-hoodi.morph.network`) so it matches the rest of
the docs and the value provided by the MORPH_HOODI_TESTNET.rpcUrl constant;
locate the example using the symbols MORPH_MAINNET, MORPH_HOODI_TESTNET and the
rpcUrl property and replace the old URL text in the comment accordingly.
♻️ Duplicate comments (1)
docs/build-on-morph/sdk/js-sdk.mdx (1)

405-406: Note: Inconsistent output comment persists at line 506.

The serialization examples here correctly use feeTokenID: 4, but as flagged in a previous review, line 506 still shows // 6 in the parsing output comment. Consider updating for consistency.

Also applies to: 438-439

🧹 Nitpick comments (1)
src/css/figma-overrides.scss (1)

957-959: Scope the card button padding override to avoid global side effects.

.card__body .button will shrink buttons across all cards. If this is only for Alt Fee demos, consider scoping it to the Alt Fee card body.

♻️ Proposed scoping change
-.card__body .button {
+.alt-fee-card__body .button {
   padding: 10px 10px;
 }

Comment on lines +885 to 889
import { MORPH_MAINNET, MORPH_HOODI_TESTNET } from "@morph-network/chain";

console.log(morphMainnet.id); // 2818
console.log(morphHoodiTestnet.rpcUrls.default.http[0]); // https://rpc-hoodi.morphl2.io
console.log(MORPH_MAINNET.chainId); // 2818
console.log(MORPH_HOODI_TESTNET.rpcUrl); // https://rpc-hoodi.morphl2.io
```
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Inconsistent RPC URL in documentation.

Line 888 shows the old RPC URL https://rpc-hoodi.morphl2.io, but line 356 documents the updated URL as https://rpc-hoodi.morph.network. The comment should be updated for consistency.

📝 Suggested fix
-console.log(MORPH_HOODI_TESTNET.rpcUrl); // https://rpc-hoodi.morphl2.io
+console.log(MORPH_HOODI_TESTNET.rpcUrl); // https://rpc-hoodi.morph.network
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import { MORPH_MAINNET, MORPH_HOODI_TESTNET } from "@morph-network/chain";
console.log(morphMainnet.id); // 2818
console.log(morphHoodiTestnet.rpcUrls.default.http[0]); // https://rpc-hoodi.morphl2.io
console.log(MORPH_MAINNET.chainId); // 2818
console.log(MORPH_HOODI_TESTNET.rpcUrl); // https://rpc-hoodi.morphl2.io
```
import { MORPH_MAINNET, MORPH_HOODI_TESTNET } from "@morph-network/chain";
console.log(MORPH_MAINNET.chainId); // 2818
console.log(MORPH_HOODI_TESTNET.rpcUrl); // https://rpc-hoodi.morph.network
🤖 Prompt for AI Agents
In `@docs/build-on-morph/sdk/js-sdk.mdx` around lines 885 - 889, The documentation
example uses an outdated RPC URL in the console output comment; update the
comment that logs MORPH_HOODI_TESTNET.rpcUrl to the current URL
(`https://rpc-hoodi.morph.network`) so it matches the rest of the docs and the
value provided by the MORPH_HOODI_TESTNET.rpcUrl constant; locate the example
using the symbols MORPH_MAINNET, MORPH_HOODI_TESTNET and the rpcUrl property and
replace the old URL text in the comment accordingly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants