NEVER WALLET · DEVELOPER API
Authentication for connected applications
Never Wallet provides a managed authorization service for registered organizations. Integrate an existing application with the Never Wallet SDK or WalletConnect to bind users, request approval for a specific action, and verify signed authorization results. Wallet keys remain with the user.
Platform architecture
Each registered application is associated with one organization identity, permitted origins, client credentials, and optional result callback configuration. The Never Wallet managed authentication service isolates requests by application and organization. The organization’s existing application initiates actions and verifies the resulting receipt; Never Wallet operates the authorization service and wallet-facing endpoints.
Creates a scoped challenge for its authenticated user and calls the Never Wallet API with provisioned client credentials.
Checks the registration and wallet binding, maintains expiring session state, verifies the wallet response, and signs the result.
Displays the action, performs local user verification, and signs using the registered wallet authentication key.
Applications may use their existing backend or a server-side function to keep API credentials private and verify receipts. A browser-only integration must not contain an application secret. No blockchain contract is required for sign-on or off-chain authorization.
Integration capabilities
| Capability | Integration | Result |
|---|---|---|
| Organization user binding | SDK or WalletConnect binding request | Registered wallet public key bound to an application subject. |
| Application sign-on and action approval | Authorization envelope and wallet approval | Signed receipt scoped to the application, user, nonce, and action. |
| Local user verification | Wallet-controlled passkey or device biometric prompt | Wallet signature after local approval; biometric data is never returned to the application. |
| Protected x402 resource | Short-lived envelope for an allowlisted HTTPS GET URL | Desktop wallet opens the exact resource; payment, if requested, receives separate review. |
| SafePay recipient approval | Wallet user flow for destination address, passphrase, and optional location policy | Verified recipient authorization before the sender signs a separate transfer. |
| Location policy | Wallet-registered policy or sender-selected SafePay pin | Signed, time-bound attestation evaluated for the selected SafePay session. |
WalletConnect pairing may begin with its normal connection QR. Scanning a QR establishes the transport; the wallet’s approval and the application’s receipt verification complete sign-on.
Registration and setup
- Register the organization and application with Never Wallet. Never Wallet provisions
applicationId,organizationId, permitted HTTPS origins, protected resource origins where applicable, and an application credential. - Configure the supplied Never Wallet application and wallet API origins. Never Wallet operates these endpoints; no organization-hosted auth service is required.
- Place the provisioned mTLS credential or HMAC secret in the existing application’s server-side environment. Do not embed it in a webpage or mobile bundle.
- Install the SDK with
npm install ./neverwallet-sdk-2.1.0.tgz. Use the installed desktop wallet for local SDK transport or establish an approved WalletConnect session for that transport.
Initialize the client in the application’s trusted server-side code. The URLs below are configuration values supplied during registration, not organization-owned auth hosts.
import { NeverWalletAuthServerClient } from '@neverwallet/sdk/server';
const authClient = new NeverWalletAuthServerClient({
authServerOrigin: process.env.NEVERWALLET_APP_API_ORIGIN,
applicationId: process.env.NEVERWALLET_APPLICATION_ID,
hmacSecret: process.env.NEVERWALLET_APP_HMAC_SECRET
});
// A provisioned mTLS certificate/key/CA may be used instead of hmacSecret.
// Keep all application credentials in trusted server-side code.For HMAC mode, the SDK signs each request with a timestamp, request ID, and SHA-256 body digest. The managed service validates the registered client and rejects replay. Exact origins and credentials are assigned per application.
1. Bind an organization user
The application creates an expiring binding request for its authenticated user. Deliver the request by SDK or WalletConnect. The wallet performs fresh local verification and returns a public-key proof; the application submits that proof to the Never Wallet managed service.
import { createNeverWalletBindingRequest } from '@neverwallet/sdk/server';
const request = createNeverWalletBindingRequest({
applicationId: 'acme-production',
organizationId: 'acme',
subjectId: appUser.id,
requestOrigin: 'https://app.acme.example'
});
// Return request to the authenticated browser over your own API.import { NeverWalletSDK } from '@neverwallet/sdk';
const { bindingProof } = await new NeverWalletSDK().requestBinding(request);
// Return bindingProof to the application’s trusted server-side function.// In trusted server-side code, using the provisioned API client:
await authClient.bindOrganizationUser({
bindingProof,
phone: appUser.mobileE164 // only where required by configured enrollment
});At protocol level the server endpoint is PUT /v2/organization-users/binding. It verifies the exact signed application/organization/subject/wallet key/origin/nonce/expiry tuple. A key replacement requires explicit recovery; do not silently overwrite a binding.
Desktop SDK transport
The installed Windows/Linux wallet runs a loopback bridge at http://127.0.0.1:34872. The SDK supports status(), ensureWallet(), requestBinding(), requestAuthorization(), and requestX402Session(). The bridge accepts only origin-bound request envelopes and streams status; it is not a remote public auth server.
import { NeverWalletSDK } from '@neverwallet/sdk';
const wallet = new NeverWalletSDK();
await wallet.ensureWallet();
const result = await wallet.requestAuthorization(envelope, { timeoutMs: 300000 });Bridge routes: GET /sdk/v2/status, GET /sdk/v2/status/events, POST /sdk/v2/requests with kind: binding | authorization | x402, and GET /sdk/v2/requests/{id}/events. Prefer the SDK wrapper; browsers must not put auth-server secrets in bridge requests.
WalletConnect transport
After the user approves a WalletConnect session, use the SDK adapter with the approved topic and chain ID. Set transport: 'walletconnect' before creating the authorization or protected-resource envelope, because transport is part of the signed claims.
import { NeverWalletWalletConnect } from '@neverwallet/sdk';
const wallet = new NeverWalletWalletConnect({
request: input => signClient.request(input),
topic: approvedTopic,
chainId: 'bip122:000000000019d6689c085ae165831e93'
});
const result = await wallet.requestAuthorization(envelope);Methods are neverwallet_bind, neverwallet_authorize, and neverwallet_x402. Use an envelope created for the same transport; the wallet must reject a changed origin, nonce, key, or destination.
Protected x402 session
An authenticated registered application may create an envelope for a single allowlisted HTTPS GET resource. The wallet checks the signed claims and makes a one-time direct claim to the Never Wallet service. The desktop wallet then opens a short-lived, restricted resource view. This is distinct from a general browser and distinct from SafePay.
import { createNeverWalletX402Session } from '@neverwallet/sdk/server';
const input = createNeverWalletX402Session({
organizationId: 'acme', subjectId: appUser.id,
walletKeyId: appUser.walletKeyId,
requestOrigin: 'https://app.acme.example', transport: 'sdk',
resource: {
url: 'https://api.acme.example/x402/session/123',
method: 'GET', description: 'Acme protected session'
}, expiresInSeconds: 180
});
const envelope = await authClient.createX402Session(input);
// Browser: await new NeverWalletSDK().requestX402Session(envelope);The Never Wallet service verifies the resource origin allowlist. An HTTP 402 resource may ask for a separately reviewed x402 v2 payment; the wallet checks exact chain/asset/amount/recipient/scheme and asks for fresh user approval. The operator of the protected resource validates and settles any x402 payment. Claiming the session alone neither transfers funds nor authorizes an unrelated action. The protected resource view is a desktop-wallet capability; mobile integrations can use WalletConnect authorization and protected code delivery.
The wallet claim endpoint is POST /v2/wallet/x402/sessions/{sessionId}/claim. Only the wallet should submit its one-use bearer token and bound key signature. The nine-character code delivery uses the same signed session mechanism as a separate authorization factor.
QR transport and local verification
WalletConnect can use a QR code to pair an application with Never Wallet. Pairing creates a transport session; it does not authenticate an organization user or approve an action. The registered application must still request neverwallet_bind for enrollment or neverwallet_authorize for an exact action, then verify the signed result.
- The application generates the request with a fresh nonce, application and organization IDs, subject ID, permitted origin, action hash, and expiry.
- The user opens the request in Never Wallet, reviews the displayed action, and completes the wallet’s local verification prompt.
- Never Wallet signs the exact request with the bound authentication key. The managed service verifies the response and produces a short-lived result receipt.
- The application checks every receipt claim and consumes its own pending browser session nonce before completing sign-on.
Passkey and biometric verification take place in the wallet/device context. The application receives the authorization result, not a fingerprint, facial image, passkey private key, or unrestricted signing capability. A dedicated single-scan cross-device login endpoint is not part of this API reference.
SafePay recipient authorization
SafePay creates an expiring recipient authorization session for a selected network and asset. The sender supplies a recipient address and passphrase, then shares the claim URL and passphrase through separate secure channels. The recipient must control the exact destination address, supply the passphrase, and, when selected, pass a location check. The sender reviews and signs the actual transfer after verification.
// Wallet-authenticated Never Wallet cloud route (not a public org API):
POST /v1/safepay/sessions
{
"network": "optimism-mainnet", "assetType": "native",
"asset": "", "tokenId": "", "amount": "1000000000000000",
"senderAddress": "0xSender...", "recipientAddress": "0xRecipient...",
"passphrase": "a secret shared outside the link",
"locationMode": "none", "expiresAt": "<ISO time 10 min to 366 days out>"
}
// 201: { "id": "...", "status": "waiting", "claimUrl": "https://neverwallet.app/safepay/?session=...", "expiresAt": "..." }locationMode is none, recipient (recipient’s registered policy), or pin (sender-selected coordinates, radius feet, maximum accuracy feet). Never Wallet stores a one-way Argon2 passphrase verifier and bounds retries. The recipient flow uses GET /v1/safepay/session/{token} and POST /v1/safepay/session/{token}/verify with a chain-specific signature over the exact session payload, passphrase, and any required location proof. Do not reproduce this signing format from prose; use the wallet implementation.
The SafePay session API accepts the following network and asset categories. Authorization does not by itself verify settlement on every network.
| Network IDs | Asset types |
|---|---|
ethereum-mainnet, ethereum-sepolia, polygon-mainnet, polygon-amoy, base-mainnet, base-sepolia, arbitrum-mainnet, arbitrum-sepolia, optimism-mainnet, optimism-sepolia | native, erc20, erc721, erc1155 |
solana-mainnet, solana-devnet | native, spl-token, spl-nft |
bitcoin-mainnet, bitcoin-testnet3 | native, inscription, rune |
The wallet displays its applicable setup fee and any chain transaction fee before the sender signs. Fee payment, authorization, and asset transfer are distinct operations.
Location policy and attestation
A recipient can register a wallet-specific location policy; SafePay can instead use a sender-selected pin. Both use latitude/longitude, radius, and maximum acceptable GPS accuracy. The map is an address/pin entry tool; the server compares coordinates and signed proof, not map tile pixels. The policy can be disabled by a new wallet-signed update.
POST /v1/safepay/location-policy/challenge
{ "network": "optimism-mainnet", "walletAddress": "0x..." }
// Wallet signs the returned nonce with its registered chain address.
PUT /v1/safepay/location-policy
{ "network": "optimism-mainnet", "walletAddress": "0x...",
"policy": { "latitude": 40.7, "longitude": -74.0,
"radiusMeters": 60.96, "maximumAccuracyMeters": 30.48 },
"signature": "<wallet signature over policy commitment>" }For a SafePay claim the authenticated recipient calls POST /v1/safepay/session/{token}/location-challenge, obtains a one-use challenge, and has the wallet create a signed attestation. The verifier checks request hash, nonce, registered device key, expiry, withinRequestedArea: true, and acceptable accuracy. It does not accept a mere browser-provided boolean as proof. The Never Wallet service stores registered policy coordinates for verification. The attestation includes the match result and accuracy without sending the measured GPS fix to the relying application.
The SafePay location challenge is bound to its recipient session. This endpoint is not a general location oracle for third-party contracts. Device or operating-system location can be spoofed; applications should treat GPS as an additional policy factor rather than absolute proof of physical presence.
Protocol endpoint reference
The managed Never Wallet service exposes separate application and wallet-facing interfaces. Application routes require the provisioned mTLS or HMAC credential; wallet routes use one-time envelope material and the bound wallet signature. Use the SDK client for application requests and the wallet adapter for wallet calls.
| Caller | Method and path | Purpose |
|---|---|---|
| Registered application, mTLS/HMAC | PUT /v2/organization-users/binding | Bind signed wallet public key to org subject. |
| Registered application, mTLS/HMAC | POST /v2/authorizations | Issue exact-action envelope and code delivery. |
| Registered application, mTLS/HMAC | GET /v2/authorizations/{challengeId}/result | Receipt recovery/status. |
| Registered application, mTLS/HMAC | POST /v2/x402/sessions | Issue one-resource signed x402 envelope. |
| Registered application, mTLS/HMAC | DELETE /v2/organizations/{organizationId}/subjects/{subjectId}/binding | Disable this org’s binding. |
| Wallet, bearer + signature | POST /v2/wallet/authorizations/{challengeId}/verify | Submit code and bound key signature. |
| Wallet, bearer + signature | POST /v2/wallet/x402/sessions/{sessionId}/claim | Claim signed protected resource/code session once. |
| Registered application | GET /.well-known/jwks.json | Obtain Ed25519 result verification keys. |
| Authenticated wallet/cloud | /v1/safepay/* | Session, recipient claim, location challenge and policy routes; not an org-server API. |
Errors include invalid origin/binding/signature, expired or replayed nonce, mismatched transport or wallet key, canceled wallet request, passphrase lock, missing recipient location policy, stale/mismatched location proof, and unsupported settlement verification. Fail closed and let the user start a fresh request; never silently fall back to a lower factor count.
On-chain integrations
Authentication and application sign-on use the managed Never Wallet API; organizations do not deploy an auth contract. An on-chain contract cannot query the user’s biometric sensor, GPS receiver, or a private authorization session. A dapp may request wallet approval through the integration described above and verify the result off-chain before it initiates a chain transaction.
Asset escrow is a separate integration. If a product requires funds to be held pending approval and automatically refunded at expiry, an EVM implementation must be deployed and reviewed on each EVM network it supports. Solana requires a Solana program; Bitcoin requires a Bitcoin-specific transaction/script design. Organization registration can be represented in managed platform configuration rather than a separate contract for each organization.
For an on-chain release condition based on an off-chain authorization, the asset-holding program would need to verify a domain-separated, short-lived attestation bound to the chain, contract, asset, recipient, session, nonce and deadline. Keep precise location coordinates and passphrases off-chain. An ordinary externally owned wallet transfer does not pass through a contract’s release policy unless the asset is deposited into that contract or controlled by a compatible smart account.
Security and operations
- Register exact application and resource origins. Keep application mTLS/HMAC credentials in trusted server-side infrastructure; never place them in browser code or QR content.
- Bind receipt validation to issuer, audience, application, organization, subject, key ID, nonce, action hash/type, origin, transport, expiry and result. Consume the pending app nonce once.
- Show user-readable action details in the wallet. Require new local verification for a new approval; passkey/biometric prompts do not disclose biometric data.
- For money movement, show chain, network, asset contract/mint, recipient, amount, fee, and deadline before signature. Do not treat SafePay authorization as an escrow or a blockchain confirmation.
- Do not log claim URLs, passphrases, submission tokens, full location policies, auth codes, private keys, or raw JWTs. Rate limit and expire sessions; revoke a lost organization binding and its active app sessions.
- Use HTTPS and separately configured keys in production. Test wrong org, wrong subject, replayed nonce, wrong origin, changed action, missing location, low GPS accuracy, expiration, and recipient mismatch.
Standards
- W3C Web Authentication — passkey and relying-party verification.
- ERC-1271 and ERC-4337 — EVM smart-account signature and execution patterns.
- Solana programs — chain-specific on-chain execution.
- x402 protocol — HTTP payment-required resource flow.
Protocol identifiers: neverwallet-org-auth/v2 for registered organization requests and neverwallet-x402/v1 for protected resource sessions. SDK package: @neverwallet/sdk, version 2.1.0.