o1-labs / o1js

TypeScript framework for zk-SNARKs and zkApps
https://docs.minaprotocol.com/en/zkapps/how-to-write-a-zkapp
Apache License 2.0
531 stars 121 forks source link

Can release o1js lib without sharedArrayBuffer ? #1787

Open lvshaoping007 opened 3 months ago

lvshaoping007 commented 3 months ago

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 commented 3 months ago

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 commented 3 months ago

SharedArrayBuffer is needed for creating zk proofs / compiling.

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

dfstio commented 3 months ago

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 commented 3 months ago

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

lvshaoping007 commented 3 months ago

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 commented 3 months ago

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 commented 3 months ago

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 commented 3 months ago

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 commented 3 months ago

Yeah that would be the o1js/light idea.

It will take some refactors but it's definitely possible

EmrePiconbello commented 3 months ago

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 commented 3 months ago

Yeah that would be the o1js/light idea.

It will take some refactors but it's definitely possible

Looking forward to o1js/light

lvshaoping007 commented 3 months ago

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 commented 3 months ago

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 commented 3 months ago

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:

saitunc commented 3 months ago

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 commented 2 months ago

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 commented 2 months ago

@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 commented 2 months ago

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 commented 2 months ago

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 commented 2 months ago

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

andrewferrone commented 2 months ago

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

mrcnk commented 2 months ago

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 commented 2 months ago

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 commented 1 month ago

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 commented 1 month ago

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:

Therefore, current limitations in comparison with the web:

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:

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:

dfstio commented 1 month ago
  • 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:

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 commented 1 month ago

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