applesauce-wallet 0.0.0-next-20250313125308 → 0.0.0-next-20250313145241
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/actions/tokens.d.ts +1 -1
- package/dist/actions/tokens.js +2 -2
- package/dist/helpers/__tests__/tokens.test.js +11 -4
- package/dist/helpers/history.d.ts +1 -1
- package/dist/helpers/history.js +5 -2
- package/dist/helpers/tokens.d.ts +3 -3
- package/dist/helpers/tokens.js +11 -7
- package/dist/queries/history.js +1 -1
- package/dist/queries/tokens.js +1 -1
- package/package.json +5 -5
package/dist/actions/tokens.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { NostrEvent } from "nostr-tools";
|
|
|
6
6
|
* @param token the cashu token to add
|
|
7
7
|
* @param redeemed an array of nutzap event ids to mark as redeemed
|
|
8
8
|
*/
|
|
9
|
-
export declare function ReceiveToken(token: Token, redeemed?: string[]): Action;
|
|
9
|
+
export declare function ReceiveToken(token: Token, redeemed?: string[], fee?: number): Action;
|
|
10
10
|
/** An action that deletes old tokens and creates a new one but does not add a history event */
|
|
11
11
|
export declare function RolloverTokens(tokens: NostrEvent[], token: Token): Action;
|
|
12
12
|
/** An action that deletes old token events and adds a spend history item */
|
package/dist/actions/tokens.js
CHANGED
|
@@ -7,11 +7,11 @@ import { WalletHistoryBlueprint } from "../blueprints/history.js";
|
|
|
7
7
|
* @param token the cashu token to add
|
|
8
8
|
* @param redeemed an array of nutzap event ids to mark as redeemed
|
|
9
9
|
*/
|
|
10
|
-
export function ReceiveToken(token, redeemed) {
|
|
10
|
+
export function ReceiveToken(token, redeemed, fee) {
|
|
11
11
|
return async ({ factory, publish }) => {
|
|
12
12
|
const amount = token.proofs.reduce((t, p) => t + p.amount, 0);
|
|
13
13
|
const tokenEvent = await factory.sign(await factory.create(WalletTokenBlueprint, token, []));
|
|
14
|
-
const history = await factory.sign(await factory.create(WalletHistoryBlueprint, { direction: "in", amount, mint: token.mint, created: [tokenEvent.id] }, redeemed ?? []));
|
|
14
|
+
const history = await factory.sign(await factory.create(WalletHistoryBlueprint, { direction: "in", amount, mint: token.mint, created: [tokenEvent.id], fee }, redeemed ?? []));
|
|
15
15
|
await publish("Save tokens", tokenEvent);
|
|
16
16
|
await publish("Save transaction", history);
|
|
17
17
|
};
|
|
@@ -22,7 +22,7 @@ describe("dumbTokenSelection", () => {
|
|
|
22
22
|
await unlockTokenContent(b, user);
|
|
23
23
|
expect(dumbTokenSelection([a, b], 40)).toEqual([b]);
|
|
24
24
|
});
|
|
25
|
-
it("should enough tokens to total min amount", async () => {
|
|
25
|
+
it("should select enough tokens to total min amount", async () => {
|
|
26
26
|
const a = await user.signEvent(await factory.create(WalletTokenBlueprint, {
|
|
27
27
|
mint: "https://money.com",
|
|
28
28
|
proofs: [{ secret: "A", C: "A", id: "A", amount: 100 }],
|
|
@@ -45,13 +45,20 @@ describe("dumbTokenSelection", () => {
|
|
|
45
45
|
await unlockTokenContent(a, user);
|
|
46
46
|
expect(() => dumbTokenSelection([a], 120)).toThrow();
|
|
47
47
|
});
|
|
48
|
-
it("should
|
|
48
|
+
it("should ignore locked tokens", async () => {
|
|
49
49
|
const a = await user.signEvent(await factory.create(WalletTokenBlueprint, {
|
|
50
50
|
mint: "https://money.com",
|
|
51
51
|
proofs: [{ secret: "A", C: "A", id: "A", amount: 100 }],
|
|
52
52
|
}));
|
|
53
|
+
await unlockTokenContent(a, user);
|
|
54
|
+
const bDraft = await factory.create(WalletTokenBlueprint, {
|
|
55
|
+
mint: "https://money.com",
|
|
56
|
+
proofs: [{ secret: "B", C: "B", id: "B", amount: 50 }],
|
|
57
|
+
});
|
|
58
|
+
bDraft.created_at -= 60 * 60 * 7;
|
|
59
|
+
const b = await user.signEvent(bDraft);
|
|
53
60
|
// manually remove the hidden content to lock it again
|
|
54
|
-
Reflect.deleteProperty(
|
|
55
|
-
expect(
|
|
61
|
+
Reflect.deleteProperty(b, HiddenContentSymbol);
|
|
62
|
+
expect(dumbTokenSelection([a, b], 20)).toEqual([a]);
|
|
56
63
|
});
|
|
57
64
|
});
|
|
@@ -20,6 +20,6 @@ export declare function getHistoryRedeemed(history: NostrEvent): string[];
|
|
|
20
20
|
/** Checks if the history contents are locked */
|
|
21
21
|
export declare function isHistoryContentLocked(history: NostrEvent): boolean;
|
|
22
22
|
/** Returns the parsed content of a 7376 history event */
|
|
23
|
-
export declare function getHistoryContent(history: NostrEvent): HistoryContent;
|
|
23
|
+
export declare function getHistoryContent(history: NostrEvent): HistoryContent | undefined;
|
|
24
24
|
/** Decrypts a wallet history event */
|
|
25
25
|
export declare function unlockHistoryContent(history: NostrEvent, signer: HiddenContentSigner): Promise<HistoryContent>;
|
package/dist/helpers/history.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getHiddenTags, getOrComputeCachedValue, isETag, isHiddenTagsLocked, unlockHiddenTags, } from "applesauce-core/helpers";
|
|
1
|
+
import { getHiddenTags, getOrComputeCachedValue, isETag, isHiddenContentLocked, isHiddenTagsLocked, unlockHiddenTags, } from "applesauce-core/helpers";
|
|
2
2
|
export const WALLET_HISTORY_KIND = 7376;
|
|
3
3
|
export const HistoryContentSymbol = Symbol.for("history-content");
|
|
4
4
|
/** returns an array of redeemed event ids in a history event */
|
|
@@ -11,6 +11,8 @@ export function isHistoryContentLocked(history) {
|
|
|
11
11
|
}
|
|
12
12
|
/** Returns the parsed content of a 7376 history event */
|
|
13
13
|
export function getHistoryContent(history) {
|
|
14
|
+
if (isHistoryContentLocked(history))
|
|
15
|
+
return undefined;
|
|
14
16
|
return getOrComputeCachedValue(history, HistoryContentSymbol, () => {
|
|
15
17
|
const tags = getHiddenTags(history);
|
|
16
18
|
if (!tags)
|
|
@@ -33,6 +35,7 @@ export function getHistoryContent(history) {
|
|
|
33
35
|
}
|
|
34
36
|
/** Decrypts a wallet history event */
|
|
35
37
|
export async function unlockHistoryContent(history, signer) {
|
|
36
|
-
|
|
38
|
+
if (isHiddenContentLocked(history))
|
|
39
|
+
await unlockHiddenTags(history, signer);
|
|
37
40
|
return getHistoryContent(history);
|
|
38
41
|
}
|
package/dist/helpers/tokens.d.ts
CHANGED
|
@@ -22,15 +22,15 @@ export declare const TokenProofsTotalSymbol: unique symbol;
|
|
|
22
22
|
* Returns the decrypted and parsed details of a 7375 token event
|
|
23
23
|
* @throws
|
|
24
24
|
*/
|
|
25
|
-
export declare function getTokenContent(token: NostrEvent): TokenContent;
|
|
25
|
+
export declare function getTokenContent(token: NostrEvent): TokenContent | undefined;
|
|
26
26
|
/** Returns if token details are locked */
|
|
27
27
|
export declare function isTokenContentLocked(token: NostrEvent): boolean;
|
|
28
28
|
/** Decrypts a k:7375 token event */
|
|
29
29
|
export declare function unlockTokenContent(token: NostrEvent, signer: HiddenContentSigner): Promise<TokenContent>;
|
|
30
30
|
/** Gets the totaled amount of proofs in a token event */
|
|
31
|
-
export declare function getTokenProofsTotal(token: NostrEvent): number;
|
|
31
|
+
export declare function getTokenProofsTotal(token: NostrEvent): number | undefined;
|
|
32
32
|
/**
|
|
33
33
|
* Selects oldest tokens that total up to more than the min amount
|
|
34
34
|
* @throws
|
|
35
35
|
*/
|
|
36
|
-
export declare function dumbTokenSelection(tokens: NostrEvent[], minAmount: number): import("nostr-tools").Event[];
|
|
36
|
+
export declare function dumbTokenSelection(tokens: NostrEvent[], minAmount: number, mint?: string): import("nostr-tools").Event[];
|
package/dist/helpers/tokens.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getHiddenContent, getOrComputeCachedValue, isHiddenContentLocked, unlockHiddenContent, } from "applesauce-core/helpers";
|
|
1
|
+
import { getHiddenContent, getOrComputeCachedValue, isHiddenContentLocked, isHiddenTagsLocked, unlockHiddenContent, } from "applesauce-core/helpers";
|
|
2
2
|
export const WALLET_TOKEN_KIND = 7375;
|
|
3
3
|
export const TokenContentSymbol = Symbol.for("token-content");
|
|
4
4
|
export const TokenProofsTotalSymbol = Symbol.for("token-proofs-total");
|
|
@@ -7,6 +7,8 @@ export const TokenProofsTotalSymbol = Symbol.for("token-proofs-total");
|
|
|
7
7
|
* @throws
|
|
8
8
|
*/
|
|
9
9
|
export function getTokenContent(token) {
|
|
10
|
+
if (isHiddenTagsLocked(token))
|
|
11
|
+
return undefined;
|
|
10
12
|
return getOrComputeCachedValue(token, TokenContentSymbol, () => {
|
|
11
13
|
const plaintext = getHiddenContent(token);
|
|
12
14
|
if (!plaintext)
|
|
@@ -33,6 +35,8 @@ export async function unlockTokenContent(token, signer) {
|
|
|
33
35
|
}
|
|
34
36
|
/** Gets the totaled amount of proofs in a token event */
|
|
35
37
|
export function getTokenProofsTotal(token) {
|
|
38
|
+
if (isTokenContentLocked(token))
|
|
39
|
+
return undefined;
|
|
36
40
|
return getOrComputeCachedValue(token, TokenProofsTotalSymbol, () => {
|
|
37
41
|
const content = getTokenContent(token);
|
|
38
42
|
return content.proofs.reduce((t, p) => t + p.amount, 0);
|
|
@@ -42,14 +46,14 @@ export function getTokenProofsTotal(token) {
|
|
|
42
46
|
* Selects oldest tokens that total up to more than the min amount
|
|
43
47
|
* @throws
|
|
44
48
|
*/
|
|
45
|
-
export function dumbTokenSelection(tokens, minAmount) {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
+
export function dumbTokenSelection(tokens, minAmount, mint) {
|
|
50
|
+
// sort newest to oldest
|
|
51
|
+
const sorted = tokens
|
|
52
|
+
.filter((token) => !isTokenContentLocked(token) && (mint ? getTokenContent(token).mint === mint : true))
|
|
53
|
+
.sort((a, b) => b.created_at - a.created_at);
|
|
54
|
+
const total = sorted.reduce((t, token) => t + getTokenProofsTotal(token), 0);
|
|
49
55
|
if (total < minAmount)
|
|
50
56
|
throw new Error("Insufficient funds");
|
|
51
|
-
// sort newest to oldest
|
|
52
|
-
const sorted = Array.from(tokens).sort((a, b) => b.created_at - a.created_at);
|
|
53
57
|
let amount = 0;
|
|
54
58
|
const selected = [];
|
|
55
59
|
while (amount < minAmount) {
|
package/dist/queries/history.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { getHistoryRedeemed, isHistoryContentLocked, WALLET_HISTORY_KIND } from "../helpers/history.js";
|
|
2
1
|
import { combineLatest, filter, map, scan, startWith } from "rxjs";
|
|
2
|
+
import { getHistoryRedeemed, isHistoryContentLocked, WALLET_HISTORY_KIND } from "../helpers/history.js";
|
|
3
3
|
/** Query that returns an array of redeemed event ids for a wallet */
|
|
4
4
|
export function WalletRedeemedQuery(pubkey) {
|
|
5
5
|
return {
|
package/dist/queries/tokens.js
CHANGED
|
@@ -46,7 +46,7 @@ export function WalletBalanceQuery(pubkey) {
|
|
|
46
46
|
run: (events) => {
|
|
47
47
|
const updates = events.updates.pipe(filter((e) => e.kind === WALLET_TOKEN_KIND && e.pubkey === pubkey), startWith(undefined));
|
|
48
48
|
const timeline = events.timeline({ kinds: [WALLET_TOKEN_KIND], authors: [pubkey] });
|
|
49
|
-
return combineLatest([updates, timeline]).pipe(map(([_, tokens]) => tokens),
|
|
49
|
+
return combineLatest([updates, timeline]).pipe(map(([_, tokens]) => tokens.filter((t) => !isTokenContentLocked(t))),
|
|
50
50
|
// filter out deleted tokens
|
|
51
51
|
map(filterDeleted),
|
|
52
52
|
// map tokens to totals
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "applesauce-wallet",
|
|
3
|
-
"version": "0.0.0-next-
|
|
3
|
+
"version": "0.0.0-next-20250313145241",
|
|
4
4
|
"description": "",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -80,9 +80,9 @@
|
|
|
80
80
|
"@cashu/cashu-ts": "2.0.0-rc1",
|
|
81
81
|
"@gandlaf21/bc-ur": "^1.1.12",
|
|
82
82
|
"@noble/hashes": "^1.7.1",
|
|
83
|
-
"applesauce-actions": "0.0.0-next-
|
|
84
|
-
"applesauce-core": "0.0.0-next-
|
|
85
|
-
"applesauce-factory": "0.0.0-next-
|
|
83
|
+
"applesauce-actions": "0.0.0-next-20250313145241",
|
|
84
|
+
"applesauce-core": "0.0.0-next-20250313145241",
|
|
85
|
+
"applesauce-factory": "0.0.0-next-20250313145241",
|
|
86
86
|
"buffer": "^6.0.3",
|
|
87
87
|
"nostr-tools": "^2.10.4",
|
|
88
88
|
"rxjs": "^7.8.1"
|
|
@@ -90,7 +90,7 @@
|
|
|
90
90
|
"devDependencies": {
|
|
91
91
|
"@hirez_io/observer-spy": "^2.2.0",
|
|
92
92
|
"@types/debug": "^4.1.12",
|
|
93
|
-
"applesauce-signers": "0.0.0-next-
|
|
93
|
+
"applesauce-signers": "0.0.0-next-20250313145241",
|
|
94
94
|
"typescript": "^5.7.3",
|
|
95
95
|
"vitest": "^3.0.5"
|
|
96
96
|
},
|