@cubist-labs/cubesigner-sdk 0.3.29 → 0.4.24-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 (151) hide show
  1. package/README.md +129 -113
  2. package/dist/cjs/package.json +5 -2
  3. package/dist/cjs/src/api.d.ts +1 -2
  4. package/dist/cjs/src/api.js +2 -4
  5. package/dist/cjs/src/client/api_client.d.ts +611 -0
  6. package/dist/cjs/src/client/api_client.js +1211 -0
  7. package/dist/cjs/src/client/base_client.d.ts +92 -0
  8. package/dist/cjs/src/client/base_client.js +174 -0
  9. package/dist/cjs/src/client/session.d.ts +151 -0
  10. package/dist/cjs/src/client/session.js +193 -0
  11. package/dist/cjs/src/client.d.ts +83 -558
  12. package/dist/cjs/src/client.js +109 -358
  13. package/dist/cjs/src/error.d.ts +2 -2
  14. package/dist/cjs/src/error.js +4 -2
  15. package/dist/cjs/src/events.d.ts +34 -93
  16. package/dist/cjs/src/events.js +42 -198
  17. package/dist/cjs/src/evm/index.d.ts +10 -10
  18. package/dist/cjs/src/evm/index.js +33 -31
  19. package/dist/cjs/src/fetch.d.ts +53 -0
  20. package/dist/cjs/src/fetch.js +133 -0
  21. package/dist/cjs/src/index.d.ts +5 -170
  22. package/dist/cjs/src/index.js +8 -247
  23. package/dist/cjs/src/key.d.ts +116 -35
  24. package/dist/cjs/src/key.js +144 -37
  25. package/dist/cjs/src/mfa.d.ts +94 -13
  26. package/dist/cjs/src/mfa.js +156 -20
  27. package/dist/cjs/src/org.d.ts +358 -41
  28. package/dist/cjs/src/org.js +310 -37
  29. package/dist/cjs/src/org_event_processor.d.ts +57 -0
  30. package/dist/cjs/src/org_event_processor.js +137 -0
  31. package/dist/cjs/src/response.d.ts +22 -20
  32. package/dist/cjs/src/response.js +57 -40
  33. package/dist/cjs/src/retry.d.ts +36 -0
  34. package/dist/cjs/src/retry.js +42 -0
  35. package/dist/cjs/src/role.d.ts +46 -11
  36. package/dist/cjs/src/role.js +30 -34
  37. package/dist/cjs/src/schema.d.ts +2 -2
  38. package/dist/cjs/src/schema.js +1 -1
  39. package/dist/cjs/src/schema_types.d.ts +18 -4
  40. package/dist/cjs/src/schema_types.js +1 -1
  41. package/dist/cjs/src/signer_session.d.ts +3 -28
  42. package/dist/cjs/src/signer_session.js +9 -44
  43. package/dist/cjs/src/user_export.d.ts +1 -1
  44. package/dist/cjs/src/user_export.js +1 -1
  45. package/dist/esm/package.json +5 -2
  46. package/dist/esm/src/api.d.ts +1 -2
  47. package/dist/esm/src/api.js +2 -4
  48. package/dist/esm/src/client/api_client.d.ts +611 -0
  49. package/dist/esm/src/client/api_client.js +1207 -0
  50. package/dist/esm/src/client/base_client.d.ts +92 -0
  51. package/dist/esm/src/client/base_client.js +167 -0
  52. package/dist/esm/src/client/session.d.ts +151 -0
  53. package/dist/esm/src/client/session.js +182 -0
  54. package/dist/esm/src/client.d.ts +83 -558
  55. package/dist/esm/src/client.js +109 -358
  56. package/dist/esm/src/error.d.ts +2 -2
  57. package/dist/esm/src/error.js +4 -2
  58. package/dist/esm/src/events.d.ts +34 -93
  59. package/dist/esm/src/events.js +41 -194
  60. package/dist/esm/src/evm/index.d.ts +10 -10
  61. package/dist/esm/src/evm/index.js +33 -31
  62. package/dist/esm/src/fetch.d.ts +53 -0
  63. package/dist/esm/src/fetch.js +127 -0
  64. package/dist/esm/src/index.d.ts +5 -170
  65. package/dist/esm/src/index.js +6 -242
  66. package/dist/esm/src/key.d.ts +116 -35
  67. package/dist/esm/src/key.js +144 -36
  68. package/dist/esm/src/mfa.d.ts +94 -13
  69. package/dist/esm/src/mfa.js +154 -19
  70. package/dist/esm/src/org.d.ts +358 -41
  71. package/dist/esm/src/org.js +311 -38
  72. package/dist/esm/src/org_event_processor.d.ts +57 -0
  73. package/dist/esm/src/org_event_processor.js +133 -0
  74. package/dist/esm/src/response.d.ts +22 -20
  75. package/dist/esm/src/response.js +57 -40
  76. package/dist/esm/src/retry.d.ts +36 -0
  77. package/dist/esm/src/retry.js +36 -0
  78. package/dist/esm/src/role.d.ts +46 -11
  79. package/dist/esm/src/role.js +31 -35
  80. package/dist/esm/src/schema.d.ts +2 -2
  81. package/dist/esm/src/schema.js +1 -1
  82. package/dist/esm/src/schema_types.d.ts +18 -4
  83. package/dist/esm/src/schema_types.js +1 -1
  84. package/dist/esm/src/signer_session.d.ts +3 -28
  85. package/dist/esm/src/signer_session.js +8 -42
  86. package/dist/esm/src/user_export.d.ts +1 -1
  87. package/dist/esm/src/user_export.js +1 -1
  88. package/dist/package.json +36 -0
  89. package/dist/spec/env/beta.json +9 -0
  90. package/dist/spec/env/gamma.json +9 -0
  91. package/dist/spec/env/prod.json +9 -0
  92. package/dist/src/api.d.ts +634 -0
  93. package/dist/src/api.js +1309 -0
  94. package/dist/src/client.d.ts +575 -0
  95. package/dist/src/client.js +381 -0
  96. package/dist/src/env.d.ts +15 -0
  97. package/dist/src/env.js +35 -0
  98. package/dist/src/error.d.ts +29 -0
  99. package/dist/src/error.js +36 -0
  100. package/dist/src/events.d.ts +84 -0
  101. package/dist/src/events.js +195 -0
  102. package/dist/src/index.d.ts +207 -0
  103. package/dist/src/index.js +308 -0
  104. package/dist/src/key.d.ts +152 -0
  105. package/dist/src/key.js +242 -0
  106. package/dist/src/mfa.d.ts +94 -0
  107. package/dist/src/mfa.js +169 -0
  108. package/dist/src/org.d.ts +99 -0
  109. package/dist/src/org.js +95 -0
  110. package/dist/src/paginator.d.ts +76 -0
  111. package/dist/src/paginator.js +99 -0
  112. package/dist/src/response.d.ts +101 -0
  113. package/dist/src/response.js +164 -0
  114. package/dist/src/role.d.ts +283 -0
  115. package/dist/src/role.js +253 -0
  116. package/dist/src/schema.d.ts +6209 -0
  117. package/dist/src/schema.js +7 -0
  118. package/dist/src/schema_types.d.ts +113 -0
  119. package/dist/src/schema_types.js +3 -0
  120. package/dist/src/session/session_storage.d.ts +47 -0
  121. package/dist/src/session/session_storage.js +76 -0
  122. package/dist/src/session/signer_session_manager.d.ts +125 -0
  123. package/dist/src/session/signer_session_manager.js +239 -0
  124. package/dist/src/signer_session.d.ts +41 -0
  125. package/dist/src/signer_session.js +77 -0
  126. package/dist/src/user_export.d.ts +52 -0
  127. package/dist/src/user_export.js +129 -0
  128. package/dist/src/util.d.ts +61 -0
  129. package/dist/src/util.js +97 -0
  130. package/package.json +5 -2
  131. package/src/{api.ts → client/api_client.ts} +603 -753
  132. package/src/client/base_client.ts +226 -0
  133. package/src/client/session.ts +269 -0
  134. package/src/client.ts +108 -413
  135. package/src/error.ts +5 -3
  136. package/src/events.ts +49 -201
  137. package/src/evm/index.ts +36 -39
  138. package/src/fetch.ts +194 -0
  139. package/src/index.ts +5 -285
  140. package/src/key.ts +214 -56
  141. package/src/mfa.ts +179 -23
  142. package/src/org.ts +349 -40
  143. package/src/response.ts +56 -39
  144. package/src/retry.ts +57 -0
  145. package/src/role.ts +75 -41
  146. package/src/schema.ts +4 -1
  147. package/src/schema_types.ts +20 -4
  148. package/src/signer_session.ts +6 -42
  149. package/src/user_export.ts +1 -1
  150. package/src/session/session_storage.ts +0 -41
  151. package/src/session/signer_session_manager.ts +0 -315
