@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.
- package/dist/api/keyless.d.ts +25 -0
- package/dist/api/keyless.d.ts.map +1 -1
- package/dist/api/keyless.js +23 -1
- package/dist/api/keyless.js.map +1 -1
- package/dist/cli/localNode.d.ts.map +1 -1
- package/dist/cli/localNode.js +8 -8
- package/dist/cli/localNode.js.map +1 -1
- package/dist/cli/move.js +9 -9
- package/dist/cli/move.js.map +1 -1
- package/dist/cli/spawnArgs.d.ts +27 -0
- package/dist/cli/spawnArgs.d.ts.map +1 -1
- package/dist/cli/spawnArgs.js +55 -2
- package/dist/cli/spawnArgs.js.map +1 -1
- package/dist/core/crypto/federatedKeyless.d.ts +1 -0
- package/dist/core/crypto/federatedKeyless.d.ts.map +1 -1
- package/dist/core/crypto/federatedKeyless.js +4 -0
- package/dist/core/crypto/federatedKeyless.js.map +1 -1
- package/dist/core/crypto/keyless.d.ts +1 -0
- package/dist/core/crypto/keyless.d.ts.map +1 -1
- package/dist/core/crypto/keyless.js +7 -0
- package/dist/core/crypto/keyless.js.map +1 -1
- package/dist/internal/keyless.d.ts +26 -0
- package/dist/internal/keyless.d.ts.map +1 -1
- package/dist/internal/keyless.js +38 -0
- package/dist/internal/keyless.js.map +1 -1
- package/dist/types/keyless.d.ts +9 -0
- package/dist/types/keyless.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +37 -25
- package/src/api/keyless.ts +29 -0
- package/src/cli/localNode.ts +8 -9
- package/src/cli/move.ts +9 -9
- package/src/cli/spawnArgs.ts +57 -2
- package/src/core/crypto/federatedKeyless.ts +4 -0
- package/src/core/crypto/keyless.ts +7 -0
- package/src/internal/keyless.ts +53 -1
- package/src/types/keyless.ts +8 -0
- package/src/version.ts +1 -1
package/src/cli/spawnArgs.ts
CHANGED
|
@@ -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
|
package/src/internal/keyless.ts
CHANGED
|
@@ -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 {
|
|
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.
|
package/src/types/keyless.ts
CHANGED
|
@@ -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