Skip to content

feat: enable Platform address state transitions - #71

Merged
thephez merged 3 commits into
masterfrom
feat/enable-more-sts
Aug 3, 2026
Merged

thephez merged 3 commits into
masterfrom
feat/enable-more-sts

Conversation

@thephez

@thephez thephez commented Jul 23, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Platform address state transitions were previously stubbed out and marked disabled, throwing on prepare/execute. This PR implements them against the installed SDK so all six can be run from the UI.

Changes

  • address-operations.js — full prepare/execute/renderCode implementations replacing the disabled stubs. Each derives the sender address from its WIF via PlatformAddressSigner, fetches on-chain address info, validates balance/amount, and serializes returned addressInfos. Includes:
    • Balance and positive-amount validation, sender/recipient mismatch checks
    • Nonce/revision-conflict retry (withNonceRetry) that rebuilds options and resends
    • A self-contained base58check → CoreScript decoder (P2PKH/P2SH) for the withdraw output script
  • api-definitions.json — removed the disabled flags and the manual senderNonce inputs (now derived on-chain); switched key inputs to WIF-based fields (addressPrivateKeyWif, identityPrivateKeyWif) and added addressPrivateKeyWif to the asset-lock funding form.
  • definitions-data.js — updated auth requirements to target the new WIF fields; added the asset-lock proof requirement for addressFundFromAssetLock.
  • sdk-types.js — re-export CoreScript, PlatformAddress, PoolingWasm, and ensureInitialized.

Testing

  • New unit suite tests/unit/address-operations.test.js (216 lines) covering the operations and validation paths.
  • E2E transition specs and fixtures extended with a Platform address lifecycle; .env.example documents the new TEST_PLATFORM_ADDRESS_* / _KEY_* variables (each address must match its WIF).

Summary by CodeRabbit

  • New Features
    • Enabled platform address operations for transfers, withdrawals, identity funding, and identity creation.
    • Updated required inputs, including private key WIFs and asset-lock proofs where applicable.
    • Added stronger validation, balance checks, and automatic retries for stale transaction state.
  • Documentation
    • Refreshed platform address examples with signer-based workflows and identity checks.
  • Tests
    • Expanded unit and end-to-end coverage for platform address operations and lifecycle verification.

@coderabbitai

coderabbitai Bot commented Jul 23, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 4345841e-1a95-4954-80d7-67d9fe1dcde9

📥 Commits

Reviewing files that changed from the base of the PR and between 46f79cb and 8645818.

📒 Files selected for processing (7)
  • public/AI_REFERENCE.md
  • public/api-definitions.json
  • public/src/sdk-types.js
  • public/src/transitions/address-operations.js
  • tests/e2e/fixtures/test-data.js
  • tests/e2e/transitions/state-transitions.spec.js
  • tests/unit/address-operations.test.js
💤 Files with no reviewable changes (3)
  • tests/e2e/fixtures/test-data.js
  • tests/e2e/transitions/state-transitions.spec.js
  • public/api-definitions.json
🚧 Files skipped from review as they are similar to previous changes (3)
  • public/src/sdk-types.js
  • public/AI_REFERENCE.md
  • public/src/transitions/address-operations.js

📝 Walkthrough

Walkthrough

Platform address transitions are enabled across schemas, authentication metadata, SDK operation handlers, catalogs, reference examples, and tests. The implementation adds validation, signer construction, address parsing, nonce retry, result serialization, and end-to-end lifecycle coverage.

Changes

Platform address transitions

