ergo/
wallet.rs

1//! Wallet-like features
2
3use crate::ReturnBool;
4use crate::ReturnString;
5use ergo_lib_c_core::{
6    address::ConstAddressPtr,
7    collections::ConstCollectionPtr,
8    ergo_box::ErgoBox,
9    ergo_state_ctx::ConstErgoStateContextPtr,
10    reduced::ConstReducedTransactionPtr,
11    secret_key::SecretKey,
12    transaction::{
13        ConstTransactionHintsBagPtr, ConstUnsignedTransactionPtr, TransactionHintsBagPtr,
14        TransactionPtr,
15    },
16    wallet::*,
17    Error, ErrorPtr,
18};
19use std::{ffi::CStr, ffi::CString, os::raw::c_char};
20
21use crate::delete_ptr;
22
23/// Create new MnemonicGenerator instance
24#[no_mangle]
25pub unsafe extern "C" fn ergo_lib_mnemonic_generator(
26    language: *const c_char,
27    strength: u32,
28    mnemonic_generator_out: *mut MnemonicGeneratorPtr,
29) -> ErrorPtr {
30    let language = CStr::from_ptr(language).to_string_lossy();
31    let res = mnemonic_generator(&language, strength, mnemonic_generator_out);
32    Error::c_api_from(res)
33}
34
35/// Generate mnemonic sentence using random entropy
36#[no_mangle]
37pub unsafe extern "C" fn ergo_lib_mnemonic_generator_generate(
38    mnemonic_generator_ptr: MnemonicGeneratorPtr,
39) -> ReturnString {
40    match mnemonic_generator_generate(mnemonic_generator_ptr) {
41        Ok(value) => match CString::new(value) {
42            Ok(mnemonic) => ReturnString {
43                value: mnemonic.into_raw(),
44                error: std::ptr::null_mut(),
45            },
46            Err(e) => ReturnString {
47                value: std::ptr::null_mut(),
48                error: Error::c_api_from(Err(Error::Misc(e.to_string().into()))),
49            },
50        },
51        Err(e) => ReturnString {
52            value: std::ptr::null_mut(), // Just a dummy value
53            error: Error::c_api_from(Err(e)),
54        },
55    }
56}
57
58/// Generate mnemonic sentence using provided entropy
59#[no_mangle]
60pub unsafe extern "C" fn ergo_lib_mnemonic_generator_generate_from_entropy(
61    mnemonic_generator_ptr: MnemonicGeneratorPtr,
62    entropy: *mut u8,
63    len: usize,
64) -> ReturnString {
65    match mnemonic_generator_generate_from_entropy(mnemonic_generator_ptr, entropy, len) {
66        Ok(value) => match CString::new(value) {
67            Ok(mnemonic) => ReturnString {
68                value: mnemonic.into_raw(),
69                error: std::ptr::null_mut(),
70            },
71            Err(e) => ReturnString {
72                value: std::ptr::null_mut(),
73                error: Error::c_api_from(Err(Error::Misc(e.to_string().into()))),
74            },
75        },
76        Err(e) => ReturnString {
77            value: std::ptr::null_mut(), // Just a dummy value
78            error: Error::c_api_from(Err(e)),
79        },
80    }
81}
82
83/// Free a previously-created CString. Intended to be paired with one of the
84/// mnemonic generation functions. Called by the client.
85#[no_mangle]
86pub unsafe extern "C" fn ergo_lib_mnemonic_generator_free_mnemonic(mnemonic: *mut c_char) {
87    let s = CString::from_raw(mnemonic);
88    drop(s);
89}
90
91/// Create `Wallet` instance loading secret key from mnemonic
92/// Returns Err if a DlogSecretKey cannot be parsed from the provided phrase
93#[no_mangle]
94pub unsafe extern "C" fn ergo_lib_wallet_from_mnemonic(
95    mnemonic_phrase: *const c_char,
96    mnemonic_pass: *const c_char,
97    wallet_out: *mut WalletPtr,
98) -> ErrorPtr {
99    let mnemonic_phrase = CStr::from_ptr(mnemonic_phrase).to_string_lossy();
100    let mnemonic_pass = CStr::from_ptr(mnemonic_pass).to_string_lossy();
101    let res = wallet_from_mnemonic(&mnemonic_phrase, &mnemonic_pass, wallet_out);
102    Error::c_api_from(res)
103}
104
105/// Create `Wallet` from secrets
106#[no_mangle]
107pub unsafe extern "C" fn ergo_lib_wallet_from_secrets(
108    secret_keys_ptr: ConstCollectionPtr<SecretKey>,
109    wallet_out: *mut WalletPtr,
110) {
111    #[allow(clippy::unwrap_used)]
112    wallet_from_secrets(secret_keys_ptr, wallet_out).unwrap();
113}
114
115#[no_mangle]
116pub unsafe extern "C" fn ergo_lib_wallet_add_secret(
117    wallet_ptr: WalletPtr,
118    secret_key_ptr: *mut SecretKey,
119) -> ErrorPtr {
120    let res = wallet_add_secret(wallet_ptr, secret_key_ptr);
121    Error::c_api_from(res)
122}
123
124/// Signs a transaction
125#[no_mangle]
126pub unsafe extern "C" fn ergo_lib_wallet_sign_transaction(
127    wallet_ptr: ConstWalletPtr,
128    state_context_ptr: ConstErgoStateContextPtr,
129    unsigned_tx_ptr: ConstUnsignedTransactionPtr,
130    boxes_to_spend_ptr: ConstCollectionPtr<ErgoBox>,
131    data_boxes_ptr: ConstCollectionPtr<ErgoBox>,
132    transaction_out: *mut TransactionPtr,
133) -> ErrorPtr {
134    let res = wallet_sign_transaction(
135        wallet_ptr,
136        state_context_ptr,
137        unsigned_tx_ptr,
138        boxes_to_spend_ptr,
139        data_boxes_ptr,
140        transaction_out,
141    );
142    Error::c_api_from(res)
143}
144
145/// Signs a multi signature transaction
146#[no_mangle]
147pub unsafe extern "C" fn ergo_lib_wallet_sign_transaction_multi(
148    wallet_ptr: ConstWalletPtr,
149    state_context_ptr: ConstErgoStateContextPtr,
150    unsigned_tx_ptr: ConstUnsignedTransactionPtr,
151    boxes_to_spend_ptr: ConstCollectionPtr<ErgoBox>,
152    data_boxes_ptr: ConstCollectionPtr<ErgoBox>,
153    tx_hints_ptr: ConstTransactionHintsBagPtr,
154    transaction_out: *mut TransactionPtr,
155) -> ErrorPtr {
156    let res = wallet_sign_transaction_multi(
157        wallet_ptr,
158        state_context_ptr,
159        unsigned_tx_ptr,
160        boxes_to_spend_ptr,
161        data_boxes_ptr,
162        tx_hints_ptr,
163        transaction_out,
164    );
165    Error::c_api_from(res)
166}
167
168/// Signs a reduced transaction (generating proofs for inputs)
169#[no_mangle]
170pub unsafe extern "C" fn ergo_lib_wallet_sign_reduced_transaction(
171    wallet_ptr: ConstWalletPtr,
172    reduced_tx_ptr: ConstReducedTransactionPtr,
173    transaction_out: *mut TransactionPtr,
174) -> ErrorPtr {
175    let res = wallet_sign_reduced_transaction(wallet_ptr, reduced_tx_ptr, transaction_out);
176    Error::c_api_from(res)
177}
178
179/// Signs a multi signature reduced transaction
180#[no_mangle]
181pub unsafe extern "C" fn ergo_lib_wallet_sign_reduced_transaction_multi(
182    wallet_ptr: ConstWalletPtr,
183    reduced_tx_ptr: ConstReducedTransactionPtr,
184    tx_hints_ptr: ConstTransactionHintsBagPtr,
185    transaction_out: *mut TransactionPtr,
186) -> ErrorPtr {
187    let res = wallet_sign_reduced_transaction_multi(
188        wallet_ptr,
189        reduced_tx_ptr,
190        tx_hints_ptr,
191        transaction_out,
192    );
193    Error::c_api_from(res)
194}
195
196/// Generate Commitments for unsigned tx
197#[no_mangle]
198pub unsafe extern "C" fn ergo_lib_wallet_generate_commitments(
199    wallet_ptr: ConstWalletPtr,
200    state_context_ptr: ConstErgoStateContextPtr,
201    unsigned_tx_ptr: ConstUnsignedTransactionPtr,
202    boxes_to_spend_ptr: ConstCollectionPtr<ErgoBox>,
203    data_boxes_ptr: ConstCollectionPtr<ErgoBox>,
204    transaction_hints_bag_out: *mut TransactionHintsBagPtr,
205) -> ErrorPtr {
206    let res = wallet_generate_commitments(
207        wallet_ptr,
208        state_context_ptr,
209        unsigned_tx_ptr,
210        boxes_to_spend_ptr,
211        data_boxes_ptr,
212        transaction_hints_bag_out,
213    );
214    Error::c_api_from(res)
215}
216
217/// Generate Commitments for reduced transaction
218#[no_mangle]
219pub unsafe extern "C" fn ergo_lib_wallet_generate_commitments_for_reduced_transaction(
220    wallet_ptr: ConstWalletPtr,
221    reduced_tx_ptr: ConstReducedTransactionPtr,
222    transaction_hints_bag_out: *mut TransactionHintsBagPtr,
223) -> ErrorPtr {
224    let res = wallet_generate_commitments_for_reduced_transaction(
225        wallet_ptr,
226        reduced_tx_ptr,
227        transaction_hints_bag_out,
228    );
229    Error::c_api_from(res)
230}
231
232/// Sign an arbitrary message using a P2PK address
233#[no_mangle]
234pub unsafe extern "C" fn ergo_lib_wallet_sign_message_using_p2pk(
235    wallet_ptr: ConstWalletPtr,
236    address_ptr: ConstAddressPtr,
237    message_ptr: *const u8,
238    message_length: usize,
239    signed_message_out: *mut SignedMessagePtr,
240) -> ErrorPtr {
241    let res = wallet_sign_message_using_p2pk(
242        wallet_ptr,
243        address_ptr,
244        message_ptr,
245        message_length,
246        signed_message_out,
247    );
248    Error::c_api_from(res)
249}
250
251/// Verify that the signature is presented to satisfy SigmaProp conditions.
252#[no_mangle]
253pub unsafe extern "C" fn ergo_lib_verify_signature(
254    address_ptr: ConstAddressPtr,
255    message_ptr: *const u8,
256    message_length: usize,
257    signed_message_ptr: ConstSignedMessagePtr,
258) -> ReturnBool {
259    match verify_signature(address_ptr, message_ptr, message_length, signed_message_ptr) {
260        Ok(value) => ReturnBool {
261            value,
262            error: std::ptr::null_mut(),
263        },
264        Err(e) => ReturnBool {
265            value: false, // Just a dummy value
266            error: Error::c_api_from(Err(e)),
267        },
268    }
269}
270
271/// Drop `SignedMessage`
272#[no_mangle]
273pub unsafe extern "C" fn ergo_lib_signed_message_delete(ptr: SignedMessagePtr) {
274    delete_ptr(ptr)
275}
276
277/// Drop `Wallet`
278#[no_mangle]
279pub unsafe extern "C" fn ergo_lib_wallet_delete(ptr: WalletPtr) {
280    delete_ptr(ptr)
281}