@burnt-labs/expo-satya-attest 0.3.2 → 1.0.0

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.
Files changed (296) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/PROVIDER_CONFIG.md +36 -28
  3. package/PROVIDER_REGISTRY.md +102 -200
  4. package/PUBLISHING.md +29 -26
  5. package/README.md +127 -133
  6. package/android/build.gradle +2 -2
  7. package/android/src/main/java/expo/modules/satyaattest/SatyaAttestModule.kt +24 -97
  8. package/android/src/main/java/uniffi/satya_ffi/satya_ffi.kt +5 -70
  9. package/android/src/main/jniLibs/arm64-v8a/libsatya_ffi.so +0 -0
  10. package/android/src/main/jniLibs/armeabi-v7a/libsatya_ffi.so +0 -0
  11. package/android/src/main/jniLibs/x86_64/libsatya_ffi.so +0 -0
  12. package/build/SatyaAttestModule.d.ts +1 -29
  13. package/build/SatyaAttestModule.d.ts.map +1 -1
  14. package/build/SatyaAttestModule.js.map +1 -1
  15. package/build/SatyaAttestModule.web.d.ts +1 -2
  16. package/build/SatyaAttestModule.web.d.ts.map +1 -1
  17. package/build/SatyaAttestModule.web.js +10 -10
  18. package/build/SatyaAttestModule.web.js.map +1 -1
  19. package/build/SatyaMobileClient.d.ts +1 -15
  20. package/build/SatyaMobileClient.d.ts.map +1 -1
  21. package/build/SatyaMobileClient.js +26 -30
  22. package/build/SatyaMobileClient.js.map +1 -1
  23. package/build/SatyaProviderAttestButton.d.ts +3 -124
  24. package/build/SatyaProviderAttestButton.d.ts.map +1 -1
  25. package/build/SatyaProviderAttestButton.js +20 -1715
  26. package/build/SatyaProviderAttestButton.js.map +1 -1
  27. package/build/components/providerAttest/ProviderAttestModal.d.ts +8 -0
  28. package/build/components/providerAttest/ProviderAttestModal.d.ts.map +1 -0
  29. package/build/components/providerAttest/ProviderAttestModal.js +141 -0
  30. package/build/components/providerAttest/ProviderAttestModal.js.map +1 -0
  31. package/build/components/providerAttest/backendVerifier.d.ts +4 -0
  32. package/build/components/providerAttest/backendVerifier.d.ts.map +1 -0
  33. package/build/components/providerAttest/backendVerifier.js +57 -0
  34. package/build/components/providerAttest/backendVerifier.js.map +1 -0
  35. package/build/components/providerAttest/constants.d.ts +4 -0
  36. package/build/components/providerAttest/constants.d.ts.map +1 -0
  37. package/build/components/providerAttest/constants.js +4 -0
  38. package/build/components/providerAttest/constants.js.map +1 -0
  39. package/build/components/providerAttest/copy.d.ts +4 -0
  40. package/build/components/providerAttest/copy.d.ts.map +1 -0
  41. package/build/components/providerAttest/copy.js +27 -0
  42. package/build/components/providerAttest/copy.js.map +1 -0
  43. package/build/components/providerAttest/popupRelay.d.ts +10 -0
  44. package/build/components/providerAttest/popupRelay.d.ts.map +1 -0
  45. package/build/components/providerAttest/popupRelay.js +125 -0
  46. package/build/components/providerAttest/popupRelay.js.map +1 -0
  47. package/build/components/providerAttest/providerResolution.d.ts +17 -0
  48. package/build/components/providerAttest/providerResolution.d.ts.map +1 -0
  49. package/build/components/providerAttest/providerResolution.js +125 -0
  50. package/build/components/providerAttest/providerResolution.js.map +1 -0
  51. package/build/components/providerAttest/replayRewrite.d.ts +3 -0
  52. package/build/components/providerAttest/replayRewrite.d.ts.map +1 -0
  53. package/build/components/providerAttest/replayRewrite.js +21 -0
  54. package/build/components/providerAttest/replayRewrite.js.map +1 -0
  55. package/build/components/providerAttest/styles.d.ts +179 -0
  56. package/build/components/providerAttest/styles.d.ts.map +1 -0
  57. package/build/components/providerAttest/styles.js +124 -0
  58. package/build/components/providerAttest/styles.js.map +1 -0
  59. package/build/components/providerAttest/theme.d.ts +17 -0
  60. package/build/components/providerAttest/theme.d.ts.map +1 -0
  61. package/build/components/providerAttest/theme.js +29 -0
  62. package/build/components/providerAttest/theme.js.map +1 -0
  63. package/build/components/providerAttest/types.d.ts +94 -0
  64. package/build/components/providerAttest/types.d.ts.map +1 -0
  65. package/build/components/providerAttest/types.js +8 -0
  66. package/build/components/providerAttest/types.js.map +1 -0
  67. package/build/components/providerAttest/urlUtils.d.ts +6 -0
  68. package/build/components/providerAttest/urlUtils.d.ts.map +1 -0
  69. package/build/components/providerAttest/urlUtils.js +80 -0
  70. package/build/components/providerAttest/urlUtils.js.map +1 -0
  71. package/build/components/providerAttest/useEdgeSwipeBack.d.ts +2 -0
  72. package/build/components/providerAttest/useEdgeSwipeBack.d.ts.map +1 -0
  73. package/build/components/providerAttest/useEdgeSwipeBack.js +14 -0
  74. package/build/components/providerAttest/useEdgeSwipeBack.js.map +1 -0
  75. package/build/components/providerAttest/useHtmlCaptureTrigger.d.ts +17 -0
  76. package/build/components/providerAttest/useHtmlCaptureTrigger.d.ts.map +1 -0
  77. package/build/components/providerAttest/useHtmlCaptureTrigger.js +37 -0
  78. package/build/components/providerAttest/useHtmlCaptureTrigger.js.map +1 -0
  79. package/build/components/providerAttest/useManagedPopupController.d.ts +31 -0
  80. package/build/components/providerAttest/useManagedPopupController.d.ts.map +1 -0
  81. package/build/components/providerAttest/useManagedPopupController.js +128 -0
  82. package/build/components/providerAttest/useManagedPopupController.js.map +1 -0
  83. package/build/components/providerAttest/useNativeReplayRunner.d.ts +22 -0
  84. package/build/components/providerAttest/useNativeReplayRunner.d.ts.map +1 -0
  85. package/build/components/providerAttest/useNativeReplayRunner.js +103 -0
  86. package/build/components/providerAttest/useNativeReplayRunner.js.map +1 -0
  87. package/build/components/providerAttest/useProviderAttestFlow.d.ts +49 -0
  88. package/build/components/providerAttest/useProviderAttestFlow.d.ts.map +1 -0
  89. package/build/components/providerAttest/useProviderAttestFlow.js +379 -0
  90. package/build/components/providerAttest/useProviderAttestFlow.js.map +1 -0
  91. package/build/components/providerAttest/useProviderInjectedScripts.d.ts +26 -0
  92. package/build/components/providerAttest/useProviderInjectedScripts.d.ts.map +1 -0
  93. package/build/components/providerAttest/useProviderInjectedScripts.js +110 -0
  94. package/build/components/providerAttest/useProviderInjectedScripts.js.map +1 -0
  95. package/build/components/providerAttest/useProviderMessageHandler.d.ts +31 -0
  96. package/build/components/providerAttest/useProviderMessageHandler.d.ts.map +1 -0
  97. package/build/components/providerAttest/useProviderMessageHandler.js +159 -0
  98. package/build/components/providerAttest/useProviderMessageHandler.js.map +1 -0
  99. package/build/components/providerAttest/useProviderNavigationHandlers.d.ts +30 -0
  100. package/build/components/providerAttest/useProviderNavigationHandlers.d.ts.map +1 -0
  101. package/build/components/providerAttest/useProviderNavigationHandlers.js +170 -0
  102. package/build/components/providerAttest/useProviderNavigationHandlers.js.map +1 -0
  103. package/build/components/providerAttest/webviewRuntime.d.ts +9 -0
  104. package/build/components/providerAttest/webviewRuntime.d.ts.map +1 -0
  105. package/build/components/providerAttest/webviewRuntime.js +75 -0
  106. package/build/components/providerAttest/webviewRuntime.js.map +1 -0
  107. package/build/debugLog.d.ts +10 -33
  108. package/build/debugLog.d.ts.map +1 -1
  109. package/build/debugLog.js +84 -75
  110. package/build/debugLog.js.map +1 -1
  111. package/build/index.d.ts +7 -5
  112. package/build/index.d.ts.map +1 -1
  113. package/build/index.js +5 -10
  114. package/build/index.js.map +1 -1
  115. package/build/{providerPolicy.d.ts → providerPolicy/index.d.ts} +5 -5
  116. package/build/providerPolicy/index.d.ts.map +1 -0
  117. package/build/providerPolicy/index.js +134 -0
  118. package/build/providerPolicy/index.js.map +1 -0
  119. package/build/providerRegistry/capture.d.ts +14 -0
  120. package/build/providerRegistry/capture.d.ts.map +1 -0
  121. package/build/providerRegistry/capture.js +111 -0
  122. package/build/providerRegistry/capture.js.map +1 -0
  123. package/build/providerRegistry/client.d.ts +3 -0
  124. package/build/providerRegistry/client.d.ts.map +1 -0
  125. package/build/providerRegistry/client.js +143 -0
  126. package/build/providerRegistry/client.js.map +1 -0
  127. package/build/providerRegistry/endpoints.d.ts +8 -0
  128. package/build/providerRegistry/endpoints.d.ts.map +1 -0
  129. package/build/providerRegistry/endpoints.js +98 -0
  130. package/build/providerRegistry/endpoints.js.map +1 -0
  131. package/build/providerRegistry/index.d.ts +4 -0
  132. package/build/providerRegistry/index.d.ts.map +1 -0
  133. package/build/providerRegistry/index.js +4 -0
  134. package/build/providerRegistry/index.js.map +1 -0
  135. package/build/providerRegistry/readers.d.ts +12 -0
  136. package/build/providerRegistry/readers.d.ts.map +1 -0
  137. package/build/providerRegistry/readers.js +75 -0
  138. package/build/providerRegistry/readers.js.map +1 -0
  139. package/build/providerRegistry/rules.d.ts +16 -0
  140. package/build/providerRegistry/rules.d.ts.map +1 -0
  141. package/build/providerRegistry/rules.js +385 -0
  142. package/build/providerRegistry/rules.js.map +1 -0
  143. package/build/providerRegistry/template.d.ts +7 -0
  144. package/build/providerRegistry/template.d.ts.map +1 -0
  145. package/build/providerRegistry/template.js +137 -0
  146. package/build/providerRegistry/template.js.map +1 -0
  147. package/build/providerRegistry/url.d.ts +5 -0
  148. package/build/providerRegistry/url.d.ts.map +1 -0
  149. package/build/providerRegistry/url.js +25 -0
  150. package/build/providerRegistry/url.js.map +1 -0
  151. package/build/satyaConfig.d.ts +24 -0
  152. package/build/satyaConfig.d.ts.map +1 -0
  153. package/build/satyaConfig.js +77 -0
  154. package/build/satyaConfig.js.map +1 -0
  155. package/build/types/artifact.types.d.ts +15 -0
  156. package/build/types/artifact.types.d.ts.map +1 -0
  157. package/build/types/artifact.types.js +2 -0
  158. package/build/types/artifact.types.js.map +1 -0
  159. package/build/types/error.types.d.ts +38 -0
  160. package/build/types/error.types.d.ts.map +1 -0
  161. package/build/types/error.types.js +67 -0
  162. package/build/types/error.types.js.map +1 -0
  163. package/build/types/index.d.ts +5 -0
  164. package/build/types/index.d.ts.map +1 -0
  165. package/build/types/index.js +5 -0
  166. package/build/types/index.js.map +1 -0
  167. package/build/types/mobile.types.d.ts +22 -0
  168. package/build/types/mobile.types.d.ts.map +1 -0
  169. package/build/types/mobile.types.js +2 -0
  170. package/build/types/mobile.types.js.map +1 -0
  171. package/build/types/provider.types.d.ts +161 -0
  172. package/build/types/provider.types.d.ts.map +1 -0
  173. package/build/types/provider.types.js +2 -0
  174. package/build/types/provider.types.js.map +1 -0
  175. package/build/utils/verifierUrl.d.ts +3 -0
  176. package/build/utils/verifierUrl.d.ts.map +1 -0
  177. package/build/utils/verifierUrl.js +39 -0
  178. package/build/utils/verifierUrl.js.map +1 -0
  179. package/build/webview/index.d.ts +59 -0
  180. package/build/webview/index.d.ts.map +1 -0
  181. package/build/webview/index.js +36 -0
  182. package/build/webview/index.js.map +1 -0
  183. package/build/webview/scripts/activeFetchScript.d.ts +11 -0
  184. package/build/webview/scripts/activeFetchScript.d.ts.map +1 -0
  185. package/build/webview/scripts/activeFetchScript.js +62 -0
  186. package/build/webview/scripts/activeFetchScript.js.map +1 -0
  187. package/build/webview/scripts/cookieSnapshotScript.d.ts +2 -0
  188. package/build/webview/scripts/cookieSnapshotScript.d.ts.map +1 -0
  189. package/build/webview/scripts/cookieSnapshotScript.js +44 -0
  190. package/build/webview/scripts/cookieSnapshotScript.js.map +1 -0
  191. package/build/webview/scripts/debugLoggerScript.d.ts +2 -0
  192. package/build/webview/scripts/debugLoggerScript.d.ts.map +1 -0
  193. package/build/webview/scripts/debugLoggerScript.js +23 -0
  194. package/build/webview/scripts/debugLoggerScript.js.map +1 -0
  195. package/build/webview/scripts/documentStartBridgeScript.d.ts +2 -0
  196. package/build/webview/scripts/documentStartBridgeScript.d.ts.map +1 -0
  197. package/build/webview/scripts/documentStartBridgeScript.js +266 -0
  198. package/build/webview/scripts/documentStartBridgeScript.js.map +1 -0
  199. package/build/webview/scripts/nativePopupsFlagScript.d.ts +2 -0
  200. package/build/webview/scripts/nativePopupsFlagScript.d.ts.map +1 -0
  201. package/build/webview/scripts/nativePopupsFlagScript.js +4 -0
  202. package/build/webview/scripts/nativePopupsFlagScript.js.map +1 -0
  203. package/build/webview/scripts/popupBridgeScript.d.ts +2 -0
  204. package/build/webview/scripts/popupBridgeScript.d.ts.map +1 -0
  205. package/build/webview/scripts/popupBridgeScript.js +188 -0
  206. package/build/webview/scripts/popupBridgeScript.js.map +1 -0
  207. package/build/webview/scripts/providerInjectionScript.d.ts +3 -0
  208. package/build/webview/scripts/providerInjectionScript.d.ts.map +1 -0
  209. package/build/webview/scripts/providerInjectionScript.js +21 -0
  210. package/build/webview/scripts/providerInjectionScript.js.map +1 -0
  211. package/build/webview/scripts/requestInterceptorScript.d.ts +2 -0
  212. package/build/webview/scripts/requestInterceptorScript.d.ts.map +1 -0
  213. package/build/webview/scripts/requestInterceptorScript.js +472 -0
  214. package/build/webview/scripts/requestInterceptorScript.js.map +1 -0
  215. package/ios/Frameworks/libsatya_ffi-rs.xcframework/ios-arm64/Headers/satya_ffi.swift +5 -83
  216. package/ios/Frameworks/libsatya_ffi-rs.xcframework/ios-arm64/Headers/satya_ffiFFI.h +0 -12
  217. package/ios/Frameworks/libsatya_ffi-rs.xcframework/ios-arm64/libsatya_ffi.a +0 -0
  218. package/ios/Frameworks/libsatya_ffi-rs.xcframework/ios-arm64_x86_64-simulator/Headers/satya_ffi.swift +5 -83
  219. package/ios/Frameworks/libsatya_ffi-rs.xcframework/ios-arm64_x86_64-simulator/Headers/satya_ffiFFI.h +0 -12
  220. package/ios/Frameworks/libsatya_ffi-rs.xcframework/ios-arm64_x86_64-simulator/libsatya_ffi.a +0 -0
  221. package/ios/Generated/satya_ffi.swift +5 -83
  222. package/ios/SatyaAttest.podspec +1 -1
  223. package/ios/SatyaAttestModule.swift +16 -71
  224. package/package.json +3 -3
  225. package/scripts/build-rust-android.sh +60 -1
  226. package/src/SatyaAttestModule.ts +1 -29
  227. package/src/SatyaAttestModule.web.ts +12 -11
  228. package/src/SatyaMobileClient.ts +41 -38
  229. package/src/SatyaProviderAttestButton.tsx +37 -2276
  230. package/src/components/providerAttest/ProviderAttestModal.tsx +290 -0
  231. package/src/components/providerAttest/backendVerifier.ts +62 -0
  232. package/src/components/providerAttest/constants.ts +3 -0
  233. package/src/components/providerAttest/copy.ts +29 -0
  234. package/src/components/providerAttest/popupRelay.ts +133 -0
  235. package/src/components/providerAttest/providerResolution.ts +160 -0
  236. package/src/components/providerAttest/replayRewrite.ts +31 -0
  237. package/src/components/providerAttest/styles.ts +130 -0
  238. package/src/components/providerAttest/theme.ts +46 -0
  239. package/src/components/providerAttest/types.ts +113 -0
  240. package/src/components/providerAttest/urlUtils.ts +81 -0
  241. package/src/components/providerAttest/useEdgeSwipeBack.ts +19 -0
  242. package/src/components/providerAttest/useHtmlCaptureTrigger.ts +59 -0
  243. package/src/components/providerAttest/useManagedPopupController.ts +196 -0
  244. package/src/components/providerAttest/useNativeReplayRunner.ts +146 -0
  245. package/src/components/providerAttest/useProviderAttestFlow.ts +489 -0
  246. package/src/components/providerAttest/useProviderInjectedScripts.ts +173 -0
  247. package/src/components/providerAttest/useProviderMessageHandler.ts +206 -0
  248. package/src/components/providerAttest/useProviderNavigationHandlers.ts +258 -0
  249. package/src/components/providerAttest/webviewRuntime.ts +83 -0
  250. package/src/debugLog.ts +99 -83
  251. package/src/index.ts +19 -21
  252. package/src/{providerPolicy.ts → providerPolicy/index.ts} +71 -38
  253. package/src/providerRegistry/capture.ts +153 -0
  254. package/src/providerRegistry/client.ts +200 -0
  255. package/src/providerRegistry/endpoints.ts +157 -0
  256. package/src/providerRegistry/index.ts +3 -0
  257. package/src/providerRegistry/readers.ts +131 -0
  258. package/src/providerRegistry/rules.ts +524 -0
  259. package/src/providerRegistry/template.ts +193 -0
  260. package/src/providerRegistry/url.ts +28 -0
  261. package/src/satyaConfig.ts +127 -0
  262. package/src/types/artifact.types.ts +15 -0
  263. package/src/types/error.types.ts +86 -0
  264. package/src/types/index.ts +4 -0
  265. package/src/types/mobile.types.ts +35 -0
  266. package/src/types/provider.types.ts +173 -0
  267. package/src/utils/verifierUrl.ts +44 -0
  268. package/src/webview/index.ts +81 -0
  269. package/src/webview/scripts/activeFetchScript.ts +73 -0
  270. package/src/webview/scripts/cookieSnapshotScript.ts +43 -0
  271. package/src/webview/scripts/debugLoggerScript.ts +22 -0
  272. package/src/webview/scripts/documentStartBridgeScript.ts +265 -0
  273. package/src/webview/scripts/nativePopupsFlagScript.ts +3 -0
  274. package/src/webview/scripts/popupBridgeScript.ts +187 -0
  275. package/src/webview/scripts/providerInjectionScript.ts +21 -0
  276. package/src/webview/scripts/requestInterceptorScript.ts +471 -0
  277. package/build/SatyaAttest.types.d.ts +0 -324
  278. package/build/SatyaAttest.types.d.ts.map +0 -1
  279. package/build/SatyaAttest.types.js +0 -10
  280. package/build/SatyaAttest.types.js.map +0 -1
  281. package/build/providerPolicy.d.ts.map +0 -1
  282. package/build/providerPolicy.js +0 -117
  283. package/build/providerPolicy.js.map +0 -1
  284. package/build/providerRegistry.d.ts +0 -18
  285. package/build/providerRegistry.d.ts.map +0 -1
  286. package/build/providerRegistry.js +0 -1117
  287. package/build/providerRegistry.js.map +0 -1
  288. package/build/providerWebview.d.ts +0 -107
  289. package/build/providerWebview.d.ts.map +0 -1
  290. package/build/providerWebview.js +0 -1142
  291. package/build/providerWebview.js.map +0 -1
  292. package/build/providers.json +0 -3076
  293. package/src/SatyaAttest.types.ts +0 -369
  294. package/src/providerRegistry.ts +0 -1415
  295. package/src/providerWebview.ts +0 -1214
  296. package/src/providers.json +0 -3076
