Repository: Chia-Network/chia-blockchain
Pull request: Added: Support CLI NFT Pagination
Closes #15260 

Following the instructions in issue #15260, exposed `count` (as `--num`) and `start_index` (as `--start-index`) through to `nft_get_nfts` rpc call via the `chia wallet nft list ...` command.

Issue #15260 is assigned to @paninaro and any work by them for this issue can take precedence. The issue doesn't have any labels assigned so there might be a different direction that I'm unaware of. 

Regardless I had some free time today and saw the issue as low-hanging with my familiarity with the CLI paths, I have no opinion if this PR is accepted or denied.

<!-- Merging Requirements:
- Please give your PR a title that is release-note friendly
- In order to be merged, you must add the most appropriate category Label (Added, Changed, Fixed) to your PR
-->
<!-- Explain why this is an improvement (Does this add missing functionality, improve performance, or reduce complexity?) -->
### Purpose:

To support pagination NFT listing pagination from the CLI

<!-- Does this PR introduce a breaking change? -->
### Current Behavior:

Listing NFTs from the CLI like 

    chia wallet nft list ...

~is hard-coded to 100,000 (previously 50 before #15293).~ _Changed in https://github.com/Chia-Network/chia-blockchain/pull/15342/commits/33aa6da9c1b69d16ba02b5a847401f0074ea4eb3 and https://github.com/Chia-Network/chia-blockchain/pull/15342/commits/d02d32f99dc9ab335e4af0e64b846fc996d191fd to `50`_


### New Behavior:

Listing NFTs from the CLI can be paginated by supplying `--num` and `--start-index` args, like: 

    chia wallet nft list --num 200 --start-index 100 ...

<!-- As we aim for complete code coverage, please include details regarding unit, and regression tests -->
### Testing Notes:

I created a NFT wallet on testnet, and minted 2 NFTs to it. 

- I requested didn't supply any `--num` or `--starting-index` and the CLI returned all (2) NFTs
- I requested `--num 1` with `chia wallet nft list -i 8 --num 1` and was given back only 1 NFT
- I requested `--num 1`, `--start-index 1` with `chia wallet nft list -i 8 --num 1 --start-index 1` and was given back only 1 NFT, which was the 2nd NFT
- I requested `--start-index 1` with `chia wallet nft list -i 8 --start-index 1` and was given back all NFTs after index=1, which was the 2nd NFT
- I requested `--num 9999999` (`9_999_999`) with `chia wallet nft list -i 8 --num 9999999` and was returned all (2) NFTs
- I requested `--start-index 3` with `chia wallet nft list -i 8 --start-index 2` and was given the message `No NFTs Found for wallet with id 8 on key 1234567890` (Appropriately)

<!-- Attach any visual examples, or supporting evidence (attach any .gif/video/console output below) -->

### chia-docs Notes:

Depending if the `--num`, `--start-index` help text I used is appropriate - there is a separate PR for [cli-reference/nfts.md](https://github.com/Chia-Network/chia-docs/blob/main/docs/cli-reference/nfts.md) available here: https://github.com/Chia-Network/chia-docs/pull/303

Problem statement:
CLI nft listing doesn't support pagination
When listing NFTs on the CLI, the number of returned NFTs is capped at 50 due to the RPC hardcoding a default `num` value. Since the CLI doesn't expose `--start-index` and `--num` options, there's no way to get a complete listing for collections > 50 NFTs.

Should be a simple change to expose those flags and pass them through to the `nft_get_nfts` RPC.

Hints from issue discussion:

Commit message: Merge branch 'Chia-Network:main' into 15260-nft-pagination-with-args-exposed-to-rpc-nft_get_nfts

Patch to review:
diff --git a/chia/cmds/wallet.py b/chia/cmds/wallet.py
index 2acd0eae837e..9288ff80fe65 100644
--- a/chia/cmds/wallet.py
+++ b/chia/cmds/wallet.py
@@ -1139,12 +1139,14 @@ def nft_transfer_cmd(
 )
 @click.option("-f", "--fingerprint", help="Set the fingerprint to specify which key to use", type=int)
 @click.option("-i", "--id", help="Id of the NFT wallet to use", type=int, required=True)
-def nft_list_cmd(wallet_rpc_port: Optional[int], fingerprint: int, id: int) -> None:
+@click.option("--num", help="Number of NFTs to return", type=int, default=100_000)
+@click.option("--start-index", help="Which starting index to list NFTs from, used in pagination", type=int, default=0)
+def nft_list_cmd(wallet_rpc_port: Optional[int], fingerprint: int, id: int, num: int, start_index: int) -> None:
     import asyncio
 
     from .wallet_funcs import list_nfts
 
-    extra_params = {"wallet_id": id}
+    extra_params = {"wallet_id": id, "num": num, "start_index": start_index}
     asyncio.run(execute_with_wallet(wallet_rpc_port, fingerprint, extra_params, list_nfts))
 
 
diff --git a/chia/cmds/wallet_funcs.py b/chia/cmds/wallet_funcs.py
index 83b4f6ccbcef..fb5bdd038e95 100644
--- a/chia/cmds/wallet_funcs.py
+++ b/chia/cmds/wallet_funcs.py
@@ -1077,9 +1077,11 @@ def print_nft_info(nft: NFTInfo, *, config: Dict[str, Any]) -> None:
 
 async def list_nfts(args: Dict, wallet_client: WalletRpcClient, fingerprint: int) -> None:
     wallet_id = args["wallet_id"]
+    num = args["num"]
+    start_index = args["start_index"]
     try:
         config = load_config(DEFAULT_ROOT_PATH, "config.yaml", SERVICE_NAME)
-        response = await wallet_client.list_nfts(wallet_id)
+        response = await wallet_client.list_nfts(wallet_id, num, start_index)
         nft_list = response["nft_list"]
         if len(nft_list) > 0:
             for n in nft_list:
diff --git a/chia/rpc/wallet_rpc_client.py b/chia/rpc/wallet_rpc_client.py
index 39a29122e33f..6835d4a03176 100644
--- a/chia/rpc/wallet_rpc_client.py
+++ b/chia/rpc/wallet_rpc_client.py
@@ -958,8 +958,8 @@ async def count_nfts(self, wallet_id: Optional[int]):
         response = await self.fetch("nft_count_nfts", request)
         return response
 
-    async def list_nfts(self, wallet_id):
-        request: Dict[str, Any] = {"wallet_id": wallet_id, "num": 100_000}
+    async def list_nfts(self, wallet_id, num=100_000, start_index=0):
+        request: Dict[str, Any] = {"wallet_id": wallet_id, "num": num, "start_index": start_index}
         response = await self.fetch("nft_get_nfts", request)
         return response
 


Code review comments:
diff_hunk: @@ -1139,12 +1139,14 @@ def nft_transfer_cmd(
 )
 @click.option("-f", "--fingerprint", help="Set the fingerprint to specify which key to use", type=int)
 @click.option("-i", "--id", help="Id of the NFT wallet to use", type=int, required=True)
-def nft_list_cmd(wallet_rpc_port: Optional[int], fingerprint: int, id: int) -> None:
+@click.option("--num", help="Number of NFTs to return", type=int, default=100_000)
+@click.option("--start-index", help="Which starting index to list NFTs from, used in pagination", type=int, default=0)
path: chia/cmds/wallet.py
text: @user1:
there is no pagination (as in, pages are not used but offset), so I'd remove last part of the sentence 

@author:
will do

@author:
I've rephrased it a little for I think a little better legibility, after removing mention of pagination https://github.com/Chia-Network/chia-blockchain/pull/15342/commits/17ea29321cd1b5239c39e33eaff7b1a10d272169

diff_hunk: @@ -958,8 +958,8 @@ async def count_nfts(self, wallet_id: Optional[int]):
         response = await self.fetch("nft_count_nfts", request)
         return response
 
-    async def list_nfts(self, wallet_id):
-        request: Dict[str, Any] = {"wallet_id": wallet_id, "num": 100_000}
+    async def list_nfts(self, wallet_id, num=100_000, start_index=0):
path: chia/rpc/wallet_rpc_client.py
text: @user1:
100k limit was there because we didn't have pagination, it's better to move this back to `50`. 
```suggestion
async def list_nfts(self, wallet_id, num=50, start_index=0):
```

diff_hunk: @@ -1139,12 +1139,14 @@ def nft_transfer_cmd(
 )
 @click.option("-f", "--fingerprint", help="Set the fingerprint to specify which key to use", type=int)
 @click.option("-i", "--id", help="Id of the NFT wallet to use", type=int, required=True)
-def nft_list_cmd(wallet_rpc_port: Optional[int], fingerprint: int, id: int) -> None:
+@click.option("--num", help="Number of NFTs to return", type=int, default=100_000)
path: chia/cmds/wallet.py
text: @user2:
```suggestion
@user1.option("--num", help="Number of NFTs to return", type=int, default=50)
```