feat: implement issues #73, #74, #99, #472 — storage, UI components, wallet orchestration, rate-limiting#955
Merged
Conversation
…ncore-org#73) - Add SecureStorageManager with unlock/lock/save/get/export/import API - Wire storage payload format + AES-GCM encryption via PBKDF2 key derivation - Ensure lock() clears in-memory CryptoKey and auto-lock timer - Add chrome-compat.test.ts: smoke tests for Chrome, Firefox (browser), and localStorage fallback adapter wiring + lock/unlock lifecycle - Add background/storage.ts: re-exports getStorageManager and resetSharedStorageManagerForTests from the shared security module Security checklist: - Encryption key never stored (in-memory only, cleared on lock()) - Unique IV + per-payload salt generated for each encryption (AES-256-GCM) - Master salt generated on first use and persisted (non-sensitive) - PBKDF2 with 100,000 iterations + SHA-256 - Auto-lock timer resets on activity via touch() - Wrong password returns false, leaves manager locked Closes ancore-org#73
AddressDisplay enhancements: - showIdenticon prop: renders deterministic Identicon avatar alongside address - Full-address Tooltip on hover and focus-within (existing ui/tooltip.tsx) - isValid prop: destructive border + AlertCircle icon for invalid addresses - aria-live polite region announces 'Address copied to clipboard' to screen readers - Copy button aria-label toggles between 'Copy address' and 'Copied!' - aria-label on <code> element exposes full untruncated address New Storybook stories: - Identicon.stories.tsx: Default, Small, Large, CustomLabel, UniquePerAddress, SizeScale - QRCode.stories.tsx: Default, Small, Large, CustomLabel, PaymentURI, SizeScale, ReceiveCard - address-display.stories.tsx: updated with WithIdenticon, ValidAddress, InvalidAddress, InvalidWithIdenticon, MultipleAddresses, InCard compound examples Tests (address-display.test.tsx): - 22 tests covering all props: truncation, label, copy, clipboard, aria-live, onCopy, controlled copied, tooltip aria-label, identicon rendering, isValid feedback, className All 190 tests pass across 18 test files. Closes ancore-org#74
…core-org#99) - Add create-wallet.ts: CreateWalletParams, CreateWalletResult types and createWallet() function that orchestrates generateMnemonic → deriveKeypairFromMnemonic → encryptSecretKey (optional, password-gated) - Add AncoreClient.createWallet(params?) delegating to the orchestration layer - Export createWalletOrchestration, CreateWalletParams, CreateWalletResult from index.ts - Add @ancore/crypto moduleNameMapper to jest.config.cjs, fixing the previously failing wallet.test.ts suite as a side-effect - Add create-wallet.test.ts: 21 unit tests with all @ancore/crypto dependencies mocked, covering both the standalone createWallet() function and the AncoreClient.createWallet() delegation path All 31 test suites (463 tests) pass. Closes ancore-org#99
…org#472) - Add ROUTE_RATE_LIMIT_CONFIG: central map keyed by Express route path /relay/execute → 30 rpm (baseline) /relay/validate → 60 rpm (read-only, more permissive) /relay/session-key → 10 rpm (sensitive mutation, stricter) /relay/revoke-session-key → 10 rpm (sensitive mutation, stricter) /relay/status → 120 rpm (monitoring, very permissive) /health → 120 rpm (monitoring, very permissive) - Add DEFAULT_ROUTE_CONFIG (20 rpm) as a fail-safe for unconfigured routes - createRouteRateLimiter(route, override?): factory that looks up the map, applies optional override, and wires express-rate-limit with standardHeaders:true / legacyHeaders:false (RateLimit-* draft spec) - 429 body includes { error, route, retryAfter } for client-side handling - resolveRouteConfig() helper for test-time introspection without constructing a middleware instance - 24 unit tests covering: config map values, stricter session-key defaults, DEFAULT_ROUTE_CONFIG fallback, resolveRouteConfig, enforcement (allows N, blocks N+1), correct 429 body, per-account isolation, per-route isolation, RateLimit draft headers, no legacy X-RateLimit headers, override precedence Closes ancore-org#472
|
@gregemax Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
|
Caution Review failedAn error occurred during the review process. Please try again later. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
14 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR resolves four independent issues across the monorepo in a single batch. Every commit is independently scoped and all relevant tests pass.
Changes
#73 — Implement Secure Storage Manager for Browser Extension
Commit:
ec384b8Files changed:
packages/core-sdk/src/storage/__tests__/chrome-compat.test.ts(new)apps/extension-wallet/src/background/storage.ts(new)SecureStorageManagerwith PBKDF2 + AES-256-GCM encryption already existed. This commit adds the two missing deliverables:createStorageAdapter()selects the correct adapter (Chrome/Firefox/localStorage fallback) based on runtime globals, and that the full unlock → save → lock → re-unlock → get round-trip works for each adapter.getSharedStorageManagerasgetStorageManagerfrom the shared security singleton, eliminating import scatter.#74 — Create Address and QR Code Display Components
Commit:
46afaf1Files changed:
packages/ui-kit/src/components/address-display.tsx(modified)packages/ui-kit/src/components/address-display.test.tsx(modified, 22 tests)packages/ui-kit/src/components/address-display.stories.tsx(modified)packages/ui-kit/src/components/Identicon.stories.tsx(new)packages/ui-kit/src/components/QRCode.stories.tsx(new)AddressDisplayadditions:showIdenticon— renders a 24 px deterministicIdenticonavatar alongside the addressisValid—falseapplies a destructive border +AlertCircleicon;undefined(default) shows nothingui/tooltip.tsx, no new deps)aria-live="polite"region announces "Address copied to clipboard"; copy-buttonaria-labeltoggles between "Copy address" and "Copied!"New Storybook stories: Identicon (Default, Small, Large, UniquePerAddress, SizeScale) and QRCode (Default, PaymentURI, SizeScale, ReceiveCard).
All 190 ui-kit tests pass.
#99 — Core SDK Create Wallet (mnemonic → keypair → encrypted output)
Commit:
8220efdFiles changed:
packages/core-sdk/src/create-wallet.ts(new)packages/core-sdk/src/ancore-client.ts(modified)packages/core-sdk/src/index.ts(modified)packages/core-sdk/jest.config.cjs(modified)packages/core-sdk/src/__tests__/create-wallet.test.ts(new, 21 tests)create-wallet.tsorchestrates:generateMnemonic()→deriveKeypairFromMnemonic(mnemonic, accountIndex)→ optionalencryptSecretKey(mnemonic, password). Returns a typedCreateWalletResult—publicKeyandcontractIdare safe to persist;mnemonic,secretKey, andencryptedMnemonicmust be handled in-memory only.AncoreClient.createWallet(params?)is a thin delegation to the orchestration layer.Adding
@ancore/cryptotomoduleNameMapperinjest.config.cjsalso fixes the previously failingwallet.test.tssuite as a side-effect. All 31 core-sdk test suites (463 tests) pass.#472 — [RELAYER] Add per-route rate-limit config map and tests
Commit:
f173aceFiles changed:
services/relayer/src/middleware/routeRateLimiter.ts(new)services/relayer/src/middleware/__tests__/routeRateLimiter.test.ts(new, 24 tests)Central
ROUTE_RATE_LIMIT_CONFIGmap:/relay/execute/relay/validate/relay/session-key/relay/revoke-session-key/relay/status/healthDEFAULT_ROUTE_CONFIG(20 rpm) is a fail-safe for unconfigured routes.createRouteRateLimiter(route, override?)wiresexpress-rate-limitwithstandardHeaders: true/legacyHeaders: false(RateLimit-* draft spec). 429 body:{ error, route, retryAfter }.Tests cover: config map values, stricter session-key defaults, DEFAULT fallback, enforcement, per-account isolation, per-route isolation, RateLimit draft headers, no legacy X-RateLimit headers, override precedence.
Test summary
@ancore/core-sdk@ancore/ui-kit@ancore/relayerCloses #73
Closes #74
Closes #99
Closes #472