package/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.0.0 - 2026-06-22
4
+
5
+ - Breaking: providers now load at runtime from `PROVIDER_REGISTRY_API` / `providerRegistryApi` by configured `providerId`; the SDK no longer ships or reads a bundled provider JSON.
6
+ - Breaking: current SDK artifacts use `policyHash` as the provider policy binding. `templateHash` and `parserHash` are no longer part of the SDK-side provider contract.
7
+ - Removed notary-facing SDK flow. Mobile apps act as the witness and submit app/device attestations to the verifier service.
8
+ - Added typed SDK errors via `SatyaErrorCode`, verifier URL normalization, provider-registry validation, and configurable redacted logging.
9
+ - Added `autoStart` and `renderButton` props so apps can use their own connect buttons or auto-open the managed WebView when app state is ready.
10
+ - Updated the example app to display SDK/debug logs in the UI when logging is enabled.
11
+
3
12
  ## 0.3.2 - 2026-06-16
4
13
 
5
14
  - Added a visible close button to the managed provider WebView header. It uses the same cancel path as the device back action and iOS edge-swipe gesture, so users can exit login or capture flows without relying only on platform gestures.
@@ -8,11 +8,13 @@ A provider config is **trusted policy** for the native replay flow. One config d
8
8
  - which response fields may be disclosed (`revealRules`),
