@@ -4,15 +4,15 @@ import (
44 "cmp"
55 "context"
66 "fmt"
7+ "log"
8+ "slices"
9+
710 "github.com/jellydator/ttlcache/v3"
8- "github.com/pkg/errors"
911 qubic "github.com/qubic/go-node-connector"
1012 "github.com/qubic/go-node-connector/types"
1113 "github.com/qubic/qubic-stats-api/protobuff"
1214 "google.golang.org/grpc/codes"
1315 "google.golang.org/grpc/status"
14- "log"
15- "slices"
1616)
1717
1818type AssetService interface {
@@ -65,7 +65,7 @@ func (s *AssetServiceImpl) GetOwnedAssets(ctx context.Context, issuerIdentity, a
6565 var owner types.Identity
6666 owner , err := owner .FromPubKey (asset .Asset .PublicKey , false )
6767 if err != nil {
68- return nil , 0 , - 1 , errors . Wrap ( err , "failed to get identity for public key" )
68+ return nil , 0 , - 1 , fmt . Errorf ( "failed to get identity for public key: %w" , err )
6969 }
7070
7171 assetOwnership := protobuff.AssetOwnership {
@@ -92,6 +92,10 @@ func (s *AssetServiceImpl) getAssetOwners(ctx context.Context, issuerIdentity, a
9292 if err != nil {
9393 return nil , err
9494 }
95+ queriedAssets , err = combineEntriesForSameIdentity (* queriedAssets )
96+ if err != nil {
97+ return nil , err
98+ }
9599 if len (* queriedAssets ) > 0 {
96100 // we only cache queries that return data
97101 s .assetOwnerCache .Set (key , queriedAssets , ttlcache .DefaultTTL )
@@ -101,15 +105,46 @@ func (s *AssetServiceImpl) getAssetOwners(ctx context.Context, issuerIdentity, a
101105 return assets , nil
102106}
103107
108+ // combineEntriesForSameIdentity there might be several entries for one identity and different managing contracts
109+ func combineEntriesForSameIdentity (ownerships []types.AssetOwnership ) (* types.AssetOwnerships , error ) {
110+ var identityMap = make (map [[32 ]byte ]* types.AssetOwnership )
111+
112+ // combine multiple ownerships for the same identity into one
113+ for _ , ownership := range ownerships {
114+ val , found := identityMap [ownership .Asset .PublicKey ]
115+ if ! found {
116+ identityMap [ownership .Asset .PublicKey ] = & ownership
117+ } else {
118+ val .Asset .NumberOfUnits += ownership .Asset .NumberOfUnits
119+ }
120+ }
121+
122+ // create combined ownership list
123+ var combined = make (types.AssetOwnerships , 0 , len (identityMap ))
124+ for _ , v := range identityMap {
125+ combined = append (combined , * v )
126+ }
127+
128+ slices .SortFunc (combined , func (a , b types.AssetOwnership ) int {
129+ if a .Asset .NumberOfUnits > b .Asset .NumberOfUnits {
130+ return - 1 // reverse sort
131+ } else {
132+ return 1
133+ }
134+ })
135+
136+ return & combined , nil
137+ }
138+
104139func (s * AssetServiceImpl ) getAssetOwnersFromNode (ctx context.Context , identity string , name string ) (* types.AssetOwnerships , error ) {
105140 client , err := s .qPool .Get ()
106141 if err != nil {
107- return nil , errors . Wrap ( err , "getting pool connection" )
142+ return nil , fmt . Errorf ( "getting pool connection: %w" , err )
108143 }
109144 assets , err := client .GetAssetOwnershipsByFilter (ctx , identity , name , "" , 0 )
110145 if err != nil {
111146 _ = s .qPool .Close (client )
112- return nil , errors . Wrap ( err , "getting asset ownerships" )
147+ return nil , fmt . Errorf ( "getting asset ownerships: %w" , err )
113148 }
114149 err = s .qPool .Put (client )
115150 if err != nil {
0 commit comments