Skip to content

docs(near): add NEAR chain page, changelog stream, and intents-flows guide - #431

Open
shahan-khatchadourian-anchorage wants to merge 3 commits into
mainfrom
shahankhatchadourian/near-c-docs
Open

docs(near): add NEAR chain page, changelog stream, and intents-flows guide#431
shahan-khatchadourian-anchorage wants to merge 3 commits into
mainfrom
shahankhatchadourian/near-c-docs

Conversation

@shahan-khatchadourian-anchorage

@shahan-khatchadourian-anchorage shahan-khatchadourian-anchorage commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Sixth PR of the NEAR chain-support stack (stacked on #430). Documents NEAR on the docs site (visualsign.dev).

Stack: A1 (#425) -> A2 (#426) -> A3 (#428) -> A4 (#429) -> B (#430) -> C (this) -> D (wallet-signed token metadata).

What this PR does

  • docs/chains/near.mdx: mirrors chains/tron.mdx's structure -- the two input formats under one CHAIN_NEAR identity, the intent-type table, signature standards, visualization strategy, and parser_cli examples for both a transaction and an intents envelope.
  • docs/changelog/near.mdx: a new changelog stream. Page shell only (frontmatter, subscribe/filter line) with no <Update> block -- this repo's changelog is curated at release time from draft fragments (docs/changelog/_drafts/README.md), so a PR author doesn't fabricate a release version. changelog.mdx's stream index and the drafts README's category list both gain a near entry.
  • docs/changelog/_drafts/2026-07-30-near-chain-launch.md: the draft fragment for this stack's own user-facing change, per that workflow.
  • docs/wallet-integration/dapps/near-intents.mdx: the three flows a NEAR Intents user signs -- deposit and withdraw (ordinary NEAR transactions) and the pre-signature intent envelope in between -- with real, parser_cli-verified request/response examples for each, the shared envelope format, and the implicit-account model.
  • docs/wallet-integration/core-concepts/how-parsing-works.mdx: NEAR added to the chain-agnostic input-format table.

Verification

  • Every parser_cli output shown in these pages was generated by an actual run and copied verbatim (not hand-typed or reformatted) -- including the exact --output json key ordering and the FallbackText field on every entry.
  • make -C docs broken-links passes with the same 7 pre-existing rss.xml false positives every existing chain/blog page already has (Mintlify-hosted feeds the local checker can't resolve) -- zero new broken links or anchors.
  • Internal review checked every factual claim in both new content pages against the actual visualsign-near source (the intent-type table field-by-field against render.rs, the signature-standard list against standard_name(), the format-discrimination description against tx.rs) and caught two inaccuracies before this PR was opened: the add_public_key/remove_public_key table row used the wrong field label, and the deposit example's JSON blocks didn't match the real serialization shape (missing FallbackText, wrong key order) -- both fixed with real, re-verified output.

@shahan-khatchadourian-anchorage shahan-khatchadourian-anchorage changed the title shahankhatchadourian/near c docs docs(near): add NEAR chain page, changelog stream, and intents-flows guide Jul 31, 2026
@shahan-khatchadourian-anchorage
shahan-khatchadourian-anchorage force-pushed the shahankhatchadourian/near-c-docs branch from 7b543f0 to 244a62e Compare July 31, 2026 10:48
@shahan-khatchadourian-anchorage
shahan-khatchadourian-anchorage force-pushed the shahankhatchadourian/near-c-docs branch from 244a62e to d7f238b Compare July 31, 2026 10:53
@shahan-khatchadourian-anchorage
shahan-khatchadourian-anchorage marked this pull request as ready for review July 31, 2026 10:58
Copilot AI review requested due to automatic review settings July 31, 2026 10:58

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds NEAR documentation to the Mintlify docs site (visualsign.dev) to complete the NEAR-consolidation stack, covering NEAR chain decoding, NEAR Intents signing flows, and a dedicated NEAR changelog stream aligned with the existing draft-fragment workflow.

Changes:

  • Introduces a new NEAR chain page describing input formats, intent types, signature standards, and parser_cli usage.
  • Adds a NEAR Intents flows guide for wallet/dApp integrations with real parser_cli-verified examples.
  • Adds a NEAR changelog stream (index + stream page) and a corresponding draft changelog fragment/category wiring.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
docs/wallet-integration/dapps/near-intents.mdx New guide describing the three NEAR Intents user-signing flows with example inputs/outputs.
docs/wallet-integration/core-concepts/how-parsing-works.mdx Adds NEAR to the input-format/encoding overview table.
docs/docs.json Adds NEAR pages to navigation (dApps section, Chains section, Changelog streams).
docs/changelog/near.mdx New NEAR changelog stream shell with RSS link and tag filter line.
docs/changelog/_drafts/README.md Updates the draft workflow docs to include the new near category and stream page.
docs/changelog/_drafts/2026-07-30-near-chain-launch.md Draft fragment announcing NEAR chain + NEAR Intents preset support.
docs/changelog.mdx Adds NEAR to the changelog stream index cards.
docs/chains/near.mdx New NEAR chain documentation page (formats, intent table, standards, visualization strategy, CLI examples).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread docs/chains/near.mdx Outdated
Comment thread docs/chains/near.mdx Outdated

NEAR carries two distinct payload shapes under a single `CHAIN_NEAR` identity, discriminated purely by input format:

- **A borsh-encoded transaction** (`near::sign_transaction`) — the standard NEAR wire format (`near-primitives::Transaction`, signed or unsigned), hex or base64 encoded.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed — now reads near_primitives::transaction::Transaction or SignedTransaction, matching the actual types in tx.rs.

Comment thread docs/wallet-integration/core-concepts/how-parsing-works.mdx Outdated

@prasanna-anchorage prasanna-anchorage left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The prose here is the best writing in the stack. The format-discrimination explanation, the fail-closed args-decoding rationale, the note that storage_deposit is a second unrefunded debit, the warning that a wrong decimals would silently misrender -- these read like they were written by someone who understands why each decision was made, not just what the code does. The intent-type table matches render.rs field-for-field; I checked every row.

I also want to credit line 54 specifically: "Verification recovers a signing key; it does not prove that key controls the claimed account." That's the #428 finding, fixed in prose before I raised it. It's the stack invariant applied exactly right -- the doc states what was checked and stops there.

Blocking on one thing, mechanical but user-facing: all four parser_cli outputs on these pages show a payload type the parser doesn't emit. I ran the two documented commands verbatim against this branch:

documented:  Type: VisualSign
actual:      Type: NearTx

Same for the two JSON blocks in near-intents.mdx ("PayloadType": "VisualSign" vs "NearTx"). Everything else in all four blocks is byte-accurate -- I diffed them field by field, including FallbackText and key ordering, and even re-ran the ft_transfer_call deposit example after wrongly suspecting its Amount shape was hand-written. It wasn't; it's exact. Only this one field is wrong, consistently, in all four places.

This is the same fabricated string that's failing CI on #430, where two e2e tests assert "PayloadType": "VisualSign". Six occurrences across two PRs, both stating the output was copied verbatim from real runs. It looks less like a typo than a snippet template with VisualSign baked in that's being reused across pages -- worth finding and fixing at the source, because the next page will inherit it too. Related: the deposit example's command is -t <borsh-encoded-transaction-hex>, a placeholder, so that block can't have been produced by running what's shown.

I'd rather flag this bluntly than politely, because "generated by an actual run and copied verbatim" is a claim reviewers lean on -- I skipped re-verifying several blocks on that basis before deciding to check. It's a genuinely good practice and worth keeping; it just has to be true.

Minor: line 116 documents --network as "accepted for parity but isn't used today", which is accurate now but contradicts what I asked for on #430 (erroring rather than silently ignoring). Whichever way that lands, this line moves with it.

Comment thread docs/chains/near.mdx Outdated
```
┌─ Transaction: Transfer
│ Version: 0
│ Type: VisualSign

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Type: VisualSign should be Type: NearTx, here and at line 103.

I ran the exact command in the block above against this branch:

┌─ Transaction: Transfer
│  Version: 0
│  Type: NearTx
│
└─ Fields:
   ├─ Network: NEAR Mainnet
   ├─ From: alice.near
   ├─ To: bob.near
   └─ Amount: 1 NEAR

Every other line matches what's documented exactly. The formatter prints the payload type straight through (parser/cli-core/src/output.rs:157 -- writeln!(f, "│ Type: {}", self.payload.payload_type)), and the crate's constant is NearTx, so VisualSign isn't a value this path can produce for any input.

Same fix at line 103 for the intents envelope block -- I ran that one too and it also prints Type: NearTx, with the remaining seven field lines matching character for character.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed — both occurrences now read Type: NearTx. Re-ran both commands against a built parser_cli to confirm the output matches exactly.

"Type": "text_v2"
}
],
"PayloadType": "VisualSign",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

"PayloadType": "VisualSign" should be "NearTx", here and at line 144.

I rebuilt this deposit transaction (ft_transfer_call to wrap.near with receiver_id: intents.near, 1 yocto deposit, 100 Tgas) and ran --output json against this branch. The response matches this block exactly -- Recipient as address_v2, Amount as amount_v2 with "Abbreviation": "raw token units", Deposit as 0.000000000000000000000001 NEAR, Gas as 100 Tgas -- with "PayloadType": "NearTx" as the only difference.

Worth saying I went in expecting the Amount entry to be wrong: push_amount_and_notes builds it with create_number_field, so I assumed it would serialize as a number type rather than amount_v2. It doesn't -- the wire shape is exactly what you documented. That block is accurate; only the payload type isn't.

The surrounding explanation is worth keeping as-is, particularly the note that this path's Amount stays in raw base units because the args decoder doesn't attempt token resolution, with the pointer to where resolution does happen. That's the kind of distinction that stops someone filing a bug against correct behavior.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed — both occurrences now read "PayloadType": "NearTx". Re-ran the JSON output against a built parser_cli to confirm it matches exactly.

Comment thread docs/chains/near.mdx Outdated

## Signature standards

The intents preset verifies all seven signature standards the protocol defines — NEP-413, ERC-191, TIP-191, raw ed25519, WebAuthn, TonConnect, and SEP-53 — using the protocol's own canonical implementation ([`near/intents`](https://github.com/near/intents)) rather than a reimplementation, so new intent variants and signing standards stay correct as the protocol evolves. Verification recovers a signing key; it does not prove that key controls the claimed account (no on-chain state is available to the parser to check that binding).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This sentence is right about the conclusion and wrong about the reason, and the reason matters because it's load-bearing for the fix.

"No on-chain state is available to the parser to check that binding" implies binding is inherently uncheckable here. But line 21 of this same page says accounts are "implicit -- derived deterministically from a public key, with no on-chain registration step", and that HSM keys "always produce implicit accounts: a 64-character hex string for ed25519 keys, an EVM-style 0x… address for secp256k1 keys."

If the account id is a deterministic function of the key, recomputing it from the recovered key needs no chain access at all. I confirmed this against #429's own fixtures -- the raw_ed25519 vector's public_key base58-decodes to exactly its signer_id:

ed25519:8rVvtHWFr8hasdQGGD5WiQBTyr4iH2ruEPPVfj491RPN
  -> 74affa71ab030d400fdfa1bed033dfa6fd3ae34f92d17c046ebe368e80d53751
signer_id:
     74affa71ab030d400fdfa1bed033dfa6fd3ae34f92d17c046ebe368e80d53751

and the ERC-191 generator derives its signer_id as 0x + keccak(pubkey)[12..], which inverts just as easily.

So the accurate statement is narrower: binding is verifiable offline for implicit accounts -- the case this page says HSM keys always produce -- and needs chain state only for named accounts like alice.near. As written, the doc discourages a check that's available for the dominant case.

Suggest something like: "For implicit accounts the recovered key can be checked against the account id directly, since the id is derived from the key. For named accounts, confirming the key is authorized requires on-chain state the parser does not have." This should move together with whatever #429 decides -- I raised the same point there against those fixtures.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed — rewritten to describe the tiered behavior: for an implicit account the account id is itself derived from the key, so the recovered key is compared against it directly (a mismatch renders as a hard finding, not a hedge); for a named account like alice.near, that binding genuinely needs on-chain access-key state the parser doesn't have, so it stays an explicit "not verified" caveat. Matches what landed in the intents preset and verification-tests PRs. Also caught and fixed a related stale line further down the page claiming --network "isn't used today" — that's no longer true after the CLI-wiring PR.

@pepe-anchor pepe-anchor left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Peer Review Summary — NEAR stack #431 (COMMENT)\n\n1 finding: 1 LOW. Detailed inline comment below.\n\nKey concern: Docs show Amount as AmountV2 but code produces Number field.


AI Review on behalf of @pepe-anchor. Please flag any inaccuracies.

"AmountV2": { "Abbreviation": "raw token units", "Amount": "1000000000000000000000000" },
"FallbackText": "1000000000000000000000000 raw token units",
"Label": "Amount",
"Type": "amount_v2"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[LOW] Deposit flow JSON example shows Amount as AmountV2 but code produces Number field

The deposit flow example (ft_transfer_call to wrap.near) shows the Args Amount field as an AmountV2 with "Abbreviation": "raw token units" and "Type": "amount_v2". The actual code in src/chain_parsers/visualsign-near/src/actions.rs, function push_amount_and_notes(), calls create_number_field("Amount", amount, "raw token units") which produces a SignablePayloadField::Number variant serialized as "type": "number" with a "Number": { "Number": "..." } structure. The correct output would look like:

{
  "FallbackText": "1000000000000000000000000 raw token units",
  "Label": "Amount",
  "Number": { "Number": "1000000000000000000000000" },
  "Type": "number"
}

The FallbackText and Label are correct; only the variant and its serialized shape are wrong. Wallet integrators who code against the JSON schema will parse the wrong type. The intents envelope's own Amount field (shown later in the same doc) correctly renders as AmountV2 because the intents render path uses create_amount_field via token_amount_field().


Authored by Claude on behalf of @pepe-anchor. Please flag any inaccuracies, I'm not always right.


Authored by Claude on behalf of @pepe-anchor. Please flag any inaccuracies, I'm not always right.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I think this one's inverted -- the doc is right and the suggested correction would introduce the error it's guarding against. Worth checking my working, since it turns on something non-obvious.

SignablePayloadField derives only Deserialize (visualsign/src/lib.rs:123); serialization goes through a hand-written impl Serialize (lib.rs:354), so the #[serde(rename = "number")] tag governs deserialization only and never appears in emitted JSON. That impl delegates to FieldSerializer::serialize_to_map (lib.rs:249), whose Number arm builds an AmountV2 and tags it "amount_v2", deriving Abbreviation as the remainder of fallback_text after the numeric value. get_expected_fields agrees (Number { .. } => push("AmountV2")), and Serialize hard-errors on any produced/expected mismatch, so a "Type": "number" payload isn't producible by this code.

Confirmed empirically rather than by reading: create_number_field("Amount", "1000000000000000000000000", "raw token units") serializes to

{"AmountV2":{"Abbreviation":"raw token units","Amount":"1000000000000000000000000"},"FallbackText":"1000000000000000000000000 raw token units","Label":"Amount","Type":"amount_v2"}

which is the documented example key for key.

So create_number_field vs create_amount_field is an internal distinction that doesn't reach the wire -- both emit amount_v2 -- which is exactly the kind of thing worth having asked about. No doc change; shout if you read the serializer differently.

@pepe-anchor
pepe-anchor force-pushed the shahankhatchadourian/near-c-docs branch from 5405f78 to dd7c503 Compare August 7, 2026 14:56
Base automatically changed from shahankhatchadourian/near-b-wiring to main August 7, 2026 17:33
…guide

Adds the docs.json-wired pages for NEAR:

- docs/chains/near.mdx: mirrors chains/tron.mdx's structure -- the two
  input formats under one CHAIN_NEAR identity, the intent-type table,
  signature standards, visualization strategy, and parser_cli examples
  for both a transaction and an intents envelope.
- docs/changelog/near.mdx: a new changelog stream (page shell only, no
  fabricated release version -- the actual <Update> block is added by
  a maintainer at curation time per the existing drafts workflow).
  changelog.mdx's stream index and docs/changelog/_drafts/README.md's
  category list gain a near entry.
- docs/changelog/_drafts/2026-07-30-near-chain-launch.md: the draft
  fragment for this migration's own user-facing change.
- docs/wallet-integration/dapps/near-intents.mdx: the three flows a
  NEAR Intents user signs -- deposit and withdraw (ordinary NEAR
  transactions) and the pre-signature intent envelope in between --
  with real, parser_cli-verified request/response examples for each,
  plus the shared envelope format and implicit-account model. Framed
  for wallet integrators rather than third-party dApp authors, since
  NEAR Intents is a single fixed protocol this parser already fully
  decodes, unlike Ethereum's arbitrary-contract ecosystem.
- docs/wallet-integration/core-concepts/how-parsing-works.mdx: NEAR
  added to the chain-agnostic input-format table.

All parser_cli output in these pages was generated and copied from
real runs, not hand-typed. make -C docs broken-links passes with the
same 7 pre-existing rss.xml false positives every existing chain page
already has (dynamically-generated feeds the local checker can't
resolve), zero new broken links.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- near.mdx, near-intents.mdx: "Type"/"PayloadType" examples said
  VisualSign; the crate's actual constant (and every rendered output)
  is NearTx. Verified all four occurrences by running the documented
  commands against a built parser_cli.
- near.mdx: "no on-chain state is available to check that binding" was
  wrong for implicit accounts -- the account id is itself derived from
  the key, so the recovered key is checked against it directly (a
  mismatch is a hard finding). Only named accounts genuinely need
  chain access the parser doesn't have. Matches the tiered check
  landed in the intents preset and verification-tests PRs.
- near.mdx: the --network line was stale after the CLI wiring PR;
  describes what --network actually does now (verified against the
  built CLI: mainnet default, testnet override, invalid-value error).
- near.mdx: near-primitives::Transaction -> the actual
  near_primitives::transaction::{Transaction, SignedTransaction} path;
  "a execute_intents" -> "an execute_intents".
- how-parsing-works.mdx: Hex/base64 -> Hex/Base64, matching every
  other row's capitalization.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
`changelog/near.mdx` carried a Subscribe link with no `<Update>` blocks
behind it -- the only changelog page in that state, since Mintlify builds
the feed from the entries on the page. The launch draft moves onto the page
as its first entry and is deleted from `_drafts/`, which is the flow
`_drafts/README.md` describes.

`description` normally carries the first release tag containing the change
(`git tag --contains <sha>`); NEAR is unreleased, so no such tag exists yet
and the attribute is omitted rather than guessed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants