-
Notifications
You must be signed in to change notification settings - Fork 53
feat(wasm-sdk)!: add shielded pool WASM bindings and query methods #3235
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
Merged
Merged
Changes from 18 commits
Commits
Show all changes
48 commits
Select commit
Hold shift + click to select a range
c5325c9
feat(wasm-dpp2,js-sdk): add shielded pool WASM bindings and JS SDK me…
QuantumExplorer 65c02a6
revert: remove js-dash-sdk and wasm-dpp changes from shielded PR
QuantumExplorer 8b71f68
feat(wasm-sdk): add shielded pool query methods
QuantumExplorer 3256346
feat(wasm-dpp2): implement shielded proof result wrappers
QuantumExplorer d08e087
fix(wasm-sdk): correct computePlatformSighash doc for extraData format
QuantumExplorer 98a20b6
fix(wasm-sdk): remove needless borrow in computePlatformSighash
QuantumExplorer 5d4ee20
fix(wasm): address PR review feedback for shielded bindings
QuantumExplorer 35b7ba4
fix(wasm-sdk): reject nullifiers that are not exactly 32 bytes
QuantumExplorer a87c6ad
Merge branch 'v3.1-dev' into feat/zk-wasm-js-bindings
QuantumExplorer 0b48cd3
Merge branch 'v3.1-dev' into feat/zk-wasm-js-bindings
QuantumExplorer 74e9290
feat(wasm): address all review feedback on shielded WASM bindings
QuantumExplorer 7f216ec
feat(wasm): improve TypeScript interface definitions per shumkov review
QuantumExplorer c6a73b7
fix(wasm): use base64 string for all byte fields in OrchardActionJSON
QuantumExplorer 4e29ccd
fix(wasm): use number | string for BigInt fields in JSON interfaces
QuantumExplorer fd850e1
fix(wasm): use typed parameters in shielded transition constructors
QuantumExplorer 2db3796
fix(wasm): correct TS types to match actual serde output
QuantumExplorer c55a943
Merge branch 'v3.1-dev' into feat/zk-wasm-js-bindings
QuantumExplorer c6a2b3f
fix(wasm): change $version to $formatVersion, add Options constructor
QuantumExplorer df3de08
refactor(wasm-dpp2): unify rs-dpp/wasm-dpp2 typing and conversion con…
shumkov 05e96f4
fix(wasm-dpp2): replace bare object types with typed JSON externs
shumkov 26d7d0c
refactor(wasm-dpp2): convert shielded getters to property style
shumkov a84bfd6
Merge remote-tracking branch 'origin/v3.1-dev' into feat/zk-wasm-js-b…
shumkov 42d02a1
style(wasm-dpp2): apply rustfmt
shumkov f200b65
fix(ci): resolve eslint and clippy lints surfaced by full CI run
shumkov 321b18c
fix(platform-wallet): update spv_sync test to flat CoreChangeSet shape
shumkov c48b224
test(platform-value): lock in BinaryData byte-input deserialization
shumkov 7ecdf5e
fix(wasm-dpp2): type outputAddress as Uint8Array in Object form + str…
shumkov f6ce62d
fix(dpp,wasm-dpp2): emit pooling as a string in JSON, fix broken TS t…
shumkov e87d363
fix(wasm-dpp2): enforce 216-byte encryptedNote at the boundary (mirro…
shumkov e3b301c
revert(wasm-dpp2): remove encryptedNote 216-byte check, codify thin-w…
shumkov 19d7f54
refactor(wasm-dpp2): remove wasm-side size caps, defer to DPP validation
shumkov 1dc3fbf
fix(wasm-dpp2): preserve Map entries in toJSON for verified-result wr…
shumkov cad8e46
fix(dpp): align address_funds::serde_helpers feature gate with module…
shumkov b9abce9
feat(js-evo-sdk): add ShieldedFacade for shielded pool queries
shumkov e82fc64
test(wasm-sdk): add unit tests for shielded query result types
shumkov 1f7eef5
style(dpp): fmt pooling_serde Visitor and discriminant error
shumkov 4a4b8f8
fix(dpp): satisfy clippy on serde_helpers gating and pooling_serde im…
shumkov e6b3655
test(wasm-sdk): add functional tests for shielded query methods
shumkov b78a6e9
refactor(wasm-sdk): drop redundant IShielded* TS interfaces in querie…
shumkov 51da814
refactor(wasm-sdk): apply json_safe_fields convention to shielded wra…
shumkov ec2bcf2
chore(dpp): make serde_bytes and serde_bytes_var modules public
shumkov 04cfcc4
refactor(wasm-sdk,js-evo-sdk): null/undefined convention for shielded…
shumkov 624d3f7
fix(dpp): make serde_bytes / serde_bytes_var deserialize accept byte …
shumkov 9d8d45b
refactor(wasm-sdk): drop bytes_b64 in shielded.rs, codify round-trip …
shumkov 9acf091
refactor(wasm-sdk): use wasm_dpp2::utils::try_to_fixed_bytes in parse…
shumkov 130fbda
refactor(wasm-sdk,js-evo-sdk): tighten Array typing on shielded queries
shumkov f8fa60e
style(wasm-sdk): fmt single-line wasm_bindgen attribute on getShielde…
shumkov 607726e
refactor(wasm-dpp2): split proof_result into per-domain submodules
shumkov File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| pub mod shield_from_asset_lock_transition; | ||
| pub mod shield_transition; | ||
| pub mod shielded_transfer_transition; | ||
| pub mod shielded_withdrawal_transition; | ||
| pub mod unshield_transition; | ||
|
|
||
| pub use shield_from_asset_lock_transition::ShieldFromAssetLockTransitionWasm; | ||
| pub use shield_transition::ShieldTransitionWasm; | ||
| pub use shielded_transfer_transition::ShieldedTransferTransitionWasm; | ||
| pub use shielded_withdrawal_transition::ShieldedWithdrawalTransitionWasm; | ||
| pub use unshield_transition::UnshieldTransitionWasm; | ||
|
|
||
| use crate::error::WasmDppResult; | ||
| use wasm_bindgen::prelude::wasm_bindgen; | ||
|
|
||
| /// Compute the platform sighash from an Orchard bundle commitment and extra data. | ||
| /// | ||
| /// `sighash = SHA-256("DashPlatformSighash" || bundleCommitment || extraData)` | ||
| /// | ||
| /// - For shield and shielded_transfer transitions, `extraData` should be empty. | ||
| /// - For unshield transitions, `extraData` = serialized `outputAddress` bytes. | ||
| /// - For shielded withdrawal transitions, `extraData` = `outputScript` bytes. | ||
| #[wasm_bindgen(js_name = computePlatformSighash)] | ||
| pub fn compute_platform_sighash_wasm( | ||
| bundle_commitment: &[u8], | ||
| extra_data: &[u8], | ||
| ) -> WasmDppResult<Vec<u8>> { | ||
| if bundle_commitment.len() != 32 { | ||
| return Err(crate::error::WasmDppError::invalid_argument(format!( | ||
| "bundleCommitment must be exactly 32 bytes, got {}", | ||
| bundle_commitment.len() | ||
| ))); | ||
| } | ||
| let commitment: &[u8; 32] = bundle_commitment.try_into().expect("checked length above"); | ||
| let result = dpp::shielded::compute_platform_sighash(commitment, extra_data); | ||
| Ok(result.to_vec()) | ||
| } | ||
271 changes: 271 additions & 0 deletions
271
packages/wasm-dpp2/src/shielded/shield_from_asset_lock_transition.rs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,271 @@ | ||
| use crate::asset_lock_proof::AssetLockProofWasm; | ||
| use crate::error::{WasmDppError, WasmDppResult}; | ||
| use crate::identifier::IdentifierWasm; | ||
| use crate::utils::try_from_options; | ||
| use crate::{impl_wasm_conversions_serde, impl_wasm_type_info}; | ||
| use dpp::platform_value::BinaryData; | ||
| use dpp::serialization::{PlatformDeserializable, PlatformSerializable}; | ||
| use dpp::state_transition::shield_from_asset_lock_transition::ShieldFromAssetLockTransition; | ||
| use dpp::state_transition::shield_from_asset_lock_transition::v0::ShieldFromAssetLockTransitionV0; | ||
| use dpp::state_transition::{StateTransition, StateTransitionLike}; | ||
| use serde::{Deserialize, Serialize}; | ||
| use wasm_bindgen::prelude::*; | ||
|
|
||
| #[derive(Deserialize)] | ||
| #[serde(rename_all = "camelCase")] | ||
| struct ShieldFromAssetLockTransitionSimpleFields { | ||
| #[serde(default)] | ||
| actions: Vec<dpp::shielded::SerializedAction>, | ||
|
shumkov marked this conversation as resolved.
Outdated
|
||
| #[serde(default)] | ||
| value_balance: u64, | ||
| #[serde(default)] | ||
| anchor: Vec<u8>, | ||
| #[serde(default)] | ||
| proof: Vec<u8>, | ||
| #[serde(default)] | ||
| binding_signature: Vec<u8>, | ||
| #[serde(default)] | ||
| signature: Vec<u8>, | ||
| } | ||
|
shumkov marked this conversation as resolved.
|
||
|
|
||
| #[wasm_bindgen(typescript_custom_section)] | ||
| const TS_TYPES: &str = r#" | ||
| /** | ||
| * A serialized Orchard action (spend-output pair) in binary/Object form. | ||
| */ | ||
| export interface SerializedOrchardAction { | ||
| nullifier: Uint8Array; | ||
| rk: Uint8Array; | ||
| cmx: Uint8Array; | ||
| encryptedNote: Uint8Array; | ||
| cvNet: Uint8Array; | ||
| spendAuthSig: Uint8Array; | ||
| } | ||
|
|
||
| /** | ||
| * A serialized Orchard action (spend-output pair) in JSON form. | ||
| */ | ||
| export interface SerializedOrchardActionJSON { | ||
| nullifier: string; | ||
| rk: string; | ||
| cmx: string; | ||
| encryptedNote: string; | ||
| cvNet: string; | ||
| spendAuthSig: string; | ||
| } | ||
|
|
||
| /** | ||
| * Options for constructing a ShieldFromAssetLockTransition. | ||
| * Uses WASM instance types for complex fields like AssetLockProof. | ||
| */ | ||
| export interface ShieldFromAssetLockTransitionOptions { | ||
| assetLockProof: AssetLockProof; | ||
| actions: SerializedOrchardAction[]; | ||
| valueBalance: bigint; | ||
| anchor: Uint8Array; | ||
| proof: Uint8Array; | ||
| bindingSignature: Uint8Array; | ||
| signature: Uint8Array; | ||
| } | ||
|
|
||
| /** | ||
| * ShieldFromAssetLockTransition serialized as a plain object. | ||
| */ | ||
| export interface ShieldFromAssetLockTransitionObject { | ||
| $formatVersion: string; | ||
| assetLockProof: AssetLockProofObject; | ||
| actions: SerializedOrchardAction[]; | ||
| valueBalance: bigint; | ||
| anchor: Uint8Array; | ||
| proof: Uint8Array; | ||
| bindingSignature: Uint8Array; | ||
| signature: Uint8Array; | ||
| } | ||
|
|
||
| /** | ||
| * ShieldFromAssetLockTransition serialized as JSON (human-readable). | ||
| */ | ||
| export interface ShieldFromAssetLockTransitionJSON { | ||
| $formatVersion: string; | ||
| assetLockProof: AssetLockProofJSON; | ||
| actions: SerializedOrchardActionJSON[]; | ||
| valueBalance: number | string; | ||
| anchor: string; | ||
| proof: string; | ||
| bindingSignature: string; | ||
| signature: string; | ||
| } | ||
| "#; | ||
|
|
||
| #[wasm_bindgen] | ||
| extern "C" { | ||
| #[wasm_bindgen(typescript_type = "ShieldFromAssetLockTransitionOptions")] | ||
| pub type ShieldFromAssetLockTransitionOptionsJs; | ||
|
|
||
| #[wasm_bindgen(typescript_type = "ShieldFromAssetLockTransitionObject")] | ||
| pub type ShieldFromAssetLockTransitionObjectJs; | ||
|
|
||
| #[wasm_bindgen(typescript_type = "ShieldFromAssetLockTransitionJSON")] | ||
| pub type ShieldFromAssetLockTransitionJSONJs; | ||
| } | ||
|
|
||
| #[derive(Clone, Serialize, Deserialize)] | ||
| #[serde(transparent)] | ||
| #[wasm_bindgen(js_name = ShieldFromAssetLockTransition)] | ||
| pub struct ShieldFromAssetLockTransitionWasm(ShieldFromAssetLockTransition); | ||
|
|
||
| impl From<ShieldFromAssetLockTransition> for ShieldFromAssetLockTransitionWasm { | ||
| fn from(v: ShieldFromAssetLockTransition) -> Self { | ||
| ShieldFromAssetLockTransitionWasm(v) | ||
| } | ||
| } | ||
|
|
||
| impl From<ShieldFromAssetLockTransitionWasm> for ShieldFromAssetLockTransition { | ||
| fn from(v: ShieldFromAssetLockTransitionWasm) -> Self { | ||
| v.0 | ||
| } | ||
| } | ||
|
|
||
| #[wasm_bindgen(js_class = ShieldFromAssetLockTransition)] | ||
| impl ShieldFromAssetLockTransitionWasm { | ||
|
QuantumExplorer marked this conversation as resolved.
|
||
| #[wasm_bindgen(constructor)] | ||
| pub fn new( | ||
| options: ShieldFromAssetLockTransitionOptionsJs, | ||
| ) -> WasmDppResult<ShieldFromAssetLockTransitionWasm> { | ||
| // Extract assetLockProof as a WASM instance (required) | ||
| let asset_lock: AssetLockProofWasm = try_from_options(&options, "assetLockProof")?; | ||
|
|
||
| // Extract remaining simple fields via serde | ||
| let fields: ShieldFromAssetLockTransitionSimpleFields = | ||
| serde_wasm_bindgen::from_value(options.into()) | ||
| .map_err(|e| WasmDppError::serialization(e.to_string()))?; | ||
|
|
||
| let anchor: [u8; 32] = fields | ||
| .anchor | ||
| .try_into() | ||
| .map_err(|_| WasmDppError::invalid_argument("anchor must be exactly 32 bytes"))?; | ||
|
|
||
| let binding_signature: [u8; 64] = fields.binding_signature.try_into().map_err(|_| { | ||
| WasmDppError::invalid_argument("bindingSignature must be exactly 64 bytes") | ||
| })?; | ||
|
|
||
| Ok(ShieldFromAssetLockTransitionWasm( | ||
| ShieldFromAssetLockTransition::V0(ShieldFromAssetLockTransitionV0 { | ||
| asset_lock_proof: asset_lock.into(), | ||
| actions: fields.actions, | ||
| value_balance: fields.value_balance, | ||
| anchor, | ||
| proof: fields.proof, | ||
| binding_signature, | ||
| signature: BinaryData::from(fields.signature), | ||
| }), | ||
| )) | ||
| } | ||
|
|
||
| #[wasm_bindgen(js_name = getType)] | ||
| pub fn get_type(&self) -> u8 { | ||
| self.0.state_transition_type() as u8 | ||
| } | ||
|
|
||
| /// Returns the asset lock proof as a JS value. | ||
| #[wasm_bindgen(js_name = getAssetLockProof)] | ||
| pub fn get_asset_lock_proof(&self) -> WasmDppResult<JsValue> { | ||
|
shumkov marked this conversation as resolved.
Outdated
|
||
| let proof = match &self.0 { | ||
| ShieldFromAssetLockTransition::V0(v0) => &v0.asset_lock_proof, | ||
| }; | ||
| serde_wasm_bindgen::to_value(proof).map_err(|e| WasmDppError::serialization(e.to_string())) | ||
|
shumkov marked this conversation as resolved.
Outdated
|
||
| } | ||
|
|
||
| /// Returns the serialized Orchard actions as a JS array. | ||
| #[wasm_bindgen(js_name = getActions)] | ||
| pub fn get_actions(&self) -> WasmDppResult<JsValue> { | ||
|
shumkov marked this conversation as resolved.
Outdated
|
||
| let inner = match &self.0 { | ||
| ShieldFromAssetLockTransition::V0(v0) => &v0.actions, | ||
| }; | ||
| serde_wasm_bindgen::to_value(inner).map_err(|e| WasmDppError::serialization(e.to_string())) | ||
| } | ||
|
|
||
| /// Returns the net value balance. | ||
| #[wasm_bindgen(js_name = getValueBalance)] | ||
| pub fn get_value_balance(&self) -> u64 { | ||
| match &self.0 { | ||
| ShieldFromAssetLockTransition::V0(v0) => v0.value_balance, | ||
| } | ||
| } | ||
|
|
||
| /// Returns the anchor (32-byte Merkle root). | ||
| #[wasm_bindgen(js_name = getAnchor)] | ||
| pub fn get_anchor(&self) -> Vec<u8> { | ||
| match &self.0 { | ||
| ShieldFromAssetLockTransition::V0(v0) => v0.anchor.to_vec(), | ||
| } | ||
| } | ||
|
|
||
| /// Returns the Halo2 proof bytes. | ||
| #[wasm_bindgen(js_name = getProof)] | ||
| pub fn get_proof(&self) -> Vec<u8> { | ||
| match &self.0 { | ||
| ShieldFromAssetLockTransition::V0(v0) => v0.proof.clone(), | ||
| } | ||
| } | ||
|
|
||
| /// Returns the RedPallas binding signature (64 bytes). | ||
| #[wasm_bindgen(js_name = getBindingSignature)] | ||
| pub fn get_binding_signature(&self) -> Vec<u8> { | ||
| match &self.0 { | ||
| ShieldFromAssetLockTransition::V0(v0) => v0.binding_signature.to_vec(), | ||
| } | ||
| } | ||
|
|
||
| /// Returns the ECDSA signature. | ||
| #[wasm_bindgen(js_name = getSignature)] | ||
| pub fn get_signature(&self) -> Vec<u8> { | ||
| match &self.0 { | ||
| ShieldFromAssetLockTransition::V0(v0) => v0.signature.to_vec(), | ||
| } | ||
| } | ||
|
|
||
| #[wasm_bindgen(js_name = getModifiedDataIds)] | ||
| pub fn modified_data_ids(&self) -> Vec<IdentifierWasm> { | ||
| self.0 | ||
| .modified_data_ids() | ||
| .into_iter() | ||
| .map(IdentifierWasm::from) | ||
| .collect() | ||
| } | ||
|
|
||
| #[wasm_bindgen(js_name = toBytes)] | ||
| pub fn to_bytes(&self) -> WasmDppResult<Vec<u8>> { | ||
| Ok(PlatformSerializable::serialize_to_bytes( | ||
| &StateTransition::ShieldFromAssetLock(self.0.clone()), | ||
| )?) | ||
| } | ||
|
|
||
| #[wasm_bindgen(js_name = fromBytes)] | ||
| pub fn from_bytes(bytes: Vec<u8>) -> WasmDppResult<ShieldFromAssetLockTransitionWasm> { | ||
| let st = StateTransition::deserialize_from_bytes(&bytes)?; | ||
| match st { | ||
| StateTransition::ShieldFromAssetLock(inner) => Ok(inner.into()), | ||
| _ => Err(WasmDppError::invalid_argument( | ||
| "Invalid state transition type: expected ShieldFromAssetLock", | ||
| )), | ||
| } | ||
| } | ||
|
|
||
| #[wasm_bindgen(js_name = toStateTransition)] | ||
| pub fn to_state_transition(&self) -> crate::state_transitions::base::StateTransitionWasm { | ||
| StateTransition::ShieldFromAssetLock(self.0.clone()).into() | ||
| } | ||
| } | ||
|
|
||
| impl_wasm_conversions_serde!( | ||
| ShieldFromAssetLockTransitionWasm, | ||
| ShieldFromAssetLockTransition, | ||
| ShieldFromAssetLockTransitionObjectJs, | ||
| ShieldFromAssetLockTransitionJSONJs | ||
| ); | ||
|
|
||
| impl_wasm_type_info!( | ||
| ShieldFromAssetLockTransitionWasm, | ||
| ShieldFromAssetLockTransition | ||
| ); | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.