feat: add fund platform address mode#9
feat: add fund platform address mode#9thepastaclaw wants to merge 1 commit intoPastaPastaPasta:mainfrom
Conversation
Add new 'fund_address' mode to the bridge that lets users send L1 DASH directly to a Platform address (bech32m) using an asset lock. Flow: 1. User enters their platform address private key (WIF) 2. Bridge derives and displays the bech32m platform address for confirmation 3. Same L1 deposit → asset lock flow as topup mode 4. Calls sdk.addresses.fundFromAssetLock() instead of sdk.identities.topUp() New files: - src/platform/address.ts — fundPlatformAddress() implementation - src/ui/fund-address.ts — enter_platform_address step UI Updated: - src/types.ts — added fund_address mode + enter_platform_address step + state fields - src/ui/state.ts — setMode(), setPlatformAddressKey(), setFundAddressComplete() - src/ui/components.ts — mode button + fund-address step rendering - src/main.ts — startFundAddress(), event handlers, step routing
📝 WalkthroughWalkthroughThis pull request adds a complete fund-address flow to the Dash bridge, enabling users to fund a platform address from an asset lock. New UI components capture the platform address private key, render progress through deposit waiting and funding steps, and expose state management functions. A new Changes
Sequence DiagramsequenceDiagram
participant User
participant UI
participant State
participant Main as Main<br/>(startFundAddress)
participant SDK as Dash SDK
participant Insight
participant Platform as Platform<br/>fundPlatformAddress
User->>UI: Select "Fund Platform Address"
UI->>State: setMode('fund_address')
State-->>UI: Enter platform private key step
User->>UI: Input platform address private key
UI->>State: setPlatformAddress(privateKeyWif, address)
User->>UI: Click Continue
UI->>Main: Trigger fund process
Main->>SDK: Generate one-time asset-lock key pair
SDK-->>Main: keyPair, depositAddress
State->>State: Update with depositAddress
Main->>Main: Auto-download key backup
Main->>Insight: Poll for deposit
Insight-->>Main: Deposit detected
Main->>SDK: Build asset-lock transaction
SDK-->>Main: Transaction built
Main->>SDK: Broadcast transaction
Insight->>Insight: InstantSend confirmation
Main->>SDK: Build asset-lock proof
SDK-->>Main: Proof hex
Main->>Platform: fundPlatformAddress(platformKey, proof)
Platform->>SDK: Call sdk.addresses.fundFromAssetLock
SDK-->>Platform: Platform address funded
Platform-->>Main: { success: true, address }
State->>State: setFundAddressComplete
UI-->>User: Show completion screen
Estimated Code Review Effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 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: 1
🧹 Nitpick comments (3)
src/main.ts (2)
245-279: Platform key validation onblur/paste— consider also triggering oninputor Enter key.Currently the key is only validated on
blur(focus lost) orpaste. If a user types a WIF key manually and then clicks "Continue" without tabbing away, the key won't be validated and the button will remain disabled. This is a minor UX gap since most users will paste, but adding aninputevent (debounced) or validating on Enter would improve the experience.That said, this is consistent with how DPNS and manage identity key inputs work in this file (also blur/paste only), so this can be deferred.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main.ts` around lines 245 - 279, The current validation only runs on blur/paste for platformAddressKeyInput; extend it to also validate on user typing and when they press Enter by wiring validatePlatformKey to a debounced input event handler on platformAddressKeyInput (use a short debounce, e.g., 200–300ms) and add a keydown listener that calls validatePlatformKey when the Enter key is pressed; keep the existing error handling and state updates via updateState(setPlatformAddress(...)) and ensure you reference the existing validatePlatformKey, platformAddressKeyInput, updateState, and setPlatformAddress symbols when adding these listeners.
1114-1211:startFundAddress()largely duplicatesstartTopUp()(steps 1–6 are identical).The deposit → build → sign → broadcast → ISLock flow (lines 1118–1188) is a near-verbatim copy of
startTopUp()(lines 1006–1086). Only step 7 (the SDK call) differs. Consider extracting the shared deposit-to-proof pipeline into a helper to reduce ~70 lines of duplication.This is a pre-existing pattern (also shared with
startBridgeandrecheckDeposit), so it's not new to this PR — deferring is reasonable.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main.ts` around lines 1114 - 1211, startFundAddress duplicates the deposit→build→sign→broadcast→ISLock pipeline found in startTopUp (and similar logic in startBridge/recheckDeposit); extract that shared flow into a single helper (e.g., createAssetLockFlow or getAssetLockProof) that accepts parameters like depositAddress/privateKey or one-time keypair and returns {signedTxHex, txid, islockBytes, assetLockProof, utxo} (or throws on timeout), then update startFundAddress, startTopUp, startBridge and recheckDeposit to call this helper and only perform their unique final steps (e.g., fundPlatformAddress) using the returned proof; ensure the helper encapsulates steps: generate/wire one-time keypair (or accept it), waitForUtxo (insightClient.waitForUtxo), createAssetLockTransaction, signTransaction, serialize/hex conversion, broadcastTransaction, waitForInstantSendLock (dapiClient.waitForInstantSendLock), and buildInstantAssetLockProof so state updates and error handling in callers are simplified.src/ui/components.ts (1)
355-431:renderEnterPlatformAddressStep— consider escapingplatformAddressPrivateKeyWifandplatformAddressbefore interpolation intoinnerHTML.Static analysis flags XSS risk on lines 369–396 where
state.platformAddressPrivateKeyWifandstate.platformAddressare interpolated directly intoinnerHTML. In practice these are Base58Check/bech32m strings with restricted character sets (only stored after SDK validation succeeds), so the actual risk is very low. However, the codebase already has anescapeHtmlhelper — using it here would be a consistent defensive measure.This is the same pattern used elsewhere in the file for identity IDs and addresses, so it's not a regression.
Defensive escaping example for the WIF value attribute
placeholder="Enter your platform address private key in WIF format..." - value="${state.platformAddressPrivateKeyWif || ''}" + value="${escapeHtml(state.platformAddressPrivateKeyWif || '')}" />And similarly for
state.platformAddressin the address display anddata-copyattribute.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/ui/components.ts` around lines 355 - 431, renderEnterPlatformAddressStep currently interpolates state.platformAddressPrivateKeyWif and state.platformAddress directly into innerHTML which can trigger static-analysis XSS warnings; update the function to pass those values through the existing escapeHtml helper before interpolation (apply to the input value attribute, the <code class="address"> content, and the data-copy attribute on the copy button) so all dynamic HTML fragments use escaped strings (refer to escapeHtml, platformAddressPrivateKeyWif, platformAddress, renderEnterPlatformAddressStep).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/main.ts`:
- Line 1191: The current call to updateState(setStep(state, 'topping_up')) uses
the wrong step identifier; replace the 'topping_up' step with the dedicated
'funding_address' step so the step metadata (used by getStepDescription and
progress) matches the flow—locate the invocation of updateState and setStep in
main.ts and change the second argument from 'topping_up' to 'funding_address' so
renderProcessingStep and getStepDescription reflect the correct "Funding
address..." semantics.
---
Nitpick comments:
In `@src/main.ts`:
- Around line 245-279: The current validation only runs on blur/paste for
platformAddressKeyInput; extend it to also validate on user typing and when they
press Enter by wiring validatePlatformKey to a debounced input event handler on
platformAddressKeyInput (use a short debounce, e.g., 200–300ms) and add a
keydown listener that calls validatePlatformKey when the Enter key is pressed;
keep the existing error handling and state updates via
updateState(setPlatformAddress(...)) and ensure you reference the existing
validatePlatformKey, platformAddressKeyInput, updateState, and
setPlatformAddress symbols when adding these listeners.
- Around line 1114-1211: startFundAddress duplicates the
deposit→build→sign→broadcast→ISLock pipeline found in startTopUp (and similar
logic in startBridge/recheckDeposit); extract that shared flow into a single
helper (e.g., createAssetLockFlow or getAssetLockProof) that accepts parameters
like depositAddress/privateKey or one-time keypair and returns {signedTxHex,
txid, islockBytes, assetLockProof, utxo} (or throws on timeout), then update
startFundAddress, startTopUp, startBridge and recheckDeposit to call this helper
and only perform their unique final steps (e.g., fundPlatformAddress) using the
returned proof; ensure the helper encapsulates steps: generate/wire one-time
keypair (or accept it), waitForUtxo (insightClient.waitForUtxo),
createAssetLockTransaction, signTransaction, serialize/hex conversion,
broadcastTransaction, waitForInstantSendLock
(dapiClient.waitForInstantSendLock), and buildInstantAssetLockProof so state
updates and error handling in callers are simplified.
In `@src/ui/components.ts`:
- Around line 355-431: renderEnterPlatformAddressStep currently interpolates
state.platformAddressPrivateKeyWif and state.platformAddress directly into
innerHTML which can trigger static-analysis XSS warnings; update the function to
pass those values through the existing escapeHtml helper before interpolation
(apply to the input value attribute, the <code class="address"> content, and the
data-copy attribute on the copy button) so all dynamic HTML fragments use
escaped strings (refer to escapeHtml, platformAddressPrivateKeyWif,
platformAddress, renderEnterPlatformAddressStep).
| updateState(setInstantLockReceived(state, islockBytes, assetLockProof)); | ||
|
|
||
| // Step 7: Fund the platform address | ||
| updateState(setStep(state, 'topping_up')); |
There was a problem hiding this comment.
Bug: Step should be 'funding_address', not 'topping_up'.
The types define a dedicated 'funding_address' step with its own description ("Funding address...") and progress value. Using 'topping_up' here means getStepDescription returns "Adding credits..." instead of "Funding address...", and the step semantics don't match the flow.
The rendering still works because renderProcessingStep checks state.mode === 'fund_address' for headlines, but the step metadata is wrong.
🐛 Proposed fix
- updateState(setStep(state, 'topping_up'));
+ updateState(setStep(state, 'funding_address'));🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/main.ts` at line 1191, The current call to updateState(setStep(state,
'topping_up')) uses the wrong step identifier; replace the 'topping_up' step
with the dedicated 'funding_address' step so the step metadata (used by
getStepDescription and progress) matches the flow—locate the invocation of
updateState and setStep in main.ts and change the second argument from
'topping_up' to 'funding_address' so renderProcessingStep and getStepDescription
reflect the correct "Funding address..." semantics.
|
Superseded by #10 which has a more complete implementation. |
Summary
Adds a new Fund Platform Address mode to the bridge, allowing users to send L1 DASH directly to a Platform address (bech32m).
Requested by thephez.
Flow
sdk.addresses.fundFromAssetLock()instead ofsdk.identities.topUp()Files Changed
src/platform/address.ts(new) —fundPlatformAddress()implementation usingsdk.addresses.fundFromAssetLock()src/ui/fund-address.ts(new) —enter_platform_addressstep UI (key input + derived address display)src/types.ts— addedfund_addresstoBridgeMode,enter_platform_addresstoBridgeStep, new state fieldssrc/ui/state.ts—setMode()handler,setPlatformAddressKey(),setFundAddressComplete()src/ui/components.ts— mode button + fund-address step renderingsrc/main.ts—startFundAddress()function + event handlers + step routingBuild
npm run buildpasses with zero TypeScript errors.Summary by CodeRabbit