Skip to content

DIP: Dash Platform Application Key Exchange and State Transition Signing#181

Open
PastaPastaPasta wants to merge 6 commits into
dashpay:masterfrom
PastaPastaPasta:dip-pasta-yappr
Open

DIP: Dash Platform Application Key Exchange and State Transition Signing#181
PastaPastaPasta wants to merge 6 commits into
dashpay:masterfrom
PastaPastaPasta:dip-pasta-yappr

Conversation

@PastaPastaPasta

@PastaPastaPasta PastaPastaPasta commented Mar 11, 2026

Copy link
Copy Markdown
Member

Summary

  • Defines the dash-key: URI protocol for wallet-based QR code login to Dash Platform applications using ECDH key exchange and AES-256-GCM encryption
  • Defines the dash-st: URI protocol for requesting wallet signature and broadcast of unsigned state transitions
  • Specifies the full cryptographic flow: BIP32 derivation (m/9'/coin_type'/21'/account'), HKDF key derivation, ECDH shared secret, and per-contract/per-identity key isolation
  • Documents the loginKeyResponse Platform contract schema, indices, and polling mechanism
  • Covers first-time key registration via IdentityUpdateTransition with ECDSA_HASH160 keys

Test plan

  • Review spec for technical accuracy against existing implementations in dash-evo-tool and yappr
  • Verify all cryptographic parameters (HKDF salts, info fields, key sizes) match implementations
  • Review security considerations section for completeness

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Documentation
    • Added a specification for two URI-based wallet protocols: key-exchange (deterministic login key derivation, ECDH/shared-secret, AES-256-GCM encryption, registration flow, polling, UX prompts, validation, and security considerations) and state-transition signing (unsigned transition format, query parameters, encodings, wallet validation/signing flow).
    • Added a Masternode Reward Shares specification introducing a unified payouts list, payout ordering/rounding and validation rules, registration/update semantics, consensus/reporting expectations, deployment guidance, and security considerations.

…ansition Signing

Defines the dash-key: and dash-st: URI protocols for wallet-based QR code login to Dash Platform applications. Covers ECDH key exchange, AES-256-GCM encryption, BIP32+HKDF key derivation, the loginKeyResponse contract schema, and first-time key registration flow.
@coderabbitai

coderabbitai Bot commented Mar 11, 2026

Copy link
Copy Markdown

Need the big picture first? Review this PR in Change Stack to see what changed before going file by file.

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds two new DIPs: dip-pasta-yappr.md describing dash-key and dash-st wallet–app URI protocols, cryptographic flows, encodings, and UX/validation; and dip-pasta-masternode-shares.md defining provider payload v4 with a unified payouts list, payment/validation rules, RPC changes, deployment guidance, tests, and security notes.

Changes

DIP: Wallet–App Protocols (dash-key / dash-st)

Layer / File(s) Summary
dash-key & dash-st specification
dip-pasta-yappr.md
New specification introducing two URI-based protocols for wallet–app interaction: URI formats and query parameters, payload encodings, deterministic login key derivation (BIP32 path + HKDF), ECDH shared-secret and AES-256-GCM encryption, application key derivation, Dash data contract (loginKeyResponse) and lifecycle, dash-st unsigned state-transition signing workflow, first-time login registration (IdentityUpdateTransition), validation rules, nonce management, UX wallet prompts, and security considerations.

Masternode Reward Shares

