circles_transfers/
error.rs1use alloy_primitives::Address;
2use thiserror::Error;
3
4#[derive(Debug, Clone, Copy)]
6pub enum TransfersErrorSource {
7 Transfers,
8 Pathfinding,
9 FlowMatrix,
10 Validation,
11}
12
13#[derive(Debug, Error)]
15pub enum TransferError {
16 #[error("{message}")]
18 Generic {
19 message: String,
20 code: Option<String>,
21 category: TransfersErrorSource,
22 },
23 #[error("No valid transfer path found from {from:#x} to {to:#x}. {reason}")]
25 NoPathFound {
26 from: Address,
27 to: Address,
28 reason: String,
29 },
30 #[error("Insufficient balance for transfer. Requested: {requested} wei, available: {available} wei.")]
32 InsufficientBalance {
33 requested: String,
34 available: String,
35 from: Address,
36 to: Address,
37 },
38 #[error("Insufficient unwrapped token balance; wrapped tokens present but use_wrapped_balances is false.")]
40 WrappedTokensRequired,
41 #[error("Flow matrix contains {count} unregistered avatar(s): {addresses:?}")]
43 UnregisteredAvatars {
44 addresses: Vec<Address>,
45 count: usize,
46 },
47 #[error(
49 "Flow matrix terminal sum ({terminal_sum}) does not equal expected amount ({expected})"
50 )]
51 FlowMatrixMismatch {
52 terminal_sum: String,
53 expected: String,
54 },
55 #[error("Transfer path is empty for route from {from:#x} to {to:#x}")]
57 EmptyPath { from: Address, to: Address },
58}
59
60impl TransferError {
61 pub fn no_path_found(from: Address, to: Address, reason: Option<String>) -> Self {
62 TransferError::NoPathFound {
63 from,
64 to,
65 reason: reason.unwrap_or_else(|| "This could mean there's no trust connection, insufficient balance, or the tokens are not transferable.".to_string()),
66 }
67 }
68
69 pub fn insufficient_balance(
70 requested: alloy_primitives::U256,
71 available: alloy_primitives::U256,
72 from: Address,
73 to: Address,
74 ) -> Self {
75 TransferError::InsufficientBalance {
76 requested: requested.to_string(),
77 available: available.to_string(),
78 from,
79 to,
80 }
81 }
82
83 pub fn wrapped_tokens_required() -> Self {
84 TransferError::WrappedTokensRequired
85 }
86
87 pub fn unregistered_avatars(addresses: Vec<Address>) -> Self {
88 let count = addresses.len();
89 TransferError::UnregisteredAvatars { addresses, count }
90 }
91
92 pub fn flow_matrix_mismatch(
93 terminal_sum: alloy_primitives::U256,
94 expected: alloy_primitives::U256,
95 ) -> Self {
96 TransferError::FlowMatrixMismatch {
97 terminal_sum: terminal_sum.to_string(),
98 expected: expected.to_string(),
99 }
100 }
101
102 pub fn empty_path(from: Address, to: Address) -> Self {
103 TransferError::EmptyPath { from, to }
104 }
105
106 pub fn generic(
107 message: impl Into<String>,
108 code: Option<impl Into<String>>,
109 category: TransfersErrorSource,
110 ) -> Self {
111 TransferError::Generic {
112 message: message.into(),
113 code: code.map(|c| c.into()),
114 category,
115 }
116 }
117}