# Lightstreams Docs

Build powerful privacy-centric web3 applications.

## Welcome! Let us help you build great apps.&#x20;

Lightstreams provides secure data sharing for web3 applications.

![The future is here!](https://2039801026-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LozRZUf94C_7q5CsAQX%2F-LozlFaOFwLtVsCsIZX9%2F-Lozp3RtH3MvGfonr6sk%2Flightstreams_splash.png?alt=media\&token=fb92f281-e2dc-4aaa-aeec-e5b00db0ff21)


# Why Lightstreams

We envision a future where data sovereignty prevails—no third-party should be in control of your data.

At Lightstreams, we want to help you create powerful apps where people have **full sovereignty** over their **data**. Our tools will help you quickly build a new generation of web3 application that can make this happen! :muscle:&#x20;

![](https://2039801026-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LozRZUf94C_7q5CsAQX%2F-LpT42ZzMnr4V4rLt-9J%2F-LpTEBgUUa0oB-zZ7VSy%2F21affaf5.png?alt=media\&token=a81da552-736b-4a4a-a545-c091f6b40d62)

{% hint style="info" %}
The online world today consists of siloed walled gardens where people do not have full control over their data and the content they create.&#x20;
{% endhint %}

### :sparkles: Build Apps that Use Web3 Storage

Until now, developing apps that allow users to tightly control access to their personal information and content was a challenge. Lightstreams changes that by enabling app users to approve access to their content and data using distributed web3 storage.

### :family\_mwgb: Access Control

Leverage simple APIs to manage access within private groups for content sharing.

Data remains inaccessible (even in encrypted form) without explicit permission. Users retain full control over granting and revoking access permissions, ensuring only authorised parties can view their data.


# Data Sovereignty

A paradigm shift in managing user data.

We believe applications should be designed where:

* User data remains private and confidential.&#x20;
* User data is not managed or controlled by a single entity.

Many people use *privacy* and *confidentiality* interchangeably, yet the two words and *anonymity* mean significantly different things. The differences matter when it comes to data ownership, rights, responsibilities, and protections.&#x20;

{% hint style="info" %}
Being **anonymous** does not guarantee **privacy**.&#x20;
{% endhint %}

**Anonymity** – is ensuring that an individual is not known and cannot be identified.

**Privacy** – is the individual or an entity’s right to keep personal data to themselves and to not have their actions recorded or monitored.

**Confidentiality** – refers to controlling access to protected information that is shared between parties by consent.

## Smart Vault: Privacy & Confidentiality&#x20;

The Smart Vault by Lightstreams can be used by applications to manage access to protected information that is shared between people. \
\
Each application runs an instance of the Smart Vault that connects to a peer-to-peer network of other Smart Vaults.\
\
When permission is granted, data is transmitted directly between each person's Smart Vault in a peer-to-peer manner so that each persona has a copy of the data.&#x20;

Unlike cloud services like Google Drive, DropBox or Sharepoint, there is no central intermediary acting as the central storage and conduit.&#x20;

![](https://2039801026-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LozRZUf94C_7q5CsAQX%2F-Lsrd_-x5UnI2uXL8Ldm%2F-LsrdsNw_hm8EuOJaC4K%2Fsv_med.png?alt=media\&token=551f67bc-2f45-417e-86e7-ba7ea62ad8c7)

Learn more about the Smart Vault...

{% content-ref url="/pages/-Lspp1nDkLV\_JfdigoaS" %}
[Smart Vault](/products/smart-vault)
{% endcontent-ref %}


# Overview

Build powerful privacy-centric applications.

## Introduction

Lightstreams is a data-sharing network designed specifically for web3 applications, featuring permissioned access control. It builds upon the [IPFS protocol](https://ipfs.tech/), which has been enhanced to include file access controls, adapting it for enhanced security and privacy needs.&#x20;

## Components

The technology stack of Lightstreams comprises several key components:

* [Smart Vault](/products/smart-vault) - This is a decentralized datastore that includes robust privacy controls, ensuring secure storage and controlled access to data.
* [Lightstreams SDK](/products/smart-vault/sdk) - A comprehensive Software Development Kit that facilitates interaction with a Lightstreams node, simplifying the development process for developers.


# Privacy and Confidentiality

Lightstreams is designed for privacy-centric web3 applications.

In many scenarios where users interact with applications, it is crucial that their data, including personal information and activity, remain confidential and not publicly accessible. This presents a significant challenge in the web3 domain, where public blockchains are predominantly used, making it relatively easy to trace user activities and shared data.

Lightstreams addresses this challenge with its Smart Vault, a privacy-focused and confidential solution for web3 applications. The Smart Vault is a decentralized datastore that incorporates access controls for the sharing and selling of digital content. It operates on the IPFS Network, leveraging this peer-to-peer overlay network as a distributed data storage system.

The Smart Vault enhances the IPFS protocol by adding a security layer that restricts access to protected files. Data owners have full authority over who can access their data, the conditions under which access is granted, and the ability to revoke permissions at any time.

Applications of Smart Vault include:

* Selling digital content such as videos, music, and images.
* Transferring ownership of digital assets, for example, land titles and vehicle registrations.
* Tracing the custody of goods within a value chain, such as the supply chain of food.
* Sharing content within private groups.
* Storing personal information and user activity securely.


# Smart Vault

Secure Distributed Storage and Decentralized Data Exchange

![Exchange data and sell content using smart contracts](https://2039801026-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LozRZUf94C_7q5CsAQX%2F-M6GCnfAUOyPrY6BV5xj%2F-M6GD69hiQBFCDjMv58c%2FSmartVault_Logo%20\(1\).png?alt=media\&token=3dec564b-b46c-4ae6-9b2e-e6c4c5952e21)

## Introduction

The Smart Vault provides distributed data storage and rights management for applications that want to monetize content or exchange data securely in a peer-to-peer connected network. The Smart Vault is designed with smart contracts for managing the security for accessing a file, a paradigm shift in access control. The use of smart contracts allows for complex and dynamic access control rules and at the same time eliminates any lock-in to using an intermediary for managing access control rules.&#x20;

Users of Smart Vault-enabled applications can have true ownership and sovereignty over their data. They control where it is stored and who has access and since their data is not stored centrally, the risk of their data being lost, hacked or sold onto third parties is reduced.&#x20;

## What is the Smart Vault?

The Smart Vault is a decentralized data store where rights to access to data are managed and controlled by smart contracts. \
\
Using the Smart Vault, a person can share data directly to members of a private group, transfer ownership of assets or sell content directly to customers with payments automatically and instantly managed by smart contracts.

&#x20;Applications can use the Smart Vault to:

* Sell digital content (e.g. video, music, images).
* License rights to digital content.
* Transfer ownership of digital assets (e.g. and titles, vehicle registrations).
* Track and trace a product with a value chain (e.g. a food supply chain).
* Share confidential information directly between members within a private group.
* Selectively disclose self-sovereign identity claims.
* Source always up to date customer data across applications.

## The Benefits of Using the Smart Vault

### Eliminate the Cost of Blockchain Storage. &#x20;

Storing data on the blockchain is both impractical and expensive. By using the Smart Vault you can store your application's state information on a decentralized datastore that is managed by smart contracts. Storage costs are eliminated since users of your application store and manage data within a Smart Vault that they own.

### Eliminate Data Liability.

As a developer, you must ensure that your application complies with data privacy laws such as GDPR and CCPA regulations when handling the personal data of users. By letting users store and manage data using a Smart Vault, you eliminate your compliance burden and the liability associated with protecting and securing this sensitive data.

### Create Decentralized Private Groups.&#x20;

The Smart Vault provides applications with granular control for accessing data. No one can access data unless they are granted permission, including access to the data in encrypted format. The data owner always has control over who has access, when access was approved and they can revoke access to anyone at any time.\
\
Note: Some decentralized datastores provide data privacy by solely using encryption and storing the information publicly without access controls. The encrypted data is available to *anyone* to downloa&#x64;*,* regardless of having permission or not. This method leaks information about the encrypted data and the data owner.

### Sell Content. Transfer and Track Assets.

‌The Smart Vault enables you to develop peer-to-peer business models for selling digital content and transferring assets. Digital content (video, music, art, games) can be sold by content producers in a peer-to-peer manner giving greater control and a reduction in cost. The sale and transfer of ownership of digitized assets (e.g. land titles, vehicle registrations) can also be executed directly between parties without requiring an intermediary.

## How Does it Work?

> **Data is stored in a distributed manner by Smart Vault nodes that have been granted permission. Data owners manage access permissions using smart contracts.**

### IPFS Distributed Storage

The Smart Vault uses the [**InterPlanetary File System(IPFS)**](https://ipfs.io/) an open standard for storing and transmitting data in a distributed manner. The IPFS protocol provides high redundancy and availability of data by multiple computers hosting and serving the same file in parallel to applications. Applications retrieve files  using an addressing scheme that is based on the content of the file rather than its location. The IPFS protocol provides a paradigm shift from traditional application design where one entity usually hosts all user information and content that it needs.&#x20;

The Smart Vault extends the IPFS protocol so that files are only transmitted to other Smart Vault nodes that have been authorized to access the protected data.

{% hint style="info" %}
The default IPFS protocol has no security mechanism for restricting access to data. The Smart Vault extends the IPFS protocol with a security layer for controlling access to protected data.
{% endhint %}

### Distributed Peer-to-Peer Transmission

A file that is stored in a Smart Vault is broken into blocks of data. When a block of data refers to a protected file, transmission of the block will only be permitted by verifying that the blockchain account requesting the data has been authorized.&#x20;

Data blocks are transmitted in a peer-to-peer manner between nodes such that a Smart Vault will receive data in parallel from multiple Smart Vault nodes at the same time. This redundancy ensures that access to the data will still be available when a Smart Vault is offline.

### Ethereum Smart Contract Permissions

The Smart Vault has been designed to integrate with smart contract enabled blockchain such as [Lightchain](broken://pages/-LozsEK6YOeAFrX2aB19). Permissions to access a file are managed by a smart contract that is controlled by the data owner. The smart contract has an Access Control List (ACL) that is used for managing access to the file. The ACL is a list of permissions that accounts can be granted to control file access.&#x20;

By using Smart contracts file access is managed in a decentralized manner and provides granular control for granting permissions. Permissions can be granted to single account or multiple accounts for a private group.

Smart contracts also ensure transparency and audibility for when, by whom, and to who permission was granted.

## Demonstration&#x20;

You can see a demonstration of the Smart Vault as follows:

{% content-ref url="/pages/-LspwQULfHemn\_toyOKl" %}
[Broken mention](broken://pages/-LspwQULfHemn_toyOKl)
{% endcontent-ref %}


# Disclosures and Disclaimer

Security Issues, Disclosures and Disclaimers

The [Smart Vault](https://docs.lightstreams.network/products/smart-vault) and its implementations are still in heavy development.\
\
This means that there may be problems in our software or the underlying software, or there may be mistakes in our implementations. We take security vulnerabilities very seriously. If you discover a security issue, please bring it to our attention right away!\
\
If you find a vulnerability -- please send your report to [support@lightstreams.io](mailto:%20support@lightstreams.io). \
\
**DISCLAIMER**: These technical documents are for informational, illustration and discussions purposes only. This technical documents may not be complete or final, maybe an estimate, are subject to change and do not contain material information regarding an investment, including specific information relating to an investment’s risks. Lightstreams Network OÜ does not make any representations and warranties as to the accuracy or completeness of the information contained in this document and website that are express, implied, statutory or otherwise, whatsoever, including, but not limited to: (i) warranties of merchantability, fitness for a particular purpose, suitability, usage, title or non infringement; (ii) that the contents of this document are free from error; and (iii) that such contents will not infringe third-party rights. Lightstreams Network OÜ and its affiliates shall have no liability for damages of any kind arising out of the use, reference to, or reliance on these technical documents or any of the content contained herein, even if advised of the possibility of such damages. In no event will Lightstreams Network OÜ or its affiliates be liable to any person or entity for any damages, losses, liabilities, costs or expenses of any kind, whether direct or indirect, consequential, compensatory, incidental, actual, exemplary, punitive or special for the use of, reference to, or reliance on these technical documents, website, white paper, blogs or any of the content contained herein, including, without limitation, any loss of business, revenue, profits, data, use, goodwill or other intangible losses.


# Demo

If you are a developer, you can follow these instructions to run a demo application of the Smart Vault to see it in action. The demo has a demonstration Content Access Control user interface for uploading files and granting access to other accounts.

## Requirements

* A Docker Client. See: [https://www.docker.com/products/docker-desktop](https://www.docker.com/products/docker-desktop/)

<div align="left"><figure><img src="https://2039801026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LozRZUf94C_7q5CsAQX%2Fuploads%2FnEWLX1ZBhKEgnfShLVSl%2FScreenshot%202024-04-28%20at%2018.10.09.png?alt=media&amp;token=663da5cf-bee5-432f-b0a5-ce63335bcb01" alt="" width="237"><figcaption></figcaption></figure></div>

## Instructions

1. Run an instance of the demo application.

```
docker run -p 9091:9091 -p 4002:4002 -it --name demo1 lightstreams/leth-0.33.2-alpha-demo
```

**Note:** port 9001 is used for serving the user interface of the demo and port 4002 is used for the peer-to-peer transmission of data between Smart Vaults.\
\
2\. Now open your browser at the following address: [http://localhost:9091](http://localhost:9091/)

<figure><img src="https://2039801026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LozRZUf94C_7q5CsAQX%2Fuploads%2Fq0QwcONhcjvcGdwD2749%2FScreenshot%202024-04-28%20at%2017.18.00.png?alt=media&amp;token=bd817bd8-c6e5-4b01-a2b6-362f56dbe299" alt=""><figcaption><p>Demo - instance 1</p></figcaption></figure>

The demo application will open and will display your Account address and Balance of test tokens. \
\
The account address is your identifier and is used by other people for granting you permission to a file. Normally, for each file you wish to access, the Smart Vault will generate another Account address. However, for this demo we will use just one. \
\
This application uses our test network, so your balance will be automatically topped up with 100 TPHT. \
The test tokens are used for creating and interacting with smart contracts that are used for managing access control permissions to files.\
\
3\. Click the Upload button and upload a file.&#x20;

<figure><img src="https://2039801026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LozRZUf94C_7q5CsAQX%2Fuploads%2FtRbWeiWiMF9ctTAseSL5%2FScreenshot%202024-04-28%20at%2017.25.50.png?alt=media&amp;token=c77db909-5a42-47b4-a266-a583c34195de" alt=""><figcaption><p>Upload a file</p></figcaption></figure>

4. Once the file is uploaded you will see the Meta details about the file.

<figure><img src="https://2039801026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LozRZUf94C_7q5CsAQX%2Fuploads%2F5nWaftMl2M2X4KayYwcQ%2FScreenshot%202024-04-28%20at%2017.26.14.png?alt=media&amp;token=0a294ec8-79a2-4f66-881f-ed07cdcf3e19" alt=""><figcaption><p>Meta details of the file</p></figcaption></figure>

The meta details give the following information about the file:\
Meta Address - This is the address used for searching for the file. This contains the public meta information about the file (Filename, File Type, File IPFS Address, Owner Account and ACL Address).<br>

5. Now in another console window, run another instance of the demo.

```
docker run -p 9092:9092 -p 4003:4003 -it --name demo2 lightstreams/leth-0.33.2-alpha-demo /bin/sh -c "~/run.sh 2"
```

**Note:** If you have another computer, you could run this command also that machine.

6. Open your browser at the following address: [http://localhost:9092](http://localhost:9091/)

<figure><img src="https://2039801026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LozRZUf94C_7q5CsAQX%2Fuploads%2FA0ezgIbdY3QzsV4PEiD1%2FScreenshot%202024-04-28%20at%2017.47.14.png?alt=media&amp;token=3b123fc9-d0dd-44b8-b493-552cc9d3a35b" alt=""><figcaption><p>Demo - instance 2</p></figcaption></figure>

7. Now we will grant the demo 2 instance to be able to access the file that was uploaded.\
   \
   Copy the account number from demo2 and paste it into the Permissions box in demo1 and click Grant.&#x20;

<figure><img src="https://2039801026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LozRZUf94C_7q5CsAQX%2Fuploads%2Fb2ARP3KbfbJuzdZ3zybG%2FScreenshot%202024-04-28%20at%2017.50.04.png?alt=media&amp;token=37f854a4-6271-42f6-91c1-7dd6c0449044" alt=""><figcaption></figcaption></figure>

8. Now we will access the file on demo3.\
   \
   Copy the Meta Address from demo1. On demo2, click Search and paste the Meta Address.

<figure><img src="https://2039801026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LozRZUf94C_7q5CsAQX%2Fuploads%2FHsIb3ZDLDijn3mFO3leL%2FScreenshot%202024-04-28%20at%2018.02.59.png?alt=media&amp;token=f6bd31b2-a25f-4329-8e4f-775e8dd76534" alt=""><figcaption></figcaption></figure>

9. Now click Search

<figure><img src="https://2039801026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LozRZUf94C_7q5CsAQX%2Fuploads%2FI2hulCOxITcwHDDV7nYP%2FScreenshot%202024-04-28%20at%2018.04.40.png?alt=media&amp;token=7b0a26b7-078f-4b6d-8e0e-c7a6c2c2e9c4" alt=""><figcaption></figcaption></figure>

This pulls the public information about the contained at the Meta Address.

10. Now, click Access.

<figure><img src="https://2039801026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LozRZUf94C_7q5CsAQX%2Fuploads%2F2oo9tbIzAEMvOK8gywEX%2FScreenshot%202024-04-28%20at%2018.06.16.png?alt=media&amp;token=56080ce7-b81f-4347-8f77-fe3df9a75274" alt=""><figcaption></figcaption></figure>

The file has been transmitted from the instance of demo 1 to demo 2.\
\
**Note:** When multiple instances have copies of the same file they will transmit the data simultaneously to other authorised instances.

### Clean up

To stop the docker containers and remove them:

```
docker stop demo1
docker stop demo2
docker rm demo1
docker rm demo2
```

## More instances

If you would like to run more instances to test out the peer-to-peer nature of the network. \
\
For example, having demo1 grant access to demo3 and then stop demo1. When demo3 requests the file, demo2 which has a copy, will verify demo3 has been granted permission and will transmit the content.\
\
**Note:** Data is transmitted directly between peers via a secure SSL connection. \
\
Run a third instance and navigate to [http://localhost:9093](http://localhost:9091/)

```
docker run -p 9093:9093 -p 4004:4004 -it --name demo3 lightstreams/leth-0.33.2-alpha-demo /bin/sh -c "~/run.sh 3"
```

Run a forth instance and navigate to [http://localhost:9094](http://localhost:9091/)

```
docker run -p 9094:9094 -p 4005:4005 -it --name demo4 lightstreams/leth-0.33.2-alpha-demo /bin/sh -c "~/run.sh 4"
```

## Local Stand-Alone Cluster

You can run a stand-alone cluster of the blockchain network and smart vault overlay network on your local machine for development and testing purposes by the following these instructions:&#x20;

{% embed url="<https://github.com/lightstreams-network/lightstreams-local-demo>" %}

## Contact

If you are interested in our team doing further development to customise the Smart Vault or add features to suit your use case, then please get in contract with us at: <support@lightstreams.io>


# Getting Started


# Install

## Download Leth

***Download binaries***

\== macOS ==

```
wget "https://s3.eu-central-1.amazonaws.com/lightstreams-public/leth/latest/leth-osx" -O /usr/local/bin/leth
```

\== Linux (amd64) ==

```
wget "https://s3.eu-central-1.amazonaws.com/lightstreams-public/leth/latest/leth-linux-amd64" -O /usr/local/bin/leth
```

## Update Permissions

For downloaded binaries, set the right executable permissions, as follow:

```
chmod u+x /usr/local/bin/leth
```

## Validate versions

```
> leth version
Version: 0.33.0-alpha Demo
```


# Run a Smart Vault Node

## Connecting to the Test Network

You will initialize and connect your node to the Lightstreams test blockchain network called Sirius. The nodes use the blockchain network for deploying and controlling smart contracts.&#x20;

**Smart Vault uses smart contracts for managing files access permissions.**

### Initialize the node

```bash
leth init --nodeid=1 --network=sirius --lightclient=true --blockchain_url=https://rpc.sirius.lightstreams.io --federation=false --demo=true
```

### Start the node

```bash
leth run --nodeid=1 --network=sirius --https

2020-03-30T16:49:46.650+0200	INFO	lethnode/node.go:162	Starting Leth Node online/offline services...
2020-03-30T16:49:46.652+0200	INFO	lethnode/node.go:186	Starting Leth Blockchain online service...
2020-03-30T16:49:46.653+0200	INFO	lethnode/node.go:189	Waiting for Leth Blockchain service to start...
2020-03-30T16:49:46.822+0200	INFO	lethexec/exec.go:21	LN-SIRIUS: Running '/Users/enchanterio/go/bin/lightchain' with args: 'lightchain, run, --datadir=/Users/enchanterio/.lightstreams_2/sirius, --tmt_rpc_port=26757, --tmt_p2p_port=26756, --rpc, --rpcaddr=0.0.0.0, --rpcport=8645, --rpcapi, eth,net,web3,personal,debug, --rpcvhosts=localhost, --rpccorsdomain=*, --ws, --wsaddr=0.0.0.0, --wsport=8646'
2020-03-30T16:49:56.653+0200	INFO	lethnode/node.go:192	Connecting to SIRIUS network...
2020-03-30T16:49:56.664+0200	INFO	lethnode/node.go:448	Ethereum client is now fully synced and available!
2020-03-30T16:49:58.197+0200	INFO	lethnode/node.go:230	Starting Leth IPFS online service...
2020-03-30T16:49:58.198+0200	INFO	lethnode/node.go:233	Starting Leth RegistryDB offline service...
2020-03-30T16:49:58.199+0200	INFO	lethnode/node.go:240	Starting Leth SmartVault online service...
2020-03-30T16:49:58.199+0200	INFO	lethregistry/registry.go:323	RegistryDB is at the latest migration version	{"version": "1"}
2020-03-30T16:49:58.225+0200	INFO	lethnode/node.go:270	Starting Leth HTTP online service on port 9092...
2020-03-30T16:49:58.225+0200	INFO	lethnode/node.go:254	Starting Leth RevokedFiles offline service...
2020-03-30T16:49:58.225+0200	INFO	lethnode/node.go:265	Starting Leth TokenCache offline service...

2020-03-30... All Leth online/offline services are up and running!
```

### Stopping the node

You can stop a node at any time by pressing **Ctrl+C**

## OPTIONAL: Create a Second Node

Smart Vault is all about peer-to-peer content sharing. If you are interested in Smart Vault, sooner or later you will want to share a file between two nodes. To have two Smart Vault nodes running locally on the same computer to test the peer-to-peer behaviour of sharing files then run the following commands:

### Initialize the node

In a new command window, start the second node:

```javascript
leth init --nodeid=2 --network=sirius --lightclient=true --blockchain_url=https://rpc.sirius.lightstreams.io
```

### Start the node

Run the secord node:

```bash
leth run --nodeid=2 --network=sirius --https
```


# Share a Private File

In this guide, you will use Lightstreams node to share a file in a peer-to-peer manner with another node. No intermediary server will be used.

### Create a test file

```bash
echo "SmartVault is awesome." > smart_vault.txt
```

### Add the file to your node

```bash
curl -X POST \
  http://localhost:9091/storage/add \
  -H 'multipart/form-data; boundary="===============1648430772=="' \
  -F owner=YOUR_ACCT \
  -F password=YOUR_PWD \
  -F file=@smart_vault.txt
```

Where:

* `file` the absolute path to the file you want to share
* `owner` the address of the file owner. This address needs to have a positive PHT balance to pay for the smart contract transaction fees
* `password` the password to unlock owner account

Output:

```javascript
{
   "meta":"QmbVtvd1rD9pDHpx7AUqrsh3CoCMW3Na3g4fAwXJxyaawz",
   "acl":"0x7000f85C4065643435E8A350655F3153c7dd030E"
}
```

Note:

* `"meta"` a public file describing the file meta information. The protected content is stored in a secure manner. You can share this address with everyone. They won't be able to access the protected content. Only read the file metadata.
* `"acl"` a smart contract address for controlling all the file access permissions and rules for the .&#x20;

### Grant permission to another device

Create a new account for node 2:

```
curl --location --request POST 'http://localhost:9092/user/signup' \
--header 'Content-Type: application/json' \
--data-raw '{
	"password": "PWD_Node2"
}'

> {"account": "0xFb0bC1AC4a627fcdd215b7eF9617172276a402d0"}
```

Generate the token for node 2 account `0xFb0bC1AC4a627fcdd215b7eF9617172276a402d0`:

```bash
curl --location --request POST 'http://localhost:9092/user/signin' \
--header 'Content-Type: application/json' \
--data-raw '{
	"account": "0xFb0bC1AC4a627fcdd215b7eF9617172276a402d0",
	"password": "PWD_Node2"
}'

> { "token": "eyJibG9DB9...hUh4yICLseCD5ejRs" }
```

Attempt to read the protected file with node 2 account credentials (token):\
**Note:** Replace \[meta] and \[token] in the query string with the meta hash and token string you generated.

```
curl --request GET 'http://localhost:9092/storage/stream?meta=[meta]&token=[token]'
```

Where:

* `meta` is the protected's file public meta address: `QmbVtvd1rD9pDHpx7AUqrsh3CoCMW3Na3g4fAwXJxyaawz`
* `token` is your auth token generated by `/user/signin` request

Output:

```javascript
{"error":{
    "message": "no READ access. Account '0xFb0bC1AC4a627fcdd215b7eF9617172276a402d0' is unable to access Smart Vault protected file 'QmXT5yfwk9zpVHZZ9WYzAFiSV3N2YAx8nFqd5w3t2jrsvo' with public meta 'QmbVtvd1rD9pDHpx7AUqrsh3CoCMW3Na3g4fAwXJxyaawz'.",
    "code":"TOKEN_DENIED"
}
```

This error is expected because the file owner never actually granted permission to Lightstreams node 2 account: `0xFb0bC1AC4a627fcdd215b7eF9617172276a402d0`.

Let's grant Leth node 2 a read permission.

### Granting a READ permission

From Node 1 account run:

```bash
curl --location --request POST 'http://localhost:9091/acl/grant' \
--header 'Content-Type: application/json' \
--data-raw '{
  "acl": "0x7000f85C4065643435E8A350655F3153c7dd030E",
  "owner": "0xa92e3705e6d70cb45782bf055e41813060e4ce07",
  "password": "PWD_Node2",
  "to": "0xFb0bC1AC4a627fcdd215b7eF9617172276a402d0",
  "permission": "read"
}'

> { "is_granted": "true" }
```

Where:

* `acl` corresponds to the smart contract address provided after we published the file
* `to` is the account we are granting access to
* `permission` is the permission to grant, it may be: `['read', 'write', 'admin', 'noaccess']`

### Try to access the file again

```bash
curl --request GET 'http://localhost:9092/storage/stream?meta=[meta]&token=[token]' > ./sv.txt

vim ./sv.txt
> Smart Vault is awesome.
```

### Reading the meta file

In case you want to get information about the privately stored file, you can do so using the `/storage/meta` route.&#x20;

This returns public information about the file, without revealing its content.

```bash
curl --request GET 'http://localhost:9092/storage/meta?meta=QmbVtvd1rD9pDHpx7AUqrsh3CoCMW3Na3g4fAwXJxyaawz
```

Output:

```javascript
{
    "filename": "smart_vault.txt",
    "ext": "txt",
    "owner": "0xa92e3705e6d70cb45782bf055e41813060e4ce07",
    "hash": "QmPVKAWBPzZVgGU1yVZuBhRWkePYbWLYrwetme1wNn2JQ8",
    "acl": "0x7000f85C4065643435E8A350655F3153c7dd030E"
}
```

Note:

* `filename` is the original filename when file was uploaded
* `ext` is the original file extension
* `owner` who uploaded the file
* `hash` the hash of the protected file stored in IPFS (not the public Meta file hash)
* `acl` address of the contract handling file permissions

**Congratulations!** You just shared a private file over the internet in a peer-to-peer manner.


# Smart Vault SDK

A Software Development Kit for the Smart Vault

Lightstreams provides a Software Development Kit with the following tools for interacting with the Smart Vault.

* [Smart Vault API](https://docs-api.lightstreams.network/) - A HTTP interface that a client application can use to connect to and manage the Smart Vault.&#x20;
* [Lightstreams Javascript SDK](/products/smart-vault/sdk/js-sdk) - a library the provides modules that a Javascript client can use for managing Lightstreams accounts and interacting with the Smart Vault.
* [Smart Vault CLI](/products/smart-vault/sdk/leth) - A command line interface for interacting with the Smart Vault.&#x20;


# Smart Vault JS SDK

Javascript Software Development Kit

The Lightstreams Javascript SDK provides is a library the provides modules for account management and interacting with a Lightstreams node.

## Source&#x20;

The [**Lightstreams Javascript SDK**](https://github.com/lightstreams-network/lightstreams-js-sdk) Github repository.

## Requirements

* Node >= 10
* Lightstreams node. [How to install](/products/smart-vault/getting-started/installation)

### How to use

**Install node module**

Install `lightstreams-js-sdk` as part of your project dependencies:

```bash
npm install git+https://git@github.com:lightstreams-network/lightstreams-js-sdk#master --save
```

## Modules

### 1. Wallets (ethers-js)

Learn more about [ethers-js](https://docs.ethers.io/ethers.js/html/api-wallet.html#wallet)

**How to create a random new wallet**

```javascript
import { EthersWallet as EW } from 'lightstreams-js-sdk';

const encryptedJson = await EW.Keystore.createRandomWallet(seedPhrase, password);
```

**How to create a wallet from seed phrase**

```javascript
import { EthersWallet as EW } from 'lightstreams-js-sdk';

const encryptedJson = await EW.Keystore.createWallet(seedPhrase, password);
```

**How to generate a random seed phrase**

```javascript
import { EthersWallet as EW } from 'lightstreams-js-sdk';

const randomSeedPhrase = EW.Keystore.generateRandomSeedPhrase();
```

#### 1.1 Account

**How to create a new account**

```javascript
import { EthersWallet as EW } from 'lightstreams-js-sdk';
const encryptedJson = await EW.Keystore.createRandomWallet(seedPhrase, password);
const account = EW.Account.createAccount(encryptedJson)
```

**Public account object API**

* `lock():void`: Lock wallet account
* `unlock(password):void`: Unlock wallet account
* `isLocked():boolean`: Return false is the account is unlock
* `sign(txParams):string`: Return a signed transaction. Wallet must be unlocked
* `export():object`: Returns encrypted privatekey in json format
* `seedPhrase():array`: Return account seed phrase. Wallet must be unlocked

### 2. Web3 provider

In this repository you can find a customize web3 provider which uses a local keystorage to sign transactions. In addition other ethereum public API methods such as `eth_lockAccount`, `eth_unlockAccount` and `eth_newAccount` are being overwritten to use the key local storage.

**How to initialize a LS web3 provider**

```javascript
import { Web3 } from 'lightstreams-js-sdk';

Web3.newEngine(window.process.env.WEB3_PROVIDER).then(web3 => {
  window.web3 = this.state.web3;
});
```

Using this web3 provider you could create a new account and unlock it as you would regularly do web3 engine api methods, such as:

```javascript
web3.eth.personal.newAccount("password");
web3.eth.personal.unlockAccount("0x0Address", "password", 1000);
```

**How to import a wallet**

```
import { EthersWallet as EW } from 'lightstreams-js-sdk';

const encryptedJson = await EW.Keystore.createRandomWallet(password);
web3.currentProvider.importAccount(encryptedJson);
```

### 3. ENS

Learn more about it in [official docs](https://docs.ens.domains/).

**How to register new tld**

```javascript
import { ENS } from 'lightstreams-js-sdk';

const account = "0x0Address"; // Owner account
const tld = "lsn"
const { ensAddress, resolverAddress } = await ENS.SDK.deployNewRegistry(web3, { from: account });
await ENS.SDK.registerNode(web3, { ensAddress, from: account, node: tld});
```

**How to use ENS official sdk** Read docs [here](https://docs.ens.domains/dapp-developer-guide/working-with-ens)

```javascript
const domain = 'fanbase.lsn';
const ens = ENS.SDK.initializeManager(web3.currentProvider, ensAddress);
console.log(`Registering ${domain}...`);
await ens.setSubnodeOwner(domain, account, { from: account });
console.log(`Setting resolver ...`);
await ens.setResolver(domain, resolverAddress, { from: account });
console.log(`Setting address ...`);
await ens.resolver(domain).setAddr(account, { from: account });
let address = await ens.resolver(domain).addr();
console.log(`${domain} is pointing to ${address}`);
```

### 4. Smart vault

#### 4.1 Gateway proxy

**Sample usage**

```
const { Gateway as useGateway }  = require('lightstreams-js-sdk')
const gateway = useGateway('https://gateway.sirius.lightstreams.io')
```

Once `LightstreamsSDK` is initialized you interact with it as follow:

```
// Get user balance
const account = "0xa981f8ca77d069d79b609ca0069b052db79e7e30"
const { balance } = await gateway.wallet.balance(account)
```

**Available Methods**

Gateway SDK interface is made to match, one to one, every available [smart vault endpoints](https://docs.lightstreams.network/api-docs).

* [/user/signup](https://docs.lightstreams.network/api-docs/#operation/userSignup)  ->  `gateway.user.signUp(password)`
* [/user/signin](https://docs.lightstreams.network/api-docs/#operation/userSignin) -> `gateway.user.signIn(account, password)`
* [/wallet/balance](https://docs.lightstreams.network/api-docs/#operation/walletBalance) -> `gateway.wallet.balance(account)`
* [/wallet/transfer](https://docs.lightstreams.network/api-docs/#operation/walletTransfer) -> `gateway.wallet.transfer(from, password, to, amountWei)`
* [/storage/add](https://docs.lightstreams.network/api-docs/#tag/Storage) -> `gateway.storage.add(owner, password, file)`
* [/storage/fetch](https://docs.lightstreams.network/api-docs/#operation/storageFetch) -> `gateway.storage.fetch(meta, token, stream)`
* [/acl/grant](https://docs.lightstreams.network/api-docs/#operation/aclGrant) -> `gateway.acl.grant(acl, owner, password, to, permission)`
* /acl/revoke   ->  `gateway.acl.revoke(acl, owner, password, to)`
* [/acl/grant-public](https://docs.lightstreams.network/api-docs/#operation/aclGrantPublic) ->  `gateway.acl.grantPublic(acl, owner, password)`
* [/acl/revoke-public](https://docs.lightstreams.network/api-docs/#operation/aclRevoke) -> `gateway.acl.revokePublic(acl, owner, password)`
* [/shop/create](https://docs.lightstreams.network/api-docs/#operation/shopCreate) -> `gateway.shop.create(from, password)`
* [/shop/shell](https://docs.lightstreams.network/api-docs/#operation/shopSell) ->  `gateway.shop.sell(shop, from, password, acl, priceWei)`
* [/shop/buy](https://docs.lightstreams.network/api-docs/#operation/shopBuy) -> `gateway.shop.buy(shop, from, password, acl)`
* [/erc20/balance](https://docs.lightstreams.network/api-docs/#operation/erc20Balance) -> `gateway.erc20.balance(erc20_address, account)`
* [/erc20/transfer](https://docs.lightstreams.network/api-docs/#operation/erc20Transfer)    ->  `gateway.erc20.transfer(erc20_address, from, password, to, amount)`
* [/erc20/purchase](https://docs.lightstreams.network/api-docs/#operation/erc20Purchase)    -> `gateway.erc20.purchase(erc20_address, account, password, amount_wei)`

####

##


# Smart Vault CLI

Lightstreams Command Line Tool.

Leth is the Command Line Interface tool for interacting with a Lightstreams node and Smart Vault. Leth also exposes a HTTP API for accessing these same commands from a client.

## leth

The Leth tool run at the command line.

```
leth [flags]
```

**Options**

```
  -h, --help   help for leth
```

## acl

Features Leth Access Control List (ACL) capabilities such as granting file permissions.

```
leth acl [flags]
```

**Options**

```
  -h, --help   help for acl
```

## acl grant

Grant an ACL permission to another account.

Usage:

```
leth acl grant --nodeid=1 --network=rinkeby --permission=read --acl=0xd966aa573f8AcBfEb3724B661B420c258ceA5D38 --owner=0xadC486F16F003897fb927e22438cb1b820f79879 --to=0xadc486f16f003897fb927e22438cb1b820f79879
```

Possible Outputs:

```
{"is/granted":"true"}
{"error": {"code": "SOME/INTERNAL/ERROR/CODE", "message": "explanatory error message"}}
```

```
leth acl grant [flags]
```

**Options**

```
      --acl string          ACL ID (Deployed Smart Contract Hex Addr) associated with the stored file.
  -h, --help                help for grant
      --network string      Possible values: 'sirius', 'mainnet', 'standalone', 'rinkeby', 'ganache'.
      --nodeid int          ID of the node in order to support multiple nodes on the same machine. 0 by default.
      --owner string        The account with rights to grant the ACL permission.
      --permission string   Permission to grant. Possible values: [noaccess,read,write,admin]
      --to string           Account address to whom the permission should be granted.
```

## acl grant-public

Grant a read access to everybody.

Usage:

```
leth acl grant-public --nodeid=1 --network=rinkeby --acl=0xd966aa573f8AcBfEb3724B661B420c258ceA5D38 --owner=0xadC486F16F003897fb927e22438cb1b820f79879
```

Possible Outputs:

```
{"is/granted":"true"}
{"error": {"code": "SOME/INTERNAL/ERROR/CODE", "message": "explanatory error message"}}
```

```
leth acl grant-public [flags]
```

**Options**

```
      --acl string       ACL ID (Deployed Smart Contract Hex Addr) associated with the stored file.
  -h, --help             help for grant-public
      --network string   Possible values: 'sirius', 'mainnet', 'standalone', 'rinkeby', 'ganache'.
      --nodeid int       ID of the node in order to support multiple nodes on the same machine. 0 by default.
      --owner string     The account with rights to grant the ACL permission.
```

## acl revoke-public

Revoke a public read access from everybody.

Usage:

```
leth acl revoke-public --nodeid=1 --network=rinkeby --acl=0xd966aa573f8AcBfEb3724B661B420c258ceA5D38 --owner=0xadC486F16F003897fb927e22438cb1b820f79879
```

Possible Outputs:

```
{"is/revoked":"true"}
{"error": {"code": "SOME/INTERNAL/ERROR/CODE", "message": "explanatory error message"}}
```

```
leth acl revoke-public [flags]
```

**Options**

```
      --acl string       ACL ID (Deployed Smart Contract Hex Addr) associated with the stored file.
  -h, --help             help for revoke-public
      --network string   Possible values: 'sirius', 'mainnet', 'standalone', 'rinkeby', 'ganache'.
      --nodeid int       ID of the node in order to support multiple nodes on the same machine. 0 by default.
      --owner string     The account with rights to grant the ACL permission.
```

## auth

Verifies that an authentication token is valid.

Usage:

```
leth auth --nodeid=1 --network=rinkeby --peer=QmW6hffkDWCYK988j1oyAi26F6HEkHDvQ7qKKxoSNJwmyS --token=eyJibG9ja2NoYWluIjoiRVRIIiwiZXRoX2FkZHJlc3MiOiIweEM5NjZhYTU3MzA4QWNCZkViMzcyNkI2NjFCQzIwYzI1OGNlQTVEMzgiLCJpYXQiOjI3NzExNDUsImVhdCI6Mjc3MTIwNX0.2Z2Qm8MSVaTTVZRbtIjuKjjQXYFuprmmo5Okat85RiIkEwIFQObaimFkCieonHG6dyFqKx6h-hFdGeV8DbtEbAE
```

Possible Outputs:

```
{"is/authenticated":"true","user":"0xC966aa57308AcBfEb3726B661BC20c258ceA5D38"}
{"error": {"code": "SOME/INTERNAL/ERROR/CODE", "message": "explanatory error message"}}
```

```
leth auth [flags]
```

**Options**

```
  -h, --help             help for auth
      --network string   Possible values: 'sirius', 'mainnet', 'standalone', 'rinkeby', 'ganache'.
      --nodeid int       ID of the node in order to support multiple nodes on the same machine. 0 by default.
      --token string     Token to authenticate.
      --peer string      PeerID who generated this token.
```

## docs

Generates LETH / usage docs based on code into the: 'docs/cmd/auto/generated'.

```
leth docs [flags]
```

**Options**

```
  -h, --help   help for docs
```

## init

Initializes new Lightstreams node for connecting to the chosen network.

```
leth init [flags]
```

**Options**

```
      --force            Force node data initialization, erase previous folder in case this exists. False by default.
  -h, --help             help for init
      --network string   Possible values: 'sirius', 'mainnet', 'standalone', 'rinkeby', 'ganache'.
      --nodeid int       ID of the node in order to support multiple nodes on the same machine. 0 by default.
```

## run

Runs full Leth node by spawning blockchain and IPFS daemons.

```
leth run [flags]
```

**Options**

```
  -h, --help             help for run
      --https            Serves an HTTPs server on your localhost. False by default.
      --network string   Possible values: 'sirius', 'mainnet', 'standalone', 'rinkeby', 'ganache'.
      --nodeid int       ID of the node in order to support multiple nodes on the same machine. 0 by default.
```

## shop

Features capabilities for selling/buying digital content.

```
leth shop [flags]
```

**Options**

```
  -h, --help   help for shop
```

## shop buy

Allows an account to purchase permission to access a copy of the digital content from a seller.

Usage:

```
leth shop buy --nodeid=1 --network=rinkeby --shop=0xshopIDF16F003897fb927e22438cb1b820f79879 --acl=0xd966aa573f8AcBfEb3724B661B420c258ceA5D38 --from=0xadC486F16F003897fb927e22438cb1b820f79879
```

Possible Outputs:

```
{"success":"true"}
{"error": {"code": "SOME/INTERNAL/ERROR/CODE", "message": "explanatory error message"}}
```

```
leth shop buy [flags]
```

**Options**

```
      --acl string       ACL ID to buy.
      --from string      The account buying the ACL permission.
  -h, --help             help for buy
      --network string   Possible values: 'sirius', 'mainnet', 'standalone', 'rinkeby', 'ganache'.
      --nodeid int       ID of the node in order to support multiple nodes on the same machine. 0 by default.
      --shop string      Shop ID where ACL can be bought.
```

## shop create

Creates a smart contract for managing the sale of digital content.

Usage:

```
leth shop create --nodeid=1 --network=rinkeby --from=0xadC486F16F003897fb927e22438cb1b820f79879
```

Possible Outputs:

```
{"shop":"0xshopIDF16F003897fb927e22438cb1b820f79879"}
{"error": {"code": "SOME/INTERNAL/ERROR/CODE", "message": "explanatory error message"}}
```

```
leth shop create [flags]
```

**Options**

```
      --from string      The owner of the shop.
  -h, --help             help for create
      --network string   Possible values: 'sirius', 'mainnet', 'standalone', 'rinkeby', 'ganache'.
      --nodeid int       ID of the node in order to support multiple nodes on the same machine. 0 by default.
```

## shop sell

Specifies digital content for sale that to the smart contract controlling access permissions to the digital content.

Usage:

```
leth shop sell --nodeid=1 --network=rinkeby --shop=0xshopIDF16F003897fb927e22438cb1b820f79879 --acl=0xd966aa573f8AcBfEb3724B661B420c258ceA5D38 --price/wei=1000000000000000000 --from=0xadC486F16F003897fb927e22438cb1b820f79879 
```

Possible Outputs:

```
{"success":"true"}
{"error": {"code": "SOME/INTERNAL/ERROR/CODE", "message": "explanatory error message"}}
```

```
leth shop sell [flags]
```

**Options**

```
      --acl leth storage add    ACL ID to sell (returned by leth storage add /).
      --from string             The account with rights to sell an ACL permission in the shop.
  -h, --help                    help for sell
      --network string          Possible values: 'sirius', 'mainnet', 'standalone', 'rinkeby', 'ganache'.
      --nodeid int              ID of the node in order to support multiple nodes on the same machine. 0 by default.
      --price/wei string        For how much PHTs in Wei can users buy this ACL?
      --shop leth shop create   Shop ID where ACL can be sold/bought. (returned by leth shop create /).
```

## user

Capabilities for managing a user's account.&#x20;

```
leth user [flags]
```

**Options**

```
  -h, --help   help for user
```

## user signin

Generates an authentication token to be used verifying a user's identity.&#x20;

Usage:

```
leth user signin --nodeid=1 --network=rinkeby --account=0xadc486f16f003897fb927e22438cb1b820f79879 --peer=QmW6hffkDWCYK988j1oyAi26F6HEkHDvQ7qKKxoSNJwmyS
```

Possible Outputs:

```
{"token":"eyJibG9ja2NoYWluIjoiRVRIIiwiZXRoX2FkZHJlc3MiOiIweGU5Q2JmNjgzRjQ3OTkwMTEzNGE3QTc4RTkxYzljNTIzM2I4RjlDMDQiLCJpYXQiOjMwNTA0NjcsImVhdCI6MzA1MDUyN30.VkAWASrD/20MggH2laXjPlcFpVVPsoLniyTyyTPwFoYV5EQfZG/p/YP-q8u1eyxOpm5Xq4ai5MMcFnu9HBbAE"}
{"error": {"code": "SOME/INTERNAL/ERROR/CODE", "message": "explanatory error message"}}
```

```
leth user signin [flags]
```

**Options**

```
      --account string   Your account HEX address to login with.
  -h, --help             help for signin
      --network string   Possible values: 'sirius', 'mainnet', 'standalone', 'rinkeby', 'ganache'.
      --nodeid int       ID of the node in order to support multiple nodes on the same machine. 0 by default.
      --peer string      The PeerId of the Smart Vault node where this token will be valid for.
```

## user signup

Creates a new user account.

Usage:

```
leth user signup --nodeid=1 --network=rinkeby
```

Possible Outputs:

```
{"account":"0xadc486f16f003897fb927e22438cb1b820f79879","error":""}
{"account":"0x0000000000000000000000000000000000000000","error":"some error message"}
```

```
leth user signup [flags]
```

**Options**

```
  -h, --help             help for signup
      --network string   Possible values: 'sirius', 'mainnet', 'standalone', 'rinkeby', 'ganache'.
      --nodeid int       ID of the node in order to support multiple nodes on the same machine. 0 by default.
```

## version

Returns the version of the Leth tool.

```
leth version [flags]
```

**Options**

```
  -h, --help   help for version
```

## wallet

Capabilities for managing a user's funds.

```
leth wallet [flags]
```

**Options**

```
  -h, --help   help for wallet
```

## wallet balance

Get an account balance in Wei.

Usage:

```
leth wallet balance --nodeid=1 --network=rinkeby --account=0xadc486f16f003897fb927e22438cb1b820f79879
```

Possible Outputs (3ETH):

```
{"balance":"3000000000000000000","error":""}
{"balance":"0","error":"some error message"}
```

```
leth wallet balance [flags]
```

**Options**

```
      --account string   Account address to check balance for.
  -h, --help             help for balance
      --network string   Possible values: 'sirius', 'mainnet', 'standalone', 'rinkeby', 'ganache'.
      --nodeid int       ID of the node in order to support multiple nodes on the same machine. 0 by default.
```

## wallet transfer

Transfer funds from an account to another.

Usage:

```
leth wallet transfer --nodeid=1 --network=rinkeby --from=0xadc486f16f003897fb927e22438cb1b820f79879 --to=0x0dD46808e9780E4a23dd562962300bA029bCfFEf --value=1200000000000000000
```

Possible Outputs:

```
{"success":"true"}
{"error": {"code": "SOME/INTERNAL/ERROR/CODE", "message": "explanatory error message"}}
```

```
leth wallet transfer [flags]
```

### Options

```
      --from string      Account address to transfer Ether from.
  -h, --help             help for transfer
      --network string   Possible values: 'sirius', 'mainnet', 'standalone', 'rinkeby', 'ganache'.
      --nodeid int       ID of the node in order to support multiple nodes on the same machine. 0 by default.
      --to string        Account address to transfer Ether to.
      --value string     Amount of Ether to transfer in Wei format. 1 ETH = 1000000000000000000 Wei
```

###


