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