async fn send(
    memo: Memo,
    amount: ICPTs,
    fee: ICPTs,
    from_subaccount: Option<Subaccount>,
    to: AccountIdentifier,
    created_at_time: Option<TimeStamp>,
) -> BlockHeight {
    let caller_principal_id = caller();

    if !LEDGER.read().unwrap().can_send(&caller_principal_id) {
        panic!(
            "Sending from non-self-authenticating principal or non-whitelisted canister is not allowed: {}",
            caller_principal_id
        );
    }

    let from = AccountIdentifier::new(caller_principal_id, from_subaccount);
    let minting_acc = LEDGER
        .read()
        .unwrap()
        .minting_account_id
        .expect("Minting canister id not initialized");

    let transfer = if from == minting_acc {
        assert_eq!(fee, ICPTs::ZERO, "Fee for minting should be zero");
        assert_ne!(
            to, minting_acc,
            "It is illegal to mint to a minting_account"
        );
        Transfer::Mint { to, amount }
    } else if to == minting_acc {
        assert_eq!(fee, ICPTs::ZERO, "Fee for burning should be zero");
        if amount < MIN_BURN_AMOUNT {
            panic!("Burns lower than {} are not allowed", MIN_BURN_AMOUNT);
        }
        Transfer::Burn { from, amount }
    } else {
        if fee != TRANSACTION_FEE {
            panic!("Transaction fee should be {}", TRANSACTION_FEE);
        }
        Transfer::Send {
            from,
            to,
            amount,
            fee,
        }
    };
    let (height, _) = add_payment(memo, transfer, created_at_time);
    // Don't put anything that could ever trap after this call or people using this
    // endpoint. If something did panic the payment would appear to fail, but would
    // actually succeed on chain.
    archive_blocks().await;
    height
}
/// This is the only operation that changes the state of the canister blocks and
/// balances after init. This creates a payment from the caller's account. It
/// returns the index of the resulting transaction
///
/// # Arguments
///
/// * `memo` -  A 8 byte "message" you can attach to transactions to help the
///   receiver disambiguate transactions
/// * `amount` - The number of ICPTs the recipient gets. The number of ICPTs
///   withdrawn is equal to the amount + the fee
/// * `fee` - The maximum fee that the sender is willing to pay. If the required
///   fee is greater than this the transaction will be rejected otherwise the
///   required fee will be paid. TODO(ROSETTA1-45): automatically pay a lower
///   fee if possible
/// * `from_subaccount` - The subaccount you want to draw funds from
/// * `to` - The account you want to send the funds to
/// * `to_subaccount` - The subaccount you want to send funds to
This is the only operation that changes the state of the canister blocks and
balances after init. This creates a payment from the caller's account. It
returns the index of the resulting transaction
This is the only operation that changes the state of the canister blocks and balances after init . This creates a payment from the caller ' s account . It returns the index of the resulting transaction
async fn send(
    memo: Memo,
    amount: ICPTs,
    fee: ICPTs,
    from_subaccount: Option<Subaccount>,
    to: AccountIdentifier,
    created_at_time: Option<TimeStamp>,
) -> BlockHeight {
    let caller_principal_id = caller();
    if !LEDGER.read().unwrap().can_send(&caller_principal_id) {
        panic!(
            "Sending from non-self-authenticating principal or non-whitelisted canister is not allowed: {}",
            caller_principal_id
        );
    }
    let from = AccountIdentifier::new(caller_principal_id, from_subaccount);
    let minting_acc = LEDGER
        .read()
        .unwrap()
        .minting_account_id
        .expect("Minting canister id not initialized");
    let transfer = if from == minting_acc {
        assert_eq!(fee, ICPTs::ZERO, "Fee for minting should be zero");
        assert_ne!(
            to, minting_acc,
            "It is illegal to mint to a minting_account"
        );
        Transfer::Mint { to, amount }
    } else if to == minting_acc {
        assert_eq!(fee, ICPTs::ZERO, "Fee for burning should be zero");
        if amount < MIN_BURN_AMOUNT {
            panic!("Burns lower than {} are not allowed", MIN_BURN_AMOUNT);
        }
        Transfer::Burn { from, amount }
    } else {
        if fee != TRANSACTION_FEE {
            panic!("Transaction fee should be {}", TRANSACTION_FEE);
        }
        Transfer::Send {
            from,
            to,
            amount,
            fee,
        }
    };
    let (height, _) = add_payment(memo, transfer, created_at_time);
    // Don't put anything that could ever trap after this call or people using this
    // endpoint. If something did panic the payment would appear to fail, but would
    // actually succeed on chain.
    archive_blocks().await;
    height
}
async fn send ( memo : Memo , amount : ICPTs , fee : ICPTs , from_subaccount : Option < Subaccount > , to : AccountIdentifier , created_at_time : Option < TimeStamp > , ) -> BlockHeight { let caller_principal_id = caller ( ) ; if ! LEDGER . read ( ) . unwrap ( ) . can_send ( & caller_principal_id ) { panic ! ( " " caller_principal_id ) ; } let from = AccountIdentifier :: new ( caller_principal_id , from_subaccount ) ; let minting_acc = LEDGER . read ( ) . unwrap ( ) . minting_account_id . expect ( " " ) ; let transfer = if from == minting_acc { assert_eq ! ( fee ICPTs ZERO " " ) ; assert_ne ! ( to minting_acc " " ) ; Transfer :: Mint { to , amount } } else if to == minting_acc { assert_eq ! ( fee ICPTs ZERO " " ) ; if amount < MIN_BURN_AMOUNT { panic ! ( " " MIN_BURN_AMOUNT ) ; } Transfer :: Burn { from , amount } } else { if fee != TRANSACTION_FEE { panic ! ( " " TRANSACTION_FEE ) ; } Transfer :: Send { from , to , amount , fee , } } ; let ( height , _ ) = add_payment ( memo , transfer , created_at_time ) ; // Don't put anything that could ever trap after this call or people using this // endpoint. If something did panic the payment would appear to fail, but would // actually succeed on chain. archive_blocks ( ) . await ; height }
This is the only operation that changes the state of the canister blocks and
balances after init.
This is the only operation that changes the state of the canister blocks and balances after init .
memo
Memo
amount
ICPTs
fee
ICPTs
from_subaccount
Option<Subaccount>
to
AccountIdentifier
created_at_time
Option<TimeStamp>
memo
Memo
amount
ICPTs
fee
ICPTs
from_subaccount
Option<Subaccount>
to
AccountIdentifier
created_at_time
Option<TimeStamp>