1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
use crate::error::{HeadlessDappError, Result};
use crate::{
encoding::address_string_to_ergo_tree, encoding::serialize_p2s_from_ergo_tree,
P2PKAddressString, P2SAddressString,
};
use crate::{BlockHeight, ErgoAddressString, NanoErg};
use ergo_lib::chain::ergo_box::{BoxValue, ErgoBox, ErgoBoxCandidate, NonMandatoryRegisters};
use ergo_lib::chain::token::{Token, TokenAmount};
use ergo_lib::{ast::constant::Constant, chain::transaction::unsigned::UnsignedTransaction};
use ergo_lib_wasm::transaction::UnsignedTransaction as WUnsignedTransaction;
use json::object;
use std::convert::TryFrom;
use wasm_bindgen::prelude::*;
pub fn create_candidate(
value: NanoErg,
output_address: &ErgoAddressString,
tokens: &Vec<Token>,
registers: &Vec<Constant>,
current_height: BlockHeight,
) -> Result<ErgoBoxCandidate> {
let obb_value = BoxValue::new(value).map_err(|_| HeadlessDappError::InvalidBoxValue(value))?;
let obb_registers = NonMandatoryRegisters::from_ordered_values(registers.clone())
.map_err(|_| HeadlessDappError::InvalidRegisterValues())?;
let obb_ergo_tree = address_string_to_ergo_tree(output_address)
.map_err(|_| HeadlessDappError::InvalidP2PKAddress(output_address.clone()))?;
let output_bank_candidate = ErgoBoxCandidate {
value: obb_value,
ergo_tree: obb_ergo_tree,
tokens: tokens.clone(),
additional_registers: obb_registers.clone(),
creation_height: current_height as u32,
};
Ok(output_bank_candidate)
}
pub fn find_and_sum_other_tokens(
filter_tokens: &Vec<Token>,
input_boxes: &Vec<ErgoBox>,
) -> Vec<Token> {
let mut new_tokens: Vec<Token> = vec![];
for b in input_boxes {
for t in b.tokens.clone() {
let filter_tokens_check = filter_tokens.iter().any(|tok| tok.token_id == t.token_id);
let new_tokens_check = new_tokens.iter().any(|tok| t.token_id == tok.token_id);
if filter_tokens_check {
continue;
} else if new_tokens_check {
new_tokens = new_tokens
.iter()
.map(|tok| {
if tok.token_id == t.token_id {
Token {
token_id: tok.token_id.clone(),
amount: TokenAmount::try_from(
u64::from(tok.amount) + u64::from(t.amount),
)
.unwrap(),
}
} else {
tok.clone()
}
})
.collect();
} else {
new_tokens.push(t)
}
}
}
new_tokens
}
#[wasm_bindgen]
pub fn w_unsigned_transaction_to_assembler_spec(
wrapped_unsigned_tx: WUnsignedTransaction,
transaction_fee: NanoErg,
) -> String {
let unsigned_tx = wrapped_unsigned_tx.into();
unsigned_transaction_to_assembler_spec(unsigned_tx, transaction_fee)
}
pub fn unsigned_transaction_to_assembler_spec(
unsigned_tx: UnsignedTransaction,
transaction_fee: NanoErg,
) -> String {
let mut tx_spec = object! {
"requests": [],
};
for i in 0..unsigned_tx.output_candidates.len() {
let output = unsigned_tx.output_candidates[i].clone();
tx_spec["requests"][i]["value"] = output.value.as_u64().clone().into();
tx_spec["requests"][i]["address"] = serialize_p2s_from_ergo_tree(output.ergo_tree).into();
for n in 0..output.tokens.len() {
let token = output.tokens[n].clone();
let tok_id: String = token.token_id.0.into();
let tok_amount: u64 = token.amount.into();
tx_spec["requests"][i]["assets"][n]["tokenId"] = tok_id.into();
tx_spec["requests"][i]["assets"][n]["amount"] = tok_amount.into();
}
let registers = output.additional_registers.get_ordered_values();
for y in 0..registers.len() {
if y == 0 {
tx_spec["requests"][i]["registers"]["R4"] = registers[y].base16_str().into();
}
if y == 1 {
tx_spec["requests"][i]["registers"]["R5"] = registers[y].base16_str().into();
}
if y == 2 {
tx_spec["requests"][i]["registers"]["R6"] = registers[y].base16_str().into();
}
if y == 3 {
tx_spec["requests"][i]["registers"]["R7"] = registers[y].base16_str().into();
}
if y == 4 {
tx_spec["requests"][i]["registers"]["R8"] = registers[y].base16_str().into();
}
if y == 5 {
tx_spec["requests"][i]["registers"]["R9"] = registers[y].base16_str().into();
}
}
tx_spec["fee"] = transaction_fee.into();
let inputs = unsigned_tx.inputs.clone();
for y in 0..inputs.len() {
let box_id: String = inputs[y].box_id.clone().into();
tx_spec["inputs"][y] = box_id.into();
}
let data_inputs = unsigned_tx.data_inputs.clone();
for y in 0..data_inputs.len() {
let box_id: String = data_inputs[y].box_id.clone().into();
tx_spec["dataInputs"][y] = box_id.into();
}
}
tx_spec.pretty(2)
}