diff --git a/Sources/KukaiCoreSwift/Clients/TzKTClient.swift b/Sources/KukaiCoreSwift/Clients/TzKTClient.swift index 4498a0e..48920fe 100644 --- a/Sources/KukaiCoreSwift/Clients/TzKTClient.swift +++ b/Sources/KukaiCoreSwift/Clients/TzKTClient.swift @@ -923,7 +923,7 @@ public class TzKTClient { continue } else if balance.token.metadata != nil { // Else create a Token object and put into array, if we have valid metadata (e.g. able to tell how many decimals it has) - tokens.append(Token(from: balance.token, andTokenAmount: balance.tokenAmount)) + tokens.append(Token(from: balance, andTokenAmount: balance.tokenAmount)) } } diff --git a/Sources/KukaiCoreSwift/Models/BakingBad/TzKTBalance.swift b/Sources/KukaiCoreSwift/Models/BakingBad/TzKTBalance.swift index be66298..aba0984 100644 --- a/Sources/KukaiCoreSwift/Models/BakingBad/TzKTBalance.swift +++ b/Sources/KukaiCoreSwift/Models/BakingBad/TzKTBalance.swift @@ -21,6 +21,12 @@ public struct TzKTBalance: Codable { /// Details about the Token public let token: TzKTBalanceToken + /// The block level where the token was first seen + public let firstLevel: Decimal + + /// The block level where the token was last seen + public let lastLevel: Decimal + /// Helper to convert the RPC token balance to a `TokenAmount` object public var tokenAmount: TokenAmount { return TokenAmount(fromRpcAmount: balance, decimalPlaces: token.metadata?.decimalsInt ?? 0) ?? .zero() diff --git a/Sources/KukaiCoreSwift/Models/NFT.swift b/Sources/KukaiCoreSwift/Models/NFT.swift index 955eb23..bdcebee 100644 --- a/Sources/KukaiCoreSwift/Models/NFT.swift +++ b/Sources/KukaiCoreSwift/Models/NFT.swift @@ -64,6 +64,12 @@ public struct NFT: Codable, Hashable { return favouriteSortIndex != nil } + /// The block level where the token was first seen + public var firstlevel: Decimal + + /// The block level where the token was last seen + public var lastLevel: Decimal + /** Create a more developer friednly `NFT` from a generic `TzKTBalance` object @@ -83,6 +89,8 @@ public struct NFT: Codable, Hashable { displayURI = URL(string: tzkt.token.metadata?.displayUri ?? "") thumbnailURI = URL(string: tzkt.token.metadata?.thumbnailUri ?? "") metadata = tzkt.token.metadata + firstlevel = tzkt.firstLevel + lastLevel = tzkt.lastLevel } /// Confomring to Equatable diff --git a/Sources/KukaiCoreSwift/Models/Token.swift b/Sources/KukaiCoreSwift/Models/Token.swift index 3eee7a5..b529d3c 100644 --- a/Sources/KukaiCoreSwift/Models/Token.swift +++ b/Sources/KukaiCoreSwift/Models/Token.swift @@ -87,6 +87,12 @@ public class Token: Codable, CustomStringConvertible { /// Recording if the position the index the user chose for the favourite token to appear public var favouriteSortIndex: Int? = nil + /// The block level where the token was first seen + public var firstlevel: Decimal + + /// The block level where the token was last seen + public var lastLevel: Decimal + /// The individual NFT's owned of this token type public var nfts: [NFT]? @@ -126,6 +132,8 @@ public class Token: Codable, CustomStringConvertible { self.tokenId = tokenId self.nfts = nfts self.mintingTool = mintingTool + self.firstlevel = 0 + self.lastLevel = 0 // TODO: make failable init if let faVersion = faVersion, faVersion == .fa2 && tokenId == nil { @@ -136,23 +144,25 @@ public class Token: Codable, CustomStringConvertible { /** Init a `Token` from an object returned by the TzKT API */ - public init(from: TzKTBalanceToken, andTokenAmount: TokenAmount, stakedTokenAmount: TokenAmount? = nil, unstakedTokenAmount: TokenAmount? = nil) { - let decimalsString = from.metadata?.decimals ?? "0" + public init(from: TzKTBalance, andTokenAmount: TokenAmount, stakedTokenAmount: TokenAmount? = nil, unstakedTokenAmount: TokenAmount? = nil) { + let decimalsString = from.token.metadata?.decimals ?? "0" let decimalsInt = Int(decimalsString) ?? 0 - let isNFT = (from.metadata?.artifactUri != nil && decimalsInt == 0 && from.standard == .fa2) + let isNFT = (from.token.metadata?.artifactUri != nil && decimalsInt == 0 && from.token.standard == .fa2) - self.name = from.contract.alias - self.symbol = isNFT ? from.contract.alias ?? "" : from.displaySymbol + self.name = from.token.contract.alias + self.symbol = isNFT ? from.token.contract.alias ?? "" : from.token.displaySymbol self.tokenType = isNFT ? .nonfungible : .fungible - self.faVersion = from.standard + self.faVersion = from.token.standard self.balance = andTokenAmount self.stakedBalance = stakedTokenAmount ?? .zeroBalance(decimalPlaces: andTokenAmount.decimalPlaces) self.unstakedBalance = unstakedTokenAmount ?? .zeroBalance(decimalPlaces: andTokenAmount.decimalPlaces) - self.thumbnailURL = from.metadata?.thumbnailURL ?? TzKTClient.avatarURL(forToken: from.contract.address) - self.tokenContractAddress = from.contract.address - self.tokenId = Decimal(string: from.tokenId) ?? 0 + self.thumbnailURL = from.token.metadata?.thumbnailURL ?? TzKTClient.avatarURL(forToken: from.token.contract.address) + self.tokenContractAddress = from.token.contract.address + self.tokenId = Decimal(string: from.token.tokenId) ?? 0 self.nfts = [] - self.mintingTool = from.metadata?.mintingTool + self.mintingTool = from.token.metadata?.mintingTool + self.firstlevel = from.firstLevel + self.lastLevel = from.lastLevel // TODO: make failable init if let faVersion = faVersion, faVersion == .fa2 && tokenId == nil { @@ -183,6 +193,8 @@ public class Token: Codable, CustomStringConvertible { self.tokenId = Decimal(string: from.token.tokenId) ?? 0 self.nfts = [] self.mintingTool = from.mintingTool + self.firstlevel = from.level + self.lastLevel = from.level // TODO: make failable init if let faVersion = faVersion, faVersion == .fa2 && tokenId == nil { diff --git a/Tests/KukaiCoreSwiftTests/MockConstants.swift b/Tests/KukaiCoreSwiftTests/MockConstants.swift index c550eca..cffef78 100644 --- a/Tests/KukaiCoreSwiftTests/MockConstants.swift +++ b/Tests/KukaiCoreSwiftTests/MockConstants.swift @@ -413,7 +413,7 @@ public struct MockConstants { public static let token10Decimals = Token(name: "Token 10 decimals", symbol: "TK10", tokenType: .fungible, faVersion: .fa2, balance: TokenAmount.zero(), thumbnailURL: nil, tokenContractAddress: "KT1G1cCRNBgQ48mVDjopHjEmTN5Sbtar8nn9", tokenId: 0, nfts: nil, mintingTool: nil) public static let nftMetadata = TzKTBalanceMetadata(name: "NFT Name", symbol: "NFT", decimals: "0", formats: nil, displayUri: MediaProxySerivceTests.ipfsURIWithoutExtension, artifactUri: nil, thumbnailUri: MediaProxySerivceTests.ipfsURIWithExtension, description: "A sample description", mintingTool: nil, tags: nil, minter: nil, shouldPreferSymbol: nil, attributes: nil, ttl: nil) public static let tokenWithNFTs = Token(name: "Token with NFTS", symbol: "T-NFT", tokenType: .nonfungible, faVersion: .fa2, balance: TokenAmount.zero(), thumbnailURL: nil, tokenContractAddress: "KT1G1cCRNBgQ48mVDjopHjEmTN5Sbtabc123", tokenId: 0, nfts: [ - NFT(fromTzKTBalance: TzKTBalance(balance: "1", token: TzKTBalanceToken(contract: TzKTAddress(alias: nil, address: "KT1G1cCRNBgQ48mVDjopHjEmTN5Sbtabc123"), tokenId: "4", standard: .fa2, totalSupply: "1", metadata: MockConstants.nftMetadata))) + NFT(fromTzKTBalance: TzKTBalance(balance: "1", token: TzKTBalanceToken(contract: TzKTAddress(alias: nil, address: "KT1G1cCRNBgQ48mVDjopHjEmTN5Sbtabc123"), tokenId: "4", standard: .fa2, totalSupply: "1", metadata: MockConstants.nftMetadata), firstLevel: 0, lastLevel: 0)) ], mintingTool: nil) diff --git a/Tests/KukaiCoreSwiftTests/Models/TokenTests.swift b/Tests/KukaiCoreSwiftTests/Models/TokenTests.swift index 4cd52dd..3d03cf5 100644 --- a/Tests/KukaiCoreSwiftTests/Models/TokenTests.swift +++ b/Tests/KukaiCoreSwiftTests/Models/TokenTests.swift @@ -21,7 +21,7 @@ class TokenTests: XCTestCase { func testToken() { let token = Token(name: "test1", symbol: "T", tokenType: .fungible, faVersion: .fa1_2, balance: TokenAmount(fromNormalisedAmount: 3, decimalPlaces: 4), thumbnailURL: URL(string: "ipfs://abcdefgh1234"), tokenContractAddress: "KT1abc", tokenId: nil, nfts: nil, mintingTool: nil) - let tzktBalance = TzKTBalance(balance: "1", token: TzKTBalanceToken(contract: TzKTAddress(alias: "Test Alias", address: "KT1abc"), tokenId: "0", standard: .fa2, totalSupply: "1", metadata: nil)) + let tzktBalance = TzKTBalance(balance: "1", token: TzKTBalanceToken(contract: TzKTAddress(alias: "Test Alias", address: "KT1abc"), tokenId: "0", standard: .fa2, totalSupply: "1", metadata: nil), firstLevel: 0, lastLevel: 0) let nft = NFT(fromTzKTBalance: tzktBalance) let token2 = Token(name: "test2", symbol: "F", tokenType: .nonfungible, faVersion: .fa2, balance: TokenAmount.zero(), thumbnailURL: URL(string: "ipfs://abcdefgh1234"), tokenContractAddress: "KT1abc", tokenId: 0, nfts: [nft], mintingTool: nil) diff --git a/Tests/KukaiCoreSwiftTests/Models/TzKTTransactionTests.swift b/Tests/KukaiCoreSwiftTests/Models/TzKTTransactionTests.swift index 0be2ccf..3c8ec05 100644 --- a/Tests/KukaiCoreSwiftTests/Models/TzKTTransactionTests.swift +++ b/Tests/KukaiCoreSwiftTests/Models/TzKTTransactionTests.swift @@ -97,7 +97,7 @@ final class TzKTTransactionTests: XCTestCase { transaction.processAdditionalData(withCurrentWalletAddress: "tz1abc") if let json = try? JSONEncoder().encode(transaction), let jsonString = String(data: json, encoding: .utf8) { - XCTAssert(jsonString.count == 944, jsonString.count.description) + XCTAssert(jsonString.count == 973, jsonString.count.description) } else { XCTFail() }