Kaynağa Gözat

bundle sdk js bindings

thesimplekid 1 yıl önce
ebeveyn
işleme
17c6bc5f4b

+ 7 - 0
bindings/cashu-sdk-js/.gitignore

@@ -0,0 +1,7 @@
+/target
+**/*.rs.bk
+Cargo.lock
+bin/
+pkg/
+wasm-pack.log
+*.tgz

+ 12 - 0
bindings/cashu-sdk-js/examples/amount.js

@@ -0,0 +1,12 @@
+const {Amount, loadWasmAsync, loadWasmSync } = require("..");
+
+
+function main() {
+  loadWasmSync();
+
+  let amount = Amount.fromSat(BigInt(10));
+
+  console.log(amount.toSat())
+}
+
+main();

+ 19 - 0
bindings/cashu-sdk-js/examples/wallet.js

@@ -0,0 +1,19 @@
+const {Amount, loadWasmAsync, Wallet, Client } = require("..");
+
+
+async  function main() {
+  await loadWasmAsync();
+
+  let client = new Client("https://mutinynet-cashu.thesimpekid.space");
+
+  let keys = await client.getKeys();
+
+  let wallet = new Wallet(client, keys);
+
+  let amount = Amount.fromSat(BigInt(10));
+  let pr = await wallet.requestMint(amount);
+
+  console.log(pr);
+}
+
+main();

+ 1 - 2
bindings/cashu-sdk-js/justfile

@@ -2,5 +2,4 @@ build:
 	wasm-pack build
 
 pack:
-	wasm-pack pack
-
+	npm run package

+ 44 - 0
bindings/cashu-sdk-js/package.json

@@ -0,0 +1,44 @@
+{
+  "name": "@rust-cashu/cashu-sdk",
+  "version": "0.0.1",
+  "description": "Cashu protocol implementation, for JavaScript",
+  "keywords": [
+    "cashu",
+    "protocol",
+    "rust",
+    "bindings"
+  ],
+  "license": "BSD-3-Clause",
+  "homepage": "https://github.com/thesimplekid/cashu-crab",
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/thesimplekid/cashu-crab"
+  },
+  "bugs": {
+    "url": "https://github.com/thesimplekid/cashu-crab/issues"
+  },
+  "author": {
+    "name": "thesimplekid",
+    "email": "tsk@thesimplekid.com",
+    "url": "https://github.com/thesimplekid"
+  },
+  "main": "pkg/cashu_sdk_js.js",
+  "types": "pkg/cashu_sdk_js.d.ts",
+  "files": [
+      "pkg/cashu_sdk_js_bg.wasm.js",
+      "pkg/cashu_sdk_js_bg.wasm.d.ts",
+      "pkg/cashu_sdk_js.js",
+      "pkg/cashu_sdk_js.d.ts"
+  ],
+  "devDependencies": {
+    "wasm-pack": "^0.10.2"
+  },
+  "engines": {
+    "node": ">= 10"
+  },
+  "scripts": {
+    "build": "WASM_PACK_ARGS=--release ./scripts/build.sh",
+    "build:dev": "WASM_PACK_ARGS=--dev ./scripts/build.sh",
+    "package": "npm run build && npm pack"
+  }
+}

+ 21 - 0
bindings/cashu-sdk-js/scripts/LICENSE

@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2022-2023 Yuki Kishimoto
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.

+ 35 - 0
bindings/cashu-sdk-js/scripts/build.sh

@@ -0,0 +1,35 @@
+#!/bin/bash
+#
+# Build the JavaScript modules
+#
+# This script is really a workaround for https://github.com/rustwasm/wasm-pack/issues/1074.
+#
+# Currently, the only reliable way to load WebAssembly in all the JS
+# environments we want to target (web-via-webpack, web-via-browserify, jest)
+# seems to be to pack the WASM into base64, and then unpack it and instantiate
+# it at runtime.
+#
+# Hopefully one day, https://github.com/rustwasm/wasm-pack/issues/1074 will be
+# fixed and this will be unnecessary.
+
+set -e
+
+cd $(dirname "$0")/..
+
+WASM_BINDGEN_WEAKREF=1 wasm-pack build --target nodejs --scope rust-cashu --out-dir pkg "${WASM_PACK_ARGS[@]}"
+
+# Convert the Wasm into a JS file that exports the base64'ed Wasm.
+echo "module.exports = \`$(base64 pkg/cashu_sdk_js_bg.wasm)\`;" > pkg/cashu_sdk_js_bg.wasm.js
+
+# In the JavaScript:
+#  1. Strip out the lines that load the WASM, and our new epilogue.
+#  2. Remove the imports of `TextDecoder` and `TextEncoder`. We rely on the global defaults.
+{
+  sed -e '/Text..coder.*= require(.util.)/d' \
+      -e '/^const path = /,$d' pkg/cashu_sdk_js.js
+  cat scripts/epilogue.js
+} > pkg/cashu_sdk_js.js.new
+mv pkg/cashu_sdk_js.js.new pkg/cashu_sdk_js.js
+
+# also extend the typescript
+cat scripts/epilogue.d.ts >> pkg/cashu_sdk_js.d.ts

+ 10 - 0
bindings/cashu-sdk-js/scripts/epilogue.d.ts

@@ -0,0 +1,10 @@
+/**
+ * Load the WebAssembly module in the background, if it has not already been loaded.
+ *
+ * Returns a promise which will resolve once the other methods are ready.
+ *
+ * @returns {Promise<void>}
+ */
+ export function loadWasmAsync(): Promise<void>;
+
+ export function loadWasmSync(): void;

