• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

bmresearch / Solnet / 10672350157

02 Sep 2024 07:46PM UTC coverage: 77.453% (+0.2%) from 77.239%
10672350157

push

github

BifrostTitan
Agave v2.0 Migration

Updated the RPC client and removed deprecated code from the SDK.
Cleaned up all the warnings across the solution and added a few sys-vars that were missing.
Generate Seed in Mnemonic class now uses System.Security.Cryptography instead of bouncy castle sdk

1111 of 1682 branches covered (66.05%)

Branch coverage included in aggregate %.

6 of 10 new or added lines in 6 files covered. (60.0%)

18 existing lines in 4 files now uncovered.

5117 of 6359 relevant lines covered (80.47%)

1328281.27 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

76.19
/src/Solnet.Extensions/TokenMintResolver.cs
1
using Solnet.Extensions.TokenMint;
2
using System;
3
using System.Collections.Generic;
4
using System.Net.Http;
5
using System.Text.Json;
6
using System.Threading.Tasks;
7

8
namespace Solnet.Extensions
9
{
10
    /// <summary>
11
    /// The default implementation of the TokenMintResolver.
12
    /// <para>You can create your own by implementing ITokenMintResolver.</para>
13
    /// <para>You can use the Load method to load the Solana ecosystem's standard token list or 
14
    /// populate your own instance with TokenDef objects.</para>
15
    /// </summary>
16
    public class TokenMintResolver : ITokenMintResolver
17
    {
18

19
        /// <summary>
20
        /// The URL of the standard token list
21
        /// </summary>
22
        private const string TOKENLIST_GITHUB_URL = "https://cdn.jsdelivr.net/gh/solflare-wallet/token-list@latest/solana-tokenlist.json";
23

24
        /// <summary>
25
        /// Internal lookfor for resolving mint public key addresses to TokenDef objects.
26
        /// </summary>
27
        private Dictionary<string, TokenDef> _tokens;
28

29
        /// <summary>
30
        /// Map of known tokens.
31
        /// </summary>
32
        public IReadOnlyDictionary<string, TokenDef> KnownTokens => _tokens;
×
33

34
        /// <summary>
35
        /// Constructs an empty TokenMintResolver object.
36
        /// </summary>
37
        public TokenMintResolver()
14✔
38
        {
39
            _tokens = new Dictionary<string, TokenDef>();
14✔
40
        }
14✔
41

42
        /// <summary>
43
        /// Constructs an empty TokenMintResolver and populates with deserialized TokenListDoc.
44
        /// </summary>
45
        /// <param name="tokenList">A deserialised token list.</param>
46
        internal TokenMintResolver(TokenListDoc tokenList) : this()
3✔
47
        {
48
            foreach (var token in tokenList.tokens)
18✔
49
            {
50
                Add(token);
6✔
51
            }
52
        }
3✔
53

54
        /// <summary>
55
        /// Return an instance of the TokenMintResolver loaded with the Solana token list.
56
        /// </summary>
57
        /// <returns>An instance of the TokenMintResolver populated with Solana token list definitions.</returns>
58
        public static TokenMintResolver Load()
59
        {
60
            return LoadAsync().Result;
×
61
        }
62

63
        /// <summary>
64
        /// Return an instance of the TokenMintResolver loaded dererialised token list JSON from the specified URL.
65
        /// </summary>
66
        /// <param name="url"></param>
67
        /// <returns>An instance of the TokenMintResolver populated with Solana token list definitions.</returns>
68
        public static TokenMintResolver Load(string url)
69
        {
70
            return LoadAsync(url).Result;
×
71
        }
72

73
        /// <summary>
74
        /// Return an instance of the TokenMintResolver loaded with the Solana token list.
75
        /// </summary>
76
        /// <returns>A task that will result in an instance of the TokenMintResolver populated with Solana token list definitions.</returns>
77
        public static async Task<TokenMintResolver> LoadAsync()
78
        {
79
            return await LoadAsync(TOKENLIST_GITHUB_URL);
×
80
        }
×
81

82
        /// <summary>
83
        /// Return an instance of the TokenMintResolver loaded with the Solana token list.
84
        /// </summary>
85
        /// <returns>A task that will result in an instance of the TokenMintResolver populated with Solana token list definitions.</returns>
86
        public static async Task<TokenMintResolver> LoadAsync(string url)
87
        {
NEW
88
            using (var wc = new HttpClient())
×
89
            {
NEW
90
                var json = await wc.GetStringAsync(url);
×
91
                return ParseTokenList(json);
×
92
            }
93
        }
×
94

95
        /// <summary>
96
        /// Return an instance of the TokenMintResolver loaded with the dererialised JSON string supplied.
97
        /// </summary>
98
        /// <param name="json">The JSON to parse - should be shaped the same as the Solana token list.</param>
99
        /// <returns>An instance of the TokenMintResolver populated with the deserialized JSON provided.</returns>
100
        public static TokenMintResolver ParseTokenList(string json)
101
        {
102
            if (json is null) throw new ArgumentNullException(nameof(json));
3!
103
            var options = new JsonSerializerOptions(JsonSerializerDefaults.Web);
3✔
104
            var tokenList = JsonSerializer.Deserialize<TokenListDoc>(json, options);
3✔
105
            return new TokenMintResolver(tokenList);
3✔
106
        }
107

108
        /// <summary>
109
        /// Resolve a token mint public key address into the token def.
110
        /// <para>
111
        /// If a token is not known, a default Unknown TokenDef instance with be created for that mint and stashed for any future lookups.
112
        /// </para>
113
        /// <para>
114
        /// Unknown tokens will have decimal places of -1 by design. 
115
        /// This will prevent their use when converting decimal balance values into lamports for TransactionBuilder.
116
        /// It is unlikely this scenario will be encountered often as Unknown token are encounted by the TokenWallet Load method
117
        /// when processing TokenAccountInfo RPC results that do contain the decimal places.
118
        /// </para>
119
        /// </summary>
120
        /// <param name="tokenMint"></param>
121
        /// <returns></returns>
122
        public TokenDef Resolve(string tokenMint)
123
        {
124
            if (tokenMint == null) throw new ArgumentNullException(nameof(tokenMint));
192!
125
            if (_tokens.ContainsKey(tokenMint))
192✔
126
            {
127
                return _tokens[tokenMint];
148✔
128
            }
129
            else
130
            {
131
                var unknown = new TokenDef(tokenMint, $"Unknown {tokenMint}", string.Empty, -1);
44✔
132
                _tokens[tokenMint] = unknown;
44✔
133
                return unknown;
44✔
134
            }
135
        }
136

137
        /// <summary>
138
        /// Add a token to the TokenMintResolver lookup.
139
        /// Any collisions on token mint will replace the previous instance.
140
        /// </summary>
141
        /// <param name="token">An instance of TokenDef to be added.</param>
142
        public void Add(TokenDef token)
143
        {
144
            if (token is null) throw new ArgumentNullException(nameof(token));
32!
145
            _tokens[token.TokenMint] = token;
32✔
146
        }
32✔
147

148
        /// <summary>
149
        /// Construct a TokenDef instance populated with extension goodies from the Solana token list.
150
        /// </summary>
151
        /// <param name="tokenItem">A TokenListItem instance.</param>
152
        internal void Add(TokenListItem tokenItem)
153
        {
154
            if (tokenItem is null) throw new ArgumentNullException(nameof(tokenItem));
6!
155

156
            // pick out the token logo or null
157
            string logoUrl = tokenItem.LogoUri;
6✔
158

159
            // pick out the coingecko identifier if available
160
            string coingeckoId = null;
6✔
161
            if (tokenItem.Extensions?.ContainsKey("coingeckoId") ?? false) coingeckoId = ((JsonElement) tokenItem.Extensions["coingeckoId"]).GetString();
12!
162

163
            // pick out the project website if available
164
            string projectUrl = null;
6✔
165
            if (tokenItem.Extensions?.ContainsKey("website") ?? false) projectUrl = ((JsonElement)tokenItem.Extensions["website"]).GetString();
12!
166

167
            // construct the TokenDef instance
168
            var token = new TokenDef(tokenItem.Address, tokenItem.Name, tokenItem.Symbol, tokenItem.Decimals)
6✔
169
            {
6✔
170
                CoinGeckoId = coingeckoId,
6✔
171
                TokenLogoUrl = logoUrl,
6✔
172
                TokenProjectUrl = projectUrl
6✔
173
            };
6✔
174

175
            // stash it
176
            _tokens[token.TokenMint] = token;
6✔
177
        }
6✔
178

179

180
    }
181

182
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc