UNPKG

@arklabs/wallet-sdk

Version:

Bitcoin wallet SDK with Taproot and Ark integration

148 lines (147 loc) 5.98 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.IndexedDBVtxoRepository = void 0; const DB_NAME = "wallet-db"; const STORE_NAME = "vtxos"; const DB_VERSION = 1; class IndexedDBVtxoRepository { constructor() { this.db = null; this.initDB(); } initDB() { return new Promise((resolve, reject) => { const request = indexedDB.open(DB_NAME, DB_VERSION); request.onerror = () => { reject(request.error); }; request.onsuccess = () => { this.db = request.result; resolve(); }; request.onupgradeneeded = (event) => { const db = event.target.result; if (!db.objectStoreNames.contains(STORE_NAME)) { const store = db.createObjectStore(STORE_NAME, { keyPath: ["txid", "vout"], }); store.createIndex("state", "virtualStatus.state", { unique: false, }); } }; }); } async addOrUpdate(vtxos) { if (!this.db) { await this.initDB(); if (!this.db) throw new Error("Failed to initialize database"); } return new Promise((resolve, reject) => { const transaction = this.db.transaction(STORE_NAME, "readwrite"); const store = transaction.objectStore(STORE_NAME); const requests = vtxos.map((vtxo) => { return new Promise((resolveRequest, rejectRequest) => { const request = store.put(vtxo); request.onsuccess = () => resolveRequest(); request.onerror = () => rejectRequest(request.error); }); }); Promise.all(requests) .then(() => resolve()) .catch(reject); }); } async deleteAll() { if (!this.db) { await this.initDB(); if (!this.db) throw new Error("Failed to initialize database"); } return new Promise((resolve, reject) => { const transaction = this.db.transaction(STORE_NAME, "readwrite"); const store = transaction.objectStore(STORE_NAME); const request = store.clear(); request.onsuccess = () => resolve(); request.onerror = () => reject(request.error); }); } async getSpendableVtxos() { if (!this.db) { await this.initDB(); if (!this.db) throw new Error("Failed to initialize database"); } return new Promise((resolve, reject) => { const transaction = this.db.transaction(STORE_NAME, "readonly"); const store = transaction.objectStore(STORE_NAME); const stateIndex = store.index("state"); // Get both settled and pending vtxos const settledRequest = stateIndex.getAll("settled"); const pendingRequest = stateIndex.getAll("pending"); Promise.all([ new Promise((resolveSettled, rejectSettled) => { settledRequest.onsuccess = () => { resolveSettled(settledRequest.result); }; settledRequest.onerror = () => rejectSettled(settledRequest.error); }), new Promise((resolvePending, rejectPending) => { pendingRequest.onsuccess = () => { resolvePending(pendingRequest.result); }; pendingRequest.onerror = () => rejectPending(pendingRequest.error); }), ]) .then(([settledVtxos, pendingVtxos]) => { resolve([...settledVtxos, ...pendingVtxos]); }) .catch(reject); }); } async getAllVtxos() { if (!this.db) { await this.initDB(); if (!this.db) throw new Error("Failed to initialize database"); } return new Promise((resolve, reject) => { const transaction = this.db.transaction(STORE_NAME, "readonly"); const store = transaction.objectStore(STORE_NAME); const stateIndex = store.index("state"); // Get all vtxos by state const settledRequest = stateIndex.getAll("settled"); const pendingRequest = stateIndex.getAll("pending"); const spentRequest = stateIndex.getAll("swept"); Promise.all([ new Promise((resolveSettled, rejectSettled) => { settledRequest.onsuccess = () => { resolveSettled(settledRequest.result); }; settledRequest.onerror = () => rejectSettled(settledRequest.error); }), new Promise((resolvePending, rejectPending) => { pendingRequest.onsuccess = () => { resolvePending(pendingRequest.result); }; pendingRequest.onerror = () => rejectPending(pendingRequest.error); }), new Promise((resolveSpent, rejectSpent) => { spentRequest.onsuccess = () => { resolveSpent(spentRequest.result); }; spentRequest.onerror = () => rejectSpent(spentRequest.error); }), ]) .then(([settledVtxos, pendingVtxos, spentVtxos]) => { resolve({ spendable: [...settledVtxos, ...pendingVtxos], spent: spentVtxos, }); }) .catch(reject); }); } } exports.IndexedDBVtxoRepository = IndexedDBVtxoRepository;