-
Notifications
You must be signed in to change notification settings - Fork 7
Standard for index discovery from ledgers #106
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from all commits
Commits
Show all changes
22 commits
Select commit
Hold shift + click to select a range
470b634
get git number for the discover index standard
bogwar 96f9448
initial file
bogwar ea02f8e
intro & metadata
bogwar 40a3ce7
include part of index.did
bogwar 4c65464
specify that metadata can be fetched via icrc1_get_metadata
bogwar 3566eb9
added some other methods for the index
bogwar 317af75
method descriptions for the index API?
bogwar 6ea31c3
remove numbering for API methods
bogwar 374be35
fixed the link to the standard
bogwar 98838cf
no error handlingin get_account_transactions description
bogwar 13aaa60
refinement of the Transaction types, fixex missing info
bogwar 43d368b
adjusted the text of the undocumented methods
bogwar 9c65052
fixes
bogwar d45963b
Update ICRCs/ICRC-106/ICRC-106.md
bogwar fca083d
Update ICRCs/ICRC-106/ICRC-106.md
bogwar 64cbbeb
Update ICRCs/ICRC-106/ICRC-106.md
bogwar 6cce7cd
Update ICRCs/ICRC-106/ICRC-106.md
bogwar a98a389
Update ICRCs/ICRC-106/ICRC-106.md
bogwar 9febeb5
Update ICRCs/ICRC-106/ICRC-106.md
bogwar c088a31
Update ICRCs/ICRC-106/ICRC-106.md
bogwar 95078c4
beautified .did; explain the use of subaccount listing
bogwar 2fee169
clarify the scope of the standard
bogwar File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,224 @@ | ||
| | Status | | ||
| |:------:| | ||
| |Draft| | ||
|
|
||
| # ICRC-106: Standard for Associating Index Canisters with ICRC-1 Tokens | ||
|
|
||
| ## 1. Introduction | ||
|
|
||
| Wallet applications and token management tools often need to retrieve both token metadata and transaction history for a given principal. However, identifying an associated index canister for ICRC-1 tokens is currently unstandardized, leading to inconsistencies in wallet integrations. | ||
|
|
||
| Standard **ICRC-106** : | ||
| 1. Introduces a standard approach for indicating the presence of an index canister for ICRC-1 tokens through ledger metadata. | ||
| 2. Defines a minimal interface for the associated index canister to facilitate querying transaction history in a consistent manner. | ||
|
|
||
| This draft standard aims to improve interoperability, simplify wallet integrations, and enable token-related applications to reliably access transaction histories. It acts as a placeholder and documentation source until a more comprehensive standard for index canisters will be developed. | ||
|
|
||
|
|
||
| ## 2. Metadata | ||
|
|
||
| A ledger implementing ICRC-106 MUST include the following entry in the output of the `icrc1_supported_standards` method: | ||
|
|
||
| ```candid | ||
| record { name = "ICRC-106"; url = "https://github.com/dfinity/ICRC/blob/main/ICRCs/ICRC-106" } | ||
| ``` | ||
|
|
||
| Additionally, the ledger MUST provide the following metadata entry retrievable via the `icrc1_metadata` method: | ||
|
|
||
| - `icrc106:index_principal` (text): The textual representation of the principal of the associated index canister. | ||
|
|
||
| These metadata entries allow clients to discover and interact with the index canister associated with a ledger and can be retrieved using method `icrc1_metadata` defined by the ICRC-1 standard. | ||
|
|
||
|
|
||
| Compliant ledgers MUST also implement the following endpoint for programmatically retrieving the index principal: | ||
|
|
||
| ```candid | ||
| icrc106_get_index_principal: () -> (principal) query; | ||
| ``` | ||
|
|
||
| The metadata entry `icrc106:index_principal` and the `icrc106_get_index_principal` method MUST provide consistent information. Specifically: | ||
|
|
||
| - The `icrc106:index_principal` metadata entry MUST represent the textual form of the principal returned by the `icrc106_get_index_principal` method. | ||
| - The `icrc106_get_index_principal` method MUST return the principal corresponding to the index canister associated with the ledger, as specified in the `icrc106:index_principal` metadata entry. | ||
|
|
||
| This requirement ensures that both mechanisms reliably point to the same index canister. | ||
|
|
||
|
|
||
| ## 3. Index Canister Interface | ||
|
|
||
| The index canister associated with the ledger SHOULD implement the following minimal Candid interface: | ||
bogwar marked this conversation as resolved.
Show resolved
Hide resolved
bogwar marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| ```candid | ||
| type Tokens = nat; | ||
|
|
||
| type BlockIndex = nat; | ||
|
|
||
| type SubAccount = blob; | ||
bogwar marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| type Account = record { | ||
| owner: principal; | ||
| subaccount: opt SubAccount; | ||
| }; | ||
|
|
||
| type GetAccountTransactionsArgs = record { | ||
| account: Account; | ||
| start: opt BlockIndex; // The block index of the last transaction seen by the client. | ||
| max_results: nat; // Maximum number of transactions to fetch. | ||
| }; | ||
|
|
||
| type Burn = record { | ||
| from : Account; | ||
| memo : opt blob; | ||
| created_at_time : opt nat64; | ||
bogwar marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| amount : Tokens; | ||
| spender : opt Account; | ||
| }; | ||
|
|
||
| type Mint = record { | ||
| to : Account; | ||
| memo : opt blob; | ||
| created_at_time : opt nat64; | ||
| amount : Tokens; | ||
| }; | ||
|
|
||
| type Transfer = record { | ||
| to : Account; | ||
| fee : opt Tokens; | ||
| from : Account; | ||
| memo : opt blob; | ||
| created_at_time : opt nat64; | ||
bogwar marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| amount : Tokens; | ||
| spender : opt Account; | ||
| }; | ||
|
|
||
| type Approve = record { | ||
| fee : opt Tokens; | ||
| from : Account; | ||
| memo : opt blob; | ||
| created_at_time : opt nat64; | ||
bogwar marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| amount : Tokens; | ||
| expected_allowance : opt nat; | ||
bogwar marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| expires_at : opt nat64; | ||
bogwar marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| spender : Account; | ||
| }; | ||
|
|
||
| type Transaction = record { | ||
| burn : opt Burn; | ||
| kind : text; | ||
bogwar marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| mint : opt Mint; | ||
| approve : opt Approve; | ||
| timestamp : nat64; | ||
bogwar marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| transfer : opt Transfer; | ||
| }; | ||
|
|
||
| type TransactionWithId = record { | ||
| id : BlockIndex; | ||
| transaction : Transaction; | ||
| }; | ||
|
|
||
| type GetTransactions = record { | ||
| balance : Tokens; | ||
| transactions : vec TransactionWithId; | ||
| // The txid of the oldest transaction the account has | ||
| oldest_tx_id : opt BlockIndex; | ||
| }; | ||
|
|
||
| type GetTransactionsErr = record { | ||
| message : text; | ||
| }; | ||
|
|
||
| type GetAccountTransactionsResult = variant { | ||
| Ok : GetTransactions; | ||
| Err : GetTransactionsErr; | ||
| }; | ||
|
|
||
| type ListSubaccountsArgs = record { | ||
| owner: principal; | ||
| start: opt SubAccount; | ||
| }; | ||
|
|
||
| type Status = record { | ||
| num_blocks_synced : BlockIndex; | ||
| }; | ||
|
|
||
| service : { | ||
bogwar marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| get_account_transactions: (GetAccountTransactionsArgs) -> (GetAccountTransactionsResult) query; | ||
| ledger_id: () -> (principal) query; | ||
| list_subaccounts : (ListSubaccountsArgs) -> (vec SubAccount) query; | ||
bogwar marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| status : () -> (Status) query; | ||
| } | ||
| ``` | ||
|
|
||
|
|
||
|
|
||
| # Methods Provided by the Index Canister | ||
|
|
||
| The index canister provides methods to facilitate querying of transaction history and metadata associated with accounts. Below is a description of the relevant methods specified in this standard, including their purpose, input, output, and typical use case. | ||
|
|
||
| --- | ||
|
|
||
| ## get_account_transactions | ||
| - **Purpose**: Retrieves transactions associated with a specific account, starting from a specified block index and returning up to a maximum number of results. Transactions are returned in **reverse chronological order** (newest to oldest). | ||
| - **Input**: | ||
| - `account`: The account (principal and optional subaccount) for which transactions are to be fetched. | ||
| - `start`: *(Optional)* The block index of the most recent transaction the client has already seen. If provided, only transactions with block indices **less than** this value will be returned. | ||
| - `max_results`: The maximum number of transactions to return. | ||
| - **Output**: | ||
| - **`Ok`**: Returns a record containing: | ||
| - `balance`: The current token balance of the account. | ||
| - `transactions`: A vector of `TransactionWithId`, each containing: | ||
| - `id`: The block index of the transaction. | ||
| - `transaction`: Details of the transaction (burn, transfer, approval, and timestamp). | ||
| - `oldest_tx_id`: *(Optional)* The block index of the oldest transaction for the account, or `None` if no transactions exist. | ||
| - **Typical Use Case**: This method is often used by wallets to display transaction history and update account balances. It also supports paginated transaction retrieval for efficient history browsing. | ||
|
|
||
| --- | ||
|
|
||
| ## list_subaccounts | ||
| - **Purpose**: Lists all subaccounts associated with a specified principal. | ||
| - **Input**: | ||
| - `owner`: The principal for which to list subaccounts. | ||
bogwar marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| - `start`: *(Optional)* Specifies the subaccount to start listing from. Only subaccounts lexicographically greater than `start` will be included. If start is omitted, the method will return all subaccounts from the beginning of the list, ordered lexicographically. | ||
bogwar marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| - **Output**: A vector of `SubAccount`, each representing a subaccount under the specified principal. The list will be empty if the principal has not used subaccounts, or if there are no subaccounts lexicographically higher than `start`. | ||
| - **Typical Use Case**: Useful for wallets or tools that need to enumerate *all* subaccounts associated with a user. To get all subaccounts, start with no start parameter and repeatedly call the method, updating start with the last subaccount from each response, until the returned list is empty. | ||
|
|
||
|
|
||
| --- | ||
|
|
||
| ## ledger_id | ||
| - **Purpose**: Retrieves the principal of the ledger canister that the index is linked to. | ||
| - **Input**: None. | ||
| - **Output**: The `principal` of the ledger canister. | ||
| - **Typical Use Case**: This method is primarily used for validating the relationship between the index and the ledger, ensuring they are correctly linked, and facilitating integrations requiring the ledger’s identity. | ||
|
|
||
|
|
||
| --- | ||
|
|
||
| ## status | ||
| - **Purpose**: Retrieves the synchronization and operational status of the index canister. | ||
| - **Input**: None. | ||
| - **Output**: A `Status` record containing: | ||
| - `num_blocks_synced`: The total number of blocks that have been successfully synchronized by the index canister. | ||
| - **Typical Use Case**: Used for monitoring the health and synchronization status of the index, this method is helpful for determining whether the index has fully caught up with the ledger and is operational. | ||
|
|
||
|
|
||
| ## Optional Methods | ||
bogwar marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| While the methods defined in this standard are sufficient for compliance with ICRC-106, certain implementations of the index canister may include additional methods to extend functionality. These methods are not required by ICRC-106 but may be present for advanced use cases: | ||
|
|
||
| - **`get_blocks`**: Fetches raw block data for a specified range of indices. This is useful for applications requiring detailed historical data. | ||
| - **`get_fee_collectors_ranges`**: Provides detailed information about fee collection, including accounts and associated block ranges. | ||
| - **`icrc1_balance_of`**: Queries the token balance of specific accounts. This method is commonly used for token management in wallets and tools. | ||
|
|
||
| These methods, while potentially helpful, are outside the scope of ICRC-106 and are not guaranteed to be present in all index canisters. Developers should refer to the documentation of the specific implementation they are working with for details on these optional methods. | ||
bogwar marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
|
|
||
|
|
||
|
|
||
| ## 4. Implementation Considerations | ||
|
|
||
| Implementers should ensure that: | ||
| - The `icrc106:index_principal` metadata entry accurately reflects the principal of the associated index canister. | ||
bogwar marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| - Any changes to the index canister interface should maintain backward compatibility. | ||
|
|
||
| By adhering to ICRC-106, ledger canisters provide a standardized mechanism for clients to discover and interact with their associated index canisters, improving integration and user experience within the Internet Computer ecosystem. | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.