Skip to content

Commit f3249d9

Browse files
authored
feat(apps/hermes): new client package for hermes (#1653)
* add functions for v2 endpoints * precommit * remove oracle-swap and send-usd examples * fix error * fix precommit * fix error * replace axios with fetch * create new hermes client package * revert price-service changes * update readme * update ci workflow * update package-lock.json * fix cargo * fix cargo * fix errors * refactor * address comments * address comments * address comments * address comments * add CI to check hermes client api types * fix ci * remove ci * add CI back * updated generated types * update precommit to exlcude serverTypes.d.ts * address comments * remove dockerfile * address comments * fix test * address comments * update package-lock.json * rename to HermesClient * rename HermesConnection to HermesClient * address comments * make openapi-zod-client dev-dep * address comments * add workflow * update workflow * update package name
1 parent 0f7141e commit f3249d9

File tree

126 files changed

+65913
-91162
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

126 files changed

+65913
-91162
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
name: Check Hermes Client API Types
2+
3+
on:
4+
pull_request:
5+
paths: [apps/hermes/client/**]
6+
push:
7+
branches: [main]
8+
paths: [apps/hermes/client/**]
9+
jobs:
10+
test:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v4
14+
- uses: actions/setup-node@v3
15+
with:
16+
node-version: 18
17+
cache: "npm"
18+
- name: Install deps
19+
run: npm ci
20+
- name: Generate API Types
21+
run: npx lerna run generate-hermes-api-types
22+
- name: Check API Types
23+
run: npx lerna run check-hermes-api-types

.github/workflows/ci-hermes.yml renamed to .github/workflows/ci-hermes-server.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
name: Check Hermes
1+
name: Check Hermes Server
22

33
on:
44
pull_request:
5-
paths: [apps/hermes/**]
5+
paths: [apps/hermes/server/**]
66
push:
77
branches: [main]
8-
paths: [apps/hermes/**]
8+
paths: [apps/hermes/server/**]
99
jobs:
1010
test:
1111
runs-on: ubuntu-latest
@@ -20,4 +20,4 @@ jobs:
2020
- name: Install protoc
2121
uses: arduino/setup-protoc@v3
2222
- name: Run executor tests
23-
run: cargo test --manifest-path ./apps/hermes/Cargo.toml
23+
run: cargo test --manifest-path ./apps/hermes/server/Cargo.toml
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: Publish Hermes Client package
2+
3+
on:
4+
push:
5+
tags:
6+
- hermes-client-v*
7+
jobs:
8+
publish-js:
9+
name: Publish Hermes Client to NPM
10+
runs-on: ubuntu-latest
11+
steps:
12+
- uses: actions/checkout@v2
13+
- uses: actions/setup-node@v2
14+
with:
15+
node-version: "18"
16+
registry-url: "https://registry.npmjs.org"
17+
- run: npm ci
18+
- run: npx lerna run build --no-private
19+
- run: npx lerna publish from-git --yes --no-private --no-git-tag-version
20+
env:
21+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

.pre-commit-config.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,13 @@ repos:
5050
- id: cargo-fmt-hermes
5151
name: Cargo format for Hermes
5252
language: "rust"
53-
entry: cargo +nightly-2024-03-26 fmt --manifest-path ./apps/hermes/Cargo.toml --all -- --config-path rustfmt.toml
53+
entry: cargo +nightly-2024-03-26 fmt --manifest-path ./apps/hermes/server/Cargo.toml --all -- --config-path rustfmt.toml
5454
pass_filenames: false
5555
files: apps/hermes
5656
- id: cargo-clippy-hermes
5757
name: Cargo clippy for Hermes
5858
language: "rust"
59-
entry: cargo +nightly-2024-03-26 clippy --manifest-path ./apps/hermes/Cargo.toml --tests --fix --allow-dirty --allow-staged -- -D warnings
59+
entry: cargo +nightly-2024-03-26 clippy --manifest-path ./apps/hermes/server/Cargo.toml --tests --fix --allow-dirty --allow-staged -- -D warnings
6060
pass_filenames: false
6161
files: apps/hermes
6262
# Hooks for Fortuna

apps/hermes/client/js/.eslintrc.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
module.exports = {
2+
root: true,
3+
parser: "@typescript-eslint/parser",
4+
plugins: ["@typescript-eslint"],
5+
extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
6+
};

apps/hermes/client/js/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
lib/

apps/hermes/client/js/README.md

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# Hermes Client
2+
3+
[Pyth Network](https://pyth.network/) provides real-time pricing data in a variety of asset classes, including cryptocurrency, equities, FX and commodities.
4+
These prices are available either via HTTP or Streaming from [Hermes](/apps/hermes).
5+
This library is a client for interacting with Hermes, allowing your application to consume Pyth real-time prices in on- and off-chain Javascript/Typescript applications.
6+
7+
## Installation
8+
9+
### npm
10+
11+
```
12+
$ npm install --save @pythnetwork/hermes-client
13+
```
14+
15+
### Yarn
16+
17+
```
18+
$ yarn add @pythnetwork/hermes-client
19+
```
20+
21+
## Quickstart
22+
23+
Typical usage of the connection is along the following lines:
24+
25+
```typescript
26+
const connection = new HermesClient("https://hermes.pyth.network", {}); // See Hermes endpoints section below for other endpoints
27+
28+
const priceIds = [
29+
// You can find the ids of prices at https://pyth.network/developers/price-feed-ids
30+
"0xe62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43", // BTC/USD price id
31+
"0xff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace", // ETH/USD price id
32+
];
33+
34+
// Get price feeds
35+
const priceFeeds = await connection.getPriceFeeds("btc", "crypto");
36+
console.log(priceFeeds);
37+
38+
// Latest price updates
39+
const priceUpdates = await connection.getLatestPriceUpdates(priceIds);
40+
console.log(priceUpdates);
41+
```
42+
43+
`HermesClient` also allows subscribing to real-time price updates over a Server-Sent Events (SSE) connection:
44+
45+
```typescript
46+
// Streaming price updates
47+
const eventSource = await connection.getStreamingPriceUpdates(priceIds);
48+
49+
eventSource.onmessage = (event) => {
50+
console.log("Received price update:", event.data);
51+
};
52+
53+
eventSource.onerror = (error) => {
54+
console.error("Error receiving updates:", error);
55+
eventSource.close();
56+
};
57+
58+
await sleep(5000);
59+
60+
// To stop listening to the updates, you can call eventSource.close();
61+
console.log("Closing event source.");
62+
eventSource.close();
63+
```
64+
65+
### On-chain Applications
66+
67+
On-chain applications will need to submit the price updates returned by Hermes to the Pyth contract on their blockchain.
68+
By default, these updates are returned as binary data and is serialized as either a base64 string or a hex string depending on the chosen encoding. This binary data will need to be submitted to the Pyth contract.
69+
70+
### Examples
71+
72+
The [HermesClient](./src/examples/HermesClient.ts) example demonstrates both the examples above.
73+
You can run it with `npm run example`.
74+
A full command that prints BTC and ETH price feeds, in the testnet network, looks like so:
75+
76+
```bash
77+
npm run example -- \
78+
--endpoint https://hermes.pyth.network \
79+
--price-ids \
80+
0xe62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43 \
81+
0xff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace
82+
```
83+
84+
## Hermes endpoints
85+
86+
Pyth offers a free public endpoint at [https://hermes.pyth.network](https://hermes.pyth.network). However, it is
87+
recommended to obtain a private endpoint from one of the Hermes RPC providers for more reliability. You can find more
88+
information about Hermes RPC providers
89+
[here](https://docs.pyth.network/documentation/pythnet-price-feeds/hermes#public-endpoint).

apps/hermes/client/js/jest.config.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
2+
module.exports = {
3+
preset: "ts-jest",
4+
testEnvironment: "node",
5+
};

apps/hermes/client/js/package.json

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
{
2+
"name": "@pythnetwork/hermes-client",
3+
"version": "1.0.0",
4+
"description": "Pyth Hermes Client",
5+
"author": {
6+
"name": "Pyth Data Association"
7+
},
8+
"homepage": "https://pyth.network",
9+
"main": "lib/HermesClient.js",
10+
"types": "lib/HermesClient.d.ts",
11+
"files": [
12+
"lib/**/*"
13+
],
14+
"repository": {
15+
"type": "git",
16+
"url": "https://github.com/pyth-network/pyth-crosschain",
17+
"directory": "apps/hermes/client/js"
18+
},
19+
"publishConfig": {
20+
"access": "public"
21+
},
22+
"scripts": {
23+
"test": "jest --testPathIgnorePatterns=.*.e2e.test.ts --passWithNoTests",
24+
"test:e2e": "jest --testPathPattern=.*.e2e.test.ts",
25+
"build": "tsc",
26+
"generate-hermes-api-types": "openapi-zod-client https://hermes.pyth.network/docs/openapi.json --output src/zodSchemas.ts && prettier --write src/zodSchemas.ts",
27+
"check-hermes-api-types": "git diff --exit-code src/zodSchemas.ts",
28+
"example": "npm run build && node lib/examples/HermesClient.js",
29+
"format": "prettier --write \"src/**/*.ts\"",
30+
"lint": "eslint src/",
31+
"prepublishOnly": "npm run build && npm test && npm run lint",
32+
"preversion": "npm run lint",
33+
"version": "npm run format && git add -A src"
34+
},
35+
"keywords": [
36+
"pyth",
37+
"oracle"
38+
],
39+
"license": "Apache-2.0",
40+
"devDependencies": {
41+
"@types/eventsource": "^1.1.15",
42+
"@types/jest": "^29.4.0",
43+
"@types/yargs": "^17.0.10",
44+
"@typescript-eslint/eslint-plugin": "^5.21.0",
45+
"@typescript-eslint/parser": "^5.21.0",
46+
"eslint": "^8.14.0",
47+
"jest": "^29.4.0",
48+
"openapi-zod-client": "^1.18.1",
49+
"prettier": "^2.6.2",
50+
"ts-jest": "^29.0.5",
51+
"typescript": "^4.6.3",
52+
"yargs": "^17.4.1"
53+
},
54+
"dependencies": {
55+
"eventsource": "^2.0.2",
56+
"zod": "^3.23.8"
57+
}
58+
}

0 commit comments

Comments
 (0)