UNPKG

@opendatalabs/vana-sdk

Version:

A TypeScript library for interacting with Vana Network smart contracts.

434 lines 14.9 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 node_exports = {}; __export(node_exports, { NodePlatformAdapter: () => NodePlatformAdapter, nodePlatformAdapter: () => nodePlatformAdapter }); module.exports = __toCommonJS(node_exports); var import_pgp_utils = require("./shared/pgp-utils"); var import_error_utils = require("./shared/error-utils"); var import_stream_utils = require("./shared/stream-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_node = require("../crypto/ecies/node"); var import_interface = require("../crypto/ecies/interface"); var import_crypto = require("crypto"); var import_secp256k1 = __toESM(require("secp256k1"), 1); const getOpenPGP = (0, import_lazy_import.lazyImport)(() => import("openpgp")); class NodeCryptoAdapter { eciesProvider = new import_node.NodeECIESUint8Provider(); 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. * Obtain from key generation or user profile. * @returns Encrypted data as a hex string containing IV, ephemeral key, ciphertext, and MAC * * @throws {Error} If encryption fails or public key is invalid */ async encryptWithPublicKey(data, publicKeyHex) { try { const publicKeyBytes = (0, import_crypto_utils.processWalletPublicKey)(publicKeyHex); const publicKey = Buffer.from(publicKeyBytes); const message = Buffer.from(data, "utf8"); const encrypted = await this.eciesProvider.encrypt(publicKey, message); const result = Buffer.concat([ encrypted.iv, encrypted.ephemPublicKey, encrypted.ciphertext, encrypted.mac ]); return result.toString("hex"); } catch (error) { if (error instanceof import_interface.ECIESError) { throw error; } throw new Error( `Encryption failed: ${error instanceof Error ? error.message : String(error)}` ); } } /** * Decrypts ECIES-encrypted data using a private key. * * @param encryptedData - Hex string containing encrypted data. * Must include IV, ephemeral public key, ciphertext, and MAC. * @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 * @throws {ECIESError} If using custom ECIES and specific error occurs */ async decryptWithPrivateKey(encryptedData, privateKeyHex) { try { const privateKeyBuffer = (0, import_crypto_utils.processWalletPrivateKey)(privateKeyHex); const encryptedHex = encryptedData.startsWith("0x") ? encryptedData.slice(2) : encryptedData; const encryptedBuffer = Buffer.from(encryptedHex, "hex"); const { iv, ephemPublicKey, ciphertext, mac } = (0, import_crypto_utils.parseEncryptedDataBuffer)(encryptedBuffer); const encryptedObj = { iv, ephemPublicKey, ciphertext, mac }; const decrypted = await this.eciesProvider.decrypt( privateKeyBuffer, encryptedObj ); return new TextDecoder().decode(decrypted); } catch (error) { if (error instanceof import_interface.ECIESError) { throw error; } throw new Error( `Decryption failed: ${error instanceof Error ? error.message : String(error)}` ); } } /** * Generates a new secp256k1 key pair for ECIES operations. * * @returns Object containing hex-encoded public and private keys * @returns returns.publicKey - Compressed public key in hex format * @returns returns.privateKey - Private key in hex format * * @throws {Error} If key generation fails */ async generateKeyPair() { try { const secp256k1 = import_secp256k1.default; let privateKey; do { privateKey = (0, import_crypto.randomBytes)(32); } while (!secp256k1.privateKeyVerify(privateKey)); const publicKey = Buffer.from( secp256k1.publicKeyCreate(privateKey, true) ); return { privateKey: privateKey.toString("hex"), publicKey: publicKey.toString("hex") }; } catch (error) { throw (0, import_error_utils.wrapCryptoError)("key generation", 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 (with or without 0x prefix). * Obtain from wallet connection or user profile. * @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)("encrypt with wallet public key", 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)("decrypt with wallet private key", 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. Note that this is not * deterministic due to OpenPGP's random salt generation. * * @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" }); if (encrypted instanceof Uint8Array) { return encrypted; } if (encrypted && typeof encrypted === "object" && "getReader" in encrypted) { return await (0, import_stream_utils.streamToUint8Array)( encrypted ); } throw new Error("Unexpected encrypted data format"); } catch (error) { throw (0, import_error_utils.wrapCryptoError)("encrypt with password", 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: decrypted } = await openpgp.decrypt({ message, passwords: [password], format: "binary" }); return new Uint8Array(decrypted); } catch (error) { throw (0, import_error_utils.wrapCryptoError)("decrypt with password", error); } } } class NodePGPAdapter { /** * 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 (0, import_error_utils.wrapCryptoError)("PGP encryption", 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 (0, import_error_utils.wrapCryptoError)("PGP decryption", 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 NodeHttpAdapter { /** * Performs an HTTP request using fetch. * * @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 * * @throws {Error} If fetch is not available in the environment */ async fetch(url, options) { if (typeof globalThis.fetch !== "undefined") { return globalThis.fetch(url, options); } throw new Error("No fetch implementation available in Node.js environment"); } } class NodeCacheAdapter { cache = /* @__PURE__ */ new Map(); defaultTtl = 2 * 60 * 60 * 1e3; // 2 hours in milliseconds /** * Retrieves a cached value by key. * * @param key - The cache key to look up. * Typically derived from operation parameters. * @returns The cached value or null if not found/expired */ get(key) { const entry = this.cache.get(key); if (!entry) { return null; } if (Date.now() > entry.expires) { this.cache.delete(key); return null; } return entry.value; } /** * Stores a value in the cache with TTL. * * @param key - The cache key. * Should be unique per operation. * @param value - The value to cache. * Typically serialized data or signatures. */ set(key, value) { this.cache.set(key, { value, expires: Date.now() + this.defaultTtl }); } /** * Removes a specific key from the cache. * * @param key - The cache key to remove. * Use when cached data becomes invalid. */ delete(key) { this.cache.delete(key); } /** * Clears all cached values. * * @remarks * Use with caution as this removes all cached signatures * and other performance optimizations. */ clear() { this.cache.clear(); } } class NodePlatformAdapter { crypto; pgp; http; cache; platform = "node"; constructor() { this.crypto = new NodeCryptoAdapter(); this.pgp = new NodePGPAdapter(); this.http = new NodeHttpAdapter(); this.cache = new NodeCacheAdapter(); } } const nodePlatformAdapter = new NodePlatformAdapter(); // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { NodePlatformAdapter, nodePlatformAdapter }); //# sourceMappingURL=node.cjs.map