Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Upgrade Arkade SDKs and harden Ark wallet integration#8585

Merged
Overtorment merged 42 commits into
masterfrom
feat/arkade-sdk-upgrade
Jun 1, 2026
Merged

Upgrade Arkade SDKs and harden Ark wallet integration#8585
Overtorment merged 42 commits into
masterfrom
feat/arkade-sdk-upgrade

Conversation

@pietro909

Copy link
Copy Markdown
Collaborator

Replaces #8538

Summary

Upgrades the Arkade SDKs and overhauls the Ark/Lightning wallet integration to take advantage of the new SDK surface. The wallet now delegates swap orchestration, claim/refund, and persistence to the SDK's repositories and swap manager rather than re-implementing them in app code.

Structured as 8 logical commits on top of bw/master.

What changed

  • SDK upgrade — bumps @arkade-os/ts-sdk and @arkade-os/boltz-swap to their latest releases.
  • Realm wiring — Ark wallet now uses the SDK's Realm-backed repositories for swap and notification state; lifecycle (open/close, wallet delete) is hardened with regression tests.
  • Foreground swap managerWalletsCarousel, TransactionListItem, WalletTransactions, WalletDetails, lndViewInvoice and TransactionStatus consume the SDK swap manager directly. Wallet activity is now derived from the union of on-chain history and swap state.
  • Per-swap claim/refund + import-time restore — failed/expired swaps are reconcilable from the UI, and wallet-import restores in-flight swaps so they survive reinstalls.
  • Background monitoring + notifications — adds blue_modules/arkade-background.ts and blue_modules/arkade-notifications.ts driving Android/iOS background ticks to claim/refund swaps and notify the user. iOS background mode and Android scheduler config included.
  • Localization — new strings in loc/en.json for swap states, claim/refund actions, and notifications.
  • Tests — new unit suites for the background worker, notifications, Realm adapter, derivation, and the wallet-onDelete path; an SDK-contract test pins the surface we depend on; e2e setup updates stabilize iOS sync and the Arkade indexer.

pietro909 added 10 commits May 21, 2026 18:03
Hook the lightning-ark wallet up to the new Arkade SDK repositories layer,
introduce the Realm-backed Arkade adapter instance, register the delegate
contract via RestDelegatorProvider on Wallet.create, and set the Boltz
swap referral.
Tighten Realm-backed Arkade adapter setup so the database lifecycle is
deterministic across wallet import, app boot, and tests. Fix integration
tests to handle Realm persistence in mocks and proper initialization in
wallet-import.
Surface per-swap claim and refund controls, restore swaps on wallet
import, drop the racing Claim CTA in the LN invoice view (show a
Receiving spinner and let SwapManager events drive UI state), and
keep the transactions header mounted so the list does not jump on
scroll.
Wire iOS/Android background task plumbing for Ark swap monitoring,
surface actionable swap notifications via the notification suppression
repository, and drop the racing Electrum probe from SelfTest.
Add unit and integration coverage for the lightning-ark wallet's
contract with the Arkade SDK (derivation, sync, swaps); refresh
SDK fixture set.
Stabilize the e2e suite on real devices: unstall Detox iOS sync on
NotificationSettings, skip the Arkade indexer stream in iOS sync,
and tighten the wallet-discovery / import / watch-only e2e flows.
# Conflicts:
#	package-lock.json
#	package.json
#	screen/transactions/TransactionStatus.tsx
@socket-security

socket-security Bot commented May 21, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Updatednpm/​@​arkade-os/​sdk@​0.3.12 ⏵ 0.4.3271 +410099 +1100 +1100
Updatednpm/​@​arkade-os/​boltz-swap@​0.2.19 ⏵ 0.3.3780 +210099 +1100 +1100

View full report

@pietro909 pietro909 requested review from GladosBlueWallet, Overtorment and limpbrains and removed request for Overtorment and limpbrains May 22, 2026 07:34
@pietro909 pietro909 added the testflight Upload iOS and macOS builds to Testflight. label May 22, 2026
@github-actions

Copy link
Copy Markdown

✅ Build 8.0.0 (1779435704) has been uploaded to TestFlight and will be available for testing soon.

@GladosBlueWallet GladosBlueWallet left a comment

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.

The pending pill has been taught to confuse dead history with live state. Ark failed/refunded rows still set ispaid false, so this carousel will keep shouting pending long after the swap is dead. State machines are not decorative murals.

Comment thread components/WalletsCarousel.tsx Outdated
// never depend on a Lightning shape.
const isLightningShaped = item.type === LightningCustodianWallet.type || item.type === LightningArkWallet.type;
const hasPendingTx = isLightningShaped
? item.getTransactions().some((tx: any) => tx.ispaid === false)

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.

This treats terminal Ark history as pending because getTransactions() now leaves ispaid false for Failed: and Refunded: rows. After a failed/refunded swap, the wallet card will stay on pending until the row disappears. The state machine is lying to the UI.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Addresses in 546af9f