Layer / File(s) Summary
Transition contracts and authentication
public/api-definitions.json, public/src/definitions-data.js, public/src/sdk-types.js, public/sdk-operation-catalog.json
Updates transition inputs, private-key targets, asset-lock proof requirements, SDK type exports, and enabled operation metadata.
Functional address operations
public/src/transitions/address-operations.js
Replaces disabled handlers with functional preparation and execution for six address transitions, including validation, funding checks, nonce retry, Core address parsing, serialization, and code rendering.
Reference examples
public/AI_REFERENCE.md
Updates address-transition examples to use platform signers, WIF keys, plain input/output objects, and runtime address and identity checks.
Unit and end-to-end validation
tests/unit/*, tests/e2e/*
Adds mocked unit coverage, API-definition checks, lifecycle fixtures, query helpers, parameter handling, and conditional serial end-to-end tests.
Documentation validation report
public/documentation-check-report.txt
Updates the documentation check timestamp while retaining the successful status.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant TransitionUI
  participant addressTransitionOperations
  participant AddressState
  participant SDKAddresses
  TransitionUI->>addressTransitionOperations: prepare transition inputs
  addressTransitionOperations->>AddressState: fetch address or identity data
  addressTransitionOperations->>SDKAddresses: execute address operation
  SDKAddresses-->>addressTransitionOperations: return transition result
  addressTransitionOperations-->>TransitionUI: serialized result and address information
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 10.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: enabling Platform address state transitions.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/enable-more-sts

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@thephez
thephez changed the base branch from master to refactor/extract-transition-ops July 23, 2026 18:43
Base automatically changed from refactor/extract-transition-ops to master July 23, 2026 19:48
Remove the 'disabled' flags gating Platform address operations and update their inputs to the SDK's WIF-based key model, dropping the manual senderNonce fields.

Expose the additional SDK exports (CoreScript, PlatformAddress, PoolingWasm, ensureInitialized) needed by the address handler, add asset-lock proof auth wiring for addressFundFromAssetLock, and cover the address operations with unit and e2e tests.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@thephez
thephez force-pushed the feat/enable-more-sts branch from f91668b to 6aecf2a Compare July 23, 2026 20:15
@thephez
thephez marked this pull request as ready for review July 23, 2026 20:15
@thepastaclaw

thepastaclaw commented Jul 23, 2026 •

Copy link
Copy Markdown
Contributor

ℹ️ Review superseded (commit 8645818)
Last checked: 2026-08-03 16:10 UTC

@thephez

thephez commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 23, 2026 •

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (2)
public/src/transitions/address-operations.js (2)

92-100: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Nonce/revision retry relies on brittle error-message matching.

withNonceRetry detects retryable failures via /nonce|revision/i.test(String(error?.message || error)). If the SDK changes wording, wraps errors, or localizes messages, the retry silently stops firing and callers get a hard failure instead of a rebuild+retry.

Please check whether @dashevo/evo-sdk exposes a typed/coded error (e.g. an error class or code property) for nonce/revision conflicts that could be matched instead of the message string.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@public/src/transitions/address-operations.js` around lines 92 - 100, Update
withNonceRetry to detect nonce/revision conflicts using the typed or coded error
contract exposed by `@dashevo/evo-sdk`, rather than matching error.message text.
Inspect the SDK’s error class/code and use that stable identifier in the retry
condition, while preserving the existing prepared.rebuild guard, rebuild, retry,
and rethrow behavior for non-matching errors.

102-134: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Hand-rolled Base58Check decoding for Core addresses.

coreScript reimplements Base58 decoding, leading-zero handling, and double-SHA256 checksum verification from scratch. The version bytes (0x4c/0x8c P2PKH, 0x10/0x13 P2SH) are correct per Dash's documented address conversion scheme, but this is exactly the kind of address/checksum parsing that's easy to get subtly wrong on edge cases and better delegated to a vetted library or an existing SDK helper.

Please check whether @dashevo/evo-sdk's CoreScript (or another exported helper) already offers a fromAddress/parse method that performs this decoding, to avoid maintaining bespoke Base58Check logic for money-moving address parsing.

Separately, note this function accepts both mainnet (0x4c/0x10) and testnet (0x8c/0x13) prefixes without checking the address against the SDK's configured network, so a testnet address could be accepted while connected to mainnet (or vice versa) without an early, friendly validation error.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@public/src/transitions/address-operations.js` around lines 102 - 134, Replace
the bespoke Base58Check decoding in coreScript with the vetted `@dashevo/evo-sdk`
CoreScript.fromAddress or equivalent exported address parser, preserving the
existing CoreScript result and error behavior. Use the SDK/configured network
validation so mainnet and testnet prefixes are rejected when they do not match
the active network, and remove the now-unneeded manual decoding and checksum
logic.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@public/api-definitions.json`:
- Around line 2497-2502: Change the input type for both addressPrivateKeyWif and
identityPrivateKeyWif from text to password in the corresponding API definition
entries, matching the existing masked private-key field behavior.

In `@public/src/transitions/address-operations.js`:
- Line 198: Validate the non-empty `values.coreFeePerByte` value before
constructing the return object in the address-operation flow, rejecting
non-numeric or otherwise invalid values with a clear client-side validation
error instead of passing `NaN` to `sdk.addresses.withdraw`; preserve `undefined`
for empty or null values.
- Around line 248-264: Update addressCreateIdentity’s prepare and execute
methods to match the nonce/revision retry flow used by addressTransfer,
addressTopUpIdentity, and addressWithdraw: return a rebuild closure that
recreates the spending input and prepared identity options, then invoke
createIdentity through withNonceRetry so conflicts rebuild the consumed
platform-address input before retrying.

In `@tests/e2e/.env.example`:
- Around line 11-16: Add TEST_PLATFORM_ASSET_LOCK_PROOF and
TEST_PLATFORM_ASSET_LOCK_PRIVATE_KEY to the Platform Address lifecycle block in
tests/e2e/.env.example. The references in
tests/e2e/fixtures/test-data.js:956-971 and
tests/e2e/transitions/state-transitions.spec.js:1321-1327 require these
variables; no direct changes are needed there.

---

Nitpick comments:
In `@public/src/transitions/address-operations.js`:
- Around line 92-100: Update withNonceRetry to detect nonce/revision conflicts
using the typed or coded error contract exposed by `@dashevo/evo-sdk`, rather than
matching error.message text. Inspect the SDK’s error class/code and use that
stable identifier in the retry condition, while preserving the existing
prepared.rebuild guard, rebuild, retry, and rethrow behavior for non-matching
errors.
- Around line 102-134: Replace the bespoke Base58Check decoding in coreScript
with the vetted `@dashevo/evo-sdk` CoreScript.fromAddress or equivalent exported
address parser, preserving the existing CoreScript result and error behavior.
Use the SDK/configured network validation so mainnet and testnet prefixes are
rejected when they do not match the active network, and remove the now-unneeded
manual decoding and checksum logic.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 78addb80-19d2-4351-bb9b-21bdd2b6fad2

📥 Commits

Reviewing files that changed from the base of the PR and between 0a822f5 and 6aecf2a.

📒 Files selected for processing (13)
  • public/AI_REFERENCE.md
  • public/api-definitions.json
  • public/sdk-operation-catalog.json
  • public/src/definitions-data.js
  • public/src/sdk-types.js
  • public/src/transitions/address-operations.js
  • tests/e2e/.env.example
  • tests/e2e/fixtures/test-data.js
  • tests/e2e/queries/query-execution.spec.js
  • tests/e2e/transitions/state-transitions.spec.js
  • tests/e2e/utils/sdk-page.js
  • tests/unit/address-operations.test.js
  • tests/unit/transition-operations.test.js

Comment thread public/api-definitions.json
Comment thread public/src/transitions/address-operations.js Outdated
Comment thread public/src/transitions/address-operations.js
Comment thread tests/e2e/.env.example
@thephez

thephez commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 23, 2026 •

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@thephez

thephez commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 23, 2026 •

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
public/documentation-check-report.txt (1)

4-4: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Avoid committing a wall-clock timestamp in the tracked report.

scripts/check_documentation.py regenerates this line with datetime.now().isoformat(), so every documentation check produces a new diff even when documentation is unchanged. Remove the timestamp from the committed report or publish this report as a CI artifact instead.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@public/documentation-check-report.txt` at line 4, Remove the generated
wall-clock Timestamp line from the tracked documentation-check report, or stop
tracking the report and publish it only as a CI artifact. Ensure
scripts/check_documentation.py output no longer creates recurring diffs for
unchanged documentation.
tests/e2e/.env.example (1)

17-18: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Reorder the asset-lock variables.

dotenv-linter requires TEST_PLATFORM_ASSET_LOCK_PRIVATE_KEY to appear before TEST_PLATFORM_ASSET_LOCK_PROOF.

Proposed fix
-TEST_PLATFORM_ASSET_LOCK_PROOF=YOUR_CONSUMABLE_ASSET_LOCK_PROOF
 TEST_PLATFORM_ASSET_LOCK_PRIVATE_KEY=YOUR_ASSET_LOCK_PRIVATE_KEY_WIF
+TEST_PLATFORM_ASSET_LOCK_PROOF=YOUR_CONSUMABLE_ASSET_LOCK_PROOF
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/e2e/.env.example` around lines 17 - 18, Reorder the asset-lock
environment variables in the example configuration so
TEST_PLATFORM_ASSET_LOCK_PRIVATE_KEY appears before
TEST_PLATFORM_ASSET_LOCK_PROOF, while preserving both variable names and
placeholder values.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@public/documentation-check-report.txt`:
- Line 4: Remove the generated wall-clock Timestamp line from the tracked
documentation-check report, or stop tracking the report and publish it only as a
CI artifact. Ensure scripts/check_documentation.py output no longer creates
recurring diffs for unchanged documentation.

In `@tests/e2e/.env.example`:
- Around line 17-18: Reorder the asset-lock environment variables in the example
configuration so TEST_PLATFORM_ASSET_LOCK_PRIVATE_KEY appears before
TEST_PLATFORM_ASSET_LOCK_PROOF, while preserving both variable names and
placeholder values.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: c243d1c5-6876-41a7-a961-992a8a10b253

📥 Commits

Reviewing files that changed from the base of the PR and between 6aecf2a and 46f79cb.

📒 Files selected for processing (5)
  • public/api-definitions.json
  • public/documentation-check-report.txt
  • public/src/transitions/address-operations.js
  • tests/e2e/.env.example
  • tests/unit/address-operations.test.js
🚧 Files skipped from review as they are similar to previous changes (3)
  • tests/unit/address-operations.test.js
  • public/api-definitions.json
  • public/src/transitions/address-operations.js

@thepastaclaw thepastaclaw left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Preliminary review — Codex only

The Platform address implementation is generally well structured, but three verified runtime and documentation contract mismatches prevent advertised flows from working correctly. Asset-lock funding always builds a structurally invalid transition, an empty optional withdrawal fee fails SDK deserialization, and the generated withdrawal example references missing symbols and an input the UI never supplies.

Validated blockers were found in the Codex precheck. Sonnet is deferred until a fresh Codex revalidation clears the blocker gate.

Review provenance

  • Codex reviewers: gpt-5.6-sol — general (completed)
  • Verifier: gpt-5.6-sol — verifier
  • Sonnet: not run (deferred by blocker gate)

🔴 3 blocking

🤖 Prompt for all review comments with AI agents
These findings are from an automated code review. Verify each finding against the current code and only fix it if needed.

In `public/src/transitions/address-operations.js`:
- [BLOCKING] public/src/transitions/address-operations.js:249-250: Build a remainder output and valid fee strategy for asset-lock funding
  Asset-lock funding requires exactly one output with no `amount`, which becomes the remainder recipient. This code always supplies an explicit amount, so SDK structure validation rejects the transition with `Exactly one output must have None value (remainder recipient)`. The facade also constructs this transition with no address inputs, while an omitted `feeStrategy` defaults to `DeductFromInput(0)`, which is out of bounds for the empty input set. Every request built by this operation therefore fails before broadcast. Emit the single recipient without an amount, pass a strategy such as `FeeStrategyStep.reduceOutput(0)`, and remove the now-inapplicable required `amount` input from `public/api-definitions.json`, fixtures, and the generated example.
- [BLOCKING] public/src/transitions/address-operations.js:205: Default the optional withdrawal fee before calling the SDK
  `coreFeePerByte` is optional in `public/api-definitions.json`, and the displayed placeholder of `1` is not submitted as a value. Leaving the field empty produces `null`, which this helper converts to `undefined`, but the options object still includes that property. The installed SDK deserializes `coreFeePerByte` into a required `u32`, so withdrawal preparation fails whenever the user accepts the form's advertised optional behavior. Apply the displayed default here or mark the field required.
- [BLOCKING] public/src/transitions/address-operations.js:216: Generate an executable withdrawal example
  The generated snippet imports only `PlatformAddressSigner` and `PrivateKey`, then references `CoreScript` and `PoolingWasm` without importing them. It also uses `coreAddressHash`, which is neither defined in the example nor supplied by the UI; the documented input is the Base58Check `toAddress`. This broken renderer is used by the UI code preview and propagated into `public/AI_REFERENCE.md`, so copying the example raises a `ReferenceError` before the SDK call. Import the required SDK symbols and generate a `toAddress` conversion equivalent to the runtime `coreScript()` path.

Comment thread public/src/transitions/address-operations.js Outdated
Comment thread public/src/transitions/address-operations.js Outdated
Comment thread public/src/transitions/address-operations.js Outdated
Default an omitted withdrawal core fee per byte to 1 instead of sending undefined to the SDK's required u32 field.

Generate an executable withdrawal example: import CoreScript/PoolingWasm and derive the output script from the Base58Check toAddress via a self-contained helper rather than the undefined coreAddressHash.

Build asset-lock funding with a single remainder output (no amount) and a reduceOutput(0) fee strategy, and drop the now-inapplicable amount input.
@thephez
thephez merged commit 5d92d2f into master Aug 3, 2026
2 checks passed
@thephez
thephez deleted the feat/enable-more-sts branch August 3, 2026 16:09
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

Successfully merging this pull request may close these issues.

2 participants