NEP-641 is Final, and the last line of its Reference Implementation section reads:
TypeScript resolver (wallet-selector / NEAR Connect integration): TBD.
I would like to take that on. Starting this week, building in public, repo up in the next couple of days and I will report progress in this thread.
Before I get going I checked whether anyone already has. I could not find a GitHub repo or an npm package implementing it. Closest adjacent work I found is the near-sign-verify package by elliotBraem, which handles NEP-413 signature auth but not 641 resolution. If someone is working on this and I have missed it, please say so now and I will contribute there instead.
Why I care about this one
I came at 641 sideways. I was looking for a way to do selective disclosure on Intents, something an account holder could give an accountant or a counterparty to prove one transaction happened without opening up the entire account. There is nothing like that today, and 641 turns out to be most of the foundation already: the signed envelope, the five-axis replay binding, the delegation model, the NEP-413 bridge, and a payload that is deliberately opaque and would happily carry a disclosure claim.
But an attestation is worthless if the recipient cannot check it, and that recipient is in a browser, not a Rust toolchain. Right now RpcResolver only exists in Rust. So the TypeScript resolver is the thing standing in front of every offchain-auth use case, not only mine. Login flows, MPC signing approvals, confidential swap intents, all of them need a browser-side verifier before they are real.
Scope
Porting what crates/signatures/nep641 already does, in this order, publishing as each stage becomes independently useful:
OffchainMessageconstruction and the canonical hash, with vectors matching the Rust output:
SHA3-256(b"NEAR_NEP641_OFFCHAIN_MESSAGE/V1" || borsh(msg))
-
AccessKeyAuthorizationand the NEP-413 mapping, including therecipientstring format andnonceas canonical hash. This is the path most existing wallets need -
RpcResolver: block pinning, concurrent key and contract resolution, full-access precedence -
Recursive
pendingresolution with the per-edgeexpectequality checks, plus depth and count caps
The spec’s caller-side algorithm is detailed enough that most of this is a careful port rather than a design exercise, which is a compliment to the NEP.
Three questions
-
Where should it live? wallet-selector, NEAR Connect, standalone package, or inside
near/intents. I lean standalone first so anything can depend on it without pulling in a framework, then integrate. Happy to be told otherwise. -
Test vectors. Are there canonical ones from the Rust implementation I should match against, or should I generate them and propose them as fixtures? I would rather they be shared than mine.
-
Borsh and SHA3 in the browser. The Drawbacks section flags this. Any preference on dependencies, or should I keep it zero-dependency and inline what is needed?
One thing I know I cannot solve alone
Resolution needs live RPC against a pinned block, so you cannot verify from bytes alone. For login flows that is fine. For the audit case it is not, because what the recipient actually wants is a file they can keep and check next year. Local WASM execution is in Future Possibilities.
Not blocking on this, and it is a later problem than the resolver. But if anyone has thought about whether a narrower offline-verifiable subset is possible, I would like to hear it before I design the disclosure layer on top.
If either of the NEP authors is reading, I would particularly like to know whether the scope above matches what you had in mind for the TS side.
Repo and first commits shortly. Will keep this thread updated.
For context: I run Zcash India, where selective disclosure has been the central unsolved problem for years. That is what sent me looking here.
Jatin, Zcash India