Skip to content

Wasm bindings #49

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

Draft
wants to merge 21 commits into
base: main
Choose a base branch
from
Draft

Conversation

riverKanies
Copy link
Contributor

@riverKanies riverKanies commented Mar 12, 2025

WIP!

Closes #46

WASM bindings are now building (only on Uri type rn)

the payjoinError depended on io so I modified that to just handle strings for now, need to sort out what we actually want to do here

@DanGould
Copy link
Contributor

DanGould commented Mar 12, 2025

payjoin/io pulls in reqwest, which is not going to work in wasm. You're going to want to feature gate that (perhaps with payjoin-ffi's own io feature and NOT enable it for the wasm targets.

Comment on lines +1 to +3
[env]
AR = "/opt/homebrew/opt/llvm/bin/llvm-ar"
CC = "/opt/homebrew/opt/llvm/bin/clang"
Copy link
Contributor

Choose a reason for hiding this comment

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

Not everyone building is going to use homebrew. You probably don't want to commit your own environment here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeah this is something we've been noting in the readme on wasm libs since it's mac specific

@riverKanies
Copy link
Contributor Author

riverKanies commented Mar 12, 2025

Original error:
Seems it's almost building the wasm bindings but hitting this error on the Proxy:

error[E0432]: unresolved import `reqwest::Proxy`
   --> /Users/river/.cargo/registry/src/index.crates.io-6f17d22bba15001f/payjoin-0.22.0/src/io.rs:21:27
    |
21  |     use reqwest::{Client, Proxy};
    |                           ^^^^^ no `Proxy` in the root
    |
note: found an item that was configured out
   --> /Users/river/.cargo/registry/src/index.crates.io-6f17d22bba15001f/reqwest-0.12.9/src/lib.rs:348:27
    |
348 |     pub use self::proxy::{Proxy,NoProxy};
    |                           ^^^^^
note: the item is gated here
   --> /Users/river/.cargo/registry/src/index.crates.io-6f17d22bba15001f/reqwest-0.12.9/src/lib.rs:337:1
    |
