Skip to content

Instantly share code, notes, and snippets.

@wjjwztc
Forked from dougpfeffer/snapshot.rb
Created March 17, 2022 01:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wjjwztc/0fe0114c2bf17e8155ee137a683bba78 to your computer and use it in GitHub Desktop.
Save wjjwztc/0fe0114c2bf17e8155ee137a683bba78 to your computer and use it in GitHub Desktop.
NFT Collection Snapshot Generate with Moralis
# Quick NFT collection snapshot generated using Moralis' API.
# Works with ERC721 and 1155s.
#
# More notes here:
# https://mirror.xyz/pfeffunit.eth/NixhRf1Ghj8IxaMiJBKoXUP-wy0Mn2g7nAEpn55w3Rc
require 'net/http'
require 'uri'
require 'json'
MORALIS_API_KEY = '' # Get an API key from https://moralis.io
# Given a contract address an a page (based on Morali's pagination logic), return a batch of holder info.
def fetchHolders(contractAddress, page)
url = "https://deep-index.moralis.io/api/v2/nft/#{contractAddress}/owners?chain=eth&format=decimal&offset="
owners = []
uri = URI.parse("#{url}#{500 * page}")
request = Net::HTTP::Get.new(uri)
request['X-API-Key'] = MORALIS_API_KEY
req_options = {
use_ssl: uri.scheme == "https",
}
response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
http.request(request)
end
data = JSON.parse(response.body)
return {total: data['total'], owners: data['result'].map{|r| r['owner_of']}}
end
# These are the contracts to you want to download.
# Note that this WILL NOT work for OpenSea contracts, only contracts that are bespoke to the given project.
# 'Name' is used for your sanity and for generating the CSVs.
contracts = [
{name: 'Forgotten Runes Wizards Cult', address: '0x521f9C7505005CFA19A8E5786a9c3c9c9F5e6f42'},
{name: 'CrypToadz', address: '0x1CB1A5e65610AEFF2551A50f76a87a7d3fB649C6'}
]
contracts.each do |c|
puts c[:name]
page = 0
owners = []
keepGoing = true
while true do
results = fetchHolders(c[:address], page)
owners.concat(results[:owners])
puts "Got #{results[:total]} of #{owners.length}..."
if results[:total] <= owners.length
break
end
page = page + 1
sleep(1) # Be polite
end
File.write("#{c[:name].downcase.gsub(' ', '-')}.csv", owners.uniq.join("\n"))
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment