Audit and update specs rd5 (#1850)

* first commit sc-02

* prep for pr

* fix

* specs pass 1

* update specs
This commit is contained in:
Justin Hernandez
2026-03-12 16:22:31 -07:00
committed by GitHub
parent 95d893fa45
commit a56edbab75
10 changed files with 222 additions and 17 deletions

View File

@@ -210,6 +210,7 @@ describe('Adapter integration tests', () => {
await expect(adapter.generateKey('my-key')).rejects.toThrow('Native key generation failed');
});
it('should get public key via bridge and decode base64', async () => {
const pubKeyBytes = new Uint8Array([4, 10, 20, 30, 40]);
const pubKeyBase64 = btoa(

View File

@@ -11,3 +11,6 @@ For full retirement process, see [SPECS-REORG-PLAN.md](./archive/SPECS-REORG-PLA
| `specs/projects/kmp/*` | 2026-03-05 | KMP specs retired from active project tree | KMP planning/execution remains under SDK workstreams; historical KMP context kept in `specs/archive/kmp/` | N/A |
| `specs/topics/CI-COVERAGE-GAPS.md` | 2026-03-06 | CI coverage expansion delivered | Added dedicated CI coverage workflows across webview, KMP, RN test app, and Swift package; moved to archive after rollout | N/A |
| `specs/ios-crash-fix/SPEC.md` | 2026-03-10 | iOS simulator crash mitigation delivered | Shipped deterministic simulator launch, simulator-only Sentry replay/screenshot reduction, and a binary-pod arm64 simulator audit with Rosetta fallback retained for `libtesseract` | N/A |
| `specs/topics/EUCLID-WEB-CONSOLIDATION.md` | 2026-03-12 | Superseded by WebView SPEC.md scope reset | Phased migration plan replaced by WV-01 through WV-04; `euclid-web` renamed to `webview-app` | N/A |
| `specs/topics/LOTTIE-DOTLOTTIE-REVIEW.md` | 2026-03-12 | Branch review for reverted migration | One-off review of `justin/lottie-dotlottie-conversion`; migration reverted in PR #1848 | N/A |
| `specs/topics/SECURITY-HARDENING.md` | 2026-03-12 | All items re-homed to owning backlogs | APDU hardening done in NS-04/RN-03; crypto surface done in SC-02; file was already context-only | N/A |

View File

@@ -15,10 +15,7 @@
## Topics
- [CI Coverage Gaps](./archive/CI-COVERAGE-GAPS.md)
- [Euclid Web Consolidation](./topics/EUCLID-WEB-CONSOLIDATION.md)
- [Lottie dotLottie Review](./topics/LOTTIE-DOTLOTTIE-REVIEW.md)
- [Security Hardening](./topics/SECURITY-HARDENING.md)
No active topic docs. See [Spec Archive](./ARCHIVE.md) for retired topics.
## Framework

View File

@@ -1,6 +1,6 @@
# SDK Project
Last updated: March 11, 2026
Last updated: March 12, 2026
Status: Active (WebView-first)
## Start Here
@@ -29,5 +29,3 @@ Status: Active (WebView-first)
## Related
- [Paused Work Index](./paused/INDEX.md) — retained native/KMP/RN tracks for future reuse
- [Euclid Web Consolidation](../../topics/EUCLID-WEB-CONSOLIDATION.md) — background on shared WebView convergence
- [Security Hardening](../../topics/SECURITY-HARDENING.md) — historical native hardening context, now mostly parked with paused workstreams

View File

@@ -1,6 +1,6 @@
# Self SDK — Overview
> Last updated: 2026-03-11
> Last updated: 2026-03-12
> Owner: Self Engineering
> Status: Active (WebView-first; native-module work paused)
@@ -31,6 +31,8 @@ On **March 11, 2026**, the active SDK delivery target changed:
- [x] `WV-02` formalized the provider-agnostic KYC capture and handoff contract
- [x] `WV-03` removed native-scan and NFC assumptions from the active WebView flow/docs
- [x] `WV-04` added the browser/native host callback contract for ready, result, dismiss, and cancel handling
- [x] `SC-01` consolidated bridge-layer fallback duplicates with engine-owned adapters
- [x] `SC-02` exposed `generateKey()`/`getPublicKey()` in the crypto adapter surface
### Paused

View File

@@ -1,6 +1,6 @@
# SDK Core Adaptation — Implementation Spec
> Last updated: 2026-03-11
> Last updated: 2026-03-12
> Owner: SDK Core
> Project: [SDK Overview](../../OVERVIEW.md)
> Status: Active
@@ -60,6 +60,7 @@
- [x] All chunks done (4A4F) — config, browser entry, lifecycle events, conditional store, web fallbacks
- [x] Bridge-layer fallback duplicates removed
- [x] `generateKey()`/`getPublicKey()` exposed in `CryptoAdapter` and `BridgeCryptoAdapter` interfaces
- [ ] Reusable adapter assembly factories extracted from app provider
## Execution Model
@@ -69,19 +70,21 @@
## Backlog
| ID | Title | Status | Priority | Depends On | Plan | PR |
| ----- | ---------------------------------------------------------------------------- | ------ | -------- | ---------- | -------------------------------------------------------------------------------- | --- |
| SC-01 | Consolidate bridge-layer fallback duplicates with engine-owned adapters | Done | High | - | [plans/SC-01-fallback-adapter-dedup.md](./plans/SC-01-fallback-adapter-dedup.md) | - |
| SC-02 | Expose `generateKey()` and `getPublicKey()` in bridge crypto adapter surface | Done | Medium | SC-01 | [plans/SC-02-crypto-bridge-surface.md](./plans/SC-02-crypto-bridge-surface.md) | - |
| ID | Title | Status | Priority | Depends On | Plan | PR |
| ----- | ---------------------------------------------------------------------------- | ------ | -------- | ---------- | ------------------------------------------------------------------------------------------ | --- |
| SC-01 | Consolidate bridge-layer fallback duplicates with engine-owned adapters | Done | High | - | [plans/SC-01-fallback-adapter-dedup.md](./plans/SC-01-fallback-adapter-dedup.md) | - |
| SC-02 | Expose `generateKey()` and `getPublicKey()` in bridge crypto adapter surface | Done | Medium | SC-01 | [plans/SC-02-crypto-bridge-surface.md](./plans/SC-02-crypto-bridge-surface.md) | - |
| SC-03 | Extract reusable app adapter factories for SelfClient assembly | Ready | Medium | SC-02 | [plans/SC-03-selfclient-adapter-assembly.md](./plans/SC-03-selfclient-adapter-assembly.md) | - |
Allowed statuses: `Ready`, `In Progress`, `Blocked`, `Deferred`, `Done`
## Active Plans
| Plan | IDs | Status |
| -------------------------------------------------------------------------------- | ----- | ------ |
| [plans/SC-01-fallback-adapter-dedup.md](./plans/SC-01-fallback-adapter-dedup.md) | SC-01 | Done |
| [plans/SC-02-crypto-bridge-surface.md](./plans/SC-02-crypto-bridge-surface.md) | SC-02 | Done |
| Plan | IDs | Status |
| ------------------------------------------------------------------------------------------ | ----- | ------ |
| [plans/SC-01-fallback-adapter-dedup.md](./plans/SC-01-fallback-adapter-dedup.md) | SC-01 | Done |
| [plans/SC-02-crypto-bridge-surface.md](./plans/SC-02-crypto-bridge-surface.md) | SC-02 | Done |
| [plans/SC-03-selfclient-adapter-assembly.md](./plans/SC-03-selfclient-adapter-assembly.md) | SC-03 | Ready |
## Completion Checklist

View File

@@ -0,0 +1,201 @@
# SC-03: Extract Reusable App Adapter Factories for SelfClient Assembly
> Last updated: 2026-03-12
> Status: Ready
> Priority: Medium
> Depends on: SC-02 (Done)
- Workstream: sdk-core
- Backlog ID: SC-03
- Owner: SDK Core
- Branch: TBD
- PR: TBD
## Context
You are extracting the generic app-side adapter factories that are still
duplicated inside the RN app's `createSelfClient()` assembly.
Today, `app/src/providers/selfClientProvider.tsx` (519 lines) still inlines
generic crypto and network adapters even though those pieces are not app-
specific. The WebView app follows a different bridge-oriented assembly path and
is intentionally out of scope for this plan.
The result:
1. Every new adapter method (like `generateKey`/`getPublicKey` in SC-02) must be
patched in the app provider by hand — the app CI broke because its inline
crypto adapter was missing the new methods.
2. The app's crypto adapter reimplements `createWebCryptoAdapter()` from
`mobile-sdk-alpha/src/adapters/browser/crypto.ts` with slightly different
algorithm normalization.
3. The app's WebSocket adapter is a copy of what could be a shared factory.
### What exists today
| Consumer | File | LOC | Relevant duplicated adapter assembly |
| ----------- | ----------------------------------------------------------- | --- | ------------------------------------------------------------------- |
| RN app | `app/src/providers/selfClientProvider.tsx` | 519 | crypto (hash+stubs), network (fetch+ws) |
| WebView app | `packages/webview-app/src/providers/SelfClientProvider.tsx` | 108 | Different bridge-oriented assembly path; out of scope for this plan |
### What the SDK already provides
| Adapter | Factory | Location |
| ------------------ | ----------------------------- | ------------------------------------------------------ |
| Crypto (browser) | `createWebCryptoAdapter()` | `mobile-sdk-alpha/src/adapters/browser/crypto.ts` |
| Crypto (RN) | `createCryptoAdapter()` | `mobile-sdk-alpha/src/adapters/react-native/crypto.ts` |
| Network (fetch+ws) | **None** | Inlined in both consumers |
| Navigation | **None** (app-specific) | Inlined in app consumer |
| Analytics | `createWebAnalyticsAdapter()` | `mobile-sdk-alpha/src/adapters/browser/analytics.ts` |
## What You Will Do
### 1. Create a default network adapter factory
**Create:** `packages/mobile-sdk-alpha/src/adapters/browser/network.ts`
The app and webview-app both construct identical `{ http: { fetch }, ws: { connect } }`
objects using the platform's native `fetch` and `WebSocket`. Extract this into a
shared factory.
```typescript
import type { NetworkAdapter, WsConn } from '../../types/public';
export function createWebNetworkAdapter(): NetworkAdapter {
return {
http: {
fetch: (input: RequestInfo, init?: RequestInit) => fetch(input, init),
},
ws: {
connect: (url: string): WsConn => {
const socket = new WebSocket(url);
return {
send: data => socket.send(data),
close: () => socket.close(),
onMessage: cb => {
socket.addEventListener('message', ev =>
cb((ev as MessageEvent).data),
);
},
onError: cb => {
socket.addEventListener('error', e => cb(e));
},
onClose: cb => {
socket.addEventListener('close', () => cb());
},
};
},
},
};
}
```
### 2. Export the new factory from the browser barrel
**File:** `packages/mobile-sdk-alpha/src/adapters/browser/index.ts`
Add `createWebNetworkAdapter` to the barrel export.
### 3. Export the new factory from the browser entry point
**File:** `packages/mobile-sdk-alpha/src/browser.ts`
Re-export `createWebNetworkAdapter` so `@selfxyz/mobile-sdk-alpha/browser`
consumers can import it.
### 4. Replace the app's inline network adapter
**File:** `app/src/providers/selfClientProvider.tsx`
Replace the inline `network: { http: { fetch: ... }, ws: { connect: ... } }`
block (~20 lines) with:
```typescript
import { createWebNetworkAdapter } from '@selfxyz/mobile-sdk-alpha/browser';
// ...
network: createWebNetworkAdapter(),
```
### 5. Replace the app's inline crypto adapter
**File:** `app/src/providers/selfClientProvider.tsx`
Replace the inline `crypto: { hash(...) { ... }, sign(...) { ... }, generateKey(...) { ... }, getPublicKey(...) { ... } }`
block (~30 lines) with:
```typescript
import { createWebCryptoAdapter } from '@selfxyz/mobile-sdk-alpha/browser';
// ...
crypto: createWebCryptoAdapter(),
```
The app's inline hash implementation is functionally identical to
`createWebCryptoAdapter()` but with less robust algorithm normalization. The
throwing stubs for `sign`, `generateKey`, and `getPublicKey` are identical.
### 6. Update SPEC.md backlog
**File:** `specs/projects/sdk/workstreams/sdk-core/SPEC.md`
- Add SC-03 row to backlog table
- Add SC-03 to active plans table
## Files You Will Modify
| File | Change | Risk |
| ----------------------------------------------------------- | -------------------------------------------------- | -------------------------------------------------- |
| `packages/mobile-sdk-alpha/src/adapters/browser/network.ts` | **Create** — new network adapter factory | **Low** — follows existing adapter factory pattern |
| `packages/mobile-sdk-alpha/src/adapters/browser/index.ts` | Add barrel export | **Low** — additive |
| `packages/mobile-sdk-alpha/src/browser.ts` | Add re-export | **Low** — additive |
| `app/src/providers/selfClientProvider.tsx` | Replace inline crypto + network with factory calls | **Medium** — touches app provider |
| `specs/projects/sdk/workstreams/sdk-core/SPEC.md` | Add SC-03 to backlog | **None** |
## Files You Will NOT Modify
| File | Why |
| ----------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
| `packages/webview-app/src/providers/SelfClientProvider.tsx` | Already uses bridge adapter factories — different assembly path that is intentionally out of scope here. |
| `packages/mobile-sdk-alpha/src/client.ts` | `createSelfClient()` factory is correct as-is |
| `packages/mobile-sdk-alpha/src/context.tsx` | `SelfClientProvider` React wrapper is correct as-is |
| `packages/mobile-sdk-alpha/src/types/public.ts` | No interface changes needed |
| `packages/webview-bridge/**` | Bridge adapters are a separate assembly path |
## Constraints
- **No regressions in the RN app.** The app must continue to work identically
after replacing inline adapters with factory calls.
- **No new dependencies.** `createWebNetworkAdapter()` uses only platform globals
(`fetch`, `WebSocket`).
- **App-specific wiring stays in the app.** Navigation (React Navigation refs),
analytics (Sentry + app tracking service), auth (keychain provider), documents
(passport data provider), and event listeners are app-specific and remain in
`selfClientProvider.tsx`. Only the generic/duplicated parts move to factories.
- **Don't touch the webview-app provider.** It has its own adapter type
(`SelfClientAdapters`) that includes lifecycle and biometrics — adapters the
SDK's `Adapters` interface doesn't define. That is a separate concern and not
part of SC-03.
## Validation
```bash
# SDK core types + tests
cd packages/mobile-sdk-alpha && yarn types && yarn test
# App types
cd app && yarn types
# Full lint pass
yarn lint
```
**Expected:** All pass with zero errors.
## Definition of Done
- [ ] `createWebNetworkAdapter()` factory exists in `mobile-sdk-alpha/src/adapters/browser/`
- [ ] Factory is exported from both `browser/index.ts` barrel and `browser.ts` entry point
- [ ] App's `selfClientProvider.tsx` uses `createWebCryptoAdapter()` instead of inline crypto
- [ ] App's `selfClientProvider.tsx` uses `createWebNetworkAdapter()` instead of inline network
- [ ] `yarn types` clean in both `mobile-sdk-alpha` and `app`
- [ ] `yarn test` passes in `mobile-sdk-alpha`
- [ ] Backlog row added in SPEC.md