diff --git a/src/components/post-feed/like-tip-modal.js b/src/components/post-feed/like-tip-modal.js index 4d0af8b..d6e4c5f 100644 --- a/src/components/post-feed/like-tip-modal.js +++ b/src/components/post-feed/like-tip-modal.js @@ -40,12 +40,32 @@ function LikeTipModal ({ show, post, wallet, profiles = {}, onHide, onSuccess }) setError('') setSubmitting(false) - const memoLike = new MemoLike({ wallet }) - const page = new LikeTipPage({ memoLike }) - const result = page.open(post.txid, post.addr) - if (!result.ok) { - setError(formatError(result)) + let cancelled = false + + const checkBalance = async () => { + try { + // Refresh the wallet's spendable UTXOs so the gating balance check is + // accurate against the live minimal-slp-wallet (which exposes + // wallet.utxos as a UtxoStore object, not an array). + if (typeof wallet.getUtxos === 'function') { + await wallet.getUtxos() + } + if (cancelled) return + + const memoLike = new MemoLike({ wallet }) + const page = new LikeTipPage({ memoLike }) + const result = page.open(post.txid, post.addr) + if (!result.ok) { + setError(formatError(result)) + } + } catch (err) { + if (!cancelled) setError(err.message) + } } + + checkBalance() + + return () => { cancelled = true } }, [show, post, wallet]) async function handleSubmit () { diff --git a/src/services/memo-like.js b/src/services/memo-like.js index 78bb5fd..038ccf2 100644 --- a/src/services/memo-like.js +++ b/src/services/memo-like.js @@ -98,7 +98,12 @@ class MemoLike extends MemoAction { // used by different wallet adapters. getSpendableSats () { if (!this.wallet) return 0 - const utxos = this.wallet.utxos || [] + // minimal-slp-wallet exposes wallet.utxos as a UtxoStore object whose + // spendable BCH outputs live under utxoStore.bchUtxos, while the test and + // acceptance wallets use a plain array. Accept both shapes. + const utxos = Array.isArray(this.wallet.utxos) + ? this.wallet.utxos + : (this.wallet.utxos?.utxoStore?.bchUtxos || []) return utxos.reduce((sum, u) => { const value = u.value ?? u.satoshis ?? u.amount ?? 0 return sum + value diff --git a/test/unit/memo-like.test.js b/test/unit/memo-like.test.js index a7c0c77..8030a0f 100644 --- a/test/unit/memo-like.test.js +++ b/test/unit/memo-like.test.js @@ -260,3 +260,27 @@ test('getSpendableSats returns 0 without a wallet or spendable values', () => { assert.equal(new MemoLike({ wallet: { utxos: undefined } }).getSpendableSats(), 0) assert.equal(new MemoLike({ wallet: { utxos: [{ txid: 'u1' }] } }).getSpendableSats(), 0) }) + +test('getSpendableSats reads spendable BCH outputs from the wallet UtxoStore object', () => { + // minimal-slp-wallet exposes wallet.utxos as a UtxoStore object whose + // spendable BCH outputs live under utxoStore.bchUtxos. + const utxoStore = { + utxoStore: { + bchUtxos: [ + { txid: 'u1', satoshis: 1500 }, + { txid: 'u2', value: 2000 }, + { txid: 'u3', satoshis: 2500 } + ], + slpUtxos: { type1: { tokens: [] }, nft: [] } + } + } + const wallet = fakeWallet({ utxos: utxoStore }) + + assert.equal(new MemoLike({ wallet }).getSpendableSats(), 6000) +}) + +test('getSpendableSats returns 0 for an empty UtxoStore object', () => { + const wallet = fakeWallet({ utxos: { utxoStore: { bchUtxos: [] } } }) + + assert.equal(new MemoLike({ wallet }).getSpendableSats(), 0) +})