diff --git a/package.json b/package.json index 9acf0aa..e875d5e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "minibits_wallet", - "version": "0.1.9-beta.35", + "version": "0.1.9-beta.36", "private": true, "scripts": { "android:clean": "cd android && ./gradlew clean", diff --git a/src/services/wallet/nwcTransferTask.ts b/src/services/wallet/nwcTransferTask.ts index 76b88fe..e4332d1 100644 --- a/src/services/wallet/nwcTransferTask.ts +++ b/src/services/wallet/nwcTransferTask.ts @@ -19,7 +19,8 @@ import { receiveSync } from './receiveTask' const { transactionsStore, mintsStore, - proofsStore, + proofsStore, + walletStore } = rootStoreInstance const NWC_TRANSFER = 'nwcTransferTask' @@ -205,55 +206,42 @@ export const nwcTransferTask = async function ( log.debug('[nwcTransfer] Invoice PAID', { transactionId - }) + }) + + proofsStore.removeProofs(proofsToMeltFrom as Proof[], true, false) // Save preimage asap if(meltQuote.payment_preimage) { transaction.setProof(meltQuote.payment_preimage) } - // If noting was returned, all reserves were spent on fees + // If nothing was returned, all reserves were spent on fees let totalFeePaid = proofsToMeltFromAmount - amountToTransfer - let lightningFeePaid = totalFeePaid - meltFeeReserve - - let returnedAmount = 0 + let lightningFeePaid = totalFeePaid - meltFeeReserve + let meltFeePaid = meltFeeReserve + let swapFeePaid = 0 + let returnedAmount if (tokenToReturn) { - // Save in case receive fails - const outputToken = CashuUtils.encodeToken(tokenToReturn) - transaction.setOutputToken(outputToken) + // Save returned token in case receive fails + const outputTokenBeforeSwap = CashuUtils.encodeToken(tokenToReturn) + transaction.setOutputToken(outputTokenBeforeSwap) - // Swap received feeSaved proofs as they were issued to the server wallet thus are not linked to wallet seed - const { - receivedProofs: returnedProofs - } = await receiveSync( + // Swap returned proofs as they were issued to the server wallet thus are not linked to the wallet seed + const receiveResult = await receiveSync( mintUrl, tokenToReturn, memo, transactionId ) - // Spend pending proofs that were used to settle the lightning invoice - proofsStore.removeProofs(proofsToMeltFrom as Proof[], true, false) - returnedAmount = CashuUtils.getProofsAmount(returnedProofs) - - const returnedTokenEntry: TokenEntryV3 = { - mint: mintUrl, - proofs: returnedProofs, - } - - const swappedOutputToken = CashuUtils.encodeToken({ - token: [returnedTokenEntry], - unit, - }) - - transaction.setOutputToken(swappedOutputToken) - - totalFeePaid = totalFeePaid - returnedAmount - lightningFeePaid = totalFeePaid - meltFeeReserve - } else { - // Spend pending proofs that were used to settle the lightning invoice - proofsStore.removeProofs(proofsToMeltFrom as Proof[], true, false) + swapFeePaid = receiveResult.swapFeePaid + totalFeePaid = totalFeePaid - receiveResult.receivedAmount + lightningFeePaid = totalFeePaid - meltFeeReserve - swapFeePaid + returnedAmount = receiveResult.receivedAmount + + // re-save with swapped token + transaction.setOutputToken(receiveResult.outputToken) } // Save final fee in db @@ -266,7 +254,9 @@ export const nwcTransferTask = async function ( status: TransactionStatus.COMPLETED, lightningFeeReserve: meltQuote.fee_reserve, lightningFeePaid, - meltFeePaid: totalFeePaid - lightningFeePaid, + meltFeePaid, + swapFeePaid, + returnedAmount, preimage: meltQuote.payment_preimage, createdAt: new Date(), }) @@ -285,7 +275,8 @@ export const nwcTransferTask = async function ( transaction, message: `Lightning invoice has been successfully paid and settled with your Minibits ecash. Fee has been ${formatCurrency(transaction.fee, getCurrency(unit).code)} ${getCurrency(unit).code}.`, lightningFeePaid, - meltFeePaid: totalFeePaid - lightningFeePaid, + meltFeePaid, + swapFeePaid, totalFeePaid, meltQuote, preimage: meltQuote.payment_preimage, diff --git a/src/services/wallet/receiveTask.ts b/src/services/wallet/receiveTask.ts index 30695cc..9a7676d 100644 --- a/src/services/wallet/receiveTask.ts +++ b/src/services/wallet/receiveTask.ts @@ -462,21 +462,43 @@ export const receiveSync = async function ( transactionId ) - const receivedResult = await walletStore.receive( - mintToReceive, - unit as MintUnit, - token, - swapFeeReserve, - { - preference: amountPreferences, - counter: lockedProofsCounter.inFlightFrom as number // MUST be counter value before increase - } - ) - - const receivedProofs = receivedResult.proofs - const swapFeePaid = receivedResult.swapFeePaid + let receivedResult = undefined - // log.trace('[receiveTask]', {receivedProofs}) + try { + receivedResult = await walletStore.receive( + mintToReceive, + unit as MintUnit, + token, + swapFeeReserve, + { + preference: amountPreferences, + counter: lockedProofsCounter.inFlightFrom as number // MUST be counter value before increase + } + ) + } catch (e: any) { + // ugly but should do the trick if previous nwcTransfer got interrupted + if(e.message.includes('outputs have already been signed before')) { + + log.error('[receiveSync] Increasing proofsCounter outdated values and repeating receiveSync.') + + lockedProofsCounter.increaseProofsCounter(10) + receivedResult = await walletStore.receive( + mintToReceive, + unit as MintUnit, + token, + swapFeeReserve, + { + preference: amountPreferences, + counter: lockedProofsCounter.inFlightFrom as number // MUST be counter value before increase + } + ) + } else { + throw e + } + } + + const receivedProofs = receivedResult!.proofs + const swapFeePaid = receivedResult!.swapFeePaid // If we've got valid response, decrease proofsCounter and let it be increased back in next step when adding proofs lockedProofsCounter.decreaseProofsCounter(countOfInFlightProofs) diff --git a/src/services/wallet/transferTask.ts b/src/services/wallet/transferTask.ts index d05168a..8659230 100644 --- a/src/services/wallet/transferTask.ts +++ b/src/services/wallet/transferTask.ts @@ -206,16 +206,17 @@ export const transferTask = async function ( transactionId }) + // Spend pending proofs that were used to settle the lightning invoice + proofsStore.removeProofs(proofsToMeltFrom as Proof[], true, false) + // Save preimage asap if(preimage) { transaction.setProof(preimage) } - - // Spend pending proofs that were used to settle the lightning invoice - proofsStore.removeProofs(proofsToMeltFrom as Proof[], true, false) let totalFeePaid = proofsToMeltFromAmount - amountToTransfer let lightningFeePaid = totalFeePaid - meltFeeReserve + let meltFeePaid = meltFeeReserve let returnedAmount = CashuUtils.getProofsAmount(returnedProofs) if(returnedProofs.length > 0) { @@ -242,10 +243,7 @@ export const transferTask = async function ( transaction.setOutputToken(outputToken) totalFeePaid = totalFeePaid - returnedAmount - lightningFeePaid = totalFeePaid - meltFeeReserve - } else { - // Spend pending proofs that were used to settle the lightning invoice - proofsStore.removeProofs(proofsToMeltFrom as Proof[], true, false) + lightningFeePaid = totalFeePaid - meltFeeReserve } // release lock @@ -260,7 +258,7 @@ export const transferTask = async function ( transactionData.push({ status: TransactionStatus.COMPLETED, lightningFeePaid, - meltFeePaid: totalFeePaid - lightningFeePaid, + meltFeePaid, returnedAmount, preimage, counter: lockedProofsCounter.counter, @@ -281,7 +279,7 @@ export const transferTask = async function ( transaction, message: `Lightning invoice has been successfully paid and settled with your Minibits ecash. Fee has been ${formatCurrency(transaction.fee, getCurrency(unit).code)} ${getCurrency(unit).code}.`, lightningFeePaid, - meltFeePaid: totalFeePaid - lightningFeePaid, + meltFeePaid, totalFeePaid, meltQuote, preimage,