Introduction
Sandbox Base URL
https://sandbox.hydrogenplatform.com/hydro/v1
Production Base URL
https://api.hydrogenplatform.com/hydro/v1
Hydro is an open source blockchain protocol incubated by Hydrogen. Hydro enables private financial systems to seamlessly leverage the public blockchain. Cloud applications throughout the financial services ecosystem can now benefit from the power of smart contracts, creating more secure, transparent, and low cost financial products globally.
The Hydro API enables applications to interface with Hydro’s smart contracts. All Hydrogen APIs are built on REST principles, with resource oriented URLs and HTTP response codes. All API responses are returned in JSON format.
The Hydrogen 2FA App is built on Hydro Raindrop, which provides security through blockchain-based authentication. It offers a server-side authentication protocol for databases, APIs, and large systems, as well as a client-side multi-factor authentication protocol for individual user accounts.
Resources
Hydrogen 2FA App
Open Source Hydro Project
Authentication
All Atom APIs use the same authentication and authorization. Please refer to the Nucleus API for detailed documentation.
Environments
Sandbox Base URL
https://sandbox.hydrogenplatform.com/hydro/v1
Production Base URL
https://api.hydrogenplatform.com/hydro/v1
The Hydro API has two environments: Hydro Sandbox and Hydro Production. You will be given separate API credentials for each environment.
In Sandbox, you will be interacting with Hydro smart contracts on the Rinkeby Ethereum Testnet. We strongly advise that you test out your application using the Sandbox API first, as you don’t need to use real Hydro tokens to do so. If your testing requires use of the Hydro mobile app, you will need access to our Beta version of the app for either iOS or Android. Please contact us if you would like to request access to a Beta version of the app.
Once you are done testing, you can switch over to the Production API, which interfaces with Hydro smart contracts on the Ethereum Mainnet.
Developer Tools
npm install -S @hydrogenplatform/raindrop
pip install raindrop
For our first release, Raindrop, we’ve created open-source SDKs in Javascript and Python to empower developers building applications on top of Hydro. These SDKs are the recommended way to interact with Raindrop. The sample Javascript and Python code in the sidebar will be from these SDKs.
Errors
ERROR CODES
Code | Description |
---|---|
400 |
Bad Request |
401 |
Unauthorized. Occurs when you are using an invalid or expired access token |
404 |
Not Found. Occurs when you are requesting a resource which doesn’t exist, such as an incorrect URL or ID |
405 |
Method Not Allowed. Occurs when you use a method not supported such as a GET on a POST |
415 |
Unsupported Media Type. Content-Type must be passed as application/json and not form-data |
500 |
Internal Server Error |
503 |
Service Unavailable. If the API is down for maintenance you will see this error |
STATUS CODES
Code | Description |
---|---|
200 |
Ok. The request was successful. |
201 |
Created. The request resulted in the successful creation of a resource. |
204 |
No Content. The request was successful but there is no additional content to send in the response body. This will occur on a successful DELETE. |
Versioning
The Hydro API is currently in major version 1.0
. All features which are not backwards compatible will be pushed as a major version release. Features that we consider to be backwards compatible include the following:
- Adding new API resources
- Adding new optional request parameters to existing API methods
- Adding new fields to existing API responses
- Changing the order of fields in existing API responses
- Changing the length or format of objects
Transactions
Example Request
curl -X GET -H "Authorization: Bearer <access_token>" \
"https://[sandbox][api].hydrogenplatform.com/hydro/v1/transaction?transaction_hash=0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060"
transactionHash = "0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060"
RaindropPartnerObject.transactionStatus(transactionHash)
Example Response
{
"transaction_hash": "0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060",
"completed": true
}
Certain methods in the Hydro API trigger transactions on the Ethereum blockchain. Transactions take time to be confirmed, so rather than waiting for confirmation, these methods will return a transaction_hash
as soon as our internal logic has completed successfully and the appropriate transaction has been broadcast to the Ethereum network. Since some methods in the Hydro API will be contingent on confirmation of transactions on the Ethereum blockchain, you will occasionally need to check for confirmation prior to calling an endpoint. Whenever necessary, this will be explicitly stated within our documentation. In general, transactions on the Ethereum network take about 20 seconds to clear; however, this may vary depending on network activity.
Whenever a method returns a transaction_hash
you can check the confirmation status of the corresponding transaction with a GET /transaction
.
HTTP REQUEST
GET /transaction?transaction_hash={transaction_hash}
ARGUMENTS
Parameter | Data Type | Parameter Type | Description |
---|---|---|---|
transaction_hash |
string | query string | The transaction hash |
RESPONSE
Field | Type | Description |
---|---|---|
transaction_hash |
string | The transaction hash |
completed |
boolean | Indication of whether the transaction has been confirmed |
Raindrop
Raindrop is Hydro’s security protocol. Raindrop consists of two implementations: Server-side and Client-side.
These implementations may be used in conjunction, or independently, according to a company’s needs. For instance, a company may use Server-side Raindrop to secure its private databases, while using Client-side Raindrop for users to secure their accounts.
Resources
Raindrop White Paper
Server-side Raindrop Video Tutorial
Client-side Raindrop Mobile App
Client-side Raindrop UI Tools
Client-side Raindrop Implementation Guide
Libraries
Javascript
Python
PHP
Java
Server-side
SDK Initialization
const raindrop = require("@hydrogenplatform/raindrop")
new raindrop.server.RaindropPartner({
environment: "Sandbox",
clientId: "yourId",
clientSecret: "yourSecret"
})
import raindrop
raindrop.ServerRaindropPartner('Sandbox', 'your_id', 'your_secret')
Server-side Raindrop is meant to secure access to large systems, databases, and APIs. Server-side Raindrop consists of a transaction performed via a smart contract that publicly validates access to a private system. The technology complements existing private authentication methods, and is intended to provide additional security for sensitive financial data that is increasingly at risk from hacking and breaches.
Server-side Raindrop is a four-step process:
- Whitelist each user that will be required to authenticate.
- Request a challenge string from the Hydro API.
- Relay information to the user who performs the raindrop on the Hydro Smart Contract, outside of the API.
- Verify that the user is authenticated with a call to the Hydro API.
Our server-side raindrop video tutorial serves as an additional resource for helping developers follow the server-side raindrop workflow.
Whitelist
Example Request
curl -X POST -H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
"address": "0xWY81621928g5454415154354ac82cd2F266181G7"
}' "https://[sandbox][api].hydrogenplatform.com/hydro/v1/whitelist"
address = "0x0000000000000000000000000000000000000000"
partner.whitelist(address)
address = "0x0000000000000000000000000000000000000000"
partner.whitelist(address)
Example Response
{
"hydro_address_id": "cbcd0758-1314-11e8-b642-0ed5f89f718b",
"transaction_hash": "0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060"
}
All users who want to access to your Raindrop-enabled system will have to be whitelisted. Whenever they perform an authentication, they will also need your partner_id
that you received when setting up your credentials with our API. We recommend passing this partner_id
to accessors when you whitelist them and asking them to store it. Alternatively, you could pass it to them whenever they are performing a challenge.
In order to be whitelisted, users (for example, clients or developers utilizing your platform/API) must provide the address of an Ethereum account which they own and are able to transact from. This address will be stored both on the blockchain and in Hydro’s private database. After each successful whitelist
call, each user will be assigned a unique hydro_address_id
tied directly to your API key. This hydro_address_id
must be passed in all following calls involving that user. To whitelist a user:
POST
to/whitelist
with the user’s Ethereumaddress
in the post body.- Returns
hydro_address_id
if the address has been successfully whitelisted. This process may take around 30 seconds to store the address on the Hydro contract on the blockchain - Use this
hydro_address_id
for all subsequent API calls involving this user
HTTP REQUEST
POST /whitelist
ARGUMENTS
Parameter | Type | Required | Description |
---|---|---|---|
address |
string | required | The user’s Ethereum address |
RESPONSE
Field | Type | Description |
---|---|---|
hydro_address_id |
string | The authenticating user’s newly assigned address id |
transaction_hash |
string | The hash of the transaction whitelisting the user |
Challenge
Example Request
curl -X POST -H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
"hydro_address_id": "cbcd0758-1314-11e8-b642-0ed5f89f718b"
}' "https://[sandbox][api].hydrogenplatform.com/hydro/v1/challenge"
hydroAddressId = "cbcd0758-1314-11e8-b642-0ed5f89f718b"
partner.requestChallenge(hydroAddressId)
hydro_address_id = "cbcd0758-1314-11e8-b642-0ed5f89f718b"
partner.request_challenge(hydro_address_id)
Example Response
{
"amount": 313820000000000000,
"challenge": 445253481902,
"partner_id": 1,
"transaction_hash": "0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060"
}
After being whitelisted, each user must authenticate through the Server-side Raindrop process once every 24 hours to retain access to the protected system. Every time a user wishes to authenticate, you must request a challenge on their behalf. Each challenge consists of 3 elements:
amount
- Quantity of Hydro tokens the user associated withhydro_address_id
is required to send to Hydro’s authentication smart contract. The amounts may seem large, but remember that our token has 18 decimal places. For example, 313820000000000000 is actually .31382 Hydro.challenge
- A randomly generated number used to confirm the validity of the transaction. Only the client requesting the challenge will know the value.partner_id
- This is the id you will use to connect your credentials in Hydro to the smart contract. We recommend you pass this to authenticating parties when you whitelist them and ask them to store it.
You will need to relay these values to the authenticating user who will send them to a Hydro smart contract, so treat them accordingly.
HTTP REQUEST
POST /challenge
ARGUMENTS
Parameter | Type | Required | Description |
---|---|---|---|
hydro_address_id |
string | required | The authenticating user’s address id |
RESPONSE
Parameter | Type | Description |
---|---|---|
amount |
integer | The challenge amount |
challenge |
integer | The challenge string |
partner_id |
integer | The unique identifier assigned to your firm |
transaction_hash |
string | The hash of the transaction that updates the user’s raindrop requirements |
Smart Contract
The owner of the Ethereum/Hydro address must now use the challenge values to “perform the raindrop”, which means authenticating on a Hydro smart contract. This process needs to happen outside of the Hydro API. Here are a few ways that users can perform a raindrop:
REQUIRED AUTHENTICATION DETAILS
Environment | Network | Address | ABI |
---|---|---|---|
Sandbox |
Rinkeby | 0x4959c7f62051D6b2ed6EaeD3AAeE1F961B145F20 |
ABI |
Production |
Mainnet | 0xEBBdf302c940c6bfd49C6b165f457fdb324649bc |
ABI |
Manually through Ethereum Wallet
- Open the Contracts tab and click
Watch Contract
. - Enter the appropriate address and ABI from above in the
Contract Address
andJSON Interface
fields, depending on your target environment. - Click on the added contract and select
Authenticate
from the function dropdown. - Fill in the
_value
,_data
, and_partner id
fields with theamount
,challenge
, andpartner_id
returned from the challenge. - Once this transaction is confirmed the raindrop has been completed. The transaction will fail if any values sent are incorrect.
Manually through MyEtherWallet or MyCrypto
- Click the
Contracts
tab. - Enter the appropriate address and ABI from above in the
Contract Address
andJSON Interface
fields, depending on your target environment. - Select
Authenticate
from the function dropdown. (Note: If you are on Rinkeby you can get Hydro tokens to use for testing by clickinggetMoreTokens
) - Fill in the
_value
,_data
, and_partnerId
fields with theamount
,challenge
, andpartner_id
returned from the challenge - Once this transaction is confirmed the raindrop has been completed. The transaction will fail if any values sent are incorrect.
Programmatically through Javascript or Python
Web3.js and Web3.py have extensive documentation on how to transact with an Ethereum smart contract.
ARGUMENTS
Parameter | Type | Description |
---|---|---|
amount |
integer | The amount returned from the challenge |
challenge |
string | The challenge returned from the challenge |
partner_id |
integer | The partner id returned from the challenge |
Authenticate
Example Request
curl -X GET -H "Authorization: Bearer <access_token>" \
"https://[sandbox][api].hydrogenplatform.com/hydro/v1/authenticate?hydro_address_id=cbcd0758-1314-11e8-b642-0ed5f89f718b"
hydroAddressId = "cbcd0758-1314-11e8-b642-0ed5f89f718b"
partner.authenticate(hydroAddressId)
hydro_address_id = "cbcd0758-1314-11e8-b642-0ed5f89f718b"
partner.authenticate(hydro_address_id)
Example Response
{
"verified": true,
"authentication_id": "bece93a4-1331-11e8-b642-83b5f899c98b",
"timestamp": "2018-06-01T17:55:01.000Z"
}
Once the raindrop has been completed by the end user and confirmed in the blockchain, the final authentication check can be performed. This endpoint will return with code 200
and metadata associated with the verification if the raindrop was performed successfully. Unsuccessful verifications will return with code 401
. The user should be allowed to proceed with any further authentication procedures such as OAuth, or gain access to the system outright only if a 200
is returned.
HTTP REQUEST
GET /authenticate?hydro_address_id={hydro_address_id}
ARGUMENTS
Parameter | Type | Required | Description |
---|---|---|---|
hydro_address_id |
string | required | The authenticating user’s address id |
RESPONSE
Field | Type | Description |
---|---|---|
verified |
boolean | A boolean indicating the status of this verification attempt. |
authentication_id |
UUID | A UUID for this verification attempt. |
timestamp |
timestamp | The time of this verification attempt. |
Client-side
const raindrop = require("@hydrogenplatform/raindrop")
new raindrop.client.RaindropPartner({
environment: "Sandbox",
clientId: "yourId",
clientSecret: "yourSecret",
applicationId: "yourApplicationId"
})
import raindrop
raindrop.ClientRaindropPartner('Sandbox', 'your_id', 'your_secret', 'your_application_id')
Currently live in the iOS and Google Play stores!
Client-side Raindrop is a multi-factor authentication (MFA) solution for client login portals with many end-users frequently requesting access to their respective accounts. Client-side Raindrop integrates through our API with the Hydro app on a user’s mobile device to provide an added layer of security on login attempts and other access requests.
From the perspective of an end-user, connectivity to the Hydro API for Client-side Raindrop is handled by our mobile app. Accordingly, this documentation will focus on helping partners integrate Client-side Raindrop into their applications. While we anticipate that authentication will mainly be used for login portals, Client-side Raindrop authentication can be triggered upon any event, such as whenever a user tries to conduct a large balance transfer.
Before implementing Client-side Raindrop, you will need to register an application through your Hydrogen account. Once you have received an application_id
, you will be able to start registering users.
Partners setting up Client-side Raindrop will need to follow a four-step process:
- Register users to authenticate their login attempts through the Hydro mobile app.
- Generate the message that users will need to type into their Hydro app on their phones.
- Verify the signed message sent from the user’s phone to the Hydro API.
- Unregister users who opt to disable MFA from your application.
In addition, partners setting up Client-side Raindrop will need to set up a 2FA/authentication portal on their sites with which users can interact. For further instructions on integrating this logic into your platform, please refer to our Raindrop UI tools and our accompanying implementation guide.
Register User
Example Request
curl -X POST -H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
"hydro_id": "testName",
"application_id": "519935c8-c271-385d-3136-r6gh1r679125"
}' "https://[sandbox][api].hydrogenplatform.com/hydro/v1/application/client"
hydroID = "testName"
partner.registerUser(hydroID)
hydro_id = "testName"
partner.register_user(hydro_id)
Response (201 Created)
To register a user, you will need to collect the HydroID that identifies them on the Hydro app and map it to your application. Once you have this information:
POST
it ashydro_id
to/application/client
along with yourapplication_id
.- Returns a
201
if the user has been successfully mapped to your application.
After you have registered the user, you will need to request that they complete a verification before you permanently map their hydro_id
to your internal site identifier in your database. This is because there is a chance that the user may have mistakenly passed you a hydro_id
that belongs to a different user. Once the user has completed a verification, you can be certain that they have passed you the correct hydro_id
. Your application must provide this hydro_id
for subsequent API calls, so please store it mapped to the user’s internal identifier in your system.
HTTP REQUEST
POST /application/client
ARGUMENTS
Parameter | Type | Required | Description |
---|---|---|---|
hydro_id |
string | required | The user’s claimed HydroID from their mobile app |
application_id |
string | required | Your unique application ID |
Generate Message
Example Request
partner.generateMessage()
partner.generate_message()
Example Message
425663
When a user performs an event that triggers a Hydro 2FA requirement on your platform (most commonly, a login attempt), you will need to display a message to them that they will type into their mobile app. You can obtain this message in two ways:
- Use our provided Javascript or Python SDK to generate a 6-digit message in the back-end of your application.
- Generate a message internally. If you choose to generate the message internally, it will need to be numeric for compatibility with the Hydro API and the user’s phone app.
We strongly recommend that you use our SDKs, as they will create a one-time six digit code using a Cryptographically Secure Random Number Generator (CSPRNG). Once you’ve obtained the message, you will need to display it on a redirect screen that you provide to your users. For further instruction on integrating this logic into your portal, please refer to our Raindrop UI tools. This screen will also need to contain a button allowing users to indicate that they’ve signed the message on their app, at which time you should proceed to verify the signature.
Verify Signature
Example Request
curl -X GET -H "Authorization: Bearer <access_token>" \
"https://[sandbox][api].hydrogenplatform.com/hydro/v1/verify_signature?message=425663&hydro_id=testuser&application_id=519935c8-c271-385d-3136-r6gh1r679125"
hydroID = "testName"
message = "425663"
partner.verifySignature(hydroID, message)
hydro_id = "testName"
message = "425663"
partner.verify_signature(hydro_id, message)
Example Response
{
"authenticated": true,
"verification_id": "bece93a4-1331-11e8-b642-83b5f899c98b",
"timestamp": "2018-06-01T17:55:01.000Z"
}
Once a user has been provided a message, they will need to input that message into their mobile device. The Hydro mobile app will sign the message with their locally stored private key and send the signed message to the Raindrop API. Then, they will click the proceed button on your platform which will be part of the screen you can generate using our Raindrop UI tools.
At this point, you will need to GET
the confirmation of the signature from the Raindrop API at /verify_signature
. The API will verify that the correct user signed the message against the information stored on the blockchain. Successful verifications will return with code 200
and metadata associated with the verification. Unsuccessful verifications will return with code 401
. You should restrict execution of the event or login to be contingent on this verification.
While the above process provides a bare-minimum implementation protocol of MFA, we recommend the following best-practices for added security and user-friendliness.
We strongly recommend implementing a 90 second time-out component of your MFA process. This gives the user enough time to locate their mobile device and sign in without leaving an access avenue open to their account if they get distracted.
To add more user-friendliness for most platforms using Client Raindrop to secure user logins, we recommend implementing an option for a 24 hour Time to Live (TTL) for a user’s device upon login. This allows a user to repeatedly access an account from an authorized device without frequently needing to authenticate that device.
HTTP REQUEST
GET /verify_signature?message={message}&hydro_id={hydro_id}&application_id={application_id}
ARGUMENTS
Parameter | Type | Required | Description |
---|---|---|---|
message |
string | required | The generated six-digit code |
hydro_id |
string | required | The authenticating user’s HydroID |
application_id |
string | required | Your unique application ID |
RESPONSE
Field | Type | Description |
---|---|---|
authenticated |
boolean | A boolean indicating the status of this authentication attempt. |
verification_id |
UUID | A UUID for this verification attempt. |
timestamp |
timestamp | The time of this verification attempt. |
Unregister User
Example Request
curl -X DELETE -H "Authorization: Bearer <access_token>" \
"https://[sandbox][api].hydrogenplatform.com/hydro/v1/application/client?hydro_id=testName&application_id=519935c8-c271-385d-3136-r6gh1r679125"
hydroID = "testName"
partner.unregisterUser(hydroID)
hydro_id = "testName"
partner.unregister_user(hydro_id)
Response (204 No Content)
For a variety of reasons, a user may want to disable MFA or may delete their account on your platform. In this event, you will need to unlink their HydroID on your platform and communicate this information to us with a DELETE
to /application/client
. Once this occurs, we will remove their mapping to your application in our database, and your app name will no longer show up on their Hydro mobile app until they re-register.
HTTP REQUEST
DELETE /application/client?hydro_id={hydro_id}&application_id={application_id}
ARGUMENTS
Parameter | Type | Required | Description |
---|---|---|---|
hydro_id |
string | required | The authenticating user’s HydroID |
application_id |
string | required | Your unique application ID |