337 | / if_hyper! {
338 | |     #[cfg(test)]
339 | |     #[macro_use]
340 | |     extern crate doc_comment;
...   |
367 | |     mod util;
368 | | }
    | |_^
    = note: this error originates in the macro `if_hyper` (in Nightly builds, run with -Z macro-backtrace for more info)

   Compiling bitcoin-ffi v0.1.2 (https://github.com/bitcoindevkit/bitcoin-ffi.git?rev=4cd8e644dbf4e001d71d5fffb232480fa5ff2246#4cd8e644)
error[E0599]: no method named `proxy` found for struct `ClientBuilder` in the current scope
  --> /Users/river/.cargo/registry/src/index.crates.io-6f17d22bba15001f/payjoin-0.22.0/src/io.rs:26:36
   |
26 |     let client = Client::builder().proxy(proxy).build()?;
   |                                    ^^^^^ method not found in `ClientBuilder`

More helpful notes from Dan:
"""
I suggest ignoring fetch_ohttp_keys to start

There's a separate https-in-websocket implementation and support on the relay so we can avoid it in the browser

That implementation is here: https://github.com/MutinyWallet/mutiny-node/pull/820/files#diff-9bd1c92f85da5773c1cf3b66662d28004dd0c00ab719781af7d7a77aa712fb20R140-R187 and could be part of a wasm feature exclusive function

You could get ohttp-keys out of band and encode the binary in your js blob to make smoke tests work without JIT fetching that's done with fetch_ohttp_keys

Gotta just disable the io feature on the wasm path so reqwest isn't a dependency. I left a comment
"""

@riverKanies
Copy link
Contributor Author

@DanGould I noted your comment:
"You could get ohttp-keys out of band and encode the binary in your js blob to make smoke tests work without JIT fetching that's done with fetch_ohttp_keys"
But I do not yet fully understand what would be involved here. I need to get ohttp keys to init a Receiver so I can test wasm bindings. I think it'd be easiest if I could get them as a string I can just hard code in js to start. But I'm not yet familiar with the ohttp protocol so I have some questions. Should I just get some ohttp keys using the payjoin-cli? are they 'ephemeral' keys so to speak, what I mean is: anyone who has them can act on behalf of the user essentially? Are there considerations about keys expiring? For the hackathon we will need to address this in some semi-robust way.

You also mentioned the possibility of passing keys through bip21 OH1 param, who would be doing the passing here? would this be an additional QR shared between receiver and sender? I was thinking keys come from the relay. Anyway, I'm working to understand this better now, but any hints would be appreciated

@DanGould
Copy link
Contributor

Should I just get some ohttp keys using the payjoin-cli?

Read fetch_ohttp_keys to get the binary (file). You can get it with a GET request in your browser or with curl

are they 'ephemeral' keys so to speak, what I mean is: anyone who has them can act on behalf of the user essentially?

Which user?

OhttpKeys (OHTTP Key Configurations ) replace TLS certificates.

Are there considerations about keys expiring? For the hackathon we will need to address this in some semi-robust way.

Yes, they expire, but are long lived so hard coding will work for demo purposes. If you control the directory server for the purposes of a demo you control when the keys are refreshed.

You also mentioned the possibility of passing keys through bip21 OH1 param, who would be doing the passing here? would this be an additional QR shared between receiver and sender? I was thinking keys come from the relay.

OH1... in a bip21 fragment is a bech32 encoding of the OHTTP Keys. That can be read in the source. No additional QR, it's already in the bip21, and I wouldn't bother with QR scanning for a simple demo. Just use the URI text. OhttpKeys come from the Directory.

@riverKanies
Copy link
Contributor Author

Should I just get some ohttp keys using the payjoin-cli?

Read fetch_ohttp_keys to get the binary (file). You can get it with a GET request in your browser or with curl

Are there considerations about keys expiring? For the hackathon we will need to address this in some semi-robust way.

Yes, they expire, but are long lived so hard coding will work for demo purposes. If you control the directory server for the purposes of a demo you control when the keys are refreshed.

ok cool, makes sense now. they are gateway keys, not session keys. I added a convenience method to the cli for this payjoin/rust-payjoin#589

Experimenting with exposing just the Uri type with WASM bindings first

Want to test "wasm" feature flag for WASM specific modifications to methods

the .cargo/config settings are mac specific

Hitting issue with the proxy
Need to sort out how to handle errors
Just remove redundant (hopefully) rlib type
starting with only string inputs/outputs

err: getting null rust pointer in browser when trying to call .id() or .to_json()
Need to pass in system time from JS conotext for WASM

todo: turst current time logic into a helper method
wrap PdkRequest and make js getters

err: currently getting a timeout error when actually making the request,
probably the url or body is the issue
@darioAnongba
Copy link

little comment:reqwest should work in the browser when targeting wasm @DanGould

@DanGould
Copy link
Contributor

@darioAnongba I had used reqwest in this mutiny payjoin implementation. The only place it's used in the payjoin library is with the io feature for fetch via HTTPS-in-HTTP (CONNECT tunnel) which I'm not sure I could get working with reqwest compiled to wasm.

@DanGould
Copy link
Contributor

What's the plan for rebase / review here? It'd be nice if there were some piece of this we could start with, like a feature that enables just a small surface of the API, maybe even a single struct since reviewing it all at once is going to be a lot harder, and the underlying payjoin-ffi crate keeps changing making rebases harder as the tip of this diverges.

the browser demo is fully working now

only supports v2
doesn't yet fully validate checks
limited options
@riverKanies
Copy link
Contributor Author

https://mutinynet.com/tx/f90380bdb2284a7586a386017177257d2454aab100f2a21d5ed2a6e3baf48f6e
demo complete. here's first payjoin with wasm bindings

I'll start looking at merge conflicts to rebase and work up a minimal smaller pr to start.
also quite a bit of cleanup, and this does not yet include full functionality, just happy path for v2 with normal defaults pretty much

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.

Support WASM with wasm_bindgen and conditional compilation
3 participants