linera_sdk/abis/
fungible.rs

1// Copyright (c) Zefchain Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4//! An ABI for applications that implement a fungible token.
5
6use std::collections::BTreeMap;
7
8use async_graphql::{InputObject, Request, Response, SimpleObject};
9use linera_base::{
10    abi::{ContractAbi, ServiceAbi},
11    data_types::Amount,
12    identifiers::{AccountOwner, ChainId},
13};
14use linera_sdk_derive::GraphQLMutationRootInCrate;
15use serde::{Deserialize, Serialize};
16
17/// An ABI for applications that implement a fungible token.
18pub struct FungibleTokenAbi;
19
20impl ContractAbi for FungibleTokenAbi {
21    type Operation = Operation;
22    type Response = FungibleResponse;
23}
24
25impl ServiceAbi for FungibleTokenAbi {
26    type Query = Request;
27    type QueryResponse = Response;
28}
29
30/// An operation
31#[derive(Debug, Deserialize, Serialize, GraphQLMutationRootInCrate)]
32pub enum Operation {
33    /// Requests an account balance.
34    Balance {
35        /// Owner to query the balance for
36        owner: AccountOwner,
37    },
38    /// Requests this fungible token's ticker symbol.
39    TickerSymbol,
40    /// Transfers tokens from a (locally owned) account to a (possibly remote) account.
41    Transfer {
42        /// Owner to transfer from
43        owner: AccountOwner,
44        /// Amount to be transferred
45        amount: Amount,
46        /// Target account to transfer the amount to
47        target_account: Account,
48    },
49    /// Same as `Transfer` but the source account may be remote. Depending on its
50    /// configuration, the target chain may take time or refuse to process
51    /// the message.
52    Claim {
53        /// Source account to claim amount from
54        source_account: Account,
55        /// Amount to be claimed
56        amount: Amount,
57        /// Target account to claim the amount into
58        target_account: Account,
59    },
60}
61
62/// A fungible response
63#[derive(Debug, Deserialize, Serialize, Default)]
64pub enum FungibleResponse {
65    /// OK response
66    #[default]
67    Ok,
68    /// Balance response
69    Balance(Amount),
70    /// Ticker symbol response
71    TickerSymbol(String),
72}
73
74/// The initial state to instantiate fungible with
75#[derive(Clone, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)]
76pub struct InitialState {
77    /// Accounts and their respective initial balances
78    pub accounts: BTreeMap<AccountOwner, Amount>,
79}
80
81/// The parameters to instantiate fungible with
82#[derive(Clone, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)]
83pub struct Parameters {
84    /// Ticker symbol for the fungible
85    pub ticker_symbol: String,
86}
87
88impl Parameters {
89    /// Instantiate parameters
90    pub fn new(ticker_symbol: &str) -> Self {
91        let ticker_symbol = ticker_symbol.to_string();
92        Self { ticker_symbol }
93    }
94}
95
96/// An account.
97#[derive(
98    Clone,
99    Copy,
100    Debug,
101    Deserialize,
102    Eq,
103    Ord,
104    PartialEq,
105    PartialOrd,
106    Serialize,
107    SimpleObject,
108    InputObject,
109)]
110#[graphql(input_name = "FungibleAccount")]
111pub struct Account {
112    /// Chain ID of the account
113    pub chain_id: ChainId,
114    /// Owner of the account
115    pub owner: AccountOwner,
116}
117
118/// A builder type for constructing the initial state of the application.
119#[derive(Debug, Default)]
120pub struct InitialStateBuilder {
121    /// Accounts and their respective initial balances
122    account_balances: BTreeMap<AccountOwner, Amount>,
123}
124
125impl InitialStateBuilder {
126    /// Adds an account to the initial state of the application.
127    pub fn with_account(mut self, account: AccountOwner, balance: impl Into<Amount>) -> Self {
128        self.account_balances.insert(account, balance.into());
129        self
130    }
131
132    /// Returns the serialized initial state of the application, ready to use as the
133    /// initialization argument.
134    pub fn build(&self) -> InitialState {
135        InitialState {
136            accounts: self.account_balances.clone(),
137        }
138    }
139}