applesauce-wallet 0.0.0-next-20250313135311 → 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.
@@ -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 throw if tokens are locked", async () => {
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(a, HiddenContentSymbol);
55
- expect(() => dumbTokenSelection([a], 20)).toThrow();
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>;
@@ -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
- await unlockHiddenTags(history, signer);
38
+ if (isHiddenContentLocked(history))
39
+ await unlockHiddenTags(history, signer);
37
40
  return getHistoryContent(history);
38
41
  }
@@ -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[];
@@ -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
- if (tokens.some((t) => isTokenContentLocked(t)))
47
- throw new Error("All tokens must be unlocked");
48
- const total = tokens.reduce((t, token) => t + getTokenProofsTotal(token), 0);
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) {
@@ -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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "applesauce-wallet",
3
- "version": "0.0.0-next-20250313135311",
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-20250313135311",
84
- "applesauce-core": "0.0.0-next-20250313135311",
85
- "applesauce-factory": "0.0.0-next-20250313135311",
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-20250313135311",
93
+ "applesauce-signers": "0.0.0-next-20250313145241",
94
94
  "typescript": "^5.7.3",
95
95
  "vitest": "^3.0.5"
96
96
  },