metaboss
metaboss copied to clipboard
snapshot unlisted holders
Is there a way to snapshot unlisted holders of NFTs from a candy machine?
I've been using tools like sol-nft.tools and solanatools.dev but I can't seem to differentiate the difference between marketplace wallets and regular wallets
Do you have some idea how to do this using only on-chain info? This has been requested before and it would be a nice feature to have, but I'm not sure how to differentiate NFTs owned by marketplaces and by normal users without maintaining some kind of off-chain list of marketplace addresses (which would be onerous to compile and maintain).
Hey @samuelvanderwaal - Magic Eden recently updated their API and it looks like the solana program they use for listing as well.
Before, your NFT was transferred to their account. Now it is still owned you, but the token is "delegated" to them.
This is data about the token when unlisted:
info: {
isNative: false,
mint: 'CU6pBuaoyuuUW3sSQS9zp2qJNE67oGT1sqxoKUQUVCxg',
owner: 'DwsV6adiviFnYbjXSWwh6GXzMQPHtS47jVcihGLPdqpD',
state: 'initialized',
tokenAmount: { amount: '1', decimals: 0, uiAmount: 1, uiAmountString: '1' }
}
and when listed:
info: {
delegate: '1BWutmTvYPwDtmw9abTkS4Ssr8no61spGAvW1X6NDix',
delegatedAmount: { amount: '1', decimals: 0, uiAmount: 1, uiAmountString: '1' },
isNative: false,
mint: 'CU6pBuaoyuuUW3sSQS9zp2qJNE67oGT1sqxoKUQUVCxg',
owner: 'DwsV6adiviFnYbjXSWwh6GXzMQPHtS47jVcihGLPdqpD',
state: 'initialized',
tokenAmount: { amount: '1', decimals: 0, uiAmount: 1, uiAmountString: '1' }
}
So we should be able to filter out those that are delegated. I got the above using the @project-serum/anchor package and haven't done much with Rust yet, but if I get the chance I will dig into how this can be implemented in metaboss, perhaps as option on the snapshot
command like --undelegated
Haven't looked at other marketplaces so not sure if this applies to them, but certainly for ME's recent updates.
Realised a caveat to this: any tokens listed on ME before their update to start using "delegate" are still using the old method.
So tokens held by this account are with ME:
GUfCR9mK6azb9vcpsxgXyj7XRPAKJd4KMHTTVvtncGgp
OK this README from another repo (from searching for that address) has these as marketplace addresses:
Digital Eyes - "F4ghBzHFNgJxV4wEQDchU5i7n4XWWMBSaq7CuswGiVsr"
Magic Eden - "GUfCR9mK6azb9vcpsxgXyj7XRPAKJd4KMHTTVvtncGgp"
Solanart - "3D49QorJyNaL4rcpiynbuS3pRH4Y7EXEM6v6ZGaqfFGK"
From: https://github.com/heisenberglit/AirdropSol/blob/main/README.md
@jarvisjohnson great research and thoughts, thanks! I'm mulling this over as a feature for 0.4.0 or 0.5.0 which are the next two big updates I have on the Metaboss roadmap. Using delegated accounts as a filter is a good idea as it's reliable and objective and lets the users determine what it actually means. I'm still concerned about adding a feature that claims to show all unlisted vs listed NFTs as it seems like marketplaces do things differently leading to a lot of edge cases and creating a maintenance hassle.
Sounds great @samuelvanderwaal - yeah totally that makes sense. Very true on listed / unlisted, difficult to keep up with them all.
Btw, thanks for the tool, has been very helpful to many of us!
Chiming in here. I had this same trouble on my typescript code assembling a list of holders. Initially, I collected a list of exclusions with known marketplace addresses and then applied a filter based on that:
{
"exclusions": {
"digital_eyes": "F4ghBzHFNgJxV4wEQDchU5i7n4XWWMBSaq7CuswGiVsr",
"exchange_art": "BjaNzGdwRcFYeQGfuLYsc1BbaNRG1yxyWs1hZuGRT8J2",
"magic_eden": "GUfCR9mK6azb9vcpsxgXyj7XRPAKJd4KMHTTVvtncGgp",
"solanart": "3D49QorJyNaL4rcpiynbuS3pRH4Y7EXEM6v6ZGaqfFGK"
}
}
But this is flaky. Plus, at some point I started getting an error with some other owner address (sorry I don't recall the exact error or what I was trying to do with it) for which googling it wasn't enough to determine if it was a marketplace or not. During investigation I realized that owner address was a PDA. And all other "valid" owners were not. And I checked my list of exclusions and turned out all of them were PDAs too. And it kinda makes sense. When a "human" owner transfers (or delegates?) their NFTs, they end up in the hands of a PDA, not another "human" owner with a "valid" wallet.
So I figured the on-chain way to check if the holder is a "real" holder or not, could be to check if the address is on curve or not:
web3.PublicKey.isOnCurve(new web3.PublicKey('1BWutmTvYPwDtmw9abTkS4Ssr8no61spGAvW1X6NDix').toBuffer())
// => false
Apparently, it works for ME's new delegated address too.
So I think the owner address being on curve or not, seems to be a good indicator of the owner holding on their wallet or not. Let me know if you find my reasoning to be wrong!
@oboxodo Really smart reasoning here. I'll have to look into it more but if it makes sense I'll add it to the roadmap for one of the upcoming versions.
I wouldn't use the isOnCurve method since it will break unlisted but staking scenarios and other escrow-like methods. What I've been doing at JungleCats is taking holder snapshots and filter by known marketplace escrow wallets. This, however still causes an issue even more now that Auction House is coming.
I wouldn't use the isOnCurve method since it will break unlisted but staking scenarios and other escrow-like methods. What I've been doing at JungleCats is taking holder snapshots and filter by known marketplace escrow wallets. This, however still causes an issue even more now that Auction House is coming.
Can you give an example of this? Don't most escrows use PDAs?
@kevinrodriguez-io do you have a list of known marketpalces you could share? Or know of some "official"(ish) list someone is maintaining somewhere?
I think an alternative would be for metaboss to include a boolean indicating if the holder's address is on curve or not. Then whoever is requesting the snapshot can decide what to do. Maybe filter out the ones not on curve (this is what I do).