diff --git a/docs/guides/products/integrity/concepts/_category_.json b/docs/guides/products/integrity/concepts/_category_.json new file mode 100644 index 00000000..e985683b --- /dev/null +++ b/docs/guides/products/integrity/concepts/_category_.json @@ -0,0 +1,5 @@ +{ + "position": 2, + "label": "Concepts", + "collapsible": true +} diff --git a/docs/guides/products/integrity/concepts/anchor-entity.mdx b/docs/guides/products/integrity/concepts/anchor-entity.mdx new file mode 100644 index 00000000..5b4e1ec8 --- /dev/null +++ b/docs/guides/products/integrity/concepts/anchor-entity.mdx @@ -0,0 +1,27 @@ +--- +title: 'Anchor entity' +sidebar_position: 4 +--- + +# The anchor entity + +As described in the [Protocol Overview](./protocol.mdx#protocol-overview), we use a set of sparse Merkle trees that forms our Rollup. Once you send some data, it gets enqueued until we trigger the anchor mechanism. + +This process consists in getting all the pending data and adding them to the state tree. This will produce a state transition and the resulting root will be transacted into several blockchain networks following the time intervals described in the [Networks supported](./networks-supported.mdx#networks-supported) section. + +:::tip +As a more formal definition: An anchor is a snapshot of the state tree which is registered to the blockchain protocol. It is formed by the resulting state of the state transition. +::: + +### Anchor identifier + +We identify anchors with sequential numbers starting from 1. When you send a new data for certification, you will receive the anchor identifier in which your data will be processed, usually this is the next available one. + +### Relation of anchors with blockchain networks + +It's important to note that not all the anchors processed are transacted into all the blockchain networks supported by BLOOCK. This means that if you directly query some root of a random anchor into a network, it's possible (and common) that the result is not found. +This is because we have different transaction intervals for the different networks supported. However, we do guarantee that every anchor gets transacted to at least one network. +The integrity proof retrieval process manages this so you don't get an integrity proof that results in a root not transacted to the selected network. +For a better understanding of this topic, here's a diagram of how anchors and transactions work together: + +![5 - Integrity](/static/docs/guides/integrity/5-integrity.png) diff --git a/docs/guides/products/integrity/concepts/integrity-proof-entity.mdx b/docs/guides/products/integrity/concepts/integrity-proof-entity.mdx new file mode 100644 index 00000000..cfa1083f --- /dev/null +++ b/docs/guides/products/integrity/concepts/integrity-proof-entity.mdx @@ -0,0 +1,28 @@ +--- +title: 'Integrity proof entity' +sidebar_position: 5 +--- + +# The integrity proof entity {#integrity-proof-entity} + +Once a data submitted to BLOOCK for certification gets included in an anchor, you are able to retrieve an integrity proof for it. +This proof is computed as an optimized Merkle proof by BLOOCK representing the minimal necessary data to mathematically prove that a record was included at a certain point in time to the blockchain. The computed proof has the following properties: +Timeless, meaning that, once retrieved, those can be verified at any time in the future. + +- Proofs can be retrieved for multiple records which enables to verify the existence of a set of records at once. +- Proofs are auto verifiable by the user without the intervention of BLOOCK. + +:::tip +It's important to note that BLOOCK is not able to emit fraudulent proofs because of the cryptographic properties of the Merkle trees. +::: + +When you retrieve an integrity proof for one or more data to be able to further verify them, you will receive a set of data consisting of: + +| Field | Description | +| ------ | ------------------------------------------------------------------------------------------------------ | +| Leaves | An array of hashes that contains exactly the input data to get the integrity proof from. | +| Nodes | An array of hashes that will be combined with the leaves to run the Merkle proof verification process. | +| Bitmap | Hexadecimal value used to combine the leaves and nodes in order to correctly compute the proof. | +| Depth | Additional information needed to run the verification process. | +| Root | The anchor root that the integrity proof should resolve to when verified. | +| Anchor | Contains information related to the anchor from which the integrity proof was computed from. | diff --git a/docs/guides/products/integrity/networks-supported.mdx b/docs/guides/products/integrity/concepts/networks-supported.mdx similarity index 69% rename from docs/guides/products/integrity/networks-supported.mdx rename to docs/guides/products/integrity/concepts/networks-supported.mdx index cd8608c4..2ebfa54e 100644 --- a/docs/guides/products/integrity/networks-supported.mdx +++ b/docs/guides/products/integrity/concepts/networks-supported.mdx @@ -1,9 +1,9 @@ --- title: 'Networks supported' -sidebar_position: 3 +sidebar_position: 2 --- -# Networks supported +# Networks supported {#networks-supported} BLOOCK's protocol allows for interoperability between different blockchain networks, meaning that anchors processed by our system gets transacted in multiple chains so you are able to verify your data in any of them. @@ -16,7 +16,7 @@ This allows for different benefits for our customers such as: We transact to each network in different intervals. This is because of two reasons: the chain's block interval and the transaction cost. -## Live environment +## Networks Here is a list of blockchain we integrate with and the the approximate transaction intervals: @@ -46,13 +46,3 @@ Here is a list of blockchain we integrate with and the the approximate transacti - -## Test environment - -Our test environment is designed for development-only purposes, providing low transaction intervals to facilitate the development and integration with our SDKs. - -To do so, anchors processed in that environment are only transacted into a private EVM-compatible blockchain managed by BLOOCK called BloockChain: - -| Network | Contract address | Interval | -| ----------- | ---------------------------------------- | ---------- | -| BloockChain | d2d1BBcbee7741f8C846826F55b7c17fc5cf969a | \~1 minute | diff --git a/docs/guides/products/integrity/protocol.mdx b/docs/guides/products/integrity/concepts/protocol.mdx similarity index 94% rename from docs/guides/products/integrity/protocol.mdx rename to docs/guides/products/integrity/concepts/protocol.mdx index 5c770e70..0dbc1889 100644 --- a/docs/guides/products/integrity/protocol.mdx +++ b/docs/guides/products/integrity/concepts/protocol.mdx @@ -1,9 +1,9 @@ --- title: 'Protocol' -sidebar_position: 2 +sidebar_position: 1 --- -# Overview +# Overview {#protocol-overview} This is an overview of the BLOOCK's Protocol and its technological stack. It's objective is to provide an introduction for developers to BLOOCK's technical stack. It also offers the approach to achieve high scalability. The explanation assumes you are familiar with the Ethereum ecosystem, the basic concepts of cryptography, and structures such as hashing and Merkle trees. @@ -11,6 +11,8 @@ This is an overview of the BLOOCK's Protocol and its technological stack. It's o BLOOCK is a rollup solution that allows scaling data-tamper proofing on top of permissionless blockchain technologies. It uses blockchains for state storage but not for the computation of the aggregations, which is made internally with a specific frequency that depends on the network it is anchored to. The basic architecture of BLOOCK is simplified to ease understanding: +![3 - Integrity](/static/docs/guides/integrity/3-integrity.png) + ## Protocol BLOOCK manages an internal protocol that aggregates and consolidates messages to the L2 rollup with a certain time frequency. The messages received are queued internally between anchors in a pool of pending certificates. When the anchoring mechanism is executed, all the pending messages of the pool are included in the state chain of each client. A state chain is client independent and each client owns its chain of states. A genesis random hash forms the first block of each client state chain along with a set of certifications sent since the last confirmed anchor. From there on, the last client block root represents each block and all the certifications sent since the last confirmed anchor. Some may be wondering why is it necessary to separate each client message into independent shards. Mainly because of the following crucial points: @@ -20,3 +22,5 @@ BLOOCK manages an internal protocol that aggregates and consolidates messages to - _**Right to be forgotten:**_ Any client in need to remove all certifications from BLOOCK State will be allowed to do so. BLOOCK will just keep the root of each of its blocks in the Rollup, which indeed has 0 links to the certifications sent thanks to the first block genesis hash. Once all client messages have been included in their respective state chains, the root of each new block created is appended to the BLOOCK Rollup stored by an only-append binary sparse Merkle tree. Once this action is finalized, we can conclude that all pending messages have been incorporated into the state of BLOOCK. Since we have a single shared state tree, BLOOCK can provide proofs that concatenate multiple certificates efficiently. + +![4 - Integrity](/static/docs/guides/integrity/4-integrity.png) diff --git a/docs/guides/products/integrity/concepts/record-entity.mdx b/docs/guides/products/integrity/concepts/record-entity.mdx new file mode 100644 index 00000000..e238dd40 --- /dev/null +++ b/docs/guides/products/integrity/concepts/record-entity.mdx @@ -0,0 +1,63 @@ +--- +title: 'Record entity' +sidebar_position: 3 +--- + +# The Record entity + +The principal element of the BLOOCK SDKs is the Record as it's used on most of the functionalities. It's responsible for different interactions such as: + +- Encapsulate your data +- Hashing +- Add [digital signatures](./../../key/overview.mdx#what-digital-signature) +- Add [encryption](./../../key/concepts/operations.mdx#operations) +- Add self-contained metadata + +### Record builders + +In order to generate a Record, our SDKs provide different builders to do so. Those builders enable to set as input different data types, formats or encodings based on your needs. + +#### Available builders + +Currently, the following builders are available: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameDescription
fromStringIt takes a UTF-8 string as input
fromBytesIt takes an array of bytes as input
fromHex + It takes a hash string (hex encoded 64-chars long string) as input +
fromJsonIt takes a JSON as input
fromRecordIt takes a record as input
fromFileIt takes a file (as a byte array) as input
fromLoaderIt takes a Loader as input
diff --git a/docs/guides/products/integrity/features/_category_.json b/docs/guides/products/integrity/features/_category_.json index 3c02b759..310a41b4 100644 --- a/docs/guides/products/integrity/features/_category_.json +++ b/docs/guides/products/integrity/features/_category_.json @@ -1,5 +1,5 @@ { - "position": 4, + "position": 3, "label": "Features", "collapsible": true } diff --git a/docs/guides/products/integrity/features/prepare-data.mdx b/docs/guides/products/integrity/features/prepare-data.mdx index 7f98724d..484d7b72 100644 --- a/docs/guides/products/integrity/features/prepare-data.mdx +++ b/docs/guides/products/integrity/features/prepare-data.mdx @@ -3,77 +3,12 @@ title: 'Prepare data' sidebar_position: 1 --- -# Prepare data +# Prepare data {#prepare-data} The first step of the certification process is to prepare the data that you want to certify through BLOOCK. This basically translates to load this data to the SDK, standardize it and compute a hash using the algorithm that BLOOCK uses internally (Keccak256). Luckily, all this process is done by the SDK internally so all you need to do is -## The Record entity - -The principal element of the BLOOCK SDKs is the Record as it's used on most of the functionalities. It's responsible for different interactions such as: - -- Encapsulate your data -- Hashing -- Add [digital signatures](broken-reference) -- Add [encryption](broken-reference) -- Add self-contained metadata - -### Record builders - -In order to generate a Record, our SDKs provide different builders to do so. Those builders enable to set as input different data types, formats or encodings based on your needs. - -#### Available builders - -Currently, the following builders are available: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameDescription
fromStringIt takes a UTF-8 string as input
fromBytesIt takes an array of bytes as input
fromHex - It takes a hash string (hex encoded 64-chars long string) as input -
fromJsonIt takes a JSON as input
fromRecordIt takes a record as input
fromFileIt takes a file (as a byte array) as input
fromLoader - It takes a Loader as input (for more information check{' '} - - Broken link - - ) -
- ## Examples import SdkCodeBlock from '/docs/partials/_sdk-code-block.mdx'; diff --git a/docs/guides/products/integrity/features/send-data.mdx b/docs/guides/products/integrity/features/send-data.mdx index 3121f6da..da4ab7a9 100644 --- a/docs/guides/products/integrity/features/send-data.mdx +++ b/docs/guides/products/integrity/features/send-data.mdx @@ -5,12 +5,12 @@ sidebar_position: 2 # Send data -Once you have your [data prepared](prepare-data.md), you can send it to BLOOCK so it can be certified using our protocol. +Once you have your [data prepared](./prepare-data.mdx#prepare-data), you can send it to BLOOCK so it can be certified using our protocol. When you send a new record to BLOOCK, it's queued internally and assigned to an Anchor. Once this Anchor is processed and transacted into the blockchain, the record gets certified and you will be able to verify it. :::tip -The certification of a record may take some time to be confirmed. In order to manage this time interval, see [Synchronization](synchronization.mdx). +The certification of a record may take some time to be confirmed. In order to manage this time interval, see [Synchronization](./synchronization.mdx#synchronization). ::: ## Examples diff --git a/docs/guides/products/integrity/features/synchronization.mdx b/docs/guides/products/integrity/features/synchronization.mdx index 3ff32bb4..3afe3958 100644 --- a/docs/guides/products/integrity/features/synchronization.mdx +++ b/docs/guides/products/integrity/features/synchronization.mdx @@ -3,7 +3,7 @@ title: 'Synchronization' sidebar_position: 3 --- -# Synchronization +# Synchronization {#synchronization} Once a data is sent for certification to BLOOCK, there's a time interval until it gets processed and transacted to the different blockchain networks. This time interval can be variable and, in some networks, pretty long, @@ -43,7 +43,7 @@ Once a webhook is configured and a new anchor is processed for one of the select ## Synchronous :::tip -`It's recommended to only use this method for networks with low internal times (<3 minutes)` +It's recommended to only use this method for networks with low internal times (<3 minutes) ::: It's also possible to wait for the interval in a synchronous manner by using our SDKs directly. This allows to keep a single code snippet that handles all the certification flow. diff --git a/docs/guides/products/integrity/features/verification.mdx b/docs/guides/products/integrity/features/verification.mdx index b694d27a..cb7bc37f 100644 --- a/docs/guides/products/integrity/features/verification.mdx +++ b/docs/guides/products/integrity/features/verification.mdx @@ -48,7 +48,7 @@ An integrity proof is a set of data computed by BLOOCK based on one (or more) Re Once an Integrity proof is computed it's valid over time. You can store it internally and use it for later verification to ensure full independence from our service from this point. :::tip -You will not be able to verify a Record that is not fully processed and transacted to Blockchain. See [Syncronization](synchronization.md) for information about how to manage it. +You will not be able to verify a Record that is not fully processed and transacted to Blockchain. See [Syncronization](./synchronization.mdx#syncronization) for information about how to manage it. ::: Our SDKs allow to easily retrieve this integrity proof. Here are some code examples of how to implement it: @@ -72,7 +72,7 @@ import GetProofGo from '!!raw-loader!@site/examples/integrity/get_proof/get_proo The next step in the verification process is to verify the integrity proof retrieved in the previous step. This is made by locally computing the result of the proof, which is the value (root) that, at some point of time, got transacted into blockchain. :::tip -For more detail about this process, you can see the [Protocol](broken-reference) section. +For more detail about this process, you can see the [Protocol](./../concepts/protocol.mdx#protocol-overview) section. ::: All this process is managed by our SDKs and can be implemented as follows: @@ -91,17 +91,9 @@ import VerifyProofGo from '!!raw-loader!@site/examples/integrity/verify_proof/ve go={VerifyProofGo} /> -### Validate digital signatures - -:::tip -This step is only needed if a digital signature is detected in the Record's metadata. See the [Digital signature](broken-reference) section for more detail. -::: - -This step is used to verify the authenticity of the Records (---) - ### Validate in blockchain -The last step of the verification process is to check if the output of the [Verify integrity proof](verification.md#verify-the-integrity-proof) step is actually in the selected blockchain network. +The last step of the verification process is to check if the output of the [Verify integrity proof](./../concepts/integrity-proof-entity.mdx#integrity-proof-entity) step is actually in the selected blockchain network. This is made by querying the obtained root on the BLOOCK's Smart Contract deployed on each network available. The result of this query is a timestamp (specifically the block time) when this root was transacted into the network. diff --git a/docs/guides/products/integrity/overview.mdx b/docs/guides/products/integrity/overview.mdx index a4d07cba..45f7d385 100644 --- a/docs/guides/products/integrity/overview.mdx +++ b/docs/guides/products/integrity/overview.mdx @@ -3,22 +3,34 @@ title: 'Overview' sidebar_position: 1 --- -This section provides all the information needed to understand and integrate with BLOOCK's data certification service based on permissionless blockchains. +BLOOCK's digital notarization service provides users with a secure and efficient means to notarize their information by sealing it to decentralized ledgers. Through this process, BLOOCK ensures the integrity, irrefutable timestamping, and verifiability of data across platforms. -# Certification flow +#### Key Features: -In order to certify some data with BLOOCK, there are some steps that are happening, some of them need to be implemented by you (using our SDKs) and others are done by BLOOCK itself. +1. **Seal to Decentralized Ledgers**: Notarize your information by securely sealing it to decentralized ledgers, guaranteeing its authenticity and immutability. +2. **Scalability**: Scale up on-demand without the hassle of distributed ledger throughput constraints, allowing users to notarize large volumes of data seamlessly. +3. **Accuracy**: Ensure the accuracy of your information without any limitations, with BLOOCK's system automatically normalizing and standardizing data to meet universal standards. +4. **Cost-Efficiency**: Significantly diminish decentralized network costs, volatility, and uncertainties while remaining aligned with core principles, enabling cost-effective notarization solutions. +5. **Universal Notarization**: Digitally notarize any type of information, regardless of its nature, with BLOOCK's system accommodating diverse data formats and ensuring compliance with universal standards. -As a summary, you will need to implement only two parts: +## The basics -1. Prepare data +### Certification flow + +To certify data with BLOOCK, the process involves several steps, some of which require implementation on your end using our SDKs, while others are handled by BLOOCK itself. Below is a summary of the certification flow: + +1. Prepare data: 2. Send data 3. Synchronization -If you want more detail about the process, here's a diagram of all the certification process: +Here's a diagram of the certification process: + +![1 - Integrity](/static/docs/guides/integrity/1-integrity.png) + +### Validation flow -# Validation flow +For the validation flow, verifying the authenticity and integrity of certified data involves a series of steps. These steps are detailed in the verification section of our documentation and can be implemented using examples provided. Additionally, we offer ready-to-use tools in the Validators section for those who prefer a more streamlined approach. -For the verification flow, there are also some steps that need to be followed to implement it. It's all described with examples in the verification section and if you want some ready-to-use tools, see the Validators section for some options. +Here's a diagram of the verification process: -If you want more detail about the process, here's a diagram of all the verification process: +![2 - Integrity](/static/docs/guides/integrity/2-integrity.png) diff --git a/docs/guides/webhooks/concepts/_category_.json b/docs/guides/webhooks/concepts/_category_.json new file mode 100644 index 00000000..e985683b --- /dev/null +++ b/docs/guides/webhooks/concepts/_category_.json @@ -0,0 +1,5 @@ +{ + "position": 2, + "label": "Concepts", + "collapsible": true +} diff --git a/docs/guides/webhooks/concepts/event-types.mdx b/docs/guides/webhooks/concepts/event-types.mdx new file mode 100644 index 00000000..e697f8d7 --- /dev/null +++ b/docs/guides/webhooks/concepts/event-types.mdx @@ -0,0 +1,98 @@ +--- +title: 'Event types' +sidebar_position: 1 +--- + +# Event types {#event-types} + +:::tip +It is important to note that you can configure as many events as you wish in the same webhook endpoint. +::: + +### Digital notaritzation + +#### Record entity + +1. **Ethereum Mainnet**: you will receive every time your record it's transacted and confirmed on Ethereum. +2. **Gnosis Chain**: you will receive every time your record it's transacted and confirmed on Gnosis Chain. +3. **Polygon PoS**: you will receive every time your record it's transacted and confirmed on Polygon PoS. + +**Body**: + +```json +{ + "anchor_id": 910150, + "client_id": "5aa90030-f3b2-4122-b8e9-f7f6cf91ec53", + "created_at": 1710418514, + "event_type": "integrity.record.gnosis_chain.confirmed", + "networks": [ + { + "anchor_id": 910150, + "created_at": 1710418583, + "name": "gnosis_chain", + "status": "Confirmed", + "test": false, + "tx_hash": "0x87a27e5d618bec4024d55ddf43927158f0666cf3df8ff87bfe63d89744867f15" + } + ], + "record": "001886f291d6c68bef7803d0a1c96d081376f852543967e06da2c4cb5c3cf63d", + "test": false +} +``` + +#### Anchor entity + +1. **Ethereum Mainnet**: you will receive every time an anchor it's transacted and confirmed on Ethereum. +2. **Gnosis Chain**: you will receive every time an anchor it's transacted and confirmed on Gnosis Chain. +3. **Polygon PoS**: you will receive every time an anchor it's transacted and confirmed on Polygon PoS. + +**Body**: + +```json +{ + "webhook_id": "7518043d-4774-4305-b5c9-3868e129123a", + "request_id": "fe0c1d29-8b7f-11ed-85ce-0242ac190005", + "type": "core.bloock_chain", + "created_at": 1672761735, + "data": { + "created_at": 1672735289, + "finalized": true, + "id": 102217, + "message_count": 1, + "network": { + "anchor_id": 102217, + "created_at": 1672735355, + "name": "bloock_chain", + "status": "Confirmed", + "test": false, + "tx_hash": "0x7ca9e361c9a7b4fbf4b3c2ac709d06fa8ae9e0acd648dc3a364bf9d29a39e18a" + }, + "root": "b068d911852f369cd09f4ebb1bb8c037cd9f28852976934fdb4358945759ad7c", + "test": false + } +} +``` + +Here you have some differences between the record and anchor events: + +| Aspect | Anchor Webhook Event | Record Webhook Event | +| ------------------------- | ----------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ | +| Event Triggered | Triggered when an anchor is transacted on the selected network. | Triggered when a record is transacted and confirmed on the network. | +| Frequency of Events | Occurs with every anchor transacted on the selected network. | Occurs with your records transacted and confirmed. | +| Information Received | Provides information about the anchor and networks. | Provides information about the record transaction and networks. | +| Use Case | Useful for tracking the status of anchor transactions. | Useful for tracking the status of record transactions. | +| Verification Process | Requires comparison between sent and received anchors to verify transaction status. | No additional comparison needed, as it directly indicates record transaction status. | +| Implementation Complexity | May require additional logic for comparing anchors. | Straightforward, as it directly indicates record transaction status. | + +### Identity + +1. **SMTP proof**: you will receive every time your issuer state is transacted on Polygon PoS. + +**Body**: + +```json +{ + "credential_id": "9032be8d-4df6-4869-a232-c609d9635f62", + "proof": "eyJ0eXBlIjoiSWRlbjNTcGFyc2VNZXJrbGVUcmVlUHJvb2YiLCJpc3N1ZXJEYXRhIjp7ImlkIjoiZGlkOnBvbHlnb25pZDpwb2x5Z29uOm1haW46MnE5YTZCWVg1MUNMU2REamZxNkJzQlVEZmFHN1Nva2ltZ3lEWnVQTjdHIiwic3RhdGUiOnsidHhJZCI6IjB4NDZlODdmNWFmMWQ3NTNkMDA4YjVmYjQ4ZmVmMTA1NTcyMDNhYzUzODViYzAwOTZmNjBkNGExMDA3NmM2YWYxNCIsImJsb2NrVGltZXN0YW1wIjoxNzEwMTQ2MDU5LCJibG9ja051bWJlciI6NTQ1MjM4NjksInJvb3RPZlJvb3RzIjoiOTdjNGM3YmNlZWU3Njg3NjU0MGY0MDEwYTVlZDBjZThhYWJhM2VkNmE5OTg5NDY5OWRhZTliZmIzN2ZkMDMxMSIsImNsYWltc1RyZWVSb290IjoiYTY1NTA3NmRjZDU1NzBjMzE2YzAxODc2OTBhZmMzYTM0NWExNWVhYTNlYmMyNzE5N2EwNzU4YTQ5MjY1ZTMxMSIsInJldm9jYXRpb25UcmVlUm9vdCI6IjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAiLCJ2YWx1ZSI6ImIzYjY0MGMyZDFlNzYxMzgwOTljM2Y0ODg2NTI4ZGRlNTY2ZGM1MGE4ZjNlZWYwZjU1MDcwYTI1YzdmYjU5MWQifX0sImNvcmVDbGFpbSI6Ijg3NmFjMmZhMzQwMjE0OTkyNmFjM2QyM2Y1Zjk0ZWQ5MmEwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMjExYmJjZmJkYmNiMDhlMWZkNmNhMTNhYTNjOWVjMjQxM2M5ZTBmYWQ3YjNhODI2ZDkzNmEyMjA4MGUwZDAwNjdlMjBiN2M4NTBkYWRmMDc3YjFjZGQ0NzUyMDdhOGU3ZWE5ODY1Y2M3NDk4YWVjMGVjMjEyNzhkNzY5ZmIxMTAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDA5YjdjMGU1ZDAwMDAwMDAwZTZjYzZiNjcwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwIiwibXRwIjp7ImV4aXN0ZW5jZSI6dHJ1ZSwic2libGluZ3MiOlsiMTExNDQ0MjE5NTIzMjkwNzQ1MTMxNzgwNjczNTQ4Mjk5MTU5MjExNjAxNzkzNzIyMzY4MjgwMTgwMTM2MjIyNTE5MjE0OTA4NzU5MzUiLCIxOTgyNDI4OTk3NjY3Mjk0OTM4NDMxNDIzMjY5MDg2MTcyNzU3MDc4ODkzNjc2NzM2MTc5NDk2MTY2OTgxOTAzNjgzNDI5NjI2NTkzNiIsIjE0MDAzNTE1Mjg3MDY3NTA3NzYxNTgyODA0NTM3MTk1NzU3MjQ2MTEyNTEzNTY3NjA5MDc0MzAxMzMxNDIzODg0NjQ5MDU5MDk5MjUyIiwiOTQxNzE4NjEwNTYwODcwNjc3NjU1NzczMjI1MzU0MzY4MDkxNzA1NDIxMDczNjgxNjMwMjMxNDg5NjY1MDc4MjUwNDQzOTI1MjY2MSIsIjE5NzYzOTg5NjgxNjUxNTMwNjcxMTczODUzNTU4MzM3NjIyMzAwMzI3OTkxNTQ2MDM2MjYyNTQ3NTczNDY1MTc4ODcxMDU1MDcwMTM3Il19fQ==" +} +``` diff --git a/docs/guides/webhooks/features/_category_.json b/docs/guides/webhooks/features/_category_.json new file mode 100644 index 00000000..310a41b4 --- /dev/null +++ b/docs/guides/webhooks/features/_category_.json @@ -0,0 +1,5 @@ +{ + "position": 3, + "label": "Features", + "collapsible": true +} diff --git a/docs/guides/webhooks/configure.mdx b/docs/guides/webhooks/features/configure.mdx similarity index 68% rename from docs/guides/webhooks/configure.mdx rename to docs/guides/webhooks/features/configure.mdx index 4961ffe6..e5758965 100644 --- a/docs/guides/webhooks/configure.mdx +++ b/docs/guides/webhooks/features/configure.mdx @@ -1,6 +1,6 @@ --- title: 'Configure Webhooks' -sidebar_position: 2 +sidebar_position: 1 --- # Configure Webhooks @@ -38,52 +38,17 @@ In this example, the /bloock_ethereum_mainnet route is configured to accept only The following information must be provided: - **URL**: https://your.apidomain.com/endpoint/bloock_ethereum_mainnet -- **Event Listening**: You must select the type of network you want to listen to. For example, if I subscribe to core.ethereum_mainnet webhook, every time a new anchor is confirmed on this network, will fire an event. It's important to differentiate between the core and core-test prefix. The first indicates we are listening a production environment event and the second reference to a test environment event. +- **Event Listening**: You must select the type of event you want to listen ![3 - Configure webhooks](/static/docs/guides/webhooks/configure/3-configure.png) Once all the information required is filed in, click on Create button. -**Check webhook structure** - -It is important that you know the request's structure that we send to your API endpoint. Each event is structured with a webhoook_id, request_id, type, created_at and related Bloock resource nested under data. Your endpoint must parse the payload of each event. - -- **Header**: data (timestamp) and signature (HMAC SHA256). - -`t=1672761735,v1=8071c487388bd9eba106fccd42e2842c58000f722f9147b6d27440a4bd9bf5c4` - -- **Payload** - -```json -{ - "webhook_id": "7518043d-4774-4305-b5c9-3868e129123a", - "request_id": "fe0c1d29-8b7f-11ed-85ce-0242ac190005", - "type": "core.bloock_chain", - "created_at": 1672761735, - "data": { - "created_at": 1672735289, - "finalized": true, - "id": 102217, - "message_count": 1, - "network": { - "anchor_id": 102217, - "created_at": 1672735355, - "name": "bloock_chain", - "status": "Confirmed", - "test": false, - "tx_hash": "0x7ca9e361c9a7b4fbf4b3c2ac709d06fa8ae9e0acd648dc3a364bf9d29a39e18a" - }, - "root": "b068d911852f369cd09f4ebb1bb8c037cd9f28852976934fdb4358945759ad7c", - "test": false - } -} -``` - **Return a 2xx response** Your endpoint must quickly return a successful status code (2xx) prior to any complex logic that could cause a timeout. -Use [webhook signatures](/guides/webhooks/verify) to verify that Bloock generated a webhook request and that it didn't come from a server acting like Bloock. +Use [webhook signatures](./verify.mdx#webhook-signatures) to verify that Bloock generated a webhook request and that it didn't come from a server acting like Bloock. ## 5. Watch your webhook list @@ -101,7 +66,7 @@ To check for your webhook information, click the See details button. ![5 - Configure webhooks](/static/docs/guides/webhooks/configure/5-configure.png) -In this section, you'll see the URL, Status and the Signing Secret. The Signing Secret is what will help you validate the [HMAC SHA256 signature](/guides/webhooks/verify) which is used to verify all the webhook requests provided from [BLOOCK](https://dashboard.bloock.com). +In this section, you'll see the URL, Status and the Signing Secret. The Signing Secret is what will help you validate the HMAC SHA256 signature which is used to verify all the webhook requests provided from BLOOCK. ![6 - Configure webhooks](/static/docs/guides/webhooks/configure/6-configure.png) diff --git a/docs/guides/webhooks/features/verify.mdx b/docs/guides/webhooks/features/verify.mdx new file mode 100644 index 00000000..357d1fdc --- /dev/null +++ b/docs/guides/webhooks/features/verify.mdx @@ -0,0 +1,39 @@ +--- +title: 'Check the webhook signature' +sidebar_position: 3 +--- + +import SdkCodeBlock from '/docs/partials/_sdk-code-block.mdx'; +import CodeBlock from '@theme/CodeBlock'; + +# Check the webhook signatures {#webhook-signatures} + +Verify the events that BLOOCK sends to your webhook endpoints. + +BLOOCK signs the webhook events it sends to your endpoints by including a signature in each event's `Bloock-Signature` header. This allows you to verify that the events were sent by BLOOCK, not by a third party. + +Before you can verify signatures, you need to retrieve your endpoint's signing secret from your Dashboard's Webhook's settings. Select an endpoint that you want to obtain the secret for, then click the Click to reveal button. + +![1 - Verify webhooks](/static/docs/guides/webhooks/verify/1-verify.png) + +BLOOCK generates a unique secret key for each endpoint. If you use multiple endpoints, you must obtain a secret for each one you want to verify signatures on. After this setup, Bloock starts to sign each webhook it sends to the endpoint. + +**Preventing replay attacks** + +A replay attack is when an attacker intercepts a valid payload and its signature, then re-transmits them. To mitigate such attacks, BLOOCK includes a timestamp in the `Bloock-Signature` header. Because this timestamp is part of the signed payload, it is also verified by the signature, so an attacker can't change the timestamp without invalidating the signature. If the signature is valid but the timestamp is too old, you can have your application reject the payload. + +BLOOCK defines a default tolerance of ten minutes between the timestamp and the current time. You can enable and disable the tolerance control and change this tolerance by changing the number of minutes when verifying signatures. + +## Verifying signatures using our SDK library + +Use our SDK to verify signatures. You perform the verification by providing the event payload, the `Bloock-Signature` header, and the endpoint's secret. If verification fails, Bloock returns an error and a false boolean. Remember to import our SDK first. + +:::warning +Bloock requires the raw body of the request to perform signature verification. If you're using a framework, make sure it doesn't manipulate the raw body. Any manipulation to the raw body of the request causes the verification to fail. +::: + +import VerifyWebhookJs from '!!raw-loader!@site/examples/webhooks/verify-sdk/verify-sdk.ts'; +import VerifyWebhookPy from '!!raw-loader!@site/examples/webhooks/verify-sdk/verify-sdk.py'; +import VerifyWebhookGo from '!!raw-loader!@site/examples/webhooks/verify-sdk/verify-sdk.go'; + + diff --git a/docs/guides/webhooks/overview.mdx b/docs/guides/webhooks/overview.mdx index 5ff152f2..f085f478 100644 --- a/docs/guides/webhooks/overview.mdx +++ b/docs/guides/webhooks/overview.mdx @@ -3,10 +3,10 @@ title: 'Overview' sidebar_position: 1 --- -# Overview +# Receive BLOOCK events -Listen for events on your Bloock integration so you can automatically trigger reactions. +Listen for events on your BLOOCK integration so you can automatically trigger reactions. First, we should understand what is a webhook. A webhook is an HTTP request, triggered by an event in the source system and then, sent to the destination system. Webhooks are automatically sent out when their event is fired in the source system. -BLOOCK uses webhooks to notify your application when an event happens in the source system. Webhooks are particularly useful for asynchronous events like when we want to wait for an anchor confirmed. When the users send a record to Bloock, internally, it is processed and included in an anchor. Normally, once the user sends their record to the blockchain, they will go through a long process of polling, or waiting for the anchor confirmation before knowing whether their record was successfully sent. In order to avoid this issue, users can now subscribe to our waiting_anchor webhook and provide us the URL they want to be notified. +BLOOCK uses webhooks to notify your application when an event occurs in the source system. Webhooks are particularly useful for asynchronous events such as when we want to wait for a record to be confirmed. When users submit a record to BLOOCK, internally, it is processed and included in an anchor. Normally, once a user submits their record to the blockchain, they will go through a long process of polling, or waiting for anchor confirmation before they know if their record was successfully submitted. To avoid this problem, users can now subscribe to our events and provide us with the URL they want to be notified. diff --git a/docs/guides/webhooks/verify.mdx b/docs/guides/webhooks/verify.mdx deleted file mode 100644 index b60021c7..00000000 --- a/docs/guides/webhooks/verify.mdx +++ /dev/null @@ -1,73 +0,0 @@ ---- -title: 'Check the webhook signature' -sidebar_position: 3 ---- - -import SdkCodeBlock from '/docs/partials/_sdk-code-block.mdx'; -import CodeBlock from '@theme/CodeBlock'; - -# Check the webhook signatures - -Verify the events that Bloock sends to your webhook endpoints. - -Bloock signs the webhook events it sends to your endpoints by including a signature in each event's Bloock-Signature header. This allows you to verify that the events were sent by Bloock, not by a third party. - -Before you can verify signatures, you need to retrieve your endpoint's signing secret from your Dashboard's Webhook's settings. Select an endpoint that you want to obtain the secret for, then click the Click to reveal button. - -![1 - Verify webhooks](/static/docs/guides/webhooks/verify/1-verify.png) - -Bloock generates a unique secret key for each endpoint. If you use multiple endpoints, you must obtain a secret for each one you want to verify signatures on. After this setup, Bloock starts to sign each webhook it sends to the endpoint. - -**Preventing replay attacks** - -A replay attack is when an attacker intercepts a valid payload and its signature, then re-transmits them. To mitigate such attacks, Bloock includes a timestamp in the Bloock-Signature header. Because this timestamp is part of the signed payload, it is also verified by the signature, so an attacker can't change the timestamp without invalidating the signature. If the signature is valid but the timestamp is too old, you can have your application reject the payload. - -Bloock defines a default tolerance of ten minutes between the timestamp and the current time. You can enable and disable the tolerance control and change this tolerance by changing the number of minutes when verifying signatures. - -## Verifying signatures using our SDK library - -Use our SDK to verify signatures. You perform the verification by providing the event payload, the Bloock-Signature header, and the endpoint's secret. If verification fails, Bloock returns an error and a false boolean. Remember to import our SDK first. - -:::warning -Bloock requires the raw body of the request to perform signature verification. If you're using a framework, make sure it doesn't manipulate the raw body. Any manipulation to the raw body of the request causes the verification to fail. -::: - -import VerifyWebhookJs from '!!raw-loader!@site/examples/webhooks/verify-sdk/verify-sdk.ts'; -import VerifyWebhookPy from '!!raw-loader!@site/examples/webhooks/verify-sdk/verify-sdk.py'; -import VerifyWebhookGo from '!!raw-loader!@site/examples/webhooks/verify-sdk/verify-sdk.go'; - - - -## Verifying signatures manually - -The Bloock-Signature header included in each signed event contains a timestamp and one signature. The timestamp is prefixed by t=, signature is prefixed by v1=. - -``` -Bloock-Signature: -t=1492774577, -v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd -``` - -Bloock generates signatures using a hash-based message authentication code ([HMAC](https://es.wikipedia.org/wiki/HMAC)) with [SHA-256](https://es.wikipedia.org/wiki/SHA-2). - -This code shows how to verify your webhook events signatures manually. - -import VerifyManualGo from '!!raw-loader!@site/examples/webhooks/verify-manual/verify-manual.go'; - - - {VerifyManualGo} - - -**Step 1: Extract the timestamp and signatures from the header** - -Split the header, using the , character as the separator, to get a list of elements. Then split each element, using the = character as the separator, to get a prefix and value pair. - -The value for the prefix t corresponds to the timestamp, and v1 corresponds to the signature. - -**Step 2: Determine the expected signature** - -Compute an HMAC with the SHA256 hash function. Use the endpoint's signing secret as the key, and use the concatenation of the timestamp with the payload. - -**Step 3: Compare the signatures** - -Compare the signature in the header to the expected signature. For an equality match, compute the difference between the current timestamp and the received timestamp, then decide if the difference is within your tolerance. diff --git a/static/static/docs/guides/integrity/1-integrity.png b/static/static/docs/guides/integrity/1-integrity.png new file mode 100644 index 00000000..7e727ac1 Binary files /dev/null and b/static/static/docs/guides/integrity/1-integrity.png differ diff --git a/static/static/docs/guides/integrity/2-integrity.png b/static/static/docs/guides/integrity/2-integrity.png new file mode 100644 index 00000000..59277d70 Binary files /dev/null and b/static/static/docs/guides/integrity/2-integrity.png differ diff --git a/static/static/docs/guides/integrity/3-integrity.png b/static/static/docs/guides/integrity/3-integrity.png new file mode 100644 index 00000000..c7cd27cd Binary files /dev/null and b/static/static/docs/guides/integrity/3-integrity.png differ diff --git a/static/static/docs/guides/integrity/4-integrity.png b/static/static/docs/guides/integrity/4-integrity.png new file mode 100644 index 00000000..2602729e Binary files /dev/null and b/static/static/docs/guides/integrity/4-integrity.png differ diff --git a/static/static/docs/guides/integrity/5-integrity.png b/static/static/docs/guides/integrity/5-integrity.png new file mode 100644 index 00000000..1f895a57 Binary files /dev/null and b/static/static/docs/guides/integrity/5-integrity.png differ diff --git a/static/static/docs/guides/webhooks/configure/3-configure.png b/static/static/docs/guides/webhooks/configure/3-configure.png index 6ec3b641..d1007e0d 100644 Binary files a/static/static/docs/guides/webhooks/configure/3-configure.png and b/static/static/docs/guides/webhooks/configure/3-configure.png differ diff --git a/static/static/docs/guides/webhooks/configure/4-configure.png b/static/static/docs/guides/webhooks/configure/4-configure.png index d1be7da4..639ee89c 100644 Binary files a/static/static/docs/guides/webhooks/configure/4-configure.png and b/static/static/docs/guides/webhooks/configure/4-configure.png differ