Skip to content

Comments

Add a new EdgeCurrencyWallet.split method#701

Merged
swansontec merged 1 commit intomasterfrom
william/multi-split
Feb 11, 2026
Merged

Add a new EdgeCurrencyWallet.split method#701
swansontec merged 1 commit intomasterfrom
william/multi-split

Conversation

@swansontec
Copy link
Contributor

@swansontec swansontec commented Jan 30, 2026

CHANGELOG

Does this branch warrant an entry to the CHANGELOG?

  • Yes
  • No

Dependencies

none

Description

none

Note

Medium Risk
Touches wallet-splitting and key/login-kit application paths, which can affect wallet creation/restoration and BCH replay-protection behavior. The surface area is moderate and covered by updated unit tests, but failures could impact wallet availability if edge cases aren’t handled.

Overview
Adds wallet-scoped splitting via EdgeCurrencyWallet.split, allowing callers to request one or more split wallets and receive per-wallet EdgeResult success/failure objects.

Refactors splitWalletInfo to accept the source walletInfo, validate requested wallet types/plugins, optionally apply BCH→BSV replay protection, restore previously archived/deleted split wallets, and best-effort apply requested name/fiatCurrencyCode on new wallets. EdgeAccount.splitWalletInfo remains but is now deprecated and implemented as a thin wrapper around the new split logic, and a shared makeEdgeResult helper is moved to src/util/edgeResult.ts.

Updates types/tests and fake plugins to support the new API and multi-plugin split scenarios (including improved duplicate-split error messaging and a new tulipcoin test plugin).

Written by Cursor Bugbot for commit 7bcfbd0. This will update automatically on new commits. Configure here.

Copy link
Contributor

@Jon-edge Jon-edge left a comment

Choose a reason for hiding this comment

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

Small comment

await makeEdgeResult(
finishWalletSplitting(
ai,
splitInfos.get(splitInfo.walletType)?.id ?? '',
Copy link
Contributor

Choose a reason for hiding this comment

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

The splitInfos.get(splitInfo.walletType)?.id ?? '' fallback passes an empty string to finishWalletSplitting if the map lookup fails. While this should never happen after the validation loop, consider throwing an explicit error:

const walletId = splitInfos.get(splitInfo.walletType)?.id
if (walletId == null) throw new Error(`Missing wallet info for ${splitInfo.walletType}`)

Or maybe just a comment

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good idea

@swansontec swansontec enabled auto-merge February 11, 2026 00:13
@swansontec swansontec merged commit a8fbd27 into master Feb 11, 2026
3 checks passed
@swansontec swansontec deleted the william/multi-split branch February 11, 2026 00:16
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

true
)
if (result.ok) return result.result.id
throw result.error
Copy link

Choose a reason for hiding this comment

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

Deprecated method now throws on wallet load failure

Medium Severity

The deprecated splitWalletInfo now throws if waitForCurrencyWallet fails, whereas previously the error was caught and the wallet ID was still returned. In the old code, the entire wallet-load-and-copy-metadata block was wrapped in a single try/catch that called ai.props.onError and then returned newWalletInfo.id. Now, finishWalletSplitting lets waitForCurrencyWallet errors propagate into makeEdgeResult, producing { ok: false, error }, which the account-api destructures as throw result.error. Since the keys are already saved on the server at that point, the split succeeded at the data level but the caller gets an exception and cannot retry (due to the rejectDupes duplicate check).

Additional Locations (1)

Fix in Cursor Fix in Web

}
if (needsProtection) return newWalletInfo.id
throw new Error('This wallet has already been split')
if (hasChanges) await changeWalletStates(ai, accountId, newStates)
Copy link

Choose a reason for hiding this comment

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

Redundant archived/deleted check in restore loop

Low Severity

The if (existingWalletInfo.archived || existingWalletInfo.deleted) check at line 177 is always true because items are only added to toRestore when that exact condition holds (line 156). This makes the hasChanges flag and its guard also always true when toRestore.length > 0, adding unnecessary indirection that may mislead future readers into thinking some toRestore items might not need state changes.

Fix in Cursor Fix in Web

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