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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
use std::fmt;

use fuel_types::{Bytes32, Bytes64};
use fuels::{
    prelude::*,
    types::{Bits256, Identity, B512},
};

pub mod bindings {
    include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
}

impl std::error::Error for bindings::Error {}
impl fmt::Display for bindings::Error {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let msg = match self {
            crate::ContractError::ContractNotConfigured => "contract is not configured",
            crate::ContractError::AssetNotConfigured => "the asset is not configured",
            crate::ContractError::NotAuthorized => "not authorized",
            crate::ContractError::RemainingAssets => {
                "withdraw asset fees before changing the asset"
            }
            crate::ContractError::NonZeroFee => "set fee to 0 when disabling the asset",
            crate::ContractError::ZeroAuthority => "zero authority is not allowed",
            crate::ContractError::ZeroFee => "zero fee is not allowed",
            crate::ContractError::NoFeePaid => "client must pay the fee",
            crate::ContractError::WrongFeePaid => "client must pay the correct fee",
            crate::ContractError::SeedInUse => "seed is in use",
            crate::ContractError::NoAmountSpecified => "you should specify an amount",
            crate::ContractError::NotEnoughFunds => "not enough funds to withdraw",
            crate::ContractError::UnknownRequest => "request seed is unknown",
            crate::ContractError::InvalidResponse => "randomness response is invalid",
            crate::ContractError::Responded => "an authority is already responded",
            crate::ContractError::Fulfilled => "request is fulfilled",
        };
        f.write_str(msg)
    }
}

impl<T: Account> fmt::Debug for bindings::VrfMethods<T> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("VrfMethods").finish_non_exhaustive()
    }
}

impl bindings::Event {
    pub fn seed(&self) -> &Bits256 {
        match self {
            crate::Event::Fulfill(bindings::Fulfill { seed, .. }) => seed,
            crate::Event::Response(bindings::Response { seed, .. }) => seed,
            crate::Event::Request(bindings::Request { seed, .. }) => seed,
            crate::Event::Reset(bindings::Reset { seed }) => seed,
        }
    }
}

impl fmt::Display for bindings::Event {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            bindings::Event::Fulfill(x) => write!(f, "Event: {}", x),
            bindings::Event::Request(x) => write!(f, "Event: {}", x),
            bindings::Event::Response(x) => write!(f, "Event: {}", x),
            bindings::Event::Reset(x) => write!(f, "Event: {}", x),
        }
    }
}

impl fmt::Display for bindings::Fulfill {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(
            f,
            "Fulfill: seed={}, randomness={}",
            Bytes32::from(self.seed.0),
            randomness_to_bytes64(self.randomness),
        )
    }
}

impl fmt::Display for bindings::Request {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(
            f,
            "Request: no={}, seed={}, client={}",
            self.no,
            Bytes32::new(self.seed.0),
            match self.client {
                Identity::Address(x) => Bech32Address::from(x).to_string(),
                Identity::ContractId(x) => Bech32ContractId::from(x).to_string(),
            },
        )
    }
}

impl fmt::Display for bindings::Response {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(
            f,
            "Response: seed={}, authority={}, randomness={}",
            Bytes32::from(self.seed.0),
            Bech32Address::from(self.authority),
            randomness_to_bytes64(self.randomness),
        )
    }
}

impl fmt::Display for bindings::Reset {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "Reset: seed={}", Bytes32::new(self.seed.0))
    }
}

impl bindings::FulfillersKeys {
    pub fn is_empty(&self) -> bool {
        self.keys
            .first()
            .map(|x| *x == Address::zeroed())
            .unwrap_or(true)
    }

    pub fn iter(&self) -> FulfillersKeysIter<'_> {
        FulfillersKeysIter::new(self)
    }
}

pub struct FulfillersKeysIter<'a> {
    keys: &'a bindings::FulfillersKeys,
    next: u8,
}

impl<'a> FulfillersKeysIter<'a> {
    fn new(keys: &'a bindings::FulfillersKeys) -> Self {
        Self { keys, next: 0 }
    }
}

impl<'a> Iterator for FulfillersKeysIter<'a> {
    type Item = &'a Address;

    fn next(&mut self) -> Option<Self::Item> {
        match self.keys.keys.get(self.next as usize) {
            Some(addr) => {
                if *addr == Address::zeroed() {
                    None
                } else {
                    self.next += 1;
                    Some(addr)
                }
            }
            None => None,
        }
    }
}

pub fn randomness_to_bytes64(randomness: B512) -> Bytes64 {
    let mut bytes = [0_u8; 64];
    bytes[..32].copy_from_slice(&randomness.bytes[0].0);
    bytes[32..].copy_from_slice(&randomness.bytes[1].0);
    Bytes64::new(bytes)
}