9
9
  - which template/parser identities the verifier accepts (`templateGovernance`).
10
10
 
11
- The built-in registry lives at [`src/providers.json`](./src/providers.json). It is a
12
- byte-identical copy of the central registry in
13
- [`burnt-labs/provider-bank`](https://github.com/burnt-labs/provider-bank)
14
- (`provider-bank/providers.json`). Edit it there, sync the copy here, then run
15
- `npm run test:providers`.
11
+ Provider configs are loaded from the Provider Registry API runtime artifact at
12
+ `/.well-known/provider-registry/providers.json`. Edit provider data in the registry
13
+ backend, then run the backend registry validation and the SDK validator tests:
14
+
15
+ ```bash
16
+ npm run test:providers
17
+ ```
16
18
 
17
19
  ## Object map
18
20
 
@@ -40,6 +42,10 @@ field table (`Req?` = required `yes` / optional `no`).
40
42
  ```json
41
43
  {
42
44
  "schemaVersion": "1.0.0",
45
+ "registryVersion": 42,
46
+ "minimumAllowedRegistryVersion": 40,
47
+ "currentSnapshotSha256": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
48
+ "generatedAt": "2026-06-16T00:00:00.000Z",
43
49
  "providers": []
44
50
  }
45
51
  ```
@@ -48,6 +54,10 @@ field table (`Req?` = required `yes` / optional `no`).
48
54
  |---|---|---|---|
49
55
  | `providers` | yes | `Provider[]` | Non-empty array of provider objects. Provider ids must be unique. |
50
56
  | `schemaVersion` | no | `string` | Registry-level version. Optional in the SDK loader; each provider still needs its own `schemaVersion`. |
57
+ | `registryVersion` | no | `number` | Monotonic committed registry version emitted by the provider registry backend. Required when a loader/verifier sets a minimum version floor. |
58
+ | `minimumAllowedRegistryVersion` | no | `number` | Registry-published rollback floor for registry-wide loaders such as verifier startup. |
59
+ | `currentSnapshotSha256` | no | `string` | SHA-256 hex of the canonical current snapshot. Used for diagnostics/cache keys. |
60
+ | `generatedAt` | no | `string` | Snapshot generation timestamp. |
51
61
 
52
62
  ---
53
63
 
@@ -65,8 +75,7 @@ field table (`Req?` = required `yes` / optional `no`).
65
75
  "spkiSha256B64Pins": ["AAAA…="]
66
76
  },
