fix: polish trezor send loading states - #708

Open
ben-kaufman wants to merge 4 commits into
masterfrom
fix/trezor-send-ui-polish
Open

fix: polish trezor send loading states#708
ben-kaufman wants to merge 4 commits into
masterfrom
fix/trezor-send-ui-polish

Conversation

@ben-kaufman

@ben-kaufmanben-kaufman commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Fixes#696

Description

This PR polishes the transient loading states in the Trezor send flow:

  • shows inline loading feedback while the selected hardware-wallet source refreshes or a transaction preview is prepared
  • prevents repeated source, Continue, fee, and swipe actions while their required hardware-wallet state is unavailable
  • keeps the previous fee visible while a replacement preview loads, with the spinner on the speed icon
  • separates a temporarily disabled swipe from the post-swipe submission spinner, matching the intended Figma behavior

This is stacked on #688. Review this PR against feat/trezor-send; it contains only the loading-state polish for that flow.

Linked Issues/Tasks

Screenshot / Video

Funding-source refreshContinue preparation
Trezor funding-source refreshContinue preparation loading
Confirm preview refreshSign With Device
Confirm preview loadingSign With Device
pr-708-trezor-send-polish.mov

QA Notes

Manual Tests

  • 1. Send → Amount → switch the funding source to Trezor: the source chip shows a blue spinner, and the source control and Continue cannot be triggered again until the available amount finishes refreshing.
  • 2. Send → Confirm → switch to Trezor or change the fee speed: the previous fee stays visible, the speed icon is replaced by its tinted spinner, and the confirmation swipe remains disabled until a valid preview is ready.
  • 3. Send → Confirm → swipe after the fee is ready: the knob reaches the right side and shows the submission spinner while the flow proceeds to Sign With Device.
  • 4.regression: switch back to Spending or Savings: the normal source, fee, Continue, and swipe behavior remains available.

Automated Checks

  • HwFundingSignerTests: 26 tests passed, including source-refresh, unavailable-fee, and preview-loading coverage.
  • SwiftFormat lint passed for the changed files.
  • git diff --check passed.

@greptile-apps

Copy link
Copy Markdown

Greptile Summary

This PR separates disabled and submitting states in the swipe control and adds explicit hardware-wallet funding-source and preview loading state across the send flow.

  • Adds tintable activity indicators and loading support to shared controls.
  • Tracks hardware funding-source and transaction-preview preparation in HwSendCoordinator.
  • Disables repeated source, fee, Continue, and swipe actions while required hardware state is unavailable.
  • Adds coordinator tests for source refresh and preview preparation.

Confidence Score: 4/5

The hardware-source loading failure path should be fixed before merging because a fee-estimation failure can trap the send screen with no usable source-selection or Continue action.

Hardware selection now starts an externally visible loading state that is cleared only after a refresh or preview, but the amount view can return before starting either operation when its fee rate is unavailable.

Files Needing Attention: Bitkit/Views/Wallets/Send/SendAmountView.swift; Bitkit/ViewModels/HwFundingSigner.swift

Important Files Changed

FilenameOverview
Bitkit/ViewModels/HwFundingSigner.swiftAdds request-scoped funding-source and preview loading flags, including stale-request invalidation and cancellation cleanup.
Bitkit/Views/Wallets/Send/SendAmountView.swiftConnects hardware loading to source and Continue controls, but can leave both unavailable when fee resolution fails before balance refresh.
Bitkit/Views/Wallets/Send/SendConfirmationView.swiftPresents hardware preview loading on the fee icon and disables source, fee, and swipe actions until preview readiness.
Bitkit/Components/SwipeButton.swiftSeparates temporarily disabled presentation from the post-swipe spinner while retaining unified interaction blocking.
BitkitTests/HwFundingSignerTests.swiftCovers successful funding-source refresh and preview-loading transitions but not unavailable fee-rate or refresh-failure recovery.

Sequence Diagram

sequenceDiagram
participant U as User
participant V as SendAmountView
participant C as HwSendCoordinator
participant F as Fee estimation
U->>V: Select Trezor
V->>C: selectWallet(showsLoading: true)
C-->>V: "isFundingSourceLoading = true"
V->>F: Resolve selected fee rate
alt Fee rate available
V->>C: refreshAvailable(...)
C-->>V: "Balance and loading=false"
else Fee estimation fails
V-->>V: Refresh guard returns
Note over V,C: Loading remains true and source control stays disabled
end
Loading

Reviews (1): Last reviewed commit: "fix: polish trezor send loading states" | Re-trigger Greptile

Comment threadBitkit/Views/Wallets/Send/SendAmountView.swift
@ovitrifovitrif linked an issue Aug 31, 2026 that may be closed by this pull request
Base automatically changed from feat/trezor-send to masterSeptember 1, 2026 08:43

@ovitrifovitrif 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.

Confirm still traps source, fee, and swipe after a missing fee rate, and the Amount → Confirm reload blanks the fee Amount just prepared.

  • Switching to Trezor on Confirm sets isFundingSourceLoading through selectWallet(..., showsLoading: true), then calculateTransactionFee() returns when selectedFeeRateSatsPerVByte is nil, so nothing settles the flag. Source, fee, and swipe stay disabled until the sheet is dismissed.
  • displayedTransactionFee only preserves a fee already stored in local transactionFee. Confirm's first preparePreview zeros previewFeeSats while transactionFee is still 0, so the fee from Amount disappears until the duplicate preview returns.
  • testCoordinatorTracksPreviewPreparation only covers a successful estimate. Nothing would fail if preparePreview's catch stopped clearing isPreviewLoading.

Comment threadBitkit/Views/Wallets/Send/SendConfirmationView.swift
Comment threadBitkit/Views/Wallets/Send/SendConfirmationView.swift
Comment threadBitkitTests/HwFundingSignerTests.swift
@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

All three Confirm loading and fee findings are fixed in signed commit bb94073 and the threads are resolved. HwFundingSignerTests passes 26 of 26. @ovitrif please re-review the updated head.

@ovitrif

Copy link
Copy Markdown
Collaborator

@ben-kaufman Can we please include media in PR description (screens / recs) 🙏🏻 ?
Thanks

@ben-kaufmanChatGPT Codex Connector

Copy link
Copy Markdown
ContributorAuthor

@ovitrif Added four screenshots and a recording to the PR description covering the funding-source refresh, Continue preparation, Confirm preview refresh, and transition to Sign With Device. Thanks!

@ovitrifovitrif 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.

QA Notes

iPhone 17 simulator, iOS 26.5, regtest.

  • Amount: switching the source to Trezor refreshed available funds; source and Continue were usable after settle.
  • Confirm: the previous fee stayed visible across Trezor and Savings switches; swipe proceeded once the preview was ready.
  • Swipe after the fee was ready reached Sign With Device.
  • Switching back to Savings restored source, fee, Continue, and swipe.

Approve.

@ovitrif

ovitrif commented Sep 1, 2026

Copy link
Copy Markdown
Collaborator

LGTM, tested all cases from QA notes.

Before merge we still need e2e green, maybe merge with master so it retriggers properly? cc. @ben-kaufman 🙏🏻

Meanwhile @piotr-iohk can have a look to confirm if the e2e failure would likely succeed next run:
https://github.com/synonymdev/bitkit-ios/actions/runs/33512189709/job/99876203530?pr=708

thanks 🙏🏻

@ovitrif
ovitrif enabled auto-merge September 1, 2026 14:49
Sign up for freeto 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.

Trezor send UI polish

2 participants

@ben-kaufman@ovitrif
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

fix: polish trezor send loading states - #708

Open
ben-kaufman wants to merge 4 commits into
masterfrom
fix/trezor-send-ui-polish
Open

fix: polish trezor send loading states#708
ben-kaufman wants to merge 4 commits into
masterfrom
fix/trezor-send-ui-polish

Conversation

@ben-kaufman

@ben-kaufmanben-kaufman commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Fixes#696

Description

This PR polishes the transient loading states in the Trezor send flow:

  • shows inline loading feedback while the selected hardware-wallet source refreshes or a transaction preview is prepared
  • prevents repeated source, Continue, fee, and swipe actions while their required hardware-wallet state is unavailable
  • keeps the previous fee visible while a replacement preview loads, with the spinner on the speed icon
  • separates a temporarily disabled swipe from the post-swipe submission spinner, matching the intended Figma behavior

This is stacked on #688. Review this PR against feat/trezor-send; it contains only the loading-state polish for that flow.

Linked Issues/Tasks

Screenshot / Video

Funding-source refreshContinue preparation
Trezor funding-source refreshContinue preparation loading
Confirm preview refreshSign With Device
Confirm preview loadingSign With Device
pr-708-trezor-send-polish.mov

QA Notes

Manual Tests

  • 1. Send → Amount → switch the funding source to Trezor: the source chip shows a blue spinner, and the source control and Continue cannot be triggered again until the available amount finishes refreshing.
  • 2. Send → Confirm → switch to Trezor or change the fee speed: the previous fee stays visible, the speed icon is replaced by its tinted spinner, and the confirmation swipe remains disabled until a valid preview is ready.
  • 3. Send → Confirm → swipe after the fee is ready: the knob reaches the right side and shows the submission spinner while the flow proceeds to Sign With Device.
  • 4.regression: switch back to Spending or Savings: the normal source, fee, Continue, and swipe behavior remains available.

Automated Checks

  • HwFundingSignerTests: 26 tests passed, including source-refresh, unavailable-fee, and preview-loading coverage.
  • SwiftFormat lint passed for the changed files.
  • git diff --check passed.

@greptile-apps

Copy link
Copy Markdown

Greptile Summary

This PR separates disabled and submitting states in the swipe control and adds explicit hardware-wallet funding-source and preview loading state across the send flow.

  • Adds tintable activity indicators and loading support to shared controls.
  • Tracks hardware funding-source and transaction-preview preparation in HwSendCoordinator.
  • Disables repeated source, fee, Continue, and swipe actions while required hardware state is unavailable.
  • Adds coordinator tests for source refresh and preview preparation.

Confidence Score: 4/5

The hardware-source loading failure path should be fixed before merging because a fee-estimation failure can trap the send screen with no usable source-selection or Continue action.

Hardware selection now starts an externally visible loading state that is cleared only after a refresh or preview, but the amount view can return before starting either operation when its fee rate is unavailable.

Files Needing Attention: Bitkit/Views/Wallets/Send/SendAmountView.swift; Bitkit/ViewModels/HwFundingSigner.swift

Important Files Changed

FilenameOverview
Bitkit/ViewModels/HwFundingSigner.swiftAdds request-scoped funding-source and preview loading flags, including stale-request invalidation and cancellation cleanup.
Bitkit/Views/Wallets/Send/SendAmountView.swiftConnects hardware loading to source and Continue controls, but can leave both unavailable when fee resolution fails before balance refresh.
Bitkit/Views/Wallets/Send/SendConfirmationView.swiftPresents hardware preview loading on the fee icon and disables source, fee, and swipe actions until preview readiness.
Bitkit/Components/SwipeButton.swiftSeparates temporarily disabled presentation from the post-swipe spinner while retaining unified interaction blocking.
BitkitTests/HwFundingSignerTests.swiftCovers successful funding-source refresh and preview-loading transitions but not unavailable fee-rate or refresh-failure recovery.

Sequence Diagram

sequenceDiagram
participant U as User
participant V as SendAmountView
participant C as HwSendCoordinator
participant F as Fee estimation
U->>V: Select Trezor
V->>C: selectWallet(showsLoading: true)
C-->>V: "isFundingSourceLoading = true"
V->>F: Resolve selected fee rate
alt Fee rate available
V->>C: refreshAvailable(...)
C-->>V: "Balance and loading=false"
else Fee estimation fails
V-->>V: Refresh guard returns
Note over V,C: Loading remains true and source control stays disabled
end
Loading

Reviews (1): Last reviewed commit: "fix: polish trezor send loading states" | Re-trigger Greptile

Comment threadBitkit/Views/Wallets/Send/SendAmountView.swift
@ovitrifovitrif linked an issue Aug 31, 2026 that may be closed by this pull request
Base automatically changed from feat/trezor-send to masterSeptember 1, 2026 08:43

@ovitrifovitrif 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.

Confirm still traps source, fee, and swipe after a missing fee rate, and the Amount → Confirm reload blanks the fee Amount just prepared.

  • Switching to Trezor on Confirm sets isFundingSourceLoading through selectWallet(..., showsLoading: true), then calculateTransactionFee() returns when selectedFeeRateSatsPerVByte is nil, so nothing settles the flag. Source, fee, and swipe stay disabled until the sheet is dismissed.
  • displayedTransactionFee only preserves a fee already stored in local transactionFee. Confirm's first preparePreview zeros previewFeeSats while transactionFee is still 0, so the fee from Amount disappears until the duplicate preview returns.
  • testCoordinatorTracksPreviewPreparation only covers a successful estimate. Nothing would fail if preparePreview's catch stopped clearing isPreviewLoading.

Comment threadBitkit/Views/Wallets/Send/SendConfirmationView.swift
Comment threadBitkit/Views/Wallets/Send/SendConfirmationView.swift
Comment threadBitkitTests/HwFundingSignerTests.swift
@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

All three Confirm loading and fee findings are fixed in signed commit bb94073 and the threads are resolved. HwFundingSignerTests passes 26 of 26. @ovitrif please re-review the updated head.

@ovitrif

Copy link
Copy Markdown
Collaborator

@ben-kaufman Can we please include media in PR description (screens / recs) 🙏🏻 ?
Thanks

@ben-kaufmanChatGPT Codex Connector

Copy link
Copy Markdown
ContributorAuthor

@ovitrif Added four screenshots and a recording to the PR description covering the funding-source refresh, Continue preparation, Confirm preview refresh, and transition to Sign With Device. Thanks!

@ovitrifovitrif 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.

QA Notes

iPhone 17 simulator, iOS 26.5, regtest.

  • Amount: switching the source to Trezor refreshed available funds; source and Continue were usable after settle.
  • Confirm: the previous fee stayed visible across Trezor and Savings switches; swipe proceeded once the preview was ready.
  • Swipe after the fee was ready reached Sign With Device.
  • Switching back to Savings restored source, fee, Continue, and swipe.

Approve.

@ovitrif

ovitrif commented Sep 1, 2026

Copy link
Copy Markdown
Collaborator

LGTM, tested all cases from QA notes.

Before merge we still need e2e green, maybe merge with master so it retriggers properly? cc. @ben-kaufman 🙏🏻

Meanwhile @piotr-iohk can have a look to confirm if the e2e failure would likely succeed next run:
https://github.com/synonymdev/bitkit-ios/actions/runs/33512189709/job/99876203530?pr=708

thanks 🙏🏻

@ovitrif
ovitrif enabled auto-merge September 1, 2026 14:49
Sign up for freeto 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.

Trezor send UI polish

2 participants

@ben-kaufman@ovitrif
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix: polish trezor send loading states - #708

Open
ben-kaufman wants to merge 4 commits into
masterfrom
fix/trezor-send-ui-polish
Open

fix: polish trezor send loading states#708
ben-kaufman wants to merge 4 commits into
masterfrom
fix/trezor-send-ui-polish

Conversation

@ben-kaufman

@ben-kaufmanben-kaufman commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Fixes#696

Description

This PR polishes the transient loading states in the Trezor send flow:

  • shows inline loading feedback while the selected hardware-wallet source refreshes or a transaction preview is prepared
  • prevents repeated source, Continue, fee, and swipe actions while their required hardware-wallet state is unavailable
  • keeps the previous fee visible while a replacement preview loads, with the spinner on the speed icon
  • separates a temporarily disabled swipe from the post-swipe submission spinner, matching the intended Figma behavior

This is stacked on #688. Review this PR against feat/trezor-send; it contains only the loading-state polish for that flow.

Linked Issues/Tasks

Screenshot / Video

Funding-source refreshContinue preparation
Trezor funding-source refreshContinue preparation loading
Confirm preview refreshSign With Device
Confirm preview loadingSign With Device
pr-708-trezor-send-polish.mov

QA Notes

Manual Tests

  • 1. Send → Amount → switch the funding source to Trezor: the source chip shows a blue spinner, and the source control and Continue cannot be triggered again until the available amount finishes refreshing.
  • 2. Send → Confirm → switch to Trezor or change the fee speed: the previous fee stays visible, the speed icon is replaced by its tinted spinner, and the confirmation swipe remains disabled until a valid preview is ready.
  • 3. Send → Confirm → swipe after the fee is ready: the knob reaches the right side and shows the submission spinner while the flow proceeds to Sign With Device.
  • 4.regression: switch back to Spending or Savings: the normal source, fee, Continue, and swipe behavior remains available.

Automated Checks

  • HwFundingSignerTests: 26 tests passed, including source-refresh, unavailable-fee, and preview-loading coverage.
  • SwiftFormat lint passed for the changed files.
  • git diff --check passed.

@greptile-apps

Copy link
Copy Markdown

Greptile Summary

This PR separates disabled and submitting states in the swipe control and adds explicit hardware-wallet funding-source and preview loading state across the send flow.

  • Adds tintable activity indicators and loading support to shared controls.
  • Tracks hardware funding-source and transaction-preview preparation in HwSendCoordinator.
  • Disables repeated source, fee, Continue, and swipe actions while required hardware state is unavailable.
  • Adds coordinator tests for source refresh and preview preparation.

Confidence Score: 4/5

The hardware-source loading failure path should be fixed before merging because a fee-estimation failure can trap the send screen with no usable source-selection or Continue action.

Hardware selection now starts an externally visible loading state that is cleared only after a refresh or preview, but the amount view can return before starting either operation when its fee rate is unavailable.

Files Needing Attention: Bitkit/Views/Wallets/Send/SendAmountView.swift; Bitkit/ViewModels/HwFundingSigner.swift

Important Files Changed

FilenameOverview
Bitkit/ViewModels/HwFundingSigner.swiftAdds request-scoped funding-source and preview loading flags, including stale-request invalidation and cancellation cleanup.
Bitkit/Views/Wallets/Send/SendAmountView.swiftConnects hardware loading to source and Continue controls, but can leave both unavailable when fee resolution fails before balance refresh.
Bitkit/Views/Wallets/Send/SendConfirmationView.swiftPresents hardware preview loading on the fee icon and disables source, fee, and swipe actions until preview readiness.
Bitkit/Components/SwipeButton.swiftSeparates temporarily disabled presentation from the post-swipe spinner while retaining unified interaction blocking.
BitkitTests/HwFundingSignerTests.swiftCovers successful funding-source refresh and preview-loading transitions but not unavailable fee-rate or refresh-failure recovery.

Sequence Diagram

sequenceDiagram
participant U as User
participant V as SendAmountView
participant C as HwSendCoordinator
participant F as Fee estimation
U->>V: Select Trezor
V->>C: selectWallet(showsLoading: true)
C-->>V: "isFundingSourceLoading = true"
V->>F: Resolve selected fee rate
alt Fee rate available
V->>C: refreshAvailable(...)
C-->>V: "Balance and loading=false"
else Fee estimation fails
V-->>V: Refresh guard returns
Note over V,C: Loading remains true and source control stays disabled
end
Loading

Reviews (1): Last reviewed commit: "fix: polish trezor send loading states" | Re-trigger Greptile

Comment threadBitkit/Views/Wallets/Send/SendAmountView.swift
@ovitrifovitrif linked an issue Aug 31, 2026 that may be closed by this pull request
Base automatically changed from feat/trezor-send to masterSeptember 1, 2026 08:43

@ovitrifovitrif 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.

Confirm still traps source, fee, and swipe after a missing fee rate, and the Amount → Confirm reload blanks the fee Amount just prepared.

  • Switching to Trezor on Confirm sets isFundingSourceLoading through selectWallet(..., showsLoading: true), then calculateTransactionFee() returns when selectedFeeRateSatsPerVByte is nil, so nothing settles the flag. Source, fee, and swipe stay disabled until the sheet is dismissed.
  • displayedTransactionFee only preserves a fee already stored in local transactionFee. Confirm's first preparePreview zeros previewFeeSats while transactionFee is still 0, so the fee from Amount disappears until the duplicate preview returns.
  • testCoordinatorTracksPreviewPreparation only covers a successful estimate. Nothing would fail if preparePreview's catch stopped clearing isPreviewLoading.

Comment threadBitkit/Views/Wallets/Send/SendConfirmationView.swift
Comment threadBitkit/Views/Wallets/Send/SendConfirmationView.swift
Comment threadBitkitTests/HwFundingSignerTests.swift
@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

All three Confirm loading and fee findings are fixed in signed commit bb94073 and the threads are resolved. HwFundingSignerTests passes 26 of 26. @ovitrif please re-review the updated head.

@ovitrif

Copy link
Copy Markdown
Collaborator

@ben-kaufman Can we please include media in PR description (screens / recs) 🙏🏻 ?
Thanks

@ben-kaufmanChatGPT Codex Connector

Copy link
Copy Markdown
ContributorAuthor

@ovitrif Added four screenshots and a recording to the PR description covering the funding-source refresh, Continue preparation, Confirm preview refresh, and transition to Sign With Device. Thanks!

@ovitrifovitrif 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.

QA Notes

iPhone 17 simulator, iOS 26.5, regtest.

  • Amount: switching the source to Trezor refreshed available funds; source and Continue were usable after settle.
  • Confirm: the previous fee stayed visible across Trezor and Savings switches; swipe proceeded once the preview was ready.
  • Swipe after the fee was ready reached Sign With Device.
  • Switching back to Savings restored source, fee, Continue, and swipe.

Approve.

@ovitrif

ovitrif commented Sep 1, 2026

Copy link
Copy Markdown
Collaborator

LGTM, tested all cases from QA notes.

Before merge we still need e2e green, maybe merge with master so it retriggers properly? cc. @ben-kaufman 🙏🏻

Meanwhile @piotr-iohk can have a look to confirm if the e2e failure would likely succeed next run:
https://github.com/synonymdev/bitkit-ios/actions/runs/33512189709/job/99876203530?pr=708

thanks 🙏🏻

@ovitrif
ovitrif enabled auto-merge September 1, 2026 14:49
Sign up for freeto 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.

Trezor send UI polish

2 participants