Layer / File(s) Summary
Header and Table of Contents
dip-pasta-masternode-shares.md
Document header, metadata, and table of contents for the Masternode Reward Shares DIP.
Intent and context
dip-pasta-masternode-shares.md
Defines intent to extend deterministic masternode lists to split owner rewards across multiple payout scripts and outlines motivation and related work.
Protocol changes and validation rules
dip-pasta-masternode-shares.md
Introduces provider transaction payload v4 with unified payouts list, payout entry/list structure, consensus ordering/rounding, ProRegTx/ProUpRegTx payload updates, list replacement semantics, payment construction (operator subtraction then basis-point splitting), and enumerated validation constraints.
RPC/JSON and filtering interoperability
dip-pasta-masternode-shares.md
Requires RPC/JSON inputs to accept payouts arrays, JSON outputs to expose payouts, and updates special transaction/bloom filtering to include all payout scripts.
Deployment, compatibility, and rationale
dip-pasta-masternode-shares.md
Activation and compatibility expectations, equivalence behavior for single-entry payouts, and rationale for unified list, max entries, basis-point choice, and operator reward handling.
Test requirements and security considerations
dip-pasta-masternode-shares.md
Enumerated valid/invalid test cases, runtime payment/reporting expectations, and security notes on key reuse, dust limits, and off-chain distribution removal.
Copyright and license
dip-pasta-masternode-shares.md
License and copyright attribution for the DIP.

Sequence Diagram(s)

sequenceDiagram
    participant App
    participant Wallet
    participant Node
    App->>Wallet: Open `dash-key:` URI (includes login request)
    Wallet->>Wallet: Derive deterministic login key (BIP32 + HKDF)
    Wallet->>App: Provide public key / Base58 payload (encrypted loginKeyResponse request)
    App->>Node: Query `loginKeyResponse` contract / poll
    Node-->>App: Return `loginKeyResponse` (encrypted payload)
    App->>Wallet: Forward encrypted loginKeyResponse
    Wallet->>Wallet: ECDH -> derive shared-secret, decrypt (AES-256-GCM)
    Wallet-->>App: Confirm login (signed response / auth keys)
Loading
sequenceDiagram
    participant App
    participant Wallet
    participant Node
    participant IdentityStore
    App->>Wallet: Open `dash-st:` URI with unsigned state transition
    Wallet->>Wallet: Validate wallet identity/keys, fetch signing keys
    Wallet->>IdentityStore: (optional) check identity/key metadata
    Wallet->>Node: (optional) request additional state or fees
    Wallet->>Wallet: Sign state transition per-identity/key selection
    Wallet-->>App: Return signed state transition (encoded)
    App->>Node: Submit signed state transition to network
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and specifically describes the main change: a DIP document defining Dash Platform application key exchange and state transition signing protocols.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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 and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
dip-pasta-yappr.md (2)

262-265: Consider clarifying concurrent request handling.

The keyIndex logic states that if no document exists, keyIndex is 0. If a wallet processes multiple key exchange requests for the same identity and contract concurrently (before the first document is created), both could use keyIndex 0, potentially creating a race condition. Consider adding guidance on how wallets should handle this scenario (e.g., serialize requests per identity+contract or retry on conflict).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@dip-pasta-yappr.md` around lines 262 - 265, Clarify concurrent-request
behavior for keyIndex/loginKeyResponse: explain that when no loginKeyResponse
exists wallets must handle races by serializing requests per identity+contract
or using a create-if-not-exists atomic operation and retry-on-conflict;
reference the keyIndex and loginKeyResponse documents and state a recommended
strategy (e.g., queue/serialize per identity+contract, use optimistic
concurrency/version checks on loginKeyResponse, or retry on conflict) so two
concurrent requests cannot both assume keyIndex = 0 and create duplicate keys.

391-401: Consider exponential backoff for revision conflict retries.

The document lifecycle specifies retrying up to 3 times with a fixed 500ms delay on revision conflicts. Consider recommending exponential backoff (e.g., 500ms, 1000ms, 2000ms) to reduce contention under high load while maintaining the same maximum retry count.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@dip-pasta-yappr.md` around lines 391 - 401, The retry logic for handling
revision conflicts when updating a loginKeyResponse document should use
exponential backoff instead of a fixed 500ms delay: update the retry loop that
currently retries up to 3 times with a fixed 500ms pause to instead wait 500ms,
then 1000ms, then 2000ms between attempts (keeping the same max retry count),
and continue to re-query the loginKeyResponse document on each retry and
preserve the existing update/create flow and revision bump behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@dip-pasta-yappr.md`:
- Line 36: The Table of Contents link fragment "#supported-encodings" is broken
because the actual header is "## Encoding"; update either the TOC entry or the
heading so they match—e.g., change the TOC item "* [Supported
Encodings](`#supported-encodings`)" to "* [Encoding](`#encoding`)" or rename the
header "## Encoding" to "## Supported Encodings" so the fragment and header text
are consistent.

---

Nitpick comments:
In `@dip-pasta-yappr.md`:
- Around line 262-265: Clarify concurrent-request behavior for
keyIndex/loginKeyResponse: explain that when no loginKeyResponse exists wallets
must handle races by serializing requests per identity+contract or using a
create-if-not-exists atomic operation and retry-on-conflict; reference the
keyIndex and loginKeyResponse documents and state a recommended strategy (e.g.,
queue/serialize per identity+contract, use optimistic concurrency/version checks
on loginKeyResponse, or retry on conflict) so two concurrent requests cannot
both assume keyIndex = 0 and create duplicate keys.
- Around line 391-401: The retry logic for handling revision conflicts when
updating a loginKeyResponse document should use exponential backoff instead of a
fixed 500ms delay: update the retry loop that currently retries up to 3 times
with a fixed 500ms pause to instead wait 500ms, then 1000ms, then 2000ms between
attempts (keeping the same max retry count), and continue to re-query the
loginKeyResponse document on each retry and preserve the existing update/create
flow and revision bump behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 6edfd7c4-83bf-45c9-b579-c785373b1631

📥 Commits

Reviewing files that changed from the base of the PR and between 40b74e9 and 9482c77.

📒 Files selected for processing (1)
  • dip-pasta-yappr.md

Comment thread dip-pasta-yappr.md

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9482c77c3f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread dip-pasta-yappr.md Outdated
Comment thread dip-pasta-yappr.md Outdated
Comment thread dip-pasta-yappr.md Outdated
Comment thread dip-pasta-yappr.md Outdated
| ---------- | ----- | ----------- |
| 9' | Feature purpose (per [DIP-0009](https://github.com/dashpay/dips/blob/master/dip-0009.md)) | |
| coin_type' | `5` (mainnet) or `1` (testnet/devnet/regtest) | Per [BIP-0044](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki) |
| 21' | Key exchange feature index | |

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Why 21?

Comment thread dip-pasta-yappr.md Outdated
Comment thread dip-pasta-yappr.md Outdated
| --------- | -------- | ----------- |
| `n` | Yes | Network identifier (`m`, `t`, `d`, or `r`) |
| `v` | Yes | Protocol version; must be `1` |
| `id` | No | Base58-encoded identity identifier hint (32 bytes); wallet should pre-select this identity |

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Extraneous word?

Suggested change
| `id` | No | Base58-encoded identity identifier hint (32 bytes); wallet should pre-select this identity |
| `id` | No | Base58-encoded identity identifier (32 bytes); wallet should pre-select this identity |

Comment thread dip-pasta-yappr.md Outdated
Comment thread dip-pasta-yappr.md
- Fix broken ToC link: rename heading to 'Supported Encodings' to match ToC entry
- Make Binary Payload Layout a subsection of URI Format and reorder above Network Identifiers
- Simplify BIP32 path table by removing empty Description column
- Add hyperlink to Network Identifiers from dash-st component table
- Remove extraneous 'hint' from id parameter description
- Remove unnecessary 'Read Only' rows from key registration tables

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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 `@dip-pasta-masternode-shares.md`:
- Around line 15-28: The Table of Contents entries use two spaces after numeric
list markers which violates markdownlint MD030; update each TOC line (e.g., "1. 
[Abstract](`#abstract`)", "4.  [Specification](`#specification`)" and the nested
items like "4.  1.  [Terminology](`#terminology`)") to use a single space after
the period (e.g., "1. [Abstract](`#abstract`)"), and apply the same single-space
fix to the remaining TOC entries indicated in the comment (including lines
29-32) so all numbered list markers conform to MD030.
🪄 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

Run ID: 4d7df077-48e0-48c6-b473-46f573c1b5eb

📥 Commits

Reviewing files that changed from the base of the PR and between 50756a7 and adbe162.

📒 Files selected for processing (1)
  • dip-pasta-masternode-shares.md

Comment on lines +15 to +28
1. [Abstract](#abstract)
2. [Motivation](#motivation)
3. [Prior Work](#prior-work)
4. [Specification](#specification)
1. [Terminology](#terminology)
2. [Provider Transaction Version](#provider-transaction-version)
3. [Masternode Payout Share](#masternode-payout-share)
4. [Registering a Masternode](#registering-a-masternode)
5. [Updating Masternode Payout Shares](#updating-masternode-payout-shares)
6. [Masternode List State](#masternode-list-state)
7. [Masternode Reward Payments](#masternode-reward-payments)
8. [Validation Rules](#validation-rules)
9. [RPC and JSON Interfaces](#rpc-and-json-interfaces)
10. [Special Transaction Filtering](#special-transaction-filtering)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Fix list marker spacing to pass markdownlint.

The Table of Contents uses 2 spaces after numbered list markers, but markdownlint rule MD030 expects exactly 1 space. This will cause the GitHub Actions lint check to fail.

📝 Proposed fix for list marker spacing
-1.  [Abstract](`#abstract`)
-2.  [Motivation](`#motivation`)
-3.  [Prior Work](`#prior-work`)
-4.  [Specification](`#specification`)
-    1.  [Terminology](`#terminology`)
-    2.  [Provider Transaction Version](`#provider-transaction-version`)
-    3.  [Masternode Payout Share](`#masternode-payout-share`)
-    4.  [Registering a Masternode](`#registering-a-masternode`)
-    5.  [Updating Masternode Payout Shares](`#updating-masternode-payout-shares`)
-    6.  [Masternode List State](`#masternode-list-state`)
-    7.  [Masternode Reward Payments](`#masternode-reward-payments`)
-    8.  [Validation Rules](`#validation-rules`)
-    9.  [RPC and JSON Interfaces](`#rpc-and-json-interfaces`)
-    10. [Special Transaction Filtering](`#special-transaction-filtering`)
+1. [Abstract](`#abstract`)
+2. [Motivation](`#motivation`)
+3. [Prior Work](`#prior-work`)
+4. [Specification](`#specification`)
+    1. [Terminology](`#terminology`)
+    2. [Provider Transaction Version](`#provider-transaction-version`)
+    3. [Masternode Payout Share](`#masternode-payout-share`)
+    4. [Registering a Masternode](`#registering-a-masternode`)
+    5. [Updating Masternode Payout Shares](`#updating-masternode-payout-shares`)
+    6. [Masternode List State](`#masternode-list-state`)
+    7. [Masternode Reward Payments](`#masternode-reward-payments`)
+    8. [Validation Rules](`#validation-rules`)
+    9. [RPC and JSON Interfaces](`#rpc-and-json-interfaces`)
+    10. [Special Transaction Filtering](`#special-transaction-filtering`)

Apply the same 1-space correction to the remaining TOC entries (lines 29-32).

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
1. [Abstract](#abstract)
2. [Motivation](#motivation)
3. [Prior Work](#prior-work)
4. [Specification](#specification)
1. [Terminology](#terminology)
2. [Provider Transaction Version](#provider-transaction-version)
3. [Masternode Payout Share](#masternode-payout-share)
4. [Registering a Masternode](#registering-a-masternode)
5. [Updating Masternode Payout Shares](#updating-masternode-payout-shares)
6. [Masternode List State](#masternode-list-state)
7. [Masternode Reward Payments](#masternode-reward-payments)
8. [Validation Rules](#validation-rules)
9. [RPC and JSON Interfaces](#rpc-and-json-interfaces)
10. [Special Transaction Filtering](#special-transaction-filtering)
1. [Abstract](`#abstract`)
2. [Motivation](`#motivation`)
3. [Prior Work](`#prior-work`)
4. [Specification](`#specification`)
1. [Terminology](`#terminology`)
2. [Provider Transaction Version](`#provider-transaction-version`)
3. [Masternode Payout Share](`#masternode-payout-share`)
4. [Registering a Masternode](`#registering-a-masternode`)
5. [Updating Masternode Payout Shares](`#updating-masternode-payout-shares`)
6. [Masternode List State](`#masternode-list-state`)
7. [Masternode Reward Payments](`#masternode-reward-payments`)
8. [Validation Rules](`#validation-rules`)
9. [RPC and JSON Interfaces](`#rpc-and-json-interfaces`)
10. [Special Transaction Filtering](`#special-transaction-filtering`)
🧰 Tools
🪛 GitHub Check: lint

[failure] 24-24: Spaces after list markers
dip-pasta-masternode-shares.md:24:5 MD030/list-marker-space Spaces after list markers [Expected: 1; Actual: 2] https://github.com/DavidAnson/markdownlint/blob/v0.38.0/doc/md030.md


[failure] 23-23: Spaces after list markers
dip-pasta-masternode-shares.md:23:5 MD030/list-marker-space Spaces after list markers [Expected: 1; Actual: 2] https://github.com/DavidAnson/markdownlint/blob/v0.38.0/doc/md030.md


[failure] 22-22: Spaces after list markers
dip-pasta-masternode-shares.md:22:5 MD030/list-marker-space Spaces after list markers [Expected: 1; Actual: 2] https://github.com/DavidAnson/markdownlint/blob/v0.38.0/doc/md030.md


[failure] 21-21: Spaces after list markers
dip-pasta-masternode-shares.md:21:5 MD030/list-marker-space Spaces after list markers [Expected: 1; Actual: 2] https://github.com/DavidAnson/markdownlint/blob/v0.38.0/doc/md030.md


[failure] 20-20: Spaces after list markers
dip-pasta-masternode-shares.md:20:5 MD030/list-marker-space Spaces after list markers [Expected: 1; Actual: 2] https://github.com/DavidAnson/markdownlint/blob/v0.38.0/doc/md030.md


[failure] 19-19: Spaces after list markers
dip-pasta-masternode-shares.md:19:5 MD030/list-marker-space Spaces after list markers [Expected: 1; Actual: 2] https://github.com/DavidAnson/markdownlint/blob/v0.38.0/doc/md030.md


[failure] 18-18: Spaces after list markers
dip-pasta-masternode-shares.md:18:1 MD030/list-marker-space Spaces after list markers [Expected: 1; Actual: 2] https://github.com/DavidAnson/markdownlint/blob/v0.38.0/doc/md030.md


[failure] 17-17: Spaces after list markers
dip-pasta-masternode-shares.md:17:1 MD030/list-marker-space Spaces after list markers [Expected: 1; Actual: 2] https://github.com/DavidAnson/markdownlint/blob/v0.38.0/doc/md030.md


[failure] 16-16: Spaces after list markers
dip-pasta-masternode-shares.md:16:1 MD030/list-marker-space Spaces after list markers [Expected: 1; Actual: 2] https://github.com/DavidAnson/markdownlint/blob/v0.38.0/doc/md030.md


[failure] 15-15: Spaces after list markers
dip-pasta-masternode-shares.md:15:1 MD030/list-marker-space Spaces after list markers [Expected: 1; Actual: 2] https://github.com/DavidAnson/markdownlint/blob/v0.38.0/doc/md030.md

🤖 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 `@dip-pasta-masternode-shares.md` around lines 15 - 28, The Table of Contents
entries use two spaces after numeric list markers which violates markdownlint
MD030; update each TOC line (e.g., "1.  [Abstract](`#abstract`)", "4. 
[Specification](`#specification`)" and the nested items like "4.  1. 
[Terminology](`#terminology`)") to use a single space after the period (e.g., "1.
[Abstract](`#abstract`)"), and apply the same single-space fix to the remaining
TOC entries indicated in the comment (including lines 29-32) so all numbered
list markers conform to MD030.

@thephez

thephez commented Jun 8, 2026

Copy link
Copy Markdown
Collaborator

@PastaPastaPasta those last 4 commits don't belong on this branch?

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