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