Repository: ergoplatform/sigma-rust (language: rust)

Issue:
Add `(Coll[Byte], Coll[Byte])` and `(Long, Long)` support for `Constant` conversion in JS



Discussion / hints:

Fix patch:
diff --git a/bindings/ergo-lib-wasm/src/ast.rs b/bindings/ergo-lib-wasm/src/ast.rs
index a16890cae..42552ee42 100644
--- a/bindings/ergo-lib-wasm/src/ast.rs
+++ b/bindings/ergo-lib-wasm/src/ast.rs
@@ -120,4 +120,44 @@ impl Constant {
         let c: ergo_lib::ergotree_ir::mir::constant::Constant = ProveDlog::new(ecp).into();
         Ok(c.into())
     }
+
+    /// Create `(Coll[Byte], Coll[Byte])` tuple Constant
+    pub fn from_tuple_coll_bytes(bytes1: &[u8], bytes2: &[u8]) -> Constant {
+        let t = (bytes1.to_vec(), bytes2.to_vec());
+        let c: ergo_lib::ergotree_ir::mir::constant::Constant = t.into();
+        c.into()
+    }
+
+    /// Extract `(Coll[Byte], Coll[Byte])` tuple from Constant as array of Uint8Array
+    pub fn to_tuple_coll_bytes(&self) -> Result<Vec<Uint8Array>, JsValue> {
+        let (bytes1, bytes2) = self
+            .0
+            .clone()
+            .try_extract_into::<(Vec<u8>, Vec<u8>)>()
+            .map_err(|e| JsValue::from_str(&format!("{:?}", e)))?;
+        Ok(vec![
+            Uint8Array::from(bytes1.as_slice()),
+            Uint8Array::from(bytes2.as_slice()),
+        ])
+    }
+
+    /// Create `(Long, Long)` tuple Constant
+    pub fn from_tuple_i64(l1: &I64, l2: &I64) -> Constant {
+        let c: ergo_lib::ergotree_ir::mir::constant::Constant =
+            (i64::from((*l1).clone()), i64::from((*l2).clone())).into();
+        c.into()
+    }
+
+    /// Extract `(Long, Long)` tuple from Constant as array of strings
+    pub fn to_tuple_i64(&self) -> Result<Vec<JsValue>, JsValue> {
+        let (l1, l2) = self
+            .0
+            .clone()
+            .try_extract_into::<(i64, i64)>()
+            .map_err(|e| JsValue::from_str(&format!("{:?}", e)))?;
+        Ok(vec![
+            JsValue::from_str(&l1.to_string()),
+            JsValue::from_str(&l2.to_string()),
+        ])
+    }
 }
diff --git a/ergo-lib/CHANGELOG.md b/ergo-lib/CHANGELOG.md
index cc612b3a3..4c49e3043 100644
--- a/ergo-lib/CHANGELOG.md
+++ b/ergo-lib/CHANGELOG.md
@@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
 ## [Unreleased] - ReleaseDate
 
 ### Added 
+- add (Coll[Byte], Coll[Byte]) and (Long, Long) support for Constant conversion in JS [#386](https://github.com/ergoplatform/sigma-rust/pull/386);
 - `Coll.slice` [#309](https://github.com/ergoplatform/sigma-rust/pull/309);
 - Byte-wise XOR for byte arrays [#310](https://github.com/ergoplatform/sigma-rust/pull/310);
 - `Constant::from_i64_str_array` and `to_i64_str_array` for `Coll[Long]` encoding [#311](https://github.com/ergoplatform/sigma-rust/pull/311);


Test patch:
diff --git a/bindings/ergo-lib-wasm/tests/test_constant.js b/bindings/ergo-lib-wasm/tests/test_constant.js
index fe926eb7f..32e6bb79a 100644
--- a/bindings/ergo-lib-wasm/tests/test_constant.js
+++ b/bindings/ergo-lib-wasm/tests/test_constant.js
@@ -1,7 +1,7 @@
 import { expect, assert } from 'chai';
 
 import {
-    Constant, I64
+  Constant, I64
 } from '../pkg/ergo_lib_wasm';
 
 it('decode Constant i32', async () => {
@@ -53,3 +53,24 @@ it('Constant from EcPoint bytes', async () => {
   let c = Constant.from_ecpoint_bytes(Uint8Array.from(Buffer.from(base16_bytes_str, 'hex')));
   expect(c != null);
 });
+
+it('roundtrip tuple of byte arrays', async () => {
+  let bytes1 = new Uint8Array([1, 1, 2, 255]);
+  let bytes2 = new Uint8Array([5, 6, 7, 255]);
+  let c = Constant.from_tuple_coll_bytes(bytes1, bytes2);
+  let encoded = c.encode_to_base16();
+  let decoded_c = Constant.decode_from_base16(encoded);
+  let decoded_c_value = decoded_c.to_tuple_coll_bytes();
+  expect(decoded_c_value.toString()).equal([bytes1, bytes2].toString());
+});
+
+it('roundtrip tuple of i64', async () => {
+  let value_str1 = '9223372036854775807'; // i64 max value
+  let value_str2 = '29428734987293874';
+  let c = Constant.from_tuple_i64(I64.from_str(value_str1), I64.from_str(value_str2));
+  let encoded = c.encode_to_base16();
+  let decoded_c = Constant.decode_from_base16(encoded);
+  let decoded_c_value = decoded_c.to_tuple_i64();
+  expect(decoded_c_value.toString()).equal([value_str1, value_str2].toString());
+});
+