diff --git a/Solnet.Metaplex/MetadataAccount.cs b/Solnet.Metaplex/MetadataAccount.cs
index 81eaee4..65da563 100644
--- a/Solnet.Metaplex/MetadataAccount.cs
+++ b/Solnet.Metaplex/MetadataAccount.cs
@@ -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
{
@@ -72,7 +74,7 @@ public class OnchainDataV1
public bool isMutable;
/// Edition Type
public int editionNonce;
- /// Token Standard - Fungible / non-fungible
+ /// primarySaleHappened
public bool primarySaleHappened;
/// metadata json
public string metadata;
@@ -90,21 +92,6 @@ public OnchainDataV1(string _name, string _symbol, string _uri, uint _sellerFee,
primarySaleHappened = _primarySaleHappened;
}
- /// Tries to get a json file from the uri
- public async Task 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;
- }
}
/// Metadata Onchain DataV3 structure
public class OnChainDataV3
@@ -149,21 +136,7 @@ public OnChainDataV3(string _name, string _symbol, string _uri, uint _sellerFee,
tokenStandard = _tokenStandard;
}
- /// Tries to get a json file from the uri
- public async Task 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;
- }
}
/// Metadata account class V2
public class MetadataAccount
@@ -178,6 +151,8 @@ public class MetadataAccount
public OnchainDataV1 metadataV1;
/// data struct
public OnChainDataV3 metadataV3;
+ /// Off Chain Metadata
+ public MetaplexTokenStandard offchainData;
/// version of metadata. V1 or V3
public int MetadataVersion;
/// standard Solana account info
@@ -188,25 +163,47 @@ public class MetadataAccount
/// Constructor
/// Soloana account info
/// /// Metadata Account Version - Either 1 or 3
- 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);
}
}
+ /// Tries to get a json file from the uri
+ 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(offsiteTokenRetrieval);
+ }
+ return metadata;
+ }
/// Parse version 1 Data used for V1 metadata accounts
/// data
/// data struct
@@ -234,7 +231,7 @@ public static OnchainDataV1 ParseDataV1(List 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
{
@@ -287,8 +284,8 @@ public static OnChainDataV3 ParseDataV3(List 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
{
@@ -307,7 +304,7 @@ public static OnChainDataV3 ParseDataV3(List data)
o++;
bool hasCollectionlink = binData.GetBool(o);
o++;
-
+
Collection collectionLink = null;
if (hasCollectionlink == true)
{
@@ -315,33 +312,33 @@ public static OnChainDataV3 ParseDataV3(List data)
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');
@@ -382,7 +379,8 @@ async public static Task 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
{
@@ -391,7 +389,7 @@ async public static Task GetAccount(IRpcClient client, PublicKe
PublicKey metadataAddress;
byte nonce;
- PublicKey.TryFindProgramAddress(new List()
+ PublicKey.TryFindProgramAddress(new List()
{
Encoding.UTF8.GetBytes("metadata"),
MetadataProgram.ProgramIdKey,
diff --git a/Solnet.Metaplex/MetadataJson.cs b/Solnet.Metaplex/MetadataJson.cs
new file mode 100644
index 0000000..d823c08
--- /dev/null
+++ b/Solnet.Metaplex/MetadataJson.cs
@@ -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 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 files { get; set; }
+
+ [JsonProperty("creators")]
+ public List creators { get; set; }
+ }
+}
diff --git a/Solnet.Metaplex/Solnet.Metaplex.csproj b/Solnet.Metaplex/Solnet.Metaplex.csproj
index b01c327..63bf2d0 100644
--- a/Solnet.Metaplex/Solnet.Metaplex.csproj
+++ b/Solnet.Metaplex/Solnet.Metaplex.csproj
@@ -21,6 +21,7 @@
+
diff --git a/Solnet.Metaplex/packages.lock.json b/Solnet.Metaplex/packages.lock.json
index e2a4ee0..8562709 100644
--- a/Solnet.Metaplex/packages.lock.json
+++ b/Solnet.Metaplex/packages.lock.json
@@ -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, )",