fix(sdk): use string keys instead of object keys in JavaScript Maps#3145
fix(sdk): use string keys instead of object keys in JavaScript Maps#3145
Conversation
JavaScript Map uses reference equality for object keys, making lookups fail when a new object is constructed from the same bytes. Convert all IdentifierWasm keys to base58 strings and PlatformAddressWasm keys to hex strings. ProTxHash-based keys use hex to match ProTxHash conventions. Update unchecked_return_type annotations from Map<Identifier, ...> to Map<string, ...> accordingly. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
📝 WalkthroughWalkthroughMap keys exposed at the WASM/JS boundary were changed from object wrappers (Identifier/PlatformAddress/ProTxHash) to string representations (base58 or hex) across wasm-dpp2, wasm-sdk, js-evo-sdk facades, and tests. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
packages/wasm-sdk/src/state_transitions/addresses.rs (1)
33-56:⚠️ Potential issue | 🟡 MinorStale doc comment: still references
Map<PlatformAddress, PlatformAddressInfo>.Line 35 says "to Map<PlatformAddress, PlatformAddressInfo>" but the function now produces
Map<string, PlatformAddressInfo>with hex string keys.Proposed fix
-/// This helper handles the common pattern of converting IndexMap<PlatformAddress, Option<AddressInfo>> -/// to Map<PlatformAddress, PlatformAddressInfo> for WASM bindings. +/// This helper handles the common pattern of converting IndexMap<PlatformAddress, Option<AddressInfo>> +/// to Map<string, PlatformAddressInfo> for WASM bindings, using hex string keys.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/wasm-sdk/src/state_transitions/addresses.rs` around lines 33 - 56, Update the stale doc comment on function address_infos_to_js_map to state that it converts IndexMap<PlatformAddress, Option<AddressInfo>> into a JavaScript Map<string, PlatformAddressInfo> where keys are hex strings (produced by PlatformAddressWasm::from(...).to_hex()) and values are PlatformAddressInfo (PlatformAddressInfoWasm), instead of claiming Map<PlatformAddress, PlatformAddressInfo>; be concise and mention that keys are hex string representations of PlatformAddress.packages/wasm-dpp2/src/state_transitions/proof_result.rs (1)
249-249:⚠️ Potential issue | 🟡 MinorStale type comments not updated to reflect string keys
Both field comments still reference
IdentifierWasmkeys, but after lines 789 and 811 the runtime keys arestring(base58). The comment at line 509 (Map<string(hex), ...>) shows the correct pattern.📝 Proposed fix
pub struct VerifiedTokenIdentitiesBalancesWasm { - balances: Map, // Map<IdentifierWasm, BigInt> + balances: Map, // Map<string, BigInt> }pub struct VerifiedDocumentsWasm { - documents: Map, // Map<IdentifierWasm, DocumentWasm | undefined> + documents: Map, // Map<string, DocumentWasm | undefined> }Also applies to: 322-322
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/wasm-dpp2/src/state_transitions/proof_result.rs` at line 249, Update the stale field comments in proof_result.rs to reflect that runtime map keys are strings (base58) rather than IdentifierWasm: change the comment for the balances field (Map, previously annotated as Map<IdentifierWasm, BigInt>) to indicate Map<string(base58), BigInt> and make the same update for the other affected field referenced around the 322 comment; locate the fields by name (e.g., balances) in the ProofResult struct and replace IdentifierWasm in comments with the correct string(base58) key notation to match the runtime behavior shown elsewhere (e.g., the Map<string(hex), ...> comment).
🧹 Nitpick comments (3)
packages/wasm-sdk/tests/functional/identities.spec.ts (1)
172-179: Add an assertion on the Map key to actually exercise the PR's fix.The updated comment correctly documents that keys are now
string(base58), but the test body never touches the keys — it only readsbalances.values(). A regression where keys revert toIdentifierobjects would silently pass this test.Since
TEST_IDENTITYis already a base58 string, the cleanest fix is to look up viabalances.get(TEST_IDENTITY)directly:✅ Proposed assertion improvement
- // getIdentitiesBalances returns Map<string, bigint | null> where keys are base58-encoded identifiers const balances = await client.getIdentitiesBalances([TEST_IDENTITY]); expect(balances).to.be.instanceOf(Map); expect(balances.size).to.equal(1); + // Keys must be base58 strings — string lookup must succeed (core fix in this PR) + expect(Array.from(balances.keys())[0]).to.be.a('string'); + expect(Array.from(balances.keys())[0]).to.equal(TEST_IDENTITY); + // Retrieve by string key directly + const balance = balances.get(TEST_IDENTITY); - // For existing identity, balance should be present - const balance = Array.from(balances.values())[0]; expect(typeof balance).to.equal('bigint');🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/wasm-sdk/tests/functional/identities.spec.ts` around lines 172 - 179, The test currently only inspects values and misses verifying that Map keys are base58 strings; update the assertions around balances (returned by client.getIdentitiesBalances) to directly assert the Map contains the key TEST_IDENTITY (e.g., use balances.get(TEST_IDENTITY) or balances.has(TEST_IDENTITY)) and then assert the retrieved value is a bigint; ensure you still check balances is a Map and its size is 1 but replace the Array.from(balances.values())[0] lookup with a direct lookup using TEST_IDENTITY so the test fails if keys are not the expected base58 string.packages/wasm-sdk/src/queries/token.rs (1)
408-408: Minor: duplicated price schedule →(base_price, current_price)extraction logic.The
match schedule { SinglePrice(..) => ..., SetPrices(..) => ... }block appears identically inget_token_price_by_contract(Lines 204–222),get_token_direct_purchase_prices(Lines 429–446), andget_token_direct_purchase_prices_with_proof_info(Lines 767–784). Consider extracting a small helper to avoid this triplication.Also applies to: 448-452
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/wasm-sdk/src/queries/token.rs` at line 408, Duplicate logic extracting (base_price, current_price) from a PriceSchedule enum is repeated in get_token_price_by_contract, get_token_direct_purchase_prices, and get_token_direct_purchase_prices_with_proof_info; factor it into a small helper like fn extract_prices(schedule: &PriceSchedule) -> (PriceType, PriceType) (use the actual price numeric type in the crate) that matches on SinglePrice and SetPrices and returns (base_price, current_price), then replace the repeated match blocks in those functions with calls to extract_prices and update any imports/visibility accordingly.packages/wasm-dpp2/tests/unit/ProofResult.spec.ts (1)
370-395: Consider asserting value retrieval by string keyThe test currently only checks
size === 1after the round-trip. Adding agetassertion would directly validate the core fix — that lookups by base58 string actually return the expected value from the map produced by the WASM binding.✅ Suggested addition
const result = wasm.VerifiedTokenIdentitiesBalances.fromObject(data); expect(result.balances).to.be.instanceOf(Map); expect(result.balances.size).to.equal(1); + expect(result.balances.get(id1.toBase58())).to.equal(999000n);const result = wasm.VerifiedDocuments.fromObject(data); expect(result.documents).to.be.instanceOf(Map); expect(result.documents.size).to.equal(1); + expect(result.documents.has(id1.toBase58())).to.equal(true);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/wasm-dpp2/tests/unit/ProofResult.spec.ts` around lines 370 - 395, The test should assert that map lookups by the base58 key return the expected value: after creating id1 (Identifier) and setting balancesMap with id1.toBase58() -> 999000n, add assertions that result.balances.get(id1.toBase58()) === 999000n and that after serializing with result.toObject() and rehydrating via wasm.VerifiedTokenIdentitiesBalances.fromObject(obj) the roundtrip.balances.get(id1.toBase58()) === 999000n so you verify fromObject/toObject preserves key lookup behavior for VerifiedTokenIdentitiesBalances.balances.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/wasm-sdk/src/queries/epoch.rs`:
- Around line 521-525: The map that builds ProTxHash keys in the proof-info
variants uses IdentifierWasm::from(identifier).to_base58(), causing inconsistent
key formats versus the non-proof variants; update those occurrences (the closure
building the Map from counts.0.into_iter() in the proof-info methods such as
getEvonodesProposedEpochBlocksByIdsWithProofInfo and the other proof-info
helper) to use .to_hex() instead of .to_base58() so ProTxHash keys match the
ProTxHashWasm hex convention used elsewhere.
In `@packages/wasm-sdk/tests/functional/epochs-blocks.spec.ts`:
- Around line 103-107: The comment is incorrect: byRange keys are hex strings
(created via IdentifierWasm::from(identifier).to_hex()), not base58. Update the
comment near byRange.keys() to state the keys are hex, and when you pass that
key (testProTxHash) into getEvonodesProposedEpochBlocksByIdsWithProofInfo (which
expects base58 keys) convert the hex key to base58 first (e.g., decode the hex
Identifier and call its to_base58 / toBase58 equivalent) so the key formats
match between getEvonodesProposedEpochBlocksByRange and
getEvonodesProposedEpochBlocksByIdsWithProofInfo.
---
Outside diff comments:
In `@packages/wasm-dpp2/src/state_transitions/proof_result.rs`:
- Line 249: Update the stale field comments in proof_result.rs to reflect that
runtime map keys are strings (base58) rather than IdentifierWasm: change the
comment for the balances field (Map, previously annotated as Map<IdentifierWasm,
BigInt>) to indicate Map<string(base58), BigInt> and make the same update for
the other affected field referenced around the 322 comment; locate the fields by
name (e.g., balances) in the ProofResult struct and replace IdentifierWasm in
comments with the correct string(base58) key notation to match the runtime
behavior shown elsewhere (e.g., the Map<string(hex), ...> comment).
In `@packages/wasm-sdk/src/state_transitions/addresses.rs`:
- Around line 33-56: Update the stale doc comment on function
address_infos_to_js_map to state that it converts IndexMap<PlatformAddress,
Option<AddressInfo>> into a JavaScript Map<string, PlatformAddressInfo> where
keys are hex strings (produced by PlatformAddressWasm::from(...).to_hex()) and
values are PlatformAddressInfo (PlatformAddressInfoWasm), instead of claiming
Map<PlatformAddress, PlatformAddressInfo>; be concise and mention that keys are
hex string representations of PlatformAddress.
---
Nitpick comments:
In `@packages/wasm-dpp2/tests/unit/ProofResult.spec.ts`:
- Around line 370-395: The test should assert that map lookups by the base58 key
return the expected value: after creating id1 (Identifier) and setting
balancesMap with id1.toBase58() -> 999000n, add assertions that
result.balances.get(id1.toBase58()) === 999000n and that after serializing with
result.toObject() and rehydrating via
wasm.VerifiedTokenIdentitiesBalances.fromObject(obj) the
roundtrip.balances.get(id1.toBase58()) === 999000n so you verify
fromObject/toObject preserves key lookup behavior for
VerifiedTokenIdentitiesBalances.balances.
In `@packages/wasm-sdk/src/queries/token.rs`:
- Line 408: Duplicate logic extracting (base_price, current_price) from a
PriceSchedule enum is repeated in get_token_price_by_contract,
get_token_direct_purchase_prices, and
get_token_direct_purchase_prices_with_proof_info; factor it into a small helper
like fn extract_prices(schedule: &PriceSchedule) -> (PriceType, PriceType) (use
the actual price numeric type in the crate) that matches on SinglePrice and
SetPrices and returns (base_price, current_price), then replace the repeated
match blocks in those functions with calls to extract_prices and update any
imports/visibility accordingly.
In `@packages/wasm-sdk/tests/functional/identities.spec.ts`:
- Around line 172-179: The test currently only inspects values and misses
verifying that Map keys are base58 strings; update the assertions around
balances (returned by client.getIdentitiesBalances) to directly assert the Map
contains the key TEST_IDENTITY (e.g., use balances.get(TEST_IDENTITY) or
balances.has(TEST_IDENTITY)) and then assert the retrieved value is a bigint;
ensure you still check balances is a Map and its size is 1 but replace the
Array.from(balances.values())[0] lookup with a direct lookup using TEST_IDENTITY
so the test fails if keys are not the expected base58 string.
- Use ProTxHashWasm for ProTxHash map keys in epoch.rs instead of IdentifierWasm, with hex encoding matching ProTxHash conventions - Add From<Identifier> for ProTxHashWasm conversion - Fix stale doc comments in addresses.rs, proof_result.rs, and epochs-blocks.spec.ts to reflect string key types Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
🧹 Nitpick comments (2)
packages/wasm-sdk/src/state_transitions/addresses.rs (1)
219-222:addressInfosgetters on result structs are missingunchecked_return_typeafter the key-type change.The PR updates
unchecked_return_typefor the three methods that return aMapdirectly (addressFundsTransfer,addressFundsWithdraw,addressFundingFromAssetLock), but theaddressInfosgetters onIdentityTopUpFromAddressesResultWasm(line 219),IdentityTransferToAddressesResultWasm(line 564), andIdentityCreateFromAddressesResultWasm(line 808) all call the sameaddress_infos_to_js_maphelper and now serveMap<string, PlatformAddressInfo>without advertising that to TypeScript consumers.♻️ Proposed additions for all three getters
- #[wasm_bindgen(getter = "addressInfos")] + #[wasm_bindgen(getter = "addressInfos", unchecked_return_type = "Map<string, PlatformAddressInfo>")] pub fn address_infos(&self) -> Map {Apply identically at lines 219, 564, and 808.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/wasm-sdk/src/state_transitions/addresses.rs` around lines 219 - 222, The addressInfos getters on IdentityTopUpFromAddressesResultWasm, IdentityTransferToAddressesResultWasm, and IdentityCreateFromAddressesResultWasm call address_infos_to_js_map and now return a Map<string, PlatformAddressInfo> but lack the unchecked_return_type annotation; update each getter's attribute to #[wasm_bindgen(getter = "addressInfos", unchecked_return_type)] so the TypeScript signature reflects the actual keyed value type (apply the change to the address_infos method on each of those three structs).packages/wasm-dpp2/src/core/pro_tx_hash.rs (1)
160-164: Consider adding a doc comment clarifying the semantic constraint.This
From<Identifier>impl silently reinterprets any 32-byteIdentifieras aProTxHash. It is semantically valid only when theIdentifierwraps actual ProTxHash bytes (e.g., evonode IDs fromProposerBlockCountById). Without a comment, future callers may invoke this conversion for non-ProTxHash identifiers and get a well-typed but semantically wrong value.🔧 Suggested clarifying doc comment
+/// Reinterprets the raw 32-byte buffer of an `Identifier` as a `ProTxHash`. +/// +/// # Safety / Correctness +/// This conversion is only semantically meaningful when the `Identifier` actually +/// represents an evonode ProTxHash (e.g., keys from `ProposerBlockCountById`). +/// Using it for arbitrary identifiers (document IDs, contract IDs, etc.) will +/// produce a structurally valid but meaningless `ProTxHashWasm`. impl From<dpp::platform_value::Identifier> for ProTxHashWasm { fn from(id: dpp::platform_value::Identifier) -> Self { ProTxHashWasm(ProTxHash::from_byte_array(id.to_buffer())) } }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/wasm-dpp2/src/core/pro_tx_hash.rs` around lines 160 - 164, Add a doc comment on the impl From<dpp::platform_value::Identifier> for ProTxHashWasm explaining that the conversion simply reinterprets the 32-byte Identifier bytes via ProTxHash::from_byte_array and is only semantically valid when the Identifier actually contains ProTxHash bytes (e.g., evonode IDs from ProposerBlockCountById); indicate that using this conversion on other Identifier values produces a well-typed but semantically incorrect ProTxHash and callers should validate the identifier source before converting.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@packages/wasm-dpp2/src/core/pro_tx_hash.rs`:
- Around line 160-164: Add a doc comment on the impl
From<dpp::platform_value::Identifier> for ProTxHashWasm explaining that the
conversion simply reinterprets the 32-byte Identifier bytes via
ProTxHash::from_byte_array and is only semantically valid when the Identifier
actually contains ProTxHash bytes (e.g., evonode IDs from
ProposerBlockCountById); indicate that using this conversion on other Identifier
values produces a well-typed but semantically incorrect ProTxHash and callers
should validate the identifier source before converting.
In `@packages/wasm-sdk/src/state_transitions/addresses.rs`:
- Around line 219-222: The addressInfos getters on
IdentityTopUpFromAddressesResultWasm, IdentityTransferToAddressesResultWasm, and
IdentityCreateFromAddressesResultWasm call address_infos_to_js_map and now
return a Map<string, PlatformAddressInfo> but lack the unchecked_return_type
annotation; update each getter's attribute to #[wasm_bindgen(getter =
"addressInfos", unchecked_return_type)] so the TypeScript signature reflects the
actual keyed value type (apply the change to the address_infos method on each of
those three structs).
|
@thepastaclaw can you fix these and make PR on my PR? |
|
@shumkov I pushed a branch with the TS facade key-type fixes requested in your comment: It updates I could not run a fully clean local |
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
packages/js-evo-sdk/src/addresses/facade.ts (2)
35-59:⚠️ Potential issue | 🟡 MinorStale
@returnsJSDoc — map keys are nowstring, notPlatformAddress.Lines 39–40 and 52–53 still describe the map keys as
PlatformAddress, but the actual return type is nowMap<string, ...>(hex-encoded address). Consumers relying on the docs to understand key lookup will be misled.📝 Suggested doc fix
- * `@returns` Map of PlatformAddress to PlatformAddressInfo (or undefined for unfunded addresses) + * `@returns` Map of hex-encoded PlatformAddress string to PlatformAddressInfo (or undefined for unfunded addresses)- * `@returns` ProofMetadataResponse containing Map of PlatformAddress to PlatformAddressInfo + * `@returns` ProofMetadataResponse containing Map of hex-encoded PlatformAddress string to PlatformAddressInfo🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/js-evo-sdk/src/addresses/facade.ts` around lines 35 - 59, The JSDoc for getMany and getManyWithProof incorrectly states the Map keys are PlatformAddress while the functions return Map<string, ...> (hex-encoded addresses); update the `@returns` descriptions in the JSDoc for both getMany and getManyWithProof to say "Map<string, PlatformAddressInfo | undefined>" and "ProofMetadataResponse containing Map<string, PlatformAddressInfo | undefined>" (or equivalent wording) so docs match the actual return types of getMany and getManyWithProof.
122-227:⚠️ Potential issue | 🟡 MinorSame stale
@returnsJSDoc inwithdraw(line 126) andfundFromAssetLock(line 194–195).Both still say "Map of PlatformAddress to PlatformAddressInfo" while the return type is now
Map<string, wasm.PlatformAddressInfo>with hex-encoded keys.📝 Suggested doc fix
- * `@returns` Promise resolving to Map of PlatformAddress to PlatformAddressInfo + * `@returns` Promise resolving to Map of hex-encoded PlatformAddress string to PlatformAddressInfo(apply to both
withdrawandfundFromAssetLockJSDoc blocks)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/js-evo-sdk/src/addresses/facade.ts` around lines 122 - 227, Update the `@returns` JSDoc for withdraw and fundFromAssetLock to reflect the actual return type Map<string, wasm.PlatformAddressInfo> (hex-encoded string keys) instead of "Map of PlatformAddress to PlatformAddressInfo"; mention that the map keys are hex-encoded PlatformAddress strings to avoid confusion (update the JSDoc blocks above the withdraw method and the fundFromAssetLock method).
🧹 Nitpick comments (1)
packages/js-evo-sdk/src/epoch/facade.ts (1)
50-72: Consider documenting the string key encoding format across all facades.
Map<string, ...>is now the return type across all facades, but the string encoding differs:
- Most Identifier-keyed maps → base58 (e.g., identities, tokens, documents, contracts, groups)
- PlatformAddress maps → hex (
addresses/facade.ts)- ProTxHash maps → hex (this file)
Without this documented, a consumer calling
map.get(id.toHex())on a base58-keyed map will silently miss every entry. A brief JSDoc@returnsnote or a descriptive type alias (e.g.,type Base58String = string) on the changed methods would make the encoding self-documenting.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/js-evo-sdk/src/epoch/facade.ts` around lines 50 - 72, Update the facade methods (evonodesProposedBlocksByIds, evonodesProposedBlocksByIdsWithProof, evonodesProposedBlocksByRange, evonodesProposedBlocksByRangeWithProof) to document the string-key encoding used for map keys: add a concise JSDoc `@returns` note indicating that the Map keys are hex-encoded ProTxHash strings (or define and use a descriptive type alias like HexString = string and reference it in the JSDoc return type), so consumers know to call map.get(id.toHex()) rather than base58 variants.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In `@packages/js-evo-sdk/src/addresses/facade.ts`:
- Around line 35-59: The JSDoc for getMany and getManyWithProof incorrectly
states the Map keys are PlatformAddress while the functions return Map<string,
...> (hex-encoded addresses); update the `@returns` descriptions in the JSDoc for
both getMany and getManyWithProof to say "Map<string, PlatformAddressInfo |
undefined>" and "ProofMetadataResponse containing Map<string,
PlatformAddressInfo | undefined>" (or equivalent wording) so docs match the
actual return types of getMany and getManyWithProof.
- Around line 122-227: Update the `@returns` JSDoc for withdraw and
fundFromAssetLock to reflect the actual return type Map<string,
wasm.PlatformAddressInfo> (hex-encoded string keys) instead of "Map of
PlatformAddress to PlatformAddressInfo"; mention that the map keys are
hex-encoded PlatformAddress strings to avoid confusion (update the JSDoc blocks
above the withdraw method and the fundFromAssetLock method).
---
Nitpick comments:
In `@packages/js-evo-sdk/src/epoch/facade.ts`:
- Around line 50-72: Update the facade methods (evonodesProposedBlocksByIds,
evonodesProposedBlocksByIdsWithProof, evonodesProposedBlocksByRange,
evonodesProposedBlocksByRangeWithProof) to document the string-key encoding used
for map keys: add a concise JSDoc `@returns` note indicating that the Map keys are
hex-encoded ProTxHash strings (or define and use a descriptive type alias like
HexString = string and reference it in the JSDoc return type), so consumers know
to call map.get(id.toHex()) rather than base58 variants.
ℹ️ Review info
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
packages/js-evo-sdk/src/addresses/facade.tspackages/js-evo-sdk/src/contracts/facade.tspackages/js-evo-sdk/src/documents/facade.tspackages/js-evo-sdk/src/epoch/facade.tspackages/js-evo-sdk/src/group/facade.tspackages/js-evo-sdk/src/identities/facade.tspackages/js-evo-sdk/src/tokens/facade.tspackages/js-evo-sdk/src/voting/facade.ts
🎭 Audit SummaryReviewed by: Claude Code with a 2-agent team:
Verdict: ✅ ApproveNo blockers. No correctness issues. The PR solves a real JS Findings
Pre-existing / Outside-diffNo pre-existing issues found within the scope of this change (CodeRabbit already flagged the stale doc comment in Confirmed Safe
Positive Observations
🤖 Generated with Claude Code |
lklimek
left a comment
There was a problem hiding this comment.
Fix the test please, otherwise LGTM.
| const id2 = wasm.Identifier.fromBase58('ckBqfQe7LU7vwrwXopyCB4n5phZShjA16BGhNGpsD5U'); | ||
|
|
||
| // This simulates getEvonodesProposedEpochBlocksByIds which returns Map<Identifier, bigint> | ||
| // This simulates getEvonodesProposedEpochBlocksByIds which returns Map<string, bigint> |
There was a problem hiding this comment.
[MEDIUM] The comment was updated to say Map<string, bigint>, but the test still constructs the Map with Identifier objects as keys:
const map = new Map([
[id1, 100n], // id1 is an Identifier object, not a string
[id2, 200n],
]);This passes incidentally because testJsValueToJson calls .toString() on any key, but it no longer simulates the actual runtime scenario it claims to simulate.
// This simulates getEvonodesProposedEpochBlocksByIds which returns Map<string, bigint>
const map = new Map([
[id1.toBase58(), 100n],
[id2.toBase58(), 200n],
Issue being fixed or feature implemented
JavaScript
Mapuses reference equality for object keys. When Rust WASM bindings create Maps withIdentifierWasmorPlatformAddressWasmobjectsas keys, the resulting JS Maps are unusable —
map.get(new Identifier(sameBytes))returnsundefinedbecause it's a different object instance.What was done?
Converted all WASM Map keys from object instances to string primitives across
wasm-sdkandwasm-dpp2:Identifierkeys →.to_base58()string (35 locations across 10 Rust files)PlatformAddresskeys →.to_hex()string (address.rs,addresses.rs)epoch.rs→.to_hex()to matchProTxHashWasmhex conventionunchecked_return_typeannotations fromMap<Identifier, ...>/Map<PlatformAddress, ...>toMap<string, ...>Identifierobject creationRust files:
token.rs(10 fixes),group.rs(7),identity.rs(4),epoch.rs(4),address.rs(2),document.rs(2),data_contract.rs(2),
votes.rs(1),addresses.rs(1),proof_result.rs(2)How Has This Been Tested?
cargo check -p wasm-sdkandcargo check -p wasm-dpp2— compile cleanwasm-dpp2:Group.spec.ts,ProofResult.spec.ts,TokenConfiguration.spec.ts,TokenDistributionRules.spec.ts,TokenPreProgrammedDistribution.spec.ts,js-value-to-json.spec.tswasm-sdk:epochs-blocks.spec.ts,identities.spec.tsBreaking Changes
Map keys returned by all
wasm-sdkquery methods andwasm-dpp2proof result methods change fromIdentifier/PlatformAddressobjects tostring. Consumers that previously called.toBase58()or.toHex()on map keys should use the key directly. Consumers that compared keys byreference were already broken.
Checklist:
For repository code-owners and collaborators only
Summary by CodeRabbit
API Changes
Tests