From a2f0364de50fbef075929ba9850e161f2b81148f Mon Sep 17 00:00:00 2001 From: bluezdot <72647326+bluezdot@users.noreply.github.com> Date: Tue, 18 Jun 2024 09:54:21 +0700 Subject: [PATCH 01/17] [Issue-182] Handle get current address inscription for NftHandler --- .../extension-base/src/koni/api/nft/index.ts | 8 +++-- .../src/koni/api/nft/inscription/index.ts | 3 +- .../extension-base/src/koni/api/nft/nft.ts | 3 +- .../src/koni/background/handlers/State.ts | 3 ++ .../src/koni/background/subscription.ts | 19 ++++++----- .../src/services/hiro-service/utils/index.ts | 33 +++++-------------- .../storage-service/DatabaseService.ts | 4 +++ .../services/storage-service/db-stores/Nft.ts | 8 +++++ 8 files changed, 43 insertions(+), 38 deletions(-) diff --git a/packages/extension-base/src/koni/api/nft/index.ts b/packages/extension-base/src/koni/api/nft/index.ts index 4acf9f3230..3f40c39d21 100644 --- a/packages/extension-base/src/koni/api/nft/index.ts +++ b/packages/extension-base/src/koni/api/nft/index.ts @@ -75,7 +75,7 @@ const createOrdinalApi = (chain: string, subscanChain: string, addresses: string return new OrdinalNftApi(addresses, chain, subscanChain); }; -export class NftHandler { +export class NftService { // General settings chainInfoMap: Record = {}; addresses: string[] = []; @@ -203,13 +203,15 @@ export class NftHandler { public async handleNfts ( nftContracts: _ChainAsset[], updateItem: (chain: string, data: NftItem, owner: string) => void, - updateCollection: (chain: string, data: NftCollection) => void) { + updateCollection: (chain: string, data: NftCollection) => void, + getOffset?: (address: string) => Promise) { this.setupApi(); this.setupNftContracts(nftContracts); await Promise.all(this.handlers.map(async (handler) => { await handler.fetchNfts({ updateItem, - updateCollection + updateCollection, + getOffset }); })); } diff --git a/packages/extension-base/src/koni/api/nft/inscription/index.ts b/packages/extension-base/src/koni/api/nft/inscription/index.ts index a078520642..4d854d0f94 100644 --- a/packages/extension-base/src/koni/api/nft/inscription/index.ts +++ b/packages/extension-base/src/koni/api/nft/inscription/index.ts @@ -126,7 +126,8 @@ export class InscriptionApi extends BaseNftApi { public async handleNfts (params: HandleNftParams) { try { await Promise.all(this.addresses.map(async (address) => { - const balances = await getAddressInscriptions(address); + const offset = params.getOffset && await params.getOffset(address); + const balances = await getAddressInscriptions(address, offset); if (balances.length > 0) { const collectionMap: Record = {}; diff --git a/packages/extension-base/src/koni/api/nft/nft.ts b/packages/extension-base/src/koni/api/nft/nft.ts index 396265a172..7af49e6742 100644 --- a/packages/extension-base/src/koni/api/nft/nft.ts +++ b/packages/extension-base/src/koni/api/nft/nft.ts @@ -7,7 +7,8 @@ import { baseParseIPFSUrl } from '@subwallet/extension-base/utils'; export interface HandleNftParams { updateItem: (chain: string, data: NftItem, owner: string) => void, - updateCollection: (chain: string, data: NftCollection) => void + updateCollection: (chain: string, data: NftCollection) => void, + getOffset?: (address: string) => Promise } export abstract class BaseNftApi { diff --git a/packages/extension-base/src/koni/background/handlers/State.ts b/packages/extension-base/src/koni/background/handlers/State.ts index ff065cb705..9471405cd6 100644 --- a/packages/extension-base/src/koni/background/handlers/State.ts +++ b/packages/extension-base/src/koni/background/handlers/State.ts @@ -8,6 +8,7 @@ import { isSubscriptionRunning, unsubscribe } from '@subwallet/extension-base/ba import { AccountRefMap, AddTokenRequestExternal, AmountData, APIItemState, ApiMap, AuthRequestV2, BasicTxErrorType, ChainStakingMetadata, ChainType, ConfirmationsQueue, CrowdloanItem, CrowdloanJson, CurrentAccountInfo, CurrentAccountProxyInfo, EvmProviderErrorType, EvmSendTransactionParams, EvmSendTransactionRequest, EvmSignatureRequest, ExternalRequestPromise, ExternalRequestPromiseStatus, ExtrinsicType, MantaAuthorizationContext, MantaPayConfig, MantaPaySyncState, NftCollection, NftItem, NftJson, NominatorMetadata, RequestAccountExportPrivateKey, RequestCheckPublicAndSecretKey, RequestConfirmationComplete, RequestConfirmationCompleteBitcoin, RequestCrowdloanContributions, RequestSettingsType, ResponseAccountExportPrivateKey, ResponseCheckPublicAndSecretKey, ServiceInfo, SingleModeJson, StakingItem, StakingJson, StakingRewardItem, StakingRewardJson, StakingType, UiSettings } from '@subwallet/extension-base/background/KoniTypes'; import { AccountJson, RequestAuthorizeTab, RequestRpcSend, RequestRpcSubscribe, RequestRpcUnsubscribe, RequestSign, ResponseRpcListProviders, ResponseSigning } from '@subwallet/extension-base/background/types'; import { ALL_ACCOUNT_KEY, ALL_GENESIS_HASH, MANTA_PAY_BALANCE_INTERVAL } from '@subwallet/extension-base/constants'; +import { NftService } from '@subwallet/extension-base/koni/api/nft'; import { BalanceService } from '@subwallet/extension-base/services/balance-service'; import { ServiceStatus } from '@subwallet/extension-base/services/base/types'; import BuyService from '@subwallet/extension-base/services/buy-service'; @@ -136,6 +137,7 @@ export default class KoniState { readonly buyService: BuyService; readonly earningService: EarningService; readonly feeService: FeeService; + readonly nftService: NftService; // Handle the general status of the extension private generalStatus: ServiceStatus = ServiceStatus.INITIALIZING; @@ -166,6 +168,7 @@ export default class KoniState { this.transactionService = new TransactionService(this); this.earningService = new EarningService(this); this.feeService = new FeeService(this); + this.nftService = new NftService(); this.subscription = new KoniSubscription(this, this.dbService); this.cron = new KoniCron(this, this.subscription, this.dbService); diff --git a/packages/extension-base/src/koni/background/subscription.ts b/packages/extension-base/src/koni/background/subscription.ts index aea4c35568..2910faa328 100644 --- a/packages/extension-base/src/koni/background/subscription.ts +++ b/packages/extension-base/src/koni/background/subscription.ts @@ -3,7 +3,7 @@ import { _ChainAsset, _ChainInfo } from '@subwallet/chain-list/types'; import { subscribeCrowdloan } from '@subwallet/extension-base/koni/api/dotsama/crowdloan'; -import { NftHandler } from '@subwallet/extension-base/koni/api/nft'; +import { NftService } from '@subwallet/extension-base/koni/api/nft'; import { _EvmApi, _SubstrateApi } from '@subwallet/extension-base/services/chain-service/types'; import { COMMON_RELOAD_EVENTS, EventItem, EventType } from '@subwallet/extension-base/services/event-service/types'; import DatabaseService from '@subwallet/extension-base/services/storage-service/DatabaseService'; @@ -16,8 +16,6 @@ import KoniState from './handlers/State'; type SubscriptionName = 'balance' | 'crowdloan' | 'yieldPoolStats' | 'yieldPosition'; -const nftHandler = new NftHandler(); - export class KoniSubscription { private eventHandler?: (events: EventItem[], eventTypes: EventType[]) => void; private subscriptionMap: Record void) | undefined> = { @@ -30,11 +28,13 @@ export class KoniSubscription { public dbService: DatabaseService; private state: KoniState; private logger: Logger; + private nftService: NftService; constructor (state: KoniState, dbService: DatabaseService) { this.dbService = dbService; this.state = state; this.logger = createLogger('Subscription'); + this.nftService = this.state.nftService; } getSubscriptionMap () { @@ -142,15 +142,16 @@ export class KoniSubscription { } initNftSubscription (addresses: string[], substrateApiMap: Record, evmApiMap: Record, smartContractNfts: _ChainAsset[], chainInfoMap: Record) { - nftHandler.setChainInfoMap(chainInfoMap); - nftHandler.setDotSamaApiMap(substrateApiMap); - nftHandler.setWeb3ApiMap(evmApiMap); - nftHandler.setAddresses(addresses); + this.nftService.setChainInfoMap(chainInfoMap); + this.nftService.setDotSamaApiMap(substrateApiMap); + this.nftService.setWeb3ApiMap(evmApiMap); + this.nftService.setAddresses(addresses); - nftHandler.handleNfts( + this.nftService.handleNfts( smartContractNfts, (...args) => this.state.updateNftData(...args), - (...args) => this.state.setNftCollection(...args) + (...args) => this.state.setNftCollection(...args), + (address: string) => this.dbService.getAddressTotalNfts([address]) ).catch(this.logger.log); } diff --git a/packages/extension-base/src/services/hiro-service/utils/index.ts b/packages/extension-base/src/services/hiro-service/utils/index.ts index a46ecbe3e4..42de05a119 100644 --- a/packages/extension-base/src/services/hiro-service/utils/index.ts +++ b/packages/extension-base/src/services/hiro-service/utils/index.ts @@ -1,7 +1,7 @@ // Copyright 2019-2022 @subwallet/extension-base authors & contributors // SPDX-License-Identifier: Apache-2.0 -import { Brc20Metadata, Inscription, InscriptionFetchedData } from '@subwallet/extension-base/services/chain-service/handler/bitcoin/strategy/BlockStream/types'; +import { Brc20Metadata, InscriptionFetchedData } from '@subwallet/extension-base/services/chain-service/handler/bitcoin/strategy/BlockStream/types'; import { HiroService } from '@subwallet/extension-base/services/hiro-service'; // todo: handle inscription testnet @@ -44,34 +44,19 @@ export async function getInscriptionContent (inscriptionId: string) { } // todo: handle large inscriptions -export async function getAddressInscriptions (address: string, isCompress = true) { - const inscriptionsFullList: Inscription[] = []; - const pageSize = 60; - let offset = 0; - +export async function getAddressInscriptions (address: string, offset = 0, limit = 25) { const hiroService = HiroService.getInstance(); try { - while (true) { - const response = await hiroService.getAddressInscriptionsInfo({ - limit: String(pageSize), - offset: String(offset), - address: String(address) - }) as unknown as InscriptionFetchedData; - - const inscriptions = response.results; - - if (inscriptions.length !== 0 && !(isCompress && offset >= 360)) { - inscriptionsFullList.push(...inscriptions); - offset += pageSize; - } else { - break; - } - } + const response = await hiroService.getAddressInscriptionsInfo({ + limit: String(limit), + offset: String(offset), + address: String(address) + }) as unknown as InscriptionFetchedData; - return inscriptionsFullList; + return response.results; } catch (error) { - console.error(`Failed to get ${address} inscriptions`, error); + console.error(`Failed to get ${address} inscriptions with offset ${offset} and limit ${limit}`, error); throw error; } } diff --git a/packages/extension-base/src/services/storage-service/DatabaseService.ts b/packages/extension-base/src/services/storage-service/DatabaseService.ts index a47b710f68..f11e34b352 100644 --- a/packages/extension-base/src/services/storage-service/DatabaseService.ts +++ b/packages/extension-base/src/services/storage-service/DatabaseService.ts @@ -214,6 +214,10 @@ export default class DatabaseService { return this.stores.nft.cleanUpNfts(chain, reformatAddress(owner, 42), collectionIds, nftIds); } + async getAddressTotalNfts (addresses: string[], chainHashes?: string[]) { + return this.stores.nft.getAddressTotalNfts(addresses, chainHashes); + } + async getNft (addresses: string[], chainHashes?: string[]) { return this.stores.nft.getNft(addresses, chainHashes); } diff --git a/packages/extension-base/src/services/storage-service/db-stores/Nft.ts b/packages/extension-base/src/services/storage-service/db-stores/Nft.ts index 696cfe9e10..f77348af09 100644 --- a/packages/extension-base/src/services/storage-service/db-stores/Nft.ts +++ b/packages/extension-base/src/services/storage-service/db-stores/Nft.ts @@ -8,6 +8,14 @@ import { liveQuery } from 'dexie'; import { INft } from '../databases'; export default class NftStore extends BaseStoreWithAddressAndChain { + getAddressTotalNfts (addresses: string[], chainList: string[] = []) { + if (addresses.length) { + return this.table.where('address').anyOfIgnoreCase(addresses).and((item) => chainList && chainList.includes(item.chain)).count(); + } + + return this.table.filter((item) => chainList && chainList.includes(item.chain)).count(); + } + getNft (addresses: string[], chainList: string[] = []) { if (addresses.length) { return this.table.where('address').anyOfIgnoreCase(addresses).and((item) => chainList && chainList.includes(item.chain)).toArray(); From 06951547e32508c039456465e54f8ee84b407c4b Mon Sep 17 00:00:00 2001 From: bluezdot <72647326+bluezdot@users.noreply.github.com> Date: Tue, 18 Jun 2024 10:32:59 +0700 Subject: [PATCH 02/17] [Issue-182] Handle action load more inscription --- .../extension-base/src/background/KoniTypes.ts | 1 + packages/extension-base/src/koni/api/nft/index.ts | 14 ++++++++++++++ .../src/koni/background/handlers/Extension.ts | 8 ++++++++ .../src/koni/background/handlers/State.ts | 8 ++++++++ .../src/messaging/transaction/nft.ts | 4 ++++ 5 files changed, 35 insertions(+) diff --git a/packages/extension-base/src/background/KoniTypes.ts b/packages/extension-base/src/background/KoniTypes.ts index 48e5ba99e7..cc65b75455 100644 --- a/packages/extension-base/src/background/KoniTypes.ts +++ b/packages/extension-base/src/background/KoniTypes.ts @@ -2278,6 +2278,7 @@ export interface KoniRequestSignatures { 'pri(assetSetting.update)': [AssetSettingUpdateReq, boolean]; // NFT functions + 'pri(inscription.loadMoreInscription)': [null, null] 'pri(evmNft.submitTransaction)': [NftTransactionRequest, SWTransactionResponse]; 'pri(evmNft.getTransaction)': [NftTransactionRequest, EvmNftTransaction]; 'pri(substrateNft.submitTransaction)': [NftTransactionRequest, SWTransactionResponse]; diff --git a/packages/extension-base/src/koni/api/nft/index.ts b/packages/extension-base/src/koni/api/nft/index.ts index 3f40c39d21..532b4dac12 100644 --- a/packages/extension-base/src/koni/api/nft/index.ts +++ b/packages/extension-base/src/koni/api/nft/index.ts @@ -215,4 +215,18 @@ export class NftService { }); })); } + + public async loadMoreNfts ( + updateItem: (chain: string, data: NftItem, owner: string) => void, + updateCollection: (chain: string, data: NftCollection) => void, + getOffset?: (address: string) => Promise + ) { + await Promise.all(this.handlers.map(async (handler) => { + await handler.fetchNfts({ + updateItem, + updateCollection, + getOffset + }); + })); + } } diff --git a/packages/extension-base/src/koni/background/handlers/Extension.ts b/packages/extension-base/src/koni/background/handlers/Extension.ts index 9511e694a0..d7afff0207 100644 --- a/packages/extension-base/src/koni/background/handlers/Extension.ts +++ b/packages/extension-base/src/koni/background/handlers/Extension.ts @@ -2135,6 +2135,10 @@ export default class KoniExtension { }); } + private loadMoreInscription () { + this.#koniState.loadMoreInscription(); + } + private async evmNftSubmitTransaction (inputData: NftTransactionRequest): Promise { const { networkKey, params, recipientAddress, senderAddress } = inputData; const contractAddress = params.contractAddress as string; @@ -5373,6 +5377,10 @@ export default class KoniExtension { case 'pri(accounts.get.meta)': return this.getAccountMeta(request as RequestAccountMeta); + // Load more Inscriptions + case 'pri(inscription.loadMoreInscription)': + return this.loadMoreInscription(); + /// Send NFT case 'pri(evmNft.submitTransaction)': return this.evmNftSubmitTransaction(request as NftTransactionRequest); diff --git a/packages/extension-base/src/koni/background/handlers/State.ts b/packages/extension-base/src/koni/background/handlers/State.ts index 9471405cd6..e50c12e1f9 100644 --- a/packages/extension-base/src/koni/background/handlers/State.ts +++ b/packages/extension-base/src/koni/background/handlers/State.ts @@ -501,6 +501,14 @@ export default class KoniState { this.dbService.updateNominatorMetadata(item).catch((e) => this.logger.warn(e)); } + public loadMoreInscription () { + this.nftService.loadMoreNfts( + (...args) => this.updateNftData(...args), + (...args) => this.setNftCollection(...args), + (address: string) => this.dbService.getAddressTotalNfts([address]) + ).catch(this.logger.log); + } + public setNftCollection (network: string, data: NftCollection, callback?: (data: NftCollection) => void): void { this.dbService.addNftCollection(data).catch((e) => this.logger.warn(e)); callback && callback(data); diff --git a/packages/extension-koni-ui/src/messaging/transaction/nft.ts b/packages/extension-koni-ui/src/messaging/transaction/nft.ts index f963c382d9..e7b03fb292 100644 --- a/packages/extension-koni-ui/src/messaging/transaction/nft.ts +++ b/packages/extension-koni-ui/src/messaging/transaction/nft.ts @@ -19,6 +19,10 @@ export async function subscribeNftCollection (callback: (data: NftCollection[]) return sendMessage('pri(nftCollection.getSubscription)', null, callback); } +export async function loadMoreNft () { + return sendMessage('pri(inscription.loadMoreInscription)'); +} + export async function evmNftSubmitTransaction (request: NftTransactionRequest): Promise { return sendMessage('pri(evmNft.submitTransaction)', request); } From 23ad9ab8443fc26be6a007261ce83e1ac59cdbdc Mon Sep 17 00:00:00 2001 From: bluezdot <72647326+bluezdot@users.noreply.github.com> Date: Tue, 18 Jun 2024 11:38:27 +0700 Subject: [PATCH 03/17] [Issue-182] Handle total inscription balance --- .../src/background/KoniTypes.ts | 6 ++++ .../helpers/balance/bitcoin.ts | 28 +++++++++++++++---- .../bitcoin/strategy/BlockStream/types.ts | 4 ++- .../src/types/balance/balance.ts | 4 ++- 4 files changed, 34 insertions(+), 8 deletions(-) diff --git a/packages/extension-base/src/background/KoniTypes.ts b/packages/extension-base/src/background/KoniTypes.ts index cc65b75455..c4e2779328 100644 --- a/packages/extension-base/src/background/KoniTypes.ts +++ b/packages/extension-base/src/background/KoniTypes.ts @@ -2232,6 +2232,12 @@ export interface RequestAccountProxyCreateSuri { suri: string; } +export type BitcoinBalanceMetadata = { + inscriptionCount: number +} + +export type _BalanceMetadata = unknown; + /* Campaign */ // Use stringify to communicate, pure boolean value will error with case 'false' value diff --git a/packages/extension-base/src/services/balance-service/helpers/balance/bitcoin.ts b/packages/extension-base/src/services/balance-service/helpers/balance/bitcoin.ts index f07a085e37..fa41356885 100644 --- a/packages/extension-base/src/services/balance-service/helpers/balance/bitcoin.ts +++ b/packages/extension-base/src/services/balance-service/helpers/balance/bitcoin.ts @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 import { _AssetType, _ChainAsset, _ChainInfo } from '@subwallet/chain-list/types'; -import { APIItemState } from '@subwallet/extension-base/background/KoniTypes'; +import { APIItemState, BitcoinBalanceMetadata } from '@subwallet/extension-base/background/KoniTypes'; import { COMMON_REFRESH_BALANCE_INTERVAL } from '@subwallet/extension-base/constants'; import { Brc20BalanceItem } from '@subwallet/extension-base/services/chain-service/handler/bitcoin/strategy/BlockStream/types'; import { _BitcoinApi } from '@subwallet/extension-base/services/chain-service/types'; @@ -161,7 +161,14 @@ export const getTransferableBitcoinUtxos = async (bitcoinApi: _BitcoinApi, addre async function getBitcoinBalance (bitcoinApi: _BitcoinApi, addresses: string[]) { return await Promise.all(addresses.map(async (address) => { try { - const filteredUtxos = await getTransferableBitcoinUtxos(bitcoinApi, address); + const [filteredUtxos, addressSummaryInfo] = await Promise.all([ + getTransferableBitcoinUtxos(bitcoinApi, address), + bitcoinApi.api.getAddressSummaryInfo(address) + ]); + + const bitcoinBalanceMetadata = { + inscriptionCount: addressSummaryInfo.total_inscription + } as BitcoinBalanceMetadata; let balanceValue = new BigN(0); @@ -169,11 +176,19 @@ async function getBitcoinBalance (bitcoinApi: _BitcoinApi, addresses: string[]) balanceValue = balanceValue.plus(utxo.value); }); - return balanceValue.toString(); + return { + balance: balanceValue.toString(), + bitcoinBalanceMetadata: bitcoinBalanceMetadata + }; } catch (error) { console.log('Error while fetching Bitcoin balances', error); - return '0'; + return { + balance: '0', + bitcoinBalanceMetadata: { + inscriptionCount: 0 + } + }; } })); } @@ -184,13 +199,14 @@ export function subscribeBitcoinBalance (addresses: string[], chainInfo: _ChainI const getBalance = () => { getBitcoinBalance(bitcoinApi, addresses) .then((balances) => { - return balances.map((balance, index): BalanceItem => { + return balances.map(({ balance, bitcoinBalanceMetadata }, index): BalanceItem => { return { address: addresses[index], tokenSlug: nativeSlug, state: APIItemState.READY, free: balance, - locked: '0' + locked: '0', + metadata: bitcoinBalanceMetadata }; }); }) diff --git a/packages/extension-base/src/services/chain-service/handler/bitcoin/strategy/BlockStream/types.ts b/packages/extension-base/src/services/chain-service/handler/bitcoin/strategy/BlockStream/types.ts index e964350aea..a51a393f9e 100644 --- a/packages/extension-base/src/services/chain-service/handler/bitcoin/strategy/BlockStream/types.ts +++ b/packages/extension-base/src/services/chain-service/handler/bitcoin/strategy/BlockStream/types.ts @@ -32,7 +32,9 @@ export interface BitcoinAddressSummaryInfo { spent_txo_count: number, spent_txo_sum: number, tx_count: number - } + }, + balance: number, + total_inscription: number } // todo: combine RunesByAddressResponse & RunesCollectionInfoResponse diff --git a/packages/extension-base/src/types/balance/balance.ts b/packages/extension-base/src/types/balance/balance.ts index 1846b1c5bf..fffdb50d7d 100644 --- a/packages/extension-base/src/types/balance/balance.ts +++ b/packages/extension-base/src/types/balance/balance.ts @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 import { _ChainAsset, _ChainInfo } from '@subwallet/chain-list/types'; -import { APIItemState } from '@subwallet/extension-base/background/KoniTypes'; +import { _BalanceMetadata, APIItemState } from '@subwallet/extension-base/background/KoniTypes'; import { _EvmApi } from '@subwallet/extension-base/services/chain-service/types'; import { ApiPromise } from '@polkadot/api'; @@ -43,6 +43,8 @@ export interface BalanceItem { // substrate fields substrateInfo?: SubstrateBalance; + + metadata?: _BalanceMetadata; } /** Balance info of all tokens on an address */ From 7812d227ec9e5dc2f21886c5c9a9d7bb2424b4a0 Mon Sep 17 00:00:00 2001 From: bluezdot <72647326+bluezdot@users.noreply.github.com> Date: Tue, 18 Jun 2024 15:46:41 +0700 Subject: [PATCH 04/17] [Issue-182] fix: trigger only inscription handler --- packages/extension-base/src/koni/api/nft/index.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/extension-base/src/koni/api/nft/index.ts b/packages/extension-base/src/koni/api/nft/index.ts index 532b4dac12..84c51dd8c4 100644 --- a/packages/extension-base/src/koni/api/nft/index.ts +++ b/packages/extension-base/src/koni/api/nft/index.ts @@ -203,15 +203,13 @@ export class NftService { public async handleNfts ( nftContracts: _ChainAsset[], updateItem: (chain: string, data: NftItem, owner: string) => void, - updateCollection: (chain: string, data: NftCollection) => void, - getOffset?: (address: string) => Promise) { + updateCollection: (chain: string, data: NftCollection) => void) { this.setupApi(); this.setupNftContracts(nftContracts); await Promise.all(this.handlers.map(async (handler) => { await handler.fetchNfts({ updateItem, - updateCollection, - getOffset + updateCollection }); })); } @@ -221,7 +219,9 @@ export class NftService { updateCollection: (chain: string, data: NftCollection) => void, getOffset?: (address: string) => Promise ) { - await Promise.all(this.handlers.map(async (handler) => { + const inscriptionApiHandlers = this.handlers.filter((handler) => handler instanceof InscriptionApi); + + await Promise.all(inscriptionApiHandlers.map(async (handler) => { await handler.fetchNfts({ updateItem, updateCollection, From 8c4277d77149b446aafac0d327df1612b25eef1f Mon Sep 17 00:00:00 2001 From: bluezdot <72647326+bluezdot@users.noreply.github.com> Date: Tue, 18 Jun 2024 15:46:57 +0700 Subject: [PATCH 05/17] [Issue-182] fix: fix inscription count --- packages/extension-base/src/koni/background/handlers/State.ts | 2 +- packages/extension-base/src/koni/background/subscription.ts | 3 +-- .../src/services/storage-service/DatabaseService.ts | 2 +- packages/extension-koni-ui/src/messaging/transaction/nft.ts | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/packages/extension-base/src/koni/background/handlers/State.ts b/packages/extension-base/src/koni/background/handlers/State.ts index e50c12e1f9..23e671f315 100644 --- a/packages/extension-base/src/koni/background/handlers/State.ts +++ b/packages/extension-base/src/koni/background/handlers/State.ts @@ -505,7 +505,7 @@ export default class KoniState { this.nftService.loadMoreNfts( (...args) => this.updateNftData(...args), (...args) => this.setNftCollection(...args), - (address: string) => this.dbService.getAddressTotalNfts([address]) + (address: string) => this.dbService.getAddressTotalInscriptions([address], ['bitcoin']) ).catch(this.logger.log); } diff --git a/packages/extension-base/src/koni/background/subscription.ts b/packages/extension-base/src/koni/background/subscription.ts index 2910faa328..d8a0b2acba 100644 --- a/packages/extension-base/src/koni/background/subscription.ts +++ b/packages/extension-base/src/koni/background/subscription.ts @@ -150,8 +150,7 @@ export class KoniSubscription { this.nftService.handleNfts( smartContractNfts, (...args) => this.state.updateNftData(...args), - (...args) => this.state.setNftCollection(...args), - (address: string) => this.dbService.getAddressTotalNfts([address]) + (...args) => this.state.setNftCollection(...args) ).catch(this.logger.log); } diff --git a/packages/extension-base/src/services/storage-service/DatabaseService.ts b/packages/extension-base/src/services/storage-service/DatabaseService.ts index f11e34b352..4b809b1903 100644 --- a/packages/extension-base/src/services/storage-service/DatabaseService.ts +++ b/packages/extension-base/src/services/storage-service/DatabaseService.ts @@ -214,7 +214,7 @@ export default class DatabaseService { return this.stores.nft.cleanUpNfts(chain, reformatAddress(owner, 42), collectionIds, nftIds); } - async getAddressTotalNfts (addresses: string[], chainHashes?: string[]) { + async getAddressTotalInscriptions (addresses: string[], chainHashes?: string[]) { return this.stores.nft.getAddressTotalNfts(addresses, chainHashes); } diff --git a/packages/extension-koni-ui/src/messaging/transaction/nft.ts b/packages/extension-koni-ui/src/messaging/transaction/nft.ts index e7b03fb292..9a4175d3b6 100644 --- a/packages/extension-koni-ui/src/messaging/transaction/nft.ts +++ b/packages/extension-koni-ui/src/messaging/transaction/nft.ts @@ -19,7 +19,7 @@ export async function subscribeNftCollection (callback: (data: NftCollection[]) return sendMessage('pri(nftCollection.getSubscription)', null, callback); } -export async function loadMoreNft () { +export async function loadMoreInscription () { return sendMessage('pri(inscription.loadMoreInscription)'); } From c1b74cfbb6a92959e27dd9837b334429c50740a2 Mon Sep 17 00:00:00 2001 From: lw Date: Tue, 18 Jun 2024 18:39:59 +0700 Subject: [PATCH 06/17] Update loadmore function for collection --- .../Popup/Home/Nfts/NftCollectionDetail.tsx | 158 +++++++++++++++--- .../src/Popup/Home/Nfts/NftCollections.tsx | 12 +- .../src/Popup/Home/Nfts/utils.ts | 51 +++++- 3 files changed, 189 insertions(+), 32 deletions(-) diff --git a/packages/extension-koni-ui/src/Popup/Home/Nfts/NftCollectionDetail.tsx b/packages/extension-koni-ui/src/Popup/Home/Nfts/NftCollectionDetail.tsx index b6f7bc550b..6ff9d084f9 100644 --- a/packages/extension-koni-ui/src/Popup/Home/Nfts/NftCollectionDetail.tsx +++ b/packages/extension-koni-ui/src/Popup/Home/Nfts/NftCollectionDetail.tsx @@ -8,36 +8,77 @@ import { SHOW_3D_MODELS_CHAIN } from '@subwallet/extension-koni-ui/constants'; import { DataContext } from '@subwallet/extension-koni-ui/contexts/DataContext'; import { useNavigateOnChangeAccount } from '@subwallet/extension-koni-ui/hooks'; import useTranslation from '@subwallet/extension-koni-ui/hooks/common/useTranslation'; +import { loadMoreNft } from '@subwallet/extension-koni-ui/messaging'; import { InscriptionGalleryWrapper } from '@subwallet/extension-koni-ui/Popup/Home/Nfts/component/InscriptionGalleryWrapper'; import { NftGalleryWrapper } from '@subwallet/extension-koni-ui/Popup/Home/Nfts/component/NftGalleryWrapper'; -import { INftCollectionDetail, INftItemDetail } from '@subwallet/extension-koni-ui/Popup/Home/Nfts/utils'; +import { getTotalCollectionItems, INftCollectionDetail, INftItemDetail } from '@subwallet/extension-koni-ui/Popup/Home/Nfts/utils'; +import { RootState } from '@subwallet/extension-koni-ui/stores'; import { ThemeProps } from '@subwallet/extension-koni-ui/types'; -import { SwList } from '@subwallet/react-ui'; +import { Input, SwList } from '@subwallet/react-ui'; import CN from 'classnames'; import { Image } from 'phosphor-react'; -import React, { useCallback, useContext } from 'react'; +import React, { useCallback, useContext, useEffect, useMemo, useState } from 'react'; +import { useSelector } from 'react-redux'; import { useLocation, useNavigate } from 'react-router-dom'; import styled from 'styled-components'; -type Props = ThemeProps +type Props = ThemeProps; +type SearchInputProps = { + initValue?: string; + placeholder: string; + onChange: (value: string) => void; +}; + +const SearchInput = ({ initValue = '', onChange, placeholder }: SearchInputProps) => { + const [searchValue, setSearchValue] = useState(initValue); + + const _onChange = useCallback((e: React.ChangeEvent) => { + setSearchValue(e.target.value); + }, []); + + useEffect(() => { + const timeout: NodeJS.Timeout = setTimeout(() => { + onChange(searchValue); + }, 500); + + return () => { + clearTimeout(timeout); + }; + }, [onChange, searchValue]); + + return ( + + ); +}; function Component ({ className = '' }: Props): React.ReactElement { const location = useLocation(); const { collectionInfo, nftList } = location.state as INftCollectionDetail; + const balanceMap = useSelector((state: RootState) => state.balance.balanceMap); + const currentAccountProxy = useSelector((state: RootState) => state.accountState.currentAccountProxy); const { t } = useTranslation(); const navigate = useNavigate(); const dataContext = useContext(DataContext); + const [searchValue, setSearchValue] = useState(''); useNavigateOnChangeAccount('/home/nfts/collections'); - const searchNft = useCallback((nftItem: NftItem, searchText: string) => { - const searchTextLowerCase = searchText.toLowerCase(); - return ( - nftItem.name?.toLowerCase().includes(searchTextLowerCase) || - nftItem.id.toLowerCase().includes(searchTextLowerCase) - ); - }, []); + const searchNft = useCallback( + (nftItem: NftItem) => { + const searchTextLowerCase = searchValue.toLowerCase(); + + return ( + nftItem.name?.toLowerCase().includes(searchTextLowerCase) || + nftItem.id.toLowerCase().includes(searchTextLowerCase) + ); + }, + [searchValue] + ); // todo: `need optimize child router for nfts` const handleOnClickNft = useCallback((state: INftItemDetail) => { @@ -90,10 +131,54 @@ function Component ({ className = '' }: Props): React.ReactElement { ); }, [t]); + const onChangeSearchInput = useCallback((value: string) => { + setSearchValue(value); + }, []); + + const totalItems = useMemo(() => { + return getTotalCollectionItems(collectionInfo.collectionId, currentAccountProxy, balanceMap, nftList.length); + }, [balanceMap, collectionInfo.collectionId, currentAccountProxy, nftList.length]); + + const hasMoreItems = useMemo(() => { + if (searchValue.length === 2) { + return false; + } + + return nftList.length < totalItems; + }, [nftList.length, searchValue.length, totalItems]); + + const onLoadMoreItems = useCallback(() => { + loadMoreNft().catch(console.log); + }, []); + + // note: memo to hot fix list scroll problem + const listSection = useMemo(() => ( + <> +
+ ('Search collectible name or ID')} + searchTerm={searchValue} + /> +
+ + ), [emptyNft, hasMoreItems, nftList, onLoadMoreItems, renderNft, searchNft, searchValue, t]); + return ( { {collectionInfo.collectionName || collectionInfo.collectionId}
-  ({nftList.length}) +  ({totalItems})
)} > - ('Search collectible name or ID')} - /> +
+
+ ('Search collectible name or ID')} + /> +
+ + {listSection} +
); @@ -154,11 +235,34 @@ const NftCollectionDetail = styled(Component)(({ theme: { token } }: Prop overflow: 'hidden' }, + '.ant-sw-list-section': { + display: 'flex', + overflow: 'hidden', + flexDirection: 'column' + }, + + '.ant-sw-list-search-input': { + padding: token.padding, + paddingTop: 0 + }, + '.collection-name': { overflow: 'hidden', textOverflow: 'ellipsis' }, + '.ant-sw-list-wrapper': { + flex: '1 1 100vh', + overflow: 'hidden' + }, + + '.ant-sw-list': { + overflow: 'auto', + maxHeight: '100%', + paddingLeft: token.padding, + paddingRight: token.padding + }, + '.nft_item_list__container': { flex: 1, height: '100%', diff --git a/packages/extension-koni-ui/src/Popup/Home/Nfts/NftCollections.tsx b/packages/extension-koni-ui/src/Popup/Home/Nfts/NftCollections.tsx index 344d67642e..8db89cb326 100644 --- a/packages/extension-koni-ui/src/Popup/Home/Nfts/NftCollections.tsx +++ b/packages/extension-koni-ui/src/Popup/Home/Nfts/NftCollections.tsx @@ -7,12 +7,14 @@ import { DataContext } from '@subwallet/extension-koni-ui/contexts/DataContext'; import { useGetNftByAccount, useNotification, useSetCurrentPage, useTranslation } from '@subwallet/extension-koni-ui/hooks'; import { reloadCron } from '@subwallet/extension-koni-ui/messaging'; import { NftGalleryWrapper } from '@subwallet/extension-koni-ui/Popup/Home/Nfts/component/NftGalleryWrapper'; -import { INftCollectionDetail } from '@subwallet/extension-koni-ui/Popup/Home/Nfts/utils'; +import { getTotalCollectionItems, INftCollectionDetail } from '@subwallet/extension-koni-ui/Popup/Home/Nfts/utils'; +import { RootState } from '@subwallet/extension-koni-ui/stores'; import { ThemeProps } from '@subwallet/extension-koni-ui/types'; import { ActivityIndicator, ButtonProps, Icon, SwList } from '@subwallet/react-ui'; import CN from 'classnames'; import { ArrowClockwise, Image } from 'phosphor-react'; import React, { useCallback, useContext } from 'react'; +import { useSelector } from 'react-redux'; import { useNavigate } from 'react-router-dom'; import styled from 'styled-components'; @@ -31,6 +33,8 @@ function Component ({ className = '' }: Props): React.ReactElement { const dataContext = useContext(DataContext); const { nftCollections, nftItems } = useGetNftByAccount(); const [loading, setLoading] = React.useState(false); + const balanceMap = useSelector((state: RootState) => state.balance.balanceMap); + const currentAccountProxy = useSelector((state: RootState) => state.accountState.currentAccountProxy); const notify = useNotification(); const subHeaderButton: ButtonProps[] = [ @@ -102,13 +106,13 @@ function Component ({ className = '' }: Props): React.ReactElement { fallbackImage={fallbackImage} handleOnClick={handleOnClickCollection} image={nftCollection.image} - itemCount={nftList.length} + itemCount={getTotalCollectionItems(nftCollection.collectionId, currentAccountProxy, balanceMap, nftList.length)} key={`${nftCollection.collectionId}_${nftCollection.chain}`} routingParams={state} title={nftCollection.collectionName || nftCollection.collectionId} /> ); - }, [getNftsByCollection, handleOnClickCollection]); + }, [balanceMap, currentAccountProxy, getNftsByCollection, handleOnClickCollection]); const emptyNft = useCallback(() => { return ( @@ -123,7 +127,7 @@ function Component ({ className = '' }: Props): React.ReactElement { return ( , isTestnet = false): number | undefined { + if (!isTestnet) { + return (balanceMap[address]?.['bitcoin-NATIVE-BTC']?.metadata as BitcoinBalanceMetadata)?.inscriptionCount; + } + + return (balanceMap[address]?.['bitcoinTestnet-NATIVE-BTC']?.metadata as BitcoinBalanceMetadata)?.inscriptionCount; +} + +export function getTotalCollectionItems ( + collectionId: string, + accountProxy: AccountProxy | null, + balanceMap: Record, + itemsLength: number +): number { + if (!accountProxy) { + return itemsLength; + } + + if (collectionId === 'INSCRIPTION') { + for (const account of accountProxy.accounts) { + if (account.type !== 'bitcoin-86') { + continue; + } + + const totalInscription = getTotalInscriptions(account.address, balanceMap); + + if (totalInscription) { + return totalInscription; + } + } + } else if (collectionId === 'INSCRIPTION_TESTNET') { + for (const account of accountProxy.accounts) { + if (account.type !== 'bittest-86') { + continue; + } + + const totalInscription = getTotalInscriptions(account.address, balanceMap, true); + + if (totalInscription) { + return totalInscription; + } + } + } + + return itemsLength; +} From b0d9547ad05fb0a236e7e9b67ff50f3b977f2c8d Mon Sep 17 00:00:00 2001 From: lw Date: Tue, 18 Jun 2024 19:52:12 +0700 Subject: [PATCH 07/17] Update fetching list collection logic --- .../Popup/Home/Nfts/NftCollectionDetail.tsx | 22 +++++++++++++++---- .../src/Popup/Home/Nfts/NftCollections.tsx | 2 +- .../src/Popup/Home/Nfts/utils.ts | 3 +-- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/packages/extension-koni-ui/src/Popup/Home/Nfts/NftCollectionDetail.tsx b/packages/extension-koni-ui/src/Popup/Home/Nfts/NftCollectionDetail.tsx index 6ff9d084f9..4939fd0780 100644 --- a/packages/extension-koni-ui/src/Popup/Home/Nfts/NftCollectionDetail.tsx +++ b/packages/extension-koni-ui/src/Popup/Home/Nfts/NftCollectionDetail.tsx @@ -6,9 +6,9 @@ import { OrdinalRemarkData } from '@subwallet/extension-base/types'; import { EmptyList, Layout, PageWrapper } from '@subwallet/extension-koni-ui/components'; import { SHOW_3D_MODELS_CHAIN } from '@subwallet/extension-koni-ui/constants'; import { DataContext } from '@subwallet/extension-koni-ui/contexts/DataContext'; -import { useNavigateOnChangeAccount } from '@subwallet/extension-koni-ui/hooks'; +import { useGetNftByAccount, useNavigateOnChangeAccount } from '@subwallet/extension-koni-ui/hooks'; import useTranslation from '@subwallet/extension-koni-ui/hooks/common/useTranslation'; -import { loadMoreNft } from '@subwallet/extension-koni-ui/messaging'; +import { loadMoreInscription } from '@subwallet/extension-koni-ui/messaging'; import { InscriptionGalleryWrapper } from '@subwallet/extension-koni-ui/Popup/Home/Nfts/component/InscriptionGalleryWrapper'; import { NftGalleryWrapper } from '@subwallet/extension-koni-ui/Popup/Home/Nfts/component/NftGalleryWrapper'; import { getTotalCollectionItems, INftCollectionDetail, INftItemDetail } from '@subwallet/extension-koni-ui/Popup/Home/Nfts/utils'; @@ -57,7 +57,21 @@ const SearchInput = ({ initValue = '', onChange, placeholder }: SearchInputProps function Component ({ className = '' }: Props): React.ReactElement { const location = useLocation(); - const { collectionInfo, nftList } = location.state as INftCollectionDetail; + const { collectionInfo } = location.state as INftCollectionDetail; + const { nftItems } = useGetNftByAccount(); + + const nftList = useMemo(() => { + const result: NftItem[] = []; + + nftItems.forEach((nftItem) => { + if (nftItem.collectionId === collectionInfo.collectionId && nftItem.chain === collectionInfo.chain) { + result.push(nftItem); + } + }); + + return result; + }, [collectionInfo.chain, collectionInfo.collectionId, nftItems]); + const balanceMap = useSelector((state: RootState) => state.balance.balanceMap); const currentAccountProxy = useSelector((state: RootState) => state.accountState.currentAccountProxy); @@ -148,7 +162,7 @@ function Component ({ className = '' }: Props): React.ReactElement { }, [nftList.length, searchValue.length, totalItems]); const onLoadMoreItems = useCallback(() => { - loadMoreNft().catch(console.log); + loadMoreInscription().catch(console.log); }, []); // note: memo to hot fix list scroll problem diff --git a/packages/extension-koni-ui/src/Popup/Home/Nfts/NftCollections.tsx b/packages/extension-koni-ui/src/Popup/Home/Nfts/NftCollections.tsx index 8db89cb326..84f3b77f63 100644 --- a/packages/extension-koni-ui/src/Popup/Home/Nfts/NftCollections.tsx +++ b/packages/extension-koni-ui/src/Popup/Home/Nfts/NftCollections.tsx @@ -99,7 +99,7 @@ function Component ({ className = '' }: Props): React.ReactElement { } } - const state: INftCollectionDetail = { collectionInfo: nftCollection, nftList }; + const state: INftCollectionDetail = { collectionInfo: nftCollection }; return ( Date: Tue, 18 Jun 2024 20:16:18 +0700 Subject: [PATCH 08/17] [Issue-182] Handle inscription testnet --- .../extension-base/src/koni/api/nft/index.ts | 10 +++++-- .../src/koni/api/nft/inscription/index.ts | 29 ++++++++++++++----- .../src/services/chain-service/constants.ts | 3 +- .../src/services/hiro-service/utils/index.ts | 4 +-- 4 files changed, 34 insertions(+), 12 deletions(-) diff --git a/packages/extension-base/src/koni/api/nft/index.ts b/packages/extension-base/src/koni/api/nft/index.ts index 84c51dd8c4..529fb4f0be 100644 --- a/packages/extension-base/src/koni/api/nft/index.ts +++ b/packages/extension-base/src/koni/api/nft/index.ts @@ -48,12 +48,18 @@ function createSubstrateNftApi (chain: string, substrateApi: _SubstrateApi | nul } function createBitcoinInscriptionApi (chain: string, addresses: string[]) { - const filteredAddresses = addresses.filter((a) => { + const mainnetAddresses = addresses.filter((a) => { return getKeypairTypeByAddress(a) === 'bitcoin-86'; }); + const testnetAddresses = addresses.filter((a) => { + return getKeypairTypeByAddress(a) === 'bittest-86'; + }) + if (_NFT_CHAIN_GROUP.bitcoin.includes(chain)) { - return new InscriptionApi(chain, filteredAddresses); + return new InscriptionApi(chain, mainnetAddresses); + } else if (_NFT_CHAIN_GROUP.bitcoinTest.includes(chain)) { + return new InscriptionApi(chain, testnetAddresses); } else { return null; } diff --git a/packages/extension-base/src/koni/api/nft/inscription/index.ts b/packages/extension-base/src/koni/api/nft/inscription/index.ts index 4d854d0f94..c85d41f7d9 100644 --- a/packages/extension-base/src/koni/api/nft/inscription/index.ts +++ b/packages/extension-base/src/koni/api/nft/inscription/index.ts @@ -23,9 +23,22 @@ const ORDINAL_COLLECTION_INFO: NftCollection = { collectionName: 'Inscriptions' }; +const ORDINAL_COLLECTION_INFO_TEST: NftCollection = { + chain: 'bitcoinTestnet', + collectionId: 'INSCRIPTION_TESTNET', + collectionName: 'Inscriptions Testnet' +} + +const checkTestnet = (chain: string) => { + return chain === ORDINAL_COLLECTION_INFO_TEST.chain; +} + export class InscriptionApi extends BaseNftApi { + private isTestnet: boolean; + constructor (chain: string, addresses: string[]) { super(chain, undefined, addresses); + this.isTestnet = checkTestnet(chain); } private createIframePreviewUrl (id: string) { @@ -124,10 +137,12 @@ export class InscriptionApi extends BaseNftApi { } public async handleNfts (params: HandleNftParams) { + const collectionInfo = this.isTestnet ? ORDINAL_COLLECTION_INFO_TEST : ORDINAL_COLLECTION_INFO; + try { await Promise.all(this.addresses.map(async (address) => { const offset = params.getOffset && await params.getOffset(address); - const balances = await getAddressInscriptions(address, offset); + const balances = await getAddressInscriptions(address, this.isTestnet, offset); if (balances.length > 0) { const collectionMap: Record = {}; @@ -148,22 +163,22 @@ export class InscriptionApi extends BaseNftApi { name: `#${ins.number.toString()}`, image: this.parseInsUrl(ins.id, ins.content_type), description: content ? JSON.stringify(content) : undefined, - collectionId: ORDINAL_COLLECTION_INFO.collectionId, + collectionId: collectionInfo.collectionId, rarity: ins.sat_rarity, properties: propertiesMap }; params.updateItem(this.chain, parsedNft, ins.address); - if (!collectionMap[ORDINAL_COLLECTION_INFO.collectionId]) { + if (!collectionMap[collectionInfo.collectionId]) { const parsedCollection: NftCollection = { - collectionId: ORDINAL_COLLECTION_INFO.collectionId, + collectionId: collectionInfo.collectionId, chain: this.chain, - collectionName: ORDINAL_COLLECTION_INFO.collectionName, - image: ORDINAL_COLLECTION_INFO.image + collectionName: collectionInfo.collectionName, + image: collectionInfo.image }; - collectionMap[ORDINAL_COLLECTION_INFO.collectionId] = parsedCollection; + collectionMap[collectionInfo.collectionId] = parsedCollection; params.updateCollection(this.chain, parsedCollection); } } diff --git a/packages/extension-base/src/services/chain-service/constants.ts b/packages/extension-base/src/services/chain-service/constants.ts index 19b16ed932..ab751268ad 100644 --- a/packages/extension-base/src/services/chain-service/constants.ts +++ b/packages/extension-base/src/services/chain-service/constants.ts @@ -65,7 +65,8 @@ export const _NFT_CHAIN_GROUP = { unique_network: ['unique_network', 'quartz', 'opal'], bitcountry: ['bitcountry', 'pioneer', 'continuum_network'], vara: ['vara_network'], - bitcoin: ['bitcoin'] + bitcoin: ['bitcoin'], + bitcoinTest: ['bitcoinTestnet'] }; // Staking-------------------------------------------------------------------------------------------------------------- diff --git a/packages/extension-base/src/services/hiro-service/utils/index.ts b/packages/extension-base/src/services/hiro-service/utils/index.ts index 42de05a119..d2a9747944 100644 --- a/packages/extension-base/src/services/hiro-service/utils/index.ts +++ b/packages/extension-base/src/services/hiro-service/utils/index.ts @@ -44,8 +44,8 @@ export async function getInscriptionContent (inscriptionId: string) { } // todo: handle large inscriptions -export async function getAddressInscriptions (address: string, offset = 0, limit = 25) { - const hiroService = HiroService.getInstance(); +export async function getAddressInscriptions (address: string, isTestnet: boolean, offset = 0, limit = 25) { + const hiroService = HiroService.getInstance(isTestnet); try { const response = await hiroService.getAddressInscriptionsInfo({ From 9f82a243c94412a8997401b7d0486af98b7f3eb5 Mon Sep 17 00:00:00 2001 From: bluezdot <72647326+bluezdot@users.noreply.github.com> Date: Tue, 18 Jun 2024 20:39:50 +0700 Subject: [PATCH 09/17] fix eslint --- packages/extension-base/src/koni/api/nft/index.ts | 2 +- packages/extension-base/src/koni/api/nft/inscription/index.ts | 4 ++-- .../src/Popup/Home/Nfts/NftCollectionDetail.tsx | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/extension-base/src/koni/api/nft/index.ts b/packages/extension-base/src/koni/api/nft/index.ts index 529fb4f0be..2a58b86308 100644 --- a/packages/extension-base/src/koni/api/nft/index.ts +++ b/packages/extension-base/src/koni/api/nft/index.ts @@ -54,7 +54,7 @@ function createBitcoinInscriptionApi (chain: string, addresses: string[]) { const testnetAddresses = addresses.filter((a) => { return getKeypairTypeByAddress(a) === 'bittest-86'; - }) + }); if (_NFT_CHAIN_GROUP.bitcoin.includes(chain)) { return new InscriptionApi(chain, mainnetAddresses); diff --git a/packages/extension-base/src/koni/api/nft/inscription/index.ts b/packages/extension-base/src/koni/api/nft/inscription/index.ts index c85d41f7d9..00750f836c 100644 --- a/packages/extension-base/src/koni/api/nft/inscription/index.ts +++ b/packages/extension-base/src/koni/api/nft/inscription/index.ts @@ -27,11 +27,11 @@ const ORDINAL_COLLECTION_INFO_TEST: NftCollection = { chain: 'bitcoinTestnet', collectionId: 'INSCRIPTION_TESTNET', collectionName: 'Inscriptions Testnet' -} +}; const checkTestnet = (chain: string) => { return chain === ORDINAL_COLLECTION_INFO_TEST.chain; -} +}; export class InscriptionApi extends BaseNftApi { private isTestnet: boolean; diff --git a/packages/extension-koni-ui/src/Popup/Home/Nfts/NftCollectionDetail.tsx b/packages/extension-koni-ui/src/Popup/Home/Nfts/NftCollectionDetail.tsx index 4939fd0780..1a1918bf8a 100644 --- a/packages/extension-koni-ui/src/Popup/Home/Nfts/NftCollectionDetail.tsx +++ b/packages/extension-koni-ui/src/Popup/Home/Nfts/NftCollectionDetail.tsx @@ -207,7 +207,7 @@ function Component ({ className = '' }: Props): React.ReactElement { {collectionInfo.collectionName || collectionInfo.collectionId}
-  ({totalItems}) +  ({nftList.length})
)} From 2f728ab5d09cf26347f4493ab16c51874dc6e754 Mon Sep 17 00:00:00 2001 From: bluezdot <72647326+bluezdot@users.noreply.github.com> Date: Tue, 18 Jun 2024 21:10:21 +0700 Subject: [PATCH 10/17] [Issue-182] fix: fix query inscription count --- packages/extension-base/src/koni/api/nft/index.ts | 2 +- .../src/koni/api/nft/inscription/index.ts | 6 +++--- packages/extension-base/src/koni/api/nft/nft.ts | 2 +- .../src/koni/background/handlers/State.ts | 2 +- .../src/services/storage-service/DatabaseService.ts | 4 ++-- .../src/services/storage-service/db-stores/Nft.ts | 11 ++++++++--- 6 files changed, 16 insertions(+), 11 deletions(-) diff --git a/packages/extension-base/src/koni/api/nft/index.ts b/packages/extension-base/src/koni/api/nft/index.ts index 2a58b86308..586b3e8ac3 100644 --- a/packages/extension-base/src/koni/api/nft/index.ts +++ b/packages/extension-base/src/koni/api/nft/index.ts @@ -223,7 +223,7 @@ export class NftService { public async loadMoreNfts ( updateItem: (chain: string, data: NftItem, owner: string) => void, updateCollection: (chain: string, data: NftCollection) => void, - getOffset?: (address: string) => Promise + getOffset?: (address: string, chain: string) => Promise ) { const inscriptionApiHandlers = this.handlers.filter((handler) => handler instanceof InscriptionApi); diff --git a/packages/extension-base/src/koni/api/nft/inscription/index.ts b/packages/extension-base/src/koni/api/nft/inscription/index.ts index 00750f836c..767a7b954a 100644 --- a/packages/extension-base/src/koni/api/nft/inscription/index.ts +++ b/packages/extension-base/src/koni/api/nft/inscription/index.ts @@ -17,13 +17,13 @@ interface FetchedData { results: InscriptionResponseItem[] } -const ORDINAL_COLLECTION_INFO: NftCollection = { +export const ORDINAL_COLLECTION_INFO: NftCollection = { chain: 'bitcoin', collectionId: 'INSCRIPTION', collectionName: 'Inscriptions' }; -const ORDINAL_COLLECTION_INFO_TEST: NftCollection = { +export const ORDINAL_COLLECTION_INFO_TEST: NftCollection = { chain: 'bitcoinTestnet', collectionId: 'INSCRIPTION_TESTNET', collectionName: 'Inscriptions Testnet' @@ -141,7 +141,7 @@ export class InscriptionApi extends BaseNftApi { try { await Promise.all(this.addresses.map(async (address) => { - const offset = params.getOffset && await params.getOffset(address); + const offset = params.getOffset && await params.getOffset(address, collectionInfo.chain); const balances = await getAddressInscriptions(address, this.isTestnet, offset); if (balances.length > 0) { diff --git a/packages/extension-base/src/koni/api/nft/nft.ts b/packages/extension-base/src/koni/api/nft/nft.ts index 7af49e6742..5e4ae6909c 100644 --- a/packages/extension-base/src/koni/api/nft/nft.ts +++ b/packages/extension-base/src/koni/api/nft/nft.ts @@ -8,7 +8,7 @@ import { baseParseIPFSUrl } from '@subwallet/extension-base/utils'; export interface HandleNftParams { updateItem: (chain: string, data: NftItem, owner: string) => void, updateCollection: (chain: string, data: NftCollection) => void, - getOffset?: (address: string) => Promise + getOffset?: (address: string, chain: string) => Promise } export abstract class BaseNftApi { diff --git a/packages/extension-base/src/koni/background/handlers/State.ts b/packages/extension-base/src/koni/background/handlers/State.ts index 23e671f315..1f0b2a06f9 100644 --- a/packages/extension-base/src/koni/background/handlers/State.ts +++ b/packages/extension-base/src/koni/background/handlers/State.ts @@ -505,7 +505,7 @@ export default class KoniState { this.nftService.loadMoreNfts( (...args) => this.updateNftData(...args), (...args) => this.setNftCollection(...args), - (address: string) => this.dbService.getAddressTotalInscriptions([address], ['bitcoin']) + (address: string, chain: string) => this.dbService.getAddressTotalInscriptions([address], chain) ).catch(this.logger.log); } diff --git a/packages/extension-base/src/services/storage-service/DatabaseService.ts b/packages/extension-base/src/services/storage-service/DatabaseService.ts index 4b809b1903..cc17b21369 100644 --- a/packages/extension-base/src/services/storage-service/DatabaseService.ts +++ b/packages/extension-base/src/services/storage-service/DatabaseService.ts @@ -214,8 +214,8 @@ export default class DatabaseService { return this.stores.nft.cleanUpNfts(chain, reformatAddress(owner, 42), collectionIds, nftIds); } - async getAddressTotalInscriptions (addresses: string[], chainHashes?: string[]) { - return this.stores.nft.getAddressTotalNfts(addresses, chainHashes); + async getAddressTotalInscriptions (addresses: string[], chain: string) { + return this.stores.nft.getAddressTotalInscriptions(addresses, chain); } async getNft (addresses: string[], chainHashes?: string[]) { diff --git a/packages/extension-base/src/services/storage-service/db-stores/Nft.ts b/packages/extension-base/src/services/storage-service/db-stores/Nft.ts index f77348af09..a1feb7e580 100644 --- a/packages/extension-base/src/services/storage-service/db-stores/Nft.ts +++ b/packages/extension-base/src/services/storage-service/db-stores/Nft.ts @@ -2,18 +2,23 @@ // SPDX-License-Identifier: Apache-2.0 import { NftItem } from '@subwallet/extension-base/background/KoniTypes'; +import { ORDINAL_COLLECTION_INFO, ORDINAL_COLLECTION_INFO_TEST } from '@subwallet/extension-base/koni/api/nft/inscription'; import BaseStoreWithAddressAndChain from '@subwallet/extension-base/services/storage-service/db-stores/BaseStoreWithAddressAndChain'; import { liveQuery } from 'dexie'; import { INft } from '../databases'; export default class NftStore extends BaseStoreWithAddressAndChain { - getAddressTotalNfts (addresses: string[], chainList: string[] = []) { + getAddressTotalInscriptions (addresses: string[], chain: string) { + const collectionId = chain === 'bitcoin' ? ORDINAL_COLLECTION_INFO.collectionId : ORDINAL_COLLECTION_INFO_TEST.collectionId; + if (addresses.length) { - return this.table.where('address').anyOfIgnoreCase(addresses).and((item) => chainList && chainList.includes(item.chain)).count(); + return this.table + .where('address').anyOfIgnoreCase(addresses) + .and((item) => chain === item.chain && item.collectionId === collectionId).count(); } - return this.table.filter((item) => chainList && chainList.includes(item.chain)).count(); + return this.table.filter((item) => chain === item.chain).count(); } getNft (addresses: string[], chainList: string[] = []) { From 0be6e05331403e9487677a8df956d2da014d820e Mon Sep 17 00:00:00 2001 From: lw Date: Wed, 19 Jun 2024 10:17:22 +0700 Subject: [PATCH 11/17] Fix loadmore issue when searching --- .../src/Popup/Home/Nfts/NftCollectionDetail.tsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/extension-koni-ui/src/Popup/Home/Nfts/NftCollectionDetail.tsx b/packages/extension-koni-ui/src/Popup/Home/Nfts/NftCollectionDetail.tsx index 1a1918bf8a..ba223fe38f 100644 --- a/packages/extension-koni-ui/src/Popup/Home/Nfts/NftCollectionDetail.tsx +++ b/packages/extension-koni-ui/src/Popup/Home/Nfts/NftCollectionDetail.tsx @@ -154,7 +154,7 @@ function Component ({ className = '' }: Props): React.ReactElement { }, [balanceMap, collectionInfo.collectionId, currentAccountProxy, nftList.length]); const hasMoreItems = useMemo(() => { - if (searchValue.length === 2) { + if (searchValue.length >= 2) { return false; } @@ -162,8 +162,10 @@ function Component ({ className = '' }: Props): React.ReactElement { }, [nftList.length, searchValue.length, totalItems]); const onLoadMoreItems = useCallback(() => { - loadMoreInscription().catch(console.log); - }, []); + if (hasMoreItems) { + loadMoreInscription().catch(console.log); + } + }, [hasMoreItems]); // note: memo to hot fix list scroll problem const listSection = useMemo(() => ( From ab0a608df6a1ba30e160ff435f1044dabc46bf64 Mon Sep 17 00:00:00 2001 From: bluezdot <72647326+bluezdot@users.noreply.github.com> Date: Wed, 19 Jun 2024 10:35:25 +0700 Subject: [PATCH 12/17] [Issue-182] optimize retrieve content inscriptions --- .../src/koni/api/nft/inscription/index.ts | 59 +++++++++++++++---- .../src/services/hiro-service/utils/index.ts | 4 +- 2 files changed, 51 insertions(+), 12 deletions(-) diff --git a/packages/extension-base/src/koni/api/nft/inscription/index.ts b/packages/extension-base/src/koni/api/nft/inscription/index.ts index 767a7b954a..24043551c3 100644 --- a/packages/extension-base/src/koni/api/nft/inscription/index.ts +++ b/packages/extension-base/src/koni/api/nft/inscription/index.ts @@ -45,6 +45,10 @@ export class InscriptionApi extends BaseNftApi { return `https://ordinals.com/preview/${id}`; } + get collectionInfo () { + return this.isTestnet ? ORDINAL_COLLECTION_INFO_TEST : ORDINAL_COLLECTION_INFO; + } + private parseInsUrl (id: string, type: string) { if (type.startsWith('audio/') || type.startsWith('text/html') || type.startsWith('image/svg') || type.startsWith('video/') || type.startsWith('model/gltf')) { return this.createIframePreviewUrl(id); @@ -136,22 +140,54 @@ export class InscriptionApi extends BaseNftApi { return propertiesMap; } - public async handleNfts (params: HandleNftParams) { - const collectionInfo = this.isTestnet ? ORDINAL_COLLECTION_INFO_TEST : ORDINAL_COLLECTION_INFO; + public async updateTextInscription (inscriptions: Inscription[], params: HandleNftParams, collectionMap: Record ) { + await Promise.all(inscriptions.map(async (ins) => { + const content = await getInscriptionContent(this.isTestnet, ins.id); + const propertiesMap = this.handleProperties(ins); + + const parsedNft: NftItem = { + id: ins.id, + chain: this.chain, + owner: ins.address, + name: `#${ins.number.toString()}`, + image: this.parseInsUrl(ins.id, ins.content_type), + description: content ? JSON.stringify(content) : undefined, + collectionId: this.collectionInfo.collectionId, + rarity: ins.sat_rarity, + properties: propertiesMap + }; + + params.updateItem(this.chain, parsedNft, ins.address); + + if (!collectionMap[this.collectionInfo.collectionId]) { + const parsedCollection: NftCollection = { + collectionId: this.collectionInfo.collectionId, + chain: this.chain, + collectionName: this.collectionInfo.collectionName, + image: this.collectionInfo.image + }; + + collectionMap[this.collectionInfo.collectionId] = parsedCollection; + params.updateCollection(this.chain, parsedCollection); + } + })); + } + public async handleNfts (params: HandleNftParams) { try { await Promise.all(this.addresses.map(async (address) => { - const offset = params.getOffset && await params.getOffset(address, collectionInfo.chain); + const offset = params.getOffset && await params.getOffset(address, this.collectionInfo.chain); const balances = await getAddressInscriptions(address, this.isTestnet, offset); if (balances.length > 0) { const collectionMap: Record = {}; + const textIns: Inscription[] = []; for (const ins of balances) { let content; if (ins.content_type.startsWith('text/plain') || ins.content_type.startsWith('application/json')) { - content = await getInscriptionContent(ins.id); + textIns.push(ins); } const propertiesMap = this.handleProperties(ins); @@ -163,25 +199,28 @@ export class InscriptionApi extends BaseNftApi { name: `#${ins.number.toString()}`, image: this.parseInsUrl(ins.id, ins.content_type), description: content ? JSON.stringify(content) : undefined, - collectionId: collectionInfo.collectionId, + collectionId: this.collectionInfo.collectionId, rarity: ins.sat_rarity, properties: propertiesMap }; params.updateItem(this.chain, parsedNft, ins.address); - if (!collectionMap[collectionInfo.collectionId]) { + if (!collectionMap[this.collectionInfo.collectionId]) { const parsedCollection: NftCollection = { - collectionId: collectionInfo.collectionId, + collectionId: this.collectionInfo.collectionId, chain: this.chain, - collectionName: collectionInfo.collectionName, - image: collectionInfo.image + collectionName: this.collectionInfo.collectionName, + image: this.collectionInfo.image }; - collectionMap[collectionInfo.collectionId] = parsedCollection; + collectionMap[this.collectionInfo.collectionId] = parsedCollection; params.updateCollection(this.chain, parsedCollection); } } + + // handle all inscriptions has text content + await this.updateTextInscription(textIns, params, collectionMap); } })); } catch (error) { diff --git a/packages/extension-base/src/services/hiro-service/utils/index.ts b/packages/extension-base/src/services/hiro-service/utils/index.ts index d2a9747944..8a8eaa88ff 100644 --- a/packages/extension-base/src/services/hiro-service/utils/index.ts +++ b/packages/extension-base/src/services/hiro-service/utils/index.ts @@ -31,8 +31,8 @@ export async function getBrc20Metadata (ticker: string) { } } -export async function getInscriptionContent (inscriptionId: string) { - const hiroService = HiroService.getInstance(); +export async function getInscriptionContent (isTestnet: boolean, inscriptionId: string) { + const hiroService = HiroService.getInstance(isTestnet); try { return await hiroService.getInscriptionContent(inscriptionId); From 904c0460115c2f2c5d2bffee627a09eb72108fe3 Mon Sep 17 00:00:00 2001 From: bluezdot <72647326+bluezdot@users.noreply.github.com> Date: Wed, 19 Jun 2024 14:47:31 +0700 Subject: [PATCH 13/17] [Issue-182] fix get keyring account when reload nft --- .../extension-base/src/koni/background/handlers/State.ts | 5 +++-- .../src/services/storage-service/DatabaseService.ts | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/extension-base/src/koni/background/handlers/State.ts b/packages/extension-base/src/koni/background/handlers/State.ts index 1f0b2a06f9..a668f0ba4c 100644 --- a/packages/extension-base/src/koni/background/handlers/State.ts +++ b/packages/extension-base/src/koni/background/handlers/State.ts @@ -1896,9 +1896,10 @@ export default class KoniState { } public async reloadNft () { - const currentAddress = this.keyringService.currentAccount.address; + const accountProxyId = this.keyringService.currentAccountProxy.proxyId; + const addresses = this.getAccountProxyAddresses(accountProxyId); - await this.dbService.removeNftsByAddress(currentAddress); + await this.dbService.removeNftsByAddress(addresses); return await this.cron.reloadNft(); } diff --git a/packages/extension-base/src/services/storage-service/DatabaseService.ts b/packages/extension-base/src/services/storage-service/DatabaseService.ts index cc17b21369..dc60c89338 100644 --- a/packages/extension-base/src/services/storage-service/DatabaseService.ts +++ b/packages/extension-base/src/services/storage-service/DatabaseService.ts @@ -234,8 +234,8 @@ export default class DatabaseService { return this.stores.nft.removeNfts(chain, address, collectionId, nftIds); } - removeNftsByAddress (address: string) { - return this.stores.nft.removeNftsByAddress([address]); + removeNftsByAddress (addresses: string[]) { + return this.stores.nft.removeNftsByAddress(addresses); } // Chain From f3a6f800dacf0ca15cfde5aa959e74d8b62cb7a3 Mon Sep 17 00:00:00 2001 From: bluezdot <72647326+bluezdot@users.noreply.github.com> Date: Fri, 21 Jun 2024 15:11:31 +0700 Subject: [PATCH 14/17] [Issue-182] handle all account inscription --- .../services/balance-service/helpers/group.ts | 23 +++++------- .../src/Popup/Home/Nfts/utils.ts | 36 +++++++++---------- 2 files changed, 26 insertions(+), 33 deletions(-) diff --git a/packages/extension-base/src/services/balance-service/helpers/group.ts b/packages/extension-base/src/services/balance-service/helpers/group.ts index bafe7a93da..e2d25f7a93 100644 --- a/packages/extension-base/src/services/balance-service/helpers/group.ts +++ b/packages/extension-base/src/services/balance-service/helpers/group.ts @@ -1,7 +1,7 @@ // Copyright 2019-2022 @subwallet/extension-base // SPDX-License-Identifier: Apache-2.0 -import { APIItemState } from '@subwallet/extension-base/background/KoniTypes'; +import { APIItemState, BitcoinBalanceMetadata } from '@subwallet/extension-base/background/KoniTypes'; import { BalanceItem } from '@subwallet/extension-base/types'; import { sumBN } from '@subwallet/extension-base/utils'; import BN from 'bn.js'; @@ -28,22 +28,15 @@ export const groupBalance = (items: BalanceItem[], address: string, token: strin : APIItemState.PENDING }; + let allInscription = 0; + for (const item of items) { - if (item.substrateInfo) { - if (!result.substrateInfo) { - result.substrateInfo = { ...item.substrateInfo }; - } else { - const old = { ...result.substrateInfo }; - const _new = { ...item.substrateInfo }; - - result.substrateInfo = { - reserved: new BN(old.reserved || '0').add(new BN(_new.reserved || '0')).toString(), - feeFrozen: new BN(old.feeFrozen || '0').add(new BN(_new.feeFrozen || '0')).toString(), - miscFrozen: new BN(old.miscFrozen || '0').add(new BN(_new.miscFrozen || '0')).toString() - }; - } - } + const inscriptionCount = (item.metadata as BitcoinBalanceMetadata)?.inscriptionCount; + + allInscription = inscriptionCount ? allInscription + inscriptionCount : allInscription; } + result.metadata = { inscriptionCount: allInscription } as BitcoinBalanceMetadata; + return result; }; diff --git a/packages/extension-koni-ui/src/Popup/Home/Nfts/utils.ts b/packages/extension-koni-ui/src/Popup/Home/Nfts/utils.ts index dd3f3d8043..a52550d684 100644 --- a/packages/extension-koni-ui/src/Popup/Home/Nfts/utils.ts +++ b/packages/extension-koni-ui/src/Popup/Home/Nfts/utils.ts @@ -3,6 +3,8 @@ import { BitcoinBalanceMetadata, NftCollection, NftItem } from '@subwallet/extension-base/background/KoniTypes'; import { AccountProxy } from '@subwallet/extension-base/background/types'; +import { ALL_ACCOUNT_KEY } from '@subwallet/extension-base/constants'; +import { ORDINAL_COLLECTION_INFO } from '@subwallet/extension-base/koni/api/nft/inscription'; import { BalanceInfo } from '@subwallet/extension-base/types'; export interface INftCollectionDetail { @@ -35,29 +37,27 @@ export function getTotalCollectionItems ( return itemsLength; } - if (collectionId === 'INSCRIPTION') { - for (const account of accountProxy.accounts) { - if (account.type !== 'bitcoin-86') { - continue; - } + const isAllAccount = accountProxy.proxyId === ALL_ACCOUNT_KEY; + const isTestnet = collectionId !== ORDINAL_COLLECTION_INFO.collectionId; + const accountType = isTestnet ? 'bittest-86' : 'bitcoin-86'; - const totalInscription = getTotalInscriptions(account.address, balanceMap); + if (isAllAccount) { + const totalInscription = getTotalInscriptions(ALL_ACCOUNT_KEY, balanceMap, isTestnet); - if (totalInscription) { - return totalInscription; - } + if (totalInscription) { + return totalInscription; + } + } + + for (const account of accountProxy.accounts) { + if (account.type !== accountType) { + continue; } - } else if (collectionId === 'INSCRIPTION_TESTNET') { - for (const account of accountProxy.accounts) { - if (account.type !== 'bittest-86') { - continue; - } - const totalInscription = getTotalInscriptions(account.address, balanceMap, true); + const totalInscription = getTotalInscriptions(account.address, balanceMap, isTestnet); - if (totalInscription) { - return totalInscription; - } + if (totalInscription) { + return totalInscription; } } From 1b08b30f37f8463c09e1bbe1d2e4f68774f34929 Mon Sep 17 00:00:00 2001 From: lw Date: Fri, 21 Jun 2024 15:41:24 +0700 Subject: [PATCH 15/17] Update logic for getTotalCollectionItems --- .../src/Popup/Home/Nfts/utils.ts | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/packages/extension-koni-ui/src/Popup/Home/Nfts/utils.ts b/packages/extension-koni-ui/src/Popup/Home/Nfts/utils.ts index a52550d684..946e0e243d 100644 --- a/packages/extension-koni-ui/src/Popup/Home/Nfts/utils.ts +++ b/packages/extension-koni-ui/src/Popup/Home/Nfts/utils.ts @@ -4,7 +4,7 @@ import { BitcoinBalanceMetadata, NftCollection, NftItem } from '@subwallet/extension-base/background/KoniTypes'; import { AccountProxy } from '@subwallet/extension-base/background/types'; import { ALL_ACCOUNT_KEY } from '@subwallet/extension-base/constants'; -import { ORDINAL_COLLECTION_INFO } from '@subwallet/extension-base/koni/api/nft/inscription'; +import { ORDINAL_COLLECTION_INFO, ORDINAL_COLLECTION_INFO_TEST } from '@subwallet/extension-base/koni/api/nft/inscription'; import { BalanceInfo } from '@subwallet/extension-base/types'; export interface INftCollectionDetail { @@ -33,31 +33,31 @@ export function getTotalCollectionItems ( balanceMap: Record, itemsLength: number ): number { - if (!accountProxy) { + if (!accountProxy || ![ORDINAL_COLLECTION_INFO.collectionId, ORDINAL_COLLECTION_INFO_TEST.collectionId].includes(collectionId)) { return itemsLength; } - const isAllAccount = accountProxy.proxyId === ALL_ACCOUNT_KEY; - const isTestnet = collectionId !== ORDINAL_COLLECTION_INFO.collectionId; - const accountType = isTestnet ? 'bittest-86' : 'bitcoin-86'; + const isTestnet = collectionId === ORDINAL_COLLECTION_INFO_TEST.collectionId; - if (isAllAccount) { + if (accountProxy.proxyId === ALL_ACCOUNT_KEY) { const totalInscription = getTotalInscriptions(ALL_ACCOUNT_KEY, balanceMap, isTestnet); if (totalInscription) { return totalInscription; } - } + } else { + const targetAccountType = isTestnet ? 'bittest-86' : 'bitcoin-86'; - for (const account of accountProxy.accounts) { - if (account.type !== accountType) { - continue; - } + for (const account of accountProxy.accounts) { + if (account.type !== targetAccountType) { + continue; + } - const totalInscription = getTotalInscriptions(account.address, balanceMap, isTestnet); + const totalInscription = getTotalInscriptions(account.address, balanceMap, isTestnet); - if (totalInscription) { - return totalInscription; + if (totalInscription) { + return totalInscription; + } } } From 956e44482c0adbd8d7844f729d05b0c0eeef1b8b Mon Sep 17 00:00:00 2001 From: bluezdot <72647326+bluezdot@users.noreply.github.com> Date: Fri, 21 Jun 2024 17:59:07 +0700 Subject: [PATCH 16/17] [Issue-182] fix bug proxy account on computing all acount --- packages/extension-base/src/services/balance-service/index.ts | 2 +- .../src/Popup/Home/Nfts/NftCollectionDetail.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/extension-base/src/services/balance-service/index.ts b/packages/extension-base/src/services/balance-service/index.ts index 989e906551..b7561580ae 100644 --- a/packages/extension-base/src/services/balance-service/index.ts +++ b/packages/extension-base/src/services/balance-service/index.ts @@ -305,7 +305,7 @@ export class BalanceService implements StoppableServiceInterface { } addLazy('updateBalanceStore', () => { - const isAllAccount = isAccountAll(this.state.keyringService.currentAccount.address); + const isAllAccount = isAccountAll(this.state.keyringService.currentAccountProxy.proxyId); this.balanceMap.updateBalanceItems(this.balanceUpdateCache, isAllAccount); diff --git a/packages/extension-koni-ui/src/Popup/Home/Nfts/NftCollectionDetail.tsx b/packages/extension-koni-ui/src/Popup/Home/Nfts/NftCollectionDetail.tsx index ba223fe38f..fe2ed03d36 100644 --- a/packages/extension-koni-ui/src/Popup/Home/Nfts/NftCollectionDetail.tsx +++ b/packages/extension-koni-ui/src/Popup/Home/Nfts/NftCollectionDetail.tsx @@ -209,7 +209,7 @@ function Component ({ className = '' }: Props): React.ReactElement { {collectionInfo.collectionName || collectionInfo.collectionId}
-  ({nftList.length}) +  ({totalItems})
)} From 5fc56ce73e951732ab49c3eb5b5a278f389ddd86 Mon Sep 17 00:00:00 2001 From: bluezdot <72647326+bluezdot@users.noreply.github.com> Date: Sat, 22 Jun 2024 11:34:41 +0700 Subject: [PATCH 17/17] [Issue-182] Fix bug init bitcoin cron nft --- packages/extension-base/src/koni/background/cron.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/extension-base/src/koni/background/cron.ts b/packages/extension-base/src/koni/background/cron.ts index ea3b0f78f8..3be21ad687 100644 --- a/packages/extension-base/src/koni/background/cron.ts +++ b/packages/extension-base/src/koni/background/cron.ts @@ -195,7 +195,7 @@ export class KoniCron { }; checkNetworkAvailable = (serviceInfo: ServiceInfo): boolean => { - return Object.keys(serviceInfo.chainApiMap.substrate).length > 0 || Object.keys(serviceInfo.chainApiMap.evm).length > 0; + return Object.keys(serviceInfo.chainApiMap.substrate).length > 0 || Object.keys(serviceInfo.chainApiMap.evm).length > 0 || Object.keys(serviceInfo.chainApiMap.bitcoin).length > 0; }; public async reloadNft () {