+ 76 - 0
bindings/cashu-sdk-js/scripts/epilogue.js

@@ -0,0 +1,76 @@
+let inited = false;
+module.exports.loadWasmSync = function () {
+    if (inited) {
+        return;
+    }
+    if (initPromise) {
+        throw new Error("Asynchronous initialisation already in progress: cannot initialise synchronously");
+    }
+    const bytes = unbase64(require("./cashu_sdk_js_bg.wasm.js"));
+    const mod = new WebAssembly.Module(bytes);
+    const instance = new WebAssembly.Instance(mod, imports);
+    wasm = instance.exports;
+    wasm.__wbindgen_start();
+    inited = true;
+};
+
+let initPromise = null;
+
+/**
+ * Load the WebAssembly module in the background, if it has not already been loaded.
+ *
+ * Returns a promise which will resolve once the other methods are ready.
+ *
+ * @returns {Promise<void>}
+ */
+module.exports.loadWasmAsync = function () {
+    if (inited) {
+        return Promise.resolve();
+    }
+    if (!initPromise) {
+        initPromise = Promise.resolve()
+            .then(() => require("./cashu_sdk_js_bg.wasm.js"))
+            .then((b64) => WebAssembly.instantiate(unbase64(b64), imports))
+            .then((result) => {
+                wasm = result.instance.exports;
+                wasm.__wbindgen_start();
+                inited = true;
+            });
+    }
+    return initPromise;
+};
+
+const b64lookup = new Uint8Array([
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 62, 0, 62, 0, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 63, 0, 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,
+]);
+
+// base64 decoder, based on the code at https://developer.mozilla.org/en-US/docs/Glossary/Base64#solution_2_%E2%80%93_rewriting_atob_and_btoa_using_typedarrays_and_utf-8
+function unbase64(sBase64) {
+    const sB64Enc = sBase64.replace(/[^A-Za-z0-9+/]/g, "");
+    const nInLen = sB64Enc.length;
+    const nOutLen = (nInLen * 3 + 1) >> 2;
+    const taBytes = new Uint8Array(nOutLen);
+
+    let nMod3;
+    let nMod4;
+    let nUint24 = 0;
+    let nOutIdx = 0;
+    for (let nInIdx = 0; nInIdx < nInLen; nInIdx++) {
+        nMod4 = nInIdx & 3;
+        nUint24 |= b64lookup[sB64Enc.charCodeAt(nInIdx)] << (6 * (3 - nMod4));
+        if (nMod4 === 3 || nInLen - nInIdx === 1) {
+            nMod3 = 0;
+            while (nMod3 < 3 && nOutIdx < nOutLen) {
+                taBytes[nOutIdx] = (nUint24 >>> ((16 >>> nMod3) & 24)) & 255;
+                nMod3++;
+                nOutIdx++;
+            }
+            nUint24 = 0;
+        }
+    }
+
+    return taBytes;
+}