@calimero-network/mero-js 26.11.0 → 27.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 (220) hide show
  1. package/README.md +73 -288
  2. package/dist/cloud-v2/attestation.d.ts +91 -0
  3. package/dist/cloud-v2/attestation.js +135 -0
  4. package/dist/cloud-v2/capabilities.d.ts +30 -0
  5. package/dist/cloud-v2/capabilities.js +31 -0
  6. package/dist/cloud-v2/client.d.ts +426 -0
  7. package/dist/cloud-v2/client.js +646 -0
  8. package/dist/cloud-v2/errors.d.ts +98 -0
  9. package/dist/cloud-v2/errors.js +165 -0
  10. package/dist/cloud-v2/index.d.ts +10 -0
  11. package/dist/cloud-v2/index.js +5 -0
  12. package/dist/cloud-v2/passkey.d.ts +27 -0
  13. package/dist/cloud-v2/passkey.js +73 -0
  14. package/dist/crypto/internal.d.ts +3 -37
  15. package/dist/crypto/internal.js +3 -72
  16. package/dist/index.browser.mjs +4 -2
  17. package/dist/index.browser.mjs.map +4 -4
  18. package/dist/index.cjs +1750 -12772
  19. package/dist/index.cjs.map +4 -4
  20. package/dist/index.d.ts +3 -56
  21. package/dist/index.js +14 -75
  22. package/dist/index.mjs +1750 -12772
  23. package/dist/index.mjs.map +4 -4
  24. package/dist/sealed/index.d.ts +4 -4
  25. package/dist/sealed/index.js +2 -2
  26. package/dist/sealed/release.d.ts +21 -76
  27. package/dist/sealed/release.js +24 -108
  28. package/dist/sealed/sealed.d.ts +8 -56
  29. package/dist/sealed/sealed.js +11 -89
  30. package/dist/sealed/verify.d.ts +7 -13
  31. package/dist/sealed/verify.js +3 -7
  32. package/package.json +8 -13
  33. package/dist/account/account-admin.d.ts +0 -80
  34. package/dist/account/account-admin.js +0 -346
  35. package/dist/account/account.d.ts +0 -196
  36. package/dist/account/account.js +0 -269
  37. package/dist/account/application-id.d.ts +0 -50
  38. package/dist/account/application-id.js +0 -83
  39. package/dist/account/bootstrap-from-invitation.d.ts +0 -110
  40. package/dist/account/bootstrap-from-invitation.js +0 -80
  41. package/dist/account/create-context.d.ts +0 -103
  42. package/dist/account/create-context.js +0 -267
  43. package/dist/account/govern.d.ts +0 -24
  44. package/dist/account/govern.js +0 -50
  45. package/dist/account/index.d.ts +0 -26
  46. package/dist/account/index.js +0 -15
  47. package/dist/account/join-as-account.d.ts +0 -23
  48. package/dist/account/join-as-account.js +0 -34
  49. package/dist/account/join-with-node.d.ts +0 -115
  50. package/dist/account/join-with-node.js +0 -161
  51. package/dist/account/node-admin.d.ts +0 -20
  52. package/dist/account/node-admin.js +0 -33
  53. package/dist/account/relay-from-invitation.d.ts +0 -137
  54. package/dist/account/relay-from-invitation.js +0 -180
  55. package/dist/account/relay-login-error.d.ts +0 -32
  56. package/dist/account/relay-login-error.js +0 -34
  57. package/dist/account/session.d.ts +0 -266
  58. package/dist/account/session.js +0 -915
  59. package/dist/account/wordlist.d.ts +0 -16
  60. package/dist/account/wordlist.js +0 -273
  61. package/dist/admin-api/admin-client.d.ts +0 -688
  62. package/dist/admin-api/admin-client.js +0 -1230
  63. package/dist/admin-api/admin-factory.d.ts +0 -14
  64. package/dist/admin-api/admin-factory.js +0 -22
  65. package/dist/admin-api/admin-types.d.ts +0 -2046
  66. package/dist/admin-api/admin-types.js +0 -12
  67. package/dist/admin-api/index.d.ts +0 -4
  68. package/dist/admin-api/index.js +0 -5
  69. package/dist/admin-api/redeem-invitation.d.ts +0 -101
  70. package/dist/admin-api/redeem-invitation.js +0 -200
  71. package/dist/auth/index.d.ts +0 -34
  72. package/dist/auth/index.js +0 -67
  73. package/dist/auth-api/auth-client.d.ts +0 -31
  74. package/dist/auth-api/auth-client.js +0 -117
  75. package/dist/auth-api/auth-factory.d.ts +0 -7
  76. package/dist/auth-api/auth-factory.js +0 -41
  77. package/dist/auth-api/auth-types.d.ts +0 -130
  78. package/dist/auth-api/auth-types.js +0 -2
  79. package/dist/auth-api/index.d.ts +0 -3
  80. package/dist/auth-api/index.js +0 -4
  81. package/dist/capabilities.d.ts +0 -84
  82. package/dist/capabilities.js +0 -117
  83. package/dist/cloud/account-ownership.d.ts +0 -63
  84. package/dist/cloud/account-ownership.js +0 -87
  85. package/dist/cloud/cloud-client.d.ts +0 -949
  86. package/dist/cloud/cloud-client.js +0 -1068
  87. package/dist/cloud/connect.d.ts +0 -213
  88. package/dist/cloud/connect.js +0 -260
  89. package/dist/cloud/enrol-redirect.d.ts +0 -181
  90. package/dist/cloud/enrol-redirect.js +0 -244
  91. package/dist/cloud/index.d.ts +0 -12
  92. package/dist/cloud/index.js +0 -10
  93. package/dist/cloud/link-redirect.d.ts +0 -95
  94. package/dist/cloud/link-redirect.js +0 -121
  95. package/dist/cloud/link-state.d.ts +0 -36
  96. package/dist/cloud/link-state.js +0 -104
  97. package/dist/cloud/routing-proof.d.ts +0 -113
  98. package/dist/cloud/routing-proof.js +0 -96
  99. package/dist/device-cert/device-cert.d.ts +0 -189
  100. package/dist/device-cert/device-cert.js +0 -239
  101. package/dist/device-cert/device-scope.d.ts +0 -58
  102. package/dist/device-cert/device-scope.js +0 -76
  103. package/dist/device-cert/index.d.ts +0 -4
  104. package/dist/device-cert/index.js +0 -3
  105. package/dist/ephemeral/codec.d.ts +0 -4
  106. package/dist/ephemeral/codec.js +0 -12
  107. package/dist/ephemeral/index.d.ts +0 -57
  108. package/dist/ephemeral/index.js +0 -101
  109. package/dist/ephemeral/types.d.ts +0 -27
  110. package/dist/ephemeral/types.js +0 -1
  111. package/dist/errors/classify.d.ts +0 -65
  112. package/dist/errors/classify.js +0 -117
  113. package/dist/errors/index.d.ts +0 -2
  114. package/dist/errors/index.js +0 -1
  115. package/dist/events/group.d.ts +0 -95
  116. package/dist/events/group.js +0 -10
  117. package/dist/events/index.d.ts +0 -5
  118. package/dist/events/index.js +0 -2
  119. package/dist/events/sse.d.ts +0 -127
  120. package/dist/events/sse.js +0 -469
  121. package/dist/events/ws.d.ts +0 -57
  122. package/dist/events/ws.js +0 -212
  123. package/dist/http-client/api-response.d.ts +0 -15
  124. package/dist/http-client/api-response.js +0 -1
  125. package/dist/http-client/http-factory.d.ts +0 -71
  126. package/dist/http-client/http-factory.js +0 -68
  127. package/dist/http-client/http-types.d.ts +0 -87
  128. package/dist/http-client/http-types.js +0 -1
  129. package/dist/http-client/index.d.ts +0 -7
  130. package/dist/http-client/index.js +0 -11
  131. package/dist/http-client/path-segment.d.ts +0 -1
  132. package/dist/http-client/path-segment.js +0 -8
  133. package/dist/http-client/retry.d.ts +0 -5
  134. package/dist/http-client/retry.js +0 -82
  135. package/dist/http-client/signal-utils.d.ts +0 -2
  136. package/dist/http-client/signal-utils.js +0 -41
  137. package/dist/http-client/web-client.d.ts +0 -80
  138. package/dist/http-client/web-client.js +0 -557
  139. package/dist/invitation/index.d.ts +0 -2
  140. package/dist/invitation/index.js +0 -2
  141. package/dist/invitation/invitation.d.ts +0 -106
  142. package/dist/invitation/invitation.js +0 -104
  143. package/dist/login/index.d.ts +0 -4
  144. package/dist/login/index.js +0 -3
  145. package/dist/login/login.d.ts +0 -111
  146. package/dist/login/login.js +0 -110
  147. package/dist/login/session.d.ts +0 -124
  148. package/dist/login/session.js +0 -141
  149. package/dist/mero-js.d.ts +0 -231
  150. package/dist/mero-js.js +0 -469
  151. package/dist/namespace-op/index.d.ts +0 -2
  152. package/dist/namespace-op/index.js +0 -3
  153. package/dist/namespace-op/namespace-op.d.ts +0 -150
  154. package/dist/namespace-op/namespace-op.js +0 -191
  155. package/dist/nodeDiscovery.d.ts +0 -47
  156. package/dist/nodeDiscovery.js +0 -101
  157. package/dist/owner-op/index.d.ts +0 -2
  158. package/dist/owner-op/index.js +0 -3
  159. package/dist/owner-op/owner-op.d.ts +0 -119
  160. package/dist/owner-op/owner-op.js +0 -214
  161. package/dist/presence/relay-presence.d.ts +0 -56
  162. package/dist/presence/relay-presence.js +0 -107
  163. package/dist/presence/statement.d.ts +0 -12
  164. package/dist/presence/statement.js +0 -17
  165. package/dist/relay/index.d.ts +0 -4
  166. package/dist/relay/index.js +0 -2
  167. package/dist/relay/nonce-source.d.ts +0 -72
  168. package/dist/relay/nonce-source.js +0 -111
  169. package/dist/relay/relay-client.d.ts +0 -472
  170. package/dist/relay/relay-client.js +0 -518
  171. package/dist/relay-attestation/attest-node-key.d.ts +0 -66
  172. package/dist/relay-attestation/attest-node-key.js +0 -110
  173. package/dist/relay-attestation/index.d.ts +0 -1
  174. package/dist/relay-attestation/index.js +0 -1
  175. package/dist/request/caller-proof.d.ts +0 -43
  176. package/dist/request/caller-proof.js +0 -36
  177. package/dist/request/index.d.ts +0 -3
  178. package/dist/request/index.js +0 -3
  179. package/dist/request/proof-signer.d.ts +0 -49
  180. package/dist/request/proof-signer.js +0 -59
  181. package/dist/request/request-sig.d.ts +0 -99
  182. package/dist/request/request-sig.js +0 -95
  183. package/dist/request-proof/authorizer.d.ts +0 -41
  184. package/dist/request-proof/authorizer.js +0 -60
  185. package/dist/request-proof/index.d.ts +0 -4
  186. package/dist/request-proof/index.js +0 -2
  187. package/dist/request-proof/request-proof.d.ts +0 -53
  188. package/dist/request-proof/request-proof.js +0 -95
  189. package/dist/rpc/index.d.ts +0 -64
  190. package/dist/rpc/index.js +0 -78
  191. package/dist/signer/index.d.ts +0 -2
  192. package/dist/signer/index.js +0 -3
  193. package/dist/signer/signer.d.ts +0 -92
  194. package/dist/signer/signer.js +0 -147
  195. package/dist/token-store/index.d.ts +0 -27
  196. package/dist/token-store/index.js +0 -62
  197. package/dist/transport/index.d.ts +0 -6
  198. package/dist/transport/index.js +0 -3
  199. package/dist/transport/mero-client.d.ts +0 -294
  200. package/dist/transport/mero-client.js +0 -386
  201. package/dist/transport/relay-observer.d.ts +0 -152
  202. package/dist/transport/relay-observer.js +0 -173
  203. package/dist/transport/relay-transport.d.ts +0 -73
  204. package/dist/transport/relay-transport.js +0 -94
  205. package/dist/transport/types.d.ts +0 -100
  206. package/dist/transport/types.js +0 -32
  207. package/dist/types/api-response.d.ts +0 -15
  208. package/dist/types/api-response.js +0 -1
  209. package/dist/types/index.d.ts +0 -1
  210. package/dist/types/index.js +0 -1
  211. package/dist/warrant/creation-warrant.d.ts +0 -163
  212. package/dist/warrant/creation-warrant.js +0 -194
  213. package/dist/warrant/governance-op.d.ts +0 -202
  214. package/dist/warrant/governance-op.js +0 -355
  215. package/dist/warrant/governance-warrant.d.ts +0 -124
  216. package/dist/warrant/governance-warrant.js +0 -164
  217. package/dist/warrant/index.d.ts +0 -8
  218. package/dist/warrant/index.js +0 -5
  219. package/dist/warrant/warrant.d.ts +0 -188
  220. package/dist/warrant/warrant.js +0 -202