@ben-kaufman@ovitrif
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix: polish trezor send loading states - #708

Open
ben-kaufman wants to merge 4 commits into
masterfrom
fix/trezor-send-ui-polish
Open

fix: polish trezor send loading states#708
ben-kaufman wants to merge 4 commits into
masterfrom
fix/trezor-send-ui-polish

Conversation

@ben-kaufman

@ben-kaufmanben-kaufman commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Fixes#696

Description

This PR polishes the transient loading states in the Trezor send flow:

  • shows inline loading feedback while the selected hardware-wallet source refreshes or a transaction preview is prepared
  • prevents repeated source, Continue, fee, and swipe actions while their required hardware-wallet state is unavailable
  • keeps the previous fee visible while a replacement preview loads, with the spinner on the speed icon
  • separates a temporarily disabled swipe from the post-swipe submission spinner, matching the intended Figma behavior

This is stacked on #688. Review this PR against feat/trezor-send; it contains only the loading-state polish for that flow.

Linked Issues/Tasks

Screenshot / Video

Funding-source refreshContinue preparation
Trezor funding-source refreshContinue preparation loading
Confirm preview refreshSign With Device
Confirm preview loadingSign With Device
pr-708-trezor-send-polish.mov

QA Notes

Manual Tests

  • 1. Send → Amount → switch the funding source to Trezor: the source chip shows a blue spinner, and the source control and Continue cannot be triggered again until the available amount finishes refreshing.
  • 2. Send → Confirm → switch to Trezor or change the fee speed: the previous fee stays visible, the speed icon is replaced by its tinted spinner, and the confirmation swipe remains disabled until a valid preview is ready.
  • 3. Send → Confirm → swipe after the fee is ready: the knob reaches the right side and shows the submission spinner while the flow proceeds to Sign With Device.
  • 4.regression: switch back to Spending or Savings: the normal source, fee, Continue, and swipe behavior remains available.

Automated Checks

  • HwFundingSignerTests: 26 tests passed, including source-refresh, unavailable-fee, and preview-loading coverage.
  • SwiftFormat lint passed for the changed files.
  • git diff --check passed.

@greptile-apps

Copy link
Copy Markdown

Greptile Summary

This PR separates disabled and submitting states in the swipe control and adds explicit hardware-wallet funding-source and preview loading state across the send flow.

  • Adds tintable activity indicators and loading support to shared controls.
  • Tracks hardware funding-source and transaction-preview preparation in HwSendCoordinator.
  • Disables repeated source, fee, Continue, and swipe actions while required hardware state is unavailable.
  • Adds coordinator tests for source refresh and preview preparation.

Confidence Score: 4/5

The hardware-source loading failure path should be fixed before merging because a fee-estimation failure can trap the send screen with no usable source-selection or Continue action.

Hardware selection now starts an externally visible loading state that is cleared only after a refresh or preview, but the amount view can return before starting either operation when its fee rate is unavailable.

Files Needing Attention: Bitkit/Views/Wallets/Send/SendAmountView.swift; Bitkit/ViewModels/HwFundingSigner.swift

Important Files Changed

FilenameOverview
Bitkit/ViewModels/HwFundingSigner.swiftAdds request-scoped funding-source and preview loading flags, including stale-request invalidation and cancellation cleanup.
Bitkit/Views/Wallets/Send/SendAmountView.swiftConnects hardware loading to source and Continue controls, but can leave both unavailable when fee resolution fails before balance refresh.
Bitkit/Views/Wallets/Send/SendConfirmationView.swiftPresents hardware preview loading on the fee icon and disables source, fee, and swipe actions until preview readiness.
Bitkit/Components/SwipeButton.swiftSeparates temporarily disabled presentation from the post-swipe spinner while retaining unified interaction blocking.
BitkitTests/HwFundingSignerTests.swiftCovers successful funding-source refresh and preview-loading transitions but not unavailable fee-rate or refresh-failure recovery.

Sequence Diagram

sequenceDiagram
participant U as User
participant V as SendAmountView
participant C as HwSendCoordinator
participant F as Fee estimation
U->>V: Select Trezor
V->>C: selectWallet(showsLoading: true)
C-->>V: "isFundingSourceLoading = true"
V->>F: Resolve selected fee rate
alt Fee rate available
V->>C: refreshAvailable(...)
C-->>V: "Balance and loading=false"
else Fee estimation fails
V-->>V: Refresh guard returns
Note over V,C: Loading remains true and source control stays disabled
end
Loading

Reviews (1): Last reviewed commit: "fix: polish trezor send loading states" | Re-trigger Greptile

Comment threadBitkit/Views/Wallets/Send/SendAmountView.swift
@ovitrifovitrif linked an issue Aug 31, 2026 that may be closed by this pull request
Base automatically changed from feat/trezor-send to masterSeptember 1, 2026 08:43

@ovitrifovitrif 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.

Confirm still traps source, fee, and swipe after a missing fee rate, and the Amount → Confirm reload blanks the fee Amount just prepared.

  • Switching to Trezor on Confirm sets isFundingSourceLoading through selectWallet(..., showsLoading: true), then calculateTransactionFee() returns when selectedFeeRateSatsPerVByte is nil, so nothing settles the flag. Source, fee, and swipe stay disabled until the sheet is dismissed.
  • displayedTransactionFee only preserves a fee already stored in local transactionFee. Confirm's first preparePreview zeros previewFeeSats while transactionFee is still 0, so the fee from Amount disappears until the duplicate preview returns.
  • testCoordinatorTracksPreviewPreparation only covers a successful estimate. Nothing would fail if preparePreview's catch stopped clearing isPreviewLoading.

Comment threadBitkit/Views/Wallets/Send/SendConfirmationView.swift
Comment threadBitkit/Views/Wallets/Send/SendConfirmationView.swift
Comment threadBitkitTests/HwFundingSignerTests.swift
@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

All three Confirm loading and fee findings are fixed in signed commit bb94073 and the threads are resolved. HwFundingSignerTests passes 26 of 26. @ovitrif please re-review the updated head.

@ovitrif

Copy link
Copy Markdown
Collaborator

@ben-kaufman Can we please include media in PR description (screens / recs) 🙏🏻 ?
Thanks

@ben-kaufmanChatGPT Codex Connector

Copy link
Copy Markdown
ContributorAuthor

@ovitrif Added four screenshots and a recording to the PR description covering the funding-source refresh, Continue preparation, Confirm preview refresh, and transition to Sign With Device. Thanks!

@ovitrifovitrif 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.

QA Notes

iPhone 17 simulator, iOS 26.5, regtest.

  • Amount: switching the source to Trezor refreshed available funds; source and Continue were usable after settle.
  • Confirm: the previous fee stayed visible across Trezor and Savings switches; swipe proceeded once the preview was ready.
  • Swipe after the fee was ready reached Sign With Device.
  • Switching back to Savings restored source, fee, Continue, and swipe.

Approve.

@ovitrif

ovitrif commented Sep 1, 2026

Copy link
Copy Markdown
Collaborator

LGTM, tested all cases from QA notes.

Before merge we still need e2e green, maybe merge with master so it retriggers properly? cc. @ben-kaufman 🙏🏻

Meanwhile @piotr-iohk can have a look to confirm if the e2e failure would likely succeed next run:
https://github.com/synonymdev/bitkit-ios/actions/runs/33512189709/job/99876203530?pr=708

thanks 🙏🏻

@ovitrif
ovitrif enabled auto-merge September 1, 2026 14:49
Sign up for freeto 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.

Trezor send UI polish

2 participants

@ben-kaufman@ovitrif
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

