Skip to content

Commit

Permalink
Merge branch 'impl_pay_to_contract'
Browse files Browse the repository at this point in the history
  • Loading branch information
rantan committed Aug 19, 2024
2 parents 94d748a + c79034b commit d7908c0
Show file tree
Hide file tree
Showing 4 changed files with 196 additions and 19 deletions.
11 changes: 6 additions & 5 deletions tapyrus-wallet-ffi/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions tapyrus-wallet-ffi/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ default = ["uniffi/cli"]

[dependencies]
uniffi = { version = "=0.25.0" }
tdk_wallet = { git = "https://github.com/chaintope/tdk", branch = "fix_no_tpc_sent_and_no_tpc_change", subdirectory = "crates/wallet" }
tdk_sqlite = { git = "https://github.com/chaintope/tdk", branch = "fix_no_tpc_sent_and_no_tpc_change", subdirectory = "crates/sqlite" }
tdk_esplora = { git = "https://github.com/chaintope/tdk", branch = "fix_no_tpc_sent_and_no_tpc_change", subdirectory = "crates/esplora", features = ["blocking"] }
tdk_wallet = { git = "https://github.com/chaintope/tdk", branch = "for_test", subdirectory = "crates/wallet" }
tdk_sqlite = { git = "https://github.com/chaintope/tdk", branch = "for_test", subdirectory = "crates/sqlite" }
tdk_esplora = { git = "https://github.com/chaintope/tdk", branch = "for_test", subdirectory = "crates/esplora", features = ["blocking"] }

[build-dependencies]
uniffi = { version = "=0.25.0", features = ["build"] }
Expand Down
164 changes: 155 additions & 9 deletions tapyrus-wallet-ffi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,13 +104,25 @@ pub(crate) struct TxOut {
pub unspent: bool,
}

#[derive(Debug, Clone)]
pub(crate) struct Contract {
pub contract_id: String,
pub contract: String,
pub payment_base: String,
pub payable: bool,
}

impl From<tdk_wallet::chain::Contract> for Contract {
fn from(contract: tdk_wallet::chain::Contract) -> Self {
Contract {
contract_id: contract.contract_id,
contract: String::from_utf8(contract.contract).unwrap(),
payment_base: contract.payment_base.to_string(),
payable: contract.spendable,
}
}
}

pub(crate) struct GetNewAddressResult {
pub address: String,
pub public_key: String,
Expand Down Expand Up @@ -310,6 +322,63 @@ impl Display for GetTxOutByAddressError {

impl std::error::Error for GetTxOutByAddressError {}

#[derive(Debug)]
pub(crate) enum CalcPayToContractAddressError {
FailedToParsePublicKey,
InvalidColorId,
ContractError { cause: String },
}

impl Display for CalcPayToContractAddressError {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
CalcPayToContractAddressError::FailedToParsePublicKey => {
write!(f, "Failed to parse public key")
}
CalcPayToContractAddressError::InvalidColorId => write!(f, "Invalid color id"),
CalcPayToContractAddressError::ContractError { cause: e } => {
write!(f, "Contract error: {}", e)
}
}
}
}

impl std::error::Error for CalcPayToContractAddressError {}

#[derive(Debug)]
pub(crate) enum StoreContractError {
ContractError { cause: String },
FailedToParsePublicKey,
}

impl Display for StoreContractError {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
StoreContractError::ContractError { cause: e } => write!(f, "Contract error: {}", e),
StoreContractError::FailedToParsePublicKey => {
write!(f, "Failed to parse public key")
}
}
}
}

impl std::error::Error for StoreContractError {}

#[derive(Debug)]
pub(crate) enum UpdateContractError {
ContractError { cause: String },
}

impl Display for UpdateContractError {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
UpdateContractError::ContractError { cause: e } => write!(f, "Contract error: {}", e),
}
}
}

impl std::error::Error for UpdateContractError {}

impl HdWallet {
pub fn new(config: Arc<Config>) -> Result<Self, NewError> {
let Config {
Expand Down Expand Up @@ -527,6 +596,9 @@ impl HdWallet {
.unwrap();
TransferError::UnknownUtxo { utxo: utxo.clone() }
}
AddUtxoError::ContractError => {
panic!("ContractError")
}
})?;

let mut psbt =
Expand Down Expand Up @@ -627,22 +699,55 @@ impl HdWallet {
public_key: String,
contract: String,
color_id: Option<String>,
) -> String {
"15Q1z9LJGeaU6oHeEvT1SKoeCUJntZZ9Tg".to_string()
) -> Result<String, CalcPayToContractAddressError> {
let wallet = self.get_wallet();
let payment_base = PublicKey::from_str(&public_key)
.map_err(|_| CalcPayToContractAddressError::FailedToParsePublicKey)?;
let contract = contract.as_bytes().to_vec();
let color_id = match color_id {
Some(id) => Some(
ColorIdentifier::from_str(&id)
.map_err(|_| CalcPayToContractAddressError::InvalidColorId)?,
),
None => None,
};
let address = wallet
.create_pay_to_contract_address(&payment_base, contract, color_id)
.map_err(|e| CalcPayToContractAddressError::ContractError {
cause: e.to_string(),
})?;
Ok(address.to_string())
}

pub fn store_contract(&self, contract: Contract) -> () {
()
pub fn store_contract(&self, contract: Contract) -> Result<Contract, StoreContractError> {
let mut wallet = self.get_wallet();
let payment_base = PublicKey::from_str(&contract.payment_base)
.map_err(|_| StoreContractError::FailedToParsePublicKey)?;
let contract = wallet
.store_contract(
contract.contract_id,
contract.contract.as_bytes().to_vec(),
payment_base,
contract.payable,
)
.map_err(|e| StoreContractError::ContractError {
cause: e.to_string(),
})?;
Ok(contract.into())
}

pub fn update_contract(
&self,
contract_id: String,
contract: Option<String>,
payment_base: Option<String>,
payable: Option<bool>,
) -> () {
()
payable: bool,
) -> Result<(), UpdateContractError> {
let mut wallet = self.get_wallet();
wallet.update_contract(contract_id, payable).map_err(|e| {
UpdateContractError::ContractError {
cause: e.to_string(),
}
})?;
Ok(())
}
}

Expand Down Expand Up @@ -734,6 +839,43 @@ mod test {
assert_eq!(balance, 0, "Balance should be 0");
}

#[test]
fn test_calc_p2c_address() {
let wallet = get_wallet();
let public_key =
"039be0d2b0c3b6f7fad77f142257aee12b2a34047aa3191edc0424cd15e0fa15da".to_string();
let address = wallet
.calc_p2c_address(public_key, "content".to_string(), None)
.expect("Failed to calculate P2C address");
assert_eq!(
address, "1NUKT87AxtsJ74EiZ6esDz8kjppHS4cKz2",
"Address should be equal"
);
}

#[test]
fn test_store_contract() {
// remove sqlite file
let _ = fs::remove_file("tests/tapyrus-wallet.sqlite");

let wallet = get_wallet();
let contract = Contract {
contract_id: "contract_id".to_string(),
contract: "contract".to_string(),
payment_base: "039be0d2b0c3b6f7fad77f142257aee12b2a34047aa3191edc0424cd15e0fa15da"
.to_string(),
payable: true,
};
let stored_contract = wallet
.store_contract(contract.clone())
.expect("Failed to store contract");

// Update contract
let updated_contract = wallet
.update_contract(contract.contract_id.clone(), false)
.expect("Failed to update contract");
}

#[test]
#[ignore] // This test is for manual testing with esplora-tapyrus.
fn test_with_esplora() {
Expand Down Expand Up @@ -817,6 +959,10 @@ mod test {
.expect("Failed to transfer");
}

#[test]
#[ignore] // This test is for manual testing with esplora-tapyrus.
fn test_p2c_transfer() {}

#[test]
#[ignore] // This test is for manual testing with esplora-tapyrus.
fn test_get_transaction() {
Expand Down
34 changes: 32 additions & 2 deletions tapyrus-wallet-ffi/src/wallet.udl
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,33 @@ interface GetTxOutByAddressError {
UnknownTransaction();
};

/// The error for HDWallet#calc_p2c_address
[Error]
interface CalcPayToContractAddressError {
/// Occur if the public key is invalid
FailedToParsePublicKey();
/// Occur if the contract is wrong
ContractError(string cause);
/// Occur if the color id is invalid
InvalidColorId();
};

/// The error for HDWallet#store_contract
[Error]
interface StoreContractError {
/// Occur if the contract is wrong
ContractError(string cause);
/// Occur if the public key is invalid
FailedToParsePublicKey();
};

/// The error for HDWallet#update_contract
[Error]
interface UpdateContractError {
/// Occur if the contract is wrong
ContractError(string cause);
};

/// The HDWallet
interface HdWallet {
/// Create a new HDWallet instance
Expand Down Expand Up @@ -198,10 +225,13 @@ interface HdWallet {
sequence<TxOut> get_tx_out_by_address(string tx, string address);

/// Get the pay to contract address
[Throws=CalcPayToContractAddressError]
string calc_p2c_address(string public_key, string contract, string? color_id);
/// Store the contract
void store_contract(Contract contract);
[Throws=StoreContractError]
Contract store_contract(Contract contract);
/// Update the contract payable
void update_contract(string contract_id, string? contract, string? payment_base, boolean? payable);
[Throws=UpdateContractError]
void update_contract(string contract_id, boolean payable);
};

0 comments on commit d7908c0

Please sign in to comment.