├── .github
├── CODEOWNERS
└── workflows
│ └── codeowners.yml
├── .gitignore
├── .vscode
├── extensions.json
├── markdown.code-snippets
└── settings.json
├── README.md
├── babel.config.js
├── blog
├── 2021-09-03-marine-rs-sdk-test-update.md
├── 2021-09-08-aqua-compiler-0.3.md
└── authors.yml
├── docs.iml
├── docs
├── aqua-book
│ ├── aqua-js-api.md
│ ├── changelog.md
│ ├── getting-started
│ │ ├── getting-started.md
│ │ ├── installation
│ │ │ ├── Aqua-Extension-for-VSCode.png
│ │ │ └── installation.md
│ │ └── quick-start.md
│ ├── introduction.md
│ ├── language
│ │ ├── abilities.md
│ │ ├── closures.md
│ │ ├── crdt-streams.md
│ │ ├── expressions
│ │ │ ├── expressions.md
│ │ │ ├── functions.md
│ │ │ ├── header.md
│ │ │ ├── overridable-constants.md
│ │ │ └── services.md
│ │ ├── flow
│ │ │ ├── conditional.md
│ │ │ ├── flow.md
│ │ │ ├── iterative.md
│ │ │ ├── parallel.md
│ │ │ └── sequential.md
│ │ ├── header
│ │ │ ├── control-scope-and-visibility.md
│ │ │ └── header.md
│ │ ├── language.md
│ │ ├── services.md
│ │ ├── topology.md
│ │ ├── types.md
│ │ └── values.md
│ └── libraries
│ │ ├── aqua-ipfs.md
│ │ ├── aqua-lib.md
│ │ ├── libraries.md
│ │ └── registry.md
├── build
│ ├── concepts
│ │ ├── best_practices.md
│ │ ├── fluence_functions_revisited.md
│ │ ├── http_gateways.md
│ │ ├── marketplace.md
│ │ ├── scheduling_functions.md
│ │ └── security.md
│ ├── examples
│ │ └── frpc.md
│ ├── glossary.md
│ ├── how-to
│ │ ├── configure.md
│ │ ├── deploy.md
│ │ ├── develop.md
│ │ ├── migrate.md
│ │ ├── monitor.md
│ │ ├── schedule_functions.md
│ │ ├── securing_functions.md
│ │ ├── setting_up.md
│ │ ├── setup_payments.md
│ │ └── test.md
│ ├── introducing_fluence.md
│ ├── overview
│ │ ├── fluence_functions.md
│ │ ├── getting_started.md
│ │ └── roadmap.md
│ ├── quickstarts
│ │ ├── connecting_to_local_storage.md
│ │ ├── connecting_to_the_world.md
│ │ └── your_first_function.md
│ ├── references.md
│ ├── security.md
│ ├── setting-up
│ │ ├── installing_cli.md
│ │ ├── setting_up.md
│ │ └── working_with_local_networks.md
│ └── tutorials
│ │ ├── event_handling_in_js.md
│ │ ├── testing_serverless.md
│ │ └── workflow_fundamentals.md
├── learn
│ ├── fluence-comparison.md
│ ├── governance
│ │ └── overview.md
│ ├── how-it-works.md
│ ├── overview.md
│ ├── use-cases.md
│ └── why-fluence.md
└── marine-book
│ ├── basic-concepts
│ ├── an-example-of-Fluence-service.png
│ └── basic-concepts.md
│ ├── changelog.md
│ ├── introduction.md
│ ├── marine-runtime
│ ├── api
│ │ ├── api.md
│ │ ├── core-api.md
│ │ ├── marine-api.md
│ │ └── marine-js-api.md
│ ├── architecture
│ │ ├── architecture
│ │ │ ├── Marine-Layered-Architecture.png
│ │ │ └── architecture.md
│ │ ├── core
│ │ │ ├── core.md
│ │ │ ├── marine-performance.png
│ │ │ ├── marine-using-interface-types-V1.png
│ │ │ ├── multi-module-call-step-1.png
│ │ │ ├── multi-module-call-step-2.png
│ │ │ ├── multi-module-call-step-3.png
│ │ │ ├── multi-module-call-step-4.png
│ │ │ ├── multi-module-call-step-5.png
│ │ │ ├── passing-scheme-between-three-modules.png
│ │ │ └── scheme-with-Wasmer-instances.png
│ │ ├── interface-types-instructions.md
│ │ └── marine-js
│ │ │ ├── marine-js.md
│ │ │ ├── marine-web-scheme.png
│ │ │ └── marine-web-value-passing.png
│ ├── configuration-file.md
│ ├── host-exports.md
│ ├── i-value-and-i-type.md
│ ├── marine-runtime.md
│ ├── module-types
│ │ ├── marine-as-ecosystem.png
│ │ └── module-types.md
│ └── mounted-binaries.md
│ ├── marine-rust-sdk
│ ├── developing
│ │ ├── call-parameters.md
│ │ ├── developing.md
│ │ ├── environment-variables.md
│ │ ├── export-functions.md
│ │ ├── import-functions.md
│ │ ├── logging.md
│ │ ├── module-manifest.md
│ │ ├── mounted-binaries.md
│ │ └── structures.md
│ ├── marine-rust-sdk.md
│ ├── module-abi.md
│ └── testing-and-debugging
│ │ ├── internal-debugging-api.md
│ │ ├── testing-a-module.md
│ │ ├── testing-a-service.md
│ │ ├── testing-and-debugging.md
│ │ └── using-cargo-build-scripts.md
│ ├── marine-tooling-reference
│ ├── marine-cli.md
│ ├── marine-repl.md
│ └── marine-tooling-reference.md
│ └── quick-start
│ ├── develop-a-multi-modules-service.md
│ ├── develop-a-single-module-service.md
│ ├── quick-start.md
│ └── setting-up-the-development-environment.md
├── docusaurus.config.ts
├── package-lock.json
├── package.json
├── sidebars.js
├── src
├── css
│ └── custom.scss
├── pages
│ ├── index.module.scss
│ └── index.tsx
└── types.d.ts
├── static
├── .nojekyll
├── img
│ ├── aurora-connect-faucet.png
│ ├── aurora-explorer-inspect-transfers.png
│ ├── aurora-faucet-connect-metamask.png
│ ├── aurora-request-eth.png
│ ├── aurora-request-success.png
│ ├── aurora-testnet-success-metamask.png
│ ├── favicon.ico
│ ├── fluence-chain-diagram.png
│ ├── fluence-faucet-add-tUSDC-metamask.png
│ ├── fluence-faucet-add-tUSDC.png
│ ├── fluence-faucet-confirm-fluence-transfer.png
│ ├── fluence-faucet-confirm-tUSDC-added.png
│ ├── fluence-faucet-login.png
│ ├── fluence-faucet-request-tUSDC.png
│ ├── fluence-faucet-sign-up.png
│ ├── fluence-faucet-tUSDC-transfer-update.png
│ ├── fluence-functions.png
│ ├── logo.svg
│ ├── marine.jpg
│ ├── marketplace-capacity.png
│ ├── marketplace-matching.png
│ ├── marketplace-provider-resources.png
│ ├── marketplace-providers.png
│ ├── metamask-add-manually.png
│ ├── metamask-add-network.png
│ ├── metamask-aurora-chain-info.png
│ ├── metamask-mumbai-chain-info.png
│ ├── metamask-request-mumbai-tokens.png
│ ├── metamask-updated-MATIC-balance.png
│ ├── metamask-updated-aeth-balance.png
│ ├── metamask_tx_prompt.png
│ ├── mvm
│ │ └── dar_faucet.png
│ └── polygon-explorer-inspect-transfers.png
└── mermaid.js
├── tsconfig.json
└── vercel.json
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | # about codeowners
2 | # https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners
3 |
4 | # default owner is Artem since he setup up docusaurus
5 | * @shamsartem
6 |
7 | .github/** @nahsi
8 |
9 | blog/** @evgenyponomarev
10 | docs/learn/** @evgenyponomarev
11 | docs/build/** @boneyard93501
12 | docs/aqua-book/** @alari
13 | docs/marine-book/** @mikevoronov
14 |
--------------------------------------------------------------------------------
/.github/workflows/codeowners.yml:
--------------------------------------------------------------------------------
1 | name: codeowners
2 |
3 | on:
4 | pull_request:
5 | paths:
6 | - ".github/workflows/codeowners.yml"
7 | - ".github/CODEOWNERS"
8 |
9 | concurrency:
10 | group: "${{ github.workflow }}-${{ github.ref }}"
11 | cancel-in-progress: true
12 |
13 | jobs:
14 | validate:
15 | name: Validate CODEOWNERS
16 | runs-on: ubuntu-latest
17 | steps:
18 | - name: Checkout
19 | uses: actions/checkout@v4
20 |
21 | - name: Validate CODEOWNERS file
22 | uses: mszostok/codeowners-validator@v0.7.4
23 | with:
24 | checks: "files,owners,duppatterns,syntax"
25 | github_access_token: ${{ secrets.FLUENCEBOT_RELEASE_PLEASE_PAT }}
26 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Dependencies
2 | /node_modules
3 |
4 | # Production
5 | /build
6 | # Generated files
7 | .docusaurus
8 | .cache-loader
9 | .idea
10 |
11 | # Misc
12 | .DS_Store
13 | .env.local
14 | .env.development.local
15 | .env.test.local
16 | .env.production.local
17 |
18 | npm-debug.log*
19 | yarn-debug.log*
20 | yarn-error.log*
21 |
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "streetsidesoftware.code-spell-checker",
4 | "blackmist.LinkCheckMD"
5 | ]
6 | }
7 |
--------------------------------------------------------------------------------
/.vscode/markdown.code-snippets:
--------------------------------------------------------------------------------
1 | {
2 | "Tabs imports": {
3 | "prefix": "import-tabs",
4 | "body": [
5 | "import Tabs from \"@theme/Tabs\";",
6 | "import TabItem from \"@theme/TabItem\";"
7 | ],
8 | "description": "Import tabs"
9 | },
10 | "Tabs": {
11 | "prefix": "tabs",
12 | "body": [
13 | "",
14 | "",
15 | "",
16 | "",
17 | "",
18 | "",
19 | "",
20 | "",
21 | "",
22 | "",
23 | "",
24 | "",
25 | ]
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "cSpell.words": [
3 | "acks",
4 | "appendable",
5 | "builtins",
6 | "bytearray",
7 | "canonicalization",
8 | "canonicalized",
9 | "codomain",
10 | "commoditized",
11 | "composability",
12 | "concat",
13 | "contravariance",
14 | "CRDT",
15 | "ctypes",
16 | "deallocate",
17 | "dockerized",
18 | "EVM",
19 | "featureful",
20 | "fldist",
21 | "fluence",
22 | "fluencelabs",
23 | "ftype",
24 | "gibibyte",
25 | "hostless",
26 | "incentivized",
27 | "instanceof",
28 | "ipfs",
29 | "kademlia",
30 | "kibibyte",
31 | "kibibytes",
32 | "koderhq",
33 | "kras",
34 | "libp2p",
35 | "mebibyte",
36 | "microservices",
37 | "MITM",
38 | "mrepl",
39 | "mtype",
40 | "multiaddr",
41 | "multiaddress",
42 | "multiaddresses",
43 | "overridable",
44 | "pebibyte",
45 | "permisisonless",
46 | "permissioned",
47 | "permissioning",
48 | "permissionless",
49 | "PITM",
50 | "pluggable",
51 | "preopened",
52 | "println",
53 | "pseudocode",
54 | "quickstart",
55 | "roundtrips",
56 | "runtimes",
57 | "rustup",
58 | "sandboxed",
59 | "specificator",
60 | "specificators",
61 | "struct",
62 | "structs",
63 | "subnetworks",
64 | "tebibyte",
65 | "Tendermint",
66 | "tetraplet",
67 | "tetraplets",
68 | "toolchains",
69 | "usize",
70 | "wasi",
71 | "wasmer"
72 | ],
73 | "cSpell.ignoreRegExpList": ["/dns4/[a-zA-Z0-9/\\-\\.]*", "12d[a-zA-Z0-9]*"],
74 | "markdown.updateLinksOnFileMove.enabled": "always",
75 | "markdown.validate.enabled": true,
76 | "markdown.validate.fileLinks.enabled": "error",
77 | "markdown.validate.fileLinks.markdownFragmentLinks": "error",
78 | "markdown.validate.fragmentLinks.enabled": "error",
79 | "markdown.validate.referenceLinks.enabled": "error",
80 | "cSpell.language": "en,en-US"
81 | }
82 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Fluence Docs
2 |
3 | Fluence Docs are built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator.
4 |
5 | ## Contributing
6 |
7 | - Generally docs hierarchy should be reflected in the file hierarchy, but ultimately the docs tree must be set up inside `sidebars.js` file. If you put a markdown file inside a directory - don't ever name it `index.md` - use the same name as the directory itself instead (e.g. [basic-concepts.md](./docs/marine-book/basic-concepts/basic-concepts.md))
8 | - Currently the index page is redirected to `/docs/learn/overview`. This is because we don't have a design of what's best to place on the index page. The redirect is configured in the `vercel.json` file
9 | - Avoid adding a lot of images. Images are added using `` syntax. If you have to add an image - please put it inside the directory near the doc where it is used. Check out [basic-concepts.md](./docs/marine-book/basic-concepts/basic-concepts.md). Please use .png or even better - svg for diagrams and .jpg for photos, resize the image as small as you are comfortable and compress it using [tinypng.com](https://tinypng.com/) (or [svgomg](https://jakearchibald.github.io/svgomg/) for .svg).
10 | - When adding ANY github links please use [permalinks](https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/creating-a-permanent-link-to-a-code-snippet) - otherwise links will point to the wrong place eventually. I also added new experimental markdown related settings to .vscode/settings.json which help a lot with writing valid markdown. Also [this vscode extension](https://marketplace.visualstudio.com/items?itemName=blackmist.LinkCheckMD) can help you find broken external links as well
11 | - Please at least use spell checker inside your editor or maybe Grammarly and be attentive when writing docs - they are the face of the company in a sense
12 | - [Here](https://github.com/fluencelabs/docs/blob/9c6e5a257f453b6dbffb856fc236917908e80602/docusaurus.config.js#L61) is where you can add syntax highlight for other programming languages. Use \`\`\`aqua and \`\`\`air for codeblocks in these languages. Use \`\`\`sh for something that you intend to type in a shell. Maybe don't put \$ signs and execution results right inside \`\`\`sh code-blocks for the following reasons: \$ signs and commands output mixed with all of it make it harder to copy and use the code from the docs and also some of the commands output will be changed by us and will have to be maintained in the docs as well which is very inconvenient.
13 | - Headings are not just a stylistic tool but also semantic one. Headings are used to give document a structure which is especially important for page navigation for certain people and also for generating valid quick navigation tree that is displayed on the right side of the docs. So basically the main rule is to not skip heading levels (e.g. don't do #Heading followed immediately by ###Heading - use ##Heading instead)
14 | - For the lack of maintainer, Blog is currently removed from `sidebars.js` but we can add it back. It's still available and working
15 | - For `mermaid` code to work you would currently need to do the following:
16 | ````markdown
17 | Some text that you have in your md
18 |
19 | mermaid
20 | ```mermaid
21 | graph YourDiagram;
22 | A-->B;
23 | A-->C;
24 | B-->D;
25 | C-->D;
26 | ```
27 |
28 | rest of the text on your page
29 | ````
30 | Notice the blank line before and after the mermaid section
31 | - TODO: would be cool to have docs near the code (e.g. put Marine docs to Marine repo) - I think it can be done with CI build process but I think there unfortunately is no out-of-the-box solution. If it would be possible - changelogs from github and fluence-js docs, etc. could be included in these docs
32 |
33 | ## Installation
34 |
35 | ```sh
36 | npm i
37 | ```
38 |
39 | ## Local Development
40 |
41 | ```sh
42 | npm run dev
43 | ```
44 |
45 | This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.
46 |
47 | ## Build
48 |
49 | ```sh
50 | npm run build
51 | ```
52 |
53 | This command generates static content into the `build` directory and can be served using any static contents hosting service.
54 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [require.resolve('@docusaurus/core/lib/babel/preset')],
3 | };
4 |
--------------------------------------------------------------------------------
/blog/2021-09-03-marine-rs-sdk-test-update.md:
--------------------------------------------------------------------------------
1 | ---
2 | slug: marine-rs-sdk-test-v0.2.0
3 | title: marine-rs-sdk-test v0.2.0
4 | authors: mikevoronov
5 | tags: [marine]
6 | ---
7 |
8 | Updated the marine-rs-sdk-test to the 0.2.0 version with the following changes:
9 |
10 | - `#[marine_test]` defines `marine_test_env` namespace with module interfaces
11 |
12 | - module interface type can be accessed by `marine_test_env::::ModuleInterface`
13 |
14 | - structs exported by a module can be accessed by `marine_test_env::::`
15 |
16 | - functions under `#[marine_test]` must specify in the arguments modules they use
17 |
18 | Chosen naming and passing modules interfaces in arguments should make tests more readable.
19 | Here is an example of a test written in old and new ways:
20 |
21 | old:
22 | ```rust
23 | #[marine_test(config_path = "../Config.toml", modules_dir = "../artifacts")]
24 | fn empty_string() {
25 | let actual = greeting.greeting(String::new());
26 | assert_eq!(actual, "Hi, ");
27 | }
28 | ```
29 |
30 | new:
31 | ```rust
32 | #[marine_test(config_path = "../Config.toml", modules_dir = "../artifacts")]
33 | fn empty_string(greeting: marine_test_env::greeting::ModuleInterface {
34 | let actual = greeting.greeting(String::new());
35 | assert_eq!(actual, "Hi, ");
36 | }
37 | ```
38 |
39 | Also the update the solves problem with the same structures from different modules: they are now linked and have the same type.
40 |
41 | If you need more examples, please look at tests in [call_parameters](https://github.com/fluencelabs/marine/blob/master/examples/call_parameters/src/main.rs#L43) and [greeting](https://github.com/fluencelabs/marine/blob/master/examples/greeting/src/main.rs#L30), they are already using new interface.
42 |
--------------------------------------------------------------------------------
/blog/2021-09-08-aqua-compiler-0.3.md:
--------------------------------------------------------------------------------
1 | ---
2 | slug: aqua-v0.3
3 | title: Aqua v0.3
4 | authors: alari
5 | tags: [aqua]
6 | ---
7 |
8 | We have released the Aqua compiler 0.3.
9 |
10 | Now Aqua compiler runs natively in the javascript environment and distributed as [@fluencelabs/aqua](https://www.npmjs.com/package/@fluencelabs/aqua) NPM package.
11 |
12 | The next milestone is to call Aqua functions from the Aqua itself: we're building Aqua REPL.
13 | See the [changelog](https://fluence.dev/docs/aqua-book/changelog#030--september-8-2021).
14 |
--------------------------------------------------------------------------------
/blog/authors.yml:
--------------------------------------------------------------------------------
1 | shamsartem:
2 | name: Artsiom Shamsutdzinau
3 | title: Web Developer
4 | url: https://github.com/shamsartem
5 | image_url: https://github.com/shamsartem.png
6 |
7 | mikevoronov:
8 | name: Mike Voronov
9 | title: R&D Engineer
10 | url: https://github.com/mikevoronov
11 | image_url: https://github.com/mikevoronov.png
12 |
13 | alari:
14 | name: Dmitry Kurinskiy
15 | title: Co-founder & CTO at Fluence Labs
16 | url: https://github.com/alari
17 | image_url: https://github.com/alari.png
18 |
--------------------------------------------------------------------------------
/docs.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/docs/aqua-book/aqua-js-api.md:
--------------------------------------------------------------------------------
1 | # Aqua JS API
2 |
3 | Aqua JS API allows you to manage all aspects of [Aqua](introduction.md) development from your JS projects.
4 |
5 | To install the Aqua API package:
6 |
7 | ```sh
8 | npm install --save @fluencelabs/aqua-api
9 | ```
10 |
11 | # API
12 | API compiles high-level Aqua code into low-level AIR instructions that can be used with Fluence JS client to make peer-to-peer calls.
13 |
14 | API has only one function:
15 |
16 | ```typescript
17 | export class Compiler {
18 | compile(input: Input | Path | Call, imports: string[], config?: AquaConfig): Promise;
19 | }
20 | ```
21 |
22 | where input can be:
23 |
24 | - Aqua code as a string
25 |
26 | ```typescript
27 | export class Input {
28 | input: string
29 | }
30 | ```
31 |
32 | - Path to `.aqua` file or directory with `.aqua` files.
33 | - Note: paths must be absolute
34 |
35 | ```typescript
36 | export class Path {
37 | path: string
38 | }
39 | ```
40 |
41 | - Information about a function that you want to call. It wraps aqua code to gather and print call result. Also, it
42 | checks correctness of arguments.
43 |
44 | ```typescript
45 | export class Call {
46 | functionCall: string
47 | arguments: any
48 | input: Input | Path
49 | }
50 | ```
51 |
52 | - `imports` is a path to files that is necessary for compilation but not needed to be compiled into AIR functions. More information [here](language/header/header.md).
53 | - `config` is the following `AquaConfig` data structure
54 |
55 | ```typescript
56 | export class AquaConfig {
57 | // compiler log level. Default: info
58 | logLevel?: string
59 | // constants can be defined or overrided by this option
60 | constants?: string[]
61 | // switches off error bubbling to initiator. Default: false
62 | noXor?: boolean
63 | // switches off first hop to relay peer. Default: false
64 | noRelay?: boolean
65 | }
66 | ```
67 | More info about overridable constants [here](language/expressions/overridable-constants.md).
68 |
69 | Compilation result:
70 | ```typescript
71 | export class CompilationResult {
72 | // list of compiled services. Can be useful to create handlers for this services
73 | services: Record
74 | // list of Aqua functions
75 | functions: Record
76 | // information about function that is compiled with `Call` input
77 | functionCall?: AquaFunction
78 | // list of compilation errors in Aqua code. If not empty, then compilation failed and other fields will be empty
79 | errors: string[]
80 | }
81 | ```
82 |
83 | # Usage example
84 | https://github.com/fluencelabs/aqua/tree/main/api/aqua-api-example/
--------------------------------------------------------------------------------
/docs/aqua-book/getting-started/getting-started.md:
--------------------------------------------------------------------------------
1 | # Getting Started
2 |
3 | [Aqua](https://github.com/fluencelabs/aqua), part of Fluence Lab's Aquamarine Web3 stack, is a purpose-built language to program peer-to-peer networks and compose distributed services hosted on peer-to-peer nodes into applications and backends.
4 |
5 | In addition to the language specification, Aqua provides a compiler, which produces Aqua Intermediary Representation (AIR) and an execution stack, Aqua VM, that is part of every Fluence node implementation to execute AIR.
6 |
--------------------------------------------------------------------------------
/docs/aqua-book/getting-started/installation/Aqua-Extension-for-VSCode.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliezzahn/docs/7af66c0600393eaadff7ffb28ba49a0febfc021a/docs/aqua-book/getting-started/installation/Aqua-Extension-for-VSCode.png
--------------------------------------------------------------------------------
/docs/aqua-book/getting-started/installation/installation.md:
--------------------------------------------------------------------------------
1 | # Installation
2 |
3 | To work with Aqua code from command line, install [Fluence CLI](https://github.com/fluencelabs/cli) and use [`fluence aqua`](https://github.com/fluencelabs/cli/blob/main/docs/commands/README.md#fluence-aqua) subcommand.
4 |
5 | Also, the compiler API is exposed as an npm package, see [Aqua JS API](../../aqua-js-api.md).
6 |
7 | Moreover, a VSCode syntax-highlighting extension is available. In VSCode, click on the Extensions button, search for `aqua` and install the extension.
8 |
9 | 
10 |
--------------------------------------------------------------------------------
/docs/aqua-book/getting-started/quick-start.md:
--------------------------------------------------------------------------------
1 | import Tabs from "@theme/Tabs";
2 | import TabItem from "@theme/TabItem";
3 |
4 | # Quick Start
5 |
6 | Every Fluence reference node comes with a set of builtin services that are accessible to Aqua programs.
7 | Let's use those readily available services to get the timestamp of a few of our peer-to-peer neighborhood nodes with Aqua.
8 |
9 | ```aqua
10 | -- timestamp_getter.aqua
11 | import "@fluencelabs/aqua-lib/builtin.aqua"
12 |
13 | func ts_getter(node: string, num_peers: u32) -> []u64:
14 | res: *u64
15 |
16 | on node:
17 | key <- Op.string_to_b58(node)
18 | nodes <- Kademlia.neighborhood(key, nil, [num_peers])
19 | for n <- nodes par:
20 | on n:
21 | try:
22 | res <- Peer.timestamp_ms()
23 |
24 | join res[num_peers - 1]
25 |
26 | <- res
27 | ```
28 |
29 | Let's explain this script line by line. First of all, it brings builtin services (see [aqua-lib](../libraries/aqua-lib.md)) in scope by import:
30 |
31 | ```aqua
32 | import "@fluencelabs/aqua-lib/builtin.aqua"
33 | ```
34 |
35 | Next it defines a function named `ts_getter` with two parameters: `node` which is peer id and `num_peers` which is how many neighbors to check.
36 | That function returns array of obtained timestamps.
37 |
38 | ```aqua
39 | func ts_getter(node: string, num_peers: u32) -> []u64:
40 | ```
41 |
42 | On the first line it creates stream variable (see [CRDT Streams](../language/crdt-streams.md)) `res`:
43 |
44 | ```aqua
45 | res: *u64
46 | ```
47 |
48 | Then execution is transfered on peer with id that was passed in `node` (see [`on` expression](../language/topology.md#on-expression)):
49 |
50 | ```aqua
51 | on node:
52 | ```
53 |
54 | On `node` it obtains no more than `num_peers` neighbour nodes using builtin services:
55 |
56 | ```aqua
57 | key <- Op.string_to_b58(node)
58 | nodes <- Kademlia.neighborhood(key, nil, [num_peers])
59 | ```
60 |
61 | After that for each of the obtained nodes in parallel (see [Parallel `for`](../language/flow/iterative.md#parallel-for)) it tries (see [try](../language/flow/conditional#try)) to push local timestamp to `res`:
62 |
63 | ```aqua
64 | for n <- nodes par:
65 | on n:
66 | try:
67 | res <- Peer.timestamp_ms()
68 | ```
69 |
70 | Back on `node` element `res[num_peers - 1]` is joined (see [`join` expression](../language/flow/parallel.md#explicit-join-expression)) thus making all results available:
71 |
72 | ```aqua
73 | join res[num_peers - 1]
74 | ```
75 |
76 | Finally, stream is converted to scalar (see [Streams Lifecycle](../language/crdt-streams.md#streams-lifecycle-and-guarantees)) and returned:
77 |
78 | ```aqua
79 | <- res
80 | ```
81 |
82 | See the [ts-oracle example](https://github.com/fluencelabs/examples/tree/d52f06dfc3d30799fe6bd8e3e602c8ea1d1b8e8a/aqua-examples/ts-oracle) for the corresponding Aqua files in the `aqua-script` directory.
83 |
84 | Now that we have our script, let's use [Fluence CLI](https://github.com/fluencelabs/cli) to run it:
85 |
86 |
87 |
88 |
89 | ```sh
90 | # use `fluence run` as your client with some peer id
91 | fluence run \
92 | --relay /dns4/kras-02.fluence.dev/tcp/19001/wss/p2p/12D3KooWHLxVhUQyAuZe6AHMB29P7wkvTNMn7eDMcsqimJYLKREf \
93 | -i aqua-scripts/timestamp_getter.aqua \
94 | -f 'ts_getter("12D3KooWHLxVhUQyAuZe6AHMB29P7wkvTNMn7eDMcsqimJYLKREf", 10)'
95 | ```
96 |
97 |
98 |
99 |
100 | Here we go. Ten timestamps in micro seconds obtained in parallel:
101 | ```json
102 | [
103 | [
104 | 1624928596292,
105 | 1624928596291,
106 | 1624928596291,
107 | 1624928596299,
108 | 1624928596295,
109 | 1624928596286,
110 | 1624928596295,
111 | 1624928596284,
112 | 1624928596293,
113 | 1624928596289
114 | ]
115 | ]
116 | ```
117 |
118 |
119 |
120 |
121 | And that's it. We now have ten timestamps right from our selected peer's neighbors.
122 |
123 | Note that if you try to request too many peers, execution could halt.
124 |
--------------------------------------------------------------------------------
/docs/aqua-book/introduction.md:
--------------------------------------------------------------------------------
1 | import ReactPlayer from "react-player";
2 |
3 | # Introduction
4 |
5 | Fluence is an open protocol and a framework for internet or private cloud applications. Fluence provides a peer-to-peer development stack so that you can create applications free of proprietary cloud platforms, centralized APIs, and untrustworthy third-parties. The Fluence stack is open source and is maintained and governed by a community of developers.
6 |
7 | At the core of Fluence is the open-source language **Aqua** that allows for the programming of peer-to-peer scenarios separately from the computations on peers. Applications are turned into hostless workflows over distributed function calls, which enables various levels of decentralization: from handling by a limited set of servers to complete peer-to-peer architecture by connecting user devices directly.
8 |
9 |
10 |
11 |
12 |
13 |
14 | This book, currently in its alpha version, is dedicated to Aqua, with plans to significantly broaden its scope in the future.
15 |
--------------------------------------------------------------------------------
/docs/aqua-book/language/abilities.md:
--------------------------------------------------------------------------------
1 | # Abilities
2 |
3 | Abilities are a way to organize code in modules and implement inversion of control pattern in Aqua.
4 |
5 |
6 | Ability is a product of [scalars](types.md#scalars), [structures](types.md#structures), [arrows](types.md#arrow-types) and other abilities.
7 |
8 | ```aqua
9 | data Struct:
10 | int: i8
11 |
12 | ability Simple:
13 | st: Struct
14 | arrow(x: i8) -> bool
15 |
16 | ability Complex:
17 | simple: Simple
18 | field: string
19 | ```
20 |
21 | ## Creating abilities
22 |
23 | Abilities could be created inside functions just like [structures](types.md#structures).
24 |
25 |
26 | ```aqua
27 | func main():
28 | closure = (x: i8) -> bool:
29 | <- x > 0
30 |
31 | field = "complex"
32 |
33 | MyComplex = Complex(
34 | simple = Simple(
35 | st = Struct(int = 0),
36 | arrow = closure
37 | ),
38 | field -- short for `field = field`
39 | )
40 | ```
41 |
42 | ## Passing abilities
43 |
44 | Abilities could be passed to and returned from functions, althrough they require special syntax:
45 | - Abilities required by function are listed before arguments without names
46 | - Abilities returned by function are listed in return types just as any other types
47 |
48 | ```aqua
49 | ability Additional:
50 | value: string
51 |
52 | func createComplex{Simple, Additional}(int: i8) -> Complex, string:
53 | MyComplex = Complex(
54 | simple = Simple(
55 | st = Struct(int = int),
56 | arrow = Simple.arrow
57 | ),
58 | field = Additional.value
59 | )
60 |
61 | <- MyComplex, Additional.value
62 |
63 | func main() -> string, string:
64 | closure = (x: i8) -> bool:
65 | <- x > 0
66 |
67 | MySimple = Simple(
68 | st = Struct(int = 0),
69 | arrow = closure
70 | )
71 |
72 | MyAdditional = Additional(value = "additional")
73 |
74 | MyComplex, value = createComplex{MySimple, MyAdditional}(42)
75 |
76 | <- MyComples.field, value
77 | ```
78 |
79 |
80 |
81 | ## Why abilities are special
82 |
83 | Abilities are fully resolved in compile time and do not affect runtime by any means.
84 | In this sense they are more like a context or trait implementation in other languages.
85 | For this reason special syntax is used.
86 |
87 | ## Limitations
88 |
89 | As abilities do not exist in runtime, they could not be put into a [collection](types.md#collection-types).
--------------------------------------------------------------------------------
/docs/aqua-book/language/closures.md:
--------------------------------------------------------------------------------
1 | # Closures
2 |
3 | In Aqua, you can create an arrow within the function, enclosing its context.
4 |
5 | ```aqua
6 | service Hello:
7 | say_hello(to_name: string, peer: string)
8 |
9 | func bar(callback: string -> ()):
10 | callback("Fish")
11 |
12 | func foo(peer: string):
13 | on peer:
14 | -- Capture service resolution
15 | Hello "world"
16 | -- Create a closure named "closure"
17 | closure = (name: string) -> string:
18 | -- Use a value that's available on the definition site
19 | -- To call a service that's resolved on the definition site
20 | Hello.say_hello(name, peer)
21 | -- Return a value from the closure; syntax is the same as in functions
22 | <- name
23 | -- Pass this closure to another function
24 | bar(closure)
25 | ```
26 |
27 | Closures can be created anywhere in the function, starting with Aqua 0.4.1, and then used just like any other arrow (argument of arrow type, function, or service method): passed to another function as an argument, or called right there.
28 |
29 | Closures enclose over three domains:
30 |
31 | * Values in scope,
32 | * Service resolutions,
33 | * Topology: place where the closure is defined should be the place where it's executed.
34 |
35 | Comparing with functions, closures have one important difference: functions are detached from topology by default. `func` keyword can be used to bring this behavior to closures, if needed.
36 |
37 | ```aqua
38 | service Hello:
39 | say_hello()
40 |
41 | func foo():
42 | on HOST_PEER_ID:
43 | Hello "hello"
44 |
45 | -- This closure will execute on HOST_PEER_ID
46 | closure = ():
47 | Hello.say_hello()
48 |
49 | fn = func ():
50 | Hello.say_hello()
51 |
52 | -- Will go to HOST_PEER_ID, where Hello service is resolved, and call say_hello
53 | closure()
54 |
55 | -- Will be called on current peer, probably INIT_PEER_ID, and may fail
56 | -- in case Hello service is not defined or has another ID
57 | fn()
58 | ```
59 |
60 | It is not yet possible to return an arrow from an arrow.
61 |
--------------------------------------------------------------------------------
/docs/aqua-book/language/crdt-streams.md:
--------------------------------------------------------------------------------
1 | # CRDT Streams
2 |
3 | In Aqua, an ordinary value is a name that points to a single result:
4 |
5 | ```aqua
6 | value <- foo()
7 | ```
8 |
9 | A stream, on the other hand, is a name that points to zero or more results:
10 |
11 | ```aqua
12 | values: *string
13 |
14 | -- Write to a stream several times
15 | values <- foo()
16 | values <- foo()
17 |
18 | -- A value can be pushed to a stream
19 | -- without an explicit function call with <<- operator:
20 | values <<- "foo"
21 | x <- foo()
22 | values <<- x
23 | ```
24 |
25 | Stream is a kind of [collection](types.md#collection-types) and can be used in place of other collections:
26 |
27 | ```aqua
28 | func foo(peer: string, relay: ?string):
29 | on peer via relay:
30 | Op.noop()
31 |
32 | func bar(peer: string, relay: string):
33 | relayMaybe: *string
34 | if peer != INIT_PEER_ID:
35 | -- Write into a stream
36 | relayMaybe <<- relay
37 | -- Pass a stream as an optional value
38 | foo(peer, relayMaybe)
39 | ```
40 |
41 | But the most powerful use of streams pertains to their use with parallel execution, which incurs non-determinism.
42 |
43 | ## Streams: Lifecycle And Guarantees
44 |
45 | A stream's lifecycle can be separated into three stages:
46 |
47 | * Source: (Parallel) Writes to a stream
48 | * Map: Handles the stream values
49 | * Sink: Converts the resulting stream into a scalar
50 |
51 | Consider the following example:
52 |
53 | ```aqua
54 | alias PeerId: string
55 |
56 | func foo(peers: []PeerId) -> string:
57 | -- Store a list of peer IDs collected from somewhere
58 | -- This is a stream (denoted by *, which means "0 or more values")
59 | resp: *PeerId
60 |
61 | -- Will go to all peers in parallel
62 | for p <- peers par:
63 | -- Move execution flow to the peer p
64 | on p:
65 | -- Get a peer ID from a service call (called on p)
66 | resp <- Srv.call()
67 |
68 | -- You can think of resp2 as a locally consistent lazy list
69 | resp2: *PeerId
70 |
71 | -- What is the value of resp at this point?
72 | -- Keep an eye on the `par` there: actually, it's FORKing execution
73 | -- to several branches on different peers.
74 | for r <- resp par:
75 | -- Move execution to peer r
76 | on r:
77 | -- Call Srv locally
78 | resp2 <- Srv.call()
79 |
80 | -- Wait for 6 responses on resp2: it's JOIN
81 | Op.identity(resp2!5)
82 | -- Once we have 6 responses, merge them
83 | -- Function treats resp2 as an array of strings, and concatenates all
84 | -- of them into a single string.
85 | -- This function call "fixes" the content of resp2, making a single observation.
86 | -- This is a "stream canonicalization" event: values, order, and length
87 | -- is fixed at the moment of first function call, function will not be called
88 | -- again, with different data.
89 | r <- Srv.concat(resp2)
90 | -- You can keep writing to a stream after it's value is used
91 |
92 | <- r
93 | ```
94 |
95 | In this case, for each peer `p` in `peers`, a new `PeerID` is going to be obtained from the `Srv.call` and written into the `resp` stream.
96 |
97 | Every peer `p` in peers does not know anything about how the other iterations proceed.
98 |
99 | Once `PeerId` is written to the `resp` stream, the second `for` is triggered. This is the mapping stage.
100 |
101 | And then the results are sent to the first peer, to call Op.identity there. This Op.identity waits until element number 5 is defined on `resp2` stream.
102 |
103 | When the join is complete, the stream is consumed by the concatenation service to produce a scalar value, which is returned.
104 |
105 | During execution, involved peers have different views on the state of execution: each of the `for` parallel branches has no view or access to the other branches' data and eventually, the execution flows to the initial peer. The initial peer then merges writes to the `resp` stream and to the `resp2` stream, respectively. These writes are done in a conflict-free fashion. Furthermore, the respective heads of the `resp`, `resp2` streams will not change from each peer's point of view as they are immutable and new values can only be appended. However, different peers may have a different order of the stream values depending on the order of receiving these values.
106 |
107 | ### Stream restrictions
108 |
109 | Restriction is a part of π calculus that bounds (restricts) a name to a scope. For Aqua streams it means that the stream is not accessible outside of definition scope, and the stream is always fresh when execution enters the scope.
110 |
111 | These behaviors are introduced in [Aqua 0.5](https://github.com/fluencelabs/aqua/releases/tag/0.5.0).
112 |
113 | ```aqua
114 | -- Note: returns []string (immutable, readonly collection), not *string
115 | func someFunc(xs: []string) -> []string:
116 | -- This stream is available within the function, and is empty
117 | outside: *string
118 | for x <- xs:
119 | -- This stream is empty at the beginning of each iteration
120 | inside: *string
121 |
122 | -- We can manipulate the inside stream within the scope
123 | if x == "ok"
124 | inside <<- "ok"
125 | else:
126 | inside <<- "not ok"
127 |
128 | -- Read the value
129 | if inside! == "ok":
130 | outside <<- "result"
131 |
132 | -- outside stream is not escaping this function scope:
133 | -- it is converted to an array (canonicalized) and cannot be appended after that
134 | <- outside
135 | ```
136 |
137 | You still can keep streams as streams by using them as `*string` arguments, or by returning them as `*string`.
138 |
139 | ### Note
140 | `data` types must be immutable, therefore streams are not allowed in the type declarations.
141 |
--------------------------------------------------------------------------------
/docs/aqua-book/language/expressions/expressions.md:
--------------------------------------------------------------------------------
1 | # Expressions
2 |
3 | Aqua file consists of a header and a body.
4 |
5 | ## Body expressions
6 |
7 | `func`
8 |
9 | Function definition is the most crucial part of the language, see [Functions](functions.md) for details.
10 |
11 | [Expressions source code](https://github.com/fluencelabs/aqua/tree/main/semantics/src/main/scala/aqua/semantics/expr)
12 |
--------------------------------------------------------------------------------
/docs/aqua-book/language/expressions/functions.md:
--------------------------------------------------------------------------------
1 | # Functions
2 |
3 | A function in Aqua is a block of code expressing a workflow, i.e., a coordination scenario that works across one or more peers.
4 |
5 | A function may take arguments of any type and may return a value.
6 |
7 | A function can call other functions, take functions as arguments of [arrow type](../types.md#arrow-types) and be provided as an arrow argument.
8 |
9 | Essentially, a function is an arrow. The function call is an expression that connects named arguments to an arrow, and gives a name to the result.
10 |
11 | In essense, all a function does is call its arguments or service functions.
12 |
13 | ```aqua
14 | service MySrv:
15 | foo()
16 |
17 | func do_something(): -- arrow of type: -> ()
18 | MySrv "srv id"
19 | MySrv.foo()
20 | ```
21 |
22 |
--------------------------------------------------------------------------------
/docs/aqua-book/language/expressions/header.md:
--------------------------------------------------------------------------------
1 | # Header
2 |
3 | ## Header expressions
4 |
5 | ### `import`
6 |
7 | The `import` expression brings everything defined within the imported file into the scope.
8 |
9 | ```aqua
10 | import "path/to/file.aqua"
11 | ```
12 |
13 | The to be imported file path is first resolved relative to the source file path followed by checking for an `-imports` directories.
14 |
15 | See [Imports & Exports](../header/header.md) for details.
16 |
--------------------------------------------------------------------------------
/docs/aqua-book/language/expressions/overridable-constants.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: Static configuration pieces that affect compilation
3 | ---
4 |
5 | # Overridable constants
6 |
7 | ## `const`
8 |
9 | Constant definition.
10 |
11 | Constants can be used all across functions, exported and imported. If a constant is defined using `?=` , it can be overridden by value via compiler flags or imported values.
12 |
13 | ```aqua
14 | -- This can be overridden with --const 'TARGET_PEER_ID = "other peer id"'
15 | const TARGET_PEER_ID ?= "this is a target peer id"
16 |
17 | -- This constant cannot be overridden
18 | const SERVICE_ID = "service id"
19 | ```
20 |
21 | You can assign only literals to constants. Constant type is the same as literal type. You can override only with a subtype of that literal type.
22 |
--------------------------------------------------------------------------------
/docs/aqua-book/language/expressions/services.md:
--------------------------------------------------------------------------------
1 | # Services
2 |
3 | A service is a program running on a peer. Every service has an interface that consists of a list of functions. To call a service, the service must be identified: so, every service has an ID that must be resolved in the peer scope.
4 |
5 | In the service definition, you enumerate all the functions, their names, argument, and return types, and optionally provide the default Service ID.
6 |
7 | Services that are a part of the protocol, i.e. are available from the peer node, come along with IDs. Example of predefined service:
8 |
9 | ```aqua
10 | service Peer("peer"):
11 | foo() -- no arguments, no return
12 | bar(i: bool) -> bool
13 |
14 | func usePeer() -> bool:
15 | Peer.foo() -- results in a call of service "peer", function "foo", on current peer ID
16 | z <- Peer.bar(true)
17 | <- z
18 | ```
19 |
20 | Example of a custom service:
21 |
22 | ```aqua
23 | service MyService:
24 | foo()
25 | bar(i: bool, z: i32) -> string
26 |
27 | func useMyService(k: i32) -> string:
28 | -- Need to tell the compiler what does "my service" mean in this scope
29 | MyService "my service id"
30 | MyService.foo()
31 | on "another peer id":
32 | -- Need to redefine MyService in scope of this peer as well
33 | MyService "another service id"
34 | z <- MyService.bar(false, k)
35 | <- z
36 | ```
37 |
38 | Service definitions have types. Type of a service is a product type of arrows. See [Types](../types.md#type-of-a-service-and-a-file).
39 |
--------------------------------------------------------------------------------
/docs/aqua-book/language/flow/conditional.md:
--------------------------------------------------------------------------------
1 | # Conditional
2 |
3 | Aqua supports branching, you can:
4 | - Check boolean expression with [`if`](#if)
5 | - Recover from error with [`try`](#try) or [`otherwise`](#otherwise)
6 | - Return different results with [conditional return](#conditional-return)
7 |
8 | ## Contract
9 |
10 | * The second branch of the conditional operator is executed if and only if the first block failed.
11 | * The second branch has no access to the first branch's data.
12 | * A conditional block is considered "executed" if and only if any branch was executed successfully.
13 | * A conditional block is considered "failed" if and only if the second (recovery) branch failed.
14 |
15 | ## Conditional operations
16 |
17 | ### `if`
18 |
19 | The first branch of the conditional operator, executed only if the condition holds.
20 |
21 | ```aqua
22 | x = true
23 | if x:
24 | -- always executed
25 | foo()
26 |
27 | if x == false:
28 | -- never executed
29 | bar()
30 |
31 | if x != false:
32 | -- always executed
33 | baz()
34 | ```
35 |
36 | Any expression that produces `bool` is acceptable as a condition.
37 |
38 | `if` corresponds to `match`, `mismatch` extension of π-calculus.
39 |
40 | ### `else`
41 |
42 | The second branch of `if`, executed only in case the condition does not hold.
43 |
44 | ```aqua
45 | if false:
46 | foo() -- skipped
47 | else:
48 | bar() -- executed
49 | ```
50 |
51 | If you want to set a variable based on condition, see [conditional return](#conditional-return).
52 |
53 | ### `try`
54 |
55 | Tries to perform operations, swallows produced error (if there's no `catch`, otherwise executes `catch`).
56 |
57 | ```aqua
58 | try:
59 | -- If foo fails with an error, execution will continue
60 | -- You should write your logic in a non-blocking fashion:
61 | -- If your code below depends on `x`, it may halt as `x` is not resolved.
62 | -- See conditional return below for workaround
63 | x <- foo()
64 | ```
65 |
66 | ### `catch`
67 |
68 | Catches the standard error from the `try` block.
69 |
70 | ```aqua
71 | try:
72 | foo()
73 | catch e:
74 | logError(e)
75 | ```
76 |
77 | Type of `e` is:
78 |
79 | ```aqua
80 | data LastError:
81 | instruction: string -- What AIR instruction failed
82 | msg: string -- Human-readable error message
83 | peer_id: string -- On what peer the error happened
84 | ```
85 |
86 | ### `otherwise`
87 |
88 | You may add `otherwise` to provide recovery for any block or expression:
89 |
90 | ```aqua
91 | x <- foo()
92 | otherwise:
93 | -- if foo can't be executed, then do bar()
94 | y <- bar()
95 | ```
96 |
97 | ## Conditional return
98 |
99 | In Aqua, functions may have only one return expression, which is the very last.
100 |
101 | So to get the value based on condition, we need to use a [writeable collection](../types.md#collection-types).
102 |
103 | ```aqua
104 | -- result may have 0 or more values of type string and is writeable
105 | resultBox: *string
106 | try:
107 | resultBox <- foo()
108 | otherwise:
109 | resultBox <- bar()
110 |
111 | -- now result contains only one value, let's extract it!
112 | result = resultBox!
113 |
114 | -- Type of result is string
115 | -- Please note that if there were no writes to resultBox,
116 | -- the first use of result will halt.
117 | -- So you need to be careful about it and ensure that there's always a value.
118 | ```
119 |
--------------------------------------------------------------------------------
/docs/aqua-book/language/flow/flow.md:
--------------------------------------------------------------------------------
1 | # Execution flow
2 |
3 | Aqua's main goal is to express how the execution flows: moves from peer to peer, forks to parallel flows and then joins back, uses data from one step in another.
4 |
5 | As the foundation of Aqua is based on π-calculus, finally flow is decomposed into [sequential](sequential.md) (`seq`, `.`), [conditional](conditional.md) (`xor`, `+`), [parallel](parallel.md) (`par`, `|`) computations and [iterations](iterative.md) based on data (`!P`). For each basic way to organize the flow, Aqua follows a set of rules to execute the operations:
6 |
7 | * What data is available for use?
8 | * What data is exported and can be used below?
9 | * How errors and failures are handled?
10 |
11 | These rules form a contract, as in [design-by-contract](https://en.wikipedia.org/wiki/Design_by_contract) programming.
12 |
--------------------------------------------------------------------------------
/docs/aqua-book/language/flow/iterative.md:
--------------------------------------------------------------------------------
1 | # Iterative
2 |
3 | π-calculus has a notion of the repetitive process: `!P = P | !P`. That means, you can always fork a new `P` process if you need it.
4 |
5 | In Aqua, two operations correspond to it: you can call a service function (it's just available when it's needed), and you can use `for` loop to iterate on collections.
6 |
7 | ## `for` expression
8 |
9 | In short, `for` looks like the following:
10 |
11 | ```aqua
12 | xs: []string
13 |
14 | for x <- xs:
15 | y <- foo(x)
16 |
17 | -- x and y are not accessible there, you can even redefine them
18 | x <- bar()
19 | y <- baz()
20 | ```
21 |
22 | ## Contract
23 |
24 | * Iterations of `for` loop are executed sequentially by default.
25 | * Variables defined inside `for` loop are not available outside.
26 | * `for` loop's code has access to all variables above.
27 | * `for` can be executed on a variable of any [Collection type](../types.md#collection-types).
28 |
29 | ### Conditional `for`
30 |
31 | For can be executed on a variable of any [Collection type](../types.md#collection-types). You can make several trials in a loop, and break once any trial succeeded.
32 |
33 | ```aqua
34 | xs: []string
35 |
36 | for x <- xs try:
37 | -- Will stop trying once foo succeeds
38 | foo(x)
39 | ```
40 |
41 | The contract is changed as in [Parallel](parallel.md#contract) flow.
42 |
43 | ### Parallel `for`
44 |
45 | Running many operations in parallel is the most commonly used pattern for `for`.
46 |
47 | ```aqua
48 | xs: []string
49 |
50 | for x <- xs par:
51 | on x:
52 | foo()
53 |
54 | -- Once the fastest x succeeds, execution continues
55 | -- If you want to make the subsequent execution independent from for,
56 | -- mark it with par, e.g.:
57 | par continueWithBaz()
58 | ```
59 |
60 | The contract is changed as in [Conditional](conditional.md#contract) flow.
61 |
62 | ### Export data from `for`
63 |
64 | The way to export data from `for` is the same as in [Conditional return](conditional.md#conditional-return) and [Race patterns](parallel.md#join-behavior).
65 |
66 | ```aqua
67 | xs: []string
68 | return: *string
69 |
70 | -- can be par, try, or nothing
71 | for x <- xs par:
72 | on x:
73 | return <- foo()
74 |
75 | -- Wait for 6 fastest results -- see Join behavior
76 | baz(return!5, return)
77 | ```
78 |
79 | ### `for` on streams
80 |
81 | `for` on streams is one of the most advanced and powerful parts of Aqua. See [CRDT streams](../crdt-streams.md) for details.
82 |
--------------------------------------------------------------------------------
/docs/aqua-book/language/flow/sequential.md:
--------------------------------------------------------------------------------
1 | # Sequential
2 |
3 | By default, Aqua code is executed line by line, sequentially.
4 |
5 | ## Contract
6 |
7 | * Data from the first line is available on the second line
8 | * A second line will be executed only if the first line succeeded
9 | * If any line failed, then the whole block is failed
10 | * If all lines succeeded, then the whole block is succeeded
11 |
12 | ```aqua
13 | f <- first() -- first line
14 | second(f) -- second line
15 | ```
16 |
17 | _A block of code is any number of lines on the same indentation level or deeper._
18 |
19 | ## Sequential operations
20 |
21 | ### call arrow
22 |
23 | Any runnable piece of code in Aqua is an arrow from its domain to the codomain.
24 |
25 | ```aqua
26 | -- Call a function
27 | foo()
28 |
29 | -- Call a function that returns something, assign results to a variable
30 | x <- foo()
31 |
32 | -- Call an ability function
33 | y <- Peer.identify()
34 |
35 | -- Pass an argument
36 | z <- Op.identity(y)
37 | ```
38 |
39 | When you write `<-`, this means not just "assign results of the function on the right to variable on the left". It means that all the effects are executed: [service](../services.md) may change state, the [topology](../topology.md) may be shifted. But you end up being (semantically) on the same peer where you have called the arrow.
40 |
41 | ### on
42 |
43 | `on` denotes the peer where the code must be executed. `on` is handled sequentially, and the code inside is executed line by line by default.
44 |
45 | ```aqua
46 | func foo():
47 | -- Will be executed where `foo` was executed
48 | bar()
49 |
50 | -- Move to another peer
51 | on another_peer:
52 | -- To call bar, we need to leave the peer where we were and get to another_peer
53 | -- It's done automatically
54 | bar()
55 |
56 | on third_peer via relay:
57 | -- This is executed on third_peer
58 | -- But we denote that to get to third_peer and to leave third_peer
59 | -- an additional hop is needed: get to relay, then to peer
60 | bar()
61 |
62 | -- Will be executed in the `foo` call site again
63 | -- To get from the previous `bar`, compiler will add a hop to relay
64 | bar()
65 | ```
66 |
67 | See more in the [Topology](../topology.md) section.
68 |
--------------------------------------------------------------------------------
/docs/aqua-book/language/header/header.md:
--------------------------------------------------------------------------------
1 | # Imports And Exports
2 |
3 | An Aqua source file has a header and a body. The body contains function definitions, services, types, constants. The header manages what is imported from other files and what is exported.
4 |
5 | ## Aqua source file header
6 |
7 | When header is omitted, `.aqua` file exports and declares everything it contains. With `aqua` header you can control what gets exported from the aqua file.
8 |
9 | ```aqua
10 | -- `aqua` expression may be only on the very first line of the file
11 | aqua AquaFile declares *
12 | ```
13 |
14 | `Aqua.File` may contain dots.
15 |
16 | `AquaFile` can be used as the aqua's name when this file is `use`d. In this case, only what is enumerated in `declares` section will be available. `declares *` allows you to declare everything in the file as the module interface.
17 |
18 | ```aqua
19 | aqua AquaFile declares CONST_NAME, ServiceName, MyType, fn
20 |
21 | const CONST_NAME = "something"
22 |
23 | service ServiceName:
24 | do_something()
25 |
26 | data MyType:
27 | result: i32
28 |
29 | function fn() -> string:
30 | <- CONST_NAME
31 | ```
32 |
33 | ## Import Expression
34 |
35 | The main way to import a file is via `import` expression:
36 |
37 | ```aqua
38 | import "@fluencelabs/aqua-lib/builtin.aqua"
39 |
40 | func foo():
41 | Op.noop()
42 | ```
43 |
44 | Aqua compiler takes a source directory and a list of import directories (usually with `node_modules` as a default). You can use relative paths to `.aqua` files, relatively to the current file's path, and to import folders.
45 |
46 | :::info
47 | `.aqua` extension in `import` and `use` expressions can be omitted. So, `import "builtin.aqua"` does exactly the same as `import "builtin"`.
48 | :::
49 |
50 | Everything defined in the file is imported into the current namespace.
51 |
52 | You can cherry-pick and rename imports using `import ... from` expression:
53 |
54 | ```aqua
55 | import Op as Noop from "@fluencelabs/aqua-lib/builtin"
56 |
57 | func foo():
58 | Noop.noop()
59 | ```
60 |
61 | ## Use Expression
62 |
63 | The `use` expression makes it possible to import a file into a named scope.
64 |
65 | ```aqua
66 | use Op from "@fluencelabs/aqua-lib/builtin" as BuiltIn
67 |
68 | func foo():
69 | BuiltIn.Op.noop()
70 | ```
71 |
72 | If the imported file has a `aqua` header, `from` and `as` sections of `use` may be omitted.
73 |
74 | ```aqua
75 | use "@fluencelabs/aqua-lib/builtin.aqua"
76 | -- Assume that builtin.aqua's header is `aqua BuiltIn declares *`
77 |
78 | func foo():
79 | BuiltIn.Op.noop()
80 | ```
81 |
82 | ## Export
83 |
84 | While it's useful to split the code into several functions into different files, it's not always a good idea to compile everything into the host language.
85 |
86 | Another problem is libraries distribution. If a developer wants to deliver an `.aqua` library, he or she often needs to provide it in compiled form as well.
87 |
88 | `export` lets a developer decide what exactly is going to be exported, including imported functions.
89 |
90 | ```aqua
91 | import bar from "lib"
92 |
93 | -- Exported functions and services will be compiled for the host language
94 | -- You can use several `export` expressions
95 | export foo as my_foo
96 | export bar, MySrv
97 |
98 | service MySrv:
99 | call_something()
100 |
101 | func foo() -> bool:
102 | <- true
103 | ```
104 |
--------------------------------------------------------------------------------
/docs/aqua-book/language/language.md:
--------------------------------------------------------------------------------
1 | # Language
2 |
3 | Aqua is a language for distributed workflow coordination in p2p networks.
4 |
5 | It's structured with significant indentation:
6 | - Tabs and spaces are allowed simultaneously
7 | - Indentation of a parent block should be a strict prefix of indentation of a child block
8 | - First line in a block defines indentation and all consequent lines should have the same indentation
9 |
10 | ```aqua
11 | -- Comments begin with double-dash and end with the line (inline)
12 | func foo(): -- Comments are allowed almost everywhere
13 | -- Body of the block expression is indented
14 | bar(5)
15 | ```
16 |
17 | Values in Aqua have types, which are designated by a colon, `:`, as seen in the function signature below. The type of a return, which is yielded when a function is executed, is denoted by an arrow pointing to the right `->` , whereas yielding is denoted by an arrow pointing to the left `<-`.
18 |
19 | ```aqua
20 | -- Define a function that yields a string
21 | func bar(arg: i16) -> string:
22 | -- Call a function
23 | someFunc(arg)
24 |
25 | -- Yield a value from a function
26 | x <- someFunc(arg)
27 |
28 | -- Return a yielded results from a function
29 | <- "return literal"
30 | ```
31 |
32 | Subsequent sections explain the main parts of Aqua.
33 |
34 | Data:
35 |
36 | * [Types](types.md)
37 | * [Values of that types](values.md)
38 |
39 | Execution:
40 |
41 | * [Topology](topology.md) – how to express where the code should be executed
42 | * [Execution flow](flow/flow.md) – control structures
43 |
44 | Computations:
45 |
46 | * [Services](services.md)
47 | * [Abilities](abilities.md)
48 |
49 | Advanced parallelism:
50 |
51 | * [CRDT Streams](crdt-streams.md)
52 |
53 | Code management:
54 |
55 | * [Imports & exports](header/header.md)
56 |
57 | Reference:
58 |
59 | * [Expressions](expressions/expressions.md)
60 |
--------------------------------------------------------------------------------
/docs/aqua-book/language/services.md:
--------------------------------------------------------------------------------
1 | # Services
2 |
3 | Services describe what can be called on peers, and how to call it. A service interfaces functions (often provided via WebAssembly interface) executable on a peer. Example of service definition:
4 |
5 | ```aqua
6 | service MyService:
7 | foo(arg: string) -> string
8 | bar() -> bool
9 | baz(arg: i32)
10 | ```
11 |
12 | Service functions in Aqua have no function body. Computations, of any complexity, are implemented with any programming language that fits, and then brought to the Aqua execution context. Aqua calls these functions but does not peak into what's going on inside.
13 |
14 | ## Built-in Services
15 |
16 | Some services may be singletons available on all peers. Such services are called built-ins, and are always available in any scope.
17 |
18 | ```aqua
19 | -- Built-in service has a constant ID, so it's always resolved
20 | service Op("op"):
21 | noop()
22 |
23 | func foo():
24 | -- Call the noop function of "op" service locally
25 | Op.noop()
26 | ```
27 |
28 | ## Service Resolution
29 |
30 | A peer may host many services of the same type. To distinguish services from each other, Aqua requires Service resolution to be done: that means, the developer must provide an ID of the service to be used on the peer.
31 |
32 | ```aqua
33 | service MyService:
34 | noop()
35 |
36 | func foo():
37 | -- Will fail
38 | MyService.noop()
39 |
40 | -- Resolve MyService: it has id "noop"
41 | MyService "noop"
42 |
43 | -- Can use it now
44 | MyService.noop()
45 |
46 | on "other peer":
47 | -- Should fail: we haven't resolved MyService ID on other peer
48 | MyService.noop()
49 |
50 | -- Resolve MyService on peer "other peer"
51 | MyService "other noop"
52 | MyService.noop()
53 |
54 | -- Moved back to initial peer, here MyService is resolved to "noop"
55 | MyService.noop()
56 | ```
57 |
58 | There's no way to call an external function in Aqua without defining all the data types and the service type. One of the most convenient ways to do it is to generate Aqua types from Wasm code in Marine.
59 |
--------------------------------------------------------------------------------
/docs/aqua-book/libraries/aqua-lib.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: API of protocol-level service (a.k.a builtins)
3 | ---
4 |
5 | # @fluencelabs/aqua-lib
6 |
7 | ## Releases
8 |
9 | You can find the latest releases of `aqua-lib` [on NPM](https://www.npmjs.com/package/@fluencelabs/aqua-lib) and changelogs are [on GitHub](https://github.com/fluencelabs/aqua-lib/releases)
10 |
11 | ## API
12 |
13 | The most up-to-date documentation of the API is in the code, please [check it out on GitHub](https://github.com/fluencelabs/aqua-lib/blob/main/builtin.aqua)
14 |
15 | ### Services
16 |
17 | `aqua-lib` defines a number of services available on peers in the Fluence Network:
18 |
19 | * `Op` - short for "Operations". Functions for data transformation.
20 | * `Peer` - functions affecting peer's internal state
21 | * `Kademlia` - functions to manipulate libp2p Kademlia
22 | * `Srv` - short for "Service". Functions for service manipulation
23 | * `Dist` - short for "Distribution". Functions for module and blueprint distribution
24 | * `Script` - functions to run and remove scheduled (recurring) scripts
25 |
26 | ## How to use it
27 |
28 | ### In Aqua
29 |
30 | Add `@fluencelabs/aqua-lib` to your dependencies as described in [Libraries doc](./libraries.md), and then import it in your Aqua script:
31 |
32 | ```aqua
33 | import "@fluencelabs/aqua-lib/builtin.aqua"
34 |
35 | -- gather Peer.identify from all nodes in the neighborhood
36 | func getPeersInfo() -> []Info:
37 | infos: *Info
38 | nodes <- Kademlia.neighborhood(INIT_PEER_ID, nil, nil)
39 | for node <- nodes:
40 | on node:
41 | infos <- Peer.identify()
42 | <- infos
43 | ```
44 |
45 | ### In TypeScript
46 |
47 | `aqua-lib` is meant to be used to write Aqua scripts, and since`aqua-lib` doesn't export any top-level functions, it's not callable directly in the TypeScript.
48 |
49 | ## Patterns
50 |
51 | ### Functions With A Variable Number Of Arguments
52 |
53 | Currently, Aqua doesn't allow to define functions with a variable number of arguments. And that limits `aqua-lib` API. But there's a way around that.
54 |
55 | Let's take `Op.concat_strings` as an example. You can use it to concatenate several strings. `aqua-lib` provides the following signature:
56 |
57 | ```aqua
58 | concat_strings(a: string, b: string) -> string
59 | ```
60 |
61 | Sometimes that is enough, but sometimes you need to concatenate more than 2 strings at a time. Happily, under the hood `concat_strings` accepts any number of arguments, so you can redeclare it with the number of arguments that you want:
62 |
63 | ```aqua
64 | service MyOp("op"):
65 | concat_strings(a: string, b: string, c: string, d: string) -> string
66 | ```
67 |
68 | #### List of operations with a variable number of arguments
69 |
70 | Here's a full list of other Op-s that you can apply this pattern to
71 |
72 | * `Op.concat` - can concatenate any number of arrays
73 | * `Op.array` - wraps any number of arguments into an array
74 | * `Op.concat_string` - concatenates any number of strings
75 |
--------------------------------------------------------------------------------
/docs/aqua-book/libraries/libraries.md:
--------------------------------------------------------------------------------
1 | # Libraries
2 |
3 | `import` declaration allows to use functions, services and data types defined in another module on the file system. While it's a very simple mechanic, together with NPM flexibility it enables full-blown package management in Aqua.
4 |
5 | ## Available Aqua Libraries
6 |
7 | * Builtin services API: [@fluencelabs/aqua-lib](aqua-lib.md) (see on [NPM](https://www.npmjs.com/package/@fluencelabs/aqua-lib))
8 | * Registry: [@fluencelabs/registry](registry.md) (see on [NPM](https://www.npmjs.com/package/@fluencelabs/registry))
9 | * IPFS API: [@fluencelabs/aqua-ipfs](aqua-ipfs.md) (see on [NPM](https://www.npmjs.com/package/@fluencelabs/aqua-ipfs))
10 |
11 | ## How To Use Aqua Libraries
12 |
13 | To use a library, you need to download it by adding the library to `dependencies` in `package.json` and then running `npm install`.
14 |
15 | :::info
16 | If you're not familiar with NPM, `package.json` is a project definition file. You can specify `dependencies` to be downloaded from [npm](https://npmjs.org) and define custom commands (`scripts`), which can be executed from the command line, e.g. `npm run compile-aqua.`
17 |
18 | To create an NPM project, run `npm init`in a directory of your choice and follow the instructions.
19 | :::
20 |
21 | Here's an example of adding `aqua-lib` to `package.json` dependencies:
22 |
23 | ```json
24 | {
25 | "name": "my-awesome-project",
26 | "version": "0.0.1",
27 | "dependencies": {
28 | "@fluencelabs/aqua-lib": "0.1.10"
29 | }
30 | }
31 | ```
32 |
33 | After running `npm i`, you will have `@fluencelabs/aqua-lib` in `node_modules`
34 |
35 | ### In Aqua
36 |
37 | After the library is downloaded, you can import it in your `.aqua` script as documented in [Imports And Exports](../language/header/header.md):
38 |
39 | ```typescript
40 | import "@fluencelabs/aqua-lib/builtin.aqua"
41 | ```
42 |
43 | Check out corresponding pages for the API of available libraries.
44 |
45 | ### In TypeScript and JavaScript
46 |
47 | To execute Aqua functions, you need to be connected to the Fluence network. The easiest way is to add JS SDK to `dependencies`:
48 |
49 | ```json
50 | "dependencies": {
51 | "@fluencelabs/registry": "0.3.2",
52 | "@fluencelabs/fluence": "0.21.5",
53 | "@fluencelabs/fluence-network-environment": "1.0.13"
54 | }
55 | ```
56 |
57 | After executing `npm install`, the Aqua API is ready to use. Now you need to export `registry` functions to TypeScript, that's easy. Create a file `export.aqua`:
58 |
59 | ```aqua
60 | import createRouteAndRegisterBlocking, resolveRoute from "@fluencelabs/registry/routing.aqua"
61 |
62 | export createRouteAndRegisterBlocking, resolveRoute
63 | ```
64 |
65 | Now, install Aqua compiler and compile your Aqua code to TypeScript:
66 |
67 | ```sh
68 | npm install --save-dev @fluencelabs/aqua
69 | aqua -i . -o src/generated/
70 | ```
71 |
72 | That's it. Now let's call some functions on the Registry service:
73 |
74 | ```typescript
75 | import { Fluence } from "@fluencelabs/fluence";
76 | import { krasnodar } from "@fluencelabs/fluence-network-environment";
77 | import { createRouteAndRegisterBlocking, resolveRoute } from "./generated/export";
78 |
79 | async function main() {
80 | // connect to the Fluence network
81 | await Fluence.start({ connectTo: krasnodar[1] });
82 |
83 | let label = "myLabel";
84 | let value = "put anything useful here";
85 | let serviceId = "Foo";
86 | let ack = 5;
87 |
88 | // create route and register for it
89 | let relay = Fluence.getStatus().relayPeerId;
90 | let route_id = await createRouteAndRegisterBlocking(
91 | label, value, relay, serviceId,
92 | (s) => console.log(`node ${s} saved the record`),
93 | ack
94 | );
95 |
96 | // this will contain peer as route provider
97 | let providers = await resolveRoute(route_id, ack);
98 | }
99 |
100 | main().then(() => process.exit(0))
101 | .catch(error => {
102 | console.error(error);
103 | process.exit(1);
104 | });
105 |
106 | ```
107 |
--------------------------------------------------------------------------------
/docs/aqua-book/libraries/registry.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: Aqua implementation of Fluence Registry and ResourcesAPI
3 | ---
4 |
5 | # @fluencelabs/registry
6 |
7 | Fluence Registry is an essential part of the Fluence network protocol. It provides a Resources API that can be used for service advertisement and discovery. For more details check out our [community call](https://www.youtube.com/watch?v=Md0_Ny_5_1o&t=770s).
8 |
9 | ## Releases
10 |
11 | You can find the latest `registry` release [on NPM](https://www.npmjs.com/package/@fluencelabs/registry) and the changelogs are in the [GitHub](https://github.com/fluencelabs/registry/releases) repo.
12 |
13 | ## API
14 |
15 | For the API implementation, take a look at [resources-api.aqua](https://github.com/fluencelabs/registry/blob/main/aqua/resources-api.aqua) in the `registry` repo.
16 |
17 | ## Learn
18 |
19 | You can checkout [README](https://github.com/fluencelabs/registry#readme) and follow the [example](https://github.com/fluencelabs/registry/tree/main/example#services-advertisement-and-discovery)
--------------------------------------------------------------------------------
/docs/build/concepts/best_practices.md:
--------------------------------------------------------------------------------
1 | # Best Practices
--------------------------------------------------------------------------------
/docs/build/concepts/fluence_functions_revisited.md:
--------------------------------------------------------------------------------
1 | # Fluence Functions Revisited
--------------------------------------------------------------------------------
/docs/build/concepts/http_gateways.md:
--------------------------------------------------------------------------------
1 | # Handling HTTP Events
--------------------------------------------------------------------------------
/docs/build/concepts/scheduling_functions.md:
--------------------------------------------------------------------------------
1 | # Scheduling Fluence Functions
2 |
3 | ## Introduction
4 |
5 | Like most serverless function, Fluence compute functions sit idle unless invoked. For the most part, event-based triggers will do the job, **link** to js-client. However, time-based triggers, such as cronjobs to poll some resource or simply wake up some other function at some pre-determined interval, are also a common source of function invocation.
6 |
7 | The Fluence Cloudless platform accommodates time-based triggers via Cloudless Scheduled Functions (aka spells).
--------------------------------------------------------------------------------
/docs/build/concepts/security.md:
--------------------------------------------------------------------------------
1 | # Security
--------------------------------------------------------------------------------
/docs/build/examples/frpc.md:
--------------------------------------------------------------------------------
1 | # Decentralized RPC With Fluence Functions
2 |
3 | Fluence's [fRPC Substrate](https://github.com/fluencelabs/frPC-Substrate) is a starter kit that includes all the components you need to quickly enable your dAPP with decentralized RPC using existing RPC as Service providers, e.g., Infura, Alchemy, QuickNode, etc., without having to modify your dApp's business logic or web3 libraries.
--------------------------------------------------------------------------------
/docs/build/how-to/configure.md:
--------------------------------------------------------------------------------
1 | # Configure FLuence CLI
--------------------------------------------------------------------------------
/docs/build/how-to/deploy.md:
--------------------------------------------------------------------------------
1 | # Deploy Your Fluence Functions
--------------------------------------------------------------------------------
/docs/build/how-to/develop.md:
--------------------------------------------------------------------------------
1 | # Develop Your Fluence Functions
2 |
3 |
--------------------------------------------------------------------------------
/docs/build/how-to/migrate.md:
--------------------------------------------------------------------------------
1 | # How To Migrate Your Deployed Fluence Functions
--------------------------------------------------------------------------------
/docs/build/how-to/monitor.md:
--------------------------------------------------------------------------------
1 | # How To Monitor Your Fluence Functions
2 |
--------------------------------------------------------------------------------
/docs/build/how-to/securing_functions.md:
--------------------------------------------------------------------------------
1 | # Secure your Fluence Functions
--------------------------------------------------------------------------------
/docs/build/how-to/setting_up.md:
--------------------------------------------------------------------------------
1 | # Set Up Your Development Environment
2 |
3 | ## Overview
4 |
5 | Fluence provides an CLI that not only supports the scaffolding of development projects bu also manages a number of development dependencies including the Rust development tools necessary to code your business logic and compile to wasm-wasi. With respect to
6 |
7 |
8 | ## Fluence Tooling
9 |
10 | ### Preparing your system
11 |
12 | [node](https://nodejs.org/en/learn/getting-started/how-to-install-nodejs)
13 |
14 | ### FLuence CLI
15 |
16 | #### Install From Binary
17 |
18 | #### Install From Package Manager
19 |
20 | #### Install From Source
21 |
22 |
23 | ### VSCode Plug-In
24 |
25 | VSCode marketplace
26 |
27 |
28 | ## Crypto Wallet
29 |
30 | Note: Hopefully we won't need that
31 |
32 | ## Payment Account
33 |
34 | Fiat On Ramp: TBD
35 |
36 |
--------------------------------------------------------------------------------
/docs/build/how-to/setup_payments.md:
--------------------------------------------------------------------------------
1 | # Manage Payments And Billing
--------------------------------------------------------------------------------
/docs/build/how-to/test.md:
--------------------------------------------------------------------------------
1 | # Test Your Fluence Functions
--------------------------------------------------------------------------------
/docs/build/overview/getting_started.md:
--------------------------------------------------------------------------------
1 | # Getting Started
2 |
3 | Let's explore the obligatory **Hello World** example as an end-to-end Fluence Cloudless App, which includes the following steps:
4 |
5 | * Scaffold a Fluence Cloud Function project with the [Fluence CLI](./../glossary#fluence-cli)
6 | * Create the Hello World example and compile it to Wasm
7 | * Distribute the Wasm module to capacity (hardware) providers
8 | * Execute your Fluence Functions Hello World application
9 |
10 | But first, let's get set up.
11 |
12 | ## Setting Up
13 |
14 | The recommended way to interact with the Fluence serverless network is to use the Fluence CLI. The CLI provides full lifecycle management for your Fluence Functions as well as your tooling and development dependencies. If you haven't installed the Fluence CLI already, use the install script provided below or check out the [Setting up](./../setting-up/setting_up.md) section.
15 |
16 | ```bash
17 | curl -qsL https://raw.githubusercontent.com/fluencelabs/cli/main/install.sh | bash
18 | ```
19 |
20 | :::note
21 | Currently, Fluence CLI does not support Windows OS but supports Windows Linux Subsystem (WLS).
22 | :::
23 |
24 | :::info
25 | During the installation process, you may be asked to provide *sudo* access to set the symlink for the binary.
26 | Alternative installation approaches can be found in the [Readme](https://github.com/fluencelabs/cli?tab=readme-ov-file#installation-and-usage).
27 | :::
28 |
29 | After the installation process is complete, update the CLI with `fluence update stable` and check the version:
30 |
31 | ```bash
32 | fluence --version
33 | @fluencelabs/cli/0.15.10 darwin-arm64 node-v18.19.1
34 | ```
35 |
36 | If you get the above CLI version, or higher, you are good to go.
37 |
38 | ## Hello World
39 |
40 | With the Fluence CLI installed, let's create our *hello world* project:
41 |
42 | ```bash
43 | fluence init hello-fluence
44 | ```
45 |
46 | You will be asked to choose from different scaffolding templates:
47 |
48 | ```bash
49 | fluence init hello-fluence
50 | ? Select template (Use arrow keys)
51 | ❯ quickstart
52 | minimal
53 | ts
54 | js
55 | ```
56 |
57 | Select the (default) *quickstart* template and in the subsequent network selection prompt continue to stay with the default (*kras*) network. Fluence CLI now scaffolds a project with the quickstart template and for the *kras* test network. Since this is your first use of the Fluence CLI, several dependencies may be downloaded and installed. Once the project has been successfully installed, you should see a message similar to:
58 |
59 | ```bash
60 | Successfully initialized Fluence CLI project template at /hello-fluence
61 | ```
62 |
63 | Now *cd* into the *hello-fluence* directory and feel free to poke around the project. Our next step is to run *hello world*
64 |
65 | ```bash
66 | $ fluence run -f 'helloWorldRemote("Fluence")' --quiet
67 | ```
68 | Which results in the following response:
69 |
70 | ```bash
71 | "Hi, Fluence"
72 | ```
73 |
74 | Congratulations! You just scaffolded your first Fluence project and executed your first *Hello World* on a remote peer on the *dar* test network. We'll revisit our *Hello World* project in the [Quickstart](./../quickstarts/your_first_function.md) section.
--------------------------------------------------------------------------------
/docs/build/overview/roadmap.md:
--------------------------------------------------------------------------------
1 | # Roadmap
2 |
3 | Coming soon.
--------------------------------------------------------------------------------
/docs/build/references.md:
--------------------------------------------------------------------------------
1 | # References
--------------------------------------------------------------------------------
/docs/build/security.md:
--------------------------------------------------------------------------------
1 | # Security
2 |
3 | revised edition
--------------------------------------------------------------------------------
/docs/build/setting-up/setting_up.md:
--------------------------------------------------------------------------------
1 | # Setting Up
2 |
3 | ## Introduction
4 |
5 | In order to get your [Cloudless App](./../glossary#cloudless-app) developed and running, some housekeeping with respect to both development and payment environments are required.
6 |
7 | Fluence Cloudless offers you, the developer, a great degree of control over almost every aspect of your Cloudless App:
8 |
9 | * which data center(s) host you cloudless code, e.g., geo-location or carbon footprint requirements
10 | * what capacity capabilities execute your functions, e.g., CPU and RAM type
11 | * what level of resources you want to power your functions, e.g., number of CPUs
12 | * what level of availability you want for your Cloudless App.
13 |
14 | Moreover, in Fluence's *"verify, don't trust"* paradigm, providers have to submit [cryptographic proofs](./../glossary#proofs) attesting to the correct execution of your Cloudless Functions in order to be able to collect the pre-agreed price for their compute services rendered. Hence, the underlying billing and payment models also are different.
15 |
16 | Instead of a credit card on file that is (for the most part) charged at the end of the month for compute service charges incurred over the billing period, e.g., the last calendar month, as reported by the cloud provider, Fluence Cloudless operates on a pre-payment and token model putting you, the developer, fully into control of your payments.
17 |
18 | ### Fluence Networks
19 |
20 | In order to create and operate your Cloudless App, you need to interact with two different networks: the Fluence Compute Network and the Fluence Compute Marketplace. The Fluence Compute Network is a peer-to-peer network connecting peers, i.e., servers in various data centers, hosting and executing your Cloudless Deployments on demand. The Fluence Compute Marketplace is a blockchain hosting the necessary smart contracts to allow you to commit your [developer offer](./../glossary#developer-offer) for matching with [provider offers](./../glossary#provider-offer) and to manage the proof-based charges from each peer owner, i.e., provider, running your [Cloudless Deployments](./../glossary#cloudless-deployment). Each network is available in a production, i.e., mainnet, or testing, i.e., testnet, flavor. In addition, the remote testnets can be stood-up locally to further ease development.
21 |
22 | Table 1: Network Names
23 |
24 | | | Compute Network | Marketplace Network |
25 | |---|---|---|
26 | | testnet| `dar`| TBD|
27 | | mainnet| `kras` | TBD |
28 | | local | `dar` | TBD|
29 |
30 | Testnet deployments require the same token types than the mainnet except that those tokens have no trading value and are freely available in small quantities to cloudless developers from the testnet *faucet*, i.e., a web app that facilitates the distribution of free tokens. In the case of the Fluence testnet. Again, both **tFLT** and **tUSDC** carry no trading value and are freely available to developers in small but sufficient quantities to develop and test their Cloudless Apps.
31 |
32 | For details concerning the operation of a local network, see [Working With A Local Network](./working_with_local_networks.md).
33 |
34 | ## Setting Up For Payment
35 |
36 | In order to handle tokens, testnet or otherwise, you need a crypto wallet. If you are unfamiliar with crypto wallets, have a look at this [introduction](https://www.coindesk.com/learn/your-first-crypto-wallet-how-to-use-it-and-why-you-need-one/) but [DuckDuckGo](https://duckduckgo.com/?q=introduction+to+crypto+wallets&df=y&ia=web) is your friend. Note that you will be storing ERC 20 type tokens and interacting with an EVM-compatible blockchain. That is, select a [wallet that is compatible with the Ethereum Virtual Machine](https://shardeum.org/blog/what-is-evm-wallet/). For illustrative purposes, we'll be using [MetaMask](https://metamask.io/). Moreover, we will primarily focus on testnet deployments. A guide for migrating your Cloudless App to mainnet is coming soon.
37 |
38 | Assuming you have your wallet ready to go, you need to add the testnet and testnet tokens **tFLT** and **tUSDC**, respectively, request test tokens from the Fluence faucet.
39 |
40 | ### Creating And Funding Your Wallet
41 |
42 | It is recommended to use a dedicated development account for your testnet. That is, create a new account in your wallet and name it, say, *Fluence DAR Testnet* and use this account only to manage your testnet tokens and chain interactions.
43 |
44 | In your wallet, you need to create a network entry for the Fluence IPC `dar` testnet. Use the following parameters:
45 |
46 | ```json
47 | {
48 | "network name": "Fluence Dar Testnet"
49 | "rpc url": "https://ipc-dar.fluence.dev",
50 | "chain id": 3525067388221321,
51 | "currency symbol": "tFLT",
52 | "block explorer url": "https://blockscout.dar.fluence.dev/"
53 | }
54 | ```
55 |
56 | Once you got the network set, it's time to visit the faucet and request our token allocation. You can find all relevant support urls for the `dar` testnet [here](https://dar.fluence.dev/).
57 |
58 | ### Requesting Test Tokens From The Faucet
59 |
60 | Now that your account and wallet are setup, select the Fluence network you just added and grab the account address you want to use to hold your testnet tokens. Go to the Fluence [dar testnet faucet](https://faucet-dar.fluence.dev/), which prompts you to sign in with an email address. Shortly after submitting your email address, you will receive an email from `Faucet`. Make sure to check your spam folder. Copy the code into the open field and submit. At this point, you should see a screen similar to this:
61 |
62 |
63 |
64 |