7

How do you use a private RPC on the frontend for better performance, but without letting people simply copy-paste your RPC URL and using it in their projects for free?

4 Answers 4

6

This is indeed a tricky problem. Because browser frontends are inherently untrusted from the perspective of the server-side, there is no bulletproof way to verify whether a request is really coming from a specific frontend. As soon as your RPC URL has been shared, it is technically possible to spoof requests.

To limit other website frontends (dApps) from making requests to your RPC you can check the Origin header server-side. Individual users and mobile clients can still trivially spoof this header. More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Origin

Since you cannot restrict the inflow of requests, you can at least limit the kinds of requests that your server responds to (using a reverse proxy such as NGINX). For example, you could block all RPC methods that your website doesn't need and check for specific arguments (e.g. program ID). This can make your RPC useless for unrelated use-cases and thus less attractive for abuse.

All of the above are just workarounds though. Ideologically, imho it is the user's responsibility of getting their own RPC access, instead of just relying on whatever a dApp serves them (verify > trust, and so on).

4

Once you make your private RPC URL available on your frontend, there's nothing you can do to prevent tech-saavy users from snatching that link and using it for themselves for other purposes. I wouldn't recommend this.

If you're loading on-chain data directly from the frontend, you can add an input field to allow users to put in their own RPC URL for better performance. I tend to use GenesysGo for the public.

Otherwise, if you want faster transactions, you can serialize and send the transaction to your server, then execute the transaction in the back-end using your RPC.

1

Ephemeral, IP Bound API Keys with Per Key Rate Limits.

You could have some kind of "/api-key" endpoint that serves up an ephemeral api key. Make sure it's unavailable cross domain. That key would be used to access your endpoint, but it would only be valid for a certain amount of time. Make it sticky by requesting ip address. Meaning if the same client requests it multiple times, they get the same key, until it expires.

Then put a gateway or proxy in front of your rpc endpoint that will authorize the api key, possibly rate limit it, and importantly, check its expiration.

This way if someone copies it and pastes it into their own dApp, it would quickly stop working.

I suppose, if they REALLY wanted to use your endpoint, they could host an "/api-key" endpoint of their own that proxies through to yours. But at that point they are really going out of their way to be abusive.

Also, you can rate limit them, without throttling your other users, because they'll have a different api key than everyone else. Essentially, everyone using their site, will be sharing the same api key, while all the users on your site, will get their own api key. With each api-key having its own rate limit state.

It gets to a point where it's cheaper, and easier for them to just get their own endpoint.

0

Check out this detailed guide created specifically for this: How to store your Web3 DApp secrets: Guide to environment variables.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.