-
Notifications
You must be signed in to change notification settings - Fork 1
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
Compressed NFTs #12
Merged
Merged
Compressed NFTs #12
Changes from all commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
893759c
WIP: partial draft of compressed NFTs
ray-kast a100069
Scaffolded new backends and asset API client.
ray-kast 450f463
Refactor events.rs.
ray-kast e94fc36
refactor: support mcc
kespinola 6245577
refactor: adding certified_collections and actions for updating a col…
kespinola 5eab139
refactor: unify collection creation to single backend since both requ…
kespinola b5b5975
feat: add extra account for doing creator verification of compressed …
kespinola 74b8ff6
Merge pull request #21 from holaplex/espi/mcc-collections
kespinola fcd1bff
fix: handle signed requests for collections
kespinola a2c2215
faet: generate instruction and submit transactions for minting to a c…
kespinola File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,3 @@ | ||
[workspace] | ||
members = ["consumer", "core", "entity", "migration", "indexer"] | ||
resolver = "2" | ||
|
||
[workspace.dependencies] | ||
holaplex-hub-nfts-solana-core = { path = "core" } | ||
holaplex-hub-nfts-solana-entity = { path = "entity" } | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
mod b58 { | ||
use serde::{de::Visitor, Deserializer, Serializer}; | ||
|
||
pub fn serialize<S: Serializer>(bytes: &[u8], ser: S) -> Result<S::Ok, S::Error> { | ||
ser.serialize_str(&bs58::encode(bytes).into_string()) | ||
} | ||
|
||
pub fn deserialize<'de, D: Deserializer<'de>>(de: D) -> Result<Vec<u8>, D::Error> { | ||
struct Vis; | ||
|
||
impl<'a> Visitor<'a> for Vis { | ||
type Value = Vec<u8>; | ||
|
||
fn expecting(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
f.write_str("a base58-encoded string") | ||
} | ||
|
||
fn visit_str<E: serde::de::Error>(self, s: &str) -> Result<Self::Value, E> { | ||
bs58::decode(s).into_vec().map_err(E::custom) | ||
} | ||
} | ||
|
||
de.deserialize_str(Vis) | ||
} | ||
} | ||
|
||
#[derive(serde::Serialize, serde::Deserialize)] | ||
pub struct Base58(#[serde(with = "b58")] pub Vec<u8>); | ||
|
||
impl From<Vec<u8>> for Base58 { | ||
fn from(v: Vec<u8>) -> Self { | ||
Self(v) | ||
} | ||
} | ||
|
||
impl From<Base58> for Vec<u8> { | ||
fn from(Base58(v): Base58) -> Self { | ||
v | ||
} | ||
} | ||
|
||
#[derive(serde::Serialize, serde::Deserialize)] | ||
pub struct Asset { | ||
pub interface: String, | ||
pub id: Base58, | ||
pub content: serde_json::Value, | ||
pub authorities: Vec<AssetAuthority>, | ||
pub compression: AssetCompression, | ||
pub grouping: Vec<AssetGrouping>, | ||
pub royalty: AssetRoyalty, | ||
pub creators: Vec<AssetCreator>, | ||
pub ownership: AssetOwnership, | ||
pub supply: Option<u32>, | ||
pub mutable: bool, | ||
} | ||
|
||
#[derive(serde::Serialize, serde::Deserialize)] | ||
pub struct AssetAuthority { | ||
pub address: Base58, | ||
pub scopes: Vec<String>, | ||
} | ||
|
||
#[derive(serde::Serialize, serde::Deserialize)] | ||
pub struct AssetCompression { | ||
pub eligible: bool, | ||
pub compressed: bool, | ||
pub data_hash: Base58, | ||
pub creator_hash: Base58, | ||
pub asset_hash: Base58, | ||
pub tree: Base58, | ||
pub seq: u32, | ||
pub leaf_id: u32, | ||
} | ||
|
||
#[derive(serde::Serialize, serde::Deserialize)] | ||
pub struct AssetGrouping { | ||
pub group_key: String, | ||
pub group_value: Base58, | ||
} | ||
|
||
#[derive(serde::Serialize, serde::Deserialize)] | ||
pub struct AssetRoyalty { | ||
pub royalty_model: String, | ||
pub target: Option<serde_json::Number>, // TODO: what type is this | ||
pub percent: serde_json::Number, // TODO: this is fractional, use BCD to avoid rounding error | ||
pub basis_points: u32, | ||
pub primary_sale_happened: bool, | ||
pub locked: bool, | ||
} | ||
|
||
#[derive(serde::Serialize, serde::Deserialize)] | ||
pub struct AssetCreator { | ||
pub address: Base58, | ||
pub share: u32, | ||
pub verified: bool, | ||
} | ||
|
||
#[derive(serde::Serialize, serde::Deserialize)] | ||
pub struct AssetOwnership { | ||
pub frozen: bool, | ||
pub delegated: bool, | ||
pub delegate: Base58, | ||
pub ownership_model: String, | ||
pub owner: Base58, | ||
} | ||
|
||
#[derive(serde::Serialize, serde::Deserialize)] | ||
pub struct AssetProof { | ||
pub root: Base58, | ||
pub proof: Vec<Base58>, | ||
pub node_index: u32, | ||
pub leaf: Base58, | ||
pub tree_id: Base58, | ||
} | ||
|
||
#[jsonrpsee::proc_macros::rpc(client)] | ||
pub trait Rpc { | ||
#[method(name = "getAsset", param_kind = map)] | ||
fn get_asset(&self, id: &str) -> Result<Asset, Error>; | ||
|
||
#[method(name = "getAssetProof", param_kind = map)] | ||
fn get_asset_proof(&self, id: &str) -> Result<AssetProof, Error>; | ||
|
||
// Supposedly Triton offers these but their docs were crashing my browser | ||
// so I don't know what the signatures are. | ||
|
||
// #[method(name = "getAssetsByAuthority")] | ||
// fn get_assets_by_authority(&self); | ||
|
||
// #[method(name = "getAssetsByOwner")] | ||
// fn get_assets_by_owner(&self); | ||
|
||
// #[method(name = "getAssetsByGroup")] | ||
// fn get_assets_by_group(&self); | ||
|
||
// #[method(name = "getAssetsByCreator")] | ||
// fn get_assets_by_creator(&self); | ||
|
||
// #[method(name = "searchAssets")] | ||
// fn search_assets(&self); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
use holaplex_hub_nfts_solana_core::proto::{ | ||
MetaplexMasterEditionTransaction, SolanaPendingTransaction, TransferMetaplexAssetTransaction, | ||
}; | ||
use holaplex_hub_nfts_solana_entity::{collection_mints, collections}; | ||
use hub_core::prelude::*; | ||
use solana_program::pubkey::Pubkey; | ||
|
||
#[derive(Clone)] | ||
pub struct MasterEditionAddresses { | ||
pub metadata: Pubkey, | ||
pub associated_token_account: Pubkey, | ||
pub owner: Pubkey, | ||
pub master_edition: Pubkey, | ||
pub mint: Pubkey, | ||
pub update_authority: Pubkey, | ||
} | ||
|
||
#[derive(Clone)] | ||
pub struct MintEditionAddresses { | ||
pub edition: Pubkey, | ||
pub mint: Pubkey, | ||
pub metadata: Pubkey, | ||
pub owner: Pubkey, | ||
pub associated_token_account: Pubkey, | ||
pub recipient: Pubkey, | ||
} | ||
|
||
#[derive(Clone)] | ||
pub struct MintMetaplexAddresses { | ||
pub mint: Pubkey, | ||
pub metadata: Pubkey, | ||
pub owner: Pubkey, | ||
pub associated_token_account: Pubkey, | ||
pub recipient: Pubkey, | ||
pub update_authority: Pubkey, | ||
} | ||
|
||
#[derive(Clone)] | ||
pub struct MintCompressedMintV1Addresses { | ||
pub owner: Pubkey, | ||
pub recipient: Pubkey, | ||
} | ||
|
||
#[derive(Clone)] | ||
pub struct UpdateMasterEditionAddresses { | ||
pub metadata: Pubkey, | ||
pub update_authority: Pubkey, | ||
} | ||
|
||
#[derive(Clone)] | ||
pub struct TransferAssetAddresses { | ||
pub owner: Pubkey, | ||
pub recipient: Pubkey, | ||
pub recipient_associated_token_account: Pubkey, | ||
pub owner_associated_token_account: Pubkey, | ||
} | ||
|
||
/// Represents a response from a transaction on the blockchain. This struct | ||
/// provides the serialized message and the signatures of the signed message. | ||
pub struct TransactionResponse<A> { | ||
/// The serialized version of the message from the transaction. | ||
pub serialized_message: Vec<u8>, | ||
|
||
/// The signatures of the signed message or the public keys of wallets that should sign the transaction. Order matters. | ||
pub signatures_or_signers_public_keys: Vec<String>, | ||
|
||
/// Addresses that are related to the transaction. | ||
pub addresses: A, | ||
} | ||
|
||
impl<A> From<TransactionResponse<A>> for SolanaPendingTransaction { | ||
fn from( | ||
TransactionResponse { | ||
serialized_message, | ||
signatures_or_signers_public_keys, | ||
.. | ||
}: TransactionResponse<A>, | ||
) -> Self { | ||
Self { | ||
serialized_message, | ||
signatures_or_signers_public_keys, | ||
} | ||
} | ||
} | ||
|
||
pub trait CollectionBackend { | ||
fn create( | ||
&self, | ||
txn: MetaplexMasterEditionTransaction, | ||
) -> Result<TransactionResponse<MasterEditionAddresses>>; | ||
|
||
fn update( | ||
&self, | ||
collection: &collections::Model, | ||
txn: MetaplexMasterEditionTransaction, | ||
) -> Result<TransactionResponse<UpdateMasterEditionAddresses>>; | ||
} | ||
|
||
pub trait MintBackend<T, R> { | ||
fn mint(&self, collection: &collections::Model, txn: T) -> Result<TransactionResponse<R>>; | ||
} | ||
|
||
#[async_trait] | ||
pub trait TransferBackend { | ||
async fn transfer( | ||
&self, | ||
collection_mint: &collection_mints::Model, | ||
txn: TransferMetaplexAssetTransaction, | ||
) -> Result<TransactionResponse<TransferAssetAddresses>>; | ||
} |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
note to self: why did i do this?