Type cashu-ts Amount correctly

This commit is contained in:
minibits-cash
2026-09-29 09:36:00 +02:00
parent 718029a6e5
commit a9f4a6e7a4
11 changed files with 28 additions and 16 deletions
+2 -1
View File
@@ -5,6 +5,7 @@ import {
flow,
isAlive,
} from 'mobx-state-tree'
import { Amount } from '@cashu/cashu-ts'
import { withSetPropAction } from './helpers/withSetPropAction'
import { ProofModel, Proof, ProofRecord, ProofState } from './Proof'
import { TransactionData, TransactionStatus } from './Transaction'
@@ -588,7 +589,7 @@ import {
} else {
const node = ProofModel.create({
...proof,
amount: Number(proof.amount),
amount: Amount.from(proof.amount as any).toNumber(),
mintUrl: commitMintUrl,
tId: group.tId,
unit: reservation.unit,
+2 -2
View File
@@ -596,7 +596,7 @@ export const NfcPayScreen = observer(function NfcPayScreen({ route }: Props) {
log.trace('[handlePaymentRequest] decoded Cashu payment request', { pr })
// Validate basics
if (!pr.amount || Number(pr.amount) <= 0) {
if (!pr.amount || pr.amount.toNumber() <= 0) {
throw new AppError(Err.VALIDATION_ERROR, 'Payment request has no valid amount')
}
@@ -616,7 +616,7 @@ export const NfcPayScreen = observer(function NfcPayScreen({ route }: Props) {
// setEncodedCashuPaymentRequest(encoded)
if (pr.description) setMemo(pr.description)
const requiredAmount = Number(pr.amount)
const requiredAmount = pr.amount.toNumber()
const eligibleBalances = await getEligibleMintBalancesForCashu(pr, requiredAmount, unit)
if (eligibleBalances.length === 0) {
+1 -1
View File
@@ -625,7 +625,7 @@ export const SendScreen = observer(function SendScreen({ route }: Props) {
setIsCashuPrWithDesc(true)
}
const prAmount = pr.amount ? Number(pr.amount) : undefined
const prAmount = pr.amount ? pr.amount.toNumber() : undefined
if (prAmount) {
setAmountToSend(`${numbro(prAmount / getCurrency(unitRef.current).precision).format({
+11 -1
View File
@@ -38,11 +38,20 @@ const isObj = function(v: unknown): v is object {
return typeof v === 'object'
}
/**
* An amount as a number. cashu-ts (4.x) types proof, token and payment-request
* amounts as `Amount` objects, while our own models hold plain numbers; `Number()`
* on an `Amount` is deprecated and throws in cashu-ts v5.
*/
const toNumberAmount = function(amount: number | Amount | bigint | string): number {
return typeof amount === 'number' ? amount : Amount.from(amount).toNumber()
}
/**
* Sum the amounts of an array of proofs
*/
const sumProofs = function(proofs: CashuProof[]): number {
return proofs.reduce((acc: number, proof: CashuProof) => acc + Number(proof.amount), 0)
return proofs.reduce((acc: number, proof: CashuProof) => acc + toNumberAmount(proof.amount as any), 0)
}
const CASHU_URI_PREFIXES = [
@@ -839,6 +848,7 @@ export const CashuUtils = {
extractEncodedCashuPaymentRequest,
getProofsAmount,
getMintsFromToken,
toNumberAmount,
findExactMatch,
findMinExcess,
getProofsToSend,
+2 -1
View File
@@ -1,4 +1,5 @@
import {isAlive} from 'mobx-state-tree'
import {Amount} from '@cashu/cashu-ts'
import {Proof, ProofState} from '../../models/Proof'
import {CashuProof} from '../cashu/cashuUtils'
import {TransactionStatus} from '../../models/Transaction'
@@ -225,7 +226,7 @@ export const commitReservation = function (
// binding can't bind non-primitive objects to an INTEGER column and
// would silently drop the row, leaving the proof in MST but absent
// from the database (lost on the next restart).
const amount = typeof proof.amount === 'number' ? proof.amount : Number(proof.amount)
const amount = typeof proof.amount === 'number' ? proof.amount : Amount.from(proof.amount as any).toNumber()
batch.push([
`INSERT OR REPLACE INTO proofs (id, amount, secret, C, dleq_r, dleq_s, dleq_e, unit, tId, mintUrl, state, updatedAt)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
@@ -381,7 +381,7 @@ async function finalize(
transactionId,
)
const receivedAmount = receivedProofs.reduce((acc, p) => acc + Number(p.amount), 0)
const receivedAmount = CashuUtils.getProofsAmount(receivedProofs)
const outputToken = getEncodedToken({
mint: mintUrl,
proofs: normalizeProofAmounts(receivedProofs),
@@ -140,7 +140,7 @@ const handleClaimTask = async function (params: {
const result: TransactionTaskResult = await receiveTask(
decodedToken,
Number(tokenInfo.amount),
tokenInfo.amount.toNumber(),
tokenInfo.memo || 'Received to Lightning address',
encodedToken,
)
@@ -402,7 +402,7 @@ const handleReceivedEventTask = async function (encryptedEvent: NostrEvent): Pro
if (incoming.type === IncomingDataType.CASHU) {
const tokenInfo = getTokenMetadata(incoming.encoded)
const amountToReceive = Number(tokenInfo.amount)
const amountToReceive = tokenInfo.amount.toNumber()
const memo = tokenInfo.memo || 'Received over Nostr'
const {unit, mint: mintUrl} = tokenInfo
@@ -70,7 +70,7 @@ import {
NUT20_RECOVERY_GAP_LIMIT,
} from '../../cashu/nut20'
import {capMintAmount, mintableAmount} from './onchainAmounts'
import {CashuProof} from '../../cashu/cashuUtils'
import {CashuProof, CashuUtils} from '../../cashu/cashuUtils'
import {MintUnit} from '../currency'
import {WalletUtils} from '../utils'
import {sendTopupNotification} from '../notifications'
@@ -548,7 +548,7 @@ async function _mintAvailable(
})
}
const mintedAmount = proofs.reduce((acc, p) => acc + Number(p.amount), 0)
const mintedAmount = CashuUtils.getProofsAmount(proofs)
const currentSpendable = proofsStore.getUnitBalance(unit)?.unitBalance ?? 0
const balanceAfter = currentSpendable + mintedAmount
@@ -318,7 +318,7 @@ async function execute(prepared: PreparedReceiveData): Promise<CompletedTransact
tx.id,
)
const receivedAmount = proofs.reduce((acc, p) => acc + Number(p.amount), 0)
const receivedAmount = CashuUtils.getProofsAmount(proofs)
const outputToken = getEncodedToken({
mint: prepared.mintUrl,
proofs: normalizeProofAmounts(proofs),
@@ -56,7 +56,7 @@ import {
isPrepared,
isReverted,
} from '../../../models/TransactionStates'
import {CashuProof} from '../../cashu/cashuUtils'
import {CashuProof, CashuUtils} from '../../cashu/cashuUtils'
import {LightningUtils} from '../../lightning/lightningUtils'
import {MintUnit, formatCurrency, getCurrency} from '../currency'
import {NostrEvent} from '../../nostrService'
@@ -533,7 +533,7 @@ async function _finalizePaid(tx: Transaction): Promise<CompletedTransaction> {
})
const currentSpendable = proofsStore.getUnitBalance(unit)?.unitBalance ?? 0
const proofsAmount = proofs.reduce((acc, p) => acc + Number(p.amount), 0)
const proofsAmount = CashuUtils.getProofsAmount(proofs)
const balanceAfter = currentSpendable + proofsAmount
const txData = _parseData(tx)
+2 -2
View File
@@ -10,7 +10,7 @@ import { TransactionTaskResult } from '../walletService'
import { ProofReservation } from './proofReservation'
import { WalletUtils } from './utils'
import { MintUnit } from './currency'
import { Token, getEncodedToken, normalizeProofAmounts } from '@cashu/cashu-ts'
import { Token, getEncodedToken, normalizeProofAmounts, sumProofs } from '@cashu/cashu-ts'
const {
mintsStore,
@@ -99,7 +99,7 @@ try {
// simulated: the original pending proofs were PENDING (contribute 0 to
// UNSPENT pool); moving them to SPENT changes nothing. The new fresh
// proofs added as UNSPENT raise the spendable balance.
const receivedAmount = receivedProofs.reduce((sum, p) => sum + Number(p.amount), 0)
const receivedAmount = sumProofs(receivedProofs).toNumber()
const currentSpendable = proofsStore.getUnitBalance(unit)?.unitBalance ?? 0
const balanceAfter = currentSpendable + receivedAmount