Transaction signature

🚧

Transaction signature

This section provides developers with examples related to transaction creation and signature. It also includes sequence diagrams and step-by-step details. Please refer to this section when you want to understand details on transactions.

1. Simple transaction creation, signing and broadcast

ActorsDescription
ClientService or GUI
tg-validatordCentral daemon of the solution
tg-vaultdBridge to 1 or N HSMs
HSMHardware device in charge of validating busniess rules and creating signed transaction

Thist workflow includes DB interaction and tg-vaultd/HSM interaction as an example.

1.1 Conditions

  • 2 signatures are required
  • There are 2 clients

1.2 Sequences

Sequence diagram

1.3 Details

StepIDAPI/JOBSwaggerRequest ProtoReply ProtoImpacted DB tablesRequest State changes
1CreateOutgoingRequest()APIswaggerCreateOutgoingRequestRequest-requests,users,wallets,wl_addresses,rulesNONE -> CREATED
2RequestAPI-Request---
3GetRequestsForApproval()APIswaggerGetRequestsForApprovalRequest-requests,users-
4GetRequestsReplyAPI--GetRequestsReply--
5ApproveRequests()APIswaggerApproveRequestsRequest-users,requests,rulesCREATED -> APPROVING
6ApproveRequestsReplyAPI--ApproveRequestsReply--
7GetRequestsForApproval()APIswaggerGetRequestsForApprovalRequest-requests,users-
8GetRequestsReplyAPI--GetRequestsReply--
9ApproveRequests()APIswaggerApproveRequestsRequest-users,requests,rulesAPPROVING -> APPROVED
10ApproveRequestsReplyAPI--ApproveRequestsReply--
11HandleApprovedRequestsjob---requestsAPPROVED -> HSM_READY
12HandleHsmReadyRequestsjob---requests,signed_requestsHSM_READY -> HSM_SIGNED
13HandleHsmSignedRequestsjob---requests,signed_requestsHSM_SIGNED -> BROADCASTING

2. Examples

2.1 Authenticate

curl -X POST "https://int-validator-core-crdb.t-bx.io/rjpyber72n6brsdzksotivcm33mw78q4/api/rest/v1/authentication/token" -H "accept: application/json" -H "Content-Type: application/json" -d "{ \"email\": \"[email protected]\", \"password\": \"XXX\"}"
#{"result":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MTEsImV4dGVybmFsVXNlcklEIjoidGVhbTFAYmFuay5jb20iLCJ0ZW5hbnRJRCI6MSwiZmlyc3RuYW1lIjoiSm9obiIsImxhc3RuYW1lIjoiVDEiLCJyb2xlcyI6WyJyZXF1ZXN0Y3JlYXRvciIsInJlcXVlc3RhcHByb3ZlciJdLCJlbWFpbCI6InRlYW0xQGJhbmsuY29tIiwiZXhwIjoxNTgyMzQ5ODM0LCJpYXQiOjE1ODIyNjM0MzR9.ysWkCtXRyCWEdy65kOuU2vm7WpopBrUJN5vp3oRpO2I"}

export AUTH="Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MTEsImV4dGVybmFsVXNlcklEIjoidGVhbTFAYmFuay5jb20iLCJ0ZW5hbnRJRCI6MSwiZmlyc3RuYW1lIjoiSm9obiIsImxhc3RuYW1lIjoiVDEiLCJyb2xlcyI6WyJyZXF1ZXN0Y3JlYXRvciIsInJlcXVlc3RhcHByb3ZlciJdLCJlbWFpbCI6InRlYW0xQGJhbmsuY29tIiwiZXhwIjoxNTgyNjE1NTk5LCJpYXQiOjE1ODI1MjkxOTl9.d8KCM7aLqebC5jB6YFz-5VG9Fo-I7avoLXqXj10ygvM"

2.2 Create Outgoing Transaction

curl -X POST "https://int-validator-core-crdb.t-bx.io/rjpyber72n6brsdzksotivcm33mw78q4/api/rest/v1/requests/outgoing" -H "accept: application/json" -H "Content-Type: application/json"  -H "$AUTH" -d "{ \"amount\": \"100000\", \"fee\": \"4865\",\"fromAddressId\": \"1\",\"toAddressId\": \"204\", \"comment\": \"Ich bin eine flying Roasted Butternut Squash Boodles\", \"useUnconfirmedFunds\": true, \"feePaidByReceiver\": true}" | jq .
# {
#   "result": {
#     "id": "442",
#     "tenantId": "1",
#     "currency": "BTC",
#     "envelope": "CgM0NDIQmfGjk6Ops/oVGAEqmgUSrAEKPwoPbS80NCcvMCcvMCcvMC8wGiAeyruP7CoNYcGISzRo8iZmuVnV6M9gLiZuShy7aDtKKiABKNHEFDD/////DxIoCiIxQ3Zoeml0ZFZMUGhOVGZ3NU5rUm9YWHZveldacGZhWXQ2EJ/nBRoVCg9tLzQ0Jy8wJy8wJy8wLzAYsbcOMig0NDI6NDY5ZTMxOGUtYjcxZC00MGUwLTg0ZjctNzVlOGQwOWE3Yzg2IhMKCnJlcXVlc3RfaWQQARoDNDQyIhIKCXJ1bGVzX2tleRABGgNCVEMiEQoIY3VycmVuY3kQARoDQlRDIlsKBnNvdXJjZRAEGkcIARJDCAESIjFKTUJZTU1pOWlqSlJlVFlxdEZUU2RlVkJ6azhOSGRzVHUaCm5vc3RybyBCVEMiD20vNDQnLzAnLzAnLzAvMCIGc291cmNlImIKC2Rlc3RpbmF0aW9uEAUaRBJCCMwBEiIxQ3Zoeml0ZFZMUGhOVGZ3NU5rUm9YWHZveldacGZhWXQ2GghteSBsYWJlbCIPbS80NCcvMCcvMCcvMC84IgtkZXN0aW5hdGlvbiKeAQoGYW1vdW50EAoaiQEKAwGGoBIHMTAuMDQzMBoKMTAwNDIuOTcwMCAIKgNCVEMyA0NIRjphCh12YWxpZGF0b3ItY29yZUB0YXVydXNncm91cC5jaBJAffe4nBGVSajYYQxxzEZbQuj0snr8WOC1P506eXRn2EUsDrAnkWvNW9wfU+pwUoBVUaXl/veYW/6m/DJsEKijLCIGYW1vdW50Ih4KEXRvdGFsX2ZpYXRfYW1vdW50EAEaBzEwLjA0MzAiCwoDZmVlEAIaAhMBIh4KFGZlZV9wYWlkX2J5X3JlY2VpdmVyEAEaBHRydWU=",
#     "status": "CREATED",
#     "trails": [
#       {
#         "userId": "11",
#         "externalUserId": "[email protected]",
#         "action": "created",
#         "comment": "Ich bin eine flying Roasted Butternut Squash Boodles",
#         "requestStatus": "CREATED"
#       },
#       {
#         "userId": "1",
#         "externalUserId": "[email protected]",
#         "action": "approvers_assigned",
#         "comment": "rule = [source: any, destination: any, amount: 10.0000], approvals = ['team1': 1 sig, 'team2': 1 sig]",
#         "requestStatus": "CREATED"
#       }
#     ],
#     "rule": "rule = [source: any, destination: any, amount: 10.0000], approvals = ['team1': 1 sig, 'team2': 1 sig]",
#     "approvers": {
#       "parallel": [
#         {
#           "sequential": [
#             {
#               "externalGroupID": "team1",
#               "minimumSignatures": 1
#             },
#             {
#               "externalGroupID": "team2",
#               "minimumSignatures": 1
#             }
#           ]
#         }
#       ]
#     }
#   }
# }

2.3 Get request for approval

