From 4f611fbbca34ef363f8d1b9f01fe38dd9a0323e9 Mon Sep 17 00:00:00 2001 From: Ovi Trif Date: Mon, 26 Oct 2026 17:10:30 +0100 Subject: [PATCH] test: stop buying blocktank channels in e2e specs --- test/helpers/native-migration.ts | 48 ++---------- test/specs/hardware-wallet.e2e.ts | 3 +- test/specs/migration.e2e.ts | 120 ++++-------------------------- test/specs/multiaddress.e2e.ts | 3 +- test/specs/transfer.e2e.ts | 6 +- 5 files changed, 27 insertions(+), 153 deletions(-) diff --git a/test/helpers/native-migration.ts b/test/helpers/native-migration.ts index 5b65ee47..2a21d967 100644 --- a/test/helpers/native-migration.ts +++ b/test/helpers/native-migration.ts @@ -1,36 +1,27 @@ import fs from 'node:fs'; import path from 'node:path'; import { - acknowledgeReceivedPayment, completeOnboarding, confirmInputOnKeyboard, doNavigationClose, elementById, expectTextWithin, - expectSavingsBalance, - expectSpendingBalance, - getReceiveAddress, getSavingsBalance, getSeed, getSpendingBalance, getTotalBalance, receiveOnchainFunds, restoreWallet, - swipeFullScreen, tap, - transferSavingsToSpending, typeText, waitForBackup, waitForWalletHome, } from './actions'; import { getAppId, getBackend } from './constants'; import type { ElectrumClient } from './electrum'; -import { payInvoice } from './regtest'; import { getNativeAppPath, grantIOSCameraPermission, reinstallAppFromPath } from './setup'; const FUNDING_SATS = 200_000; -const SPENDING_SATS = 50_000; -const PAYMENT_SATS = 1_000; const DEPOSIT_TAG = 'e2e'; export type MigrationBalances = { savings: number; spending: number; total: number }; @@ -94,7 +85,7 @@ export async function prepareNativeMigrationWallet( await receiveOnchainFunds({ sats: FUNDING_SATS, verifyBalances: true }); await electrum.waitForSync(); - // Tag the sole deposit before creating the transfer; row order is unambiguous here. + // Tag the sole deposit; row order is unambiguous here. await tap('ActivitySavings'); await tap('Activity-1'); await tap('ActivityTag'); @@ -103,22 +94,16 @@ export async function prepareNativeMigrationWallet( if (driver.isAndroid) await confirmInputOnKeyboard(); await returnToWalletHome(); - await transferSavingsToSpending({ - amountSats: SPENDING_SATS, - waitForSync: electrum.waitForSync, - triggerBackgroundPaymentsIntro: true, - }); - await expectSpendingBalance(SPENDING_SATS, { timeout: 180_000 }); - await expectSavingsBalance(0, { condition: 'gt' }); + // No spending balance: Blocktank staging no longer creates orders (synonymdev/blocktank-lsp-http#168). let balances = await readMigrationBalances(); try { await driver.waitUntil( async () => { balances = await readMigrationBalances(); return ( - balances.savings > 0 && - balances.spending === SPENDING_SATS && - balances.total === balances.savings + balances.spending + balances.savings === FUNDING_SATS && + balances.spending === 0 && + balances.total === FUNDING_SATS ); }, { timeout: 30_000, interval: 1_000, timeoutMsg: 'Source balances did not settle' } @@ -200,8 +185,6 @@ async function verifyNativeHistory() { await expectTextWithin('Activity-1', '+'); await elementById('Activity-2').waitForDisplayed({ reverse: true }); await tap(`Tag-${DEPOSIT_TAG}-delete`); - await tap('Tab-other'); - await expectTextWithin('Activity-1', '-'); await doNavigationClose(); } @@ -213,31 +196,12 @@ export async function verifyNativeMigration( recordStage(method, 'target-recovered', await readMigrationBalances()); await verifyNativeHistory(); - // A live payment checks channel usability, beyond a cached spending balance. - // The regtest helper pays into the wallet; outbound payment is covered separately. - const invoice = await getReceiveAddress('lightning'); - await swipeFullScreen('down'); - await payInvoice(invoice, PAYMENT_SATS); - await acknowledgeReceivedPayment(); - const afterPayment = { - savings: balances.savings, - spending: balances.spending + PAYMENT_SATS, - total: balances.total + PAYMENT_SATS, - }; - await expectMigrationBalances(afterPayment); - recordStage(method, 'payment-received', await readMigrationBalances()); await waitForBackup(); await driver.terminateApp(getAppId()); await driver.activateApp(getAppId()); - await expectMigrationBalances(afterPayment); + await expectMigrationBalances(balances); recordStage(method, 'relaunch-verified', await readMigrationBalances()); await verifyNativeHistory(); - await tap('ActivityShowAll'); - await tap('Tab-received'); - // The only new received transaction is the live Lightning payment. - await expectTextWithin('Activity-1', '1 000'); - await expectTextWithin('Activity-1', '+'); - await doNavigationClose(); } function recordStage(method: string, stage: string, balances?: MigrationBalances) { diff --git a/test/specs/hardware-wallet.e2e.ts b/test/specs/hardware-wallet.e2e.ts index 2bddb11f..fff5f3d2 100644 --- a/test/specs/hardware-wallet.e2e.ts +++ b/test/specs/hardware-wallet.e2e.ts @@ -90,7 +90,8 @@ describe('@hardware_wallet @ios_gate - Hardware Wallet', () => { await expectSpendingBalance(0); }); - ciIt('@hardware_wallet_3 - Can transfer hardware wallet funds to spending', async () => { + // Blocktank staging no longer creates orders (synonymdev/blocktank-lsp-http#168) + ciIt.skip('@hardware_wallet_3 - Can transfer hardware wallet funds to spending', async () => { const fundingSats = 100_000; const transferSats = 20_000; diff --git a/test/specs/migration.e2e.ts b/test/specs/migration.e2e.ts index fed1d5af..07dd6780 100644 --- a/test/specs/migration.e2e.ts +++ b/test/specs/migration.e2e.ts @@ -56,7 +56,6 @@ const TAG_SENT = 'sent'; const INITIAL_FUND_SATS = 500_000; // 500k sats initial funding const ONCHAIN_SEND_SATS = 50_000; // 50k sats for on-chain send test // const CJIT_INVOICE_SATS = 3000; // Unused - Blocktank regtest doesn't support CJIT -const TRANSFER_TO_SPENDING_SATS = 100_000; // 100k for creating a channel // Passphrase for passphrase-protected wallet tests const TEST_PASSPHRASE = 'supersecret'; @@ -317,7 +316,8 @@ async function getRnTotalBalance(): Promise { * 1. Create new wallet (optionally with passphrase) * 2. Fund with on-chain tx (add tag to latest tx) * 3. Send on-chain tx (add tag to latest tx) - * 4. Transfer to spending balance (create channel via Blocktank) + * + * No spending balance: Blocktank staging no longer creates orders (synonymdev/blocktank-lsp-http#168). * * On iOS: RN app has poor Appium support for wallet creation, so we restore * from mnemonic/balance provided via env vars (RN_MNEMONIC, RN_BALANCE). @@ -391,18 +391,10 @@ async function setupLegacyWallet( await sendRnOnchain(ONCHAIN_SEND_SATS); await tagLatestTransaction(TAG_SENT); - // 3. Transfer to spending (create channel via Blocktank) - console.info('→ Step 3: Creating spending balance (channel)...'); - await transferToSpendingRN(TRANSFER_TO_SPENDING_SATS); - - // Verify spending balance is visible (channel created) - console.info('→ Verifying spending balance is visible...'); - await assertRnSpendingBalanceVisible(TRANSFER_TO_SPENDING_SATS); - // Get final balance before migration const balance = await getRnTotalBalance(); - await waitForRnBackup(); + await waitForRnBackup(false); console.info('=== Legacy wallet setup complete ==='); // Output for iOS CI to capture @@ -857,64 +849,6 @@ async function sendRnOnchain( console.info(`→ Sent ${sats} sats`); } -/** - * Transfer savings to spending balance (create channel via Blocktank) - */ -async function transferToSpendingRN(sats: number, existingBalance = 0): Promise { - // Navigate via ActivitySavings -> TransferToSpending - // ActivitySavings should be visible near the top of the wallet screen - try { - await elementById('ActivitySavings').waitForDisplayed({ timeout: 5000 }); - } catch { - console.info('→ Scrolling to find ActivitySavings...'); - // Scroll down to reveal ActivitySavings if hidden - await swipeFullScreenRN('down'); - } - await tap('ActivitySavings'); - await elementById('TransferToSpending').waitForDisplayed(); - await tap('TransferToSpending'); - - // Handle intro screen if shown - await sleep(1000); - await tap('SpendingIntro-button'); // "Get Started" - await sleep(1000); // let animation finish - - // Enter amount - const satsStr = String(sats); - for (const digit of satsStr) { - await tap(`N${digit}`); - } - await tap('SpendingAmountContinue'); - - // Confirm screen - swipe to transfer (no intermediate button needed) - await sleep(1000); - await dragOnElement('GRAB', 'right', 0.95); - await sleep(5000); - await handleAndroidAlert(); - - // Mine blocks periodically to progress the channel opening - console.info('→ Mining blocks to confirm channel...'); - for (let i = 0; i < 10; i++) { - await mineBlocks(1); - // Check if spending balance shows the transferred amount (transfer complete) - try { - await elementById('TransferSuccess-button').waitForDisplayed(); - await sleep(1000); - break; - } catch { - console.info('→ Transfer successful screen did not appear, waiting...'); - } - } - - await sleep(3000); - await tap('TransferSuccess-button'); - await electrumClient?.waitForSync(); - await sleep(3000); - const expectedBalance = (existingBalance + sats).toLocaleString('en').replace(/,/g, ' '); - await expectText(expectedBalance); - console.info(`→ Created spending balance with ${sats} sats`); -} - /** * Tag the latest (most recent) transaction in the activity list. * @@ -1033,32 +967,6 @@ async function tapActivityAndWaitForTag(activityId: string): Promise { } } -/** - * Assert that spending balance is visible in RN app. - * Waits for ActivitySpending to show the expected amount. - */ -async function assertRnSpendingBalanceVisible(expectedSats: number): Promise { - const expectedText = expectedSats.toLocaleString('en').replace(/,/g, ' '); - for (let attempt = 1; attempt <= 10; attempt++) { - try { - await elementById('ActivitySpending').waitForDisplayed({ timeout: 5_000 }); - const spendingEl = await elementById('ActivitySpending'); - const text = await getAccessibleText(spendingEl); - if (text.includes(expectedText.replace(/\s/g, '')) || text.includes(expectedText)) { - console.info(`→ Spending balance confirmed: ${text}`); - return; - } - console.info( - `→ Spending balance check (attempt ${attempt}/10): "${text}" vs "${expectedText}"` - ); - } catch { - console.info(`→ ActivitySpending not visible yet (attempt ${attempt}/10)`); - } - await sleep(2_000); - } - throw new Error(`RN source spending balance did not reach ${expectedSats} sats`); -} - /** Verify the final metadata and channel backups before exporting or migrating a source wallet. */ async function waitForRnBackup(requireConnections = true): Promise { await tap('HeaderMenu'); @@ -1198,19 +1106,19 @@ async function verifyMigration( await expectMigrationBalances({ total: expectedBalance, - spending: TRANSFER_TO_SPENDING_SATS, - savings: expectedBalance - TRANSFER_TO_SPENDING_SATS, + spending: 0, + savings: expectedBalance, }); // Go to activity list to verify transactions exist await tap('ActivityShowAll'); - // All transactions (Transfer, Sent, Received = 3 items) - await expectTextWithin('Activity-1', '-'); // Transfer (spending) - await expectTextWithin('Activity-2', '-'); // Sent - await expectTextWithin('Activity-3', '+'); // Received + // All transactions (Sent, Received = 2 items) + await expectTextWithin('Activity-1', '-'); // Sent + await expectTextWithin('Activity-2', '+'); // Received + await elementById('Activity-3').waitForDisplayed({ reverse: true }); - // Sent tab: should show Sent tx only (not Transfer) + // Sent tab: should show Sent tx only await tap('Tab-sent'); await expectTextWithin('Activity-1', '-'); await elementById('Activity-2').waitForDisplayed({ reverse: true }); @@ -1220,11 +1128,9 @@ async function verifyMigration( await expectTextWithin('Activity-1', '+'); await elementById('Activity-2').waitForDisplayed({ reverse: true }); - // Other tab: should show Transfer (spending) tx + // Other tab: no transfers without a spending balance await tap('Tab-other'); - await elementById('Activity-1').waitForDisplayed(); - await expectTextWithin('Activity-1', '-'); // Transfer shows here - await elementById('Activity-2').waitForDisplayed({ reverse: true }); + await elementById('Activity-1').waitForDisplayed({ reverse: true }); if (verifyTags) { // filter by receive tag (metadata restore can lag Electrum balance after mnemonic restore) @@ -1238,7 +1144,7 @@ async function verifyMigration( // filter by send tag await openTagFilter(TAG_SENT); await tap(`Tag-${TAG_SENT}`); - await expectTextWithin('Activity-1', '-'); // Only sent tx has this tag (not Transfer) + await expectTextWithin('Activity-1', '-'); // Only sent tx has this tag await elementById('Activity-2').waitForDisplayed({ reverse: true }); await tap(`Tag-${TAG_SENT}-delete`); diff --git a/test/specs/multiaddress.e2e.ts b/test/specs/multiaddress.e2e.ts index dd5c828a..3ebf6ff5 100644 --- a/test/specs/multiaddress.e2e.ts +++ b/test/specs/multiaddress.e2e.ts @@ -112,7 +112,8 @@ describe('@multi_address - Multi address', () => { await expect(spendingBalanceAfter).toEqual(0); }); - ciIt( + // Blocktank staging no longer creates orders (synonymdev/blocktank-lsp-http#168) + ciIt.skip( '@multi_address_2, @multi_address_staging, @staging - Receive to each address type, transfer all to spending, close channel to taproot', async () => { const addressTypes: addressTypePreference[] = ['p2pkh', 'p2sh-p2wpkh', 'p2wpkh', 'p2tr']; diff --git a/test/specs/transfer.e2e.ts b/test/specs/transfer.e2e.ts index 6deaa08c..5f2e6293 100644 --- a/test/specs/transfer.e2e.ts +++ b/test/specs/transfer.e2e.ts @@ -361,7 +361,8 @@ describe('@transfer - Transfer', () => { electrum?.stop(); }); - ciIt( + // Blocktank staging no longer creates orders (synonymdev/blocktank-lsp-http#168) + ciIt.skip( '@transfer_1, @transfer_staging, @staging - Can buy a channel from Blocktank with default and custom receive capacity', async () => { await receiveOnchainFunds({ sats: 1000_000, expectHighBalanceWarning: true }); @@ -410,7 +411,8 @@ describe('@transfer - Transfer', () => { } ); - ciIt( + // Blocktank staging no longer creates orders (synonymdev/blocktank-lsp-http#168) + ciIt.skip( '@transfer_max, @transfer_staging, @staging - Can fund a Blocktank channel at the settled maximum', async () => { await receiveOnchainFunds({ sats: 100_000 });