diff --git a/aqua-examples/near-integration/README.md b/aqua-examples/near-integration/README.md index 3d3ab70..f049815 100644 --- a/aqua-examples/near-integration/README.md +++ b/aqua-examples/near-integration/README.md @@ -1,7 +1,19 @@ # NEAR + Fluence + Aqua Integrations ## Overview -We provide integration examples for both a [Fluence JS](https://github.com/fluencelabs/fluence-js) node based on the [NEAR API JS](https://docs.near.org/docs/api/javascript-library) and distributed [Wasm services](https://github.com/fluencelabs/marine) wrapping the [NEAR RPC API](https://docs.near.org/docs/api/rpc). A [NEAR CLI](https://docs.near.org/docs/tools/near-cli) integration is planned for the near future. +We provide integration examples for both a [Fluence JS](https://github.com/fluencelabs/fluence-js) peer based on the [NEAR API JS](https://docs.near.org/docs/api/javascript-library) and distributed [Wasm services](https://github.com/fluencelabs/marine) wrapping the [NEAR RPC API](https://docs.near.org/docs/api/rpc). A [NEAR CLI](https://docs.near.org/docs/tools/near-cli) integration is planned for the near future. + +In our examples we've been using the [Aqua CLI](https://doc.fluence.dev/aqua-book/aqua-cli) `aqua` and [Marine tooling](https://doc.fluence.dev/marine-book/marine-tooling-reference) (the [Marine REPL](https://doc.fluence.dev/marine-book/marine-tooling-reference/marine-repl) `mrepl` and [Marine CLI](https://doc.fluence.dev/marine-book/marine-tooling-reference/marine-cli) `marine`). + +For the purpose of this tutorial, we'll be using Fluence's new `fluence` CLI tool, which wraps the CLIs you have already been using, e.g., the `aqua` CLI and Marine tooling CLIs (`marine` and `mrepl`), and brings additional features such as project template generation, wrapper generation for deployed services, project dependencies install. See the [Fluence CLI docs](https://github.com/fluencelabs/fluence-cli#readme) for more information. + +## Prerequisites + +Please make sure you have the latest Fluence CLI installed by running the following command: + +```bash +npm install -g @fluencelabs/cli +``` ## Fluence JS NEAR Signing Peer @@ -34,7 +46,7 @@ Note that we added additional parameters to our `sendMoney` implementation: *nea sendMoney(receiverId: string, amount: BN) ``` -Once we compile Aqua with the `npm run compile aqua` command, which writes the Typescript output into the `/src/_aqua` dir, we can then use the generated code, see `src/_aqua/near_signing_node.ts`, to implement our `sendMoney` service and any of ther other interfaces specified in Fluence JS, which essentially follows the [NEAR example](https://docs.near.org/docs/api/naj-quick-reference#send-tokens): +Once we compile Aqua with the `npm run compile aqua` command, which writes the Typescript output into the `/src/_aqua` dir, we can then use the generated code, see `src/_aqua/near_signing_node.ts`, to implement our `sendMoney` service and any of the other interfaces specified in Fluence JS, which essentially follows the [NEAR example](https://docs.near.org/docs/api/naj-quick-reference#send-tokens): ```typescript // index.ts @@ -45,15 +57,13 @@ async send_money(network_id: string, account_id: string, receiver_id: string, am const config = get_config(network_id, this._keyStore); const near = await network_connect(config); let account = await near.account(account_id); - let tx_receipt = await account.sendMoney(receiver_id, amount) - // return Promise.resolve(tx_receipt); + let tx_receipt = await account.sendMoney(receiver_id, amount); let result = Promise.resolve(tx_receipt); return result; } ``` - -Just like in the **quickstart example**, we implement the `send_money` method for the `class NearSigner implements NearSignerApiDef` class, where `NearSignerApiDef` is generated code from the Aqua compilation and which we register (as an exposed service) in `async main` like so: +We implement the `send_money` method for the `class NearSigner implements NearSignerApiDef` class, where `NearSignerApiDef` is generated code from the Aqua compilation and which we register (as an exposed service) in `async main` like so: ```typescript // index.ts @@ -63,7 +73,38 @@ async function main() { // ... ``` -For the complete implementation details, see `src/index.ts`. Before we test our code, please note that in this implementation the wallet credentials are presumed to be in the `~/.near-credentials` directory of the machine/system that runs the Fluence Signing Node. For *testnet* wallets, see https://wallet.testnet.near.org/ and https://docs.near.org/docs/develop/basics/create-account, to get started. +For the complete implementation details, see `src/index.ts`. Before we test our code, please note that in this implementation the wallet credentials are presumed to be in the `~/.near-credentials` directory of the machine/system that runs the Fluence Signing Node. + +For *testnet* wallets, see https://wallet.testnet.near.org/ and https://docs.near.org/docs/develop/basics/create-account, to get started. + +If you haven't setup Near locally, go to the [Near documentation](https://docs.near.org/tools/near-cli), install the `near` CLI as described in [its github repo](https://github.com/near/near-cli): + +``` +npm install -g near-cli +``` + +Login using the `near` CLI with the following command: + +``` +near login +``` + +You'll get the output: + +``` +Please authorize at least one account at the URL above. + +Which account did you authorize for use with NEAR CLI? +Enter it here (if not redirected automatically): +Logged in as [ .testnet ] with public key [ ed25519:.testnet.json +``` Note the implementations of `account_state` and `get_balance`, which follow the same implementation pattern discussed above but actually do not require account or wallet access. @@ -89,11 +130,13 @@ Which produces output similar to: ```bash > near-signing-node@0.1.0 compile-aqua -> aqua -i aqua/ -o src/_aqua +> fluence aqua -i aqua/ -o src/_aqua -2021.12.14 00:22:34 [INFO] Aqua Compiler 0.5.0-SNAPSHOT -2021.12.14 00:22:34 [INFO] Result /Users/bebo/localdev/examples/aqua-examples/near-integration/near-signing-node/src/_aqua/near_signing_node.ts: compilation OK (3 functions, 1 services) -2021.12.14 00:22:34 [INFO] Result /Users/bebo/localdev/examples/aqua-examples/near-integration/near-signing-node/src/_aqua/near_demo.ts: compilation OK (2 functions, 1 services) +Compiling +... done +2022.08.12 14:11:24:024 main INFO aqua.AquaCli.main:133 + Aqua Compiler 0.7.4-332 +Result /aqua-examples/near-integration/near-signing-node/src/_aqua/near_signing_node.ts: compilation OK (4 functions, 2 services) ``` You can check the generated Typescript and AIR code in the `src/_aqua` directory. With our setup complete, let's start the peer: @@ -109,7 +152,7 @@ Which produces output similar to: > near-signing-node@0.1.0 start > node -r ts-node/register src/index.ts -PeerId: 12D3KooWLCaFtoq9uu1jFg38uZXU4fNAkcL5X3xoQu6UqFxRFavU +PeerId: 12D3KooWRfvdqfDXw4yLnYLpHLrMm56M3G1nAbti4fDdEhgr5gp2 Relay id: 12D3KooWFEwNWcHqi9rtsmDhsYcDbRUCDXH84RC4FW6UfsFWaoHi ctrl-c to exit ``` @@ -117,148 +160,225 @@ ctrl-c to exit Please take note of the **relay id** and **peer id** for use in your client peer. In order to call the `account_state` method, open a new terminal window and navigate to the `~/examples/aqua-examples/near-integration/near-signing-node` directory and execute: ```bash -aqua run \ - -i aqua -a "/dns4/kras-04.fluence.dev/tcp/19001/wss/p2p/12D3KooWFEwNWcHqi9rtsmDhsYcDbRUCDXH84RC4FW6UfsFWaoHi" \ - -f 'account_state("testnet", "", "lame_password", "", "relay id")' +fluence run \ + -i aqua -f 'account_state("testnet", "", "lame_password", "", "")' ``` -*Replace* `` with your testnet account and `` and `` with the values provided by your peer output as discussed above. Once you've done that, the output should be similar to: +*Replace* `` with your Near testnet account and `` and `` with the values provided by your peer output as discussed above. Once you've done that, the output should be similar to: ```bash -Your peerId: 12D3KooWJYGtESBvtLiCyY1XUrXR5WYBtfAU697SqVnwi5XmqkqW -[ - { - "amount": "199998727964846286399080000", - "block_hash": "5Ves5ocsxmUSbsh6ZF5wutLiZSsPgm43H4H4zVDkacnA", - "block_height": 74936860, - "code_hash": "11111111111111111111111111111111", - "locked": "0", - "storage_paid_at": 0, - "storage_usage": 674 - } -] +Running: + function: account_state("testnet", "", "lame_password", "12D3KooWRfvdqfDXw4yLnYLpHLrMm56M3G1nAbti4fDdEhgr5gp2", "12D3KooWFEwNWcHqi9rtsmDhsYcDbRUCDXH84RC4FW6UfsFWaoHi") + relay: /dns4/kras-06.fluence.dev/tcp/19001/wss/p2p/12D3KooWDUszU2NeWyUVjCXhGEt1MoZrhvdmaQQwtZUriuGN1jTr +... done + +Result: + +{ + "amount": "199999827797124999999980000", + "block_hash": "6MKaFMkDMqcZrG8toTdAhoqLXrxMJL1JmHWQDnshcstF", + "block_height": 97232435, + "code_hash": "11111111111111111111111111111111", + "locked": "0", + "storage_paid_at": 0, + "storage_usage": 346 +} ``` +In the output above listed the called function (`account_state`) with its arguments as well as the relay used for the call. So, you can observe the context of the function call. And there's a result of the call, of course. In our case it displays [the basic information](https://docs.near.org/tools/near-api-js/account#state) for our Near account described in [AccountView Interface](https://near.github.io/near-api-js/interfaces/providers_provider.accountview.html). + Similarly, we can call our `send_money` service with Aqua: ```aqua - aqua run \ +fluence run \ -i aqua \ - -a "/dns4/kras-04.fluence.dev/tcp/19001/wss/p2p/12D3KooWFEwNWcHqi9rtsmDhsYcDbRUCDXH84RC4FW6UfsFWaoHi" \ - -f 'send_money("testnet", "", "", "10000", "lame_password", "", "")' + -f 'send_money("testnet", "", "", "10000", "lame_password", "", "")' + ``` -Replace the <`from`> and <`to`> account placeholders with your respective testnet wallets and the `peer id` and `relay id` with the values provided by your peer. Executing above Aqua statement produces a transaction receipt similar to the one below: +Replace the `near-from-account` and `near-to-account` account placeholders with your respective testnet wallets and the `your-peer-id` and `your-relay-id` with the values provided by your peer. Executing above Aqua statement produces a transaction receipt similar to the one below: ```bash +Running: + function: send_money("testnet", "", "", "10000", "lame_password", "12D3KooWRfvdqfDXw4yLnYLpHLrMm56M3G1nAbti4fDdEhgr5gp2", "12D3KooWFEwNWcHqi9rtsmDhsYcDbRUCDXH84RC4FW6UfsFWaoHi") + relay: /dns4/kras-03.fluence.dev/tcp/19001/wss/p2p/12D3KooWJd3HaMJ1rpLY1kQvcjRPEvnDwcXrH8mJvk7ypcZXqXGE +... done -Your peerId: 12D3KooWG8yhYea2x8LiWWruLqRyrbHNAyq6oAj5jkjDLZe21YK1 -[ - { - "receipts_outcome": [ - { - "block_hash": "7ZgHzMZsSirCxmJJ9tJJuHGjZBs1eG2tFWpYMBjYn9X1", - "id": "7viub5UekSHHYi8ovEt5TuQNgtqZSgPx6EgUutv5i561", - "outcome": { - "executor_id": "", - "gas_burnt": 223182562500, - "logs": [], - "metadata": { - "gas_profile": [], - "version": 1 - }, - "receipt_ids": [ - "E5ajp367DHvZcitj6eZ9nCE6rSYUmZi2njg9LnkdbZvM" - ], - "status": { - "SuccessValue": "" - }, - "tokens_burnt": "22318256250000000000" - }, - "proof": [ - { - "direction": "Right", - "hash": "AD7yhCufivqSZHRuTuqATFjjhkY9AiBHPGSqLvmADKJh" - }, - { - "direction": "Right", - "hash": "3fiJCKaok6BVoKMrgBHTedJWbeNU5nNJzpN82Kxjyw94" - } - ] - }, - { - "block_hash": "14EVqK6jpkKbkozEbdf5WrpxGAqzfq78kqj7Gv9smLBs", - "id": "E5ajp367DHvZcitj6eZ9nCE6rSYUmZi2njg9LnkdbZvM", - "outcome": { - "executor_id": "", - "gas_burnt": 223182562500, - "logs": [], - "metadata": { - "gas_profile": [], - "version": 1 - }, - "receipt_ids": [], - "status": { - "SuccessValue": "" - }, - "tokens_burnt": "0" - }, - "proof": [ - { - "direction": "Left", - "hash": "7cnaRc9PjGPHXd3fLngDQy8XQhmKtQXTPdrbq8Aas2Ti" - } - ] - } - ], - "status": { - "SuccessValue": "" - }, - "transaction": { - "actions": [ - { - "Transfer": { - "deposit": "10000" - } - } - ], - "hash": "3bmedi7erFPpwEWWgQHuMppoorvzed8x7w5mttofCVQw", - "nonce": 74253069000003, - "public_key": "ed25519:632DzcF3w7SLXJzDRcFdSHUBY2De8LECfJ9kCC4yERuj", - "receiver_id": "", - "signature": "ed25519:5zmMLczayMnnykBdn9MM3hUCWigZM5JgfAyT1E7mu7a4RNzPq9uahAKiGs1JWxNCor6zGHNbX8cpQYC59axxFtjR", - "signer_id": "" - }, - "transaction_outcome": { - "block_hash": "J4gEefXV6FM1crRxxQbHhhVWpuPdPHnEAx5Kb5coCDdj", - "id": "3bmedi7erFPpwEWWgQHuMppoorvzed8x7w5mttofCVQw", +Result: + +{ + "receipts_outcome": [ + { + "block_hash": "EzB5BiTVyqzJjqbTzRRKfQ2qWdj48F5vArVwtdwDmNaG", + "id": "FmhBQNgwtvaJUxTEbPhqfsUSjuwjcYw4iLsb1LLsKDDH", "outcome": { - "executor_id": "", + "executor_id": "", "gas_burnt": 223182562500, "logs": [], "metadata": { - "gas_profile": null, + "gas_profile": [], "version": 1 }, "receipt_ids": [ - "7viub5UekSHHYi8ovEt5TuQNgtqZSgPx6EgUutv5i561" + "9Q5mKcBgnoN1cM47nfwBRiN6vUoZa4vPhn6boyXZitNd" ], "status": { - "SuccessReceiptId": "7viub5UekSHHYi8ovEt5TuQNgtqZSgPx6EgUutv5i561" + "SuccessValue": "" }, "tokens_burnt": "22318256250000000000" }, + "proof": [ + { + "direction": "Left", + "hash": "EA96udAi8vcAdLHnbKPHTW4qKHnMXhJ4zjD4csETYk9r" + }, + { + "direction": "Right", + "hash": "CNtBo5A3Sma7RrK2J9ntTq7p3v7fxS8zYmdXYWDCfscT" + } + ] + }, + { + "block_hash": "4WX1AZ9VSJDzjv1j6uHqNcz4W7iqz6XyiCqj7wpGn6h1", + "id": "9Q5mKcBgnoN1cM47nfwBRiN6vUoZa4vPhn6boyXZitNd", + "outcome": { + "executor_id": "", + "gas_burnt": 223182562500, + "logs": [], + "metadata": { + "gas_profile": [], + "version": 1 + }, + "receipt_ids": [], + "status": { + "SuccessValue": "" + }, + "tokens_burnt": "0" + }, "proof": [] } + ], + "status": { + "SuccessValue": "" + }, + "transaction": { + "actions": [ + { + "Transfer": { + "deposit": "10000" + } + } + ], + "hash": "2cCxw5RGTqD9UCwqth3Pe3FhRcYkqRimnzyhYWCBKjjA", + "nonce": 96699860000005, + "public_key": "ed25519:82CcWWRM9scav5hbqUVL4JZsBwagqFvjZrLDbaoiE9pr", + "receiver_id": "", + "signature": "ed25519:2cmhrzp4PeKPcXE1vUW89krdTcdsApY3h6TT7CshWdrZMBLUjfJQF6pijzYcFUhpwArNQwDmD9GkVep9gYJTb4Hd", + "signer_id": "" + }, + "transaction_outcome": { + "block_hash": "DhS6KZzK9PdCqot2k4hewfAWkc7nQ9mnZM91XKZdVRkQ", + "id": "2cCxw5RGTqD9UCwqth3Pe3FhRcYkqRimnzyhYWCBKjjA", + "outcome": { + "executor_id": "", + "gas_burnt": 223182562500, + "logs": [], + "metadata": { + "gas_profile": null, + "version": 1 + }, + "receipt_ids": [ + "FmhBQNgwtvaJUxTEbPhqfsUSjuwjcYw4iLsb1LLsKDDH" + ], + "status": { + "SuccessReceiptId": "FmhBQNgwtvaJUxTEbPhqfsUSjuwjcYw4iLsb1LLsKDDH" + }, + "tokens_burnt": "22318256250000000000" + }, + "proof": [] } -] +} ``` -You can use the [Testnet Explorer](https://explorer.near.org/) to further investigate the token transfer you just executed. +It's rather convenient to call the `account_state` and `send_money` functions. However, there's still a couple of things we need to remember and use such as `` and ``. As a matter of fact we can simplify a method call, and `--json-service` param of the `fluence` CLI comes in handy. + +Upon the Near signing node start, it creates a JSON file with its peer id and relay id information we can use with the `fluence` CLI and in our Aqua code. + +The `js-services.json` looks like: + +```json +{ + "name": "JsService", + "serviceId": "JsService", + "functions": [ + { + "name": "get", + "result": { + "peerId": "12D3KooWRfvdqfDXw4yLnYLpHLrMm56M3G1nAbti4fDdEhgr5gp2", + "relayPeerId": "12D3KooWFEwNWcHqi9rtsmDhsYcDbRUCDXH84RC4FW6UfsFWaoHi" + } + } + ] +} +``` + +And the corresponding Aqua code for `transfer_money` looks slightly different: instead of using the function signature to pass the `node` and `relay` arguments, we're now injecting the values with `JsService.get()` into the function body: + +```aqua +-- near_signing_node.aqua +func transfer_money(network_id:string, account_id:string, receiver_id:string, amount:string, password: string) -> string: + services <- JsService.get() -- step 1 + on services.peerId via services.relayPeerId: -- step 2 + res <- NearSignerApi.send_money(network_id, account_id, receiver_id, amount, password) -- step 3 + <- res +``` + +On the step 1 using the defined function `get()` of the `JsService` service we get the information about our service (its peer id and relay id) which is wrapped in the `Services` data structure. On step 2 we specify, that the next block should be executed on our JS peer with the id we got on the 1st step (so we extract it using `services.peerId`) which we connect to thru a relay with the `services.relayPeerId` relay id. On the 3rd step we call the Near API service wrapper using `NearSignerApi.send_money` to call the corresponding NEAR API function `sendMoney`. + +Those parameters values we injected in the function body are available thru the `js-services.json` and the following definitions in our Aqua code: + +```aqua +-- near_signing_node.aqua +data Services: + peerId: string + relayPeerId: string + +service JsService("JsService"): + get: -> Services +``` + +Considering all the above, the `transfer_money` call looks like: + +```bash +fluence run \ + -i aqua \ + -f 'transfer_money("testnet", "", "", "10000", "lame_password")' --json-service js-services.json +``` + +The similar approach can be used for the `account_state` with its updated implementation `account_state_view`: + +```aqua +-- near_signing_node.aqua +func account_state_view(network_id:string, account_id:string, password: string) -> string: + services <- JsService.get() + on services.peerId via services.relayPeerId: + res <- NearSignerApi.account_state(network_id, account_id, password) + <- res +``` + +And we can call the `account_state_view` in a similar fashion as we've done for the `transfer_money`: + +```bash +fluence run \ + -i aqua \ + -f 'account_state_view("testnet", "", "lame_password")' --json-service js-services.json +``` + +You can use the [Testnet Explorer](https://explorer.near.org/) to further investigate the token transfer you executed. ### Summary -In this section, we implemented a basic Fluence peer that outlines an approach to shield our NEAR wallet keys from other network participants and to implement singing related functionality, such as the `send_money` token transfer method. Additional methods, such as the more generic `sign transaction` and `deploy contract` can be easily implemented this way and we are looking forward to your pull requests. Also note, that our simple string return can be vastly improved by adding the appropriate *interfaces*. +In this section, we implemented a basic Fluence peer that outlines an approach to shield our NEAR wallet keys from other network participants and to implement singing related functionality, such as the `transfer_money` token transfer method. Additional methods, such as the more generic `sign transaction` and `deploy contract` can be easily implemented this way and we are looking forward to your pull requests. Also note, that our simple string return can be vastly improved by adding the appropriate *interfaces*. In the next section, we briefly discuss how a variety of NEAR methods can be implemented as distributed, hosted services for easy deployment, re-use and scalability. @@ -270,7 +390,7 @@ In order to create a NEAR Wasm adapter, we wrap whatever functionality we need f ### Creating And Deploying NEAR Wasm Services -In the `services` directory, you find a minimal Wasm adapter for [NEAR RPC API](https://docs.near.org/docs/api/rpc) to get you started. Since we are connecting to on-chain resources via JSON-RPC, we need our service module to have access to [cUrl](https://doc.fluence.dev/docs/tutorials_tutorials/curl-as-a-service), which we provide with the [cUrl adapter](../near-integration/services/curl-adapter/): +In the `services/near-adapter/modules` directory, you find a minimal WASM adapter `near-rpc-services` for [NEAR RPC API](https://docs.near.org/docs/api/rpc) to get you started. Since we are connecting to on-chain resources via JSON-RPC, we need our service module to have access to [cUrl](https://doc.fluence.dev/docs/tutorials_tutorials/curl-as-a-service), which we provide with the [cUrl adapter](../near-integration/services/near-adapter/modules/curl-adapter/): ```rust // src/main.rs @@ -308,23 +428,26 @@ pub fn node_status(network_id: String) -> Result { Note that we use the `Result` struct to capture the curl response. -Assuming you compiled the code with `./scripts/build.sh`, we can interact with the `node_status` in `mrepl`. Open the REPL with `mrepl configs/Config.toml` and: +We can interact with the `node_status` in REPL. Please make sure you are in the `near-integration/services` directory. Open the REPL with `fluence service repl nearAdapter` and get the following output: ```bash -mrepl configs/Config.toml -Welcome to the Marine REPL (version 0.9.1) +fluence service repl nearAdapter +Making sure service and modules are downloaded and built... done +Welcome to the Marine REPL (version 0.18.0) Minimal supported versions sdk: 0.6.0 interface-types: 0.20.0 -app service was created with service id = e9ecced7-521c-4dd7-b205-61c8da3be0da -elapsed time 91.995618ms +app service was created with service id = e5ae9c3e-60f8-4ae7-b434-6f8085246c1d +elapsed time 326.464043ms 1> call near_rpc_services node_status ["testnet"] -result: Object({"stderr": String(" % Total % Received % Xferd Average Speed Time Time Time Current\n Dload Upload Total Spent Left Speed\n\r 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0\r100 68 0 0 100 68 0 110 --:--:-- --:--:-- --:--:-- 110\r100 5384 100 5316 100 68 8091 103 --:--:-- --:--:-- --:--:-- 8182\n"), "stdout": String("{\"jsonrpc\":\"2.0\",\"result\":{\"version\":{\"version\":\"1.23.0-rc.1\",\"build\":\"crates-0.10.0-70-g93e8521c9\"},\"chain_id\":\"testnet\",\"protocol_version\":49,\"latest_protocol_version\":49, - -\"latest_state_root\":\"CfxNRB5SNAiCmsMLbyAi7LD6YRVak7BH8REbumeg5GvD\",\"latest_block_time\":\"2021-12-08T09:20:24.293798434Z\",\"syncing\":false,\"earliest_block_hash\":\"CTBCW2Xm1xHeVKs3R5ZSULmVPc8Gj5tVVmH6HDrwRAeF\",\"earliest_block_height\":74004638,\"earliest_block_time\":\"2021-12-06T08:48:52.331327624Z\"},\"validator_account_id\":null},\"id\":\"dontcare\"}")}) - elapsed time: 666.350943ms +result: Object({"stderr": String(""), "stdout": String("{\"jsonrpc\":\"2.0\",\"result\":{\"chain_id\":\"testnet\",\"latest_protocol_version\":55,\"protocol_version\":54,\"rpc_addr\":\"0.0.0.0:4040\",\"sync_info\":{\"earliest_block_hash\":\"87rXaRN96eVGijmoxXMvKm9XAas1RedpHgh5ifaMfQne\",\"earliest_block_height\":96939089,\"earliest_block_time\":\"2022-08-07T05:20:29.139629926Z\",\"epoch_id\":\"9fvV3KdWb71CtFj6shiFrAgBfq4Zqk16reWBXSGRhgZy\",\"epoch_start_height\":97111890,\"latest_block_hash\":\"Dn6Q8cPogGmGj3m15t2e1c6hgbrBpmd8yrjegX5GU2Nb\",\"latest_block_height\":97136216,\"latest_block_time\":\"2022-08-09T10:12:28.971640387Z\",\"latest_state_root\":\"HBRDv6dEYwv1WEiwTDwPHzXBLmFG5c19YVqHGADH5gM7\",\"syncing\":false},\"validator_account_id\":null,\"validators\":[{\"account_id\":\"legends.pool.f863973.m0\",\"is_slashed\":false}, +... +... +... +{\"account_id\":\"kuutamo.pool.f863973.m0\",\"is_slashed\":false},{\"account_id\":\"gargoyle.pool.f863973.m0\",\"is_slashed\":false}],\"version\":{\"build\":\"crates-0.14.0-148-g5228fb106\",\"rustc_version\":\"1.61.0\",\"version\":\"1.28.0-rc.3\"}},\"id\":\"dontcare\"}")}) + elapsed time: 539.529855ms 2> ... @@ -338,13 +461,13 @@ data Result: stderr: string stdout: string -service RPCService: - node_status(network_id: string, block_ref:string) -> Result +service NearRpcServices: + node_status(network_id: string) -> Result -func rpc_foo(network_id: string, block_ref:string, node_string, service_id: string ) -> string: +func rpc_foo(network_id: string, node: string, service_id: string) -> string: on node: - RPCService service_id - res <- RPCService.node_status(network_id, block_ref) + NearRpcServices service_id + res <- NearRpcServices.node_status(network_id) if res.stderr: result <<- "call failed" else: @@ -352,66 +475,84 @@ func rpc_foo(network_id: string, block_ref:string, node_string, service_id: stri <- result ``` -Before we can use our Fluence NEAR adapter, we need to deploy our Wasm modules to one or more host peers. We can do that with [Aqua CLI](https://doc.fluence.dev/aqua-book/aqua-cli): +Before we can use our Fluence NEAR adapter, we need to deploy our Wasm modules to one or more host peers. We can do that with [Fluence CLI](https://github.com/fluencelabs/fluence-cli#fluence-deploy): ```bash -aqua remote deploy_service \ - --addr /dns4/kras-04.fluence.dev/tcp/19001/wss/p2p/12D3KooWFEwNWcHqi9rtsmDhsYcDbRUCDXH84RC4FW6UfsFWaoHi \ - --config-path configs/near_deploy_cfg.json \ - --service near-adapter +fluence deploy ``` -Which gives us the deployment information: +The `fluence` CLI will make sure that all required services and modules are in place, can be either downloaded or built. It gives us the deployment confirmation: ```bash -Your peerId: 12D3KooWNg9YAJWzSRC5Wt2U38beXWAZQfZc2xxqVLVogRkSYKiv -"Going to upload a module..." -2022.02.07 01:58:44 [INFO] created ipfs client to /ip4/164.90.164.229/tcp/5001 -2022.02.07 01:58:44 [INFO] connected to ipfs -2022.02.07 01:58:45 [INFO] file uploaded -"Going to upload a module..." -2022.02.07 01:58:45 [INFO] created ipfs client to /ip4/164.90.164.229/tcp/5001 -2022.02.07 01:58:46 [INFO] connected to ipfs -2022.02.07 01:58:49 [INFO] file uploaded -"Now time to make a blueprint..." -"Blueprint id:" -"24b026f9b1b3f189d7998f875c0eb0c3394e546ee248ea292a27a555d3643774" -"And your service id is:" -"b39eb93d-0e7b-478c-976f-2e5b05ec02fb" +Making sure all services are downloaded... done +Making sure all modules are downloaded and built... done + +Going to deploy services described in /examples/aqua-examples/near-integration/services/fluence.yaml: + +nearAdapter: + get: ./near-adapter + deploy: + - deployId: default + + +? Do you want to deploy all of these services? Yes +Deploying: + service: nearAdapter + deployId: default + on: 12D3KooWCMr9mU894i8JXAFqpgoFtx6qnV1LFPSfVc3Y34N4h4LS +... done +Compiling /examples/aqua-examples/near-integration/services/.fluence/aqua/deployed.app.aqua... done + +Currently deployed services listed in /examples/aqua-examples/near-integration/services/.fluence/app.yaml: + +nearAdapter: + default: + - blueprintId: ef2c354407c29317657c47403630a0217601934f4ceda58b7642ef8985a983df + serviceId: 5bc6970c-1f7a-4e24-bc93-519dd4c40daf + peerId: 12D3KooWCMr9mU894i8JXAFqpgoFtx6qnV1LFPSfVc3Y34N4h4LS + ``` -Please note the node id, "12D3KooWFEwNWcHqi9rtsmDhsYcDbRUCDXH84RC4FW6UfsFWaoHi", and service id "b39eb93d-0e7b-478c-976f-2e5b05ec02fb" for future use in our Aqua. Let's have a look at our aqua script in 'aqua/near_adapter_demo.aqua`: +Please note the helper generated in Aqua by the CLI in the `.fluence/aqua/deployed.app.aqua` file for future use in our Aqua. Let's have a look at our Aqua script in `./src/aqua/main.aqua`: ```aqua --- aqua/near_adapter_demo_aqua -func node_status(network_id: string, node: string, service_id: string) -> Result: - on node: - NearRpcServices service_id +-- aqua/main.aqua +func node_report(network_id: string) -> Result: + services <- App.services() + on services.nearAdapter.default!.peerId: + NearRpcServices services.nearAdapter.default!.serviceId res <- NearRpcServices.node_status(network_id) <- res ``` -Which we can run with the `aqua cli`: +Which we can run with the `fluence` CLI: ```bash -aqua run \ - -i aqua/near_adapter_demo.aqua \ - -a /dns4/kras-04.fluence.dev/tcp/19001/wss/p2p/12D3KooWFEwNWcHqi9rtsmDhsYcDbRUCDXH84RC4FW6UfsFWaoHi \ - -f 'node_status("testnet", "12D3KooWFEwNWcHqi9rtsmDhsYcDbRUCDXH84RC4FW6UfsFWaoHi", "b39eb93d-0e7b-478c-976f-2e5b05ec02fb")' +fluence run -f 'node_report("testnet")' ``` Which results in the following output: ```bash -Your peerId: 12D3KooWMWt2xWsqZxF3sEcBajsDRVARziKdyqkCoDXKeqYMnawm +Running: + function: node_report("testnet") + relay: /dns4/kras-02.fluence.dev/tcp/19001/wss/p2p/12D3KooWHLxVhUQyAuZe6AHMB29P7wkvTNMn7eDMcsqimJYLKREf +... done + +Result: + { "stderr": "", - "stdout": "{\"jsonrpc\":\"2.0\",\"result\":{\"version\":{\"version\":\"1.24.0-rc.2\",\"build\":\"crates-0.11.0-72-g6c5199f3b\"},\"chain_id\":\"testnet\",\"protocol_version\":51,\"latest_protocol_version\":51,\"rpc_addr\":\"0.0.0.0:4040\",\"validators\":[{\"account_id\":\"node1\",\"is_slashed\":false},{\"account_id\":\"node0\",\"is_slashed\":false},{\"account_id\":\"node2\",\"is_slashed\":false},{\"account_id\":\"node3\",\"is_slashed\":false},{\"account_id\":\"staked.pool.f863973.m0\",\"is_slashed\":false},{\"account_id\":\"masternode24.pool.f863973.m0\",\"is_slashed\":false},{\"account_id\":\"01node.pool.f863973.m0\",\"is_slashed\":false},{\"account_id\":\"p2p.pool.f863973.m0\",\"is_slashed\":false},{\"account_id\":\"legends. - \"latest_block_height\":81641688,\"latest_state_root\":\"4yNrvAWtpEEAzCigEsYLriY4KG9gECDebrUk3b8EBAk1\",\"latest_block_time\":\"2022-02-07T08:02:25.995190071Z\",\"syncing\":false,\"earliest_block_hash\":\"H3nLmP5PPLSCX863ipiMSRZaBAsBKhXUkAsSzuaBJJYJ\",\"earliest_block_height\":81395663,\"earliest_block_time\":\"2022-02-05T08:47:02.279368896Z\"},\"validator_account_id\":null},\"id\":\"dontcare\"}" + "stdout": "{\"jsonrpc\":\"2.0\",\"result\":{\"chain_id\":\"testnet\",\"latest_protocol_version\":55,\"protocol_version\":54,\"rpc_addr\":\"0.0.0.0:4040\",\"sync_info\":{\"earliest_block_hash\":\"87rXaRN96eVGijmoxXMvKm9XAas1RedpHgh5ifaMfQne\",\"earliest_block_height\":96939089,\"earliest_block_time\":\"2022-08-07T05:20:29.139629926Z\",\"epoch_id\":\"9fvV3KdWb71CtFj6shiFrAgBfq4Zqk16reWBXSGRhgZy\",\"epoch_start_height\":97111890,\"latest_block_hash\":\"2DcwXKkZf175VExkDpryH73p99rHQjdu54u4Y5vfambK\",\"latest_block_height\":97136905,\"latest_block_time\":\"2022-08-09T10:30:51.592058687Z\",\"latest_state_root\":\"AmXivm3DbmRqU9fYQe6tDuC3ujz2UbdeYNeLmSRrxzsZ\",\"syncing\":false},\"validator_account_id\":null,\"validators\":[{\"account_id\":\"legends.pool.f863973.m0\",\"is_slashed\":false}, + ... + ... + ... + {\"account_id\":\"stakingfacilities.pool.f863973.m0\",\"is_slashed\":false},{\"account_id\":\"kuutamo.pool.f863973.m0\",\"is_slashed\":false},{\"account_id\":\"gargoyle.pool.f863973.m0\",\"is_slashed\":false}],\"version\":{\"build\":\"crates-0.14.0-148-g5228fb106\",\"rustc_version\":\"1.61.0\",\"version\":\"1.28.0-rc.3\"}},\"id\":\"dontcare\"}" } + ``` -Give the already implemented `view_account` and `tx_status` functions a try or add more methods from the RPC API -- we are looking forward to your pull requests. +Give the already implemented `view_account_report` and `tx_status_report` functions a try or add more methods from the RPC API -- we are looking forward to your pull requests. ### Summary diff --git a/aqua-examples/near-integration/near-signing-node/.gitignore b/aqua-examples/near-integration/near-signing-node/.gitignore index 893da1f..05cd771 100644 --- a/aqua-examples/near-integration/near-signing-node/.gitignore +++ b/aqua-examples/near-integration/near-signing-node/.gitignore @@ -47,4 +47,10 @@ package-lock.json # fluence -src/_aqua/* \ No newline at end of file +src/_aqua/* +# recommended by Fluence Labs: +.fluence +**/node_modules +**/target/ +.vscode/settings.json +.repl_history diff --git a/aqua-examples/near-integration/near-signing-node/aqua/near_signing_node.aqua b/aqua-examples/near-integration/near-signing-node/aqua/near_signing_node.aqua index 398d382..5a4be8a 100644 --- a/aqua-examples/near-integration/near-signing-node/aqua/near_signing_node.aqua +++ b/aqua-examples/near-integration/near-signing-node/aqua/near_signing_node.aqua @@ -1,3 +1,14 @@ +module Main + +export account_state, send_money, NearSignerApi, account_state_view, transfer_money, JsService + +data Services: + peerId: string + relayPeerId: string + +service JsService("JsService"): + get: -> Services + data AccountState: amount: string block_hash: string @@ -12,11 +23,23 @@ service NearSignerApi("near"): send_money(network_id: string, account_id: string, receiver_id:string, amount:string, password: string) -> string get_balance(network_id: string, account_id: string, password: string) -> string +func account_state_view(network_id:string, account_id:string, password: string) -> string: + services <- JsService.get() + on services.peerId via services.relayPeerId: + res <- NearSignerApi.account_state(network_id, account_id, password) + <- res + func account_state(network_id:string, account_id:string, password: string, node:string, relay:string) -> string: on node via relay: res <- NearSignerApi.account_state(network_id, account_id, password) <- res +func transfer_money(network_id:string, account_id:string, receiver_id:string, amount:string, password: string) -> string: + services <- JsService.get() + on services.peerId via services.relayPeerId: + res <- NearSignerApi.send_money(network_id, account_id, receiver_id, amount, password) + <- res + func send_money(network_id:string, account_id:string, receiver_id:string, amount:string, password: string, node:string, relay:string) -> string: on node via relay: res <- NearSignerApi.send_money(network_id, account_id, receiver_id, amount, password) diff --git a/aqua-examples/near-integration/near-signing-node/fluence.yaml b/aqua-examples/near-integration/near-signing-node/fluence.yaml new file mode 100644 index 0000000..6e6603e --- /dev/null +++ b/aqua-examples/near-integration/near-signing-node/fluence.yaml @@ -0,0 +1,23 @@ +# yaml-language-server: $schema=.fluence/schemas/fluence.yaml.json + +# EXAMPLES: +# services: +# someService: # Service name. It must start with a lowercase letter and contain only letters, numbers, and underscores. +# get: https://github.com/fluencelabs/services/blob/master/adder.tar.gz?raw=true # URL or path +# deploy: +# - deployId: default # must start with a lowercase letter and contain only letters, numbers, and underscores. +# # Used in aqua to access deployed service ids +# # You can access deployment info in aqua like this: +# # services <- App.services() +# # on services.someService.default!.peerId: +# peerId: MY_PEER # Peer id or peer id name to deploy on. Default: Random peer id is selected for each deploy +# count: 1 # How many times to deploy. Default: 1 +# # overrideModules: # Override modules from service.yaml +# # facade: +# # get: ./relative/path # Override facade module +# peerIds: # A map of named peerIds. Optional. +# MY_PEER: 12D3KooWCMr9mU894i8JXAFqpgoFtx6qnV1LFPSfVc3Y34N4h4LS +# relays: kras # Array of relay multi-addresses or keywords: kras, testnet, stage. Default: kras + +version: 1 + diff --git a/aqua-examples/near-integration/near-signing-node/package.json b/aqua-examples/near-integration/near-signing-node/package.json index 83880f1..387230c 100644 --- a/aqua-examples/near-integration/near-signing-node/package.json +++ b/aqua-examples/near-integration/near-signing-node/package.json @@ -5,7 +5,7 @@ "main": "index.js", "scripts": { "start": "node -r ts-node/register src/index.ts", - "compile-aqua": "aqua -i aqua/ -o src/_aqua", + "compile-aqua": "fluence aqua -i aqua/ -o src/_aqua", "watch-aqua": "chokidar \"**/*.aqua\" -c \"npm run compile-aqua\"" }, "author": "", diff --git a/aqua-examples/near-integration/near-signing-node/src/index.ts b/aqua-examples/near-integration/near-signing-node/src/index.ts index 880d69c..9c7d4eb 100644 --- a/aqua-examples/near-integration/near-signing-node/src/index.ts +++ b/aqua-examples/near-integration/near-signing-node/src/index.ts @@ -35,8 +35,7 @@ class NearSigner implements NearSignerApiDef { const config = get_config(network_id, this._keyStore); const near = await network_connect(config); let account = await near.account(account_id); - let tx_receipt = await account.sendMoney(receiver_id, amount) - // return Promise.resolve(tx_receipt); + let tx_receipt = await account.sendMoney(receiver_id, amount); let result = Promise.resolve(tx_receipt); return result; } @@ -128,11 +127,37 @@ async function main() { KeyPair: await FluenceKeyPair.fromEd25519SK(SeedArray) }); - console.log("PeerId: ", Fluence.getStatus().peerId); - console.log("Relay id: ", Fluence.getStatus().relayPeerId); + const peerId = Fluence.getStatus().peerId; + const relayPeerId = Fluence.getStatus().relayPeerId; + console.log("PeerId: ", peerId); + console.log("Relay id: ", relayPeerId); registerNearSignerApi("near", new NearSigner()); + const jsonServices = JSON.stringify( + { + name: "JsService", + serviceId: "JsService", + functions: [ + { + name: "get", + result: { + peerId, + relayPeerId + }, + }, + ], + }, + null, + 2 + ) + // console.log("js-service.json: ", jsonServices) + var fs = require('fs'); + fs.writeFileSync("js-services.json", jsonServices, function(err: any) { + console.log("Error occured while writing the JSON Object to the file."); + return console.log(err); + } + ); console.log("ctrl-c to exit"); // await Fluence.stop(); diff --git a/aqua-examples/near-integration/services/.gitignore b/aqua-examples/near-integration/services/.gitignore new file mode 100644 index 0000000..9fcf45a --- /dev/null +++ b/aqua-examples/near-integration/services/.gitignore @@ -0,0 +1,7 @@ +.idea +.DS_Store +.fluence +**/node_modules +**/target/ +.vscode/settings.json +.repl_history \ No newline at end of file diff --git a/aqua-examples/near-integration/services/configs/curl_adapter_cfg.json b/aqua-examples/near-integration/services/configs/curl_adapter_cfg.json deleted file mode 100644 index ff99bf7..0000000 --- a/aqua-examples/near-integration/services/configs/curl_adapter_cfg.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "curl_adapter", - "mountedBinaries": { - "curl": "/usr/bin/curl" - }, - "mem_page_count": 10, - "logger_enabled": false -} diff --git a/aqua-examples/near-integration/services/configs/near_deploy_cfg.json b/aqua-examples/near-integration/services/configs/near_deploy_cfg.json deleted file mode 100644 index 8a1f7aa..0000000 --- a/aqua-examples/near-integration/services/configs/near_deploy_cfg.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "near-adapter": { - "name": "near-adapter", - "modules": [ - { - "name": "curl_adapter", - "path": "./artifacts/curl_adapter.wasm", - "mounted_binaries": [["curl", "/usr/bin/curl"]], - "logger_enabled": true - }, - { - "name": "near_rpc_services", - "path": "./artifacts/near_rpc_services.wasm", - "logger_enabled": true - } - ] - } -} diff --git a/aqua-examples/near-integration/services/configs/near_rpc_services_cfg.json b/aqua-examples/near-integration/services/configs/near_rpc_services_cfg.json deleted file mode 100644 index 05e2c64..0000000 --- a/aqua-examples/near-integration/services/configs/near_rpc_services_cfg.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "near_rpc_services", - "mem_page_count": 10, - "logger_enabled": true -} diff --git a/aqua-examples/near-integration/services/fluence.yaml b/aqua-examples/near-integration/services/fluence.yaml new file mode 100644 index 0000000..a48e88f --- /dev/null +++ b/aqua-examples/near-integration/services/fluence.yaml @@ -0,0 +1,26 @@ +# yaml-language-server: $schema=.fluence/schemas/fluence.yaml.json + +# EXAMPLES: +# services: +# someService: # Service name in camelCase +# get: https://github.com/fluencelabs/services/blob/master/adder.tar.gz?raw=true # URL or path +# deploy: +# - deployId: default # any unique string in camelCase. Used in aqua to access deployed service ids +# # You can access deployment info in aqua like this: +# # services <- App.services() +# # on services.someService.default!.peerId: +# peerId: MY_PEER # Peer id or peer id name to deploy on. Default: Random peer id is selected for each deploy +# count: 1 # How many times to deploy. Default: 1 +# # overrideModules: # Override modules from service.yaml +# # facade: +# # get: ./relative/path # Override facade module +# peerIds: # A map of named peerIds. Optional. +# MY_PEER: 12D3KooWCMr9mU894i8JXAFqpgoFtx6qnV1LFPSfVc3Y34N4h4LS +# relays: kras # Array of relay multi-addresses or keywords: kras, testnet, stage. Default: kras + +version: 1 +services: + nearAdapter: + get: ./near-adapter + deploy: + - deployId: default diff --git a/aqua-examples/near-integration/services/configs/Config.toml b/aqua-examples/near-integration/services/near-adapter/Config.toml similarity index 100% rename from aqua-examples/near-integration/services/configs/Config.toml rename to aqua-examples/near-integration/services/near-adapter/Config.toml diff --git a/aqua-examples/near-integration/services/near-adapter/modules/curl-adapter/.gitignore b/aqua-examples/near-integration/services/near-adapter/modules/curl-adapter/.gitignore new file mode 100644 index 0000000..dbb360f --- /dev/null +++ b/aqua-examples/near-integration/services/near-adapter/modules/curl-adapter/.gitignore @@ -0,0 +1,14 @@ +target/ +**/*.rs.bk +.idea + +# MacOS misc file +*.DS_Store + +# Wasm files +*.wasm +*.wat + +# REPL history files +*.repl_history + diff --git a/aqua-examples/near-integration/services/curl-adapter/Cargo.toml b/aqua-examples/near-integration/services/near-adapter/modules/curl-adapter/Cargo.toml similarity index 100% rename from aqua-examples/near-integration/services/curl-adapter/Cargo.toml rename to aqua-examples/near-integration/services/near-adapter/modules/curl-adapter/Cargo.toml diff --git a/aqua-examples/near-integration/services/near-adapter/modules/curl-adapter/Config.toml b/aqua-examples/near-integration/services/near-adapter/modules/curl-adapter/Config.toml new file mode 100644 index 0000000..166d476 --- /dev/null +++ b/aqua-examples/near-integration/services/near-adapter/modules/curl-adapter/Config.toml @@ -0,0 +1,4 @@ +modules_dir = "artifacts/" + +[[module]] + name = "curl_adapter" diff --git a/aqua-examples/near-integration/services/near-adapter/modules/curl-adapter/README.md b/aqua-examples/near-integration/services/near-adapter/modules/curl-adapter/README.md new file mode 100644 index 0000000..8e6f025 --- /dev/null +++ b/aqua-examples/near-integration/services/near-adapter/modules/curl-adapter/README.md @@ -0,0 +1,18 @@ +# Marine Starter Template + +Get started quickly with your Wasm project with this template. +To use this template you should have the following components available: + +* Rust [installation instructions](https://www.rust-lang.org/tools/install) +* cargo generate [installation instructions](https://github.com/cargo-generate/cargo-generate#installation) +* Marine [installation instructions](https://github.com/cargo-generate/cargo-generate#installation) + +Use the template with `cargo generate`: + +```bash +cargo generate --git https://github.com/fluencelabs/marine-template +``` + +Which will prompt you for the project name and then generate the project, which will be your directory name. `cd` into your new directory and run `./build.sh` to compile the supplied __greeting__ function to a Wasm file ready for Marine. + +Check out the [Fluence documentation](https://doc.fluence.dev/docs/) for more details on Marine and Aqua. diff --git a/aqua-examples/near-integration/services/near-adapter/modules/curl-adapter/module.yaml b/aqua-examples/near-integration/services/near-adapter/modules/curl-adapter/module.yaml new file mode 100644 index 0000000..5e7da74 --- /dev/null +++ b/aqua-examples/near-integration/services/near-adapter/modules/curl-adapter/module.yaml @@ -0,0 +1,33 @@ +# yaml-language-server: $schema=../../../.fluence/schemas/module.yaml.json + +# EXAMPLES: +# name: facade +# type: rust # use this for modules written in rust and expected to be built with marine +# maxHeapSize: "100" # 100 bytes +# # maxHeapSize: 100K # 100 kilobytes +# # maxHeapSize: 100 Ki # 100 kibibytes +# # Max size of the heap that a module can allocate in format: +# # where ? is an optional field and specificator is one from the following (case-insensitive): +# # K, Kb - kilobyte; Ki, KiB - kibibyte; M, Mb - megabyte; Mi, MiB - mebibyte; G, Gb - gigabyte; Gi, GiB - gibibyte; +# # Current limit is 4 GiB +# loggerEnabled: true # true, if it allows module to use the Marine SDK logger. +# loggingMask: 0 # manages the logging targets, described in here: https://doc.fluence.dev/marine-book/marine-rust-sdk/developing/logging#using-target-map +# mountedBinaries: +# curl: /usr/bin/curl # a map of mounted binary executable files +# preopenedFiles: # a list of files and directories that this module could access with WASI +# - ./dir +# volumes: # a map of accessible files and their aliases. +# # Aliases should be normally used in Marine module development because it's hard to know the full path to a file. +# aliasForSomePath: ./some/path +# envs: # 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 +# ENV1: arg1 +# ENV2: arg2 + +version: 0 +type: rust +name: curl_adapter +mountedBinaries: + curl: /usr/bin/curl # a map of mounted binary executable files +loggerEnabled: true +maxHeapSize: 640K diff --git a/aqua-examples/near-integration/services/curl-adapter/src/main.rs b/aqua-examples/near-integration/services/near-adapter/modules/curl-adapter/src/main.rs similarity index 100% rename from aqua-examples/near-integration/services/curl-adapter/src/main.rs rename to aqua-examples/near-integration/services/near-adapter/modules/curl-adapter/src/main.rs diff --git a/aqua-examples/near-integration/services/near-adapter/modules/near-rpc-services/.gitignore b/aqua-examples/near-integration/services/near-adapter/modules/near-rpc-services/.gitignore new file mode 100644 index 0000000..dbb360f --- /dev/null +++ b/aqua-examples/near-integration/services/near-adapter/modules/near-rpc-services/.gitignore @@ -0,0 +1,14 @@ +target/ +**/*.rs.bk +.idea + +# MacOS misc file +*.DS_Store + +# Wasm files +*.wasm +*.wat + +# REPL history files +*.repl_history + diff --git a/aqua-examples/near-integration/services/near-rpc-services/Cargo.toml b/aqua-examples/near-integration/services/near-adapter/modules/near-rpc-services/Cargo.toml similarity index 100% rename from aqua-examples/near-integration/services/near-rpc-services/Cargo.toml rename to aqua-examples/near-integration/services/near-adapter/modules/near-rpc-services/Cargo.toml diff --git a/aqua-examples/near-integration/services/near-adapter/modules/near-rpc-services/Config.toml b/aqua-examples/near-integration/services/near-adapter/modules/near-rpc-services/Config.toml new file mode 100644 index 0000000..d69ee98 --- /dev/null +++ b/aqua-examples/near-integration/services/near-adapter/modules/near-rpc-services/Config.toml @@ -0,0 +1,4 @@ +modules_dir = "artifacts/" + +[[module]] + name = "near_rpc_services" diff --git a/aqua-examples/near-integration/services/near-adapter/modules/near-rpc-services/README.md b/aqua-examples/near-integration/services/near-adapter/modules/near-rpc-services/README.md new file mode 100644 index 0000000..8e6f025 --- /dev/null +++ b/aqua-examples/near-integration/services/near-adapter/modules/near-rpc-services/README.md @@ -0,0 +1,18 @@ +# Marine Starter Template + +Get started quickly with your Wasm project with this template. +To use this template you should have the following components available: + +* Rust [installation instructions](https://www.rust-lang.org/tools/install) +* cargo generate [installation instructions](https://github.com/cargo-generate/cargo-generate#installation) +* Marine [installation instructions](https://github.com/cargo-generate/cargo-generate#installation) + +Use the template with `cargo generate`: + +```bash +cargo generate --git https://github.com/fluencelabs/marine-template +``` + +Which will prompt you for the project name and then generate the project, which will be your directory name. `cd` into your new directory and run `./build.sh` to compile the supplied __greeting__ function to a Wasm file ready for Marine. + +Check out the [Fluence documentation](https://doc.fluence.dev/docs/) for more details on Marine and Aqua. diff --git a/aqua-examples/near-integration/services/near-adapter/modules/near-rpc-services/module.yaml b/aqua-examples/near-integration/services/near-adapter/modules/near-rpc-services/module.yaml new file mode 100644 index 0000000..bdd0344 --- /dev/null +++ b/aqua-examples/near-integration/services/near-adapter/modules/near-rpc-services/module.yaml @@ -0,0 +1,31 @@ +# yaml-language-server: $schema=../../../.fluence/schemas/module.yaml.json + +# EXAMPLES: +# name: facade +# type: rust # use this for modules written in rust and expected to be built with marine +# maxHeapSize: "100" # 100 bytes +# # maxHeapSize: 100K # 100 kilobytes +# # maxHeapSize: 100 Ki # 100 kibibytes +# # Max size of the heap that a module can allocate in format: +# # where ? is an optional field and specificator is one from the following (case-insensitive): +# # K, Kb - kilobyte; Ki, KiB - kibibyte; M, Mb - megabyte; Mi, MiB - mebibyte; G, Gb - gigabyte; Gi, GiB - gibibyte; +# # Current limit is 4 GiB +# loggerEnabled: true # true, if it allows module to use the Marine SDK logger. +# loggingMask: 0 # manages the logging targets, described in here: https://doc.fluence.dev/marine-book/marine-rust-sdk/developing/logging#using-target-map +# mountedBinaries: +# curl: /usr/bin/curl # a map of mounted binary executable files +# preopenedFiles: # a list of files and directories that this module could access with WASI +# - ./dir +# volumes: # a map of accessible files and their aliases. +# # Aliases should be normally used in Marine module development because it's hard to know the full path to a file. +# aliasForSomePath: ./some/path +# envs: # 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 +# ENV1: arg1 +# ENV2: arg2 + +version: 0 +type: rust +name: near_rpc_services +loggerEnabled: true +maxHeapSize: 640K diff --git a/aqua-examples/near-integration/services/near-rpc-services/src/main.rs b/aqua-examples/near-integration/services/near-adapter/modules/near-rpc-services/src/main.rs similarity index 100% rename from aqua-examples/near-integration/services/near-rpc-services/src/main.rs rename to aqua-examples/near-integration/services/near-adapter/modules/near-rpc-services/src/main.rs diff --git a/aqua-examples/near-integration/services/near-rpc-services/src/utils.rs b/aqua-examples/near-integration/services/near-adapter/modules/near-rpc-services/src/utils.rs similarity index 100% rename from aqua-examples/near-integration/services/near-rpc-services/src/utils.rs rename to aqua-examples/near-integration/services/near-adapter/modules/near-rpc-services/src/utils.rs diff --git a/aqua-examples/near-integration/services/near-adapter/service.yaml b/aqua-examples/near-integration/services/near-adapter/service.yaml new file mode 100644 index 0000000..cadff43 --- /dev/null +++ b/aqua-examples/near-integration/services/near-adapter/service.yaml @@ -0,0 +1,36 @@ +# yaml-language-server: $schema=../.fluence/schemas/service.yaml.json + +# EXAMPLES: +# modules: +# facade: +# get: modules/facade +# +# # Overrides for module: +# maxHeapSize: "100" # 100 bytes +# # maxHeapSize: 100K # 100 kilobytes +# # maxHeapSize: 100 Ki # 100 kibibytes +# # Max size of the heap that a module can allocate in format: +# # where ? is an optional field and specificator is one from the following (case-insensitive): +# # K, Kb - kilobyte; Ki, KiB - kibibyte; M, Mb - megabyte; Mi, MiB - mebibyte; G, Gb - gigabyte; Gi, GiB - gibibyte; +# # Current limit is 4 GiB +# loggerEnabled: true # true, if it allows module to use the Marine SDK logger. +# loggingMask: 0 # manages the logging targets, described in here: https://doc.fluence.dev/marine-book/marine-rust-sdk/developing/logging#using-target-map +# mountedBinaries: +# curl: /usr/bin/curl # a map of mounted binary executable files +# preopenedFiles: # a list of files and directories that this module could access with WASI +# - ./dir +# volumes: # a map of accessible files and their aliases. +# # Aliases should be normally used in Marine module development because it's hard to know the full path to a file. +# aliasForSomePath: ./some/path +# envs: # 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 +# ENV1: arg1 +# ENV2: arg2 + +version: 0 +name: nearAdapter +modules: + facade: + get: modules/near-rpc-services + curlAdapter: + get: modules/curl-adapter diff --git a/aqua-examples/near-integration/services/near-rpc-services/.gitignore b/aqua-examples/near-integration/services/near-rpc-services/.gitignore deleted file mode 100644 index bbccc88..0000000 --- a/aqua-examples/near-integration/services/near-rpc-services/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -debug/ -target/ -Cargo.lock -**/*.bk -**/*.bak diff --git a/aqua-examples/near-integration/services/scripts/build.sh b/aqua-examples/near-integration/services/scripts/build.sh deleted file mode 100755 index 5f559c7..0000000 --- a/aqua-examples/near-integration/services/scripts/build.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -o nounset -o pipefail - -mkdir -p artifacts -rm -f artifacts/*.wasm - -cd curl-adapter -cargo update --aggressive -marine build --release - -cd ../near-rpc-services -cargo update --aggressive -marine build --release -cd .. - -cp near-rpc-services/target/wasm32-wasi/release/near_rpc_services.wasm artifacts/ -cp curl-adapter/target/wasm32-wasi/release/curl_adapter.wasm artifacts/ diff --git a/aqua-examples/near-integration/services/aqua/near_adapter_demo.aqua b/aqua-examples/near-integration/services/src/aqua/main.aqua similarity index 53% rename from aqua-examples/near-integration/services/aqua/near_adapter_demo.aqua rename to aqua-examples/near-integration/services/src/aqua/main.aqua index c8334bc..41667be 100644 --- a/aqua-examples/near-integration/services/aqua/near_adapter_demo.aqua +++ b/aqua-examples/near-integration/services/src/aqua/main.aqua @@ -1,3 +1,8 @@ +module Main +import App from "deployed.app.aqua" + +export App, node_report + data Result: stderr: string stdout: string @@ -22,6 +27,12 @@ service NearRpcServices: view_account(network_id: string, account_id: string) -> Result view_account_structured(network_id: string, account_id: string) -> VAResult +func node_report(network_id: string) -> Result: + services <- App.services() + on services.nearAdapter.default!.peerId: + NearRpcServices services.nearAdapter.default!.serviceId + res <- NearRpcServices.node_status(network_id) + <- res func node_status(network_id: string, node: string, service_id: string) -> Result: on node: @@ -35,12 +46,25 @@ func view_account(network_id: string, account_id: string, node: string, service_ res <- NearRpcServices.view_account(network_id, account_id) <- res +func view_account_report(network_id: string, account_id: string) -> Result: + services <- App.services() + on services.nearAdapter.default!.peerId: + NearRpcServices services.nearAdapter.default!.serviceId + res <- NearRpcServices.view_account(network_id, account_id) + <- res + func view_account_structured(network_id: string, account_id: string, node: string, service_id: string) -> VAResult: on node: NearRpcServices service_id res <- NearRpcServices.view_account_structured(network_id, account_id) <- res +func view_account_structured_report(network_id: string, account_id: string) -> VAResult: + services <- App.services() + on services.nearAdapter.default!.peerId: + NearRpcServices services.nearAdapter.default!.serviceId + res <- NearRpcServices.view_account_structured(network_id, account_id) + <- res func account_balance(network_id: string, account_id: string, node: string, service_id: string) -> string: on node: @@ -48,8 +72,22 @@ func account_balance(network_id: string, account_id: string, node: string, servi res <- NearRpcServices.view_account_structured(network_id, account_id) <- res.stdout.amount +func account_balance_report(network_id: string, account_id: string) -> string: + services <- App.services() + on services.nearAdapter.default!.peerId: + NearRpcServices services.nearAdapter.default!.serviceId + res <- NearRpcServices.view_account_structured(network_id, account_id) + <- res.stdout.amount + func tx_status(network_id: string, tx_id: string, account_id: string, receipt: bool, node: string, service_id: string) -> Result: on node: NearRpcServices service_id res <- NearRpcServices.tx_status(network_id, tx_id, account_id, receipt) - <- res \ No newline at end of file + <- res + +func tx_status_report(network_id: string, tx_id: string, account_id: string, receipt: bool) -> Result: + services <- App.services() + on services.nearAdapter.default!.peerId: + NearRpcServices services.nearAdapter.default!.serviceId + res <- NearRpcServices.tx_status(network_id, tx_id, account_id, receipt) + <- res \ No newline at end of file