mirror of
https://github.com/minibits-cash/minibits_wallet.git
synced 2026-10-05 11:18:24 +00:00
137 lines
3.9 KiB
TypeScript
137 lines
3.9 KiB
TypeScript
import {log} from '../logService'
|
|
import {
|
|
Transaction,
|
|
TransactionData,
|
|
TransactionStatus,
|
|
} from '../../models/Transaction'
|
|
import {rootStoreInstance} from '../../models'
|
|
import AppError, {Err} from '../../utils/AppError'
|
|
import { TransactionTaskResult } from '../walletService'
|
|
import { WalletUtils } from './utils'
|
|
import { MintUnit } from './currency'
|
|
import { Token, getEncodedToken, normalizeProofAmounts } from '@cashu/cashu-ts'
|
|
|
|
const {
|
|
mintsStore,
|
|
proofsStore,
|
|
walletStore
|
|
} = rootStoreInstance
|
|
|
|
export const REVERT_TASK = 'revertTask'
|
|
|
|
export const revertTask = async function (
|
|
transaction: Transaction
|
|
): Promise<TransactionTaskResult> {
|
|
|
|
|
|
let transactionData = [] as unknown as TransactionData
|
|
|
|
try {
|
|
transactionData = JSON.parse(transaction.data)
|
|
} catch (e) {}
|
|
|
|
const unit = transaction.unit as MintUnit
|
|
|
|
try {
|
|
|
|
const allProofs = proofsStore.getByTransactionId(transaction.id)
|
|
const pendingProofs = allProofs.filter(p => p.isPending === true)
|
|
|
|
if(pendingProofs.length === 0) {
|
|
throw new AppError(Err.VALIDATION_ERROR, 'Missing proofs to swap')
|
|
}
|
|
|
|
const mintInstance = mintsStore.findByUrl(transaction.mint)
|
|
|
|
if(!mintInstance) {
|
|
throw new AppError(Err.VALIDATION_ERROR, 'Missing mint')
|
|
}
|
|
|
|
// We will swap pending proofs with the mint for fresh ones that we receive to the wallet.
|
|
// This will invalidate originally sent proofs effectively reverting the transaction.
|
|
const encodedToken: Token = {
|
|
mint: mintInstance.mintUrl,
|
|
proofs: normalizeProofAmounts(pendingProofs),
|
|
unit
|
|
}
|
|
|
|
const receivedResult = await walletStore.receive(
|
|
transaction.mint,
|
|
unit as MintUnit,
|
|
encodedToken,
|
|
transaction.id
|
|
)
|
|
|
|
const receivedProofs = receivedResult.proofs
|
|
const mintFeePaid = receivedResult.swapFeePaid
|
|
|
|
// store freshed proofs as encoded token in tx data
|
|
const outputToken = getEncodedToken({
|
|
mint: mintInstance.mintUrl,
|
|
proofs: normalizeProofAmounts(receivedProofs),
|
|
unit
|
|
})
|
|
|
|
// Remove original pending proofs
|
|
proofsStore.moveToSpent(pendingProofs)
|
|
|
|
// add fresh proofs to spendable wallet
|
|
const { updatedAmount: receivedAmount } = proofsStore.addOrUpdate(receivedProofs, {
|
|
mintUrl: mintInstance.mintUrl,
|
|
unit,
|
|
tId: transaction.id,
|
|
isPending: false,
|
|
isSpent: false
|
|
})
|
|
|
|
// Update transaction status
|
|
transactionData.push({
|
|
status: TransactionStatus.REVERTED,
|
|
mintFeePaid,
|
|
createdAt: new Date(),
|
|
})
|
|
|
|
const balanceAfter = proofsStore.getUnitBalance(unit)?.unitBalance
|
|
|
|
transaction.update({
|
|
status: TransactionStatus.REVERTED,
|
|
data: JSON.stringify(transactionData),
|
|
outputToken,
|
|
balanceAfter,
|
|
...(mintFeePaid > 0 && {fee: mintFeePaid})
|
|
})
|
|
|
|
return {
|
|
taskFunction: REVERT_TASK,
|
|
mintUrl: mintInstance.mintUrl,
|
|
transaction,
|
|
message: `Transaction has been reverted and funds were returned to spendable balance.`,
|
|
receivedAmount,
|
|
} as TransactionTaskResult
|
|
|
|
} catch (e: any) {
|
|
if (transaction) {
|
|
transactionData.push({
|
|
status: TransactionStatus.ERROR,
|
|
error: WalletUtils.formatError(e),
|
|
errorToken: e.params?.errorToken || undefined
|
|
})
|
|
|
|
transaction.update({
|
|
status: TransactionStatus.ERROR,
|
|
data: JSON.stringify(transactionData)
|
|
})
|
|
}
|
|
|
|
log.error(e.name, e.message)
|
|
|
|
return {
|
|
taskFunction: REVERT_TASK,
|
|
mintUrl: transaction.mint,
|
|
transaction,
|
|
message: e.message,
|
|
error: WalletUtils.formatError(e),
|
|
} as TransactionTaskResult
|
|
}
|
|
}
|