use sha2::{Digest, Sha256};
#[allow(clippy::too_many_arguments)]
pub fn derive_order_id(
user_pubkey: &[u8],
client_nonce: u64,
origin_chain_id: u64,
destination_chain_id: u64,
input_token: &[u8],
output_token: &[u8],
input_amount: u128,
output_amount: u128,
) -> [u8; 32] {
let mut h = Sha256::new();
h.update(user_pubkey);
h.update(client_nonce.to_le_bytes());
h.update(origin_chain_id.to_le_bytes());
h.update(destination_chain_id.to_le_bytes());
h.update(input_token);
h.update(output_token);
h.update(input_amount.to_le_bytes());
h.update(output_amount.to_le_bytes());
let mut out = [0u8; 32];
out.copy_from_slice(&h.finalize());
out
}
#[derive(Debug, Clone)]
pub struct GaslessLockParams<'a> {
pub depositor_address: &'a str,
pub token_contract: &'a str,
pub token_contract_destination_chain: &'a str,
pub destination_chain_id: &'a str,
pub amount_in: u128,
pub amount_out: u128,
pub order_id: &'a str,
pub deadline: u64,
pub nonce: u64,
pub open_deadline: u64,
pub user_signature: &'a [u8],
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn order_id_is_deterministic() {
let a = derive_order_id(&[1; 32], 42, 1, 501, b"0xaaa", b"MintXYZ", 100, 200);
let b = derive_order_id(&[1; 32], 42, 1, 501, b"0xaaa", b"MintXYZ", 100, 200);
assert_eq!(a, b);
}
#[test]
fn order_id_changes_with_nonce() {
let a = derive_order_id(&[1; 32], 1, 1, 501, b"t1", b"t2", 100, 200);
let b = derive_order_id(&[1; 32], 2, 1, 501, b"t1", b"t2", 100, 200);
assert_ne!(a, b);
}
#[test]
fn order_id_endianness_is_le() {
let id = derive_order_id(&[], 0, 0, 0, &[], &[], 0, 0);
let mut h = Sha256::new();
h.update([0u8; 56]);
let mut want = [0u8; 32];
want.copy_from_slice(&h.finalize());
assert_eq!(id, want);
}
}