diff --git a/docs/SECURITY_AUDIT.md b/docs/SECURITY_AUDIT.md index 1eecfe5..885bb00 100644 --- a/docs/SECURITY_AUDIT.md +++ b/docs/SECURITY_AUDIT.md @@ -70,18 +70,18 @@ version with `pnpm.overrides` (see `package.json`). Except where noted, every override stays within a range the consumer already declares, so runtime behaviour is preserved: -| Override (package selector) | Forced to | Reported advisory | -| --------------------------------------------- | --------- | ---------------------------------------------------- | -| `axios` | `1.20.0` | Multiple GHSA advisories on the 1.x line. | -| `form-data` | `4.0.6` | GHSA-hmw2-7cc7-3qxx. | -| `follow-redirects` | `1.16.1` | GHSA-q3jh-wrc6-jgq8, GHSA-8r9p-f939-6h3c. | -| `hono` | `4.13.13` | Multiple GHSA advisories on the 4.x line. | -| `socket.io-parser` | `4.2.7` | GHSA-2m8v-j782-fhvr. | -| `browserslist` | `4.29.3` | GHSA-c83g-rgw3-j3cx, GHSA-73wf-gq98-2v4g. | -| `metro>image-size` | `2.0.4` | GHSA-5p2g-fcmc-qvqq, GHSA-w3rx-r6r6-pgpr. | -| `shell-quote` | `1.12.0` | GHSA-pqg4-j6r4-53mv (critical), GHSA-395f-4hp3-45gv. | -| `@stellar/stellar-sdk>toml` | `4.2.0` | GHSA-82x6-q7mm-w9cf, GHSA-v5mp-jgw5-2x6j. | -| `engine.io-client>ws`, `ethers>ws`, `viem>ws` | `8.22.0` | GHSA-96hv-2xvq-fx4p, GHSA-58qx-3vcg-4xpx. | +| Override (package selector) | Forced to | Reported advisory | +| --------------------------------------------- | --------- | -------------------------------------------------------------------------------------------------------- | +| `axios` | `1.20.0` | Multiple GHSA advisories on the 1.x line. | +| `form-data` | `4.0.6` | GHSA-hmw2-7cc7-3qxx. | +| `follow-redirects` | `1.16.1` | GHSA-q3jh-wrc6-jgq8, GHSA-8r9p-f939-6h3c. | +| `hono` | `4.13.13` | Multiple GHSA advisories on the 4.x line. | +| `socket.io-parser` | `4.2.7` | GHSA-2m8v-j782-fhvr. | +| `browserslist` | `4.29.3` | GHSA-c83g-rgw3-j3cx, GHSA-73wf-gq98-2v4g. | +| `metro>image-size` | `2.0.4` | GHSA-5p2g-fcmc-qvqq, GHSA-w3rx-r6r6-pgpr. | +| `shell-quote` | `1.12.0` | GHSA-pqg4-j6r4-53mv (critical), GHSA-395f-4hp3-45gv. | +| `@stellar/stellar-sdk>toml` | `5.0.1` | GHSA-82x6-q7mm-w9cf, GHSA-v5mp-jgw5-2x6j, GHSA-4qx8-w7c3-pj3p, GHSA-9j65-hcg3-gc64, GHSA-9qmh-m7c6-f92p. | +| `engine.io-client>ws`, `ethers>ws`, `viem>ws` | `8.22.0` | GHSA-96hv-2xvq-fx4p, GHSA-58qx-3vcg-4xpx. | Overrides that cross a declared major range are scoped to the single path that needs them with pnpm's `parent>child` syntax, so they cannot silently change a diff --git a/package.json b/package.json index da14e89..64fc9c9 100644 --- a/package.json +++ b/package.json @@ -129,7 +129,7 @@ "metro>image-size": "2.0.4", "shell-quote": "1.12.0", "socket.io-parser": "4.2.7", - "@stellar/stellar-sdk>toml": "4.2.0", + "@stellar/stellar-sdk>toml": "5.0.1", "engine.io-client>ws": "8.22.0", "ethers>ws": "8.22.0", "viem>ws": "8.22.0" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d6d6e95..8291c8b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -13,7 +13,7 @@ overrides: metro>image-size: 2.0.4 shell-quote: 1.12.0 socket.io-parser: 4.2.7 - '@stellar/stellar-sdk>toml': 4.2.0 + '@stellar/stellar-sdk>toml': 5.0.1 engine.io-client>ws: 8.22.0 ethers>ws: 8.22.0 viem>ws: 8.22.0 @@ -7296,8 +7296,8 @@ packages: resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} engines: {node: '>=0.6'} - toml@4.2.0: - resolution: {integrity: sha512-TvAJjbHZlYmI323+srtqHQFyJsoWy6mI09ppkuj9+iRsqsVKG9fvTcOP7FHF2UCb0QSYtjEavffrKzdd0XgClg==} + toml@5.0.1: + resolution: {integrity: sha512-EqYNA/YvUNndrA2B3O2ojzLQoTQrBxeZ9UIjQwk8t10oe6n7dwclBwd9IdZQTOKwe6vWX+AXtl6IntXRbepdxQ==} engines: {node: '>=20'} tough-cookie@6.0.2: @@ -11553,7 +11553,7 @@ snapshots: eventsource: 2.0.2 feaxios: 0.0.23 randombytes: 2.1.0 - toml: 4.2.0 + toml: 5.0.1 urijs: 1.19.11 transitivePeerDependencies: - bare-url @@ -17549,7 +17549,7 @@ snapshots: toidentifier@1.0.1: {} - toml@4.2.0: {} + toml@5.0.1: {} tough-cookie@6.0.2: dependencies: diff --git a/scripts/dependency-compatibility.test.mjs b/scripts/dependency-compatibility.test.mjs index 3603081..932f6fc 100644 --- a/scripts/dependency-compatibility.test.mjs +++ b/scripts/dependency-compatibility.test.mjs @@ -121,8 +121,8 @@ describe('toml override compatibility', () => { it('keeps stellar-sdk on a patched toml that preserves its parse contract', () => { const sdk = requireFrom('@stellar/stellar-sdk'); const version = installedVersion(sdk, 'toml'); - expect(version).toMatch(/^4\./); - expect(versionAtLeast(version, '4.2.0')).toBe(true); + expect(version).toMatch(/^5\./); + expect(versionAtLeast(version, '5.0.1')).toBe(true); const toml = sdk('toml'); // StellarToml.Resolver runs `toml.parse(response.data)` and returns the diff --git a/src/pages/Activity.tsx b/src/pages/Activity.tsx index f0fd7b8..362ed1e 100644 --- a/src/pages/Activity.tsx +++ b/src/pages/Activity.tsx @@ -62,7 +62,7 @@ export default function Activity() { + + +
+
+
+ + +
+ +
+ + +
+ +
+ + +
+ + + {filteredEntries.length} {filteredEntries.length === 1 ? 'entry' : 'entries'} + +
+ +
+
+ Export CSV + + +

