@cubist-labs/cubesigner-sdk 0.4.244 → 0.4.246

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 (53) hide show
  1. package/dist/package.json +1 -1
  2. package/dist/spec/env/gamma.json +5 -0
  3. package/dist/src/audit_log.d.ts +3 -3
  4. package/dist/src/client/api_client.d.ts +13 -6
  5. package/dist/src/client/api_client.d.ts.map +1 -1
  6. package/dist/src/client/api_client.js +23 -13
  7. package/dist/src/client/base_client.d.ts +5 -1
  8. package/dist/src/client/base_client.d.ts.map +1 -1
  9. package/dist/src/client/base_client.js +15 -9
  10. package/dist/src/client/session.d.ts +3 -1
  11. package/dist/src/client/session.d.ts.map +1 -1
  12. package/dist/src/client/session.js +7 -3
  13. package/dist/src/client.d.ts +12 -5
  14. package/dist/src/client.d.ts.map +1 -1
  15. package/dist/src/client.js +15 -4
  16. package/dist/src/diffie_hellman.js +2 -2
  17. package/dist/src/env.d.ts +7 -0
  18. package/dist/src/env.d.ts.map +1 -1
  19. package/dist/src/env.js +14 -1
  20. package/dist/src/key.js +3 -3
  21. package/dist/src/policy.d.ts +24 -7
  22. package/dist/src/policy.d.ts.map +1 -1
  23. package/dist/src/policy.js +34 -16
  24. package/dist/src/response.d.ts +3 -3
  25. package/dist/src/response.d.ts.map +1 -1
  26. package/dist/src/response.js +3 -6
  27. package/dist/src/schema.d.ts +186 -33
  28. package/dist/src/schema.d.ts.map +1 -1
  29. package/dist/src/schema.js +1 -1
  30. package/dist/src/schema_types.d.ts.map +1 -1
  31. package/dist/src/schema_types.js +2 -1
  32. package/dist/src/scopes.d.ts.map +1 -1
  33. package/dist/src/scopes.js +14 -11
  34. package/dist/src/user_export.d.ts +1 -1
  35. package/dist/src/user_export.js +3 -3
  36. package/dist/src/util.d.ts +7 -0
  37. package/dist/src/util.d.ts.map +1 -1
  38. package/dist/src/util.js +30 -7
  39. package/package.json +1 -1
  40. package/src/client/api_client.ts +26 -14
  41. package/src/client/base_client.ts +12 -2
  42. package/src/client/session.ts +10 -3
  43. package/src/client.ts +17 -4
  44. package/src/diffie_hellman.ts +1 -1
  45. package/src/env.ts +17 -0
  46. package/src/key.ts +2 -2
  47. package/src/policy.ts +34 -16
  48. package/src/response.ts +6 -9
  49. package/src/schema.ts +202 -49
  50. package/src/schema_types.ts +1 -0
  51. package/src/scopes.ts +13 -10
  52. package/src/user_export.ts +2 -2
  53. package/src/util.ts +34 -8
@@ -63,4 +63,11 @@ export declare function delay(ms: number): Promise<void>;
63
63
  * @returns Hex string prefixed with "0x"
64
64
  */
65
65
  export declare function encodeToHex(message: string | Uint8Array): string;
66
+ /**
67
+ * Decodes a hex string into a byte array.
68
+ *
69
+ * @param hex The hex string to decode, with or without a "0x" prefix
70
+ * @returns Decoded byte array
71
+ */
72
+ export declare function decodeFromHex(hex: string): Uint8Array;
66
73
  //# sourceMappingURL=util.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../src/util.ts"],"names":[],"mappings":"AAAA,oBAAoB;AACpB,MAAM,WAAW,OAAO;IACtB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAAC;CAC1E;AAED,sBAAsB;AACtB,MAAM,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAAC,CAAC;AAEtF,qBAAqB;AACrB,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAAC;AAE/E,iCAAiC;AACjC,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAG1D;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAIpD;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CAI1D;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,WAAW,GAAG,MAAM,CAO7E;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,WAAW,GAAG,MAAM,CAIhF;AAED;;;;;GAKG;AACH,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/C;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,MAAM,CAGhE"}
1
+ {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../src/util.ts"],"names":[],"mappings":"AAAA,oBAAoB;AACpB,MAAM,WAAW,OAAO;IACtB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAAC;CAC1E;AAED,sBAAsB;AACtB,MAAM,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAAC,CAAC;AAEtF,qBAAqB;AACrB,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAAC;AAE/E,iCAAiC;AACjC,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAG1D;AAKD;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAIpD;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CAI1D;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,WAAW,GAAG,MAAM,CAM7E;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,WAAW,GAAG,MAAM,CAIhF;AAED;;;;;GAKG;AACH,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/C;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,MAAM,CAGhE;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAgBrD"}
package/dist/src/util.js CHANGED
@@ -7,6 +7,7 @@ exports.encodeToBase64 = encodeToBase64;
7
7
  exports.encodeToBase64Url = encodeToBase64Url;
8
8
  exports.delay = delay;
9
9
  exports.encodeToHex = encodeToHex;
10
+ exports.decodeFromHex = decodeFromHex;
10
11
  /**
11
12
  * Path join
12
13
  *
@@ -18,6 +19,8 @@ function pathJoin(dir, file) {
18
19
  const sep = globalThis?.process?.platform === "win32" ? "\\" : "/";
19
20
  return `${dir}${sep}${file}`;
20
21
  }
22
+ // eslint-disable-next-line no-restricted-globals -- intentionally checking for Buffer before using it
23
+ const nodeBuffer = typeof Buffer === "function" ? Buffer : undefined;
21
24
  /**
22
25
  * Browser-friendly helper for decoding a 'base64'-encoded string into a byte array.
23
26
  *
@@ -25,8 +28,8 @@ function pathJoin(dir, file) {
25
28
  * @returns Decoded byte array
26
29
  */
27
30
  function decodeBase64(b64) {
28
- return typeof Buffer === "function"
29
- ? Buffer.from(b64, "base64")
31
+ return nodeBuffer
32
+ ? nodeBuffer.from(b64, "base64")
30
33
  : Uint8Array.from(atob(b64), (c) => c.charCodeAt(0));
31
34
  }
32
35
  /**
@@ -49,8 +52,8 @@ function decodeBase64Url(b64url) {
49
52
  */
50
53
  function encodeToBase64(buffer) {
51
54
  const bytes = buffer instanceof ArrayBuffer ? new Uint8Array(buffer) : new Uint8Array(buffer);
52
- const b64 = typeof Buffer === "function"
53
- ? Buffer.from(bytes).toString("base64")
55
+ const b64 = nodeBuffer
56
+ ? nodeBuffer.from(bytes).toString("base64")
54
57
  : btoa(bytes.reduce((s, b) => s + String.fromCharCode(b), ""));
55
58
  return b64;
56
59
  }
@@ -82,7 +85,27 @@ function delay(ms) {
82
85
  * @returns Hex string prefixed with "0x"
83
86
  */
84
87
  function encodeToHex(message) {
85
- const buff = typeof message === "string" ? Buffer.from(message, "utf8") : Buffer.from(message);
86
- return "0x" + buff.toString("hex");
88
+ const bytes = typeof message === "string" ? new TextEncoder().encode(message) : message;
89
+ return "0x" + Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
87
90
  }
88
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBd0JBLDRCQUdDO0FBUUQsb0NBSUM7QUFRRCwwQ0FJQztBQVNELHdDQU9DO0FBUUQsOENBSUM7QUFRRCxzQkFFQztBQVNELGtDQUdDO0FBcEZEOzs7Ozs7R0FNRztBQUNILFNBQWdCLFFBQVEsQ0FBQyxHQUFXLEVBQUUsSUFBWTtJQUNoRCxNQUFNLEdBQUcsR0FBRyxVQUFVLEVBQUUsT0FBTyxFQUFFLFFBQVEsS0FBSyxPQUFPLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDO0lBQ25FLE9BQU8sR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLElBQUksRUFBRSxDQUFDO0FBQy9CLENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILFNBQWdCLFlBQVksQ0FBQyxHQUFXO0lBQ3RDLE9BQU8sT0FBTyxNQUFNLEtBQUssVUFBVTtRQUNqQyxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsUUFBUSxDQUFDO1FBQzVCLENBQUMsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3pELENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILFNBQWdCLGVBQWUsQ0FBQyxNQUFjO0lBQzVDLG9HQUFvRztJQUNwRyxNQUFNLEdBQUcsR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDN0UsT0FBTyxZQUFZLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDM0IsQ0FBQztBQUVEOzs7Ozs7R0FNRztBQUNILFNBQWdCLGNBQWMsQ0FBQyxNQUFzQztJQUNuRSxNQUFNLEtBQUssR0FBRyxNQUFNLFlBQVksV0FBVyxDQUFDLENBQUMsQ0FBQyxJQUFJLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDOUYsTUFBTSxHQUFHLEdBQ1AsT0FBTyxNQUFNLEtBQUssVUFBVTtRQUMxQixDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDO1FBQ3ZDLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDbkUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBRUQ7Ozs7O0dBS0c7QUFDSCxTQUFnQixpQkFBaUIsQ0FBQyxNQUFzQztJQUN0RSxNQUFNLEdBQUcsR0FBRyxjQUFjLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDbkMsb0dBQW9HO0lBQ3BHLE9BQU8sR0FBRyxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0FBQ3pFLENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILFNBQWdCLEtBQUssQ0FBQyxFQUFVO0lBQzlCLE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLFVBQVUsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUMzRCxDQUFDO0FBRUQ7Ozs7OztHQU1HO0FBQ0gsU0FBZ0IsV0FBVyxDQUFDLE9BQTRCO0lBQ3RELE1BQU0sSUFBSSxHQUFHLE9BQU8sT0FBTyxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDL0YsT0FBTyxJQUFJLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUNyQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqIEpTT04gbWFwIHR5cGUgKi9cbmV4cG9ydCBpbnRlcmZhY2UgSnNvbk1hcCB7XG4gIFttZW1iZXI6IHN0cmluZ106IHN0cmluZyB8IG51bWJlciB8IGJvb2xlYW4gfCBudWxsIHwgSnNvbkFycmF5IHwgSnNvbk1hcDtcbn1cblxuLyoqIEpTT04gYXJyYXkgdHlwZSAqL1xuZXhwb3J0IHR5cGUgSnNvbkFycmF5ID0gQXJyYXk8c3RyaW5nIHwgbnVtYmVyIHwgYm9vbGVhbiB8IG51bGwgfCBKc29uQXJyYXkgfCBKc29uTWFwPjtcblxuLyoqIEFueSBKU09OIHZhbHVlICovXG5leHBvcnQgdHlwZSBKc29uVmFsdWUgPSBzdHJpbmcgfCBudW1iZXIgfCBib29sZWFuIHwgbnVsbCB8IEpzb25BcnJheSB8IEpzb25NYXA7XG5cbi8qKiBUaGUgYWRkcmVzcyBvZiBhIGNvbnRyYWN0LiAqL1xuZXhwb3J0IHR5cGUgQ29udHJhY3RBZGRyZXNzID0ge1xuICBjaGFpbl9pZDogc3RyaW5nO1xuICBhZGRyZXNzOiBzdHJpbmc7XG59O1xuXG4vKipcbiAqIFBhdGggam9pblxuICpcbiAqIEBwYXJhbSBkaXIgUGFyZW50IGRpcmVjdG9yeVxuICogQHBhcmFtIGZpbGUgUGF0aG5hbWVcbiAqIEByZXR1cm5zIE5ldyBwYXRobmFtZVxuICovXG5leHBvcnQgZnVuY3Rpb24gcGF0aEpvaW4oZGlyOiBzdHJpbmcsIGZpbGU6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IHNlcCA9IGdsb2JhbFRoaXM/LnByb2Nlc3M/LnBsYXRmb3JtID09PSBcIndpbjMyXCIgPyBcIlxcXFxcIiA6IFwiL1wiO1xuICByZXR1cm4gYCR7ZGlyfSR7c2VwfSR7ZmlsZX1gO1xufVxuXG4vKipcbiAqIEJyb3dzZXItZnJpZW5kbHkgaGVscGVyIGZvciBkZWNvZGluZyBhICdiYXNlNjQnLWVuY29kZWQgc3RyaW5nIGludG8gYSBieXRlIGFycmF5LlxuICpcbiAqIEBwYXJhbSBiNjQgVGhlICdiYXNlNjQnLWVuY29kZWQgc3RyaW5nIHRvIGRlY29kZVxuICogQHJldHVybnMgRGVjb2RlZCBieXRlIGFycmF5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZWNvZGVCYXNlNjQoYjY0OiBzdHJpbmcpOiBVaW50OEFycmF5IHtcbiAgcmV0dXJuIHR5cGVvZiBCdWZmZXIgPT09IFwiZnVuY3Rpb25cIlxuICAgID8gQnVmZmVyLmZyb20oYjY0LCBcImJhc2U2NFwiKVxuICAgIDogVWludDhBcnJheS5mcm9tKGF0b2IoYjY0KSwgKGMpID0+IGMuY2hhckNvZGVBdCgwKSk7XG59XG5cbi8qKlxuICogQnJvd3Nlci1mcmllbmRseSBoZWxwZXIgZm9yIGRlY29kaW5nIGEgJ2Jhc2U2NHVybCctZW5jb2RlZCBzdHJpbmcgaW50byBhIGJ5dGUgYXJyYXkuXG4gKlxuICogQHBhcmFtIGI2NHVybCBUaGUgJ2Jhc2U2NHVybCctZW5jb2RlZCBzdHJpbmcgdG8gZGVjb2RlXG4gKiBAcmV0dXJucyBEZWNvZGVkIGJ5dGUgYXJyYXlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlY29kZUJhc2U2NFVybChiNjR1cmw6IHN0cmluZyk6IFVpbnQ4QXJyYXkge1xuICAvLyBOT1RFOiB0aGVyZSBpcyBubyBcImJhc2U2NHVybFwiIGVuY29kaW5nIGluIHRoZSBcImJ1ZmZlclwiIG1vZHVsZSBmb3IgdGhlIGJyb3dzZXIgKHVubGlrZSBpbiBub2RlLmpzKVxuICBjb25zdCBiNjQgPSBiNjR1cmwucmVwbGFjZSgvLS9nLCBcIitcIikucmVwbGFjZSgvXy9nLCBcIi9cIikucmVwbGFjZSgvPSokL2csIFwiXCIpO1xuICByZXR1cm4gZGVjb2RlQmFzZTY0KGI2NCk7XG59XG5cbi8qKlxuICpcbiAqIEJyb3dzZXItZnJpZW5kbHkgaGVscGVyIGZvciBlbmNvZGluZyBhIGJ5dGUgYXJyYXkgaW50byBhIHBhZGRlZCBgYmFzZTY0YC1lbmNvZGVkIHN0cmluZy5cbiAqXG4gKiBAcGFyYW0gYnVmZmVyIFRoZSBieXRlIGFycmF5IHRvIGVuY29kZVxuICogQHJldHVybnMgVGhlICdiYXNlNjQnIGVuY29kaW5nIG9mIHRoZSBieXRlIGFycmF5LlxuICovXG5leHBvcnQgZnVuY3Rpb24gZW5jb2RlVG9CYXNlNjQoYnVmZmVyOiBJdGVyYWJsZTxudW1iZXI+IHwgQXJyYXlCdWZmZXIpOiBzdHJpbmcge1xuICBjb25zdCBieXRlcyA9IGJ1ZmZlciBpbnN0YW5jZW9mIEFycmF5QnVmZmVyID8gbmV3IFVpbnQ4QXJyYXkoYnVmZmVyKSA6IG5ldyBVaW50OEFycmF5KGJ1ZmZlcik7XG4gIGNvbnN0IGI2NCA9XG4gICAgdHlwZW9mIEJ1ZmZlciA9PT0gXCJmdW5jdGlvblwiXG4gICAgICA/IEJ1ZmZlci5mcm9tKGJ5dGVzKS50b1N0cmluZyhcImJhc2U2NFwiKVxuICAgICAgOiBidG9hKGJ5dGVzLnJlZHVjZSgocywgYikgPT4gcyArIFN0cmluZy5mcm9tQ2hhckNvZGUoYiksIFwiXCIpKTtcbiAgcmV0dXJuIGI2NDtcbn1cblxuLyoqXG4gKiBCcm93c2VyLWZyaWVuZGx5IGhlbHBlciBmb3IgZW5jb2RpbmcgYSBieXRlIGFycmF5IGludG8gYSAnYmFzZTY0dXJsYC1lbmNvZGVkIHN0cmluZy5cbiAqXG4gKiBAcGFyYW0gYnVmZmVyIFRoZSBieXRlIGFycmF5IHRvIGVuY29kZVxuICogQHJldHVybnMgVGhlICdiYXNlNjR1cmwnIGVuY29kaW5nIG9mIHRoZSBieXRlIGFycmF5LlxuICovXG5leHBvcnQgZnVuY3Rpb24gZW5jb2RlVG9CYXNlNjRVcmwoYnVmZmVyOiBJdGVyYWJsZTxudW1iZXI+IHwgQXJyYXlCdWZmZXIpOiBzdHJpbmcge1xuICBjb25zdCBiNjQgPSBlbmNvZGVUb0Jhc2U2NChidWZmZXIpO1xuICAvLyBOT1RFOiB0aGVyZSBpcyBubyBcImJhc2U2NHVybFwiIGVuY29kaW5nIGluIHRoZSBcImJ1ZmZlclwiIG1vZHVsZSBmb3IgdGhlIGJyb3dzZXIgKHVubGlrZSBpbiBub2RlLmpzKVxuICByZXR1cm4gYjY0LnJlcGxhY2UoL1xcKy9nLCBcIi1cIikucmVwbGFjZSgvXFwvL2csIFwiX1wiKS5yZXBsYWNlKC89KiQvZywgXCJcIik7XG59XG5cbi8qKlxuICogU2xlZXBzIGZvciBgbXNgIG1pbGxpc2Vjb25kcy5cbiAqXG4gKiBAcGFyYW0gbXMgTWlsbGlzZWNvbmRzIHRvIHNsZWVwXG4gKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCBpcyByZXNvbHZlZCBhZnRlciBgbXNgIG1pbGxpc2Vjb25kcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlbGF5KG1zOiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIG1zKSk7XG59XG5cbi8qKlxuICogQ29udmVydHMgYSBzdHJpbmcgb3IgYSB1aW50OCBhcnJheSBpbnRvIGEgaGV4IHN0cmluZy4gU3RyaW5ncyBhcmUgZW5jb2RlZCBpbiBVVEYtOCBiZWZvcmVcbiAqIGJlaW5nIGNvbnZlcnRlZCB0byBoZXguXG4gKlxuICogQHBhcmFtIG1lc3NhZ2UgVGhlIGlucHV0XG4gKiBAcmV0dXJucyBIZXggc3RyaW5nIHByZWZpeGVkIHdpdGggXCIweFwiXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlbmNvZGVUb0hleChtZXNzYWdlOiBzdHJpbmcgfCBVaW50OEFycmF5KTogc3RyaW5nIHtcbiAgY29uc3QgYnVmZiA9IHR5cGVvZiBtZXNzYWdlID09PSBcInN0cmluZ1wiID8gQnVmZmVyLmZyb20obWVzc2FnZSwgXCJ1dGY4XCIpIDogQnVmZmVyLmZyb20obWVzc2FnZSk7XG4gIHJldHVybiBcIjB4XCIgKyBidWZmLnRvU3RyaW5nKFwiaGV4XCIpO1xufVxuIl19
91
+ /**
92
+ * Decodes a hex string into a byte array.
93
+ *
94
+ * @param hex The hex string to decode, with or without a "0x" prefix
95
+ * @returns Decoded byte array
96
+ */
97
+ function decodeFromHex(hex) {
98
+ const clean = hex.startsWith("0x") ? hex.slice(2) : hex;
99
+ if (clean.length % 2 !== 0) {
100
+ throw new Error(`Invalid hexadecimal string length, must be even: ${clean.length}`);
101
+ }
102
+ if (!/^[0-9a-fA-F]*$/.test(clean)) {
103
+ throw new Error(`Invalid hexadecimal character in: '${clean}'`);
104
+ }
105
+ const bytes = new Uint8Array(clean.length / 2);
106
+ for (let i = 0; i < bytes.length; i++) {
107
+ bytes[i] = parseInt(clean.slice(i * 2, i * 2 + 2), 16);
108
+ }
109
+ return bytes;
110
+ }
111
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBd0JBLDRCQUdDO0FBV0Qsb0NBSUM7QUFRRCwwQ0FJQztBQVNELHdDQU1DO0FBUUQsOENBSUM7QUFRRCxzQkFFQztBQVNELGtDQUdDO0FBUUQsc0NBZ0JDO0FBOUdEOzs7Ozs7R0FNRztBQUNILFNBQWdCLFFBQVEsQ0FBQyxHQUFXLEVBQUUsSUFBWTtJQUNoRCxNQUFNLEdBQUcsR0FBRyxVQUFVLEVBQUUsT0FBTyxFQUFFLFFBQVEsS0FBSyxPQUFPLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDO0lBQ25FLE9BQU8sR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLElBQUksRUFBRSxDQUFDO0FBQy9CLENBQUM7QUFFRCxzR0FBc0c7QUFDdEcsTUFBTSxVQUFVLEdBQUcsT0FBTyxNQUFNLEtBQUssVUFBVSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztBQUVyRTs7Ozs7R0FLRztBQUNILFNBQWdCLFlBQVksQ0FBQyxHQUFXO0lBQ3RDLE9BQU8sVUFBVTtRQUNmLENBQUMsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxRQUFRLENBQUM7UUFDaEMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDekQsQ0FBQztBQUVEOzs7OztHQUtHO0FBQ0gsU0FBZ0IsZUFBZSxDQUFDLE1BQWM7SUFDNUMsb0dBQW9HO0lBQ3BHLE1BQU0sR0FBRyxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsR0FBRyxD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TSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7UUFDdEMsS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztJQUN6RCxDQUFDO0lBQ0QsT0FBTyxLQUFLLENBQUM7QUFDZixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqIEpTT04gbWFwIHR5cGUgKi9cbmV4cG9ydCBpbnRlcmZhY2UgSnNvbk1hcCB7XG4gIFttZW1iZXI6IHN0cmluZ106IHN0cmluZyB8IG51bWJlciB8IGJvb2xlYW4gfCBudWxsIHwgSnNvbkFycmF5IHwgSnNvbk1hcDtcbn1cblxuLyoqIEpTT04gYXJyYXkgdHlwZSAqL1xuZXhwb3J0IHR5cGUgSnNvbkFycmF5ID0gQXJyYXk8c3RyaW5nIHwgbnVtYmVyIHwgYm9vbGVhbiB8IG51bGwgfCBKc29uQXJyYXkgfCBKc29uTWFwPjtcblxuLyoqIEFueSBKU09OIHZhbHVlICovXG5leHBvcnQgdHlwZSBKc29uVmFsdWUgPSBzdHJpbmcgfCBudW1iZXIgfCBib29sZWFuIHwgbnVsbCB8IEpzb25BcnJheSB8IEpzb25NYXA7XG5cbi8qKiBUaGUgYWRkcmVzcyBvZiBhIGNvbnRyYWN0LiAqL1xuZXhwb3J0IHR5cGUgQ29udHJhY3RBZGRyZXNzID0ge1xuICBjaGFpbl9pZDogc3RyaW5nO1xuICBhZGRyZXNzOiBzdHJpbmc7XG59O1xuXG4vKipcbiAqIFBhdGggam9pblxuICpcbiAqIEBwYXJhbSBkaXIgUGFyZW50IGRpcmVjdG9yeVxuICogQHBhcmFtIGZpbGUgUGF0aG5hbWVcbiAqIEByZXR1cm5zIE5ldyBwYXRobmFtZVxuICovXG5leHBvcnQgZnVuY3Rpb24gcGF0aEpvaW4oZGlyOiBzdHJpbmcsIGZpbGU6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IHNlcCA9IGdsb2JhbFRoaXM/LnByb2Nlc3M/LnBsYXRmb3JtID09PSBcIndpbjMyXCIgPyBcIlxcXFxcIiA6IFwiL1wiO1xuICByZXR1cm4gYCR7ZGlyfSR7c2VwfSR7ZmlsZX1gO1xufVxuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcmVzdHJpY3RlZC1nbG9iYWxzIC0tIGludGVudGlvbmFsbHkgY2hlY2tpbmcgZm9yIEJ1ZmZlciBiZWZvcmUgdXNpbmcgaXRcbmNvbnN0IG5vZGVCdWZmZXIgPSB0eXBlb2YgQnVmZmVyID09PSBcImZ1bmN0aW9uXCIgPyBCdWZmZXIgOiB1bmRlZmluZWQ7XG5cbi8qKlxuICogQnJvd3Nlci1mcmllbmRseSBoZWxwZXIgZm9yIGRlY29kaW5nIGEgJ2Jhc2U2NCctZW5jb2RlZCBzdHJpbmcgaW50byBhIGJ5dGUgYXJyYXkuXG4gKlxuICogQHBhcmFtIGI2NCBUaGUgJ2Jhc2U2NCctZW5jb2RlZCBzdHJpbmcgdG8gZGVjb2RlXG4gKiBAcmV0dXJucyBEZWNvZGVkIGJ5dGUgYXJyYXlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlY29kZUJhc2U2NChiNjQ6IHN0cmluZyk6IFVpbnQ4QXJyYXkge1xuICByZXR1cm4gbm9kZUJ1ZmZlclxuICAgID8gbm9kZUJ1ZmZlci5mcm9tKGI2NCwgXCJiYXNlNjRcIilcbiAgICA6IFVpbnQ4QXJyYXkuZnJvbShhdG9iKGI2NCksIChjKSA9PiBjLmNoYXJDb2RlQXQoMCkpO1xufVxuXG4vKipcbiAqIEJyb3dzZXItZnJpZW5kbHkgaGVscGVyIGZvciBkZWNvZGluZyBhICdiYXNlNjR1cmwnLWVuY29kZWQgc3RyaW5nIGludG8gYSBieXRlIGFycmF5LlxuICpcbiAqIEBwYXJhbSBiNjR1cmwgVGhlICdiYXNlNjR1cmwnLWVuY29kZWQgc3RyaW5nIHRvIGRlY29kZVxuICogQHJldHVybnMgRGVjb2RlZCBieXRlIGFycmF5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZWNvZGVCYXNlNjRVcmwoYjY0dXJsOiBzdHJpbmcpOiBVaW50OEFycmF5IHtcbiAgLy8gTk9URTogdGhlcmUgaXMgbm8gXCJiYXNlNjR1cmxcIiBlbmNvZGluZyBpbiB0aGUgXCJidWZmZXJcIiBtb2R1bGUgZm9yIHRoZSBicm93c2VyICh1bmxpa2UgaW4gbm9kZS5qcylcbiAgY29uc3QgYjY0ID0gYjY0dXJsLnJlcGxhY2UoLy0vZywgXCIrXCIpLnJlcGxhY2UoL18vZywgXCIvXCIpLnJlcGxhY2UoLz0qJC9nLCBcIlwiKTtcbiAgcmV0dXJuIGRlY29kZUJhc2U2NChiNjQpO1xufVxuXG4vKipcbiAqXG4gKiBCcm93c2VyLWZyaWVuZGx5IGhlbHBlciBmb3IgZW5jb2RpbmcgYSBieXRlIGFycmF5IGludG8gYSBwYWRkZWQgYGJhc2U2NGAtZW5jb2RlZCBzdHJpbmcuXG4gKlxuICogQHBhcmFtIGJ1ZmZlciBUaGUgYnl0ZSBhcnJheSB0byBlbmNvZGVcbiAqIEByZXR1cm5zIFRoZSAnYmFzZTY0JyBlbmNvZGluZyBvZiB0aGUgYnl0ZSBhcnJheS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGVuY29kZVRvQmFzZTY0KGJ1ZmZlcjogSXRlcmFibGU8bnVtYmVyPiB8IEFycmF5QnVmZmVyKTogc3RyaW5nIHtcbiAgY29uc3QgYnl0ZXMgPSBidWZmZXIgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlciA/IG5ldyBVaW50OEFycmF5KGJ1ZmZlcikgOiBuZXcgVWludDhBcnJheShidWZmZXIpO1xuICBjb25zdCBiNjQgPSBub2RlQnVmZmVyXG4gICAgPyBub2RlQnVmZmVyLmZyb20oYnl0ZXMpLnRvU3RyaW5nKFwiYmFzZTY0XCIpXG4gICAgOiBidG9hKGJ5dGVzLnJlZHVjZSgocywgYikgPT4gcyArIFN0cmluZy5mcm9tQ2hhckNvZGUoYiksIFwiXCIpKTtcbiAgcmV0dXJuIGI2NDtcbn1cblxuLyoqXG4gKiBCcm93c2VyLWZyaWVuZGx5IGhlbHBlciBmb3IgZW5jb2RpbmcgYSBieXRlIGFycmF5IGludG8gYSAnYmFzZTY0dXJsYC1lbmNvZGVkIHN0cmluZy5cbiAqXG4gKiBAcGFyYW0gYnVmZmVyIFRoZSBieXRlIGFycmF5IHRvIGVuY29kZVxuICogQHJldHVybnMgVGhlICdiYXNlNjR1cmwnIGVuY29kaW5nIG9mIHRoZSBieXRlIGFycmF5LlxuICovXG5leHBvcnQgZnVuY3Rpb24gZW5jb2RlVG9CYXNlNjRVcmwoYnVmZmVyOiBJdGVyYWJsZTxudW1iZXI+IHwgQXJyYXlCdWZmZXIpOiBzdHJpbmcge1xuICBjb25zdCBiNjQgPSBlbmNvZGVUb0Jhc2U2NChidWZmZXIpO1xuICAvLyBOT1RFOiB0aGVyZSBpcyBubyBcImJhc2U2NHVybFwiIGVuY29kaW5nIGluIHRoZSBcImJ1ZmZlclwiIG1vZHVsZSBmb3IgdGhlIGJyb3dzZXIgKHVubGlrZSBpbiBub2RlLmpzKVxuICByZXR1cm4gYjY0LnJlcGxhY2UoL1xcKy9nLCBcIi1cIikucmVwbGFjZSgvXFwvL2csIFwiX1wiKS5yZXBsYWNlKC89KiQvZywgXCJcIik7XG59XG5cbi8qKlxuICogU2xlZXBzIGZvciBgbXNgIG1pbGxpc2Vjb25kcy5cbiAqXG4gKiBAcGFyYW0gbXMgTWlsbGlzZWNvbmRzIHRvIHNsZWVwXG4gKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCBpcyByZXNvbHZlZCBhZnRlciBgbXNgIG1pbGxpc2Vjb25kcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlbGF5KG1zOiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIG1zKSk7XG59XG5cbi8qKlxuICogQ29udmVydHMgYSBzdHJpbmcgb3IgYSB1aW50OCBhcnJheSBpbnRvIGEgaGV4IHN0cmluZy4gU3RyaW5ncyBhcmUgZW5jb2RlZCBpbiBVVEYtOCBiZWZvcmVcbiAqIGJlaW5nIGNvbnZlcnRlZCB0byBoZXguXG4gKlxuICogQHBhcmFtIG1lc3NhZ2UgVGhlIGlucHV0XG4gKiBAcmV0dXJucyBIZXggc3RyaW5nIHByZWZpeGVkIHdpdGggXCIweFwiXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlbmNvZGVUb0hleChtZXNzYWdlOiBzdHJpbmcgfCBVaW50OEFycmF5KTogc3RyaW5nIHtcbiAgY29uc3QgYnl0ZXMgPSB0eXBlb2YgbWVzc2FnZSA9PT0gXCJzdHJpbmdcIiA/IG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShtZXNzYWdlKSA6IG1lc3NhZ2U7XG4gIHJldHVybiBcIjB4XCIgKyBBcnJheS5mcm9tKGJ5dGVzLCAoYikgPT4gYi50b1N0cmluZygxNikucGFkU3RhcnQoMiwgXCIwXCIpKS5qb2luKFwiXCIpO1xufVxuXG4vKipcbiAqIERlY29kZXMgYSBoZXggc3RyaW5nIGludG8gYSBieXRlIGFycmF5LlxuICpcbiAqIEBwYXJhbSBoZXggVGhlIGhleCBzdHJpbmcgdG8gZGVjb2RlLCB3aXRoIG9yIHdpdGhvdXQgYSBcIjB4XCIgcHJlZml4XG4gKiBAcmV0dXJucyBEZWNvZGVkIGJ5dGUgYXJyYXlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlY29kZUZyb21IZXgoaGV4OiBzdHJpbmcpOiBVaW50OEFycmF5IHtcbiAgY29uc3QgY2xlYW4gPSBoZXguc3RhcnRzV2l0aChcIjB4XCIpID8gaGV4LnNsaWNlKDIpIDogaGV4O1xuXG4gIGlmIChjbGVhbi5sZW5ndGggJSAyICE9PSAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIGhleGFkZWNpbWFsIHN0cmluZyBsZW5ndGgsIG11c3QgYmUgZXZlbjogJHtjbGVhbi5sZW5ndGh9YCk7XG4gIH1cblxuICBpZiAoIS9eWzAtOWEtZkEtRl0qJC8udGVzdChjbGVhbikpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgaGV4YWRlY2ltYWwgY2hhcmFjdGVyIGluOiAnJHtjbGVhbn0nYCk7XG4gIH1cblxuICBjb25zdCBieXRlcyA9IG5ldyBVaW50OEFycmF5KGNsZWFuLmxlbmd0aCAvIDIpO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGJ5dGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgYnl0ZXNbaV0gPSBwYXJzZUludChjbGVhbi5zbGljZShpICogMiwgaSAqIDIgKyAyKSwgMTYpO1xuICB9XG4gIHJldHVybiBieXRlcztcbn1cbiJdfQ==
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "url": "git+https://github.com/cubist-labs/CubeSigner-TypeScript-SDK.git",
6
6
  "directory": "packages/sdk"
7
7
  },
8
- "version": "0.4.244",
8
+ "version": "0.4.246",
9
9
  "description": "CubeSigner TypeScript SDK",
10
10
  "license": "MIT OR Apache-2.0",
11
11
  "author": "Cubist, Inc.",
@@ -159,6 +159,7 @@ import {
159
159
  coerceBucketInfo,
160
160
  coercePolicyInfo,
161
161
  type BucketInfo,
162
+ MultiRegionEnv,
162
163
  } from "../index";
163
164
  import { assertOk, op, type Op, type Operation, apiFetch } from "../fetch";
164
165
  import {
@@ -204,7 +205,7 @@ export type SessionSelector =
204
205
  */
205
206
  export class ApiClient extends BaseClient {
206
207
  /**
207
- * Creates a new client using the same session manager but targeting a
208
+ * Creates a **new** client using the same session manager but targeting a
208
209
  * different (child) organization.
209
210
  *
210
211
  * @param targetOrgId The ID of an organization that the new client should target
@@ -215,7 +216,7 @@ export class ApiClient extends BaseClient {
215
216
  }
216
217
 
217
218
  /**
218
- * Creates a new client using with an updated {@link ClientConfig}.
219
+ * Creates a **new** client using with an updated {@link ClientConfig}.
219
220
  *
220
221
  * @param cfg Partial configuration to apply on top of the existing client
221
222
  * @returns A new client with the updated configuration
@@ -229,7 +230,20 @@ export class ApiClient extends BaseClient {
229
230
  }
230
231
 
231
232
  /**
232
- * Creates a new client in which the current session will assume a given role.
233
+ * Creates a **new** client with a preferred regional environment {@link env} to use.
234
+ *
235
+ * @param env Preferred environment to use.
236
+ * @returns A new client with updated preferred environment.
237
+ */
238
+ withPreferredEnv(env: EnvInterface | undefined) {
239
+ return new ApiClient(this.sessionMeta, this.sessionManager, this.orgId, {
240
+ ...this.config,
241
+ preferredEnv: env,
242
+ });
243
+ }
244
+
245
+ /**
246
+ * Creates a **new** client in which the current session will assume a given role.
233
247
  * No validation is done on the client side; the back end will reject subsequent
234
248
  * requests if the current session is not allowed to assume that role.
235
249
  *
@@ -2744,7 +2758,7 @@ export class ApiClient extends BaseClient {
2744
2758
  ): Promise<CubeSignerResponse<UserExportCompleteResponse>> {
2745
2759
  // base64-encode the public key
2746
2760
  const subtle = await loadSubtleCrypto();
2747
- const publicKeyB64 = encodeToBase64(Buffer.from(await subtle.exportKey("raw", publicKey)));
2761
+ const publicKeyB64 = encodeToBase64(await subtle.exportKey("raw", publicKey));
2748
2762
 
2749
2763
  const o = op("/v0/org/{org_id}/user/me/export", "patch");
2750
2764
  // make the request
@@ -2996,7 +3010,7 @@ export class ApiClient extends BaseClient {
2996
3010
  * @returns The session data.
2997
3011
  */
2998
3012
  static async oidcSessionCreate(
2999
- env: EnvInterface,
3013
+ env: EnvInterface | MultiRegionEnv,
3000
3014
  orgId: string,
3001
3015
  token: string,
3002
3016
  scopes: Array<Scope>,
@@ -3007,10 +3021,11 @@ export class ApiClient extends BaseClient {
3007
3021
  ): Promise<CubeSignerResponse<SessionData>> {
3008
3022
  const o = op("/v0/org/{org_id}/oidc", "post");
3009
3023
 
3024
+ env = MultiRegionEnv.create(env);
3010
3025
  const loginFn = async (mfaHeaders?: HeadersInit) => {
3011
3026
  const data = await retryOn5XX(() =>
3012
3027
  o({
3013
- baseUrl: env.SignerApiRoot,
3028
+ baseUrl: env.primary.SignerApiRoot,
3014
3029
  params: { path: { org_id: orgId } },
3015
3030
  headers: mergeHeaders(headers, mfaHeaders, authHeader(token)),
3016
3031
  body: {
@@ -3023,9 +3038,7 @@ export class ApiClient extends BaseClient {
3023
3038
 
3024
3039
  return mapResponse(data, (sessionInfo): SessionData => {
3025
3040
  return {
3026
- env: {
3027
- ["Dev-CubeSignerStack"]: env,
3028
- },
3041
+ env: env.spec,
3029
3042
  org_id: orgId,
3030
3043
  token: sessionInfo.token,
3031
3044
  refresh_token: sessionInfo.refresh_token,
@@ -3132,23 +3145,22 @@ export class ApiClient extends BaseClient {
3132
3145
  * @returns The session data
3133
3146
  */
3134
3147
  static async passkeyLoginComplete(
3135
- env: EnvInterface,
3148
+ env: EnvInterface | MultiRegionEnv,
3136
3149
  body: PasskeyAssertAnswer,
3137
3150
  purpose?: string | null,
3138
3151
  headers?: HeadersInit,
3139
3152
  ): Promise<SessionData> {
3140
3153
  const o = op("/v0/passkey", "patch");
3154
+ env = MultiRegionEnv.create(env);
3141
3155
  const resp = await retryOn5XX(() =>
3142
3156
  o({
3143
- baseUrl: env.SignerApiRoot,
3157
+ baseUrl: env.primary.SignerApiRoot,
3144
3158
  body,
3145
3159
  headers,
3146
3160
  }),
3147
3161
  ).then(assertOk);
3148
3162
  return {
3149
- env: {
3150
- ["Dev-CubeSignerStack"]: env,
3151
- },
3163
+ env: env.spec,
3152
3164
  org_id: resp.org_id!, // 'org_id' is always set from this endpoint
3153
3165
  token: resp.token,
3154
3166
  refresh_token: resp.refresh_token,
@@ -78,9 +78,16 @@ export class BaseClient extends EventEmitter<ClientEvents> {
78
78
  /** MUTABLE configuration. */
79
79
  readonly config: ClientConfig;
80
80
 
81
+ readonly #preferredEnv: EnvInterface | undefined;
82
+
81
83
  /** @returns The env */
82
84
  get env(): EnvInterface {
83
- return this.sessionMeta.env["Dev-CubeSignerStack"];
85
+ return this.#preferredEnv ?? this.sessionMeta.env["Dev-CubeSignerStack"];
86
+ }
87
+
88
+ /** @returns All available regional environments */
89
+ get envs(): EnvInterface[] {
90
+ return Object.values(this.sessionMeta.env);
84
91
  }
85
92
 
86
93
  /**
@@ -126,10 +133,13 @@ export class BaseClient extends EventEmitter<ClientEvents> {
126
133
  sessionMeta: SessionMetadata,
127
134
  manager: SessionManager,
128
135
  targetOrgId?: string,
129
- config?: ClientConfig,
136
+ config?: ClientConfig & {
137
+ preferredEnv?: EnvInterface;
138
+ },
130
139
  ) {
131
140
  super();
132
141
  this.#targetOrgId = targetOrgId;
142
+ this.#preferredEnv = config?.preferredEnv;
133
143
  this.sessionManager = manager;
134
144
  this.sessionMeta = sessionMeta;
135
145
  this.config = {
@@ -1,4 +1,4 @@
1
- import type { EnvInterface, StackName } from "../env";
1
+ import type { EnvInterface, Region, StackName } from "../env";
2
2
  import { apiFetch, assertOk } from "../fetch";
3
3
  import { retryOn5XX } from "../retry";
4
4
  import type { ClientSessionInfo } from "../schema_types";
@@ -35,6 +35,9 @@ export interface SessionData {
35
35
  session_exp: number | null | undefined; // may be missing in legacy session files
36
36
  /** Available regional environment parameters */
37
37
  env: Record<StackName, EnvInterface>;
38
+ /** Other regional environments (not included in 'env'), mapped by region. */
39
+ // NOTE: this is the format the CLI produces
40
+ other_envs?: Record<Region, EnvInterface>;
38
41
  }
39
42
 
40
43
  // Rather than just doing a simple Pick, we go the extra mile to ensure that
@@ -284,9 +287,13 @@ export function refresh(session: SessionData): Promise<SessionData> {
284
287
  * @returns The session metadata
285
288
  */
286
289
  export function metadata(session: SessionData): SessionMetadata {
287
- const { env, org_id, role_id, purpose, session_exp } = session;
290
+ const { env, other_envs, org_id, role_id, purpose, session_exp } = session;
291
+ const merged = { ...env };
292
+ Object.entries(other_envs ?? {}).forEach(([region, env]) => {
293
+ merged[`Dev-CubeSignerStack-${region}`] = env;
294
+ });
288
295
  return {
289
- env,
296
+ env: merged,
290
297
  org_id,
291
298
  role_id,
292
299
  purpose,
package/src/client.ts CHANGED
@@ -5,7 +5,7 @@ import type { EmailOtpResponse, IdentityProof, RatchetConfig } from "./schema_ty
5
5
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
6
6
  import { AddFidoChallenge, TotpChallenge } from "./mfa";
7
7
  import { Org } from "./org";
8
- import type { MfaReceipts, SessionData, SessionInfo, SessionManager } from ".";
8
+ import type { EnvInterface, MfaReceipts, SessionData, SessionInfo, SessionManager } from ".";
9
9
  import { Key } from ".";
10
10
 
11
11
  /** Options for logging in with OIDC token */
@@ -30,13 +30,16 @@ export class CubeSignerClient {
30
30
  return this.#apiClient;
31
31
  }
32
32
 
33
- /**
34
- * @returns The environment.
35
- */
33
+ /** @returns The environment. */
36
34
  get env() {
37
35
  return this.#apiClient.env;
38
36
  }
39
37
 
38
+ /** @returns All available regional environments */
39
+ get envs() {
40
+ return this.#apiClient.envs;
41
+ }
42
+
40
43
  /**
41
44
  * @returns The org ID of the client.
42
45
  */
@@ -53,6 +56,16 @@ export class CubeSignerClient {
53
56
  this.#apiClient = apiClient;
54
57
  }
55
58
 
59
+ /**
60
+ * Creates a NEW client with a preferred regional environment {@link env} to use.
61
+ *
62
+ * @param env Preferred environment to use.
63
+ * @returns A new client with updated preferred environment.
64
+ */
65
+ withPreferredEnv(env: EnvInterface | undefined) {
66
+ return new CubeSignerClient(this.#apiClient.withPreferredEnv(env));
67
+ }
68
+
56
69
  /**
57
70
  * Construct a client with a session or session manager
58
71
  *
@@ -20,7 +20,7 @@ export async function diffieHellmanDecrypt(
20
20
  const suite = await userExportCipherSuite();
21
21
 
22
22
  // Decrypt the ciphertext using the HPKE one-shot API
23
- const tdec = new TextDecoder();
23
+ const tdec = new TextDecoder("utf-8");
24
24
  // this is the info string used by the back-end when encrypting
25
25
  const tenc = new TextEncoder();
26
26
  const info = toArrayBuffer(tenc.encode("cubist-signer::DiffieHellmanResult"));
package/src/env.ts CHANGED
@@ -56,6 +56,23 @@ export class MultiRegionEnv {
56
56
  }
57
57
  }
58
58
 
59
+ /**
60
+ * Convert either a single or multi-region environment to {@link MultiRegionEnv}.
61
+ *
62
+ * @param env Either a single or multi-region environment.
63
+ * @returns The resulting {@link MultiRegionEnv}
64
+ */
65
+ static create(env: EnvInterface | MultiRegionEnv): MultiRegionEnv {
66
+ return env instanceof MultiRegionEnv
67
+ ? env
68
+ : new MultiRegionEnv(
69
+ {
70
+ ["Dev-CubeSignerStack"]: env,
71
+ },
72
+ env.Region,
73
+ );
74
+ }
75
+
59
76
  /**
60
77
  * @returns The mapping from stack name to corresponding regional environment parameters.
61
78
  * @internal
package/src/key.ts CHANGED
@@ -658,8 +658,8 @@ export class Key {
658
658
  // construct the request
659
659
  const subtle = await loadSubtleCrypto();
660
660
  const req: DiffieHellmanRequest = {
661
- points: points.map((pt) => encodeToBase64(Buffer.from(pt))),
662
- public_key: encodeToBase64(Buffer.from(await subtle.exportKey("raw", publicKey))),
661
+ points: points.map((pt) => encodeToBase64(pt)),
662
+ public_key: encodeToBase64(await subtle.exportKey("raw", publicKey)),
663
663
  };
664
664
 
665
665
  // send
package/src/policy.ts CHANGED
@@ -21,7 +21,7 @@ import type {
21
21
  PolicyInfo,
22
22
  } from ".";
23
23
 
24
- import { loadSubtleCrypto } from ".";
24
+ import { loadSubtleCrypto, encodeToHex, decodeFromHex } from ".";
25
25
 
26
26
  /**
27
27
  * Named policy rule type.
@@ -104,7 +104,7 @@ export async function uploadWasmFunction(
104
104
  // get the SHA-256 hash of the function to get the upload url.
105
105
  const subtle = await loadSubtleCrypto();
106
106
  const hashBytes = await subtle.digest("SHA-256", policy);
107
- const hash = "0x" + Buffer.from(hashBytes).toString("hex");
107
+ const hash = encodeToHex(new Uint8Array(hashBytes));
108
108
 
109
109
  // get the upload URL
110
110
  const { signed_url } = await apiClient.wasmPolicyUpload({ hash });
@@ -619,28 +619,46 @@ export class C2FInvocation {
619
619
  return this.#data.response;
620
620
  }
621
621
 
622
- /** @returns The standard output stream. Usually a UTF-8 encoded string. */
623
- get stdout(): Buffer {
624
- return this.fromHex(this.#data.stdout);
622
+ /**
623
+ * The standard output stream as raw bytes. Usually a UTF-8 encoded string,
624
+ * use {@link TextDecoder} to decode.
625
+ *
626
+ * @returns The standard output stream.
627
+ */
628
+ get stdoutBytes(): Uint8Array {
629
+ return decodeFromHex(this.#data.stdout);
625
630
  }
626
631
 
627
- /** @returns The standard error stream. Usually a UTF-8 encoded string. */
628
- get stderr(): Buffer {
629
- return this.fromHex(this.#data.stderr);
632
+ /**
633
+ * The standard error stream as raw bytes. Usually a UTF-8 encoded string, use
634
+ * {@link TextDecoder} to decode.
635
+ *
636
+ * @returns The standard error stream.
637
+ */
638
+ get stderrBytes(): Uint8Array {
639
+ return decodeFromHex(this.#data.stderr);
630
640
  }
631
641
 
632
- // --------------------------------------------------------------------------
633
- // -- INTERNAL --------------------------------------------------------------
634
- // --------------------------------------------------------------------------
642
+ /**
643
+ * The standard output stream as a Buffer. Usually a UTF-8 encoded string.
644
+ *
645
+ * @returns The standard output stream.
646
+ * @deprecated Use {@link stdoutBytes} instead for browser compatibility.
647
+ */
648
+ get stdout(): Buffer {
649
+ // eslint-disable-next-line no-restricted-globals -- Buffer return type preserved for backwards compatibility
650
+ return Buffer.from(this.stdoutBytes);
651
+ }
635
652
 
636
653
  /**
637
- * Helper method for converting hex-encoded data to a `Buffer`.
654
+ * The standard error stream as a Buffer. Usually a UTF-8 encoded string.
638
655
  *
639
- * @param hex The hex-encoded data.
640
- * @returns The data.
656
+ * @returns The standard error stream.
657
+ * @deprecated Use {@link stderrBytes} instead for browser compatibility.
641
658
  */
642
- private fromHex(hex: string): Buffer {
643
- return Buffer.from(hex.startsWith("0x") ? hex.slice(2) : hex, "hex");
659
+ get stderr(): Buffer {
660
+ // eslint-disable-next-line no-restricted-globals -- Buffer return type preserved for backwards compatibility
661
+ return Buffer.from(this.stderrBytes);
644
662
  }
645
663
 
646
664
  /**
package/src/response.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { MfaVote, EnvInterface, MfaReceipts, MfaRequired } from ".";
2
- import { CubeSignerClient, isManyMfaReceipts } from ".";
2
+ import { CubeSignerClient, MultiRegionEnv, isManyMfaReceipts } from ".";
3
3
  import { encodeToBase64Url } from "./util";
4
4
  import type { AcceptedResponse, AcceptedValue, BinanceDryRun, SignDryRun } from "./schema_types";
5
5
 
@@ -51,7 +51,7 @@ function asAccepted<U>(resp: Response<U>): AcceptedValue | undefined {
51
51
  * A response of a CubeSigner request.
52
52
  */
53
53
  export class CubeSignerResponse<U> {
54
- readonly #env: EnvInterface;
54
+ readonly #env: MultiRegionEnv;
55
55
  readonly #requestFn: RequestFn<U>;
56
56
  readonly #resp: Response<U>;
57
57
 
@@ -120,11 +120,8 @@ export class CubeSignerResponse<U> {
120
120
  const session = this.asMfaRequired()?.session ?? undefined;
121
121
  if (session === undefined) return;
122
122
 
123
- const env = this.#env;
124
123
  return await CubeSignerClient.create({
125
- env: {
126
- "Dev-CubeSignerStack": env,
127
- },
124
+ env: this.#env.spec,
128
125
  org_id: this.mfaRequired.org_id,
129
126
  session_exp: session.expiration,
130
127
  session_info: session.session_info,
@@ -262,7 +259,7 @@ export class CubeSignerResponse<U> {
262
259
  * @param resp The response as returned by the OpenAPI client.
263
260
  * @internal
264
261
  */
265
- protected constructor(env: EnvInterface, requestFn: RequestFn<U>, resp: Response<U>) {
262
+ protected constructor(env: MultiRegionEnv, requestFn: RequestFn<U>, resp: Response<U>) {
266
263
  this.#env = env;
267
264
  this.#requestFn = requestFn;
268
265
  this.#resp = resp;
@@ -280,12 +277,12 @@ export class CubeSignerResponse<U> {
280
277
  * @internal
281
278
  */
282
279
  static async create<U>(
283
- env: EnvInterface,
280
+ env: EnvInterface | MultiRegionEnv,
284
281
  requestFn: RequestFn<U>,
285
282
  mfaReceipt?: MfaReceipts,
286
283
  ): Promise<CubeSignerResponse<U>> {
287
284
  const seed = await requestFn(this.getMfaHeaders(mfaReceipt));
288
- return new CubeSignerResponse(env, requestFn, seed);
285
+ return new CubeSignerResponse(MultiRegionEnv.create(env), requestFn, seed);
289
286
  }
290
287
 
291
288
  /**