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

Can release o1js lib without sharedArrayBuffer ? #1787

Open
lvshaoping007 opened this issue Aug 1, 2024 · 27 comments
Open

Can release o1js lib without sharedArrayBuffer ? #1787

lvshaoping007 opened this issue Aug 1, 2024 · 27 comments

Comments

@lvshaoping007
Copy link

Can o1js teams release a new o1js lib without sharedArrayBuffer? Because sharedArrayBuffer currently causes some compatibility issues, which affect the actual experience of users with o1js

extension:
extension cannot use o1js directly, because the front-end does not support Function and eval
So we tried sandbox, but it prompted a sharedArrayBuffer exception. The exception is as follows
Failed to execute 'postMessage' on 'Worker': SharedArrayBuffer transfer requires self.crossOriginIsolated. but sandbox can not use crossOriginIsolated

Android:
The system browser on the Android does not support SharedArrayBuffer by default, so for Android users, they cannot use zkApp to build zk-transactions on the client.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer

@dfstio
Copy link

dfstio commented Aug 1, 2024

This is an important request; I fully support it.

Statistics show that more than 60% of MinaNFT users visit the minanft.io site from mobile devices, and having o1js/light with a small size that can work on both iPhone and Android is very important for user experience.

I will be happy to participate in testing this version of the library.

@mitschabaude
Copy link
Collaborator

SharedArrayBuffer is needed for creating zk proofs / compiling.

Would you have a use case for o1js without those features?

@dfstio
Copy link

dfstio commented Aug 1, 2024

SharedArrayBuffer is needed for creating zk proofs / compiling.

Would you have a use case for o1js without those features?

Yes, this case already exists as MinaNFT does all the compiling and proof creation with zkCloudWorker in the cloud. In the browser

  1. The state of the contract and all accounts are checked
  2. The nonce is calculated taking into account all pending txs
  3. The tx is created with Mina.transaction (without compiling the SmartContract)
  4. The tx is serialized
  5. The tx is signed in Auro Wallet using onlySign option
  6. The serialized tx and signedData from Auro Wallet are sent to the zkCloudWorker

No compiling or proving is being made on the frontend, and this allows to present the Auro Wallet sign transaction form within 5 seconds after the user pressed the button.

The compiling and proving take place in the cloud, where zkCloudWorker

  1. Deserialize tx
  2. Prepares new, identical tx using Mina.transaction and deserialized transaction
  3. Compiles SmartContract
  4. Proves tx
  5. Sends tx to the network
  6. Monitor the tx for inclusion in the block or replacement by the user and take the necessary actions as the result of the tx to be included in the block or not included.

o1js/light will be

  1. Much lighter, without the necessity to download 100 MB that is critical for mobile devices
  2. Can run in Android and other environments where Shared ArrayBuffer is not supported or the proving and compilation is not required. Right now, it is not possible to calculate Poseidon hash or Merkle Tree root in such environments that significantly limit the possibilities of the zkApps

@dfstio
Copy link

dfstio commented Aug 1, 2024

The relevant discussion on discord: https://discord.com/channels/484437221055922177/1228326948078489642

@lvshaoping007
Copy link
Author

SharedArrayBuffer is needed for creating zk proofs / compiling.

Would you have a use case for o1js without those features?

Is there no other way besides SharedArrayBuffer? Because compatibility is also an important basis for the popularity of a library.
For Android and extension, we can only prove and compiling through the server at present, and the front end is only used for interaction and signing. But this is obviously only part of the function of o1js. We should try to put what the front end can do on the front end.

@mitschabaude
Copy link
Collaborator

Is there no other way besides SharedArrayBuffer?

SharedArrayBuffer is needed for parallelism (now way around that!), and I think single-threaded proving would be prohibitively slow esp. on Android. (Also, it would be a significant refactor to even support single-threaded proving without SharedArrayBuffer)

@dfstio
Copy link

dfstio commented Aug 2, 2024

It was in the press recently that the most used smartphone by Telegram users is Samsung costing $180.
I do not believe that proving is possible in this environment; we need to move it to the cloud. But calculation of Poseidon hash and Merkle Tree root (for small trees) is possible.

@lvshaoping007
Copy link
Author

Is there no other way besides SharedArrayBuffer?

SharedArrayBuffer is needed for parallelism (now way around that!), and I think single-threaded proving would be prohibitively slow esp. on Android. (Also, it would be a significant refactor to even support single-threaded proving without SharedArrayBuffer)

Yes, can it be built and signed only on the extension or Android, and the rest of the things (such as proof, compile, etc.) are handled by the server? Currently, due to compatibility, the Android cannot even create zkApp transactions

@mitschabaude
Copy link
Collaborator

Yeah that would be the o1js/light idea.

It will take some refactors but it's definitely possible

@EmrePiconbello
Copy link