curl "https://int-validator-core-crdb.t-bx.io/rjpyber72n6brsdzksotivcm33mw78q4/api/rest/v1/requests/for-approval" -H "accept: application/json" -H "Content-Type: application/json"  -H "$AUTH" | jq .
# {
#   "result": [
#     {
#       "id": "442",
#       "tenantId": "1",
#       "currency": "BTC",
#       "envelope": "CgM0NDIQmfGjk6Ops/oVGAEqmgUSrAEKPwoPbS80NCcvMCcvMCcvMC8wGiAeyruP7CoNYcGISzRo8iZmuVnV6M9gLiZuShy7aDtKKiABKNHEFDD/////DxIoCiIxQ3Zoeml0ZFZMUGhOVGZ3NU5rUm9YWHZveldacGZhWXQ2EJ/nBRoVCg9tLzQ0Jy8wJy8wJy8wLzAYsbcOMig0NDI6NDY5ZTMxOGUtYjcxZC00MGUwLTg0ZjctNzVlOGQwOWE3Yzg2IhMKCnJlcXVlc3RfaWQQARoDNDQyIhIKCXJ1bGVzX2tleRABGgNCVEMiEQoIY3VycmVuY3kQARoDQlRDIlsKBnNvdXJjZRAEGkcIARJDCAESIjFKTUJZTU1pOWlqSlJlVFlxdEZUU2RlVkJ6azhOSGRzVHUaCm5vc3RybyBCVEMiD20vNDQnLzAnLzAnLzAvMCIGc291cmNlImIKC2Rlc3RpbmF0aW9uEAUaRBJCCMwBEiIxQ3Zoeml0ZFZMUGhOVGZ3NU5rUm9YWHZveldacGZhWXQ2GghteSBsYWJlbCIPbS80NCcvMCcvMCcvMC84IgtkZXN0aW5hdGlvbiKeAQoGYW1vdW50EAoaiQEKAwGGoBIHMTAuMDQzMBoKMTAwNDIuOTcwMCAIKgNCVEMyA0NIRjphCh12YWxpZGF0b3ItY29yZUB0YXVydXNncm91cC5jaBJAffe4nBGVSajYYQxxzEZbQuj0snr8WOC1P506eXRn2EUsDrAnkWvNW9wfU+pwUoBVUaXl/veYW/6m/DJsEKijLCIGYW1vdW50Ih4KEXRvdGFsX2ZpYXRfYW1vdW50EAEaBzEwLjA0MzAiCwoDZmVlEAIaAhMBIh4KFGZlZV9wYWlkX2J5X3JlY2VpdmVyEAEaBHRydWU=",
#       "status": "CREATED",
#       "trails": [
#         {
#           "userId": "11",
#           "externalUserId": "[email protected]",
#           "action": "created",
#           "comment": "Ich bin eine flying Roasted Butternut Squash Boodles",
#           "date": "2020-02-19T12:24:47.748229Z",
#           "requestStatus": "CREATED"
#         },
#         {
#           "userId": "1",
#           "externalUserId": "[email protected]",
#           "action": "approvers_assigned",
#           "comment": "rule = [source: any, destination: any, amount: 10.0000], approvals = ['team1': 1 sig, 'team2': 1 sig]",
#           "date": "2020-02-19T12:24:47.774836Z",
#           "requestStatus": "CREATED"
#         }
#       ],
#       "creationDate": "2020-02-19T12:24:47.586041Z",
#       "updateDate": "2020-02-19T12:24:47.713648Z",
#       "metadata": {
#         "hash": "fda859afd5dcc16f7abec8e7ab7fc528d90b094e43eeb111037581c45f8e16b5",
#         "payload": [
#           {
#             "column": "",
#             "key": "request_id",
#             "type": "String",
#             "value": "442"
#           },
#           {
#             "column": "",
#             "key": "rules_key",
#             "type": "String",
#             "value": "BTC"
#           },
#           {
#             "column": "",
#             "key": "currency",
#             "type": "String",
#             "value": "BTC"
#           },
#           {
#             "column": "source",
#             "key": "source",
#             "type": "Source",
#             "value": {
#               "payload": {
#                 "address": "1JMBYMMi9ijJReTYqtFTSdeVBzk8NHdsTu",
#                 "id": "1",
#                 "label": "nostro BTC",
#                 "path": "m/44'/0'/0'/0/0"
#               },
#               "type": "SourceInternalAddress"
#             }
#           },
#           {
#             "column": "destination",
#             "key": "destination",
#             "type": "Destination",
#             "value": {
#               "payload": {
#                 "address": "1CvhzitdVLPhNTfw5NkRoXXvozWZpfaYt6",
#                 "id": "204",
#                 "label": "my label",
#                 "path": "m/44'/0'/0'/0/8"
#               },
#               "type": "DestinationInternalAddress"
#             }
#           },
#           {
#             "column": "amount",
#             "key": "amount",
#             "type": "Amount",
#             "value": {
#               "currencyFrom": "BTC",
#               "currencyTo": "CHF",
#               "decimals": "8",
#               "rate": "10042.9700",
#               "valueFrom": "100000",
#               "valueTo": "10.0430"
#             }
#           },
#           {
#             "column": "",
#             "key": "total_fiat_amount",
#             "type": "String",
#             "value": "10.0430"
#           },
#           {
#             "column": "",
#             "key": "fee",
#             "type": "BigInt",
#             "value": "4865"
#           },
#           {
#             "column": "",
#             "key": "fee_paid_by_receiver",
#             "type": "String",
#             "value": "true"
#           }
#         ]
#       },
#       "rule": "rule = [source: any, destination: any, amount: 10.0000], approvals = ['team1': 1 sig, 'team2': 1 sig]",
#       "approvers": {
#         "parallel": [
#           {
#             "sequential": [
#               {
#                 "externalGroupID": "team1",
#                 "minimumSignatures": 1
#               },
#               {
#                 "externalGroupID": "team2",
#                 "minimumSignatures": 1
#               }
#             ]
#           }
#         ]
#       }
#     }
#   ],
#   "totalItems": "1"
# }

2.4 Sign the transaction with first user

  1. Order transaction you would like to sign by ID (here there is only 442)
  2. Sign the array of all metada.hash
  3. Build up the ECDSA signature, encode it in Base64
echo -n '["fda859afd5dcc16f7abec8e7ab7fc528d90b094e43eeb111037581c45f8e16b5"]' | openssl  dgst -sha256 -sign yubikey1-key.pem | openssl asn1parse -inform DER
#    0:d=0  hl=2 l=  68 cons: SEQUENCE
#    2:d=1  hl=2 l=  32 prim: INTEGER           :234C56C972372F7DC331900ABEF2979E5583DC61975A1D00B8BE731C3D760C6A
#   36:d=1  hl=2 l=  32 prim: INTEGER           :76FE947687631B822419ACD181DBBB3F881F77F1480C2B5C5485B9B57CDC7C9F

echo -n "234C56C972372F7DC331900ABEF2979E5583DC61975A1D00B8BE731C3D760C6A76FE947687631B822419ACD181DBBB3F881F77F1480C2B5C5485B9B57CDC7C9F" | xxd -p -r | base64 | tr -d '\n'
#I0xWyXI3L33DMZAKvvKXnlWD3GGXWh0AuL5zHD12DGp2/pR2h2MbgiQZrNGB27s/iB938UgMK1xUhbm1fNx8nw==
  1. Send the signed request
curl -X POST "https://int-validator-core-crdb.t-bx.io/rjpyber72n6brsdzksotivcm33mw78q4/api/rest/v1/requests/approve" -H "accept: application/json" -H "Content-Type: application/json"  -H "$AUTH" -d "{ \"signature\": \"I0xWyXI3L33DMZAKvvKXnlWD3GGXWh0AuL5zHD12DGp2/pR2h2MbgiQZrNGB27s/iB938UgMK1xUhbm1fNx8nw==\", \"comment\": \"try01\", \"requestIds\": [ \"442\" ]}"
#{"signedRequests":"1"}

2.5 Sign the transaction with the second user

  1. Auth
curl -X POST "https://int-validator-core-crdb.t-bx.io/rjpyber72n6brsdzksotivcm33mw78q4/api/rest/v1/authentication/token" -H "accept: application/json" -H "Content-Type: application/json" -d "{ \"email\": \"[email protected]\", \"password\": \"XXXX\"}"
#{"result":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MTIsImV4dGVybmFsVXNlcklEIjoidGVhbTJAYmFuay5jb20iLCJ0ZW5hbnRJRCI6MSwiZmlyc3RuYW1lIjoiSm9obiIsImxhc3RuYW1lIjoiVDIiLCJyb2xlcyI6WyJyZxF1ZXN0YXBwcm92ZXIiXSwiZW1haWwiOiJ0ZWFtMkBiYW5rLmNvbSIsImV4cCI6MTU4MjI3NDQ1MiwiaWF0IjoxNTgyMTg4MDUyfQ.9-7pUrRG7Slpeod8NuY55cTSNOXsMGFE5Lb_GLv32AE"}
export AUTH="Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MTIsImV4dGVybmFsVXNlcklExjoidGVhbTJAYmFuay5jb20iLCJ0ZW5hbnRJRCI6MSwiZmlyc3RuYW1lIjoiSm9obiIsImxhc3RuYW1lIjoiVDIiLCJyb2xlcyI6WyJyZXF1ZXN0YXBwcm92ZXIiXSwiZW1haWwiOiJ0ZWFtMkBiYW5rLmNvbSIsImV4cCI6MTU4MjI3NDQ1MiwiaWF0IjoxNTgyMTg4MDUyfQ.9-7pUrRG7Slpeod8NuY55cTSNOXsMGFE5Lb_GLv32AE"
  1. Sign
echo -n '["fda859afd5dcc16f7abec8e7ab7fc528d90b094e43eeb111037581c45f8e16b5"]' | openssl  dgst -sha256 -sign yubikey2-key.pem | openssl asn1parse -inform DER
#    0:d=0  hl=2 l=  70 cons: SEQUENCE
#    2:d=1  hl=2 l=  33 prim: INTEGER           :D0BC45E1436E2057E8CF8D79353045CB812718218BA23C277D5DE645F6AF3E4D
#   37:d=1  hl=2 l=  33 prim: INTEGER           :8DCF22A046E7EADF687904790D86FBAB0B27E4C09E160483298C29395C8D2A5C

echo -n "D0BC45E1436E2057E8CF8D79353045CB812718218BA23C277D5DE645F6AF3E4D8DCF22A046E7EADF687904790D86FBAB0B27E4C09E160483298C29395C8D2A5C" | xxd -p -r | base64 | tr -d '\n'
#0LxF4UNuIFfoz415NTBFy4EnGCGLojwnfV3mRfavPk2NzyKgRufq32h5BHkNhvurCyfkwJ4WBIMpjCk5XI0qXA==

curl -X POST "https://int-validator-core-crdb.t-bx.io/rjpyber72n6brsdzksotivcm33mw78q4/api/rest/v1/requests/approve" -H "accept: application/json" -H "Content-Type: application/json"  -H "$AUTH" -d "{ \"signature\": \"0LxF4UNuIFfoz415NTBFy4EnGCGLojwnfV3mRfavPk2NzyKgRufq32h5BHkNhvurCyfkwJ4WBIMpjCk5XI0qXA==\", \"comment\": \"try01\", \"requestIds\": [ \"442\" ], \"hashes\": [ \"fda859afd5dcc16f7abec8e7ab7fc528d90b094e43eeb111037581c45f8e16b5\" ]}"
#{"signedRequests":"1"}

2.6 Get the status of the transaction

curl "https://int-validator-core-crdb.t-bx.io/rjpyber72n6brsdzksotivcm33mw78q4/api/rest/v1/requests/442" -H "accept: application/json" -H "Content-Type: application/json"  -H "$AUTH" | jq .
# {
#   "result": {
#     "id": "442",
#     "tenantId": "1",
#     "currency": "BTC",
#     "envelope": "CgM0NDIQmfGjk6Ops/oVGAEq1AYSrAEKPwoPbS80NCcvMCcvMCcvMC8wGiAeyruP7CoNYcGISzRo8iZmuVnV6M9gLiZuShy7aDtKKiABKNHEFDD/////DxIoCiIxQ3Zoeml0ZFZMUGhOVGZ3NU5rUm9YWHZveldacGZhWXQ2EJ/nBRoVCg9tLzQ0Jy8wJy8wJy8wLzAYsbcOMig0NDI6NDY5ZTMxOGUtYjcxZC00MGUwLTg0ZjctNzVlOGQwOWE3Yzg2GlsKFwoOdGVhbTFAYmFuay5jb20aBXRyeTAxEkBmZGE4NTlhZmQ1ZGNjMTZmN2FiZWM4ZTdhYjdmYzUyOGQ5MGIwOTRlNDNlZWIxMTEwMzc1ODFjNDVmOGUxNmI1GlsKFwoOdGVhbTJAYmFuay5jb20aBXRyeTAxEkBmZGE4NTlhZmQ1ZGNjMTZmN2FiZWM4ZTdhYjdmYzUyOGQ5MGIwOTRlNDNlZWIxMTEwMzc1ODFjNDVmOGUxNmI1IhMKCnJlcXVlc3RfaWQQARoDNDQyIhIKCXJ1bGVzX2tleRABGgNCVEMiEQoIY3VycmVuY3kQARoDQlRDIlsKBnNvdXJjZRAEGkcIARJDCAESIjFKTUJZTU1pOWlqSlJlVFlxdEZUU2RlVkJ6azhOSGRzVHUaCm5vc3RybyBCVEMiD20vNDQnLzAnLzAnLzAvMCIGc291cmNlImIKC2Rlc3RpbmF0aW9uEAUaRBJCCMwBEiIxQ3Zoeml0ZFZMUGhOVGZ3NU5rUm9YWHZveldacGZhWXQ2GghteSBsYWJlbCIPbS80NCcvMCcvMCcvMC84IgtkZXN0aW5hdGlvbiKeAQoGYW1vdW50EAoaiQEKAwGGoBIHMTAuMDQzMBoKMTAwNDIuOTcwMCAIKgNCVEMyA0NIRjphCh12YWxpZGF0b3ItY29yZUB0YXVydXNncm91cC5jaBJAffe4nBGVSajYYQxxzEZbQuj0snr8WOC1P506eXRn2EUsDrAnkWvNW9wfU+pwUoBVUaXl/veYW/6m/DJsEKijLCIGYW1vdW50Ih4KEXRvdGFsX2ZpYXRfYW1vdW50EAEaBzEwLjA0MzAiCwoDZmVlEAIaAhMBIh4KFGZlZV9wYWlkX2J5X3JlY2VpdmVyEAEaBHRydWU=",
#     "status": "BROADCASTING",
#     "trails": [
#       {
#         "userId": "11",
#         "externalUserId": "[email protected]",
#         "action": "created",
#         "comment": "Ich bin eine flying Roasted Butternut Squash Boodles",
#         "date": "2020-02-19T12:24:47.748229Z",
#         "requestStatus": "CREATED"
#       },
#       {
#         "userId": "1",
#         "externalUserId": "[email protected]",
#         "action": "approvers_assigned",
#         "comment": "rule = [source: any, destination: any, amount: 10.0000], approvals = ['team1': 1 sig, 'team2': 1 sig]",
#         "date": "2020-02-19T12:24:47.774836Z",
#         "requestStatus": "CREATED"
#       },
#       {
#         "userId": "11",
#         "externalUserId": "[email protected]",
#         "action": "approved",
#         "comment": "try01",
#         "date": "2020-02-20T08:12:51.209785Z",
#         "requestStatus": "APPROVING"
#       },
#       {
#         "userId": "12",
#         "externalUserId": "[email protected]",
#         "action": "approved",
#         "comment": "try01",
#         "date": "2020-02-20T08:43:53.445343Z",
#         "requestStatus": "APPROVING"
#       },
#       {
#         "userId": "1",
#         "externalUserId": "[email protected]",
#         "action": "approval_completed",
#         "date": "2020-02-20T08:43:53.667491Z",
#         "requestStatus": "APPROVED"
#       },
#       {
#         "userId": "1",
#         "externalUserId": "[email protected]",
#         "action": "hsm_ready",
#         "date": "2020-02-20T08:43:58.097522Z",
#         "requestStatus": "HSM_READY"
#       },
#       {
#         "userId": "1",
#         "externalUserId": "[email protected]",
#         "action": "hsm_signed",
#         "comment": "transaction signed by the HSM: 442:469e318e-b71d-40e0-84f7-75e8d09a7c86",
#         "date": "2020-02-20T08:44:04.448018Z",
#         "requestStatus": "HSM_SIGNED"
#       },
#       {
#         "userId": "1",
#         "externalUserId": "[email protected]",
#         "action": "broadcasting",
#         "comment": "broadcasting transaction (id: '442:469e318e-b71d-40e0-84f7-75e8d09a7c86', hash: '1a1c279eed33c4bcb36ba3c79062b76c166e84e76efa1c7b60ba3c689042b160')",
#         "date": "2020-02-20T08:44:13.270210Z",
#         "requestStatus": "BROADCASTING"
#       }
#     ],
#     "signedRequests": [
#       {
#         "id": "322",
#         "signedRequest": "01000000012a4a3b68bb1c4a6e262e60cfe8d559b96626f268344b88c1610d2aec8fbbca1e010000006b483045022100956bad7056aa431d17b1127adb0be883d931aa7de211c3e8c04d37aa4654c20402204bf316025c82f11a47f6333b6e196bba758cc7e67a1de85b75e5f40a35947845012102de4efb33938e1ba6936cf01d8b6f78d4587644d923f2fd1b4db260159dc1e348ffffffff029f730100000000001976a91482d1a692a74887c0f7b22728f751c746f809ec9688acb19b0300000000001976a914be4b41a078c0be0567bfdbfa0a4ab0b90652d54888ac00000000",
#         "status": "BROADCASTING",
#         "hash": "1a1c279eed33c4bcb36ba3c79062b76c166e84e76efa1c7b60ba3c689042b160",
#         "creationDate": "2020-02-20T08:44:04.439848Z",
#         "updateDate": "2020-02-20T08:44:13.251440Z",
#         "broadcastDate": "2020-02-20T08:44:13.251440Z"
#       }
#     ],
#     "creationDate": "2020-02-19T12:24:47.586041Z",
#     "updateDate": "2020-02-20T08:44:13.257347Z",
#     "metadata": {
#       "hash": "fda859afd5dcc16f7abec8e7ab7fc528d90b094e43eeb111037581c45f8e16b5",
#       "payload": [
#         {
#           "column": "",
#           "key": "request_id",
#           "type": "String",
#           "value": "442"
#         },
#         {
#           "column": "",
#           "key": "rules_key",
#           "type": "String",
#           "value": "BTC"
#         },
#         {
#           "column": "",
#           "key": "currency",
#           "type": "String",
#           "value": "BTC"
#         },
#         {
#           "column": "source",
#           "key": "source",
#           "type": "Source",
#           "value": {
#             "payload": {
#               "address": "1JMBYMMi9ijJReTYqtFTSdeVBzk8NHdsTu",
#               "id": "1",
#               "label": "nostro BTC",
#               "path": "m/44'/0'/0'/0/0"
#             },
#             "type": "SourceInternalAddress"
#           }
#         },
#         {
#           "column": "destination",
#           "key": "destination",
#           "type": "Destination",
#           "value": {
#             "payload": {
#               "address": "1CvhzitdVLPhNTfw5NkRoXXvozWZpfaYt6",
#               "id": "204",
#               "label": "my label",
#               "path": "m/44'/0'/0'/0/8"
#             },
#             "type": "DestinationInternalAddress"
#           }
#         },
#         {
#           "column": "amount",
#           "key": "amount",
#           "type": "Amount",
#           "value": {
#             "currencyFrom": "BTC",
#             "currencyTo": "CHF",
#             "decimals": "8",
#             "rate": "10042.9700",
#             "valueFrom": "100000",
#             "valueTo": "10.0430"
#           }
#         },
#         {
#           "column": "",
#           "key": "total_fiat_amount",
#           "type": "String",
#           "value": "10.0430"
#         },
#         {
#           "column": "",
#           "key": "fee",
#           "type": "BigInt",
#           "value": "4865"
#         },
#         {
#           "column": "",
#           "key": "fee_paid_by_receiver",
#           "type": "String",
#           "value": "true"
#         }
#       ]
#     },
#     "rule": "rule = [source: any, destination: any, amount: 10.0000], approvals = ['team1': 1 sig, 'team2': 1 sig]",
#     "approvers": {
#       "parallel": [
#         {
#           "sequential": [
#             {
#               "externalGroupID": "team1",
#               "minimumSignatures": 1
#             },
#             {
#               "externalGroupID": "team2",
#               "minimumSignatures": 1
#             }
#           ]
#         }
#       ]
#     }
#   }
# }