mirror of
https://github.com/fluencelabs/examples
synced 2025-04-25 10:42:16 +00:00
parent
6381411ed9
commit
10b9cad438
@ -0,0 +1,61 @@
|
|||||||
|
(xor
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(call %init_peer_id% ("getDataSrv" "-relay-") [] -relay-)
|
||||||
|
(call %init_peer_id% ("getDataSrv" "coin") [] coin)
|
||||||
|
)
|
||||||
|
(call %init_peer_id% ("getDataSrv" "currency") [] currency)
|
||||||
|
)
|
||||||
|
(call %init_peer_id% ("getDataSrv" "node") [] node)
|
||||||
|
)
|
||||||
|
(call %init_peer_id% ("getDataSrv" "pg_sid") [] pg_sid)
|
||||||
|
)
|
||||||
|
(call %init_peer_id% ("getDataSrv" "mean_sid") [] mean_sid)
|
||||||
|
)
|
||||||
|
(call -relay- ("op" "noop") [])
|
||||||
|
)
|
||||||
|
(xor
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(call node ("op" "string_to_b58") [node] k)
|
||||||
|
(call node ("peer" "timestamp_ms") [] ts_ms0)
|
||||||
|
)
|
||||||
|
(call node (pg_sid "price_getter") [coin currency ts_ms0] res0)
|
||||||
|
)
|
||||||
|
(call node ("op" "identity") [res0.$.result!] $prices)
|
||||||
|
)
|
||||||
|
(call node ("peer" "timestamp_ms") [] ts_ms1)
|
||||||
|
)
|
||||||
|
(call node (pg_sid "price_getter") [coin currency ts_ms1] res1)
|
||||||
|
)
|
||||||
|
(call node ("op" "identity") [res1.$.result!] $prices)
|
||||||
|
)
|
||||||
|
(call node (mean_sid "mean") [$prices] result)
|
||||||
|
)
|
||||||
|
(seq
|
||||||
|
(call -relay- ("op" "noop") [])
|
||||||
|
(call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 1])
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(call -relay- ("op" "noop") [])
|
||||||
|
)
|
||||||
|
(xor
|
||||||
|
(call %init_peer_id% ("callbackSrv" "response") [result])
|
||||||
|
(call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 2])
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 3])
|
||||||
|
)
|
@ -0,0 +1,47 @@
|
|||||||
|
(xor
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(call %init_peer_id% ("getDataSrv" "-relay-") [] -relay-)
|
||||||
|
(call %init_peer_id% ("getDataSrv" "payload") [] payload)
|
||||||
|
)
|
||||||
|
(call %init_peer_id% ("getDataSrv" "ns_pairs") [] ns_pairs)
|
||||||
|
)
|
||||||
|
(fold ns_pairs p
|
||||||
|
(par
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(call -relay- ("op" "noop") [])
|
||||||
|
(xor
|
||||||
|
(seq
|
||||||
|
(call p.$.node! ("op" "string_to_b58") [p.$.node!] k)
|
||||||
|
(fold payload d
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(call p.$.node! ("peer" "timestamp_ms") [] ts_ms)
|
||||||
|
(call p.$.node! (p.$.service_id! "price_getter") [d.$.coin! d.$.currency! ts_ms] $prices)
|
||||||
|
)
|
||||||
|
(next d)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(seq
|
||||||
|
(call -relay- ("op" "noop") [])
|
||||||
|
(call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 1])
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(call %init_peer_id% ("op" "noop") [])
|
||||||
|
)
|
||||||
|
(next p)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(xor
|
||||||
|
(call %init_peer_id% ("callbackSrv" "response") [$prices])
|
||||||
|
(call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 2])
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 3])
|
||||||
|
)
|
@ -0,0 +1,39 @@
|
|||||||
|
(xor
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(call %init_peer_id% ("getDataSrv" "-relay-") [] -relay-)
|
||||||
|
(call %init_peer_id% ("getDataSrv" "payload") [] payload)
|
||||||
|
)
|
||||||
|
(fold payload p
|
||||||
|
(par
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(call -relay- ("op" "noop") [])
|
||||||
|
(xor
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(call p.$.node! ("op" "string_to_b58") [p.$.node!] k)
|
||||||
|
(call p.$.node! ("peer" "timestamp_ms") [] ts_ms)
|
||||||
|
)
|
||||||
|
(call p.$.node! (p.$.service_id! "price_getter") [p.$.coin! p.$.currency! ts_ms] $prices)
|
||||||
|
)
|
||||||
|
(seq
|
||||||
|
(call -relay- ("op" "noop") [])
|
||||||
|
(call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 1])
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(call %init_peer_id% ("op" "noop") [])
|
||||||
|
)
|
||||||
|
(next p)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(xor
|
||||||
|
(call %init_peer_id% ("callbackSrv" "response") [$prices])
|
||||||
|
(call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 2])
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 3])
|
||||||
|
)
|
@ -0,0 +1,47 @@
|
|||||||
|
(xor
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(call %init_peer_id% ("getDataSrv" "-relay-") [] -relay-)
|
||||||
|
(call %init_peer_id% ("getDataSrv" "payloads") [] payloads)
|
||||||
|
)
|
||||||
|
(call %init_peer_id% ("getDataSrv" "ns_pairs") [] ns_pairs)
|
||||||
|
)
|
||||||
|
(fold ns_pairs p
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(call -relay- ("op" "noop") [])
|
||||||
|
(xor
|
||||||
|
(seq
|
||||||
|
(call p.$.node! ("op" "string_to_b58") [p.$.node!] k)
|
||||||
|
(fold payloads d
|
||||||
|
(seq
|
||||||
|
(seq
|
||||||
|
(call p.$.node! ("peer" "timestamp_ms") [] ts_ms)
|
||||||
|
(call p.$.node! (p.$.service_id! "price_getter") [d.$.coin! d.$.currency! ts_ms] $prices)
|
||||||
|
)
|
||||||
|
(next d)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(seq
|
||||||
|
(call -relay- ("op" "noop") [])
|
||||||
|
(call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 1])
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(call -relay- ("op" "noop") [])
|
||||||
|
)
|
||||||
|
(next p)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(xor
|
||||||
|
(call %init_peer_id% ("callbackSrv" "response") [$prices])
|
||||||
|
(call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 2])
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 3])
|
||||||
|
)
|
217
aqua-examples/price-oracle/aqua-scripts/builtin.aqua
Normal file
217
aqua-examples/price-oracle/aqua-scripts/builtin.aqua
Normal file
@ -0,0 +1,217 @@
|
|||||||
|
-- Default public interface of Fluence nodes
|
||||||
|
|
||||||
|
alias Field : []string
|
||||||
|
alias Argument : []string
|
||||||
|
alias Bytes : []u8
|
||||||
|
alias PeerId : string
|
||||||
|
alias Pairs : [][]string
|
||||||
|
alias Base58String : string
|
||||||
|
|
||||||
|
-- There are two types of dependencies: named and by-hash.
|
||||||
|
-- name:foobar – specifies dependency by module name, points to a module with import name 'foobar'
|
||||||
|
-- hash:04dc884... – specifies dependency by module hash
|
||||||
|
-- By-hash dependencies are preffered since they are deteremenistic
|
||||||
|
-- while by-name dependency can yield different modules at different points in time
|
||||||
|
alias Dependency : string
|
||||||
|
|
||||||
|
data Service:
|
||||||
|
id: string
|
||||||
|
blueprint_id: string
|
||||||
|
owner_id: string
|
||||||
|
|
||||||
|
data FunctionSignature:
|
||||||
|
arguments: []Argument
|
||||||
|
name: string
|
||||||
|
output_types: []string
|
||||||
|
|
||||||
|
data RecordType:
|
||||||
|
fields: []Field
|
||||||
|
id: u64
|
||||||
|
name: string
|
||||||
|
|
||||||
|
data Interface:
|
||||||
|
function_signatures: []FunctionSignature
|
||||||
|
record_types: []RecordType
|
||||||
|
|
||||||
|
data Info:
|
||||||
|
external_addresses: []string
|
||||||
|
|
||||||
|
data ModuleConfig:
|
||||||
|
name: string
|
||||||
|
|
||||||
|
data Module:
|
||||||
|
name: string
|
||||||
|
hash: string
|
||||||
|
config: ModuleConfig
|
||||||
|
|
||||||
|
data AddBlueprint:
|
||||||
|
name: string
|
||||||
|
dependencies: []Dependency
|
||||||
|
|
||||||
|
data Blueprint:
|
||||||
|
id: string
|
||||||
|
name: string
|
||||||
|
dependencies: []Dependency
|
||||||
|
|
||||||
|
data ScriptInfo:
|
||||||
|
id: string
|
||||||
|
src: string
|
||||||
|
failures: u32
|
||||||
|
interval: string
|
||||||
|
owner: string
|
||||||
|
|
||||||
|
data Contact:
|
||||||
|
peer_id: string
|
||||||
|
addresses: []string
|
||||||
|
|
||||||
|
service Op("op"):
|
||||||
|
-- does nothing
|
||||||
|
noop()
|
||||||
|
-- returns length of the passed array
|
||||||
|
array_length(array: []string) -> u32
|
||||||
|
-- takes any number of arguments and wraps them into a single array
|
||||||
|
array(a: string, b: ?string, c: ?string, d: ?string) -> []string
|
||||||
|
-- takes any number of arrays and flattens them by concatenating
|
||||||
|
concat(a: []string, b: ?[]string, c: ?[]string, d: ?[]string) -> []string
|
||||||
|
-- takes a single argument and returns it back
|
||||||
|
identity(s: ?string) -> ?string
|
||||||
|
string_to_b58(s: string) -> Base58String
|
||||||
|
string_from_b58(b: Base58String) -> string
|
||||||
|
bytes_to_b58(bs: []u8) -> Base58String
|
||||||
|
bytes_from_b58(b: Base58String) -> []u8
|
||||||
|
-- Applies SHA256 to the given string
|
||||||
|
-- Argument: s - string to apply sha256 to (hash is applied to utf8 bytes of s)
|
||||||
|
-- Returns: returns sha256 multihash encoded as base58
|
||||||
|
sha256_string(s: string) -> Base58String
|
||||||
|
|
||||||
|
service Peer("peer"):
|
||||||
|
-- Checks if there is a direct connection to the peer identified by a given PeerId
|
||||||
|
-- Argument: PeerId – id of the peer to check if there's a connection with
|
||||||
|
-- Returns: bool - true if connected to the peer, false otherwise
|
||||||
|
is_connected(peer: PeerId) -> bool
|
||||||
|
|
||||||
|
-- Initiates a connection to the specified peer
|
||||||
|
-- Arguments:
|
||||||
|
-- id - id of the target peer
|
||||||
|
-- multiaddrs – an array of target peer's addresses
|
||||||
|
-- Returns: bool - true if connection was successful
|
||||||
|
connect(id: PeerId, multiaddrs: ?[]string) -> bool
|
||||||
|
-- Resolves the contact of a peer via Kademlia
|
||||||
|
-- Argument: PeerId – id of the target peer
|
||||||
|
-- Returns: Contact - true if connection was successful
|
||||||
|
get_contact(peer: PeerId) -> Contact
|
||||||
|
|
||||||
|
-- Get information about the peer
|
||||||
|
identify() -> Info
|
||||||
|
|
||||||
|
-- Get Unix timestamp in milliseconds
|
||||||
|
timestamp_ms() -> u64
|
||||||
|
|
||||||
|
-- Get Unix timestamp in seconds
|
||||||
|
timestamp_sec() -> u64
|
||||||
|
|
||||||
|
service Kademlia("kad"):
|
||||||
|
-- Instructs node to return the locally-known nodes
|
||||||
|
-- in the Kademlia neighborhood for a given key
|
||||||
|
-- Arguments:
|
||||||
|
-- key – base58 string
|
||||||
|
-- already_hashed – default false; if set to true, key is considered to be a SHA256 multihash
|
||||||
|
-- count – default 20; limits number of returned nodes
|
||||||
|
neighborhood(key: Base58String, already_hashed: ?bool, count: ?u32) -> []PeerId
|
||||||
|
-- Merges given lists and sorts them by distance to target
|
||||||
|
-- Arguments:
|
||||||
|
-- target – base58 string; result is sorted by XOR distance to target
|
||||||
|
-- left – list of base58 strings
|
||||||
|
-- right – list of base58 strings
|
||||||
|
-- count – how many items to return, unlimited by default
|
||||||
|
-- Returns: list of base58 strings sorted by distance to target; list will contain at most count elements
|
||||||
|
merge(target: Base58String, left: []string, right: []string, count: ?u32) -> []string
|
||||||
|
|
||||||
|
service Srv("srv"):
|
||||||
|
-- Used to create a service on a certain node
|
||||||
|
-- Arguments:
|
||||||
|
-- blueprint_id – ID of the blueprint that has been added to the node specified in the service call by the dist add_blueprint service.
|
||||||
|
-- Returns: service_id – the service ID of the created service.
|
||||||
|
create(blueprint_id: string) -> string
|
||||||
|
|
||||||
|
-- Used to remove a service from a certain node
|
||||||
|
-- Arguments:
|
||||||
|
-- service_id – ID of the service to remove
|
||||||
|
remove(service_id: string)
|
||||||
|
|
||||||
|
-- Returns a list of services running on a peer
|
||||||
|
list() -> []Service
|
||||||
|
|
||||||
|
-- Adds an alias on service, so, service could be called
|
||||||
|
-- not only by service_id but by alias as well.
|
||||||
|
-- Arguments:
|
||||||
|
-- alias - settable service name
|
||||||
|
-- service_id – ID of the service whose interface you want to name.
|
||||||
|
add_alias(alias: string, service_id: string)
|
||||||
|
|
||||||
|
-- Resolves given alias to a service id
|
||||||
|
-- If there's no such alias, throws an error
|
||||||
|
-- Returns: service id associated with the given alias
|
||||||
|
resolve_alias(alias: string) -> string
|
||||||
|
|
||||||
|
-- Retrieves the functional interface of a service running
|
||||||
|
-- on the node specified in the service call
|
||||||
|
-- Argument: service_id – ID of the service whose interface you want to retrieve.
|
||||||
|
get_interface(service_id: string) -> Interface
|
||||||
|
|
||||||
|
service Dist("dist"):
|
||||||
|
-- Constructs a ModuleConfig structure
|
||||||
|
-- Arguments:
|
||||||
|
-- module_name - import name of the module
|
||||||
|
-- mem_pages_count - Maximum memory size accessible by a module in Wasm pages (64 Kb)
|
||||||
|
-- logger_enabled - Defines whether Marine should provide a special host log_utf8_string function for this module
|
||||||
|
-- preopened_files - Files available for this module. Module can access only files from this list
|
||||||
|
-- envs - environment variables available for this module
|
||||||
|
-- mapped_dirs - Directory mapping, e.g. [["/sites", "./web/data"]] so all
|
||||||
|
-- reads & writes to /sites will actually to go ./web/data
|
||||||
|
-- mounted_binaries - Mapping of host binaries available to call from module,
|
||||||
|
-- e.g. [["curl", "/usr/bin/curl"]] will allow module to
|
||||||
|
-- call /usr/bin/curl binary as function 'curl'
|
||||||
|
-- logging_mask - Binary mask to enable & disable logging targets. Targets are
|
||||||
|
-- configured in WasmLoggerBuilder::with_target_map
|
||||||
|
-- mem_pages_count - Maximum memory size accessible by a module in Wasm pages (64 Kb)
|
||||||
|
make_module_config(name: string, mem_pages_count: ?u32, logger_enabled: ?bool, preopened_files: ?[]string, envs: ?Pairs, mapped_dirs: ?Pairs, mounted_binaries: ?Pairs, logging_mask: ?i32) -> ModuleConfig
|
||||||
|
|
||||||
|
-- Used to add modules to the node specified in the service call
|
||||||
|
-- Arguments:
|
||||||
|
-- bytes – a base64 string containing the .wasm module to add.
|
||||||
|
-- config – module info
|
||||||
|
-- Returns: blake3 hash of the module
|
||||||
|
add_module(wasm_b56_content: Bytes, conf: ModuleConfig) -> string
|
||||||
|
|
||||||
|
-- Get a list of modules available on the node
|
||||||
|
list_modules() -> []Module
|
||||||
|
|
||||||
|
-- Get the interface of a module
|
||||||
|
get_interface(module_id: string) -> Interface
|
||||||
|
|
||||||
|
-- Creates Blueprint structure from from blueprint name and dependencies (modules)
|
||||||
|
make_blueprint(name: string, dependencies: []Dependency) -> AddBlueprint
|
||||||
|
-- Add a blueprint to the node
|
||||||
|
add_blueprint(blueprint: AddBlueprint) -> string
|
||||||
|
|
||||||
|
-- Used to get the blueprints available on the node specified in the service call.
|
||||||
|
-- A blueprint is an object of the following structure
|
||||||
|
list_blueprints() -> []Blueprint
|
||||||
|
|
||||||
|
service Script("script"):
|
||||||
|
-- Adds the given script to a node
|
||||||
|
-- Arguments:
|
||||||
|
-- air_script - raw AIR script without any undefined variables
|
||||||
|
-- interval - if not set, script will be ran only once
|
||||||
|
-- if set, script will be ran once in the interval
|
||||||
|
-- (NOTE: actual interval may vary by up to 3 seconds)
|
||||||
|
-- TODO: change interval to ?u64 when node API is updated
|
||||||
|
add(air_script: string, interval: ?string) -> string
|
||||||
|
|
||||||
|
-- Removes recurring script from a node. Only a creator of the script can delete it
|
||||||
|
remove(script_id: string) -> bool
|
||||||
|
|
||||||
|
-- Returns a list of existing scripts on the node.
|
||||||
|
-- Each object in the list is of the following structure
|
||||||
|
list() -> ScriptInfo
|
@ -0,0 +1,49 @@
|
|||||||
|
-- import "@fluencelabs/aqua-lib/builtin.aqua"
|
||||||
|
import "builtin.aqua"
|
||||||
|
|
||||||
|
data Result:
|
||||||
|
result: f64
|
||||||
|
success: bool
|
||||||
|
error_msg: string
|
||||||
|
|
||||||
|
service PriceGetterService:
|
||||||
|
price_getter(coin: string, currency: string, timestamp_ms: u64) -> Result
|
||||||
|
|
||||||
|
service MeanService:
|
||||||
|
mean(data: []f64) -> Result
|
||||||
|
|
||||||
|
service F64Op("op"):
|
||||||
|
identity(x:f64) -> f64
|
||||||
|
|
||||||
|
data Payload:
|
||||||
|
coin: string
|
||||||
|
currency: string
|
||||||
|
|
||||||
|
data NodeServicePair:
|
||||||
|
node: string
|
||||||
|
service_id: string
|
||||||
|
|
||||||
|
-- func get_price(coin: string, currency: string, node: string, service_id: string, logError:string, string -> ()) -> Result:
|
||||||
|
func get_price(coin: string, currency: string, node: string, pg_sid: string, mean_sid: string) -> Result:
|
||||||
|
prices: *f64
|
||||||
|
on node:
|
||||||
|
k <- Op.string_to_b58(node)
|
||||||
|
|
||||||
|
PriceGetterService pg_sid
|
||||||
|
MeanService mean_sid
|
||||||
|
|
||||||
|
ts_ms0 <- Peer.timestamp_ms()
|
||||||
|
res0 <- PriceGetterService.price_getter(coin, currency, ts_ms0)
|
||||||
|
-- if price.success:
|
||||||
|
prices <- F64Op.identity(res0.result)
|
||||||
|
|
||||||
|
ts_ms1 <- Peer.timestamp_ms()
|
||||||
|
res1 <- PriceGetterService.price_getter(coin, currency, ts_ms1)
|
||||||
|
-- if price.success:
|
||||||
|
prices <- F64Op.identity(res1.result)
|
||||||
|
|
||||||
|
result <- MeanService.mean(prices)
|
||||||
|
-- else:
|
||||||
|
-- logError("price_getter: ", price.error_msg)
|
||||||
|
<- result
|
||||||
|
|
19
aqua-examples/price-oracle/configs/Config.toml
Normal file
19
aqua-examples/price-oracle/configs/Config.toml
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
modules_dir = "artifacts/"
|
||||||
|
|
||||||
|
[[module]]
|
||||||
|
name = "curl_adapter"
|
||||||
|
logger_enabled = false
|
||||||
|
mem_pages_count = 1
|
||||||
|
|
||||||
|
[module.mounted_binaries]
|
||||||
|
curl = "/usr/bin/curl"
|
||||||
|
|
||||||
|
[[module]]
|
||||||
|
name = "price_getter_service"
|
||||||
|
logger_enabled = false
|
||||||
|
mem_pages_count = 1
|
||||||
|
|
||||||
|
[[module]]
|
||||||
|
name = "mean_service"
|
||||||
|
logger_enabled = false
|
||||||
|
mem_pages_count = 1
|
8
aqua-examples/price-oracle/configs/curl_adapter_cfg.json
Normal file
8
aqua-examples/price-oracle/configs/curl_adapter_cfg.json
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"name": "curl_adapter",
|
||||||
|
"mountedBinaries": {
|
||||||
|
"curl": "/usr/bin/curl"
|
||||||
|
},
|
||||||
|
"mem_page_count": 1,
|
||||||
|
"logger_enabled": false
|
||||||
|
}
|
5
aqua-examples/price-oracle/configs/mean_service_cfg.json
Normal file
5
aqua-examples/price-oracle/configs/mean_service_cfg.json
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"name": "mean_service",
|
||||||
|
"mem_page_count": 1,
|
||||||
|
"logger_enabled": false
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"name": "price_getter_service",
|
||||||
|
"mem_page_count": 1,
|
||||||
|
"logger_enabled": false
|
||||||
|
}
|
14
aqua-examples/price-oracle/curl_adapter/Cargo.toml
Normal file
14
aqua-examples/price-oracle/curl_adapter/Cargo.toml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
[package]
|
||||||
|
name = "curl_adapter"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Fluence Labs"]
|
||||||
|
edition = "2018"
|
||||||
|
publish = false
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
path = "src/main.rs"
|
||||||
|
name = "curl_adapter"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
marine-rs-sdk = "0.6.11"
|
||||||
|
log = "0.4.8"
|
37
aqua-examples/price-oracle/curl_adapter/src/main.rs
Normal file
37
aqua-examples/price-oracle/curl_adapter/src/main.rs
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#![allow(improper_ctypes)]
|
||||||
|
|
||||||
|
use marine_rs_sdk::marine;
|
||||||
|
use marine_rs_sdk::module_manifest;
|
||||||
|
|
||||||
|
use marine_rs_sdk::MountedBinaryResult;
|
||||||
|
|
||||||
|
module_manifest!();
|
||||||
|
|
||||||
|
pub fn main() {}
|
||||||
|
|
||||||
|
#[marine]
|
||||||
|
pub fn curl_request(cmd: Vec<String>) -> MountedBinaryResult {
|
||||||
|
curl(cmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[marine]
|
||||||
|
#[link(wasm_import_module = "host")]
|
||||||
|
extern "C" {
|
||||||
|
fn curl(cmd: Vec<String>) -> MountedBinaryResult;
|
||||||
|
}
|
16
aqua-examples/price-oracle/data/deployed_services.json
Normal file
16
aqua-examples/price-oracle/data/deployed_services.json
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"service": "price_getter",
|
||||||
|
"deployed": [
|
||||||
|
"12D3KooWCMr9mU894i8JXAFqpgoFtx6qnV1LFPSfVc3Y34N4h4LS",
|
||||||
|
"c315073d-4311-4db3-be57-8f154f032d28"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"service": "mean",
|
||||||
|
"deployed": [
|
||||||
|
"12D3KooWCMr9mU894i8JXAFqpgoFtx6qnV1LFPSfVc3Y34N4h4LS",
|
||||||
|
"dd47389f-25d9-4870-a2a9-909359e73580"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
22
aqua-examples/price-oracle/mean_service/Cargo.toml
Normal file
22
aqua-examples/price-oracle/mean_service/Cargo.toml
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
[package]
|
||||||
|
name = "price_getter_service"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["boneyard93501 <4523011+boneyard93501@users.noreply.github.com>"]
|
||||||
|
edition = "2018"
|
||||||
|
description = "price-getter-service, a Marine wasi module"
|
||||||
|
license = "Apache-2.0"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "mean_service"
|
||||||
|
path = "src/main.rs"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
marine-rs-sdk = "0.6.11"
|
||||||
|
log = "0.4.14"
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
marine-rs-sdk-test = "0.1.11"
|
||||||
|
|
||||||
|
[dev]
|
||||||
|
[profile.release]
|
||||||
|
opt-level = "s"
|
53
aqua-examples/price-oracle/mean_service/src/main.rs
Normal file
53
aqua-examples/price-oracle/mean_service/src/main.rs
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* 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};
|
||||||
|
|
||||||
|
module_manifest!();
|
||||||
|
|
||||||
|
fn main() {}
|
||||||
|
|
||||||
|
#[marine]
|
||||||
|
pub struct Result {
|
||||||
|
pub result: f64,
|
||||||
|
pub success: bool,
|
||||||
|
pub error_msg: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[marine]
|
||||||
|
pub fn mean(data: Vec<f64>) -> Result {
|
||||||
|
match calc_mean(data.iter()) {
|
||||||
|
Some(res) => Result {
|
||||||
|
result: res,
|
||||||
|
success: true,
|
||||||
|
error_msg: "".to_string(),
|
||||||
|
},
|
||||||
|
None => Result {
|
||||||
|
result: -1f64,
|
||||||
|
success: false,
|
||||||
|
error_msg: "Failure to calculate mean. Check your inputs.".to_string(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn calc_mean<'a>(data: impl ExactSizeIterator<Item = &'a f64>) -> Option<f64> {
|
||||||
|
let n = data.len() as u64;
|
||||||
|
if n < 1 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
let res = (data.sum::<f64>() / n as f64) as f64;
|
||||||
|
let res = format!("{:.2}", res).parse::<f64>().unwrap();
|
||||||
|
Some(res)
|
||||||
|
}
|
26
aqua-examples/price-oracle/price_getter_service/Cargo.toml
Normal file
26
aqua-examples/price-oracle/price_getter_service/Cargo.toml
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
[package]
|
||||||
|
name = "price_getter_service"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["boneyard93501 <4523011+boneyard93501@users.noreply.github.com>"]
|
||||||
|
edition = "2018"
|
||||||
|
description = "price-getter-service, a Marine wasi module"
|
||||||
|
license = "Apache-2.0"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "price_getter_service"
|
||||||
|
path = "src/main.rs"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
marine-rs-sdk = "0.6.11"
|
||||||
|
log = "0.4.14"
|
||||||
|
picorand = "0.1.1"
|
||||||
|
fstrings = "0.2.3"
|
||||||
|
hex = "0.4.3"
|
||||||
|
serde_json = "1.0.57"
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
marine-rs-sdk-test = "0.1.11"
|
||||||
|
|
||||||
|
[dev]
|
||||||
|
[profile.release]
|
||||||
|
opt-level = "s"
|
95
aqua-examples/price-oracle/price_getter_service/src/main.rs
Normal file
95
aqua-examples/price-oracle/price_getter_service/src/main.rs
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
/*
|
||||||
|
* 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 hex;
|
||||||
|
use marine_rs_sdk::{marine, module_manifest, MountedBinaryResult};
|
||||||
|
use picorand::{PicoRandGenerate, WyRand, RNG};
|
||||||
|
use serde_json;
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate fstrings;
|
||||||
|
|
||||||
|
module_manifest!();
|
||||||
|
|
||||||
|
pub fn main() {}
|
||||||
|
|
||||||
|
#[marine]
|
||||||
|
pub struct Result {
|
||||||
|
pub result: f64,
|
||||||
|
pub success: bool,
|
||||||
|
pub error_msg: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[marine]
|
||||||
|
pub fn price_getter(coin: String, currency: String, timestamp_ms: u64) -> Result {
|
||||||
|
let url =
|
||||||
|
f!("https://api.coingecko.com/api/v3/simple/price?ids={coin}&vs_currencies={currency}");
|
||||||
|
let curl_cmd = vec![
|
||||||
|
"-X".to_string(),
|
||||||
|
"GET".to_string(),
|
||||||
|
"-H".to_string(),
|
||||||
|
"Accept: application/json".to_string(),
|
||||||
|
url,
|
||||||
|
];
|
||||||
|
let response = curl_request(curl_cmd);
|
||||||
|
let result = String::from_utf8(response.stdout);
|
||||||
|
|
||||||
|
match result {
|
||||||
|
Ok(res) => {
|
||||||
|
let json_res = serde_json::from_str(&res.clone());
|
||||||
|
if json_res.is_err() {
|
||||||
|
return Result {
|
||||||
|
result: -1f64,
|
||||||
|
success: false,
|
||||||
|
error_msg: "Failure to complete call".to_string(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
let json_res: serde_json::Value = json_res.unwrap();
|
||||||
|
let value = json_res[coin.to_lowercase()][currency.to_lowercase()].as_f64();
|
||||||
|
if value.is_none() {
|
||||||
|
return Result {
|
||||||
|
result: -1f64,
|
||||||
|
success: false,
|
||||||
|
error_msg:
|
||||||
|
"No price value from source available. Check your coin and currency values."
|
||||||
|
.to_string(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
let value: f64 = value.unwrap();
|
||||||
|
|
||||||
|
let mut rng = RNG::<WyRand, u16>::new(timestamp_ms);
|
||||||
|
let multiplier = rng.generate_range(5, 20) as f64;
|
||||||
|
let rnd_value = value * (1f64 + multiplier / 100f64);
|
||||||
|
Result {
|
||||||
|
result: format!("{:.2}", rnd_value).parse::<f64>().unwrap(),
|
||||||
|
success: true,
|
||||||
|
error_msg: "".to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(_) => Result {
|
||||||
|
result: -1f64,
|
||||||
|
success: false,
|
||||||
|
error_msg: String::from_utf8(response.stderr).unwrap(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[marine]
|
||||||
|
#[link(wasm_import_module = "curl_adapter")]
|
||||||
|
extern "C" {
|
||||||
|
pub fn curl_request(cmd: Vec<String>) -> MountedBinaryResult;
|
||||||
|
}
|
24
aqua-examples/price-oracle/scripts/build.sh
Executable file
24
aqua-examples/price-oracle/scripts/build.sh
Executable file
@ -0,0 +1,24 @@
|
|||||||
|
#!/usr/bin/env bash -o errexit -o nounset -o pipefail
|
||||||
|
|
||||||
|
mkdir -p artifacts
|
||||||
|
|
||||||
|
cd curl_adapter
|
||||||
|
cargo update --aggressive
|
||||||
|
marine build --release
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
cd price_getter_service
|
||||||
|
cargo update --aggressive
|
||||||
|
marine build --release
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
cd mean_service
|
||||||
|
cargo update --aggressive
|
||||||
|
marine build --release
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
rm -f artifacts/*.wasm
|
||||||
|
|
||||||
|
cp curl_adapter/target/wasm32-wasi/release/curl_adapter.wasm artifacts/
|
||||||
|
cp price_getter_service/target/wasm32-wasi/release/price_getter_service.wasm artifacts/
|
||||||
|
cp mean_service/target/wasm32-wasi/release/mean_service.wasm artifacts/
|
Loading…
x
Reference in New Issue
Block a user