UNPKG

zkfold-smart-wallet-api

Version:

Smart Wallet API - Browser and extension compatible

686 lines (645 loc) 22.6 kB
import * as CSL from '@emurgo/cardano-serialization-lib-browser'; /** * The recipient address types we support. */ export declare enum AddressType { Bech32 = 0, Email = 1 } export declare function b64ToBn(b64: string): BigIntWrap; /** * A wrapper for interaction with the backend. * @class */ export declare class Backend { private url; private secret; /** * Creates a new Backend object. * @param {string} url - Backend's URL * @param {string} secret - optional Backend's secret (API key) */ constructor(url: string, secret?: string | null); private headers; /** * Get server settings including network and version information. * @async * @returns {Settings} */ settings(): Promise<Settings>; /** * Get Google OAuth credentials * @async * @returns {ClientCredentials} */ credentials(): Promise<ClientCredentials>; /** * Return wallet's address by email. The wallet can be not initialised, i.e. this function will return the address for any email. * @async * @param {string} email * @returns {CSL.Address} */ walletAddress(email: string): Promise<CSL.Address>; /** * Activate a Smart Wallet. * This will create a minting transaction which should be signed and submitted. * @async * @param {string} jwt - Base64url-decoded Google JSON web token without signature * @param {string} payment_key_hash - Token name (the hash of a public key used to initialise the wallet) * @param {ProofBytes} proof_bytes - Zero-knowledge proof that the user possesses a valid JWT * @returns {CreateWalletResponse} */ activateWallet(jwt: string, payment_key_hash: string, proof_bytes: ProofBytes): Promise<CreateWalletResponse>; /** * Activate a Smart Wallet and send funds from it. * This will create transaction which should be signed and submitted. * @async * @param {string} jwt - Base64url-decoded Google JSON web token without signature * @param {string} payment_key_hash - Token name (the hash of a public key used to initialise the wallet) * @param {ProofBytes} proof_bytes - Zero-knowledge proof that the user possesses a valid JWT * @param {Output[]} outs - Transaction outputs (where to send funds) * @returns {CreateWalletResponse} */ activateAndSendFunds(jwt: string, payment_key_hash: string, proof_bytes: ProofBytes, outs: Output[]): Promise<CreateWalletResponse>; /** * Send funds from an activated Smart Wallet. * This will create transaction which should be signed and submitted. * @async * @param {string} email * @param {Output[]} outs - Transaction outputs (where to send funds) * @param {string} payment_key_hash - Token name (the hash of a public key used to initialise the wallet) * @returns {SendFundsResponse} */ sendFunds(email: string, outs: Output[], payment_key_hash: string): Promise<SendFundsResponse>; /** * Submit a CBOR-encoded transaction. * @async * @param {string} transaction * @param {string[]} email_recipients * @returns {SubmitTxResult} - Transaction ID and email delivery errors, if any */ submitTx(transaction: string, email_recipients?: string[], sender?: string): Promise<SubmitTxResult>; /** * Add a witness to the transaction, submit it and notify recipients by email. * @async * @param {string} unsigned_transaction * @param {string} vkey_witness * @param {string[]} email_recipients * @returns {SubmitTxResult} - Transaction ID and email delivery errors, if any */ addVkeyAndSubmitTx(unsigned_transaction: string, vkey_witness: string, email_recipients?: string[], sender?: string): Promise<SubmitTxResult>; /** * Get all UTxOs held by an address * @async * @param {CSL.Address} address * @returns {UTxO[]} */ addressUtxo(address: CSL.Address): Promise<UTxO[]>; /** * Get assets held by an address and their approximate value in USD * @async * @param {CSL.Address} address * @returns {BalanceResponse} */ balance(address: CSL.Address): Promise<BalanceResponse>; /** * Get transaction history of a email address * @async * @param {string} address * @returns {Transaction[]} */ txHistory(email: string): Promise<Transaction[]>; } /** * Balance of a wallet * * @property {number} lovelace - The number of lovelace held * @property {Array} tokens - The array of tokens held * @property {number} usd - the approximate value of the assets in USD */ export declare interface BalanceResponse { lovelace: number; tokens: PrettyToken[]; usd: number; } /** * Convert BigInt to byte array */ export declare function bigIntToBytes(bigInt: bigint): Uint8Array; /** * Wrapper for various integer types used in communication with the Backend, Prover, and CSL. * Provides a JSON representation unavailable for bignum. */ export declare class BigIntWrap { private int; constructor(num: string | number | bigint | CSL.BigNum); add(other: BigIntWrap): BigIntWrap; increase(other: BigIntWrap): void; toString(): string; toNumber(): number; toBigInt(): bigint; toBigNum(): CSL.BigNum; toJSON(): bigint; } /** * Convert bytes to base64url string */ export declare function bytesToBase64Url(bytes: Uint8Array): string; /** * Convert bytes to hex string */ export declare function bytesToHex(bytes: Uint8Array): string; /** * OAuth client credentials * * @property {string} client_id - OAuth client id * @property {string} client_secret - OAuth client secret */ export declare interface ClientCredentials { client_id: string; client_secret: string; } /** * This object is sent by the backend upon successful initialisation of a Gmail-based wallet. * * @property {CSL.Address} address - The new wallet's address * @property {string} transaction - Transaction to be signed and submitted to initialise the wallet * @property {number} transaction_fee - The expected fee of the wallet initialisation transaction * @property {string} transaction_id - The ID of the wallet initialisation transaction */ export declare interface CreateWalletResponse { address: CSL.Address; transaction: string; transaction_fee: number; transaction_id: string; } export declare function deserialize(jsonString: string): any; /** * Email address to which notification couldn't be delivered and the reason. * * @property {string} email - Email address * @property {string} error - The reason why notification failed */ export declare interface FailedNotification { email: string; error: string; } export declare class GoogleApi { private clientId; private clientSecret; private redirectURL; constructor(clientId: string, clientSecret: string, redirectURL: string); /** * Generates the Google OAuth2 authorization URL. * @param {string} state - A unique state string to prevent CSRF attacks. * @returns {string} The Google OAuth2 authorization URL. */ getAuthUrl(state: string): string; /** * Exchanges an authorization code for a JWT. * @param {string} code - The authorization code received from Google. * @returns {Promise<string | null>} A promise that resolves to the JWT or null if not found. */ getJWTFromCode(code: string): Promise<string | null>; /** * Fetches Google's public keys and returns the one matching the given key ID. * @param {string} keyId - The key ID to match. * @returns {Promise<GoogleCertKey | null>} A promise that resolves to the matching key or null if not found. */ getMatchingKey(keyId: string): Promise<GoogleCertKey | null>; /** * Extracts the key ID from a JWT. * @param {string} jwt - The JWT string. * @returns {string} The key ID. */ getKeyId(jwt: string): string; /** * Extracts the user ID (email) from a JWT. * @param {string} jwt - The JWT string. * @returns {string} The user ID (email). */ getUserId(jwt: string): string; /** * Extracts the signature from a JWT. * @param {string} jwt - The JWT string. * @returns {string} The signature. */ getSignature(jwt: string): string; /** * Strips the signature from a JWT. * @param {string} jwt - The JWT string. * @returns {string} The JWT without the signature. */ stripSignature(jwt: string): string; } export declare type GoogleCertKey = { kid: string; n: string; e: string; [key: string]: unknown; }; export declare type GoogleTokenResponse = { id_token?: string; [key: string]: unknown; }; export declare function harden(num: number): number; /** * Convert a hex string to a byte array * https://stackoverflow.com/questions/14603205/how-to-convert-hex-string-into-a-bytes-array-and-a-bytes-array-in-the-hex-strin */ export declare function hexToBytes(hex: string): Uint8Array; /** * Transaction output as expected by the backend. * * @property {string} address * @property {TxDatum} datum - Optional datum (inline or just hash) to be included * @property {Value} value * * @example * * { "address": "addr_test1qrsuhwqdhz0zjgnf46unas27h93amfghddnff8lpc2n28rgmjv8f77ka0zshfgssqr5cnl64zdnde5f8q2xt923e7ctqu49mg5", * "datum": { * "datum": "some_datum_data", * "is_inline": true * }, * "value": { * "ff80aaaf03a273b8f5c558168dc0e2377eea810badbae6eceefc14ef.474f4c44": 101, * "lovelace": 22 * } * } */ export declare interface Output { address: string; datum?: TxDatum; value: Value; } /** * Details of a token from Cardano Token Registry * * @property {string} asset - The asset name <minting_policy_id>.<asset_name> * @property {string} ticker - The ticker of a token (e.g. SNEK) * @property {string} token_name - The token name (e.g. Snek) * @property {number} decimal_adjustment - The numeric value that specifies the number of decimal places that the token can have * @property {string} logo - The token logo as a base64 string */ export declare interface PrettyToken { asset: string; amount: number; ticker?: string; description: string; token_name: string; decimal_adjustment?: number; logo?: string; } /** * ProofBytes used by Plonkup. * This object will be sent to the backend as a proof that user possesses a valid JSON Web Token * and used in the script redeemer. */ export declare interface ProofBytes { "a_xi_int": BigIntWrap; "b_xi_int": BigIntWrap; "c_xi_int": BigIntWrap; "cmA_bytes": string; "cmB_bytes": string; "cmC_bytes": string; "cmF_bytes": string; "cmH1_bytes": string; "cmH2_bytes": string; "cmQhigh_bytes": string; "cmQlow_bytes": string; "cmQmid_bytes": string; "cmZ1_bytes": string; "cmZ2_bytes": string; "f_xi_int": BigIntWrap; "h1_xi'_int": BigIntWrap; "h2_xi_int": BigIntWrap; "l1_xi": BigIntWrap; "l_xi": BigIntWrap[]; "proof1_bytes": string; "proof2_bytes": string; "s1_xi_int": BigIntWrap; "s2_xi_int": BigIntWrap; "t_xi'_int": BigIntWrap; "t_xi_int": BigIntWrap; "z1_xi'_int": BigIntWrap; "z2_xi'_int": BigIntWrap; } /** * ZK Proof input * * @property {BigIntWrap} piPubE - Google's RSA public exponent * @property {BigIntWrap} piPubN - Google's RSA public modulus * @property {BigIntWrap} piSignature - Signature attached to the Google OAuth JSON Web Token * @property {BigIntWrap} piTokenName - The name of the token minted in the wallet initialisation transaction */ export declare interface ProofInput { piPubE: BigIntWrap; piPubN: BigIntWrap; piSignature: BigIntWrap; piTokenName: BigIntWrap; } /** * A wrapper for interaction with the prover * @class */ export declare class Prover { private url; /** * Creates a new Prover object. * @param {string} url - Prover's URL */ constructor(url: string); private headers; /** * Get all public keys held by the Prover * @async * @returns {ProverPublicKey[]} */ serverKeys(): Promise<ProverPublicKey[]>; /** * Submit a proof request to the Prover. It will return a Request ID which can be used to retrieve proof status * @async * @param {ProofInput} proofInput for the expMod circuit: exponent, modulus, signature and token name * @returns {string} proof request ID */ requestProof(proofInput: ProofInput): Promise<string>; /** * Retrieve the status of a Proof Request * @async * @param {string} proofId request ID * @returns {ProofBytes | string} ProofBytes if the proof has finished or 'Pending' otherwise */ proofStatus(proofId: string): Promise<ProofBytes | null>; /** * Obtain a Proof from the Prover. Unlike requestProof(), this method waits for the proof completion * @async * @param {ProofInput} proofInput for the expMod circuit: exponent, modulus, signature and token name * @returns {ProofBytes} ZK proof bytes for the expMod circuit */ prove(proofInput: ProofInput): Promise<ProofBytes>; private parseProverKeys; private parseProofStatus; private parseProofBytes; } /** * RSA public key provided by the prover with its unique identifier * * @property {string} pkbId - Public key identifier * @property {PublicKey} pkbPublic - Public key itself */ export declare interface ProverPublicKey { pkbId: string; pkbPublic: PublicKey; } /** * RSA public key provided by the prover * * @property {BigIntWrap} public_e - Public exponent * @property {BigIntWrap} public_n - Public modulus * @property {BigIntWrap} public_size - Key size in bits */ export declare interface PublicKey { public_e: BigIntWrap; public_n: BigIntWrap; public_size: BigIntWrap; } /** * Transaction input reference containing transaction id and output index. * * @property {string} transaction_id * @property {number} output_index * * Will be serialised to JSON as `${transaction_id}#${output_index}`. For example, * "4293386fef391299c9886dc0ef3e8676cbdbc2c9f2773507f1f838e00043a189#1" */ export declare interface Reference { transaction_id: string; output_index: number; } /** * This object is sent by the backend upon a successful request to the /send_funds endpoint * * @property {string} transaction - Transaction to be signed and submitted * @property {number} transaction_fee - The expected fee of the transaction * @property {string} transaction_id - The ID of the transaction */ export declare interface SendFundsResponse { transaction: string; transaction_fee: number; transaction_id: string; } /** * JSON serialization utilities to handle big integers */ export declare function serialize(data: any): string; /** * Smart Wallet Backend settings */ export declare interface Settings { network: string; version: string; } /** * Describes the recipient of ADA * @property {AddressType} recipientType - Type of wallet the recipient holds * @property {string} address - Cardano address if recipientType is Bech32, email otherwise * @property {Asset} assets - A dictionary of assets to send. For ADA, use 'lovelace' as the key. For other assets, use the format '<PolicyID>.<AssetName>' */ export declare interface SmartTxRecipient { recipientType: AddressType; address: string; assets: Value; } /** * Transaction ID and email delivery errors, if any * * @property {string} transaction_id - Transaction ID * @property {Array} notifier_errors - Recipients who were not notified */ export declare interface SubmitTxResult { transaction_id: string; notifier_errors: FailedNotification[]; } /** * Transaction from transaction history * * @property {string} transaction_id - Transaction id * @property {{ [asset: string]: number }} value_diff - Dictionary with sent (negative value) and received (positive value) assets * @property {string} timestamp - Transaction date * @property {CSL.Address[]} from_addrs - Addresses in the transaction inputs * @property {CSL.Address[]} to_addrs - Addresses in the transaction outputs */ export declare interface Transaction { transaction_id: string; value_diff: { [asset: string]: number; }; timestamp: string; from_addrs: CSL.Address[]; to_addrs: CSL.Address[]; } export declare interface TransactionRequest { recipient: string; recipientType: AddressType; asset: string; amount: string; } /** * Optional datum (inline or just hash) to be included. * * @property {any} datum - Datum data * @property {boolean} is_inline - true for inline datum, false for just datum hash */ export declare interface TxDatum { datum: any; is_inline: boolean; } /** * UTxO object containing transaction where it was created, address and assets. * * @param {Reference} ref - Transaction output reference * @param {CLS.Address} address - UTxO address * @param {Value} value - UTxO assets * * @example * * { * "address": "addr_test1qrsuhwqdhz0zjgnf46unas27h93amfghddnff8lpc2n28rgmjv8f77ka0zshfgssqr5cnl64zdnde5f8q2xt923e7ctqu49mg5", * "ref": { * "transaction_id": "4293386fef391299c9886dc0ef3e8676cbdbc2c9f2773507f1f838e00043a189", * "output_index": 1 * } * "value": { * "ff80aaaf03a273b8f5c558168dc0e2377eea810badbae6eceefc14ef.474f4c44": 101, * "lovelace": 22 * } * } */ export declare interface UTxO { ref: Reference; address: CSL.Address; value: Value; } /** * Value object representing assets (lovelace and tokens). * The keys are asset identifiers (policy_id + '.' + asset_name in hex) or 'lovelace' for ADA. * The values are BigIntWrap representing the quantity of each asset. */ export declare interface Value { [key: string]: BigIntWrap; } export declare type Version = 'v0'; /** * The Wallet which can be initialised with an email address. */ export declare class Wallet extends EventTarget { private jwt?; private tokenSKey?; private userId?; private activated; private proof; private storage; private session; private googleApi; private backend; private prover; /** * @param {Backend} backend - A Backend object for interaction with the backend * @param {Prover} prover - A Prover object for interaction with the prover * @param {GoogleApi} googleApi - A GoogleApi object for interaction with Google OAuth */ constructor(backend: Backend, prover: Prover, googleApi: GoogleApi); login(): void; isActivated(): boolean; isLoggedIn(): boolean; hasProof(): boolean; logout(): void; oauthCallback(callbackData: string): Promise<void>; private getProof; getUserId(): string; /** * @async * Get the Cardano address for a gmail address */ addressForGmail(gmail: string): Promise<CSL.Address>; /** * @async * Get the Wallet's address */ getAddress(): Promise<CSL.Address>; /** * @async * Get wallet's balance as an object with asset names as property names and amounts as their values. */ getBalance(): Promise<BalanceResponse>; /** * @async * Get the approximate USD value of all wallet's assets */ getUSDValue(): Promise<number>; /** * @async * Get wallet's transaction history */ getTxHistory(): Promise<Transaction[]>; /** * Get extensions turned on in the wallet */ getExtensions(): string[]; /** * @async * Get UTxOs held by the wallet */ getUtxos(): Promise<UTxO[]>; /** * @async * Get wallet's used addresses (currently only wallet's main address) */ getUsedAddresses(): Promise<CSL.Address[]>; /** * @async * Get wallet's unused addresses */ getUnusedAddresses(): Promise<CSL.Address[]>; /** * @async * Get wallet's reward addresses (currently none) */ getRewardAddresses(): Promise<CSL.Address[]>; /** * @async * Get wallet's change address (currently wallet's main address) */ getChangeAddress(): Promise<CSL.Address>; /** * @async * Send a transaction from this wallet. * * @param {TransactionRequest} request - Transaction request object */ sendTransaction(request: TransactionRequest): Promise<void>; private awaitTxConfirmed; private checkTransactionStatus; private sendTo; } /** Events emitted by the Wallet object. * * 'walletInitialized' - emitted when the wallet is successfully initialized * 'proofComputationComplete' - emitted when ZK proof computation is complete * 'transactionComplete' - emitted when a transaction is successfully completed * 'transactionFailed' - emitted when a transaction fails * 'walletLoggedOut' - emitted when the wallet is logged out */ export declare type WalletEvent = 'initialized' | 'proof_computed' | 'transaction_initiated' | 'transaction_pending' | 'transaction_confirmed' | 'transaction_failed' | 'logged_out'; /** * Data required to initialise a wallet. * * data is Google JSON Web Token as a string * rootKey is the private key to sign transactions (can be generated randomly) */ export declare interface WalletInitialiser { jwt: string; tokenSKey?: string; } export { }