Introduction
In this tutorial, you will learn how to quickly access the internet when running code on the Golem network. You will get familiar with the concept of Golem manifest, outbound, and some security policies that are in place to protect the providers from malicious code.
This tutorial is designed for: OS X 10.14+, Ubuntu 18.04 or 20.04, and Windows
Prerequisites
- Yagna service installed and running with the
try_golem
app-key configured (see instructions).
Overview
In this tutorial, you will create a requestor script that will download a code from the ipfs.io
site to a provider. To achieve the goal you will use the outbound feature.
The ipfs.io URL was selected as a target URL for the example, as it is included in the default provider’s whitelist. You can check here for other entries. Please note that a provider can choose to add, remove, or completely wipe the whitelist.
As the requestor needs to list all URLs they want to access in a manifest file, you need to create one and provide it when creating a new TaskExecutor. There is a CLI tool that we will use to create this manifest.
You can read more about outbound feature here.
Let’s code.
Initialize the project
First, create a project directory and navigate there:
mkdir outbound-example
cd outbound-example
Then initialise the project and install JS SDK.
npm init
npm install @golem-sdk/golem-js
Next, install Golem SDK CLI
- a companion tool that will facilitate manifest creation.
npm install -g @golem-sdk/cli
Manifest creation
Once you have the project, open a terminal and run:
golem-sdk manifest create golem/examples-outbound:latest
This will create a basic manifest.json
file. You will use it to inform the provider what GVMI image we will be using. The manifest contains also your application version, application name, and description, all read from your package.json
file (you can edit this information if you want).
Adding outbound configuration
The next step is to configure our manifest, so you can access a public URL. The CLI also has a handy command that will take care of that for you:
golem-sdk manifest net add-outbound https://ipfs.io
This has added https://ipfs.io
as the URL you want to access from the provider node. The command can be run multiple times to add more URLs or you can pass them all at once.
Now our manifest is ready, you can start coding the application.
Requestor script
The application will be very simple. It will use curl
to download an example image from IPFS to demonstrate how to enable and access the internet from the Golem SDK.
Let’s start with a simple boilerplate, copy the following code to a javascript file:
import { TaskExecutor } from '@golem-sdk/golem-js'
import { readFile } from 'fs/promises'
;(async function main() {
const executor = await TaskExecutor.create({})
try {
// Your code goes here
} catch (err) {
console.error('The task failed due to', err)
} finally {
await executor.end()
}
})()
The snippet above is using async/await to synchronize asynchronous calls, for simplicity and compatibility, we wrap all the code into an asynchronous main function. The next thing to do is to correctly initialize the `TaskExecutor``. For this purpose, let's use the manifest file we’ve just created.
At the top of the main function replace the executor initialization with the following:
// Load the manifest file.
const manifest = await readFile(`./manifest.json`)
// Create and configure a TaskExecutor instance.
const executor = await TaskExecutor.create({
capabilities: ['inet', 'manifest-support'],
yagnaOptions: { apiKey: 'try_golem' },
manifest: manifest.toString('base64'),
})
This is the most important part. First, it is specifying additional requirements to the demand:
- 'inet' - indicates the script requires outbound service
- 'manifest-support' - informs, that it will use manifest to specify a demand.
Instead of providing an image tag or hash, it uses a manifest file that describes what will be run on providers.
Please note the loaded manifest is encoded to base64.
yagnaOptions: { apiKey: 'try_golem' }
- defined the api key, to get access to the Yagna service. This particular key is available if you start the yagna according to the procedure provided in the installation example, you can also configure your unique keys. See here for instructions.
In this example, you will simply fetch an example file from IPFS using the curl
command, available in our GVMI image. So first let’s save the URL near the top of the file (just after the imports):
import { TaskExecutor } from '@golem-sdk/golem-js'
import { readFile } from 'fs/promises'
const url =
"https://ipfs.io/ipfs/bafybeihkoviema7g3gxyt6la7vd5ho32ictqbilu3wnlo3rs7ewhnp7lly";
And finally, let’s execute some code on the provider. You will run a single task on the provider, using the TaskExecutor.run() function. To make this work, put the following code in the try/catch block:
await executor.run(async (ctx) => {
const result = await ctx.run(`curl ${url} -o /golem/work/example.jpg`);
console.log((await ctx.run("ls -l")).stdout);
if (result.result === "Ok") {
console.log("File downloaded!");
} else {
console.error("Failed to download the file!", result.stderr);
}
});
And that’s it! Now, make sure your yagna service is running and you can start this script.
This is how the entire file should look like:
import { TaskExecutor } from "@golem-sdk/golem-js";
import { readFile } from "fs/promises";
const url =
"https://ipfs.io/ipfs/bafybeihkoviema7g3gxyt6la7vd5ho32ictqbilu3wnlo3rs7ewhnp7lly";
(async function main() {
// Load the manifest.
const manifest = await readFile(`./manifest.json`);
// Create and configure a TaskExecutor instance.
const executor = await TaskExecutor.create({
capabilities: ["inet", "manifest-support"],
yagnaOptions: { apiKey: "try_golem" },
manifest: manifest.toString("base64"),
});
try {
await executor.run(async (ctx) => {
const result = await ctx.run(`curl ${url} -o /golem/work/example.jpg`);
console.log((await ctx.run("ls -l")).stdout);
if (result.result === "Ok") {
console.log("File downloaded!");
} else {
console.error("Failed to download the file!", result.stderr);
}
});
} catch (err) {
console.error("The task failed due to", err);
} finally {
await executor.end();
}
})();
You can run it now. In the output, you should see “File downloaded!” between log lines and the output of the ls -l
command showing th size of the fole downloaded . That means the code works.
- Another outbound example
Default Golem whitelist
More on the Payload Manifest