Skip to content

Instantly share code, notes, and snippets.

@dougpfeffer
Last active March 1, 2023 10:19
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save dougpfeffer/692e4c78a7ba9e56108311544a9400f6 to your computer and use it in GitHub Desktop.
Save dougpfeffer/692e4c78a7ba9e56108311544a9400f6 to your computer and use it in GitHub Desktop.
NFT Collection Snapshot Generate with Moralis
# Requires a Moralis API key.
# Writes out lists of owners of each token of each contract listed in the `CONTRACTS` array.
# Doesn't work on OpenSea contracts.
require 'net/http'
require 'uri'
require 'json'
MORALIS_API_KEY = ''
# These are the contracts to you want to download.
# Note that this WILL NOT work for OpenSea contracts, only contracts that are custom to the given project.
# 'Name' is used for your sanity and for generating the CSVs.
CONTRACTS = [
{name: 'Turf', address: '0x55d89273143DE3dE00822c9271DbCBD9B44B44C6'}
]
# Given a contract address an a page (based on Morali's pagination logic), return a batch of holder info.
def fetchHolders(contractAddress, page, cursor = nil)
url = "https://deep-index.moralis.io/api/v2/nft/#{contractAddress}/owners?chain=eth&format=decimal"
owners = []
if cursor
url = url + '&cursor=' + cursor
end
uri = URI.parse(url)
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 {cursor: data['cursor'], total: data['total'], owners: data['result'].map{|r| r['owner_of']}}
end
cursor = nil
CONTRACTS.each do |c|
puts c[:name]
page = 0
owners = []
keepGoing = true
while true do
results = fetchHolders(c[:address], page, cursor)
cursor = results[:cursor]
owners.concat(results[:owners])
if results[:total] <= owners.length
break
end
puts "Got #{owners.length} of #{results[:total]} ..."
page = page + 1
sleep(1) # Be polite
end
File.write("#{c[:name].downcase.gsub(' ', '-')}.csv", owners.join("\n"))
end
@dougpfeffer
Copy link
Author

Updated to work with Moralis API updates, and other minor tweaks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment