Setup Ephemeral Keys

Setup an Ephemeral Key Pair

  1. Create a new useEphemeralKeyPair() hook to hold all of the logic for creating and storing ephemeral key pairs.
    • Save the EphemeralKeyPair in local storage, keyed by its nonce
    hooks/useEphemeralKeyPair.ts

    import { EphemeralKeyPair } from '@aptos-labs/ts-sdk';
    export default function useEphemeralKeyPair() {
    const ephemeralKeyPair = EphemeralKeyPair.generate();
    storeEphemeralKeyPair(ephemeralKeyPair);
    return ephemeralKeyPair;
    }

  2. Example implementation for storeEphemeralKeyPair():

    This implementation is an example of how to store the EphemeralKeyPair in local storage using the nonce as the key. Different implementations may be used according to your application's needs.

    hooks/useEphemeralKeyPair.ts

    /**
    * Stored ephemeral key pairs in localStorage (nonce -> ephemeralKeyPair)
    */
    export type StoredEphemeralKeyPairs = { [nonce: string]: EphemeralKeyPair };
    /**
    * Retrieve all ephemeral key pairs from localStorage and decode them. The new ephemeral key pair
    * is then stored in localStorage with the nonce as the key.
    */
    export const storeEphemeralKeyPair = (
    ephemeralKeyPair: EphemeralKeyPair,
    ): void => {
    // Retrieve the current ephemeral key pairs from localStorage
    const accounts = getLocalEphemeralKeyPairs();
    // Store the new ephemeral key pair in localStorage
    accounts[ephemeralKeyPair.nonce] = ephemeralKeyPair;
    localStorage.setItem(
    "ephemeral-key-pairs",
    encodeEphemeralKeyPairs(accounts),
    );
    };
    /**
    * Retrieve all ephemeral key pairs from localStorage and decode them.
    */
    export const getLocalEphemeralKeyPairs = (): StoredEphemeralKeyPairs => {
    const rawEphemeralKeyPairs = localStorage.getItem("ephemeral-key-pairs");
    try {
    return rawEphemeralKeyPairs
    ? decodeEphemeralKeyPairs(rawEphemeralKeyPairs)
    : {};
    } catch (error) {
    // eslint-disable-next-line no-console
    console.warn(
    "Failed to decode ephemeral key pairs from localStorage",
    error,
    );
    return {};
    }
    };
    /**
    * Encoding for the EphemeralKeyPair class to be stored in localStorage
    */
    const EphemeralKeyPairEncoding = {
    decode: (e: any) => EphemeralKeyPair.fromBytes(e.data),
    encode: (e: EphemeralKeyPair) => ({ __type: 'EphemeralKeyPair', data: e.bcsToBytes() }),
    };
    /**
    * Stringify the ephemeral key pairs to be stored in localStorage
    */
    export const encodeEphemeralKeyPairs = (
    keyPairs: StoredEphemeralKeyPairs,
    ): string =>
    JSON.stringify(keyPairs, (_, e) => {
    if (typeof e === "bigint") return { __type: "bigint", value: e.toString() };
    if (e instanceof Uint8Array)
    return { __type: "Uint8Array", value: Array.from(e) };
    if (e instanceof EphemeralKeyPair)
    return EphemeralKeyPairEncoding.encode(e);
    return e;
    });
    /**
    * Parse the ephemeral key pairs from a string
    */
    export const decodeEphemeralKeyPairs = (
    encodedEphemeralKeyPairs: string,
    ): StoredEphemeralKeyPairs =>
    JSON.parse(encodedEphemeralKeyPairs, (_, e) => {
    if (e && e.__type === "bigint") return BigInt(e.value);
    if (e && e.__type === "Uint8Array") return new Uint8Array(e.value);
    if (e && e.__type === "EphemeralKeyPair")
    return EphemeralKeyPairEncoding.decode(e);
    return e;
    });
    export default function useEphemeralKeyPair() {
    const ephemeralKeyPair = EphemeralKeyPair.generate();
    storeEphemeralKeyPair(ephemeralKeyPair);
    return ephemeralKeyPair;
    }

  3. Within the old WalletButtons component, we create an ephemeral key pair in the background.
    WalletButtons/index.tsx

    import { useKeylessAccount } from "@/context/KeylessAccountContext";
    const ephemeralKeyPair = useEphemeralKeyPair();