@aptos-labs/ts-sdk 7.1.2 → 7.2.0-beta.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 (41) hide show
  1. package/dist/api/keyless.d.ts +25 -0
  2. package/dist/api/keyless.d.ts.map +1 -1
  3. package/dist/api/keyless.js +23 -1
  4. package/dist/api/keyless.js.map +1 -1
  5. package/dist/cli/localNode.d.ts.map +1 -1
  6. package/dist/cli/localNode.js +8 -8
  7. package/dist/cli/localNode.js.map +1 -1
  8. package/dist/cli/move.js +9 -9
  9. package/dist/cli/move.js.map +1 -1
  10. package/dist/cli/spawnArgs.d.ts +27 -0
  11. package/dist/cli/spawnArgs.d.ts.map +1 -1
  12. package/dist/cli/spawnArgs.js +55 -2
  13. package/dist/cli/spawnArgs.js.map +1 -1
  14. package/dist/core/crypto/federatedKeyless.d.ts +1 -0
  15. package/dist/core/crypto/federatedKeyless.d.ts.map +1 -1
  16. package/dist/core/crypto/federatedKeyless.js +4 -0
  17. package/dist/core/crypto/federatedKeyless.js.map +1 -1
  18. package/dist/core/crypto/keyless.d.ts +1 -0
  19. package/dist/core/crypto/keyless.d.ts.map +1 -1
  20. package/dist/core/crypto/keyless.js +7 -0
  21. package/dist/core/crypto/keyless.js.map +1 -1
  22. package/dist/internal/keyless.d.ts +26 -0
  23. package/dist/internal/keyless.d.ts.map +1 -1
  24. package/dist/internal/keyless.js +38 -0
  25. package/dist/internal/keyless.js.map +1 -1
  26. package/dist/types/keyless.d.ts +9 -0
  27. package/dist/types/keyless.d.ts.map +1 -1
  28. package/dist/version.d.ts +1 -1
  29. package/dist/version.d.ts.map +1 -1
  30. package/dist/version.js +1 -1
  31. package/dist/version.js.map +1 -1
  32. package/package.json +37 -25
  33. package/src/api/keyless.ts +29 -0
  34. package/src/cli/localNode.ts +8 -9
  35. package/src/cli/move.ts +9 -9
  36. package/src/cli/spawnArgs.ts +57 -2
  37. package/src/core/crypto/federatedKeyless.ts +4 -0
  38. package/src/core/crypto/keyless.ts +7 -0
  39. package/src/internal/keyless.ts +53 -1
  40. package/src/types/keyless.ts +8 -0
  41. package/src/version.ts +1 -1
@@ -25,7 +25,7 @@
25
25
  * Common, legitimate CLI argument characters (letters, digits, `-`, `_`,
26
26
  * `=`, `.`, `,`, `:`, `/`, `\`, space) are unaffected.
27
27
  */
28
- const UNSAFE_SHELL_CHARS = /[&|;<>`$()"'\n\r^!*?%]/;
28
+ const UNSAFE_SHELL_CHARS = /[&|;<>`$()[\]#"'\n\r^!*?%]/;
29
29
 
30
30
  /**
31
31
  * Validates that a CLI argument does not contain shell metacharacters that
@@ -40,7 +40,7 @@ export function assertSafeCliArg(arg: string): void {
40
40
  if (UNSAFE_SHELL_CHARS.test(arg)) {
41
41
  throw new Error(
42
42
  `CLI argument contains characters that could be interpreted by the shell: ${JSON.stringify(arg)}. ` +
43
- "Remove shell metacharacters (& | ; < > \" ' ` $ ( ) ^ ! * ? % newlines).",
43
+ "Remove shell metacharacters (& | ; < > \" ' ` $ ( ) [ ] # ^ ! * ? % newlines).",
44
44
  );
45
45
  }
46
46
  }
@@ -53,3 +53,58 @@ export function assertSafeCliArgs(args: ReadonlyArray<string>): void {
53
53
  assertSafeCliArg(arg);
54
54
  }
55
55
  }
56
+
57
+ /**
58
+ * Validates a single CLI argument and returns a copy with any shell
59
+ * metacharacters stripped out.
60
+ *
61
+ * {@link assertSafeCliArg} already rejects every shell metacharacter, so the
62
+ * scrubbing chain below is a runtime no-op for any argument that passes
63
+ * validation. We keep it as defense-in-depth and, importantly, so that static
64
+ * analysis (e.g. CodeQL's "Unsafe shell command constructed from library
65
+ * input" query) can see that the value flowing into `spawn(..., { shell: true })`
66
+ * on Windows has been stripped of shell metacharacters. CodeQL only recognizes
67
+ * a sequence of `String.prototype.replace` calls that covers every shell
68
+ * metacharacter as a sanitizer barrier; a `RegExp.test`-based guard in a
69
+ * separate function is not enough to break the tracked data flow.
70
+ *
71
+ * The chain strips every character that {@link UNSAFE_SHELL_CHARS}/
72
+ * {@link assertSafeCliArg} reject, so the scrub is a complete superset of the
73
+ * validation blocklist rather than only the subset CodeQL requires.
74
+ *
75
+ * @returns the validated argument with shell metacharacters removed.
76
+ * @throws Error if `arg` contains any unsafe shell character.
77
+ */
78
+ export function sanitizeCliArg(arg: string): string {
79
+ assertSafeCliArg(arg);
80
+ return arg
81
+ .replace(/&/g, "")
82
+ .replace(/\|/g, "")
83
+ .replace(/;/g, "")
84
+ .replace(/</g, "")
85
+ .replace(/>/g, "")
86
+ .replace(/`/g, "")
87
+ .replace(/\$/g, "")
88
+ .replace(/\(/g, "")
89
+ .replace(/\)/g, "")
90
+ .replace(/\[/g, "")
91
+ .replace(/\]/g, "")
92
+ .replace(/#/g, "")
93
+ .replace(/"/g, "")
94
+ .replace(/'/g, "")
95
+ .replace(/\^/g, "")
96
+ .replace(/!/g, "")
97
+ .replace(/\*/g, "")
98
+ .replace(/\?/g, "")
99
+ .replace(/%/g, "")
100
+ .replace(/\n/g, "")
101
+ .replace(/\r/g, "");
102
+ }
103
+
104
+ /**
105
+ * Validates and scrubs every element of an args array, returning the sanitized
106
+ * array that should be passed to `spawn`. See {@link sanitizeCliArg}.
107
+ */
108
+ export function sanitizeCliArgs(args: ReadonlyArray<string>): string[] {
109
+ return args.map(sanitizeCliArg);
110
+ }
@@ -16,6 +16,10 @@ import {
16
16
  } from "./keyless.js";
17
17
  import { AptosConfig } from "../../api/aptosConfig.js";
18
18
  import { Signature } from "../index.js";
19
+ // Register keyless variants so that importing `FederatedKeylessPublicKey` directly
20
+ // triggers registration without relying on the keyless.ts cross-import. Kept from being
21
+ // tree-shaken away via the `sideEffects` allowlist in package.json. See keyless.ts.
22
+ import "./keylessRegistration.js";
19
23
 
20
24
  /**
21
25
  * Represents the FederatedKeylessPublicKey public key
@@ -40,6 +40,13 @@ import { FederatedKeylessPublicKey } from "./federatedKeyless.js";
40
40
  import { generateSigningMessage } from "../../transactions/transactionBuilder/signingMessage.js";
41
41
  import { WeierstrassPoint } from "@noble/curves/abstract/weierstrass.js";
42
42
  import { Fp2 } from "@noble/curves/abstract/tower.js";
43
+ // Register keyless variants with the AnyPublicKey/AnySignature registry. This lives
44
+ // next to the primitive definitions so that importing any keyless primitive (e.g.
45
+ // `KeylessPublicKey`/`KeylessSignature`) triggers registration — not only importing an
46
+ // account class. It is kept from being tree-shaken away via the `sideEffects` allowlist
47
+ // in package.json. Without it, deserializing a keyless AnyPublicKey/AnySignature in a
48
+ // bundled (tree-shaken) build throws "Unknown variant index for AnyPublicKey: 3".
49
+ import "./keylessRegistration.js";
43
50
 
44
51
  /**
45
52
  * @group Implementation
@@ -27,7 +27,13 @@ import { Account } from "../account/index.js";
27
27
  import { EphemeralKeyPair } from "../account/EphemeralKeyPair.js";
28
28
  import { KeylessAccount } from "../account/KeylessAccount.js";
29
29
  import { ProofFetchCallback } from "../account/AbstractKeylessAccount.js";
30
- import { PepperFetchRequest, PepperFetchResponse, ProverRequest, ProverResponse } from "../types/keyless.js";
30
+ import {
31
+ PepperFetchRequest,
32
+ PepperFetchResponse,
33
+ ProverRequest,
34
+ ProverResponse,
35
+ SignatureFetchResponse,
36
+ } from "../types/keyless.js";
31
37
  import { lookupOriginalAccountAddress } from "./account.js";
32
38
  import { FederatedKeylessPublicKey } from "../core/crypto/federatedKeyless.js";
33
39
  import { FederatedKeylessAccount } from "../account/FederatedKeylessAccount.js";
@@ -76,6 +82,52 @@ export async function getPepper(args: {
76
82
  return Hex.fromHexInput(data.pepper).toUint8Array();
77
83
  }
78
84
 
85
+ /**
86
+ * Retrieves the `pepper_base` for an account — the VUF signature from which the final pepper is derived.
87
+ *
88
+ * Unlike {@link getPepper} (which hits the pepper service `fetch` endpoint and returns the 31-byte derived
89
+ * pepper), this hits the `signature` endpoint and returns the raw 48-byte `pepper_base` (a compressed
90
+ * BLS12-381 G1 point). `pepper_base` is deterministic for a given OIDC identity, independent of the ephemeral
91
+ * key and of the derivation path, which makes it a stable seed for deriving a confidential-asset decryption
92
+ * key (see `@aptos-labs/confidential-asset`'s `TwistedEd25519PrivateKey.fromPepperBase`). Deriving secrets
93
+ * from `pepper_base` rather than the final pepper also ensures a leaked pepper does not compromise them.
94
+ *
95
+ * @param args - The arguments required to fetch the pepper base.
96
+ * @param args.aptosConfig - The configuration object for Aptos.
97
+ * @param args.jwt - The JSON Web Token used for authentication.
98
+ * @param args.ephemeralKeyPair - The ephemeral key pair used for the operation.
99
+ * @param args.uidKey - An optional unique identifier key (defaults to "sub").
100
+ * @param args.derivationPath - An optional derivation path for the key.
101
+ * @returns A Uint8Array containing the 48-byte `pepper_base`.
102
+ * @group Implementation
103
+ */
104
+ export async function getPepperBase(args: {
105
+ aptosConfig: AptosConfig;
106
+ jwt: string;
107
+ ephemeralKeyPair: EphemeralKeyPair;
108
+ uidKey?: string;
109
+ derivationPath?: string;
110
+ }): Promise<Uint8Array> {
111
+ const { aptosConfig, jwt, ephemeralKeyPair, uidKey = "sub", derivationPath } = args;
112
+
113
+ const body = {
114
+ jwt_b64: jwt,
115
+ epk: ephemeralKeyPair.getPublicKey().bcsToHex().toStringWithoutPrefix(),
116
+ exp_date_secs: ephemeralKeyPair.expiryDateSecs,
117
+ epk_blinder: Hex.fromHexInput(ephemeralKeyPair.blinder).toStringWithoutPrefix(),
118
+ uid_key: uidKey,
119
+ derivation_path: derivationPath,
120
+ };
121
+ const { data } = await postAptosPepperService<PepperFetchRequest, SignatureFetchResponse>({
122
+ aptosConfig,
123
+ path: "signature",
124
+ body,
125
+ originMethod: "getPepperBase",
126
+ overrides: { WITH_CREDENTIALS: false },
127
+ });
128
+ return Hex.fromHexInput(data.signature).toUint8Array();
129
+ }
130
+
79
131
  /**
80
132
  * Generates a zero-knowledge proof based on the provided parameters.
81
133
  * This function is essential for creating a signed proof that can be used in various cryptographic operations.
@@ -45,6 +45,14 @@ export type PepperFetchRequest = {
45
45
  */
46
46
  export type PepperFetchResponse = { pepper: string; address: string };
47
47
 
48
+ /**
49
+ * The response from the pepper service `signature` endpoint, containing the VUF signature — i.e. the
50
+ * 48-byte `pepper_base` (compressed BLS12-381 G1 point) from which the final pepper is derived.
51
+ * @group Implementation
52
+ * @category Types
53
+ */
54
+ export type SignatureFetchResponse = { signature: string };
55
+
48
56
  /**
49
57
  * The response for keyless configuration containing the maximum committed EPK bytes.
50
58
  * @group Implementation
package/src/version.ts CHANGED
@@ -6,4 +6,4 @@
6
6
  *
7
7
  * hardcoded for now, we would want to have it injected dynamically
8
8
  */
9
- export const VERSION = "7.1.2";
9
+ export const VERSION = "7.2.0-beta.0";