zash-sdk
================
<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->
Delightful, ergonomic blockchain data SDK built for data scientist, ML
engineers and data analysts. Wrangle and explore transactions under a
minute.
## Install
``` sh
pip install zash-sdk
```
## Quickstart
### Authentication
Get your credentials from [zash.sh](https://zash.sh)
``` python
from zash_sdk.zash import Zash
zash = Zash('your_username', 'your_api_key')
```
Authenticated!
### Accessing NFT collection trades
Grab all Bored Ape trades in x2y2 since yesterday (contract address
[here](https://etherscan.io/address/0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d)):
``` python
bayc = zash.nft('eth').collection('0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D')
```
``` python
trades_df = bayc.trades('yesterday')
trades_df.query("marketplace_name == 'x2y2'").head()
```
<div>
<style scoped>
.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
</style>
<table border="1" class="dataframe">
<thead>
<tr style="text-align: right;">
<th></th>
<th>id</th>
<th>hash</th>
<th>buyer</th>
<th>seller</th>
<th>collection_address</th>
<th>token_id</th>
<th>marketplace_address</th>
<th>marketplace_name</th>
<th>price</th>
<th>currency</th>
<th>block_hash</th>
<th>block_number</th>
<th>mint</th>
<th>bundle</th>
<th>timestamp</th>
<th>updated_at</th>
</tr>
</thead>
<tbody>
<tr>
<th>19</th>
<td>e80e354c-e3d8-3538-9788-817693f55783</td>
<td>0x6a7d16abd0b13522a99c5879f2e62ae66c15d91e4be7...</td>
<td>0xbdBa56dac0C99FA9A020045D9ccc774Ed2489558</td>
<td>0xed2ab4948bA6A909a7751DEc4F34f303eB8c7236</td>
<td>0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D</td>
<td>7369</td>
<td>0x74312363e45DCaBA76c59ec49a7Aa8A65a67EeD3</td>
<td>x2y2</td>
<td>69.000000</td>
<td>ETH</td>
<td>0x1407e979138ab4e4cff899a25c735b587279898edb59...</td>
<td>15490769</td>
<td>False</td>
<td>False</td>
<td>1662560018</td>
<td>2022-09-07 14:16:27</td>
</tr>
<tr>
<th>68</th>
<td>3a018278-681f-31e9-815f-97694ea9e48f</td>
<td>0x14f6f7698fe763c61ebb146d047fdc70973bb8f2a1d9...</td>
<td>0xed2ab4948bA6A909a7751DEc4F34f303eB8c7236</td>
<td>0x70219c18604DebF89379d566a622BDe2c5bc7621</td>
<td>0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D</td>
<td>4788</td>
<td>0x74312363e45DCaBA76c59ec49a7Aa8A65a67EeD3</td>
<td>x2y2</td>
<td>67.670000</td>
<td>WETH</td>
<td>0xd07c225d1ad934f6544114734392ebe9e767388ae80a...</td>
<td>15493679</td>
<td>False</td>
<td>False</td>
<td>1662600397</td>
<td>2022-09-08 01:31:10</td>
</tr>
<tr>
<th>78</th>
<td>2b2da6c2-717d-3d7c-87d0-af205258adec</td>
<td>0xeb23a4aa54a9b26bb6c1e50c9a4f5608572a5029f4d3...</td>
<td>0xed2ab4948bA6A909a7751DEc4F34f303eB8c7236</td>
<td>0xDa6391FB338F155a5b1036b9f5F7D19F4076779E</td>
<td>0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D</td>
<td>3277</td>
<td>0x74312363e45DCaBA76c59ec49a7Aa8A65a67EeD3</td>
<td>x2y2</td>
<td>67.273004</td>
<td>WETH</td>
<td>0x32f058cb9aca9f92629ee47414a70a8a865dc6fde22b...</td>
<td>15493761</td>
<td>False</td>
<td>False</td>
<td>1662601462</td>
<td>2022-09-08 01:46:13</td>
</tr>
</tbody>
</table>
</div>
A closer look at a trade:
``` python
trade = trades_df.query("marketplace_name == 'x2y2'").head(1).squeeze()
trade
```
id e80e354c-e3d8-3538-9788-817693f55783
hash 0x6a7d16abd0b13522a99c5879f2e62ae66c15d91e4be7...
buyer 0xbdBa56dac0C99FA9A020045D9ccc774Ed2489558
seller 0xed2ab4948bA6A909a7751DEc4F34f303eB8c7236
collection_address 0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D
token_id 7369
marketplace_address 0x74312363e45DCaBA76c59ec49a7Aa8A65a67EeD3
marketplace_name x2y2
price 69.0
currency ETH
block_hash 0x1407e979138ab4e4cff899a25c735b587279898edb59...
block_number 15490769
mint False
bundle False
timestamp 1662560018
updated_at 2022-09-07 14:16:27
Name: 19, dtype: object
``` python
# You can check out the transaction on etherscan:
!echo https://etherscan.io/tx/{trade['hash']}
```
https://etherscan.io/tx/0x6a7d16abd0b13522a99c5879f2e62ae66c15d91e4be7caa745c5bf0b0b2c3031
### Simple marketplace comparison
You can get near-real time view of a chain in a single line:
``` python
last_hour_trades = zash.nft('eth').trades('1 hour ago')
```
[`NFT.trades`](https://zashdev.github.io/nft.html#nft.trades) accepts
time ranges or shortcuts such as “yesterday” or “today”.
``` python
# offmarket marketplaces are labelled as -
last_hour_trades\
.query('marketplace_name != "-"')\
.groupby('marketplace_name')\
.agg({"price":'sum'})\
.sort_values('price', ascending=False)\
.plot(kind='bar', ylabel='price_in_eth', legend=False)
```
<AxesSubplot:xlabel='marketplace_name', ylabel='price_in_eth'>
![](index_files/figure-gfm/cell-8-output-2.png)
## Example: Deep dive on BNB
In this example, we’ll show you can go from a macro view to a micro one,
from marketplaces all the way to the tokens.
Let’s look at BNB chain this time, across all marketplaces:
``` python
bnb = zash.nft('bnb')
trades = bnb.trades('1 hour ago')
```
Off-market trades are market with “-” in marketplace names, you can
filter them out as such:
``` python
marketplace_trades = trades.query('marketplace_name != "-"')
```
``` python
marketplace_trades.groupby('marketplace_name').agg({"price":'sum'}).plot(kind='bar')
```
<AxesSubplot:xlabel='marketplace_name'>
![](index_files/figure-gfm/cell-11-output-2.png)
From here we see Element has the highest volume, can do a drill on this
to find out the top collections:
``` python
top = marketplace_trades.query("marketplace_name == 'element'")\
.groupby('collection_address')\
.sum('price')[['price']]\
.sort_values('price', ascending=False)
top
```
<div>
<style scoped>
.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
</style>
<table border="1" class="dataframe">
<thead>
<tr style="text-align: right;">
<th></th>
<th>price</th>
</tr>
<tr>
<th>collection_address</th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<th>0xE3b1D32e43Ce8d658368e2CBFF95D57Ef39Be8a6</th>
<td>3.9900</td>
</tr>
<tr>
<th>0x9CEE09946A8113a503C1264e328c0e3aEe4c8bCf</th>
<td>0.3000</td>
</tr>
<tr>
<th>0x85F0e02cb992aa1F9F47112F815F519EF1A59E2D</th>
<td>0.2000</td>
</tr>
<tr>
<th>0xADc466855ebe8d1402C5F7e6706Fccc3AEdB44a0</th>
<td>0.0110</td>
</tr>
<tr>
<th>0xC2A19349D5f451071C3085B90f531D19F190FF21</th>
<td>0.0099</td>
</tr>
<tr>
<th>0x1e13BDCB500a9B24b8221B290aD5E535D34E4218</th>
<td>0.0000</td>
</tr>
</tbody>
</table>
</div>
We see that `0xE3b1D32e43Ce8d658368e2CBFF95D57Ef39Be8a6` has the highest
volume as a collection. To find more about this collection we can grab
it and check it’s metadata:
``` python
bnb.collection('0xE3b1D32e43Ce8d658368e2CBFF95D57Ef39Be8a6').metadata()
```
collection_id 0xe3b1d32e43ce8d658368e2cbff95d57ef39be8a6
name SPACE ID
slug space-id-bnb-name
marketplace tofu
website_url https://space.id/
discord_url https://discord.gg/cXP5UtYjHY
twitter_url https://twitter.com/SpaceIDProtocol
floor_price 28.93
updated_at 2022-08-30 11:53:38.548041
created_at 2022-08-07 12:49:06
Name: SPACE ID, dtype: object
We see it is Space ID! We even have Twitter, Discord and website
references to find more about this dapp/collection. Let’s do more
drilling on this, checking out what was the split on primary vs
secondary and also top mints traded can be a good idea:
``` python
spaceid = bnb.collection('0xE3b1D32e43Ce8d658368e2CBFF95D57Ef39Be8a6')
spaceid_trades = spaceid.trades('last month')
```
``` python
# can look at some price summary stats:
spaceid_trades['price'].describe()
```
count 54230.000000
mean 0.220979
std 1.219418
min 0.000000
25% 0.008280
50% 0.009268
75% 0.037172
max 123.000000
Name: price, dtype: float64
Can check primary vs seconday split on volume:
``` python
spaceid_trades.groupby('mint').sum('price')[['price']].plot(kind='barh')
```
<AxesSubplot:ylabel='mint'>
![](index_files/figure-gfm/cell-16-output-2.png)
We can also check for primary vs secondary trade counts…
``` python
spaceid_trades['mint'].value_counts(normalize=True).reset_index().style.format({'mint': "%{:.2f}"})
```
<style type="text/css">
</style>
<table id="T_72b57">
<thead>
<tr>
<th class="blank level0" > </th>
<th id="T_72b57_level0_col0" class="col_heading level0 col0" >index</th>
<th id="T_72b57_level0_col1" class="col_heading level0 col1" >mint</th>
</tr>
</thead>
<tbody>
<tr>
<th id="T_72b57_level0_row0" class="row_heading level0 row0" >0</th>
<td id="T_72b57_row0_col0" class="data row0 col0" >False</td>
<td id="T_72b57_row0_col1" class="data row0 col1" >%0.57</td>
</tr>
<tr>
<th id="T_72b57_level0_row1" class="row_heading level0 row1" >1</th>
<td id="T_72b57_row1_col0" class="data row1 col0" >True</td>
<td id="T_72b57_row1_col1" class="data row1 col1" >%0.43</td>
</tr>
</tbody>
</table>
So primary and secondary sale numbers are close but secondary sales
volume is almost 5x.
Next, we can check out also highest value token trade as an example:
``` python
top_trade = spaceid_trades\
.query('mint == False')\
.sort_values('price', ascending=False).head(1).squeeze()
top_trade
```
id 56466d58-e366-3f96-8bd6-115f1054bf36
hash 0x99eceaa0a93e960f162f94b3248aadba2d280af4c245...
buyer 0x68CA671253729039c1596856A0492B5979FCF37b
seller 0xC25751a1cE2eE2F62599F3Cc238a874C631aa4FC
collection_address 0xE3b1D32e43Ce8d658368e2CBFF95D57Ef39Be8a6
token_id 4563769053854199209000009877284788645708242223...
marketplace_address 0xb3e3DfCb2d9f3DdE16d78B9e6EB3538Eb32B5ae1
marketplace_name element
price 123.0
currency BNB
block_hash 0xae31bce2d4f9e6442b83f41e47236ef56f970ba9c2c1...
block_number 21088593
mint False
bundle False
timestamp 1662447211
updated_at 2022-09-06 07:01:48
Name: 15223, dtype: object
If we are curious to get more info on this we can then grab this token
as such:
``` python
token = spaceid.token(top_trade.token_id)
pprint(token.metadata())
```
{'attributes': BoxList([{'trait_type': 'Created Date', 'display_type': 'date', 'value': 1661401461}, {'trait_type': 'Registration Date', 'display_type': 'date', 'value': 1661401461}, {'trait_type': 'Expiration Date', 'display_type': 'date', 'value': 1692955724}, {'trait_type': 'Length', 'display_type': 'number', 'value': 3}, {'trait_type': 'Segment Length', 'display_type': 'number', 'value': 3}, {'trait_type': 'Character Set', 'display_type': 'string', 'value': 'digit'}]),
'description': '123.bnb, a bnb name.',
'image': 'https://meta.image.space.id/image/mainnet/45637690538541992090000098772847886457082422231295691457910964509567538102535.svg',
'name': '123.bnb',
'name_length': 3,
'segment_length': 3,
'uri': 'https://meta.space.id/45637690538541992090000098772847886457082422231295691457910964509567538102535'}
So this is `123.bnb` id!
We also have traits (can be used to calculate rarities for PFP/Gamefi
collections), and more info that can be accessed with the token model.
You can then also get the history of trades as such:
``` python
token_trades = token.trades('last month')
```
``` python
token_trades.sort_values('timestamp', ascending=True)
```
<div>
<style scoped>
.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
</style>
<table border="1" class="dataframe">
<thead>
<tr style="text-align: right;">
<th></th>
<th>id</th>
<th>hash</th>
<th>buyer</th>
<th>seller</th>
<th>collection_address</th>
<th>token_id</th>
<th>marketplace_address</th>
<th>marketplace_name</th>
<th>price</th>
<th>currency</th>
<th>block_hash</th>
<th>block_number</th>
<th>mint</th>
<th>bundle</th>
<th>timestamp</th>
<th>updated_at</th>
</tr>
</thead>
<tbody>
<tr>
<th>0</th>
<td>f072e372-518d-31b5-bd91-803162bb1d73</td>
<td>0xe1e0ac10537fd5b2a723a3dedea6feb2223083bd83f1...</td>
<td>0xC25751a1cE2eE2F62599F3Cc238a874C631aa4FC</td>
<td>0x48af770f89F03C6cCea6919df6F89bC903cE2F9C</td>
<td>0xE3b1D32e43Ce8d658368e2CBFF95D57Ef39Be8a6</td>
<td>4563769053854199209000009877284788645708242223...</td>
<td>0x48af770f89F03C6cCea6919df6F89bC903cE2F9C</td>
<td>-</td>
<td>0.0</td>
<td>BNB</td>
<td>0xf88eb7636afedda5a88dc8b4f6f53558052e5838941d...</td>
<td>20739907</td>
<td>False</td>
<td>True</td>
<td>1661398772</td>
<td>2022-08-26 20:26:52</td>
</tr>
<tr>
<th>1</th>
<td>037e325f-8e64-355d-ad07-0c812d94ac39</td>
<td>0xe1e0ac10537fd5b2a723a3dedea6feb2223083bd83f1...</td>
<td>0x48af770f89F03C6cCea6919df6F89bC903cE2F9C</td>
<td>0x0000000000000000000000000000000000000000</td>
<td>0xE3b1D32e43Ce8d658368e2CBFF95D57Ef39Be8a6</td>
<td>4563769053854199209000009877284788645708242223...</td>
<td>0x48af770f89F03C6cCea6919df6F89bC903cE2F9C</td>
<td>-</td>
<td>0.0</td>
<td>BNB</td>
<td>0xf88eb7636afedda5a88dc8b4f6f53558052e5838941d...</td>
<td>20739907</td>
<td>True</td>
<td>True</td>
<td>1661398772</td>
<td>2022-08-26 20:26:52</td>
</tr>
<tr>
<th>2</th>
<td>56466d58-e366-3f96-8bd6-115f1054bf36</td>
<td>0x99eceaa0a93e960f162f94b3248aadba2d280af4c245...</td>
<td>0x68CA671253729039c1596856A0492B5979FCF37b</td>
<td>0xC25751a1cE2eE2F62599F3Cc238a874C631aa4FC</td>
<td>0xE3b1D32e43Ce8d658368e2CBFF95D57Ef39Be8a6</td>
<td>4563769053854199209000009877284788645708242223...</td>
<td>0xb3e3DfCb2d9f3DdE16d78B9e6EB3538Eb32B5ae1</td>
<td>element</td>
<td>123.0</td>
<td>BNB</td>
<td>0xae31bce2d4f9e6442b83f41e47236ef56f970ba9c2c1...</td>
<td>21088593</td>
<td>False</td>
<td>False</td>
<td>1662447211</td>
<td>2022-09-06 07:01:48</td>
</tr>
</tbody>
</table>
</div>
Apparently, there was only a single mint (combined with a transfer to
the owner) and then a secondary sale worth \~\$34,194.
Wrapping up, this was just an example of how from gross analysis you can
go to token level in just a few lines. Let us know how we can improve
the docs if you have any [ideas](mailto:efe@joinzash.com).
## Advanced
### Social metrics over time
Since Twitter and Discord metrics can be significant indicators for NFT
collections we aggregate these metrics as well. Specifically, for
Twitter we pull follower/following/tweet counts and for Discord
active/passive members. Note: Currently this is only supported for `eth`
chain.
Here is an example of discord members over time for BAYC for instance:
``` python
zash.nft('eth')\
.collection('0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D')\
.socials('boredapeyachtclub')\
.discord\
.set_index('ts')\
.resample('D').mean()\
.plot()
```
<AxesSubplot:xlabel='ts'>
![](index_files/figure-gfm/cell-22-output-2.png)
Looks like active member activity started to fluctuate as we went deeper
into the bear market 🐻
### Network analysis on trades
We are building and enriching network analysis tools to be go deeper on
a given trade network. Below is a flavor of what is to come.
``` python
from zash_sdk.graph import *
network = build_network(bayc.trades('yesterday'))
plot_trade_network(network)
```
![](index_files/figure-gfm/cell-23-output-1.png)
You can filter for wash trades (triangular or bidirectional cycles for
instance).
### Streaming
Our API already has real-time trade streaming endpoint, you can connect
to it [here](https://zashapi.readme.io/reference/streaming-api).
Alternatively, our SDK also has methods for streaming full spectrum of
activities of a given collection. This includes, listings, offers,
transfers and sales across all marketplaces. Currently, available for
Ethereum only. Sample usage:
### Stay tuned!
This is the beginning of what you can do with Zash SDK. We would be
adding transparent NFT price prediction and wallet based analysis tools
in the upcoming weeks. If you have any feature requests [get in
touch](mailto:efe@joinzash.com). We are also
[hiring](https://northern-steel-324.notion.site/Zash-is-Hiring-d5e19210b944486c8fd11f385a176999)!
Raw data
{
"_id": null,
"home_page": "https://github.com/zashdev/zash-sdk",
"name": "zash-sdk",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.7",
"maintainer_email": "",
"keywords": "nbdev jupyter notebook python",
"author": "efx",
"author_email": "efe@joinzash.com",
"download_url": "https://files.pythonhosted.org/packages/77/17/8ac5384c5f211a853371e1556b4655641266524df6539ab3da3b739c5520/zash-sdk-0.0.10.tar.gz",
"platform": null,
"description": "zash-sdk\n================\n\n<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->\n\nDelightful, ergonomic blockchain data SDK built for data scientist, ML\nengineers and data analysts. Wrangle and explore transactions under a\nminute.\n\n## Install\n\n``` sh\npip install zash-sdk\n```\n\n## Quickstart\n\n### Authentication\n\nGet your credentials from [zash.sh](https://zash.sh)\n\n``` python\nfrom zash_sdk.zash import Zash\nzash = Zash('your_username', 'your_api_key')\n```\n\n Authenticated!\n\n### Accessing NFT collection trades\n\nGrab all Bored Ape trades in x2y2 since yesterday (contract address\n[here](https://etherscan.io/address/0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d)):\n\n``` python\nbayc = zash.nft('eth').collection('0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D')\n```\n\n``` python\ntrades_df = bayc.trades('yesterday')\ntrades_df.query(\"marketplace_name == 'x2y2'\").head()\n```\n\n<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>id</th>\n <th>hash</th>\n <th>buyer</th>\n <th>seller</th>\n <th>collection_address</th>\n <th>token_id</th>\n <th>marketplace_address</th>\n <th>marketplace_name</th>\n <th>price</th>\n <th>currency</th>\n <th>block_hash</th>\n <th>block_number</th>\n <th>mint</th>\n <th>bundle</th>\n <th>timestamp</th>\n <th>updated_at</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>19</th>\n <td>e80e354c-e3d8-3538-9788-817693f55783</td>\n <td>0x6a7d16abd0b13522a99c5879f2e62ae66c15d91e4be7...</td>\n <td>0xbdBa56dac0C99FA9A020045D9ccc774Ed2489558</td>\n <td>0xed2ab4948bA6A909a7751DEc4F34f303eB8c7236</td>\n <td>0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D</td>\n <td>7369</td>\n <td>0x74312363e45DCaBA76c59ec49a7Aa8A65a67EeD3</td>\n <td>x2y2</td>\n <td>69.000000</td>\n <td>ETH</td>\n <td>0x1407e979138ab4e4cff899a25c735b587279898edb59...</td>\n <td>15490769</td>\n <td>False</td>\n <td>False</td>\n <td>1662560018</td>\n <td>2022-09-07 14:16:27</td>\n </tr>\n <tr>\n <th>68</th>\n <td>3a018278-681f-31e9-815f-97694ea9e48f</td>\n <td>0x14f6f7698fe763c61ebb146d047fdc70973bb8f2a1d9...</td>\n <td>0xed2ab4948bA6A909a7751DEc4F34f303eB8c7236</td>\n <td>0x70219c18604DebF89379d566a622BDe2c5bc7621</td>\n <td>0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D</td>\n <td>4788</td>\n <td>0x74312363e45DCaBA76c59ec49a7Aa8A65a67EeD3</td>\n <td>x2y2</td>\n <td>67.670000</td>\n <td>WETH</td>\n <td>0xd07c225d1ad934f6544114734392ebe9e767388ae80a...</td>\n <td>15493679</td>\n <td>False</td>\n <td>False</td>\n <td>1662600397</td>\n <td>2022-09-08 01:31:10</td>\n </tr>\n <tr>\n <th>78</th>\n <td>2b2da6c2-717d-3d7c-87d0-af205258adec</td>\n <td>0xeb23a4aa54a9b26bb6c1e50c9a4f5608572a5029f4d3...</td>\n <td>0xed2ab4948bA6A909a7751DEc4F34f303eB8c7236</td>\n <td>0xDa6391FB338F155a5b1036b9f5F7D19F4076779E</td>\n <td>0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D</td>\n <td>3277</td>\n <td>0x74312363e45DCaBA76c59ec49a7Aa8A65a67EeD3</td>\n <td>x2y2</td>\n <td>67.273004</td>\n <td>WETH</td>\n <td>0x32f058cb9aca9f92629ee47414a70a8a865dc6fde22b...</td>\n <td>15493761</td>\n <td>False</td>\n <td>False</td>\n <td>1662601462</td>\n <td>2022-09-08 01:46:13</td>\n </tr>\n </tbody>\n</table>\n</div>\n\nA closer look at a trade:\n\n``` python\ntrade = trades_df.query(\"marketplace_name == 'x2y2'\").head(1).squeeze()\ntrade\n```\n\n id e80e354c-e3d8-3538-9788-817693f55783\n hash 0x6a7d16abd0b13522a99c5879f2e62ae66c15d91e4be7...\n buyer 0xbdBa56dac0C99FA9A020045D9ccc774Ed2489558\n seller 0xed2ab4948bA6A909a7751DEc4F34f303eB8c7236\n collection_address 0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D\n token_id 7369\n marketplace_address 0x74312363e45DCaBA76c59ec49a7Aa8A65a67EeD3\n marketplace_name x2y2\n price 69.0\n currency ETH\n block_hash 0x1407e979138ab4e4cff899a25c735b587279898edb59...\n block_number 15490769\n mint False\n bundle False\n timestamp 1662560018\n updated_at 2022-09-07 14:16:27\n Name: 19, dtype: object\n\n``` python\n# You can check out the transaction on etherscan:\n!echo https://etherscan.io/tx/{trade['hash']}\n```\n\n https://etherscan.io/tx/0x6a7d16abd0b13522a99c5879f2e62ae66c15d91e4be7caa745c5bf0b0b2c3031\n\n### Simple marketplace comparison\n\nYou can get near-real time view of a chain in a single line:\n\n``` python\nlast_hour_trades = zash.nft('eth').trades('1 hour ago')\n```\n\n[`NFT.trades`](https://zashdev.github.io/nft.html#nft.trades) accepts\ntime ranges or shortcuts such as \u201cyesterday\u201d or \u201ctoday\u201d.\n\n``` python\n# offmarket marketplaces are labelled as -\nlast_hour_trades\\\n .query('marketplace_name != \"-\"')\\\n .groupby('marketplace_name')\\\n .agg({\"price\":'sum'})\\\n .sort_values('price', ascending=False)\\\n .plot(kind='bar', ylabel='price_in_eth', legend=False)\n```\n\n <AxesSubplot:xlabel='marketplace_name', ylabel='price_in_eth'>\n\n![](index_files/figure-gfm/cell-8-output-2.png)\n\n## Example: Deep dive on BNB\n\nIn this example, we\u2019ll show you can go from a macro view to a micro one,\nfrom marketplaces all the way to the tokens.\n\nLet\u2019s look at BNB chain this time, across all marketplaces:\n\n``` python\nbnb = zash.nft('bnb')\ntrades = bnb.trades('1 hour ago')\n```\n\nOff-market trades are market with \u201c-\u201d in marketplace names, you can\nfilter them out as such:\n\n``` python\nmarketplace_trades = trades.query('marketplace_name != \"-\"')\n```\n\n``` python\nmarketplace_trades.groupby('marketplace_name').agg({\"price\":'sum'}).plot(kind='bar')\n```\n\n <AxesSubplot:xlabel='marketplace_name'>\n\n![](index_files/figure-gfm/cell-11-output-2.png)\n\nFrom here we see Element has the highest volume, can do a drill on this\nto find out the top collections:\n\n``` python\ntop = marketplace_trades.query(\"marketplace_name == 'element'\")\\\n .groupby('collection_address')\\\n .sum('price')[['price']]\\\n .sort_values('price', ascending=False)\ntop\n```\n\n<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>price</th>\n </tr>\n <tr>\n <th>collection_address</th>\n <th></th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>0xE3b1D32e43Ce8d658368e2CBFF95D57Ef39Be8a6</th>\n <td>3.9900</td>\n </tr>\n <tr>\n <th>0x9CEE09946A8113a503C1264e328c0e3aEe4c8bCf</th>\n <td>0.3000</td>\n </tr>\n <tr>\n <th>0x85F0e02cb992aa1F9F47112F815F519EF1A59E2D</th>\n <td>0.2000</td>\n </tr>\n <tr>\n <th>0xADc466855ebe8d1402C5F7e6706Fccc3AEdB44a0</th>\n <td>0.0110</td>\n </tr>\n <tr>\n <th>0xC2A19349D5f451071C3085B90f531D19F190FF21</th>\n <td>0.0099</td>\n </tr>\n <tr>\n <th>0x1e13BDCB500a9B24b8221B290aD5E535D34E4218</th>\n <td>0.0000</td>\n </tr>\n </tbody>\n</table>\n</div>\n\nWe see that `0xE3b1D32e43Ce8d658368e2CBFF95D57Ef39Be8a6` has the highest\nvolume as a collection. To find more about this collection we can grab\nit and check it\u2019s metadata:\n\n``` python\nbnb.collection('0xE3b1D32e43Ce8d658368e2CBFF95D57Ef39Be8a6').metadata()\n```\n\n collection_id 0xe3b1d32e43ce8d658368e2cbff95d57ef39be8a6\n name SPACE ID\n slug space-id-bnb-name\n marketplace tofu\n website_url https://space.id/\n discord_url https://discord.gg/cXP5UtYjHY\n twitter_url https://twitter.com/SpaceIDProtocol\n floor_price 28.93\n updated_at 2022-08-30 11:53:38.548041\n created_at 2022-08-07 12:49:06\n Name: SPACE ID, dtype: object\n\nWe see it is Space ID! We even have Twitter, Discord and website\nreferences to find more about this dapp/collection. Let\u2019s do more\ndrilling on this, checking out what was the split on primary vs\nsecondary and also top mints traded can be a good idea:\n\n``` python\nspaceid = bnb.collection('0xE3b1D32e43Ce8d658368e2CBFF95D57Ef39Be8a6')\nspaceid_trades = spaceid.trades('last month')\n```\n\n``` python\n# can look at some price summary stats:\nspaceid_trades['price'].describe()\n```\n\n count 54230.000000\n mean 0.220979\n std 1.219418\n min 0.000000\n 25% 0.008280\n 50% 0.009268\n 75% 0.037172\n max 123.000000\n Name: price, dtype: float64\n\nCan check primary vs seconday split on volume:\n\n``` python\nspaceid_trades.groupby('mint').sum('price')[['price']].plot(kind='barh')\n```\n\n <AxesSubplot:ylabel='mint'>\n\n![](index_files/figure-gfm/cell-16-output-2.png)\n\nWe can also check for primary vs secondary trade counts\u2026\n\n``` python\nspaceid_trades['mint'].value_counts(normalize=True).reset_index().style.format({'mint': \"%{:.2f}\"})\n```\n\n<style type=\"text/css\">\n</style>\n<table id=\"T_72b57\">\n <thead>\n <tr>\n <th class=\"blank level0\" > </th>\n <th id=\"T_72b57_level0_col0\" class=\"col_heading level0 col0\" >index</th>\n <th id=\"T_72b57_level0_col1\" class=\"col_heading level0 col1\" >mint</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th id=\"T_72b57_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n <td id=\"T_72b57_row0_col0\" class=\"data row0 col0\" >False</td>\n <td id=\"T_72b57_row0_col1\" class=\"data row0 col1\" >%0.57</td>\n </tr>\n <tr>\n <th id=\"T_72b57_level0_row1\" class=\"row_heading level0 row1\" >1</th>\n <td id=\"T_72b57_row1_col0\" class=\"data row1 col0\" >True</td>\n <td id=\"T_72b57_row1_col1\" class=\"data row1 col1\" >%0.43</td>\n </tr>\n </tbody>\n</table>\n\nSo primary and secondary sale numbers are close but secondary sales\nvolume is almost 5x.\n\nNext, we can check out also highest value token trade as an example:\n\n``` python\ntop_trade = spaceid_trades\\\n .query('mint == False')\\\n .sort_values('price', ascending=False).head(1).squeeze()\ntop_trade\n```\n\n id 56466d58-e366-3f96-8bd6-115f1054bf36\n hash 0x99eceaa0a93e960f162f94b3248aadba2d280af4c245...\n buyer 0x68CA671253729039c1596856A0492B5979FCF37b\n seller 0xC25751a1cE2eE2F62599F3Cc238a874C631aa4FC\n collection_address 0xE3b1D32e43Ce8d658368e2CBFF95D57Ef39Be8a6\n token_id 4563769053854199209000009877284788645708242223...\n marketplace_address 0xb3e3DfCb2d9f3DdE16d78B9e6EB3538Eb32B5ae1\n marketplace_name element\n price 123.0\n currency BNB\n block_hash 0xae31bce2d4f9e6442b83f41e47236ef56f970ba9c2c1...\n block_number 21088593\n mint False\n bundle False\n timestamp 1662447211\n updated_at 2022-09-06 07:01:48\n Name: 15223, dtype: object\n\nIf we are curious to get more info on this we can then grab this token\nas such:\n\n``` python\ntoken = spaceid.token(top_trade.token_id)\npprint(token.metadata())\n```\n\n {'attributes': BoxList([{'trait_type': 'Created Date', 'display_type': 'date', 'value': 1661401461}, {'trait_type': 'Registration Date', 'display_type': 'date', 'value': 1661401461}, {'trait_type': 'Expiration Date', 'display_type': 'date', 'value': 1692955724}, {'trait_type': 'Length', 'display_type': 'number', 'value': 3}, {'trait_type': 'Segment Length', 'display_type': 'number', 'value': 3}, {'trait_type': 'Character Set', 'display_type': 'string', 'value': 'digit'}]),\n 'description': '123.bnb, a bnb name.',\n 'image': 'https://meta.image.space.id/image/mainnet/45637690538541992090000098772847886457082422231295691457910964509567538102535.svg',\n 'name': '123.bnb',\n 'name_length': 3,\n 'segment_length': 3,\n 'uri': 'https://meta.space.id/45637690538541992090000098772847886457082422231295691457910964509567538102535'}\n\nSo this is `123.bnb` id!\n\nWe also have traits (can be used to calculate rarities for PFP/Gamefi\ncollections), and more info that can be accessed with the token model.\n\nYou can then also get the history of trades as such:\n\n``` python\ntoken_trades = token.trades('last month')\n```\n\n``` python\ntoken_trades.sort_values('timestamp', ascending=True)\n```\n\n<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>id</th>\n <th>hash</th>\n <th>buyer</th>\n <th>seller</th>\n <th>collection_address</th>\n <th>token_id</th>\n <th>marketplace_address</th>\n <th>marketplace_name</th>\n <th>price</th>\n <th>currency</th>\n <th>block_hash</th>\n <th>block_number</th>\n <th>mint</th>\n <th>bundle</th>\n <th>timestamp</th>\n <th>updated_at</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>0</th>\n <td>f072e372-518d-31b5-bd91-803162bb1d73</td>\n <td>0xe1e0ac10537fd5b2a723a3dedea6feb2223083bd83f1...</td>\n <td>0xC25751a1cE2eE2F62599F3Cc238a874C631aa4FC</td>\n <td>0x48af770f89F03C6cCea6919df6F89bC903cE2F9C</td>\n <td>0xE3b1D32e43Ce8d658368e2CBFF95D57Ef39Be8a6</td>\n <td>4563769053854199209000009877284788645708242223...</td>\n <td>0x48af770f89F03C6cCea6919df6F89bC903cE2F9C</td>\n <td>-</td>\n <td>0.0</td>\n <td>BNB</td>\n <td>0xf88eb7636afedda5a88dc8b4f6f53558052e5838941d...</td>\n <td>20739907</td>\n <td>False</td>\n <td>True</td>\n <td>1661398772</td>\n <td>2022-08-26 20:26:52</td>\n </tr>\n <tr>\n <th>1</th>\n <td>037e325f-8e64-355d-ad07-0c812d94ac39</td>\n <td>0xe1e0ac10537fd5b2a723a3dedea6feb2223083bd83f1...</td>\n <td>0x48af770f89F03C6cCea6919df6F89bC903cE2F9C</td>\n <td>0x0000000000000000000000000000000000000000</td>\n <td>0xE3b1D32e43Ce8d658368e2CBFF95D57Ef39Be8a6</td>\n <td>4563769053854199209000009877284788645708242223...</td>\n <td>0x48af770f89F03C6cCea6919df6F89bC903cE2F9C</td>\n <td>-</td>\n <td>0.0</td>\n <td>BNB</td>\n <td>0xf88eb7636afedda5a88dc8b4f6f53558052e5838941d...</td>\n <td>20739907</td>\n <td>True</td>\n <td>True</td>\n <td>1661398772</td>\n <td>2022-08-26 20:26:52</td>\n </tr>\n <tr>\n <th>2</th>\n <td>56466d58-e366-3f96-8bd6-115f1054bf36</td>\n <td>0x99eceaa0a93e960f162f94b3248aadba2d280af4c245...</td>\n <td>0x68CA671253729039c1596856A0492B5979FCF37b</td>\n <td>0xC25751a1cE2eE2F62599F3Cc238a874C631aa4FC</td>\n <td>0xE3b1D32e43Ce8d658368e2CBFF95D57Ef39Be8a6</td>\n <td>4563769053854199209000009877284788645708242223...</td>\n <td>0xb3e3DfCb2d9f3DdE16d78B9e6EB3538Eb32B5ae1</td>\n <td>element</td>\n <td>123.0</td>\n <td>BNB</td>\n <td>0xae31bce2d4f9e6442b83f41e47236ef56f970ba9c2c1...</td>\n <td>21088593</td>\n <td>False</td>\n <td>False</td>\n <td>1662447211</td>\n <td>2022-09-06 07:01:48</td>\n </tr>\n </tbody>\n</table>\n</div>\n\nApparently, there was only a single mint (combined with a transfer to\nthe owner) and then a secondary sale worth \\~\\$34,194.\n\nWrapping up, this was just an example of how from gross analysis you can\ngo to token level in just a few lines. Let us know how we can improve\nthe docs if you have any [ideas](mailto:efe@joinzash.com).\n\n## Advanced\n\n### Social metrics over time\n\nSince Twitter and Discord metrics can be significant indicators for NFT\ncollections we aggregate these metrics as well. Specifically, for\nTwitter we pull follower/following/tweet counts and for Discord\nactive/passive members. Note: Currently this is only supported for `eth`\nchain.\n\nHere is an example of discord members over time for BAYC for instance:\n\n``` python\nzash.nft('eth')\\\n .collection('0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D')\\\n .socials('boredapeyachtclub')\\\n .discord\\\n .set_index('ts')\\\n .resample('D').mean()\\\n .plot()\n```\n\n <AxesSubplot:xlabel='ts'>\n\n![](index_files/figure-gfm/cell-22-output-2.png)\n\nLooks like active member activity started to fluctuate as we went deeper\ninto the bear market \ud83d\udc3b\n\n### Network analysis on trades\n\nWe are building and enriching network analysis tools to be go deeper on\na given trade network. Below is a flavor of what is to come.\n\n``` python\nfrom zash_sdk.graph import *\nnetwork = build_network(bayc.trades('yesterday'))\nplot_trade_network(network)\n```\n\n![](index_files/figure-gfm/cell-23-output-1.png)\n\nYou can filter for wash trades (triangular or bidirectional cycles for\ninstance).\n\n### Streaming\n\nOur API already has real-time trade streaming endpoint, you can connect\nto it [here](https://zashapi.readme.io/reference/streaming-api).\n\nAlternatively, our SDK also has methods for streaming full spectrum of\nactivities of a given collection. This includes, listings, offers,\ntransfers and sales across all marketplaces. Currently, available for\nEthereum only. Sample usage:\n\n### Stay tuned!\n\nThis is the beginning of what you can do with Zash SDK. We would be\nadding transparent NFT price prediction and wallet based analysis tools\nin the upcoming weeks. If you have any feature requests [get in\ntouch](mailto:efe@joinzash.com). We are also\n[hiring](https://northern-steel-324.notion.site/Zash-is-Hiring-d5e19210b944486c8fd11f385a176999)!\n",
"bugtrack_url": null,
"license": "Apache Software License 2.0",
"summary": "SDK",
"version": "0.0.10",
"project_urls": {
"Homepage": "https://github.com/zashdev/zash-sdk"
},
"split_keywords": [
"nbdev",
"jupyter",
"notebook",
"python"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "946a8ad211ceff8746918a453721c33452ff3bb5637cb9f25135c255a2324d83",
"md5": "53616bfbb0d0045eafda8dc5fb67884d",
"sha256": "4738a0f1faf18dc6106029f84e26de056311bf42c5789db90882aac07fdd8201"
},
"downloads": -1,
"filename": "zash_sdk-0.0.10-py3-none-any.whl",
"has_sig": false,
"md5_digest": "53616bfbb0d0045eafda8dc5fb67884d",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.7",
"size": 21700,
"upload_time": "2023-05-22T16:55:48",
"upload_time_iso_8601": "2023-05-22T16:55:48.412110Z",
"url": "https://files.pythonhosted.org/packages/94/6a/8ad211ceff8746918a453721c33452ff3bb5637cb9f25135c255a2324d83/zash_sdk-0.0.10-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "77178ac5384c5f211a853371e1556b4655641266524df6539ab3da3b739c5520",
"md5": "96e37251b898f26cc9e49accd1eefbcf",
"sha256": "7405e2c224aab52458976b8d382a3c9ea86a98c789a85d7856296cd220f60be5"
},
"downloads": -1,
"filename": "zash-sdk-0.0.10.tar.gz",
"has_sig": false,
"md5_digest": "96e37251b898f26cc9e49accd1eefbcf",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.7",
"size": 26726,
"upload_time": "2023-05-22T16:55:50",
"upload_time_iso_8601": "2023-05-22T16:55:50.285127Z",
"url": "https://files.pythonhosted.org/packages/77/17/8ac5384c5f211a853371e1556b4655641266524df6539ab3da3b739c5520/zash-sdk-0.0.10.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-05-22 16:55:50",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "zashdev",
"github_project": "zash-sdk",
"github_not_found": true,
"lcname": "zash-sdk"
}