@@ -1,130 +0,0 @@
1
- export { ApiResponse } from '../http-client/index.js';
2
- export interface HealthResponse {
3
- status: 'alive' | 'not_alive';
4
- storage: boolean;
5
- uptime_seconds: number;
6
- }
7
- export interface IdentityResponse {
8
- service: string;
9
- version: string;
10
- authentication_mode: string;
11
- providers: string[];
12
- }
13
- export interface ProvidersResponse {
14
- providers: Array<{
15
- name: string;
16
- type: string;
17
- description: string;
18
- configured: boolean;
19
- config: Record<string, unknown>;
20
- }>;
21
- count: number;
22
- /**
23
- * App origins, besides the node's own and the registry-declared frontends,
24
- * that this node's login page may hand a token pair to (`callback-url`):
25
- * exact `http(s)` origins from the node's
26
- * `[server.embedded_auth.development] trusted_callback_origins`. Absent on
27
- * nodes from before it existed; treat that as none.
28
- */
29
- trusted_callback_origins?: string[];
30
- }
31
- export interface TokenRequest {
32
- auth_method: string;
33
- public_key: string;
34
- client_name: string;
35
- permissions?: string[];
36
- timestamp: number;
37
- provider_data: Record<string, unknown>;
38
- }
39
- export interface TokenResponse {
40
- data: {
41
- access_token: string;
42
- refresh_token: string;
43
- error?: string | null;
44
- };
45
- error?: string | null;
46
- }
47
- export interface RefreshTokenRequest {
48
- access_token: string;
49
- refresh_token: string;
50
- }
51
- export interface MockTokenRequest {
52
- client_name: string;
53
- permissions?: string[];
54
- node_url?: string;
55
- access_token_expiry?: number;
56
- refresh_token_expiry?: number;
57
- }
58
- export interface RevokeTokenRequest {
59
- client_id: string;
60
- }
61
- export interface RevokeTokenResponse {
62
- success: boolean;
63
- message: string;
64
- }
65
- export interface CreateKeyRequest {
66
- /** Public key to register as a root key. */
67
- public_key: string;
68
- /** Auth method / provider name (e.g. "user_password"). */
69
- auth_method: string;
70
- /** Provider-specific data. */
71
- provider_data: Record<string, unknown>;
72
- /** Target node URL to scope the root key to (optional). */
73
- target_node_url?: string;
74
- }
75
- export interface CreateKeyResponse {
76
- status: boolean;
77
- message: string;
78
- }
79
- export interface DeleteKeyResponse {
80
- success: boolean;
81
- message: string;
82
- }
83
- export interface RootKey {
84
- key_id: string;
85
- public_key: string;
86
- auth_method: string;
87
- created_at: number;
88
- revoked_at?: number | null;
89
- permissions: string[];
90
- }
91
- export interface ClientKey {
92
- client_id: string;
93
- root_key_id: string;
94
- name: string;
95
- permissions: string[];
96
- created_at: number;
97
- revoked_at?: number | null;
98
- is_valid: boolean;
99
- }
100
- export interface GenerateClientKeyRequest {
101
- /** Context the client key is scoped to (optional). */
102
- context_id?: string;
103
- /** Context identity (executor public key) the client key is for (optional). */
104
- context_identity?: string;
105
- /** Additional permissions to request (validated against the root key). */
106
- permissions?: string[];
107
- /** Target node URL to scope the client key/tokens to (optional). */
108
- target_node_url?: string;
109
- }
110
- export interface DeleteClientResponse {
111
- success: boolean;
112
- message: string;
113
- }
114
- export interface UpdateKeyPermissionsRequest {
115
- /** Permission strings to add (OR-ed onto the key's current set). */
116
- add?: string[];
117
- /** Permission strings to remove (applied before `add`). */
118
- remove?: string[];
119
- }
120
- export interface PermissionResponse {
121
- data: {
122
- permissions: string[];
123
- };
124
- error?: string | null;
125
- }
126
- export interface AuthApiClientConfig {
127
- baseUrl: string;
128
- getAuthToken?: () => Promise<string | undefined>;
129
- timeoutMs?: number;
130
- }
@@ -1,2 +0,0 @@
1
- // Auth API Types - Generated from OpenAPI 3.0.3 specification
2
- export {};
@@ -1,3 +0,0 @@
1
- export * from './auth-client.js';
2
- export * from './auth-types.js';
3
- export * from './auth-factory.js';
@@ -1,4 +0,0 @@
1
- // Auth API client
2
- export * from './auth-client.js';
3
- export * from './auth-types.js';
4
- export * from './auth-factory.js';
@@ -1,84 +0,0 @@
1
- /**
2
- * Capability bits as defined by core's `MemberCapabilities`.
3
- *
4
- * The per-member value is a u32 bitmask. Core currently assigns bits 0..=9
5
- * (the entries below); bits 10 and above are unassigned — do not repurpose
6
- * them for application data, as a future core release may claim them.
7
- */
8
- export declare const CAPABILITIES: {
9
- readonly CAN_CREATE_CONTEXT: number;
10
- readonly CAN_INVITE_MEMBERS: number;
11
- readonly CAN_JOIN_OPEN_SUBGROUPS: number;
12
- readonly MANAGE_MEMBERS: number;
13
- readonly MANAGE_APPLICATION: number;
14
- readonly CAN_CREATE_SUBGROUP: number;
15
- readonly CAN_DELETE_SUBGROUP: number;
16
- readonly CAN_MANAGE_VISIBILITY: number;
17
- readonly CAN_MANAGE_METADATA: number;
18
- /**
19
- * Publish writes attributed to ANOTHER member, under a warrant that member
20
- * signed — the grant delegated execution runs on.
21
- *
22
- * Implied by nothing: not by membership, not by admin, and not propagated by
23
- * the subgroup-admit cascade. So every group is authorship-closed until an
24
- * admin sets this bit, and a relay without it is refused at
25
- * `performIntent` before anything executes. That is why it is worth naming
26
- * here rather than leaving callers to write `1 << 9`: a client granting it
27
- * has to be able to say what it is granting.
28
- */
29
- readonly CAN_AUTHOR_ON_BEHALF: number;
30
- };
31
- export type CapabilityName = keyof typeof CAPABILITIES;
32
- export type CapabilityBit = (typeof CAPABILITIES)[CapabilityName];
33
- /**
34
- * Ready-made masks for `setDefaultCapabilities` / `setMemberCapabilities` and
35
- * `RelayClient.foundNamespace({ defaultCapabilities })`, so an app can name the
36
- * default it gives members instead of passing a bare number.
37
- *
38
- * Why this matters: a namespace's default mask is copied into a non-admin
39
- * member's row when they join, and a namespace starts without
40
- * `CAN_CREATE_CONTEXT` in it. An app that never sets a default leaves every
41
- * invited member unable to create a context until an admin grants it by hand.
42
- *
43
- * None of these include `CAN_AUTHOR_ON_BEHALF`; grant that deliberately (see
44
- * `AdminApiClient.grantAuthorship` / `openToDelegatedExecution`).
45
- */
46
- export declare const CAPABILITY_PRESETS: {
47
- /** No capabilities. */
48
- readonly NONE: 0;
49
- /** Join Open subgroups only: what a namespace starts with. */
50
- readonly JOIN_ONLY: number;
51
- /**
52
- * Create contexts, invite members, join Open subgroups (= 7). A member who
53
- * can work in the namespace but not reshape it.
54
- */
55
- readonly CONTRIBUTOR: number;
56
- /**
57
- * `CONTRIBUTOR` plus create and delete subgroups and manage their visibility
58
- * (= 231). What mero-chat gives members, so they can start and close their
59
- * own channels.
60
- */
61
- readonly COLLABORATOR: number;
62
- };
63
- export type CapabilityPreset = keyof typeof CAPABILITY_PRESETS;
64
- /**
65
- * Builds a u32 mask from capability names and/or bit values:
66
- * `capMask('CAN_CREATE_CONTEXT', 'CAN_INVITE_MEMBERS') === 3`.
67
- * Throws on a name core does not assign, so a typo can't silently yield 0.
68
- */
69
- export declare function capMask(...caps: Array<CapabilityName | number>): number;
70
- /**
71
- * The names of the assigned capability bits set in `mask`, in bit order.
72
- * Unassigned bits (10 and above) are not reported.
73
- */
74
- export declare function capNames(mask: number): CapabilityName[];
75
- /**
76
- * Returns true if `mask` has every bit of `cap` set. Both operands are
77
- * coerced to unsigned 32-bit (`>>> 0`) before comparing so a high bit such
78
- * as `1 << 31` doesn't fall foul of `&` yielding a signed result.
79
- */
80
- export declare function hasCap(mask: number, cap: number): boolean;
81
- /** Returns `mask` with every bit of `cap` set (u32-normalized). */
82
- export declare function withCap(mask: number, cap: number): number;
83
- /** Returns `mask` with every bit of `cap` cleared (u32-normalized). */
84
- export declare function withoutCap(mask: number, cap: number): number;
@@ -1,117 +0,0 @@
1
- // Member capability bitmask constants — mirrors core's `MemberCapabilities`
2
- // (crates/context/config/src/lib.rs). The value stored per-member is a u32
3
- // bitmask. Core currently assigns bits 0..=9; bits 10 and above are unassigned
4
- // and may be claimed by future core versions, so an application MUST NOT
5
- // assume any particular bit is safe for its own use unless core documents it
6
- // as reserved for applications.
7
- /**
8
- * Capability bits as defined by core's `MemberCapabilities`.
9
- *
10
- * The per-member value is a u32 bitmask. Core currently assigns bits 0..=9
11
- * (the entries below); bits 10 and above are unassigned — do not repurpose
12
- * them for application data, as a future core release may claim them.
13
- */
14
- export const CAPABILITIES = {
15
- CAN_CREATE_CONTEXT: 1 << 0,
16
- CAN_INVITE_MEMBERS: 1 << 1,
17
- CAN_JOIN_OPEN_SUBGROUPS: 1 << 2,
18
- MANAGE_MEMBERS: 1 << 3,
19
- MANAGE_APPLICATION: 1 << 4,
20
- CAN_CREATE_SUBGROUP: 1 << 5,
21
- CAN_DELETE_SUBGROUP: 1 << 6,
22
- CAN_MANAGE_VISIBILITY: 1 << 7,
23
- CAN_MANAGE_METADATA: 1 << 8,
24
- /**
25
- * Publish writes attributed to ANOTHER member, under a warrant that member
26
- * signed — the grant delegated execution runs on.
27
- *
28
- * Implied by nothing: not by membership, not by admin, and not propagated by
29
- * the subgroup-admit cascade. So every group is authorship-closed until an
30
- * admin sets this bit, and a relay without it is refused at
31
- * `performIntent` before anything executes. That is why it is worth naming
32
- * here rather than leaving callers to write `1 << 9`: a client granting it
33
- * has to be able to say what it is granting.
34
- */
35
- CAN_AUTHOR_ON_BEHALF: 1 << 9,
36
- };
37
- /**
38
- * Ready-made masks for `setDefaultCapabilities` / `setMemberCapabilities` and
39
- * `RelayClient.foundNamespace({ defaultCapabilities })`, so an app can name the
40
- * default it gives members instead of passing a bare number.
41
- *
42
- * Why this matters: a namespace's default mask is copied into a non-admin
43
- * member's row when they join, and a namespace starts without
44
- * `CAN_CREATE_CONTEXT` in it. An app that never sets a default leaves every
45
- * invited member unable to create a context until an admin grants it by hand.
46
- *
47
- * None of these include `CAN_AUTHOR_ON_BEHALF`; grant that deliberately (see
48
- * `AdminApiClient.grantAuthorship` / `openToDelegatedExecution`).
49
- */
50
- export const CAPABILITY_PRESETS = {
51
- /** No capabilities. */
52
- NONE: 0,
53
- /** Join Open subgroups only: what a namespace starts with. */
54
- JOIN_ONLY: CAPABILITIES.CAN_JOIN_OPEN_SUBGROUPS,
55
- /**
56
- * Create contexts, invite members, join Open subgroups (= 7). A member who
57
- * can work in the namespace but not reshape it.
58
- */
59
- CONTRIBUTOR: CAPABILITIES.CAN_CREATE_CONTEXT |
60
- CAPABILITIES.CAN_INVITE_MEMBERS |
61
- CAPABILITIES.CAN_JOIN_OPEN_SUBGROUPS,
62
- /**
63
- * `CONTRIBUTOR` plus create and delete subgroups and manage their visibility
64
- * (= 231). What mero-chat gives members, so they can start and close their
65
- * own channels.
66
- */
67
- COLLABORATOR: CAPABILITIES.CAN_CREATE_CONTEXT |
68
- CAPABILITIES.CAN_INVITE_MEMBERS |
69
- CAPABILITIES.CAN_JOIN_OPEN_SUBGROUPS |
70
- CAPABILITIES.CAN_CREATE_SUBGROUP |
71
- CAPABILITIES.CAN_DELETE_SUBGROUP |
72
- CAPABILITIES.CAN_MANAGE_VISIBILITY,
73
- };
74
- /**
75
- * Builds a u32 mask from capability names and/or bit values:
76
- * `capMask('CAN_CREATE_CONTEXT', 'CAN_INVITE_MEMBERS') === 3`.
77
- * Throws on a name core does not assign, so a typo can't silently yield 0.
78
- */
79
- export function capMask(...caps) {
80
- let mask = 0;
81
- for (const cap of caps) {
82
- if (typeof cap === 'number') {
83
- mask |= cap;
84
- }
85
- else if (Object.prototype.hasOwnProperty.call(CAPABILITIES, cap)) {
86
- mask |= CAPABILITIES[cap];
87
- }
88
- else {
89
- throw new Error(`unknown capability: ${String(cap)}`);
90
- }
91
- }
92
- return mask >>> 0;
93
- }
94
- /**
95
- * The names of the assigned capability bits set in `mask`, in bit order.
96
- * Unassigned bits (10 and above) are not reported.
97
- */
98
- export function capNames(mask) {
99
- return Object.keys(CAPABILITIES).filter((name) => hasCap(mask, CAPABILITIES[name]));
100
- }
101
- /**
102
- * Returns true if `mask` has every bit of `cap` set. Both operands are
103
- * coerced to unsigned 32-bit (`>>> 0`) before comparing so a high bit such
104
- * as `1 << 31` doesn't fall foul of `&` yielding a signed result.
105
- */
106
- export function hasCap(mask, cap) {
107
- const capU32 = cap >>> 0;
108
- return ((mask & capU32) >>> 0) === capU32;
109
- }
110
- /** Returns `mask` with every bit of `cap` set (u32-normalized). */
111
- export function withCap(mask, cap) {
112
- return (mask | cap) >>> 0;
113
- }
114
- /** Returns `mask` with every bit of `cap` cleared (u32-normalized). */
115
- export function withoutCap(mask, cap) {
116
- return (mask & ~cap) >>> 0;
117
- }
@@ -1,63 +0,0 @@
1
- import { type Signer } from '../signer/signer.js';
2
- /**
3
- * The `ownership_proof` body for `POST /api/cloud/me/namespaces/{ns}/enable-ha`
4
- * and for `POST /api/cloud/accounts/{account}/namespaces/{ns}/enable-ha`.
5
- */
6
- export interface AccountOwnershipProof {
7
- kind: 'account';
8
- /** hex `AccountProof<DeviceCert>`, the account's credential. */
9
- credential: string;
10
- /** base64 UTF-8 JSON, the claim. */
11
- signed_payload: string;
12
- /** base64 ed25519 by the certified device key. */
13
- signature: string;
14
- }
15
- /** What every account claim needs; the audience and `subject` differ per route. */
16
- interface AccountClaimBase {
17
- /** The namespace, hex: the id `foundNamespace` returned. */
18
- namespaceId: string;
19
- /** The founding account, hex. */
20
- accountId: string;
21
- /** The salt `foundNamespace` returned, hex (32 bytes). */
22
- salt: string;
23
- /** The account's credential, hex `AccountProof<DeviceCert>`. */
24
- credential: string;
25
- deviceSecret?: string;
26
- signer?: Signer;
27
- /** Lifetime in ms; default one minute, at most five. */
28
- ttlMs?: number;
29
- /** For tests. */
30
- now?: () => number;
31
- }
32
- export interface AccountOwnershipClaimInput extends AccountClaimBase {
33
- /** The cloud login's email: the claim is for this login only. */
34
- subject: string;
35
- }
36
- /**
37
- * Input for {@link signAccountHaClaim}: the same as the session claim, minus
38
- * `subject` — there is no login to bind it to.
39
- */
40
- export interface AccountHaClaimInput extends AccountClaimBase {
41
- /**
42
- * The relay that founded the namespace (the delegated session's `relayUrl`).
43
- * Signed into the claim so nobody forwarding it can swap it: the cloud
44
- * resolves it to one of its own fleet relays and hands that relay's
45
- * addresses to the fleet node as its admitter. Leave it out when unknown.
46
- */
47
- relayUrl?: string;
48
- }
49
- /** The audience of the session route's claim (`/api/cloud/me/...`). */
50
- export declare const ACCOUNT_OWNERSHIP_AUDIENCE = "mdma:enable-ha-namespace";
51
- /** The audience of the anonymous account route's claim (`/api/cloud/accounts/...`). */
52
- export declare const ACCOUNT_HA_AUDIENCE = "mdma:enable-ha-namespace-as-account";
53
- /** The founder's claim for the SESSION route, bound to one cloud login (`subject`). */
54
- export declare function signAccountOwnershipClaim(input: AccountOwnershipClaimInput): Promise<AccountOwnershipProof>;
55
- /**
56
- * The founder's claim for the ANONYMOUS account route
57
- * (`POST /api/cloud/accounts/{account}/namespaces/{ns}/enable-ha`): no cloud
58
- * session, so no `subject`, and its own audience so a claim minted for one
59
- * route can never be replayed on the other. The cloud finds the user to bill
60
- * through the account's wallet link instead.
61
- */
62
- export declare function signAccountHaClaim(input: AccountHaClaimInput): Promise<AccountOwnershipProof>;
63
- export {};
@@ -1,87 +0,0 @@
1
- /**
2
- * The ownership claim an account with no node presents to enable HA for a
3
- * namespace it founded through a relay (mdma#415).
4
- *
5
- * A node proves ownership with a proof signed by the namespace's group key,
6
- * which a nodeless account does not hold. The account instead proves it is the
7
- * FOUNDER: a namespace id is `domain_hash("calimero.namespace.id.v1",
8
- * [founder_account, salt])`, so only the founding account, with the salt its
9
- * founding returned, reproduces it. Its device key signs the claim, and its
10
- * certificate says whose device that is. The cloud also requires the login to
11
- * be linked to that account.
12
- *
13
- * Signature input: `"calimero.mdma.account-ownership-claim.v1\0" ‖ payload`,
14
- * where `payload` is the UTF-8 JSON sent (base64) as `signed_payload`.
15
- */
16
- import { concat } from '../crypto/internal.js';
17
- import { resolveSigner } from '../signer/signer.js';
18
- const DOMAIN = new TextEncoder().encode('calimero.mdma.account-ownership-claim.v1\0');
19
- /** What the cloud accepts; it caps a claim's lifetime at five minutes. */
20
- const DEFAULT_TTL_MS = 60000;
21
- const MAX_TTL_MS = 5 * 60000;
22
- /** The cloud's limit on `relay_url`. */
23
- const MAX_RELAY_URL = 1024;
24
- /** The audience of the session route's claim (`/api/cloud/me/...`). */
25
- export const ACCOUNT_OWNERSHIP_AUDIENCE = 'mdma:enable-ha-namespace';
26
- /** The audience of the anonymous account route's claim (`/api/cloud/accounts/...`). */
27
- export const ACCOUNT_HA_AUDIENCE = 'mdma:enable-ha-namespace-as-account';
28
- function base64(bytes) {
29
- let binary = '';
30
- for (const b of bytes)
31
- binary += String.fromCharCode(b);
32
- return btoa(binary);
33
- }
34
- const hex32 = (value, what) => {
35
- if (!/^[0-9a-fA-F]{64}$/.test(value))
36
- throw new Error(`${what} must be 64 hex characters`);
37
- return value.toLowerCase();
38
- };
39
- /**
40
- * Sign one claim. `subject` is spliced in after `salt` only when given, so the
41
- * session claim keeps its exact field order and the account claim has no
42
- * `subject` key at all (not a null one: the cloud tells the two apart by it).
43
- */
44
- async function signClaim(input, audience, subject, relayUrl) {
45
- if (relayUrl !== undefined && !(relayUrl.length > 0 && relayUrl.length <= MAX_RELAY_URL)) {
46
- throw new Error(`relayUrl must be a non-empty string of at most ${MAX_RELAY_URL} characters`);
47
- }
48
- const ttl = input.ttlMs ?? DEFAULT_TTL_MS;
49
- if (!(ttl > 0 && ttl <= MAX_TTL_MS))
50
- throw new Error(`ttlMs must be in (0, ${MAX_TTL_MS}]`);
51
- const groupId = hex32(input.namespaceId, 'namespaceId');
52
- const accountId = hex32(input.accountId, 'accountId');
53
- const salt = hex32(input.salt, 'salt');
54
- const signer = await resolveSigner(input.deviceSecret, input.signer, 'deviceSecret');
55
- const issued = (input.now ?? Date.now)();
56
- const nonce = Array.from(crypto.getRandomValues(new Uint8Array(16)), (b) => b.toString(16).padStart(2, '0')).join('');
57
- const payload = new TextEncoder().encode(JSON.stringify({
58
- v: 1,
59
- audience,
60
- group_id: groupId,
61
- account_id: accountId,
62
- salt,
63
- ...(subject === undefined ? {} : { subject }),
64
- nonce,
65
- issued_at_ms: issued,
66
- expires_at_ms: issued + ttl,
67
- ...(relayUrl === undefined ? {} : { relay_url: relayUrl }),
68
- }));
69
- const signature = await signer.sign(concat(DOMAIN, payload));
70
- return { kind: 'account', credential: input.credential, signed_payload: base64(payload), signature: base64(signature) };
71
- }
72
- /** The founder's claim for the SESSION route, bound to one cloud login (`subject`). */
73
- export async function signAccountOwnershipClaim(input) {
74
- if (!input.subject)
75
- throw new Error('subject must be the cloud login email');
76
- return signClaim(input, ACCOUNT_OWNERSHIP_AUDIENCE, input.subject);
77
- }
78
- /**
79
- * The founder's claim for the ANONYMOUS account route
80
- * (`POST /api/cloud/accounts/{account}/namespaces/{ns}/enable-ha`): no cloud
81
- * session, so no `subject`, and its own audience so a claim minted for one
82
- * route can never be replayed on the other. The cloud finds the user to bill
83
- * through the account's wallet link instead.
84
- */
85
- export async function signAccountHaClaim(input) {
86
- return signClaim(input, ACCOUNT_HA_AUDIENCE, undefined, input.relayUrl);
87
- }