67
77
  "templateGovernance": {
68
- "templateHash": "dev-acme-current-user-v1-template",
69
- "parserHash": "parser-sha256:0000…0000"
78
+ "policyHash": "policy-sha256:0000…0000"
70
79
  }
71
80
  }
72
81
  ```
@@ -76,12 +85,12 @@ field table (`Req?` = required `yes` / optional `no`).
76
85
  | Field | Type | Description |
77
86
  |---|---|---|
78
87
  | `schemaVersion` | `string` | Provider schema version (built-ins use `1.0.0`). |
79
- | `providerId` | `string` | Stable, unique id, e.g. `kaggle.current_user.v1`. Include a proof name + `.vN` suffix so verifier policy can pin it. Participates in `parserHash`. |
88
+ | `providerId` | `string` | Stable, unique id, e.g. `kaggle.current_user.v1`. Include a proof name + `.vN` suffix so verifier policy can pin it. Participates in `policyHash`. |
80
89
  | `name` | `string` | User-facing name shown in selectors/UI. |
81
90
  | `login` | `object` | Page opened in the managed WebView. See §2. |
82
91
  | `endpoints` | `Endpoint[]` | Non-empty (max 20). Each is one replayable request. If no endpoint is selected, the SDK uses the first. See §3. |
83
92
  | `tlsIdentityPolicy` | `object` | Pinned host + SPKI pins. See §7. |
84
- | `templateGovernance` | `object` | Template/parser identity. See §8. |
93
+ | `templateGovernance` | `object` | Provider policy identity. See §8. |
85
94
 
86
95
  **Optional fields**
87
96
 
@@ -93,9 +102,6 @@ field table (`Req?` = required `yes` / optional `no`).
93
102
  | `userAgent` | `{ ios, android }` | Per-platform UA (each `string` or `null`) for the WebView when no `webViewUserAgent` prop is set. Use when the provider serves different pages to mobile vs desktop and replay must match. |
94
103
  | `injection` | `string` / `string[]` / `null` | Trusted WebView JavaScript run on every page. See §9. |
95
104
  | `auth` | `object` | Provider-auth metadata. Preserved but not interpreted by the managed flow. |
96
- | `label`, `displayName` | `string` | Legacy display fields; normalized for compatibility. Prefer `name`. |
97
- | `target` | `object` | Legacy `{ scheme: "https", host: expectedSni, port: 443 }`. Auto-generated when omitted. |
98
- | `webLogin` | `object` | Legacy; `login.url` is preferred. `webLogin.startUrl` maps to `login.url`. |
99
105
 
100
106
  Unknown top-level keys are cloned through but ignored by native replay/verification —
101
107
  never put security-critical behavior in an undocumented key.
@@ -150,7 +156,7 @@ Each endpoint describes one replayable request and its disclosure policy.
150
156
 
151
157
  | Field | Type | Description |
152
158
  |---|---|---|
153
- | `id` | `string` | Starts with a letter; letters/digits/`_`/`-` only; unique per provider. Participates in `parserHash`. |
159
+ | `id` | `string` | Starts with a letter; letters/digits/`_`/`-` only; unique per provider. Participates in `policyHash`. |
154
160
  | `url` | `string` | HTTPS replay URL. Host must equal `tlsIdentityPolicy.expectedSni`. For dynamic endpoints (`replayCapturedUrl`) this is a stable prefix used for host pinning + match rules. |
155
161
  | `method` | `string` | One of `GET`, `POST`, `PUT`, `PATCH`, `DELETE`, `HEAD`, `OPTIONS`. Must agree with the `methodEquals` rule. |
156
162
  | `headers` | `string[]` | Non-empty request-header allowlist for native replay. Only these captured headers are forwarded. Include `cookie` for cookie-auth endpoints, `user-agent` when behavior depends on it. `capture.headers` names are auto-added here. |
@@ -190,7 +196,7 @@ proof request matches. **Every endpoint must include a method rule and a URL rul
190
196
  ## 5. `revealRules[]`
191
197
 
192
198
  Describes exactly what the artifact may disclose. Each disclosed `RECV BODY` value becomes
193
- a claim. These rules are part of `parserHash`.
199
+ a claim. These rules are part of `policyHash`.
194
200
 
195
201
  | Field | Req? | Type | Description |
196
202
  |---|---|---|---|
@@ -324,7 +330,8 @@ instead of the template `url`, still constrained to the pinned host:
324
330
  ```
325
331
 
326
332
  The template `url` is just the stable prefix (host/SNI + `urlContains`); the per-user URL
327
- is captured and replayed. Not part of the parser hash.
333
+ is captured and replayed. It does not change the policy identity unless governance
334
+ tooling explicitly includes it.
328
335
 
329
336
  ---
330
337
 
@@ -358,39 +365,40 @@ Ties the provider to verifier-side allowlists.
358
365
 
359
366
  ```json
360
367
  "templateGovernance": {
361
- "templateHash": "dev-acme-current-user-v1-template",
362
- "parserHash": "parser-sha256:0000…0000"
368
+ "policyHash": "policy-sha256:0000…0000"
363
369
  }
364
370
  ```
365
371
 
366
372
  | Field | Req? | Type | Description |
367
373
  |---|---|---|---|
368
- | `templateHash` | yes | `string` | Template identity accepted by the verifier. |
369
- | `parserHash` | yes | `string` | `parser-sha256:<64 hex>` derived from provider id, endpoint ids/order, response types, and reveal rules. See below. |
374
+ | `policyHash` | yes | `string` | `policy-sha256:<64 hex>` identity accepted by the SDK and verifier for this provider policy. |
370
375
  | `fixtureSetHash` | no | `string` | Fixture-set identity. Defaults to `unversioned-fixtures`. |
371
376
  | `governancePolicyVersion` | no | `string` | Defaults to `embedded-registry`. |
372
- | `providerActivationState` | no | `string` | Defaults to `experimental`; production policy should require governed active templates. |
373
377
 
374
- **Parser hash.** It is derived, not arbitrary. The test script canonicalizes:
378
+ **Policy hash.** It is derived, not arbitrary. The provider-policy tooling
379
+ canonicalizes security-sensitive provider policy fields:
375
380
 
376
381
  ```json
377
382
  {
378
- "schema": "satya-provider-parser-policy-v1",
383
+ "schema": "satya-provider-policy-v1",
379
384
  "providerId": "<provider id>",
385
+ "target": { "host": "<host>" },
386
+ "tlsIdentityPolicy": { "expectedSni": "<sni>", "spkiSha256B64Pins": [] },
380
387
  "endpoints": [{ "id": "<id>", "responseType": "<type>", "revealRules": [] }]
381
388
  }
382
389
  ```
383
390
 
384
- SHA-256 hashes it, and stores `parser-sha256:<hex>`. Any change to `providerId`, endpoint
385
- ids/order, `responseType`, or `revealRules` changes it. After editing providers:
391
+ It SHA-256 hashes the canonical policy and stores `policy-sha256:<hex>`. Any
392
+ change to provider id, target host, TLS identity policy, endpoint ids/order,
393
+ response type, or reveal rules should change it. After editing providers:
386
394
 
387
395
  ```bash
388
396
  cd platform_sdks/expo-satya-attest
389
- npm run test:providers # prints the expected parser hash when stale
397
+ npm run test:providers
390
398
  ```
391
399
 
392
- The client and backend verifier pin provider id, template hash, parser hash, activation
393
- state, and SPKI policy before accepting an artifact.
400
+ The client and backend verifier pin provider id, policy hash, and SPKI policy before
401
+ accepting an artifact.
394
402
 
395
403
  ---
396
404
 
@@ -487,7 +495,7 @@ console.log(body.match(/octolytics-actor-login" content="(.*?)"/)?.[1]);
487
495
  - raw `allowedRequestHeaders`, `allowedResponseBodyJsonPaths`, and `privacyPolicy` are
488
496
  rejected (the loader derives them from `revealRules`),
489
497
  - SPKI pins are SHA-256 base64,
490
- - `parserHash` matches the canonical parser policy.
498
+ - `policyHash` matches the canonical provider policy.
491
499
 
492
500
  ## 12. Authoring tips
493
501
 
@@ -1,235 +1,137 @@
1
- # Provider Registry
1
+ # Provider Registry Runtime
2
2
 
3
- `@burnt-labs/expo-satya-attest` ships with a built-in provider registry at
4
- [`src/providers.json`](./src/providers.json) a vendored copy of the centralized
5
- registry in [`burnt-labs/provider-bank`](https://github.com/burnt-labs/provider-bank)
6
- (`provider-bank/providers.json`), which is the source of truth shared across
7
- services. Apps can also supply their own registry when they want provider templates
8
- outside the SDK package.
3
+ `@burnt-labs/expo-satya-attest` loads provider policy from the Provider Registry API at
4
+ runtime. The SDK no longer ships a bundled registry JSON or supports local registry
5
+ fallbacks.
9
6
 
10
- Use a custom registry when:
7
+ Default API:
11
8
 
12
- - your app needs providers that are not in the SDK package,
13
- - your app wants to pin a private allow-list,
14
- - your team wants to update provider templates through its own release process.
9
+ ```text
10
+ https://api.provider-registry.burnt.com
11
+ ```
15
12
 
16
- For the provider JSON schema, optional fields, parser hash rules, and authoring
17
- guidance, see [`PROVIDER_CONFIG.md`](./PROVIDER_CONFIG.md).
13
+ Default SDK load flow:
18
14
 
19
- ## Loading A Custom Registry
15
+ 1. `GET {PROVIDER_REGISTRY_API}/api/providers/{providerId}`
16
+ 2. Reject missing or inactive provider records.
17
+ 3. Normalize the raw provider into the runtime shape needed by the SDK.
18
+ 4. Enforce SDK-owned runtime safety checks: HTTPS URLs, no user roots, SPKI pin syntax,
19
+ selected endpoint request matching, and supported reveal parsing.
20
20
 
21
- For a hosted registry:
21
+ The SDK intentionally loads one provider at a time. The Provider Registry service owns
22
+ provider-schema governance, migration compatibility, versioning, and registry-wide
23
+ metadata checks.
22
24
 
23
- ```tsx
24
- import { SatyaProviderAttestButton } from '@burnt-labs/expo-satya-attest';
25
-
26
- export function PayrollProof() {
27
- return (
28
- <SatyaProviderAttestButton
29
- providerId="acme.payroll.v1"
30
- providerRegistrySource={{
31
- url: 'https://example.com/.well-known/satya/providers.json',
32
- timeoutMs: 10000,
33
- maxBytes: 524288,
34
- }}
35
- providerPolicyRefresh="verifier-required"
36
- transportConfig={{
37
- notaryUrl: 'https://verifier.example.com',
38
- cloudProjectNumber: 0,
39
- }}
40
- verifyBackend
41
- buttonLabel="Open payroll"
42
- />
43
- );
44
- }
25
+ ## SDK Init
26
+
27
+ Configure the SDK once during app startup:
28
+
29
+ ```ts
30
+ import { initSatyaAttest } from '@burnt-labs/expo-satya-attest';
31
+
32
+ initSatyaAttest({
33
+ providerId: 'kaggle.current_user.v1',
34
+ providerRegistryApi: 'https://api.provider-registry.burnt.com',
35
+ registryTimeoutMs: 15000,
36
+ registryMaxBytes: 524288,
37
+ logLevel: 'warn',
38
+ logger: (entry) => {
39
+ // Send to your app logger, if desired.
40
+ },
41
+ });
45
42
  ```
46
43
 
47
- For an in-app registry object:
44
+ Options:
48
45
 
49
- ```tsx
50
- import {
51
- SatyaProviderAttestButton,
52
- type SatyaProviderRegistry,
53
- } from '@burnt-labs/expo-satya-attest';
54
-
55
- const registry: SatyaProviderRegistry = {
56
- schemaVersion: '1.0.0',
57
- providers: [
58
- // provider templates
59
- ],
60
- };
46
+ | Option | Default | Description |
47
+ | --------------------- | ----------------------------------------: | --------------------------------------------------------------------------- |
48
+ | `providerId` | none | Provider id to load from the registry API. Required before provider lookup. |
49
+ | `providerRegistryApi` | `https://api.provider-registry.burnt.com` | HTTPS base URL for the Provider Registry API. |
50
+ | `registryTimeoutMs` | `15000` | Per-request timeout for provider fetches. |
51
+ | `registryMaxBytes` | `524288` | Maximum response body size. |
52
+ | `logLevel` | env-driven or `silent` | One of `silent`, `error`, `warn`, `info`, `debug`, `trace`. |
53
+ | `logger` | none | Optional structured log sink. |
54
+ | `verboseLogging` | `false` | When true, disables default redaction. Do not enable in production. |
61
55
 
62
- <SatyaProviderAttestButton
63
- providerId="acme.payroll.v1"
64
- providerRegistrySource={registry}
65
- providerPolicyRefresh="verifier-required"
66
- transportConfig={{ notaryUrl: 'https://verifier.example.com' }}
67
- />;
56
+ The Expo example also reads `EXPO_PUBLIC_PROVIDER_ID` and
57
+ `EXPO_PUBLIC_PROVIDER_REGISTRY_API` so app developers can point a build at one provider
58
+ and registry API without code changes.
59
+
60
+ ## Provider Lookup
61
+
62
+ Load the configured provider template for diagnostics or custom UI:
63
+
64
+ ```ts
65
+ import { initSatyaAttest, loadProviderTemplate } from '@burnt-labs/expo-satya-attest';
66
+
67
+ initSatyaAttest({ providerId: 'kaggle.current_user.v1' });
68
+
69
+ const template = await loadProviderTemplate();
68
70
  ```
69
71
 
70
- To populate your own selector UI:
72
+ The SDK-owned button resolves the configured provider from the Provider Registry API:
71
73
 
72
74
  ```tsx
73
- import { listProviderRefs, loadProviderRegistry } from '@burnt-labs/expo-satya-attest';
74
-
75
- const registry = await loadProviderRegistry({
76
- url: 'https://example.com/.well-known/satya/providers.json',
77
- });
78
- const providers = listProviderRefs(registry);
75
+ <SatyaProviderAttestButton
76
+ providerPolicyRefresh="verifier-first"
77
+ transportConfig={{ verifierUrl: 'https://verifier.example.com' }}
78
+ verifyBackend
79
+ />
79
80
  ```
80
81
 
81
- `providerTemplate` still works for one-off integrations and wins over
82
- `providerRegistrySource` when both are supplied.
82
+ `providerTemplate` remains available for tightly controlled tests or one-off
83
+ integrations where the host app already owns a full template object. There is no
84
+ alternate registry-source prop and no local HTTP registry mode.
83
85
 
84
- ## Registry URL Rules
86
+ ## Supporting Endpoints
85
87
 
86
- Hosted registries are fetched with `GET` and must use HTTPS by default.
88
+ - `GET /api/providers` is useful for registry diagnostics and admin UIs.
89
+ - `GET /api/providers/{providerId}` is the SDK provider config source.
90
+ - `GET /.well-known/provider-registry/providers.json` is still useful for verifier
91
+ startup and registry-wide diagnostics.
87
92
 
88
- ```ts
89
- providerRegistrySource={{
90
- url: 'https://example.com/.well-known/satya/providers.json',
91
- headers: { Authorization: 'Bearer ...' },
92
- timeoutMs: 10000,
93
- maxBytes: 524288
94
- }}
95
- ```
93
+ ## Errors
94
+
95
+ Provider registry failures throw `SatyaError` with a stable `code`, message, optional
96
+ context, and optional cause. Codes include:
96
97
 
97
- Security rules enforced by the SDK:
98
+ - `SATYA_REGISTRY_INFO_MISMATCH`
99
+ - `SATYA_REGISTRY_FETCH_FAILED`
100
+ - `SATYA_REGISTRY_INVALID`
101
+ - `SATYA_PROVIDER_NOT_FOUND`
102
+ - `SATYA_PROVIDER_POLICY_MISMATCH`
98
103
 
99
- - `https://` is required by default,
100
- - URL credentials such as `https://user:pass@example.com/...` are rejected,
101
- - request headers cannot contain newline characters,
102
- - fetches are timeout bounded,
103
- - response bodies are size bounded,
104
- - JSON is validated and cloned before use.
104
+ The SDK fails closed: it does not open the provider WebView when the registry cannot be
105
+ loaded or validated.
105
106
 
106
- `allowInsecureHttp: true` exists only for local development:
107
+ ## Logging And Redaction
108
+
109
+ SDK logs are structured and redacted by default. Tokens, cookies, auth headers, request
110
+ bodies, and response bodies are replaced with byte-count placeholders unless
111
+ `verboseLogging` is enabled. Use `logger` to mirror logs into a host app sink.
107
112
 
108
113
  ```ts
109
- providerRegistrySource={{
110
- url: 'http://127.0.0.1:8080/providers.json',
111
- allowInsecureHttp: true
112
- }}
114
+ initSatyaAttest({
115
+ logLevel: 'debug',
116
+ logger: (entry) => myLogger.debug(entry),
117
+ });
113
118
  ```
114
119
 
115
- Do not use insecure HTTP for production registries. A registry controls provider
116
- hosts, login URLs, WebView injection, request match rules, reveal rules, template
117
- hashes, parser hashes, and SPKI pin fallback policy.
120
+ ## Registry Shape
118
121
 
119
- ## File Format
120
-
121
- Top-level registry shape:
122
+ Top-level artifact:
122
123
 
123
124
  ```json
124
125
  {
125
126
  "schemaVersion": "1.0.0",
126
- "providers": [
127
- {
128
- "schemaVersion": "1.0.0",
129
- "providerId": "acme.current_user.v1",
130
- "name": "Acme",
131
- "login": {
132
- "url": "https://acme.example/login"
133
- },
134
- "endpoints": [
135
- {
136
- "id": "primary",
137
- "url": "https://acme.example/api/current-user",
138
- "method": "GET",
139
- "headers": ["accept", "cookie", "user-agent"],
140
- "responseType": "json",
141
- "requestMatchRules": [
142
- { "type": "methodEquals", "pattern": "GET" },
143
- { "type": "urlContains", "pattern": "/api/current-user" }
144
- ],
145
- "revealRules": [
146
- {
147
- "action": "REVEAL",
148
- "direction": "RECV",
149
- "part": "BODY",
150
- "params": {
151
- "type": "json",
152
- "path": "$.accountHolder.name",
153
- "alias": "accountHolderName"
154
- }
155
- }
156
- ]
157
- }
158
- ],
159
- "tlsIdentityPolicy": {
160
- "expectedSni": "acme.example",
161
- "spkiSha256B64Pins": ["AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="]
162
- },
163
- "templateGovernance": {
164
- "templateHash": "dev-acme-current-user-v1-template",
165
- "parserHash": "parser-sha256:0000000000000000000000000000000000000000000000000000000000000000"
166
- }
167
- }
168
- ]
127
+ "registryVersion": 42,
128
+ "minimumAllowedRegistryVersion": 40,
129
+ "currentSnapshotSha256": "0123456789abcdef",
130
+ "generatedAt": "2026-06-18T00:00:00.000Z",
131
+ "providers": []
169
132
  }
170
133
  ```
171
134
 
172
- The SDK normalizes an endpoint into the compatibility `proofTarget` shape used by
173
- native replay. Raw provider configs should use endpoint `headers` instead of
174
- `privacyPolicy.allowedRequestHeaders`; the response reveal allowlist
175
- (`privacyPolicy.allowedResponseReveals`, plus the legacy `allowedResponseBodyJsonPaths`
176
- subset) is derived from `revealRules`, so raw configs should not include those keys.
177
-
178
- `responseType` may be `json`, `html`, or `text`. Reveal rules support three
179
- `params.type` values: `json` (JSON path), `regex` (a capture group over the raw body —
180
- the mechanism behind HTML/text providers), and `jsonRegex` (a JSON-path value run through
181
- a regex). `regex`/`jsonRegex` reveals require an explicit `params.alias`. See
182
- [`PROVIDER_CONFIG.md`](./PROVIDER_CONFIG.md#reveal-rules) for the full reveal-rule schema.
183
-
184
- ## Validation Rules
185
-
186
- The SDK rejects custom registries unless each provider satisfies the runtime checks
187
- documented in [`PROVIDER_CONFIG.md`](./PROVIDER_CONFIG.md#validation-checklist). The
188
- built-in `src/providers.json` has an additional test guard:
189
-
190
- ```bash
191
- cd platform_sdks/expo-satya-attest
192
- npm run test:providers
193
- ```
194
-
195
- That script validates provider ids, endpoints, request matching, `responseType`, reveal
196
- rules (`json` / `regex` / `jsonRegex`), reveal aliases, SPKI pin syntax, and canonical
197
- parser hashes. It also rejects the old raw schema fields `privacyPolicy`,
198
- `allowedRequestHeaders`, and `allowedResponseBodyJsonPaths`.
199
-
200
- `npm test` runs this provider check and then a reveal-rule unit suite
201
- (`test:reveal`, `internal/module_scripts/test-reveal-rules.mjs`) that exercises the
202
- compiled validator against positive and negative reveal-rule cases.
203
-
204
- ## Security Review Notes
205
-
206
- Threat model: a provider registry controls the login URL, WebView injection scripts,
207
- request matching rules, replay URL, trusted SNI, template hash, parser hash, reveal
208
- rules, and optional SPKI pins. Treat it as trusted policy, not ordinary app content.
209
-
210
- Confirmed protections in the SDK:
211
-
212
- - remote registries are HTTPS-only by default, with timeout and size limits,
213
- - registry URLs with embedded credentials are rejected,
214
- - registry request headers are sanitized for newline injection,
215
- - templates are validated and cloned before use,
216
- - custom templates cannot enable user-installed roots,
217
- - replay URL, endpoint host, and expected SNI must agree,
218
- - request matching must bind both method and URL,
219
- - verifier SPKI policy is checked against provider id, host, template hash, and
220
- parser hash before those pins are used,
221
- - backend verification independently re-derives trusted template and pin policy.
222
-
223
- Residual risks and required operating practices:
224
-
225
- - a malicious host app can intentionally pass a malicious registry or template. The SDK
226
- is not a trust boundary against the application that embeds it,
227
- - a compromised registry host can change templates. Production backends must reject
228
- unknown `templateHash` / `parserHash` values and should use
229
- `providerPolicyRefresh="verifier-required"`,
230
- - do not put secrets in registry URLs. Use short-lived headers if a private registry
231
- needs authentication,
232
- - do not use `allowInsecureHttp` outside local development,
233
- - keep verifier provider policy in sync with custom registry templates. Client-side
234
- registry validation protects replay setup; verifier policy decides whether an
235
- artifact is acceptable.
135
+ Provider and endpoint fields are documented in [`PROVIDER_CONFIG.md`](./PROVIDER_CONFIG.md).
136
+ The SDK validates only the fields it needs to execute the mobile flow safely; registry
137
+ schema governance and migrations stay on the Provider Registry service.
package/PUBLISHING.md CHANGED
@@ -107,16 +107,16 @@ npm run check:pack
107
107
 
108
108
  What each check covers:
109
109
 
110
- | Check | Purpose |
111
- |---|---|
112
- | `check:metadata` | Confirms package metadata, README, LICENSE, plugin, and module config exist. |
113
- | `clean` + `build` | Rebuilds TypeScript output in `build/`. |
114
- | `lint` | Runs ESLint over `src/`. |
115
- | `test:providers` | Validates provider ids, template hashes, parser hashes, request match rules, HTTPS proof URLs, SNI, and SPKI pins. |
116
- | `test:publishing-workflows` | Confirms publish workflows build iOS artifacts with simulator slices and matching Rust targets. |
117
- | `check:example` | Type-checks the Expo example when its dependencies are installed. |
118
- | `check:native-artifacts` | Fails if Android `.so`, generated Kotlin, iOS XCFramework, or generated Swift glue are missing. |
119
- | `check:pack` | Runs `npm pack --dry-run --json` and verifies the actual tarball contents. |
110
+ | Check | Purpose |
111
+ | --------------------------- | ------------------------------------------------------------------------------------------------- |
112
+ | `check:metadata` | Confirms package metadata, README, LICENSE, plugin, and module config exist. |
113
+ | `clean` + `build` | Rebuilds TypeScript output in `build/`. |
114
+ | `lint` | Runs ESLint over `src/`. |
115
+ | `test:providers` | Validates provider ids, policy hashes, request match rules, HTTPS proof URLs, SNI, and SPKI pins. |
116
+ | `test:publishing-workflows` | Confirms publish workflows build iOS artifacts with simulator slices and matching Rust targets. |
117
+ | `check:example` | Type-checks the Expo example when its dependencies are installed. |
118
+ | `check:native-artifacts` | Fails if Android `.so`, generated Kotlin, iOS XCFramework, or generated Swift glue are missing. |
119
+ | `check:pack` | Runs `npm pack --dry-run --json` and verifies the actual tarball contents. |
120
120
 
121
121
  The package uses a `files` whitelist in `package.json`, so `node_modules`, the example
122
122
  app, `.env` files, `.DS_Store`, build caches, and generated tarballs are kept out of the
@@ -135,7 +135,6 @@ Check that the tarball contains:
135
135
 
136
136
  ```text
137
137
  build/
138
- src/providers.json
139
138
  app.plugin.js
140
139
  expo-module.config.json
141
140
  android/src/main/
@@ -189,33 +188,37 @@ npm version patch
189
188
  npm publish
190
189
  ```
191
190
 
192
- ## GitHub Packages Preview
191
+ ## npm Snapshots
193
192
 
194
- Pushes to `earnos-ready-plugin` publish a preview package to GitHub Packages with a
193
+ Every push to `main` publishes a snapshot package to the public npm registry with a
195
194
  unique prerelease version:
196
195
 
197
196
  ```text
198
- 0.1.0-earnos.<run>.<attempt>.sha-<commit>
197
+ 1.0.1-snapshot.<run>.<attempt>.sha-<commit>
199
198
  ```
200
199
 
201
- The workflow uses the `earnos-ready` dist-tag so test apps do not need to know the
202
- generated version:
200
+ The snapshot workflow increments the package's patch base in CI before publishing. For
201
+ example, if `package.json` is `1.0.0`, the snapshot version is based on `1.0.1`:
202
+ `1.0.1-snapshot.<run>.<attempt>.sha-<commit>`.
203
+
204
+ Snapshots use the `snapshot` dist-tag so test apps do not need to know the generated
205
+ version:
203
206
 
204
207
  ```bash
205
- @burnt-labs:registry=https://npm.pkg.github.com
206
- //npm.pkg.github.com/:_authToken=${GITHUB_PACKAGES_TOKEN}
208
+ npm install @burnt-labs/expo-satya-attest@snapshot
209
+ npx expo install react-native-webview
207
210
  ```
208
211
 
209
- Then install the preview package:
212
+ To inspect the exact snapshot version currently behind the dist-tag:
210
213
 
211
214
  ```bash
212
- npm install @burnt-labs/expo-satya-attest@earnos-ready
213
- npx expo install react-native-webview
215
+ npm view @burnt-labs/expo-satya-attest dist-tags.snapshot
214
216
  ```
215
217
 
216
- Use a GitHub token with `read:packages` for `GITHUB_PACKAGES_TOKEN`. The branch preview
217
- workflow publishes with the repository `GITHUB_TOKEN`, `packages: write`, and does not
218
- publish to npm.
218
+ Snapshots are not tagged as `latest`. Stable releases still require a matching
219
+ `expo-satya-attest-vX.Y.Z` or `vX.Y.Z` tag and publish through the stable release
220
+ workflow. Prefer the package-specific `expo-satya-attest-vX.Y.Z` form in this
221
+ monorepo.
219
222
 
220
223
  ## Post-Publish Smoke Test
221
224
 
@@ -268,7 +271,7 @@ GitHub release tarball smoke test:
268
271
 
269
272
  ```bash
270
273
  cd /private/tmp/SatyaSmoke
271
- npm install https://github.com/<owner>/<repo>/releases/download/expo-satya-attest-v0.2.2/burnt-labs-expo-satya-attest-0.2.2.tgz
274
+ npm install https://github.com/<owner>/<repo>/releases/download/expo-satya-attest-v1.0.0/burnt-labs-expo-satya-attest-1.0.0.tgz
272
275
  npx expo install react-native-webview
273
276
  ```
274
277
 
@@ -276,7 +279,7 @@ For a raw Git install, publish the SDK from a dedicated repo or a subtree/split
276
279
  where the SDK package is at the Git root:
277
280
 
278
281
  ```bash
279
- npm install github:<owner>/<sdk-repo>#v0.2.2
282
+ npm install github:<owner>/<sdk-repo>#v1.0.0
280
283
  ```
281
284
 
282
285
  Do not document a normal monorepo Git URL as plug-and-play unless the Git ref has