I captured the http message exchanges for the following cleos command by using TCPDUMP.
cleos --wallet-url http://172.18.0.1:8899 -u http://172.18.0.1:8888 push action shlee create '["shlee", 7, "feed dragon"]' -p shlee
It takes 6 http request/response message exchanges.
Step 1. to nodeos
POST /v1/chain/get_abi HTTP/1.0
Host: 172.18.0.1:8888
content-length: 24
Accept: */*
Connection: close
{"account_name":"shlee"}
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Connection: close
Content-Length: 928
Content-type: application/json
Server: WebSocket++/0.7.0
{"account_name":"shlee","abi":{"version":"eosio::abi/1.0","types":[],"structs":[{"name":"todo","base":"","fields":[{"name":"id","type":"uint64"},{"name":"description","type":"string"},{"name":"completed","type":"uint64"}]},{"name":"create","base":"","fields":[{"name":"author","type":"name"},{"name":"id","type":"uint32"},{"name":"description","type":"string"}]},{"name":"destroy","base":"","fields":[{"name":"author","type":"name"},{"name":"id","type":"uint32"}]},{"name":"complete","base":"","fields":[{"name":"author","type":"name"},{"name":"id","type":"uint32"}]}],"actions":[{"name":"create","type":"create","ricardian_contract":""},{"name":"destroy","type":"destroy","ricardian_contract":""},{"name":"complete","type":"complete","ricardian_contract":""}],"tables":[{"name":"todos","index_type":"i64","key_names":["id"],"key_types":["uint64"],"type":"todo"}],"ricardian_clauses":[],"error_messages":[],"abi_extensions":[]}}
Step 2. to nodeos to get the chain id.
POST /v1/chain/get_info HTTP/1.0
Host: 172.18.0.1:8888
content-length: 0
Accept: */*
Connection: close
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Connection: close
Content-Length: 578
Content-type: application/json
Server: WebSocket++/0.7.0
{"server_version":"cc9decff","chain_id":"cf057bbfb72640471fd910bcb67639c22df9f92470936cddc1ade0e2f2e7dc4f","head_block_num":746976,"last_irreversible_block_num":746975,"last_irreversible_block_id":"000b65df039e8ccbf66084ebb2e3a5582bd89d908f300e866969746caee92930","head_block_id":"000b65e08ca87bbd0dd67f75ad9b381cbd2249e76c3bfec063e11213669398d4","head_block_time":"2018-11-22T01:59:19.000","head_block_producer":"eosio","virtual_block_cpu_limit":200000000,"virtual_block_net_limit":1048576000,"block_cpu_limit":199900,"block_net_limit":1048576,"server_version_string":"v1.2.4"}
Step 3. to keosd to get all the public keys.
POST /v1/wallet/get_public_keys HTTP/1.0
Host: 172.18.0.1:8899
content-length: 0
Accept: */*
Connection: close
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Connection: close
Content-Length: 393
Content-type: application/json
Server: WebSocket++/0.7.0
["EOS5Cm2ntfRafTjYD2SNejTN3ARRneBXTKBnVn9KGUYsfdsvgFVjK","EOS5ES24U95W9nkfTr9iL2Xk6yC366RZxBit4RzXX7ffia9BJnWmb","EOS5TPrAUwRK6CXrYhmwDC3xXAaEAaG2uiCuZzuNyMcMwD7EciZLv","EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV","EOS6gYNENaNqx9zeUUgy87uxgvWYiU2FUwJr3YsQHMrk8hscbu2Eu","EOS77WKReas8f2sAiS8rbU6iacvnhGaYGJ6bPxGqgqoKVQTvEXf56","EOS8PVjQLubNH9cAyZNoPGNRPFoUa716Q3jRzStefqaqV3JH4aYJm"]
Step 4. to nodeos to get the required public key to submit the transaction. Basically, it is the "active" public key of the user "shlee"
POST /v1/chain/get_required_keys HTTP/1.0
Host: 172.18.0.1:8888
content-length: 792
Accept: */*
Connection: close
{"transaction":{"expiration":"2018-11-22T01:59:49","ref_block_num":26079,"ref_block_prefix":3951321334,"max_net_usage_words":0,"max_cpu_usage_ms":0,"delay_sec":0,"context_free_actions":[],"actions":[{"account":"shlee","name":"create","authorization":[{"actor":"shlee","permission":"active"}],"data":"0000000000a562c3070000000b6665656420647261676f6e"}],"transaction_extensions":[]},"available_keys":["EOS5Cm2ntfRafTjYD2SNejTN3ARRneBXTKBnVn9KGUYsfdsvgFVjK","EOS5ES24U95W9nkfTr9iL2Xk6yC366RZxBit4RzXX7ffia9BJnWmb","EOS5TPrAUwRK6CXrYhmwDC3xXAaEAaG2uiCuZzuNyMcMwD7EciZLv","EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV","EOS6gYNENaNqx9zeUUgy87uxgvWYiU2FUwJr3YsQHMrk8hscbu2Eu","EOS77WKReas8f2sAiS8rbU6iacvnhGaYGJ6bPxGqgqoKVQTvEXf56","EOS8PVjQLubNH9cAyZNoPGNRPFoUa716Q3jRzStefqaqV3JH4aYJm"]}
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Connection: close
Content-Length: 75
Content-type: application/json
Server: WebSocket++/0.7.0
{"required_keys":["EOS6gYNENaNqx9zeUUgy87uxgvWYiU2FUwJr3YsQHMrk8hscbu2Eu"]}
Step 5. to keosd to sign the transaction. keosd returns the signatures starting with "SIG_K1_...."
POST /v1/wallet/sign_transaction HTTP/1.0
Host: 172.18.0.1:8899
content-length: 531
Accept: */*
Connection: close
[{"expiration":"2018-11-22T01:59:49","ref_block_num":26079,"ref_block_prefix":3951321334,"max_net_usage_words":0,"max_cpu_usage_ms":0,"delay_sec":0,"context_free_actions":[],"actions":[{"account":"shlee","name":"create","authorization":[{"actor":"shlee","permission":"active"}],"data":"0000000000a562c3070000000b6665656420647261676f6e"}],"transaction_extensions":[],"signatures":[],"context_free_data":[]},["EOS6gYNENaNqx9zeUUgy87uxgvWYiU2FUwJr3YsQHMrk8hscbu2Eu"],"cf057bbfb72640471fd910bcb67639c22df9f92470936cddc1ade0e2f2e7dc4f"]
HTTP/1.1 201 Created
Access-Control-Allow-Origin: *
Connection: close
Content-Length: 507
Content-type: application/json
Server: WebSocket++/0.7.0
{"expiration":"2018-11-22T01:59:49","ref_block_num":26079,"ref_block_prefix":3951321334,"max_net_usage_words":0,"max_cpu_usage_ms":0,"delay_sec":0,"context_free_actions":[],"actions":[{"account":"shlee","name":"create","authorization":[{"actor":"shlee","permission":"active"}],"data":"0000000000a562c3070000000b6665656420647261676f6e"}],"transaction_extensions":[],"signatures":["SIG_K1_Ka4ebw48DQkmTUoCcHx6eCS8M2UG9Gyz3xzcX77njvYXmYbiLQ1UjNXriZBQ1zGMNAxaP76mDKSBSt7fEk6Yv4GKMaHhK6"],"context_free_data":[]}
Step 6. to nodes to push the transaction.
POST /v1/chain/push_transaction HTTP/1.0
Host: 172.18.0.1:8888
content-length: 335
Accept: */*
Connection: close
{"signatures":["SIG_K1_Ka4ebw48DQkmTUoCcHx6eCS8M2UG9Gyz3xzcX77njvYXmYbiLQ1UjNXriZBQ1zGMNAxaP76mDKSBSt7fEk6Yv4GKMaHhK6"],"compression":"none","packed_context_free_data":"","packed_trx":"950df65bdf65f66084eb00000000010000000000a562c300000000a86cd445010000000000a562c300000000a8ed3232180000000000a562c3070000000b6665656420647261676f6e00"}
HTTP/1.1 202 Accepted
Access-Control-Allow-Origin: *
Connection: close
Content-Length: 923
Content-type: application/json
Server: WebSocket++/0.7.0
{"transaction_id":"de9b775c4cb19f94dc07e9ad177d2b74d29304d7ba641c80be91aac45348a995","processed":{"id":"de9b775c4cb19f94dc07e9ad177d2b74d29304d7ba641c80be91aac45348a995","receipt":{"status":"executed","cpu_usage_us":757,"net_usage_words":15},"elapsed":757,"net_usage":120,"scheduled":false,"action_traces":[{"receipt":{"receiver":"shlee","act_digest":"896371bd40154bb3f5ff3d2d8065d174da32d1316113e490af15b9121ef482f3","global_sequence":746987,"recv_sequence":6,"auth_sequence":[["shlee",7]],"code_sequence":1,"abi_sequence":1},"act":{"account":"shlee","name":"create","authorization":[{"actor":"shlee","permission":"active"}],"data":{"author":"shlee","id":7,"description":"feed dragon"},"hex_data":"0000000000a562c3070000000b6665656420647261676f6e"},"elapsed":527,"cpu_usage":0,"console":"","total_cpu_usage":0,"trx_id":"de9b775c4cb19f94dc07e9ad177d2b74d29304d7ba641c80be91aac45348a995","inline_traces":[]}],"except":null}}
In this 6 steps, the private key of the user shlee has never been transferred through the HTTP request/response messages.
I just want to mimic the behavior of cleos command by using node.js RPC.
But it seems that developers do not use keosd for the wallets. Instead they use different mechanisms to manage the keys. I'd like to know the key managing practices in real systems.