fix: polish trezor send loading states - #708

Open
ben-kaufman wants to merge 4 commits into
masterfrom
fix/trezor-send-ui-polish
Open

fix: polish trezor send loading states#708
ben-kaufman wants to merge 4 commits into
masterfrom
fix/trezor-send-ui-polish

Conversation

@ben-kaufman

@ben-kaufmanben-kaufman commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Fixes#696

Description

This PR polishes the transient loading states in the Trezor send flow:

  • shows inline loading feedback while the selected hardware-wallet source refreshes or a transaction preview is prepared
  • prevents repeated source, Continue, fee, and swipe actions while their required hardware-wallet state is unavailable
  • keeps the previous fee visible while a replacement preview loads, with the spinner on the speed icon
  • separates a temporarily disabled swipe from the post-swipe submission spinner, matching the intended Figma behavior

This is stacked on #688. Review this PR against feat/trezor-send; it contains only the loading-state polish for that flow.

Linked Issues/Tasks

Screenshot / Video

Funding-source refreshContinue preparation
Trezor funding-source refreshContinue preparation loading
Confirm preview refreshSign With Device
Confirm preview loadingSign With Device
pr-708-trezor-send-polish.mov

QA Notes

Manual Tests

  • 1. Send → Amount → switch the funding source to Trezor: the source chip shows a blue spinner, and the source control and Continue cannot be triggered again until the available amount finishes refreshing.
  • 2. Send → Confirm → switch to Trezor or change the fee speed: the previous fee stays visible, the speed icon is replaced by its tinted spinner, and the confirmation swipe remains disabled until a valid preview is ready.
  • 3. Send → Confirm → swipe after the fee is ready: the knob reaches the right side and shows the submission spinner while the flow proceeds to Sign With Device.
  • 4.regression: switch back to Spending or Savings: the normal source, fee, Continue, and swipe behavior remains available.

Automated Checks

  • HwFundingSignerTests: 26 tests passed, including source-refresh, unavailable-fee, and preview-loading coverage.
  • SwiftFormat lint passed for the changed files.
  • git diff --check passed.

@greptile-apps

Copy link
Copy Markdown

Greptile Summary

This PR separates disabled and submitting states in the swipe control and adds explicit hardware-wallet funding-source and preview loading state across the send flow.

  • Adds tintable activity indicators and loading support to shared controls.
  • Tracks hardware funding-source and transaction-preview preparation in HwSendCoordinator.
  • Disables repeated source, fee, Continue, and swipe actions while required hardware state is unavailable.
  • Adds coordinator tests for source refresh and preview preparation.

Confidence Score: 4/5

The hardware-source loading failure path should be fixed before merging because a fee-estimation failure can trap the send screen with no usable source-selection or Continue action.

Hardware selection now starts an externally visible loading state that is cleared only after a refresh or preview, but the amount view can return before starting either operation when its fee rate is unavailable.

Files Needing Attention: Bitkit/Views/Wallets/Send/SendAmountView.swift; Bitkit/ViewModels/HwFundingSigner.swift

Important Files Changed

FilenameOverview
Bitkit/ViewModels/HwFundingSigner.swiftAdds request-scoped funding-source and preview loading flags, including stale-request invalidation and cancellation cleanup.
Bitkit/Views/Wallets/Send/SendAmountView.swiftConnects hardware loading to source and Continue controls, but can leave both unavailable when fee resolution fails before balance refresh.
Bitkit/Views/Wallets/Send/SendConfirmationView.swiftPresents hardware preview loading on the fee icon and disables source, fee, and swipe actions until preview readiness.
Bitkit/Components/SwipeButton.swiftSeparates temporarily disabled presentation from the post-swipe spinner while retaining unified interaction blocking.
BitkitTests/HwFundingSignerTests.swiftCovers successful funding-source refresh and preview-loading transitions but not unavailable fee-rate or refresh-failure recovery.

Sequence Diagram

sequenceDiagram
participant U as User
participant V as SendAmountView
participant C as HwSendCoordinator
participant F as Fee estimation
U->>V: Select Trezor
V->>C: selectWallet(showsLoading: true)
C-->>V: "isFundingSourceLoading = true"
V->>F: Resolve selected fee rate
alt Fee rate available
V->>C: refreshAvailable(...)
C-->>V: "Balance and loading=false"
else Fee estimation fails
V-->>V: Refresh guard returns
Note over V,C: Loading remains true and source control stays disabled
end
Loading

Reviews (1): Last reviewed commit: "fix: polish trezor send loading states" | Re-trigger Greptile

Comment threadBitkit/Views/Wallets/Send/SendAmountView.swift
@ovitrifovitrif linked an issue Aug 31, 2026 that may be closed by this pull request
Base automatically changed from feat/trezor-send to masterSeptember 1, 2026 08:43

@ovitrifovitrif 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.

Confirm still traps source, fee, and swipe after a missing fee rate, and the Amount → Confirm reload blanks the fee Amount just prepared.

  • Switching to Trezor on Confirm sets isFundingSourceLoading through selectWallet(..., showsLoading: true), then calculateTransactionFee() returns when selectedFeeRateSatsPerVByte is nil, so nothing settles the flag. Source, fee, and swipe stay disabled until the sheet is dismissed.
  • displayedTransactionFee only preserves a fee already stored in local transactionFee. Confirm's first preparePreview zeros previewFeeSats while transactionFee is still 0, so the fee from Amount disappears until the duplicate preview returns.
  • testCoordinatorTracksPreviewPreparation only covers a successful estimate. Nothing would fail if preparePreview's catch stopped clearing isPreviewLoading.

Comment threadBitkit/Views/Wallets/Send/SendConfirmationView.swift
Comment threadBitkit/Views/Wallets/Send/SendConfirmationView.swift
Comment threadBitkitTests/HwFundingSignerTests.swift
@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

All three Confirm loading and fee findings are fixed in signed commit bb94073 and the threads are resolved. HwFundingSignerTests passes 26 of 26. @ovitrif please re-review the updated head.

@ovitrif

Copy link
Copy Markdown
Collaborator

@ben-kaufman Can we please include media in PR description (screens / recs) 🙏🏻 ?
Thanks

@ben-kaufmanChatGPT Codex Connector

Copy link
Copy Markdown
ContributorAuthor

@ovitrif Added four screenshots and a recording to the PR description covering the funding-source refresh, Continue preparation, Confirm preview refresh, and transition to Sign With Device. Thanks!

@ovitrifovitrif 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.

QA Notes

iPhone 17 simulator, iOS 26.5, regtest.

  • Amount: switching the source to Trezor refreshed available funds; source and Continue were usable after settle.
  • Confirm: the previous fee stayed visible across Trezor and Savings switches; swipe proceeded once the preview was ready.
  • Swipe after the fee was ready reached Sign With Device.
  • Switching back to Savings restored source, fee, Continue, and swipe.

Approve.

@ovitrif

ovitrif commented Sep 1, 2026

Copy link
Copy Markdown
Collaborator

LGTM, tested all cases from QA notes.

Before merge we still need e2e green, maybe merge with master so it retriggers properly? cc. @ben-kaufman 🙏🏻

Meanwhile @piotr-iohk can have a look to confirm if the e2e failure would likely succeed next run:
https://github.com/synonymdev/bitkit-ios/actions/runs/33512189709/job/99876203530?pr=708

thanks 🙏🏻

@ovitrif
ovitrif enabled auto-merge September 1, 2026 14:49
Sign up for freeto 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.

Trezor send UI polish

2 participants

@ben-kaufman@ovitrif
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix: polish trezor send loading states - #708

Open
ben-kaufman wants to merge 4 commits into
masterfrom
fix/trezor-send-ui-polish
Open

fix: polish trezor send loading states#708
ben-kaufman wants to merge 4 commits into
masterfrom
fix/trezor-send-ui-polish

Conversation

@ben-kaufman

@ben-kaufmanben-kaufman commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Fixes#696

Description

This PR polishes the transient loading states in the Trezor send flow:

  • shows inline loading feedback while the selected hardware-wallet source refreshes or a transaction preview is prepared
  • prevents repeated source, Continue, fee, and swipe actions while their required hardware-wallet state is unavailable
  • keeps the previous fee visible while a replacement preview loads, with the spinner on the speed icon
  • separates a temporarily disabled swipe from the post-swipe submission spinner, matching the intended Figma behavior

This is stacked on #688. Review this PR against feat/trezor-send; it contains only the loading-state polish for that flow.

Linked Issues/Tasks

Screenshot / Video

Funding-source refreshContinue preparation
Trezor funding-source refreshContinue preparation loading
Confirm preview refreshSign With Device
Confirm preview loadingSign With Device
pr-708-trezor-send-polish.mov

QA Notes

Manual Tests

  • 1. Send → Amount → switch the funding source to Trezor: the source chip shows a blue spinner, and the source control and Continue cannot be triggered again until the available amount finishes refreshing.
  • 2. Send → Confirm → switch to Trezor or change the fee speed: the previous fee stays visible, the speed icon is replaced by its tinted spinner, and the confirmation swipe remains disabled until a valid preview is ready.
  • 3. Send → Confirm → swipe after the fee is ready: the knob reaches the right side and shows the submission spinner while the flow proceeds to Sign With Device.
  • 4.regression: switch back to Spending or Savings: the normal source, fee, Continue, and swipe behavior remains available.

Automated Checks

  • HwFundingSignerTests: 26 tests passed, including source-refresh, unavailable-fee, and preview-loading coverage.
  • SwiftFormat lint passed for the changed files.
  • git diff --check passed.

@greptile-apps

Copy link
Copy Markdown

Greptile Summary

This PR separates disabled and submitting states in the swipe control and adds explicit hardware-wallet funding-source and preview loading state across the send flow.

  • Adds tintable activity indicators and loading support to shared controls.
  • Tracks hardware funding-source and transaction-preview preparation in HwSendCoordinator.
  • Disables repeated source, fee, Continue, and swipe actions while required hardware state is unavailable.
  • Adds coordinator tests for source refresh and preview preparation.

Confidence Score: 4/5

The hardware-source loading failure path should be fixed before merging because a fee-estimation failure can trap the send screen with no usable source-selection or Continue action.

Hardware selection now starts an externally visible loading state that is cleared only after a refresh or preview, but the amount view can return before starting either operation when its fee rate is unavailable.

Files Needing Attention: Bitkit/Views/Wallets/Send/SendAmountView.swift; Bitkit/ViewModels/HwFundingSigner.swift

Important Files Changed

FilenameOverview
Bitkit/ViewModels/HwFundingSigner.swiftAdds request-scoped funding-source and preview loading flags, including stale-request invalidation and cancellation cleanup.
Bitkit/Views/Wallets/Send/SendAmountView.swiftConnects hardware loading to source and Continue controls, but can leave both unavailable when fee resolution fails before balance refresh.
Bitkit/Views/Wallets/Send/SendConfirmationView.swiftPresents hardware preview loading on the fee icon and disables source, fee, and swipe actions until preview readiness.
Bitkit/Components/SwipeButton.swiftSeparates temporarily disabled presentation from the post-swipe spinner while retaining unified interaction blocking.
BitkitTests/HwFundingSignerTests.swiftCovers successful funding-source refresh and preview-loading transitions but not unavailable fee-rate or refresh-failure recovery.

Sequence Diagram

sequenceDiagram
participant U as User
participant V as SendAmountView
participant C as HwSendCoordinator
participant F as Fee estimation
U->>V: Select Trezor
V->>C: selectWallet(showsLoading: true)
C-->>V: "isFundingSourceLoading = true"
V->>F: Resolve selected fee rate
alt Fee rate available
V->>C: refreshAvailable(...)
C-->>V: "Balance and loading=false"
else Fee estimation fails
V-->>V: Refresh guard returns
Note over V,C: Loading remains true and source control stays disabled
end
Loading

Reviews (1): Last reviewed commit: "fix: polish trezor send loading states" | Re-trigger Greptile

Comment threadBitkit/Views/Wallets/Send/SendAmountView.swift
@ovitrifovitrif linked an issue Aug 31, 2026 that may be closed by this pull request
Base automatically changed from feat/trezor-send to masterSeptember 1, 2026 08:43

@ovitrifovitrif 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.

Confirm still traps source, fee, and swipe after a missing fee rate, and the Amount → Confirm reload blanks the fee Amount just prepared.

  • Switching to Trezor on Confirm sets isFundingSourceLoading through selectWallet(..., showsLoading: true), then calculateTransactionFee() returns when selectedFeeRateSatsPerVByte is nil, so nothing settles the flag. Source, fee, and swipe stay disabled until the sheet is dismissed.
  • displayedTransactionFee only preserves a fee already stored in local transactionFee. Confirm's first preparePreview zeros previewFeeSats while transactionFee is still 0, so the fee from Amount disappears until the duplicate preview returns.
  • testCoordinatorTracksPreviewPreparation only covers a successful estimate. Nothing would fail if preparePreview's catch stopped clearing isPreviewLoading.

Comment threadBitkit/Views/Wallets/Send/SendConfirmationView.swift
Comment threadBitkit/Views/Wallets/Send/SendConfirmationView.swift
Comment threadBitkitTests/HwFundingSignerTests.swift
@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

All three Confirm loading and fee findings are fixed in signed commit bb94073 and the threads are resolved. HwFundingSignerTests passes 26 of 26. @ovitrif please re-review the updated head.

@ovitrif

Copy link
Copy Markdown
Collaborator

@ben-kaufman Can we please include media in PR description (screens / recs) 🙏🏻 ?
Thanks

@ben-kaufmanChatGPT Codex Connector

Copy link
Copy Markdown
ContributorAuthor

@ovitrif Added four screenshots and a recording to the PR description covering the funding-source refresh, Continue preparation, Confirm preview refresh, and transition to Sign With Device. Thanks!

@ovitrifovitrif 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.

QA Notes

iPhone 17 simulator, iOS 26.5, regtest.

  • Amount: switching the source to Trezor refreshed available funds; source and Continue were usable after settle.
  • Confirm: the previous fee stayed visible across Trezor and Savings switches; swipe proceeded once the preview was ready.
  • Swipe after the fee was ready reached Sign With Device.
  • Switching back to Savings restored source, fee, Continue, and swipe.

Approve.

@ovitrif

ovitrif commented Sep 1, 2026

Copy link
Copy Markdown
Collaborator

LGTM, tested all cases from QA notes.

Before merge we still need e2e green, maybe merge with master so it retriggers properly? cc. @ben-kaufman 🙏🏻

Meanwhile @piotr-iohk can have a look to confirm if the e2e failure would likely succeed next run:
https://github.com/synonymdev/bitkit-ios/actions/runs/33512189709/job/99876203530?pr=708

thanks 🙏🏻

@ovitrif
ovitrif enabled auto-merge September 1, 2026 14:49
Sign up for freeto 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.

Trezor send UI polish

2 participants

@ben-kaufman@ovitrif
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix: polish trezor send loading states - #708

Open
ben-kaufman wants to merge 4 commits into
masterfrom
fix/trezor-send-ui-polish
Open

fix: polish trezor send loading states#708
ben-kaufman wants to merge 4 commits into
masterfrom
fix/trezor-send-ui-polish

Conversation

@ben-kaufman

@ben-kaufmanben-kaufman commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Fixes#696

Description

This PR polishes the transient loading states in the Trezor send flow:

  • shows inline loading feedback while the selected hardware-wallet source refreshes or a transaction preview is prepared
  • prevents repeated source, Continue, fee, and swipe actions while their required hardware-wallet state is unavailable
  • keeps the previous fee visible while a replacement preview loads, with the spinner on the speed icon
  • separates a temporarily disabled swipe from the post-swipe submission spinner, matching the intended Figma behavior

This is stacked on #688. Review this PR against feat/trezor-send; it contains only the loading-state polish for that flow.

Linked Issues/Tasks

Screenshot / Video

Funding-source refreshContinue preparation
Trezor funding-source refreshContinue preparation loading
Confirm preview refreshSign With Device
Confirm preview loadingSign With Device
pr-708-trezor-send-polish.mov

QA Notes

Manual Tests

  • 1. Send → Amount → switch the funding source to Trezor: the source chip shows a blue spinner, and the source control and Continue cannot be triggered again until the available amount finishes refreshing.
  • 2. Send → Confirm → switch to Trezor or change the fee speed: the previous fee stays visible, the speed icon is replaced by its tinted spinner, and the confirmation swipe remains disabled until a valid preview is ready.
  • 3. Send → Confirm → swipe after the fee is ready: the knob reaches the right side and shows the submission spinner while the flow proceeds to Sign With Device.
  • 4.regression: switch back to Spending or Savings: the normal source, fee, Continue, and swipe behavior remains available.

Automated Checks

  • HwFundingSignerTests: 26 tests passed, including source-refresh, unavailable-fee, and preview-loading coverage.
  • SwiftFormat lint passed for the changed files.
  • git diff --check passed.

@greptile-apps

Copy link
Copy Markdown

Greptile Summary

This PR separates disabled and submitting states in the swipe control and adds explicit hardware-wallet funding-source and preview loading state across the send flow.

  • Adds tintable activity indicators and loading support to shared controls.
  • Tracks hardware funding-source and transaction-preview preparation in HwSendCoordinator.
  • Disables repeated source, fee, Continue, and swipe actions while required hardware state is unavailable.
  • Adds coordinator tests for source refresh and preview preparation.

Confidence Score: 4/5

The hardware-source loading failure path should be fixed before merging because a fee-estimation failure can trap the send screen with no usable source-selection or Continue action.

Hardware selection now starts an externally visible loading state that is cleared only after a refresh or preview, but the amount view can return before starting either operation when its fee rate is unavailable.

Files Needing Attention: Bitkit/Views/Wallets/Send/SendAmountView.swift; Bitkit/ViewModels/HwFundingSigner.swift

Important Files Changed

FilenameOverview
Bitkit/ViewModels/HwFundingSigner.swiftAdds request-scoped funding-source and preview loading flags, including stale-request invalidation and cancellation cleanup.
Bitkit/Views/Wallets/Send/SendAmountView.swiftConnects hardware loading to source and Continue controls, but can leave both unavailable when fee resolution fails before balance refresh.
Bitkit/Views/Wallets/Send/SendConfirmationView.swiftPresents hardware preview loading on the fee icon and disables source, fee, and swipe actions until preview readiness.
Bitkit/Components/SwipeButton.swiftSeparates temporarily disabled presentation from the post-swipe spinner while retaining unified interaction blocking.
BitkitTests/HwFundingSignerTests.swiftCovers successful funding-source refresh and preview-loading transitions but not unavailable fee-rate or refresh-failure recovery.

Sequence Diagram

sequenceDiagram
participant U as User
participant V as SendAmountView
participant C as HwSendCoordinator
participant F as Fee estimation
U->>V: Select Trezor
V->>C: selectWallet(showsLoading: true)
C-->>V: "isFundingSourceLoading = true"
V->>F: Resolve selected fee rate
alt Fee rate available
V->>C: refreshAvailable(...)
C-->>V: "Balance and loading=false"
else Fee estimation fails
V-->>V: Refresh guard returns
Note over V,C: Loading remains true and source control stays disabled
end
Loading

Reviews (1): Last reviewed commit: "fix: polish trezor send loading states" | Re-trigger Greptile

Comment threadBitkit/Views/Wallets/Send/SendAmountView.swift
@ovitrifovitrif linked an issue Aug 31, 2026 that may be closed by this pull request
Base automatically changed from feat/trezor-send to masterSeptember 1, 2026 08:43

@ovitrifovitrif 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.

Confirm still traps source, fee, and swipe after a missing fee rate, and the Amount → Confirm reload blanks the fee Amount just prepared.

  • Switching to Trezor on Confirm sets isFundingSourceLoading through selectWallet(..., showsLoading: true), then calculateTransactionFee() returns when selectedFeeRateSatsPerVByte is nil, so nothing settles the flag. Source, fee, and swipe stay disabled until the sheet is dismissed.
  • displayedTransactionFee only preserves a fee already stored in local transactionFee. Confirm's first preparePreview zeros previewFeeSats while transactionFee is still 0, so the fee from Amount disappears until the duplicate preview returns.
  • testCoordinatorTracksPreviewPreparation only covers a successful estimate. Nothing would fail if preparePreview's catch stopped clearing isPreviewLoading.

Comment threadBitkit/Views/Wallets/Send/SendConfirmationView.swift
Comment threadBitkit/Views/Wallets/Send/SendConfirmationView.swift
Comment threadBitkitTests/HwFundingSignerTests.swift
@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

All three Confirm loading and fee findings are fixed in signed commit bb94073 and the threads are resolved. HwFundingSignerTests passes 26 of 26. @ovitrif please re-review the updated head.

@ovitrif

Copy link
Copy Markdown
Collaborator

@ben-kaufman Can we please include media in PR description (screens / recs) 🙏🏻 ?
Thanks

@ben-kaufmanChatGPT Codex Connector

Copy link
Copy Markdown
ContributorAuthor

@ovitrif Added four screenshots and a recording to the PR description covering the funding-source refresh, Continue preparation, Confirm preview refresh, and transition to Sign With Device. Thanks!

@ovitrifovitrif 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.

QA Notes

iPhone 17 simulator, iOS 26.5, regtest.

  • Amount: switching the source to Trezor refreshed available funds; source and Continue were usable after settle.
  • Confirm: the previous fee stayed visible across Trezor and Savings switches; swipe proceeded once the preview was ready.
  • Swipe after the fee was ready reached Sign With Device.
  • Switching back to Savings restored source, fee, Continue, and swipe.

Approve.

@ovitrif

ovitrif commented Sep 1, 2026

Copy link
Copy Markdown
Collaborator

LGTM, tested all cases from QA notes.

Before merge we still need e2e green, maybe merge with master so it retriggers properly? cc. @ben-kaufman 🙏🏻

Meanwhile @piotr-iohk can have a look to confirm if the e2e failure would likely succeed next run:
https://github.com/synonymdev/bitkit-ios/actions/runs/33512189709/job/99876203530?pr=708

thanks 🙏🏻

@ovitrif
ovitrif enabled auto-merge September 1, 2026 14:49
Sign up for freeto 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.

Trezor send UI polish

2 participants

@ben-kaufman@ovitrif
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

