Skip to content
LogoLogo

Hold, as a template

#[weld::template]
struct Proposal {
    #[signatory] sender: Party,
    #[observer]  recipient: Party,
    asset: Asset, amount: u128,
    recipient_fi: FiIndex, deadline_bucket: Field,
    payload_root: Field,
}
impl Proposal {
    #[choice(controllers = [self.recipient], consuming)]
    fn accept(self, tx: Tx) -> (Verdict, Effects) {
        (Verdict::ok(), Effects::new().pay_from_bound(self.recipient, self.asset, self.amount))
    }
    #[choice(controllers = [], consuming)]                 // any actor vouched by recipient_fi
    fn reject(self, tx: Tx) -> (Verdict, Effects) {
        let v = Verdict::require(tx.fi_indices().contains(self.recipient_fi), "hold/wrong-fi");
        (v, Effects::new().pay_from_bound(self.sender, self.asset, self.amount))
    }
    #[choice(controllers = [self.sender], consuming)]
    fn reclaim(self, tx: Tx) -> (Verdict, Effects) {
        let v = Verdict::require(tx.time_bucket() > self.deadline_bucket, "hold/not-expired");
        (v, Effects::new().pay_from_bound(self.sender, self.asset, self.amount))
    }
}

Initiate is Proposal::create plus bind. All three closings are one fragment with one consumed record, one consumed bound note, and one created note, and are therefore indistinguishable on chain, including reclaim, which improves on Weld spec §4.13. The recipient FI's on_workflow policy sees the Proposal opening and the payload, exactly as its on_accept did.