UNPKG

@opendatalabs/vana-sdk

Version:

A TypeScript library for interacting with Vana Network smart contracts.

409 lines 14.1 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var browser_exports = {}; __export(browser_exports, { BrowserPlatformAdapter: () => BrowserPlatformAdapter }); module.exports = __toCommonJS(browser_exports); var import_pgp_utils = require("./shared/pgp-utils"); var import_error_utils = require("./shared/error-utils"); var import_lazy_import = require("../utils/lazy-import"); var import_WalletKeyEncryptionService = require("../crypto/services/WalletKeyEncryptionService"); var import_crypto_utils = require("../utils/crypto-utils"); var import_viem = require("viem"); var secp256k1 = __toESM(require("@noble/secp256k1"), 1); var import_browser = require("../crypto/ecies/browser"); const getOpenPGP = (0, import_lazy_import.lazyImport)(() => import("openpgp")); class BrowserCryptoAdapter { eciesProvider = new import_browser.BrowserECIESUint8Provider(); walletService = new import_WalletKeyEncryptionService.WalletKeyEncryptionService({ eciesProvider: this.eciesProvider }); /** * Encrypts data using ECIES with a public key. * * @param data - The plaintext string to encrypt. * Typically user data or sensitive information. * @param publicKeyHex - The recipient's public key in hex format. * Can include or omit the '0x' prefix. * @returns Encrypted data as a hex string without '0x' prefix * * @throws {Error} If encryption fails or public key is invalid */ async encryptWithPublicKey(data, publicKeyHex) { try { const prefixedHex = publicKeyHex.startsWith("0x") ? publicKeyHex : `0x${publicKeyHex}`; const publicKeyBytes = (0, import_viem.fromHex)(prefixedHex, "bytes"); const encrypted = await this.eciesProvider.encrypt( publicKeyBytes, (0, import_viem.stringToBytes)(data) ); const result = (0, import_viem.concat)([ encrypted.iv, encrypted.ephemPublicKey, encrypted.ciphertext, encrypted.mac ]); return (0, import_viem.toHex)(result).slice(2); } catch (error) { throw (0, import_error_utils.wrapCryptoError)("encryptWithPublicKey", error); } } /** * Decrypts ECIES-encrypted data using a private key. * * @param encryptedData - Hex string containing encrypted data. * Can include or omit the '0x' prefix. * @param privateKeyHex - The private key in hex format. * Must correspond to the public key used for encryption. * @returns The decrypted plaintext string * * @throws {Error} If decryption fails or MAC verification fails */ async decryptWithPrivateKey(encryptedData, privateKeyHex) { try { const encryptedHex = encryptedData.startsWith("0x") ? encryptedData : `0x${encryptedData}`; const privateHex = privateKeyHex.startsWith("0x") ? privateKeyHex : `0x${privateKeyHex}`; const encryptedBytes = (0, import_viem.fromHex)(encryptedHex, "bytes"); const privateKeyBytes = (0, import_viem.fromHex)(privateHex, "bytes"); const encrypted = (0, import_crypto_utils.parseEncryptedDataBuffer)(encryptedBytes); const decrypted = await this.eciesProvider.decrypt( privateKeyBytes, encrypted ); return (0, import_viem.bytesToString)(decrypted); } catch (error) { throw (0, import_error_utils.wrapCryptoError)("decryptWithPrivateKey", error); } } /** * Encrypts data using a wallet's public key. * * @param data - The plaintext string to encrypt. * Typically permission data or DLP metadata. * @param publicKey - The wallet's public key. * Automatically handles compressed/uncompressed formats. * @returns Encrypted data as a hex string * * @throws {Error} If encryption fails or key processing fails */ async encryptWithWalletPublicKey(data, publicKey) { try { return await this.walletService.encryptWithWalletPublicKey( data, publicKey ); } catch (error) { throw (0, import_error_utils.wrapCryptoError)("encryptWithWalletPublicKey", error); } } /** * Decrypts data using a wallet's private key. * * @param encryptedData - Hex string containing encrypted data. * Must be encrypted with corresponding wallet public key. * @param privateKey - The wallet's private key. * Obtain from wallet connection (handle with care). * @returns The decrypted plaintext string * * @throws {Error} If decryption fails or key is invalid */ async decryptWithWalletPrivateKey(encryptedData, privateKey) { try { return await this.walletService.decryptWithWalletPrivateKey( encryptedData, privateKey ); } catch (error) { throw (0, import_error_utils.wrapCryptoError)("decryptWithWalletPrivateKey", error); } } /** * Generates a new secp256k1 key pair for ECIES operations. * * @returns Object containing hex-encoded public and private keys * @returns returns.privateKey - Private key in hex format without '0x' * @returns returns.publicKey - Compressed public key in hex format without '0x' * * @throws {Error} If key generation fails */ async generateKeyPair() { try { const privateKeyBytes = secp256k1.utils.randomPrivateKey(); const publicKeyBytes = secp256k1.getPublicKey(privateKeyBytes, true); return { privateKey: (0, import_viem.toHex)(privateKeyBytes).slice(2), publicKey: (0, import_viem.toHex)(publicKeyBytes).slice(2) }; } catch (error) { throw (0, import_error_utils.wrapCryptoError)("generateKeyPair", error); } } /** * Encrypts binary data using password-based encryption. * * @param data - Binary data to encrypt. * Typically file contents or serialized objects. * @param password - Password for encryption. * Often derived from wallet signatures. * @returns Encrypted data as Uint8Array * * @remarks * Uses OpenPGP for password-based encryption with automatic * salt generation for security. * * @throws {Error} If encryption fails */ async encryptWithPassword(data, password) { try { const openpgp = await getOpenPGP(); const message = await openpgp.createMessage({ binary: data }); const encrypted = await openpgp.encrypt({ message, passwords: [password], format: "binary" }); return new Uint8Array(encrypted); } catch (error) { throw (0, import_error_utils.wrapCryptoError)("encryptWithPassword", error); } } /** * Decrypts password-encrypted binary data. * * @param encryptedData - Password-encrypted data as Uint8Array. * Must be encrypted with the same password. * @param password - Password for decryption. * Must match the encryption password. * @returns Decrypted data as Uint8Array * * @throws {Error} If decryption fails or password is incorrect */ async decryptWithPassword(encryptedData, password) { try { const openpgp = await getOpenPGP(); const message = await openpgp.readMessage({ binaryMessage: encryptedData }); const { data } = await openpgp.decrypt({ message, passwords: [password], format: "binary" }); return new Uint8Array(data); } catch (error) { throw (0, import_error_utils.wrapCryptoError)("decryptWithPassword", error); } } } class BrowserPGPAdapter { /** * Encrypts data using PGP public key encryption. * * @param data - The plaintext string to encrypt. * Typically messages or structured data. * @param publicKeyArmored - ASCII-armored PGP public key. * Obtain from PGP key generation or key servers. * @returns ASCII-armored encrypted message * * @throws {Error} If encryption fails or public key is invalid */ async encrypt(data, publicKeyArmored) { try { const openpgp = await getOpenPGP(); const publicKey = await openpgp.readKey({ armoredKey: publicKeyArmored }); const encrypted = await openpgp.encrypt({ message: await openpgp.createMessage({ text: data }), encryptionKeys: publicKey, config: { preferredCompressionAlgorithm: openpgp.enums.compression.zlib } }); return encrypted; } catch (error) { throw new Error(`PGP encryption failed: ${String(error)}`); } } /** * Decrypts PGP-encrypted data using a private key. * * @param encryptedData - ASCII-armored encrypted message. * Must be encrypted with corresponding public key. * @param privateKeyArmored - ASCII-armored PGP private key. * Must correspond to the public key used for encryption. * @returns The decrypted plaintext string * * @throws {Error} If decryption fails or private key is invalid */ async decrypt(encryptedData, privateKeyArmored) { try { const openpgp = await getOpenPGP(); const privateKey = await openpgp.readPrivateKey({ armoredKey: privateKeyArmored }); const message = await openpgp.readMessage({ armoredMessage: encryptedData }); const { data: decrypted } = await openpgp.decrypt({ message, decryptionKeys: privateKey }); return decrypted; } catch (error) { throw new Error(`PGP decryption failed: ${String(error)}`); } } /** * Generates a new PGP key pair. * * @param options - Key generation options * @param options.name - Name for the key identity. * Defaults to 'Vana User'. * @param options.email - Email for the key identity. * Defaults to 'user@vana.com'. * @param options.passphrase - Passphrase to protect the private key. * If not provided, key is unprotected. * @returns ASCII-armored public and private keys * * @throws {Error} If key generation fails */ async generateKeyPair(options) { try { const openpgp = await getOpenPGP(); const keyGenParams = (0, import_pgp_utils.getPGPKeyGenParams)(options); const { privateKey, publicKey } = await openpgp.generateKey(keyGenParams); return { publicKey, privateKey }; } catch (error) { throw (0, import_error_utils.wrapCryptoError)("PGP key generation", error); } } } class BrowserHttpAdapter { /** * Performs an HTTP request using the Fetch API. * * @param url - The URL to fetch. * Must be a valid HTTP/HTTPS URL. * @param options - Standard fetch options. * See MDN fetch documentation for details. * @returns Standard fetch Response object */ async fetch(url, options) { return fetch(url, options); } } class BrowserCacheAdapter { prefix = "vana_cache_"; /** * Retrieves a cached value by key. * * @param key - The cache key to look up. * Automatically prefixed to avoid conflicts. * @returns The cached value or null if not found */ get(key) { try { if (typeof sessionStorage === "undefined") { return null; } return sessionStorage.getItem(this.prefix + key); } catch { return null; } } /** * Stores a value in sessionStorage. * * @param key - The cache key. * Automatically prefixed with 'vana_cache_'. * @param value - The value to cache. * Will be cleared when tab closes. */ set(key, value) { try { if (typeof sessionStorage === "undefined") { return; } sessionStorage.setItem(this.prefix + key, value); } catch { } } /** * Removes a specific key from the cache. * * @param key - The cache key to remove. * Only removes the prefixed key. */ delete(key) { try { if (typeof sessionStorage === "undefined") { return; } sessionStorage.removeItem(this.prefix + key); } catch { } } /** * Clears all Vana-prefixed cache entries. * * @remarks * Only removes entries with the 'vana_cache_' prefix, * preserving other sessionStorage data. */ clear() { try { if (typeof sessionStorage === "undefined") { return; } const keysToRemove = []; for (let i = 0; i < sessionStorage.length; i++) { const key = sessionStorage.key(i); if (key?.startsWith(this.prefix)) { keysToRemove.push(key); } } keysToRemove.forEach((key) => { sessionStorage.removeItem(key); }); } catch { } } } class BrowserPlatformAdapter { crypto = new BrowserCryptoAdapter(); pgp = new BrowserPGPAdapter(); http = new BrowserHttpAdapter(); cache = new BrowserCacheAdapter(); platform = "browser"; } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { BrowserPlatformAdapter }); //# sourceMappingURL=browser.cjs.map