nep641-ts: the TypeScript resolver NEP-641 lists as TBD
NEP-641 is Final, and the last line of its Reference Implementation section says the TypeScript resolver is TBD. Nothing implements it, so a NEP-641 authorization can be verified on a server or in a contract but not in a browser. That blocks two things the NEP itself names as target use cases, and both sit on the Intents roadmap: approving a confidential swap intent from a frontend, and dApp sign-in for accounts whose authority lives in contract code rather than an access key.
Half the work is already done, unfunded and public. nep641-ts 0.2.0 is on npm with 507 tests, near/intents#350 is approved by @frol, #351 is open, and near/NEPs#654 clarifies five things the spec left undocumented, at his request. One of those five is a case where the obvious TypeScript implementation accepts authorizations that deployed contracts reject.
This asks for $23,000 over twelve weeks to finish it: RpcResolver, recursive resolution, the error taxonomy Gem Wallet requested publicly, an integration adapter, and a 1.0 release. A disclosure profile is deliberately out of scope until the confidential model settles.
Everything is MIT and already public, so if this is declined the vectors, the spec clarifications and the package all remain. Funding buys a schedule.
Organization
Primary person’s contact information
Jatin Sahijwani
Email: jatinsahijwani2151@gmail.com
Telegram: @jatin102938
GitHub: jatinsahijwani (Jatin Sahijwani) · GitHub
Forum: Profile - jatinsahijwani - NEAR Forum
Size of the whole team
One. This is an individual proposal, not a company.
Size of the engineering team
One.
Team location
India.
Team background and bios
I build, and I run Zcash India, which I founded and have operated since February 2026.
I have completed a funded grant before: zero-knowledge developer tooling for the Arbitrum ecosystem, delivered through Questbook. Ten or more Web3 hackathon wins across several ecosystems before that.
Zcash India also runs OpenLightNodes, an independent lightwalletd node in Mumbai. Open source, wallet-usable, with a public status page. The grant proposal for it was declined by Zcash Community Grants. We kept it running anyway and it is still running.
I also have an open PR against the Zodl Android wallet adding Hindi localization, 1,051 strings plus the locale wiring.
There is prior NEAR contact too. In August we ran a joint event in Ahmedabad with NEAR Legion, 50+ attendees, on CrossPay and how NEAR Intents enable private cross-chain payments from shielded ZEC. Unpaid, and not a deliverable on either side.
Selective disclosure has been the central unsolved problem in the Zcash community for years. That is what brought me to NEAR’s confidential work, and from there to NEP-641.
Any affiliations with other NEAR ecosystem partners?
None. Zcash India is a separate ecosystem and is not a NEAR partner. No prior funding from the NEAR Foundation or any NEAR body.
Professional Experience
Examples of relevant experience with NEAR blockchain
All of the following are from the last three weeks and are publicly verifiable.
| Contribution | Status |
|---|---|
near/intents#350, canonical OffchainMessage hash vectors |
Approved by @frol |
| near/intents#351, 112 access-key and NEP-413 conformance vectors | Open |
| near/NEPs#654, non-normative clarifications to NEP-641 | Open, at @frol’s request |
| nep641-ts, the implementation | Published, 0.2.0 on npm, stages 1 and 2 complete, 507 tests |
| Forum thread | Open since 16 August, with the NEP author and Gem Wallet participating |
docs/SPEC-NOTES.md in that repository documents eleven divergences between the NEP prose and its Rust reference implementation, each cited to file and line at pinned commits and each verified against generated vectors rather than read from source alone. Five of those became the NEP clarification PR.
Non-technical capabilities
Community operations and developer relations, from running Zcash India. Started February 2026 with 1 X follower and 5 Telegram members, at 1,536 and 1,332 as of August, all organic with no paid promotion.
Seven months in: five monthly online events, every one over the 65 attendee target, three developer workshops, five offline events totalling 847+ attendees across five cities with a wallet created for almost every attendee, six completed bounty programmes, and five Indian businesses now listed on ZecMap as accepting ZEC.
Reported monthly on the Zcash community forum, same cadence I have used in the NEAR thread.
In-House Resources
Design, UX/UI: none, and none required. This is a library with no user interface.
Project management: self-managed, with progress reported publicly in the forum thread at each stage.
Customer support: I answer issues on the repository and questions in the forum thread.
BD / Marketing: not applicable, though I can bring the work in front of an Indian developer audience through Zcash India if that is useful.
Portfolio of relevant work
nep641-ts is the relevant portfolio, and it is the subject of this proposal. Stages 1 and 2 are complete and were built before any funding was requested.
Body
What is missing
NEP-641, “Offchain Authorizations for Smart Contracts”, is Final. The last line of its Reference Implementation section reads:
TypeScript resolver (wallet-selector / NEAR Connect integration): TBD.
Nothing implements it. I searched GitHub and npm before starting and again since, and found no repository or package that does. RpcResolver exists only in Rust, which means a NEP-641 authorization can be verified on a server or inside a contract, but not in a browser.
Why that matters to Intents specifically
The NEP names two target use cases. Both sit directly on the Intents roadmap.
“Offchain action approval: authorizing an MPC signing request, a confidential swap intent, or any other offchain action.” That phrase is from the spec. Approving a confidential swap intent from a frontend requires verifying a NEP-641 authorization in that frontend, which is not currently possible in TypeScript. This is Advancing Confidentiality Features on the roadmap: privacy features that are easier to use and cover more use cases.
“dApp sign-in: the dApp issues a fresh payload; the wallet contract attests it; the backend grants a session. No transaction, no access key.” This is the onboarding path for accounts whose authority lives in contract code rather than an access key, which includes passkey wallets, Ethereum-key wallets, multisigs and deterministic accounts. This is Improving User Access: simpler onboarding.
There is also a distribution argument. Brave Wallet now carries NEAR Intents to 110M+ monthly actives. When the surface is a browser wallet, “cannot be verified in a browser” stops being a theoretical gap in a standard and becomes a constraint on what can ship there.
One finding worth flagging
Writing the second implementation surfaced something the spec does not say.
The reference verifies ed25519 signatures with the cofactorless equation, after an explicit small-order key rejection. @noble/curves, the library any TypeScript implementer would reach for first, uses the cofactored equation by default. The two disagree on a public key carrying an order-8 torsion component, and the disagreement runs in the permissive direction: the obvious implementation accepts authorizations that deployed NEP-641 contracts reject. The key is not itself low order, so the weak-key check does not catch it.
The spec’s entire specification of signature verification is one sentence: “All native NEAR Protocol key types SHOULD be supported; access_key and signature curves MUST match.” The equation choice is left to the implementer, and the wrong choice is the default one.
That vector is now committed in #351, and the clarification is in near/NEPs#654 at @frol’s request. Ten further divergences of the same class are documented in docs/SPEC-NOTES.md, including two, subsecond timestamp rendering and path encoding in Borsh, where an implementation passes every test the reference ships and still produces a hash no contract accepts.
None of this makes NEP-641 flawed. But every additional TypeScript implementation will rediscover these at its own cost, and some will get them wrong silently. One correct implementation with the conformance suite upstream removes that risk once, for everyone.
Why fund this rather than build it internally
This is roughly an engineer-quarter. Half of it is already done, in public, at no cost to NEAR, and the maintainer of the reference implementation has approved a PR from it. The conformance vectors have already been contributed back to near/intents, so that work benefits the Rust implementation regardless of what happens to this proposal.
$23,000 is meaningfully less than a quarter of an Intents engineer’s time, and it does not consume the context of anyone currently shipping confidentiality features, trading capabilities or onboarding.
The downside is also small. Everything is MIT and already public. The conformance vectors go to near/intents regardless, the spec clarifications are in review at @frol’s request regardless, and 0.2.0 is on npm regardless. If this were declined tomorrow, or if I failed to deliver stages 3 and 4, NEAR keeps all of it. Funding buys a schedule and a finished resolver, not the difference between something and nothing.
Scope, licensing, and what is deliberately excluded
I have built stages 1 and 2 unfunded, to establish the work is real before asking for anything:
- Stage 1: the
OffchainMessageenvelope, its Borsh encoding, and the canonicalSHA3-256hash. Reproduces the Rust byte for byte across 21 generated vectors. - Stage 2:
AccessKeyAuthorization, the NEP-413 mapping and prehash, ed25519 and secp256k1 verification, and implicit account derivation. 507 tests against 135 generated vectors.
This proposal covers stages 3 and 4, which complete the resolver, plus the error taxonomy a wallet team asked for publicly, integration, and a 1.0 release.
Licensing. MIT, matching near/intents. Public and MIT from the first commit.
Naming. Published as nep641-ts rather than nep641, deliberately, since the bare standard name belongs with whatever NEAR considers canonical. Happy to republish under a NEAR-scoped name such as @near-js/nep641, or transfer it outright, if you would rather own the package.
Explicitly out of scope. A disclosure payload profile for NEP-641, which is what originally brought me to this work, is deliberately excluded. @frol relayed that the Intents team has that in their backlog and that pending changes to the confidential model may block it. Pricing work that may need rebuilding would waste your money and my time, so it is left for a separate proposal once that settles.
Goals / Milestones
The finished effort is a published, documented, framework-agnostic TypeScript package that resolves a NEP-641 authorization end to end in a browser, byte-compatible with the Rust reference and pinned by vectors generated from it.
| Milestone | Deliverable | Timeline |
|---|---|---|
| M1 | RpcResolver: block pinning, concurrent access-key and contract resolution, full-access precedence, and the chain-state checks deferred from stage 2 |
Weeks 1 to 4 |
| M2 | Recursive pending resolution with per-edge expect equality checks, depth and sub-authorization caps |
Weeks 4 to 6 |
| M3 | Typed error taxonomy, structured around the three categories Gem Wallet requested in the forum thread: temporary, account or permissions, invalid request. Structured type plus the underlying contract panic message preserved | Weeks 6 to 8 |
| M4 | Integration adapter for wallet-selector or NEAR Connect, whichever the maintainers prefer, with a PR opened and review iterated on. Priced small because merging it is their call, not mine | Weeks 8 to 10 |
| M5 | Documentation, conformance vectors upstreamed, 1.0 published to npm, maintenance handover note | Weeks 10 to 12 |
Twelve weeks from funding confirmation. Progress reported publicly in the existing forum thread at each milestone, as it has been for stages 1 and 2.
Metrics
- Conformance. Every published NEP-641 vector in
near/intentspasses against this implementation, and this package’s vectors go upstream so any future implementation in any language checks against the same set. Already true for stages 1 and 2, re-verified at every release. - Integration. wallet-selector or NEAR Connect depends on the package, or an equivalent path agreed with those maintainers, delivered in M4. Without this the work has not reached anyone.
- Wallet uptake. At least one NEAR wallet using the resolver in production or a public branch within three months of 1.0. Gem Wallet has already specified requirements for the error surface in the forum thread, which is why M3 exists.
- Adoption. npm weekly downloads and dependent repositories, reported at 1.0 and at three months. Currently zero, which is the point.
Competitor Comparison
There is no competitor. No GitHub repository and no npm package implements NEP-641 in TypeScript, checked before starting and again since. near-sign-verify by elliotBraem covers NEP-413 signature auth but not 641 resolution, which is a strictly smaller problem: it verifies one signature against one access key, where 641 resolves a recursive authorization graph across wallet contracts, extensions and multisigs, against a pinned block, with per-edge payload equality checks.
The alternative to funding this is not that nothing gets built. It is that each dApp writes its own partial resolver against a spec whose byte-level behaviour, as docs/SPEC-NOTES.md shows, is discoverable only by reading Rust, and gets the ed25519 equation wrong in the permissive direction.
Current Market Size
Every NEAR dApp doing sign-in without a transaction, every account governed by contract code rather than an access key, every MPC signing approval, and every confidential swap intent needs an offchain authorization verified somewhere. Today that can only happen server-side.
near/intents has 55 stars and 40 forks. NEP-641 is Final with a merged reference implementation, so this is a standard NEAR has already committed to rather than one seeking adoption. Confidential Intents is generally available through the 1Click Swap API, and the NEAR@3.33 milestone program targets $70M in confidential TVL.
Usage & Examples
npm i nep641-ts works today. 0.2.0 is on the registry, MIT, with the stage 1 and 2 surface usable now: message construction, the canonical hash, the NEP-413 mapping and prehash, ed25519 and secp256k1 verification, and implicit account derivation. Types ship with it and the README examples run against the published package.
Integration targets named by @frol in our first exchange: near.com and Trezu, the multichain treasury product. Shared treasuries are a natural early consumer, since an accountant or auditor needs authorizations verified in a frontend rather than through a backend they do not control.
Gem Wallet engaged in the forum thread unprompted and specified what they need from the error surface: whether a failure is temporary and retryable, related to the account or its permissions, or an invalid request. That requirement became milestone M3.
Vectors from this work are already flowing back upstream. #350 is approved and #351 is open, so the conformance suite improves for every implementation in every language, not only this one.
Budget
Budget Total
$23,000 USD.
Budget Breakdown
| Item | Amount |
|---|---|
M1: RpcResolver, block pinning, concurrent resolution, chain-state checks |
$8,500 |
M2: recursive pending resolution, expect checks, depth and count caps |
$5,500 |
| M3: typed error taxonomy | $3,500 |
| M4: integration adapter and PR | $2,000 |
| M5: documentation, upstreamed vectors, 1.0 release, maintenance handover | $3,500 |
| Total | $23,000 |
M4 is deliberately the smallest line. Building the adapter and opening the PR is mine to do; whether wallet-selector or NEAR Connect merges it is not, and I would rather not be paid as though it were. The weight sits on M1 to M3, which are the resolver itself and entirely within my control.
This is one individual’s time for twelve weeks. No infrastructure cost, no third-party service, no ongoing operational expense, because a library has none. Stages 1 and 2, roughly a third of the total work, are already complete and are not in this figure.
There is also no recurring dependency here. After 1.0 the package is small, pinned to a Final standard, and cheap to maintain, so this is a one-off build rather than a subsidy.
I will maintain it unfunded for at least six months past 1.0: bug fixes, dependency updates, and conformance against any new vectors in near/intents. If NEAR would rather own it outright before then, the transfer offer under Naming stands. Either way there is no second proposal for keeping this alive.
The scope and the milestone split are both open to being reshaped if a different structure fits how this normally gets funded.
Next step
A named reviewer on the Intents side who can send two things in writing: the preferred M4 integration target, wallet-selector or NEAR Connect or something else, and anything in the confidential model roadmap that should change this scope and that I cannot see from outside. I will take it from there and iterate in the thread. No meeting needed, async works better for something this specific and it leaves a record.
I will keep contributing conformance vectors and NEP clarifications either way. This proposal only decides whether the resolver gets finished on a schedule or in gaps between other work.
Package: https://www.npmjs.com/package/nep641-ts
Repository: GitHub - jatinsahijwani/nep641-ts: TypeScript implementation of NEP-641: offchain authorizations for NEAR smart contracts · GitHub
Forum thread: Building the TypeScript resolver for NEP-641 (currently listed as TBD)