Skip to content

[DOCS] handles page, and the onchain ACP sharing registry - #60

Merged
alexandrecarvalheira merged 2 commits into
mainfrom
docs/handles-and-onchain-acp
Aug 28, 2026
Merged

[DOCS] handles page, and the onchain ACP sharing registry#60
alexandrecarvalheira merged 2 commits into
mainfrom
docs/handles-and-onchain-acp

Conversation

@alexandrecarvalheira

Copy link
Copy Markdown
Collaborator

Item 3 on the queue: a home for wrap/unwrap, and a proper explanation of onchain shared ACPs.

New page: handles, wrap, and unwrap

unwrap and wrap existed only as bare signatures in the utility reference, which left unanswered the question they actually raise. The new page answers it.

Both are internal pure casts over the same bytes32. No cryptography, no TaskManager call, no storage. The load-bearing point:

Wrapping grants nothing. The type records what kind of value this is. The ACL decides whether you may use it. wrap touches only the first.

So FHE.wrapEuint32(someHandleFromAnEvent) succeeds, and the first FHE operation on it reverts. That asymmetry is the thing worth writing down, because the cast looks like acquisition and isn't.

The page covers when unwrap is right (generic bytes32 slots, events, mapping keys, identity comparison as distinct from FHE.eq), when wrap is right (recovering a handle the contract already owns), and the case where neither is: a value that arrived from outside. That routes to the typed forms rather than a guarded bare handle, since there is one for every way a value can reach you.

Value came from Type Conversion
A user, offchain externalEuintXX + bytes proof FHE.asEuintXX(handle, proof)
Another contract, as an argument sharedEuintXX receiveEuintXXParam, checks sharer is msg.sender
Another contract, as a return value sharedEuintXX receiveEuintXXFromCall, checks sharer is the callee
Your own storage euintXX wrapEuintXX

Placed after inputs in Core Concepts, which is where the type families are introduced.

Onchain ACP sharing, expanded

Four lines and a code block became a method table with the actor, the transaction-versus-read distinction, and the registry config shape.

Verified against the published ACP page, not just the SDK source, which corrected four things I had wrong or missing: shareOnChain returns { txHash, shareId }; getIncomingShares filters to still-importable shares; importFromChain also stores and activates the ACP; and cancelShare only works on a share not yet imported.

One claim removed. I had written that dismissShare and cancelShare "do the same thing, either side can clear a share." The first half is true, both resolve to the same removeShareOnChain(shareId) in the SDK. The second half was my inference from identical implementations, and I never verified what the registry contract authorizes per caller. The note now says only what I can back.

Also adds the privacy caveat: posting onchain makes the issuer-to-recipient relationship public, which the offline route avoids.

Vale and lint-docs.py exit 0. mint validate and mint broken-links --check-anchors --check-redirects pass.

🤖 Generated with Claude Code

alexandrecarvalheira and others added 2 commits August 28, 2026 12:09
…oes not give you

unwrap and wrap were documented only as bare signatures in the utility
reference, which left the question they actually raise unanswered.

The new page states it: both are internal pure casts over the same
bytes32, and wrapping grants nothing. The type records what kind of value
this is, the ACL decides whether you may use it, and wrap touches only
the first. Wrapping an arbitrary handle succeeds; the first FHE operation
on it reverts.

Covers when unwrap is right (storage slots, events, mapping keys,
identity comparison), when wrap is right (recovering a handle the
contract already owns), and routes the arrived-from-outside case to the
typed forms rather than a guarded bare handle: externalEuintXX with its
proof, receiveEuintXXParam for an argument, receiveEuintXXFromCall for a
return value.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The section was four lines and a code block. It now covers who calls each
method, which of them send transactions, and what the registry does.

Checked against the published ACP page rather than the SDK source alone,
which corrected four things: shareOnChain returns { txHash, shareId },
getIncomingShares filters to still-importable shares, importFromChain
also stores and activates the ACP, and cancelShare only works on a share
that has not been imported yet.

Drops a claim I could not support. Both cancelShare and dismissShare
resolve to the same registry call in the SDK, but that does not mean
either party can clear any share, since the registry's own authorization
was not verified. The note now says only that they share a call and are
named for who is acting.

Adds the privacy caveat: posting onchain makes the issuer to recipient
relationship public, which the offline route avoids.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@mintlify

mintlify Bot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
fhenix 🟢 Ready View Preview Aug 28, 2026, 3:11 PM

@alexandrecarvalheira
alexandrecarvalheira merged commit 38ab9b9 into main Aug 28, 2026
3 checks passed
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.

1 participant