blob: 3f2a70ac530bc6bf0c1067d3768f8356f284b990 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
const number = (value: unknown) => {
const parsed = Number(value);
return Number.isFinite(parsed) ? parsed : 0;
};
export const debitTotal = ({
amount,
tip = 0,
fee = 0,
ourfee = 0,
}: {
amount: unknown;
tip?: unknown;
fee?: unknown;
ourfee?: unknown;
}) => number(amount) + number(tip) + number(fee) + number(ourfee);
// Enforce a caller-specific spending allowance at debit's final choke point,
// after mutable invoice metadata (notably an internal invoice tip) and fees have
// been captured. Checking earlier lets a recipient mutate the tip between the
// NWC budget check and the ledger debit.
export const assertWithinSpendLimit = ({
amount,
tip = 0,
fee = 0,
ourfee = 0,
maxTotal,
}: {
amount: unknown;
tip?: unknown;
fee?: unknown;
ourfee?: unknown;
maxTotal?: number;
}) => {
const total = debitTotal({ amount, tip, fee, ourfee });
if (maxTotal !== undefined && total > maxTotal)
throw new Error(`Budget exceeded: ${total} of ${maxTotal} remaining`);
return total;
};
|