ethglobal / nfthack-support

Issue tracker for NFTHack support
5 stars 2 forks source link

Easiest way to get tokenId of a newly minted NFT? #6

Open arthur-ver opened 3 years ago

arthur-ver commented 3 years ago

Without using a subgraph.

My current approach is to getLogs(filter) after tx 1 confirmation using ethers.js filter

const filter = {
    address: contractAddress,
    topics: [ 
        ethers.utils.id("Transfer(address,address,uint256)"),
        null,
        ethers.utils.hexZeroPad(toAdress, 32)
    ]
}

provider.getLogs(filter).then((logs) => {
    resolve(logs)
})
jzaki commented 3 years ago

@arthur-ver Are you still looking into this? Please ping me in the #hack-support discord channel :)

tenthirtyone commented 3 years ago

@arthur-ver The only requirements for tokenId to mint is that the id is not already used and it is a valid uint256. Most 721 contracts I have seen store a Struct with their app-specific token data in an array on the contract that implements the 721 standard. TokenId is generally incremental based on the length of the existing 721 token array.

Here is how CryptoKitties stored their ERC-721 kitties: https://gist.github.com/arpit/071e54b95a81d13cb29681407680794f#file-cryptokitties-sol-L317 https://gist.github.com/arpit/071e54b95a81d13cb29681407680794f#file-cryptokitties-sol-L408

Kitty[] kitties;

...

uint256 newKittenId = kitties.push(_kitty) - 1;

The logi in their top-level contract only has the game logic and this worked for them. If the app uses a different strategy to generate tokenIds I would look at their smart contract logic to see if this is deterministic.

arthur-ver commented 3 years ago

I'm using ethers.js and Zora ZDK which handles all transactions, I can only get a transaction hash in the callback. My current approach is to send a transaction and initialize a contract events listener using ethers.js, but for some reason it doesn't work 1 out of 10 times.

Another solution would be to get totalSupply() directly from the contract before minting and then just +1, but what if someone else mints before my transaction gets confirmed?

Is there any way to get that information from a transaction hash?

tenthirtyone commented 3 years ago

@arthur-ver I am looking into the zdk unit tests to find a use case that may help - can you take a look and see if there are any tests for what you're trying to do?

https://github.com/ourzora/zdk/blob/master/tests/zora.test.ts#L290

I was thinking this may be something you could use: https://github.com/ourzora/zdk/blob/master/tests/zora.test.ts#L366

arthur-ver commented 3 years ago

Ok, thank you!

I know there is a way through Etherscan API to get more information on the transaction hash. Maybe worth looking into it :)

adamwhitakerwilson commented 3 years ago

Punks https://api.covalenthq.com/v1/1/tokens/0xb47e3cd837ddf8e4c57f05d70ab865de6e193bbb/nft_token_ids/?page-number=0&page-size=999999 Zora Ids https://api.covalenthq.com/v1/1/tokens/0xabEFBc9fD2F806065b4f3C237d4b59D9A97Bcac7/nft_token_ids/?page-number=0&page-size=999999

jzaki commented 3 years ago

If this is still active, here's a link to a 721 example: listenting to events with Ethers. @arthur-ver If it's only working 1 in 10, it might be a race condition. Is the listener+filter set up before the contract interaction?

arthur-ver commented 3 years ago

@jzaki @adamwhitakerwilson Thank you for your feedback, that's exactly how I used ethers.js for listening to contract events.

I solved the problem using Parsiq. I've setup a smart trigger that sends a webhook to my API once the Transfer() event meets certain criteria. That way, even if the user closes the window before the transaction gets confirmed, the new token Id will still be set successfully