harbinger-poster
is a reference implementation for a server side hosted poster for the Harbinger oracle system. Harbinger-Poster is a Serverless Framework application written in Typescript and deployed to Amazon Web Services. To get started with Harbinger, visit the main documentation.
This library provides functionality for posting update to Harbinger. Users interested in posting prices might also be interested in Harbinger CLI which provides a non-hosted poster solution. Entities who wish to sign prices for Harbinger may want to look at Harbinger Signer. Developers of new Harbinger components may be interested in harbinger-lib.
In order to ensure that the data in the Harbinger Tezos price storage contract is kept up to date, you can choose to run the aforementioned command line process that periodically retrieves a signed price from the Coinbase Pro API and generates the Tezos operation that updates the contract, or you can deploy this Serverless Framework application to Amazon Web Services and it will run every 5 minutes and perform these same tasks for you automatically. Of course, you are free to run the CLI tool instead, but the Serverless application doesn't require that you run a long-lived server.
To be clear, you only need to run one or the other: The command line updater OR the Serverless updater, not both. Running both won't hurt anything though.
You should have already deployed the storage and normalizer contracts using the command line harbinger
utility before beginning these steps. If you haven't done that, please go back and complete those steps first.
In order to setup the Serverless application, you'll need to perform the following setup tasks first:
- Install the AWS CLI on your system.
- Create an AWS access key and configure the AWS CLI by running the
aws configure
command. - Login to the AWS console with an account that has the ability to create KMS keys and SSM parameters, and grant permissions to use them. An admin role will work best.
- Be sure to select the correct region that you would like to deploy to. The serverless.yml file in this repository is set to use the
eu-west-1
(Ireland) region, but you can easily edit this file and select a different region if you like. The important thing is to ensure that the region you select in the console is the same region that is specified in the Serverless configuration file. - In the AWS console, select the KMS service:
- Click the "Create key" button:
- Select Asymmetric under Key type, then select Sign and verify under Key usage, then select ECC_SECG_P256K1 under Key spec, and click the Next button:
- On the next page, input an Alias for the key and an optional Description, then click the Next button:
- The next page is where you can define key administrators. There is no need to change any settings on this page, unless you would like to give additional IAM users or roles administrative permissions to the key. Click the Next button to continue:
- This page is where you can define additional IAM users or roles that have key usage permissions. There is no need to change any settings on this page, unless you would like to give additional IAM users or roles usage permissions for the key. Click the Next button to continue:
- Click Next to accept the default key policy, which only grants access to the root user. We'll edit this policy later to give the Serverless application rights to sign with the key.
- Finally, click Finish and you should see a Success message similar to the following:
- Copy the KMS key ID to your clipboard, or save it somewhere, then, launch Systems Manager from the Services section of the console (top left):
- Select Parameter Store on the left navigation bar:
- Click the Create Parameter button in the top left:
- Name the parameter
/tezos/poster-kms-key-id
and give it an optional description. Leave the other settings at default (Standard tier, String type, Data type text), and paste or enter the KMS key ID you saved in step 13 as the value, without quotes or any surrounding characters, then click the Create parameter button:
The following steps are only required if you are planning on using the Coinbase Pro API as a price data provider. Other exchanges don't currently require creating an API key to view their price data. If you are using another exchange besides Coinbase Pro, skip to step 25.
- Access your Coinbase Pro API key settings either with the link or by accessing your profile menu in the top right:
- Click the New API Key button in the top right:
- Give the API key a nickname, check the box for View permissions only, and either save the passphrase somewhere secure or replace the default random passphrase with a strong passphrase of your choice, then click the Create API Key button:
- If you have 2-factor authentication enabled, you'll need to go through the 2-step verification, then click the Add an API Key button:
- Store the API Secret in a secure place, then click the Done button:
- Now you should see the View key that you just created, and you'll need to copy the API key itself and store it somewhere for the next steps. You can click the API key itself to copy it to your clipboard:
- Create another parameter named
/tezos/coinbase-pro-api-key
and give it an optional description. This parameter should be of typeSecureString
, but you can leave the rest of the settings at their defaults, and input your Coinbase Pro API key (with view permissions) as the value, then click the Create parameter button:
-
Create two more parameters, one named
/tezos/coinbase-pro-api-passphrase
and the second one named/tezos/coinbase-pro-api-secret
with the values that you saved previously in steps 19 and 21. These should both be of typeSecureString
as well. -
Clone this repository to your local system, and edit lines 48-49 of
serverless.yml
. Replace the empty string with the public address (KT1...
) of the oracle contract you deployed with the CLI earlier. Optionally, if you'd also like to push data to a normalizer as you post, you can also edit lines 52-53 to specify the public address (KT1...
) of the normalizer contract. Otherwise, leave it as the empty string to not post updates. -
Install all NPM dependencies by typing
npm i
inside the repository directory, then typesls deploy --stage {{ exchange }}
(replace exchange with one ofcoinbase
,binance
,gemini
, orokex
) to deploy the application. If all goes well, you should see output similar to this. You'll want to save the two endpoints for use later.
- Now, navigate back to KMS in the AWS console, and click on the Customer Managed Key you created earlier to modify the key policy. Click the button that says Switch to Policy View:
- Now, click the button that says Edit:
- Now we'll need to modify the key policy in order to enable the IAM role that the Serverless application will execute with to use the key for signing operations. You'll need to insert an additional JSON element or section into the Statement array. The section you'll need to insert is highlighted in the screenshot below. Don't forget to separate each statement with a comma. Here is the code you'll need to insert:
,
{
"Sid": "Allow use of the key for digital signing",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::{{ AWS Account ID }}:role/harbinger-poster-{{ Exchange }}-{{ AWS Region }}-lambdaRole"
},
"Action": [
"kms:Sign",
"kms:Verify",
"kms:GetPublicKey"
],
"Resource": "*"
}
Important Note: You must replace the 3 sections of the JSON in each statement that have {{ }}
(double curly braces) surrounding them with the appropriate information. This string should also have no spaces in it.
- AWS Account ID - This is your 12-digit numeric AWS account ID
- Exchange - This is the string
coinbase
,binance
,gemini
, orokex
(all lower case) depending on which exchange the signer you are using is from - Region - This is the AWS region you are deploying to, such as
eu-west-1
Congratulations, you've just deployed a Serverless application that will automatically poll the Coinbase Pro signed price oracle every 5 minutes and update the storage contract with the lastest signed prices. There will be a small amount of fees required to perform these storage updates, so you'll need to send some XTZ to the address represented by the KMS key we created previously. This is how you determine the address to send fees to:
- Curl the
info
endpoint that is displayed when you ran the last step (sls deploy
) and it should output thetz2...
address. You will need to include anx-api-key
header that is set to the API key that was output by the previoussls deploy
command. Here is the full command:
curl --silent -H 'x-api-key: {{ your API key }}' https://{{ your API gateway }}.execute-api.eu-west-1.amazonaws.com/{{ exchange }}/info
If you get a {"message": "Internal server error"}
instead, you should check your Lambda logs inside the AWS console to see what went wrong. Most likely you have either not created all of the Systems Manager parameters correctly or the KMS key policy is not 100% correct. You should see output like this:
- Fund the
tz2...
account by transferring a small amount of XTZ to it. Please note that because it is a brand new account you will need to also use the--burn-cap 0.257
option when you send to it.
Harbinger is written and maintained by Luke Youngblood and Keefer Taylor.