Workflow updating files of dogewallet

This commit is contained in:
RanchiMall Dev 2026-01-12 12:05:42 +00:00
parent f9801ca065
commit d7070a9dea
7 changed files with 17418 additions and 0 deletions

View File

@ -0,0 +1,507 @@
(function (EXPORTS) {
"use strict";
const dogeBlockchainAPI = EXPORTS;
const DEFAULT = {
fee: 0.09,
};
//Get balance for the given Address
dogeBlockchainAPI.getBalance = function (addr) {
return new Promise((resolve, reject) => {
fetch(
`https://go.getblock.io/b05a36f1d01d401196afbb1d3957a9f3/api/address/${addr}`
)
.then((response) => {
if (!response.ok)
throw new Error(`HTTP error! Status: ${response.status}`);
return response.json();
})
.then((data) => {
console.log("Balance data:", data);
if (data && typeof data.balance !== "undefined")
resolve(parseFloat(data.balance));
else reject("Balance not found in response");
})
.catch((error) => reject(error));
});
};
// Helper function to get UTXOs for an address
const getUTXOs = async (addr) => {
const url = `https://go.getblock.io/b05a36f1d01d401196afbb1d3957a9f3/api/address/${addr}?details=txs`;
const res = await fetch(url);
const data = await res.json();
if (!data.txs) throw new Error("No transactions found for address");
const utxos = [];
data.txs.forEach((tx) => {
tx.vout.forEach((vout) => {
const addresses =
vout.addresses ||
(vout.scriptPubKey ? vout.scriptPubKey.addresses : []);
if (
!vout.spent &&
vout.scriptPubKey &&
vout.scriptPubKey.hex &&
addresses &&
addresses.some((a) => a.toLowerCase() === addr.toLowerCase())
) {
console.log("Found UTXO:", {
txid: tx.txid,
vout: vout.n,
value: parseFloat(vout.value),
});
utxos.push({
txid: tx.txid,
vout: vout.n,
value: parseFloat(vout.value),
scriptPubKey: vout.scriptPubKey.hex,
});
}
});
});
return utxos;
};
function toDOGE(val) {
if (typeof val === "string" && val.includes("DOGE")) {
return parseFloat(val.replace("DOGE", "").trim());
}
const num = parseFloat(val || "0");
return isNaN(num) ? 0 : num;
}
/**
* Get transaction history for a Dogecoin address
* @param {string} address - The Dogecoin address to check
* @param {Object} options - Optional parameters
* @param {number} options.limit - Number of transactions to retrieve (default: 10)
* @param {number} options.offset - Offset for pagination
* @returns {Promise} Promise object that resolves with transaction list
*/
dogeBlockchainAPI.getDogeTransactions = function (address, options = {}) {
return new Promise((resolve, reject) => {
console.log(`Fetching transaction history for: ${address}`);
fetch(
`https://go.getblock.io/b05a36f1d01d401196afbb1d3957a9f3/api/address/${address}?details=txs`
)
.then((response) => {
if (!response.ok) {
if (response.status === 429) {
throw new Error(
"API rate limit exceeded. Please try again later."
);
}
throw new Error(`HTTP error! Status: ${response.status}`);
}
return response.json();
})
.then(async (data) => {
console.log("Raw API response data:", data);
const txs = data.txs || [];
const txids = txs.map((tx) => tx.txid) || [];
console.log(
`Found ${txids.length} transactions for address ${address}`
);
const limit = options.limit || 10;
const offset = options.offset || 0;
const maxTxToProcess = Math.min(10, limit);
const txsToProcess = txs.slice(offset, offset + maxTxToProcess);
if (txsToProcess.length === 0) {
console.log("No transactions to process based on offset/limit");
resolve({
transactions: [],
total: txs.length,
offset: offset,
limit: limit,
});
return;
}
console.log(`Processing ${txsToProcess.length} transactions`);
const transactions = txsToProcess;
console.log("Transactions to process:", transactions);
try {
const processedTransactions = transactions.map((tx) => {
const inputs = tx.vin || [];
const outputs = tx.vout || [];
// Check if address is sender (in vin)
const isSender = inputs.some((i) =>
i.addresses?.includes(address)
);
// Check if address is receiver (in vout)
const isReceiver = outputs.some(
(o) =>
(o.addresses && o.addresses.includes(address)) ||
(o.scriptPubKey?.addresses &&
o.scriptPubKey.addresses.includes(address))
);
let type = "unknown";
let value = 0;
let fromAddresses = [];
let toAddresses = [];
// Extract sender addresses (from)
inputs.forEach((input) => {
if (input.addresses && input.addresses.length > 0) {
input.addresses.forEach((addr) => {
if (!fromAddresses.includes(addr)) {
fromAddresses.push(addr);
}
});
}
});
// Extract recipient addresses (to)
outputs.forEach((output) => {
const outAddresses =
output.addresses ||
(output.scriptPubKey ? output.scriptPubKey.addresses : []);
if (outAddresses && outAddresses.length > 0) {
outAddresses.forEach((addr) => {
if (!toAddresses.includes(addr)) {
toAddresses.push(addr);
}
});
}
});
if (isSender && isReceiver) {
type = "self";
const totalInput = inputs
.filter((i) => i.addresses?.includes(address))
.reduce((sum, i) => sum + toDOGE(i.value), 0);
const totalOutput = outputs
.filter(
(o) =>
(o.addresses && o.addresses.includes(address)) ||
(o.scriptPubKey?.addresses &&
o.scriptPubKey.addresses.includes(address))
)
.reduce((sum, o) => sum + toDOGE(o.value), 0);
value = totalOutput - totalInput;
} else if (isSender) {
type = "sent";
const totalInput = inputs
.filter((i) => i.addresses?.includes(address))
.reduce((sum, i) => sum + toDOGE(i.value), 0);
const changeBack = outputs
.filter(
(o) =>
(o.addresses && o.addresses.includes(address)) ||
(o.scriptPubKey?.addresses &&
o.scriptPubKey.addresses.includes(address))
)
.reduce((sum, o) => sum + toDOGE(o.value), 0);
value = -(totalInput - changeBack);
} else if (isReceiver) {
type = "received";
value = outputs
.filter(
(o) =>
(o.addresses && o.addresses.includes(address)) ||
(o.scriptPubKey?.addresses &&
o.scriptPubKey.addresses.includes(address))
)
.reduce((sum, o) => sum + toDOGE(o.value), 0);
}
console.log(`Transaction ${tx.txid} time data:`, {
blockTime: tx.blocktime,
blockheight: tx.blockheight,
time: tx.time,
});
const timestamp =
tx.time ||
tx.blockTime ||
(tx.confirmations
? Math.floor(Date.now() / 1000) - tx.confirmations * 600
: Math.floor(Date.now() / 1000));
return {
txid: tx.txid,
type,
value: value.toFixed(8),
time: timestamp,
blockHeight: tx.blockheight,
formattedTime: new Date(timestamp * 1000).toLocaleString(),
confirmations: tx.confirmations || 0,
rawTx: tx.hex,
fromAddresses: fromAddresses,
toAddresses: toAddresses,
};
});
if (processedTransactions.length > 0) {
console.log(
"Sample transaction processed:",
processedTransactions[0]
);
console.log("Raw transaction data:", transactions[0]);
} else {
console.log("No transactions were processed successfully");
console.log("Original txids found:", txids);
}
resolve({
transactions: processedTransactions,
total: txids.length,
offset: offset,
limit: limit,
});
} catch (error) {
console.error("Error processing transactions:", error);
reject(error);
}
})
.catch((error) => {
console.error("API Error:", error);
reject(error);
});
});
};
/**
* Send Dogecoin transaction using direct RPC calls to GetBlock.io
* This method implements the full RPC workflow: createrawtransaction -> signrawtransaction -> sendrawtransaction
* @param {string} senderAddr - Sender's Dogecoin address
* @param {string} receiverAddr - Receiver's Dogecoin address
* @param {number} sendAmt - Amount to send in DOGE
* @param {string} privKey - Private key of the sender
* @returns {Promise} Promise that resolves with the transaction ID
*/
dogeBlockchainAPI.sendDogecoinRPC = function (
senderAddr,
receiverAddr,
sendAmt,
privKey
) {
return new Promise((resolve, reject) => {
if (!dogeCrypto.validateDogeID(senderAddr, true))
return reject(`Invalid sender address: ${senderAddr}`);
if (!dogeCrypto.validateDogeID(receiverAddr))
return reject(`Invalid receiver address: ${receiverAddr}`);
if (typeof sendAmt !== "number" || sendAmt <= 0)
return reject(`Invalid send amount: ${sendAmt}`);
if (privKey.length < 1 || !dogeCrypto.verifyPrivKey(privKey, senderAddr))
return reject("Invalid Private key!");
const fee = DEFAULT.fee;
const apiToken = "c9888622feab498ab709c20ea8646bf0";
const rpcEndpoint = `https://go.getblock.io/${apiToken}/`;
async function rpc(method, params = []) {
const res = await fetch(rpcEndpoint, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ jsonrpc: "2.0", id: "1", method, params }),
});
const text = await res.text();
try {
const data = JSON.parse(text);
if (data.error) throw new Error(JSON.stringify(data.error));
return data.result;
} catch (err) {
console.error("Raw RPC response:\n", text);
throw new Error("Failed to parse JSON-RPC response");
}
}
// Get UTXOs for the address
getUTXOs(senderAddr)
.then(async (utxos) => {
if (utxos.length === 0) return reject("No valid UTXOs found");
console.log("Found UTXOs:", utxos);
const utxoTotal = utxos.reduce((sum, utxo) => sum + utxo.value, 0);
console.log("Total UTXO value:", utxoTotal);
if (utxoTotal < sendAmt + fee)
return reject(
`Insufficient funds: ${utxoTotal} < ${sendAmt + fee}`
);
const inputs = utxos.map((utxo) => ({
txid: utxo.txid,
vout: utxo.vout,
}));
console.log("inputs:", inputs);
// Calculate change amount
const change = utxoTotal - sendAmt - fee;
const outputs = {
[senderAddr]: Number(change.toFixed(8)),
[receiverAddr]: Number(sendAmt.toFixed(8)),
};
console.log("outputs:", outputs);
try {
// Create raw transaction
console.log("Creating raw transaction...");
const rawTx = await rpc("createrawtransaction", [inputs, outputs]);
console.log("Raw transaction hex:", rawTx);
// Sign raw transaction
console.log("Signing transaction...");
const signedTx = await rpc("signrawtransaction", [
rawTx,
[
{
txid: utxos[0].txid,
vout: utxos[0].vout,
scriptPubKey: utxos[0].scriptPubKey,
amount: utxos[0].value.toFixed(8),
},
],
[privKey],
]);
if (!signedTx.complete) {
return reject(
`Failed to sign transaction: ${JSON.stringify(signedTx.errors)}`
);
}
console.log("Signed transaction hex:", signedTx.hex);
// Send raw transaction
console.log("Broadcasting transaction...");
const txid = await rpc("sendrawtransaction", [signedTx.hex]);
resolve(txid);
} catch (error) {
console.error("RPC error:", error);
reject(error);
}
})
.catch((error) => reject(error));
});
};
/**
* Get transaction details by transaction ID
* @param {string} txid - The transaction ID to look up
* @returns {Promise} Promise object that resolves with transaction details
*/
dogeBlockchainAPI.getTransactionDetails = function (txid) {
return new Promise((resolve, reject) => {
if (!txid || typeof txid !== "string" || txid.length !== 64) {
reject(new Error("Invalid transaction ID format"));
return;
}
console.log(`Fetching transaction details for txid: ${txid}`);
fetch(
`https://go.getblock.io/b05a36f1d01d401196afbb1d3957a9f3/api/tx/${txid}`
)
.then((response) => {
if (!response.ok) {
if (response.status === 404) {
throw new Error("Transaction not found");
} else if (response.status === 429) {
throw new Error(
"API rate limit exceeded. Please try again later."
);
}
throw new Error(`HTTP error! Status: ${response.status}`);
}
return response.json();
})
.then((data) => {
console.log("Transaction details data:", data);
if (!data || !data.txid) {
throw new Error("Invalid transaction data returned");
}
const processedData = {
txid: data.txid,
blockHeight: data.blockheight,
blockHash: data.blockhash,
blockTime: data.blocktime
? new Date(data.blocktime * 1000).toLocaleString()
: "Pending",
confirmations: data.confirmations || 0,
fees: data.fees,
size: data.size,
inputsCount: data.vin ? data.vin.length : 0,
outputsCount: data.vout ? data.vout.length : 0,
totalInput: 0,
totalOutput: 0,
inputs: [],
outputs: [],
};
// Process inputs
if (data.vin && Array.isArray(data.vin)) {
data.vin.forEach((input) => {
const inputValue = parseFloat(input.value || 0);
processedData.totalInput += inputValue;
const inputData = {
txid: input.txid,
vout: input.vout,
addresses: input.addresses || [],
value: inputValue,
};
processedData.inputs.push(inputData);
});
}
// Process outputs
if (data.vout && Array.isArray(data.vout)) {
data.vout.forEach((output) => {
const outputValue = parseFloat(output.value || 0);
processedData.totalOutput += outputValue;
const addresses =
output.scriptPubKey && output.scriptPubKey.addresses
? output.scriptPubKey.addresses
: [];
const outputData = {
n: output.n,
addresses: addresses,
value: outputValue,
spent: output.spent || false,
scriptPubKey: output.scriptPubKey
? output.scriptPubKey.hex
: "",
};
processedData.outputs.push(outputData);
});
}
resolve(processedData);
})
.catch((error) => {
console.error("Error fetching transaction details:", error);
reject(error);
});
});
};
})(
"object" === typeof module ? module.exports : (window.dogeBlockchainAPI = {})
);

View File

@ -0,0 +1,281 @@
(function (EXPORTS) {
"use strict";
const dogeCrypto = EXPORTS;
//Generates a new flo ID and returns private-key, public-key and floID
const generateNewID = (dogeCrypto.generateNewID = function () {
var key = new Bitcoin.ECKey(false);
key.setCompressed(true);
return {
floID: key.getBitcoinAddress(),
pubKey: key.getPubKeyHex(),
privKey: key.getBitcoinWalletImportFormat(),
};
});
Object.defineProperties(dogeCrypto, {
newID: {
get: () => generateNewID(),
},
hashID: {
value: (str) => {
let bytes = ripemd160(Crypto.SHA256(str, { asBytes: true }), {
asBytes: true,
});
bytes.unshift(bitjs.pub);
var hash = Crypto.SHA256(
Crypto.SHA256(bytes, {
asBytes: true,
}),
{
asBytes: true,
}
);
var checksum = hash.slice(0, 4);
return bitjs.Base58.encode(bytes.concat(checksum));
},
},
tmpID: {
get: () => {
let bytes = Crypto.util.randomBytes(20);
bytes.unshift(bitjs.pub);
var hash = Crypto.SHA256(
Crypto.SHA256(bytes, {
asBytes: true,
}),
{
asBytes: true,
}
);
var checksum = hash.slice(0, 4);
return bitjs.Base58.encode(bytes.concat(checksum));
},
},
});
//Verify the private-key for the given public-key or doge-ID
dogeCrypto.verifyPrivKey = function (privateKeyWIF, dogeAddress) {
if (!privateKeyWIF || !dogeAddress) return false;
try {
var derivedAddress =
dogeCrypto.generateMultiChain(privateKeyWIF).DOGE.address;
return derivedAddress === dogeAddress;
} catch (e) {
console.error("verifyPrivKey error:", e);
return false;
}
};
//Check if the given doge-id is valid or not
dogeCrypto.validateDogeID = function (dogeID) {
if (!dogeID) return false;
try {
// Decode Base58Check
let bytes = bitjs.Base58.decode(dogeID);
if (!bytes || bytes.length < 25) return false;
let version = bytes[0];
return version === 0x1e;
} catch (e) {
return false;
}
};
//Generates multi-chain addresses (DOGE, BTC, FLO, LTC) from the given WIF or new WIF
dogeCrypto.generateMultiChain = function (inputWif) {
try {
const origBitjsPub = bitjs.pub;
const origBitjsPriv = bitjs.priv;
const origBitjsCompressed = bitjs.compressed;
const origCoinJsCompressed = coinjs.compressed;
bitjs.compressed = true;
coinjs.compressed = true;
const versions = {
DOGE: { pub: 0x1e, priv: 0x9e },
BTC: { pub: 0x00, priv: 0x80 },
FLO: { pub: 0x23, priv: 0xa3 },
LTC: { pub: 0x30, priv: 0xb0 },
};
let privKeyHex;
let compressed = true;
if (typeof inputWif === "string" && inputWif.length > 0) {
const decode = Bitcoin.Base58.decode(inputWif);
const keyWithVersion = decode.slice(0, decode.length - 4);
let key = keyWithVersion.slice(1);
if (key.length >= 33 && key[key.length - 1] === 0x01) {
key = key.slice(0, key.length - 1);
compressed = true;
} else {
compressed = false;
}
privKeyHex = Crypto.util.bytesToHex(key);
} else {
const newKey = generateNewID();
const decode = Bitcoin.Base58.decode(newKey.privKey);
const keyWithVersion = decode.slice(0, decode.length - 4);
let key = keyWithVersion.slice(1);
if (key.length >= 33 && key[key.length - 1] === 0x01) {
key = key.slice(0, key.length - 1);
}
privKeyHex = Crypto.util.bytesToHex(key);
}
bitjs.compressed = compressed;
coinjs.compressed = compressed;
// Generate public key
const pubKey = bitjs.newPubkey(privKeyHex);
const result = {
DOGE: { address: "", privateKey: "" },
BTC: { address: "", privateKey: "" },
FLO: { address: "", privateKey: "" },
LTC: { address: "", privateKey: "" },
};
// For DOGE
bitjs.pub = versions.DOGE.pub;
bitjs.priv = versions.DOGE.priv;
result.DOGE.address = bitjs.pubkey2address(pubKey);
result.DOGE.privateKey = bitjs.privkey2wif(privKeyHex);
// For BTC
bitjs.pub = versions.BTC.pub;
bitjs.priv = versions.BTC.priv;
result.BTC.address = coinjs.bech32Address(pubKey).address;
result.BTC.privateKey = bitjs.privkey2wif(privKeyHex);
// For FLO
bitjs.pub = versions.FLO.pub;
bitjs.priv = versions.FLO.priv;
result.FLO.address = bitjs.pubkey2address(pubKey);
result.FLO.privateKey = bitjs.privkey2wif(privKeyHex);
// For LTC
bitjs.pub = versions.LTC.pub;
bitjs.priv = versions.LTC.priv;
result.LTC.address = bitjs.pubkey2address(pubKey);
result.LTC.privateKey = bitjs.privkey2wif(privKeyHex);
bitjs.pub = origBitjsPub;
bitjs.priv = origBitjsPriv;
bitjs.compressed = origBitjsCompressed;
coinjs.compressed = origCoinJsCompressed;
return result;
} catch (error) {
console.error("Error in generateMultiChain:", error);
throw error;
}
};
/**
* Translates an address from one blockchain to equivalent addresses on other chains
* Works by extracting the public key hash from the address and recreating addresses with different version bytes
*/
dogeCrypto.translateAddress = function (address) {
try {
let sourceChain = null;
if (address.startsWith("bc1")) {
sourceChain = "BTC";
} else if (address.startsWith("D")) {
sourceChain = "DOGE";
} else if (address.startsWith("F")) {
sourceChain = "FLO";
} else if (address.startsWith("L")) {
sourceChain = "LTC";
} else {
throw new Error("Unsupported address format");
}
let decoded, hash160;
if (sourceChain === "BTC") {
decoded = coinjs.bech32_decode(address);
if (!decoded) throw new Error("Invalid bech32 address");
// For segwit addresses, convert from 5-bit to 8-bit
const data = coinjs.bech32_convert(decoded.data.slice(1), 5, 8, false);
hash160 = Crypto.util.bytesToHex(data);
} else {
// Handle DOGE and FLO addresses (Base58)
const decodedBytes = Bitcoin.Base58.decode(address);
if (!decodedBytes || decodedBytes.length < 25)
throw new Error("Invalid address");
// Remove version byte (first byte) and checksum (last 4 bytes)
const bytes = decodedBytes.slice(1, decodedBytes.length - 4);
hash160 = Crypto.util.bytesToHex(bytes);
}
if (!hash160) throw new Error("Could not extract hash160 from address");
const versions = {
DOGE: 0x1e,
FLO: 0x23,
BTC: 0x00,
LTC: 0x30,
};
const result = {};
// Generate address for DOGE
const dogeBytes = Crypto.util.hexToBytes(hash160);
dogeBytes.unshift(versions.DOGE);
const dogeChecksum = Crypto.SHA256(
Crypto.SHA256(dogeBytes, { asBytes: true }),
{ asBytes: true }
).slice(0, 4);
result.DOGE = Bitcoin.Base58.encode(dogeBytes.concat(dogeChecksum));
// Generate address for FLO
const floBytes = Crypto.util.hexToBytes(hash160);
floBytes.unshift(versions.FLO);
const floChecksum = Crypto.SHA256(
Crypto.SHA256(floBytes, { asBytes: true }),
{ asBytes: true }
).slice(0, 4);
result.FLO = Bitcoin.Base58.encode(floBytes.concat(floChecksum));
// Generate address for BTC
try {
const words = coinjs.bech32_convert(
Crypto.util.hexToBytes(hash160),
8,
5,
true
);
result.BTC = coinjs.bech32_encode("bc", [0].concat(words));
} catch (e) {
console.log("Could not generate segwit address:", e);
}
// Generate address for LTC
const ltcBytes = Crypto.util.hexToBytes(hash160);
ltcBytes.unshift(versions.LTC);
const ltcChecksum = Crypto.SHA256(
Crypto.SHA256(ltcBytes, { asBytes: true }),
{ asBytes: true }
).slice(0, 4);
result.LTC = Bitcoin.Base58.encode(ltcBytes.concat(ltcChecksum));
return result;
} catch (err) {
console.error("Address translation error:", err);
throw new Error("Address translation failed: " + err.message);
}
};
})("object" === typeof module ? module.exports : (window.dogeCrypto = {}));

