Skip to content
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

Metadata Account class now retrieves offchain metadata and stores it as a variable in the class #45

Merged
merged 2 commits into from
Nov 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 54 additions & 56 deletions Solnet.Metaplex/MetadataAccount.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
using System.Text;
using System.Threading.Tasks;
using System.Net.Http;
using Solnet.Metaplex.Json;
using Newtonsoft.Json;

namespace Solnet.Metaplex
{
Expand Down Expand Up @@ -72,7 +74,7 @@ public class OnchainDataV1
public bool isMutable;
///<summary> Edition Type </summary>
public int editionNonce;
///<summary> Token Standard - Fungible / non-fungible </summary>
///<summary> primarySaleHappened </summary>
public bool primarySaleHappened;
///<summary> metadata json </summary>
public string metadata;
Expand All @@ -90,21 +92,6 @@ public OnchainDataV1(string _name, string _symbol, string _uri, uint _sellerFee,
primarySaleHappened = _primarySaleHappened;
}

/// <summary> Tries to get a json file from the uri </summary>
public async Task<string> FetchMetadata()
{
if (uri is null)
return null;

if (metadata is null)
{
using var http = new HttpClient();
var res = await http.GetStringAsync(uri);
metadata = res;
}

return metadata;
}
}
/// <summary> Metadata Onchain DataV3 structure </summary>
public class OnChainDataV3
Expand Down Expand Up @@ -149,21 +136,7 @@ public OnChainDataV3(string _name, string _symbol, string _uri, uint _sellerFee,
tokenStandard = _tokenStandard;
}

