UNPKG

@axiom-crypto/keystore-sdk

Version:

Keystore Rollup SDK

131 lines 5.41 kB
import { AuthenticationStatusEnum, } from "../types"; import { DEFAULTS } from "../config"; import { Client, HTTPTransport, RequestManager } from "@open-rpc/client-js"; import { keccak256 } from "viem"; export function createSignatureProverClient(signatureProver) { const { url, pollingIntervalMs = DEFAULTS.POLLING_INTERVAL_MS, pollingRetries = DEFAULTS.POLLING_RETRIES, } = signatureProver; const transport = new HTTPTransport(url, { fetcher: globalThis.fetch, }); const client = new Client(new RequestManager([transport])); const dataHash = (fields) => { return keccak256(signatureProver.keyDataEncoder(fields)); }; const waitForAuthentication = async ({ hash }) => { return await waitForAuthenticationGeneric({ hash, pollingRetries, pollingIntervalMs, authStatusFn: getAuthenticationStatus, }, false); }; const waitForSponsoredAuthentication = async ({ hash }) => { return await waitForAuthenticationGeneric({ hash, pollingRetries, pollingIntervalMs, authStatusFn: getSponsoredAuthenticationStatus, }, true); }; const authenticateTransaction = async ({ transaction, authInputs, }) => { return await client.request({ method: "keystore_authenticateTransaction", params: [transaction, authInputs], }); }; const getAuthenticationStatus = async ({ requestHash, }) => { return await client.request({ method: "keystore_getAuthenticationStatus", params: [requestHash], }); }; const authenticateSponsoredTransaction = async ({ transaction, sponsoredAuthInputs, }) => { const { userAuthInputs, sponsorAuthInputs, userProof } = sponsoredAuthInputs; let finalSponsoredAuthInputs; // Case 1: proveSponsored - both user and sponsor auth inputs if (userAuthInputs && sponsorAuthInputs && !userProof) { finalSponsoredAuthInputs = { proveSponsored: { userAuthInputs, sponsorAuthInputs, }, }; } // Case 2: proveOnlySponsored - user proof and sponsor auth inputs else if (userProof && sponsorAuthInputs && !userAuthInputs) { finalSponsoredAuthInputs = { proveOnlySponsored: { userProof, sponsorAuthInputs, }, }; } // Case 3: sponsorAndProve - only user auth inputs else if (userAuthInputs && !sponsorAuthInputs && !userProof) { finalSponsoredAuthInputs = { sponsorAndProve: { userAuthInputs, }, }; } // Invalid combination else { throw new Error("Invalid combination of inputs. Must provide either: " + "[1: proveSponsored] userAuthInputs and sponsorAuthInputs, or " + "[2: proveOnlySponsored] userProof and sponsorAuthInputs, or " + "[3: sponsorAndProve] only userAuthInputs"); } return await client.request({ method: "keystore_authenticateSponsoredTransaction", params: [transaction, finalSponsoredAuthInputs], }); }; const getSponsoredAuthenticationStatus = async ({ requestHash, }) => { return await client.request({ method: "keystore_getSponsoredAuthenticationStatus", params: [requestHash], }); }; return { ...signatureProver, dataHash, waitForAuthentication, waitForSponsoredAuthentication, authenticateTransaction, getAuthenticationStatus, authenticateSponsoredTransaction, getSponsoredAuthenticationStatus, }; } async function waitForAuthenticationGeneric({ hash, pollingRetries, pollingIntervalMs, authStatusFn, }, isSponsored) { console.log("Waiting for authentication, this may take serveral minutes..."); let attempts = 0; while (attempts < pollingRetries) { try { const status = await authStatusFn({ requestHash: hash, }); switch (status.status) { case AuthenticationStatusEnum.Completed: if (!status.authenticatedTransaction) { throw new Error("No authenticated transaction found"); } console.log(`${isSponsored ? "Sponsored authentication" : "Authentication"} completed`); return status.authenticatedTransaction; case AuthenticationStatusEnum.Failed: throw new Error("Transaction authentication failed"); case AuthenticationStatusEnum.Pending: attempts++; await new Promise((resolve) => setTimeout(resolve, pollingIntervalMs)); continue; default: throw new Error("Invalid authentication status"); } } catch (error) { throw new Error(`Error waiting for authentication: ${error}`); } } throw new Error(`Timed out after ${(pollingRetries * pollingIntervalMs) / 1000} seconds`); } //# sourceMappingURL=signatureProverClient.js.map