fix: polish trezor send loading states - #708

Open
ben-kaufman wants to merge 4 commits into
masterfrom
fix/trezor-send-ui-polish
Open

fix: polish trezor send loading states#708
ben-kaufman wants to merge 4 commits into
masterfrom
fix/trezor-send-ui-polish

Conversation

@ben-kaufman

@ben-kaufmanben-kaufman commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Fixes#696

Description

This PR polishes the transient loading states in the Trezor send flow:

  • shows inline loading feedback while the selected hardware-wallet source refreshes or a transaction preview is prepared
  • prevents repeated source, Continue, fee, and swipe actions while their required hardware-wallet state is unavailable
  • keeps the previous fee visible while a replacement preview loads, with the spinner on the speed icon
  • separates a temporarily disabled swipe from the post-swipe submission spinner, matching the intended Figma behavior

This is stacked on #688. Review this PR against feat/trezor-send; it contains only the loading-state polish for that flow.

Linked Issues/Tasks

Screenshot / Video

Funding-source refreshContinue preparation
Trezor funding-source refreshContinue preparation loading
Confirm preview refreshSign With Device
Confirm preview loadingSign With Device
pr-708-trezor-send-polish.mov

QA Notes

Manual Tests

  • 1. Send → Amount → switch the funding source to Trezor: the source chip shows a blue spinner, and the source control and Continue cannot be triggered again until the available amount finishes refreshing.
  • 2. Send → Confirm → switch to Trezor or change the fee speed: the previous fee stays visible, the speed icon is replaced by its tinted spinner, and the confirmation swipe remains disabled until a valid preview is ready.
  • 3. Send → Confirm → swipe after the fee is ready: the knob reaches the right side and shows the submission spinner while the flow proceeds to Sign With Device.
  • 4.regression: switch back to Spending or Savings: the normal source, fee, Continue, and swipe behavior remains available.

Automated Checks

  • HwFundingSignerTests: 26 tests passed, including source-refresh, unavailable-fee, and preview-loading coverage.
  • SwiftFormat lint passed for the changed files.
  • git diff --check passed.

@greptile-apps

Copy link
Copy Markdown

Greptile Summary

This PR separates disabled and submitting states in the swipe control and adds explicit hardware-wallet funding-source and preview loading state across the send flow.

  • Adds tintable activity indicators and loading support to shared controls.
  • Tracks hardware funding-source and transaction-preview preparation in HwSendCoordinator.
  • Disables repeated source, fee, Continue, and swipe actions while required hardware state is unavailable.
  • Adds coordinator tests for source refresh and preview preparation.

Confidence Score: 4/5

The hardware-source loading failure path should be fixed before merging because a fee-estimation failure can trap the send screen with no usable source-selection or Continue action.

Hardware selection now starts an externally visible loading state that is cleared only after a refresh or preview, but the amount view can return before starting either operation when its fee rate is unavailable.

Files Needing Attention: Bitkit/Views/Wallets/Send/SendAmountView.swift; Bitkit/ViewModels/HwFundingSigner.swift

Important Files Changed

FilenameOverview
Bitkit/ViewModels/HwFundingSigner.swiftAdds request-scoped funding-source and preview loading flags, including stale-request invalidation and cancellation cleanup.
Bitkit/Views/Wallets/Send/SendAmountView.swiftConnects hardware loading to source and Continue controls, but can leave both unavailable when fee resolution fails before balance refresh.
Bitkit/Views/Wallets/Send/SendConfirmationView.swiftPresents hardware preview loading on the fee icon and disables source, fee, and swipe actions until preview readiness.
Bitkit/Components/SwipeButton.swiftSeparates temporarily disabled presentation from the post-swipe spinner while retaining unified interaction blocking.
BitkitTests/HwFundingSignerTests.swiftCovers successful funding-source refresh and preview-loading transitions but not unavailable fee-rate or refresh-failure recovery.

Sequence Diagram

sequenceDiagram
participant U as User
participant V as SendAmountView
participant C as HwSendCoordinator
participant F as Fee estimation
U->>V: Select Trezor
V->>C: selectWallet(showsLoading: true)
C-->>V: "isFundingSourceLoading = true"
V->>F: Resolve selected fee rate
alt Fee rate available
V->>C: refreshAvailable(...)
C-->>V: "Balance and loading=false"
else Fee estimation fails
V-->>V: Refresh guard returns
Note over V,C: Loading remains true and source control stays disabled
end
Loading

Reviews (1): Last reviewed commit: "fix: polish trezor send loading states" | Re-trigger Greptile

Comment threadBitkit/Views/Wallets/Send/SendAmountView.swift
@ovitrifovitrif linked an issue Aug 31, 2026 that may be closed by this pull request
Base automatically changed from feat/trezor-send to masterSeptember 1, 2026 08:43

@ovitrifovitrif 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.

Confirm still traps source, fee, and swipe after a missing fee rate, and the Amount → Confirm reload blanks the fee Amount just prepared.

  • Switching to Trezor on Confirm sets isFundingSourceLoading through selectWallet(..., showsLoading: true), then calculateTransactionFee() returns when selectedFeeRateSatsPerVByte is nil, so nothing settles the flag. Source, fee, and swipe stay disabled until the sheet is dismissed.
  • displayedTransactionFee only preserves a fee already stored in local transactionFee. Confirm's first preparePreview zeros previewFeeSats while transactionFee is still 0, so the fee from Amount disappears until the duplicate preview returns.
  • testCoordinatorTracksPreviewPreparation only covers a successful estimate. Nothing would fail if preparePreview's catch stopped clearing isPreviewLoading.

Comment threadBitkit/Views/Wallets/Send/SendConfirmationView.swift
Comment threadBitkit/Views/Wallets/Send/SendConfirmationView.swift
Comment threadBitkitTests/HwFundingSignerTests.swift
@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

All three Confirm loading and fee findings are fixed in signed commit bb94073 and the threads are resolved. HwFundingSignerTests passes 26 of 26. @ovitrif please re-review the updated head.

@ovitrif

Copy link
Copy Markdown
Collaborator

@ben-kaufman Can we please include media in PR description (screens / recs) 🙏🏻 ?
Thanks

@ben-kaufmanChatGPT Codex Connector

Copy link
Copy Markdown
ContributorAuthor

@ovitrif Added four screenshots and a recording to the PR description covering the funding-source refresh, Continue preparation, Confirm preview refresh, and transition to Sign With Device. Thanks!

@ovitrifovitrif 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.

QA Notes

iPhone 17 simulator, iOS 26.5, regtest.

  • Amount: switching the source to Trezor refreshed available funds; source and Continue were usable after settle.
  • Confirm: the previous fee stayed visible across Trezor and Savings switches; swipe proceeded once the preview was ready.
  • Swipe after the fee was ready reached Sign With Device.
  • Switching back to Savings restored source, fee, Continue, and swipe.

Approve.

@ovitrif

ovitrif commented Sep 1, 2026

Copy link
Copy Markdown
Collaborator

LGTM, tested all cases from QA notes.

Before merge we still need e2e green, maybe merge with master so it retriggers properly? cc. @ben-kaufman 🙏🏻

Meanwhile @piotr-iohk can have a look to confirm if the e2e failure would likely succeed next run:
https://github.com/synonymdev/bitkit-ios/actions/runs/33512189709/job/99876203530?pr=708

thanks 🙏🏻

@ovitrif
ovitrif enabled auto-merge September 1, 2026 14:49
Sign up for freeto 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.

Trezor send UI polish

2 participants

@ben-kaufman@ovitrif