I’m trying to build a contract that will purchase an NFT for me from a marketplace contract (we can assume objkt.com for now) and then transfer it to sp.sender.
I manager to create a contract that will buy the NFT, but the NFT stays with the contract.
My assumption is that I need to, once purchased, transfer the NFT from the contract (the new owner after purchasing it) to sp.sender (target owner).
My question is;
Is that the correct approach or is there a more elegant solution to passthrough sp.sender as the receiver of the NFT when purchasing the NFT from the marketplace?
If my approach is the right one, how can I then transfer from the contract to sp.sender. I wrote the code below but I keep on running in the nftContract interface doesn't exist with it. I assume I build the params for the transfer function wrong
Here is the code snippet for the purchase and transfer:
is there a more elegant solution to passthrough sp.sender as the receiver of the NFT when purchasing the NFT from the marketplace?
Yes, that’s how you should to it and that’s what you did:
sp.transfer(
[sp.record(
from_ = sp.self_address(), # This is probably wrong.
txs = [sp.record(
to_= sp.sender, # Here is the person who receives the NFT.
token_id= nftId,
amount= 1,
)],
)],
sp.mutez(0),
nftContract.unwrap_some(error="nftContract interface doesn't exist")
)
The from_ is probably wrong, in the from_ field you have to put the current owner of the NFT.
Not the person who ask for the transfer, not the receiver and not the FA2 contract.
The nftContract interface doesn't exist is another problem, I’ll answer it separately.
The new owner of the NFT should be the contract, no?
I can only imagine putting the from_ of the transfer as the current owner of the NFT failing, if the balance is not updated after the transfer, it would be like ‘stealing’ this NFT.
No?
I keep on running in the nftContract interface doesn't exist with it.
I see two mistakes you may have done.
What is nftAddress? If it corresponds to an onchain address, the current simulator is not able to reach an onchain contract. You have to create a FA2 contract in your scenario to test it. If that’s the only error, you code may work when you originate it but not in the scenario.
FA2 standard existed before the new default layout for record. As a consequence you have to specify the layout in the FA2 contact’s type. You can use the one give by the FA2 library: fa2.t.transfer_params.
from templates import fa2_lib as fa2
t = fa2.t
# In your contract
# ...
nftContract = sp.contract(t.transfer_params, nftAddress, entrypoint="transfer")
# In your scenario
# ...
scenario.add_module(fa2.t)
I’m referring to the warning here: Operations | SmartPy
Which says that operations are done after the entrypoint is completed.
So in my flow:
The contract buys the NFT
The contract sends it from itself to sp.sender.
I’m not sure who has the NFT at the beginning of 2) It should be the contract as it buying the NFT.
I confirm that you don’t have any problem here, at the beginning of 2) everything from 1) has been completed.
For example, imagine you have:
sp.transfer(blah_blah1)
sp.transfer(blah_blah2)
Both sp.transfer add transfer operations. At the end of the entrypoint the transfer operation with blah_blah1 is executed so the entrypoint called by blah_blah1 runs. At the end of it, there may be transfer executed by this entrypoint and so on. When every subsequent operations are completed then blah_blah2 is executed.
Most of the time everything behave exactly like you would think without paying attention to this warning.