feat: add send to platform address mode#15
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review infoConfiguration used: defaults Review profile: CHILL Plan: Pro 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughAdds a “send to platform address” flow: network HRP config, bech32m platform-address validation, new UI steps/mode/state, a platform API sendToPlatformAddress that funds a recipient from an asset lock, and orchestration wiring through the main deposit/finalization flow. Changes
Sequence DiagramsequenceDiagram
participant User as User/UI
participant Main as Main Flow
participant Validator as Validator
participant State as State Manager
participant Platform as Platform Module
participant SDK as evo-sdk
User->>Main: Select "Send to Platform Address"
Main->>State: setMode('send_to_address')
State-->>Main: enter_recipient_address
User->>Main: Enter recipient address + continue
Main->>Validator: validatePlatformAddress(addr, platformHrp)
Validator-->>Main: valid
Main->>State: setRecipientPlatformAddress(addr)
Main->>Main: Generate deposit keys, request deposit
User->>Main: Fund deposit
Main->>Main: Wait for deposit + InstantSend lock
Main->>Main: Build AssetLockProof
Main->>State: setStep('sending_to_address')
Main->>Platform: sendToPlatformAddress(addr, proofData, wif, network)
Platform->>SDK: sdk.addresses.fundFromAssetLock(proof, outputs)
SDK-->>Platform: tx confirmed
Platform-->>Main: { success: true, recipientAddress }
Main->>State: setSendToAddressComplete()
Main-->>User: Display completion
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related issues
Possibly related PRs
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: 5
🧹 Nitpick comments (4)
src/ui/state.ts (1)
126-131:clearModeSensitiveFieldspreservesrecipientPlatformAddressforsend_to_address, but thesend_to_addressbranch immediately overrides it withundefined— the preservation is dead code.The conditional
mode === 'send_to_address' ? state.recipientPlatformAddress : undefinedinclearModeSensitiveFieldsis immediately negated by the explicitrecipientPlatformAddress: undefinedon line 93. Either:
- Remove the conditional and always set
recipientPlatformAddress: undefinedin the helper (thesend_to_addressbranch handles its own init), or- Preserve the address on re-entry and remove the explicit
undefinedfrom the branch (if that UX is desired).♻️ Simplified version (always clear, let the branch handle init)
-function clearModeSensitiveFields(state: BridgeState, mode: BridgeMode): BridgeState { +function clearModeSensitiveFields(state: BridgeState): BridgeState { return { ...state, - recipientPlatformAddress: mode === 'send_to_address' ? state.recipientPlatformAddress : undefined, + recipientPlatformAddress: undefined, }; }And update all three call sites:
- const clearedState = clearModeSensitiveFields(state, mode); + const clearedState = clearModeSensitiveFields(state);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/ui/state.ts` around lines 126 - 131, clearModeSensitiveFields currently returns recipientPlatformAddress conditionally but that value is immediately clobbered by the send_to_address branch which sets recipientPlatformAddress = undefined; to fix, always clear recipientPlatformAddress inside clearModeSensitiveFields (replace the ternary with recipientPlatformAddress: undefined) and let the send_to_address branch initialize it if needed, then update all three call sites that use clearModeSensitiveFields to match this behavior; refer to the clearModeSensitiveFields function, the recipientPlatformAddress field, and the branch that handles 'send_to_address' when making the change.src/main.ts (1)
1094-1194:startSendToAddressnearly duplicatesstartTopUp— consider extracting common asset-lock flow.Steps 1–6 (key generation → deposit wait → tx build → sign → broadcast → wait for IS lock → build proof) are identical in
startTopUp,startSendToAddress, and partially instartBridge. Only Step 7 diverges. This triplication makes it easy for a bug fix to be applied to one path but missed in others.A shared helper like
executeAssetLockFlow(state, insightClient, dapiClient)returning the proof + WIF could eliminate ~80 duplicated lines across the three functions.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main.ts` around lines 1094 - 1194, startSendToAddress duplicates the asset-lock steps present in startTopUp and startBridge; extract Steps 1–6 (key generation, deposit wait, tx build, sign, broadcast, wait for IS lock, build proof) into a shared helper (e.g., executeAssetLockFlow) that takes the necessary inputs (state, insightClient, dapiClient, network) and returns the assetLockProof and assetLockPrivateKeyWif (and any metadata like txid/utxo if needed); replace the duplicated blocks in startSendToAddress, startTopUp, and startBridge with calls to executeAssetLockFlow, ensure updateState calls remain in the appropriate caller (or have the helper return intermediate results so callers can update state), and update error handling to propagate exceptions consistently.src/ui/components.ts (1)
868-879: Backup note is misleading forsend_to_addressmode.The
elsebranch covers bothtopupandsend_to_address, but the note on line 877 reads"One-time key for top-up. Use this WIF to recover funds if top-up fails.". Forsend_to_addressmode, this is inaccurate. Also,backup.targetIdentityIdwill beundefinedforsend_to_address, which is harmless but noisy in the JSON.♻️ Differentiate the backup content by mode
- } else { - // For top-up mode: include target identity and one-time key - backup.targetIdentityId = state.targetIdentityId; - backup.assetLockKey = state.assetLockKeyPair - ? { - wif: privateKeyToWif(state.assetLockKeyPair.privateKey, network), - publicKeyHex: bytesToHex(state.assetLockKeyPair.publicKey), - note: 'One-time key for top-up. Use this WIF to recover funds if top-up fails.', - } - : null; + } else { + // For top-up / send_to_address mode: include one-time key + if (isTopUp) { + backup.targetIdentityId = state.targetIdentityId; + } + const modeLabel = isSendToAddress ? 'send-to-address' : 'top-up'; + backup.assetLockKey = state.assetLockKeyPair + ? { + wif: privateKeyToWif(state.assetLockKeyPair.privateKey, network), + publicKeyHex: bytesToHex(state.assetLockKeyPair.publicKey), + note: `One-time key for ${modeLabel}. Use this WIF to recover funds if the operation fails.`, + } + : null; }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/ui/components.ts` around lines 868 - 879, The backup branch conflates top-up and send_to_address modes: update the else block to inspect the operation mode (e.g., state.mode or equivalent) and produce mode-specific backup fields — for topup set backup.targetIdentityId = state.targetIdentityId only when state.targetIdentityId is defined and set assetLockKey.note to the top-up wording, and for send_to_address omit targetIdentityId and use an accurate note for assetLockKey (or null) based on state.assetLockKeyPair; adjust the code around backup.targetIdentityId, backup.assetLockKey, state.targetIdentityId and state.assetLockKeyPair to avoid emitting undefined/noisy fields and to use the correct note per mode.src/platform/identity.ts (1)
440-449: Document the WASM serde constraint for fundFromAssetLock parameters instead of usingas anycasts.The
outputsandfeeStrategyparameters are cast toanybecause the SDK's WASM serde deserializer requires plain objects rather than typed instances. While this workaround is already explained in an inline comment, defining local interfaces that document the expected shape would improve clarity and catch unintended API shape changes at review time. Since@dashevo/evo-sdk@3.1.0-dev.1is a pre-release version, this would provide better future-proofing before the stable release.For example:
interface FundFromAssetLockOutput { address: string; } interface FeeStrategy { type: 'reduceOutput'; index: number; }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/platform/identity.ts` around lines 440 - 449, The outputs and feeStrategy are currently cast to any to satisfy the WASM serde requirement; define local interfaces (e.g. FundFromAssetLockOutput { address: string } and FeeStrategy { type: 'reduceOutput'; index: number }) near the call and use them to type the arrays passed into sdk.addresses.fundFromAssetLock (the call inside withRetry) instead of using as any, so the shapes are documented and checked while still providing plain object values for the WASM deserializer.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@package.json`:
- Line 13: The package.json currently pins a pre-release "@dashevo/evo-sdk" to
"3.1.0-dev.1", which is unstable; update the dependency version for
"@dashevo/evo-sdk" to the stable 3.1.x release when it becomes available (for
example change "3.1.0-dev.1" to a stable semver like "^3.1.0" or "3.1.x") so the
project uses the released API instead of the dev pre-release.
- Line 13: The project directly imports bech32m from `@scure/base` in src/main.ts
but `@scure/base` is not declared in package.json; add `@scure/base` as an explicit
dependency in package.json (pin a compatible version — e.g., match versions used
by `@scure/bip32/`@scure/bip39 or the latest stable) so the direct import in
src/main.ts (bech32m) will resolve reliably even if transitive deps change.
In `@src/platform/dpns.ts`:
- Around line 84-85: The current disabled check in src/platform/dpns.ts uses
strict undefined comparison for key.disabledAt; change the isDisabled
computation (the isDisabled variable that reads key.disabledAt) to a null-safe
check (e.g., treat both null and undefined as "not set") by using a
null-coalescing or != null style test so keys with disabledAt: null are not
considered disabled.
In `@src/platform/identity.ts`:
- Around line 452-470: The current validation in the fundFromAssetLock response
path (variable result and the maybeResult block) treats any presence of
maybeResult.message as an error and can false-positive on successful responses;
change the check to only treat explicit failure signals as errors (e.g.,
maybeResult.success === false or maybeResult.error !== undefined) and do not
treat maybeResult.message !== undefined as an error condition, or alternatively
validate against the SDK's documented response shape instead of checking for
message; update the error construction thrown from fundFromAssetLock to use only
those explicit failure conditions so successful responses with a message field
are accepted.
- Around line 23-42: The local hexToBytes in src/platform/identity.ts duplicates
the implementation in src/utils/hex.ts but adds an empty/null check; remove the
duplication by either (A) updating the hexToBytes in src/utils/hex.ts to include
the same !hex/empty-string validation and then import and use that single
hexToBytes from src/platform/identity.ts, or (B) if the stricter validation is
intentionally specific to identity operations, keep the local hexToBytes and add
a comment explaining the divergence and ensure callers of src/utils/hex.ts are
not relying on the empty-string check; locate the functions by name hexToBytes
and base64ToBytes when making the change.
---
Nitpick comments:
In `@src/main.ts`:
- Around line 1094-1194: startSendToAddress duplicates the asset-lock steps
present in startTopUp and startBridge; extract Steps 1–6 (key generation,
deposit wait, tx build, sign, broadcast, wait for IS lock, build proof) into a
shared helper (e.g., executeAssetLockFlow) that takes the necessary inputs
(state, insightClient, dapiClient, network) and returns the assetLockProof and
assetLockPrivateKeyWif (and any metadata like txid/utxo if needed); replace the
duplicated blocks in startSendToAddress, startTopUp, and startBridge with calls
to executeAssetLockFlow, ensure updateState calls remain in the appropriate
caller (or have the helper return intermediate results so callers can update
state), and update error handling to propagate exceptions consistently.
In `@src/platform/identity.ts`:
- Around line 440-449: The outputs and feeStrategy are currently cast to any to
satisfy the WASM serde requirement; define local interfaces (e.g.
FundFromAssetLockOutput { address: string } and FeeStrategy { type:
'reduceOutput'; index: number }) near the call and use them to type the arrays
passed into sdk.addresses.fundFromAssetLock (the call inside withRetry) instead
of using as any, so the shapes are documented and checked while still providing
plain object values for the WASM deserializer.
In `@src/ui/components.ts`:
- Around line 868-879: The backup branch conflates top-up and send_to_address
modes: update the else block to inspect the operation mode (e.g., state.mode or
equivalent) and produce mode-specific backup fields — for topup set
backup.targetIdentityId = state.targetIdentityId only when
state.targetIdentityId is defined and set assetLockKey.note to the top-up
wording, and for send_to_address omit targetIdentityId and use an accurate note
for assetLockKey (or null) based on state.assetLockKeyPair; adjust the code
around backup.targetIdentityId, backup.assetLockKey, state.targetIdentityId and
state.assetLockKeyPair to avoid emitting undefined/noisy fields and to use the
correct note per mode.
In `@src/ui/state.ts`:
- Around line 126-131: clearModeSensitiveFields currently returns
recipientPlatformAddress conditionally but that value is immediately clobbered
by the send_to_address branch which sets recipientPlatformAddress = undefined;
to fix, always clear recipientPlatformAddress inside clearModeSensitiveFields
(replace the ternary with recipientPlatformAddress: undefined) and let the
send_to_address branch initialize it if needed, then update all three call sites
that use clearModeSensitiveFields to match this behavior; refer to the
clearModeSensitiveFields function, the recipientPlatformAddress field, and the
branch that handles 'send_to_address' when making the change.
|
@coderabbitai only the last commit of this branch matters. The other commits are covered in #14 which this branch is based on. Do not comment on any of those commits |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain
🏁 Script executed: Length of output: 660
Let me examine what changed in that commit: 🏁 Script executed: Length of output: 569
Review of Last CommitThe change adds a ✅ Enables manual deployment triggers - The workflow can now be run manually from the GitHub Actions UI in addition to automatic deployment on pushes to ✅ Preserves existing behavior - The automatic deployment on push to ✅ Follows best practices - Adding The change looks good with no issues! This gives you the ability to manually redeploy if needed without requiring a push to main. 🧠 Learnings used |
7b32426 to
3581eaf
Compare
|
@coderabbitai review latest commit |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: Length of output: 32527
Review of Latest CommitThis commit adds a comprehensive send-to-platform-address feature. Here's my analysis: ✅ Security - Well HandledGood! XSS danger comes from injecting user and third-party markup into the DOM, and proper sanitization is essential. The code correctly uses
|
Add bridge mode for sending L1 DASH to any bech32m platform address via asset lock, without requiring the recipient's private key. - Add 'send_to_address' BridgeMode with recipient address entry UI - Add sendToPlatformAddress() using sdk.addresses.fundFromAssetLock() - Add platformHrp to NetworkConfig for bech32m address validation - Use pure JS bech32m.decode() from @scure/base (avoids WASM init issues) - Add mode-aware recheckDeposit branching - XSS-escape user-supplied addresses in innerHTML Co-authored-by: PastaClaw <pastaclaw@users.noreply.github.com> Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
3581eaf to
b2f755a
Compare
|
Rebased to main |
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/ui/components.ts (1)
870-879:⚠️ Potential issue | 🟡 MinorBackup note is misleading for
send_to_addressmode.The
notefield is hard-coded to'One-time key for top-up. Use this WIF to recover funds if top-up fails.', but thiselsebranch now coverssend_to_addressmode as well. Additionally,backup.targetIdentityIdis written asstate.targetIdentityId(which will beundefinedinsend_to_addressmode), producing a spuriousundefinedfield in the recovery JSON.🐛 Proposed fix
} else { - // For top-up mode: include target identity and one-time key - backup.targetIdentityId = state.targetIdentityId; + // For top-up/send_to_address mode: include one-time asset-lock key + if (isTopUp) { + backup.targetIdentityId = state.targetIdentityId; + } backup.assetLockKey = state.assetLockKeyPair ? { wif: privateKeyToWif(state.assetLockKeyPair.privateKey, network), publicKeyHex: bytesToHex(state.assetLockKeyPair.publicKey), - note: 'One-time key for top-up. Use this WIF to recover funds if top-up fails.', + note: isSendToAddress + ? 'One-time key for send-to-address. Use this WIF to recover funds if the send fails.' + : 'One-time key for top-up. Use this WIF to recover funds if top-up fails.', } : null; }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/ui/components.ts` around lines 870 - 879, The backup generation currently always sets backup.targetIdentityId = state.targetIdentityId (which is undefined in send_to_address mode) and unconditionally uses a top-up specific note; update the logic in the component that builds backup (the block that assigns backup.targetIdentityId and backup.assetLockKey) to: 1) only set backup.targetIdentityId when state.mode indicates top-up (e.g., state.mode === 'top_up' or whatever mode flag your code uses), 2) set the assetLockKey.note dynamically based on the mode (use the existing top-up message for top-up mode and a send-to-address appropriate message for send_to_address mode), and 3) ensure you set backup.targetIdentityId to null or omit the property for send_to_address so no undefined is emitted (adjust the branch around backup.targetIdentityId and assetLockKey assignment in the same function/block to implement these conditional assignments).
🧹 Nitpick comments (2)
src/platform/identity.ts (1)
444-446: Consider replacingas anycasts with typed interfaces or a documented workaround comment.Both
outputsandfeeStrategycasts bypass TypeScript's type checking entirely. While the existing comment explains the WASM serde motivation, these casts will silently break if the SDK's deserializer expectation changes. A minimal improvement is to define local structural interfaces matching what the WASM layer actually expects:♻️ Proposed refactor
+// These plain-object shapes match what the WASM serde deserializer expects. +// See: https://github.com/<org>/<repo>/issues/<N> for tracking proper SDK types. +interface PlatformAddressOutput { address: string } +interface FeeStrategyEntry { type: string; index: number } + const result = await withRetry( () => sdk.addresses.fundFromAssetLock({ assetLockProof, assetLockPrivateKey, - outputs: [{ address: recipientAddress }] as any, + outputs: [{ address: recipientAddress }] as unknown as PlatformAddressOutput[], signer, - feeStrategy: [{ type: 'reduceOutput', index: 0 }] as any, + feeStrategy: [{ type: 'reduceOutput', index: 0 }] as unknown as FeeStrategyEntry[], }), retryOptions );This narrows the cast surface so that structural mismatches (e.g., a renamed field) produce a TypeScript error rather than a silent runtime failure.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/platform/identity.ts` around lines 444 - 446, The code is using unsafe casts to any for the transaction fields outputs and feeStrategy (the object built with outputs: [{ address: recipientAddress }], signer, feeStrategy: [{ type: 'reduceOutput', index: 0 }]) which hides mismatches from the WASM deserializer; replace these casts by declaring small local structural interfaces (e.g., OutputShape { address: string }, FeeStrategyShape { type: string; index?: number } or more precise shapes matching the WASM expectations) and use them for outputs and feeStrategy instead of as any, or if a deliberate mismatch is unavoidable add a short comment linking to the WASM serde contract and mark the cast with a specific TODO comment; update the object definitions that reference outputs, feeStrategy, recipientAddress and signer to use the new interfaces so TypeScript will surface structural errors rather than allowing silent runtime failures.src/main.ts (1)
1097-1194:startSendToAddressduplicates all six steps ofstartTopUpverbatim.Steps 1–6 (key generation, deposit wait, tx build, tx sign, broadcast, InstantSend) are copy-pasted from
startTopUp. Only step 7 differs. Consider extracting the shared asset-lock flow into a helper:♻️ Suggested refactor sketch
+/** + * Shared steps 1-6: generate key pair, wait for deposit, build/sign/broadcast tx, + * wait for InstantSend lock, and return the proof + WIF for step 7. + */ +async function buildAssetLockProof(initialState: BridgeState): Promise<{ + assetLockProof: AssetLockProofData; + assetLockPrivateKeyWif: string; + stateWithKeys: BridgeState; +}> { + const network = getNetwork(initialState.network); + updateState(setStep(initialState, 'generating_keys')); + const assetLockKeyPair = generateKeyPair(); + const depositAddress = publicKeyToAddress(assetLockKeyPair.publicKey, network); + const stateWithKeys = setOneTimeKeyPair(initialState, assetLockKeyPair, depositAddress); + updateState(stateWithKeys); + downloadKeyBackup(stateWithKeys); + updateState(setStep(stateWithKeys, 'detecting_deposit')); + // ... (steps 2-6, identical to both functions) + return { assetLockProof, assetLockPrivateKeyWif, stateWithKeys }; +}Both
startTopUpandstartSendToAddresswould then callbuildAssetLockProofand only implement their specific step 7 logic.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main.ts` around lines 1097 - 1194, startSendToAddress duplicates steps 1–6 from startTopUp; extract the shared asset-lock flow into a helper (e.g., buildAssetLockProof or extractAssetLockFlow) that performs key generation, deposit waiting, TX creation, signing, broadcasting and InstantSend wait and returns the necessary outputs (assetLockProof, assetLockPrivateKeyWif, signedTxHex/txid, utxo, etc.) and any state updates; then replace the duplicated code in startSendToAddress and startTopUp with a call to that helper and keep only the platform-specific Step 7 (sendToPlatformAddress in startSendToAddress and top-up logic in startTopUp), preserving existing updateState calls and error handling.
🤖 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 9: The project imports bech32m from '@scure/base' (import { bech32m }
from '@scure/base') but that package is not declared in package.json; add
'@scure/base' to the dependencies in package.json (matching the appropriate
version used by `@scure/bip32/`@scure/bip39 or a compatible semver) and run
npm/yarn install to ensure clean installs succeed.
---
Outside diff comments:
In `@src/ui/components.ts`:
- Around line 870-879: The backup generation currently always sets
backup.targetIdentityId = state.targetIdentityId (which is undefined in
send_to_address mode) and unconditionally uses a top-up specific note; update
the logic in the component that builds backup (the block that assigns
backup.targetIdentityId and backup.assetLockKey) to: 1) only set
backup.targetIdentityId when state.mode indicates top-up (e.g., state.mode ===
'top_up' or whatever mode flag your code uses), 2) set the assetLockKey.note
dynamically based on the mode (use the existing top-up message for top-up mode
and a send-to-address appropriate message for send_to_address mode), and 3)
ensure you set backup.targetIdentityId to null or omit the property for
send_to_address so no undefined is emitted (adjust the branch around
backup.targetIdentityId and assetLockKey assignment in the same function/block
to implement these conditional assignments).
---
Duplicate comments:
In `@src/platform/identity.ts`:
- Around line 462-470: The current failure check incorrectly treats any presence
of maybeResult.message as an error; update the conditional in the block handling
maybeResult so that a message field on a successful response does not trigger an
exception—only treat the result as failure when maybeResult.success === false or
maybeResult.error is defined (keep using maybeResult.error ??
maybeResult.message ?? 'unknown error' for the thrown details but only when
actually failing). Locate the conditional referencing maybeResult.success,
maybeResult.error, and maybeResult.message and remove the message presence check
(or guard message usage behind a failing success flag) so successful responses
with a message no longer false-positive.
---
Nitpick comments:
In `@src/main.ts`:
- Around line 1097-1194: startSendToAddress duplicates steps 1–6 from
startTopUp; extract the shared asset-lock flow into a helper (e.g.,
buildAssetLockProof or extractAssetLockFlow) that performs key generation,
deposit waiting, TX creation, signing, broadcasting and InstantSend wait and
returns the necessary outputs (assetLockProof, assetLockPrivateKeyWif,
signedTxHex/txid, utxo, etc.) and any state updates; then replace the duplicated
code in startSendToAddress and startTopUp with a call to that helper and keep
only the platform-specific Step 7 (sendToPlatformAddress in startSendToAddress
and top-up logic in startTopUp), preserving existing updateState calls and error
handling.
In `@src/platform/identity.ts`:
- Around line 444-446: The code is using unsafe casts to any for the transaction
fields outputs and feeStrategy (the object built with outputs: [{ address:
recipientAddress }], signer, feeStrategy: [{ type: 'reduceOutput', index: 0 }])
which hides mismatches from the WASM deserializer; replace these casts by
declaring small local structural interfaces (e.g., OutputShape { address: string
}, FeeStrategyShape { type: string; index?: number } or more precise shapes
matching the WASM expectations) and use them for outputs and feeStrategy instead
of as any, or if a deliberate mismatch is unavoidable add a short comment
linking to the WASM serde contract and mark the cast with a specific TODO
comment; update the object definitions that reference outputs, feeStrategy,
recipientAddress and signer to use the new interfaces so TypeScript will surface
structural errors rather than allowing silent runtime failures.
Previously imported as a transitive dependency via @scure/bip32 and @scure/bip39, which could break on dependency updates. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
@PastaPastaPasta addressed coderabbit comment. Can we get this one merged this week? |
- Remove speculative `message` check from fundFromAssetLock error handling that could false-positive on successful results - Make recheckDeposit() create-mode check explicit and throw on unexpected modes instead of silently defaulting Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Based on #14
Add bridge mode for sending L1 DASH to any bech32m platform address
via asset lock, without requiring the recipient's private key.
Tested locally. All operations worked.
Preview: https://thephez.github.io/dash-bridge/
Co-authored-by: PastaClaw pastaclaw@users.noreply.github.com
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
Summary by CodeRabbit
New Features
Chores