chore(js-client): Update and restructure examples [fixes DXJ-454] (#464)
* Update examples * Update js-client examples * Add cli to example * Fixes * Update js-client * Update js-client version in js-client examples * PR fixes * Remove marine-js * Update locks * Fix aqua * Remove unused import * Adjust import * Change code comment * Update example structures * Fix quickstart examples * Add aqua command to README * Add marine example * Fix image links * Fixes * Misc fixes
779
quickstart/1-browser-to-browser/.fluence/schemas/fluence.json
Normal file
@ -0,0 +1,779 @@
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"services": {
|
||||
"title": "Services",
|
||||
"description": "A map with service names as keys and Service configs as values. You can have any number of services listed here as long as service name keys start with a lowercase letter and contain only letters numbers and underscores. You can use `fluence service add` command to add a service to this config",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"title": "Service config",
|
||||
"description": "Service config. Defines where the service is and how to deploy it",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"get": {
|
||||
"type": "string",
|
||||
"description": "Path to service directory or URL to the tar.gz archive with the service"
|
||||
},
|
||||
"overrideModules": {
|
||||
"type": "object",
|
||||
"title": "Overrides",
|
||||
"description": "A map of modules to override",
|
||||
"additionalProperties": {
|
||||
"type": "object",
|
||||
"title": "Module overrides",
|
||||
"description": "Overrides for the module config",
|
||||
"properties": {
|
||||
"maxHeapSize": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "Max size of the heap that a module can allocate in format: [number][whitespace?][specificator?] where ? is an optional field and specificator is one from the following (case-insensitive):\nK, Kb - kilobyte\nKi, KiB - kibibyte\nM, Mb - megabyte\nMi, MiB - mebibyte\nG, Gb - gigabyte\nGi, GiB - gibibyte\nCurrent limit is 4 GiB"
|
||||
},
|
||||
"loggerEnabled": {
|
||||
"type": "boolean",
|
||||
"nullable": true,
|
||||
"description": "Set true to allow module to use the Marine SDK logger"
|
||||
},
|
||||
"loggingMask": {
|
||||
"type": "number",
|
||||
"nullable": true,
|
||||
"description": "manages the logging targets, described in detail: https://fluence.dev/docs/marine-book/marine-rust-sdk/developing/logging#using-target-map"
|
||||
},
|
||||
"volumes": {
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"title": "Volumes",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Alias": {
|
||||
"type": "string",
|
||||
"description": "path"
|
||||
}
|
||||
},
|
||||
"description": "A map of accessible files and their aliases. Aliases should be used in Marine module development because it's hard to know the full path to a file"
|
||||
},
|
||||
"envs": {
|
||||
"type": "object",
|
||||
"title": "Environment variables",
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Environment_variable_name": {
|
||||
"type": "string",
|
||||
"description": "Environment variable value"
|
||||
}
|
||||
},
|
||||
"description": "environment variables accessible by a particular module with standard Rust env API like this: std::env::var(IPFS_ADDR_ENV_NAME). Please note that Marine adds three additional environment variables. Module environment variables could be examined with repl"
|
||||
},
|
||||
"mountedBinaries": {
|
||||
"title": "Mounted binaries",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Mounted_binary_name": {
|
||||
"type": "string",
|
||||
"description": "Path to a mounted binary"
|
||||
}
|
||||
},
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"description": "A map of binary executable files that module is allowed to call. Example: curl: /usr/bin/curl"
|
||||
}
|
||||
},
|
||||
"required": [],
|
||||
"nullable": true
|
||||
},
|
||||
"properties": {
|
||||
"Module_name": {
|
||||
"type": "object",
|
||||
"title": "Module overrides",
|
||||
"description": "Overrides for the module config",
|
||||
"properties": {
|
||||
"maxHeapSize": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "Max size of the heap that a module can allocate in format: [number][whitespace?][specificator?] where ? is an optional field and specificator is one from the following (case-insensitive):\nK, Kb - kilobyte\nKi, KiB - kibibyte\nM, Mb - megabyte\nMi, MiB - mebibyte\nG, Gb - gigabyte\nGi, GiB - gibibyte\nCurrent limit is 4 GiB"
|
||||
},
|
||||
"loggerEnabled": {
|
||||
"type": "boolean",
|
||||
"nullable": true,
|
||||
"description": "Set true to allow module to use the Marine SDK logger"
|
||||
},
|
||||
"loggingMask": {
|
||||
"type": "number",
|
||||
"nullable": true,
|
||||
"description": "manages the logging targets, described in detail: https://fluence.dev/docs/marine-book/marine-rust-sdk/developing/logging#using-target-map"
|
||||
},
|
||||
"volumes": {
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"title": "Volumes",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Alias": {
|
||||
"type": "string",
|
||||
"description": "path"
|
||||
}
|
||||
},
|
||||
"description": "A map of accessible files and their aliases. Aliases should be used in Marine module development because it's hard to know the full path to a file"
|
||||
},
|
||||
"envs": {
|
||||
"type": "object",
|
||||
"title": "Environment variables",
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Environment_variable_name": {
|
||||
"type": "string",
|
||||
"description": "Environment variable value"
|
||||
}
|
||||
},
|
||||
"description": "environment variables accessible by a particular module with standard Rust env API like this: std::env::var(IPFS_ADDR_ENV_NAME). Please note that Marine adds three additional environment variables. Module environment variables could be examined with repl"
|
||||
},
|
||||
"mountedBinaries": {
|
||||
"title": "Mounted binaries",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Mounted_binary_name": {
|
||||
"type": "string",
|
||||
"description": "Path to a mounted binary"
|
||||
}
|
||||
},
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"description": "A map of binary executable files that module is allowed to call. Example: curl: /usr/bin/curl"
|
||||
}
|
||||
},
|
||||
"required": [],
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
"nullable": true,
|
||||
"required": []
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"get"
|
||||
]
|
||||
},
|
||||
"properties": {
|
||||
"Service_name": {
|
||||
"title": "Service config",
|
||||
"description": "Service config. Defines where the service is and how to deploy it",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"get": {
|
||||
"type": "string",
|
||||
"description": "Path to service directory or URL to the tar.gz archive with the service"
|
||||
},
|
||||
"overrideModules": {
|
||||
"type": "object",
|
||||
"title": "Overrides",
|
||||
"description": "A map of modules to override",
|
||||
"additionalProperties": {
|
||||
"type": "object",
|
||||
"title": "Module overrides",
|
||||
"description": "Overrides for the module config",
|
||||
"properties": {
|
||||
"maxHeapSize": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "Max size of the heap that a module can allocate in format: [number][whitespace?][specificator?] where ? is an optional field and specificator is one from the following (case-insensitive):\nK, Kb - kilobyte\nKi, KiB - kibibyte\nM, Mb - megabyte\nMi, MiB - mebibyte\nG, Gb - gigabyte\nGi, GiB - gibibyte\nCurrent limit is 4 GiB"
|
||||
},
|
||||
"loggerEnabled": {
|
||||
"type": "boolean",
|
||||
"nullable": true,
|
||||
"description": "Set true to allow module to use the Marine SDK logger"
|
||||
},
|
||||
"loggingMask": {
|
||||
"type": "number",
|
||||
"nullable": true,
|
||||
"description": "manages the logging targets, described in detail: https://fluence.dev/docs/marine-book/marine-rust-sdk/developing/logging#using-target-map"
|
||||
},
|
||||
"volumes": {
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"title": "Volumes",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Alias": {
|
||||
"type": "string",
|
||||
"description": "path"
|
||||
}
|
||||
},
|
||||
"description": "A map of accessible files and their aliases. Aliases should be used in Marine module development because it's hard to know the full path to a file"
|
||||
},
|
||||
"envs": {
|
||||
"type": "object",
|
||||
"title": "Environment variables",
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Environment_variable_name": {
|
||||
"type": "string",
|
||||
"description": "Environment variable value"
|
||||
}
|
||||
},
|
||||
"description": "environment variables accessible by a particular module with standard Rust env API like this: std::env::var(IPFS_ADDR_ENV_NAME). Please note that Marine adds three additional environment variables. Module environment variables could be examined with repl"
|
||||
},
|
||||
"mountedBinaries": {
|
||||
"title": "Mounted binaries",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Mounted_binary_name": {
|
||||
"type": "string",
|
||||
"description": "Path to a mounted binary"
|
||||
}
|
||||
},
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"description": "A map of binary executable files that module is allowed to call. Example: curl: /usr/bin/curl"
|
||||
}
|
||||
},
|
||||
"required": [],
|
||||
"nullable": true
|
||||
},
|
||||
"properties": {
|
||||
"Module_name": {
|
||||
"type": "object",
|
||||
"title": "Module overrides",
|
||||
"description": "Overrides for the module config",
|
||||
"properties": {
|
||||
"maxHeapSize": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "Max size of the heap that a module can allocate in format: [number][whitespace?][specificator?] where ? is an optional field and specificator is one from the following (case-insensitive):\nK, Kb - kilobyte\nKi, KiB - kibibyte\nM, Mb - megabyte\nMi, MiB - mebibyte\nG, Gb - gigabyte\nGi, GiB - gibibyte\nCurrent limit is 4 GiB"
|
||||
},
|
||||
"loggerEnabled": {
|
||||
"type": "boolean",
|
||||
"nullable": true,
|
||||
"description": "Set true to allow module to use the Marine SDK logger"
|
||||
},
|
||||
"loggingMask": {
|
||||
"type": "number",
|
||||
"nullable": true,
|
||||
"description": "manages the logging targets, described in detail: https://fluence.dev/docs/marine-book/marine-rust-sdk/developing/logging#using-target-map"
|
||||
},
|
||||
"volumes": {
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"title": "Volumes",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Alias": {
|
||||
"type": "string",
|
||||
"description": "path"
|
||||
}
|
||||
},
|
||||
"description": "A map of accessible files and their aliases. Aliases should be used in Marine module development because it's hard to know the full path to a file"
|
||||
},
|
||||
"envs": {
|
||||
"type": "object",
|
||||
"title": "Environment variables",
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Environment_variable_name": {
|
||||
"type": "string",
|
||||
"description": "Environment variable value"
|
||||
}
|
||||
},
|
||||
"description": "environment variables accessible by a particular module with standard Rust env API like this: std::env::var(IPFS_ADDR_ENV_NAME). Please note that Marine adds three additional environment variables. Module environment variables could be examined with repl"
|
||||
},
|
||||
"mountedBinaries": {
|
||||
"title": "Mounted binaries",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Mounted_binary_name": {
|
||||
"type": "string",
|
||||
"description": "Path to a mounted binary"
|
||||
}
|
||||
},
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"description": "A map of binary executable files that module is allowed to call. Example: curl: /usr/bin/curl"
|
||||
}
|
||||
},
|
||||
"required": [],
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
"nullable": true,
|
||||
"required": []
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"get"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [],
|
||||
"nullable": true
|
||||
},
|
||||
"version": {
|
||||
"type": "number",
|
||||
"const": 5
|
||||
},
|
||||
"dependencies": {
|
||||
"type": "object",
|
||||
"title": "Dependencies",
|
||||
"nullable": true,
|
||||
"description": "(For advanced users) Overrides for the project dependencies",
|
||||
"properties": {
|
||||
"npm": {
|
||||
"type": "object",
|
||||
"title": "npm dependencies",
|
||||
"nullable": true,
|
||||
"description": "A map of npm aqua dependency versions. Fluence CLI ensures dependencies are installed each time you run aqua",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"npm_dependency_name": {
|
||||
"type": "string",
|
||||
"description": "npm dependency version"
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
},
|
||||
"cargo": {
|
||||
"type": "object",
|
||||
"title": "Cargo dependencies",
|
||||
"nullable": true,
|
||||
"description": "A map of cargo dependency versions. Fluence CLI ensures dependencies are installed each time you run commands that depend on Marine or Marine REPL",
|
||||
"required": [],
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Cargo_dependency_name": {
|
||||
"type": "string",
|
||||
"description": "cargo dependency version"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
},
|
||||
"aquaInputPath": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "Path to the aqua file or directory with aqua files that you want to compile by default. Must be relative to the project root dir"
|
||||
},
|
||||
"aquaOutputTSPath": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "Path to the default compilation target dir from aqua to ts. Must be relative to the project root dir"
|
||||
},
|
||||
"aquaOutputJSPath": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "Path to the default compilation target dir from aqua to js. Must be relative to the project root dir. Overrides 'aquaOutputTSPath' property"
|
||||
},
|
||||
"hosts": {
|
||||
"description": "A map of objects with worker names as keys, each object defines a list of peer IDs to host the worker on. Intended to be used by providers to deploy directly without using the blockchain",
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"additionalProperties": {
|
||||
"type": "object",
|
||||
"description": "Worker config",
|
||||
"properties": {
|
||||
"services": {
|
||||
"description": "An array of service names to include in this worker. Service names must be listed in fluence.yaml",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"nullable": true
|
||||
},
|
||||
"spells": {
|
||||
"description": "An array of spell names to include in this worker. Spell names must be listed in fluence.yaml",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"nullable": true
|
||||
},
|
||||
"peerIds": {
|
||||
"type": "array",
|
||||
"description": "An array of peer IDs to deploy on",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"minItems": 1
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
},
|
||||
"properties": {
|
||||
"workerName": {
|
||||
"type": "object",
|
||||
"description": "Worker config",
|
||||
"properties": {
|
||||
"services": {
|
||||
"description": "An array of service names to include in this worker. Service names must be listed in fluence.yaml",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"nullable": true
|
||||
},
|
||||
"spells": {
|
||||
"description": "An array of spell names to include in this worker. Spell names must be listed in fluence.yaml",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"nullable": true
|
||||
},
|
||||
"peerIds": {
|
||||
"type": "array",
|
||||
"description": "An array of peer IDs to deploy on",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"minItems": 1
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
},
|
||||
"deals": {
|
||||
"description": "A map of objects with worker names as keys, each object defines a deal",
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"additionalProperties": {
|
||||
"type": "object",
|
||||
"description": "Worker config",
|
||||
"properties": {
|
||||
"services": {
|
||||
"description": "An array of service names to include in this worker. Service names must be listed in fluence.yaml",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"nullable": true
|
||||
},
|
||||
"spells": {
|
||||
"description": "An array of spell names to include in this worker. Spell names must be listed in fluence.yaml",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"nullable": true
|
||||
},
|
||||
"minWorkers": {
|
||||
"type": "number",
|
||||
"description": "Required workers to activate the deal",
|
||||
"default": 1,
|
||||
"nullable": true,
|
||||
"minimum": 1
|
||||
},
|
||||
"targetWorkers": {
|
||||
"type": "number",
|
||||
"description": "Max workers in the deal",
|
||||
"default": 3,
|
||||
"nullable": true,
|
||||
"minimum": 1
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
},
|
||||
"properties": {
|
||||
"dealName": {
|
||||
"type": "object",
|
||||
"description": "Worker config",
|
||||
"properties": {
|
||||
"services": {
|
||||
"description": "An array of service names to include in this worker. Service names must be listed in fluence.yaml",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"nullable": true
|
||||
},
|
||||
"spells": {
|
||||
"description": "An array of spell names to include in this worker. Spell names must be listed in fluence.yaml",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"nullable": true
|
||||
},
|
||||
"minWorkers": {
|
||||
"type": "number",
|
||||
"description": "Required workers to activate the deal",
|
||||
"default": 1,
|
||||
"nullable": true,
|
||||
"minimum": 1
|
||||
},
|
||||
"targetWorkers": {
|
||||
"type": "number",
|
||||
"description": "Max workers in the deal",
|
||||
"default": 3,
|
||||
"nullable": true,
|
||||
"minimum": 1
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
},
|
||||
"spells": {
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"description": "A map with spell names as keys and spell configs as values",
|
||||
"additionalProperties": {
|
||||
"type": "object",
|
||||
"description": "Spell config",
|
||||
"properties": {
|
||||
"get": {
|
||||
"type": "string",
|
||||
"description": "Path to spell"
|
||||
},
|
||||
"version": {
|
||||
"type": "number",
|
||||
"const": 0
|
||||
},
|
||||
"aquaFilePath": {
|
||||
"type": "string",
|
||||
"description": "Path to Aqua file which contains an Aqua function that you want to use as a spell",
|
||||
"nullable": true
|
||||
},
|
||||
"function": {
|
||||
"type": "string",
|
||||
"description": "Name of the Aqua function that you want to use as a spell",
|
||||
"nullable": true
|
||||
},
|
||||
"initArgs": {
|
||||
"type": "object",
|
||||
"description": "A map of Aqua function arguments names as keys and arguments values as values. They will be passed to the spell function and will be stored in the key-value storage for this particular spell.",
|
||||
"nullable": true
|
||||
},
|
||||
"clock": {
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"description": "Trigger the spell execution periodically. If you want to disable this property by overriding it in fluence.yaml - pass empty config for it like this: `clock: {}`",
|
||||
"properties": {
|
||||
"periodSec": {
|
||||
"type": "number",
|
||||
"description": "How often the spell will be executed. If set to 0, the spell will be executed only once. If this value not provided at all - the spell will never be executed",
|
||||
"minimum": 0,
|
||||
"maximum": 3153600000,
|
||||
"nullable": true
|
||||
},
|
||||
"startTimestamp": {
|
||||
"type": "string",
|
||||
"description": "An ISO timestamp when the periodic execution should start. If this property or `startDelaySec` not specified, periodic execution will start immediately. If it is set to 0 - the spell will never be executed",
|
||||
"nullable": true
|
||||
},
|
||||
"endTimestamp": {
|
||||
"type": "string",
|
||||
"description": "An ISO timestamp when the periodic execution should end. If this property or `endDelaySec` not specified, periodic execution will never end. If it is in the past at the moment of spell creation on Rust peer - the spell will never be executed",
|
||||
"nullable": true
|
||||
},
|
||||
"startDelaySec": {
|
||||
"type": "number",
|
||||
"description": "How long to wait before the first execution in seconds. If this property or `startTimestamp` not specified, periodic execution will start immediately. WARNING! Currently your computer's clock is used to determine a final timestamp that is sent to the server. This property conflicts with `startTimestamp`. You can specify only one of them",
|
||||
"nullable": true,
|
||||
"minimum": 0,
|
||||
"maximum": 4294967295
|
||||
},
|
||||
"endDelaySec": {
|
||||
"type": "number",
|
||||
"description": "How long to wait before the last execution in seconds. If this property or `endTimestamp` not specified, periodic execution will never end. WARNING! Currently your computer's clock is used to determine a final timestamp that is sent to the server. If it is in the past at the moment of spell creation - the spell will never be executed. This property conflicts with `endTimestamp`. You can specify only one of them",
|
||||
"nullable": true,
|
||||
"minimum": 0,
|
||||
"maximum": 4294967295
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"get"
|
||||
]
|
||||
},
|
||||
"properties": {
|
||||
"Spell_name": {
|
||||
"type": "object",
|
||||
"description": "Spell config",
|
||||
"properties": {
|
||||
"get": {
|
||||
"type": "string",
|
||||
"description": "Path to spell"
|
||||
},
|
||||
"version": {
|
||||
"type": "number",
|
||||
"const": 0
|
||||
},
|
||||
"aquaFilePath": {
|
||||
"type": "string",
|
||||
"description": "Path to Aqua file which contains an Aqua function that you want to use as a spell",
|
||||
"nullable": true
|
||||
},
|
||||
"function": {
|
||||
"type": "string",
|
||||
"description": "Name of the Aqua function that you want to use as a spell",
|
||||
"nullable": true
|
||||
},
|
||||
"initArgs": {
|
||||
"type": "object",
|
||||
"description": "A map of Aqua function arguments names as keys and arguments values as values. They will be passed to the spell function and will be stored in the key-value storage for this particular spell.",
|
||||
"nullable": true
|
||||
},
|
||||
"clock": {
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"description": "Trigger the spell execution periodically. If you want to disable this property by overriding it in fluence.yaml - pass empty config for it like this: `clock: {}`",
|
||||
"properties": {
|
||||
"periodSec": {
|
||||
"type": "number",
|
||||
"description": "How often the spell will be executed. If set to 0, the spell will be executed only once. If this value not provided at all - the spell will never be executed",
|
||||
"minimum": 0,
|
||||
"maximum": 3153600000,
|
||||
"nullable": true
|
||||
},
|
||||
"startTimestamp": {
|
||||
"type": "string",
|
||||
"description": "An ISO timestamp when the periodic execution should start. If this property or `startDelaySec` not specified, periodic execution will start immediately. If it is set to 0 - the spell will never be executed",
|
||||
"nullable": true
|
||||
},
|
||||
"endTimestamp": {
|
||||
"type": "string",
|
||||
"description": "An ISO timestamp when the periodic execution should end. If this property or `endDelaySec` not specified, periodic execution will never end. If it is in the past at the moment of spell creation on Rust peer - the spell will never be executed",
|
||||
"nullable": true
|
||||
},
|
||||
"startDelaySec": {
|
||||
"type": "number",
|
||||
"description": "How long to wait before the first execution in seconds. If this property or `startTimestamp` not specified, periodic execution will start immediately. WARNING! Currently your computer's clock is used to determine a final timestamp that is sent to the server. This property conflicts with `startTimestamp`. You can specify only one of them",
|
||||
"nullable": true,
|
||||
"minimum": 0,
|
||||
"maximum": 4294967295
|
||||
},
|
||||
"endDelaySec": {
|
||||
"type": "number",
|
||||
"description": "How long to wait before the last execution in seconds. If this property or `endTimestamp` not specified, periodic execution will never end. WARNING! Currently your computer's clock is used to determine a final timestamp that is sent to the server. If it is in the past at the moment of spell creation - the spell will never be executed. This property conflicts with `endTimestamp`. You can specify only one of them",
|
||||
"nullable": true,
|
||||
"minimum": 0,
|
||||
"maximum": 4294967295
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"get"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
},
|
||||
"aquaImports": {
|
||||
"type": "array",
|
||||
"description": "A list of path to be considered by aqua compiler to be used as imports. First dependency in the list has the highest priority. Priority of imports is considered in the following order: imports from --import flags, imports from aquaImports property in fluence.yaml, project's .fluence/aqua dir, npm dependencies from fluence.yaml, npm dependencies from user's .fluence/config.yaml, npm dependencies recommended by fluence",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"nullable": true
|
||||
},
|
||||
"marineBuildArgs": {
|
||||
"type": "string",
|
||||
"description": "Space separated `cargo build` flags and args to pass to marine build. Can be overridden using --marine-build-args flag Default: --release",
|
||||
"nullable": true
|
||||
},
|
||||
"cliVersion": {
|
||||
"type": "string",
|
||||
"description": "The version of the Fluence CLI that is compatible with this project. Set this to enforce a particular set of versions of all fluence components",
|
||||
"nullable": true
|
||||
},
|
||||
"ipfsAddr": {
|
||||
"type": "string",
|
||||
"description": "IPFS multiaddress to use when uploading workers with 'deal deploy'. Default: /dns4/ipfs.fluence.dev/tcp/5001 or /ip4/127.0.0.1/tcp/5001 if using local local env (for 'workers deploy' IPFS address provided by relay that you are connected to is used)",
|
||||
"nullable": true,
|
||||
"default": "/dns4/ipfs.fluence.dev/tcp/5001"
|
||||
},
|
||||
"customFluenceEnv": {
|
||||
"type": "object",
|
||||
"description": "Custom Fluence environment to use when connecting to Fluence network",
|
||||
"nullable": true,
|
||||
"properties": {
|
||||
"contractsEnv": {
|
||||
"type": "string",
|
||||
"description": "Contracts environment to use for this fluence network to sign contracts on the blockchain",
|
||||
"enum": [
|
||||
"kras",
|
||||
"testnet",
|
||||
"stage",
|
||||
"local"
|
||||
]
|
||||
},
|
||||
"relays": {
|
||||
"type": "array",
|
||||
"description": "List of custom relay multiaddresses to use when connecting to Fluence network",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"minItems": 1
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"contractsEnv",
|
||||
"relays"
|
||||
]
|
||||
},
|
||||
"defaultSecretKeyName": {
|
||||
"description": "Secret key with this name will be used by default by js-client inside CLI to run Aqua code",
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
},
|
||||
"relaysPath": {
|
||||
"description": "Path to the directory where you want relays.json file to be generated. Must be relative to the project root dir. This file contains a list of relays to use when connecting to Fluence network and depends on the default environment that you use in your project",
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"version"
|
||||
],
|
||||
"$id": "https://fluence.dev/schemas/fluence.yaml",
|
||||
"title": "fluence.yaml",
|
||||
"description": "Defines Fluence Project, most importantly - what exactly you want to deploy and how. You can use `fluence init` command to generate a template for new Fluence project"
|
||||
}
|
@ -1,10 +1,99 @@
|
||||
# Getting started
|
||||
# 1. Browser-to-Browser
|
||||
|
||||
The first example demonstrates how to communicate between two client peers, i.e. browsers, with local services. The project is based on a create-react-app template with slight modifications to integrate Fluence. The primary focus is the integration itself and React could be swapped with any framework of your choice.
|
||||
|
||||
Make sure you are in the `examples/quickstart/1-browser-to-browser/src/frontend` directory to install the dependencies:
|
||||
|
||||
```sh
|
||||
cd 1-browser-to-browser/src/frontend
|
||||
npm install
|
||||
```
|
||||
|
||||
Run aqua compiler:
|
||||
|
||||
```bash
|
||||
npm i
|
||||
fluence aqua
|
||||
```
|
||||
|
||||
Run the app with `npm start` :
|
||||
|
||||
```sh
|
||||
npm start
|
||||
```
|
||||
|
||||
The browser window with `localhost:3000` should open
|
||||
Which opens a new tab in your browser at `http://localhost:3000`. The browser tab, representing the client peer, wants you to pick a relay node it, i.e., the browser client, can connect to and, of course, allows the peer to respond to the browser client. Select any one of the offered relays:
|
||||
|
||||
To learn more, refer to the [documentation page](https://fluence.dev//docs/build/quick-start/browser-to-browser/)
|
||||

|
||||
|
||||
The client peer is now connected to the relay and ready for business:
|
||||
|
||||

|
||||
|
||||
Let's follow the instructions, open another browser tab preferably in another browser, using `http://localhost:3000` , select any one of the relays and copying the ensuing peer id and relay peer id to the first client peer, i.e. the first browser tab, and click the `say hello` button:
|
||||
|
||||

|
||||
|
||||
Congratulations, you just sent messages between two browsers over the Fluence peer-to-peer network, which is pretty cool! Even cooler, however, is how we got here using Aqua, Fluence's distributed network and application composition language.
|
||||
|
||||
Navigate to the `aqua` directory and open the `aqua/getting-started.aqua` file in your IDE or terminal:
|
||||
|
||||
```aqua
|
||||
import "@fluencelabs/aqua-lib/builtin.aqua"
|
||||
|
||||
-- The service runs inside browser
|
||||
service HelloPeer("HelloPeer"):
|
||||
hello(from: PeerId) -> string
|
||||
|
||||
func sayHello(targetPeerId: PeerId, targetRelayPeerId: PeerId) -> string:
|
||||
on targetPeerId via targetRelayPeerId:
|
||||
res <- HelloPeer.hello(INIT_PEER_ID)
|
||||
<- res
|
||||
```
|
||||
|
||||
And yes, fewer than ten lines (!) are required for a client peer, like our browser, to connect to the network and start composing the local `HelloPeer` service to send messages.
|
||||
|
||||
In broad strokes, the Aqua code breaks down as follows:
|
||||
|
||||
- Import the Aqua [standard library](https://github.com/fluencelabs/aqua-lib) into our application (1)
|
||||
- Create a service interface binding to the local service (see below) with the `HelloPeer` namespace and `hello` function (4-5)
|
||||
- Create the function `sayHello` that executes the `hello` call on the provided `targetPeerId` via the provided `targetRelayPeerId` and returns the result (7-10). Recall the copy and paste job you did earlier in the browser tab for the peer and relay id? That's where these parameters are interacted with.
|
||||
|
||||
Not only is Aqua rather succinct in allowing you to seamlessly program both network routes and distributed application workflows but also provides the ability to compile Aqua to Typescript stubs wrapping compiled Aqua, called AIR -- short for Aqua Intermediate Representation, into ready to use code blocks. Navigate to the `src/_aqua` directory and open the `aqua/getting-started.ts` file and poke around a bit.
|
||||
|
||||
Note that the `src/App.tsx` file relies on the generated `_aqua/getting-started.ts` file (line 7):
|
||||
|
||||
```typescript
|
||||
import React, { useEffect, useState } from "react";
|
||||
import logo from "./logo.svg";
|
||||
import "./App.scss";
|
||||
|
||||
import { Fluence, kras } from "@fluencelabs/js-client";
|
||||
import { sayHello, registerHelloPeer } from "./_aqua/getting-started";
|
||||
```
|
||||
|
||||
We wrote a little more than a handful of lines of code in Aqua and ended up with a deployment-ready code block that includes both the network routing and compute logic to facilitate browser-to-browser messaging over a peer-to-peer network.
|
||||
|
||||
The local (browser) service `HelloPeer` is also implemented in the `App.tsx` file:
|
||||
|
||||
```typescript
|
||||
const connect = async (relayPeerId: string) => {
|
||||
try {
|
||||
await Fluence.connect(relayPeerId);
|
||||
|
||||
// Register handler for this call in aqua:
|
||||
// HelloPeer.hello(%init_peer_id%)
|
||||
registerHelloPeer({
|
||||
hello: (from) => {
|
||||
setHelloMessage("Hello from: \n" + from);
|
||||
return "Hello back to you, \n" + from;
|
||||
},
|
||||
});
|
||||
} catch (err) {
|
||||
console.log("Client could not connect", err);
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
To summarize, we ran an app that facilities messaging between two browsers over a peer-to-peer network. Aqua allowed us in just a few lines of code to program both the network topology and the application workflow in barely more than a handful of lines of code. Hint: You should be excited. For more information on Aqua, see the [Aqua Book](https://fluence.dev/docs/aqua-book/introduction).
|
||||
|
||||
To learn how to write and deploy your own WebAssembly modules refer to [this](https://fluence.dev/docs/build/get-started) doc.
|
||||
|
After Width: | Height: | Size: 44 KiB |
After Width: | Height: | Size: 195 KiB |
BIN
quickstart/1-browser-to-browser/assets/Relay-Selection.png
Normal file
After Width: | Height: | Size: 110 KiB |
BIN
quickstart/1-browser-to-browser/assets/getting-started.aqua.png
Normal file
After Width: | Height: | Size: 45 KiB |
13
quickstart/1-browser-to-browser/fluence.yaml
Normal file
@ -0,0 +1,13 @@
|
||||
# yaml-language-server: $schema=.fluence/schemas/fluence.json
|
||||
|
||||
# Defines Fluence Project, most importantly - what exactly you want to deploy and how. You can use `fluence init` command to generate a template for new Fluence project
|
||||
|
||||
# Documentation: https://github.com/fluencelabs/cli/tree/main/docs/configs/fluence.md
|
||||
|
||||
version: 5
|
||||
|
||||
aquaInputPath: src/aqua
|
||||
|
||||
relaysPath: src/frontend/src
|
||||
|
||||
aquaOutputTSPath: src/frontend/src/compiled-aqua
|
@ -24,7 +24,7 @@ yarn-error.log*
|
||||
|
||||
# fluence
|
||||
|
||||
src/_aqua/*
|
||||
src/compiled-aqua/*
|
||||
|
||||
public/*.wasm
|
||||
public/runnerScript.*
|
@ -3,32 +3,17 @@
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@fluencelabs/js-client.api": "0.13.1",
|
||||
"@fluencelabs/fluence-network-environment": "1.1.2",
|
||||
"@testing-library/jest-dom": "^5.14.1",
|
||||
"@testing-library/react": "^11.2.7",
|
||||
"@testing-library/user-event": "^12.8.3",
|
||||
"@types/jest": "^27.4.0",
|
||||
"@types/node": "^12.20.16",
|
||||
"@types/react": "^17.0.14",
|
||||
"@types/react-dom": "^17.0.9",
|
||||
"@types/serve-handler": "^6.1.1",
|
||||
"@fluencelabs/js-client": "^0.5.4",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-scripts": "^5.0.0",
|
||||
"typescript": "^4.6.3",
|
||||
"web-vitals": "^1.1.2"
|
||||
},
|
||||
"scripts": {
|
||||
"prestart": "npm run compile-aqua",
|
||||
"prebuild": "npm run compile-aqua",
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "jest --config=jest.config.js",
|
||||
"_test": "react-scripts test",
|
||||
"eject": "react-scripts eject",
|
||||
"compile-aqua": "fluence aqua -i ./aqua/ -o ./src/_aqua",
|
||||
"watch-aqua": "fluence aqua -w -i ./aqua/ -o ./src/_aqua"
|
||||
"eject": "react-scripts eject"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
@ -51,13 +36,21 @@
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@fluencelabs/cli": "0.9.1",
|
||||
"@fluencelabs/aqua-lib": "0.7.7",
|
||||
"@testing-library/jest-dom": "^6.1.4",
|
||||
"@testing-library/react": "^11.2.7",
|
||||
"@testing-library/user-event": "^14.5.1",
|
||||
"@types/jest": "^29.5.6",
|
||||
"@types/jest-environment-puppeteer": "^4.4.1",
|
||||
"@types/node": "^20.8.9",
|
||||
"@types/puppeteer": "^5.4.4",
|
||||
"@types/react": "^18.2.33",
|
||||
"@types/react-dom": "^18.2.14",
|
||||
"@types/serve-handler": "^6.1.3",
|
||||
"jest-puppeteer": "^6.0.2",
|
||||
"react-scripts": "^5.0.1",
|
||||
"sass": "^1.58.3",
|
||||
"serve": "^13.0.2",
|
||||
"ts-jest": "^27.1.3"
|
||||
"ts-jest": "^28.0.8",
|
||||
"typescript": "^4.9.5"
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 4.9 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
@ -2,12 +2,11 @@ import React, { useEffect, useState } from 'react';
|
||||
import logo from './logo.svg';
|
||||
import './App.scss';
|
||||
|
||||
import { Fluence } from '@fluencelabs/js-client.api';
|
||||
import type { ConnectionState } from '@fluencelabs/js-client.api';
|
||||
import { kras } from '@fluencelabs/fluence-network-environment';
|
||||
import { sayHello, registerHelloPeer } from './_aqua/getting-started';
|
||||
import { Fluence, type ConnectionState } from '@fluencelabs/js-client';
|
||||
import { sayHello, registerHelloPeer } from './compiled-aqua/getting-started';
|
||||
import relays from './relays.json';
|
||||
|
||||
const relayNodes = [kras[4], kras[5], kras[6]];
|
||||
const relayNodes = [relays[0], relays[1], relays[2]];
|
||||
|
||||
function App() {
|
||||
const [connectionState, setConnectionState] = useState<ConnectionState>('disconnected');
|
||||
@ -18,23 +17,20 @@ function App() {
|
||||
const [relayPeerIdInput, setRelayPeerIdInput] = useState<string>('');
|
||||
|
||||
useEffect(() => {
|
||||
Fluence.onConnectionStateChange((state) => {
|
||||
console.log('Connection state changed to: ', state);
|
||||
setConnectionState(state);
|
||||
if (connectionState === 'connected') {
|
||||
const client = Fluence.getClient();
|
||||
|
||||
if (state === 'connected') {
|
||||
Fluence.getClient().then((client) => {
|
||||
const peerId = client.getPeerId();
|
||||
const relayPeerId = client.getRelayPeerId();
|
||||
setPeerInfo({ peerId, relayPeerId });
|
||||
});
|
||||
}
|
||||
});
|
||||
}, []);
|
||||
const peerId = client.getPeerId();
|
||||
const relayPeerId = client.getRelayPeerId();
|
||||
setPeerInfo({ peerId, relayPeerId });
|
||||
}
|
||||
}, [connectionState]);
|
||||
|
||||
const connect = async (relayPeerId: string) => {
|
||||
try {
|
||||
setConnectionState('connecting');
|
||||
await Fluence.connect(relayPeerId);
|
||||
setConnectionState('connected');
|
||||
|
||||
// Register handler for this call in aqua:
|
||||
// HelloPeer.hello(%init_peer_id%)
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
46
quickstart/1-browser-to-browser/src/frontend/src/relays.json
Normal file
@ -0,0 +1,46 @@
|
||||
[
|
||||
{
|
||||
"multiaddr": "/dns4/0-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWSD5PToNiLQwKDXsu8JSysCwUt8BVUJEqCHcDe7P5h45e",
|
||||
"peerId": "12D3KooWSD5PToNiLQwKDXsu8JSysCwUt8BVUJEqCHcDe7P5h45e"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/1-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWR4cv1a8tv7pps4HH6wePNaK6gf1Hww5wcCMzeWxyNw51",
|
||||
"peerId": "12D3KooWR4cv1a8tv7pps4HH6wePNaK6gf1Hww5wcCMzeWxyNw51"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/2-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWKnEqMfYo9zvfHmqTLpLdiHXPe4SVqUWcWHDJdFGrSmcA",
|
||||
"peerId": "12D3KooWKnEqMfYo9zvfHmqTLpLdiHXPe4SVqUWcWHDJdFGrSmcA"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/3-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWHLxVhUQyAuZe6AHMB29P7wkvTNMn7eDMcsqimJYLKREf",
|
||||
"peerId": "12D3KooWHLxVhUQyAuZe6AHMB29P7wkvTNMn7eDMcsqimJYLKREf"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/4-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWJd3HaMJ1rpLY1kQvcjRPEvnDwcXrH8mJvk7ypcZXqXGE",
|
||||
"peerId": "12D3KooWJd3HaMJ1rpLY1kQvcjRPEvnDwcXrH8mJvk7ypcZXqXGE"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/5-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWFEwNWcHqi9rtsmDhsYcDbRUCDXH84RC4FW6UfsFWaoHi",
|
||||
"peerId": "12D3KooWFEwNWcHqi9rtsmDhsYcDbRUCDXH84RC4FW6UfsFWaoHi"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/6-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWCMr9mU894i8JXAFqpgoFtx6qnV1LFPSfVc3Y34N4h4LS",
|
||||
"peerId": "12D3KooWCMr9mU894i8JXAFqpgoFtx6qnV1LFPSfVc3Y34N4h4LS"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/7-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWDUszU2NeWyUVjCXhGEt1MoZrhvdmaQQwtZUriuGN1jTr",
|
||||
"peerId": "12D3KooWDUszU2NeWyUVjCXhGEt1MoZrhvdmaQQwtZUriuGN1jTr"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/8-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWEFFCZnar1cUJQ3rMWjvPQg6yMV2aXWs2DkJNSRbduBWn",
|
||||
"peerId": "12D3KooWEFFCZnar1cUJQ3rMWjvPQg6yMV2aXWs2DkJNSRbduBWn"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/9-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWFtf3rfCDAfWwt6oLZYZbDfn9Vn7bv7g6QjjQxUUEFVBt",
|
||||
"peerId": "12D3KooWFtf3rfCDAfWwt6oLZYZbDfn9Vn7bv7g6QjjQxUUEFVBt"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/10-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWD7CvsYcpF9HE9CCV9aY3SJ317tkXVykjtZnht2EbzDPm",
|
||||
"peerId": "12D3KooWD7CvsYcpF9HE9CCV9aY3SJ317tkXVykjtZnht2EbzDPm"
|
||||
}
|
||||
]
|
@ -0,0 +1,24 @@
|
||||
aqua Deals declares *
|
||||
|
||||
data Deal:
|
||||
definition: string
|
||||
timestamp: string
|
||||
dealIdOriginal: string
|
||||
dealId: string
|
||||
chainNetwork: string
|
||||
chainNetworkId: u64
|
||||
|
||||
data Deals:
|
||||
defaultWorker: ?Deal
|
||||
|
||||
func get() -> Deals:
|
||||
<- Deals(
|
||||
defaultWorker=?[Deal(
|
||||
definition="bafkreifzhzgakizgfyyf2cqkmrhj5p73aw3lovhaji6sad54veo5dm4nxi",
|
||||
timestamp="2023-11-30T23:34:44.833Z",
|
||||
dealIdOriginal="0x6CA51618eC0C1cc34f6D5ead6AD1BA8e57b950D0",
|
||||
dealId="6ca51618ec0c1cc34f6d5ead6ad1ba8e57b950d0",
|
||||
chainNetwork="kras",
|
||||
chainNetworkId=80001
|
||||
)]
|
||||
)
|
@ -0,0 +1,4 @@
|
||||
aqua Hosts declares *
|
||||
|
||||
func get() -> ?u8:
|
||||
<- nil
|
@ -0,0 +1,2 @@
|
||||
service Adder("adder"):
|
||||
add_one(value: u64) -> u64
|
@ -0,0 +1,9 @@
|
||||
# yaml-language-server: $schema=schemas/env.json
|
||||
|
||||
# Defines user project preferences
|
||||
|
||||
# Documentation: https://github.com/fluencelabs/cli/tree/main/docs/configs/env.md
|
||||
|
||||
version: 0
|
||||
|
||||
fluenceEnv: kras
|
@ -0,0 +1,28 @@
|
||||
{
|
||||
"$id": "https://fluence.dev/schemas/env.yaml",
|
||||
"title": "env.yaml",
|
||||
"type": "object",
|
||||
"description": "Defines user project preferences",
|
||||
"properties": {
|
||||
"fluenceEnv": {
|
||||
"title": "Fluence environment",
|
||||
"description": "Fluence environment to connect to",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"kras",
|
||||
"testnet",
|
||||
"stage",
|
||||
"local",
|
||||
"custom"
|
||||
],
|
||||
"nullable": true
|
||||
},
|
||||
"version": {
|
||||
"type": "number",
|
||||
"const": 0
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"version"
|
||||
]
|
||||
}
|
@ -0,0 +1,779 @@
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"services": {
|
||||
"title": "Services",
|
||||
"description": "A map with service names as keys and Service configs as values. You can have any number of services listed here as long as service name keys start with a lowercase letter and contain only letters numbers and underscores. You can use `fluence service add` command to add a service to this config",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"title": "Service config",
|
||||
"description": "Service config. Defines where the service is and how to deploy it",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"get": {
|
||||
"type": "string",
|
||||
"description": "Path to service directory or URL to the tar.gz archive with the service"
|
||||
},
|
||||
"overrideModules": {
|
||||
"type": "object",
|
||||
"title": "Overrides",
|
||||
"description": "A map of modules to override",
|
||||
"additionalProperties": {
|
||||
"type": "object",
|
||||
"title": "Module overrides",
|
||||
"description": "Overrides for the module config",
|
||||
"properties": {
|
||||
"maxHeapSize": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "Max size of the heap that a module can allocate in format: [number][whitespace?][specificator?] where ? is an optional field and specificator is one from the following (case-insensitive):\nK, Kb - kilobyte\nKi, KiB - kibibyte\nM, Mb - megabyte\nMi, MiB - mebibyte\nG, Gb - gigabyte\nGi, GiB - gibibyte\nCurrent limit is 4 GiB"
|
||||
},
|
||||
"loggerEnabled": {
|
||||
"type": "boolean",
|
||||
"nullable": true,
|
||||
"description": "Set true to allow module to use the Marine SDK logger"
|
||||
},
|
||||
"loggingMask": {
|
||||
"type": "number",
|
||||
"nullable": true,
|
||||
"description": "manages the logging targets, described in detail: https://fluence.dev/docs/marine-book/marine-rust-sdk/developing/logging#using-target-map"
|
||||
},
|
||||
"volumes": {
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"title": "Volumes",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Alias": {
|
||||
"type": "string",
|
||||
"description": "path"
|
||||
}
|
||||
},
|
||||
"description": "A map of accessible files and their aliases. Aliases should be used in Marine module development because it's hard to know the full path to a file"
|
||||
},
|
||||
"envs": {
|
||||
"type": "object",
|
||||
"title": "Environment variables",
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Environment_variable_name": {
|
||||
"type": "string",
|
||||
"description": "Environment variable value"
|
||||
}
|
||||
},
|
||||
"description": "environment variables accessible by a particular module with standard Rust env API like this: std::env::var(IPFS_ADDR_ENV_NAME). Please note that Marine adds three additional environment variables. Module environment variables could be examined with repl"
|
||||
},
|
||||
"mountedBinaries": {
|
||||
"title": "Mounted binaries",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Mounted_binary_name": {
|
||||
"type": "string",
|
||||
"description": "Path to a mounted binary"
|
||||
}
|
||||
},
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"description": "A map of binary executable files that module is allowed to call. Example: curl: /usr/bin/curl"
|
||||
}
|
||||
},
|
||||
"required": [],
|
||||
"nullable": true
|
||||
},
|
||||
"properties": {
|
||||
"Module_name": {
|
||||
"type": "object",
|
||||
"title": "Module overrides",
|
||||
"description": "Overrides for the module config",
|
||||
"properties": {
|
||||
"maxHeapSize": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "Max size of the heap that a module can allocate in format: [number][whitespace?][specificator?] where ? is an optional field and specificator is one from the following (case-insensitive):\nK, Kb - kilobyte\nKi, KiB - kibibyte\nM, Mb - megabyte\nMi, MiB - mebibyte\nG, Gb - gigabyte\nGi, GiB - gibibyte\nCurrent limit is 4 GiB"
|
||||
},
|
||||
"loggerEnabled": {
|
||||
"type": "boolean",
|
||||
"nullable": true,
|
||||
"description": "Set true to allow module to use the Marine SDK logger"
|
||||
},
|
||||
"loggingMask": {
|
||||
"type": "number",
|
||||
"nullable": true,
|
||||
"description": "manages the logging targets, described in detail: https://fluence.dev/docs/marine-book/marine-rust-sdk/developing/logging#using-target-map"
|
||||
},
|
||||
"volumes": {
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"title": "Volumes",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Alias": {
|
||||
"type": "string",
|
||||
"description": "path"
|
||||
}
|
||||
},
|
||||
"description": "A map of accessible files and their aliases. Aliases should be used in Marine module development because it's hard to know the full path to a file"
|
||||
},
|
||||
"envs": {
|
||||
"type": "object",
|
||||
"title": "Environment variables",
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Environment_variable_name": {
|
||||
"type": "string",
|
||||
"description": "Environment variable value"
|
||||
}
|
||||
},
|
||||
"description": "environment variables accessible by a particular module with standard Rust env API like this: std::env::var(IPFS_ADDR_ENV_NAME). Please note that Marine adds three additional environment variables. Module environment variables could be examined with repl"
|
||||
},
|
||||
"mountedBinaries": {
|
||||
"title": "Mounted binaries",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Mounted_binary_name": {
|
||||
"type": "string",
|
||||
"description": "Path to a mounted binary"
|
||||
}
|
||||
},
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"description": "A map of binary executable files that module is allowed to call. Example: curl: /usr/bin/curl"
|
||||
}
|
||||
},
|
||||
"required": [],
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
"nullable": true,
|
||||
"required": []
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"get"
|
||||
]
|
||||
},
|
||||
"properties": {
|
||||
"Service_name": {
|
||||
"title": "Service config",
|
||||
"description": "Service config. Defines where the service is and how to deploy it",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"get": {
|
||||
"type": "string",
|
||||
"description": "Path to service directory or URL to the tar.gz archive with the service"
|
||||
},
|
||||
"overrideModules": {
|
||||
"type": "object",
|
||||
"title": "Overrides",
|
||||
"description": "A map of modules to override",
|
||||
"additionalProperties": {
|
||||
"type": "object",
|
||||
"title": "Module overrides",
|
||||
"description": "Overrides for the module config",
|
||||
"properties": {
|
||||
"maxHeapSize": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "Max size of the heap that a module can allocate in format: [number][whitespace?][specificator?] where ? is an optional field and specificator is one from the following (case-insensitive):\nK, Kb - kilobyte\nKi, KiB - kibibyte\nM, Mb - megabyte\nMi, MiB - mebibyte\nG, Gb - gigabyte\nGi, GiB - gibibyte\nCurrent limit is 4 GiB"
|
||||
},
|
||||
"loggerEnabled": {
|
||||
"type": "boolean",
|
||||
"nullable": true,
|
||||
"description": "Set true to allow module to use the Marine SDK logger"
|
||||
},
|
||||
"loggingMask": {
|
||||
"type": "number",
|
||||
"nullable": true,
|
||||
"description": "manages the logging targets, described in detail: https://fluence.dev/docs/marine-book/marine-rust-sdk/developing/logging#using-target-map"
|
||||
},
|
||||
"volumes": {
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"title": "Volumes",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Alias": {
|
||||
"type": "string",
|
||||
"description": "path"
|
||||
}
|
||||
},
|
||||
"description": "A map of accessible files and their aliases. Aliases should be used in Marine module development because it's hard to know the full path to a file"
|
||||
},
|
||||
"envs": {
|
||||
"type": "object",
|
||||
"title": "Environment variables",
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Environment_variable_name": {
|
||||
"type": "string",
|
||||
"description": "Environment variable value"
|
||||
}
|
||||
},
|
||||
"description": "environment variables accessible by a particular module with standard Rust env API like this: std::env::var(IPFS_ADDR_ENV_NAME). Please note that Marine adds three additional environment variables. Module environment variables could be examined with repl"
|
||||
},
|
||||
"mountedBinaries": {
|
||||
"title": "Mounted binaries",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Mounted_binary_name": {
|
||||
"type": "string",
|
||||
"description": "Path to a mounted binary"
|
||||
}
|
||||
},
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"description": "A map of binary executable files that module is allowed to call. Example: curl: /usr/bin/curl"
|
||||
}
|
||||
},
|
||||
"required": [],
|
||||
"nullable": true
|
||||
},
|
||||
"properties": {
|
||||
"Module_name": {
|
||||
"type": "object",
|
||||
"title": "Module overrides",
|
||||
"description": "Overrides for the module config",
|
||||
"properties": {
|
||||
"maxHeapSize": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "Max size of the heap that a module can allocate in format: [number][whitespace?][specificator?] where ? is an optional field and specificator is one from the following (case-insensitive):\nK, Kb - kilobyte\nKi, KiB - kibibyte\nM, Mb - megabyte\nMi, MiB - mebibyte\nG, Gb - gigabyte\nGi, GiB - gibibyte\nCurrent limit is 4 GiB"
|
||||
},
|
||||
"loggerEnabled": {
|
||||
"type": "boolean",
|
||||
"nullable": true,
|
||||
"description": "Set true to allow module to use the Marine SDK logger"
|
||||
},
|
||||
"loggingMask": {
|
||||
"type": "number",
|
||||
"nullable": true,
|
||||
"description": "manages the logging targets, described in detail: https://fluence.dev/docs/marine-book/marine-rust-sdk/developing/logging#using-target-map"
|
||||
},
|
||||
"volumes": {
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"title": "Volumes",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Alias": {
|
||||
"type": "string",
|
||||
"description": "path"
|
||||
}
|
||||
},
|
||||
"description": "A map of accessible files and their aliases. Aliases should be used in Marine module development because it's hard to know the full path to a file"
|
||||
},
|
||||
"envs": {
|
||||
"type": "object",
|
||||
"title": "Environment variables",
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Environment_variable_name": {
|
||||
"type": "string",
|
||||
"description": "Environment variable value"
|
||||
}
|
||||
},
|
||||
"description": "environment variables accessible by a particular module with standard Rust env API like this: std::env::var(IPFS_ADDR_ENV_NAME). Please note that Marine adds three additional environment variables. Module environment variables could be examined with repl"
|
||||
},
|
||||
"mountedBinaries": {
|
||||
"title": "Mounted binaries",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Mounted_binary_name": {
|
||||
"type": "string",
|
||||
"description": "Path to a mounted binary"
|
||||
}
|
||||
},
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"description": "A map of binary executable files that module is allowed to call. Example: curl: /usr/bin/curl"
|
||||
}
|
||||
},
|
||||
"required": [],
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
"nullable": true,
|
||||
"required": []
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"get"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [],
|
||||
"nullable": true
|
||||
},
|
||||
"version": {
|
||||
"type": "number",
|
||||
"const": 5
|
||||
},
|
||||
"dependencies": {
|
||||
"type": "object",
|
||||
"title": "Dependencies",
|
||||
"nullable": true,
|
||||
"description": "(For advanced users) Overrides for the project dependencies",
|
||||
"properties": {
|
||||
"npm": {
|
||||
"type": "object",
|
||||
"title": "npm dependencies",
|
||||
"nullable": true,
|
||||
"description": "A map of npm aqua dependency versions. Fluence CLI ensures dependencies are installed each time you run aqua",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"npm_dependency_name": {
|
||||
"type": "string",
|
||||
"description": "npm dependency version"
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
},
|
||||
"cargo": {
|
||||
"type": "object",
|
||||
"title": "Cargo dependencies",
|
||||
"nullable": true,
|
||||
"description": "A map of cargo dependency versions. Fluence CLI ensures dependencies are installed each time you run commands that depend on Marine or Marine REPL",
|
||||
"required": [],
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Cargo_dependency_name": {
|
||||
"type": "string",
|
||||
"description": "cargo dependency version"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
},
|
||||
"aquaInputPath": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "Path to the aqua file or directory with aqua files that you want to compile by default. Must be relative to the project root dir"
|
||||
},
|
||||
"aquaOutputTSPath": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "Path to the default compilation target dir from aqua to ts. Must be relative to the project root dir"
|
||||
},
|
||||
"aquaOutputJSPath": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "Path to the default compilation target dir from aqua to js. Must be relative to the project root dir. Overrides 'aquaOutputTSPath' property"
|
||||
},
|
||||
"hosts": {
|
||||
"description": "A map of objects with worker names as keys, each object defines a list of peer IDs to host the worker on. Intended to be used by providers to deploy directly without using the blockchain",
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"additionalProperties": {
|
||||
"type": "object",
|
||||
"description": "Worker config",
|
||||
"properties": {
|
||||
"services": {
|
||||
"description": "An array of service names to include in this worker. Service names must be listed in fluence.yaml",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"nullable": true
|
||||
},
|
||||
"spells": {
|
||||
"description": "An array of spell names to include in this worker. Spell names must be listed in fluence.yaml",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"nullable": true
|
||||
},
|
||||
"peerIds": {
|
||||
"type": "array",
|
||||
"description": "An array of peer IDs to deploy on",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"minItems": 1
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
},
|
||||
"properties": {
|
||||
"workerName": {
|
||||
"type": "object",
|
||||
"description": "Worker config",
|
||||
"properties": {
|
||||
"services": {
|
||||
"description": "An array of service names to include in this worker. Service names must be listed in fluence.yaml",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"nullable": true
|
||||
},
|
||||
"spells": {
|
||||
"description": "An array of spell names to include in this worker. Spell names must be listed in fluence.yaml",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"nullable": true
|
||||
},
|
||||
"peerIds": {
|
||||
"type": "array",
|
||||
"description": "An array of peer IDs to deploy on",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"minItems": 1
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
},
|
||||
"deals": {
|
||||
"description": "A map of objects with worker names as keys, each object defines a deal",
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"additionalProperties": {
|
||||
"type": "object",
|
||||
"description": "Worker config",
|
||||
"properties": {
|
||||
"services": {
|
||||
"description": "An array of service names to include in this worker. Service names must be listed in fluence.yaml",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"nullable": true
|
||||
},
|
||||
"spells": {
|
||||
"description": "An array of spell names to include in this worker. Spell names must be listed in fluence.yaml",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"nullable": true
|
||||
},
|
||||
"minWorkers": {
|
||||
"type": "number",
|
||||
"description": "Required workers to activate the deal",
|
||||
"default": 1,
|
||||
"nullable": true,
|
||||
"minimum": 1
|
||||
},
|
||||
"targetWorkers": {
|
||||
"type": "number",
|
||||
"description": "Max workers in the deal",
|
||||
"default": 3,
|
||||
"nullable": true,
|
||||
"minimum": 1
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
},
|
||||
"properties": {
|
||||
"dealName": {
|
||||
"type": "object",
|
||||
"description": "Worker config",
|
||||
"properties": {
|
||||
"services": {
|
||||
"description": "An array of service names to include in this worker. Service names must be listed in fluence.yaml",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"nullable": true
|
||||
},
|
||||
"spells": {
|
||||
"description": "An array of spell names to include in this worker. Spell names must be listed in fluence.yaml",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"nullable": true
|
||||
},
|
||||
"minWorkers": {
|
||||
"type": "number",
|
||||
"description": "Required workers to activate the deal",
|
||||
"default": 1,
|
||||
"nullable": true,
|
||||
"minimum": 1
|
||||
},
|
||||
"targetWorkers": {
|
||||
"type": "number",
|
||||
"description": "Max workers in the deal",
|
||||
"default": 3,
|
||||
"nullable": true,
|
||||
"minimum": 1
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
},
|
||||
"spells": {
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"description": "A map with spell names as keys and spell configs as values",
|
||||
"additionalProperties": {
|
||||
"type": "object",
|
||||
"description": "Spell config",
|
||||
"properties": {
|
||||
"get": {
|
||||
"type": "string",
|
||||
"description": "Path to spell"
|
||||
},
|
||||
"version": {
|
||||
"type": "number",
|
||||
"const": 0
|
||||
},
|
||||
"aquaFilePath": {
|
||||
"type": "string",
|
||||
"description": "Path to Aqua file which contains an Aqua function that you want to use as a spell",
|
||||
"nullable": true
|
||||
},
|
||||
"function": {
|
||||
"type": "string",
|
||||
"description": "Name of the Aqua function that you want to use as a spell",
|
||||
"nullable": true
|
||||
},
|
||||
"initArgs": {
|
||||
"type": "object",
|
||||
"description": "A map of Aqua function arguments names as keys and arguments values as values. They will be passed to the spell function and will be stored in the key-value storage for this particular spell.",
|
||||
"nullable": true
|
||||
},
|
||||
"clock": {
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"description": "Trigger the spell execution periodically. If you want to disable this property by overriding it in fluence.yaml - pass empty config for it like this: `clock: {}`",
|
||||
"properties": {
|
||||
"periodSec": {
|
||||
"type": "number",
|
||||
"description": "How often the spell will be executed. If set to 0, the spell will be executed only once. If this value not provided at all - the spell will never be executed",
|
||||
"minimum": 0,
|
||||
"maximum": 3153600000,
|
||||
"nullable": true
|
||||
},
|
||||
"startTimestamp": {
|
||||
"type": "string",
|
||||
"description": "An ISO timestamp when the periodic execution should start. If this property or `startDelaySec` not specified, periodic execution will start immediately. If it is set to 0 - the spell will never be executed",
|
||||
"nullable": true
|
||||
},
|
||||
"endTimestamp": {
|
||||
"type": "string",
|
||||
"description": "An ISO timestamp when the periodic execution should end. If this property or `endDelaySec` not specified, periodic execution will never end. If it is in the past at the moment of spell creation on Rust peer - the spell will never be executed",
|
||||
"nullable": true
|
||||
},
|
||||
"startDelaySec": {
|
||||
"type": "number",
|
||||
"description": "How long to wait before the first execution in seconds. If this property or `startTimestamp` not specified, periodic execution will start immediately. WARNING! Currently your computer's clock is used to determine a final timestamp that is sent to the server. This property conflicts with `startTimestamp`. You can specify only one of them",
|
||||
"nullable": true,
|
||||
"minimum": 0,
|
||||
"maximum": 4294967295
|
||||
},
|
||||
"endDelaySec": {
|
||||
"type": "number",
|
||||
"description": "How long to wait before the last execution in seconds. If this property or `endTimestamp` not specified, periodic execution will never end. WARNING! Currently your computer's clock is used to determine a final timestamp that is sent to the server. If it is in the past at the moment of spell creation - the spell will never be executed. This property conflicts with `endTimestamp`. You can specify only one of them",
|
||||
"nullable": true,
|
||||
"minimum": 0,
|
||||
"maximum": 4294967295
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"get"
|
||||
]
|
||||
},
|
||||
"properties": {
|
||||
"Spell_name": {
|
||||
"type": "object",
|
||||
"description": "Spell config",
|
||||
"properties": {
|
||||
"get": {
|
||||
"type": "string",
|
||||
"description": "Path to spell"
|
||||
},
|
||||
"version": {
|
||||
"type": "number",
|
||||
"const": 0
|
||||
},
|
||||
"aquaFilePath": {
|
||||
"type": "string",
|
||||
"description": "Path to Aqua file which contains an Aqua function that you want to use as a spell",
|
||||
"nullable": true
|
||||
},
|
||||
"function": {
|
||||
"type": "string",
|
||||
"description": "Name of the Aqua function that you want to use as a spell",
|
||||
"nullable": true
|
||||
},
|
||||
"initArgs": {
|
||||
"type": "object",
|
||||
"description": "A map of Aqua function arguments names as keys and arguments values as values. They will be passed to the spell function and will be stored in the key-value storage for this particular spell.",
|
||||
"nullable": true
|
||||
},
|
||||
"clock": {
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"description": "Trigger the spell execution periodically. If you want to disable this property by overriding it in fluence.yaml - pass empty config for it like this: `clock: {}`",
|
||||
"properties": {
|
||||
"periodSec": {
|
||||
"type": "number",
|
||||
"description": "How often the spell will be executed. If set to 0, the spell will be executed only once. If this value not provided at all - the spell will never be executed",
|
||||
"minimum": 0,
|
||||
"maximum": 3153600000,
|
||||
"nullable": true
|
||||
},
|
||||
"startTimestamp": {
|
||||
"type": "string",
|
||||
"description": "An ISO timestamp when the periodic execution should start. If this property or `startDelaySec` not specified, periodic execution will start immediately. If it is set to 0 - the spell will never be executed",
|
||||
"nullable": true
|
||||
},
|
||||
"endTimestamp": {
|
||||
"type": "string",
|
||||
"description": "An ISO timestamp when the periodic execution should end. If this property or `endDelaySec` not specified, periodic execution will never end. If it is in the past at the moment of spell creation on Rust peer - the spell will never be executed",
|
||||
"nullable": true
|
||||
},
|
||||
"startDelaySec": {
|
||||
"type": "number",
|
||||
"description": "How long to wait before the first execution in seconds. If this property or `startTimestamp` not specified, periodic execution will start immediately. WARNING! Currently your computer's clock is used to determine a final timestamp that is sent to the server. This property conflicts with `startTimestamp`. You can specify only one of them",
|
||||
"nullable": true,
|
||||
"minimum": 0,
|
||||
"maximum": 4294967295
|
||||
},
|
||||
"endDelaySec": {
|
||||
"type": "number",
|
||||
"description": "How long to wait before the last execution in seconds. If this property or `endTimestamp` not specified, periodic execution will never end. WARNING! Currently your computer's clock is used to determine a final timestamp that is sent to the server. If it is in the past at the moment of spell creation - the spell will never be executed. This property conflicts with `endTimestamp`. You can specify only one of them",
|
||||
"nullable": true,
|
||||
"minimum": 0,
|
||||
"maximum": 4294967295
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"get"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
},
|
||||
"aquaImports": {
|
||||
"type": "array",
|
||||
"description": "A list of path to be considered by aqua compiler to be used as imports. First dependency in the list has the highest priority. Priority of imports is considered in the following order: imports from --import flags, imports from aquaImports property in fluence.yaml, project's .fluence/aqua dir, npm dependencies from fluence.yaml, npm dependencies from user's .fluence/config.yaml, npm dependencies recommended by fluence",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"nullable": true
|
||||
},
|
||||
"marineBuildArgs": {
|
||||
"type": "string",
|
||||
"description": "Space separated `cargo build` flags and args to pass to marine build. Can be overridden using --marine-build-args flag Default: --release",
|
||||
"nullable": true
|
||||
},
|
||||
"cliVersion": {
|
||||
"type": "string",
|
||||
"description": "The version of the Fluence CLI that is compatible with this project. Set this to enforce a particular set of versions of all fluence components",
|
||||
"nullable": true
|
||||
},
|
||||
"ipfsAddr": {
|
||||
"type": "string",
|
||||
"description": "IPFS multiaddress to use when uploading workers with 'deal deploy'. Default: /dns4/ipfs.fluence.dev/tcp/5001 or /ip4/127.0.0.1/tcp/5001 if using local local env (for 'workers deploy' IPFS address provided by relay that you are connected to is used)",
|
||||
"nullable": true,
|
||||
"default": "/dns4/ipfs.fluence.dev/tcp/5001"
|
||||
},
|
||||
"customFluenceEnv": {
|
||||
"type": "object",
|
||||
"description": "Custom Fluence environment to use when connecting to Fluence network",
|
||||
"nullable": true,
|
||||
"properties": {
|
||||
"contractsEnv": {
|
||||
"type": "string",
|
||||
"description": "Contracts environment to use for this fluence network to sign contracts on the blockchain",
|
||||
"enum": [
|
||||
"kras",
|
||||
"testnet",
|
||||
"stage",
|
||||
"local"
|
||||
]
|
||||
},
|
||||
"relays": {
|
||||
"type": "array",
|
||||
"description": "List of custom relay multiaddresses to use when connecting to Fluence network",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"minItems": 1
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"contractsEnv",
|
||||
"relays"
|
||||
]
|
||||
},
|
||||
"defaultSecretKeyName": {
|
||||
"description": "Secret key with this name will be used by default by js-client inside CLI to run Aqua code",
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
},
|
||||
"relaysPath": {
|
||||
"description": "Path to the directory where you want relays.json file to be generated. Must be relative to the project root dir. This file contains a list of relays to use when connecting to Fluence network and depends on the default environment that you use in your project",
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"version"
|
||||
],
|
||||
"$id": "https://fluence.dev/schemas/fluence.yaml",
|
||||
"title": "fluence.yaml",
|
||||
"description": "Defines Fluence Project, most importantly - what exactly you want to deploy and how. You can use `fluence init` command to generate a template for new Fluence project"
|
||||
}
|
@ -0,0 +1,93 @@
|
||||
{
|
||||
"type": "object",
|
||||
"$id": "https://fluence.dev/schemas/module.yaml",
|
||||
"title": "module.yaml",
|
||||
"description": "Defines [Marine Module](https://fluence.dev/docs/build/concepts/#modules). You can use `fluence module new` command to generate a template for new module",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "\"name\" property from the Cargo.toml (for module type \"rust\") or name of the precompiled .wasm file (for module type \"compiled\")"
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"rust",
|
||||
"compiled"
|
||||
],
|
||||
"nullable": true,
|
||||
"default": "compiled",
|
||||
"description": "Module type \"compiled\" is for the precompiled modules. Module type \"rust\" is for the source code written in rust which can be compiled into a Marine module"
|
||||
},
|
||||
"maxHeapSize": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "Max size of the heap that a module can allocate in format: [number][whitespace?][specificator?] where ? is an optional field and specificator is one from the following (case-insensitive):\nK, Kb - kilobyte\nKi, KiB - kibibyte\nM, Mb - megabyte\nMi, MiB - mebibyte\nG, Gb - gigabyte\nGi, GiB - gibibyte\nCurrent limit is 4 GiB"
|
||||
},
|
||||
"loggerEnabled": {
|
||||
"type": "boolean",
|
||||
"nullable": true,
|
||||
"description": "Set true to allow module to use the Marine SDK logger"
|
||||
},
|
||||
"loggingMask": {
|
||||
"type": "number",
|
||||
"nullable": true,
|
||||
"description": "manages the logging targets, described in detail: https://fluence.dev/docs/marine-book/marine-rust-sdk/developing/logging#using-target-map"
|
||||
},
|
||||
"volumes": {
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"title": "Volumes",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Alias": {
|
||||
"type": "string",
|
||||
"description": "path"
|
||||
}
|
||||
},
|
||||
"description": "A map of accessible files and their aliases. Aliases should be used in Marine module development because it's hard to know the full path to a file"
|
||||
},
|
||||
"envs": {
|
||||
"type": "object",
|
||||
"title": "Environment variables",
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Environment_variable_name": {
|
||||
"type": "string",
|
||||
"description": "Environment variable value"
|
||||
}
|
||||
},
|
||||
"description": "environment variables accessible by a particular module with standard Rust env API like this: std::env::var(IPFS_ADDR_ENV_NAME). Please note that Marine adds three additional environment variables. Module environment variables could be examined with repl"
|
||||
},
|
||||
"mountedBinaries": {
|
||||
"title": "Mounted binaries",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Mounted_binary_name": {
|
||||
"type": "string",
|
||||
"description": "Path to a mounted binary"
|
||||
}
|
||||
},
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"description": "A map of binary executable files that module is allowed to call. Example: curl: /usr/bin/curl"
|
||||
},
|
||||
"version": {
|
||||
"type": "number",
|
||||
"const": 0
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"version",
|
||||
"name"
|
||||
]
|
||||
}
|
@ -0,0 +1,259 @@
|
||||
{
|
||||
"type": "object",
|
||||
"$id": "https://fluence.dev/schemas/service.yaml",
|
||||
"title": "service.yaml",
|
||||
"description": "Defines a [Marine service](https://fluence.dev/docs/build/concepts/#services), most importantly the modules that the service consists of. You can use `fluence service new` command to generate a template for new service",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Service name. Currently it is used for the service name only when you add service to fluence.yaml using \"add\" command. But this name can be overridden to any other with the --name flag or manually in fluence.yaml"
|
||||
},
|
||||
"modules": {
|
||||
"title": "Modules",
|
||||
"description": "Service must have a facade module. Each module properties can be overridden by the same properties in the service config",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "object",
|
||||
"title": "Module",
|
||||
"properties": {
|
||||
"get": {
|
||||
"type": "string",
|
||||
"description": "Either path to the module directory or URL to the tar.gz archive which contains the content of the module directory"
|
||||
},
|
||||
"maxHeapSize": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "Max size of the heap that a module can allocate in format: [number][whitespace?][specificator?] where ? is an optional field and specificator is one from the following (case-insensitive):\nK, Kb - kilobyte\nKi, KiB - kibibyte\nM, Mb - megabyte\nMi, MiB - mebibyte\nG, Gb - gigabyte\nGi, GiB - gibibyte\nCurrent limit is 4 GiB"
|
||||
},
|
||||
"loggerEnabled": {
|
||||
"type": "boolean",
|
||||
"nullable": true,
|
||||
"description": "Set true to allow module to use the Marine SDK logger"
|
||||
},
|
||||
"loggingMask": {
|
||||
"type": "number",
|
||||
"nullable": true,
|
||||
"description": "manages the logging targets, described in detail: https://fluence.dev/docs/marine-book/marine-rust-sdk/developing/logging#using-target-map"
|
||||
},
|
||||
"volumes": {
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"title": "Volumes",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Alias": {
|
||||
"type": "string",
|
||||
"description": "path"
|
||||
}
|
||||
},
|
||||
"description": "A map of accessible files and their aliases. Aliases should be used in Marine module development because it's hard to know the full path to a file"
|
||||
},
|
||||
"envs": {
|
||||
"type": "object",
|
||||
"title": "Environment variables",
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Environment_variable_name": {
|
||||
"type": "string",
|
||||
"description": "Environment variable value"
|
||||
}
|
||||
},
|
||||
"description": "environment variables accessible by a particular module with standard Rust env API like this: std::env::var(IPFS_ADDR_ENV_NAME). Please note that Marine adds three additional environment variables. Module environment variables could be examined with repl"
|
||||
},
|
||||
"mountedBinaries": {
|
||||
"title": "Mounted binaries",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Mounted_binary_name": {
|
||||
"type": "string",
|
||||
"description": "Path to a mounted binary"
|
||||
}
|
||||
},
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"description": "A map of binary executable files that module is allowed to call. Example: curl: /usr/bin/curl"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"get"
|
||||
]
|
||||
},
|
||||
"properties": {
|
||||
"facade": {
|
||||
"type": "object",
|
||||
"title": "Module",
|
||||
"properties": {
|
||||
"get": {
|
||||
"type": "string",
|
||||
"description": "Either path to the module directory or URL to the tar.gz archive which contains the content of the module directory"
|
||||
},
|
||||
"maxHeapSize": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "Max size of the heap that a module can allocate in format: [number][whitespace?][specificator?] where ? is an optional field and specificator is one from the following (case-insensitive):\nK, Kb - kilobyte\nKi, KiB - kibibyte\nM, Mb - megabyte\nMi, MiB - mebibyte\nG, Gb - gigabyte\nGi, GiB - gibibyte\nCurrent limit is 4 GiB"
|
||||
},
|
||||
"loggerEnabled": {
|
||||
"type": "boolean",
|
||||
"nullable": true,
|
||||
"description": "Set true to allow module to use the Marine SDK logger"
|
||||
},
|
||||
"loggingMask": {
|
||||
"type": "number",
|
||||
"nullable": true,
|
||||
"description": "manages the logging targets, described in detail: https://fluence.dev/docs/marine-book/marine-rust-sdk/developing/logging#using-target-map"
|
||||
},
|
||||
"volumes": {
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"title": "Volumes",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Alias": {
|
||||
"type": "string",
|
||||
"description": "path"
|
||||
}
|
||||
},
|
||||
"description": "A map of accessible files and their aliases. Aliases should be used in Marine module development because it's hard to know the full path to a file"
|
||||
},
|
||||
"envs": {
|
||||
"type": "object",
|
||||
"title": "Environment variables",
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Environment_variable_name": {
|
||||
"type": "string",
|
||||
"description": "Environment variable value"
|
||||
}
|
||||
},
|
||||
"description": "environment variables accessible by a particular module with standard Rust env API like this: std::env::var(IPFS_ADDR_ENV_NAME). Please note that Marine adds three additional environment variables. Module environment variables could be examined with repl"
|
||||
},
|
||||
"mountedBinaries": {
|
||||
"title": "Mounted binaries",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Mounted_binary_name": {
|
||||
"type": "string",
|
||||
"description": "Path to a mounted binary"
|
||||
}
|
||||
},
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"description": "A map of binary executable files that module is allowed to call. Example: curl: /usr/bin/curl"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"get"
|
||||
]
|
||||
},
|
||||
"Other_module_name": {
|
||||
"type": "object",
|
||||
"title": "Module",
|
||||
"properties": {
|
||||
"get": {
|
||||
"type": "string",
|
||||
"description": "Either path to the module directory or URL to the tar.gz archive which contains the content of the module directory"
|
||||
},
|
||||
"maxHeapSize": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "Max size of the heap that a module can allocate in format: [number][whitespace?][specificator?] where ? is an optional field and specificator is one from the following (case-insensitive):\nK, Kb - kilobyte\nKi, KiB - kibibyte\nM, Mb - megabyte\nMi, MiB - mebibyte\nG, Gb - gigabyte\nGi, GiB - gibibyte\nCurrent limit is 4 GiB"
|
||||
},
|
||||
"loggerEnabled": {
|
||||
"type": "boolean",
|
||||
"nullable": true,
|
||||
"description": "Set true to allow module to use the Marine SDK logger"
|
||||
},
|
||||
"loggingMask": {
|
||||
"type": "number",
|
||||
"nullable": true,
|
||||
"description": "manages the logging targets, described in detail: https://fluence.dev/docs/marine-book/marine-rust-sdk/developing/logging#using-target-map"
|
||||
},
|
||||
"volumes": {
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"title": "Volumes",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Alias": {
|
||||
"type": "string",
|
||||
"description": "path"
|
||||
}
|
||||
},
|
||||
"description": "A map of accessible files and their aliases. Aliases should be used in Marine module development because it's hard to know the full path to a file"
|
||||
},
|
||||
"envs": {
|
||||
"type": "object",
|
||||
"title": "Environment variables",
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Environment_variable_name": {
|
||||
"type": "string",
|
||||
"description": "Environment variable value"
|
||||
}
|
||||
},
|
||||
"description": "environment variables accessible by a particular module with standard Rust env API like this: std::env::var(IPFS_ADDR_ENV_NAME). Please note that Marine adds three additional environment variables. Module environment variables could be examined with repl"
|
||||
},
|
||||
"mountedBinaries": {
|
||||
"title": "Mounted binaries",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Mounted_binary_name": {
|
||||
"type": "string",
|
||||
"description": "Path to a mounted binary"
|
||||
}
|
||||
},
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"description": "A map of binary executable files that module is allowed to call. Example: curl: /usr/bin/curl"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"get"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"facade"
|
||||
]
|
||||
},
|
||||
"version": {
|
||||
"type": "number",
|
||||
"const": 0
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"version",
|
||||
"name",
|
||||
"modules"
|
||||
]
|
||||
}
|
@ -0,0 +1,203 @@
|
||||
{
|
||||
"$id": "https://fluence.dev/schemas/workers.yaml",
|
||||
"title": "workers.yaml",
|
||||
"type": "object",
|
||||
"description": "A result of app deployment. This file is created automatically after successful deployment using `fluence workers deploy` command",
|
||||
"properties": {
|
||||
"version": {
|
||||
"type": "number",
|
||||
"const": 0
|
||||
},
|
||||
"deals": {
|
||||
"type": "object",
|
||||
"description": "A map of created deals",
|
||||
"additionalProperties": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"definition": {
|
||||
"type": "string"
|
||||
},
|
||||
"timestamp": {
|
||||
"type": "string",
|
||||
"description": "ISO timestamp of the time when the worker was deployed"
|
||||
},
|
||||
"dealId": {
|
||||
"type": "string"
|
||||
},
|
||||
"dealIdOriginal": {
|
||||
"type": "string"
|
||||
},
|
||||
"chainNetwork": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"kras",
|
||||
"testnet",
|
||||
"stage",
|
||||
"local"
|
||||
]
|
||||
},
|
||||
"chainNetworkId": {
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"timestamp",
|
||||
"definition",
|
||||
"dealId",
|
||||
"dealIdOriginal",
|
||||
"chainNetwork",
|
||||
"chainNetworkId"
|
||||
]
|
||||
},
|
||||
"properties": {
|
||||
"Worker_deployed_using_deals": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"definition": {
|
||||
"type": "string"
|
||||
},
|
||||
"timestamp": {
|
||||
"type": "string",
|
||||
"description": "ISO timestamp of the time when the worker was deployed"
|
||||
},
|
||||
"dealId": {
|
||||
"type": "string"
|
||||
},
|
||||
"dealIdOriginal": {
|
||||
"type": "string"
|
||||
},
|
||||
"chainNetwork": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"kras",
|
||||
"testnet",
|
||||
"stage",
|
||||
"local"
|
||||
]
|
||||
},
|
||||
"chainNetworkId": {
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"timestamp",
|
||||
"definition",
|
||||
"dealId",
|
||||
"dealIdOriginal",
|
||||
"chainNetwork",
|
||||
"chainNetworkId"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [],
|
||||
"nullable": true
|
||||
},
|
||||
"hosts": {
|
||||
"type": "object",
|
||||
"description": "A map of deployed workers",
|
||||
"additionalProperties": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"definition": {
|
||||
"type": "string"
|
||||
},
|
||||
"timestamp": {
|
||||
"type": "string",
|
||||
"description": "ISO timestamp of the time when the worker was deployed"
|
||||
},
|
||||
"dummyDealId": {
|
||||
"type": "string"
|
||||
},
|
||||
"installation_spells": {
|
||||
"type": "array",
|
||||
"description": "A list of installation spells",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"host_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"spell_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"worker_id": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"host_id",
|
||||
"spell_id",
|
||||
"worker_id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"relayId": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"timestamp",
|
||||
"definition",
|
||||
"installation_spells",
|
||||
"relayId",
|
||||
"dummyDealId"
|
||||
]
|
||||
},
|
||||
"properties": {
|
||||
"Worker_deployed_using_direct_hosting": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"definition": {
|
||||
"type": "string"
|
||||
},
|
||||
"timestamp": {
|
||||
"type": "string",
|
||||
"description": "ISO timestamp of the time when the worker was deployed"
|
||||
},
|
||||
"dummyDealId": {
|
||||
"type": "string"
|
||||
},
|
||||
"installation_spells": {
|
||||
"type": "array",
|
||||
"description": "A list of installation spells",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"host_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"spell_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"worker_id": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"host_id",
|
||||
"spell_id",
|
||||
"worker_id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"relayId": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"timestamp",
|
||||
"definition",
|
||||
"installation_spells",
|
||||
"relayId",
|
||||
"dummyDealId"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [],
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"version"
|
||||
]
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
# yaml-language-server: $schema=schemas/workers.json
|
||||
|
||||
# A result of app deployment. This file is created automatically after successful deployment using `fluence workers deploy` command
|
||||
|
||||
# Documentation: https://github.com/fluencelabs/cli/tree/main/docs/configs/workers.md
|
||||
|
||||
version: 0
|
||||
|
||||
deals:
|
||||
defaultWorker:
|
||||
definition: bafkreifzhzgakizgfyyf2cqkmrhj5p73aw3lovhaji6sad54veo5dm4nxi
|
||||
timestamp: 2023-11-30T23:34:44.833Z
|
||||
dealIdOriginal: "0x6CA51618eC0C1cc34f6D5ead6AD1BA8e57b950D0"
|
||||
dealId: 6ca51618ec0c1cc34f6d5ead6ad1ba8e57b950d0
|
||||
chainNetwork: kras
|
||||
chainNetworkId: 80001
|
2
quickstart/2-browser-parallel-computation/Cargo.toml
Normal file
@ -0,0 +1,2 @@
|
||||
[workspace]
|
||||
members = [ "src/services/adder/modules/adder" ]
|
128
quickstart/2-browser-parallel-computation/README.md
Normal file
@ -0,0 +1,128 @@
|
||||
# 2. Browser-Parallel-Computation
|
||||
|
||||
> It's recommended to complete [CLI quickstart](https://fluence.dev/docs/build/get-started) before exploring this example as the example contains concepts build upon deployed service
|
||||
|
||||
In the first section, we explored browser-to-browser messaging using local, i.e. browser-native, services and the Fluence network for message transport. Now we have already deployed a simple service `Adder` for you, and we will try to experiment with this.
|
||||
|
||||
The service code:
|
||||
|
||||
```rust
|
||||
use marine_rs_sdk::marine;
|
||||
|
||||
pub fn main() {}
|
||||
|
||||
#[marine]
|
||||
pub fn add_one(value: u64) -> u64 {
|
||||
value + 1
|
||||
}
|
||||
```
|
||||
|
||||
You can deploy it yourself by following [CLI quickstart](https://fluence.dev/docs/build/get-started) guide, replacing `HelloWorld` module with following code and renaming `HelloWorld` service to `Adder` service there.
|
||||
|
||||
First, let's have a look at the Aqua file. Navigate to the `2-browser-parallel-computation/src/aqua/getting_started.aqua` file in your IDE or terminal:
|
||||
|
||||
> If you have trouble reading aqua, feel free to refer to [aqua book](https://fluence.dev/docs/aqua-book/introduction)
|
||||
|
||||
> Read carefully through comments, starting with `--`.
|
||||
|
||||
```aqua
|
||||
import Subnet, Worker from "@fluencelabs/aqua-lib/subnet.aqua"
|
||||
|
||||
-- 'use' clause brings Deal service into the scope
|
||||
use "deals.aqua"
|
||||
|
||||
-- this 'import' brings every aqua service declaration into the scope
|
||||
import "services.aqua"
|
||||
|
||||
-- Function to get all workers from subnet
|
||||
func resolveSubnet() -> []Worker:
|
||||
-- Getting deal id of deployed deal to resolve subnet
|
||||
deals <- Deals.get()
|
||||
dealId = deals.defaultWorker!.dealIdOriginal
|
||||
|
||||
-- Subnets cannot be resolved on local (client) peers, e.g., the CLI client or the browser. Instead, a subnet needs to be resolved on a relay.
|
||||
on HOST_PEER_ID:
|
||||
-- Resolving subnets using Deal id of deployed service
|
||||
subnet <- Subnet.resolve(dealId)
|
||||
<- subnet.workers
|
||||
|
||||
-- This data structure represents the aqua function that is calling the worker via the frontend.
|
||||
data ComputationRequest:
|
||||
worker_id: string
|
||||
host_id: string
|
||||
value: u64
|
||||
|
||||
-- Executes single computation request
|
||||
func add_one_single(request: ComputationRequest) -> u64:
|
||||
-- Extracting worker and host for execution service request
|
||||
on request.worker_id via request.host_id:
|
||||
-- Service execution
|
||||
res <- Adder.add_one(request.value)
|
||||
-- Returning result from function
|
||||
<- res
|
||||
|
||||
func add_one_sequential(requests: []ComputationRequest) -> *u64:
|
||||
-- Stream for keeping all computation results
|
||||
results: *u64
|
||||
|
||||
-- Iterating over every computation request, one by one
|
||||
for request <- requests:
|
||||
on request.worker_id via request.host_id:
|
||||
res <- Adder.add_one(request.value)
|
||||
results <<- res
|
||||
|
||||
<- results
|
||||
|
||||
func add_one_parallel(requests: []ComputationRequest) -> *u64:
|
||||
results: *u64
|
||||
|
||||
-- Starting a parallel computation. Cycle body called in parallel
|
||||
for request <- requests par:
|
||||
on request.worker_id via request.host_id:
|
||||
res <- Adder.add_one(request.value)
|
||||
results <<- res
|
||||
|
||||
-- waiting for all parallel calls to finish
|
||||
join results[requests.length - 1]
|
||||
|
||||
<- results
|
||||
```
|
||||
|
||||
Let's navigate to the `2-browser-parallel-computation/src/frontend` directory in the VSCode terminal and install the dependencies:
|
||||
|
||||
```sh
|
||||
npm install
|
||||
```
|
||||
|
||||
Run aqua compiler:
|
||||
|
||||
```bash
|
||||
fluence aqua
|
||||
```
|
||||
|
||||
And run the application with:
|
||||
|
||||
```sh
|
||||
npm start
|
||||
```
|
||||
|
||||
Which will open a new browser tab at `http://localhost:3000` . Following the instructions, we connect to any one of the displayed relay ids.
|
||||
|
||||

|
||||
|
||||
First, try to input some numbers there. They're args for aqua functions.
|
||||
|
||||
After this you can try to click on the buttons below
|
||||
|
||||
> **Compute Single** - Takes only first number and adds 1 to the number. Returns the result of computation below.
|
||||
|
||||
> **Compute Sequential** - Each of the numbers provided is incremented one after the other. That is, we have three sequential function calls.
|
||||
|
||||
> **Compute Parallel** - Each of the three numbers provide is increment in parallel. That is, we fork the call into three arms, execute the Adder function for each arm, join the the arms and present the result, which may be either the value for each arm or a timeout.
|
||||
|
||||
|
||||
> Note: the joined results vary in order, which is determined by the latency of each of the Adder calls; fastest responses fill the array first.
|
||||
|
||||
A little more involved than our first example, but we are again getting a lot done with very little code. Of course, there could be more than one hosted service in play and we could implement, for example, hosted spell checking, text formatting and so much more without much extra effort to express additional workflow logic in our Aqua script.
|
||||
|
||||
This brings us to the end of this quick start tutorial. We hope you are as excited as we are to put Aqua and the Fluence stack to work. To continue your Fluence journey, have a look at the remainder of this book, take a deep dive into Aqua with the [Aqua book](https://fluence.dev/docs/aqua-book/introduction) or dig into Marine and Aqua examples in the [repo](https://github.com/fluencelabs/examples).
|
After Width: | Height: | Size: 75 KiB |
After Width: | Height: | Size: 185 KiB |
24
quickstart/2-browser-parallel-computation/fluence.yaml
Normal file
@ -0,0 +1,24 @@
|
||||
# yaml-language-server: $schema=.fluence/schemas/fluence.json
|
||||
|
||||
# Defines Fluence Project, most importantly - what exactly you want to deploy and how. You can use `fluence init` command to generate a template for new Fluence project
|
||||
|
||||
# Documentation: https://github.com/fluencelabs/cli/tree/main/docs/configs/fluence.md
|
||||
|
||||
version: 5
|
||||
|
||||
aquaInputPath: src/aqua/getting-started.aqua
|
||||
|
||||
deals:
|
||||
defaultWorker:
|
||||
targetWorkers: 3
|
||||
services:
|
||||
- adder
|
||||
spells: []
|
||||
|
||||
services:
|
||||
adder:
|
||||
get: src/services/adder
|
||||
|
||||
relaysPath: src/frontend/src
|
||||
|
||||
aquaOutputTSPath: src/frontend/src/compiled-aqua
|
@ -0,0 +1,60 @@
|
||||
import Subnet, Worker from "@fluencelabs/aqua-lib/subnet.aqua"
|
||||
|
||||
-- 'use' clause brings Deal service into the scope
|
||||
use "deals.aqua"
|
||||
|
||||
-- this 'import' brings every aqua service declaration into the scope
|
||||
import "services.aqua"
|
||||
|
||||
-- Function to get all workers from subnet
|
||||
func resolveSubnet() -> []Worker:
|
||||
-- Getting deal id of deployed deal to resolve subnet
|
||||
deals <- Deals.get()
|
||||
dealId = deals.defaultWorker!.dealIdOriginal
|
||||
|
||||
-- Subnets cannot be resolved on local (client) peers, e.g., the CLI client or the browser. Instead, a subnet needs to be resolved on a relay.
|
||||
on HOST_PEER_ID:
|
||||
-- Resolving subnets using Deal id of deployed service
|
||||
subnet <- Subnet.resolve(dealId)
|
||||
<- subnet.workers
|
||||
|
||||
-- This data structure represents the aqua function that is calling the worker via the frontend.
|
||||
data ComputationRequest:
|
||||
worker_id: string
|
||||
host_id: string
|
||||
value: u64
|
||||
|
||||
-- Executes single computation request
|
||||
func add_one_single(request: ComputationRequest) -> u64:
|
||||
-- Extracting worker and host for execution service request
|
||||
on request.worker_id via request.host_id:
|
||||
-- Service execution
|
||||
res <- Adder.add_one(request.value)
|
||||
-- Returning result from function
|
||||
<- res
|
||||
|
||||
func add_one_sequential(requests: []ComputationRequest) -> *u64:
|
||||
-- Stream for keeping all computation results
|
||||
results: *u64
|
||||
|
||||
-- Iterating over every computation request, one by one
|
||||
for request <- requests:
|
||||
on request.worker_id via request.host_id:
|
||||
res <- Adder.add_one(request.value)
|
||||
results <<- res
|
||||
|
||||
<- results
|
||||
|
||||
func add_one_parallel(requests: []ComputationRequest) -> *u64:
|
||||
results: *u64
|
||||
|
||||
-- Starting a parallel computation. Cycle body called in parallel
|
||||
for request <- requests par:
|
||||
on request.worker_id via request.host_id:
|
||||
res <- Adder.add_one(request.value)
|
||||
results <<- res
|
||||
|
||||
-- waiting for all parallel calls to finish
|
||||
join results[requests.length - 1]
|
||||
|
||||
<- results
|
10
quickstart/2-browser-parallel-computation/src/frontend/.gitignore
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
.idea
|
||||
.DS_Store
|
||||
/.fluence/project-secrets.yaml
|
||||
/.fluence/schemas
|
||||
**/node_modules
|
||||
**/target/
|
||||
.repl_history
|
||||
.vscode/settings.json
|
||||
|
||||
src/compiled-aqua/
|
@ -3,31 +3,17 @@
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@fluencelabs/js-client.api": "0.13.1",
|
||||
"@fluencelabs/fluence-network-environment": "1.1.2",
|
||||
"@testing-library/jest-dom": "^5.14.1",
|
||||
"@testing-library/react": "^11.2.7",
|
||||
"@testing-library/user-event": "^12.8.3",
|
||||
"@types/jest": "^27.4.0",
|
||||
"@types/node": "^12.20.16",
|
||||
"@types/react": "^17.0.14",
|
||||
"@types/react-dom": "^17.0.9",
|
||||
"@fluencelabs/js-client": "^0.5.4",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-scripts": "^5.0.0",
|
||||
"typescript": "^4.6.3",
|
||||
"web-vitals": "^1.1.2"
|
||||
},
|
||||
"scripts": {
|
||||
"prestart": "npm run compile-aqua",
|
||||
"prebuild": "npm run compile-aqua",
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "jest --config=jest.config.js",
|
||||
"_test": "react-scripts test",
|
||||
"eject": "react-scripts eject",
|
||||
"compile-aqua": "fluence aqua -i ./aqua/ -o ./src/_aqua",
|
||||
"watch-aqua": "fluence aqua -w -i ./aqua/ -o ./src/_aqua"
|
||||
"eject": "react-scripts eject"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
@ -50,14 +36,21 @@
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@fluencelabs/cli": "0.9.1",
|
||||
"@fluencelabs/aqua-lib": "0.7.7",
|
||||
"@testing-library/jest-dom": "^6.1.4",
|
||||
"@testing-library/react": "^11.2.7",
|
||||
"@testing-library/user-event": "^14.5.1",
|
||||
"@types/jest": "^29.5.6",
|
||||
"@types/jest-environment-puppeteer": "^4.4.1",
|
||||
"@types/node": "^20.8.9",
|
||||
"@types/puppeteer": "^5.4.4",
|
||||
"@types/serve-handler": "^6.1.1",
|
||||
"@types/react": "^18.2.33",
|
||||
"@types/react-dom": "^18.2.14",
|
||||
"@types/serve-handler": "^6.1.3",
|
||||
"jest-puppeteer": "^6.0.2",
|
||||
"react-scripts": "^5.0.1",
|
||||
"sass": "^1.58.3",
|
||||
"serve": "^13.0.2",
|
||||
"ts-jest": "^27.1.3"
|
||||
"ts-jest": "^28.0.8",
|
||||
"typescript": "^4.9.5"
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 4.9 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
@ -0,0 +1,233 @@
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import logo from './logo.svg';
|
||||
import './App.scss';
|
||||
|
||||
import { Fluence, type ConnectionState } from '@fluencelabs/js-client';
|
||||
import { resolveSubnet, add_one_parallel, add_one_sequential, add_one_single } from './compiled-aqua/getting-started';
|
||||
import relays from "./relays.json";
|
||||
|
||||
|
||||
const relayNodes = [relays[0], relays[1], relays[2]];
|
||||
|
||||
interface ComputationResult {
|
||||
host_id: string;
|
||||
value: number;
|
||||
worker_id: string;
|
||||
}
|
||||
|
||||
function App() {
|
||||
const [connectionState, setConnectionState] = useState<ConnectionState>('disconnected');
|
||||
const [peerInfo, setPeerInfo] = useState<{ peerId: string; relayPeerId: string } | null>(null);
|
||||
|
||||
const [numbers, setNumbers] = useState([1, 2, 3]);
|
||||
const [computedNumbers, setComputedNumbers] = useState<number[]>();
|
||||
const [computationInProgress, setComputationInProgress] = useState(false);
|
||||
|
||||
const onNumberChange = (input: string, index: number) => {
|
||||
setNumbers([...numbers.slice(0, index), Number(input) || 0, ...numbers.slice(index + 1)]);
|
||||
}
|
||||
|
||||
const numberContainers = [useRef<HTMLInputElement>(null), useRef<HTMLInputElement>(null), useRef<HTMLInputElement>(null)];
|
||||
|
||||
useEffect(() => {
|
||||
if (connectionState === 'connected') {
|
||||
const client = Fluence.getClient();
|
||||
|
||||
const peerId = client.getPeerId();
|
||||
const relayPeerId = client.getRelayPeerId();
|
||||
setPeerInfo({ peerId, relayPeerId });
|
||||
}
|
||||
}, [connectionState]);
|
||||
|
||||
const connect = async (relayPeerId: string) => {
|
||||
try {
|
||||
setConnectionState('connecting');
|
||||
await Fluence.connect(relayPeerId);
|
||||
setConnectionState('connected');
|
||||
} catch (err) {
|
||||
console.log('Client could not connect', err);
|
||||
}
|
||||
};
|
||||
|
||||
const getComputationResuls = async () => {
|
||||
const subnets = await resolveSubnet();
|
||||
const size = Math.max(subnets.length, numbers.length);
|
||||
|
||||
const computationResults: ComputationResult[] = [];
|
||||
|
||||
for (let i = 0; i < size; i++) {
|
||||
const workerId = subnets[i].worker_id;
|
||||
|
||||
if (workerId === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
computationResults.push({
|
||||
value: numbers[i],
|
||||
worker_id: workerId,
|
||||
host_id: subnets[i].host_id,
|
||||
})
|
||||
}
|
||||
|
||||
return computationResults;
|
||||
};
|
||||
|
||||
const computeSingleBtnOnClick = async () => {
|
||||
if (connectionState !== 'connected') {
|
||||
return;
|
||||
}
|
||||
setComputationInProgress(true);
|
||||
|
||||
const computationResults = await getComputationResuls();
|
||||
|
||||
const result = await add_one_single(computationResults[0]);
|
||||
setComputedNumbers([result]);
|
||||
setComputationInProgress(false);
|
||||
};
|
||||
|
||||
const computeSequentialBtnOnClick = async () => {
|
||||
if (connectionState !== 'connected') {
|
||||
return;
|
||||
}
|
||||
setComputationInProgress(true);
|
||||
|
||||
const computationResults = await getComputationResuls();
|
||||
|
||||
const results = await add_one_sequential(computationResults);
|
||||
setComputedNumbers(results);
|
||||
setComputationInProgress(false);
|
||||
};
|
||||
|
||||
const computeParallelBtnOnClick = async () => {
|
||||
if (connectionState !== 'connected') {
|
||||
return;
|
||||
}
|
||||
setComputationInProgress(true);
|
||||
|
||||
const computationResults = await getComputationResuls();
|
||||
|
||||
const results = await add_one_parallel(computationResults);
|
||||
setComputedNumbers(results);
|
||||
setComputationInProgress(false);
|
||||
};
|
||||
|
||||
const isConnected = connectionState === 'connected';
|
||||
|
||||
return (
|
||||
<div className="App">
|
||||
<header>
|
||||
<img src={logo} className="logo" alt="logo" />
|
||||
</header>
|
||||
|
||||
<div className="content">
|
||||
<h1>{connectionState}</h1>
|
||||
{isConnected ? (
|
||||
<>
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td className="bold">Peer id:</td>
|
||||
<td className="mono">
|
||||
<span id="peerId">{peerInfo?.peerId}</span>
|
||||
</td>
|
||||
<td>
|
||||
<button
|
||||
className="btn-clipboard"
|
||||
onClick={() => copyToClipboard(peerInfo?.peerId)}
|
||||
>
|
||||
<i className="gg-clipboard"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="bold">Relay peer id:</td>
|
||||
<td className="mono">
|
||||
<span id="relayId">{peerInfo?.relayPeerId}</span>
|
||||
</td>
|
||||
<td>
|
||||
<button
|
||||
className="btn-clipboard"
|
||||
onClick={() => copyToClipboard(peerInfo?.relayPeerId)}
|
||||
>
|
||||
<i className="gg-clipboard"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div>
|
||||
<h2>Input numbers for computation</h2>
|
||||
<p className="p">
|
||||
Input 3 numbers for parallel computation
|
||||
</p>
|
||||
{
|
||||
numberContainers.map((ref, i) => (
|
||||
<div className="row" key={i}>
|
||||
<label className="label bold">Number {i}</label>
|
||||
<input
|
||||
ref={ref}
|
||||
style={{width: 'auto'}}
|
||||
id="targetPeerId"
|
||||
className="input"
|
||||
type="text"
|
||||
onChange={(e) => onNumberChange(e.target.value, i)}
|
||||
value={numbers[i]}
|
||||
/>
|
||||
</div>
|
||||
))
|
||||
}
|
||||
<div className="row">
|
||||
<button className="btn btn-hello" style={{float: 'initial'}} onClick={computeSingleBtnOnClick}>
|
||||
Compute single
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="row">
|
||||
<button className="btn btn-hello" style={{float: 'initial'}} onClick={computeSequentialBtnOnClick}>
|
||||
Compute sequential
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="row">
|
||||
<button className="btn btn-hello" style={{float: 'initial'}} onClick={computeParallelBtnOnClick}>
|
||||
Compute parallel
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<h1>Intro 2: Computing on the network</h1>
|
||||
<h2>Pick a relay</h2>
|
||||
<ul>
|
||||
{relayNodes.map((x) => (
|
||||
<li key={x.peerId}>
|
||||
<span className="mono">{x.peerId}</span>
|
||||
<button className="btn" onClick={() => connect(x.multiaddr)}>
|
||||
Connect
|
||||
</button>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</>
|
||||
)}
|
||||
|
||||
{(computedNumbers || computationInProgress) && (
|
||||
<>
|
||||
<h2>Computation result</h2>
|
||||
<div id="message"> {computationInProgress ? '...' : JSON.stringify(computedNumbers)} </div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const copyToClipboard = (text?: string) => {
|
||||
if (text) {
|
||||
navigator.clipboard.writeText(text);
|
||||
}
|
||||
};
|
||||
|
||||
export default App;
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
@ -0,0 +1,46 @@
|
||||
[
|
||||
{
|
||||
"multiaddr": "/dns4/0-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWSD5PToNiLQwKDXsu8JSysCwUt8BVUJEqCHcDe7P5h45e",
|
||||
"peerId": "12D3KooWSD5PToNiLQwKDXsu8JSysCwUt8BVUJEqCHcDe7P5h45e"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/1-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWR4cv1a8tv7pps4HH6wePNaK6gf1Hww5wcCMzeWxyNw51",
|
||||
"peerId": "12D3KooWR4cv1a8tv7pps4HH6wePNaK6gf1Hww5wcCMzeWxyNw51"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/2-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWKnEqMfYo9zvfHmqTLpLdiHXPe4SVqUWcWHDJdFGrSmcA",
|
||||
"peerId": "12D3KooWKnEqMfYo9zvfHmqTLpLdiHXPe4SVqUWcWHDJdFGrSmcA"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/3-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWHLxVhUQyAuZe6AHMB29P7wkvTNMn7eDMcsqimJYLKREf",
|
||||
"peerId": "12D3KooWHLxVhUQyAuZe6AHMB29P7wkvTNMn7eDMcsqimJYLKREf"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/4-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWJd3HaMJ1rpLY1kQvcjRPEvnDwcXrH8mJvk7ypcZXqXGE",
|
||||
"peerId": "12D3KooWJd3HaMJ1rpLY1kQvcjRPEvnDwcXrH8mJvk7ypcZXqXGE"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/5-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWFEwNWcHqi9rtsmDhsYcDbRUCDXH84RC4FW6UfsFWaoHi",
|
||||
"peerId": "12D3KooWFEwNWcHqi9rtsmDhsYcDbRUCDXH84RC4FW6UfsFWaoHi"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/6-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWCMr9mU894i8JXAFqpgoFtx6qnV1LFPSfVc3Y34N4h4LS",
|
||||
"peerId": "12D3KooWCMr9mU894i8JXAFqpgoFtx6qnV1LFPSfVc3Y34N4h4LS"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/7-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWDUszU2NeWyUVjCXhGEt1MoZrhvdmaQQwtZUriuGN1jTr",
|
||||
"peerId": "12D3KooWDUszU2NeWyUVjCXhGEt1MoZrhvdmaQQwtZUriuGN1jTr"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/8-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWEFFCZnar1cUJQ3rMWjvPQg6yMV2aXWs2DkJNSRbduBWn",
|
||||
"peerId": "12D3KooWEFFCZnar1cUJQ3rMWjvPQg6yMV2aXWs2DkJNSRbduBWn"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/9-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWFtf3rfCDAfWwt6oLZYZbDfn9Vn7bv7g6QjjQxUUEFVBt",
|
||||
"peerId": "12D3KooWFtf3rfCDAfWwt6oLZYZbDfn9Vn7bv7g6QjjQxUUEFVBt"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/10-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWD7CvsYcpF9HE9CCV9aY3SJ317tkXVykjtZnht2EbzDPm",
|
||||
"peerId": "12D3KooWD7CvsYcpF9HE9CCV9aY3SJ317tkXVykjtZnht2EbzDPm"
|
||||
}
|
||||
]
|
@ -0,0 +1,14 @@
|
||||
[package]
|
||||
name = "adder"
|
||||
version = "0.1.0"
|
||||
edition = "2018"
|
||||
|
||||
[[bin]]
|
||||
name = "adder"
|
||||
path = "src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
marine-rs-sdk = "0.10.0"
|
||||
|
||||
[dev-dependencies]
|
||||
marine-rs-sdk-test = "0.10.0"
|
@ -0,0 +1,11 @@
|
||||
# yaml-language-server: $schema=../../../../../.fluence/schemas/module.json
|
||||
|
||||
# Defines [Marine Module](https://fluence.dev/docs/build/concepts/#modules). You can use `fluence module new` command to generate a template for new module
|
||||
|
||||
# Documentation: https://github.com/fluencelabs/cli/tree/main/docs/configs/module.md
|
||||
|
||||
version: 0
|
||||
|
||||
type: rust
|
||||
|
||||
name: adder
|
@ -0,0 +1,8 @@
|
||||
use marine_rs_sdk::marine;
|
||||
|
||||
pub fn main() {}
|
||||
|
||||
#[marine]
|
||||
pub fn add_one(value: u64) -> u64 {
|
||||
value + 1
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
# yaml-language-server: $schema=../../../.fluence/schemas/service.json
|
||||
|
||||
# Defines a [Marine service](https://fluence.dev/docs/build/concepts/#services), most importantly the modules that the service consists of. You can use `fluence service new` command to generate a template for new service
|
||||
|
||||
# Documentation: https://github.com/fluencelabs/cli/tree/main/docs/configs/service.md
|
||||
|
||||
version: 0
|
||||
|
||||
name: adder
|
||||
|
||||
modules:
|
||||
facade:
|
||||
get: modules/adder
|
7
quickstart/2-hosted-services/.gitignore
vendored
@ -1,7 +0,0 @@
|
||||
.DS_Store
|
||||
.repl_history
|
||||
/target
|
||||
**/**.bak
|
||||
**/**.bk
|
||||
/artifacts
|
||||
keypair.json
|
@ -1,17 +0,0 @@
|
||||
[package]
|
||||
name = "hello-world"
|
||||
version = "0.1.0"
|
||||
authors = ["Fluence Labs"]
|
||||
description = "Hello world string computation"
|
||||
edition = "2018"
|
||||
publish = false
|
||||
|
||||
[[bin]]
|
||||
name = "hello_world"
|
||||
path = "src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
marine-rs-sdk = "0.10.1"
|
||||
|
||||
[dev-dependencies]
|
||||
marine-rs-sdk-test = "0.11.0"
|
@ -1,6 +0,0 @@
|
||||
modules_dir = "artifacts/"
|
||||
|
||||
[[module]]
|
||||
name = "hello_world"
|
||||
max_heap_size = "10 KiB"
|
||||
logger_enabled = false
|
@ -1,18 +0,0 @@
|
||||
{
|
||||
"services": {
|
||||
"hello_world_compute": {
|
||||
"dependencies": ["hello_world"],
|
||||
"node": "12D3KooWHLxVhUQyAuZe6AHMB29P7wkvTNMn7eDMcsqimJYLKREf"
|
||||
}
|
||||
},
|
||||
"modules": {
|
||||
"hello_world_compute": {
|
||||
"file": "artifacts/hello_world.wasm",
|
||||
"config": {
|
||||
"preopened_files": []
|
||||
}
|
||||
}
|
||||
},
|
||||
"scripts": {},
|
||||
"script_storage": {}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
{
|
||||
"services": {
|
||||
"hello_world": {
|
||||
"dependencies": [
|
||||
"hello_world_compute"
|
||||
],
|
||||
"node": "12D3KooWHLxVhUQyAuZe6AHMB29P7wkvTNMn7eDMcsqimJYLKREf",
|
||||
"hashDependencies": [
|
||||
"hash:65267bf45b564992ceec5a5f5c36eb6f17dbbb9f0a452419ffa049d2457eeb89"
|
||||
],
|
||||
"blueprint_id": "81e837fc93b970155b5c2d44e2a18d79ca88a9917db9797a271a342c0ed6516e",
|
||||
"id": "ba24be5b-9789-48ac-b38a-82c9d3eb0d34"
|
||||
}
|
||||
},
|
||||
"modules": {
|
||||
"hello_world_compute": {
|
||||
"file": "artifacts/hello_world.wasm",
|
||||
"config": {
|
||||
"preopened_files": []
|
||||
},
|
||||
"hash": "65267bf45b564992ceec5a5f5c36eb6f17dbbb9f0a452419ffa049d2457eeb89"
|
||||
}
|
||||
},
|
||||
"scripts": {},
|
||||
"script_storage": {}
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
{
|
||||
"name": "hello_world",
|
||||
"mem_pages_count": 1,
|
||||
"logger_enabled": false
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
{
|
||||
"hello-world": {
|
||||
"modules": [
|
||||
{
|
||||
"name": "hello_world",
|
||||
"path": "./artifacts/hello_world.wasm",
|
||||
"logger_enabled": true
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -o errexit -o nounset -o pipefail
|
||||
|
||||
# This script builds all subprojects and puts all created Wasm modules in one dir
|
||||
cargo update --aggressive
|
||||
marine build --release
|
||||
|
||||
mkdir -p artifacts
|
||||
rm -f artifacts/*.wasm
|
||||
cp target/wasm32-wasi/release/hello_world.wasm artifacts/
|
@ -1,53 +0,0 @@
|
||||
/*
|
||||
* Copyright 2021 Fluence Labs Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
use marine_rs_sdk::marine;
|
||||
use marine_rs_sdk::module_manifest;
|
||||
|
||||
module_manifest!();
|
||||
|
||||
pub fn main() {}
|
||||
|
||||
#[marine]
|
||||
pub struct HelloWorld {
|
||||
pub msg: String,
|
||||
pub reply: String,
|
||||
}
|
||||
|
||||
#[marine]
|
||||
pub fn hello(from: String) -> HelloWorld {
|
||||
HelloWorld {
|
||||
msg: format!("Hello from: \n{}", from),
|
||||
reply: format!("Hello back to you, \n{}", from),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use marine_rs_sdk_test::marine_test;
|
||||
|
||||
#[marine_test(config_path = "../configs/Config.toml", modules_dir = "../artifacts")]
|
||||
fn non_empty_string(hello_world: marine_test_env::hello_world::ModuleInterface) {
|
||||
let actual = hello_world.hello("SuperNode".to_string());
|
||||
assert_eq!(actual.msg, "Hello from: \nSuperNode".to_string());
|
||||
}
|
||||
|
||||
#[marine_test(config_path = "../configs/Config.toml", modules_dir = "../artifacts")]
|
||||
fn empty_string(hello_world: marine_test_env::hello_world::ModuleInterface) {
|
||||
let actual = hello_world.hello("".to_string());
|
||||
assert_eq!(actual.msg, "Hello from: \n");
|
||||
}
|
||||
}
|
30
quickstart/3-browser-to-service/.gitignore
vendored
@ -1,30 +0,0 @@
|
||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
.pnp.js
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# fluence
|
||||
|
||||
src/_aqua/*
|
||||
|
||||
public/*.wasm
|
||||
public/runnerScript.*
|
@ -1,10 +0,0 @@
|
||||
# Getting started
|
||||
|
||||
```bash
|
||||
npm i
|
||||
npm start
|
||||
```
|
||||
|
||||
The browser window with `localhost:3000` should open
|
||||
|
||||
To learn more, refer to the [documentation page](https://fluence.dev//docs/build/quick-start/browser-to-service/)
|
@ -1,29 +0,0 @@
|
||||
import "@fluencelabs/aqua-lib/builtin.aqua"
|
||||
|
||||
const HELLO_WORLD_NODE_PEER_ID ?= "12D3KooWFEwNWcHqi9rtsmDhsYcDbRUCDXH84RC4FW6UfsFWaoHi"
|
||||
const HELLO_WORLD_SERVICE_ID ?= "1e740ce4-81f6-4dd4-9bed-8d86e9c2fa50"
|
||||
|
||||
data HelloWorld:
|
||||
msg: string
|
||||
reply: string
|
||||
|
||||
-- The service runs on a Fluence node
|
||||
service HelloWorld:
|
||||
hello(from: PeerId) -> HelloWorld
|
||||
|
||||
-- The service runs inside browser
|
||||
service HelloPeer("HelloPeer"):
|
||||
hello(message: string) -> string
|
||||
|
||||
func sayHello(targetPeerId: PeerId, targetRelayPeerId: PeerId) -> string:
|
||||
-- execute computation on a Peer in the network
|
||||
on HELLO_WORLD_NODE_PEER_ID:
|
||||
HelloWorld HELLO_WORLD_SERVICE_ID
|
||||
comp <- HelloWorld.hello(%init_peer_id%)
|
||||
|
||||
-- send the result to target browser in the background
|
||||
on targetPeerId via targetRelayPeerId:
|
||||
co HelloPeer.hello(%init_peer_id%)
|
||||
|
||||
-- send the result to the initiator
|
||||
<- comp.reply
|
@ -1,174 +0,0 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import logo from './logo.svg';
|
||||
import './App.scss';
|
||||
|
||||
import { Fluence } from '@fluencelabs/js-client.api';
|
||||
import type { ConnectionState } from '@fluencelabs/js-client.api';
|
||||
import { kras } from '@fluencelabs/fluence-network-environment';
|
||||
import { sayHello, registerHelloPeer } from './_aqua/getting-started';
|
||||
|
||||
const relayNodes = [kras[4], kras[5], kras[6]];
|
||||
|
||||
function App() {
|
||||
const [connectionState, setConnectionState] = useState<ConnectionState>('disconnected');
|
||||
const [peerInfo, setPeerInfo] = useState<{ peerId: string; relayPeerId: string } | null>(null);
|
||||
const [helloMessage, setHelloMessage] = useState<string | null>(null);
|
||||
|
||||
const [peerIdInput, setPeerIdInput] = useState<string>('');
|
||||
const [relayPeerIdInput, setRelayPeerIdInput] = useState<string>('');
|
||||
|
||||
useEffect(() => {
|
||||
Fluence.onConnectionStateChange((state) => {
|
||||
console.log('Connection state changed to: ', state);
|
||||
setConnectionState(state);
|
||||
|
||||
if (state === 'connected') {
|
||||
Fluence.getClient().then((client) => {
|
||||
const peerId = client.getPeerId();
|
||||
const relayPeerId = client.getRelayPeerId();
|
||||
setPeerInfo({ peerId, relayPeerId });
|
||||
});
|
||||
}
|
||||
});
|
||||
}, []);
|
||||
|
||||
const connect = async (relayPeerId: string) => {
|
||||
try {
|
||||
await Fluence.connect(relayPeerId);
|
||||
|
||||
// Register handler for this call in aqua:
|
||||
// HelloPeer.hello(%init_peer_id%)
|
||||
registerHelloPeer({
|
||||
hello: (from) => {
|
||||
setHelloMessage('Hello from: \n' + from);
|
||||
return 'Hello back to you, \n' + from;
|
||||
},
|
||||
});
|
||||
} catch (err) {
|
||||
console.log('Client could not connect', err);
|
||||
}
|
||||
};
|
||||
|
||||
const helloBtnOnClick = async () => {
|
||||
if (connectionState !== 'connected') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Using aqua is as easy as calling a javascript function
|
||||
const res = await sayHello(peerIdInput, relayPeerIdInput);
|
||||
setHelloMessage(res);
|
||||
};
|
||||
|
||||
const isConnected = connectionState === 'connected';
|
||||
|
||||
return (
|
||||
<div className="App">
|
||||
<header>
|
||||
<img src={logo} className="logo" alt="logo" />
|
||||
</header>
|
||||
|
||||
<div className="content">
|
||||
<h1>{connectionState}</h1>
|
||||
{isConnected ? (
|
||||
<>
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td className="bold">Peer id:</td>
|
||||
<td className="mono">
|
||||
<span id="peerId">{peerInfo?.peerId}</span>
|
||||
</td>
|
||||
<td>
|
||||
<button
|
||||
className="btn-clipboard"
|
||||
onClick={() => copyToClipboard(peerInfo?.peerId)}
|
||||
>
|
||||
<i className="gg-clipboard"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="bold">Relay peer id:</td>
|
||||
<td className="mono">
|
||||
<span id="relayId">{peerInfo?.relayPeerId}</span>
|
||||
</td>
|
||||
<td>
|
||||
<button
|
||||
className="btn-clipboard"
|
||||
onClick={() => copyToClipboard(peerInfo?.relayPeerId)}
|
||||
>
|
||||
<i className="gg-clipboard"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div>
|
||||
<h2>Say hello!</h2>
|
||||
<p className="p">
|
||||
Now try opening a new tab with the same application. Copy paste the peer id and relay
|
||||
from the second tab and say hello!
|
||||
</p>
|
||||
<div className="row">
|
||||
<label className="label bold">Target peer id</label>
|
||||
<input
|
||||
id="targetPeerId"
|
||||
className="input"
|
||||
type="text"
|
||||
onChange={(e) => setPeerIdInput(e.target.value)}
|
||||
value={peerIdInput}
|
||||
/>
|
||||
</div>
|
||||
<div className="row">
|
||||
<label className="label bold">Target relay</label>
|
||||
<input
|
||||
id="targetRelayId"
|
||||
className="input"
|
||||
type="text"
|
||||
onChange={(e) => setRelayPeerIdInput(e.target.value)}
|
||||
value={relayPeerIdInput}
|
||||
/>
|
||||
</div>
|
||||
<div className="row">
|
||||
<button className="btn btn-hello" onClick={helloBtnOnClick}>
|
||||
say hello
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<h1>Intro 3: Computing on the network</h1>
|
||||
<h2>Pick a relay</h2>
|
||||
<ul>
|
||||
{relayNodes.map((x) => (
|
||||
<li key={x.peerId}>
|
||||
<span className="mono">{x.peerId}</span>
|
||||
<button className="btn" onClick={() => connect(x.multiaddr)}>
|
||||
Connect
|
||||
</button>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</>
|
||||
)}
|
||||
|
||||
{helloMessage && (
|
||||
<>
|
||||
<h2>Message</h2>
|
||||
<div id="message"> {helloMessage} </div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const copyToClipboard = (text?: string) => {
|
||||
if (text) {
|
||||
navigator.clipboard.writeText(text);
|
||||
}
|
||||
};
|
||||
|
||||
export default App;
|
@ -1,5 +0,0 @@
|
||||
debug/
|
||||
target/
|
||||
Cargo.lock
|
||||
**/*.bk
|
||||
**/*.bak
|
@ -1,22 +0,0 @@
|
||||
[package]
|
||||
name = "adder"
|
||||
version = "0.1.0"
|
||||
authors = ["boneyard93501 <4523011+boneyard93501@users.noreply.github.com>"]
|
||||
edition = "2018"
|
||||
description = "adder, a Marine wasi module"
|
||||
license = "Apache-2.0"
|
||||
|
||||
[[bin]]
|
||||
name = "adder"
|
||||
path = "src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
marine-rs-sdk = { version = "0.10.1", features = ["logger"] }
|
||||
log = "0.4.14"
|
||||
|
||||
[dev-dependencies]
|
||||
marine-rs-sdk-test = "0.11.0"
|
||||
|
||||
[dev]
|
||||
[profile.release]
|
||||
opt-level = "s"
|
@ -1,6 +0,0 @@
|
||||
modules_dir = "artifacts/"
|
||||
|
||||
[[module]]
|
||||
name = "adder"
|
||||
max_heap_size = "10 KiB"
|
||||
logger_enabled = true
|
@ -1,3 +0,0 @@
|
||||
{
|
||||
"name": "adder"
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -o errexit -o nounset -o pipefail
|
||||
cargo update --aggressive
|
||||
|
||||
mkdir -p artifacts
|
||||
rm -f artifacts/*.wasm
|
||||
marine build --release
|
||||
cp target/wasm32-wasi/release/adder.wasm artifacts/
|
@ -1,40 +0,0 @@
|
||||
/*
|
||||
* Copyright 2021 Fluence Labs Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
use marine_rs_sdk::{marine, module_manifest, WasmLoggerBuilder};
|
||||
|
||||
module_manifest!();
|
||||
|
||||
pub fn main() {
|
||||
WasmLoggerBuilder::new().build().unwrap();
|
||||
}
|
||||
|
||||
#[marine]
|
||||
pub fn add_one(value: u64) -> u64 {
|
||||
value + 1
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use marine_rs_sdk_test::marine_test;
|
||||
|
||||
#[marine_test(config_path = "../Config.toml", modules_dir = "../artifacts")]
|
||||
fn test_greeting(adder: marine_test_env::adder::ModuleInterface) {
|
||||
let value = 5;
|
||||
let res = adder.add_one(value);
|
||||
assert_eq!(value + 1, res);
|
||||
}
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
service Op("op"):
|
||||
-- does nothing
|
||||
noop()
|
||||
|
||||
-- service interface for Wasm module
|
||||
service AddOne:
|
||||
add_one: u64 -> u64
|
||||
|
||||
-- convenience struc for (Peer Id, Service Id) tuples
|
||||
data NodeServiceTuple:
|
||||
node_id: string
|
||||
service_id: string
|
||||
|
||||
func add_one(value: u64, node: string, service_id: string) -> u64:
|
||||
on node:
|
||||
AddOne service_id
|
||||
res <- AddOne.add_one(value)
|
||||
<- res
|
||||
|
||||
func add_one_three_times(value: u64, ns_tuples: []NodeServiceTuple) -> u64:
|
||||
on ns_tuples!0.node_id:
|
||||
AddOne ns_tuples!0.service_id
|
||||
res1 <- AddOne.add_one(value)
|
||||
|
||||
on ns_tuples!1.node_id:
|
||||
AddOne ns_tuples!1.service_id
|
||||
res2 <- AddOne.add_one(res1)
|
||||
|
||||
on ns_tuples!2.node_id:
|
||||
AddOne ns_tuples!2.service_id
|
||||
res3 <- AddOne.add_one(res2)
|
||||
<- res3
|
||||
|
||||
func add_one_par(value: u64, ns_tuples: []NodeServiceTuple) -> []u64:
|
||||
res: *u64
|
||||
for ns <- ns_tuples par:
|
||||
on ns.node_id:
|
||||
AddOne ns.service_id
|
||||
res <- AddOne.add_one(value)
|
||||
Op.noop()
|
||||
join res[2]
|
||||
<- res
|
||||
|
||||
data ValueNodeService:
|
||||
node_id: string
|
||||
service_id: string
|
||||
value: u64
|
||||
|
||||
func add_one_par_alt(payload: []ValueNodeService) -> []u64:
|
||||
res: *u64
|
||||
for vns <- payload par:
|
||||
on vns.node_id:
|
||||
AddOne vns.service_id
|
||||
res <- AddOne.add_one(vns.value)
|
||||
Op.noop()
|
||||
join res[2]
|
||||
<- res
|
@ -1,6 +0,0 @@
|
||||
dist
|
||||
|
||||
|
||||
# fluence
|
||||
|
||||
src/compiled-aqua/*
|
@ -1,49 +0,0 @@
|
||||
{
|
||||
"name": "quickstart-4-example",
|
||||
"version": "0.1.0",
|
||||
"description": "Fluence Quickstart-4 Examples",
|
||||
"main": "./dist/src/index.js",
|
||||
"typings": "./dist/src/index.d.ts",
|
||||
"files": [
|
||||
"dist/*"
|
||||
],
|
||||
"bic": [
|
||||
"client-peer/*",
|
||||
"*.aqua",
|
||||
"package-lock.json"
|
||||
],
|
||||
"dependencies": {
|
||||
"@fluencelabs/fluence": "0.28.0",
|
||||
"@fluencelabs/fluence-network-environment": "^1.0.13",
|
||||
"it-all": "^1.0.5"
|
||||
},
|
||||
"scripts": {
|
||||
"compile-aqua": "aqua -i ../aqua-scripts -o src/compiled-aqua/",
|
||||
"prebuild": "npm run compile-aqua",
|
||||
"build": "tsc",
|
||||
"prestart:local": "npm run build",
|
||||
"start:local": "node dist/src/index.js local",
|
||||
"prestart:remote": "npm run build",
|
||||
"start:remote": "node dist/src/index.js krasnodar",
|
||||
"start": "npm run start:remote"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/fluencelabs/examples/quickstart"
|
||||
},
|
||||
"keywords": [
|
||||
"aqua",
|
||||
"fluence"
|
||||
],
|
||||
"author": "Fluence Labs",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "git+https://github.com/fluencelabs/examples/issues"
|
||||
},
|
||||
"homepage": "git+https://github.com/fluencelabs/examples/aqua-examples/echo-greeter#readme",
|
||||
"devDependencies": {
|
||||
"@fluencelabs/aqua": "0.10.3",
|
||||
"@fluencelabs/aqua-lib": "0.7.7",
|
||||
"typescript": "^4.6.3"
|
||||
}
|
||||
}
|
@ -1,115 +0,0 @@
|
||||
/*
|
||||
* Copyright 2021 Fluence Labs Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Fluence, setLogLevel, FluencePeer } from "@fluencelabs/fluence";
|
||||
import { krasnodar, Node } from "@fluencelabs/fluence-network-environment";
|
||||
import { add_one, add_one_par, add_one_three_times, add_one_par_alt } from "./compiled-aqua/adder";
|
||||
|
||||
|
||||
|
||||
interface NodeServiceTuple {
|
||||
node_id: string;
|
||||
service_id: string;
|
||||
}
|
||||
|
||||
let topos: Array<NodeServiceTuple> = [
|
||||
{
|
||||
"node_id": "12D3KooWFtf3rfCDAfWwt6oLZYZbDfn9Vn7bv7g6QjjQxUUEFVBt",
|
||||
"service_id": "7b2ab89f-0897-4537-b726-8120b405074d"
|
||||
},
|
||||
{
|
||||
"node_id": "12D3KooWKnEqMfYo9zvfHmqTLpLdiHXPe4SVqUWcWHDJdFGrSmcA",
|
||||
"service_id": "e013f18a-200f-4249-8303-d42d10d3ce46"
|
||||
},
|
||||
{
|
||||
"node_id": "12D3KooWDUszU2NeWyUVjCXhGEt1MoZrhvdmaQQwtZUriuGN1jTr",
|
||||
"service_id": "191ef700-fd13-4151-9b7c-3fabfe3c0387"
|
||||
}
|
||||
];
|
||||
|
||||
interface ValueNodeService {
|
||||
value: number,
|
||||
node_id: string;
|
||||
service_id: string;
|
||||
}
|
||||
|
||||
let topos_alt: Array<ValueNodeService> = [
|
||||
{
|
||||
"value": 5,
|
||||
"node_id": "12D3KooWFtf3rfCDAfWwt6oLZYZbDfn9Vn7bv7g6QjjQxUUEFVBt",
|
||||
"service_id": "7b2ab89f-0897-4537-b726-8120b405074d"
|
||||
},
|
||||
{
|
||||
"value": 10,
|
||||
"node_id": "12D3KooWKnEqMfYo9zvfHmqTLpLdiHXPe4SVqUWcWHDJdFGrSmcA",
|
||||
"service_id": "e013f18a-200f-4249-8303-d42d10d3ce46"
|
||||
},
|
||||
{
|
||||
"value": 15,
|
||||
"node_id": "12D3KooWDUszU2NeWyUVjCXhGEt1MoZrhvdmaQQwtZUriuGN1jTr",
|
||||
"service_id": "191ef700-fd13-4151-9b7c-3fabfe3c0387"
|
||||
}
|
||||
];
|
||||
|
||||
let value = 5;
|
||||
|
||||
// let greeting_service =
|
||||
|
||||
async function main() {
|
||||
// console.log("hello");
|
||||
// setLogLevel('DEBUG');
|
||||
|
||||
await Fluence.start({ connectTo: krasnodar[2] });
|
||||
console.log(
|
||||
"created a Fluence client %s with relay %s",
|
||||
Fluence.getStatus().peerId,
|
||||
Fluence.getStatus().relayPeerId
|
||||
);
|
||||
|
||||
let basic_add = await add_one(
|
||||
value,
|
||||
topos[0].node_id,
|
||||
topos[0].service_id
|
||||
);
|
||||
console.log("add_one to ", value, " equals ", basic_add);
|
||||
|
||||
|
||||
let seq_add = await add_one_three_times(
|
||||
value,
|
||||
topos
|
||||
);
|
||||
console.log("add_one sequentially equals ", seq_add);
|
||||
|
||||
let par_add = await add_one_par(
|
||||
value,
|
||||
topos
|
||||
);
|
||||
console.log("add_one parallel equals ", par_add);
|
||||
|
||||
let par_add_alt = await add_one_par_alt(
|
||||
topos_alt
|
||||
);
|
||||
console.log("add_one parallel alt equals ", par_add_alt);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
main()
|
||||
.then(() => process.exit(0))
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
process.exit(1);
|
||||
});
|
@ -1,62 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
/* Visit https://aka.ms/tsconfig.json to read more about this file */
|
||||
/* Basic Options */
|
||||
// "incremental": true, /* Enable incremental compilation */
|
||||
"target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
|
||||
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
|
||||
// "lib": [], /* Specify library files to be included in the compilation. */
|
||||
// "allowJs": true, /* Allow javascript files to be compiled. */
|
||||
// "checkJs": true, /* Report errors in .js files. */
|
||||
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
|
||||
// "declaration": true, /* Generates corresponding '.d.ts' file. */
|
||||
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
|
||||
// "sourceMap": true, /* Generates corresponding '.map' file. */
|
||||
// "outFile": "./", /* Concatenate and emit output to single file. */
|
||||
"outDir": "./dist", /* Redirect output structure to the directory. */
|
||||
"rootDir": ".", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
|
||||
// "composite": true, /* Enable project compilation */
|
||||
// "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
|
||||
// "removeComments": true, /* Do not emit comments to output. */
|
||||
// "noEmit": true, /* Do not emit outputs. */
|
||||
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
|
||||
// "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
|
||||
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
|
||||
/* Strict Type-Checking Options */
|
||||
"strict": true, /* Enable all strict type-checking options. */
|
||||
// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
|
||||
// "strictNullChecks": true, /* Enable strict null checks. */
|
||||
// "strictFunctionTypes": true, /* Enable strict checking of function types. */
|
||||
// "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
|
||||
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
|
||||
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
|
||||
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
|
||||
/* Additional Checks */
|
||||
// "noUnusedLocals": true, /* Report errors on unused locals. */
|
||||
// "noUnusedParameters": true, /* Report errors on unused parameters. */
|
||||
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
|
||||
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
|
||||
/* Module Resolution Options */
|
||||
// "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
|
||||
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
|
||||
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
|
||||
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
|
||||
// "typeRoots": [], /* List of folders to include type definitions from. */
|
||||
// "types": [], /* Type declaration files to be included in compilation. */
|
||||
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
|
||||
"esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
|
||||
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
|
||||
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
|
||||
/* Source Map Options */
|
||||
// "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
|
||||
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
|
||||
// "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
|
||||
// "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
|
||||
/* Experimental Options */
|
||||
// "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
|
||||
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
|
||||
/* Advanced Options */
|
||||
"skipLibCheck": true, /* Skip type checking of declaration files. */
|
||||
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
|
||||
}
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
[
|
||||
{
|
||||
"node_id": "12D3KooWFtf3rfCDAfWwt6oLZYZbDfn9Vn7bv7g6QjjQxUUEFVBt",
|
||||
"service_id": "7b2ab89f-0897-4537-b726-8120b405074d"
|
||||
},
|
||||
{
|
||||
"node_id": "12D3KooWKnEqMfYo9zvfHmqTLpLdiHXPe4SVqUWcWHDJdFGrSmcA",
|
||||
"service_id": "e013f18a-200f-4249-8303-d42d10d3ce46"
|
||||
},
|
||||
{
|
||||
"node_id": "12D3KooWDUszU2NeWyUVjCXhGEt1MoZrhvdmaQQwtZUriuGN1jTr",
|
||||
"service_id": "191ef700-fd13-4151-9b7c-3fabfe3c0387"
|
||||
}
|
||||
]
|
@ -1,26 +0,0 @@
|
||||
[package]
|
||||
name = "quickstart-5-timestamp-oracle"
|
||||
version = "0.1.0"
|
||||
authors = ["boneyard93501 <4523011+boneyard93501@users.noreply.github.com>"]
|
||||
edition = "2018"
|
||||
description = "ts-cons, a Marine wasi module"
|
||||
license = "Apache-2.0"
|
||||
|
||||
[[bin]]
|
||||
name = "ts_oracle"
|
||||
path = "src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
marine-rs-sdk = { version = "0.10.1", features = ["logger"] }
|
||||
log = "0.4.14"
|
||||
# picorand = "0.1.1"
|
||||
nanorand = { version = "0.7.0", default-features = false, features = [
|
||||
"wyrand",
|
||||
] }
|
||||
|
||||
[dev-dependencies]
|
||||
marine-rs-sdk-test = "0.11.0"
|
||||
|
||||
[dev]
|
||||
[profile.release]
|
||||
opt-level = "s"
|
@ -1,3 +0,0 @@
|
||||
# 5. Decentralized Oracles With Fluence And Aqua
|
||||
|
||||
See the gitbook [documentation](https://fluence.dev/docs/build/quick-start/decentralized-oracles/) for the tutorial.
|
@ -1,56 +0,0 @@
|
||||
import "@fluencelabs/aqua-lib/builtin.aqua"
|
||||
|
||||
|
||||
data Contact:
|
||||
peer_id: string
|
||||
addresses: []string
|
||||
|
||||
data Info:
|
||||
external_addresses: []string
|
||||
|
||||
service MyOp("op"):
|
||||
identity(u: u64)
|
||||
identity_string(s:string)
|
||||
|
||||
service MyOpBool("op"):
|
||||
identity(b: bool)
|
||||
|
||||
data Consensus:
|
||||
n: u32
|
||||
consensus_ts: u64
|
||||
consensus: bool
|
||||
support: u32
|
||||
err_str: string
|
||||
|
||||
data Oracle:
|
||||
n: u32
|
||||
avg: f64
|
||||
err_str: string
|
||||
|
||||
service TSOracle("service-id"):
|
||||
ts_frequency(timestamps: []u64, tolerance: u32, threshold: f64, err_value:u64) -> Consensus
|
||||
|
||||
func ts_oracle_with_consensus(tolerance: u32, threshold: f64, err_value:u64, node:string, oracle_service_id:string)-> Consensus, []string, u32:
|
||||
rtt = 1000 -- in ms
|
||||
res: *u64
|
||||
msg = "timeout"
|
||||
dead_peers: *string
|
||||
on node:
|
||||
k <- Op.string_to_b58(node)
|
||||
nodes <- Kademlia.neighborhood(k, nil, nil)
|
||||
for n <- nodes par:
|
||||
status: *string
|
||||
on n:
|
||||
res <- Peer.timestamp_ms()
|
||||
status <<- "success"
|
||||
par status <- Peer.timeout(rtt, msg)
|
||||
if status! != "success":
|
||||
res <<- err_value
|
||||
dead_peers <<- n
|
||||
|
||||
join res[Op.array_length(nodes) - Op.array_length(dead_peers) -1]
|
||||
|
||||
TSOracle oracle_service_id
|
||||
consensus <- TSOracle.ts_frequency(res, tolerance, threshold, err_value)
|
||||
|
||||
<- consensus, dead_peers, Op.array_length(nodes) - Op.array_length(dead_peers)
|
@ -1,6 +0,0 @@
|
||||
modules_dir = "artifacts/"
|
||||
|
||||
[[module]]
|
||||
name = "ts_oracle"
|
||||
max_heap_size = "20 KiB"
|
||||
logger_enabled = true
|