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 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/// A builder type for constructing the initial state of the application.
162#[derive(Debug, Default)]
163pub struct InitialStateBuilder {
164 /// Accounts and their respective initial balances
165 account_balances: BTreeMap<AccountOwner, Amount>,
166}
167
168impl InitialStateBuilder {
169 /// Adds an account to the initial state of the application.
170 pub fn with_account(mut self, account: AccountOwner, balance: impl Into<Amount>) -> Self {
171 self.account_balances.insert(account, balance.into());
172 self
173 }
174
175 /// Returns the serialized initial state of the application, ready to use as the
176 /// initialization argument.
177 pub fn build(&self) -> InitialState {
178 InitialState {
179 accounts: self.account_balances.clone(),
180 }
181 }
182}