Pay as you go
The public RPC is free and stays free, with the limits on that page. If you need more room than that gives (a bot, a backend, an indexer), you can add credit and use a key. You pay for what you use, from a balance you fill yourself. There is no plan to pick, no card and no email: an account is a wallet address.
Status. This is built and tested, and opens on the testnet once its deposit contract is deployed (the address will be on
this page and at GET https://testnet-rpc.vyrechain.com/v1/info, which always shows the prices and limits in force). The testnet's credit is test USDC and
a new account may be given a little free credit to try it. Nothing here changes the free RPC.
How it works
- Add credit. Call
deposit(account)on the credit contract with the USDC you want to add (the chain's own currency, sent as the call's value). The minimum is 1 USDC (minDepositUsdcinGET https://testnet-rpc.vyrechain.com/v1/infoshows the figure in force), so do not send less. The contract passes the whole amount on to VYRE's treasury in the same transaction and logs it; the service reads the log and adds the amount to the balance ofaccounta few seconds later. Anyone can deposit for any account, but the account must be an ordinary wallet that can sign a message (step 2): credit added to a contract wallet's address (a Safe or a smart wallet) cannot be used to make a key and is not returned by the contract. The service does not credit a deposit automatically if any of these is true, and by then the contract has already passed its money to the treasury, so write to team@vyrechain.com with the transaction and it can be credited by hand (credit added that way counts as a deposit, so the account is on the plan for accounts that have deposited):- the deposit is under the minimum (1 USDC);
- it would take the balance over the largest balance an account may hold (1,000,000 USDC);
- the amount is too large to be real, or the account is the zero address;
- the service already has as many depositing accounts as it allows.
- Make a key by signing a short message with the account's wallet. Nothing is sent and no gas is spent.
- Use the key in the URL,
https://testnet-rpc.vyrechain.com/v1/<key>, or in anAuthorization: Bearer <key>header onhttps://testnet-rpc.vyrechain.com/v1. It is the same JSON-RPC as the free endpoint, with the same methods, the same batches of up to 20 and the same limits on log queries. A request that holds a transaction to send (eth_sendRawTransactionand its variants) may hold at most 2 of them and, besides those, only simple lookups (eth_blockNumber, balances, receipts and the like); a request with a third send, or a send next to aneth_callor a log query, is refused whole with-32600, so send those in separate requests. - Watch it.
GET https://testnet-rpc.vyrechain.com/v1/usagewith the key shows the balance, today's use by method and the key's cap. - Change it whenever you like, by signing again: replace a key, set a daily spend cap on it, or revoke it. A revoked key stops working at once.
An account may hold up to 5 keys. Give each bot or app its own, with its own daily cap, so a leak costs at most that cap.
Making a key (JavaScript)
import { privateKeyToAccount } from 'viem/accounts';
const wallet = privateKeyToAccount(process.env.WALLET_KEY);
const base = 'https://testnet-rpc.vyrechain.com/v1/account';
const post = (path, body) => fetch(`${base}/${path}`, { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify(body) }).then((r) => r.json());
const ask = await post('challenge', { account: wallet.address, action: 'create-key', label: 'my bot', dailyCapUsdc: '5' });
const signature = await wallet.signMessage({ message: ask.message }); // read the message: it names this host, the account and what you are asking for
const made = await post('act', { nonce: ask.nonce, signature });
console.log(made.url); // https://testnet-rpc.vyrechain.com/v1/vk_... shown once: it is not kept anywhereThe other actions are rotate-key and revoke-key (with keyId), set-cap (with keyId and dailyCapUsdc, or none to lift
the cap) and list (ids, labels, caps and last use; never a key). A challenge is good for 5 minutes and for one try. Contract
wallets (which sign with ERC-1271) are not supported yet: sign with an ordinary wallet, and deposit from anywhere.
Compute units and prices
Every call costs compute units (CU). For an ordinary read one CU is about 250 microseconds of server time; a few calls are priced flat for now and can take the server
longer than their price suggests (eth_call and eth_estimateGas on a large transaction, eth_feeHistory over many blocks, eth_getProof and eth_getStorageValues with many keys), so the
in-flight and rate limits below, not the price, are what hold them, and the prices will be re-measured before the service is opened more widely. The price of a million CU is set by VYRE
and shown at GET https://testnet-rpc.vyrechain.com/v1/info; on the testnet it is 0.30 USDC per million CU, and a balance is kept to a billionth of a
USDC, so a cheap read costs a fraction of a thousandth of a cent.
| Call | CU |
|---|---|
eth_chainId, net_version | 4 |
eth_blockNumber, eth_gasPrice, eth_maxPriorityFeePerGas, eth_syncing, web3_clientVersion | 6 |
eth_getBalance, eth_getTransactionCount, eth_getStorageAt | 7 |
eth_getCode, eth_getBlockByNumber and eth_getBlockByHash (without transactions), eth_getTransactionByHash, eth_getTransactionReceipt, eth_feeHistory | 8 |
eth_sendRawTransaction; a block read with its transactions | 10 |
eth_getBlockReceipts | 12 |
eth_call | 20 |
eth_createAccessList | 25 |
eth_estimateGas | 30 |
eth_getProof, eth_getStorageValues | 25 |
eth_getLogs | 8, plus 1 for every 50,000 block-and-address pairs it scans, rounded up (so a scan over any block range costs at least 9; a lookup by block hash costs 8) |
other methods (net_peerCount, transaction and uncle counts, web3_sha3, ...) | 4 to 12; 12 for a method not named here |
A batch costs the sum of its calls. An answer larger than 4,096 bytes costs 1 more CU for each 9,000 bytes past that (a page of events is the
usual case). Calls refused for their form (a method not served, a log range over the cap) cost nothing. A call the node could
not answer is not charged. Every call that is served carries x-cu-cost and x-credit-usdc headers (a refusal does not; it carries Retry-After when waiting helps), and a web page's script can read them.
Limits
Each key has a rate in CU a second and a number of calls in flight, by what the account is:
| Account | CU a second (a key) | Calls at the node at once (an account), at most |
|---|---|---|
| Credit that was only given (a trial) | 200 | 2 |
| Has deposited | 2,000 | 4 |
| Deposited 200 USDC or more in the last 30 days | 5,000 | 8 |
These are the most each plan can have. The service has two slots to the node for this line and an account never takes all of them, so at the testnet's present
setting every account has 1 read call at the node at a time (a second call waits its turn for up to two seconds, then gets 503 busy); GET https://testnet-rpc.vyrechain.com/v1/info shows the number in force for each plan.
A request past a key's rate is answered with HTTP 429 and a Retry-After header that says how long to wait; a batch dearer than
the key's burst is served once and the key then waits it off. The service as a whole has a rate too; past it you get 429 with
the service is at its limit. The calls in flight are counted for the whole account, however many keys it holds, and are at most one fewer than the slots the service has
to the node (so one account's slow calls never leave the others without a slot). A Retry-After
for a rate or a busy service is at most 120 seconds (a key that has run up a larger debt waits it off at its rate); for a key whose daily cap is reached it is
the number of seconds to 00:00 UTC. These are the testnet's; GET https://testnet-rpc.vyrechain.com/v1/info shows the ones in force.
Answers that are not charged (a refusal, a 429, a read of the usage) are limited for each address that asks for them, as well as for the key: an address that sends many in a short time gets 429 with the wait and its connection is closed, whatever key it uses, until its allowance comes back. Calls that are served are not counted against it.
At zero. A call that the balance cannot cover is not made: HTTP 402 with the JSON-RPC error -32005 and the call's own id
(a list, one per call, for a batch), and the node is not asked. A key whose daily cap is reached gets 429 until 00:00 UTC. A wrong
or revoked key gets HTTP 401 with -32001, the same answer in every case. Refusals are not free of the key's rate: a key with no credit (or a blocked
account's) that keeps asking is slowed with 429 like any other.
Keep a key like a password
A key in a URL ends up in logs, browser history and chat. Send it in the Authorization header from servers, never put one in a
web page (everyone who opens the page can read it), and set a daily cap on any key that has to live somewhere less safe. If one
leaks, revoke it: you sign once and it stops.
What is kept
The wallet address of an account, the hash of each key (never the key), the balance, and counts of calls and CU per key, hour and method. No call is recorded, and no address of a caller is kept beyond the short-lived counters that hold off abuse. The deposit contract passes every deposit straight to the treasury; credit cannot be turned back into USDC by the contract.