@GladosBlueWallet GladosBlueWallet left a comment

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.

The lint fix is acceptable. Compressing the array into one line is aesthetically dubious, but the repo’s 140-column ceiling survives, so this chamber remains functional.

Comment thread class/wallets/lightning-ark-wallet.ts Outdated
if (this._wallet) {
this._transactionsHistory = await this._wallet.getTransactionHistory();
const balance = await this._wallet.getBalance();
this.balance = balance.available;

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.

Should it be balance.available or balance.total ?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I recall a discussion about this with @GladosBlueWallet and the rule is that BlueWallet shows the available balance (ie: anything you can spend).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

glados is a bot and cant discuss btw

@github-actions

Copy link
Copy Markdown

✅ Build 8.0.0 (1779716609) has been uploaded to TestFlight and will be available for testing soon.

Flag failed/refunded/expired swap rows in getTransactions and gate the
carousel pending pill on it, so a dead swap no longer pins the card to
pending forever.
@github-actions

Copy link
Copy Markdown

✅ Build 8.0.0 (1779719904) has been uploaded to TestFlight and will be available for testing soon.

@github-actions

Copy link
Copy Markdown

✅ Build 8.0.0 (1779721906) has been uploaded to TestFlight and will be available for testing soon.

Restore flat header structure so the context-menu native view gets its Yoga frame instead of drawing at origin.
Both conflicts resolved by keeping this branch's versions, which deliberately
diverged for New Architecture / Detox reasons that bw/master's changes would
regress:

- components/TransactionsNavigationHeader.tsx: kept our ActionSheet-based
  Manage Funds button. It avoids ToolTipMenu because react-native-context-menu-view
  mispositions under Fabric (overlapping the wallet label); bw/master's
  "FIX: Manage funds layout" keeps ToolTipMenu inside a balanceSection wrapper.
- screen/settings/SelfTest.tsx: kept our removal of the BlueElectrum network
  self-test (network calls + live timers hang Detox/FabricTimersIdlingResource
  on CI); bw/master's "REF: blue electrum" only refactored that block.
@github-actions

Copy link
Copy Markdown

✅ Build 8.0.0 (1779956793) has been uploaded to TestFlight and will be available for testing soon.

@github-actions

Copy link
Copy Markdown

✅ Build 8.0.0 (1779958351) has been uploaded to TestFlight and will be available for testing soon.

getTransactions() merged three feeds (Boltz swaps, boarding UTXOs, SDK
history) and reconciled the swap overlay against the SDK rows with a
fragile fingerprint matcher, so any timestamp skew surfaced one
settlement twice — e.g. a refill also showing as a phantom "Lightning"
row of the same amount.

Rebuild it: getTransactionHistory() is the single source of rows
(boarding entry -> Refill via TxKey.boardingTxid, everything else ->
native Lightning leg). Settled swaps enrich their matching native leg
in place and emit no row of their own; only non-settled swaps that need
visibility (claimable/in-flight/failed/refunded, plus open invoices for
the registry) emit a swap- row. A settlement can no longer appear both
as its native leg and as a swap- row, regardless of timestamp skew.

isInvoiceGeneratedByWallet() now answers from _swapHistory directly so a
settled invoice stays recognizable after its row is enriched onto the leg.
@github-actions

Copy link
Copy Markdown

✅ Build 8.0.0 (1779967377) has been uploaded to TestFlight and will be available for testing soon.

@github-actions

Copy link
Copy Markdown

✅ Build 8.0.0 (1779977368) has been uploaded to TestFlight and will be available for testing soon.

pietro909 and others added 2 commits May 28, 2026 22:04
getTransactionHistory() reports a swept boarding refill TWICE: once as the
boarding leg (key.boardingTxid) and once as the round key.commitmentTxid that
sweeps it into a VTXO — both RECEIVED, same amount, minutes apart, the
commitment leg carrying no arkTxid. Pass 1 of getTransactions() routed them to
two rows: a "Refill" and a phantom "Lightning" leg of the same amount.

Pre-collect the boarding fingerprints, then drop the commitment-sweep twin: a
RECEIVED entry keyed only by commitmentTxid (no arkTxid) that matches a boarding
fingerprint within the match window is the sweep, already represented by the
Refill row. Fingerprints are consumed once so each refill drops exactly one
twin; genuine arkTxid receives/sends are untouched.

Downstream workaround for an SDK bug: the SDK's own commitmentsToIgnore de-dup
misses when the boarding output's on-chain spender txid differs from the
resulting VTXO's commitmentTxId. Remove once fixed upstream.
@github-actions

Copy link
Copy Markdown

✅ Build 8.0.0 (1780002401) has been uploaded to TestFlight and will be available for testing soon.

pietro909 and others added 3 commits May 29, 2026 07:23
The consumer-side fingerprint pre-pass that collapsed duplicate boarding +
commitment-sweep rows into one Refill entry is no longer needed.
arkade-os/ts-sdk#531 (released in 0.4.32) fixes commitmentsToIgnore de-dup
at the source.
@github-actions

Copy link
Copy Markdown

✅ Build 8.0.0 (1780032985) has been uploaded to TestFlight and will be available for testing soon.

Manage Funds -> Refill had two issues:

1. A refill appeared immediately as a completed "Received / Refill" row and the headline balance jumped right away. fetchBalance() used SDK balance.total (offchain + boarding), so an unconfirmed boarding deposit inflated the balance before it was usable, and the pending boarding row (boarding-utxo-...) rendered as a confirmed receive.

2. After the deposit confirmed, the balance briefly showed ~2x the refill. getBalance().total = boarding(confirmed+unconfirmed) + offchain; during settlement the boarding UTXO is still unspent in getCoins() while its freshly-minted preconfirmed VTXO is already counted, so total double-counts the refill until getCoins() drops the spent UTXO.

Fix: headline balance is now available + recoverable (= total minus boarding.total) in both fetchBalance() and the swap-event handler, so a refill enters the balance once, at settlement. Refill rows render as "Pending" until settlement promotes them to a settled "Refill" row, and the detail screen (resolveTxDisplayState) is kept in parity. A dedup guard prevents one refill from showing as both settled and pending if the SDK feeds momentarily disagree.

Matches the reference wallets (../wallet preconfirmed:!settled, ../trixie-wallet headline = available).
@github-actions

Copy link
Copy Markdown

✅ Build 8.0.0 (1780172917) has been uploaded to TestFlight and will be available for testing soon.

pietro909 added 2 commits June 1, 2026 00:11
…-chain detail

Settled swaps are emitted as enriched native Ark legs (type 'bitcoind_tx',
synthetic 'ark-' id) that carry the swap's invoice payload. TransactionListItem
routed taps by type, so these missed the invoice branch and fell through to the
on-chain TransactionStatus screen. Route on 'payment_request' presence instead, in
both onPress and the long-press Details path, so enriched legs reach LNDViewInvoice
while refills and pure Ark transfers (no payload) keep the on-chain detail.

LNDViewInvoice gains an amount fallback to abs(value): an enriched leg has no 'amt',
so the settled success view would otherwise render 0 sats.

Locks the data contract with four unit assertions: enriched settled swaps carry
payment_request; refill rows do not.
On master, Refill / Pending refill rows (type 'bitcoind_tx', no hash, no txid)
are not tappable — tapping is a no-op. This branch gave them synthetic boarding
txids and a txid -> TransactionStatus tap branch, so they began opening the
on-chain detail. Gate that branch on the txid prefix: native Ark transfer legs
(ark-) keep opening the hash-less-tolerant TransactionStatus detail, while Refill
rows (boarding- / boarding-utxo-) navigate nowhere, restoring master behavior.

Applied to both the row tap (onPress) and the long-press Details menu. The guard
uses the same boarding- prefix that arkRowKind uses to label a row 'Refill', so
tap behavior stays consistent with the label.
@github-actions

Copy link
Copy Markdown

✅ Build 8.0.0 (1780266374) has been uploaded to TestFlight and will be available for testing soon.

@GladosBlueWallet

Copy link
Copy Markdown
Collaborator

Wake the fuck up samurai, we have PRs to merge

image

[all PRs for @Overtorment] https://github.com/BlueWallet/BlueWallet/pulls/review-requested/Overtorment

Comment on lines +386 to +389
// Boltz publishes deterministic fees, so Arkade shows a single fixed amount
// under a definite label ("Network fee"), not a "potential" bracket. Custodial
// keeps the legacy "Potential fee" label + range.
const feeLabel = wallet instanceof LightningArkWallet ? loc.lnd.network_fee : loc.lnd.potentialFee;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

its probavly the feee boltz takes, but actual lightning routing fee is still unknown? (unless boltz probed the route in advance and knows the fees on that route)

setNotificationsEnabledState(false);
}

setNotificationsEnabledState(await isNotificationsEnabled());

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

why removed?

// tapscript and hide funds from the indexer.
const DELEGATOR_URLS = {
bitcoin: 'https://delegate.arkade.money',
mutinynet: 'https://delegator.mutinynet.arkade.sh',

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

just a thought - it you really need mutinynet support, say, for dev purposes. in bluewallet.
maybe we can add a dedicated way to import mutinynet arkade wallet.
for exampe, import string like arkmutinynet://abandon abandon or smt like this

});
staticWalletCache[namespace] = wallet;
}
mm.end();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

is it still a slow operation so we need to keep an eye on its timing..?

@Overtorment Overtorment merged commit e37c4a6 into master Jun 1, 2026
16 checks passed
@Overtorment Overtorment deleted the feat/arkade-sdk-upgrade branch June 1, 2026 14:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

testflight Upload iOS and macOS builds to Testflight.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants