Per-User RPC and Transaction Authorizations
What it is (Overview)
Prividium™ exposes a Per-User RPC endpoint that embeds a user-scoped token in the RPC URL. This enables wallets to call JSON-RPC without attaching a bearer JWT on every request, while still enforcing user-level authorization and transaction constraints through the Permissions API.
A transaction authorization is a single-use, short-lived capability: the user pre-authorizes one specific transaction (exact wallet, recipient, nonce, calldata, and value) for a limited time, so the wallet can submit exactly that transaction and nothing else.
- The Per-User RPC endpoint is
POSTat:/rpc/wallet/{token}(served by the Prividium™ api) - The token is issued by the Permissions API and stored per user
- Prividium™ api validates the token and enforces transaction authorizations before delegating to the target RPC
End-to-end sequence of a transaction using the Per-User RPC URL
Token lifecycle
- Issue or fetch user's token (auth required):
GET /api/wallet/personal-rpc-token- If none exists, one is generated and stored on the user record
- Rotate/Invalidate token (auth required):
POST /api/wallet/invalidate- Generates and stores a new token; previous token becomes invalid
Token format: 16 hex characters (64 bits of entropy) generated via randomBytes(8).toString('hex').
Wallet RPC behavior (mocked and filtered)
For privacy and policy enforcement, the wallet RPC route restricts and/or mocks certain methods:
eth_getBlockByNumber: returns a real block number, while other block fields are mocked and the transactions list is always empty.eth_getBlockByHash: returns a mocked block with an empty transactions list. It does not reveal transaction hashes.eth_getTransactionReceipt: returns a receipt only for the transaction hash stored on the active authorization. It returnsnullfor any other hash. Before the target RPC reports a mined receipt, it can also returnnullfor the stored hash.eth_getCode: returns '0x' for the authorized wallet address (EOA), and a dummy code for any other address (treated as contracts).eth_getTransactionCount: returns the real nonce only for the authorized wallet address. Returns a forbidden error for any other address.- Many other methods are forbidden to avoid data leakage and side‑channel discovery (e.g., eth_estimateGas, eth_call, logs/filters, etc.).
Transaction authorizations
Transaction authorizations restrict what a token can do on-chain for a limited time window.
- Authorize a transaction (auth required):
POST /api/wallet/transaction-authorization- Body includes:
walletAddress,toAddress,nonce,calldata,value - Send the exact transaction
value. Use0when the transaction sends no ETH. - Active for 1 hour from creation
- Purpose: pre‑authorizes a single transaction shape for a short window, binding the user's wallet, target contract, nonce, calldata, and value. Required before submitting the signed transaction via the Per-User RPC URL.
Wallet RPC handlers in the Proxy enforce transaction authorizations. For example, balance queries are allowed only for
the wallet address in the authorization, and raw transactions are checked against the enabled from, to, nonce,
calldata, and value.
Authorization flow (step-by-step)
- Authorize: client (with user auth) calls api
POST /api/wallet/transaction-authorizationwithwalletAddress,toAddress,nonce,calldata,value. Send0when the transaction sends no ETH. The Permissions API stores a transaction authorization active for 1 hour. - Submit tx: dapp calls api
POST /rpc/wallet/{token}witheth_sendRawTransaction.- Prividium™ api decodes tx to
from,to,nonce,calldata,valueand checks exact match against the latest active authorization.
- Prividium™ api decodes tx to
- On success: Prividium™ api forwards to target RPC and stores the resulting
transactionHashon the authorization. - Post‑tx reads:
eth_getBlockByHashstays mocked and returns an empty transactions list.eth_getTransactionReceiptaccepts only the transaction hash stored on the active authorization. It returnsnullfor any other hash. It can also returnnulluntil the target RPC exposes a mined receipt for that hash.
- Expiry: When
activeUntilpasses or no authorization exists, wallet RPC calls become unauthorized or return empty results depending on the method.
Using it (SDK and User Panel)
- Prividium™ SDK:
getWalletToken()andgetWalletRpcUrl()helpersgetWalletRpcUrl()derives${PERMISSION_API_URL}/rpc/wallet/{token}from the configured API base URL
- User Panel: Fetches token and offers "Add Network to Wallet", passing the
${PERMISSION_API_URL}/rpc/wallet/{token}as the RPC URL to the wallet
Enabling via configuration
- Disabled by default: the per-user wallet RPC routes are not exposed unless explicitly enabled.
- How to enable:
- Set the Prividium™ API configuration flag to true (environment variable
WALLETS_API_ENABLED=true). - When enabled, the Prividium™ API registers:
POST /rpc/wallet/{token}(wallet RPC endpoint)- Wallet token and authorization routes under
/api/wallet/*
- Set the Prividium™ API configuration flag to true (environment variable
Security considerations
- Token is a bearer secret. Treat it like a password in URLs (rotate if leaked).
- 64-bit entropy (16 hex chars). Use HTTPS to prevent interception.
- Tokens do not expire automatically; rotation replaces the previous token.
- Transaction authorizations significantly limit what can be performed via the tokenized RPC by binding specific
walletAddress,toAddress,nonce,calldata, andvalue, and by time window.