[Java] Update LDK batteries to latest upstream API
[ldk-java] / typescript_strings.py
index c0a0cccbf0ed816764fb3a285cf6dae2620400ba..670eb2ae73124346a41e919247f43d601e12a63f 100644 (file)
@@ -36,12 +36,14 @@ class Consts:
 
         self.bindings_header = """
 import * as version from './version.mjs';
+import { UInt5 } from './structs/CommonBase.mjs';
 
 const imports: any = {};
 imports.env = {};
 
 var js_objs: Array<WeakRef<object>> = [];
 var js_invoke: Function;
+var getRandomValues: Function;
 
 imports.wasi_snapshot_preview1 = {
        "fd_write": (fd: number, iovec_array_ptr: number, iovec_array_len: number) => {
@@ -66,7 +68,7 @@ imports.wasi_snapshot_preview1 = {
        },
        "random_get": (buf_ptr: number, buf_len: number) => {
                const buf = new Uint8Array(wasm.memory.buffer, buf_ptr, buf_len);
-               crypto.getRandomValues(buf);
+               getRandomValues(buf);
                return 0;
        },
        "environ_sizes_get": (environ_var_count_ptr: number, environ_len_ptr: number) => {
@@ -90,25 +92,15 @@ imports.wasi_snapshot_preview1 = {
 
 var wasm: any = null;
 let isWasmInitialized: boolean = false;
-"""
 
-        if target == Target.NODEJS:
-            self.bindings_header += """import * as fs from 'fs';
-import { webcrypto as crypto } from 'crypto';
-/* @internal */
-export async function initializeWasm(path: string) {
-       const source = fs.readFileSync(path);
-       imports.env["js_invoke_function"] = js_invoke;
-       const { instance: wasmInstance } = await WebAssembly.instantiate(source, imports);"""
-        else:
-            self.bindings_header += """
-/* @internal */
-export async function initializeWasm(uri: string) {
-       const stream = fetch(uri);
-       imports.env["js_invoke_function"] = js_invoke;
-       const { instance: wasmInstance } = await WebAssembly.instantiateStreaming(stream, imports);"""
+async function finishInitializeWasm(wasmInstance: WebAssembly.Instance) {
+       if (typeof crypto === "undefined") {
+               var crypto_import = (await import('crypto')).webcrypto;
+               getRandomValues = crypto_import.getRandomValues.bind(crypto_import);
+       } else {
+               getRandomValues = crypto.getRandomValues.bind(crypto);
+       }
 
-        self.bindings_header += """
        wasm = wasmInstance.exports;
        if (!wasm.test_bigint_pass_deadbeef0badf00d(BigInt("0xdeadbeef0badf00d"))) {
                throw new Error(\"Currently need BigInt-as-u64 support, try ----experimental-wasm-bigint");
@@ -128,12 +120,33 @@ export async function initializeWasm(uri: string) {
        console.log(\"Loaded LDK-Java Bindings with LDK \" + ldk_version + \" and LDK-C-Bindings \" + c_bindings_version);
 
        isWasmInitialized = true;
-};
+}
+
+/* @internal */
+export async function initializeWasmFromUint8Array(wasmBinary: Uint8Array) {
+       imports.env["js_invoke_function"] = js_invoke;
+       const { instance: wasmInstance } = await WebAssembly.instantiate(wasmBinary, imports);
+       await finishInitializeWasm(wasmInstance);
+}
 
+/* @internal */
+export async function initializeWasmFetch(uri: string) {
+       const stream = fetch(uri);
+       imports.env["js_invoke_function"] = js_invoke;
+       const { instance: wasmInstance } = await WebAssembly.instantiateStreaming(stream, imports);
+       await finishInitializeWasm(wasmInstance);
+}"""
+
+        self.bindings_header += """
 // WASM CODEC
 
-const nextMultipleOfFour = (value: number) => {
-       return Math.ceil(value / 4) * 4;
+/* @internal */
+export function uint5ArrToBytes(inputArray: Array<UInt5>): Uint8Array {
+       const arr = new Uint8Array(inputArray.length);
+       for (var i = 0; i < inputArray.length; i++) {
+               arr[i] = inputArray[i].getVal();
+       }
+       return arr;
 }
 
 /* @internal */
@@ -212,6 +225,13 @@ export function getU32ArrayElem(arrayPointer: number, idx: number): number {
        return actualArrayViewer[idx];
 }
 
+/* @internal */
+export function getU8ArrayElem(arrayPointer: number, idx: number): number {
+       const actualArrayViewer = new Uint8Array(wasm.memory.buffer, arrayPointer + 4, idx + 1);
+       return actualArrayViewer[idx];
+}
+
+
 /* @internal */
 export function encodeString(str: string): number {
        const charArray = new TextEncoder().encode(str);
@@ -247,10 +267,16 @@ export function debugPrintRemainingAllocs() {
             self.bindings_header += "/* @internal */ export function debugPrintRemainingAllocs() { }\n"
 
         with open(outdir + "/index.mts", 'a') as index:
-            index.write("""import { initializeWasm as bindingsInit } from './bindings.mjs';
-export function initializeWasm(path: string) {
-       bindingsInit(path);
+            index.write("""import { initializeWasmFetch, initializeWasmFromUint8Array } from './bindings.mjs';
+/** Initializes the WASM backend by calling `fetch()` on the given URI - Browser only */
+export async function initializeWasmWebFetch(uri: string) {
+       await initializeWasmFetch(uri);
 }
+/** Initializes the WASM backend given a Uint8Array of the .wasm binary file - Browser or Node.JS */
+export async function initializeWasmFromBinary(bin: Uint8Array) {
+       await initializeWasmFromUint8Array(bin);
+}
+
 """)
 
         self.bindings_version_file = """export function get_ldk_java_bindings_version(): String {
@@ -268,7 +294,7 @@ function get_freeer(ptr: number, free_fn: (ptr: number) => void) {
        }
 }
 
-export default class CommonBase {
+export class CommonBase {
        protected ptr: number;
        protected ptrs_to: object[] = [];
        protected constructor(ptr: number, free_fn: (ptr: number) => void) {
@@ -291,6 +317,19 @@ export default class CommonBase {
                finalizer.unregister(o);
        }
 }
+
+export class UInt5 {
+       public constructor(private val: number) {
+               if (val > 32 || val < 0) throw new Error("UInt5 value is out of range");
+       }
+       public getVal(): number {
+               return this.val;
+       }
+}
+
+export class UnqualifiedError {
+       public constructor(val: number) {}
+}
 """
 
         self.txout_defn = """export class TxOut extends CommonBase {
@@ -557,7 +596,7 @@ jstring __attribute__((export_name("TS_get_ldk_version"))) get_ldk_version() {
 }"""
 
         self.hu_struct_file_prefix = """
-import CommonBase from './CommonBase.mjs';
+import { CommonBase, UInt5, UnqualifiedError } from './CommonBase.mjs';
 import * as bindings from '../bindings.mjs'
 
 """
@@ -576,7 +615,7 @@ import * as bindings from '../bindings.mjs'
         return None
     def create_native_arr_call(self, arr_len, ty_info):
         if ty_info.c_ty == "ptrArray":
-            assert ty_info.subty is not None and ty_info.subty.c_ty.endswith("Array")
+            assert ty_info.rust_obj == "LDKCVec_u5Z" or (ty_info.subty is not None and ty_info.subty.c_ty.endswith("Array"))
         return "init_" + ty_info.c_ty + "(" + arr_len + ", __LINE__)"
     def set_native_arr_contents(self, arr_name, arr_len, ty_info):
         if ty_info.c_ty == "int8_tArray":
@@ -607,6 +646,8 @@ import * as bindings from '../bindings.mjs'
             return None
 
     def map_hu_array_elems(self, arr_name, conv_name, arr_ty, elem_ty):
+        if elem_ty.rust_obj == "LDKu5":
+            return arr_name + " != null ? bindings.uint5ArrToBytes(" + arr_name + ") : null"
         assert elem_ty.c_ty == "uint32_t" or elem_ty.c_ty.endswith("Array")
         return arr_name + " != null ? " + arr_name + ".map(" + conv_name + " => " + elem_ty.from_hu_conv[0] + ") : null"
 
@@ -630,6 +671,8 @@ import * as bindings from '../bindings.mjs'
     def get_java_arr_elem(self, elem_ty, arr_name, idx):
         if elem_ty.c_ty == "uint32_t" or elem_ty.c_ty == "uintptr_t" or elem_ty.c_ty.endswith("Array"):
             return "bindings.getU32ArrayElem(" + arr_name + ", " + idx + ")"
+        elif elem_ty.rust_obj == "LDKu5":
+            return "bindings.getU8ArrayElem(" + arr_name + ", " + idx + ")"
         else:
             assert False
     def constr_hu_array(self, ty_info, arr_len):
@@ -683,6 +726,9 @@ import * as bindings from '../bindings.mjs'
         with open(self.outdir + "/imports.mts.part", 'a') as imports:
             imports.write(f"import {{ {', '.join(struct_names)} }} from '../{folder}/{struct_names[0]}.mjs';\n")
 
+    def fully_qualified_hu_ty_path(self, ty):
+        return ty.java_hu_ty
+
     def native_c_unitary_enum_map(self, struct_name, variants, enum_doc_comment):
         out_c = "static inline LDK" + struct_name + " LDK" + struct_name + "_from_js(int32_t ord) {\n"
         out_c = out_c + "\tswitch (ord) {\n"