Skip to content

[Migrations] Use Resource logic from backend transfer_lib crate #9

Description

@jurevans

Currently, the anoma-app-sdk arm-bindings crate is exporting bindings to instances of arm-risc0 types, and the actual resource construction logic is being defined in TypeScript . This means that resource logic is not only being duplicated across this repo and anomapay-backend, but also being defined here in TS instead of Rust, making it more difficult to audit and confirm that the TS logic matches the backend exactly.

NOTE See https://github.com/anoma/anomapay-backend/compare/main...justin/prove-feature-gate - this branch makes building to wasm32-unknown-unknown possible without affecting any previous simple_transfer builds/tests, and can provide TransferLogic & TransferLogicV2 to the SDK arm-bindings crate. FYI, this repo is not public for now, so we're discussing whether it can be published, the repo public, etc.

Since we have a Rust/wasm crate already, we could simply re-purpose the same methods from simple-transfer/transfer-lib in the backend, assuming we publish transfer-lib (and someday transfer-lib-v2) and import it here with the prove feature disabled. This will also streamline a move to TransferLogicV2, since we could build a new wasm in anoma-app-sdk supporting PA V2 as well as migrate_tx from crate.

This would ensure that Resource logic is defined in one place only. anoma-app-sdk would then only export any bindings needed by the front-end, instead of exporting bindings for every type of struct needed from arm-risc0. Instead of our Rust crate being specific to arm-bindings, we could move to a workspace with a structure like:

# 
anoma-app-lib/
  - arm-risc0-bindings/ # Formerly arm-bindings, be specific to the type of resource machine
  - anomapay/ # Builders for simple_transfer/transfer_library
  - anomapay-v2/ # Builders for simple_transfer/transfer_library_v2
  ...
  Cargo.toml

We can keep any ARM bindings that may be needed by the front-end, but otherwise should move to a pure JS-Object/json API when interacting with Wasm functionality (we should consider nuking it entirely - our workspace could instead be comprised of simply a single crate for any given Anoma app along with version like above ^^, since ARM bindings are specific to an app). Instead of passing around references to wasm Rust-struct on the JS side, we simply use a JS-object/primitive based API to interact with the wasm.

Note that the namings are updated to indicate which Anoma application (i.e., which Anoma resource machine) the crate provides functionality for, as we can add additional apps in the future.

We can keep any ARM bindings that may be needed by the front-end, but otherwise should move to a pure JS-Object/json API when interacting with Wasm functionality (we should consider nuking it entirely - our workspace could instead be comprised of simply a single crate for any given Anoma app along with version like above ^^, since ARM bindings are specific to an app). Instead of passing around references to wasm Rust-struct instances for literally everything (Resource, Digest, NullifierKey, etc.), we use builder methods (which in turn incorporate methods from TransferLogic & TransferLogicV2) which provide the translation and bindings to the Rust types, and these methods accept JS-object params and return JS-objects. The wasm-bindgen output should be significantly smaller than what arm-bindings is currently producing.

Client

We should discuss the best way to introduce V2 to consumers of @anomaorg/anoma-app-sdk. My thoughts are as follows:

We could export our builders as ResourceBuilderV1 (and ResourceBuilderV2) (naming here is just an example!), with ResourceBuilderV1 re-exported as simply ResourceBuilder initially, then when V2 is required, set ResourceBuilder to ResourceBuilderV2 (breaking change, which is good) with ResourceBuilderV1 still available as an export as before. This would avoid having new clients needing to know which version is current - it should always just be ResourceBuilder.

// Re-export of ResourceBuilderV1 initially, later exporting ResourceBuilderV2
import { ResourceBuilder } from "@anomaorg/anoma-app-sdk/anomapay";

// PA v2 migration happens:
// ResourceBuilderV2 now available, but V1 is still available as well
import 
  ResourceBuilderV1,
  ResourceBuilderV2,
 }  from "@anomaorg/anoma-app-sdk/anomapay";

Backend

One thing to consider is potential changes to backend Parameters - this is another area where the Rust / Wasm library could re-use functionality from the backend directly, provided the crate is published (eventually) and can support a wasm32-unknown-unknown build target (meaning risc0 prove feature is disabled).

Since Parameters is defined in simple_transfer/transfer_web, and to support all of the variants directly in wasm to be used by TypeScript could be complicated, this may be a case where we keep our current TypeScript definitions as is in TypeScript. We don't really need any of these methods, just the data type. The only caveat is we need to provide any V2 change, should they even be needed at all.

TODO

We currently cannot build using transfer_web as a dep, primarily because a wasm target cannot use or tolerate the system-level I/O stuff required by web-server, but libs exist within that crate defines types that are implemented (read duplicated) in the front-end, so perhaps these belong in a non-risc0 lib library, like transfer_web_lib (would add one more crate per each version though):

These seem particularly useful

Resources + witness data enum variant - Front-end uses an API defined in TypeScript to manually piece the witness data together. It potentially entirely duplicates something already defined and re-usable, provided it can be moved out of transfer_web, etc.

For now, make a branch on anomapay-backend and add to Cargo.toml to this git branch:

  • Open branch that feature-gates anything that breaks by disabling prove (transfer_lib, and any crates it imports from)
  • Set up Cargo workspace to replace arm-bindings, and move original arm-bindings into this (for now, it may become obsolete)
    • Anoma App-specific dependencies should not be included in the root workspace Cargo.toml as they are not shared
  • Setup Resource builder bindings which incorporate resource construction logic
  • Update build script to include crates under workspace, all as different wasm-pack targets - ultimately, any client app integrating with Anoma will only include on wasm file which provides bindings for that particular app (anomapay only for now)

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions