#!/bin/bash
usage() {
- echo "USAGE: path/to/ldk-c-bindings \"JNI_CFLAGS\" debug android"
+ echo "USAGE: path/to/ldk-c-bindings \"JNI_CFLAGS\" debug android web"
echo "For JNI_CFLAGS you probably want -I/usr/lib/jvm/java-11-openjdk-amd64/include/ -I/usr/lib/jvm/java-11-openjdk-amd64/include/linux/"
echo "debug should either be true, false, or leaks"
echo "debug of leaks turns on leak tracking on an optimized release bianry"
echo "android should either be true or false"
+ echo "web should either be true or false"
exit 1
}
[ "$1" = "" ] && usage
[ "$3" != "true" -a "$3" != "false" -a "$3" != "leaks" ] && usage
[ "$4" != "true" -a "$4" != "false" ] && usage
+[ "$5" != "true" -a "$5" != "false" ] && usage
set -x
echo "Creating TS bindings..."
mkdir -p ts/{enums,structs}
-rm -f ts/{enums,structs}/*.ts
-./genbindings.py "./lightning.h" ts ts ts $DEBUG_ARG typescript
+rm -f ts/{enums,structs,}/*.{mjs,mts}
+if [ "$5" = "true" ]; then
+ ./genbindings.py "./lightning.h" ts ts ts $DEBUG_ARG typescript node
+else
+ ./genbindings.py "./lightning.h" ts ts ts $DEBUG_ARG typescript browser
+fi
rm -f ts/bindings.c
if [ "$3" = "true" ]; then
echo "#define LDK_DEBUG_BUILD" > ts/bindings.c
else
$COMPILE -o liblightningjs_release.wasm -s -Os -I"$1"/lightning-c-bindings/include/ ts/bindings.c "$1"/lightning-c-bindings/target/wasm32-wasi/release/libldk.a $EXTRA_LINK
fi
+
+if [ -x "$(which tsc)" ]; then
+ cd ts
+rm -r structs # TODO: Make the human-types compile
+ if [ "$5" = "false" ]; then
+ tsc
+ else
+ tsc --types node --typeRoots .
+ cd ..
+ if [ -x "$(which node)" ]; then
+ NODE_V="$(node --version)"
+ if [ "${NODE_V:1:2}" -gt 14 ]; then
+ node ts/test/
+ fi
+ fi
+ fi
+fi
--- /dev/null
+// Minimal subset of the node 'fs' library that we depend on.
+// May be (c) Microsoft licensed under the MIT license, but API's are generally not copyrightable per recent precedent.
+declare module 'fs' {
+ export type PathLike = string | Buffer | URL;
+ export type PathOrFileDescriptor = PathLike | number;
+ export function readFileSync(
+ path: PathOrFileDescriptor,
+ options?: {
+ encoding?: null | undefined;
+ flag?: string | undefined;
+ } | null
+ ): Buffer;
+}
+declare module 'node:fs' {
+ export * from 'fs';
+}
--- /dev/null
+// Minimal subset of the node 'fs' library that we depend on.
+// May be (c) Microsoft licensed under the MIT license, but API's are generally not copyrightable per recent precedent.
+/// <reference path="fs.d.ts" />
--- /dev/null
+{
+ "name": "@types/node",
+ "version": "17.0.8",
+ "description": "TypeScript definitions for Node.js",
+ "homepage": "https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node",
+ "contributors": [],
+ "types": "index.d.ts"
+}
<html>
<head></head>
<body>
-<script type="module">
- (async() => {
- const imports = {};
- imports.wasi_snapshot_preview1 = {
- "fd_write" : () => {
- console.log("ABORT");
- },
- "random_get" : () => {
- console.log("ABORT");
- },
- "environ_sizes_get" : () => {
- console.log("wasi_snapshot_preview1:environ_sizes_get");
- },
- "proc_exit" : () => {
- console.log("wasi_snapshot_preview1:proc_exit");
- },
- "environ_get" : () => {
- console.log("wasi_snapshot_preview1:environ_get");
- },
- };
- imports.env = {};
-
- const memory = new WebAssembly.Memory({initial: 256});
- imports.env.memoryBase = 0;
- imports.env.memory = memory;
- imports.env.tableBase = 0;
- imports.env.table = new WebAssembly.Table({ initial: 4, element: 'anyfunc' });
-
- imports.env["abort"] = function() {
- console.error("ABORT");
- };
- imports.env["js_log"] = function(argument) {
- console.log("HI");
- const res = decodeUint8Array(argument, false);
- console.log(res);
- };
- imports.env["js_free"] = function(argument) {
- console.log('integer passed from wasm:', argument);
- };
- imports.env["js_invoke_function"] = function(fn, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10) {
- console.log('function called from wasm:', fn);
- };
-
- const stream = fetch('../../liblightningjs.wasm');
- const { instance: wasmInstance } = await WebAssembly.instantiateStreaming(stream, imports);
- const wasm = wasmInstance.exports;
-
-
- const encodeUint8Array = (inputArray) => {
- const cArrayPointer = wasm.TS_malloc(inputArray.length + 4);
- const arrayLengthView = new Uint32Array(memory.buffer, cArrayPointer, 1);
- arrayLengthView[0] = inputArray.length;
- const arrayMemoryView = new Uint8Array(memory.buffer, cArrayPointer + 4, inputArray.length);
- arrayMemoryView.set(inputArray);
- return cArrayPointer;
- }
-
- const encodeUint32Array = (inputArray) => {
- const cArrayPointer = wasm.TS_malloc((inputArray.length + 1) * 4);
- const arrayMemoryView = new Uint32Array(memory.buffer, cArrayPointer, inputArray.length);
- arrayMemoryView[0] = inputArray.length;
- arrayMemoryView.set(inputArray, 1);
- return cArrayPointer;
- }
-
- const getArrayLength = (arrayPointer) => {
- const arraySizeViewer = new Uint32Array(
- memory.buffer, // value
- arrayPointer, // offset
- 1 // one int
- );
- return arraySizeViewer[0];
- }
- const decodeUint8Array = (arrayPointer, free = true) => {
- const arraySize = getArrayLength(arrayPointer);
- const actualArrayViewer = new Uint8Array(
- memory.buffer, // value
- arrayPointer + 4, // offset (ignoring length bytes)
- arraySize // uint8 count
- );
- // Clone the contents, TODO: In the future we should wrap the Viewer in a class that
- // will free the underlying memory when it becomes unreachable instead of copying here.
- const actualArray = actualArrayViewer.slice(0, arraySize);
- if (free) {
- wasm.TS_free(arrayPointer);
- }
- return actualArray;
- }
-
- const result = wasm.TS_CResult_boolLightningErrorZ_ok(true);
- console.assert(wasm.TS_CResult_boolLightningErrorZ_is_ok(result));
- console.assert(wasm.TS_LDKCResult_boolLightningErrorZ_get_ok(result));
- wasm.TS_CResult_boolLightningErrorZ_free(result);
- console.assert(wasm.TS_CResult_boolLightningErrorZ_ok(false) == result); // malloc doesn't need to guarantee this, but currently does
- console.assert(wasm.TS_CResult_boolLightningErrorZ_is_ok(result));
- console.assert(!wasm.TS_LDKCResult_boolLightningErrorZ_get_ok(result));
- wasm.TS_CResult_boolLightningErrorZ_free(result);
-
- var pk_arr = [];
- for (var i = 0; i < 33; i++) { pk_arr[i] = 42; }
- const pk_bytes = encodeUint8Array(pk_arr);
- const pk_res = wasm.TS_CResult_PublicKeyErrorZ_ok(pk_bytes);
- console.assert(wasm.TS_CResult_PublicKeyErrorZ_is_ok(pk_res));
- const pk_res_bytes = wasm.TS_LDKCResult_PublicKeyErrorZ_get_ok(pk_res);
- wasm.TS_CResult_PublicKeyErrorZ_free(pk_res);
-
- console.log("pass");
- })();
+<script type="module" src="test.mjs">
</script>
</body>
</html>
--- /dev/null
+import * as ldk from "../bindings.mjs";
+async function run_tests() {
+ await ldk.initializeWasm("../../liblightningjs.wasm");
+ const result = ldk.CResult_boolLightningErrorZ_ok(true);
+ console.assert(ldk.CResult_boolLightningErrorZ_is_ok(result));
+ console.assert(ldk.CResult_boolLightningErrorZ_get_ok(result));
+ ldk.CResult_boolLightningErrorZ_free(result);
+ console.assert(ldk.CResult_boolLightningErrorZ_ok(false) == result); // malloc doesn't need to guarantee this, but currently does
+ console.assert(ldk.CResult_boolLightningErrorZ_is_ok(result));
+ console.assert(!ldk.CResult_boolLightningErrorZ_get_ok(result));
+ ldk.CResult_boolLightningErrorZ_free(result);
+
+ /*var pk_arr = [];
+ for (var i = 0; i < 33; i++) { pk_arr[i] = 42; }
+ const pk_bytes = encodeUint8Array(pk_arr);
+ const pk_res = wasm.TS_CResult_PublicKeyErrorZ_ok(pk_bytes);
+ console.assert(wasm.TS_CResult_PublicKeyErrorZ_is_ok(pk_res));
+ const pk_res_bytes = wasm.TS_LDKCResult_PublicKeyErrorZ_get_ok(pk_res);
+ wasm.TS_CResult_PublicKeyErrorZ_free(pk_res);*/
+
+ console.log("pass");
+}
+
+run_tests();
--- /dev/null
+{
+ "compilerOptions": {
+ "target": "es2021",
+ "module": "es2020",
+ "forceConsistentCasingInFileNames": true,
+
+ "strict": true,
+ "noImplicitAny": false,
+ "strictNullChecks": false,
+ "strictFunctionTypes": true,
+ "strictBindCallApply": true,
+ "strictPropertyInitialization": false,
+ "noImplicitThis": true,
+ "useUnknownInCatchVariables": true,
+ "alwaysStrict": true,
+ "noUnusedLocals": false,
+ "noUnusedParameters": false,
+ "exactOptionalPropertyTypes": false,
+ "noImplicitReturns": true,
+ "noFallthroughCasesInSwitch": true,
+ "noUncheckedIndexedAccess": true,
+ "noImplicitOverride": true,
+ "noPropertyAccessFromIndexSignature": true,
+ "allowUnusedLabels": false,
+ "allowUnreachableCode": false,
+
+ "skipLibCheck": true
+ }
+}
self.hu_struct_file_prefix = f"""
import CommonBase from './CommonBase';
-import * as bindings from '../bindings' // TODO: figure out location
+import * as bindings from '../bindings.mjs'
"""
self.c_fn_ty_pfx = ""
- self.file_ext = ".ts"
+ self.file_ext = ".mts"
self.ptr_c_ty = "uint32_t"
self.ptr_native_ty = "number"
self.result_c_ty = "uint32_t"