Webhooks

TrustVault provides webhooks to alert you of the changes in that status of your transactions. These are POST requests delivered to your server and are sent as soon as an event occurs. The body of the request contains the details of the event.

Upon receiving a webhook notification, it should be acknowledged with a HTTP success response 20x. Otherwise the webhoook notification will be attempted to be sent again according to the following schedule:

  • 1 minute from the previous attempt
  • 2 minutes from the previous attempt
  • 15 minutes from the previous attempt
  • 2 hours from the previous attempt
  • 10 hours from the previous attempt
  • 24 hours from the previous attempt

If you need to register a webhook, just get in touch with Trustology Support via help@trustology.io

Events

Event Description Event type
Bitcoin Received A bitcoin wallet belonging to the trustId has received a transaction BITCOIN_TRANSACTION_RECEIVED
Ethereum Received An ethereum wallet belonging to the trustId has received a ETH or ERC20 transaction ETHEREUM_TRANSACTION_RECEIVED
Bitcoin Transaction Created A bitcoin transaction has been created BITCOIN_TRANSACTION_CREATED
Ethereum Transaction Created An ethereum transaction has been created ETHEREUM_TRANSACTION_CREATED
Policy Change Request Created There is a request to change the policy associated with a wallet POLICY_CHANGE_REQUEST_CREATED
External Item Signed An external item has been signed EXTERNAL_ITEM_SIGNED
Delegate Signed A request belonging to the trustId has been signed by a valid delegate DELEGATE_SIGNED

Event Triggers

Event type Trigger
BITCOIN_TRANSACTION_RECEIVED 1 block confirmation (as seen by TrustVault Bitcoin indexer) of a bitcoin transaction with user trustId
ETHEREUM_TRANSACTION_RECEIVED 1 block confirmation (as seen by TrustVault Ethereum indexer) for ETH or ERC20 transaction with user trustId
BITCOIN_TRANSACTION_CREATED A Bitcoin transaction has been created (if via the API “sendToDevices” must be true), including creation via TrustVaultWeb, excluding creation via iOS
ETHEREUM_TRANSACTION_CREATED An Ethereum transaction has been created (if via the API “sendToDevices” must be true), including creation via TrustVaultWeb, excluding creation via iOS
POLICY_CHANGE_REQUEST_CREATED API only: A request has been created to change the wallet policy via the API or SDK
EXTERNAL_ITEM_SIGNED TrustVault has signed the external item due to enough signature(s) were collected to satisfy the delegate schedule
DELEGATE_SIGNED A request belonging to the trustId has been signed by a valid delegate

Event Object

Attribute Description
messageId string
Unique identifier for the webhook notification
version string
The webhook version
type string
The webhook notification type
timestamp integer
The timestamp of the webhook notification
isoTimestamp string
The timestamp of the webhook notification in ISO 8601 format
payload object
The payload for the webhook notification

Bitcoin Received Event

The bitcoin received webhook will be triggered as soon as there is 1 confirmation from a miner.

Bitcoin Transaction Received Payload

Attribute Description
trustId string
Unique identifier for the TrustVault user
subWalletId object
Unique identifier for the sub-wallet
subWalletIdString string
Unique identifier for the sub-wallet, in string format
transactionAmount string
The transaction amount in satoshi (integer string)
bitcoinAddress string
The UTXO receive address of the transaction
transactionType string
The type of transaction - RECEIVED or SELF
blockHeight integer
The block number where the transaction was included in
transactionId string
Unique identifier for the transaction in the blockchain
transactionBlockTime integer
The timestamp of the block
transactionAmountInBtc string
The transaction amount in BTC (float string)
complianceInfo object?
(optional) Compliance info of the transaction

Ethereum Received Event

The ethereum received webhook will be triggered as soon as there is 1 confirmation from a miner.

Ethereum Transaction Received Payload

Attribute Description
trustId string
Unique identifier for the TrustVault user
subWalletId object
Unique identifier for the sub-wallet
subWalletIdString string
Unique identifier for the sub-wallet, in string format
from string
Ethereum address where the transaction was sent from
to string
Ethereum address where the transaction was sent to (*)
transactionValue string
Transaction value in Wei
transactionValueInEth string
Transaction value in Eth
transactionType string
The type of transaction - RECEIVED/SELF
tokensData array
Token data (see token structure below) (**)
transactionId string
Unique identifier for the transaction in the blockchain
blockHeight string
The block number where the transaction was included in
blockHash string
Unique identifier for the block the transaction was included in
gasUsed string
Gas used by the transaction
gasPrice string
Gas price of the transaction
transactionBlockTime number
The timestamp of the block
decodedInput object
The decoded input field of the transaction
decodedEvents array
Array with all the emitted decoded events
complianceInfo object?
(optional) Compliance info of the transaction

(*)

  • In Ether transfers, to has the value of ethereum address where the Ether is transferred to.
  • In ERC20 transfers, to has the value of smart contract that manages the token transfer.

(**)

  • In Ether transfers, this array will be empty.

Ethereum Transaction Created Payload

Attribute Description
trustId string
Unique identifier for the TrustVault user
subWalletId object
Unique identifier for the sub-wallet
subWalletIdString string
Unique identifier for the sub-wallet, in string format
assetSymbol string
The symbol associated with the asset being transacted
chain string
The chain associated with this transaction. i..e ETHEREUM
signData object
The full chain specific data associated with this transaction
policyData object
The full wallet policy
transferValueDefinition object
The transfer value of the transaction in native and fiat amounts

Bitcoin Transaction Created Payload

Attribute Description
trustId string
Unique identifier for the TrustVault user
subWalletId object
Unique identifier for the wallet
subWalletIdString string
Unique identifier for the wallet, in string format
assetSymbol string
The symbol associated with the asset being transacted
chain string
The chain associated with this transaction. i..e BITCOIN
fee string
Fee in Satoshis for this transaction
signData object
The full chain specific data associated with this transaction
policyData object
The full wallet policy
transferValueDefinition object
The transfer value of the transaction in native and fiat amounts

Delegate Signed Payload

Attribute Description
trustId string
Unique identifier for the TrustVault user
requestId string
Unique identifier for the request that was signed
requestType string
The type of the request that was signed. See Request Types below
walletId string
(Optional) Unique identifier for the parent wallet associated with the request that was signed. Does not exist for CREATION type
subWalletId string
(Optional) Unique identifier for the sub-wallet associated with the transaction, in string format. Does not exist for RECOVERY / CREATION types
assetSymbol string
(Optional) The symbol associated with the asset being transacted. Does not exist for RECOVERY / CREATION types
chain string
(Optional) The chain associated with this transaction. i..e ETHEREUM. Does not exist for RECOVERY / CREATION types
publicKeys object
Contains the list of valid delgate public keys that have signed the request so far
policy object
The delegate schedule of the wallet that is associated with the request

Request Types

Attribute Description
RECOVERY A request to change the policy of a wallet (i.e. recover it)
CREATION A request to create a new wallet with a defined policy
ETH_TRANSACTION A request to send an ETH / ERC20 transaction
EXTERNAL_ETH_TRANSACTION A request to send an ETH / ERC20 transaction which coming from a 3rd party (i.e. MetaMask x TrustVault extension)
BTC_TRANSACTION A request to send a bitcoin transaction
BINANCE_TRANSACTION A request to send BNB / BEP-2 transaction
EXCHANGE_TRANSFER A request to transfer assets between exchange accounts
ETH_PERSONAL_SIGN A request to sign an Eth Personal Sign message
ETH_TYPED_DATA_SIGN A request to sign an Eth Typed Data message
EXTERNAL_SIGN A request to sign data which comes from a 3rd party

TransferValueDefinition Field

It should be noted that not all transactions can be valued. Sending ETH or BTC is quite straight forward, as is sending supported ERC-20 tokens. However, when sending to contracts it can get difficult to value the transaction. As such, we currently only support valuing the following:

  • ERC-20 supported transactions
  • ETH value transfers
  • BTC value transfers

At this time ETH transfers to any contract (including a on-chain wallet or vault) are not valued. Transactions that cannot be valued will have transferValueDefinition.transferAmount and transferValueDefinition.convertedAmount fields set to undefined.

Token Data

Attribute Description
to string
Ethereum address where the tokens were transferred to
quantity string
Quantity of tokens transferred
symbol string
Token symbol
assetName string
Name of the token
tokenDirectionType string
Direction of token transfer - RECEIVED/SELF

Compliance Info

Attribute Description
asset string
Symbol associated with the asset of the transaction (BTC, ETH etc..)
transferReference string
transactionHash:outputAddress
status string
SUCCESS/FAIL to query KYC/AML data
decision string
ALLOW/QUARANTINE
riskRating string
UNKNOWN/HIGH/LOW: Risk level of the transaction
cluster string
Cluster the transaction belongs to

Policy Change Request Created

Attribute Description
trustId string
Unique identifier for the TrustVault user
requestId string
Unique identifier for the request
policyTemplate object
Object containing the new policy for the wallet
recovererTrustVaultSignature string
The r, s values of the signature of the SHA-256(DER(policy)) as signed by the TrustVault provenance key. This ensures that you can confirm that the policy has come from TrustVault
unverifiedDigestData string
The policy object containing properties for easy signing

UnverifiedDigestData

Called “unverified” because the onus is on the caller to ensure that the message contains the same data that has been requested for this wallet. i.e. if you requested a new policy you can construct the policy object you expect, DER encode it, SHA-256 hash it and then check that your digest matches the shaSignData. Additionally, you can verify the recovererTrustVaultSignature to ensure the data was signed by TrustVault.

For testing, verification is not required and you can simply sign the shaSignData or signData depending on if your signing code request the raw message or the digest (SHA-256).

The TrustVault node.js SDK will do verification of the payload for you

Attribute Description
signData string
The message containing the DER encoded policy that must be signed if you are in control of a publicKey referenced in the policy
shaSignData string
The SHA-256 digest of the message

PolicyTemplate

Attribute Description
delegateSchedules array
An array of delegate schedules which contain and array of clauses
recovererSchedules array
An array of delegate schedules which contain and array of clauses

Sub Wallet ID object

Attribute Description
id string
Unique identifier for the HD Wallet
type string
The chain identifier where the sub wallet belongs to (“BTC”, “BINANCE”)
index number
Index of the sub wallet in the HD Wallet starting at zero (integer)

Sample Bitcoin Received Event Object

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
{
"messageId": "87f49826-dafb-46e9-a9bc-6ed7ef61f811",
"version": "1.0.2",
"type": "BITCOIN_TRANSACTION_RECEIVED",
"timestamp": 1588323320463,
"isoTimestamp": "2020-05-01T09:18:31.354Z",
"payload": {
"subWalletIdString": "f63b2ff1-f02b-48df-8b9f-bc57f5c57061/BTC/0",
"trustId": "f67ddcf6-e95d-4aa7-9a2d-e855ba5dc380",
"subWalletId": {
"id": "f63b2ff1-f02b-48df-8b9f-bc57f5c57061",
"type": "BTC",
"index": 0,
},
"transactionAmount": "142498030",
"bitcoinAddress": "342ftSRCvFHfCeFFBuz4xwbeqnDw6BGUey",
"transactionType": "RECEIVED",
"blockHeight": 627997,
"transactionId": "97f1f9150a992ac5309a0837ef3309757dc6359b8355867933d693b7c6a1ae98",
"transactionBlockTime": 1588078790,
"transactionAmountInBtc": "1.4249803",
"complianceInfo":
{
"asset": "BTC",
"transferReference": "a7431f70d4d8489289797ef62fce3bf6ce9b961dfa40ec7463361c4d85f0f6c5:3NEiAQZwbgnTPjuVqZ8RxLD6EnKPgo3XFf",
"status": "SUCCESS",
"decision": "ALLOW",
"data": {
"riskRating": "UNKNOWN",
"cluster": {
"name": "BitMEX.com",
"category": "high risk exchange"
}
}
}
}
}
}

Sample Bitcoin Transaction Created Event Object

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
{
"type": "BITCOIN_TRANSACTION_CREATED",
"messageId": "7bd6edad-e23f-476b-8cab-714cb80e4840",
"timestamp": 1588323320463,
"isoTimestamp": "2020-05-01T09:18:31.354Z",
"version": "1.0.0",
"payload": {
"requestId": "8f18b68b-eeb6-0b4c-9c93-2921b336f359",
"fee": 900,
"trustId": "c6b18fb4-3eac-420b-91f3-5ee1f679a16d",
"assetSymbol": "BTC",
"chain": "BITCOIN",
"policyData": {
"...<PolicyAssociatedWithWallet>"
},
"signData": {
"transaction": {
"version": 1,
"inputs": [
{
"address": "37thS2qbjZD47eT7M2txL1NxUywEq3hfye",
"txId": "4722c3f2d6a30fc481d237ccb4e6037cc02e3f4ff65e965b6cdbeaf0e59f52d6",
"outputIndex": 1,
"script": "a91444064f6cf221f0e64a0140b7e3707edd64bb6a1387",
"sequence": "ffffffff",
"value": 1642873750,
"publicKeyProvenanceData": {
"publicKey": "046386a33646742eeba5d202c09f123819b9785ddea5b78b5b64b36dd60397b36507a493d7a0a38334a6168f73e4ef9dfed1258b6248e8015c0e148b04cd3f6dc6",
"path": [
"0x80000049",
"0x80000000",
"0x80000000",
"0x1",
"0x45b"
],
"accountHSMProvenanceSignature": "0261a5cd98e8bef2f2610f8f09fa07d12731f69835daccccd12763dbc6137444d2cd5c850d18dc7768cfa5582f04367a58ecaeccbfde944cbbce42cf4884a024",
"unverifiedAddress": "37thS2qbjZD47eT7M2txL1NxUywEq3hfye",
"addressType": "COMPATIBILITY"
},
"unverifiedDigestData": {
"transactionDigest": "e928bcb8acf4bcda5c71151041c144e227ba60f30789fd470bd580391aa97d4a",
"signData": "30400420e928bcb8acf4bcda5c71151041c144e227ba60f30789fd470bd580391aa97d4a301c0205008000004902050080000000020500800000000201010202045b",
"shaSignData": "0ad7b306818ac11e812241fca40af3a621c348d25660fef9f5f59dacca14364f"
}
}
],
"outputs": [
{
"recipientAddress": "3AnVHpLRg63RT5Tg7XbUBtU9yFtJirT4RG",
"amountToSend": 9210000
},
{
"recipientAddress": "3MMUFRuHqjwrDbZGoq5yZgqfktD5gLGMKk",
"amountToSend": 1633653790,
"publicKeyProvenanceData": {
"publicKey": "040fbb85f7d9137ec3e88ddb88a79dbcc826e2de68fe4fb658bcef8031b1fd4b7507efc7ae6c014720929dfd5556756c387b9f7ce749ef277716d28d0ce973971a",
"path": [
"0x80000049",
"0x80000000",
"0x80000000",
"0x1",
"0x45d"
],
"accountHSMProvenanceSignature": "e1efc0d84050d61de14c584713d47147bbd6c93dedf56e55fc57e962751fccaebab89bade9b46a8cbbe7bfcaeee4d4ca981b87ff83e1dddda2f447f8809f2dbe",
"unverifiedAddress": "3MMUFRuHqjwrDbZGoq5yZgqfktD5gLGMKk",
"addressType": "COMPATIBILITY"
}
}
],
"lockTime": 0,
"sighash": 1
}
},
"transferValueDefinition": {
"type": "BITCOIN",
"transferAmount": {
"value": "0.0921",
"currency": "BTC",
"timestamp": "2021-03-09T17:26:49.028Z"
},
"convertedAmount": {
"GBP": {
"value": "3695.553945",
"currency": "GBP",
"timestamp": "2021-03-09T17:26:11.745Z"
},
"USD": {
"value": "5127.37278",
"currency": "USD",
"timestamp": "2021-03-09T17:26:11.745Z"
},
"EUR": {
"value": "4312.884588",
"currency": "EUR",
"timestamp": "2021-03-09T17:26:11.745Z"
},
"JPY": {
"value": "557217.236406",
"currency": "JPY",
"timestamp": "2021-03-09T17:26:11.745Z"
}
}
}
}
}

Sample Ethereum Transaction (ERC20) Created Event Object

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
{
"version": "1.0.1",
"type": "ETHEREUM_TRANSACTION_CREATED",
"payload": {
"assetSymbol": "OMG",
"chain": "ETHEREUM",
"signData": {
"transaction": {
"nonce": 10,
"gasPrice": "172000000000",
"gasLimit": "51303",
"chainId": 3,
"v": 3,
"to": "0x7FC6F18fa1461189aB89732d2ECAaD988E1Be26A",
"fromAddress": "0x6fe668915B32A1364FE63386b4E3cE919b267540",
"value": "0",
"data": "0xa9059cbb000000000000000000000000671e96593Ea93bfcb510375f4CeC111d0E5cf1b800000000000000000000000000000000000000000000000caf67003701680000",
"decodedInput": {
"id": "0xa9059cbb",
"signature": "transfer(address to, uint256 amount)",
"params": [
{
"name": "to",
"type": "address",
"value": "0x671e96593ea93bfcb510375f4cec111d0e5cf1b8"
},
{
"name": "amount",
"type": "uint256",
"value": "0xcaf67003701680000"
}
]
}
},
"transferValueDefinition": {
"type": "ETHEREUM",
"transferAmount": {
"value": "234",
"currency": "OMG",
"timestamp": "2021-03-09T17:26:49.028Z"
},
"convertedAmount": {
"GBP": {
"value": "884.52",
"currency": "GBP",
"timestamp": "2021-03-09T17:26:11.745Z"
},
"USD": {
"value": "1228.5",
"currency": "USD",
"timestamp": "2021-03-09T17:26:11.745Z"
},
"EUR": {
"value": "1031.94",
"currency": "EUR",
"timestamp": "2021-03-09T17:26:11.745Z"
},
"JPY": {
"value": "133380",
"currency": "JPY",
"timestamp": "2021-03-09T17:26:11.745Z"
}
}
},
"hdWalletPath": [
"0x8000002c",
"0x8000003c",
"0x80000000",
"0x0",
"0x0"
],
"unverifiedDigestData": {
"transactionDigest": "7ebf00d9345b2f2217c125afc633f623d2253a2b092992032f0d6a5f9003a62a",
"signData": "303f04207ebf00d9345b2f2217c125afc633f623d2253a2b092992032f0d6a5f9003a62a301b0205008000002c0205008000003c02050080000000020100020100",
"shaSignData": "0bdb1e2b1c75e16c887c5186f734c6c049324f9a951aed7b43bc7c19138cce9c"
}
},
"requestId": "25127cea-dbc7-6d89-ca6c-199fdaeb03c6",
"subWalletId": {
"type": "ETH",
"index": 0,
"id": "7a9e053c-47fc-489b-956f-2aafbe7d2ff0"
},
"trustId": "e7aac98f-d5c2-4adf-a47a-564aa05ce554",
"subWalletIdString": "7a9e053c-47fc-489b-956f-2aafbe7d2ff0/ETH/0",
"complianceInfo":
{
"asset": "ETH",
"transferReference": "https://etherscan.io/tx/0x3fb343d2277d04c60b5c062605a026e95fb2027c0318bfa7eabbffeb0046aebc",
"status": "SUCCESS",
"decision": "ALLOW",
"data": {
"riskRating": "UNKNOWN",
"cluster": {
"name": "BitMEX.com",
"category": "high risk exchange"
}
}
}
},
},
"messageId": "d913c151-f04b-47ca-a935-0949e4c27cb1",
"timestamp": 1611935455856,
"isoTimestamp": "2021-01-29T15:50:55.856Z"
}

Sample Ether Received Event Object

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
{
"version": "1.0.0",
"type": "ETHEREUM_TRANSACTION_RECEIVED",
"messageId": "4cfe6535-959b-4759-a9a2-043242e2ff57",
"timestamp": 1598363410185,
"isoTimestamp": "2020-08-25T13:50:10.185Z",
"payload": {
"trustId": "59ed6b8e-04f8-4815-ae59-f5e897ba3783",
"transactionValue": "2200000000000000",
"transactionValueInEth": "0.0022",
"transactionType": "RECEIVED",
"tokensData": [],
"transactionId": "0x657866589816879098d2c0644c832cb772f091929e714033e1123bdb35587a15",
"blockHeight": "8562864",
"blockHash": "0x7c8dd087c60afc21a581eaca25b62e5a35d84f6a56fff9c7a5ecbd3c1a408137",
"from": "0xEfdF561eB7eB03BF1A2e52466F7A3628a9Bb94ec",
"to": "0xe191edfa3ea87452857e81ebc744d3d94d103bc0",
"gasUsed": "21000",
"gasPrice": "102000000000",
"subWalletId": {
"id": "d11710e5-9354-4a28-accd-7e45f77f2b83",
"type": "ETH",
"index": 0
},
"subWalletIdString": "d11710e5-9354-4a28-accd-7e45f77f2b83/ETH/0",
"transactionBlockTime": 1598363384
}
}

Sample ERC20 Received Event Object

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
{
"version": "1.0.0",
"type": "ETHEREUM_TRANSACTION_RECEIVED",
"payload": {
"trustId": "e7aac98f-d5c2-4adf-a47a-564aa05ce554",
"transactionValue": "0",
"transactionValueInEth": "0",
"transactionType": "RECEIVED",
"tokensData": [
{
"to": "0x671e96593Ea93bfcb510375f4CeC111d0E5cf1b8",
"rawQuantity": "20000000000000000000",
"contractAddress": "0x35E677846E8bef84f1Ce0A182b3ddc4040a2F652",
"quantity": "20",
"symbol": "VXV",
"assetName": "VectorspaceAI",
"tokenDirectionType": "RECEIVED"
}
],
"transactionId": "0xdd60bb69855803cb1f762f4d7e65d4080f25dee222e0026539908a6b8bf8cf00",
"blockHeight": "9560642",
"blockHash": "0x64830d8dccfe2768ca5d54e47cb90248dff9cc1668e08b3259fb60a941b7707b",
"from": "0xb8fca00b882AcAbdEA9CF0F908FD0Da0FEBbFbAc",
"to": "0x7fc6f18fa1461189ab89732d2ecaad988e1be26a",
"gasUsed": "51315",
"gasPrice": "200000000000",
"subWalletId": {
"id": "7a9e053c-47fc-489b-956f-2aafbe7d2ff0",
"type": "ETH",
"index": 1
},
"subWalletIdString": "7a9e053c-47fc-489b-956f-2aafbe7d2ff0/ETH/1",
"transactionBlockTime": 1611935580,
"decodedInput": {
"id": "0xa9059cbb",
"signature": "transfer(address to, uint256 amount)",
"params": [
{
"name": "to",
"type": "address",
"value": "0x671e96593ea93bfcb510375f4cec111d0e5cf1b8"
},
{
"name": "amount",
"type": "uint256",
"value": "0x1158e460913d00000"
}
]
},
"decodedEvents": [
{
"id": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"signature": "Transfer(address indexed from, address indexed to, uint256 value)",
"params": [
{
"name": "from",
"type": "address",
"value": "0xb8fca00b882acabdea9cf0f908fd0da0febbfbac"
},
{
"name": "to",
"type": "address",
"value": "0x671e96593ea93bfcb510375f4cec111d0e5cf1b8"
},
{
"name": "value",
"type": "uint256",
"value": "0x1158e460913d00000"
}
]
}
]
},
"messageId": "1601c282-3d0f-4071-acc1-9a1f560e0d42",
"timestamp": 1611935591522,
"isoTimestamp": "2021-01-29T15:53:11.522Z"
}

Sample Policy Change Request Created Event Object

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
{
"version": "1.0.0",
"type": "POLICY_CHANGE_REQUEST_CREATED",
"messageId": "142dc928-c4b8-4362-92dd-a1d16123d14a",
"timestamp": 1598362511233,
"isoTimestamp": "2020-08-25T13:35:11.233Z",
"payload": {
"trustId": "h2209c26-f228-8524-afe5-1f4bbedd80e8",
"requestId": "e2209c26-f228-8524-afe5-1f4bbedd80e7",
"policyTemplate": {
"delegateSchedules": [
[
{
"quorumCount": 1,
"keys": [
"04a526f56356cbe2726b6315e1d04aa01d8b8729be597fb406abb959b9e27c380bdb3961c650413b6407facf96570545720d09ef45f3ee0722310289c370ca52e4"
]
}
]
],
"recovererSchedules": [
[
{
"quorumCount": 2,
"keys": [
"047c5e15091230f87a2e2e14d11dea53103aad06e4e271db282621ccc377fdf100c339557350839aa88a6809879c83e1c3f37fc6a42d5d6bbe10eeeca1e9fd81ac",
"04dd294cbbd831c977b47bae433a94d564b1dc446b2d7d305d263bd178c74b2dd41687b21db7f08c11b01bc090b1bdd80d94f7d3a54b4881e810e0a4153a187966",
"04aed00304191764c4ab31225881cd071af3f62d7f2480758e0a5f58ba8543e316553e3acc3c7c0d50f718c7f947da8908155808f72071168a514ffc869d9e0b50",
"04a875847170e3542b731f8cd21f24f61573cc5b3a6af60125eb42fe11d8816e20a6972f50b7938c76ffa5f633627e0988ae881849527684b59ae13181081ab802",
"042170e7a2ca8d94bb459909c79828305a6038dde10f25e5b00dac36bfda559d2027eff8df58ed8b611c493c641c97defd870c44f045ef7577990a8935276482e1"
]
}
],
[
{
"quorumCount": 1,
"keys": [
"047b49c8d0292dc426d2545ceb83795d94336599b8945d9d6a582a8c584b85e8c9ce665ee0917ca6e53ea7fa0028ed1e1efabe3f147e0e7062e0a09782adfced9d"
]
}
],
[
{
"quorumCount": 1,
"keys": [
"048aba94e2d1e56b0e34a77ea0691787ee0bfbc50f39bad959d4fa62b137c89a9744eeade7d6ce47968ee8f63f89b04805871d955308a3c134fbd70a29aaa22844"
]
}
]
],
"expiryTimestamp": 1598398081
},
"recovererTrustVaultSignature": "faabc9cb6960d4abb9d8fa8c4bacdd9d18e550fea4670290a8ac8770e5b9d7a952df54e39877d942a8900621cf85121e1f1eba2c45e7e0b5c30d9d0a0611ec15",
"walletId": "662dcbdf-d303-4369-878c-fccccefefd64",
"unverifiedDigestData": {
"signData": "3082024e02045f459e81304c304a30480201013043044104a526f56356cbe2726b6315e1d04aa01d8b8729be597fb406abb959b9e27c380bdb3961c650413b6407facf96570545720d09ef45f3ee0722310289c370ca52e4308201f63082015a308201560201023082014f0441047c5e15091230f87a2e2e14d11dea53103aad06e4e271db282621ccc377fdf100c339557350839aa88a6809879c83e1c3f37fc6a42d5d6bbe10eeeca1e9fd81ac044104dd294cbbd831c977b47bae433a94d564b1dc446b2d7d305d263bd178c74b2dd41687b21db7f08c11b01bc090b1bdd80d94f7d3a54b4881e810e0a4153a187966044104aed00304191764c4ab31225881cd071af3f62d7f2480758e0a5f58ba8543e316553e3acc3c7c0d50f718c7f947da8908155808f72071168a514ffc869d9e0b50044104a875847170e3542b731f8cd21f24f61573cc5b3a6af60125eb42fe11d8816e20a6972f50b7938c76ffa5f633627e0988ae881849527684b59ae13181081ab8020441042170e7a2ca8d94bb459909c79828305a6038dde10f25e5b00dac36bfda559d2027eff8df58ed8b611c493c641c97defd870c44f045ef7577990a8935276482e1304a304802010130430441047b49c8d0292dc426d2545ceb83795d94336599b8945d9d6a582a8c584b85e8c9ce665ee0917ca6e53ea7fa0028ed1e1efabe3f147e0e7062e0a09782adfced9d304a304802010130430441048aba94e2d1e56b0e34a77ea0691787ee0bfbc50f39bad959d4fa62b137c89a9744eeade7d6ce47968ee8f63f89b04805871d955308a3c134fbd70a29aaa22844",
"shaSignData": "4c73c97e194f01929e033ba196f234cf7a8539e6e6e0d5a753425e487bf8fc7a"
}
},
}

Sample External Item Signed Event Object

NOTE:

The metadata field could contain any key value pair

signature.raw is the r + s signature, digest is the data the was signed

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
{
"version": "1.0.0",
"type": "EXTERNAL_ITEM_SIGNED",
"payload": {
"requestId": "8f18b68b-eeb6-0b4c-9c93-2921b336f359",
"trustId": "00b69ce9-ab25-42ea-8217-69771e46493b",
"digest": "22800da2ef4b6304b2665e4fc3d6b7185e76691ce46f2a4d0a6eedf5968a2035",
"signature": {
"der":
"3046022100ca93732773386da574a9a74052c55fac8070178419ad6904a42652399019a2dd022100d2a9c64a738be7078a689c57421f322e177a7bc8c8f3884bd87f5d0439fec3be",
"raw":
"ca93732773386da574a9a74052c55fac8070178419ad6904a42652399019a2ddd2a9c64a738be7078a689c57421f322e177a7bc8c8f3884bd87f5d0439fec3be"
},
"wallet": {
"walletId": "90f21ca4-e1af-4212-a7bd-210b17022928"
},
"subWallet": {
"subWalletIdString": "90f21ca4-e1af-4212-a7bd-210b17022928/ETH/0"
},
"metadata": {
...
}
},
"messageId": "020752e8-92bb-e79d-2348-753bb354b9a",
"timestamp": 1622132499011,
"isoTimestamp": "2021-05-27T16:21:39.011Z"
}

Sample Delegate Signed Transaction Event Object

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
{
"version": "1.0.0",
"type": "DELEGATE_SIGNED",
"payload": {
"requestId": "961f29aa-5196-e1f7-3b3c-9f65a147e0a2",
"requestType": "ETH_TRANSACTION",
"trustId": "a9458d2b-63a2-4ef0-9b70-a0c76a2c170d",
"walletId": "ee03dd0e-c668-42d1-97df-17ff1366d758",
"subWalletId": {
"id": "ee03dd0e-c668-42d1-97df-17ff1366d758",
"type": "ETH",
"index": 0
},
"subWalletIdString": "ee03dd0e-c668-42d1-97df-17ff1366d758/ETH/0",
"assetSymbol": "ETH",
"chain": "ETHEREUM",
"publicKeys": {
"signedPublicKeys": [
"04bf5710d0edaa7eb82d22cbc681564fdd0494a8e7d77637b66575d9619862157df67b8a8a03eea5ce31e51b07e7e51281484b6ec7f49bb35e4a728555da322a27"
]
},
"policy": {
"delegateSchedules": [
[
{
"keys": [
"04bf5710d0edaa7eb82d22cbc681564fdd0494a8e7d77637b66575d9619862157df67b8a8a03eea5ce31e51b07e7e51281484b6ec7f49bb35e4a728555da322a27"
],
"quorumCount": 1
}
]
]
}
},
"messageId": "78f62e69-8ccb-4d1f-bad0-be798b56a84b",
"timestamp": 1626942773267,
"isoTimestamp": "2021-07-22T08:32:53.267Z"
}

Sample Delegate Signed Creation Event Object

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
{
"version": "1.0.0",
"type": "DELEGATE_SIGNED",
"payload": {
"requestId": "6c62fc97-6796-2b3e-fc3b-c793ce09184d",
"requestType": "CREATION",
"trustId": "fe3e95cc-5650-4918-9720-c31e732b1298",
"publicKeys": {
"signedPublicKeys": [
"046661820d3253ffb215bac4d2c11975c2f7f16c5ea7dddb53c3d17487e0ef14531da24c9b7c0551ec50e8898f7904b9a306a1aff1cfbd1e9666350317839175b2",
"0420d73a9639b8944cbf866850c729c8f1749b02b75cfcc0c30cb5175a80bfbcc868299963c4f861d33f893f0a175a20600a72861e103f9607660c60a13e38f873",
]
},
"policy": {
"delegateSchedules": [
[
{
"quorumCount": 2,
"keys": [
"046661820d3253ffb215bac4d2c11975c2f7f16c5ea7dddb53c3d17487e0ef14531da24c9b7c0551ec50e8898f7904b9a306a1aff1cfbd1e9666350317839175b2",
"0420d73a9639b8944cbf866850c729c8f1749b02b75cfcc0c30cb5175a80bfbcc868299963c4f861d33f893f0a175a20600a72861e103f9607660c60a13e38f873",
"04868307da5a195f9b3407cb396b1f597c4c28b8a67d761aec63d2b0bdac0c8a70d0d4cef9cef204c8958a62cea9b248b2158c07917464c64b00b8da7a50d8644a"
]
}
]
]
}
},
"messageId": "df5a772b-f5be-47a7-a054-4e9ec4016e6d",
"timestamp": 1626797898267,
"isoTimestamp": "2021-07-20T16:18:18.267Z"
}

Decoded Input / Logs

The variables decodedInput and decodedEvents contain the human readable decoding of the input and events variables of an Ethereum transaction. The following snippet in Typescript shows a decodedData interface that can be used to parse those two fields:

1
2
3
4
5
{
...
decodedInput: DecodedData,
dedodedEvents: DecodedData[],
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
type DecodedData = {
id: string;
signature: string;
params: SolidityType[];
};

type SolidityType = SolidityString | SolidityArray;

type SolidityString = {
name: string;
type: string;
value: string;
}

type SolidityArray = {
name: string;
type: string;
items: SolidityType[];
};

Webhook Security

Webhook notifications should be verified using the message hash signature in the header and the secret key to prevent attackers from imitating valid webhooks.

Each webhook is associated with a single secret key, which is given upon registration of the webhook. The secret key is used to generate an HMAC using SHA-256 hash algorithm.

Webhook notifications will have an X-Sha2-Signature header in the request, containing the HMAC. The secret key should be used to compute the message hash signature using the complete event object. You must ensure that the generated hash signature matches the X-Sha2-Signature header sent by TrustVault.

Verifying HMAC-256 signature

1
2
3
4
5
6
7
8
9
10
11
12
13
import * as crypto from "crypto";

// NOTE: Do not hard code your secret key. Store it somewhere safe
const secretKey = "SECRET_KEY";
const hmac = crypto.createHmac("SHA256", secretKey);

// Compute the hash from the stringified JSON request.body
const computedHashSignature = hmac.update(request.body).digest("hex");
const expectedHashSignature = request.headers["X-Sha2-Signature"];

if (computedHashSignature !== expectedHashSignature) {
throw new Error("Webhook hash signature mismatch");
}

Handle Duplicate Events

Webhook endpoints might occasionally receive the same event more than once. In particular, during chain re-organisation a webhook event could be re-sent for the exact same transaction. We advise you to guard against duplicated event receipts by making your event processing idempotent.