## File: README.md

# 

[](LICENSE)
[](https://github.com/linera-io/linera-protocol/actions/workflows/docker-compose.yml)
[](https://github.com/linera-io/linera-protocol/actions/workflows/rust.yml)
[](https://github.com/linera-io/linera-protocol/actions/workflows/documentation.yml)
[](https://x.com/linera_io)
[](https://discord.com/invite/linera)



[Linera](https://linera.io) is a decentralized blockchain infrastructure designed for highly scalable,
secure, low-latency Web3 applications.

## Documentation

Visit our [developer page](https://linera.dev) and read our
[whitepaper](https://linera.io/whitepaper) to learn more about the Linera protocol.

## Repository Structure

The main crates and directories of this repository can be summarized as follows: (listed
from low to high levels in the dependency graph)

* [`linera-base`](https://linera-io.github.io/linera-protocol/linera_base/index.html) Base
  definitions, including cryptography.

* [`linera-version`](https://linera-io.github.io/linera-protocol/linera_version/index.html)
  A library to manage version info in binaries and services.

* [`linera-views`](https://linera-io.github.io/linera-protocol/linera_views/index.html) A
  library mapping complex data structures onto a key-value store. The corresponding
  procedural macros are implemented in `linera-views-derive`.

* [`linera-execution`](https://linera-io.github.io/linera-protocol/linera_execution/index.html)
  Persistent data and the corresponding logic for runtime and execution of Linera
  applications.

* [`linera-chain`](https://linera-io.github.io/linera-protocol/linera_chain/index.html)
  Persistent data and the corresponding logic for chains of blocks, certificates, and
  cross-chain messaging.

* [`linera-storage`](https://linera-io.github.io/linera-protocol/linera_storage/index.html)
  Defines the storage abstractions for the protocol on top of `linera-chain`.

* [`linera-core`](https://linera-io.github.io/linera-protocol/linera_core/index.html) The
  core Linera protocol, including client and server logic, node synchronization, etc.

* [`linera-rpc`](https://linera-io.github.io/linera-protocol/linera_rpc/index.html)
  Defines the data-type for RPC messages (currently all client &#x2194; proxy &#x2194;
  chain &#x2194; chain interactions), and track the corresponding data schemas.

* [`linera-client`](https://linera-io.github.io/linera-protocol/linera_client/index.html)
  Library for writing Linera clients.  Used for the command-line
  client and the node service in `linera-service`, as well as the Web
  client in [`linera-web`](https://github.com/linera-io/linera-web/).

* [`linera-service`](https://linera-io.github.io/linera-protocol/linera_service/index.html)
  Executable for clients (aka CLI wallets), proxy (aka validator frontend) and servers.

* [`linera-sdk`](https://linera-io.github.io/linera-protocol/linera_sdk/index.html) The
  library to develop Linera applications written in Rust for the Wasm virtual machine. The
  corresponding procedural macros are implemented in `linera-sdk-derive`.

* [`examples`](./examples) Examples of Linera applications written in Rust.

## Prerequisites

See [`INSTALL.md`](./INSTALL.md) for software requirements to develop in this repo.

## Quickstart with the Linera CLI tool

The following commands set up a local test network and run some transfers between the
microchains owned by a single wallet.

```bash
# Make sure to compile the Linera binaries and add them in the $PATH.
# cargo build -p linera-storage-service -p linera-service --bins
export PATH="$PWD/target/debug:$PATH"

# Import the optional helper function `linera_spawn`.
source /dev/stdin <<<"$(linera net helper 2>/dev/null)"

# Run a local test network with the default parameters and a number of microchains
# owned by the default wallet. This also defines `LINERA_TMP_DIR`.
linera_spawn \
linera net up --with-faucet --faucet-port 8080

# Remember the URL of the faucet.
FAUCET_URL=http://localhost:8080

# If you're using a testnet, start here and run this instead:
#   LINERA_TMP_DIR=$(mktemp -d)
#   FAUCET_URL=https://faucet.testnet-XXX.linera.net  # for some value XXX
```

Enable logs for user applications:

```bash
export LINERA_APPLICATION_LOGS=true
```

Set the path of the future wallet:

```bash
export LINERA_WALLET="$LINERA_TMP_DIR/wallet.json"
export LINERA_KEYSTORE="$LINERA_TMP_DIR/keystore.json"
export LINERA_STORAGE="rocksdb:$LINERA_TMP_DIR/client.db"

# Initialize a new user wallet.
linera wallet init --faucet $FAUCET_URL

# Request chains.
INFO1=($(linera wallet request-chain --faucet $FAUCET_URL))
INFO2=($(linera wallet request-chain --faucet $FAUCET_URL))
CHAIN1="${INFO1[0]}"
ACCOUNT1="${INFO1[1]}"
CHAIN2="${INFO2[0]}"
ACCOUNT2="${INFO2[1]}"

# Show the different chains tracked by the wallet.
linera wallet show

# Query the chain balance of some of the chains.
linera query-balance "$CHAIN1"
linera query-balance "$CHAIN2"

# Transfer 10 units then 5 back.
linera transfer 10 --from "$CHAIN1" --to "$CHAIN2"
linera transfer 5 --from "$CHAIN2" --to "$CHAIN1"

# Query balances again.
linera query-balance "$CHAIN1"
linera query-balance "$CHAIN2"

# Now let's fund the user balances.
linera transfer 5 --from "$CHAIN1" --to "$ACCOUNT1@$CHAIN1"
linera transfer 2 --from "$ACCOUNT1@$CHAIN1" --to "$ACCOUNT2@$CHAIN2"

# Query user balances again.
linera query-balance "$ACCOUNT1@$CHAIN1"
linera query-balance "$ACCOUNT2@$CHAIN2"
```

More complex examples may be found in our [developer manual](https://linera.dev) as well
as the [example applications](./examples) in this repository.

## Contributing

We welcome contributions from the community! If you'd like to contribute to the Linera protocol:

1. Fork the repository
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request

For detailed guidelines, see our [contribution guide](./CONTRIBUTING.md).

---

## File: examples/agent/README.md

# Linera Agent

This example application runs a Large Language Model (LLM) Agent which uses an LLM
to forge queries by introspecting the Linera Node Service GraphQL API.

## How it works

The agent wraps an LLM of choice and is provided with context on what Linera is and
the core concepts. Further context is provided by performing an introspection query
which injects the Linera Node Service GraphQL schema. The schema is quite large - 
the resulting context in ~15,000 tokens being used just for context.

After the context is provided, a chat is initiated between user and agent, where the
agent writes GraphQL queries on behalf of the user and uses the Linera Node Service 
tool to submit them.

## Usage

Assume a Linera Node Service is running on `localhost:8080` and is connected to a running
network (local or otherwise).

```bash
export OPENAI_API_KEY="..." # Get your OpenAI API key here: https://openai.com/index/openai-api/
cargo run
I'm the Linera agent. How can I help! (Type 'exit' to quit.)
> Hey! What's my default chain?
Req: query { chains { default } }
========================== Response ============================
{"data":{"chains":{"default":"01a7d54c59b43084ae49ebc490bb3c7c1f0924c18e93e62ecddfaf721c98e493"}},"errors":null}
================================================================
```

---

## File: examples/amm/README.md

# Automated Market Maker (AMM) Example Application

This example implements an Automated Market Maker (AMM) which demonstrates the DeFi capabilities of the
Linera protocol. The prerequisite for the AMM application is the `fungible` application, as we will
be adding/removing liquidity and also performing a swap.

## How it works

It supports the following operations. All operations need to be executed remotely.

- Swap: For a given input token and an input amount, it swaps that token amount for an
  amount of the other token calculated based on the current AMM ratio.

- Add Liquidity: This operation allows adding liquidity to the AMM. Given a maximum
  `token0` and `token1` amount that you're willing to add, it adds liquidity such that you'll be
  adding at most `max_token0_amount` of `token0` and `max_token1_amount` of `token1`. The amounts
  will be calculated based on the current AMM ratio. The owner, in this case, refers to the user
  adding liquidity, which currently can only be a chain owner.

- Remove Liquidity: This withdraws tokens from the AMM. Given the index of the token you'd
  like to remove (can be 0 or 1), and the amount of that token that you'd like to remove, it calculates
  how much of the other token will also be removed based on the current AMM ratio. Then it removes
  the amounts from both tokens as a removal of liquidity. The owner, in this context, is the user
  removing liquidity, which currently can only be a chain owner.

## Usage

### Setting Up

Before getting started, make sure that the binary tools `linera*` corresponding to
your version of `linera-sdk` are in your PATH. For scripting purposes, we also assume
that the BASH function `linera_spawn` is defined.

From the root of Linera repository, this can be achieved as follows:

```bash
export PATH="$PWD/target/debug:$PATH"
source /dev/stdin <<<"$(linera net helper 2>/dev/null)"
```

Next, start the local Linera network and run a faucet:

```bash
FAUCET_PORT=8079
FAUCET_URL=http://localhost:$FAUCET_PORT
linera_spawn linera net up --with-faucet --faucet-port $FAUCET_PORT

# If you're using a testnet, run this instead:
#   LINERA_TMP_DIR=$(mktemp -d)
#   FAUCET_URL=https://faucet.testnet-XXX.linera.net  # for some value XXX
```

Enable logs for user applications:

```bash
export LINERA_APPLICATION_LOGS=true
```

Create the user wallet and add chains to it:

```bash
export LINERA_WALLET="$LINERA_TMP_DIR/wallet.json"
export LINERA_KEYSTORE="$LINERA_TMP_DIR/keystore.json"
export LINERA_STORAGE="rocksdb:$LINERA_TMP_DIR/client.db"

linera wallet init --faucet $FAUCET_URL

INFO_AMM=($(linera wallet request-chain --faucet $FAUCET_URL))
INFO_1=($(linera wallet request-chain --faucet $FAUCET_URL))
INFO_2=($(linera wallet request-chain --faucet $FAUCET_URL))
CHAIN_AMM="${INFO_AMM[0]}"
CHAIN_1="${INFO_1[0]}"
CHAIN_2="${INFO_2[0]}"
OWNER_AMM="${INFO_AMM[1]}"
OWNER_1="${INFO_1[1]}"
OWNER_2="${INFO_2[1]}"
```

Now we have to publish and create the fungible applications. The flag `--wait-for-outgoing-messages` waits until a quorum of validators has confirmed that all sent cross-chain messages have been delivered.

```bash
(cd examples/fungible && cargo build --release --target wasm32-unknown-unknown)

FUN1_APP_ID=$(linera --wait-for-outgoing-messages \
  publish-and-create examples/target/wasm32-unknown-unknown/release/fungible_{contract,service}.wasm \
    --json-argument "{ \"accounts\": {
        \"$OWNER_AMM\": \"100.\"
    } }" \
    --json-parameters "{ \"ticker_symbol\": \"FUN1\" }" \
)

FUN2_APP_ID=$(linera --wait-for-outgoing-messages \
  publish-and-create examples/target/wasm32-unknown-unknown/release/fungible_{contract,service}.wasm \
    --json-argument "{ \"accounts\": {
        \"$OWNER_AMM\": \"100.\"
    } }" \
    --json-parameters "{ \"ticker_symbol\": \"FUN2\" }" \
)

(cd examples/amm && cargo build --release --target wasm32-unknown-unknown)
AMM_APPLICATION_ID=$(linera --wait-for-outgoing-messages \
  publish-and-create examples/target/wasm32-unknown-unknown/release/amm_{contract,service}.wasm \
  --json-parameters "{\"tokens\":["\"$FUN1_APP_ID\"","\"$FUN2_APP_ID\""]}" \
  --required-application-ids $FUN1_APP_ID $FUN2_APP_ID)
```

### Using the AMM Application

First, a node service for the current wallet has to be started:

```bash
PORT=8080
linera service --port $PORT &
```

#### Using GraphiQL

Type each of these in the GraphiQL interface and substitute the env variables with their actual
values that we've defined above.

To properly setup the tokens in the proper chains, we need to do some transfer operations:

- Transfer 50 FUN1 from `$OWNER_AMM` in `$CHAIN_AMM` to `$OWNER_1` in `$CHAIN_1`, so they're in the proper chain.
  Run `echo "http://localhost:8080/chains/$CHAIN_AMM/applications/$FUN1_APP_ID"` to print the URL
  of the GraphiQL interface for the FUN1 app. Navigate to that URL and enter:

```gql,uri=http://localhost:8080/chains/$CHAIN_AMM/applications/$FUN1_APP_ID
mutation {
  transfer(
    owner: "$OWNER_AMM",
    amount: "50.",
    targetAccount: {
      chainId: "$CHAIN_1",
      owner: "$OWNER_1",
    }
  )
}
```

- Transfer 50 FUN1 from `$OWNER_AMM` in `$CHAIN_AMM` to `$OWNER_2` in `$CHAIN_2`, so they're in the proper chain:

```gql,uri=http://localhost:8080/chains/$CHAIN_AMM/applications/$FUN1_APP_ID
mutation {
  transfer(
    owner: "$OWNER_AMM",
    amount: "50.",
    targetAccount: {
      chainId: "$CHAIN_2",
      owner: "$OWNER_2",
    }
  )
}
```

- Transfer 50 FUN2 from `$OWNER_AMM` in `$CHAIN_AMM` to `$OWNER_1` in `$CHAIN_1`, so they're in the proper chain.
  Since this is the other token, FUN2, we need to go to its own GraphiQL interface:
  `echo "http://localhost:8080/chains/$CHAIN_AMM/applications/$FUN2_APP_ID"`.

```gql,uri=http://localhost:8080/chains/$CHAIN_AMM/applications/$FUN2_APP_ID
mutation {
  transfer(
    owner: "$OWNER_AMM",
    amount: "50.",
    targetAccount: {
      chainId: "$CHAIN_1",
      owner: "$OWNER_1",
    }
  )
}
```

- Transfer 50 FUN2 from `$OWNER_AMM` in `$CHAIN_AMM` to `$OWNER_2` in `$CHAIN_2`, so they're in the proper chain:

```gql,uri=http://localhost:8080/chains/$CHAIN_AMM/applications/$FUN2_APP_ID
mutation {
  transfer(
    owner: "$OWNER_AMM",
    amount: "50.",
    targetAccount: {
      chainId: "$CHAIN_2",
      owner: "$OWNER_2",
    }
  )
}
```

All operations can only be from a remote chain i.e. other than the chain on which `AMM` is deployed to.

Before performing any operation we need to provide liquidity to it, so we will use the `AddLiquidity` operation,
navigate to the URL you get by running `echo "http://localhost:8080/chains/$CHAIN_1/applications/$AMM_APPLICATION_ID"`.

To perform the `AddLiquidity` operation:

```gql,uri=http://localhost:8080/chains/$CHAIN_1/applications/$AMM_APPLICATION_ID
mutation {
  addLiquidity(
    owner: "$OWNER_1",
    maxToken0Amount: "50",
    maxToken1Amount: "50",
  )
}
```

To perform the `Swap` operation, navigate to the URL you get by running `echo "http://localhost:8080/chains/$CHAIN_2/applications/$AMM_APPLICATION_ID"` and
perform the following mutation:

```gql,uri=http://localhost:8080/chains/$CHAIN_2/applications/$AMM_APPLICATION_ID
mutation {
  swap(
    owner: "$OWNER_2",
    inputTokenIdx: 1,
    inputAmount: "1",
  )
}
```

To perform the `RemoveLiquidity` operation, navigate to the URL you get by running `echo "http://localhost:8080/chains/$CHAIN_1/applications/$AMM_APPLICATION_ID"` and
perform the following mutation:

```gql,uri=http://localhost:8080/chains/$CHAIN_1/applications/$AMM_APPLICATION_ID
mutation {
  removeLiquidity(
    owner: "$OWNER_1",
    tokenToRemoveIdx: 1,
    tokenToRemoveAmount: "1",
  )
}
```

To perform the `RemoveAllAddedLiquidity` operation, navigate to the URL you get by running `echo "http://localhost:8080/chains/$CHAIN_1/applications/$AMM_APPLICATION_ID"` and
perform the following mutation:

```gql,uri=http://localhost:8080/chains/$CHAIN_1/applications/$AMM_APPLICATION_ID
mutation {
  removeAllAddedLiquidity(
    owner: "$OWNER_1",
  )
}
```

#### Atomic Swaps

In general, if you send tokens to a chain owned by someone else, you rely on them
for asset availability: If they don't handle your messages, you don't have access to
your tokens.

Fortunately, Linera provides a solution based on temporary chains:
If the number of parties who want to swap tokens is limited, we can make them all chain
owners, allow only AMM operations on the chain, and allow only the AMM to close the chain.
In addition, we make an AMM operation per block mandatory, so owners cannot spam the chain
with empty blocks.

```bash
kill %% && sleep 1    # Kill the service so we can use CLI commands for chain 1.

linera --wait-for-outgoing-messages change-ownership \
    --owners "{\"$OWNER_AMM\":100,\"$OWNER_2\":100}"

linera --wait-for-outgoing-messages change-application-permissions \
    --execute-operations "[\"$AMM_APPLICATION_ID\"]" \
    --mandatory-applications "[\"$AMM_APPLICATION_ID\"]" \
    --manage-chain "[\"$AMM_APPLICATION_ID\"]"

linera service --port $PORT &
```

First, let's add some liquidity again to the AMM. Navigate to the URL you get by running
`echo "http://localhost:8080/chains/$CHAIN_1/applications/$AMM_APPLICATION_ID"` and perform the following mutation:

```gql,uri=http://localhost:8080/chains/$CHAIN_1/applications/$AMM_APPLICATION_ID
mutation {
  addLiquidity(
    owner: "$OWNER_1",
    maxToken0Amount: "40",
    maxToken1Amount: "40",
  )
}
```

The only way to close the chain is via the application. Navigate to the URL you get by running
`echo "http://localhost:8080/chains/$CHAIN_AMM/applications/$AMM_APPLICATION_ID"` and perform the following mutation:

```gql,uri=http://localhost:8080/chains/$CHAIN_AMM/applications/$AMM_APPLICATION_ID
mutation { closeChain }
```

Owner 1 should now get back their tokens, and have around 49 FUN1 left and 51 FUN2 left. To check that, navigate
to the URL you get by running `echo "http://localhost:8080/chains/$CHAIN_1/applications/$FUN1_APP_ID"`, and perform the following mutation:

```gql,uri=http://localhost:8080/chains/$CHAIN_1/applications/$FUN1_APP_ID
query {
    accounts {
        entry(
            key: "$OWNER_1"
        ) {
            value
        }
    }
}
```

Then navigate to the URL you get by running `echo "http://localhost:8080/chains/$CHAIN_1/applications/$FUN2_APP_ID"`, and perform the following mutation:

```gql,uri=http://localhost:8080/chains/$CHAIN_1/applications/$FUN2_APP_ID
query {
    accounts {
        entry(
            key: "$OWNER_1"
        ) {
            value
        }
    }
}
```

---

## File: examples/counter/README.md

# Counter Example Application

This example application implements a simple counter contract, it is initialized with an
unsigned integer that can be increased by the `increment` operation.

## How It Works

It is a simple Linera application, which is initialized by a `u64` which can be incremented
by a `u64`.

For example, if the contract was initialized with 1, querying the contract would give us 1. Now if we want to
`increment` it by 3, we will have to perform an operation with the parameter being 3. Now querying the
application would give us 4 (1+3 = 4).

## Setup and Deployment

Before getting started, make sure that the binary tools `linera*` corresponding to
your version of `linera-sdk` are in your PATH. For scripting purposes, we also assume
that the BASH function `linera_spawn` is defined.

From the root of Linera repository, this can be achieved as follows:

```bash
export PATH="$PWD/target/debug:$PATH"
eval "$(linera net helper 2>/dev/null)"
```

Next, start the local Linera network and run a faucet:

```bash
LINERA_FAUCET_PORT=8079
LINERA_FAUCET_URL=http://localhost:$LINERA_FAUCET_PORT
linera_spawn linera net up --with-faucet --faucet-port $LINERA_FAUCET_PORT

# If you're using a testnet, run this instead:
#   LINERA_TMP_DIR=$(mktemp -d)
#   export LINERA_FAUCET_URL=https://faucet.testnet-XXX.linera.net  # for some value XXX
```

Enable logs for user applications:

```bash
export LINERA_APPLICATION_LOGS=true
```

Create the user wallet and add chains to it:

```bash
export LINERA_WALLET="$LINERA_TMP_DIR/wallet.json"
export LINERA_KEYSTORE="$LINERA_TMP_DIR/keystore.json"
export LINERA_STORAGE="rocksdb:$LINERA_TMP_DIR/client.db"

linera wallet init --faucet $LINERA_FAUCET_URL

INFO=($(linera wallet request-chain --faucet $LINERA_FAUCET_URL))
CHAIN="${INFO[0]}"
OWNER="${INFO[1]}"
```

Now, compile the `counter` application WebAssembly binaries, publish and create an application instance.

```bash
cd examples/counter
cargo build --release --target wasm32-unknown-unknown

LINERA_APPLICATION_ID=$(linera publish-and-create \
  ../target/wasm32-unknown-unknown/release/counter_{contract,service}.wasm \
  --json-argument "1")
```

We have saved the `LINERA_APPLICATION_ID` as it will be useful later.

## Connecting with the Web Frontend

If you install the dependencies for the Web frontend and export the
necessary variables you can run a local development server using Vite:

```bash,ignore
export LINERA_APPLICATION_ID LINERA_FAUCET_URL
pnpm install
pnpm dev
```

This will start a server and print its address; access that URL to use
the application frontend.

Alternatively, there is a frontend in `metamask` that signs
transactions using the user's MetaMask wallet; it can be accessed the
same way.

## Connecting with the GraphQL Client

Alternatively, you can connect to the application using the GraphQL
client.  This is useful for inspecting and debugging the backend APIs.

First, a node service for the current wallet has to be started:

```bash
PORT=8080
linera service --port $PORT &
echo "http://localhost:8080/chains/$CHAIN/applications/$LINERA_APPLICATION_ID"
```

Clicking the printed URL will take you to a
[GraphiQL](https://www.gatsbyjs.com/docs/how-to/querying-data/running-queries-with-graphiql/)
environment connected to your app.

To get the current value of `counter`, you can run the query:

```gql,uri=http://localhost:8080/chains/$CHAIN/applications/$LINERA_APPLICATION_ID
query {
  value
}
```

To increase the value of the counter, you can run the `increment`
mutation. Note that the result of a mutation is the hash of the
resulting block, if any.

```gql,uri=http://localhost:8080/chains/$CHAIN/applications/$LINERA_APPLICATION_ID
mutation Increment {
  increment(value: 3)
}
```

If you run the query again, you'll now see a value of 4.

---

## File: examples/counter-no-graphql/README.md

# Counter No GraphQL Example Application

This example application implements a simple counter contract, it is initialized with an
unsigned integer that can be increased by the `increment` operation. In contrast with the
counter application, it works without GraphQL.

## How It Works

It is a simple Linera application, which is initialized by a `u64` which can be incremented
by a `u64`.

For example, if the contract was initialized with 1, querying the contract would give us 1. Now if we want to
`increment` it by 3, we will have to perform an operation with the parameter being 3. Now querying the
application would give us 4 (1+3 = 4).

## Usage

---

## File: examples/crowd-funding/README.md

# Crowd-funding Example Application

This example application implements crowd-funding campaigns using fungible tokens in
the `fungible` application. This demonstrates how to compose applications together and
how to instantiate applications where one chain has a special role.

Once an application is built and its module published on a Linera chain, the
published module can be used to create different instances. Each instance or crowd-funding
represents a different campaign.

## How It Works

The chain that created the campaign is called the "campaign chain". It is owned by the
creator (and beneficiary) of the campaign.

The goal of a crowd-funding campaign is to let people pledge any number of tokens from
their own chain(s). If enough tokens are pledged before the campaign expires, the campaign is
_successful_ and the creator can receive all the funds, including ones exceeding the funding
target. Otherwise, the campaign is _unsuccessful_ and contributors should be refunded.

## Caveat

Currently, only the owner of the campaign can create blocks that contain the `Cancel`
operation. In the future, campaign chains will not be single-owner chains and should
instead allow contributors (users with a pledge) to cancel the campaign if
appropriate (even without the owner's cooperation).

Optionally, contributors may also be able to create a block to accept a new epoch
(i.e. a change of validators).



## Usage

### Setting Up

The WebAssembly binaries for the module can be built and published using [steps from the
book](https://linera.dev/developers/getting_started.html),
summarized below.

Set up the path and the helper function. From the root of Linera repository, this can be
achieved as follows:

```bash
export PATH="$PWD/target/debug:$PATH"
source /dev/stdin <<<"$(linera net helper 2>/dev/null)"
```

Start the local Linera network and run a faucet:

```bash
FAUCET_PORT=8079
FAUCET_URL=http://localhost:$FAUCET_PORT
linera_spawn linera net up --with-faucet --faucet-port $FAUCET_PORT

# If you're using a testnet, run this instead:
#   LINERA_TMP_DIR=$(mktemp -d)
#   FAUCET_URL=https://faucet.testnet-XXX.linera.net  # for some value XXX
```

Enable logs for user applications:

```bash
export LINERA_APPLICATION_LOGS=true
```

Create the user wallets and add chains to them:

```bash
export LINERA_WALLET_1="$LINERA_TMP_DIR/wallet_1.json"
export LINERA_KEYSTORE_1="$LINERA_TMP_DIR/keystore_1.json"
export LINERA_STORAGE_1="rocksdb:$LINERA_TMP_DIR/client_1.db"
export LINERA_WALLET_2="$LINERA_TMP_DIR/wallet_2.json"
export LINERA_KEYSTORE_2="$LINERA_TMP_DIR/keystore_2.json"
export LINERA_STORAGE_2="rocksdb:$LINERA_TMP_DIR/client_2.db"

linera --with-wallet 1 wallet init --faucet $FAUCET_URL
linera --with-wallet 2 wallet init --faucet $FAUCET_URL

INFO_1=($(linera --with-wallet 1 wallet request-chain --faucet $FAUCET_URL))
INFO_2=($(linera --with-wallet 2 wallet request-chain --faucet $FAUCET_URL))
CHAIN_1="${INFO_1[0]}"
CHAIN_2="${INFO_2[0]}"
OWNER_1="${INFO_1[1]}"
OWNER_2="${INFO_2[1]}"
```

Note that `linera --with-wallet 1` is equivalent to `linera --wallet "$LINERA_WALLET_1" --keystore "$LINERA_KEYSTORE_1"
--storage "$LINERA_STORAGE_1"`.

The command below can be used to list the chains created for the test as known by each
wallet:

```bash
linera --with-wallet 1 wallet show
linera --with-wallet 2 wallet show
```

A table will be shown with the chains registered in the wallet and their meta-data:

```text,ignore
╭──────────────────────────────────────────────────────────────────┬──────────────────────────────────────────────────────────────────────────────────────╮
│ Chain Id                                                         ┆ Latest Block                                                                         │
╞══════════════════════════════════════════════════════════════════╪══════════════════════════════════════════════════════════════════════════════════════╡
│ 582843bc9322ed1928239ce3f6a855f6cd9ea94c8690907f113d6d7a8296a119 ┆ Public Key:         84eddaaafce7fb923c3b2494b3d25e54e910490a726ad9b3a2228d3fb18f9874 │
│                                                                  ┆ Owner:              849baa540589d95e167d2622018fa341553bf2aff9f328d760443282c6654deb │
│                                                                  ┆ Block Hash:         -                                                                │
│                                                                  ┆ Timestamp:          2023-06-28 09:53:51.167301                                       │
│                                                                  ┆ Next Block Height:  0                                                                │
╰──────────────────────────────────────────────────────────────────┴──────────────────────────────────────────────────────────────────────────────────────╯
```

The default chain of each wallet should be highlighted in green. Each chain has an
`Owner` field, and that is what is used for the account. Let's pick the owners of the
default chain of each wallet and call them `$OWNER_1` and `$OWNER_2`. Remember the corresponding
chain IDs as `$CHAIN_1` (the chain where we just published the application) and `$CHAIN_2`
(some user chain in wallet 2).

### Creating tokens

Compile the Wasm binaries for the two applications `fungible` and `crowd-funding`, publish
them as applications, and give them initial states. This initial state is where the tokens
are minted. After the token is created, no additional tokens can be minted and added to
the application. The initial state is a JSON string that specifies the accounts that start
with tokens.

Create a fungible token application where two accounts start with the minted tokens, one
with 100 of them and another with 200 of them:

```bash
APP_ID_0=$(linera --with-wallet 1 project publish-and-create \
           examples/fungible \
           --json-argument '{ "accounts": { "'$OWNER_1'": "100", "'$OWNER_2'": "200" } }' \
           --json-parameters "{ \"ticker_symbol\": \"FUN\" }")

# Wait for it to fully complete
sleep 8
```

We will remember the application ID for the newly created token as `$APP_ID_0`.

### Creating a crowd-funding campaign

Similarly, we're going to create a crowd-funding campaign on the default chain. We have
to specify our fungible application as a dependency and a parameter:

```bash
APP_ID_1=$(linera --with-wallet 1 \
           project publish-and-create \
           examples/crowd-funding \
           crowd_funding \
           --required-application-ids $APP_ID_0 \
           --json-argument '{ "owner": "'$OWNER_1'", "deadline": 4102473600000000, "target": "100." }' \
           --json-parameters '"'"$APP_ID_0"'"')

# Wait for it to fully complete
sleep 5
```

### Interacting with the campaign

First, a node service has to be started for each wallet, using two different ports:

```bash
linera --with-wallet 1 service --port 8080 &

# Wait for it to fully complete
sleep 2

linera --with-wallet 2 service --port 8081 &

# Wait for it to fully complete
sleep 2
```

Type each of these in the GraphiQL interface and substitute the env variables with their actual values that we've defined above.

Point your browser to http://localhost:8080, and enter the query:

```gql,uri=http://localhost:8080
query { applications(
  chainId: "$CHAIN_1"
) { id link } }
```

The response will have two entries, one for each application.

On both http://localhost:8080 and http://localhost:8081, you recognize the crowd-funding
application by its ID. The entry also has a field `link`. If you open that in a new tab, you
see the GraphQL API for that application on that chain.

Let's pledge 30 tokens by the campaign creator themselves.
For `$OWNER_1` on 8080, run `echo "http://localhost:8080/chains/$CHAIN_1/applications/$APP_ID_1"` to get the URL, open it
and run the following query:

```gql,uri=http://localhost:8080/chains/$CHAIN_1/applications/$APP_ID_1
mutation { pledge(
  owner:"$OWNER_1",
  amount:"30."
) }
```

This will make the owner show up if we list everyone who has made a pledge so far:

```gql,uri=http://localhost:8080/chains/$CHAIN_1/applications/$APP_ID_1
query { pledges { keys } }
```

To also have `$OWNER_2` make a pledge, they first need to claim their tokens. Those are still
on the other chain, where the application was created. To get the link on 8081
for the fungible application, run `echo "http://localhost:8081/chains/$CHAIN_2/applications/$APP_ID_0"`,
open it and run the following query:

```gql,uri=http://localhost:8081/chains/$CHAIN_2/applications/$APP_ID_0
mutation { claim(
  sourceAccount: {
    owner: "$OWNER_2",
    chainId: "$CHAIN_1"
  },
  amount: "200.",
  targetAccount: {
    owner: "$OWNER_2",
    chainId: "$CHAIN_2"
  }
) }
```

You can check that the 200 tokens have arrived:

```gql,uri=http://localhost:8081/chains/$CHAIN_2/applications/$APP_ID_0
query {
  accounts { entry(key: "$OWNER_2") { value } }
}
```

Now, also on 8081, you can open the link for the crowd-funding
application you get when you run `echo "http://localhost:8081/chains/$CHAIN_2/applications/$APP_ID_1"`
and run:

```gql,uri=http://localhost:8081/chains/$CHAIN_2/applications/$APP_ID_1
mutation { pledge(
  owner:"$OWNER_2",
  amount:"80."
) }
```

This pledges another 80 tokens. With 110 pledged in total, we have now reached the campaign
goal. Now the campaign owner (on 8080) can collect the funds:

```gql,uri=http://localhost:8080/chains/$CHAIN_1/applications/$APP_ID_1
mutation { collect }
```

Get the fungible application on
8080 URL by running `echo "http://localhost:8080/chains/$CHAIN_1/applications/$APP_ID_0"`,
then check that we have received 110 tokens, in addition to the
70 that we had left after pledging 30 by running the following query:

```gql,uri=http://localhost:8080/chains/$CHAIN_1/applications/$APP_ID_0
query {
  accounts { entry(key: "$OWNER_1") { value } }
}
```

---

## File: examples/fungible/web-frontend/README.md

# Getting Started with the Fungible App.

This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).

The application (contract/service) must be deployed on the network, and a Node Service must be running
on port 8080.

Web UIs for specific accounts can be opened by navigating URLs of the form
`http://localhost:3000/$CHAIN?app=$APP_ID&owner=$OWNER&port=$PORT` where
- the path is the ID of the chain where the account is located.
- the argument `app` is the token application ID obtained when creating the token.
- `owner` is the address of the chosen user account (owner must have permissions to create blocks in the given chain).
- `port` is the port of the wallet service (the wallet must know the secret key of `owner`).

## Available Scripts

In the project directory, you can run:

### `npm start`

Runs the app in the development mode.\
Open [http://localhost:3000](http://localhost:3000) to view it in your browser.

The page will reload when you make changes.\
You may also see any lint errors in the console.

### `npx prettier --write .`

Formats the project using `prettier`.

### `npm run compile`

Generates necessary graphql types `codegen.ts`

### `npm run build`

Builds the app for production to the `build` folder.\
It bundles React in production mode and optimizes the build for the best performance.

The build is minified and the filenames include the hashes.\
Your app is ready to be deployed!

See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.

### `npm run eject`

**Note: this is a one-way operation. Once you `eject`, you can't go back!**

If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.

Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own.

You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it.

## Learn More

To learn React, check out the [React documentation](https://reactjs.org/).

---

## File: examples/fungible/README.md

# Fungible Token Example Application

This example application implements fungible tokens. This demonstrates in particular
cross-chain messages and how applications are instantiated and auto-deployed.

Once this application is built and its module published on a Linera chain, the
published module can be used to create multiple application instances, where each
instance represents a different fungible token.

## How It Works

Individual chains have a set of accounts, where each account has an owner and a balance. The
same owner can have accounts on multiple chains, with a different balance on each chain. This
means that an account's balance is sharded across one or more chains.

There are two operations: `Transfer` and `Claim`. `Transfer` sends tokens from an account on the
chain where the operation is executed, while `Claim` sends a message from the current chain to
another chain in order to transfer tokens from that remote chain.

Tokens can be transferred from an account to different destinations, such as:

- other accounts on the same chain,
- the same account on another chain,
- other accounts on other chains.

## Usage

### Setting Up

The WebAssembly binaries for the module can be built and published using [steps from the
book](https://linera.dev/developers/getting_started.html),
summarized below.

Before getting started, make sure that the binary tools `linera*` corresponding to
your version of `linera-sdk` are in your PATH. For scripting purposes, we also assume
that the BASH function `linera_spawn` is defined.

From the root of Linera repository, this can be achieved as follows:

```bash
export PATH="$PWD/target/debug:$PATH"
source /dev/stdin <<<"$(linera net helper 2>/dev/null)"
```

Next, start the local Linera network and run a faucet:

```bash
FAUCET_PORT=8079
FAUCET_URL=http://localhost:$FAUCET_PORT
linera_spawn linera net up --with-faucet --faucet-port $FAUCET_PORT

# If you're using a testnet, run this instead:
#   LINERA_TMP_DIR=$(mktemp -d)
#   FAUCET_URL=https://faucet.testnet-XXX.linera.net  # for some value XXX
```

Enable logs for user applications:

```bash
export LINERA_APPLICATION_LOGS=true
```

Create the user wallet and add chains to it:

```bash
export LINERA_WALLET="$LINERA_TMP_DIR/wallet.json"
export LINERA_KEYSTORE="$LINERA_TMP_DIR/keystore.json"
export LINERA_STORAGE="rocksdb:$LINERA_TMP_DIR/client.db"

linera wallet init --faucet $FAUCET_URL

INFO_1=($(linera wallet request-chain --faucet $FAUCET_URL))
CHAIN_1="${INFO_1[0]}"
OWNER_1="${INFO_1[1]}"
INFO_2=($(linera wallet request-chain --faucet $FAUCET_URL))
CHAIN_2="${INFO_2[0]}"
OWNER_2="${INFO_2[1]}"
```

Now, compile the `fungible` application WebAssembly binaries, and publish them as an application
bytecode:

```bash
(cd examples/fungible && cargo build --release --target wasm32-unknown-unknown)

MODULE_ID=$(linera publish-module \
    examples/target/wasm32-unknown-unknown/release/fungible_{contract,service}.wasm)
```

Here, we stored the new module ID in a variable `MODULE_ID` to be reused it later.

### Creating a Token

In order to use the published module to create a token application, the initial state must be
specified. This initial state is where the tokens are minted. After the token is created, no
additional tokens can be minted and added to the application. The initial state is a JSON string
that specifies the accounts that start with tokens.

In order to select the accounts to have initial tokens, the command below can be used to list
the chains created for the test in the default wallet:

```bash
linera wallet show
```

A table will be shown with the chains registered in the wallet and their meta-data. The default
chain should be highlighted in green. Each chain has an `Owner` field, and that is what is used
for the account.

The example below creates a token application on the default chain CHAIN_1 and gives the owner 100 tokens:

```bash
APP_ID=$(linera create-application $MODULE_ID \
    --json-argument "{ \"accounts\": {
        \"$OWNER_1\": \"100.\"
    } }" \
    --json-parameters "{ \"ticker_symbol\": \"FUN\" }" \
)
```

This will store the application ID in a new variable `APP_ID`.

### Using the Token Application

Before using the token, a source and target address should be selected. The source address
should ideally be on the default chain (used to create the token) and one of the accounts chosen
for the initial state, because it will already have some initial tokens to send.

First, a node service for the current wallet has to be started:

```bash
PORT=8080
linera service --port $PORT &
```

#### Using GraphiQL

Type each of these in the GraphiQL interface and substitute the env variables with their actual values that we've defined above.

- Navigate to the URL you get by running `echo "http://localhost:8080/chains/$CHAIN_1/applications/$APP_ID"`.
- To get the current balance of user $OWNER_1, run the query:

```gql,uri=http://localhost:8080/chains/$CHAIN_1/applications/$APP_ID
query {
  accounts {
    entry(
      key: "$OWNER_1"
    ) {
      value
    }
  }
}
```

- To get the current balance of user $OWNER_2, run the query:

```gql,uri=http://localhost:8080/chains/$CHAIN_1/applications/$APP_ID
query {
  accounts {
    entry(
      key: "$OWNER_2"
    ) {
      value
    }
  }
}
```

- To transfer 50 tokens from $OWNER_1 to $OWNER_2

```gql,uri=http://localhost:8080/chains/$CHAIN_1/applications/$APP_ID
mutation {
  transfer(
    owner: "$OWNER_1",
    amount: "50.",
    targetAccount: {
      chainId: "$CHAIN_1",
      owner: "$OWNER_2"
    }
  )
}
```

- To get the new balance of user $OWNER_1, run the query:

```gql,uri=http://localhost:8080/chains/$CHAIN_1/applications/$APP_ID
query {
  accounts {
    entry(
      key: "$OWNER_1"
    ) {
      value
    }
  }
}
```

- To get the new balance of user $OWNER_2, run the query:

```gql,uri=http://localhost:8080/chains/$CHAIN_1/applications/$APP_ID
query {
  accounts {
    entry(
      key: "$OWNER_2"
    ) {
      value
    }
  }
}
```

#### Using web frontend

Installing and starting the web server:

```bash
cd examples/fungible/web-frontend
npm install --no-save

# Start the server but not open the web page right away.
BROWSER=none npm start &
```

Web UIs for specific accounts can be opened by navigating URLs of the form
`http://localhost:3000/$CHAIN?app=$APP_ID&owner=$OWNER&port=$PORT` where

- the path is the ID of the chain where the account is located.
- the argument `app` is the token application ID obtained when creating the token.
- `owner` is the address of the chosen user account (owner must have permissions to create blocks in the given chain).
- `port` is the port of the wallet service (the wallet must know the secret key of `owner`).

In this example, two web pages for OWNER_1 and OWNER_2 can be opened by navigating these URLs:

```bash
echo "http://localhost:3000/$CHAIN_1?app=$APP_ID&owner=$OWNER_1&port=$PORT"
echo "http://localhost:3000/$CHAIN_1?app=$APP_ID&owner=$OWNER_2&port=$PORT"
```

OWNER_2 doesn't have the applications loaded initially. Using the first page to
transfer tokens from OWNER_1 to OWNER_2 at CHAIN_2 will instantly update the UI of the
second page.

---

## File: examples/gen-nft/web-frontend/README.md

# Getting Started with the Gen-NFT App

This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).

The application (contract/service) must be deployed on the network, and a Node Service must be running
on port 8080.

Web UIs for specific accounts can be opened by navigating URLs of the form
`http://localhost:3000/$CHAIN?app=$APP_ID&owner=$OWNER&port=$PORT` where
- the path is the ID of the chain where the account is located.
- the argument `app` is the token application ID obtained when creating the token.
- `owner` is the address of the chosen user account (owner must have permissions to create blocks in the given chain).
- `port` is the port of the wallet service (the wallet must know the secret key of `owner`).

## Available Scripts

In the project directory, you can run:

### `npm start`

Runs the app in the development mode.\
Open [http://localhost:3000](http://localhost:3000) to view it in your browser.

The page will reload when you make changes.\
You may also see any lint errors in the console.

### `npm test`

Launches the test runner in the interactive watch mode.\
See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.

### `npm run build`

Builds the app for production to the `build` folder.\
It correctly bundles React in production mode and optimizes the build for the best performance.

The build is minified and the filenames include the hashes.\
Your app is ready to be deployed!

See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.

### `npm run eject`

**Note: this is a one-way operation. Once you `eject`, you can't go back!**

If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.

Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own.

You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it.

## Learn More

You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).

To learn React, check out the [React documentation](https://reactjs.org/).

### Code Splitting

This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting)

### Analyzing the Bundle Size

This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size)

### Making a Progressive Web App

This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app)

### Advanced Configuration

This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration)

### Deployment

This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment)

### `npm run build` fails to minify

This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify)