Skip to content

fix(api): fallback 409 for duplicate anchor (Closes #557)#5

Open
devUnixx wants to merge 269 commits into
mainfrom
fix/duplicate-anchor-fallback-557
Open

fix(api): fallback 409 for duplicate anchor (Closes #557)#5
devUnixx wants to merge 269 commits into
mainfrom
fix/duplicate-anchor-fallback-557

Conversation

@devUnixx

Copy link
Copy Markdown
Owner

Add API fallback handling to return 409 when the anchor insert indicates a duplicate/AlreadyAnchored condition.\n\nThis change detects duplicate DB insert/anchor errors and returns a 409 with the existing reading id.\n\nCloses AnnabelJoe#557

Gina-georgina and others added 30 commits May 30, 2026 13:07
…tion

Add pagination and filtering to certificates
## [1.10.0](AnnabelJoe/solarproof@v1.9.0...v1.10.0) (2026-05-30)

### Features

* add pagination and filtering to certificates [AnnabelJoe#258](AnnabelJoe#258) ([4d2bde0](AnnabelJoe@4d2bde0))
…boundaries

Implement error boundary components
## [1.11.0](AnnabelJoe/solarproof@v1.10.0...v1.11.0) (2026-05-30)

### Features

* implement global and section error boundaries [AnnabelJoe#256](AnnabelJoe#256) ([cc85f83](AnnabelJoe@cc85f83))
## [1.12.0](AnnabelJoe/solarproof@v1.11.0...v1.12.0) (2026-05-30)

### Features

* add dark mode toggle to settings and enhance theme support [AnnabelJoe#253](AnnabelJoe#253) ([249dd4f](AnnabelJoe@249dd4f))
…imiting

Implement rate limiting on /api/readings
## [1.13.0](AnnabelJoe/solarproof@v1.12.0...v1.13.0) (2026-05-30)

### Features

* implement rate limiting on /api/readings [AnnabelJoe#266](AnnabelJoe#266) ([b9e0b98](AnnabelJoe@b9e0b98))
…tion-279

feat: implement certificate retirement in energy_token (AnnabelJoe#279)
## [1.14.0](AnnabelJoe/solarproof@v1.13.0...v1.14.0) (2026-05-30)

### Features

* **contracts:** optimize Soroban storage for audit-registry ([4def0e7](AnnabelJoe@4def0e7)), closes [AnnabelJoe#281](AnnabelJoe#281)

### Documentation

* **docs:** write governance parameter tuning guide ([cd9a68c](AnnabelJoe@cd9a68c)), closes [AnnabelJoe#279](AnnabelJoe#279)
…roban-storage-281-final

feat: optimize Soroban contract storage (AnnabelJoe#281)
## [1.15.0](AnnabelJoe/solarproof@v1.14.0...v1.15.0) (2026-05-30)

### Features

* **contracts:** optimize Soroban storage for audit-registry ([f9055f7](AnnabelJoe@f9055f7)), closes [AnnabelJoe#281](AnnabelJoe#281)
…audit-293

Add dependency vulnerability scanning to CI pipeline
Standardize CHANGELOG.md and update PR template
…tests

test: add snapshot tests for React components and fix Navbar
…nnabelJoe#284)

- Tests for propose_upgrade restricted to admin
- Tests for 48-hour timelock enforcement
- Tests for upgrade announcement (event emitted)
- Tests for cancellation by admin within window
- Tests for full upgrade flow and edge cases

Closes AnnabelJoe#284
…nnabelJoe#260)

- WebSocket connection established on dashboard load
- Chart updates automatically when new meter readings arrive
- Graceful fallback to polling (30s interval) if WebSocket unavailable
- Connection status indicator: Live / Polling / Offline / Connecting

Closes AnnabelJoe#260
AnnabelJoe#319)

- energy_token: enhanced balance() and total_supply() with examples
- audit_registry: enhanced anchor(), verify(), api_signer(), admin() with
  full Arguments/Errors/Example sections
- community_governance: enhanced set_quorum_bps, get_quorum_bps,
  set_threshold_bps, get_threshold_bps, pending_upgrade,
  get_execution_timelock, proposal_count with Panics/Arguments/Examples

All public functions now have /// doc comments with Panics, Arguments,
Authorization, and example invocations where applicable.

Closes AnnabelJoe#319
devnWisdom and others added 24 commits June 25, 2026 11:36
Adds fuzz_governance fuzz target covering the full proposal lifecycle:
propose → vote → finalize → execute.

Verifies:
- proposal IDs are always positive
- vote counts match the approval pattern
- finalize() always produces a terminal status
- execute() succeeds after Passed + timelock

Closes AnnabelJoe#558
)

Adds verify_integration_test module with 9 integration tests covering:
- verify() returns None for unanchored hashes
- verify() returns correct reading_hash and anchored_at_ledger
- ledger sequence is recorded at anchor time, not query time
- verify() is idempotent across multiple calls
- two distinct hashes have independent anchors
- duplicate anchor rejection does not overwrite original anchor
- boundary values (all-zeros, all-ones)

Closes AnnabelJoe#563
…lJoe#552)

The persistent entry value for each anchor previously stored a full
AuditAnchor struct { reading_hash: BytesN<32>, anchored_at_ledger: u32 }
(36 bytes). Because reading_hash is already encoded in the storage key
(DataKey::Anchor(hash)), it was pure duplication.

Change: store only the u32 ledger sequence as the entry value.
verify() reconstructs the AuditAnchor on read at no extra I/O cost.

Result: 36 B → 4 B per persistent entry value — 88% reduction.
This directly lowers the Soroban write_bytes fee for every anchor() call.

All existing tests remain green; no public API changes.

Closes AnnabelJoe#552
…oe#559)

Adds overflow_tests module with 16 tests covering every i128
arithmetic path in energy_token:

Overflow paths:
- mint() overflows recipient balance (balance + amount > i128::MAX)
- mint() overflows total_minted counter
- transfer() overflows recipient balance
- transfer_from() overflows recipient balance

Underflow / insufficient-funds paths:
- burn() amount > balance
- burn() on zero balance
- burn_from() amount > balance
- burn_from() amount > allowance
- transfer() amount > sender balance

Positive-only / non-negative guards:
- mint(0), mint(-1) rejected
- burn(0) rejected
- transfer(0) rejected
- approve(-1) rejected

Closes AnnabelJoe#559
…-tests-559

test(energy_token): add overflow/underflow test coverage for token arithmetic
…r-storage-552

perf(audit_registry): optimize anchor payload storage and gas
…-verify-test-563

test(audit_registry): add integration tests for verify()
…e-lifecycle-558

feat(fuzz): add governance lifecycle fuzz target
## [1.17.0](AnnabelJoe/solarproof@v1.16.0...v1.17.0) (2026-06-25)

### Features

* **fuzz:** add governance lifecycle fuzz target ([AnnabelJoe#558](AnnabelJoe#558)) ([f1b1301](AnnabelJoe@f1b1301))

### Performance

* **audit_registry:** store only ledger seq in anchor entries ([AnnabelJoe#552](AnnabelJoe#552)) ([62eaf70](AnnabelJoe@62eaf70))

### Documentation

* add color contrast audit plan ([AnnabelJoe#533](AnnabelJoe#533)) ([f18bff1](AnnabelJoe@f18bff1))
* add secrets & key rotation procedures ([AnnabelJoe#527](AnnabelJoe#527)) ([ba94678](AnnabelJoe@ba94678))
* **audits:** remove stale placeholders from audit README ([f940140](AnnabelJoe@f940140))
…rement-612

docs(backlog): certificate retirement reporting backlog (Closes AnnabelJoe#612)
…#528)

- Add checkRateLimit / getClientIp helpers in lib/rate-limit.ts
- Apply 10 req/60s limit to POST /api/readings
- Apply 30 req/60s limit to GET /api/verify
- Return 429 with Retry-After + X-RateLimit-* headers on breach
- Document abuse protection rules in docs/ABUSE_PROTECTION.md

Closes AnnabelJoe#528
…oe#588)

Covers WCAG 2.1 AA requirements, keyboard navigation, screen reader
support, form labelling, colour contrast, and the string-externalisation
workflow for localization.

Closes AnnabelJoe#588
STRIDE threat model covering API, smart contracts, key management, and
public verifier. Lists 10 open items that must be resolved before
mainnet launch, with priority and owner columns.

Closes AnnabelJoe#601
docs: add production threat model review before mainnet launch
…guide

docs: add accessibility and localization contribution guide
…ection

feat(security): add IP rate limiting for public endpoints
## [1.18.0](AnnabelJoe/solarproof@v1.17.0...v1.18.0) (2026-06-25)

### Features

* **security:** add IP rate limiting for public endpoints ([AnnabelJoe#528](AnnabelJoe#528)) ([bce053a](AnnabelJoe@bce053a))

### Documentation

* add accessibility and localization contribution guide ([AnnabelJoe#588](AnnabelJoe#588)) ([df82209](AnnabelJoe@df82209))
* add production threat model review ([AnnabelJoe#601](AnnabelJoe#601)) ([c2ba58e](AnnabelJoe@c2ba58e))
* **backlog:** add certificate retirement reporting backlog\n\nCloses [AnnabelJoe#612](AnnabelJoe#612) ([8dcad69](AnnabelJoe@8dcad69))
…ability-555

docs(adr): contract upgradeability and migration plan (Closes AnnabelJoe#555)
## [1.18.1](AnnabelJoe/solarproof@v1.18.0...v1.18.1) (2026-06-25)

### Bug Fixes

* **a11y:** improve toast ARIA semantics and dismiss labels\n\nCloses [AnnabelJoe#537](AnnabelJoe#537) ([ff8701d](AnnabelJoe@ff8701d))

### Documentation

* **adr:** add contract upgradeability/migration ADR\n\nCloses [AnnabelJoe#555](AnnabelJoe#555) ([2e9b4dd](AnnabelJoe@2e9b4dd))
@github-actions

Copy link
Copy Markdown

❌ pnpm audit

┌─────────────────────┬────────────────────────────────────────────────────────┐
│ critical            │ When Vitest UI server is listening, arbitrary file can │
│                     │ be read and executed                                   │
├─────────────────────┼────────────────────────────────────────────────────────┤
│ Package             │ vitest                                                 │
├─────────────────────┼────────────────────────────────────────────────────────┤
│ Vulnerable versions │ <3.2.6                                                 │
├─────────────────────┼────────────────────────────────────────────────────────┤
│ Patched versions    │ >=3.2.6                                                │
├─────────────────────┼────────────────────────────────────────────────────────┤
│ Paths               │ apps/web > @vitest/coverage-v8@2.1.9 > vitest@2.1.9    │
│                     │                                                        │
│                     │ apps/web > vitest@2.1.9                                │
│                     │                                                        │
│                     │ packages/stellar > vitest@2.1.9                        │
├─────────────────────┼────────────────────────────────────────────────────────┤
│ More info           │ https://github.com/advisories/GHSA-5xrq-8626-4rwp      │
└─────────────────────┴────────────────────────────────────────────────────────┘
┌─────────────────────┬────────────────────────────────────────────────────────┐
│ high                │ ws: Memory exhaustion DoS from tiny fragments and data │
│                     │ chunks                                                 │
├─────────────────────┼────────────────────────────────────────────────────────┤
│ Package             │ ws                                                     │
├─────────────────────┼────────────────────────────────────────────────────────┤
│ Vulnerable versions │ >=8.0.0 <8.21.0                                        │
├─────────────────────┼────────────────────────────────────────────────────────┤
│ Patched versions    │ >=8.21.0                                               │
├─────────────────────┼────────────────────────────────────────────────────────┤
│ Paths               │ apps/web > @vitest/coverage-v8@2.1.9 > vitest@2.1.9 >  │
│                     │ jsdom@25.0.1 > ws@8.20.1                               │
│                     │                                                        │
│                     │ apps/web > jsdom@25.0.1 > ws@8.20.1                    │
│                     │                                                        │
│                     │ apps/web > vitest@2.1.9 > jsdom@25.0.1 > ws@8.20.1     │
│                     │                                                        │
│                     │ ... Found 4 paths, run `pnpm why ws` for more          │
│                     │ information                                            │
├─────────────────────┼────────────────────────────────────────────────────────┤
│ More info           │ https://github.com/advisories/GHSA-96hv-2xvq-fx4p      │
└─────────────────────┴────────────────────────────────────────────────────────┘
┌─────────────────────┬────────────────────────────────────────────────────────┐
│ high                │ form-data: CRLF injection in form-data via unescaped   │
│                     │ multipart field names and filenames                    │
├─────────────────────┼────────────────────────────────────────────────────────┤
│ Package             │ form-data                                              │
├─────────────────────┼────────────────────────────────────────────────────────┤
│ Vulnerable versions │ >=4.0.0 <4.0.6                                         │
├─────────────────────┼────────────────────────────────────────────────────────┤
│ Patched versions    │ >=4.0.6                                                │
├─────────────────────┼────────────────────────────────────────────────────────┤
│ Paths               │ apps/web >                                             │
│                     │ @solarproof/stellar@link:../../packages/stellar >      │
│                     │ @stellar/stellar-sdk@13.3.0 > axios@1.16.1 >           │
│                     │ form-data@4.0.5                                        │
│                     │                                                        │
│                     │ apps/web > @stellar/stellar-sdk@13.3.0 > axios@1.16.1  │
│                     │ > form-data@4.0.5                                      │
│                     │                                                        │
│                     │ apps/web > @vitest/coverage-v8@2.1.9 > vitest@2.1.9 >  │
│                     │ jsdom@25.0.1 > form-data@4.0.5                         │
│                     │                                                        │
│                     │ ... Found 7 paths, run `pnpm why form-data` for more   │
│                     │ information                                            │
├─────────────────────┼────────────────────────────────────────────────────────┤
│ More info           │ https://github.com/advisories/GHSA-hmw2-7cc7-3qxx      │
└─────────────────────┴────────────────────────────────────────────────────────┘
┌─────────────────────┬────────────────────────────────────────────────────────┐
│ high                │ vite: `server.fs.deny` bypass on Windows alternate     │
│                     │ paths                                                  │
├─────────────────────┼────────────────────────────────────────────────────────┤
│ Package             │ vite                                                   │
├─────────────────────┼────────────────────────────────────────────────────────┤
│ Vulnerable versions │ <=6.4.2                                                │
├─────────────────────┼────────────────────────────────────────────────────────┤
│ Patc

* Tests for useWallet hook using the mock Freighter wallet.
* Runs headlessly in CI — no browser extension required.
*/
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'
@@ -102,16 +103,17 @@
const searchParams = useSearchParams()
const [query, setQuery] = useState(searchParams.get('id') ?? '')
const [result, setResult] = useState<ChainOfCustody | null>(null)
const [error, setError] = useState<string | null>(null)
const [pageError, setPageError] = useState<Error | null>(null)
</div>
)

function ThrowError({ error }: { error: Error }) {
@github-actions

Copy link
Copy Markdown

✅ cargo audit

�[0m�[0m�[1m�[32m    Fetching�[0m advisory database from `https://github.com/RustSec/advisory-db.git`
�[0m�[0m�[1m�[32m      Loaded�[0m 1138 security advisories (from /home/runner/.cargo/advisory-db)
�[0m�[0m�[1m�[32m    Updating�[0m crates.io index
�[0m�[0m�[1m�[32m    Scanning�[0m Cargo.lock for vulnerabilities (192 crate dependencies)
�[0m�[0m�[1m�[33mCrate:    �[0m derivative
�[0m�[0m�[1m�[33mVersion:  �[0m 2.2.0
�[0m�[0m�[1m�[33mWarning:  �[0m unmaintained
�[0m�[0m�[1m�[33mTitle:    �[0m `derivative` is unmaintained; consider using an alternative
�[0m�[0m�[1m�[33mDate:     �[0m 2024-06-26
�[0m�[0m�[1m�[33mID:       �[0m RUSTSEC-2024-0388
�[0m�[0m�[1m�[33mURL:      �[0m https://rustsec.org/advisories/RUSTSEC-2024-0388

�[0m�[0m�[1m�[33mCrate:    �[0m paste
�[0m�[0m�[1m�[33mVersion:  �[0m 1.0.15
�[0m�[0m�[1m�[33mWarning:  �[0m unmaintained
�[0m�[0m�[1m�[33mTitle:    �[0m paste - no longer maintained
�[0m�[0m�[1m�[33mDate:     �[0m 2024-10-07
�[0m�[0m�[1m�[33mID:       �[0m RUSTSEC-2024-0436
�[0m�[0m�[1m�[33mURL:      �[0m https://rustsec.org/advisories/RUSTSEC-2024-0436

�[0m�[0m�[1m�[33mwarning:�[0m 2 allowed warnings found

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.