View your aggregated cryptocurrency portfolio automagically, no matter where the assets are located:
- ✅ Exchanges
- ✅ ETH wallets
- ✅ Anywhere else, no problem!
- ⭕️ Polkadot parachains (soon)
- ⭕️ BSC & HECO (someday)
As a crypto trader pro, I have long been struggling with tracking all my tokens in a unified way, since they locate in so many different places: Binance, Huobi, Coinbase, FTX, ETH hot/cold wallets, BTC wallets, BSC, HECO, ICOs, mining machines... 🤯
If you are facing similar issues, this is for you. 🎉
I made this tool for every crypto lover ❤️, like you and I, to manage all assets more conveniently. So we can be more focused on making wise trading decisions. 🥳
$ yarn add crypto-portfolio-viewer
$ npm install crypto-portfolio-viewer --save
/* ----- CommonJS ----- */
const {
getPortfolio,
printPortfolioNicely, // optional
} = require('crypto-portfolio-viewer');
/* ----- ES modules ----- */
import {
getPortfolio,
printPortfolioNicely, // optional
} from 'crypto-portfolio-viewer';
we can easily view all ETH and ERC20 tokens using ETH addresses.
const addresses = [
'0x0000000000000000000000000000000000011111',
'0x00000000000000000000000000000000000fffff',
// ......
];
(async () => {
const portfolio = await getPortfolio({ addresses });
printPortfolioNicely(portfolio);
})();
we can easily view all exchanges assets using exchange api keys. Exchange namings please refer to ccxt.
const keys = {
binance: {
apiKey: "xxxxxxxxxx",
secret: "yyyyyyyyyy"
},
ftx: {
apiKey: "aaaaaaaaaa",
secret: "bbbbbbbbbb",
},
// ......
};
(async () => {
const portfolio = await getPortfolio({ keys });
printPortfolioNicely(portfolio);
})();
we can easily view any other assets by hard coding their counts.
const othertokens = {
"BTC": [8.5], // in mysterious wallet
"BNB": [200], // in BSC
"ETH": [10, 30], // uni-LP, sushi-LP
"USDT": [
1000, // borrowed by Alex
2000, // borrowed by Kate
5000, // my mining machine's value
],
// ......
};
(async () => {
const portfolio = await getPortfolio({ othertokens });
printPortfolioNicely(portfolio);
})();
Being able to aggregate all assets is the soul of a portfolio viewer.
-- Aristotélēs
we can easily view all of our assets across many different places, by combining the usages above.
const keys = {
binance: {
apiKey: "xxxxxxxxxx",
secret: "yyyyyyyyyy"
},
ftx: {
apiKey: "aaaaaaaaaa",
secret: "bbbbbbbbbb",
},
};
const addresses = [
'0x0000000000000000000000000000000000011111',
'0x00000000000000000000000000000000000fffff',
];
const othertokens = {
"BTC": [8.5], // in cold wallet
"BNB": [200], // in BSC
"ETH": [10, 30], // uni-LP, sushi-LP
"USDT": [
1000, // borrowed by Alex
2000, // borrowed by Kate
5000, // my mining machine's value
],
};
(async () => {
const portfolio = await getPortfolio({
keys,
addresses,
othertokens,
});
printPortfolioNicely(portfolio);
})();
$ node getPortfolio.js
started to fetch portfolio data ...
(1/5) fetching exchange token counts ...
(2/5) fetching ERC20 token counts ...
(3/5) fetching other token counts ...
(4/5) fetching all token prices ...
(5/5) calculating all token values ...
finished!! Let's go Bitcoin!!
----------------------------------------------------------
₿ Binance tokens ₿
----------------------------------------------------------
| name | USD value | ratio | BTC value | price | count |
|-------|-----------|-------|-----------|--------|-------|
| TOTAL | $25000 | 100% | ₿2.5 | $0 | 0 |
| BTC | $10000 | 40% | ₿1 | $10000 | 1 |
| ETH | $10000 | 40% | ₿1 | $1000 | 10 |
| BNB | $5000 | 20% | ₿0.5 | $100 | 50 |
----------------------------------------------------------
₿ FTX tokens ₿
----------------------------------------------------------
| name | USD value | ratio | BTC value | price | count |
|-------|-----------|-------|-----------|--------|-------|
| TOTAL | $15000 | 100% | ₿1.5 | $0 | 0 |
| BTC | $10000 | 66% | ₿1 | $10000 | 1 |
| ATOM | $10000 | 66% | ₿1 | $20 | 500 |
| USDT | $-5000 | -33% | ₿-0.5 | $1 | -5000 |
// negative value means borrowed from contract or margin
// this can be disabled or customized
----------------------------------------------------------
₿ ETH + ERC20 tokens ₿
----------------------------------------------------------
| name | USD value | ratio | BTC value | price | count |
|-------|-----------|-------|-----------|--------|-------|
| TOTAL | $30000 | 100% | ₿2 | $0 | 0 |
| UNI | $20000 | 66% | ₿2 | $50 | 400 |
| ETH | $10000 | 33% | ₿1 | $1000 | 10 |
----------------------------------------------------------
₿ other tokens ₿
----------------------------------------------------------
| name | USD value | ratio | BTC value | price | count |
|-------|-----------|-------|-----------|--------|-------|
| TOTAL | $50000 | 100% | ₿5 | $0 | 0 |
| DOT | $30000 | 60% | ₿3 | $100 | 300 |
| KSM | $20000 | 40% | ₿2 | $1000 | 20 |
----------------------------------------------------------
₿ all tokens ₿
----------------------------------------------------------
| name | USD value | ratio | BTC value | price | count |
|-------|-----------|-------|-----------|--------|-------|
| TOTAL | $120000 | 100% | ₿12 | $0 | 0 |
| DOT | $30000 | 25% | ₿3 | $100 | 300 |
| KSM | $20000 | 16.7% | ₿2 | $1000 | 20 |
| UNI | $20000 | 16.7% | ₿2 | $50 | 400 |
| BTC | $20000 | 16.7% | ₿2 | $10000 | 2 |
| ETH | $20000 | 16.7% | ₿2 | $1000 | 20 |
| ATOM | $10000 | 8.3% | ₿1 | $20 | 500 |
| BNB | $5000 | 4.1% | ₿0.5 | $100 | 50 |
| USDT | $-5000 | -4.1% | ₿-0.5 | $1 | -5000 |
Viewing result nicely is the soul of a portfolio viewer.
--Shakespeare
we can easily print the result in your favorite fashion:
const myFavoritePrinter = portfolio => { ... };
(async () => {
const portfolio = await getPortfolio({
keys,
addresses,
othertokens,
});
myFavoritePrinter(portfolio);
})();
by default we view each exchange and each ETH address separately:
----------------------------------------------------------
₿ Binance tokens ₿
----------------------------------------------------------
......
----------------------------------------------------------
₿ FTX tokens ₿
----------------------------------------------------------
......
----------------------------------------------------------
₿ 0x1234...5678 tokens ₿
----------------------------------------------------------
......
----------------------------------------------------------
₿ 0x9876...5432 tokens ₿
----------------------------------------------------------
to simplify our portfolio, we can combine them as a whole
(async () => {
const portfolio = await getPortfolio({
keys,
addresses,
othertokens,
combineExchanges: true, // <--here!
combineAddresses: true, // <--here!
});
printPortfolioNicely(portfolio);
})();
----------------------------------------------------------
₿ exchange tokens ₿
----------------------------------------------------------
all exchange tokens combined print here ......
----------------------------------------------------------
₿ ETH tokens ₿
----------------------------------------------------------
all ETH + ERC20 tokens combined print here ......
For contract/future/margin assets in exchanges, since the ccxt
library that we rely on doesn't yet provide unified interfaces for these accounts, there is no automatted way to catch them into the exchange result.
But don't worry, we have 2 different ways to inlcude them into our portfolio:
We can hard code these assets in othertokens
. (see example above)
This is pretty convenient, but we will have to manually update othertokens
whenever assets change in future accounts.
We can also provide a custom fetcher
for each exchange, or call it adapter
if you prefer.
This is more flexible and powerful. One huge advantage is being able to include contract positions as assets, which I personally use A LOT!! 🥰. It enables us to more precisely calculate portfolio details.
For example, if we have 1000 USDT collateral
, as well as a contract position of BTC long (2000 USDT worth)
, then technically our 'real' portfolio should look like
{
BTC: { USD_value: 2000, ... }, // longed
USDT: { USD_value: -1000, ... }, // 1000 (collateral) - 2000 (borrowed)
TOTAL: { USD_value: 1000, ... }, // net worth
}
with method 1 (hard code), on the other hand, our 'fake' portfolio looks like
{
BTC: { USD_value: 0, ... }, // totally ignores contract positions!
USDT: { USD_value: 1000, ... }, // 1000 (collateral)
TOTAL: { USD_value: 1000, ... }, // net worth
}
There are already 2 fetchers that I personally use, feel free to use them directly if you happen to use these exchanges : )
You can also reference them to write your own, or even better, contribute your custom fetchers : )
const {
getPortfolio,
printPortfolioNicely,
fetchers,
} = require('./crypto-portfolio-viewer');
const {
fetchBinanceContractBalances,
fetchFTXContractBalances,
} = fetchers;
(async () => {
const portfolio = await getPortfolio({
keys,
addresses,
othertokens,
extraFetchers: { // <--here!
binance: fetchBinanceContractBalances,
ftx: fetchFTXContractBalances,,
},
});
printPortfolioNicely(portfolio);
})();
Currently we don't support automatically "decode" LP tokens to their real values, to track these assets, please hard code them in other tokens.
LP tokens' "decoding" might be implemented in the future : )
available parameters for getPortfolio()
:
param | type | default | required? | description |
---|---|---|---|---|
keys | object | {} | no | exchange api keys |
addresses | array | [] | no | erc20 addresses |
othertokens | object | {} | no | other tokens |
extraFetchers | object | {} | no | customized fetcher for exchanges |
combineExchanges | bool | false | no | combine exchange assets in result |
combineAddresses | bool | false | no | combine erc20 assets in result |
verbose | bool | true | no | you know it |
Feel free to open an issue, or create a pull request!
Really appreciate all the fantastic works by ccxt and coingecko-api, which provide super useful utilities supporting this library.
�coming soon