From 10d9c3fda1a047fcd07620d69ffd33be0e4e4b09 Mon Sep 17 00:00:00 2001 From: Jackson <163934542+jmintuitive@users.noreply.github.com> Date: Fri, 1 Nov 2024 11:46:32 -0400 Subject: [PATCH] Update the keyless docs (#545) * Update Keyless docs * Add docs for abstractkeylessaccount * Update KeylessAccount * Add docs to generateDocs * Run pnpm fmt --------- Co-authored-by: Greg Nazario --- examples/typescript/federated_keyless.ts | 2 +- examples/typescript/jwk_update.ts | 2 +- scripts/generateDocs.sh | 13 +++++- src/account/AbstractKeylessAccount.ts | 35 ++++++++++++++-- src/account/FederatedKeylessAccount.ts | 52 ++++++++++++++++++++++-- src/account/KeylessAccount.ts | 24 +++++++++-- src/api/keyless.ts | 4 +- src/internal/keyless.ts | 8 ++++ 8 files changed, 125 insertions(+), 15 deletions(-) diff --git a/examples/typescript/federated_keyless.ts b/examples/typescript/federated_keyless.ts index ce58582d9..445e183db 100644 --- a/examples/typescript/federated_keyless.ts +++ b/examples/typescript/federated_keyless.ts @@ -90,7 +90,7 @@ const example = async () => { const iss = "https://dev-qtdgjv22jh0v1k7g.us.auth0.com/"; - console.log("\n=== Installing JWKs ===\n"); + console.log("\n=== Installing JSON Web Key Set (JWKS) ===\n"); const jwkTxn = await aptos.updateFederatedKeylessJwkSetTransaction({ sender: bob, iss }); const committedJwkTxn = await aptos.signAndSubmitTransaction({ signer: bob, transaction: jwkTxn }); await aptos.waitForTransaction({ transactionHash: committedJwkTxn.hash }); diff --git a/examples/typescript/jwk_update.ts b/examples/typescript/jwk_update.ts index 23de60381..7da6e88db 100644 --- a/examples/typescript/jwk_update.ts +++ b/examples/typescript/jwk_update.ts @@ -2,7 +2,7 @@ /* eslint-disable no-console */ /** - * This example shows how to use install JWKs on an account to support Federated Keyless Accounts + * This example shows how to use install JSON Web Key Set (JWKS) on an account to support Federated Keyless Accounts */ import { Aptos, AptosConfig, EphemeralKeyPair, Network } from "@aptos-labs/ts-sdk"; diff --git a/scripts/generateDocs.sh b/scripts/generateDocs.sh index 08c9caf39..845ac60dc 100755 --- a/scripts/generateDocs.sh +++ b/scripts/generateDocs.sh @@ -15,8 +15,17 @@ if [ -d "docs/@aptos-labs/ts-sdk-$npm_package_version" ]; then echo "WARNING! Docs folder already exists, overwriting docs for version $npm_package_version"; fi -# TODO: This uses the --skipErrorChecking flag as otherwise it incorrectly tries to compile the tests folder. -# Remove this once test compiler errors are not intefering with docs generation. +# `npx typedoc src/index.ts` generates the typedoc docs for this SDK using the proper formatting. +# +# Explanation of each flag: +# --options typedoc.json - Loads options from the typedoc.json configuration file +# --out "docs/@aptos-labs/ts-sdk-$npm_package_version" - Specifies the output directory for the generated documentation, +# dynamically including the current npm package version in the path using the $npm_package_version variable +# --plugin typedoc-plugin-missing-exports - Includes the plugin to include private code in the generated docs (needed to show the reference docs for the Aptos mixin implementation details) +# --cleanOutputDir - Clears the output directory before generating new documentation +# --excludeInternal - Excludes internal symbols from the generated documentation (symbols marked with @internal in comments) +# --includeVersion - Includes the version of the package in the generated documentation +# --skipErrorChecking - TODO: Remove this flag when no longer needed. This avoids the docs build failing due to compiler errors in the tests folder. npx typedoc src/index.ts --options typedoc.json --out "docs/@aptos-labs/ts-sdk-$npm_package_version" --plugin typedoc-plugin-missing-exports --cleanOutputDir --excludeInternal --includeVersion --skipErrorChecking # Update the main page diff --git a/src/account/AbstractKeylessAccount.ts b/src/account/AbstractKeylessAccount.ts index e1162ddf8..583e620e7 100644 --- a/src/account/AbstractKeylessAccount.ts +++ b/src/account/AbstractKeylessAccount.ts @@ -93,7 +93,24 @@ export abstract class AbstractKeylessAccount extends Serializable implements Acc */ private readonly emitter: EventEmitter; - // Use the static constructor 'create' instead. + /** + * Use the static generator `create(...)` instead. + * Creates an instance of the KeylessAccount with an optional proof. + * + * @param args - The parameters for creating a KeylessAccount. + * @param args.address - Optional account address associated with the KeylessAccount. + * @param args.publicKey - A KeylessPublicKey or FederatedKeylessPublicKey. + * @param args.ephemeralKeyPair - The ephemeral key pair used in the account creation. + * @param args.iss - A JWT issuer. + * @param args.uidKey - The claim on the JWT to identify a user. This is typically 'sub' or 'email'. + * @param args.uidVal - The unique id for this user, intended to be a stable user identifier. + * @param args.aud - The value of the 'aud' claim on the JWT, also known as client ID. This is the identifier for the dApp's + * OIDC registration with the identity provider. + * @param args.pepper - A hexadecimal input used for additional security. + * @param args.proof - A Zero Knowledge Signature or a promise that resolves to one. + * @param args.proofFetchCallback - Optional callback function for fetching proof. + * @param args.jwt - A JSON Web Token used for authentication. + */ protected constructor(args: { address?: AccountAddress; publicKey: KeylessPublicKey | FederatedKeylessPublicKey; @@ -140,8 +157,8 @@ export abstract class AbstractKeylessAccount extends Serializable implements Acc } /** - * This initializes the asynchronous proof fetch - * @return + * This initializes the asynchronous proof fetch. + * @return Emits whether the proof succeeds or fails, but has no return. */ async init(promise: Promise) { try { @@ -156,6 +173,12 @@ export abstract class AbstractKeylessAccount extends Serializable implements Acc } } + /** + * Serializes the jwt data into a format suitable for transmission or storage. + * This function ensures that both the jwt data and the proof are properly serialized. + * + * @param serializer - The serializer instance used to convert the jwt data into bytes. + */ serialize(serializer: Serializer): void { serializer.serializeStr(this.jwt); serializer.serializeStr(this.uidKey); @@ -298,6 +321,12 @@ export class TransactionAndProof extends Serializable { this.proof = proof; } + /** + * Serializes the transaction data into a format suitable for transmission or storage. + * This function ensures that both the transaction bytes and the proof are properly serialized. + * + * @param serializer - The serializer instance used to convert the transaction data into bytes. + */ serialize(serializer: Serializer): void { serializer.serializeFixedBytes(this.transaction.bcsToBytes()); serializer.serializeOption(this.proof); diff --git a/src/account/FederatedKeylessAccount.ts b/src/account/FederatedKeylessAccount.ts index ac9a91428..6f46a06a5 100644 --- a/src/account/FederatedKeylessAccount.ts +++ b/src/account/FederatedKeylessAccount.ts @@ -16,8 +16,8 @@ import { AbstractKeylessAccount, ProofFetchCallback } from "./AbstractKeylessAcc * * Used to represent a FederatedKeyless based account and sign transactions with it. * - * Use `FederatedKeylessAccount.create()` to instantiate a KeylessAccount with a JWT, proof, EphemeralKeyPair and the - * address the JWKs are installed that will be used to verify the JWT. + * Use `FederatedKeylessAccount.create()` to instantiate a KeylessAccount with a JSON Web Token (JWT), proof, EphemeralKeyPair and the + * address the JSON Web Key Set (JWKS) are installed that will be used to verify the JWT. * * When the proof expires or the JWT becomes invalid, the KeylessAccount must be instantiated again with a new JWT, * EphemeralKeyPair, and corresponding proof. @@ -28,7 +28,20 @@ export class FederatedKeylessAccount extends AbstractKeylessAccount { */ readonly publicKey: FederatedKeylessPublicKey; - // Use the static constructor 'create' instead. + /** + * Use the static generator `FederatedKeylessAccount.create(...)` instead. + * Creates a KeylessAccount instance using the provided parameters. + * This function allows you to set up a KeylessAccount with specific attributes such as address, proof, and JWT. + * + * @param args - The parameters for creating a KeylessAccount. + * @param args.address - Optional account address associated with the KeylessAccount. + * @param args.proof - A Zero Knowledge Signature or a promise that resolves to one. + * @param args.jwt - A JSON Web Token used for authentication. + * @param args.ephemeralKeyPair - The ephemeral key pair used in the account creation. + * @param args.jwkAddress - The address which stores the JSON Web Key Set (JWKS) used to verify the JWT. + * @param args.uidKey - Optional key for user identification, defaults to "sub". + * @param args.proofFetchCallback - Optional callback function for fetching proof. + */ private constructor(args: { address?: AccountAddress; ephemeralKeyPair: EphemeralKeyPair; @@ -47,6 +60,12 @@ export class FederatedKeylessAccount extends AbstractKeylessAccount { this.publicKey = publicKey; } + /** + * Serializes the transaction data into a format suitable for transmission or storage. + * This function ensures that both the transaction bytes and the proof are properly serialized. + * + * @param serializer - The serializer instance used to convert the transaction data into bytes. + */ serialize(serializer: Serializer): void { if (this.proof === undefined) { throw new Error("Cannot serialize - proof undefined"); @@ -59,6 +78,13 @@ export class FederatedKeylessAccount extends AbstractKeylessAccount { this.proof.serialize(serializer); } + /** + * Deserializes the provided deserializer to create a KeylessAccount instance. + * This function extracts necessary components such as the JWT, UID key, pepper, ephemeral key pair, and proof from the deserializer. + * + * @param deserializer - The deserializer instance used to retrieve the serialized data. + * @returns A KeylessAccount instance created from the deserialized data. + */ static deserialize(deserializer: Deserializer): FederatedKeylessAccount { const jwt = deserializer.deserializeStr(); const uidKey = deserializer.deserializeStr(); @@ -76,10 +102,30 @@ export class FederatedKeylessAccount extends AbstractKeylessAccount { }); } + /** + * Deserialize bytes using this account's information. + * + * @param bytes The bytes being interpreted. + * @returns + */ static fromBytes(bytes: Uint8Array): FederatedKeylessAccount { return FederatedKeylessAccount.deserialize(new Deserializer(bytes)); } + /** + * Creates a KeylessAccount instance using the provided parameters. + * This function allows you to set up a KeylessAccount with specific attributes such as address, proof, and JWT. + * This is used instead of the KeylessAccount constructor. + * + * @param args - The parameters for creating a KeylessAccount. + * @param args.address - Optional account address associated with the KeylessAccount. + * @param args.proof - A Zero Knowledge Signature or a promise that resolves to one. + * @param args.jwt - A JSON Web Token used for authentication. + * @param args.ephemeralKeyPair - The ephemeral key pair used in the account creation. + * @param args.jwkAddress - The address which stores the JSON Web Key Set (JWKS) used to verify the JWT. + * @param args.uidKey - Optional key for user identification, defaults to "sub". + * @param args.proofFetchCallback - Optional callback function for fetching proof. + */ static create(args: { address?: AccountAddress; proof: ZeroKnowledgeSig | Promise; diff --git a/src/account/KeylessAccount.ts b/src/account/KeylessAccount.ts index 0d4603bf4..42226ad3a 100644 --- a/src/account/KeylessAccount.ts +++ b/src/account/KeylessAccount.ts @@ -29,11 +29,22 @@ export class KeylessAccount extends AbstractKeylessAccount { // Use the static constructor 'create' instead. /** - * Creates an instance of the transaction with an optional proof. + * Use the static generator `create(...)` instead. + * Creates an instance of the KeylessAccount with an optional proof. * - * @param args.proof - An optional ZkProof associated with the transaction. + * @param args - The parameters for creating a KeylessAccount. + * @param args.address - Optional account address associated with the KeylessAccount. + * @param args.ephemeralKeyPair - The ephemeral key pair used in the account creation. + * @param args.iss - A JWT issuer. + * @param args.uidKey - The claim on the JWT to identify a user. This is typically 'sub' or 'email'. + * @param args.uidVal - The unique id for this user, intended to be a stable user identifier. + * @param args.aud - The value of the 'aud' claim on the JWT, also known as client ID. This is the identifier for the dApp's + * OIDC registration with the identity provider. + * @param args.pepper - A hexadecimal input used for additional security. + * @param args.proof - A Zero Knowledge Signature or a promise that resolves to one. + * @param args.proofFetchCallback - Optional callback function for fetching proof. + * @param args.jwt - A JSON Web Token used for authentication. */ - // TODO: Document rest of parameters private constructor(args: { address?: AccountAddress; ephemeralKeyPair: EphemeralKeyPair; @@ -90,6 +101,12 @@ export class KeylessAccount extends AbstractKeylessAccount { }); } + /** + * Deserialize bytes using this account's information. + * + * @param bytes The bytes being interpreted. + * @returns + */ static fromBytes(bytes: Uint8Array): KeylessAccount { return KeylessAccount.deserialize(new Deserializer(bytes)); } @@ -97,6 +114,7 @@ export class KeylessAccount extends AbstractKeylessAccount { /** * Creates a KeylessAccount instance using the provided parameters. * This function allows you to set up a KeylessAccount with specific attributes such as address, proof, and JWT. + * This is used instead of the KeylessAccount constructor. * * @param args - The parameters for creating a KeylessAccount. * @param args.address - Optional account address associated with the KeylessAccount. diff --git a/src/api/keyless.ts b/src/api/keyless.ts index e1327d1b7..85d5a1dfb 100644 --- a/src/api/keyless.ts +++ b/src/api/keyless.ts @@ -155,7 +155,7 @@ export class Keyless { * @param args.jwt - The JWT token used for deriving the account. * @param args.ephemeralKeyPair - The EphemeralKeyPair used to generate the nonce in the JWT token. * @param args.jwkAddress - The address the where the JWKs used to verify signatures are found. Setting the value derives a - * FederatedKeylessAccount + * FederatedKeylessAccount. * @param args.uidKey - An optional key in the JWT token to set the uidVal in the IdCommitment. * @param args.pepper - An optional pepper value. * @param args.proofFetchCallback - An optional callback function for fetching the proof in the background, allowing for a more @@ -201,7 +201,7 @@ export class Keyless { /** * This installs a set of FederatedJWKs at an address for a given iss. * - * It will fetch the JWK set from the well-known endpoint and update the FederatedJWKs at the sender's address + * It will fetch the JSON Web Keyset (JWK) set from the well-known endpoint and update the FederatedJWKs at the sender's address * to reflect it. * * @param args.sender The account that will install the JWKs diff --git a/src/internal/keyless.ts b/src/internal/keyless.ts index a96cce7a2..c4e16f664 100644 --- a/src/internal/keyless.ts +++ b/src/internal/keyless.ts @@ -201,6 +201,11 @@ export async function deriveKeylessAccount(args: { return KeylessAccount.create({ ...args, address, proof, pepper, proofFetchCallback }); } +/** + * A JSON Web Keyset (JWK) + * + * Used to verify JSON Web Tokens (JWTs). + */ interface JWK { kty: string; // Key type kid: string; // Key ID @@ -209,6 +214,9 @@ interface JWK { e: string; // Exponent (for RSA keys) } +/** + * A collection of JSON Web Key Set (JWKS). + */ interface JWKS { keys: JWK[]; }