View File

@ -0,0 +1,124 @@
class SearchedAddressDB {
constructor() {
this.dbName = "DogeWalletDB";
this.version = 1;
this.storeName = "searchedAddresses";
this.db = null;
}
async init() {
return new Promise((resolve, reject) => {
const request = indexedDB.open(this.dbName, this.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(this.storeName)) {
const store = db.createObjectStore(this.storeName, {
keyPath: "address",
});
store.createIndex("timestamp", "timestamp", { unique: false });
}
};
});
}
async saveSearchedAddress(
address,
balance,
timestamp = Date.now(),
sourceInfo = null
) {
if (!this.db) await this.init();
return new Promise((resolve, reject) => {
const transaction = this.db.transaction([this.storeName], "readwrite");
const store = transaction.objectStore(this.storeName);
// First, check if this address already exists
const getRequest = store.get(address);
getRequest.onsuccess = () => {
const existingRecord = getRequest.result;
let finalSourceInfo = sourceInfo;
// If record exists and has sourceInfo, preserve it unless we're providing new sourceInfo
if (existingRecord && existingRecord.sourceInfo && !sourceInfo) {
finalSourceInfo = existingRecord.sourceInfo;
}
// If existing record has sourceInfo and new one doesn't, keep the existing one
else if (
existingRecord &&
existingRecord.sourceInfo &&
sourceInfo === null
) {
finalSourceInfo = existingRecord.sourceInfo;
}
const data = {
address, // This will be the DOGE address
balance,
timestamp,
formattedBalance: `${balance} DOGE`,
sourceInfo: finalSourceInfo, // Contains original blockchain info if translated from another chain
};
const putRequest = store.put(data);
putRequest.onsuccess = () => resolve();
putRequest.onerror = () => reject(putRequest.error);
};
getRequest.onerror = () => reject(getRequest.error);
});
}
async getSearchedAddresses() {
if (!this.db) await this.init();
return new Promise((resolve, reject) => {
const transaction = this.db.transaction([this.storeName], "readonly");
const store = transaction.objectStore(this.storeName);
const index = store.index("timestamp");
const request = index.getAll();
request.onsuccess = () => {
const results = request.result.sort(
(a, b) => b.timestamp - a.timestamp
);
resolve(results);
};
request.onerror = () => reject(request.error);
});
}
async deleteSearchedAddress(address) {
if (!this.db) await this.init();
return new Promise((resolve, reject) => {
const transaction = this.db.transaction([this.storeName], "readwrite");
const store = transaction.objectStore(this.storeName);
const request = store.delete(address);
request.onsuccess = () => resolve();
request.onerror = () => reject(request.error);
});
}
async clearAllSearchedAddresses() {
if (!this.db) await this.init();
return new Promise((resolve, reject) => {
const transaction = this.db.transaction([this.storeName], "readwrite");
const store = transaction.objectStore(this.storeName);
const request = store.clear();
request.onsuccess = () => resolve();
request.onerror = () => reject(request.error);
});
}
}

File diff suppressed because it is too large Load Diff

1
dogewallet/favicon.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 1.8 MiB

2806
dogewallet/index.html Normal file

File diff suppressed because it is too large Load Diff

3706
dogewallet/style.css Normal file

File diff suppressed because it is too large Load Diff