diff --git a/docs/src/developing/clients/jsonrpc-api.md b/docs/src/developing/clients/jsonrpc-api.md index 145dad27a7..237558c6f4 100644 --- a/docs/src/developing/clients/jsonrpc-api.md +++ b/docs/src/developing/clients/jsonrpc-api.md @@ -588,6 +588,7 @@ The JSON structure of token balances is defined as a list of objects in the foll - `accountIndex: ` - Index of the account in which the token balance is provided for. - `mint: ` - Pubkey of the token's mint. - `owner: ` - Pubkey of token balance's owner. +- `programId: ` - Pubkey of the Token program that owns the account. - `uiTokenAmount: ` - - `amount: ` - Raw amount of tokens as a string, ignoring decimals. - `decimals: ` - Number of decimals configured for token's mint. @@ -2546,7 +2547,7 @@ Returns all SPL Token accounts by approved Delegate. - `` - Pubkey of account delegate to query, as base-58 encoded string - `` - Either: - `mint: ` - Pubkey of the specific token Mint to limit accounts to, as base-58 encoded string; or - - `programId: ` - Pubkey of the Token program ID that owns the accounts, as base-58 encoded string + - `programId: ` - Pubkey of the Token program that owns the accounts, as base-58 encoded string - `` - (optional) Configuration object containing the following optional fields: - (optional) [Commitment](jsonrpc-api.md#configuring-state-commitment) - `encoding: ` - encoding for Account data, either "base58" (_slow_), "base64", "base64+zstd" or "jsonParsed". @@ -2648,7 +2649,7 @@ Returns all SPL Token accounts by token owner. - `` - Pubkey of account owner to query, as base-58 encoded string - `` - Either: - `mint: ` - Pubkey of the specific token Mint to limit accounts to, as base-58 encoded string; or - - `programId: ` - Pubkey of the Token program ID that owns the accounts, as base-58 encoded string + - `programId: ` - Pubkey of the Token program that owns the accounts, as base-58 encoded string - `` - (optional) Configuration object containing the following optional fields: - (optional) [Commitment](jsonrpc-api.md#configuring-state-commitment) - `encoding: ` - encoding for Account data, either "base58" (_slow_), "base64", "base64+zstd" or "jsonParsed". @@ -3762,7 +3763,8 @@ The notification will be an object with the following fields: "amount": "0", "uiAmountString": "0" }, - "owner": "LieKvPRE8XeX3Y2xVNHjKlpAScD12lYySBVQ4HqoJ5op" + "owner": "LieKvPRE8XeX3Y2xVNHjKlpAScD12lYySBVQ4HqoJ5op", + "programId": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" }, { "accountIndex": 5, @@ -3773,7 +3775,8 @@ The notification will be an object with the following fields: "amount": "11513067900", "uiAmountString": "11513.0679" }, - "owner": "rXhAofQCT7NN9TUqigyEAUzV1uLL4boeD8CRkNBSkYk" + "owner": "rXhAofQCT7NN9TUqigyEAUzV1uLL4boeD8CRkNBSkYk", + "programId": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" }, { "accountIndex": 10, @@ -3784,7 +3787,8 @@ The notification will be an object with the following fields: "amount": "0", "uiAmountString": "0" }, - "owner": "CL9wkGFT3SZRRNa9dgaovuRV7jrVVigBUZ6DjcgySsCU" + "owner": "CL9wkGFT3SZRRNa9dgaovuRV7jrVVigBUZ6DjcgySsCU", + "programId": "TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb" }, { "accountIndex": 11, @@ -3795,7 +3799,8 @@ The notification will be an object with the following fields: "amount": "15138514093", "uiAmountString": "15138.514093" }, - "owner": "LieKvPRE8XeX3Y2xVNHjKlpAScD12lYySBVQ4HqoJ5op" + "owner": "LieKvPRE8XeX3Y2xVNHjKlpAScD12lYySBVQ4HqoJ5op", + "programId": "TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb" } ], "postTokenBalances": [ @@ -3808,7 +3813,8 @@ The notification will be an object with the following fields: "amount": "0", "uiAmountString": "0" }, - "owner": "LieKvPRE8XeX3Y2xVNHjKlpAScD12lYySBVQ4HqoJ5op" + "owner": "LieKvPRE8XeX3Y2xVNHjKlpAScD12lYySBVQ4HqoJ5op", + "programId": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" }, { "accountIndex": 5, @@ -3819,7 +3825,8 @@ The notification will be an object with the following fields: "amount": "11513103028", "uiAmountString": "11513.103028" }, - "owner": "rXhAofQCT7NN9TUqigyEAUzV1uLL4boeD8CRkNBSkYk" + "owner": "rXhAofQCT7NN9TUqigyEAUzV1uLL4boeD8CRkNBSkYk", + "programId": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" }, { "accountIndex": 10, @@ -3830,7 +3837,8 @@ The notification will be an object with the following fields: "amount": "0", "uiAmountString": "0" }, - "owner": "CL9wkGFT3SZRRNa9dgaovuRV7jrVVigBUZ6DjcgySsCU" + "owner": "CL9wkGFT3SZRRNa9dgaovuRV7jrVVigBUZ6DjcgySsCU", + "programId": "TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb" }, { "accountIndex": 11, @@ -3841,7 +3849,8 @@ The notification will be an object with the following fields: "amount": "15489767829", "uiAmountString": "15489.767829" }, - "owner": "BeiHVPRE8XeX3Y2xVNrSsTpAScH94nYySBVQ4HqgN9at" + "owner": "BeiHVPRE8XeX3Y2xVNrSsTpAScH94nYySBVQ4HqgN9at", + "programId": "TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb" } ], "rewards": [] diff --git a/ledger/src/blockstore.rs b/ledger/src/blockstore.rs index 93751bd747..e9ed43565c 100644 --- a/ledger/src/blockstore.rs +++ b/ledger/src/blockstore.rs @@ -8796,6 +8796,7 @@ pub mod tests { ui_amount_string: "1.1".to_string(), }, owner: Pubkey::new_unique().to_string(), + program_id: Pubkey::new_unique().to_string(), }]), post_token_balances: Some(vec![TransactionTokenBalance { account_index: 0, @@ -8807,6 +8808,7 @@ pub mod tests { ui_amount_string: "1.1".to_string(), }, owner: Pubkey::new_unique().to_string(), + program_id: Pubkey::new_unique().to_string(), }]), rewards: Some(vec![Reward { pubkey: "My11111111111111111111111111111111111111111".to_string(), diff --git a/rpc/src/transaction_status_service.rs b/rpc/src/transaction_status_service.rs index c61743af6b..0e8b4d44e8 100644 --- a/rpc/src/transaction_status_service.rs +++ b/rpc/src/transaction_status_service.rs @@ -360,11 +360,13 @@ pub(crate) mod tests { }; let owner = Pubkey::new_unique().to_string(); + let token_program_id = Pubkey::new_unique().to_string(); let pre_token_balance = TransactionTokenBalance { account_index: 0, mint: Pubkey::new_unique().to_string(), ui_token_amount: token_amount_to_ui_amount(42, 2), owner: owner.clone(), + program_id: token_program_id.clone(), }; let post_token_balance = TransactionTokenBalance { @@ -372,6 +374,7 @@ pub(crate) mod tests { mint: Pubkey::new_unique().to_string(), ui_token_amount: token_amount_to_ui_amount(58, 2), owner, + program_id: token_program_id, }; let token_balances = TransactionTokenBalancesSet { diff --git a/storage-proto/proto/confirmed_block.proto b/storage-proto/proto/confirmed_block.proto index b2a6c48898..5d69f0e9c2 100644 --- a/storage-proto/proto/confirmed_block.proto +++ b/storage-proto/proto/confirmed_block.proto @@ -81,6 +81,7 @@ message TokenBalance { string mint = 2; UiTokenAmount ui_token_amount = 3; string owner = 4; + string program_id = 5; } message UiTokenAmount { diff --git a/storage-proto/src/convert.rs b/storage-proto/src/convert.rs index 57fbe4edb8..997898ea60 100644 --- a/storage-proto/src/convert.rs +++ b/storage-proto/src/convert.rs @@ -549,6 +549,7 @@ impl From for generated::TokenBalance { ui_amount_string: value.ui_token_amount.ui_amount_string, }), owner: value.owner, + program_id: value.program_id, } } } @@ -577,6 +578,7 @@ impl From for TransactionTokenBalance { }, }, owner: value.owner, + program_id: value.program_id, } } } diff --git a/storage-proto/src/lib.rs b/storage-proto/src/lib.rs index 04b98a99bc..90cb019033 100644 --- a/storage-proto/src/lib.rs +++ b/storage-proto/src/lib.rs @@ -116,6 +116,8 @@ pub struct StoredTransactionTokenBalance { pub ui_token_amount: StoredTokenAmount, #[serde(deserialize_with = "default_on_eof")] pub owner: String, + #[serde(deserialize_with = "default_on_eof")] + pub program_id: String, } impl From for TransactionTokenBalance { @@ -125,12 +127,14 @@ impl From for TransactionTokenBalance { mint, ui_token_amount, owner, + program_id, } = value; Self { account_index, mint, ui_token_amount: ui_token_amount.into(), owner, + program_id, } } } @@ -142,12 +146,14 @@ impl From for StoredTransactionTokenBalance { mint, ui_token_amount, owner, + program_id, } = value; Self { account_index, mint, ui_token_amount: ui_token_amount.into(), owner, + program_id, } } } diff --git a/transaction-status/src/lib.rs b/transaction-status/src/lib.rs index dc0e53178c..545acdc4fb 100644 --- a/transaction-status/src/lib.rs +++ b/transaction-status/src/lib.rs @@ -241,6 +241,7 @@ pub struct TransactionTokenBalance { pub mint: String, pub ui_token_amount: UiTokenAmount, pub owner: String, + pub program_id: String, } #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] @@ -251,6 +252,8 @@ pub struct UiTransactionTokenBalance { pub ui_token_amount: UiTokenAmount, #[serde(default, skip_serializing_if = "Option::is_none")] pub owner: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub program_id: Option, } impl From for UiTransactionTokenBalance { @@ -264,6 +267,11 @@ impl From for UiTransactionTokenBalance { } else { None }, + program_id: if !token_balance.program_id.is_empty() { + Some(token_balance.program_id) + } else { + None + }, } } } diff --git a/transaction-status/src/token_balances.rs b/transaction-status/src/token_balances.rs index f7885e8302..d8d007a0b7 100644 --- a/transaction-status/src/token_balances.rs +++ b/transaction-status/src/token_balances.rs @@ -76,6 +76,7 @@ pub fn collect_token_balances( mint, ui_token_amount, owner, + program_id, }) = collect_token_balance_from_account(bank, account_id, mint_decimals) { transaction_balances.push(TransactionTokenBalance { @@ -83,6 +84,7 @@ pub fn collect_token_balances( mint, ui_token_amount, owner, + program_id, }); } } @@ -102,6 +104,7 @@ struct TokenBalanceData { mint: String, owner: String, ui_token_amount: UiTokenAmount, + program_id: String, } fn collect_token_balance_from_account( @@ -128,6 +131,7 @@ fn collect_token_balance_from_account( mint: token_account.mint.to_string(), owner: token_account.owner.to_string(), ui_token_amount: token_amount_to_ui_amount(token_account.amount, decimals), + program_id: account.owner().to_string(), }) } @@ -266,7 +270,8 @@ mod test { decimals: 2, amount: "42".to_string(), ui_amount_string: "0.42".to_string(), - } + }, + program_id: spl_token::id().to_string(), }) );