---
# System prepended metadata

title: Untitled

---


## preconditions
* Amount sufficient
* Grab CPFs
* CPFs reserved
```rust=
// sender::State
pub enum State {
    Initiated,
    Authorizing{
        transferred: Vec<Uuid>,
        authorized: Vec<Uuid>,
    },
    Sending,
    Completed,
}

struct NewTransction {
    amount: proto::Amount
    receiver: DynamicVerifier,
}
type Action = Fn(HashMap<Uuid, Transction>, Db, UnboundedSender<Packet>, UnboundedSender<Trigger>, Keychain) -> Result<(), E>; 

```
## Sender
| trigger            | process/forward | processor                  |
| ------------------ | --------------- | -------------------------- |
| `NewTransaction`   | process         | `Sender::new_transaction`    |
| `SimplePaymentAck` | forward         | `Transaction::process_ack` |
| `AuthorizedPromissory`| forward | `Transaction::process_promissory` |


1.
```rust=
fn forward(&self, uetr: Uuid, trigger: Trigger) -> Result<Action, E> {
   if let Some(mut tranasction) = self.map.get(uetr) {
       return transaction.process(trigger);
   };
    let action = |receiver| {
         tracing::error!("Tranasction not found {uetr}");
    };
    Ok(action)
    
}

fn new_transaction(&self, txn: NewTransction) -> Result<Action, E> {
    uetr = Uuid::new_v4();
    
  let action = |map, db, gw_tx, tr_tx| {
      map.insert(uetr, Transction::new(txn));
      db.set_state(uetr, State::Initiated);
      gw_tx.send(proto::SimplePaymentRequest::new(uetr, txn.receiver, txn.amount))
    };
  Ok(action)
}
```
## SenderTransaction
```rust
impl SenderTransaction for transaction::Transaction {
fn process_ack(&mut self, trigger: Trigger) -> Result<Action, E> {
    self.state = State::Authorizing;
    let action = |sender| {
      sender.db.set_state(self.uetr, State::Authorizing);
      let promissories: Vec<AuthorizedPromissory> = db.get_reserved(self.uetr);
      for promissory in promissories {
          let packet: proto::Packet = AuthorizePromissoryPacket::new(self.uetr, promissory);
          gw_tx.send(packet)?;
        }
    
    };

}
fn process_promissory(&mut self, promissory: Trigger) -> Result<Action, E> {
    let promissory = Promissory::decode(promissory.data)?;
    self.state.authorized.push(promissory.id);
    if self.state.authorized != self.state.transferred {
        let action = |sender: &Sender| {
            // and all IDs as vec : [authorized...]/[transferred...]
            tracing::info!("{authorized}/{transferred}")
            sender.db.set_state(self.uetr, self.state);
            sender.db.set_authorized_promissory(promissory);
            let promissories: Vec<AuthorizedPromissory> = db.set(self.uetr);
        };
        return Ok(action);
    } else {
        let authorized_ids = self.state.authorized;
        self.state = State::Sending;
        let action = |sender: &Sender| {
            tracing::info!("{authorized}/{transferred}")
            sender.db.set_state(self.uetr, self.state);
            sender.db.set_authorized_promissory(promissory);
            let promissories: Vec<AuthorizedPromissory> =  sender.db.get_authorized_promissories(authorized_ids);
            
            for promissory in promissores {
                sender.gw_tx.send(promissory)?;
            }
        };
        Ok(action)
}
```


## Receiver
| trigger          | process/forward | action            |
| ---------------- | ------------- | ----------------- |
| `SimplePaymentRequest` | process       | `Receiver::new_transaction` |
|  `AuthorizedPromissory`| forward | `Transaction::process_promissory`|


1.
```rust=
fn new_transaction(&self, packet: proto::Packet) -> Result<Action, E> {
   let msg = deserialize(packet);
  let action = |map, db, gw_tx, tr_tx| {
      msg = deserialize.map_ok_and_err();
      if let Ok(header, req) = msg {
          // we auto accept
          db.set_state(header.uetr, State::Receiving{expected_amount, vec![]};
          map.insert(header.uetr, Transction::new(req));
          gw_tx.send(Ack::new(header, req));
      } else {
          gw_tx.send(Nack::new());
      }
    };
    Ok(action)
}
```

## ReceiverTransaction
```rust!

impl ReceiverTransaction for transaction::Transaction {
fn process_promissory(&mut self, trigger: Trigger) -> Result<Action, E> {
    let promissory: AuthorziedPromissory = Promissory::decode(trigger)?;
    self.state.received_ids.push(promissory.id);
    self.state.received_amount += promissory.amount;
    if received_amount < expeceted_amount {
       let action = |sender| {
          sender.db.set_state(self.uetr, self.state);
          sender.db.set_authorized_promissory(promissory);
          tracing::info!("{received_amount}/{expected_amount}");
       };
       return Ok(action);
    } else {
       self.state = State::Completed{ self.state.received_ids};
       let action = |sender| {
          sender.db.set_state(self.uetr, self.state);
          sender.db.set_authorized_promissory(promissory);
          tracing::info!("{received_amount}/{expected_amount}");         
          sender.gw_tx
           .send(SimplePaymentResponse::new(self.state.received_ids));
           Ok(())
           
       };
       Ok(action)
    }
   }
    
```
