v2.2.0 - new major version for mempool-js (#2)
* - Refactoring code. - Refactoring folder structure. - Adding apiEndpoint and websocketEndpoint to Mempool config. - Adding brownserify feature. - Adding MIT LICENSE * - Changing package.json information. - Reorganizing README.md information. - Default export for CommonJs and ES6 Modules. - Changing default variable to mempoolJS. - Organizing the API and WS providers. - Splitting websocket connection types: client and server. * Change version to 2.2.0. Reorder keywords in alphabetical order.
This commit is contained in:
166
src/addresses.ts
166
src/addresses.ts
@@ -1,166 +0,0 @@
|
||||
import api from './api';
|
||||
|
||||
const getAddress = async (params: { address: string }) => {
|
||||
return api
|
||||
.get(`/address/${params.address}`)
|
||||
.then(
|
||||
(res: {
|
||||
data: {
|
||||
address: string;
|
||||
chain_stats: {
|
||||
funded_txo_count: number;
|
||||
funded_txo_sum: number;
|
||||
spent_txo_count: number;
|
||||
spent_txo_sum: number;
|
||||
tx_count: number;
|
||||
};
|
||||
mempool_stats: {
|
||||
funded_txo_count: number;
|
||||
funded_txo_sum: number;
|
||||
spent_txo_count: number;
|
||||
spent_txo_sum: number;
|
||||
tx_count: number;
|
||||
};
|
||||
};
|
||||
}) => {
|
||||
return res.data;
|
||||
}
|
||||
)
|
||||
.catch(
|
||||
(err: {
|
||||
response: {
|
||||
data: string;
|
||||
};
|
||||
}) => {
|
||||
throw err.response.data;
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const getAddressTxs = async (params: { address: string }) => {
|
||||
return api
|
||||
.get(`/address/${params.address}/txs`)
|
||||
.then(
|
||||
(res: {
|
||||
data: {
|
||||
txid: string;
|
||||
version: number;
|
||||
locktime: number;
|
||||
vin: Record<string, unknown>[];
|
||||
vout: Record<string, unknown>[];
|
||||
size: number;
|
||||
weight: number;
|
||||
fee: number;
|
||||
status: {
|
||||
confirmed: boolean;
|
||||
block_height: number;
|
||||
block_hash: string;
|
||||
block_time: number;
|
||||
};
|
||||
}[];
|
||||
}) => {
|
||||
return res.data;
|
||||
}
|
||||
)
|
||||
.catch(
|
||||
(err: {
|
||||
response: {
|
||||
data: string;
|
||||
};
|
||||
}) => {
|
||||
throw err.response.data;
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const getAddressTxsChain = async (params: { address: string }) => {
|
||||
return api
|
||||
.get(`/address/${params.address}/txs/chain`)
|
||||
.then(
|
||||
(res: {
|
||||
data: {
|
||||
txid: string;
|
||||
version: number;
|
||||
locktime: number;
|
||||
vin: Record<string, unknown>[];
|
||||
vout: Record<string, unknown>[];
|
||||
size: number;
|
||||
weight: number;
|
||||
fee: number;
|
||||
status: {
|
||||
confirmed: boolean;
|
||||
block_height: number;
|
||||
block_hash: string;
|
||||
block_time: number;
|
||||
};
|
||||
}[];
|
||||
}) => {
|
||||
return res.data;
|
||||
}
|
||||
)
|
||||
.catch(
|
||||
(err: {
|
||||
response: {
|
||||
data: string;
|
||||
};
|
||||
}) => {
|
||||
throw err.response.data;
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const getAddressTxsMempool = async (params: { address: string }) => {
|
||||
return api
|
||||
.get(`/address/${params.address}/txs/mempool`)
|
||||
.then((res: { data: any }) => {
|
||||
return res.data;
|
||||
})
|
||||
.catch(
|
||||
(err: {
|
||||
response: {
|
||||
data: string;
|
||||
};
|
||||
}) => {
|
||||
throw err.response.data;
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const getAddressTxsUtxo = async (params: { address: string }) => {
|
||||
return api
|
||||
.get(`/address/${params.address}/utxo`)
|
||||
.then(
|
||||
(res: {
|
||||
data: {
|
||||
txid: string;
|
||||
vout: number;
|
||||
status: {
|
||||
confirmed: boolean;
|
||||
block_height: number;
|
||||
block_hash: string;
|
||||
block_time: number;
|
||||
};
|
||||
value: number;
|
||||
}[];
|
||||
}) => {
|
||||
return res.data;
|
||||
}
|
||||
)
|
||||
.catch(
|
||||
(err: {
|
||||
response: {
|
||||
data: string;
|
||||
};
|
||||
}) => {
|
||||
throw err.response.data;
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export default {
|
||||
getAddress,
|
||||
getAddressTxs,
|
||||
getAddressTxsChain,
|
||||
getAddressTxsMempool,
|
||||
getAddressTxsUtxo,
|
||||
};
|
||||
@@ -1,4 +0,0 @@
|
||||
import axios from 'axios';
|
||||
export default axios.create({
|
||||
baseURL: 'https://mempool.space/api/',
|
||||
});
|
||||
39
src/app/addresses.ts
Normal file
39
src/app/addresses.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import { AxiosInstance } from 'axios';
|
||||
import { Address, AddressTxsUtxo, Tx, AddressInstance } from '../interfaces';
|
||||
|
||||
export const useAddresses = (api: AxiosInstance): AddressInstance => {
|
||||
const getAddress = async (address: string) => {
|
||||
const { data } = await api.get<Address>(`/address/${address}`);
|
||||
return data;
|
||||
};
|
||||
|
||||
const getAddressTxs = async (address: string) => {
|
||||
const { data } = await api.get<Tx[]>(`/address/${address}/txs`);
|
||||
return data;
|
||||
};
|
||||
|
||||
const getAddressTxsChain = async (address: string) => {
|
||||
const { data } = await api.get<Tx[]>(`/address/${address}/txs/chain`);
|
||||
return data;
|
||||
};
|
||||
|
||||
const getAddressTxsMempool = async (address: string) => {
|
||||
const { data } = await api.get<Tx[]>(`/address/${address}/txs/mempool`);
|
||||
return data;
|
||||
};
|
||||
|
||||
const getAddressTxsUtxo = async (address: string) => {
|
||||
const { data } = await api.get<AddressTxsUtxo[]>(
|
||||
`/address/${address}/utxo`
|
||||
);
|
||||
return data;
|
||||
};
|
||||
|
||||
return {
|
||||
getAddress,
|
||||
getAddressTxs,
|
||||
getAddressTxsChain,
|
||||
getAddressTxsMempool,
|
||||
getAddressTxsUtxo,
|
||||
};
|
||||
};
|
||||
74
src/app/blocks.ts
Normal file
74
src/app/blocks.ts
Normal file
@@ -0,0 +1,74 @@
|
||||
import { AxiosInstance } from 'axios';
|
||||
import { Block, BlockStatus, BlockInstance, Tx } from '../interfaces';
|
||||
|
||||
export const useBlocks = (api: AxiosInstance): BlockInstance => {
|
||||
const getBlock = async (hash: string) => {
|
||||
const { data } = await api.get<Block>(`/block/${hash}`);
|
||||
return data;
|
||||
};
|
||||
|
||||
const getBlockStatus = async (hash: string) => {
|
||||
const { data } = await api.get<BlockStatus>(`/block/${hash}/status`);
|
||||
return data;
|
||||
};
|
||||
|
||||
const getBlockTxs = async (params: {
|
||||
hash: string;
|
||||
start_index?: number;
|
||||
}) => {
|
||||
const { data } = await api.get<Tx>(
|
||||
`/block/${params.hash}/txs/${params.start_index}`
|
||||
);
|
||||
return data;
|
||||
};
|
||||
|
||||
const getBlockTxids = async (hash: string) => {
|
||||
const { data } = await api.get<string[]>(`/block/${hash}/txids`);
|
||||
return data;
|
||||
};
|
||||
|
||||
const getBlockTxid = async (params: { hash: string; index: number }) => {
|
||||
const { data } = await api.get<string>(
|
||||
`/block/${params.hash}/txid/${params.index}`
|
||||
);
|
||||
return data;
|
||||
};
|
||||
|
||||
const getBlockRaw = async (hash: string) => {
|
||||
const { data } = await api.get<string>(`/block/${hash}/raw`);
|
||||
return data;
|
||||
};
|
||||
|
||||
const getBlockHeight = async (height: number) => {
|
||||
const { data } = await api.get<string>(`/block-height/${height}`);
|
||||
return data;
|
||||
};
|
||||
|
||||
const getBlocks = async (params: { start_height?: number }) => {
|
||||
const { data } = await api.get<Block>(`/blocks/${params.start_height}`);
|
||||
return data;
|
||||
};
|
||||
|
||||
const getBlocksTipHeight = async () => {
|
||||
const { data } = await api.get<number>(`/blocks/tip/height`);
|
||||
return data;
|
||||
};
|
||||
|
||||
const getBlocksTipHash = async () => {
|
||||
const { data } = await api.get<string>(`/blocks/tip/hash`);
|
||||
return data;
|
||||
};
|
||||
|
||||
return {
|
||||
getBlock,
|
||||
getBlocks,
|
||||
getBlockStatus,
|
||||
getBlockTxs,
|
||||
getBlockTxid,
|
||||
getBlockTxids,
|
||||
getBlockRaw,
|
||||
getBlockHeight,
|
||||
getBlocksTipHash,
|
||||
getBlocksTipHeight,
|
||||
};
|
||||
};
|
||||
21
src/app/fees.ts
Normal file
21
src/app/fees.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import { AxiosInstance } from 'axios';
|
||||
import { FeesRecommended, FeesMempoolBlocks, FeeInstance } from '../interfaces';
|
||||
|
||||
export const useFees = (api: AxiosInstance): FeeInstance => {
|
||||
const getFeesRecommended = async () => {
|
||||
const { data } = await api.get<FeesRecommended>(`/v1/fees/recommended`);
|
||||
return data;
|
||||
};
|
||||
|
||||
const getFeesMempoolBlocks = async () => {
|
||||
const { data } = await api.get<FeesMempoolBlocks[]>(
|
||||
`/v1/fees/mempool-blocks`
|
||||
);
|
||||
return data;
|
||||
};
|
||||
|
||||
return {
|
||||
getFeesRecommended,
|
||||
getFeesMempoolBlocks,
|
||||
};
|
||||
};
|
||||
25
src/app/mempool.ts
Normal file
25
src/app/mempool.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { AxiosInstance } from 'axios';
|
||||
import { Mempool, MempoolRecent, MempoolInstance } from '../interfaces';
|
||||
|
||||
export const useMempool = (api: AxiosInstance): MempoolInstance => {
|
||||
const getMempool = async () => {
|
||||
const { data } = await api.get<Mempool[]>(`/mempool`);
|
||||
return data;
|
||||
};
|
||||
|
||||
const getMempoolTxids = async () => {
|
||||
const { data } = await api.get<string[]>(`/mempool/txids`);
|
||||
return data;
|
||||
};
|
||||
|
||||
const getMempoolRecent = async () => {
|
||||
const { data } = await api.get<MempoolRecent[]>(`/mempool/recent`);
|
||||
return data;
|
||||
};
|
||||
|
||||
return {
|
||||
getMempool,
|
||||
getMempoolTxids,
|
||||
getMempoolRecent,
|
||||
};
|
||||
};
|
||||
71
src/app/transactions.ts
Normal file
71
src/app/transactions.ts
Normal file
@@ -0,0 +1,71 @@
|
||||
import { AxiosInstance } from 'axios';
|
||||
import {
|
||||
Tx,
|
||||
TxStatus,
|
||||
TxMerkleProof,
|
||||
TxOutspend,
|
||||
TxInstance,
|
||||
} from '../interfaces';
|
||||
|
||||
export const useTransactions = (api: AxiosInstance): TxInstance => {
|
||||
const getTx = async (txid: string) => {
|
||||
const { data } = await api.get<Tx>(`/tx/${txid}`);
|
||||
return data;
|
||||
};
|
||||
|
||||
const getTxStatus = async (txid: string) => {
|
||||
const { data } = await api.get<TxStatus>(`/tx/${txid}/status`);
|
||||
return data;
|
||||
};
|
||||
|
||||
const getTxHex = async (txid: string) => {
|
||||
const { data } = await api.get<string>(`/tx/${txid}/hex`);
|
||||
return data;
|
||||
};
|
||||
|
||||
const getTxRaw = async (txid: string) => {
|
||||
const { data } = await api.get<string>(`/tx/${txid}/raw`);
|
||||
return data;
|
||||
};
|
||||
|
||||
const getTxMerkleBlockProof = async (txid: string) => {
|
||||
const { data } = await api.get<string>(`/tx/${txid}/merkleblock-proof`);
|
||||
return data;
|
||||
};
|
||||
|
||||
const getTxMerkleProof = async (txid: string) => {
|
||||
const { data } = await api.get<Array<TxMerkleProof>>(
|
||||
`/tx/${txid}/merkle-proof`
|
||||
);
|
||||
return data;
|
||||
};
|
||||
|
||||
const getTxOutspend = async (params: { txid: string; vout: number }) => {
|
||||
const { data } = await api.get<TxOutspend>(
|
||||
`/tx/${params.txid}/outspend/${params.vout}`
|
||||
);
|
||||
return data;
|
||||
};
|
||||
|
||||
const getTxOutspends = async (txid: string) => {
|
||||
const { data } = await api.get<Array<TxOutspend>>(`/tx/${txid}/outspends`);
|
||||
return data;
|
||||
};
|
||||
|
||||
const postTx = async (txid: string) => {
|
||||
const { data } = await api.post<string>(`/tx`, { txid: txid });
|
||||
return data;
|
||||
};
|
||||
|
||||
return {
|
||||
getTx,
|
||||
getTxStatus,
|
||||
getTxHex,
|
||||
getTxRaw,
|
||||
getTxMerkleBlockProof,
|
||||
getTxMerkleProof,
|
||||
getTxOutspend,
|
||||
getTxOutspends,
|
||||
postTx,
|
||||
};
|
||||
};
|
||||
14
src/app/websocket.ts
Normal file
14
src/app/websocket.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { WsInterface, WsInstance } from '../interfaces';
|
||||
import wsClient from '../services/wsClient';
|
||||
import wsServer from '../services/wsServer';
|
||||
|
||||
const defaultWs = 'wss://mempool.space/api/v1/ws';
|
||||
|
||||
export const useWebsocket = (websocketEndpoint?: string): WsInstance => {
|
||||
return {
|
||||
initClient: ({ options }: WsInterface) =>
|
||||
wsClient(options, defaultWs, websocketEndpoint),
|
||||
initServer: ({ options }: WsInterface) =>
|
||||
wsServer(options, defaultWs, websocketEndpoint),
|
||||
};
|
||||
};
|
||||
247
src/blocks.ts
247
src/blocks.ts
@@ -1,247 +0,0 @@
|
||||
import api from './api';
|
||||
|
||||
const getBlock = async (params: { hash: string }) => {
|
||||
return api
|
||||
.get(`/block/${params.hash}`)
|
||||
.then(
|
||||
(res: {
|
||||
data: {
|
||||
id: string;
|
||||
height: number;
|
||||
version: number;
|
||||
timestamp: number;
|
||||
tx_count: number;
|
||||
size: number;
|
||||
weight: number;
|
||||
merkle_root: string;
|
||||
previousblockhash: string;
|
||||
mediantime: number;
|
||||
nonce: number;
|
||||
bits: number;
|
||||
difficulty: number;
|
||||
};
|
||||
}) => {
|
||||
return res.data;
|
||||
}
|
||||
)
|
||||
.catch(
|
||||
(err: {
|
||||
response: {
|
||||
data: string;
|
||||
};
|
||||
}) => {
|
||||
throw err.response.data;
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const getBlockStatus = async (params: { hash: string }) => {
|
||||
return api
|
||||
.get(`/block/${params.hash}/status`)
|
||||
.then(
|
||||
(res: {
|
||||
data: {
|
||||
in_best_chain: boolean;
|
||||
height: number;
|
||||
next_best: string;
|
||||
};
|
||||
}) => {
|
||||
return res.data;
|
||||
}
|
||||
)
|
||||
.catch(
|
||||
(err: {
|
||||
response: {
|
||||
data: string;
|
||||
};
|
||||
}) => {
|
||||
throw err.response.data;
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const getBlockTxs = async (params: { hash: string; start_index?: number }) => {
|
||||
return api
|
||||
.get(`/block/${params.hash}/txs/${params.start_index}`)
|
||||
.then(
|
||||
(res: {
|
||||
data: {
|
||||
txid: string;
|
||||
version: number;
|
||||
locktime: number;
|
||||
vin: Record<string, unknown>[];
|
||||
vout: Record<string, unknown>[][];
|
||||
size: number;
|
||||
weight: number;
|
||||
fee: number;
|
||||
status: {
|
||||
confirmed: boolean;
|
||||
block_height: number;
|
||||
block_hash: string;
|
||||
block_time: number;
|
||||
};
|
||||
};
|
||||
}) => {
|
||||
return res.data;
|
||||
}
|
||||
)
|
||||
.catch(
|
||||
(err: {
|
||||
response: {
|
||||
data: string;
|
||||
};
|
||||
}) => {
|
||||
throw err.response.data;
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const getBlockTxids = async (params: { hash: string }) => {
|
||||
return api
|
||||
.get(`/block/${params.hash}/txids`)
|
||||
.then((res: { data: string[] }) => {
|
||||
return res.data;
|
||||
})
|
||||
.catch(
|
||||
(err: {
|
||||
response: {
|
||||
data: string;
|
||||
};
|
||||
}) => {
|
||||
throw err.response.data;
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const getBlockTxid = async (params: { hash: string; index: number }) => {
|
||||
return api
|
||||
.get(`/block/${params.hash}/txid/${params.index}`)
|
||||
.then((res: { data: string }) => {
|
||||
return res.data;
|
||||
})
|
||||
.catch(
|
||||
(err: {
|
||||
response: {
|
||||
data: string;
|
||||
};
|
||||
}) => {
|
||||
throw err.response.data;
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const getBlockRaw = async (params: { hash: string }) => {
|
||||
return api
|
||||
.get(`/block/${params.hash}/raw`)
|
||||
.then((res: { data: string }) => {
|
||||
return res.data;
|
||||
})
|
||||
.catch(
|
||||
(err: {
|
||||
response: {
|
||||
data: string;
|
||||
};
|
||||
}) => {
|
||||
throw err.response.data;
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const getBlockHeight = async (params: { height: number }) => {
|
||||
return api
|
||||
.get(`/block-height/${params.height}`)
|
||||
.then((res: { data: string }) => {
|
||||
return res.data;
|
||||
})
|
||||
.catch(
|
||||
(err: {
|
||||
response: {
|
||||
data: string;
|
||||
};
|
||||
}) => {
|
||||
throw err.response.data;
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const getBlocks = async (params: { start_height?: number }) => {
|
||||
return api
|
||||
.get(`/blocks/${params.start_height}`)
|
||||
.then(
|
||||
(res: {
|
||||
data: {
|
||||
id: string;
|
||||
height: number;
|
||||
version: number;
|
||||
timestamp: number;
|
||||
tx_count: number;
|
||||
size: number;
|
||||
weight: number;
|
||||
merkle_root: string;
|
||||
previousblockhash: string;
|
||||
mediantime: number;
|
||||
nonce: number;
|
||||
bits: number;
|
||||
difficulty: number;
|
||||
}[];
|
||||
}) => {
|
||||
return res.data;
|
||||
}
|
||||
)
|
||||
.catch(
|
||||
(err: {
|
||||
response: {
|
||||
data: string;
|
||||
};
|
||||
}) => {
|
||||
throw err.response.data;
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const getBlocksTipHeight = async () => {
|
||||
return api
|
||||
.get(`/blocks/tip/height`)
|
||||
.then((res: { data: number }) => {
|
||||
return res.data;
|
||||
})
|
||||
.catch(
|
||||
(err: {
|
||||
response: {
|
||||
data: string;
|
||||
};
|
||||
}) => {
|
||||
throw err.response.data;
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const getBlocksTipHash = async () => {
|
||||
return api
|
||||
.get(`/blocks/tip/hash`)
|
||||
.then((res: { data: string }) => {
|
||||
return res.data;
|
||||
})
|
||||
.catch(
|
||||
(err: {
|
||||
response: {
|
||||
data: string;
|
||||
};
|
||||
}) => {
|
||||
throw err.response.data;
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export default {
|
||||
getBlock,
|
||||
getBlocks,
|
||||
getBlockStatus,
|
||||
getBlockTxs,
|
||||
getBlockTxid,
|
||||
getBlockTxids,
|
||||
getBlockRaw,
|
||||
getBlockHeight,
|
||||
getBlocksTipHash,
|
||||
getBlocksTipHeight,
|
||||
};
|
||||
59
src/fees.ts
59
src/fees.ts
@@ -1,59 +0,0 @@
|
||||
import api from './api';
|
||||
|
||||
const getFeesRecommended = async () => {
|
||||
return await api
|
||||
.get(`/v1/fees/recommended`)
|
||||
.then(
|
||||
(res: {
|
||||
data: {
|
||||
fastestFee: number;
|
||||
halfHourFee: number;
|
||||
hourFee: number;
|
||||
};
|
||||
}) => {
|
||||
return res.data;
|
||||
}
|
||||
)
|
||||
.catch(
|
||||
(err: {
|
||||
response: {
|
||||
data: string;
|
||||
};
|
||||
}) => {
|
||||
throw err.response.data;
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const getFeesMempoolBlocks = async () => {
|
||||
return await api
|
||||
.get(`/v1/fees/mempool-blocks`)
|
||||
.then(
|
||||
(res: {
|
||||
data: {
|
||||
blockSize: number;
|
||||
blockVSize: number;
|
||||
nTx: number;
|
||||
totalFees: number;
|
||||
medianFee: number;
|
||||
feeRange: number[];
|
||||
}[];
|
||||
}) => {
|
||||
return res.data;
|
||||
}
|
||||
)
|
||||
.catch(
|
||||
(err: {
|
||||
response: {
|
||||
data: string;
|
||||
};
|
||||
}) => {
|
||||
throw err.response.data;
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export default {
|
||||
getFeesRecommended,
|
||||
getFeesMempoolBlocks,
|
||||
};
|
||||
49
src/index.ts
49
src/index.ts
@@ -1,22 +1,33 @@
|
||||
import fees from './fees';
|
||||
import mempool from './mempool';
|
||||
import blocks from './blocks';
|
||||
import transactions from './transactions';
|
||||
import addresses from './addresses';
|
||||
import websocket from './websocket';
|
||||
import { MempoolConfig, MempoolReturn } from './interfaces';
|
||||
import { makeAPI } from './services/api';
|
||||
|
||||
export { default as fees } from './fees';
|
||||
export { default as mempool } from './mempool';
|
||||
export { default as blocks } from './blocks';
|
||||
export { default as transactions } from './transactions';
|
||||
export { default as addresses } from './addresses';
|
||||
export { default as websocket } from './websocket';
|
||||
import { useAddresses } from './app/addresses';
|
||||
import { useBlocks } from './app/blocks';
|
||||
import { useFees } from './app/fees';
|
||||
import { useMempool } from './app/mempool';
|
||||
import { useTransactions } from './app/transactions';
|
||||
import { useWebsocket } from './app/websocket';
|
||||
|
||||
export default {
|
||||
fees,
|
||||
mempool,
|
||||
blocks,
|
||||
transactions,
|
||||
addresses,
|
||||
websocket,
|
||||
const apiEndpointDefault = 'https://mempool.space/api/';
|
||||
const websocketEndpointDefault = 'wss://mempool.space/api/v1/ws';
|
||||
|
||||
const mempool = (
|
||||
{ apiEndpoint, websocketEndpoint }: MempoolConfig = {
|
||||
apiEndpoint: apiEndpointDefault,
|
||||
websocketEndpoint: websocketEndpointDefault,
|
||||
}
|
||||
): MempoolReturn => {
|
||||
const { api } = makeAPI(apiEndpoint);
|
||||
|
||||
return {
|
||||
addresses: useAddresses(api),
|
||||
blocks: useBlocks(api),
|
||||
fees: useFees(api),
|
||||
mempool: useMempool(api),
|
||||
transactions: useTransactions(api),
|
||||
websocket: useWebsocket(websocketEndpoint),
|
||||
};
|
||||
};
|
||||
|
||||
mempool.default = mempool;
|
||||
export = mempool;
|
||||
|
||||
213
src/interfaces.ts
Normal file
213
src/interfaces.ts
Normal file
@@ -0,0 +1,213 @@
|
||||
import WebSocketServer from 'ws';
|
||||
export interface Address {
|
||||
address: string;
|
||||
chain_stats: {
|
||||
funded_txo_count: number;
|
||||
funded_txo_sum: number;
|
||||
spent_txo_count: number;
|
||||
spent_txo_sum: number;
|
||||
tx_count: number;
|
||||
};
|
||||
mempool_stats: {
|
||||
funded_txo_count: number;
|
||||
funded_txo_sum: number;
|
||||
spent_txo_count: number;
|
||||
spent_txo_sum: number;
|
||||
tx_count: number;
|
||||
};
|
||||
}
|
||||
|
||||
export interface AddressInstance {
|
||||
getAddress: (address: string) => Promise<Address>;
|
||||
getAddressTxs: (address: string) => Promise<Tx[]>;
|
||||
getAddressTxsChain: (address: string) => Promise<Tx[]>;
|
||||
getAddressTxsMempool: (address: string) => Promise<Tx[]>;
|
||||
getAddressTxsUtxo: (address: string) => Promise<AddressTxsUtxo[]>;
|
||||
}
|
||||
|
||||
export interface AddressTxsUtxo {
|
||||
txid: string;
|
||||
vout: number;
|
||||
status: {
|
||||
confirmed: boolean;
|
||||
block_height: number;
|
||||
block_hash: string;
|
||||
block_time: number;
|
||||
};
|
||||
value: number;
|
||||
}
|
||||
export interface Block {
|
||||
id: string;
|
||||
height: number;
|
||||
version: number;
|
||||
timestamp: number;
|
||||
tx_count: number;
|
||||
size: number;
|
||||
weight: number;
|
||||
merkle_root: string;
|
||||
previousblockhash: string;
|
||||
mediantime: number;
|
||||
nonce: number;
|
||||
bits: number;
|
||||
difficulty: number;
|
||||
}
|
||||
|
||||
export interface BlockInstance {
|
||||
getBlock: (hash: string) => Promise<Block>;
|
||||
getBlocks: (params: { start_height?: number }) => Promise<Block>;
|
||||
getBlockStatus: (hash: string) => Promise<BlockStatus>;
|
||||
getBlockTxs: (params: { hash: string; start_index?: number }) => Promise<Tx>;
|
||||
getBlockTxids: (hash: string) => Promise<string[]>;
|
||||
getBlockTxid: (params: { hash: string; index: number }) => Promise<string>;
|
||||
getBlockRaw: (hash: string) => Promise<string>;
|
||||
getBlockHeight: (height: number) => Promise<string>;
|
||||
getBlocksTipHeight: () => Promise<number>;
|
||||
getBlocksTipHash: () => Promise<string>;
|
||||
}
|
||||
|
||||
export interface BlockStatus {
|
||||
in_best_chain: boolean;
|
||||
height: number;
|
||||
next_best: string;
|
||||
}
|
||||
|
||||
export interface FeeInstance {
|
||||
getFeesRecommended: () => Promise<FeesRecommended>;
|
||||
getFeesMempoolBlocks: () => Promise<FeesMempoolBlocks[]>;
|
||||
}
|
||||
|
||||
export interface FeesMempoolBlocks {
|
||||
blockSize: number;
|
||||
blockVSize: number;
|
||||
nTx: number;
|
||||
totalFees: number;
|
||||
medianFee: number;
|
||||
feeRange: number[];
|
||||
}
|
||||
|
||||
export interface FeesRecommended {
|
||||
fastestFee: number;
|
||||
halfHourFee: number;
|
||||
hourFee: number;
|
||||
minimumFee: number;
|
||||
}
|
||||
|
||||
export interface Mempool {
|
||||
count: number;
|
||||
vsize: number;
|
||||
total_fee: number;
|
||||
fee_histogram: number[];
|
||||
}
|
||||
|
||||
export interface MempoolConfig {
|
||||
apiEndpoint?: string;
|
||||
websocketEndpoint?: string;
|
||||
}
|
||||
|
||||
export interface MempoolInstance {
|
||||
getMempool: () => Promise<Mempool[]>;
|
||||
getMempoolTxids: () => Promise<string[]>;
|
||||
getMempoolRecent: () => Promise<MempoolRecent[]>;
|
||||
}
|
||||
|
||||
export interface MempoolReturn {
|
||||
addresses: AddressInstance;
|
||||
blocks: BlockInstance;
|
||||
fees: FeeInstance;
|
||||
mempool: MempoolInstance;
|
||||
transactions: TxInstance;
|
||||
websocket: WsInstance;
|
||||
}
|
||||
|
||||
export interface MempoolRecent {
|
||||
txid: string;
|
||||
fee: number;
|
||||
vsize: number;
|
||||
value: number;
|
||||
}
|
||||
|
||||
export interface Tx {
|
||||
txid: string;
|
||||
version: number;
|
||||
locktime: number;
|
||||
vin: {
|
||||
txid: string;
|
||||
vout: number;
|
||||
prevout: {
|
||||
scriptpubkey: string;
|
||||
scriptpubkey_asm: string;
|
||||
scriptpubkey_type: string;
|
||||
scriptpubkey_address: string;
|
||||
value: number;
|
||||
};
|
||||
scriptsig: string;
|
||||
scriptsig_asm: string;
|
||||
is_coinbase: boolean;
|
||||
sequence: string;
|
||||
}[];
|
||||
vout: {
|
||||
scriptpubkey: string;
|
||||
scriptpubkey_asm: string;
|
||||
scriptpubkey_type: string;
|
||||
scriptpubkey_address: string;
|
||||
value: number;
|
||||
}[];
|
||||
size: number;
|
||||
weight: number;
|
||||
fee: number;
|
||||
status: {
|
||||
confirmed: boolean;
|
||||
block_height: number;
|
||||
block_hash: string;
|
||||
block_time: number;
|
||||
};
|
||||
}
|
||||
|
||||
export interface TxStatus {
|
||||
confirmed: boolean;
|
||||
block_height: number;
|
||||
block_hash: string;
|
||||
block_time: number;
|
||||
}
|
||||
|
||||
export interface TxMerkleProof {
|
||||
block_height: number;
|
||||
merkle: string[];
|
||||
pos: number;
|
||||
}
|
||||
|
||||
export interface TxOutspend {
|
||||
spent: boolean;
|
||||
txid: string;
|
||||
vin: number;
|
||||
status: {
|
||||
confirmed: boolean;
|
||||
block_height: number;
|
||||
block_hash: string;
|
||||
block_time: number;
|
||||
};
|
||||
}
|
||||
|
||||
export interface TxInstance {
|
||||
getTx: (txid: string) => Promise<Tx>;
|
||||
getTxStatus: (txid: string) => Promise<TxStatus>;
|
||||
getTxHex: (txid: string) => Promise<string>;
|
||||
getTxRaw: (txid: string) => Promise<string>;
|
||||
getTxMerkleBlockProof: (txid: string) => Promise<string>;
|
||||
getTxMerkleProof: (txid: string) => Promise<Array<TxMerkleProof>>;
|
||||
getTxOutspend: (params: {
|
||||
txid: string;
|
||||
vout: number;
|
||||
}) => Promise<TxOutspend>;
|
||||
getTxOutspends: (txid: string) => Promise<Array<TxOutspend>>;
|
||||
postTx: (txid: string) => Promise<unknown>;
|
||||
}
|
||||
|
||||
export interface WsInterface {
|
||||
options: string[];
|
||||
}
|
||||
|
||||
export interface WsInstance {
|
||||
initClient: ({ options }: WsInterface) => WebSocket;
|
||||
initServer: ({ options }: WsInterface) => WebSocketServer;
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
import api from './api';
|
||||
|
||||
const getMempool = async () => {
|
||||
return api
|
||||
.get(`/mempool`)
|
||||
.then(
|
||||
(res: {
|
||||
data: {
|
||||
count: number;
|
||||
vsize: number;
|
||||
total_fee: number;
|
||||
fee_histogram: number[];
|
||||
}[];
|
||||
}) => {
|
||||
return res.data;
|
||||
}
|
||||
)
|
||||
.catch(
|
||||
(err: {
|
||||
response: {
|
||||
data: string;
|
||||
};
|
||||
}) => {
|
||||
throw err.response.data;
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const getMempoolTxids = async () => {
|
||||
return api
|
||||
.get(`/mempool/txids`)
|
||||
.then((res: { data: string[] }) => {
|
||||
return res.data;
|
||||
})
|
||||
.catch(
|
||||
(err: {
|
||||
response: {
|
||||
data: string;
|
||||
};
|
||||
}) => {
|
||||
throw err.response.data;
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const getMempoolRecent = async () => {
|
||||
return api
|
||||
.get(`/mempool/recent`)
|
||||
.then(
|
||||
(res: {
|
||||
data: {
|
||||
txid: string;
|
||||
fee: number;
|
||||
vsize: number;
|
||||
value: number;
|
||||
}[];
|
||||
}) => {
|
||||
return res.data;
|
||||
}
|
||||
)
|
||||
.catch(
|
||||
(err: {
|
||||
response: {
|
||||
data: string;
|
||||
};
|
||||
}) => {
|
||||
throw err.response.data;
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export default {
|
||||
getMempool,
|
||||
getMempoolTxids,
|
||||
getMempoolRecent,
|
||||
};
|
||||
10
src/services/api.ts
Normal file
10
src/services/api.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import axios, { AxiosInstance } from 'axios';
|
||||
|
||||
export const makeAPI = (apiEndpoint?: string): { api: AxiosInstance } => {
|
||||
const api = axios.create({
|
||||
baseURL: apiEndpoint,
|
||||
});
|
||||
return {
|
||||
api,
|
||||
};
|
||||
};
|
||||
25
src/services/wsClient.ts
Normal file
25
src/services/wsClient.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
const browserWS = (
|
||||
options: string[],
|
||||
defaultWs: string,
|
||||
websocketEndpoint?: string
|
||||
): WebSocket => {
|
||||
const ws = new WebSocket(websocketEndpoint || defaultWs);
|
||||
ws.addEventListener('open', function open() {
|
||||
handleMessage(ws, options);
|
||||
});
|
||||
return ws;
|
||||
};
|
||||
|
||||
const handleMessage = (ws: WebSocket, options: string[]) => {
|
||||
ws.send(JSON.stringify({ action: 'init' }));
|
||||
setInterval(function timeout() {
|
||||
ws.send(
|
||||
JSON.stringify({
|
||||
action: 'want',
|
||||
data: options,
|
||||
})
|
||||
);
|
||||
}, 500);
|
||||
};
|
||||
|
||||
export default browserWS;
|
||||
26
src/services/wsServer.ts
Normal file
26
src/services/wsServer.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import WebSocket from 'ws';
|
||||
|
||||
const serverWS = (
|
||||
options: string[],
|
||||
defaultWs: string,
|
||||
websocketEndpoint?: string
|
||||
): WebSocket => {
|
||||
const ws = new WebSocket(websocketEndpoint || defaultWs);
|
||||
ws.on('open', function open() {
|
||||
handleMessage(ws, options);
|
||||
});
|
||||
return ws;
|
||||
};
|
||||
|
||||
const handleMessage = (ws: WebSocket, options: string[]) => {
|
||||
ws.send(JSON.stringify({ action: 'init' }));
|
||||
setInterval(function timeout() {
|
||||
ws.send(
|
||||
JSON.stringify({
|
||||
action: 'want',
|
||||
data: options,
|
||||
})
|
||||
);
|
||||
}, 500);
|
||||
};
|
||||
export default serverWS;
|
||||
@@ -1,250 +0,0 @@
|
||||
import api from './api';
|
||||
|
||||
const getTx = async (params: { txid: string }) => {
|
||||
return api
|
||||
.get(`/tx/${params.txid}`)
|
||||
.then(
|
||||
(res: {
|
||||
data: {
|
||||
txid: string;
|
||||
version: number;
|
||||
locktime: number;
|
||||
vin: {
|
||||
txid: string;
|
||||
vout: number;
|
||||
prevout: {
|
||||
scriptpubkey: string;
|
||||
scriptpubkey_asm: string;
|
||||
scriptpubkey_type: string;
|
||||
scriptpubkey_address: string;
|
||||
value: number;
|
||||
};
|
||||
scriptsig: string;
|
||||
scriptsig_asm: string;
|
||||
is_coinbase: boolean;
|
||||
sequence: string;
|
||||
}[];
|
||||
vout: {
|
||||
scriptpubkey: string;
|
||||
scriptpubkey_asm: string;
|
||||
scriptpubkey_type: string;
|
||||
scriptpubkey_address: string;
|
||||
value: number;
|
||||
}[];
|
||||
size: number;
|
||||
weight: number;
|
||||
fee: number;
|
||||
status: {
|
||||
confirmed: boolean;
|
||||
block_height: number;
|
||||
block_hash: string;
|
||||
block_time: number;
|
||||
};
|
||||
};
|
||||
}) => {
|
||||
return res.data;
|
||||
}
|
||||
)
|
||||
.catch(
|
||||
(err: {
|
||||
response: {
|
||||
data: string;
|
||||
};
|
||||
}) => {
|
||||
throw err.response.data;
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const getTxStatus = async (params: { txid: string }) => {
|
||||
return api
|
||||
.get(`/tx/${params.txid}/status`)
|
||||
.then(
|
||||
(res: {
|
||||
data: {
|
||||
confirmed: boolean;
|
||||
block_height: number;
|
||||
block_hash: string;
|
||||
block_time: number;
|
||||
};
|
||||
}) => {
|
||||
return res.data;
|
||||
}
|
||||
)
|
||||
.catch(
|
||||
(err: {
|
||||
response: {
|
||||
data: string;
|
||||
};
|
||||
}) => {
|
||||
throw err.response.data;
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const getTxHex = async (params: { txid: string }) => {
|
||||
return api
|
||||
.get(`/tx/${params.txid}/hex`)
|
||||
.then((res: { data: string }) => {
|
||||
return res.data;
|
||||
})
|
||||
.catch(
|
||||
(err: {
|
||||
response: {
|
||||
data: string;
|
||||
};
|
||||
}) => {
|
||||
throw err.response.data;
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const getTxRaw = async (params: { txid: string }) => {
|
||||
return api
|
||||
.get(`/tx/${params.txid}/raw`)
|
||||
.then((res: { data: string }) => {
|
||||
return res.data;
|
||||
})
|
||||
.catch(
|
||||
(err: {
|
||||
response: {
|
||||
data: string;
|
||||
};
|
||||
}) => {
|
||||
throw err.response.data;
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const getTxMerkleBlockProof = async (params: { txid: string }) => {
|
||||
return api
|
||||
.get(`/tx/${params.txid}/merkleblock-proof`)
|
||||
.then((res: { data: string }) => {
|
||||
return res.data;
|
||||
})
|
||||
.catch(
|
||||
(err: {
|
||||
response: {
|
||||
data: string;
|
||||
};
|
||||
}) => {
|
||||
throw err.response.data;
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const getTxMerkleProof = async (params: { txid: string }) => {
|
||||
return api
|
||||
.get(`/tx/${params.txid}/merkle-proof`)
|
||||
.then(
|
||||
(res: {
|
||||
data: {
|
||||
block_height: number;
|
||||
merkle: string[];
|
||||
pos: number;
|
||||
}[];
|
||||
}) => {
|
||||
return res.data;
|
||||
}
|
||||
)
|
||||
.catch(
|
||||
(err: {
|
||||
response: {
|
||||
data: string;
|
||||
};
|
||||
}) => {
|
||||
throw err.response.data;
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const getTxOutspend = async (params: { txid: string; vout: number }) => {
|
||||
return api
|
||||
.get(`/tx/${params.txid}/outspend/${params.vout}`)
|
||||
.then(
|
||||
(res: {
|
||||
data: {
|
||||
spent: boolean;
|
||||
txid: string;
|
||||
vin: number;
|
||||
status: {
|
||||
confirmed: boolean;
|
||||
block_height: number;
|
||||
block_hash: string;
|
||||
block_time: number;
|
||||
};
|
||||
};
|
||||
}) => {
|
||||
return res.data;
|
||||
}
|
||||
)
|
||||
.catch(
|
||||
(err: {
|
||||
response: {
|
||||
data: string;
|
||||
};
|
||||
}) => {
|
||||
throw err.response.data;
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const getTxOutspends = async (params: { txid: string }) => {
|
||||
return api
|
||||
.get(`/tx/${params.txid}/outspends`)
|
||||
.then(
|
||||
(res: {
|
||||
data: {
|
||||
spent: boolean;
|
||||
txid: string;
|
||||
vin: number;
|
||||
status: {
|
||||
confirmed: boolean;
|
||||
block_height: number;
|
||||
block_hash: string;
|
||||
block_time: number;
|
||||
};
|
||||
}[];
|
||||
}) => {
|
||||
return res.data;
|
||||
}
|
||||
)
|
||||
.catch(
|
||||
(err: {
|
||||
response: {
|
||||
data: string;
|
||||
};
|
||||
}) => {
|
||||
throw err.response.data;
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const postTx = async (params: { txid: string }) => {
|
||||
return api
|
||||
.post(`/tx`, { txid: params.txid })
|
||||
.then((res: { data: any }) => {
|
||||
return res.data;
|
||||
})
|
||||
.catch(
|
||||
(err: {
|
||||
response: {
|
||||
data: string;
|
||||
};
|
||||
}) => {
|
||||
throw err.response.data;
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export default {
|
||||
getTx,
|
||||
getTxStatus,
|
||||
getTxHex,
|
||||
getTxRaw,
|
||||
getTxMerkleBlockProof,
|
||||
getTxMerkleProof,
|
||||
getTxOutspend,
|
||||
getTxOutspends,
|
||||
postTx,
|
||||
};
|
||||
@@ -1,22 +0,0 @@
|
||||
const WebSocket = require('ws');
|
||||
|
||||
const ws = new WebSocket('wss://mempool.space/api/v1/ws');
|
||||
|
||||
const init = (params: { options: string[] }) => {
|
||||
ws.on('open', function open() {
|
||||
ws.send(JSON.stringify({ action: 'init' }));
|
||||
setInterval(function timeout() {
|
||||
ws.send(
|
||||
JSON.stringify({
|
||||
action: 'want',
|
||||
data: params.options,
|
||||
})
|
||||
);
|
||||
}, 500);
|
||||
});
|
||||
return ws;
|
||||
};
|
||||
|
||||
export default {
|
||||
init,
|
||||
};
|
||||
Reference in New Issue
Block a user