Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: proxy (Tor/SOCKS5) support: add optional configurable dart:io HttpClient. #1386

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

sneurlax
Copy link

Closes #1382.

Adds an optional HttpClient httpClient property (from `dart:io) to a Solana RpcClient (and JsonRpcClient). If it's null (as old clients will pass it by default), it changes no behavior. If it's not null, it uses the provided HttpClient to proxy requests.

You can see an example of usage in Stack Wallet at https://github.com/cypherstack/stack_wallet/blob/2feb7d0be3fb85c6db270f2a12f0ef8e5ef0334d/lib/wallets/wallet/impl/solana_wallet.dart#L419

See #1378 and #1383 for previous description and discussion.

Thank you @ookami-kb for your guidance through this process! I'm happy that Stack Wallet doesn't have to be the only Solana wallet which can proxy request through a SOCKS5 proxy like Tor. See https://github.com/Foundation-Devices/tor for an easy-to-use embeddable Tor proxy which uses the Tor project's arti (A Rust Tor Implementation).

Changes

  • Alter the RpcClient and JsonRpcClient classes and the _postRequest method in order to optionally support proxied HttpClients.

Related issues

Checklist

  • PR is ready for review (if not, it should be a draft).
  • PR title follows Conventional Commits guidelines.
  • Screenshots/video not applicable.
  • Tests unaffected.
  • Self-review done.

import 'package:solana/src/rpc/json_rpc_request.dart';

class JsonRpcClient {
JsonRpcClient(
this._url, {
required Duration timeout,
required Map<String, String> customHeaders,
HttpClient? httpClient, // Optional client for proxy support.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I forgot about one more thing, let's use Client from http package, so that it automatically handles web/native use cases.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The package:http Client only supports HTTP proxies, not SOCKS proxies. However, today I dealt with a similar problem with the Solana library, which uses an http.Client widely: you can make an http.Client with dart:io's HttpClient which does support SOCKS proxies, but you can't make a SOCKS-supporting io.HttpClient from an http.Client.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can do like this: https://github.com/cypherstack/stellar_flutter_sdk/blob/eca1d730e952cf6a6d64502f977cfc03876b75d4/lib/src/stellar_sdk.dart#L43-L50

but I can't do the reverse. http.Client is a subset of dart:io.HttpClient aiui

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, then that's actually a problem because the library should support web as well. Let me think about how to better handle that.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about a conditional import type of thing? I don't have much (any) experience using Dart/Flutter for web but I have seen some conditional import statements regarding some web stuff. Might be a possibility?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, it could be an option to hide it behind conditional imports, but it will most probably require additional work on creating interfaces and wrapping it all together. Unfortunately, I don't have time to look into it right now, so if anyone has possibility to investigate it, that would be great.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may be able to get around to it at some point. If we do, we'll update this PR and comment here

packages/solana/lib/src/rpc/json_rpc_client.dart Outdated Show resolved Hide resolved
@sneurlax
Copy link
Author

Hey @ookami-kb, any thoughts on how to handle this? We are doing maintenance by rebasing these features onto a recent master and I wondered if y'all'd like this PR updated as well or if it's unsuitable due to those platform-/compatibility-related restrictions?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Tor/SOCKS5 proxy support for Dart Solana RpcClient Tor/SOCKS5 proxy support for Dart Solana RpcClient
3 participants