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}