send-crypto
Version:
A minimal JavaScript library / wallet for sending crypto assets
120 lines • 11.2 kB
JavaScript
import axios from "axios";
import { sortUTXOs } from "../../lib/utxo";
import { DEFAULT_TIMEOUT } from "./timeout";
const fetchUTXO = (network) => async (txHash, vOut) => {
const url = `https://api.blockchair.com/${network}/dashboards/transaction/${txHash}`;
const response = (await axios.get(`${url}`, {
timeout: DEFAULT_TIMEOUT,
})).data;
if (!response.data[txHash]) {
throw new Error(`Transaction not found.`);
}
const tx = response.data[txHash];
let latestBlock = response.context.state;
if (latestBlock === 0) {
const statsUrl = `https://api.blockchair.com/${network}/stats`;
const statsResponse = (await axios.get(statsUrl)).data;
latestBlock = statsResponse.data.blocks - 1;
}
const confirmations = tx.transaction.block_id === -1
? 0
: Math.max(latestBlock - tx.transaction.block_id + 1, 0);
return {
txHash,
vOut,
amount: tx.outputs[vOut].value,
confirmations,
};
};
const fetchUTXOs = (network) => async (address, confirmations) => {
const url = `https://api.blockchair.com/${network}/dashboards/address/${address}?limit=0,100`;
const response = (await axios.get(url, { timeout: DEFAULT_TIMEOUT })).data;
let latestBlock = response.context.state;
if (latestBlock === 0) {
const statsUrl = `https://api.blockchair.com/${network}/stats`;
const statsResponse = (await axios.get(statsUrl)).data;
latestBlock = statsResponse.data.blocks - 1;
}
return response.data[address].utxo
.map((utxo) => ({
txHash: utxo.transaction_hash,
amount: utxo.value,
vOut: utxo.index,
confirmations: utxo.block_id === -1 ? 0 : latestBlock - utxo.block_id + 1,
}))
.filter((utxo) => confirmations === 0 || utxo.confirmations >= confirmations)
.sort(sortUTXOs);
};
const fetchTXs = (network) => async (address, confirmations = 0, limit = 25) => {
const url = `https://api.blockchair.com/${network}/dashboards/address/${address}?limit=${limit},0`;
const response = (await axios.get(url, { timeout: DEFAULT_TIMEOUT })).data;
let latestBlock = response.context.state;
if (latestBlock === 0) {
const statsUrl = `https://api.blockchair.com/${network}/stats`;
const statsResponse = (await axios.get(statsUrl)).data;
latestBlock = statsResponse.data.blocks - 1;
}
const txHashes = response.data[address].transactions;
let txDetails = {};
// Fetch in sets of 10
for (let i = 0; i < Math.ceil(txHashes.length / 10); i++) {
const txUrl = `https://api.blockchair.com/${network}/dashboards/transactions/${txHashes
.slice(i * 10, (i + 1) * 10)
.join(",")}`;
const txResponse = (await axios.get(txUrl, {
timeout: DEFAULT_TIMEOUT,
})).data;
txDetails = {
...txDetails,
...txResponse.data,
};
}
const received = [];
for (const txHash of txHashes) {
const tx = txDetails[txHash];
const txConfirmations = tx.transaction.block_id === -1
? 0
: Math.max(latestBlock - tx.transaction.block_id + 1, 0);
for (let i = 0; i < tx.outputs.length; i++) {
const vout = tx.outputs[i];
if (vout.recipient === address) {
received.push({
txHash: tx.transaction.hash,
amount: vout.value,
vOut: i,
confirmations: txConfirmations,
});
}
}
}
return received
.filter((utxo) => confirmations === 0 || utxo.confirmations >= confirmations)
.sort(sortUTXOs);
};
export const broadcastTransaction = (network) => async (txHex) => {
const url = `https://api.blockchair.com/${network}/push/transaction`;
const response = await axios.post(url, { data: txHex }, { timeout: DEFAULT_TIMEOUT });
if (response.data.error) {
throw new Error(response.data.error);
}
return response.data.data.transaction_hash;
};
var Networks;
(function (Networks) {
Networks["BITCOIN"] = "bitcoin";
Networks["BITCOIN_CASH"] = "bitcoin-cash";
Networks["LITECOIN"] = "litecoin";
Networks["BITCOIN_SV"] = "bitcoin-sv";
Networks["DOGECOIN"] = "dogecoin";
Networks["DASH"] = "dash";
Networks["GROESTLCOIN"] = "groestlcoin";
Networks["BITCOIN_TESTNET"] = "bitcoin/testnet";
})(Networks || (Networks = {}));
export const Blockchair = {
networks: Networks,
fetchUTXO,
fetchUTXOs,
broadcastTransaction,
fetchTXs,
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmxvY2tjaGFpci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb21tb24vYXBpcy9ibG9ja2NoYWlyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxNQUFNLE9BQU8sQ0FBQztBQUUxQixPQUFPLEVBQUUsU0FBUyxFQUFRLE1BQU0sZ0JBQWdCLENBQUM7QUFDakQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUU1QyxNQUFNLFNBQVMsR0FBRyxDQUFDLE9BQWUsRUFBRSxFQUFFLENBQUMsS0FBSyxFQUN4QyxNQUFjLEVBQ2QsSUFBWSxFQUNDLEVBQUU7SUFDZixNQUFNLEdBQUcsR0FBRyw4QkFBOEIsT0FBTywyQkFBMkIsTUFBTSxFQUFFLENBQUM7SUFFckYsTUFBTSxRQUFRLEdBQUcsQ0FDYixNQUFNLEtBQUssQ0FBQyxHQUFHLENBQXNCLEdBQUcsR0FBRyxFQUFFLEVBQUU7UUFDM0MsT0FBTyxFQUFFLGVBQWU7S0FDM0IsQ0FBQyxDQUNMLENBQUMsSUFBSSxDQUFDO0lBRVAsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUU7UUFDeEIsTUFBTSxJQUFJLEtBQUssQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO0tBQzdDO0lBRUQsTUFBTSxFQUFFLEdBQUcsUUFBUSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUVqQyxJQUFJLFdBQVcsR0FBRyxRQUFRLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQztJQUN6QyxJQUFJLFdBQVcsS0FBSyxDQUFDLEVBQUU7UUFDbkIsTUFBTSxRQUFRLEdBQUcsOEJBQThCLE9BQU8sUUFBUSxDQUFDO1FBQy9ELE1BQU0sYUFBYSxHQUFHLENBQUMsTUFBTSxLQUFLLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO1FBQ3ZELFdBQVcsR0FBRyxhQUFhLENBQUMsSUFBSSxDQUFD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