Skip to content
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

Remove requirement of providing an explicit staking target #20

Merged
merged 2 commits into from
May 2, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 57 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,7 @@ import { StakingClient } from "@coinbase/staking-client-library-ts";

const client = new StakingClient();

client.Ethereum.stake(
'holesky',
true,
'0xdb816889F2a7362EF242E5a717dfD5B38Ae849FE', // replace with your wallet address
'0xA55416de5DE61A0AC1aa8970a280E04388B1dE4b',
'123',
)
client.Ethereum.stake('holesky', '0xdb816889F2a7362EF242E5a717dfD5B38Ae849FE', '123')
.then((workflow) => {
console.log('Workflow created %s', workflow.name);
})
Expand All @@ -57,7 +51,40 @@ client.Ethereum.stake(
<summary>Output</summary>

```text
Workflow created: projects/62376b2f-3f24-42c9-9025-d576a3c06d6f/workflows/ffbf9b45-c57b-49cb-a4d5-fdab66d8cb25
Workflow created workflows/c34df125-a989-438d-8451-bd403423986a
```

</details>

### Stake SOL :diamond_shape_with_a_dot_inside:

This code sample creates a SOL staking workflow. View the full code sample [here](examples/solana/create-workflow.ts)

<details open>
<summary>Code Sample</summary>

```typescript
// examples/solana/create-workflow.ts
import { StakingClient } from "@coinbase/staking-client-library-ts";

const client = new StakingClient();

client.Solana.stake('devnet', '8rMGARtkJY5QygP1mgvBFLsE9JrvXByARJiyNfcSE5Z', '100000000')
.then((workflow) => {
console.log('Workflow created %s', workflow.name);
})
.catch(() => {
throw new Error(`Error creating workflow`);
});
```

</details>

<details>
<summary>Output</summary>

```text
Workflow created workflows/e6373b20-edf0-4cf9-91ea-709328d0d63e
```

</details>
Expand Down Expand Up @@ -153,6 +180,28 @@ client.Ethereum.listRewards(filter).then((resp) => {

</details>

## Build
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can make a Contributing.md and link that doc here? That way, someone who is trying to build/contribute to this codebase can refer to a different file than someone trying to use it. My preference would be to keep the top-level README as concise as possible.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, lets do that in a separate PR


Here are some helpful commands to build and lint the project:

### Generate client code

```shell
npm run gen
```

### Lint

```shell
npm run lint
```

### Lint Fix

```shell
npm run lint-fix
```

## Documentation

There are numerous examples in the [`examples directory`](./examples) to help get you started. For even more, refer to our [documentation website](https://docs.cdp.coinbase.com/) for detailed definitions, API specifications, integration guides, and more!
72 changes: 55 additions & 17 deletions docs/openapi/orchestration.swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -481,23 +481,7 @@
"in": "body",
"required": true,
"schema": {
"type": "object",
"properties": {
"step": {
"type": "integer",
"format": "int32",
"description": "The index of the step to be performed."
},
"data": {
"type": "string",
"description": "Transaction metadata. This is either the signed transaction or transaction hash depending on the workflow's broadcast method."
}
},
"description": "The request message for PerformWorkflowStep.",
"required": [
"step",
"data"
]
"$ref": "#/definitions/StakingServicePerformWorkflowStepBody"
}
}
],
Expand Down Expand Up @@ -745,6 +729,25 @@
"default": "BALANCE_STATE_UNSPECIFIED",
"description": "Represents the different states a stake account balance can have.\nUsed to check to see if stake is actively earning rewards or ready to be withdrawn.\n\n - BALANCE_STATE_UNSPECIFIED: The balance is not known.\n - BALANCE_STATE_INACTIVE: The balance is not actively staking.\n - BALANCE_STATE_ACTIVATING: The balance is in a warm up period and will activate in the next epoch.\n - BALANCE_STATE_ACTIVE: The balance is actively staking and earning rewards.\n - BALANCE_STATE_DEACTIVATING: The balance is in a cool down period and will be deactivated in the next epoch."
},
"StakingServicePerformWorkflowStepBody": {
"type": "object",
"properties": {
"step": {
"type": "integer",
"format": "int32",
"description": "The index of the step to be performed."
},
"data": {
"type": "string",
"description": "Transaction metadata. This is either the signed transaction or transaction hash depending on the workflow's broadcast method."
}
},
"description": "The request message for PerformWorkflowStep.",
"required": [
"step",
"data"
]
},
"WaitStepOutputWaitUnit": {
"type": "string",
"enum": [
Expand Down Expand Up @@ -809,6 +812,36 @@
},
"description": "The amount of a token you wish to perform an action\nwith."
},
"v1BulkTxStepOutput": {
"type": "object",
"properties": {
"unsignedTxs": {
"type": "array",
"items": {
"type": "string"
},
"description": "The unsigned transactions that must be signed and broadcasted.",
"readOnly": true
},
"state": {
"$ref": "#/definitions/v1BulkTxStepOutputState",
"description": "The state of the bulk tx step.",
"readOnly": true
}
},
"description": "The details of multiple transactions being constructed and broadcasted to the network."
},
"v1BulkTxStepOutputState": {
"type": "string",
"enum": [
"STATE_UNSPECIFIED",
"STATE_IN_PROGRESS",
"STATE_FAILED",
"STATE_COMPLETED"
],
"default": "STATE_UNSPECIFIED",
"description": "State defines an enumeration of states for a staking transaction.\n\n - STATE_UNSPECIFIED: Unspecified transaction state.\n - STATE_IN_PROGRESS: Txs construction in progress.\n - STATE_FAILED: Tx construction failed.\n - STATE_COMPLETED: Tx construction completed."
},
"v1Contract": {
"type": "object",
"properties": {
Expand Down Expand Up @@ -1524,6 +1557,11 @@
"$ref": "#/definitions/v1ProvisionInfraStepOutput",
"description": "The details for provisioned infrastructure.",
"readOnly": true
},
"bulkTxStepOutput": {
"$ref": "#/definitions/v1BulkTxStepOutput",
"description": "The bulk tx step output (e.g. transaction metadata such as unsigned tx, signed tx etc).",
"readOnly": true
}
},
"description": "The information for a step in the workflow.",
Expand Down
6 changes: 3 additions & 3 deletions docs/openapi/rewards.swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,7 @@
},
"date": {
"type": "string",
"title": "The date of the reward in format 'YYYY-MM-DD' in UTC.",
"description": "The date of the reward in format 'YYYY-MM-DD' in UTC.",
"readOnly": true
},
"aggregationUnit": {
Expand Down Expand Up @@ -454,7 +454,7 @@
"readOnly": true
}
},
"title": "Rewards earned within a particular period of time."
"description": "Rewards earned within a particular period of time."
},
"v1RewardRate": {
"type": "object",
Expand Down Expand Up @@ -537,7 +537,7 @@
"readOnly": true
}
},
"title": "The representation of a staking activity at a particular point in time."
"description": "The representation of a staking activity at a particular point in time."
},
"v1USDValue": {
"type": "object",
Expand Down
8 changes: 1 addition & 7 deletions examples/ethereum/create-and-process-workflow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import { calculateTimeDifference } from '../../src/utils/date';

const privateKey: string = ''; // replace with your private key
const stakerAddress: string = '0xdb816889F2a7362EF242E5a717dfD5B38Ae849FE'; // replace with your staker address
const integrationAddress: string = '0xA55416de5DE61A0AC1aa8970a280E04388B1dE4b'; // replace with your integration address
const amount: string = '123'; // replace with your amount
const network: string = 'holesky'; // replace with your network

Expand All @@ -33,12 +32,7 @@ async function stakePartialEth(): Promise<void> {

try {
// Create a new eth kiln stake workflow
workflow = await client.Ethereum.stake(
network,
stakerAddress,
integrationAddress,
amount,
);
workflow = await client.Ethereum.stake(network, stakerAddress, amount);

workflowId = workflow.name?.split('/').pop() || '';
if (workflowId == null || workflowId === '') {
Expand Down
12 changes: 3 additions & 9 deletions examples/ethereum/create-workflow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { StakingClient } from '../../src/client/staking-client';
import { Workflow } from '../../src/gen/coinbase/staking/orchestration/v1/workflow.pb';

const stakerAddress: string = '0xdb816889F2a7362EF242E5a717dfD5B38Ae849FE'; // replace with your staker address
const integrationAddress: string = '0xA55416de5DE61A0AC1aa8970a280E04388B1dE4b'; // replace with your integration address
const amount: string = '123'; // replace with your amount
const network: string = 'holesky'; // replace with your network

Expand All @@ -17,14 +16,9 @@ async function stakePartialEth(): Promise<void> {

try {
// Create a new eth kiln stake workflow
workflow = await client.Ethereum.stake(
network,
stakerAddress,
integrationAddress,
amount,
);

console.log('Workflow created %s ...', workflow.name);
workflow = await client.Ethereum.stake(network, stakerAddress, amount);
drohit-cb marked this conversation as resolved.
Show resolved Hide resolved

console.log(JSON.stringify(workflow, null, 2));
} catch (error) {
let errorMessage = '';

Expand Down
8 changes: 1 addition & 7 deletions examples/solana/create-and-process-workflow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import { calculateTimeDifference } from '../../src/utils/date';

const privateKey: string = ''; // replace with your private key
const walletAddress: string = ''; // replace with your wallet address
const validatorAddress: string = 'beefKGBWeSpHzYBHZXwp5So7wdQGX6mu4ZHCsH3uTar'; // replace with your validator address
const amount: string = '100000000'; // replace with your amount. For solana it should be >= 0.1 SOL
const network: string = 'mainnet'; // replace with your network

Expand All @@ -33,12 +32,7 @@ async function stakeSolana(): Promise<void> {

try {
// Create a new solana stake workflow
workflow = await client.Solana.stake(
network,
walletAddress,
validatorAddress,
amount,
);
workflow = await client.Solana.stake(network, walletAddress, amount);

workflowId = workflow.name?.split('/').pop() || '';
if (workflowId == null || workflowId === '') {
Expand Down
16 changes: 5 additions & 11 deletions examples/solana/create-workflow.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { StakingClient } from '../../src/client/staking-client';
import { Workflow } from '../../src/gen/coinbase/staking/orchestration/v1/workflow.pb';

const walletAddress: string = ''; // replace with your wallet address
const validatorAddress: string = 'beefKGBWeSpHzYBHZXwp5So7wdQGX6mu4ZHCsH3uTar'; // replace with your validator address
const walletAddress: string = '8rMGARtkJY5QygP1mgvBFLsE9JrvXByARJiyNfcSE5Z'; // replace with your wallet address
const amount: string = '100000000'; // replace with your amount. For solana it should be >= 0.1 SOL
const network: string = 'mainnet'; // replace with your network
const network: string = 'devnet'; // replace with your network

const client = new StakingClient();

Expand All @@ -17,14 +16,9 @@ async function stakeSolana(): Promise<void> {

try {
// Create a new solana stake workflow
workflow = await client.Solana.stake(
network,
walletAddress,
validatorAddress,
amount,
);

console.log('Workflow created %s ...', workflow.name);
workflow = await client.Solana.stake(network, walletAddress, amount);

console.log(JSON.stringify(workflow, null, 2));
} catch (error) {
let errorMessage = '';

Expand Down
2 changes: 1 addition & 1 deletion scripts/generate-client.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
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' {} \;
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/nameworkflows/name/g' {} \;
6 changes: 3 additions & 3 deletions src/client/protocols/ethereum-kiln-staking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ export class Ethereum {
async stake(
network: string,
stakerAddress: string,
integratorContractAddress: string,
amount: string,
integratorContractAddress?: string,
): Promise<Workflow> {
const req: CreateWorkflowRequest = {
workflow: {
Expand All @@ -51,8 +51,8 @@ export class Ethereum {
async unstake(
network: string,
stakerAddress: string,
integratorContractAddress: string,
amount: string,
integratorContractAddress?: string,
): Promise<Workflow> {
const req: CreateWorkflowRequest = {
workflow: {
Expand All @@ -76,7 +76,7 @@ export class Ethereum {
async claimStake(
network: string,
stakerAddress: string,
integratorContractAddress: string,
integratorContractAddress?: string,
): Promise<Workflow> {
const req: CreateWorkflowRequest = {
workflow: {
Expand Down
2 changes: 1 addition & 1 deletion src/client/protocols/solana-staking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ export class Solana {
async stake(
network: string,
walletAddress: string,
validatorAddress: string,
amount: string,
validatorAddress?: string,
): Promise<Workflow> {
const req: CreateWorkflowRequest = {
workflow: {
Expand Down
6 changes: 3 additions & 3 deletions src/client/staking-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ export class StakingClient {
return StakingService.ViewStakingContext(req, initReq);
}

// Create a workflow under a given project. This function takes the entire req object as input.
// Create a workflow under a project inferred from your API key. This function takes the entire req object as input.
drohit-cb marked this conversation as resolved.
Show resolved Hide resolved
// Use the protocol-specific helper functions like Ethereum.Stake to create a protocol and action specific workflow.
async createWorkflow(req: CreateWorkflowRequest): Promise<Workflow> {
const path: string = `/v1/workflows`;
Expand All @@ -143,7 +143,7 @@ export class StakingClient {
return StakingService.CreateWorkflow(req, initReq);
}

// Get a workflow given its project and workflow id.
// Get a workflow given workflow id and project inferred from your API key.
drohit-cb marked this conversation as resolved.
Show resolved Hide resolved
drohit-cb marked this conversation as resolved.
Show resolved Hide resolved
async getWorkflow(workflowId: string): Promise<Workflow> {
const name: string = `workflows/${workflowId}`;
const path: string = `/v1/${name}`;
Expand Down Expand Up @@ -183,7 +183,7 @@ export class StakingClient {
return StakingService.PerformWorkflowStep(req, initReq);
}

// List workflows for a given project.
// List workflows for your project inferred from your API key.
drohit-cb marked this conversation as resolved.
Show resolved Hide resolved
async listWorkflows(
pageSize: number = 100,
filter: string = '',
Expand Down
Loading
Loading