-
Notifications
You must be signed in to change notification settings - Fork 30
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
use sg721-metadata-onchain #104
Conversation
// parse token data and check whether it is of type NftExtension | ||
let extension: Option<NftExtensionMsg> = match data { | ||
Some(data) => from_json::<NftExtension>(data) | ||
.ok() | ||
.map(|ext| NftExtensionMsg { | ||
animation_url: ext.animation_url, | ||
attributes: ext.attributes, | ||
background_color: ext.background_color, | ||
description: ext.description, | ||
external_url: ext.external_url, | ||
image: ext.image, | ||
image_data: ext.image_data, | ||
youtube_url: ext.youtube_url, | ||
name: ext.name, | ||
}), | ||
None => None, | ||
}; | ||
|
||
let msg = cw721_metadata_onchain::msg::ExecuteMsg::Mint { | ||
token_id: id.into(), | ||
token_uri: uri, | ||
owner: receiver.to_string(), | ||
extension, | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Outsourced to mint_msg()
for re-use.
contracts/sg-ics721/src/execute.rs
Outdated
fn mint_msg( | ||
&self, | ||
token_id: String, | ||
token_uri: Option<String>, | ||
owner: String, | ||
data: Option<Binary>, | ||
) -> StdResult<Binary> { | ||
// parse token data and check whether it is of type NftExtension | ||
let extension: Metadata = match data { | ||
Some(data) => { | ||
match from_json::<NftExtension>(data).ok().map(|ext| Metadata { | ||
animation_url: ext.animation_url, | ||
attributes: ext.attributes.map(|traits| { | ||
traits | ||
.into_iter() | ||
.map(|t| Trait { | ||
trait_type: t.trait_type, | ||
value: t.value, | ||
display_type: t.display_type, | ||
}) | ||
.collect() | ||
}), | ||
background_color: ext.background_color, | ||
description: ext.description, | ||
external_url: ext.external_url, | ||
image: ext.image, | ||
image_data: ext.image_data, | ||
youtube_url: ext.youtube_url, | ||
name: ext.name, | ||
}) { | ||
Some(extension) => extension, | ||
None => Metadata { | ||
animation_url: None, | ||
attributes: None, | ||
background_color: None, | ||
description: None, | ||
external_url: None, | ||
image: None, | ||
image_data: None, | ||
youtube_url: None, | ||
name: None, | ||
}, | ||
} | ||
} | ||
None => Metadata { | ||
animation_url: None, | ||
attributes: None, | ||
background_color: None, | ||
description: None, | ||
external_url: None, | ||
image: None, | ||
image_data: None, | ||
youtube_url: None, | ||
name: None, | ||
}, | ||
}; | ||
|
||
let msg = sg721_metadata_onchain::ExecuteMsg::Mint { | ||
token_id, | ||
token_uri, | ||
owner, | ||
extension, | ||
}; | ||
to_json_binary(&msg) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sg-ics721 implementation with Metadata
data: Some(to_json_binary(&NftExtension { | ||
image: Some("https://ark.pass/image.png".to_string()), | ||
external_url: Some( | ||
"https://interchain.arkprotocol.io".to_string(), | ||
), | ||
description: Some("description".to_string()), | ||
..Default::default() | ||
})) | ||
.transpose() | ||
.unwrap(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
test case for token 1 with metadata. token 2 is unchanged and has no metadata
assert_eq!( | ||
token_info.extension, | ||
Some(NftExtension { | ||
image: Some("https://ark.pass/image.png".to_string()), | ||
external_url: Some("https://interchain.arkprotocol.io".to_string()), | ||
description: Some("description".to_string()), | ||
..Default::default() | ||
}) | ||
); | ||
let token_info: cw721::msg::NftInfoResponse<DefaultOptionalNftExtension> = test |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
transferred NFT 1 with onchain data
assert_eq!( | ||
token_info.extension, | ||
Some(NftExtension { | ||
..Default::default() | ||
}) | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
transferred NFT 2 with no onchain data
contracts/sg-ics721/src/execute.rs
Outdated
// parse token data and check whether it is of type NftExtension | ||
let extension: Metadata = match data { | ||
Some(data) => { | ||
match from_json::<NftExtension>(data).ok().map(|ext| Metadata { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since everything here is being added from .ext I wonder if we could put this mapping into a helper function
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, we cant, sg-ics721 requires struct of type Metadata
, whilst ics721 requires NftExtensionMsg
. See comments below.
packages/ics721/src/execute.rs
Outdated
) -> StdResult<Binary> { | ||
// parse token data and check whether it is of type NftExtension | ||
let extension: Option<NftExtensionMsg> = match data { | ||
Some(data) => from_json::<NftExtension>(data) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we put that other parse in a function I think we could re-use it here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, we cant, sg-ics721 requires struct of type Metadata
, whilst ics721 requires NftExtensionMsg
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Out of curiosity how similar are those messages?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are 100% the same. Created a new issue here: public-awesome/launchpad#695
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great, thanks
}, | ||
}; | ||
|
||
let msg = sg721_metadata_onchain::ExecuteMsg::Mint { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so my question here is, does every meta data load resolve into a metadata_onchain type message? Wondering if there is a different struct for off-chain metadata?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In case of offchain metadata:
- extension is empty onchain Metadata (with
None
values for each prop like image and attributes) token_uri
is used for offchain data, e.g. refers to an IPFS link with offchain metadata. Here JSON file on IPFS is exactly the same type forMetadata
(as defined by ERC721).
So SG NFT mint is done by this:
let msg = cw721_metadata_onchain::msg::ExecuteMsg::Mint {
token_id,
token_uri, // holds off-chain metadata
owner,
extension, // holds on-chain metadata
};
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just wondering here, if off chain metadata is minted in this way, shouldn't we not use an execute message from cw721_onchain such as to not confuse the developer? I think the data is fine just coming from the cw721_metadata_onchain directory might be a bit misleading.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh my bad (wrong example given above). This is an sg-implementation, proper code is using this:
let msg = sg721_metadata_onchain::ExecuteMsg::Mint {
token_id,
token_uri, // holds off-chain metadata
owner,
extension, // holds on-chain metadata
};
to_json_binary(&msg)
Please note that mint_msg()
returns StdResult<Binary>
for ics721 and sg-ics721.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Resolved in discord, name is coming from external repo
Ok(WasmMsg::Execute { | ||
contract_addr: nft_contract.to_string(), | ||
msg: to_json_binary(&msg)?, | ||
msg: self.mint_msg(id.into(), uri, receiver.to_string(), data)?, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@humanalgorithm look here where mint_msg
is called. This happens here in as part of callback_create_vouchers
call in Ics721Execute
trait.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
This PR uses sg721-metadata-onchain contract. It allows incoming NFTs with onchain metadata. If there is no onchain data, then
None
is used inMetadata
.