solrengine-tokens 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 930e4472835da1e01f1a9eafbb31d5c46d1921259b398b99ae15f33df17de693
4
- data.tar.gz: a398418d46fb4a10c6660594c97f0e77885cb56c0a3ae9a6830ce119d7fc34dc
3
+ metadata.gz: d2767d22284ff63196054807b027476d82ca371eb63d5090850e068379e54b72
4
+ data.tar.gz: c1428d90b5a6e24258b344d56a8057d5a02f886747dabe17c835dbf0f42fe2f1
5
5
  SHA512:
6
- metadata.gz: 55f0eb6392f6b58407ebf1c7dcf3dda97f7d04b04ac62fcbd2c798cb2e8c9281b95b46bf5b9e921016199f11972d20e38bc346fc1fd11a4d408b7b55727acce6
7
- data.tar.gz: 230707c3b92e98b0e9c055d3442573f68c9de2daed4067e118d25096d11af24981bb4e2005e47be8474c10ef3c41ab8616f1b3d0b20aa53c635477bcccca3065
6
+ metadata.gz: 73dcb287ca0d899db885be96cb5f60c361182049f17ca1636b747661f71e517162bf83257ad069ef4b14b61a3e0af2a5c2958237d9fe9a1bb7c35206b4a5e1cd
7
+ data.tar.gz: 7009ac920ba69fe8d22591e5fc5e1fc11a47600f6e0b3474d0b7e9560d8db05c710f2b91343e8de999af8e806310714572306ddc2c1afb4b764ea0d17eca5f3e
data/README.md CHANGED
@@ -12,7 +12,7 @@ gem "solrengine-tokens"
12
12
 
13
13
  ```bash
14
14
  rails generate solrengine:tokens:install
15
- rails db:migrate
15
+ rails db:prepare
16
16
  ```
17
17
 
18
18
  ## Configuration
@@ -39,6 +39,16 @@ portfolio.total_usd_value # => 1847.63
39
39
  portfolio.recent_transactions # => [{ signature:, block_time:, ... }]
40
40
  ```
41
41
 
42
+ NFTs owned by the wallet, via the Metaplex DAS API:
43
+
44
+ ```ruby
45
+ portfolio.nfts # => [{ id:, name: "Mad Lad #1234", image: "https://...", collection: "...", compressed: false }, ...]
46
+ ```
47
+
48
+ > **Note:** `Portfolio#nfts` uses the DAS `getAssetsByOwner` method, which requires a
49
+ > DAS-capable RPC endpoint (Helius, Triton, ...). The public `api.*.solana.com`
50
+ > endpoints do not serve DAS — on those, the call degrades to an empty list.
51
+
42
52
  Token metadata is fetched once from Jupiter and persisted:
43
53
 
44
54
  ```ruby
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solrengine
4
+ module Tokens
5
+ # Fetches Metaplex NFTs owned by a wallet via the DAS API
6
+ # (getAssetsByOwner). Requires a DAS-capable RPC endpoint (Helius,
7
+ # Triton, etc.) — the public Solana endpoints do not serve DAS.
8
+ class NftService
9
+ NFT_INTERFACES = [ "V1_NFT", "V2_NFT", "ProgrammableNFT", "LEGACY_NFT", "MplCoreAsset" ].freeze
10
+
11
+ def initialize
12
+ @client = Solrengine::Rpc.client
13
+ end
14
+
15
+ def nfts_for(wallet_address, page: 1, limit: 50)
16
+ response = @client.request("getAssetsByOwner", {
17
+ ownerAddress: wallet_address,
18
+ page: page,
19
+ limit: limit
20
+ })
21
+
22
+ items = response.dig("result", "items") || []
23
+ items.filter_map { |asset| build_entry(asset) }
24
+ end
25
+
26
+ private
27
+
28
+ def build_entry(asset)
29
+ return nil unless NFT_INTERFACES.include?(asset["interface"])
30
+
31
+ metadata = asset.dig("content", "metadata") || {}
32
+
33
+ {
34
+ id: asset["id"],
35
+ name: metadata["name"].presence || "Unknown",
36
+ symbol: metadata["symbol"],
37
+ description: metadata["description"],
38
+ image: image_for(asset),
39
+ collection: collection_for(asset),
40
+ compressed: asset.dig("compression", "compressed") || false,
41
+ interface: asset["interface"]
42
+ }
43
+ end
44
+
45
+ def image_for(asset)
46
+ asset.dig("content", "links", "image") ||
47
+ (asset.dig("content", "files") || []).find { |f| f["mime"].to_s.start_with?("image/") }&.dig("uri")
48
+ end
49
+
50
+ def collection_for(asset)
51
+ grouping = (asset["grouping"] || []).find { |g| g["group_key"] == "collection" }
52
+ grouping && grouping["group_value"]
53
+ end
54
+ end
55
+ end
56
+ end
@@ -18,6 +18,12 @@ module Solrengine
18
18
  tokens.sum { |t| t[:usd_value] || 0 }
19
19
  end
20
20
 
21
+ def nfts(page: 1, limit: 50)
22
+ Solrengine::Tokens.cache_fetch("solrengine_tokens/wallet/#{@wallet_address}/nfts", expires_in: 60) do
23
+ NftService.new.nfts_for(@wallet_address, page: page, limit: limit)
24
+ end
25
+ end
26
+
21
27
  def recent_transactions(limit: 5)
22
28
  Solrengine::Tokens.cache_fetch("solrengine_tokens/wallet/#{@wallet_address}/recent_txs", expires_in: 30) do
23
29
  Solrengine::Rpc.client.get_recent_signatures(@wallet_address, limit: limit)
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Solrengine
4
4
  module Tokens
5
- VERSION = "0.1.0"
5
+ VERSION = "0.2.0"
6
6
  end
7
7
  end
@@ -2,6 +2,7 @@ require "solrengine/rpc"
2
2
  require_relative "tokens/version"
3
3
  require_relative "tokens/jupiter_client"
4
4
  require_relative "tokens/token_metadata_service"
5
+ require_relative "tokens/nft_service"
5
6
  require_relative "tokens/portfolio"
6
7
  require_relative "tokens/engine" if defined?(Rails::Engine)
7
8
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: solrengine-tokens
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jose Ferrer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-03-21 00:00:00.000000000 Z
11
+ date: 2026-07-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -53,6 +53,7 @@ files:
53
53
  - lib/solrengine/tokens.rb
54
54
  - lib/solrengine/tokens/engine.rb
55
55
  - lib/solrengine/tokens/jupiter_client.rb
56
+ - lib/solrengine/tokens/nft_service.rb
56
57
  - lib/solrengine/tokens/portfolio.rb
57
58
  - lib/solrengine/tokens/token_metadata_service.rb
58
59
  - lib/solrengine/tokens/version.rb