@shuttle.technology/authorization 0.0.0-stage → 0.2.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 (93) hide show
  1. package/CHANGELOG.md +191 -0
  2. package/README.md +1124 -2
  3. package/dist/accountLists.d.ts +28 -0
  4. package/dist/accountLists.js +27 -0
  5. package/dist/aesGcmSiv.d.ts +14 -0
  6. package/dist/aesGcmSiv.js +160 -0
  7. package/dist/auth.d.ts +68 -0
  8. package/dist/auth.js +189 -0
  9. package/dist/balances.d.ts +31 -0
  10. package/dist/balances.js +44 -0
  11. package/dist/canonicalize.d.ts +19 -0
  12. package/dist/canonicalize.js +107 -0
  13. package/dist/client.d.ts +152 -0
  14. package/dist/client.js +781 -0
  15. package/dist/clientTypes.d.ts +56 -0
  16. package/dist/clientTypes.js +5 -0
  17. package/dist/configuration.d.ts +48 -0
  18. package/dist/configuration.js +72 -0
  19. package/dist/consentDebit.d.ts +36 -0
  20. package/dist/consentDebit.js +95 -0
  21. package/dist/credentials.d.ts +116 -0
  22. package/dist/credentials.js +315 -0
  23. package/dist/debitPermissionWire.d.ts +90 -0
  24. package/dist/debitPermissionWire.js +118 -0
  25. package/dist/debitPermissions.d.ts +39 -0
  26. package/dist/debitPermissions.js +117 -0
  27. package/dist/deviceKey.d.ts +13 -0
  28. package/dist/deviceKey.js +28 -0
  29. package/dist/deviceRecovery.d.ts +40 -0
  30. package/dist/deviceRecovery.js +143 -0
  31. package/dist/deviceShare.d.ts +9 -0
  32. package/dist/deviceShare.js +24 -0
  33. package/dist/deviceShareEnvelope.d.ts +13 -0
  34. package/dist/deviceShareEnvelope.js +139 -0
  35. package/dist/deviceShares.d.ts +91 -0
  36. package/dist/deviceShares.js +204 -0
  37. package/dist/errors.d.ts +280 -0
  38. package/dist/errors.js +85 -0
  39. package/dist/linkedChecks.d.ts +17 -0
  40. package/dist/linkedChecks.js +31 -0
  41. package/dist/linkedRecovery.d.ts +40 -0
  42. package/dist/linkedRecovery.js +49 -0
  43. package/dist/linkedRegistrations.d.ts +11 -0
  44. package/dist/linkedRegistrations.js +109 -0
  45. package/dist/linkedSendDisplay.d.ts +73 -0
  46. package/dist/linkedSendDisplay.js +84 -0
  47. package/dist/linkedWalletSignals.d.ts +22 -0
  48. package/dist/linkedWalletSignals.js +101 -0
  49. package/dist/linkedWallets.d.ts +401 -0
  50. package/dist/linkedWallets.js +436 -0
  51. package/dist/me.d.ts +27 -0
  52. package/dist/me.js +30 -0
  53. package/dist/mediatedOperation.d.ts +27 -0
  54. package/dist/mediatedOperation.js +68 -0
  55. package/dist/mobile.d.ts +64 -0
  56. package/dist/mobile.js +69 -0
  57. package/dist/modeC.d.ts +131 -0
  58. package/dist/modeC.js +248 -0
  59. package/dist/modeCLinked.d.ts +207 -0
  60. package/dist/modeCLinked.js +270 -0
  61. package/dist/pages.d.ts +22 -0
  62. package/dist/pages.js +45 -0
  63. package/dist/poll.d.ts +15 -0
  64. package/dist/poll.js +76 -0
  65. package/dist/redirects.d.ts +45 -0
  66. package/dist/redirects.js +108 -0
  67. package/dist/requestGrant.d.ts +169 -0
  68. package/dist/requestGrant.js +243 -0
  69. package/dist/sends.d.ts +89 -0
  70. package/dist/sends.js +127 -0
  71. package/dist/serviceGrants.d.ts +52 -0
  72. package/dist/serviceGrants.js +46 -0
  73. package/dist/slice4.d.ts +187 -0
  74. package/dist/slice4.js +299 -0
  75. package/dist/streams.d.ts +212 -0
  76. package/dist/streams.js +282 -0
  77. package/dist/trackedWallets.d.ts +53 -0
  78. package/dist/trackedWallets.js +104 -0
  79. package/dist/transferStatus.d.ts +45 -0
  80. package/dist/transferStatus.js +43 -0
  81. package/dist/walletCreateGrant.d.ts +62 -0
  82. package/dist/walletCreateGrant.js +89 -0
  83. package/dist/walletDisplayParts.d.ts +17 -0
  84. package/dist/walletDisplayParts.js +47 -0
  85. package/dist/walletEvents.d.ts +43 -0
  86. package/dist/walletEvents.js +97 -0
  87. package/dist/walletLimits.d.ts +65 -0
  88. package/dist/walletLimits.js +102 -0
  89. package/dist/walletOperations.d.ts +209 -0
  90. package/dist/walletOperations.js +317 -0
  91. package/dist/webRenewal.d.ts +92 -0
  92. package/dist/webRenewal.js +179 -0
  93. package/package.json +65 -3
package/CHANGELOG.md ADDED
@@ -0,0 +1,191 @@
1
+ # Changelog
2
+
3
+ All notable changes to `@shuttle.technology/authorization`. Versions follow
4
+ [Semantic Versioning](https://semver.org/); before 1.0.0 a minor version may
5
+ change the public API.
6
+
7
+ ## 0.2.0 — release candidate
8
+
9
+ - Uses the public package name `@shuttle.technology/authorization`.
10
+ - Preserves all eight current entry points, including
11
+ `./debit-permissions`, and the latest recovery, wallet-create grant,
12
+ registration, debit, session, wallet, and Streams behavior described below.
13
+ - Ships compiled ESM JavaScript and TypeScript declarations only; source maps,
14
+ TypeScript source, tests, demos, examples, and local state are excluded.
15
+
16
+ ### Any domain, and the current page by default
17
+
18
+ - `initializeAuthorizationClient()` takes `ClientSettings`: on the web,
19
+ `applicationOrigin` and `redirectUri` are optional and default to the current
20
+ page's origin and the current page.
21
+ - The app's origin and redirect may be http on a loopback host (`localhost`,
22
+ `127.0.0.1`, `[::1]`) for local development, besides https.
23
+ - A public client registered for any origin answers `redirects: ["*"]`; the
24
+ SDK accepts it and any redirect its own checks accept.
25
+
26
+ ### Debits come with the grant
27
+
28
+ - A service that holds `wallet:debit:user` gets its debit permission with
29
+ every wallet the person opens to it, in the same passkey confirmation:
30
+ `createWallet({ network, grant })` and `createServiceGrant()` take nothing
31
+ new. The creation's and the grant's display name the service's ceilings
32
+ (`display.debit`), and the provider's page says them.
33
+ - `walletOperationResult()` and `operationResult()` execute the permission
34
+ the consent authorized, with the device share the SDK keeps sealed to the
35
+ share keeper's key, and report `result.debit`: `succeeded` (with the
36
+ permission's operation ID) or `not_set` with `code`.
37
+ - `debitPermissions().executeDebitPermission()` without keys hands the share
38
+ the SDK keeps; the keys of an app that keeps its own share are unchanged.
39
+
40
+ ### A wallet keeps working in a new browser
41
+
42
+ - The SDK keeps each wallet's device share itself, with the non-extractable
43
+ device key it is sealed to: in the origin's IndexedDB on the web, in the
44
+ `deviceShares` store (`DeviceShareStore`) the app passes in the
45
+ dependencies on mobile (and optionally on the web).
46
+ - `createWallet({ network })` without `recipientPublicKey` makes the device
47
+ key in the SDK; `walletOperationResult()` keeps the created share. Calls
48
+ with the same `Idempotency-Key`, also at once, name the same key. The call with the app's
49
+ own key is unchanged.
50
+ - `linkedWallets().executeSend(id, version, key)` without a share sends with
51
+ the kept one, resealed to the transport key read right before.
52
+ `linkedWallets().deviceShareFor(linkedWalletId)` is that share for a Mode C
53
+ request (`signLinkedMediatedRequest`). A share the app passes itself is sent
54
+ as before and the SDK recovers nothing for it.
55
+ - In a browser that holds no share of the wallet (a new domain, cleared site
56
+ data, another browser or device) these calls first recover it: one passkey
57
+ confirmation on the provider's page (`wallet.recover` naming
58
+ `linked_wallet_id` and the new device key), after which the share the
59
+ wallet had elsewhere stops working. The tabs of one browser recover a wallet
60
+ once between them, under one Web Lock per wallet.
61
+ - A kept share that a recovery on another device replaced is told by the
62
+ device key the provider names for the wallet (`linkedWallets().deviceKey()`,
63
+ `GET /v1/linked-wallets/{id}/device-key`) and recovered with one passkey
64
+ confirmation. Every kept record carries its device key's `publicKeyHex`.
65
+ - A confirmed recovery is kept pending (its device key, operation and execute
66
+ key, no share) before it is executed. One whose end is not known yet fails
67
+ the call with `device_recovery_failed`, and the next call, in any tab,
68
+ resumes that same operation instead of starting another, also after an
69
+ execution the provider refused while another recovery of the wallet was
70
+ unresolved. A share resumed or recovered while another device recovered
71
+ after it is recovered once more, then `device_recovery_failed`. A creation's
72
+ result read late never replaces a recovery another tab kept.
73
+ - Optional: `linkedWallets().hasDeviceShare(linkedWalletId)` and
74
+ `linkedWallets().recoverDevice(linkedWalletId, { credentialId?, signal?, force? })`;
75
+ `force` recovers even when a current share is kept.
76
+ - New `ClientFlowError` codes: `device_share_unavailable`,
77
+ `device_recovery_requires_passkey`, `hosted_callback_unavailable`,
78
+ `device_recovery_not_confirmed`, `device_recovery_failed`.
79
+ - `challengeOperation()` and `challengeWalletOperation()` answer
80
+ `callbackUri`, the redirect the host's `openHosted` resolved with, when it
81
+ resolved one.
82
+ - `walletOperationResult()` reads a `device_share_recovered` result
83
+ (`linkedWalletId`, `deviceShare`), and a wallet operation may be a
84
+ `wallet.recover` of a linked wallet (`LinkedRecoverDisplay`). Code that told
85
+ a linked send's display by `"linkedWalletId" in display` now also checks
86
+ `display.kind === "wallet.send"`.
87
+ - The demo page sends from a wallet in any browser of the account: the first
88
+ send there asks for the passkey once.
89
+
90
+ ### Create a wallet and connect it in one confirmation
91
+
92
+ - `createWallet({ network, recipientPublicKey?, grant? })`: `grant`
93
+ (`{ servicePrincipalId, scopes, externalRef? }`, the rules of
94
+ `createServiceGrant()`, one to three scopes) opens the new wallet to a
95
+ service in the same passkey confirmation. The SDK checks it locally
96
+ (`invalid_operation_create`), sends the scopes in the provider's order and
97
+ refuses a display that does not name the grant back.
98
+ - The `wallet.create` display carries `grant`, and a `wallet_created` result
99
+ carries `grant: { state, operationId?, linkedWalletId?, code? }`:
100
+ `succeeded`, `pending_target_fence` (read `client.operation(operationId)`
101
+ until it ends) or `not_set` with `code` (`DEPENDENCY_UNAVAILABLE`: read the
102
+ result again; any other: `createServiceGrant()` alone). The plain call is
103
+ unchanged.
104
+ - The demo page offers its backend's service (`backendService`) in the
105
+ creation's confirmation, on by default, and says whether the service sees
106
+ the wallet.
107
+
108
+ ### Current capability summary
109
+
110
+ (Integration of 28 October 2026: an account's grant list may show `pending_source`, a first
111
+ `streams:read` grant waiting for Streams.)
112
+
113
+ The first release: the client of a person's session for web and mobile apps.
114
+
115
+ ### Package
116
+
117
+ - ES modules in `dist/` with TypeScript declarations. Entry points: the root
118
+ (`AuthorizationClient`), `./mode-c-linked`, `./mode-c`, `./linked-wallets`,
119
+ `./debit-permissions`, `./streams`, `./device-key`, `./device-share`.
120
+ - No runtime dependencies. Needs `fetch` and WebCrypto: a current browser,
121
+ Node 20 or later, or a mobile runtime that provides both. The web channel
122
+ also needs the Web Locks API (`navigator.locks`).
123
+
124
+ ### Sign-in and session
125
+
126
+ - `login()` and `signup()` open the provider's hosted sign-in page, where the
127
+ person picks a method; `exchangeHandoff()` turns the redirect back into the
128
+ session. `login(method)` and `signup(method)` still start one method.
129
+ - Mobile: one `login()` call opens the hosted page in the system browser,
130
+ checks the app link and returns the session; the refresh token lives in the
131
+ secure storage the app supplies.
132
+ - `me()` returns the account, the session and every wallet of the account
133
+ (own and linked).
134
+ - `accessToken()` returns the session's access token for the app's own
135
+ backend, renewed first when it has less than 30 seconds to live.
136
+ - Web: the session renews in the background (`refreshSession()`, and every
137
+ call that needs a fresh token) from the provider's partitioned cookie, with
138
+ no window; the tabs of one app take turns under one Web Lock, and a
139
+ sign-in's exchange goes out under it too, so a late renewal never brings
140
+ back an older session. Without the
141
+ cookie the SDK raises `web_renewal_requires_navigation` and the app calls
142
+ `restoreSession()`, the top-level restore.
143
+ - Web: a renewal or restore answers only the session it renews. When a
144
+ sign-in in another tab put its own session in the shared cookie, the SDK
145
+ installs nothing, ends the session it held and raises `session_replaced`;
146
+ the app takes up the cookie's session with `refreshSession()` or signs the
147
+ person in again. A sign-in answer a logout or a newer sign-in overtook is
148
+ revoked, through the cookie when another tab replaced its CSRF token, and a
149
+ logout that overtook it confirms nothing until that revocation is
150
+ confirmed (an answer lost or malformed counts as unconfirmed). A caller's signal ends only its wait for an exchange or a
151
+ logout, never the request.
152
+
153
+ ### Wallets
154
+
155
+ - First wallet with a passkey (`bootstrapPasskey()`, `createWallet()`), the
156
+ device share sealed to a key of the device.
157
+ - Linked wallets: list, balances, events and a live signal stream, Streams
158
+ tracking, sends with the session (Mode B), speed-up and cancel, transfer
159
+ status, and the wallet's limits, changed with a passkey.
160
+ - Mode C: request-key enrollment on a linked wallet and the signed request a
161
+ service forwards.
162
+ - Debit permissions (`linkedWallets().debitPermissions()`): a service debits a
163
+ linked wallet without the device, within bounds the person confirms with a
164
+ passkey; the execute hands the device share to the platform share keeper,
165
+ sealed to the keeper's key. List and revoke.
166
+
167
+ ### Service grants
168
+
169
+ - `createServiceGrant()` gives a service read access to one wallet, with an
170
+ optional `externalRef`.
171
+ - `serviceGrants()` lists the grants the account gave, in every state, paged.
172
+ - `revokeServiceGrant()` withdraws one.
173
+
174
+ ### Errors
175
+
176
+ - `AuthorizationError.code` is typed: one of `AuthorizationErrorCodes`, the
177
+ codes of the provider's OpenAPI document, with `AuthorizationErrorContracts`
178
+ giving the status, `retryable` and `nextAction` of each.
179
+ - `isAuthorizationError(error, ...codes)`, `WalletLimitRefusals` and
180
+ `ModeCRefusals` for the refusals an app explains to the person.
181
+ `DEBIT_PERMISSION_INVALID` (403): a debit no active permission covers.
182
+
183
+ ## 0.1.0 — published 24 October 2026
184
+
185
+ - Initial public ESM package under `@shuttle.technology/authorization` with
186
+ TypeScript declarations and seven entry points.
187
+ - Supplied the then-current Authorization wallet/session and Streams client
188
+ surface. Version 0.2.0 adds the later session, recovery, wallet-create grant,
189
+ registration, debit-permission, and related API behavior recorded above.
190
+ - The published 0.1.0 archive is the authority for that version's exact
191
+ surface.