diff --git a/Cargo.lock b/Cargo.lock
index 825ab5e78..72766bcf7 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2487,6 +2487,7 @@ dependencies = [
"ed25519-dalek",
"futures",
"hex 0.4.3",
+ "indenter",
"indicatif",
"inquire",
"interactive-clap",
diff --git a/Cargo.toml b/Cargo.toml
index 0fe903c75..ee190c237 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -53,6 +53,7 @@ open = "5"
shell-words = "1"
cargo-util = "0.1.1"
indicatif = "0.17.8"
+indenter = "0.3"
tracing = "0.1.40"
tracing-indicatif = "0.3.6"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
diff --git a/docs/GUIDE.en.md b/docs/GUIDE.en.md
index b4a8f93eb..a41f31da4 100644
--- a/docs/GUIDE.en.md
+++ b/docs/GUIDE.en.md
@@ -17,6 +17,244 @@ near --offline tokens \
sign-later
```
+_near CLI_ is a great tool for understanding NEAR on the low level. For example, if you want to view more detailed information about the RPC calls being made and their parameters, simply run the CLI with the `--teach-me` flag:
+```txt
+near --teach-me tokens \
+ fro_volod.testnet \
+ send-near volodymyr.testnet 0.1NEAR \
+ network-config testnet \
+ sign-with-keychain \
+ send
+```
+
+The result of this command will be as follows:
+
+```txt
+Unsigned transaction:
+
+signer_id: fro_volod.testnet
+receiver_id: volodymyr.testnet
+actions:
+ -- transfer deposit: 0.1 NEAR
+
+ INFO Signing the transaction with a key saved in the secure keychain ...:Getting a list of: fro_volod.testnet access keys ...
+ INFO I am making HTTP call to NEAR JSON RPC to get a list of keys for `fro_volod.testnet` account, learn more https://docs.near.org/api/rpc/access-keys#view-access-key-list
+ INFO HTTP POST https://archival-rpc.testnet.near.org/
+ INFO JSON Body:
+ | {
+ | "id": "RSDcGn4WP",
+ | "jsonrpc": "2.0",
+ | "method": "query",
+ | "params": {
+ | "account_id": "fro_volod.testnet",
+ | "finality": "final",
+ | "request_type": "view_access_key_list"
+ | }
+ | }
+ INFO JSON RPC Response:
+ | {
+ | "block_hash": "DaoWCSVSMVS6d5rLsYBgVKwSKb8XxZWN2KpEg2dQEbEY",
+ | "block_height": 169978024,
+ | "keys": [
+ | {
+ | "access_key": {
+ | "nonce": 116133598000035,
+ | "permission": "FullAccess"
+ | },
+ | "public_key": "ed25519:1TprKa4burMqDMjDHyBSUaFQQczF7NamhxTx2yEXe9P"
+ | },
+ | {
+ | "access_key": {
+ | "nonce": 94982716000000,
+ | "permission": {
+ | "FunctionCall": {
+ | "allowance": "250000000000000000000000",
+ | "method_names": [],
+ | "receiver_id": "mintspace2.testnet"
+ | }
+ | }
+ | },
+ | "public_key": "ed25519:7YCfA1KrToJtAYGTBgAMe4LWfQEi4iwLGcH2q5SvGKzD"
+ | },
+ | {
+ | "access_key": {
+ | "nonce": 147781057000109,
+ | "permission": "FullAccess"
+ | },
+ | "public_key": "ed25519:7siBhHN2eYNCubz5jAJhMdo34x33QJt5ZgUJBTNifZAx"
+ | },
+ | {
+ | "access_key": {
+ | "nonce": 101493245000000,
+ | "permission": {
+ | "FunctionCall": {
+ | "allowance": "10000000000000000000000000",
+ | "method_names": [
+ | "set_a",
+ | "set_b"
+ | ],
+ | "receiver_id": "meta.pool.testnet"
+ | }
+ | }
+ | },
+ | "public_key": "ed25519:8KHRkmpWbAp6wHZ5imAGFZzRAHzha2cZoz7cc3J42Bz8"
+ | },
+ | {
+ | "access_key": {
+ | "nonce": 98944792000000,
+ | "permission": "FullAccess"
+ | },
+ | "public_key": "ed25519:8dGkLiLD285Pzgp6v4mhaUbJyFvwEMvzjss1u9xZokTz"
+ | },
+ | {
+ | "access_key": {
+ | "nonce": 105032344000005,
+ | "permission": "FullAccess"
+ | },
+ | "public_key": "ed25519:J5uajy3m24sEQdw1uWA5kD2i3PDcxRxcFYotVZqRyrm6"
+ | }
+ | ]
+ | }
+ INFO Signing the transaction with a key saved in the secure keychain ...:Trying to sign with the legacy keychain ...:Signing the transaction with a key saved in legacy keychain ...:Getting access key information:: ed25519:7siBhHN2eYNCubz5jAJhMdo34x33QJt5ZgUJBTNifZAx on fro_volod.testnet account ...
+ INFO I am making HTTP call to NEAR JSON RPC to get an access key ed25519:7siBhHN2eYNCubz5jAJhMdo34x33QJt5ZgUJBTNifZAx details on `fro_volod.testnet` account, learn more https://docs.near.org/api/rpc/access-keys#view-access-key
+ INFO HTTP POST https://archival-rpc.testnet.near.org/
+ INFO JSON Body:
+ | {
+ | "id": "3DCGHrjRK",
+ | "jsonrpc": "2.0",
+ | "method": "query",
+ | "params": {
+ | "account_id": "fro_volod.testnet",
+ | "finality": "optimistic",
+ | "public_key": "ed25519:7siBhHN2eYNCubz5jAJhMdo34x33QJt5ZgUJBTNifZAx",
+ | "request_type": "view_access_key"
+ | }
+ | }
+ INFO JSON RPC Response:
+ | {
+ | "block_hash": "BDT76QHmdMC5yKHBuJBi3vgAC1j4hPSHoX5oVFpx1SG2",
+ | "block_height": 169978028,
+ | "nonce": 147781057000109,
+ | "permission": "FullAccess"
+ | }
+
+Your transaction was signed successfully.
+Public key: ed25519:7siBhHN2eYNCubz5jAJhMdo34x33QJt5ZgUJBTNifZAx
+Signature: ed25519:4r8YNLMkqhxSTFLejMf8JvZw6q8ue9BuQHf7JEycamAWCqLckfE5zNG7ceWoUfagQaJLTunD59ig4LuecYyVk8Qe
+ INFO Sending transaction ...:Broadcasting transaction via RPC: https://archival-rpc.testnet.near.org/
+ INFO I am making HTTP call to NEAR JSON RPC to broadcast a transaction, learn more https://docs.near.org/api/rpc/transactions#send-tx
+ INFO HTTP POST https://archival-rpc.testnet.near.org/
+ INFO JSON Body:
+ | {
+ | "id": "1ARLaDA3J",
+ | "jsonrpc": "2.0",
+ | "method": "broadcast_tx_commit",
+ | "params": [
+ | "EQAAAGZyb192b2xvZC50ZXN0bmV0AGYjuraPK0UBuPn9vFOErFp7IcGKqhQ5AqH8v2LHNdzhrjJo9WeGAAARAAAAdm9sb2R5bXlyLnRlc3RuZXSXxVsmKUVo0lmnzQ013O+bqjznbnB5g/3biI+j62VuOwEAAAADAACA9krhxwItFQAAAAAAAADAazoMP0kIphzt/zQ7Z97rr64FLGGsXMJDS8sXpuX8WwQdEgF6GZX+fz8hvKx5GqB4nrxnwrxbZScTQcs9mcEP"
+ | ]
+ | }
+ INFO JSON RPC Response:
+ | {
+ | "receipts_outcome": [
+ | {
+ | "block_hash": "7rKeJTzfty8YKWmxjCSAi3YB3AYkTs6b6BbrN3TfbzSu",
+ | "id": "HgDAs4D8SCe7RxgH9Knomg99N9LF92b7nUCC6FRbC7Eo",
+ | "outcome": {
+ | "executor_id": "volodymyr.testnet",
+ | "gas_burnt": 223182562500,
+ | "logs": [],
+ | "metadata": {
+ | "gas_profile": [],
+ | "version": 3
+ | },
+ | "receipt_ids": [
+ | "5LTPntJ4CDmnHCjb4URXqmnCxudBhmPHDv7kpuEWY8U4"
+ | ],
+ | "status": {
+ | "SuccessValue": ""
+ | },
+ | "tokens_burnt": "22318256250000000000"
+ | },
+ | "proof": [
+ | {
+ | "direction": "Right",
+ | "hash": "3sWdNsYk1wmbuQBJtWFuxVTViYjhqHrd7oahLAtGK6xC"
+ | }
+ | ]
+ | }
+ | ],
+ | "status": {
+ | "SuccessValue": ""
+ | },
+ | "transaction": {
+ | "actions": [
+ | {
+ | "Transfer": {
+ | "deposit": "100000000000000000000000"
+ | }
+ | }
+ | ],
+ | "hash": "F3eZmhtFekCrzKMbc3uk5UbKkMsuuecj6WbK9spcz8bW",
+ | "nonce": 147781057000110,
+ | "public_key": "ed25519:7siBhHN2eYNCubz5jAJhMdo34x33QJt5ZgUJBTNifZAx",
+ | "receiver_id": "volodymyr.testnet",
+ | "signature": "ed25519:4r8YNLMkqhxSTFLejMf8JvZw6q8ue9BuQHf7JEycamAWCqLckfE5zNG7ceWoUfagQaJLTunD59ig4LuecYyVk8Qe",
+ | "signer_id": "fro_volod.testnet"
+ | },
+ | "transaction_outcome": {
+ | "block_hash": "4Ctk97bpxgY3npmU41n5t7ZviKcVDD2sK6N9E1RvanER",
+ | "id": "F3eZmhtFekCrzKMbc3uk5UbKkMsuuecj6WbK9spcz8bW",
+ | "outcome": {
+ | "executor_id": "fro_volod.testnet",
+ | "gas_burnt": 223182562500,
+ | "logs": [],
+ | "metadata": {
+ | "gas_profile": null,
+ | "version": 1
+ | },
+ | "receipt_ids": [
+ | "HgDAs4D8SCe7RxgH9Knomg99N9LF92b7nUCC6FRbC7Eo"
+ | ],
+ | "status": {
+ | "SuccessReceiptId": "HgDAs4D8SCe7RxgH9Knomg99N9LF92b7nUCC6FRbC7Eo"
+ | },
+ | "tokens_burnt": "22318256250000000000"
+ | },
+ | "proof": [
+ | {
+ | "direction": "Right",
+ | "hash": "2ktmkisPC2M6uXFKc6XuAWGA1WbtewS2L6ugkLv92K6T"
+ | },
+ | {
+ | "direction": "Right",
+ | "hash": "HLHeyozXBSqN7Tz1JV3bxQ8J9z9dhAUSbKc5tXHDzHh2"
+ | }
+ | ]
+ | }
+ | }
+
+--- Logs ---------------------------
+Logs [volodymyr.testnet]: No logs
+--- Result -------------------------
+Empty result
+------------------------------------
+
+ has transferred 0.1 NEAR to successfully.
+
+Gas burned: 0.447 Tgas
+Transaction fee: 0.0000446365125 NEAR (approximately $0.00025308 USD, using $5.67 USD/NEAR exchange rate)
+Transaction ID: F3eZmhtFekCrzKMbc3uk5UbKkMsuuecj6WbK9spcz8bW
+To see the transaction in the transaction explorer, please open this url in your browser:
+https://explorer.testnet.near.org/transactionsF3eZmhtFekCrzKMbc3uk5UbKkMsuuecj6WbK9spcz8bW
+
+
+
+
+Here is your console command if you need to script it or re-run:
+ ./target/debug/near --teach-me tokens fro_volod.testnet send-near volodymyr.testnet '0.1 NEAR' network-config testnet sign-with-keychain send
+```
+
+
Before proceeding to the description of specific commands, it is necessary to consider two points common to these commands:
1. Sign transaction
diff --git a/docs/GUIDE.ru.md b/docs/GUIDE.ru.md
index a5a517a48..367385d95 100644
--- a/docs/GUIDE.ru.md
+++ b/docs/GUIDE.ru.md
@@ -15,6 +15,244 @@ near --offline tokens \
sign-later
```
+_near CLI_ — отличный инструмент для глубокого понимания NEAR. Например, если вы хотите просмотреть более подробную информацию о выполняемых вызовах RPC и их параметрах, просто запустите CLI с флагом `--teach-me`:
+```txt
+near --teach-me tokens \
+ fro_volod.testnet \
+ send-near volodymyr.testnet 0.1NEAR \
+ network-config testnet \
+ sign-with-keychain \
+ send
+```
+
+Результат выполнения команды
+
+```txt
+Unsigned transaction:
+
+signer_id: fro_volod.testnet
+receiver_id: volodymyr.testnet
+actions:
+ -- transfer deposit: 0.1 NEAR
+
+ INFO Signing the transaction with a key saved in the secure keychain ...:Getting a list of: fro_volod.testnet access keys ...
+ INFO I am making HTTP call to NEAR JSON RPC to get a list of keys for `fro_volod.testnet` account, learn more https://docs.near.org/api/rpc/access-keys#view-access-key-list
+ INFO HTTP POST https://archival-rpc.testnet.near.org/
+ INFO JSON Body:
+ | {
+ | "id": "RSDcGn4WP",
+ | "jsonrpc": "2.0",
+ | "method": "query",
+ | "params": {
+ | "account_id": "fro_volod.testnet",
+ | "finality": "final",
+ | "request_type": "view_access_key_list"
+ | }
+ | }
+ INFO JSON RPC Response:
+ | {
+ | "block_hash": "DaoWCSVSMVS6d5rLsYBgVKwSKb8XxZWN2KpEg2dQEbEY",
+ | "block_height": 169978024,
+ | "keys": [
+ | {
+ | "access_key": {
+ | "nonce": 116133598000035,
+ | "permission": "FullAccess"
+ | },
+ | "public_key": "ed25519:1TprKa4burMqDMjDHyBSUaFQQczF7NamhxTx2yEXe9P"
+ | },
+ | {
+ | "access_key": {
+ | "nonce": 94982716000000,
+ | "permission": {
+ | "FunctionCall": {
+ | "allowance": "250000000000000000000000",
+ | "method_names": [],
+ | "receiver_id": "mintspace2.testnet"
+ | }
+ | }
+ | },
+ | "public_key": "ed25519:7YCfA1KrToJtAYGTBgAMe4LWfQEi4iwLGcH2q5SvGKzD"
+ | },
+ | {
+ | "access_key": {
+ | "nonce": 147781057000109,
+ | "permission": "FullAccess"
+ | },
+ | "public_key": "ed25519:7siBhHN2eYNCubz5jAJhMdo34x33QJt5ZgUJBTNifZAx"
+ | },
+ | {
+ | "access_key": {
+ | "nonce": 101493245000000,
+ | "permission": {
+ | "FunctionCall": {
+ | "allowance": "10000000000000000000000000",
+ | "method_names": [
+ | "set_a",
+ | "set_b"
+ | ],
+ | "receiver_id": "meta.pool.testnet"
+ | }
+ | }
+ | },
+ | "public_key": "ed25519:8KHRkmpWbAp6wHZ5imAGFZzRAHzha2cZoz7cc3J42Bz8"
+ | },
+ | {
+ | "access_key": {
+ | "nonce": 98944792000000,
+ | "permission": "FullAccess"
+ | },
+ | "public_key": "ed25519:8dGkLiLD285Pzgp6v4mhaUbJyFvwEMvzjss1u9xZokTz"
+ | },
+ | {
+ | "access_key": {
+ | "nonce": 105032344000005,
+ | "permission": "FullAccess"
+ | },
+ | "public_key": "ed25519:J5uajy3m24sEQdw1uWA5kD2i3PDcxRxcFYotVZqRyrm6"
+ | }
+ | ]
+ | }
+ INFO Signing the transaction with a key saved in the secure keychain ...:Trying to sign with the legacy keychain ...:Signing the transaction with a key saved in legacy keychain ...:Getting access key information:: ed25519:7siBhHN2eYNCubz5jAJhMdo34x33QJt5ZgUJBTNifZAx on fro_volod.testnet account ...
+ INFO I am making HTTP call to NEAR JSON RPC to get an access key ed25519:7siBhHN2eYNCubz5jAJhMdo34x33QJt5ZgUJBTNifZAx details on `fro_volod.testnet` account, learn more https://docs.near.org/api/rpc/access-keys#view-access-key
+ INFO HTTP POST https://archival-rpc.testnet.near.org/
+ INFO JSON Body:
+ | {
+ | "id": "3DCGHrjRK",
+ | "jsonrpc": "2.0",
+ | "method": "query",
+ | "params": {
+ | "account_id": "fro_volod.testnet",
+ | "finality": "optimistic",
+ | "public_key": "ed25519:7siBhHN2eYNCubz5jAJhMdo34x33QJt5ZgUJBTNifZAx",
+ | "request_type": "view_access_key"
+ | }
+ | }
+ INFO JSON RPC Response:
+ | {
+ | "block_hash": "BDT76QHmdMC5yKHBuJBi3vgAC1j4hPSHoX5oVFpx1SG2",
+ | "block_height": 169978028,
+ | "nonce": 147781057000109,
+ | "permission": "FullAccess"
+ | }
+
+Your transaction was signed successfully.
+Public key: ed25519:7siBhHN2eYNCubz5jAJhMdo34x33QJt5ZgUJBTNifZAx
+Signature: ed25519:4r8YNLMkqhxSTFLejMf8JvZw6q8ue9BuQHf7JEycamAWCqLckfE5zNG7ceWoUfagQaJLTunD59ig4LuecYyVk8Qe
+ INFO Sending transaction ...:Broadcasting transaction via RPC: https://archival-rpc.testnet.near.org/
+ INFO I am making HTTP call to NEAR JSON RPC to broadcast a transaction, learn more https://docs.near.org/api/rpc/transactions#send-tx
+ INFO HTTP POST https://archival-rpc.testnet.near.org/
+ INFO JSON Body:
+ | {
+ | "id": "1ARLaDA3J",
+ | "jsonrpc": "2.0",
+ | "method": "broadcast_tx_commit",
+ | "params": [
+ | "EQAAAGZyb192b2xvZC50ZXN0bmV0AGYjuraPK0UBuPn9vFOErFp7IcGKqhQ5AqH8v2LHNdzhrjJo9WeGAAARAAAAdm9sb2R5bXlyLnRlc3RuZXSXxVsmKUVo0lmnzQ013O+bqjznbnB5g/3biI+j62VuOwEAAAADAACA9krhxwItFQAAAAAAAADAazoMP0kIphzt/zQ7Z97rr64FLGGsXMJDS8sXpuX8WwQdEgF6GZX+fz8hvKx5GqB4nrxnwrxbZScTQcs9mcEP"
+ | ]
+ | }
+ INFO JSON RPC Response:
+ | {
+ | "receipts_outcome": [
+ | {
+ | "block_hash": "7rKeJTzfty8YKWmxjCSAi3YB3AYkTs6b6BbrN3TfbzSu",
+ | "id": "HgDAs4D8SCe7RxgH9Knomg99N9LF92b7nUCC6FRbC7Eo",
+ | "outcome": {
+ | "executor_id": "volodymyr.testnet",
+ | "gas_burnt": 223182562500,
+ | "logs": [],
+ | "metadata": {
+ | "gas_profile": [],
+ | "version": 3
+ | },
+ | "receipt_ids": [
+ | "5LTPntJ4CDmnHCjb4URXqmnCxudBhmPHDv7kpuEWY8U4"
+ | ],
+ | "status": {
+ | "SuccessValue": ""
+ | },
+ | "tokens_burnt": "22318256250000000000"
+ | },
+ | "proof": [
+ | {
+ | "direction": "Right",
+ | "hash": "3sWdNsYk1wmbuQBJtWFuxVTViYjhqHrd7oahLAtGK6xC"
+ | }
+ | ]
+ | }
+ | ],
+ | "status": {
+ | "SuccessValue": ""
+ | },
+ | "transaction": {
+ | "actions": [
+ | {
+ | "Transfer": {
+ | "deposit": "100000000000000000000000"
+ | }
+ | }
+ | ],
+ | "hash": "F3eZmhtFekCrzKMbc3uk5UbKkMsuuecj6WbK9spcz8bW",
+ | "nonce": 147781057000110,
+ | "public_key": "ed25519:7siBhHN2eYNCubz5jAJhMdo34x33QJt5ZgUJBTNifZAx",
+ | "receiver_id": "volodymyr.testnet",
+ | "signature": "ed25519:4r8YNLMkqhxSTFLejMf8JvZw6q8ue9BuQHf7JEycamAWCqLckfE5zNG7ceWoUfagQaJLTunD59ig4LuecYyVk8Qe",
+ | "signer_id": "fro_volod.testnet"
+ | },
+ | "transaction_outcome": {
+ | "block_hash": "4Ctk97bpxgY3npmU41n5t7ZviKcVDD2sK6N9E1RvanER",
+ | "id": "F3eZmhtFekCrzKMbc3uk5UbKkMsuuecj6WbK9spcz8bW",
+ | "outcome": {
+ | "executor_id": "fro_volod.testnet",
+ | "gas_burnt": 223182562500,
+ | "logs": [],
+ | "metadata": {
+ | "gas_profile": null,
+ | "version": 1
+ | },
+ | "receipt_ids": [
+ | "HgDAs4D8SCe7RxgH9Knomg99N9LF92b7nUCC6FRbC7Eo"
+ | ],
+ | "status": {
+ | "SuccessReceiptId": "HgDAs4D8SCe7RxgH9Knomg99N9LF92b7nUCC6FRbC7Eo"
+ | },
+ | "tokens_burnt": "22318256250000000000"
+ | },
+ | "proof": [
+ | {
+ | "direction": "Right",
+ | "hash": "2ktmkisPC2M6uXFKc6XuAWGA1WbtewS2L6ugkLv92K6T"
+ | },
+ | {
+ | "direction": "Right",
+ | "hash": "HLHeyozXBSqN7Tz1JV3bxQ8J9z9dhAUSbKc5tXHDzHh2"
+ | }
+ | ]
+ | }
+ | }
+
+--- Logs ---------------------------
+Logs [volodymyr.testnet]: No logs
+--- Result -------------------------
+Empty result
+------------------------------------
+
+ has transferred 0.1 NEAR to successfully.
+
+Gas burned: 0.447 Tgas
+Transaction fee: 0.0000446365125 NEAR (approximately $0.00025308 USD, using $5.67 USD/NEAR exchange rate)
+Transaction ID: F3eZmhtFekCrzKMbc3uk5UbKkMsuuecj6WbK9spcz8bW
+To see the transaction in the transaction explorer, please open this url in your browser:
+https://explorer.testnet.near.org/transactionsF3eZmhtFekCrzKMbc3uk5UbKkMsuuecj6WbK9spcz8bW
+
+
+
+
+Here is your console command if you need to script it or re-run:
+ ./target/debug/near --teach-me tokens fro_volod.testnet send-near volodymyr.testnet '0.1 NEAR' network-config testnet sign-with-keychain send
+```
+
+
Прежде, чем перейти к описанию конкретных команд, необходимо рассмотреть два общих для этих команд пункта:
1. Подпись транзакции
diff --git a/src/commands/contract/call_function/as_read_only/mod.rs b/src/commands/contract/call_function/as_read_only/mod.rs
index bc2bc4e15..cac43ff1d 100644
--- a/src/commands/contract/call_function/as_read_only/mod.rs
+++ b/src/commands/contract/call_function/as_read_only/mod.rs
@@ -109,7 +109,7 @@ impl Function {
}
}
-#[tracing::instrument(name = "Getting a response to a view method ...", skip_all)]
+#[tracing::instrument(name = "Getting a response to a read-only function call ...", skip_all)]
fn call_view_function(
network_config: &crate::config::NetworkConfig,
account_id: &near_primitives::types::AccountId,
@@ -124,7 +124,7 @@ fn call_view_function(
.blocking_call_view_function(account_id, function_name, args, block_reference.clone())
.wrap_err_with(|| {
format!(
- "Failed to fetch query for view method: '{}' (contract <{}> on network <{}>)",
+ "Failed to fetch query for read-only function call: '{}' (contract <{}> on network <{}>)",
function_name, account_id, network_config.network_name
)
})?;
diff --git a/src/commands/contract/inspect/mod.rs b/src/commands/contract/inspect/mod.rs
index dde4b13b5..6a63a2704 100644
--- a/src/commands/contract/inspect/mod.rs
+++ b/src/commands/contract/inspect/mod.rs
@@ -586,6 +586,6 @@ pub async fn get_contract_abi(
.map_err(FetchAbiError::AbiUnknownFormat);
}
}
- std::thread::sleep(std::time::Duration::from_millis(100));
+ tokio::time::sleep(std::time::Duration::from_millis(100)).await;
}
}
diff --git a/src/common.rs b/src/common.rs
index c27b08cd8..c81e06455 100644
--- a/src/common.rs
+++ b/src/common.rs
@@ -2076,16 +2076,63 @@ impl JsonRpcClientExt for near_jsonrpc_client::JsonRpcClient {
tracing::Span::current().pb_set_message(&format!(
"the '{method_name}' method of the <{account_id}> contract ..."
));
+ tracing::info!(target: "near_teach_me", "the '{method_name}' method of the <{account_id}> contract ...");
+
+ let query_view_method_request = near_jsonrpc_client::methods::query::RpcQueryRequest {
+ block_reference,
+ request: near_primitives::views::QueryRequest::CallFunction {
+ account_id: account_id.clone(),
+ method_name: method_name.to_owned(),
+ args: near_primitives::types::FunctionArgs::from(args),
+ },
+ };
+ let request_payload = near_jsonrpc_client::methods::to_json(&query_view_method_request)?;
+
+ tracing::info!(
+ target: "near_teach_me",
+ parent: &tracing::Span::none(),
+ "I am making HTTP call to NEAR JSON RPC to call a read-only function {} on `{}` account, learn more https://docs.near.org/api/rpc/contracts#call-a-contract-function",
+ method_name,
+ account_id
+ );
+ tracing::info!(
+ target: "near_teach_me",
+ parent: &tracing::Span::none(),
+ "HTTP POST {}",
+ self.server_addr()
+ );
+ tracing::info!(
+ target: "near_teach_me",
+ parent: &tracing::Span::none(),
+ "JSON Body:\n{}",
+ indent_payload(&format!("{:#}", request_payload))
+ );
+
let query_view_method_response = self
- .blocking_call(near_jsonrpc_client::methods::query::RpcQueryRequest {
- block_reference,
- request: near_primitives::views::QueryRequest::CallFunction {
- account_id: account_id.clone(),
- method_name: method_name.to_owned(),
- args: near_primitives::types::FunctionArgs::from(args),
- },
- })
+ .blocking_call(query_view_method_request)
.wrap_err("Failed to make a view-function call")?;
+
+ let call_result = query_view_method_response.call_result()?;
+
+ tracing::info!(
+ target: "near_teach_me",
+ parent: &tracing::Span::none(),
+ "JSON RPC Response:\n{}",
+ indent_payload(&format!(
+ "{{\n \"block_hash\": {}\n \"block_height\": {}\n \"logs\": {:?}\n \"result\": {:?}\n}}",
+ query_view_method_response.block_hash,
+ query_view_method_response.block_height,
+ call_result.logs,
+ call_result.result
+ ))
+ );
+ tracing::info!(
+ target: "near_teach_me",
+ parent: &tracing::Span::none(),
+ "Decoding the \"result\" array of bytes as UTF-8 string (tip: here is a Python snippet: `\"\".join([chr(c) for c in result])`):\n{}",
+ indent_payload(&String::from_utf8(call_result.result.clone()).unwrap_or_else(|_| "".to_owned()))
+ );
+
query_view_method_response.call_result()
}
@@ -2101,14 +2148,52 @@ impl JsonRpcClientExt for near_jsonrpc_client::JsonRpcClient {
near_jsonrpc_primitives::types::query::RpcQueryError,
>,
> {
- tracing::Span::current().pb_set_message(&format!("{public_key} ..."));
- self.blocking_call(near_jsonrpc_client::methods::query::RpcQueryRequest {
+ tracing::Span::current()
+ .pb_set_message(&format!("{public_key} on {account_id} account ..."));
+ tracing::info!(target: "near_teach_me", "{public_key} on {account_id} account ...");
+
+ let query_view_method_request = near_jsonrpc_client::methods::query::RpcQueryRequest {
block_reference,
request: near_primitives::views::QueryRequest::ViewAccessKey {
account_id: account_id.clone(),
public_key: public_key.clone(),
},
- })
+ };
+ let request_payload = request_payload(&query_view_method_request)?;
+
+ tracing::info!(
+ target: "near_teach_me",
+ parent: &tracing::Span::none(),
+ "I am making HTTP call to NEAR JSON RPC to get an access key {} details on `{}` account, learn more https://docs.near.org/api/rpc/access-keys#view-access-key",
+ public_key,
+ account_id
+ );
+ tracing::info!(
+ target: "near_teach_me",
+ parent: &tracing::Span::none(),
+ "HTTP POST {}",
+ self.server_addr()
+ );
+ tracing::info!(
+ target: "near_teach_me",
+ parent: &tracing::Span::none(),
+ "JSON Body:\n{}",
+ indent_payload(&format!("{:#}", request_payload))
+ );
+
+ let query_view_method_response: near_jsonrpc_client::methods::query::RpcQueryResponse =
+ self.blocking_call(query_view_method_request)?;
+
+ let response_payload = response_payload(&query_view_method_response)?;
+
+ tracing::info!(
+ target: "near_teach_me",
+ parent: &tracing::Span::none(),
+ "JSON RPC Response:\n{}",
+ indent_payload(&format!("{:#}", response_payload))
+ );
+
+ Ok(query_view_method_response)
}
#[tracing::instrument(name = "Getting a list of", skip_all)]
@@ -2123,12 +2208,47 @@ impl JsonRpcClientExt for near_jsonrpc_client::JsonRpcClient {
>,
> {
tracing::Span::current().pb_set_message(&format!("{account_id} access keys ..."));
- self.blocking_call(near_jsonrpc_client::methods::query::RpcQueryRequest {
+ tracing::info!(target: "near_teach_me", "{account_id} access keys ...");
+
+ let query_view_method_request = near_jsonrpc_client::methods::query::RpcQueryRequest {
block_reference,
request: near_primitives::views::QueryRequest::ViewAccessKeyList {
account_id: account_id.clone(),
},
- })
+ };
+ let request_payload = request_payload(&query_view_method_request)?;
+
+ tracing::info!(
+ target: "near_teach_me",
+ parent: &tracing::Span::none(),
+ "I am making HTTP call to NEAR JSON RPC to get a list of keys for `{}` account, learn more https://docs.near.org/api/rpc/access-keys#view-access-key-list",
+ account_id
+ );
+ tracing::info!(
+ target: "near_teach_me",
+ parent: &tracing::Span::none(),
+ "HTTP POST {}",
+ self.server_addr()
+ );
+ tracing::info!(
+ target: "near_teach_me",
+ parent: &tracing::Span::none(),
+ "JSON Body:\n{}",
+ indent_payload(&format!("{:#}", request_payload))
+ );
+
+ let query_view_method_response = self.blocking_call(query_view_method_request)?;
+
+ let response_payload = response_payload(&query_view_method_response)?;
+
+ tracing::info!(
+ target: "near_teach_me",
+ parent: &tracing::Span::none(),
+ "JSON RPC Response:\n{}",
+ indent_payload(&format!("{:#}", response_payload))
+ );
+
+ Ok(query_view_method_response)
}
#[tracing::instrument(name = "Getting information about", skip_all)]
@@ -2143,15 +2263,93 @@ impl JsonRpcClientExt for near_jsonrpc_client::JsonRpcClient {
>,
> {
tracing::Span::current().pb_set_message(&format!("{account_id} ..."));
- self.blocking_call(near_jsonrpc_client::methods::query::RpcQueryRequest {
+ tracing::info!(target: "near_teach_me", "{account_id} ...");
+
+ let query_view_method_request = near_jsonrpc_client::methods::query::RpcQueryRequest {
block_reference,
request: near_primitives::views::QueryRequest::ViewAccount {
account_id: account_id.clone(),
},
- })
+ };
+ let request_payload = request_payload(&query_view_method_request)?;
+
+ tracing::info!(
+ target: "near_teach_me",
+ parent: &tracing::Span::none(),
+ "I am making HTTP call to NEAR JSON RPC to query information about `{}` account, learn more https://docs.near.org/api/rpc/contracts#view-account",
+ account_id
+ );
+ tracing::info!(
+ target: "near_teach_me",
+ parent: &tracing::Span::none(),
+ "HTTP POST {}",
+ self.server_addr()
+ );
+ tracing::info!(
+ target: "near_teach_me",
+ parent: &tracing::Span::none(),
+ "JSON Body:\n{}",
+ indent_payload(&format!("{:#}", request_payload))
+ );
+
+ let query_view_method_response = self.blocking_call(query_view_method_request)?;
+
+ let response_payload = response_payload(&query_view_method_response)?;
+
+ tracing::info!(
+ target: "near_teach_me",
+ parent: &tracing::Span::none(),
+ "JSON RPC Response:\n{}",
+ indent_payload(&format!("{:#}", response_payload))
+ );
+
+ Ok(query_view_method_response)
}
}
+fn request_payload(
+ query_view_method_request: &near_jsonrpc_client::methods::query::RpcQueryRequest,
+) -> Result<
+ serde_json::Value,
+ near_jsonrpc_client::errors::JsonRpcError,
+> {
+ near_jsonrpc_client::methods::to_json(query_view_method_request).map_err(|err| {
+ near_jsonrpc_client::errors::JsonRpcError::TransportError(
+ near_jsonrpc_client::errors::RpcTransportError::SendError(
+ near_jsonrpc_client::errors::JsonRpcTransportSendError::PayloadSerializeError(err),
+ ),
+ )
+ })
+}
+
+fn response_payload(
+ query_view_method_response: &near_jsonrpc_client::methods::query::RpcQueryResponse,
+) -> Result<
+ serde_json::Value,
+ near_jsonrpc_client::errors::JsonRpcError,
+> {
+ serde_json::to_value(query_view_method_response).map_err(|err| {
+ near_jsonrpc_client::errors::JsonRpcError::TransportError(
+ near_jsonrpc_client::errors::RpcTransportError::SendError(
+ near_jsonrpc_client::errors::JsonRpcTransportSendError::PayloadSerializeError(
+ err.into(),
+ ),
+ ),
+ )
+ })
+}
+
+pub(crate) fn indent_payload(s: &str) -> String {
+ use std::fmt::Write;
+
+ let mut indented_string = String::new();
+ indenter::indented(&mut indented_string)
+ .with_str(" | ")
+ .write_str(s)
+ .ok();
+ indented_string
+}
+
#[easy_ext::ext(RpcQueryResponseExt)]
pub impl near_jsonrpc_primitives::types::query::RpcQueryResponse {
fn access_key_view(&self) -> color_eyre::eyre::Result {
diff --git a/src/lib.rs b/src/lib.rs
index 0b5cc6cdd..ad273c6b4 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -16,4 +16,5 @@ pub mod utils_command;
pub struct GlobalContext {
pub config: crate::config::Config,
pub offline: bool,
+ pub teach_me: bool,
}
diff --git a/src/main.rs b/src/main.rs
index 264072120..ed20561de 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,4 +1,8 @@
-#![allow(clippy::enum_variant_names, clippy::large_enum_variant)]
+#![allow(
+ clippy::enum_variant_names,
+ clippy::large_enum_variant,
+ clippy::too_many_arguments
+)]
use clap::Parser;
#[cfg(feature = "self-update")]
use color_eyre::eyre::WrapErr;
@@ -33,6 +37,9 @@ struct Cmd {
/// Offline mode
#[interactive_clap(long)]
offline: bool,
+ /// TEACH-ME mode
+ #[interactive_clap(long)]
+ teach_me: bool,
#[interactive_clap(subcommand)]
top_level: crate::commands::TopLevelCommand,
}
@@ -48,6 +55,7 @@ impl CmdContext {
Ok(Self(crate::GlobalContext {
config: previous_context.0,
offline: scope.offline,
+ teach_me: scope.teach_me,
}))
}
}
@@ -67,33 +75,6 @@ fn main() -> crate::common::CliResult {
color_eyre::install()?;
- let indicatif_layer = IndicatifLayer::new()
- .with_progress_style(
- ProgressStyle::with_template(
- "{spinner:.blue}{span_child_prefix} {span_name} {msg} {span_fields}",
- )
- .unwrap()
- .tick_strings(&[
- "▹▹▹▹▹",
- "▸▹▹▹▹",
- "▹▸▹▹▹",
- "▹▹▸▹▹",
- "▹▹▹▸▹",
- "▹▹▹▹▸",
- "▪▪▪▪▪",
- ]),
- )
- .with_span_child_prefix_symbol("↳ ");
- tracing_subscriber::registry()
- .with(tracing_subscriber::fmt::layer().with_writer(indicatif_layer.get_stderr_writer()))
- .with(indicatif_layer)
- .with(
- EnvFilter::from_default_env()
- .add_directive(tracing::Level::WARN.into())
- .add_directive("near_cli_rs=info".parse()?),
- )
- .init();
-
#[cfg(feature = "self-update")]
let handle = std::thread::spawn(|| -> color_eyre::eyre::Result {
crate::commands::extensions::self_update::get_latest_version()
@@ -133,6 +114,50 @@ fn main() -> crate::common::CliResult {
}
},
};
+ if cli.teach_me {
+ let env_filter = EnvFilter::from_default_env()
+ .add_directive(tracing::Level::WARN.into())
+ .add_directive("near_teach_me=info".parse()?)
+ .add_directive("near_cli_rs=info".parse()?);
+ tracing_subscriber::registry()
+ .with(
+ tracing_subscriber::fmt::layer()
+ .without_time()
+ .with_target(false),
+ )
+ .with(env_filter)
+ .init();
+ } else {
+ let indicatif_layer = IndicatifLayer::new()
+ .with_progress_style(
+ ProgressStyle::with_template(
+ "{spinner:.blue}{span_child_prefix} {span_name} {msg} {span_fields}",
+ )
+ .unwrap()
+ .tick_strings(&[
+ "▹▹▹▹▹",
+ "▸▹▹▹▹",
+ "▹▸▹▹▹",
+ "▹▹▸▹▹",
+ "▹▹▹▸▹",
+ "▹▹▹▹▸",
+ "▪▪▪▪▪",
+ ]),
+ )
+ .with_span_child_prefix_symbol("↳ ");
+ let env_filter = EnvFilter::from_default_env()
+ .add_directive(tracing::Level::WARN.into())
+ .add_directive("near_cli_rs=info".parse()?);
+ tracing_subscriber::registry()
+ .with(
+ tracing_subscriber::fmt::layer()
+ .without_time()
+ .with_writer(indicatif_layer.get_stderr_writer()),
+ )
+ .with(indicatif_layer)
+ .with(env_filter)
+ .init();
+ };
let cli_cmd = match ::from_cli(Some(cli), (config,)) {
interactive_clap::ResultFromCli::Ok(cli_cmd)
@@ -197,6 +222,7 @@ fn main() -> crate::common::CliResult {
);
let self_update_cli_cmd = CliCmd {
offline: false,
+ teach_me: false,
top_level:
Some(crate::commands::CliTopLevelCommand::Extensions(
crate::commands::extensions::CliExtensionsCommands {
diff --git a/src/transaction_signature_options/send/mod.rs b/src/transaction_signature_options/send/mod.rs
index d9624b48c..da2686f3d 100644
--- a/src/transaction_signature_options/send/mod.rs
+++ b/src/transaction_signature_options/send/mod.rs
@@ -78,14 +78,36 @@ pub fn sending_signed_transaction(
signed_transaction: &near_primitives::transaction::SignedTransaction,
) -> color_eyre::Result {
tracing::Span::current().pb_set_message(network_config.rpc_url.as_str());
+ tracing::info!(target: "near_teach_me", "{}", network_config.rpc_url.as_str());
+
let retries_number = 5;
let mut retries = (1..=retries_number).rev();
let transaction_info = loop {
- let transaction_info_result = network_config.json_rpc_client().blocking_call(
+ let request =
near_jsonrpc_client::methods::broadcast_tx_commit::RpcBroadcastTxCommitRequest {
signed_transaction: signed_transaction.clone(),
- },
+ };
+ let request_payload = near_jsonrpc_client::methods::to_json(&request)?;
+
+ tracing::info!(
+ target: "near_teach_me",
+ parent: &tracing::Span::none(),
+ "I am making HTTP call to NEAR JSON RPC to broadcast a transaction, learn more https://docs.near.org/api/rpc/transactions#send-tx"
+ );
+ tracing::info!(
+ target: "near_teach_me",
+ parent: &tracing::Span::none(),
+ "HTTP POST {}",
+ network_config.rpc_url.as_str(),
);
+ tracing::info!(
+ target: "near_teach_me",
+ parent: &tracing::Span::none(),
+ "JSON Body:\n{}",
+ crate::common::indent_payload(&format!("{:#}", request_payload))
+ );
+
+ let transaction_info_result = network_config.json_rpc_client().blocking_call(request);
match transaction_info_result {
Ok(response) => {
break response;
@@ -107,6 +129,16 @@ pub fn sending_signed_transaction(
},
};
};
+
+ let response_payload = serde_json::to_value(&transaction_info)?;
+
+ tracing::info!(
+ target: "near_teach_me",
+ parent: &tracing::Span::none(),
+ "JSON RPC Response:\n{}",
+ crate::common::indent_payload(&format!("{:#}", response_payload))
+ );
+
Ok(transaction_info)
}
@@ -125,14 +157,43 @@ fn sending_delegate_action(
meta_transaction_relayer_url: url::Url,
) -> Result {
tracing::Span::current().pb_set_message(meta_transaction_relayer_url.as_str());
+ tracing::info!(target: "near_teach_me", "{}", meta_transaction_relayer_url.as_str());
+
let client = reqwest::blocking::Client::new();
- let json_payload = serde_json::json!({
+ let request_payload = serde_json::json!({
"signed_delegate_action": crate::types::signed_delegate_action::SignedDelegateActionAsBase64::from(
signed_delegate_action
).to_string()
});
- client
- .post(meta_transaction_relayer_url)
- .json(&json_payload)
- .send()
+ tracing::info!(
+ target: "near_teach_me",
+ parent: &tracing::Span::none(),
+ "I am making HTTP call to NEAR JSON RPC to broadcast a transaction, learn more https://docs.near.org/concepts/abstraction/relayers"
+ );
+ tracing::info!(
+ target: "near_teach_me",
+ parent: &tracing::Span::none(),
+ "HTTP POST {}",
+ meta_transaction_relayer_url.as_str()
+ );
+ tracing::info!(
+ target: "near_teach_me",
+ parent: &tracing::Span::none(),
+ "JSON Body:\n{}",
+ crate::common::indent_payload(&format!("{:#}", request_payload))
+ );
+
+ let response = client
+ .post(meta_transaction_relayer_url.clone())
+ .json(&request_payload)
+ .send()?;
+
+ tracing::info!(
+ target: "near_teach_me",
+ parent: &tracing::Span::none(),
+ "JSON RPC Response:\n{}",
+ crate::common::indent_payload(&format!("{:#?}", response))
+ );
+
+ Ok(response)
}
diff --git a/src/transaction_signature_options/sign_with_legacy_keychain/mod.rs b/src/transaction_signature_options/sign_with_legacy_keychain/mod.rs
index fcfe7d601..8c509f020 100644
--- a/src/transaction_signature_options/sign_with_legacy_keychain/mod.rs
+++ b/src/transaction_signature_options/sign_with_legacy_keychain/mod.rs
@@ -107,7 +107,7 @@ impl SignLegacyKeychainContext {
);
path.push(dir_name);
path.push(
- &previous_context
+ previous_context
.prepopulated_transaction
.signer_id
.to_string(),