Isn't the mobile wallets like auro or pallad support zkapps? Is this mobile browser spesific request?

Currently we are looking in to making o1js work on mobile applications directly. I like to know more details here.

@lvshaoping007
Copy link
Author

Yeah that would be the o1js/light idea.

It will take some refactors but it's definitely possible

Looking forward to o1js/light

@lvshaoping007
Copy link
Author

Isn't the mobile wallets like auro or pallad support zkapps? Is this mobile browser spesific request?

Currently we are looking in to making o1js work on mobile applications directly. I like to know more details here.

Yes, you can try to open zkApp in Android webview and build zk-command. When building, the process will throw an exception. The error is just like what I said at the beginning

@mitschabaude
Copy link
Collaborator

mitschabaude commented Aug 4, 2024

Isn't the mobile wallets like auro or pallad support zkapps?

Auro uses mina-signer, a lightweight TS library that should work everywhere but that can only sign, not create or prove, zkapp transactions

@dfstio
Copy link

dfstio commented Aug 4, 2024

Isn't the mobile wallets like auro or pallad support zkapps? Is this mobile browser spesific request?

Currently we are looking in to making o1js work on mobile applications directly. I like to know more details here.

At the moment, you need to run your zkApp inside the browser of the mobile wallet, but it is not possible to send zkApp tx now.

What I expect for MinaNFT:

  • iPhone support I will be able to add after the new version of Auro Wallet for iPhone will be available, I will use full o1js library there waiting for o1js/light
  • Android support I will be able to add fully only after o1js/light will be available, I have some workaround with limited functionality that I will use waiting for o1js/light
  • Safari support will require deep link functionality in Auro Wallet, it will allow to move the user from Safari to Auro Wallet browser in one click, will add this as soon as it will be available in Auro Wallet.
  • To add zkApp tx support to mobile app, I understand that it will be needed to add API to Auro Wallet to call from your mobile app or you should redirect the user to the Auro Wallet browser

@saitunc
Copy link

saitunc commented Aug 27, 2024

Would an ffi be a feasible solution? Of course, as dfst stated here user base might not have a powerful device for computation, but in a scenario of the existence of either C or any other efficient language that can be executed in a powerful mobile device could enable proving/compiling hence interaction with zkapps.

It was in the press recently that the most used smartphone by Telegram users is Samsung costing $180. I do not believe that proving is possible in this environment; we need to move it to the cloud. But calculation of Poseidon hash and Merkle Tree root (for small trees) is possible.

@andrewferrone
Copy link

Hey, have folks tried setting the COOP and COEP headers? It looks like you can use sharedArrayBuffer if you set the COOP and COEP headers in the request. https://web.dev/articles/coop-coep

@mrcnk
Copy link

mrcnk commented Sep 23, 2024

@andrewferrone nice one, gonna try it in Pallad soon:
https://developer.chrome.com/docs/extensions/develop/concepts/cross-origin-isolation
Note for browser wallet devs - these manifest entries are not included in @types/chrome.

@mitschabaude
Copy link
Collaborator

mitschabaude commented Sep 23, 2024

extension:
extension cannot use o1js directly, because the front-end does not support Function and eval
So we tried sandbox, but it prompted a sharedArrayBuffer exception. The exception is as follows
Failed to execute 'postMessage' on 'Worker': SharedArrayBuffer transfer requires self.crossOriginIsolated. but sandbox can not use crossOriginIsolated

So are we saying this is not an issue after all, because you can set those headers in extensions just as in normal websites? :D

That would be great news for Private Credentials!

@mrcnk
Copy link

mrcnk commented Sep 23, 2024

So in Pallad the SharedArrayBuffer is no longer an issue, but I'm getting a random Uncaught SyntaxError: missing ) after argument list when importing Field for a quick check of Field.from(5) in our background Service Worker and the only similar issue I can find is:
https://discord.com/channels/484437221055922177/910549624413102100/992009664017469470

@andrewferrone
Copy link

@mrcnk could you post your question in zkapps questions channel on Discord?

@andrewferrone
Copy link

And @mrcnk can you share the exact setup you tested on mobile please?

@mrcnk
Copy link

mrcnk commented Sep 23, 2024

It occurs in a browser extension's service worker context. I created a repro for this problem (though this time it's another SyntaxError):
https://github.com/mrcnk/o1js-ext-sw-repro
Steps to reproduce:

  1. bun install
  2. bun run build
  3. Turn on the developer mode in Chrome/Brave Extensions.
  4. Load unpacked /dist directory as an extension.
    The error will be visible after clicking Errors on the installed extension.

@martonmoro
Copy link

martonmoro commented Sep 25, 2024

I looked at setting COOP and COEP like @andrewferrone suggested and it worked for me. I created a browser extension prototype and put the o1js related stuff in a sandboxed iframe.
I added "cross_origin_embedder_policy": { "value": "require-corp" }, "cross_origin_opener_policy": { "value": "same-origin" } to the manifest.json and allow="cross-origin-isolated" to the iframe
Link to PR: https://github.com/zksecurity/mina-attestations/pull/14/files

@andrewferrone
Copy link

andrewferrone commented Oct 3, 2024

Hey, we're working on getting zkApp transaction proving functional in the browser on Android. We've got a proof of concept working now we believe. Is there anyone here with a zkApp looking to prove in browser on Android? We'd like to test our solution with you. @lvshaoping007 @EmrePiconbello

@dfstio
Copy link

dfstio commented Oct 5, 2024

Update: I did some additional tests in mobile environments. I have created a test zkApp: https://mobile-test.minatokens.com that can use Auro Wallet or a hardcoded private key, prove in the web or the cloud, and do some simple Merkle Map root calculations. It also shows system info, including CORS, SharedArrayBuffer status, and wallet info.

I have tested four environments: iPhone Safari, Auro Wallet internal browser on iPhone, Android Chrome, and Auro Wallet internal browser on Android. The results:

  • I have CORS enabled in all environments
  • I have SharedArrayBuffer available everywhere except the internal Auro Wallet internal browser on Android, exactly according to the information at https://caniuse.com/sharedarraybuffer
  • I am able to build txs calling Mina.transaction in all environments, including Auro Wallet internal browser on Android
  • I am able to sign txs in the internal Auro Wallet browser both for iPhone and Android, with onlySign option not being available in the mobile Auro Wallet and my fee and memo values discarded by the mobile wallets.
  • I'm able to compile and prove in all the environments except for the Auro Wallet internal browser on Android. In the internal Auro Wallet browser in Android, the process hangs out during compilation, even for tiny contracts. I can build the tx, but I cannot compile the contract.

Therefore, current limitations in comparison with the web:

  • compiling and proving not working on Auro Wallet internal browser on Android due to Android WebView limitations
  • 'onlySign` option is not working on mobile wallets
  • It is not possible to set custom fee and memo

As I understand, issues with onlySign, fee and memo will be fixed in the next version of the AuroWallet quite soon.

The good news is that no more limitations exist to using o1js for building txs. I remember that I have tested several months ago o1js in Netlify functions that do not support SharedArrayBuffer too, and I was unable to do simple math like Field(1).add(Field(2)), now I can calculate MerkleMap root without SharedArrayBuffer and do some math with Fields in Android WebView, that is enough to build transaction. Therefore, o1js/light is not the absolute requirement for Android WebView, although it would be good not to load 100 MB library on mobile.

Current tested workflow for the internal browser of Auro Wallet for Android:

  • Build tx inside the browser using o1js, serialize tx
  • Prove serialized tx in the cloud using zkCloudWorker
  • Sign and send proved tx in the Auro Wallet for Android

Of course, it is a non-optimal user experience, but it works. Example of the zkApp tx sent from the internal browser of Auro Wallet for Android: https://minascan.io/devnet/tx/5JuK2RweaYegyt3ddyvd5EoJsaedh7ifNuMUHjx1Ne2VdRdW4Fgc?type=zk-tx

Proposal:

  • Consider adding SDK libraries for mobile wallets to be able to communicate with mobile wallets from Chrome on Android and Safari on iPhone, removing the need to use internal browsers in the mobile wallet on Android. It will require small additional effort from the zkApp developer to use such SDK libraries, but will enable better user experience.
  • Consider creating o1js/light library that will be loaded much faster on mobile devices.

@dfstio
Copy link

dfstio commented Oct 5, 2024

  • Consider adding SDK libraries for mobile wallets to be able to communicate with mobile wallets from Chrome on Android and Safari on iPhone, removing the need to use internal browsers in the mobile wallet on Android. It will require small additional effort from the zkApp developer to use such SDK libraries, but will enable better user experience.

I tested the Metamask SDK library on Android to see how a similar workflow works on Ethereum. I've added a checkbox to my app, https://mobile-test.minatokens.com/, to send the tx on Sepolia from the Android Chrome browser.

The workflow:

  • I open https://mobile-test.minatokens.com/ in Chrome on Android (NOT in the Metamask browser)
  • I check the box "send Sepolia tx" and press the button
  • My web app connects to the Metamask app on Android and gets an address
  • My web app sends ETH to the test address.

SharedArrayBuffer is available in this setup; the wallet installed as a mobile app on Android is working. We can do the same for Mina protocol wallets.
Test code: https://github.com/zkcloudworker/minatokens/blob/mobile-test/src/lib/metamask.ts

@Trivo25
Copy link
Member

Trivo25 commented Oct 10, 2024

Thanks for looking into this @dfstio - this is super helpful!

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

No branches or pull requests

9 participants