Skip to content

Commit

Permalink
Merge branch 'master' into python
Browse files Browse the repository at this point in the history
  • Loading branch information
jalas167 authored Oct 26, 2023
2 parents cb43173 + d81b22a commit 73c3fe7
Show file tree
Hide file tree
Showing 194 changed files with 3,176 additions and 3,165 deletions.
2 changes: 1 addition & 1 deletion src/components/CustomError.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import Link from 'next/link'
export const CustomError = ({ errorCode, title, description }) => {
return (
<>
<main className="grid min-h-full place-items-center bg-white px-6 py-24 dark:bg-darkbg sm:py-32 lg:px-8">
<main className="not-prose grid min-h-full place-items-center bg-white px-6 py-24 dark:bg-darkbg sm:py-32 lg:px-8">
<div className="text-center">
<p className="text-base font-semibold text-primary dark:text-darkprimary">
{errorCode}
Expand Down
2 changes: 1 addition & 1 deletion src/components/Layout.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ function useTableOfContents(tableOfContents) {
if (tableOfContents.length === 0) return
let headings = getHeadings(tableOfContents)
function onScroll() {
let top = window.scrollY
let top = window.scrollY + 20
let current = headings[0].id
for (let heading of headings) {
if (top >= heading.top) {
Expand Down
2 changes: 1 addition & 1 deletion src/components/Navigation.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ export const NavigationItem = ({ item, isActive }) =>
</Link>
) : (
<span
className={clsx('py-0.5 text-sm', {
className={clsx('py-0.5 text-sm text-left', {
'text-primary dark:text-darkprimary': isActive,
})}
>
Expand Down
2 changes: 1 addition & 1 deletion src/components/Search.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ function SearchResult({ result, autocomplete, collection, query }) {
<div
id={`${id}-title`}
aria-hidden="true"
className="relative rounded-lg py-2 pl-3 text-sm text-slate-700 group-aria-selected:bg-slate-100 group-aria-selected:text-primary dark:text-white/50 dark:group-aria-selected:bg-slate-700/30 dark:group-aria-selected:text-white/50"
className="relative hover:cursor-pointer rounded-lg py-2 pl-3 text-sm text-slate-700 group-aria-selected:bg-slate-100 group-aria-selected:text-primary dark:text-white/50 dark:group-aria-selected:bg-slate-700/30 dark:group-aria-selected:text-white/50"
>
<div className="w-3/5 break-words md:w-3/4">
<HighlightQuery text={result.title} query={query} />
Expand Down
200 changes: 200 additions & 0 deletions src/markdoc/partials/docs/accessing-the-internet.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
## 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.

{% alert level="info" %}

This tutorial is designed for: OS X 10.14+, Ubuntu 18.04 or 20.04, and Windows

{% /alert %}

## Prerequisites

- Yagna service installed and running with the `try_golem` app-key configured ([see instructions](/docs/creators/javascript/examples/tools/yagna-installation-for-requestors)).

## Overview

In this tutorial, you will create a requestor script that will download a code from the `github.com` site to a provider. To achieve the goal you will use the outbound feature.

The github.com URL was selected as a target URL for the example, as it is included in the default provider’s whitelist. You can check [here](https://github.com/golemfactory/ya-installer-resources/tree/main/whitelist) 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 [here](/docs/creators/javascript/guides/accessing-internet).

Let’s code.

## Initialize the project

First, create a project directory and navigate there:

```bash
mkdir outbound-example
cd outbound-example
```

Then initialise the project and install JS SDK.

```bash
npm init
npm install @golem-sdk/golem-js
```

Next, install `Golem SDK CLI` - a companion tool that will facilitate manifest creation.

```shell
npm install -g @golem-sdk/cli
```

## Manifest creation

Once you have the project, open a terminal and run:

```bash
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 Golem VM image (GVMI) 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:

```bash
golem-sdk manifest net add-outbound https://github.com
```

This has added https://github.com 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 a release of the Golem SDK from GitHub. While this can be achieved without using Golem, this is just a demonstration of 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:

```javascript
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:

```javascript
// 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 a manifest to specify the 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 own unique keys. See [here](/docs/creators/javascript/examples/using-app-keys) for instructions.

In this example, you will simply fetch a release of the Golem SDK from GitHub using the `curl` command, available in our Golem VM image. So first let’s save the URL near the top of the file (just after the imports):

```javascript
import { TaskExecutor } from '@golem-sdk/golem-js'
import { readFile } from 'fs/promises'

const url =
'https://github.com/golemfactory/golem-js/archive/refs/tags/v0.11.2.tar.gz'
```

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:

```javascript
await executor.run(async (ctx) => {
const result = await ctx.run(`curl ${url} -o /golem/work/golem-js.tar.gz`)

if (result.result === 'Ok') {
console.log('SDK downloaded!')
} else {
console.error('Failed to download the SDK!', 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:

```javascript
import { TaskExecutor } from '@golem-sdk/golem-js'
import { readFile } from 'fs/promises'

const url =
'https://github.com/golemfactory/golem-js/archive/refs/tags/v0.11.2.tar.gz'

;(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/golem-js.tar.gz`)

if (result.result === 'Ok') {
console.log('SDK downloaded!')
} else {
console.error('Failed to download the SDK!', 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 “SDK downloaded!” between the log lines. That means the code works.

{% docnavigation title="Next steps" %}

- Another [outbound example](https://github.com/golemfactory/golem-js/tree/master/examples/external-request)

{% /docnavigation %}

{% docnavigation title="See also" %}

- Default Golem [whitelist](https://github.com/golemfactory/ya-installer-resources/tree/main/whitelist)

- More on the [Payload Manifest](/docs/golem/payload-manifest)

{% /docnavigation %}
96 changes: 96 additions & 0 deletions src/markdoc/partials/quickstarts/golem-in-a-browser.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
## Introduction

In most of our examples, we demonstrate how to run a requestor script in Node.js. However, you can also run your scripts in a browser context. This example will explain how to do it.

{% alert level="info" %}

Before getting started, you need to install and launch the Yagna service in version 0.13.0+. Note that such a version is available as a `release candidate`. It can be installed using instructions for manual Yagna installation available [here](/docs/creators/javascript/examples/tools/yagna-installation-for-requestors).

{% /alert %}

{% alert level="warning" %}
In addition, follow the instructions to [set up the app-key](/docs/creators/javascript/examples/tools/yagna-installation-for-requestors), but start the Yagna with a parameter that allows you to handle REST API requests with a CORS policy. You can do this by running the following command:

{% tabs %}
{% tab label="MacOS / Linux" %}

```bash
yagna service run --api-allow-origin='http://localhost:8080'
```

{% /tab %}
{% tab label="Windows" %}

```console
yagna service run --api-allow-origin=http://localhost:8080
```

{% /tab %}

{% /tabs %}

The `--api-allow-origin` value should be set to the URL where your web application will be served.
In this example, we will use `http-server`.

{% /alert %}

## Setting up the project

```bash
mkdir web_golem
cd web_golem
npm install --global http-server
```

This will install the `http-server` utility to host our web page, where we will run our Golem app.

## HTML page

Next, we'll create the main `index.html` file with the following content:

{% codefromgithub url="https://raw.githubusercontent.com/golemfactory/golem-js/master/examples/docs-examples/quickstarts/web-quickstart/index.html" language="javascript" /%}

In this layout, there are three elements:

- A "Run" button, which executes the script on Golem
- A "Results" container, which displays the results
- A "Logs" container, which displays the API logs

## Requestor script

Next, we'll create a `requestor.mjs` file with the following content:

{% codefromgithub url="https://raw.githubusercontent.com/golemfactory/golem-js/master/examples/docs-examples/quickstarts/web-quickstart/requestor.mjs" language="javascript" /%}

Note the file contains the `run()` function that creates the body of the requestor script (similar to the one we use in Node.js) and a set of helper functions that will let us present the logs and results in the browser window.

Now, ensure you:

- have your Yagna APP key set to `try_golem` (as shown in the yagna installation instruction) and
- have a running Yagna service started with the `--api-allow-origin` properly set to `http://localhost:8080`

Launch `http-server` in the project folder.

```bash
http-server
```

{% alert level="warning" %}

If, instead of using the `try_golem` app key defined by using the `YAGNA_AUTO_CONF` variable, you have created a unique app key, make sure you update the requestor.mjs code and set the proper value there. See [here](/docs/creators/javascript/examples/using-app-keys#js-task-api-examples-using-app-keys) for deails.

{% /alert %}

We should see our app available in the browser.

[Open localhost](http://localhost:8080/index)

If you click the **Run** button, after a while, in the result container, you should get the result of the script: `Hello World` and see the logs of executed commands in the log container.

![Output logs](/browser_log.png)

{% docnavigation title="Next steps" %}

- [Golem in web browser example explained](/docs/creators/javascript/tutorials/running-in-browser)

{% /docnavigation %}
Loading

0 comments on commit 73c3fe7

Please sign in to comment.