From f152bfcd7ad6fde5ee28ca25502cbbdc03f12abb Mon Sep 17 00:00:00 2001 From: 0xh3rman <119309671+0xh3rman@users.noreply.github.com> Date: Mon, 17 Jun 2024 22:25:03 +0900 Subject: [PATCH] add typeshare models EIP712Domain and ERC2612PermitMessage --- crates/primitives/src/eip712.rs | 41 ++++++++ crates/primitives/src/erc2612.rs | 160 +++++++++++++++++++++++++++++++ crates/primitives/src/lib.rs | 2 + gemstone/src/lib.rs | 50 ---------- gemstone/src/lido/mod.rs | 50 ++++++---- 5 files changed, 234 insertions(+), 69 deletions(-) create mode 100644 crates/primitives/src/eip712.rs create mode 100644 crates/primitives/src/erc2612.rs diff --git a/crates/primitives/src/eip712.rs b/crates/primitives/src/eip712.rs new file mode 100644 index 00000000..fbf1d56a --- /dev/null +++ b/crates/primitives/src/eip712.rs @@ -0,0 +1,41 @@ +use serde::{Deserialize, Serialize}; +use typeshare::typeshare; + +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +#[typeshare(swift = "Equatable, Codable")] +pub struct EIP712Domain { + pub name: String, + pub version: String, + #[serde(rename = "chainId")] + pub chain_id: u32, + #[serde(rename = "verifyingContract")] + pub verifying_contract: String, +} + +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +#[typeshare(swift = "Equatable, Codable")] +pub struct EIP712Type { + pub name: String, + pub r#type: String, +} + +pub fn eip712_domain_types() -> Vec { + vec![ + EIP712Type { + name: "name".into(), + r#type: "string".into(), + }, + EIP712Type { + name: "version".into(), + r#type: "string".into(), + }, + EIP712Type { + name: "chainId".into(), + r#type: "uint256".into(), + }, + EIP712Type { + name: "verifyingContract".into(), + r#type: "address".into(), + }, + ] +} diff --git a/crates/primitives/src/erc2612.rs b/crates/primitives/src/erc2612.rs new file mode 100644 index 00000000..009edb71 --- /dev/null +++ b/crates/primitives/src/erc2612.rs @@ -0,0 +1,160 @@ +#![allow(non_snake_case)] +use serde::{Deserialize, Serialize}; +use typeshare::typeshare; + +use crate::eip712::{EIP712Domain, EIP712Type}; + +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +#[typeshare(swift = "Equatable, Codable")] +pub struct ERC2612Permit { + pub owner: String, + pub spender: String, + pub value: String, + pub nonce: String, + pub deadline: String, +} + +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +#[typeshare(swift = "Equatable, Codable")] +pub struct ERC2612Types { + #[serde(rename = "EIP712Domain")] + pub eip712Domain: Vec, + #[serde(rename = "Permit")] + pub permit: Vec, +} + +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +#[typeshare(swift = "Equatable, Codable")] +pub struct ERC2612PermitMessage { + pub types: ERC2612Types, + #[serde(rename = "primaryType")] + pub primary_type: String, + pub domain: EIP712Domain, + pub message: ERC2612Permit, +} + +pub fn erc2612_permit_types() -> Vec { + vec![ + EIP712Type { + name: "owner".into(), + r#type: "address".into(), + }, + EIP712Type { + name: "spender".into(), + r#type: "address".into(), + }, + EIP712Type { + name: "value".into(), + r#type: "uint256".into(), + }, + EIP712Type { + name: "nonce".into(), + r#type: "uint256".into(), + }, + EIP712Type { + name: "deadline".into(), + r#type: "uint256".into(), + }, + ] +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::eip712::*; + + #[test] + fn test_erc2612_permit_message_json() { + let eip712_domain_types = eip712_domain_types(); + let permit_types = erc2612_permit_types(); + + let permit = ERC2612Permit { + owner: "0x514BCb1F9AAbb904e6106Bd1052B66d2706dBbb7".to_string(), + spender: "0x889edC2eDab5f40e902b864aD4d7AdE8E412F9B1".to_string(), + value: "11005735849467938".to_string(), + nonce: "1".to_string(), + deadline: "1718895600".to_string(), + }; + + let message = ERC2612PermitMessage { + types: ERC2612Types { + eip712Domain: eip712_domain_types, + permit: permit_types, + }, + primary_type: "Permit".to_string(), + domain: EIP712Domain { + name: "Liquid staked Ether 2.0".to_string(), + version: "2".to_string(), + chain_id: 1, + verifying_contract: "0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84".to_string(), + }, + message: permit, + }; + + let expected = r#" + { + "domain": { + "verifyingContract": "0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84", + "chainId": 1, + "version": "2", + "name": "Liquid staked Ether 2.0" + }, + "message": { + "nonce": "1", + "value": "11005735849467938", + "deadline": "1718895600", + "spender": "0x889edC2eDab5f40e902b864aD4d7AdE8E412F9B1", + "owner": "0x514BCb1F9AAbb904e6106Bd1052B66d2706dBbb7" + }, + "primaryType": "Permit", + "types": { + "Permit": [ + { + "type": "address", + "name": "owner" + }, + { + "name": "spender", + "type": "address" + }, + { + "type": "uint256", + "name": "value" + }, + { + "type": "uint256", + "name": "nonce" + }, + { + "name": "deadline", + "type": "uint256" + } + ], + "EIP712Domain": [ + { + "type": "string", + "name": "name" + }, + { + "name": "version", + "type": "string" + }, + { + "name": "chainId", + "type": "uint256" + }, + { + "type": "address", + "name": "verifyingContract" + } + ] + } + } + "#; + + assert_eq!( + message, + serde_json::from_str::(expected).unwrap() + ); + } +} diff --git a/crates/primitives/src/lib.rs b/crates/primitives/src/lib.rs index 708d6ce7..4ffb066c 100644 --- a/crates/primitives/src/lib.rs +++ b/crates/primitives/src/lib.rs @@ -91,4 +91,6 @@ pub const DEFAULT_FIAT_CURRENCY: &str = "USD"; pub mod image_formatter; pub use self::image_formatter::ImageFormatter; pub mod block_explorer; +pub mod eip712; +pub mod erc2612; pub mod explorers; diff --git a/gemstone/src/lib.rs b/gemstone/src/lib.rs index efdf4c3d..34b842d6 100644 --- a/gemstone/src/lib.rs +++ b/gemstone/src/lib.rs @@ -11,7 +11,6 @@ use payment::PaymentWrapper; use primitives::{Chain, StakeChain}; pub mod lido; use gem_bsc::stake_hub; -use lido::{ERC2612Permit, LidoWithdrawalRequest}; use std::{collections::HashMap, str::FromStr}; pub mod asset; pub mod bsc; @@ -322,52 +321,3 @@ pub fn bsc_encode_claim_call( pub fn payment_decode_url(string: &str) -> Result { payment::decode_url(string).map_err(GemstoneError::from) } - -#[uniffi::export] -pub fn lido_encode_submit(referral: String) -> Result, GemstoneError> { - lido::encode_submit_with_referral(&referral).map_err(GemstoneError::from) -} - -#[uniffi::export] -pub fn lido_encode_request_withdrawals( - amounts: Vec, - owner: String, - permit: ERC2612Permit, -) -> Result, GemstoneError> { - lido::encode_request_withdrawals_with_permit(amounts, owner, permit) - .map_err(GemstoneError::from) -} - -#[uniffi::export] -pub fn lido_decode_request_withdrawals_return( - result: Vec, -) -> Result, GemstoneError> { - lido::decode_request_withdrawals_return(&result).map_err(GemstoneError::from) -} - -#[uniffi::export] -pub fn lido_encode_claim_withdrawal(request_id: String) -> Result, GemstoneError> { - lido::encode_claim_withdrawal(&request_id).map_err(GemstoneError::from) -} - -#[uniffi::export] -pub fn lido_encode_withdrawal_request_ids(owner: String) -> Result, GemstoneError> { - lido::encode_get_withdrawal_request_ids(&owner).map_err(GemstoneError::from) -} - -#[uniffi::export] -pub fn lido_decode_withdrawal_request_ids(result: Vec) -> Result, GemstoneError> { - lido::decode_get_withdrawal_request_ids(&result).map_err(GemstoneError::from) -} - -#[uniffi::export] -pub fn lido_encode_withdrawal_statuses(request_ids: Vec) -> Result, GemstoneError> { - lido::encode_get_withdrawal_request_status(&request_ids).map_err(GemstoneError::from) -} - -#[uniffi::export] -pub fn lido_decode_get_withdrawal_statuses( - result: Vec, -) -> Result, GemstoneError> { - lido::decode_get_withdrawal_request_status(&result).map_err(GemstoneError::from) -} diff --git a/gemstone/src/lido/mod.rs b/gemstone/src/lido/mod.rs index 8aa1cb53..e6e3f54f 100644 --- a/gemstone/src/lido/mod.rs +++ b/gemstone/src/lido/mod.rs @@ -1,4 +1,4 @@ -use anyhow::Error; +use crate::GemstoneError; use gem_evm::{erc2612::Permit, lido, lido::WithdrawalRequestStatus}; #[derive(uniffi::Record, Debug)] @@ -43,41 +43,53 @@ impl From for LidoWithdrawalRequest { } } -pub fn encode_submit_with_referral(referral: &str) -> Result, Error> { - lido::encode_submit_with_referral(referral) +#[uniffi::export] +pub fn lido_encode_submit(referral: String) -> Result, GemstoneError> { + lido::encode_submit_with_referral(&referral).map_err(GemstoneError::from) } -pub fn encode_request_withdrawals_with_permit( +#[uniffi::export] +pub fn lido_encode_request_withdrawals( amounts: Vec, owner: String, permit: ERC2612Permit, -) -> Result, Error> { +) -> Result, GemstoneError> { lido::encode_request_withdrawals_with_permit(amounts, &owner, &permit.into()) + .map_err(GemstoneError::from) } -pub fn encode_claim_withdrawal(request_id: &str) -> Result, Error> { - lido::encode_claim_withdrawal(request_id) +#[uniffi::export] +pub fn lido_decode_request_withdrawals_return( + result: Vec, +) -> Result, GemstoneError> { + lido::decode_request_withdrawals_return(&result).map_err(GemstoneError::from) } -pub fn decode_request_withdrawals_return(result: &[u8]) -> Result, Error> { - lido::decode_request_withdrawals_return(result) +#[uniffi::export] +pub fn lido_encode_claim_withdrawal(request_id: String) -> Result, GemstoneError> { + lido::encode_claim_withdrawal(&request_id).map_err(GemstoneError::from) } -pub fn encode_get_withdrawal_request_ids(owner: &str) -> Result, Error> { - lido::encode_get_withdrawal_request_ids(owner) +#[uniffi::export] +pub fn lido_encode_withdrawal_request_ids(owner: String) -> Result, GemstoneError> { + lido::encode_get_withdrawal_request_ids(&owner).map_err(GemstoneError::from) } -pub fn decode_get_withdrawal_request_ids(result: &[u8]) -> Result, Error> { - lido::decode_get_withdrawal_request_ids(result) +#[uniffi::export] +pub fn lido_decode_withdrawal_request_ids(result: Vec) -> Result, GemstoneError> { + lido::decode_get_withdrawal_request_ids(&result).map_err(GemstoneError::from) } -pub fn encode_get_withdrawal_request_status(request_ids: &[String]) -> Result, Error> { - lido::encode_get_withdrawal_request_status(request_ids) +#[uniffi::export] +pub fn lido_encode_withdrawal_statuses(request_ids: Vec) -> Result, GemstoneError> { + lido::encode_get_withdrawal_request_status(&request_ids).map_err(GemstoneError::from) } -pub fn decode_get_withdrawal_request_status( - result: &[u8], -) -> Result, Error> { - lido::decode_get_withdrawal_request_status(result) +#[uniffi::export] +pub fn lido_decode_get_withdrawal_statuses( + result: Vec, +) -> Result, GemstoneError> { + lido::decode_get_withdrawal_request_status(&result) .map(|x| x.into_iter().map(LidoWithdrawalRequest::from).collect()) + .map_err(GemstoneError::from) }