package/README.md CHANGED
@@ -39,6 +39,9 @@ cs login owner@example.com --env '<gamma|prod|...>'
39
39
 
40
40
  ## Getting started
41
41
 
42
+ > [!TIP]
43
+ > For migration from `v0.3.*` to `v0.4.*`, please see [MIGRATION.md](../../MIGRATION.md#v03-to-v04)
44
+
42
45
  In this section we are going to walk through a simple CubeSigner
43
46
  setup. We'll create a signing key, then sign some EVM
44
47
  transactions, and then add a security policy to restrict the kinds of
@@ -53,32 +56,30 @@ examples below.
53
56
 
54
57
  ```typescript
55
58
  import * as cs from "@cubist-labs/cubesigner-sdk";
56
- import { JsonFileSessionStorage, loadManagementSession } from "@cubist-labs/cubesigner-sdk-fs-storage";
59
+ import { JsonFileSessionManager, defaultManagementSessionManager } from "@cubist-labs/cubesigner-sdk-fs-storage";
57
60
  import assert from "assert";
58
61
  ```
59
62
 
60
63
  ### Instantiate `CubeSignerClient`
61
64
 
62
65
  The first order of business is to create an instance of `CubeSignerClient`.
63
- We can do that by simply loading the management session token from the
66
+ We can do that by simply loading a session token from the
64
67
  default location on disk (which is where the `cs login` command saves
65
68
  it):
66
69
 
67
70
  ```typescript
68
- const cubesigner = await loadManagementSession();
71
+ const cubesigner = await cs.CubeSignerClient.create(defaultManagementSessionManager());
69
72
  ```
70
73
 
71
74
  Alternatively, a `CubeSignerClient` instance can be created by explicitly
72
75
  providing a session manager:
73
76
 
74
77
  ```typescript
75
- // Load session from a JSON file
76
- const fileStorage = new JsonFileSessionStorage<cs.SignerSessionData>(
78
+ // Create a session manager backed by a JSON file
79
+ const fileStorage = new JsonFileSessionManager(
77
80
  `${process.env.HOME}/.config/cubesigner/management-session.json`,
78
81
  );
79
- // Create a session manager for a management token
80
- const sessionMgr = await cs.SignerSessionManager.loadFromStorage(fileStorage);
81
- new cs.CubeSignerClient(sessionMgr);
82
+ await cs.CubeSignerClient.create(fileStorage);
82
83
  ```
83
84
 
84
85
  ### Get `User` and `Org` info
@@ -87,13 +88,13 @@ We can now obtain some information about the logged-in user and the
87
88
  organization the user belongs to:
88
89
 
89
90
  ```typescript
90
- const me = await cubesigner.aboutMe();
91
+ const me = await cubesigner.user();
91
92
  console.log(me);
92
93
  assert(me.user_id); // each user has a globally unique ID
93
94
  assert(me.org_ids); // IDs of all organizations this user is a member of
94
95
  assert(me.org_ids.length === 1); // assume that the user is a member of exactly one org
95
96
 
96
- const org = new cs.Org(cubesigner);
97
+ const org = await cubesigner.org();
97
98
  assert(await org.enabled()); // assume that the org is enabled
98
99
  ```
99
100
 
@@ -117,41 +118,6 @@ assert(await secpKey.type(), cs.Secp256k1.Evm);
117
118
  console.log(`Created '${cs.Secp256k1.Evm}' key ${secpKey.id}`);
118
119
  ```
119
120
 
120
- ### Create a `Role` and a `SignerSession`
121
-
122
- CubeSigner differentiates between _management_ and _signer_ sessions
123
- since managing keys (and an org) is often separate from using keys.
124
-
125
- Everything we've done so far has been using a management session. To
126
- sign a message with a key, we now need to create a signer
127
- session. Signer sessions are associated with roles (which we discuss
128
- in this section) or users (which we discuss [later](#create-a-session-for-an-oidc-user)).
129
-
130
- You can think of roles as groups
131
- that give certain users access to certain keys. To get started, let's
132
- create a `Role` and then simply call `createSession` on it:
133
-
134
- ```typescript
135
- const role = await org.createRole();
136
- const sessionStorage = new cs.MemorySessionStorage<cs.SignerSessionData>();
137
- const session = await role.createSession(sessionStorage, "readme");
138
- console.log(`Created signer session for role '${role.id}'`);
139
- ```
140
-
141
- Sessions have lifetimes, so they need to periodically refresh
142
- themselves to stay valid. When that happens, the refreshed session
143
- needs to be saved somewhere, which is why the `createSession` method
144
- requires an instance of `SessionStorage`. In this example, we don't
145
- plan to persist the session across multiple runs, so a simple
146
- in-memory storage suffices; otherwise, opting for
147
- `JsonFileSessionStorage` would be a better idea, i.e.,
148
-
149
- ```typescript
150
- // this storage persists the signer session token to a file
151
- // named 'session.json' in the current working directory
152
- new JsonFileSessionStorage("session.json");
153
- ```
154
-
155
121
  ### Sign an Ethereum transaction
156
122
 
157
123
  Let's create a dummy `EvmSignRequest`.
@@ -172,39 +138,44 @@ const eth1Request = <cs.EvmSignRequest>{
172
138
 
173
139
  It seems we have everything in place to sign this request with the
174
140
  previously created key. However, attempting to do so fails with `403
175
- Forbidden` saying something like `Role 'Role#... is not authorized to
176
- access key 'Key#...'`:
141
+ Forbidden` saying something like `Session does not have the required scopes...`
177
142
 
178
143
  ```typescript
179
144
  try {
180
- console.log("Trying to sign before adding key to role");
181
- await session.signEvm(secpKey, eth1Request);
182
- assert(false, "Must not be allowed to sign with key not in role");
145
+ console.log("Trying to sign with improper scopes");
146
+ await secpKey.signEvm(eth1Request);
147
+ assert(false, "Must not be allowed to sign without scopes");
183
148
  } catch (e) {
184
- assert(`${e}`.includes("not authorized to access key"));
149
+ assert(`${e}`.includes("Session does not have required scopes"));
185
150
  }
186
151
  ```
187
152
 
188
- By default, a newly created role does not get to access any
189
- keys. Instead, keys have to be added to a role explicitly.
190
- After we do that, the `signEvm` call should succeed:
153
+ By default, the sessions created by the CLI cannot perform signing operations. All sessions have a series of *scopes* which
154
+ which determine what that session can be used for. We'll talk more about this later, but for now just know that we need a new session with the proper scopes:
191
155
 
192
156
  ```typescript
193
- console.log("Adding key to role, then signing an Ethereum transaction");
194
- await role.addKey(secpKey);
195
- let sig = await session.signEvm(secpKey, eth1Request);
157
+ let signingClient = await cs.CubeSignerClient.create(
158
+ // declare the "sign:*" scope which allows us to sign using any keys the
159
+ // account has access to
160
+ await cubesigner.org().createSession("readme signing demo", ["sign:*"]));
161
+ const signingKey = new cs.Key(signingClient, secpKey.cached);
162
+ let sig = await signingKey.signEvm(eth1Request);
196
163
  console.log(sig.data());
197
164
  assert(sig.data().rlp_signed_tx);
198
165
  ```
199
166
 
200
167
  ### Using ethers.js instead of the SDK directly
201
168
 
169
+ If your application uses ethers.js, you can configure it to use CubeSigner to
170
+ sign transactions.
171
+
172
+
202
173
  ```typescript
203
174
  import { Signer } from "@cubist-labs/cubesigner-sdk-ethers-v6";
204
175
  import { ethers } from "ethers";
205
176
 
206
177
  // Create new Signer
207
- const ethersSigner = new Signer(secpKey.materialId, session);
178
+ const ethersSigner = new Signer(secpKey.materialId, signingClient);
208
179
  assert((await ethersSigner.getAddress()) === ethers.getAddress(secpKey.materialId));
209
180
  // sign transaction as usual:
210
181
  console.log(
@@ -217,9 +188,32 @@ console.log(
217
188
  );
218
189
  ```
219
190
 
191
+
192
+ ### Access control with `Role`
193
+
194
+ CubeSigner uses roles to control access to keys when more than one user wants to
195
+ use them. You can think of roles as groups
196
+ that give certain users access to certain keys. To get started, let's
197
+ create a `Role` and then simply call `createSession` on it:
198
+
199
+ ```typescript
200
+ // Create a role, implicitly adding ourselves as a member
201
+ const role = await org.createRole();
202
+
203
+ console.log("Adding key to role, then signing an Ethereum transaction");
204
+ await role.addKey(secpKey);
205
+
206
+ // Members of the role can create sessions which can only access keys in the role
207
+ const roleClient = await cs.CubeSignerClient.create(
208
+ // Role sessions implicitly have the "sign:*" scope
209
+ await role.createSession("readme")
210
+ );
211
+ console.log(`Created client for role '${role.id}'`);
212
+ ```
213
+
220
214
  ### Set security policies
221
215
 
222
- When we add a `Secp256k1.Evm` key to a role (as we did above), a signer session
216
+ When we add a `Secp256k1.Evm` key to a role (as we did above), a client
223
217
  associated with that role allows us to sign **any** Ethereum
224
218
  transaction with that key. If that seems too permissive, we can attach a security
225
219
  policy to restrict the allowed usages of this key in this role.
@@ -231,7 +225,8 @@ recipient, we can attach a `TxReceiver` policy to our key:
231
225
  console.log("Setting transaction receiver policy");
232
226
  await secpKey.setPolicy([{ TxReceiver: "0xff50ed3d0ec03ac01d4c79aad74928bff48a7b2b" }]);
233
227
  console.log("Signing transaction");
234
- sig = await session.signEvm(secpKey, eth1Request);
228
+ const roleKey = new cs.Key(roleClient, secpKey.cached);
229
+ sig = await roleKey.signEvm(eth1Request);
235
230
  assert(sig.data().rlp_signed_tx);
236
231
  ```
237
232
 
@@ -241,7 +236,7 @@ indeed gets rejected:
241
236
  ```typescript
242
237
  console.log("Signing a transaction to a different receiver must be rejected");
243
238
  try {
244
- await session.signEvm(secpKey, {
239
+ await roleKey.signEvm({
245
240
  chain_id: 1,
246
241
  tx: <any>{
247
242
  ...eth1Request.tx,
@@ -259,16 +254,18 @@ try {
259
254
  > `Key::appendPolicy` instead of `Key::setPolicy` to append to
260
255
  > existing policies.
261
256
 
257
+
258
+
262
259
  ### Sign a raw blob
263
260
 
264
- The `SignerSession` class exposes the `signBlob` method, which signs
261
+ The `CubeSignerClient` class exposes the `signBlob` method, which signs
265
262
  an arbitrary (raw, uninterpreted) bag of bytes with a given key. This
266
263
  operation, however, is not permitted by default; it is permanently
267
264
  disabled for `BLS` keys, and for other key types it can be enabled by
268
265
  attaching an `"AllowRawBlobSigning"` policy:
269
266
 
270
267
  ```typescript
271
- // Create a new Ed25519 key (e.g., for Cardano) and add it to our session role
268
+ // Create a new Ed25519 key (e.g., for Cardano) and add it to our roleClient's role
272
269
  const edKey = await org.createKey(cs.Ed25519.Cardano);
273
270
  await role.addKey(edKey);
274
271
  console.log(`Created '${await edKey.type()}' key ${edKey.id} and added it to role ${role.id}`);
@@ -276,11 +273,12 @@ console.log(`Created '${await edKey.type()}' key ${edKey.id} and added it to rol
276
273
  // Sign raw blobs with our new ed key and the secp we created before
277
274
  for (const key of [edKey, secpKey]) {
278
275
  console.log(`Confirming that raw blob with ${await key.type()} is rejected by default`);
276
+ const roleKey = new cs.Key(roleClient, key.cached);
279
277
  const blobReq = <cs.BlobSignRequest>{
280
278
  message_base64: "L1kE9g59xD3fzYQQSR7340BwU9fGrP6EMfIFcyX/YBc=",
281
279
  };
282
280
  try {
283
- await session.signBlob(key, blobReq);
281
+ await roleKey.signBlob(blobReq);
284
282
  assert(false, "Must be rejected by policy");
285
283
  } catch (e) {
286
284
  assert(`${e}`.includes("Raw blob signing not allowed"));
@@ -288,7 +286,7 @@ for (const key of [edKey, secpKey]) {
288
286
 
289
287
  console.log("Signing raw blob after adding 'AllowRawBlobSigning' policy");
290
288
  await key.appendPolicy(["AllowRawBlobSigning"]);
291
- const blobSig = await session.signBlob(key, blobReq);
289
+ const blobSig = await roleKey.signBlob(blobReq);
292
290
  console.log(blobSig.data());
293
291
  assert(blobSig.data().signature);
294
292
  }
@@ -300,46 +298,68 @@ for (const key of [edKey, secpKey]) {
300
298
  Trying to sign an invalid message with a secp key will fail with
301
299
  `400 Bad Request` saying `Signature scheme: InvalidMessage`.
302
300
 
303
- ### Load a signer session
301
+ ## Session Management
302
+
303
+ In the above examples we've used 3 different sessions:
304
+
305
+ 1. A management session that we created using the CLI
306
+ 2. A signing session that we created using (1)
307
+ 3. A role session that we created used (1)
304
308
 
305
- If signing is all that your application needs to do, you can instantiate a
306
- `SignerSession` directly from a signer session token, without ever needing a
307
- management session.
309
+ All `CubeSignerClient`s require a valid session in order to operate. In this section
310
+ we'll dive into the specifics of sessions in the TypeScript SDK.
308
311
 
309
- First, get an existing token for a signer session:
312
+ ### Loading from disk
313
+ If you already have an active session in `cs` (the CubeSigner CLI), you can
314
+ load it into the TypeScript SDK with a simple helper (as we did earlier).
310
315
 
311
316
  ```typescript
312
- const token = await sessionStorage.retrieve();
313
- // alternatively, save this object to a file
317
+ await cs.CubeSignerClient.create(defaultManagementSessionManager())
314
318
  ```
315
319
 
316
- or generate a new one from the command line:
320
+ Or we can use the CLI to create our own session explicitly for our JavaScript client:
317
321
 
318
322
  ```bash
319
- cs token create --role-id $ROLE_ID --purpose MyPurpose --output json
323
+ cs session create --role-id $ROLE_ID --scope sign-all --output json > session.json
320
324
  ```
321
325
 
322
- Next, create a `MemorySessionStorage` containing the previously
323
- exported signer token, and just load the session from it.
324
-
326
+ Then we can load it like so:
325
327
  ```typescript
326
- const signerSession = await cs.SignerSession.loadSignerSession(
327
- // alternatively, load 'token' from file or environment variable
328
- new cs.MemorySessionStorage(token),
329
- );
328
+ try {
329
+ await cs.CubeSignerClient.create(new JsonFileSessionManager("./session.json"));
330
+ } catch {
331
+ console.error("Unable to find file")
332
+ }
330
333
  ```
331
334
 
332
- Finally, use the new signer session to sign a transaction. To specify
333
- the signing key, you can pass its "material id" as a plain string:
335
+ ### Loading from Memory
336
+ If you already have the session information (`SessionData` in Typescript) in memory, you can
337
+ load that directly into a client.
334
338
 
335
339
  ```typescript
336
- console.log("Signing transaction using imported signer session");
337
- const secpKeyStr: string = secpKey.materialId;
338
- sig = await signerSession.signEvm(secpKeyStr, eth1Request);
339
- console.log(sig.data());
340
- assert(sig.data().rlp_signed_tx);
340
+ // Get the session data we want to use with the client
341
+ const sessionData: cs.SessionData = await role.createSession("readme");
342
+ await cs.CubeSignerClient.create(new cs.MemorySessionManager(sessionData))
343
+ // or, for short
344
+ await cs.CubeSignerClient.create(sessionData)
341
345
  ```
342
346
 
347
+ > [!WARNING]
348
+ > Clients created this way will automatically refresh the session. If you try to use this session with another client, they will both try to refresh, leading to failures.
349
+
350
+ ### Managers, Storage and Refreshing
351
+
352
+ As we've seen in the examples above, all `CubeSignerClient`s are constructed using the `create` constructor. The `create`
353
+ constructor accepts either raw `SessionData` or a `SessionManager`. So far we've seen two different session managers:
354
+ - `JsonFileSessionManager`
355
+ - `MemorySessionManager`
356
+
357
+ These managers are responsible for keeping your session tokens refreshed
358
+ and (optionally) persisted. Whenever your session tokens are refreshed,
359
+ `JsonFileSessionManager` will write the new tokens to disk.
360
+
361
+ More complex managers can be written by implementing the `SessionManager` interface.
362
+
343
363
  ### Create a session for an OIDC user
344
364
 
345
365
  CubeSigner supports the [OIDC](https://openid.net/developers/how-connect-works/)
@@ -360,7 +380,7 @@ assert(oidcToken);
360
380
  Before we can use the OIDC token for authentication, we must add an org policy
361
381
  to allow the particular issuer/audience pair from the token.
362
382
 
363
- ```ts
383
+ ```
364
384
  const oldOrgPolicy = await org.policy();
365
385
  const oidcPayload = JSON.parse(atob(oidcToken.split(".")[1].replace(/-/g, "+").replace(/_/g, "/")));
366
386
  const oidcAuthSourcesPolicy = {
@@ -372,22 +392,16 @@ console.log("Setting org policy", oidcAuthSourcesPolicy);
372
392
  await org.setPolicy([oidcAuthSourcesPolicy]);
373
393
  ```
374
394
 
375
- Finally, exchange the OIDC token for either a _signer_ session (i.e., an instance
376
- of `SignerSession`, required by all signing endpoints, e.g., `signEvm`)
395
+ Finally, exchange the OIDC token for a session.
377
396
 
378
397
  ```typescript
379
- const oidcSession = new cs.SignerSession(
380
- // we'll use this session for both signing and approving MFA request, hence the following scopes
381
- await cubesigner.oidcAuth(oidcToken, ["manage:mfa", "sign:*"]),
398
+ const oidcSessionResp = await cs.CubeSignerClient.createOidcSession(
399
+ cubesigner.env,
400
+ org.id, // org id to log into
401
+ oidcToken,
402
+ ["manage:mfa", "sign:*"] // scopes for the session
382
403
  );
383
- ```
384
-
385
- or a _management_ session (i.e., and instance of `CubeSigner`,
386
- required by all management endpoints, e.g., retrieving user
387
- information, configuring user MFA methods, etc.).
388
-
389
- ```typescript
390
- const oidcCubeSigner = new cs.CubeSignerClient(await cubesigner.oidcAuth(oidcToken, ["manage:*"]));
404
+ const oidcClient = await cs.CubeSignerClient.create(oidcSessionResp.data());
391
405
  ```
392
406
 
393
407
  > **Info**
@@ -398,7 +412,7 @@ const oidcCubeSigner = new cs.CubeSignerClient(await cubesigner.oidcAuth(oidcTok
398
412
 
399
413
  ### Set up TOTP for a user
400
414
 
401
- To manage a user we need a management session bound to that user. It
415
+ To manage a user we need a session bound to that user. It
402
416
  doesn't matter if that user is native to CubeSigner or a third-party
403
417
  OIDC user. For that purpose, in this section we are going to use the
404
418
  previously created `oidcCubeSigner` instance.
@@ -408,12 +422,12 @@ TOTP reset procedure.
408
422
 
409
423
  ```typescript
410
424
  console.log(`Setting up TOTP for user ${me.email}`);
411
- let totpResetResp = await oidcCubeSigner.resetTotpStart();
425
+ let totpResetResp = await oidcClient.resetTotp();
412
426
  ```
413
427
 
414
428
  If the user has already configured TOTP (or any other form of MFA),
415
429
  this response will require multi factor authentication. In that case,
416
- for example, call `approveTotp` and provide the code for the existing
430
+ for example, call `totpApprove` and provide the code for the existing
417
431
  TOTP to proceed:
418
432
 
419
433
  ```typescript
@@ -423,7 +437,7 @@ let totpSecret = process.env["CS_USER_TOTP_SECRET"]!;
423
437
  if (totpResetResp.requiresMfa()) {
424
438
  console.log("Resetting TOTP requires MFA");
425
439
  const code = authenticator.generate(totpSecret);
426
- totpResetResp = await totpResetResp.approveTotp(oidcSession, code);
440
+ totpResetResp = await totpResetResp.totpApprove(oidcClient, code);
427
441
  assert(!totpResetResp.requiresMfa());
428
442
  console.log("MFA approved using existing TOTP");
429
443
  }
@@ -437,7 +451,7 @@ create an authenticator for automated testing.
437
451
 
438
452
  ```typescript
439
453
  const totpChallenge = totpResetResp.data();
440
- assert(totpChallenge.totpUrl);
454
+ assert(totpChallenge.url);
441
455
  ```
442
456
 
443
457
  To complete the challenge, we must call `resetTotpComplete` and
@@ -455,14 +469,14 @@ is generating the correct code by calling `verifyTotp`
455
469
  ```typescript
456
470
  console.log(`Verifying current TOTP code`);
457
471
  let code = authenticator.generate(totpSecret);
458
- await oidcCubeSigner.verifyTotp(code);
472
+ await oidcClient.verifyTotp(code);
459
473
  ```
460
474
 
461
475
  We can also check that the user's profile now indeed includes `Totp`
462
476
  as one of the configured MFA factors.
463
477
 
464
478
  ```typescript
465
- const mfa = (await oidcCubeSigner.aboutMe()).mfa;
479
+ const mfa = (await oidcClient.user()).mfa;
466
480
  console.log("Configured MFA types", mfa);
467
481
  assert(mfa.map((m) => m.type).includes("totp"));
468
482
  ```
@@ -486,18 +500,19 @@ receive `202 Accepted` instead of `200 Ok`. The response body contains
486
500
  an MFA ID, which we can use to fetch and inspect the associated MFA
487
501
  request, see how many approvals it requires, what kind of MFA factors
488
502
  it allows, etc. Instead, since we know that our key requires TOTP, we
489
- can just call `approveTotp` on the response and pass the current TOTP
503
+ can just call `totpApprove` on the response and pass the current TOTP
490
504
  code to it; if the code is correct, the call will succeed
491
505
  and return the signature.
492
506
 
493
507
  ```typescript
494
508
  console.log(`Signing a transaction now requires TOTP`);
495
- let resp = await oidcSession.signEvm(secpKeyStr, eth1Request);
509
+ const oidcKey = new cs.Key(oidcClient, secpKey.cached);
510
+ let resp = await oidcKey.signEvm(eth1Request);
496
511
  assert(resp.requiresMfa());
497
512
 
498
513
  console.log(`Approving with TOTP code`);
499
514
  code = authenticator.generate(totpSecret);
500
- resp = await resp.approveTotp(oidcSession, code);
515
+ resp = await resp.totpApprove(oidcClient, code);
501
516
  assert(!resp.requiresMfa());
502
517
  console.log(resp.data());
503
518
  assert(resp.data().rlp_signed_tx);
@@ -510,7 +525,8 @@ we created.
510
525
 
511
526
  ```typescript
512
527
  console.log("Cleaning up");
513
- await session.sessionMgr.revoke();
528
+ await signingClient.revokeSession();
529
+ await roleClient.revokeSession();
514
530
  await role.delete();
515
531
  ```
516
532
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cubist-labs/cubesigner-sdk",
3
- "version": "0.3.29",
3
+ "version": "0.4.24-0",
4
4
  "description": "CubeSigner TypeScript SDK",
5
5
  "license": "MIT OR Apache-2.0",
6
6
  "author": "Cubist, Inc.",
@@ -27,7 +27,7 @@
27
27
  "typedoc": "typedoc"
28
28
  },
29
29
  "dependencies": {
30
- "openapi-fetch": "0.6.1"
30
+ "openapi-fetch": "0.8.2"
31
31
  },
32
32
  "optionalDependencies": {
33
33
  "@hpke/core": "^1.2.7"
@@ -37,5 +37,8 @@
37
37
  },
38
38
  "directories": {
39
39
  "test": "test"
40
+ },
41
+ "devDependencies": {
42
+ "openapi-typescript-helpers": "^0.0.7"
40
43
  }
41
44
  }
@@ -332,10 +332,9 @@ export declare class CubeSignerApi {
332
332
  * List all keys in the org.
333
333
  * @param {KeyType?} type Optional key type to filter list for.
334
334
  * @param {PageOpts?} page Pagination options. Defaults to fetching the entire result set.
335
- * @param {string?} owner Optional key owner to filter list for.
336
335
  * @return {Paginator<ListKeysResponse, KeyInfoApi>} Paginator for iterating over keys.
337
336
  */
338
- keysList(type?: KeyType, page?: PageOpts, owner?: string): Paginator<ListKeysResponse, KeyInfoApi>;
337
+ keysList(type?: KeyType, page?: PageOpts): Paginator<ListKeysResponse, KeyInfoApi>;
339
338
  /**
340
339
  * Create a new role.
341
340
  *