Skip to content

Conversation

@bordalix
Copy link
Collaborator

@bordalix bordalix commented Nov 13, 2025

Summary by CodeRabbit

  • Chores

    • Dependency updated: @arkade-os/sdk → 0.3.6
  • New Features

    • Threshold-based timing for automatic coin renewal and settlement; threshold shown in seconds
    • Improved batch lifetime calculation for more accurate rollover scheduling
    • Background/indexer support added for resolving commitment timestamps
  • Style

    • Primary styling for main action buttons; increased list/item spacing
    • UI: expiring tags and clearer settlement/boarding UTXO indicators

@bordalix bordalix requested a review from Copilot November 13, 2025 17:45
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 13, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Adds thresholdMs-based VTXO settlement lifecycle: computes batch lifetime via an Indexer, threads thresholdMs through asp/vtxo/wallet flows and UI, updates provider state handling, adds Indexer, adjusts several function signatures, adds UI props, bumps @arkade-os/sdk, and applies mechanical renames in the service worker.

Changes

Cohort / File(s) Summary
Dependency update
package.json
Bumps @arkade-os/sdk from 0.3.50.3.6.
Service worker symbol renaming
public/wallet-service-worker.mjs
Widespread mechanical renaming of internal symbols and exported identifiers (many classes/functions renamed; references updated throughout).
Types
src/lib/types.ts
Added optional thresholdMs?: number to Wallet type.
ASP / settlement APIs
src/lib/asp.ts
Import ExtendedVirtualCoin; emptyFees uses BigInt(0); getInputsToSettle now accepts optional thresholdMs and returns { inputs, vtxos, boardingUtxos }; settleVtxos and renewCoins signatures accept thresholdMs.
Indexer
src/lib/indexer.ts
New Indexer class wiring RestIndexerProvider → IndexedDB contract repo; adds `getCommitmentTxCreatedAt(txid): Promise<number
VTXO logic
src/lib/vtxo.ts
Removed maxPercentage usage; getExpiringAndRecoverableVtxos(wallet, thresholdMs) now accepts thresholdMs and returns expiring + orphan vtxos; VtxoManager instantiation uses thresholdMs.
Wallet lifecycle & batch lifetime
src/lib/wallet.ts
calcNextRollover is now async and takes (vtxos, wallet, aspInfo); removed vtxosExpiringSoon; added calcBatchLifetimeMs(aspInfo, vtxos): Promise<number> which uses Indexer to compute batch lifetime.
Wallet provider & state
src/providers/wallet.tsx
Computes batchLifetimeMs and thresholdMs (from maxPercentage), calls calcNextRollover(vtxos, wallet, aspInfo), initializes thresholdMs in default wallet, passes thresholdMs to renewCoins and settleVtxos, and updates updateWallet to accept functional updates.
Settings VTXO UI
src/screens/Settings/Vtxos.tsx
Replaced expiryThreshold state with settle flags; imports isVtxoExpiringSoon; fetches inputs using wallet.thresholdMs; UI shows expiring tag; calls settleVtxos with thresholdMs.
Transaction screen
src/screens/Wallet/Transaction.tsx
Calls getInputsToSettle with wallet.thresholdMs; destructures inputs from returned object; added wallet.thresholdMs to effect deps.
UI primitives
src/components/Button.tsx, src/components/FlexRow.tsx
Added optional main?: boolean prop to Button and FlexRow; Button passes main to FlexRow; FlexRow applies minHeight: '20px' when main is true.
Wallet index UI
src/screens/Wallet/Index.tsx
Two Button usages updated to include main prop (Send/Receive) to enable primary styling.

Sequence Diagram(s)

sequenceDiagram
    participant WP as Wallet Provider / UI
    participant IDX as Indexer
    participant ASP as ASP API
    participant DB as IndexedDB
    participant SVC as Service Worker / Settlement

    WP->>WP: calcBatchLifetimeMs(aspInfo, vtxos)
    WP->>WP: pick sample vtxo (batchExpiry + commitmentTxId)
    WP->>IDX: getCommitmentTxCreatedAt(txid)
    IDX->>DB: query 'commitmentTxs' collection (by txid)
    alt cached
        DB-->>IDX: CommitmentTxRecord {when}
    else not cached
        IDX->>ASP: fetch commitmentTx(txid)
        ASP-->>IDX: commitmentTx (may include endedAt)
        IDX->>DB: save {txid, when}
        DB-->>IDX: saved
    end
    IDX-->>WP: when (batchStart)
    WP->>WP: batchLifetimeMs = batchExpiry - batchStart
    WP->>WP: thresholdMs = batchLifetimeMs * maxPercentage
    WP->>SVC: renewCoins(wallet, dust, thresholdMs)
    SVC->>SVC: getInputsToSettle(wallet, thresholdMs)
    SVC-->>SVC: returns { inputs, vtxos, boardingUtxos }
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Areas needing extra attention:

  • src/lib/wallet.ts — async calcNextRollover and calcBatchLifetimeMs, edge cases when commitmentTxId or endedAt missing.
  • src/lib/indexer.ts — IndexedDB persistence, cache keying, and ASP fallback correctness.
  • public/wallet-service-worker.mjs — large-scale mechanical renames; verify exported API names and external consumers.
  • src/providers/wallet.tsx & UI screens — ensure state/closure safety in async effects using wallet.thresholdMs and svcWallet.

Possibly related PRs

  • add backups to Nostr #209: Overlapping mechanical renaming in public/wallet-service-worker.mjs (same file symbol changes).
  • soft settle #171: Related changes to asp/vtxo/wallet function signatures and settlement flow (thresholdMs + return-shape changes).
  • fix button size #228: Related additions of main prop to Button/FlexRow and corresponding UI updates.

Suggested reviewers

  • louisinger
  • tiero

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The title 'Fix coin control' is vague and generic, using imprecise terminology that doesn't clearly convey the specific changes made in this comprehensive pull request. Consider a more specific title that highlights the main change, such as 'Add batch lifetime threshold calculation for VTXO settlement' or 'Implement dynamic thresholding for coin selection logic'.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix_coin_control

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7400b03 and 8478276.

📒 Files selected for processing (1)
  • src/screens/Settings/Vtxos.tsx (11 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-06-30T18:33:29.839Z
Learnt from: bordalix
Repo: arkade-os/wallet PR: 114
File: src/lib/asp.ts:0-0
Timestamp: 2025-06-30T18:33:29.839Z
Learning: In src/lib/asp.ts, only the collaborativeExit function should accept both IWallet and ServiceWorkerWallet types. Other wallet functions (getBalance, getTxHistory, getReceivingAddresses, redeemNotes, sendOnChain, settleVtxos) should maintain their original IWallet-only signatures and not be updated for consistency.

Applied to files:

  • src/screens/Settings/Vtxos.tsx
🧬 Code graph analysis (1)
src/screens/Settings/Vtxos.tsx (2)
src/lib/asp.ts (2)
  • getInputsToSettle (172-179)
  • settleVtxos (181-198)
src/lib/format.ts (1)
  • prettyDelta (36-55)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: test
🔇 Additional comments (11)
src/screens/Settings/Vtxos.tsx (11)

24-24: LGTM! New expiry utility imported correctly.

The isVtxoExpiringSoon import is properly used at line 215 to tag expiring VTXOs.


42-50: LGTM! New state variables support threshold-based flows.

The hideUtxos, hasVtxosToSettle, and hasBoardingUtxosToSettle states are properly integrated into the component logic.


59-70: LGTM! Label effect dependencies are now complete.

The dependency array correctly includes hideUtxos, which resolves the previous review concern.


84-97: LGTM! Fetch effect dependencies are now complete.

The dependency array correctly includes aspInfo, svcWallet, and wallet.thresholdMs, which resolves the previous review concern.


123-134: LGTM! Threshold correctly passed to settlement.

The settleVtxos call at line 126 properly includes wallet.thresholdMs, enabling threshold-based settlement.


141-141: LGTM! Padding adjustment improves layout.

Minor styling refinement.


172-176: LGTM! Expiring tag added.

The new tag properly signals urgency for VTXOs approaching expiration.


267-276: LGTM! Boarding UTXOs correctly hidden on success.

The conditional rendering at line 267 properly respects the hideUtxos state.


292-297: LGTM! Threshold messaging clearly explains auto-renewal.

The text correctly converts wallet.thresholdMs to seconds and uses prettyDelta for readable output.


317-319: LGTM! Button visibility correctly controlled.

The button properly hides when hideUtxos is true, matching the success flow.


215-219: Verify tag priority for settled VTXOs with upcoming batch expiry.

The code prioritizes the "expiring" tag over "settled", meaning a VTXO with virtualStatus.state === 'settled' will display "expiring soon" instead if it also matches isVtxoExpiringSoon(). While orphan detection in lib/vtxo.ts suggests settled VTXOs can have batch expiry, the tag priority is undocumented. Please confirm whether this precedence is intentional and whether "settled" VTXOs should warn about expiry, or if settled status should take priority to avoid masking the final state.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Nov 13, 2025

Deploying wallet-signet with  Cloudflare Pages  Cloudflare Pages

Latest commit: 8478276
Status: ✅  Deploy successful!
Preview URL: https://55e8bda6.wallet-23u.pages.dev
Branch Preview URL: https://fix-coin-control.wallet-23u.pages.dev

View logs

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Nov 13, 2025

Deploying wallet-mutinynet with  Cloudflare Pages  Cloudflare Pages

Latest commit: 8478276
Status: ✅  Deploy successful!
Preview URL: https://61e2fe3b.arkade-wallet.pages.dev
Branch Preview URL: https://fix-coin-control.arkade-wallet.pages.dev

View logs

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Nov 13, 2025

Deploying wallet-bitcoin with  Cloudflare Pages  Cloudflare Pages

Latest commit: 8478276
Status: ✅  Deploy successful!
Preview URL: https://7654886b.wallet-bitcoin.pages.dev
Branch Preview URL: https://fix-coin-control.wallet-bitcoin.pages.dev

View logs

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR fixes coin control functionality by introducing a threshold mechanism to determine which coins should be settled. The key changes involve calculating a thresholdMs value based on batch lifetime and using it to identify expiring VTXOs.

Key Changes

  • Added thresholdMs to the Wallet type and calculated it based on batch lifetime percentage
  • Updated getInputsToSettle to return separate arrays for vtxos, boarding UTXOs, and combined inputs
  • Modified calcNextRollover to handle cases when there are no VTXOs by falling back to boarding UTXOs
  • Added new Indexer class to fetch commitment transaction timestamps for batch lifetime calculations
  • Updated SDK from version 0.3.5 to 0.3.6

Reviewed Changes

Copilot reviewed 10 out of 11 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
src/lib/indexer.ts New indexer class for fetching commitment transaction data
src/lib/wallet.ts Updated rollover calculation logic and added batch lifetime calculation
src/lib/types.ts Added optional thresholdMs field to Wallet type
src/lib/vtxo.ts Updated to use thresholdMs parameter instead of percentage
src/lib/asp.ts Modified getInputsToSettle to return structured response with separate coin types
src/providers/wallet.tsx Added calculation of thresholdMs and integration with rollover logic
src/screens/Settings/Vtxos.tsx Enhanced UI to show different settlement actions and expiring coins
src/screens/Wallet/Transaction.tsx Updated to use new getInputsToSettle response structure
package.json Updated SDK dependency to 0.3.6
public/wallet-service-worker.mjs Minified service worker bundle with variable renaming
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
public/wallet-service-worker.mjs (1)

10020-10090: Don’t record a change VTXO when no change output exists.

Lp already subtracts the target amount and returns a positive changeAmount even when the change was sent via the sub‑dust branch (i.e., no corresponding output was actually added). The block starting at Line 10041 always persists a preconfirmed change VTXO whenever changeAmount > 0n, so if the change fell below the dust threshold and subdustPkScript was used, we end up tracking a virtual coin that does not exist on-chain. This desynchronises the wallet state from reality and can corrupt future settlements.

Guard the persistence block with a check that the “normal” change output was added (i.e., skip when the sub-dust branch was taken), or otherwise persist only when the output really exists. citeturn0file0

src/providers/wallet.tsx (1)

20-23: Restore the required thresholdMs default.

Wallet now exposes a thresholdMs field, yet defaultWallet omits it. With the current Wallet typing this fails to compile (Property 'thresholdMs' is missing…) and also leaves context consumers reading wallet.thresholdMs as undefined. Please seed the default with a numeric value (e.g., 0) so the app builds and downstream logic has a safe baseline.

Apply this diff:

 const defaultWallet: Wallet = {
   network: '',
   nextRollover: 0,
+  thresholdMs: 0,
 }
🧹 Nitpick comments (1)
src/lib/vtxo.ts (1)

22-23: Parallelize the independent awaits.

manager.getExpiringVtxos() and getOrphanVtxos(wallet) don’t depend on each other, so we can fetch them concurrently to trim the response time of this helper.

-  return [...(await manager.getExpiringVtxos()), ...(await getOrphanVtxos(wallet))]
+  const [expiring, orphan] = await Promise.all([
+    manager.getExpiringVtxos(),
+    getOrphanVtxos(wallet),
+  ])
+  return [...expiring, ...orphan]
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f5694a5 and 74aca89.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (10)
  • package.json (1 hunks)
  • public/wallet-service-worker.mjs (123 hunks)
  • src/lib/asp.ts (3 hunks)
  • src/lib/indexer.ts (1 hunks)
  • src/lib/types.ts (1 hunks)
  • src/lib/vtxo.ts (1 hunks)
  • src/lib/wallet.ts (2 hunks)
  • src/providers/wallet.tsx (4 hunks)
  • src/screens/Settings/Vtxos.tsx (10 hunks)
  • src/screens/Wallet/Transaction.tsx (1 hunks)
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2025-06-30T18:33:29.839Z
Learnt from: bordalix
Repo: arkade-os/wallet PR: 114
File: src/lib/asp.ts:0-0
Timestamp: 2025-06-30T18:33:29.839Z
Learning: In src/lib/asp.ts, only the collaborativeExit function should accept both IWallet and ServiceWorkerWallet types. Other wallet functions (getBalance, getTxHistory, getReceivingAddresses, redeemNotes, sendOnChain, settleVtxos) should maintain their original IWallet-only signatures and not be updated for consistency.

Applied to files:

  • src/screens/Wallet/Transaction.tsx
  • src/lib/types.ts
  • src/lib/vtxo.ts
  • src/lib/wallet.ts
  • src/screens/Settings/Vtxos.tsx
  • src/lib/asp.ts
  • public/wallet-service-worker.mjs
  • src/providers/wallet.tsx
📚 Learning: 2025-06-30T18:23:34.163Z
Learnt from: bordalix
Repo: arkade-os/wallet PR: 114
File: public/wallet-service-worker.mjs:6350-6353
Timestamp: 2025-06-30T18:23:34.163Z
Learning: Do not review `public/wallet-service-worker.mjs` as it is a built file generated by Vite.

Applied to files:

  • src/lib/vtxo.ts
  • public/wallet-service-worker.mjs
  • src/providers/wallet.tsx
📚 Learning: 2025-08-28T15:58:17.245Z
Learnt from: bordalix
Repo: arkade-os/wallet PR: 142
File: src/lib/bip21.ts:7-13
Timestamp: 2025-08-28T15:58:17.245Z
Learning: In src/lib/bip21.ts, the encodeBip21 function is used by the wallet which always has an arkAddress available to pass to the function, while decodeBip21 is used to parse received possible BIP21 URIs which may not contain arkAddress. This explains why arkAddress is required in encodeBip21 but optional in the Bip21Decoded interface.

Applied to files:

  • src/lib/asp.ts
🧬 Code graph analysis (6)
src/screens/Wallet/Transaction.tsx (1)
src/lib/asp.ts (1)
  • getInputsToSettle (172-179)
src/lib/wallet.ts (4)
src/lib/types.ts (1)
  • Vtxo (94-94)
src/providers/asp.tsx (1)
  • AspInfo (6-6)
src/lib/utxo.ts (1)
  • getConfirmedAndNotExpiredUtxos (11-15)
src/lib/indexer.ts (1)
  • Indexer (10-38)
src/lib/indexer.ts (1)
src/providers/asp.tsx (1)
  • AspInfo (6-6)
src/screens/Settings/Vtxos.tsx (2)
src/lib/asp.ts (2)
  • getInputsToSettle (172-179)
  • settleVtxos (181-198)
src/lib/format.ts (1)
  • prettyDelta (36-55)
src/lib/asp.ts (2)
src/lib/vtxo.ts (1)
  • getExpiringAndRecoverableVtxos (18-24)
src/lib/utxo.ts (1)
  • getConfirmedAndNotExpiredUtxos (11-15)
src/providers/wallet.tsx (3)
src/lib/wallet.ts (2)
  • calcBatchLifetimeMs (37-48)
  • calcNextRollover (21-35)
src/lib/constants.ts (1)
  • maxPercentage (9-9)
src/lib/asp.ts (2)
  • renewCoins (200-203)
  • settleVtxos (181-198)
🔇 Additional comments (1)
package.json (1)

8-8: Confirm @arkade-os/sdk 0.3.6 is published before merging.

I haven’t been able to confirm that 0.3.6 is available on the npm registry. If it’s not published yet, installs will fail as soon as this lands. Please double-check the registry status before merging.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

♻️ Duplicate comments (1)
src/lib/indexer.ts (1)

26-33: Persist the commitment start timestamp

Line 28 stores commitmentTx.endedAt, but wallet.ts reads this as the batch start. We already guard startedAt; saving the end time collapses the computed lifetime toward zero and breaks the new threshold logic.

-    if (!commitmentTx?.endedAt) return null
-    const when = Number(commitmentTx.endedAt)
+    if (!commitmentTx?.startedAt) return null
+    const when = Number(commitmentTx.startedAt)
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 74aca89 and 7400b03.

📒 Files selected for processing (6)
  • src/components/Button.tsx (3 hunks)
  • src/components/FlexRow.tsx (3 hunks)
  • src/lib/indexer.ts (1 hunks)
  • src/providers/wallet.tsx (5 hunks)
  • src/screens/Settings/Vtxos.tsx (11 hunks)
  • src/screens/Wallet/Index.tsx (1 hunks)
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2025-06-30T18:33:29.839Z
Learnt from: bordalix
Repo: arkade-os/wallet PR: 114
File: src/lib/asp.ts:0-0
Timestamp: 2025-06-30T18:33:29.839Z
Learning: In src/lib/asp.ts, only the collaborativeExit function should accept both IWallet and ServiceWorkerWallet types. Other wallet functions (getBalance, getTxHistory, getReceivingAddresses, redeemNotes, sendOnChain, settleVtxos) should maintain their original IWallet-only signatures and not be updated for consistency.

Applied to files:

  • src/lib/indexer.ts
  • src/providers/wallet.tsx
  • src/screens/Settings/Vtxos.tsx
📚 Learning: 2025-06-30T18:23:34.163Z
Learnt from: bordalix
Repo: arkade-os/wallet PR: 114
File: public/wallet-service-worker.mjs:6350-6353
Timestamp: 2025-06-30T18:23:34.163Z
Learning: Do not review `public/wallet-service-worker.mjs` as it is a built file generated by Vite.

Applied to files:

  • src/providers/wallet.tsx
📚 Learning: 2025-07-21T18:25:36.391Z
Learnt from: bordalix
Repo: arkade-os/wallet PR: 121
File: src/screens/Init/Restore.tsx:58-58
Timestamp: 2025-07-21T18:25:36.391Z
Learning: In src/screens/Init/Restore.tsx, the Input component for private key restoration intentionally omits the `value` prop to make it uncontrolled. This is a security feature to prevent the private key from being displayed if users navigate away and return to the screen, avoiding potential exposure of sensitive data in the UI.

Applied to files:

  • src/screens/Wallet/Index.tsx
🧬 Code graph analysis (5)
src/lib/indexer.ts (1)
src/providers/asp.tsx (1)
  • AspInfo (6-6)
src/components/Button.tsx (1)
src/components/FlexRow.tsx (1)
  • FlexRow (17-48)
src/providers/wallet.tsx (5)
src/lib/types.ts (1)
  • Wallet (96-103)
src/lib/wallet.ts (2)
  • calcBatchLifetimeMs (37-48)
  • calcNextRollover (21-35)
src/lib/constants.ts (1)
  • maxPercentage (9-9)
src/lib/asp.ts (2)
  • renewCoins (200-203)
  • settleVtxos (181-198)
src/lib/storage.ts (1)
  • saveWalletToStorage (31-33)
src/screens/Settings/Vtxos.tsx (2)
src/lib/asp.ts (2)
  • getInputsToSettle (172-179)
  • settleVtxos (181-198)
src/lib/format.ts (1)
  • prettyDelta (36-55)
src/screens/Wallet/Index.tsx (1)
src/components/Button.tsx (1)
  • Button (21-64)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: test

@bordalix bordalix merged commit 806b0bf into master Nov 14, 2025
6 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Nov 24, 2025
@bordalix bordalix deleted the fix_coin_control branch November 26, 2025 14:29
This was referenced Nov 27, 2025
This was referenced Dec 22, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants