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

Release beta to master #1131

Merged
merged 15 commits into from
Nov 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
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
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
matrix:
# Make sure you're addressing it to the minor version, as sometimes macos was picking 20.9 while others 20.10
# and that caused issues with rollup
node-version: [18.19.x, 20.10.x]
node-version: [18.20.x, 20.18.x, 22.x]
os: [ubuntu-latest, windows-latest, macos-latest]

runs-on: ${{ matrix.os }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ jobs:
matrix:
# Make sure you're addressing it to the minor version, as sometimes macos was picking 20.9 while others 20.10
# and that caused issues with rollup
node-version: [18.19.x, 20.10.x]
node-version: [18.20.x, 20.18.x, 22.x]
os: [ubuntu-latest, windows-latest, macos-latest]

runs-on: ${{ matrix.os }}
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ distributed, computational loads through Golem Network.
disposal.
- [Usage documentation](./docs/USAGE.md) - Explore supported usage and implementation patterns.
- [Feature documentation](./docs/FEATURES.md) - Description of interesting features that we've prepared.
- [Plugin documentation](./docs/PLUGINS.md) - Learn how to write plugins that can enhance `GolemNetwork` user's experience by introducing code reusability and modularity.

## Installation

Expand Down
135 changes: 135 additions & 0 deletions docs/PLUGINS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
# Golem Network Plugins

Welcome to the Golem Network Plugins documentation! Here we aim to provide friendly and comprehensive guidance for
developers interested in creating reusable and generic modules for the Golem Network.

## Why do we need plugins?

### Requestor script maintainability

As detailed in our [concepts](./CONCEPTS.md) guide, the SDK models the intricate domain of the Golem Network by defining
the `GolemNetwork` class, which is built from various subdomains of the project.

If you've written a few `golem-js` scripts, you might have noticed your scripts growing quickly as you add logic for
market, activity, or payment events. This can make your main requestor script bulky and difficult to maintain.

Golem Plugins offer a solution to this problem by providing a simple interface for attaching different types of logic to
your `GolemNetwork` instance. This allows you to break down your large scripts into smaller, more manageable modules and
use `GolemNetwork.use` to integrate them into your main script seamlessly.

### Opening the ecosystem for extensions

We warmly invite other developers to [contribute](./CONTRIBUTING.md) to our ecosystem. We recognize that creating core
SDK components requires considerable effort and dedication.

To make contributions more accessible, we're introducing a new pathway for developers familiar with `golem-js` to create
their `GolemNetwork` plugins and share them via NPM.

## Example plugins

### Provider tracker

Let's say you want to track unique providers on the network for statistical purposes. Here's an example plugin:

```ts
import { GolemNetwork, GolemPluginInitializer } from "@golem-sdk/golem-js";

/**
* Example plugin that tracks unique provider ID/name pairs on the market
*/
const providerTracker: GolemPluginInitializer = (glm) => {
const seenProviders: { id: string; name: string }[] = [];

glm.market.events.on("offerProposalReceived", (event) => {
const { id, name } = event.offerProposal.provider;
const providerInfo = { id, name };
if (!seenProviders.includes(providerInfo)) {
seenProviders.push(providerInfo);
console.log("Saw new provider %s named %s", id, name);
}
});

// Return a cleanup function that will be executed during the `disconnect`
return () => {
console.log("Provider tracker found a total of %d providers", seenProviders.length);
};
};
```

You can connect this plugin to your main script as follows:

```ts
const glm = new GolemNetwork();

// Register the plugin that will be initialized during `connect` call
glm.use(providerTracker);
```

#### Check GLM price before starting (asynchronous plugin)

If you want to avoid running your requestor script when the GLM price exceeds a certain USD value, you can capture this
policy with a reusable plugin:

```ts
import { GolemNetwork, GolemPluginInitializer } from "@golem-sdk/golem-js";

const checkGlmPriceBeforeStarting: GolemPluginInitializer<{
maxPrice: number;
}> = async (_glm, opts) => {
// Call an exchange to get the quotes
const response = await fetch("https://api.coinpaprika.com/v1/tickers/glm-golem");

if (!response.ok) {
throw new Error("Failed to fetch GLM price");
} else {
// Execute your logic
const data = await response.json();
const price = parseFloat(data.quotes.USD.price);

console.log("=== GLM Price ===");
console.log("GLM price is", price);
console.log("=== GLM Price ===");

if (price > opts.maxPrice) {
// Throwing inside the plugin will make `connect` throw, and then prevent
// execution of the rest of the script
throw new Error("GLM price is too high, won't compute today :O");
}
}
};
```

Here's how to use the plugin:

```ts
const glm = new GolemNetwork();

glm.use(checkGlmPriceBeforeStarting, {
maxPrice: 0.5,
});
```

## Plugin lifecycle and cleanup

When you register plugins using `GolemNetwork.use`, they are initialized during the `GolemNetwork.connect` call. If any
plugin throws an error during initialization, the entire `connect` method will throw an error.

Each plugin can return a cleanup function, which will be executed during `GolemNetwork.disconnect`. This is particularly
useful for plugins that allocate resources, use timers, or open database connections.

## Synchronous and asynchronous plugins

The SDK supports both synchronous and asynchronous plugins. You can register all of them using the `GolemNetwork.use`
method, and they will be initialized sequentially in the order they were registered.

## Dear developers!

### Become a Golem Network Creator

We hope you find this guide helpful and enjoy contributing to the Golem Network. Happy coding!

### Community developed plugins

Here's the list of plugins developed by Golem's Community.

> Let us know about your plugins so we can feature them in our documentation.
Loading
Loading