-
Notifications
You must be signed in to change notification settings - Fork 302
feat(pyth-lazer-publisher-sdk): Add SDK for Publisher Transactions #2557
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 24 commits
e69e71c
ea14862
72f3dd4
a9dcdca
979f793
aa21d2a
770c987
57cb606
f5ac983
36a34bb
308ea14
1bcbe45
031ea71
a06c2d4
56b5a56
59ae65b
a88c3df
e93cdd9
3979cc8
7c8ae8c
ac2e981
d2df006
bfb713a
10b17d8
50de6e4
8c11702
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| name: Publish Rust package pyth-lazer-publisher-sdk to crates.io | ||
|
|
||
| on: | ||
| push: | ||
| tags: | ||
| - rust-pyth-lazer-publisher-sdk-v* | ||
| jobs: | ||
| publish-pyth-lazer-publisher-sdk: | ||
| name: Publish Rust package pyth-lazer-published-sdk to crates.io | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Checkout sources | ||
| uses: actions/checkout@v2 | ||
|
|
||
| - run: cargo publish --token ${CARGO_REGISTRY_TOKEN} | ||
| env: | ||
| CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} | ||
| working-directory: "lazer/sdk/rust/published-sdk" |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| # Coverage directory used by tools like istanbul | ||
| coverage | ||
|
|
||
| # Build directory | ||
| dist/ | ||
|
|
||
| # Types generated for .proto files | ||
| src/generated/ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| .vscode/ | ||
| coverage/ | ||
| dist/ | ||
| doc/ | ||
| doc*/ | ||
| node_modules/ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| # pyth-lazer-publisher-sdk - Readme | ||
|
|
||
| ## Contributing & Development | ||
|
|
||
| See [contributing.md](docs/contributing/contributing.md) for information on how to develop or contribute to this project! | ||
|
|
||
| ## Installation and build | ||
|
|
||
| ### pnpm | ||
|
|
||
| ``` | ||
| cd to crosschain root | ||
| $ pnpm install | ||
| $ pnpm turbo --filter @pythnetwork/pyth-lazer-publisher-sdk build | ||
| ``` | ||
|
|
||
| As part of the build, files will be generated from the proto files found in the lazer/proto folder. These generated files are placed in the src/generated/ folder. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| export { base as default } from "@cprussin/eslint-config"; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| { | ||
| "name": "@pythnetwork/pyth-lazer-publisher-sdk", | ||
| "version": "0.1.0", | ||
| "description": "Pyth Lazer Publisher SDK", | ||
| "publishConfig": { | ||
| "access": "public" | ||
| }, | ||
| "files": [ | ||
| "dist/**/*" | ||
| ], | ||
| "main": "./src/generated/proto.js", | ||
| "types": "./src/generated/proto.d.ts", | ||
| "exports": { | ||
| "import": { | ||
| "types": "./src/generated/proto.d.ts", | ||
| "default": "./src/generated//proto.js" | ||
| }, | ||
| "require": { | ||
| "types": "./src/generated/proto.d.ts", | ||
| "default": "./src/generated//proto.js" | ||
| } | ||
| }, | ||
| "scripts": { | ||
| "build:proto-codegen": "mkdir -p src/generated && pnpm exec pbjs -t static-module -w es6 -o src/generated/proto.js ../proto/*.proto && pnpm exec pbts -o src/generated/proto.d.ts src/generated/proto.js", | ||
| "build:cjs": "tsc --project tsconfig.build.json --verbatimModuleSyntax false --module commonjs --outDir ./dist/cjs && echo '{\"type\":\"commonjs\"}' > dist/cjs/package.json", | ||
| "build:esm": "tsc --project tsconfig.build.json --outDir ./dist/esm && echo '{\"type\":\"module\"}' > dist/esm/package.json", | ||
darunrs marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| "fix:lint": "eslint --fix . --max-warnings 0", | ||
| "test:lint": "eslint . --max-warnings 0", | ||
| "test:types": "tsc", | ||
| "test:format": "prettier --check .", | ||
| "fix:format": "prettier --write .", | ||
| "doc": "typedoc --out docs/typedoc src", | ||
| "prepublishOnly": "pnpm run build", | ||
| "publish": "pnpm run script -- publish" | ||
| }, | ||
| "type": "module", | ||
| "homepage": "https://github.com/pyth-network/pyth-crosschain/tree/main/lazer/publisher_sdk/js", | ||
| "repository": { | ||
| "type": "git", | ||
| "url": "https://github.com/pyth-network/pyth-crosschain", | ||
| "directory": "lazer/publisher_sdk/js" | ||
| }, | ||
| "keywords": [ | ||
| "pyth", | ||
| "oracle" | ||
| ], | ||
| "license": "Apache-2.0", | ||
| "devDependencies": { | ||
| "@cprussin/eslint-config": "catalog:", | ||
| "@cprussin/tsconfig": "catalog:", | ||
| "@types/node": "^18.19.54", | ||
| "eslint": "catalog:", | ||
| "prettier": "catalog:", | ||
| "protobufjs": "^7.4.0", | ||
| "protobufjs-cli": "^1.1.3", | ||
| "ts-node": "catalog:", | ||
| "typedoc": "^0.26.8", | ||
| "typescript": "catalog:" | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| { | ||
| "extends": "./tsconfig.json", | ||
| "compilerOptions": { | ||
| "noEmit": false, | ||
| "incremental": false, | ||
| "declaration": true | ||
| }, | ||
| "include": ["src/**/*"], | ||
| "exclude": ["node_modules", "dist", "examples/"] | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| { | ||
| "extends": "@cprussin/tsconfig/base.json", | ||
| "include": ["src/**/*"], | ||
| "exclude": ["node_modules", "dist"] | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| { | ||
| "$schema": "https://turbo.build/schema.json", | ||
| "extends": ["//"], | ||
| "tasks": { | ||
| "build:proto-codegen": { | ||
| "dependsOn": ["//#install:modules"], | ||
| "inputs": ["../proto/**"], | ||
| "outputs": ["src/generated/**"], | ||
| "cache": false | ||
| }, | ||
| "build": { | ||
| "dependsOn": ["build:cjs", "build:esm"], | ||
| "inputs": [ | ||
| "$TURBO_DEFAULT$", | ||
| "!README.md", | ||
| "!**/*.test.*", | ||
| "!jest.config.js", | ||
| "!eslint.config.js", | ||
| "!prettier.config.js", | ||
| "!vercel.json" | ||
| ], | ||
| "outputs": ["dist/**"] | ||
| }, | ||
| "build:cjs": { | ||
| "dependsOn": ["build:proto-codegen", "^build"], | ||
| "inputs": [ | ||
| "$TURBO_DEFAULT$", | ||
| "!README.md", | ||
| "!**/*.test.*", | ||
| "!jest.config.js", | ||
| "!eslint.config.js", | ||
| "!prettier.config.js", | ||
| "!vercel.json" | ||
| ], | ||
| "outputs": ["dist/cjs/**"] | ||
| }, | ||
| "build:esm": { | ||
| "dependsOn": ["build:proto-codegen", "^build"], | ||
| "inputs": [ | ||
| "$TURBO_DEFAULT$", | ||
| "!README.md", | ||
| "!**/*.test.*", | ||
| "!jest.config.js", | ||
| "!eslint.config.js", | ||
| "!prettier.config.js", | ||
| "!vercel.json" | ||
| ], | ||
| "outputs": ["dist/esm/**"] | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| syntax = "proto3"; | ||
|
|
||
| import "google/protobuf/timestamp.proto"; | ||
|
|
||
| package pyth_lazer_transaction; | ||
|
|
||
| // PublisherUpdate contains an array of individual updates and a timestamp | ||
| message PublisherUpdate { | ||
| // Array of updates, each of which target a single feed | ||
| repeated FeedUpdate updates = 1; | ||
|
|
||
| // ID of the Publisher that is sending the update | ||
| // Should match ID stored in Pyth Lazer | ||
| optional uint32 publisher_id = 2; | ||
|
|
||
| // Timestamp when this message was created | ||
| optional google.protobuf.Timestamp publisher_timestamp = 3; | ||
| } | ||
|
|
||
| // Update to a feed. May contain different types of data depending on what kind of update it is | ||
| message FeedUpdate { | ||
| // Feed which the update should be applied to | ||
| // Should match a feed id recognized by PythLazer | ||
| optional uint32 feed_id = 1; | ||
|
|
||
| // Timestamp when this data was first acquired or generated | ||
| optional google.protobuf.Timestamp source_timestamp = 2; | ||
|
|
||
| // one of the valid updates allowed by publishers for a lazer feed | ||
| oneof update { | ||
| PriceUpdate price_update = 3; | ||
| FundingRateUpdate funding_rate_update = 4; | ||
| }; | ||
| } | ||
|
|
||
| message PriceUpdate { | ||
| // Price for the symbol as an integer | ||
| // Should be produced with a matching exponent to the configured exponent value in PythLazer | ||
| // May be missing if no price data is available | ||
| optional int64 price = 1; | ||
|
|
||
| // Best Bid Price for the symbol as an integer | ||
| // Should be produced with a matching exponent to the configured exponent value in PythLazer | ||
| // May be missing if no data is available | ||
| optional int64 best_bid_price = 2; | ||
|
|
||
| // Best Ask Price for the symbol as an integer | ||
| // Should be produced with a matching exponent to the configured exponent value in PythLazer | ||
| // May be missing if no data is available | ||
| optional int64 best_ask_price = 3; | ||
| } | ||
|
|
||
| message FundingRateUpdate { | ||
| // Price for which the funding rate applies to | ||
| optional int64 price = 1; | ||
|
|
||
| // Perpetual Future funding rate | ||
| optional int64 rate = 2; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| syntax = "proto3"; | ||
|
|
||
| package pyth_lazer_transaction; | ||
|
|
||
| import "publisher_update.proto"; | ||
|
|
||
| // Types of Signatures allowed for signing Lazer Transactions | ||
| enum TransactionSignatureType { | ||
| // signature is 64 bytes long | ||
| ed25519 = 0; | ||
| } | ||
|
|
||
| // Signed lazer transaction payload | ||
| // This is what Pyth Lazer expects as input to the system | ||
| message SignedLazerTransaction { | ||
| // Type and signature should match | ||
| optional TransactionSignatureType signature_type = 1; | ||
|
|
||
| // Signature derived by signing payload with private key | ||
| optional bytes signature = 2; | ||
|
|
||
| // a LazerTransaction message which is already encoded with protobuf as bytes | ||
| // The encoded bytes are what should be signed | ||
| optional bytes payload = 3; | ||
| } | ||
|
Comment on lines
+15
to
+25
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. After yesterday's discussion I realized that this structure is not very well suited for governance mesages that are based on wormhole. Maybe we need something like this? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I like to have a fixed transaction layout and then have customisability in the payload layer. I see transaction as something for sequencer and content of it as something for the aggregator. It's good to have permissioning over who does what. And then, you can say that the sequencer only streams txs from verified pubkeys. Otherwise, you'd need to either think of continuing the tokenized gateway (which is kind of like sigs) or verifying wh messages (which is very expensive) |
||
|
|
||
| // Transaction contianing one of the valid Lazer Transactions | ||
| message LazerTransaction { | ||
| oneof payload { | ||
| // Expected transaction sent by Publishers | ||
| // May contain many individual updates to various feeds | ||
| PublisherUpdate publisher_update = 1; | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Usually
buildin and of itself isn't a goal -- usually you're building to do something else. My general advice is to document the actual things you might want to do in the docs (e.g. "run tests" or "run this example" etc) and let the build happen automatically with the task orchestratorThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah that makes sense. I will add in a followup PR an example showing how to use the SDK to create some of the types, sign them, and then encode them.