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
use raiden_blockchain::keys::PrivateKey;
use raiden_primitives::{
	deserializers::u256_from_str,
	packing::pack_one_to_n_iou,
	serializers::{
		to_checksum_str,
		u256_to_str,
	},
	traits::{
		Checksum,
		ToBytes,
	},
	types::{
		Address,
		BlockExpiration,
		Bytes,
		ChainID,
		OneToNAddress,
		TokenAmount,
	},
};
use serde::{
	Deserialize,
	Serialize,
};
use web3::signing::{
	self,
	Key,
};

/// Raiden's routing mode.
#[derive(Copy, Clone, PartialEq)]
pub enum RoutingMode {
	PFS,
	Private,
}

/// IOU to submit to PFS as a form of payment.
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct IOU {
	#[serde(serialize_with = "to_checksum_str")]
	pub sender: Address,
	#[serde(serialize_with = "to_checksum_str")]
	pub receiver: Address,
	#[serde(serialize_with = "to_checksum_str")]
	pub one_to_n_address: OneToNAddress,
	#[serde(serialize_with = "u256_to_str", deserialize_with = "u256_from_str")]
	pub amount: TokenAmount,
	pub expiration_block: BlockExpiration,
	pub chain_id: ChainID,
	pub signature: Option<Bytes>,
}

impl IOU {
	/// Sign IOU with private key.
	pub fn sign(&mut self, private_key: PrivateKey) -> Result<(), signing::SigningError> {
		let data = pack_one_to_n_iou(
			self.one_to_n_address,
			self.sender,
			self.receiver,
			self.amount,
			self.expiration_block,
			self.chain_id,
		);
		let signature = private_key.sign_message(&data.0)?;
		self.signature = Some(Bytes(signature.to_bytes()));
		Ok(())
	}
}

impl ToString for IOU {
	fn to_string(&self) -> String {
		format!(
			"IOU (sender = {}, receiver = {}, amount = {}, expiration = {})",
			self.sender.checksum(),
			self.receiver.checksum(),
			self.amount.to_string(),
			self.expiration_block.to_string()
		)
	}
}