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 operation
18#[derive(Debug, Deserialize, Serialize, GraphQLMutationRootInCrate)]
19pub enum NativeFungibleOperation {
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 /// Transfers tokens from a (locally owned) account to a (possibly remote) account.
28 Transfer {
29 /// Owner to transfer from
30 owner: AccountOwner,
31 /// Amount to be transferred
32 amount: Amount,
33 /// Target account to transfer the amount to
34 target_account: Account,
35 },
36 /// Same as `Transfer` but the source account may be remote. Depending on its
37 /// configuration, the target chain may take time or refuse to process
38 /// the message.
39 Claim {
40 /// Source account to claim amount from
41 source_account: Account,
42 /// Amount to be claimed
43 amount: Amount,
44 /// Target account to claim the amount into
45 target_account: Account,
46 },
47}
48
49/// An ABI for applications that implement a fungible token.
50pub struct NativeFungibleTokenAbi;
51
52impl ContractAbi for NativeFungibleTokenAbi {
53 type Operation = NativeFungibleOperation;
54 type Response = FungibleResponse;
55}
56
57impl ServiceAbi for NativeFungibleTokenAbi {
58 type Query = Request;
59 type QueryResponse = Response;
60}
61
62/// An operation
63#[derive(Debug, Deserialize, Serialize, GraphQLMutationRootInCrate)]
64pub enum FungibleOperation {
65 /// Requests an account balance.
66 Balance {
67 /// Owner to query the balance for
68 owner: AccountOwner,
69 },
70 /// Requests this fungible token's ticker symbol.
71 TickerSymbol,
72 /// Approve the transfer of tokens
73 Approve {
74 /// Owner to transfer from
75 owner: AccountOwner,
76 /// The spender account
77 spender: AccountOwner,
78 /// Maximum amount to be transferred
79 allowance: Amount,
80 },
81 /// Transfers tokens from a (locally owned) account to a (possibly remote) account.
82 Transfer {
83 /// Owner to transfer from
84 owner: AccountOwner,
85 /// Amount to be transferred
86 amount: Amount,
87 /// Target account to transfer the amount to
88 target_account: Account,
89 },
90 /// Transfers tokens from a (locally owned) account to a (possibly remote) account by using the allowance.
91 TransferFrom {
92 /// Owner to transfer from
93 owner: AccountOwner,
94 /// The spender of the amount.
95 spender: AccountOwner,
96 /// Amount to be transferred
97 amount: Amount,
98 /// Target account to transfer the amount to
99 target_account: Account,
100 },
101 /// Same as `Transfer` but the source account may be remote. Depending on its
102 /// configuration, the target chain may take time or refuse to process
103 /// the message.
104 Claim {
105 /// Source account to claim amount from
106 source_account: Account,
107 /// Amount to be claimed
108 amount: Amount,
109 /// Target account to claim the amount into
110 target_account: Account,
111 },
112}
113
114/// An ABI for applications that implement a fungible token.
115pub struct FungibleTokenAbi;
116
117impl ContractAbi for FungibleTokenAbi {
118 type Operation = FungibleOperation;
119 type Response = FungibleResponse;
120}
121
122impl ServiceAbi for FungibleTokenAbi {
123 type Query = Request;
124 type QueryResponse = Response;
125}
126
127/// A native fungible response
128#[derive(Debug, Deserialize, Serialize, Default)]
129pub enum FungibleResponse {
130 /// OK response
131 #[default]
132 Ok,
133 /// Balance response
134 Balance(Amount),
135 /// Ticker symbol response
136 TickerSymbol(String),
137}
138
139/// The initial state to instantiate fungible with
140#[derive(Clone, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)]
141pub struct InitialState {
142 /// Accounts and their respective initial balances
143 pub accounts: BTreeMap<AccountOwner, Amount>,
144}
145
146/// The parameters to instantiate fungible with
147#[derive(Clone, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)]
148pub struct Parameters {
149 /// Ticker symbol for the fungible
150 pub ticker_symbol: String,
151}
152
153impl Parameters {
154 /// Instantiate parameters
155 pub fn new(ticker_symbol: &str) -> Self {
156 let ticker_symbol = ticker_symbol.to_string();
157 Self { ticker_symbol }
158 }
159}
160
161/// An account.
162#[derive(
163 Clone,
164 Copy,
165 Debug,
166 Deserialize,
167 Eq,
168 Ord,
169 PartialEq,
170 PartialOrd,
171 Serialize,
172 SimpleObject,
173 InputObject,
174)]
175#[graphql(input_name = "FungibleAccount")]
176pub struct Account {
177 /// Chain ID of the account
178 pub chain_id: ChainId,
179 /// Owner of the account
180 pub owner: AccountOwner,
181}
182
183/// A builder type for constructing the initial state of the application.
184#[derive(Debug, Default)]
185pub struct InitialStateBuilder {
186 /// Accounts and their respective initial balances
187 account_balances: BTreeMap<AccountOwner, Amount>,
188}
189
190impl InitialStateBuilder {
191 /// Adds an account to the initial state of the application.
192 pub fn with_account(mut self, account: AccountOwner, balance: impl Into<Amount>) -> Self {
193 self.account_balances.insert(account, balance.into());
194 self
195 }
196
197 /// Returns the serialized initial state of the application, ready to use as the
198 /// initialization argument.
199 pub fn build(&self) -> InitialState {
200 InitialState {
201 accounts: self.account_balances.clone(),
202 }
203 }
204}