+ Exports include only the entries matching the current filters. Private key and memo + material is never included. +

+
+ + + {walletEntries.length === 0 && ( + + + + + + + + + } + title="No activity recorded yet." + description="Send or receive a stealth payment to see your history here." + primaryCTA={{ label: 'Send your first payment', onClick: () => navigate('/send') }} + /> + )} + + {walletEntries.length > 0 && filteredEntries.length === 0 && ( + + )} + +
+ {filteredEntries.map((entry: ActivityEntry) => ( + + ))} +
+ ); } diff --git a/src/stores/activityStore.ts b/src/stores/activityStore.ts index 5d972dc..1f45fd8 100644 --- a/src/stores/activityStore.ts +++ b/src/stores/activityStore.ts @@ -30,6 +30,7 @@ interface ActivityState { addEntry: (entry: ActivityEntry) => void; updateStatus: (id: string, status: ActivityStatus) => void; clearHistory: (chain: string, wallet: string) => void; + clearAll: () => void; pollPending: () => Promise; } @@ -49,9 +50,15 @@ export const useActivityStore = create()( entries: state.entries.map((e) => (e.id === id ? { ...e, status } : e)), })), clearHistory: (chain, wallet) => - set((state) => ({ - entries: state.entries.filter((e) => !(e.chain === chain && e.wallet === wallet)), - })), + set((state) => { + if (!wallet) return state; + return { + entries: state.entries.filter( + (e) => !(e.wallet === wallet && (chain === 'all' || !chain || e.chain === chain)), + ), + }; + }), + clearAll: () => set({ entries: [] }), pollPending: async () => { const { entries, updateStatus } = get(); const pendingTxs = entries.filter((e) => e.status === 'pending' && e.chain === 'stellar');