mirror of
https://github.com/fluencelabs/examples
synced 2024-12-05 03:30:17 +00:00
Migration of the NEAR example to using the Fluence CLI (#388)
* migrated the rust part to fluence cli; updated readme * migrated the JS part to the fluence CLI; updated the readme * small formatting fix: backtick * small formatting fix: backticks missed * removed unnecessary files * replaced aqua cli with fluence in package.json, updated readme reflecting the change * Addressed the pull-requests comments: + added more info on the fluence cli; + renamed functions so they are explanatory; + cut too verbose output; + updated the outdated output for deployment; + renamed near-related arguments so it's easy to distinguish them; + small other improvements. * readme changes: reformated to a separate tooling section * small formatting fixed in readme * Addressing pr comments: + removed the tooling section from the readme; + added a segway for using fluence cli; + fixed typo; + removed a commented both from code and the readme. * + renamed node to peer; + added a link on AccountView Near interface; * small correction regarding fluence cli statement * removed unnecessary reference for quickstart example Co-authored-by: igor <dev@igor.sh>
This commit is contained in:
parent
e68094ece2
commit
69fcb9d53f
@ -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 [ <near-account>.testnet ] with public key [ ed25519:<your-key... ] successfully
|
||||
```
|
||||
|
||||
Upon a successful login you should have a [local credentials](https://docs.near.org/tools/near-cli#access-key-location):
|
||||
|
||||
```
|
||||
ls ~/.near-credentials/testnet
|
||||
<near-account>.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 <path-to-examples>/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", "<your account>", "lame_password", "<peer id>", "relay id")'
|
||||
fluence run \
|
||||
-i aqua -f 'account_state("testnet", "<near-account>", "lame_password", "<your-peer-id>", "<your-relay-id>")'
|
||||
```
|
||||
|
||||
*Replace* `<your account>` with your testnet account and `<peer id>` and `<relay id>` with the values provided by your peer output as discussed above. Once you've done that, the output should be similar to:
|
||||
*Replace* `<near-account>` with your Near testnet account and `<your-peer-id>` and `<your-relay-id>` 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", "<near-account>", "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", "<from account>", "<to account>", "10000", "lame_password", "<peer id>", "<relay id>")'
|
||||
-f 'send_money("testnet", "<near-from-account>", "<near-to-account>", "10000", "lame_password", "<your-peer-id>", "<your-relay-id>")'
|
||||
|
||||
```
|
||||
|
||||
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", "<near-from-account>", "<near-to-account>", "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": "<from account>",
|
||||
"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": "<to account>",
|
||||
"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": "<to account>",
|
||||
"signature": "ed25519:5zmMLczayMnnykBdn9MM3hUCWigZM5JgfAyT1E7mu7a4RNzPq9uahAKiGs1JWxNCor6zGHNbX8cpQYC59axxFtjR",
|
||||
"signer_id": "<from account>"
|
||||
},
|
||||
"transaction_outcome": {
|
||||
"block_hash": "J4gEefXV6FM1crRxxQbHhhVWpuPdPHnEAx5Kb5coCDdj",
|
||||
"id": "3bmedi7erFPpwEWWgQHuMppoorvzed8x7w5mttofCVQw",
|
||||
Result:
|
||||
|
||||
{
|
||||
"receipts_outcome": [
|
||||
{
|
||||
"block_hash": "EzB5BiTVyqzJjqbTzRRKfQ2qWdj48F5vArVwtdwDmNaG",
|
||||
"id": "FmhBQNgwtvaJUxTEbPhqfsUSjuwjcYw4iLsb1LLsKDDH",
|
||||
"outcome": {
|
||||
"executor_id": "<from account>",
|
||||
"executor_id": "<near-to-account>",
|
||||
"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": "<near-from-account>",
|
||||
"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": "<near-to-account>",
|
||||
"signature": "ed25519:2cmhrzp4PeKPcXE1vUW89krdTcdsApY3h6TT7CshWdrZMBLUjfJQF6pijzYcFUhpwArNQwDmD9GkVep9gYJTb4Hd",
|
||||
"signer_id": "<near-from-account>"
|
||||
},
|
||||
"transaction_outcome": {
|
||||
"block_hash": "DhS6KZzK9PdCqot2k4hewfAWkc7nQ9mnZM91XKZdVRkQ",
|
||||
"id": "2cCxw5RGTqD9UCwqth3Pe3FhRcYkqRimnzyhYWCBKjjA",
|
||||
"outcome": {
|
||||
"executor_id": "<near-from-account>",
|
||||
"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 `<your-peer-id>` and `<your-relay-id>`. 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", "<near-from-account>", "<near-to-account>", "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", "<near-account>", "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,
|
||||
<snip>
|
||||
\"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 <path-to-examples>/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 <path-to-examples>/examples/aqua-examples/near-integration/services/.fluence/aqua/deployed.app.aqua... done
|
||||
|
||||
Currently deployed services listed in <path-to-examples>/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.<snip>
|
||||
\"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
|
||||
|
||||
|
@ -48,3 +48,9 @@ package-lock.json
|
||||
# fluence
|
||||
|
||||
src/_aqua/*
|
||||
# recommended by Fluence Labs:
|
||||
.fluence
|
||||
**/node_modules
|
||||
**/target/
|
||||
.vscode/settings.json
|
||||
.repl_history
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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": "",
|
||||
|
@ -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();
|
||||
|
7
aqua-examples/near-integration/services/.gitignore
vendored
Normal file
7
aqua-examples/near-integration/services/.gitignore
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
.idea
|
||||
.DS_Store
|
||||
.fluence
|
||||
**/node_modules
|
||||
**/target/
|
||||
.vscode/settings.json
|
||||
.repl_history
|
@ -1,8 +0,0 @@
|
||||
{
|
||||
"name": "curl_adapter",
|
||||
"mountedBinaries": {
|
||||
"curl": "/usr/bin/curl"
|
||||
},
|
||||
"mem_page_count": 10,
|
||||
"logger_enabled": false
|
||||
}
|
@ -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
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
{
|
||||
"name": "near_rpc_services",
|
||||
"mem_page_count": 10,
|
||||
"logger_enabled": true
|
||||
}
|
26
aqua-examples/near-integration/services/fluence.yaml
Normal file
26
aqua-examples/near-integration/services/fluence.yaml
Normal file
@ -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
|
14
aqua-examples/near-integration/services/near-adapter/modules/curl-adapter/.gitignore
vendored
Normal file
14
aqua-examples/near-integration/services/near-adapter/modules/curl-adapter/.gitignore
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
target/
|
||||
**/*.rs.bk
|
||||
.idea
|
||||
|
||||
# MacOS misc file
|
||||
*.DS_Store
|
||||
|
||||
# Wasm files
|
||||
*.wasm
|
||||
*.wat
|
||||
|
||||
# REPL history files
|
||||
*.repl_history
|
||||
|
@ -0,0 +1,4 @@
|
||||
modules_dir = "artifacts/"
|
||||
|
||||
[[module]]
|
||||
name = "curl_adapter"
|
@ -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.
|
@ -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: <number><whitespace?><specificator?>
|
||||
# # 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
|
14
aqua-examples/near-integration/services/near-adapter/modules/near-rpc-services/.gitignore
vendored
Normal file
14
aqua-examples/near-integration/services/near-adapter/modules/near-rpc-services/.gitignore
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
target/
|
||||
**/*.rs.bk
|
||||
.idea
|
||||
|
||||
# MacOS misc file
|
||||
*.DS_Store
|
||||
|
||||
# Wasm files
|
||||
*.wasm
|
||||
*.wat
|
||||
|
||||
# REPL history files
|
||||
*.repl_history
|
||||
|
@ -0,0 +1,4 @@
|
||||
modules_dir = "artifacts/"
|
||||
|
||||
[[module]]
|
||||
name = "near_rpc_services"
|
@ -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.
|
@ -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: <number><whitespace?><specificator?>
|
||||
# # 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
|
@ -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: <number><whitespace?><specificator?>
|
||||
# # 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
|
@ -1,5 +0,0 @@
|
||||
debug/
|
||||
target/
|
||||
Cargo.lock
|
||||
**/*.bk
|
||||
**/*.bak
|
@ -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/
|
@ -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
|
||||
|
||||
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
|
Loading…
Reference in New Issue
Block a user