// Protocol definition with component implementations
use genie::{Result, GvmComponentId, AmountInSubunits};
#[contract]
pub mod fungible_token {
pub mod root {
use genie::{deploy, installation_request, view};
/// Root component with member fields for automatic storage.
pub struct FungibleTokenSystem {
metadata: Metadata,
issuer_installed_flag: IssuerInstalledFlag,
}
impl FungibleTokenSystem {
#[installation_request]
pub async fn installation_request(
&mut self,
component_type: FungibleTokenComponents,
) -> Result<Metadata> {
// Validate and approve component installation based on role
}
#[view]
pub fn get_metadata(&self) -> Result<Metadata> {
Ok(self.metadata.clone())
}
/// Deploy returns Self with initialized fields.
/// Fields are automatically saved to storage after deployment.
#[deploy]
pub async fn deploy(name: String, symbol: String, ...) -> Result<Self> {
Ok(Self {
metadata: Metadata::new(...),
issuer_installed_flag: IssuerInstalledFlag::default(),
})
}
}
}
pub mod issuer {
use super::root::Metadata;
use genie::{install, Result};
/// Stateless component, no member fields.
pub struct FungibleTokenIssuer;
impl FungibleTokenIssuer {
#[owner]
pub fn mint(destination: GvmComponentId, amount: AmountInSubunits) -> Result<()> {
// Delegate minting to root component
}
/// Install returns Self. For stateless components, just return Self directly.
#[install]
pub async fn install(
_metadata: Metadata,
) -> Result<Self> {
Ok(Self)
}
}
}
pub mod holder {
use super::root::Metadata;
use genie::{install, Result};
/// Holder component with member fields for balance tracking.
pub struct FungibleTokenHolder {
token_store: TokenStore,
holder_metadata: HolderMetaData,
}
impl FungibleTokenHolder {
#[owner]
pub fn transfer_same_entity(&mut self, amount: AmountInSubunits, send_to: GvmComponentId) -> Result<()> {
// Debit from self, credit to recipient
}
#[owner]
pub fn transfer(&mut self, amount: AmountInSubunits, send_to: GvmComponentId) -> Result<()> {
// Fire-and-forget cross-entity transfer using spawn
}
#[owner]
pub async fn transfer_with_confirmation(&mut self, amount: AmountInSubunits, send_to: GvmComponentId) -> Result<()> {
// Async cross-entity transfer with confirmation
}
#[view]
pub fn balance(&self) -> Result<AmountInSubunits> {
Ok(self.token_store.balance())
}
#[private]
pub fn receive(&mut self, amount: AmountInSubunits) -> Result<()> {
self.token_store.credit(amount)
}
/// Install returns Self with initialized fields.
/// Fields are automatically saved to storage after installation.
#[install]
pub async fn install(
metadata: Metadata,
) -> Result<Self> {
Ok(Self {
token_store: TokenStore::new(),
holder_metadata: HolderMetaData::new(metadata),
})
}
}
}
}