/// <summary> Tries to get a json file from the uri </summary>
public async Task<string> FetchMetadata()
{
if (uri is null)
return null;

if (metadata is null)
{
using var http = new HttpClient();
var res = await http.GetStringAsync(uri);
metadata = res;
}

return metadata;
}
}
/// <summary> Metadata account class V2 </summary>
public class MetadataAccount
Expand All @@ -178,6 +151,8 @@ public class MetadataAccount
public OnchainDataV1 metadataV1;
/// <summary> data struct </summary>
public OnChainDataV3 metadataV3;
/// <summary> Off Chain Metadata </summary>
public MetaplexTokenStandard offchainData;
/// <summary> version of metadata. V1 or V3</summary>
public int MetadataVersion;
/// <summary> standard Solana account info </summary>
Expand All @@ -188,25 +163,47 @@ public class MetadataAccount
/// <summary> Constructor </summary>
/// <param name="accInfo"> Soloana account info </param>
/// /// <param name="MetadataVersion"> Metadata Account Version - Either 1 or 3</param>
public MetadataAccount(AccountInfo accInfo, int MetadataVersion)
public MetadataAccount(AccountInfo accInfo, int _MetadataVersion)
{
try
{
this.owner = new PublicKey(accInfo.Owner);
if(MetadataVersion == 1)
this.metadataV1 = ParseDataV1(accInfo.Data);
owner = new PublicKey(accInfo.Owner);
MetadataVersion = _MetadataVersion;
if (MetadataVersion == 1)
metadataV1 = ParseDataV1(accInfo.Data);
if (MetadataVersion == 3)
this.metadataV3 = ParseDataV3(accInfo.Data);
metadataV3 = ParseDataV3(accInfo.Data);
var data = Convert.FromBase64String(accInfo.Data[0]);
this.updateAuthority = new PublicKey(data[1..33]);
this.mint = new PublicKey(data[33..65]);
var UA = data.AsSpan(1, 32);
updateAuthority = new PublicKey(UA);
if (MetadataVersion == 1)
offchainData = FetchOffChainMetadata(1);
if (MetadataVersion == 3)
offchainData = FetchOffChainMetadata(3);
var _mint = data.AsSpan(33, 32);
mint = new PublicKey(_mint);
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
/// <summary> Tries to get a json file from the uri </summary>
public MetaplexTokenStandard FetchOffChainMetadata(int version)
{
MetaplexTokenStandard metadata = null;
string assetURI = metadataV3.uri;
if (version == 1)
assetURI = metadataV1.uri;
using (var httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0");
var offsiteTokenRetrieval = httpClient.GetStringAsync(new Uri(assetURI)).Result;
MetaplexTokenStandard _Metadata = JsonConvert.DeserializeObject<MetaplexTokenStandard>(offsiteTokenRetrieval);
}

return metadata;
}
/// <summary> Parse version 1 Data used for V1 metadata accounts </summary>
/// <param name="data"> data </param>
/// <returns> data struct </returns>
Expand Down Expand Up @@ -234,7 +231,7 @@ public static OnchainDataV1 ParseDataV1(List<string> data)
if (hasCreators == true)
{
creators = MetadataProgramData.DecodeCreators(binData.GetSpan(MetadataAccountLayout.creatorsCountOffset + 5, numOfCreators * (32 + 1 + 1)));
o = MetadataAccountLayout.creatorsCountOffset + 5 + (numOfCreators * (32 + 1 + 1));
o = MetadataAccountLayout.creatorsCountOffset + 5 + numOfCreators * (32 + 1 + 1);
}
else
{
Expand Down Expand Up @@ -287,8 +284,8 @@ public static OnChainDataV3 ParseDataV3(List<string> data)
if (hasCreators == true)
{
creators = MetadataProgramData.DecodeCreators(binData.GetSpan(MetadataAccountLayout.creatorsCountOffset + 5, numOfCreators * (32 + 1 + 1)));
o = MetadataAccountLayout.creatorsCountOffset + 5 + (numOfCreators * (32 + 1 + 1));
o = MetadataAccountLayout.creatorsCountOffset + 5 + numOfCreators * (32 + 1 + 1);

}
else
{
Expand All @@ -307,41 +304,41 @@ public static OnChainDataV3 ParseDataV3(List<string> data)
o++;
bool hasCollectionlink = binData.GetBool(o);
o++;

Collection collectionLink = null;
if (hasCollectionlink == true)
{
var verified = binData.GetBool(o);
o++;
var key = binData.GetPubKey(o);
o = o + 32;
collectionLink = new Collection(key, verified);

collectionLink = new Collection(key, verified);
}
else
{
o++;
}

bool isConsumable = binData.GetBool(o);
Uses usesInfo = null;
if (isConsumable == true)
{
o++;
var useMethodENUM = binData.GetBytes(o, 1)[0];
o++;
var remaining = binData.GetU64(o).ToString("x");
o = o + 8;
var total = binData.GetU64(o).ToString("x");
o = o + 8;
o++;
usesInfo = new Uses(useMethodENUM, remaining, total);
o++;
var useMethodENUM = binData.GetBytes(o, 1)[0];
o++;
var remaining = binData.GetU64(o).ToString("x");
o = o + 8;
var total = binData.GetU64(o).ToString("x");
o = o + 8;
o++;
usesInfo = new Uses(useMethodENUM, remaining, total);
}
else
{
o++;
}

name = name.TrimEnd('\0');
symbol = symbol.TrimEnd('\0');
uri = uri.TrimEnd('\0');
Expand Down Expand Up @@ -382,7 +379,8 @@ async public static Task<MetadataAccount> GetAccount(IRpcClient client, PublicKe

if (readdata.Length == 165)
{
mintAccount = new PublicKey(readdata[..32]);
byte[] _mint = readdata.AsSpan(0, 32).ToArray();
mintAccount = new PublicKey(_mint);
}
else
{
Expand All @@ -391,7 +389,7 @@ async public static Task<MetadataAccount> GetAccount(IRpcClient client, PublicKe

PublicKey metadataAddress;
byte nonce;
PublicKey.TryFindProgramAddress(new List<byte[]>()
PublicKey.TryFindProgramAddress(new List<byte[]>()
{
Encoding.UTF8.GetBytes("metadata"),
MetadataProgram.ProgramIdKey,
Expand Down
96 changes: 96 additions & 0 deletions Solnet.Metaplex/MetadataJson.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Text;

namespace Solnet.Metaplex.Json
{
public class MetaplexTokenStandard
{
[JsonProperty("name")]
public string name { get; set; }

[JsonProperty("symbol")]
public string symbol { get; set; }

[JsonProperty("description")]
public string description { get; set; }

[JsonProperty("seller_fee_basis_points")]
public int seller_fee_basis_points { get; set; }

[JsonProperty("image")]
public string image { get; set; }

[JsonProperty("animation_url")]
public string animation_url { get; set; }

[JsonProperty("external_url")]
public string external_url { get; set; }

[JsonProperty("attributes")]
public List<Attribute> attributes { get; set; }

[JsonProperty("collection")]
public Collection collection { get; set; }

[JsonProperty("properties")]
public Properties properties { get; set; }
}

public class Attribute
{
[JsonProperty("trait_type")]
public string trait_type { get; set; }

[JsonProperty("value")]
public string value { get; set; }

}
public class Collection
{
[JsonProperty("name")]
public string name { get; set; }

[JsonProperty("family")]
public string family { get; set; }

}
public class Files
{
[JsonProperty("0")]
public FileType file { get; set; }

[JsonProperty("data")]
public string category { get; set; }
}
public class FileType
{
[JsonProperty("uri")]
public string uri { get; set; }

[JsonProperty("type")]
public string type { get; set; }
}
public class Creators
{
[JsonProperty("0")]
public Creator creator { get; set; }
}
public class Creator
{
[JsonProperty("address")]
public string address { get; set; }

[JsonProperty("share")]
public int share { get; set; }
}
public class Properties
{
[JsonProperty("files")]
public List<FileType> files { get; set; }

[JsonProperty("creators")]
public List<Creator> creators { get; set; }
}
}
1 change: 1 addition & 0 deletions Solnet.Metaplex/Solnet.Metaplex.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
<PackageReference Include="Microsoft.Extensions.Logging" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.2" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="Solnet.Extensions" Version="6.1.0" />
<PackageReference Include="Solnet.Keystore" Version="6.1.0" />
<PackageReference Include="Solnet.Programs" Version="6.1.0" />
Expand Down
6 changes: 6 additions & 0 deletions Solnet.Metaplex/packages.lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@
"System.Text.Json": "6.0.0"
}
},
"Newtonsoft.Json": {
"type": "Direct",
"requested": "[13.0.1, )",
"resolved": "13.0.1",
"contentHash": "ppPFpBcvxdsfUonNcvITKqLl3bqxWbDCZIzDWHzjpdAHRFfZe0Dw9HmA0+za13IdyrgJwpkDTDA9fHaxOrt20A=="
},
"Solnet.Extensions": {
"type": "Direct",
"requested": "[6.1.0, )",
Expand Down