Skip to content

Commit

Permalink
Merge pull request #16 from coinbase/depend-on-bsr
Browse files Browse the repository at this point in the history
This PR modifies the code generation process to depend on BSR registries rather than depending on protos directly in the same repo. This allows us to remove the protos files from this repo and simplify the overall `buf` workflow.
  • Loading branch information
ProfMoo authored Apr 23, 2024
2 parents b03c0d0 + 2a12cff commit 916850d
Show file tree
Hide file tree
Showing 26 changed files with 1,129 additions and 207 deletions.
281 changes: 165 additions & 116 deletions docs/openapi/orchestration.swagger.json

Large diffs are not rendered by default.

93 changes: 23 additions & 70 deletions docs/openapi/rewards.swagger.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"swagger": "2.0",
"info": {
"title": "Coinbase Rewards API",
"description": "API that delivers crypto-forward onchain staking-related rewards data",
"title": "Rewards Service",
"description": "Service that provides access to onchain, staking-related rewards data.",
"version": "v1"
},
"tags": [
Expand Down Expand Up @@ -30,66 +30,6 @@
"application/json"
],
"paths": {
"/v1/{name}": {
"get": {
"summary": "Returns a staking balance",
"description": "Returns a specific staking balance for an address on the specific protocol at a particular point in time.",
"operationId": "RewardService_GetStake",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/v1Stake"
}
},
"400": {
"description": "The request attempted has invalid parameters",
"schema": {
"example": {
"code": 3,
"message": "Invalid stake ID. \u003cRemediation assistance here\u003e.",
"details": []
}
}
},
"401": {
"description": "Returned if authentication information is invalid",
"schema": {
"example": "Unauthorized"
}
},
"500": {
"description": "Returned when an internal server error happens.",
"schema": {
"example": {
"code": 3,
"message": "Internal server error.",
"details": []
}
}
},
"default": {
"description": "An unexpected error response.",
"schema": {
"$ref": "#/definitions/rpcStatus"
}
}
},
"parameters": [
{
"name": "name",
"description": "The resource name of the stake to retrieve.\nFormat: protocols/{protocol}/stakes/{stake}",
"in": "path",
"required": true,
"type": "string",
"pattern": "protocols/[^/]+/stakes/[^/]+"
}
],
"tags": [
"Stake"
]
}
},
"/v1/{parent}/rewards": {
"get": {
"summary": "List and filter rewards",
Expand Down Expand Up @@ -197,7 +137,7 @@
},
{
"name": "filter",
"description": "[AIP-160](https://google.aip.dev/160) format compliant filter. Supported protocols are 'ethereum', 'solana', and 'cosmos'.\nSupplying other protocols will return an error.\n* **Ethereum**:\n - Fields:\n - `address` - A ethereum validator public key.\n - `epoch` - An ethereum epoch. Supports epoch comparisons (ex: `epoch \u003e= 1000 AND epoch \u003c= 2000`).\n - Example(s):\n - `\"address='0xac53512c39d0081ca4437c285305eb423f474e6153693c12fbba4a3df78bcaa3422b31d800c5bea71c1b017168a60474' AND epoch \u003e= 234640 AND epoch \u003c 234645\"`\n\n* **Solana**:\n - Fields:\n - `address` - A solana validator or delegator address.\n - `epoch` - A solana epoch. Supports epoch comparisons (ex: `epoch \u003e= 1000 AND epoch \u003c= 2000`).\n - Example(s):\n - `\"address='beefKGBWeSpHzYBHZXwp5So7wdQGX6mu4ZHCsH3uTar' AND epoch \u003e= 440 AND epoch \u003c 450\"`\n\n* **Cosmos**:\n - Fields:\n - `address` - A cosmos validator or delegator address (ex: `cosmosvaloper1c4k24jzduc365kywrsvf5ujz4ya6mwympnc4en` and `cosmos1c4k24jzduc365kywrsvf5ujz4ya6mwymy8vq4q`)\n - `date` - A date in format 'YYYY-MM-DD'. Supports multiple comparisons (ex: `date \u003e= '2023-07-01' AND date \u003c= '2023-07-31'`).\n - Example(s):\n - `address='cosmos1mfduj0qax6ut8rd6cfc4j0ds06z0mwlhrljhqh' AND date = '2023-10-16'`",
"description": "[AIP-160](https://google.aip.dev/160) format compliant filter. Supported protocols are 'ethereum', 'solana', and 'cosmos'.\nSupplying other protocols will return an error.\n* **Ethereum**:\n - Fields:\n - `address` - A ethereum validator public key.\n - `date` - A date in format 'YYYY-MM-DD'. Supports multiple comparisons (ex: '2024-01-15).\n - `period_end_time` - A timestamp in RFC-3339 format. Supports multiple comparisons (ex: '2024-01-01T00:00:00Z' and '2024-01-15T00:00:00Z').\n - Example(s):\n - `\"address='0xac53512c39d0081ca4437c285305eb423f474e6153693c12fbba4a3df78bcaa3422b31d800c5bea71c1b017168a60474' AND date \u003e= '2024-01-01' AND date \u003c '2024-01-15'\"`\n - `\"address='0xac53512c39d0081ca4437c285305eb423f474e6153693c12fbba4a3df78bcaa3422b31d800c5bea71c1b017168a60474' AND period_end_time \u003e= '2024-01-01T00:00:00Z' AND period_end_time \u003c '2024-01-15T00:00:00Z'\"`\n - `\"address='0xac53512c39d0081ca4437c285305eb423f474e6153693c12fbba4a3df78bcaa3422b31d800c5bea71c1b017168a60474' AND date = '2024-01-01'\"`\n\n* **Solana**:\n - Fields:\n - `address` - A solana validator or delegator address.\n - `epoch` - A solana epoch. Supports epoch comparisons (ex: `epoch \u003e= 1000 AND epoch \u003c= 2000`).\n - `period_end_time` - A timestamp in RFC-3339 format. Supports multiple comparisons (ex: '2024-01-01T00:00:00Z' and '2024-01-15T00:00:00Z').\n - Example(s):\n - `\"address='beefKGBWeSpHzYBHZXwp5So7wdQGX6mu4ZHCsH3uTar' AND epoch \u003e= 540 AND epoch \u003c 550\"`\n - `\"address='beefKGBWeSpHzYBHZXwp5So7wdQGX6mu4ZHCsH3uTar' AND period_end_time \u003e= '2024-01-01T00:00:00Z' AND period_end_time \u003c '2024-01-15T00:00:00Z'\"`\n - `\"address='beefKGBWeSpHzYBHZXwp5So7wdQGX6mu4ZHCsH3uTar' AND epoch = 550\"`\n\n* **Cosmos**:\n - Fields:\n - `address` - A cosmos validator or delegator address (ex: `cosmosvaloper1c4k24jzduc365kywrsvf5ujz4ya6mwympnc4en` and `cosmos1c4k24jzduc365kywrsvf5ujz4ya6mwymy8vq4q`)\n - `date` - A date in format 'YYYY-MM-DD'. Supports multiple comparisons (ex: '2024-01-15).\n - `period_end_time` - A timestamp in RFC-3339 format. Supports multiple comparisons (ex: '2024-01-01T00:00:00Z' and '2024-01-15T00:00:00Z').\n - Example(s):\n - `\"address='cosmos1mfduj0qax6ut8rd6cfc4j0ds06z0mwlhrljhqh' AND date = '2024-11-16'\"`\n - `\"address='cosmos1mfduj0qax6ut8rd6cfc4j0ds06z0mwlhrljhqh' AND period_end_time \u003e= '2024-01-01T00:00:00Z' AND period_end_time \u003c '2024-01-15T00:00:00Z'\"`\n - `\"address='cosmos1mfduj0qax6ut8rd6cfc4j0ds06z0mwlhrljhqh' AND date = '2024-01-01'\"`",
"in": "query",
"required": false,
"type": "string"
Expand Down Expand Up @@ -279,7 +219,14 @@
},
{
"name": "filter",
"description": "[AIP-160](https://google.aip.dev/160) filter",
"description": "[AIP-160](https://google.aip.dev/160) format compliant filter. Supported protocols are 'ethereum', 'solana'.\nSupplying other protocols will return an error.\n* **Ethereum**:\n - Fields:\n - `address` - A ethereum validator public key.\n - `evaluation_time` - A timestamp in RFC-3339 format. Supports multiple comparisons (ex: '2024-01-01T00:00:00Z' and '2024-01-15T00:00:00Z').\n - Example(s):\n - `\"address='0xac53512c39d0081ca4437c285305eb423f474e6153693c12fbba4a3df78bcaa3422b31d800c5bea71c1b017168a60474'\"`\n - `\"address='0xac53512c39d0081ca4437c285305eb423f474e6153693c12fbba4a3df78bcaa3422b31d800c5bea71c1b017168a60474' AND evaluation_time \u003e= '2024-01-01T00:00:00Z' AND evaluation_time \u003c '2024-01-15T00:00:00Z'\"`\n\n* **Solana**:\n - Fields:\n - `address` - A solana staking address.\n - `evaluation_time` - A timestamp in RFC-3339 format. Supports multiple comparisons (ex: '2024-01-01T00:00:00Z' and '2024-01-15T00:00:00Z').\n - Example(s):\n - `\"address='beefKGBWeSpHzYBHZXwp5So7wdQGX6mu4ZHCsH3uTar'\"`\n - `\"address='beefKGBWeSpHzYBHZXwp5So7wdQGX6mu4ZHCsH3uTar' AND evaluation_time \u003e= '2024-01-01T00:00:00Z' AND evaluation_time \u003c '2024-01-15T00:00:00Z'\"`",
"in": "query",
"required": false,
"type": "string"
},
{
"name": "orderBy",
"description": "The order in which to sort the results.\n[AIP-132](https://google.aip.dev/132) compliant order_by field.\nThe default behavior, if not supplied, is 'evaluation_time desc'.\nExample(s):\n* 'evaluation_time desc', which returns Stakes starting with the most recent.\n* 'evaluation_time asc', which returns Stakes starting with the oldest available.\n* 'evaluation_time', which returns Stakes starting with the oldest available.",
"in": "query",
"required": false,
"type": "string"
Expand Down Expand Up @@ -379,6 +326,7 @@
},
"exp": {
"type": "string",
"format": "int64",
"description": "The number of decimals needed to convert from the raw numeric value to the most\ncommon denomination.",
"readOnly": true
},
Expand Down Expand Up @@ -472,13 +420,13 @@
"periodStartTime": {
"type": "string",
"format": "date-time",
"description": "The starting time of this reward period. Returned when querying by epoch.\nTimestamps are in UTC, conforming to the RFC-3339 spec (e.g. 2023-11-13T19:38:36Z). UTC offsets are not currently supported.\nField currently unavailable. Coming soon.",
"description": "The starting time of this reward period. Returned when querying by epoch.\nTimestamps are in UTC, conforming to the RFC-3339 spec (e.g. 2024-11-13T19:38:36Z).\nField currently unavailable. Coming soon.",
"readOnly": true
},
"periodEndTime": {
"type": "string",
"format": "date-time",
"description": "The ending time of this reward period. Returned when querying by epoch.\nTimestamps are in UTC, conforming to the RFC-3339 spec (e.g. 2023-11-13T19:38:36Z). UTC offsets are not currently supported.",
"description": "The ending time of this reward period. Returned when querying by epoch.\nTimestamps are in UTC, conforming to the RFC-3339 spec (e.g. 2024-11-13T19:38:36Z).",
"readOnly": true
},
"totalEarnedNativeUnit": {
Expand Down Expand Up @@ -519,7 +467,7 @@
"calculatedTime": {
"type": "string",
"format": "date-time",
"description": "The time at which this yield calculation was calculated.\nTimestamps are in UTC, conforming to the RFC-3339 spec (e.g. 2023-11-13T19:38:36Z). UTC offsets are not currently supported.",
"description": "The time at which this yield calculation was calculated.\nTimestamps are in UTC, conforming to the RFC-3339 spec (e.g. 2023-11-13T19:38:36Z).",
"readOnly": true
},
"calculationMethod": {
Expand All @@ -541,7 +489,7 @@
"evaluationTime": {
"type": "string",
"format": "date-time",
"description": "The time at which this balance was evaluated.\nTimestamps are in UTC, conforming to the RFC-3339 spec (e.g. 2023-11-13T19:38:36Z). UTC offsets are not currently supported.",
"description": "The time at which this balance was evaluated.\nTimestamps are in UTC, conforming to the RFC-3339 spec (e.g. 2023-11-13T19:38:36Z).",
"readOnly": true
},
"bondedStake": {
Expand Down Expand Up @@ -602,12 +550,17 @@
"conversionTime": {
"type": "string",
"format": "date-time",
"description": "The timestamp at which the USD value was sourced to convert the value into USD.\nThis value is as close to the time the reward was earned as possible.\nTimestamps are in UTC, conforming to the RFC-3339 spec (e.g. 2023-11-13T19:38:36Z). UTC offsets are not currently supported.",
"description": "The timestamp at which the USD value was sourced to convert the value into USD.\nThis value is as close to the time the reward was earned as possible.\nTimestamps are in UTC, conforming to the RFC-3339 spec (e.g. 2024-11-13T19:38:36Z).",
"readOnly": true
},
"amount": {
"$ref": "#/definitions/v1AssetAmount",
"description": "The USD value of the reward at the conversion time..",
"description": "The USD value of the reward at the conversion time.",
"readOnly": true
},
"conversionPrice": {
"type": "string",
"description": "The price of the native unit at the conversion time.",
"readOnly": true
}
},
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
"license": "Apache-2.0",
"scripts": {
"clean": "rimraf ./dist",
"gen": "npm run clean-gen && ./scripts/generate-client.sh",
"clean-gen": "rm -rf src/gen/* && rm -rf docs/openapi/*",
"build": "npm run clean && tsc",
"prepare": "npm run build",
"lint": "eslint . --ext .ts --ignore-pattern '/dist/*/*'",
Expand Down
11 changes: 11 additions & 0 deletions protos/buf.gen.orchestration.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
version: v1
plugins:
- name: grpc-gateway-ts
out: ./src/gen/
opt:
- paths=source_relative
- name: openapiv2
out: ./docs/openapi
opt:
- allow_merge=true
- merge_file_name=orchestration
11 changes: 11 additions & 0 deletions protos/buf.gen.rewards.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
version: v1
plugins:
- name: grpc-gateway-ts
out: ./src/gen/
opt:
- paths=source_relative
- name: openapiv2
out: ./docs/openapi
opt:
- allow_merge=true
- merge_file_name=rewards
6 changes: 6 additions & 0 deletions scripts/generate-client.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/bash

buf generate --template protos/buf.gen.orchestration.yaml buf.build/cdp/orchestration --path coinbase/staking/orchestration/v1 --include-imports --include-wkt
buf generate --template protos/buf.gen.rewards.yaml buf.build/cdp/rewards --path coinbase/staking/rewards/v1 --include-imports --include-wkt
# TODO: Remove this once the generation issue is fixed.
find ./src/gen -type f -exec sed -I '' -e 's/parentprotocols/parent/g' -e 's/parentprotocolsnetworks/parents/g' -e 's/parentnetworks/parent/g' -e 's/nameprojectsworkflows/name/g' -e 's/parentprojects/parent/g' -e 's/nameworkflows/name/g' {} \;
3 changes: 0 additions & 3 deletions src/client/protocols/ethereum-kiln-staking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ export class Ethereum {
amount: string,
): Promise<Workflow> {
const req: CreateWorkflowRequest = {
parent: `projects/${projectId}`,
workflow: {
action: `protocols/ethereum_kiln/networks/${network}/actions/stake`,
ethereumKilnStakingParameters: {
Expand All @@ -58,7 +57,6 @@ export class Ethereum {
amount: string,
): Promise<Workflow> {
const req: CreateWorkflowRequest = {
parent: `projects/${projectId}`,
workflow: {
action: `protocols/ethereum_kiln/networks/${network}/actions/unstake`,
ethereumKilnStakingParameters: {
Expand All @@ -84,7 +82,6 @@ export class Ethereum {
integratorContractAddress: string,
): Promise<Workflow> {
const req: CreateWorkflowRequest = {
parent: `projects/${projectId}`,
workflow: {
action: `protocols/ethereum_kiln/networks/${network}/actions/claim_stake`,
ethereumKilnStakingParameters: {
Expand Down
3 changes: 0 additions & 3 deletions src/client/protocols/solana-staking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ export class Solana {
amount: string,
): Promise<Workflow> {
const req: CreateWorkflowRequest = {
parent: `projects/${projectId}`,
workflow: {
action: `protocols/solana/networks/${network}/actions/stake`,
solanaStakingParameters: {
Expand All @@ -58,7 +57,6 @@ export class Solana {
amount: string,
): Promise<Workflow> {
const req: CreateWorkflowRequest = {
parent: `projects/${projectId}`,
workflow: {
action: `protocols/solana/networks/${network}/actions/unstake`,
solanaStakingParameters: {
Expand All @@ -84,7 +82,6 @@ export class Solana {
stakeAccountAddress: string,
): Promise<Workflow> {
const req: CreateWorkflowRequest = {
parent: `projects/${projectId}`,
workflow: {
action: `protocols/solana/networks/${network}/actions/claim_stake`,
solanaStakingParameters: {
Expand Down
1 change: 0 additions & 1 deletion src/client/staking-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,6 @@ export class StakingClient {
const initReq = await getAuthDetails(url, path, method);

const req: ListWorkflowsRequest = {
parent: parent,
pageSize: pageSize,
filter: filter,
};
Expand Down
4 changes: 2 additions & 2 deletions src/gen/coinbase/staking/orchestration/v1/api.pb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ export class StakingService {
return fm.fetchReq<CoinbaseStakingOrchestrationV1Action.ListActionsRequest, CoinbaseStakingOrchestrationV1Action.ListActionsResponse>(`/v1/${req["parent"]}/actions?${fm.renderURLSearchParams(req, ["parent"])}`, {...initReq, method: "GET"})
}
static CreateWorkflow(req: CoinbaseStakingOrchestrationV1Workflow.CreateWorkflowRequest, initReq?: fm.InitReq): Promise<CoinbaseStakingOrchestrationV1Workflow.Workflow> {
return fm.fetchReq<CoinbaseStakingOrchestrationV1Workflow.CreateWorkflowRequest, CoinbaseStakingOrchestrationV1Workflow.Workflow>(`/v1/${req["parent"]}/workflows`, {...initReq, method: "POST", body: JSON.stringify(req["workflow"], fm.replacer)})
return fm.fetchReq<CoinbaseStakingOrchestrationV1Workflow.CreateWorkflowRequest, CoinbaseStakingOrchestrationV1Workflow.Workflow>(`/v1/workflows`, {...initReq, method: "POST", body: JSON.stringify(req["workflow"], fm.replacer)})
}
static GetWorkflow(req: CoinbaseStakingOrchestrationV1Workflow.GetWorkflowRequest, initReq?: fm.InitReq): Promise<CoinbaseStakingOrchestrationV1Workflow.Workflow> {
return fm.fetchReq<CoinbaseStakingOrchestrationV1Workflow.GetWorkflowRequest, CoinbaseStakingOrchestrationV1Workflow.Workflow>(`/v1/${req["name"]}?${fm.renderURLSearchParams(req, ["name"])}`, {...initReq, method: "GET"})
}
static ListWorkflows(req: CoinbaseStakingOrchestrationV1Workflow.ListWorkflowsRequest, initReq?: fm.InitReq): Promise<CoinbaseStakingOrchestrationV1Workflow.ListWorkflowsResponse> {
return fm.fetchReq<CoinbaseStakingOrchestrationV1Workflow.ListWorkflowsRequest, CoinbaseStakingOrchestrationV1Workflow.ListWorkflowsResponse>(`/v1/${req["parent"]}/workflows?${fm.renderURLSearchParams(req, ["parent"])}`, {...initReq, method: "GET"})
return fm.fetchReq<CoinbaseStakingOrchestrationV1Workflow.ListWorkflowsRequest, CoinbaseStakingOrchestrationV1Workflow.ListWorkflowsResponse>(`/v1/workflows?${fm.renderURLSearchParams(req, [])}`, {...initReq, method: "GET"})
}
static PerformWorkflowStep(req: CoinbaseStakingOrchestrationV1Workflow.PerformWorkflowStepRequest, initReq?: fm.InitReq): Promise<CoinbaseStakingOrchestrationV1Workflow.Workflow> {
return fm.fetchReq<CoinbaseStakingOrchestrationV1Workflow.PerformWorkflowStepRequest, CoinbaseStakingOrchestrationV1Workflow.Workflow>(`/v1/${req["name"]}/step`, {...initReq, method: "POST", body: JSON.stringify(req, fm.replacer)})
Expand Down
28 changes: 28 additions & 0 deletions src/gen/coinbase/staking/orchestration/v1/ethereum.pb.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/* eslint-disable */
// @ts-nocheck
/*
* This file is a generated Typescript file for GRPC Gateway, DO NOT MODIFY
*/

import * as CoinbaseStakingOrchestrationV1Common from "./common.pb"

type Absent<T, K extends keyof T> = { [k in Exclude<keyof T, K>]?: undefined };
type OneOf<T> =
| { [k in keyof T]?: undefined }
| (
keyof T extends infer K ?
(K extends string & keyof T ? { [k in K]: T[K] } & Absent<T, K>
: never)
: never);

type BaseEthereumStakingParameters = {
}

export type EthereumStakingParameters = BaseEthereumStakingParameters
& OneOf<{ nativeStakeParameters: EthereumNativeStakeParameters }>

export type EthereumNativeStakeParameters = {
withdrawalAddress?: string
feeRecipient?: string
amount?: CoinbaseStakingOrchestrationV1Common.Amount
}
Loading

0 comments on commit 916850d

Please sign in to comment.