ergo_lib_c_core/
address.rs1use crate::ergo_tree::{ErgoTree, ErgoTreePtr};
2use crate::{
3 error::*,
4 util::{const_ptr_as_ref, mut_ptr_as_mut},
5};
6use ergo_lib::ergo_chain_types::EcPoint;
7use ergo_lib::ergotree_ir::chain::address as addr;
8use ergo_lib::ergotree_ir::ergo_tree::ErgoTree as InternalErgoTree;
9use ergo_lib::ergotree_ir::serialization::SigmaSerializable;
10use ergo_lib::ergotree_ir::sigma_protocol::sigma_boolean::ProveDlog;
11
12pub struct Address(pub(crate) ergo_lib::ergotree_ir::chain::address::Address);
14pub type AddressPtr = *mut Address;
15pub type ConstAddressPtr = *const Address;
16
17pub unsafe fn address_from_testnet(
19 address_str: &str,
20 address_out: *mut AddressPtr,
21) -> Result<(), Error> {
22 let address_out = mut_ptr_as_mut(address_out, "address_out")?;
23
24 let encoder = addr::AddressEncoder::new(addr::NetworkPrefix::Testnet);
25 let result = encoder.parse_address_from_str(address_str);
26
27 match result {
28 Ok(address) => {
29 *address_out = Box::into_raw(Box::new(Address(address)));
30 Ok(())
31 }
32 Err(err) => Err(Error::misc(err)),
33 }
34}
35
36pub unsafe fn address_from_mainnet(
38 address_str: &str,
39 address_out: *mut AddressPtr,
40) -> Result<(), Error> {
41 let address_out = mut_ptr_as_mut(address_out, "address_out")?;
42
43 let encoder = addr::AddressEncoder::new(addr::NetworkPrefix::Mainnet);
44 let result = encoder.parse_address_from_str(address_str);
45
46 match result {
47 Ok(address) => {
48 *address_out = Box::into_raw(Box::new(Address(address)));
49 Ok(())
50 }
51 Err(err) => Err(Error::misc(err)),
52 }
53}
54
55pub unsafe fn address_from_base58(
57 address_str: &str,
58 address_out: *mut AddressPtr,
59) -> Result<(), Error> {
60 let address_out = mut_ptr_as_mut(address_out, "address_out")?;
61 let result = addr::AddressEncoder::unchecked_parse_address_from_str(address_str);
62 match result {
63 Ok(address) => {
64 *address_out = Box::into_raw(Box::new(Address(address)));
65 Ok(())
66 }
67 Err(err) => Err(Error::misc(err)),
68 }
69}
70
71pub unsafe fn address_to_base58(
73 address: ConstAddressPtr,
74 network_prefix: NetworkPrefix,
75) -> Result<String, Error> {
76 let address = const_ptr_as_ref(address, "address")?;
77 Ok(addr::AddressEncoder::encode_address_as_string(
78 addr::NetworkPrefix::from(network_prefix),
79 &address.0,
80 ))
81}
82
83pub unsafe fn address_type_prefix(address: ConstAddressPtr) -> Result<AddressTypePrefix, Error> {
85 let address = const_ptr_as_ref(address, "address")?;
86 Ok(address.0.address_type_prefix().into())
87}
88
89pub unsafe fn address_from_ergo_tree(
91 ergo_tree_ptr: crate::ergo_tree::ConstErgoTreePtr,
92 address_out: *mut AddressPtr,
93) -> Result<(), Error> {
94 let ergo_tree = const_ptr_as_ref(ergo_tree_ptr, "ergo_tree_ptr")?;
95 let result = addr::Address::recreate_from_ergo_tree(&ergo_tree.0);
96 match result {
97 Ok(address) => {
98 *address_out = Box::into_raw(Box::new(Address(address)));
99 Ok(())
100 }
101 Err(err) => Err(Error::misc(err)),
102 }
103}
104
105pub unsafe fn address_to_ergo_tree(
107 address_ptr: ConstAddressPtr,
108 ergo_tree_out: *mut ErgoTreePtr,
109) -> Result<(), Error> {
110 let address = const_ptr_as_ref(address_ptr, "address_ptr")?;
111 let ergo_tree_out = mut_ptr_as_mut(ergo_tree_out, "ergo_tree_out")?;
112 let ergo_tree: InternalErgoTree = address.0.script().map_err(Error::misc)?;
113 *ergo_tree_out = Box::into_raw(Box::new(ErgoTree(ergo_tree)));
114 Ok(())
115}
116
117pub unsafe fn address_from_public_key(
119 bytes_ptr: *const u8,
120 len: usize,
121 address_out: *mut AddressPtr,
122) -> Result<(), Error> {
123 let address_out = mut_ptr_as_mut(address_out, "address_out")?;
124 let bytes = std::slice::from_raw_parts(bytes_ptr, len);
125 let address = EcPoint::sigma_parse_bytes(bytes)
126 .map(|point| ergo_lib::ergotree_ir::chain::address::Address::P2Pk(ProveDlog::new(point)))
127 .map_err(Error::misc)?;
128 *address_out = Box::into_raw(Box::new(Address(address)));
129 Ok(())
130}
131
132pub unsafe fn address_delete(address: AddressPtr) {
134 if !address.is_null() {
135 let boxed = Box::from_raw(address);
136 std::mem::drop(boxed);
137 }
138}
139
140#[repr(u8)]
142#[derive(PartialEq, Eq, Debug, Clone, Copy)]
143pub enum NetworkPrefix {
144 Mainnet = 0,
146 Testnet = 16,
148}
149
150impl From<NetworkPrefix> for addr::NetworkPrefix {
151 fn from(v: NetworkPrefix) -> Self {
152 use addr::NetworkPrefix::*;
153 match v {
154 NetworkPrefix::Mainnet => Mainnet,
155 NetworkPrefix::Testnet => Testnet,
156 }
157 }
158}
159
160impl From<addr::NetworkPrefix> for NetworkPrefix {
161 fn from(v: addr::NetworkPrefix) -> Self {
162 use NetworkPrefix::*;
163 match v {
164 addr::NetworkPrefix::Mainnet => Mainnet,
165 addr::NetworkPrefix::Testnet => Testnet,
166 }
167 }
168}
169
170#[repr(u8)]
171pub enum AddressTypePrefix {
172 P2Pk = 1,
174 Pay2Sh = 2,
176 Pay2S = 3,
178}
179
180impl From<AddressTypePrefix> for addr::AddressTypePrefix {
181 fn from(v: AddressTypePrefix) -> Self {
182 use addr::AddressTypePrefix::*;
183 match v {
184 AddressTypePrefix::P2Pk => P2Pk,
185 AddressTypePrefix::Pay2Sh => Pay2Sh,
186 AddressTypePrefix::Pay2S => Pay2S,
187 }
188 }
189}
190
191impl From<addr::AddressTypePrefix> for AddressTypePrefix {
192 fn from(v: addr::AddressTypePrefix) -> Self {
193 use AddressTypePrefix::*;
194 match v {
195 addr::AddressTypePrefix::P2Pk => P2Pk,
196 addr::AddressTypePrefix::Pay2Sh => Pay2Sh,
197 addr::AddressTypePrefix::Pay2S => Pay2S,
198 }
199 }
200}