From be1295e1bba43131517a9d37328dd7df7f2089ad Mon Sep 17 00:00:00 2001 From: Alive24 Date: Sun, 16 Feb 2025 15:01:02 +0000 Subject: [PATCH] feat: WASM executor without COI --- packages/core/src/signer/btc/verify.ts | 15 +- .../src/signer/doge/signerDogePrivateKey.ts | 13 +- packages/core/src/signer/doge/verify.ts | 12 +- packages/demo/package.json | 2 +- .../SSRI/components/ParameterInput.tsx | 2 + .../SSRI/components/ScriptAmountInput.tsx | 2 + .../components/TransactionSkeletonPanel.tsx | 2 + .../src/app/connected/(tools)/SSRI/page.tsx | 46 +- .../src/app/connected/(tools)/SSRI/types.ts | 2 + packages/demo/src/app/layout.tsx | 1 + packages/demo/src/components/Background.tsx | 2 +- packages/demo/src/components/RandomWalk.tsx | 2 +- packages/demo/src/context.tsx | 15 +- packages/demo/tsconfig.json | 19 +- packages/ssri-executor-wasm/.gitignore | 6 + packages/ssri-executor-wasm/Cargo.lock | 943 +++++++++ packages/ssri-executor-wasm/Cargo.toml | 39 + packages/ssri-executor-wasm/index.ts | 5 + packages/ssri-executor-wasm/package.json | 20 + packages/ssri-executor-wasm/src/error.rs | 20 + packages/ssri-executor-wasm/src/lib.rs | 336 ++++ packages/ssri-executor-wasm/src/ssri_vm.rs | 479 +++++ packages/ssri-executor-wasm/src/types.rs | 201 ++ packages/ssri-executor-wasm/tsconfig.json | 23 + packages/ssri-executor-wasm/webpack.config.js | 49 + packages/ssri/README.md | 3 +- packages/ssri/esbuild.commonjs.config.mjs | 28 + packages/ssri/esbuild.config.mjs | 28 + packages/ssri/package.json | 26 +- packages/ssri/src/barrel.ts | 3 + packages/ssri/src/executor.ts | 426 ++++ packages/ssri/src/executor.worker.ts | 128 ++ packages/ssri/src/rpc.worker.ts | 171 ++ packages/ssri/src/types.ts | 68 + packages/ssri/src/worker.d.ts | 13 + packages/ssri/tsconfig.base.json | 2 +- packages/ssri/tsconfig.commonjs.json | 7 +- packages/ssri/tsconfig.json | 5 + packages/udt/README.md | 9 +- pnpm-lock.yaml | 1773 +++++++++++++++-- 40 files changed, 4753 insertions(+), 193 deletions(-) create mode 100644 packages/ssri-executor-wasm/.gitignore create mode 100644 packages/ssri-executor-wasm/Cargo.lock create mode 100644 packages/ssri-executor-wasm/Cargo.toml create mode 100644 packages/ssri-executor-wasm/index.ts create mode 100644 packages/ssri-executor-wasm/package.json create mode 100644 packages/ssri-executor-wasm/src/error.rs create mode 100644 packages/ssri-executor-wasm/src/lib.rs create mode 100644 packages/ssri-executor-wasm/src/ssri_vm.rs create mode 100644 packages/ssri-executor-wasm/src/types.rs create mode 100644 packages/ssri-executor-wasm/tsconfig.json create mode 100644 packages/ssri-executor-wasm/webpack.config.js create mode 100644 packages/ssri/esbuild.commonjs.config.mjs create mode 100644 packages/ssri/esbuild.config.mjs create mode 100644 packages/ssri/src/executor.worker.ts create mode 100644 packages/ssri/src/rpc.worker.ts create mode 100644 packages/ssri/src/types.ts create mode 100644 packages/ssri/src/worker.d.ts diff --git a/packages/core/src/signer/btc/verify.ts b/packages/core/src/signer/btc/verify.ts index e0c80acd..e8835790 100644 --- a/packages/core/src/signer/btc/verify.ts +++ b/packages/core/src/signer/btc/verify.ts @@ -1,11 +1,18 @@ import { secp256k1 } from "@noble/curves/secp256k1"; import { ripemd160 } from "@noble/hashes/ripemd160"; import { sha256 } from "@noble/hashes/sha256"; -import { magicHash } from "bitcoinjs-message"; import bs58check from "bs58check"; import { Bytes, BytesLike, bytesConcat, bytesFrom } from "../../bytes/index.js"; import { Hex, hexFrom } from "../../hex/index.js"; +let magicHash: ((message: string, messagePrefix: string) => Uint8Array) | null = + null; + +if (typeof window !== "undefined") { + void import("bitcoinjs-message").then((mod) => { + magicHash = mod.magicHash; + }); +} /** * @public */ @@ -45,5 +52,9 @@ export function verifyMessageBtcEcdsa( const rawSign = bytesFrom(signature, "base64").slice(1); - return secp256k1.verify(bytesFrom(rawSign), magicHash(challenge), publicKey); + return secp256k1.verify( + bytesFrom(rawSign), + magicHash!(challenge, "\x19Bitcoin Signed Message:\n"), + publicKey, + ); } diff --git a/packages/core/src/signer/doge/signerDogePrivateKey.ts b/packages/core/src/signer/doge/signerDogePrivateKey.ts index b6d58ef8..398f8d7c 100644 --- a/packages/core/src/signer/doge/signerDogePrivateKey.ts +++ b/packages/core/src/signer/doge/signerDogePrivateKey.ts @@ -1,5 +1,6 @@ +"use client"; + import { secp256k1 } from "@noble/curves/secp256k1"; -import { magicHash } from "bitcoinjs-message"; import { Bytes, bytesConcat, @@ -12,6 +13,14 @@ import { Hex, hexFrom } from "../../hex/index.js"; import { btcP2pkhAddressFromPublicKey } from "../btc/verify.js"; import { SignerDoge } from "./signerDoge.js"; +let magicHash: ((message: string, messagePrefix: string) => Uint8Array) | null = + null; + +if (typeof window !== "undefined") { + void import("bitcoinjs-message").then((mod) => { + magicHash = mod.magicHash; + }); +} /** * A class extending SignerDoge that provides access to a Doge address. * @public @@ -85,7 +94,7 @@ export class SignerDogePrivateKey extends SignerDoge { const challenge = typeof msg === "string" ? msg : hexFrom(msg).slice(2); const signature = secp256k1.sign( - magicHash(challenge, "\x19Dogecoin Signed Message:\n"), + magicHash!(challenge, "\x19Dogecoin Signed Message:\n"), this.privateKey, ); diff --git a/packages/core/src/signer/doge/verify.ts b/packages/core/src/signer/doge/verify.ts index b63414f9..78aa8a84 100644 --- a/packages/core/src/signer/doge/verify.ts +++ b/packages/core/src/signer/doge/verify.ts @@ -1,5 +1,4 @@ import { secp256k1 } from "@noble/curves/secp256k1"; -import { magicHash } from "bitcoinjs-message"; import { bytesFrom, BytesLike } from "../../bytes/index.js"; import { hexFrom } from "../../hex/index.js"; import { @@ -7,6 +6,15 @@ import { btcPublicKeyFromP2pkhAddress, } from "../btc/verify.js"; +let magicHash: ((message: string, messagePrefix: string) => Uint8Array) | null = + null; + +if (typeof window !== "undefined") { + void import("bitcoinjs-message").then((mod) => { + magicHash = mod.magicHash; + }); +} + /** * @public */ @@ -31,7 +39,7 @@ export function verifyMessageDogeEcdsa( btcEcdsaPublicKeyHash( sig .recoverPublicKey( - magicHash(challenge, "\x19Dogecoin Signed Message:\n"), + magicHash!(challenge, "\x19Dogecoin Signed Message:\n"), ) .toHex(), ), diff --git a/packages/demo/package.json b/packages/demo/package.json index d52513a2..51dc0c3b 100644 --- a/packages/demo/package.json +++ b/packages/demo/package.json @@ -18,7 +18,7 @@ "@lit/react": "^1.0.5", "@uiw/react-json-view": "2.0.0-alpha.30", "lucide-react": "^0.427.0", - "next": "14.2.10", + "next": "15.1.7", "react": "^18", "react-dom": "^18" }, diff --git a/packages/demo/src/app/connected/(tools)/SSRI/components/ParameterInput.tsx b/packages/demo/src/app/connected/(tools)/SSRI/components/ParameterInput.tsx index 6e2b11f9..6b90748d 100644 --- a/packages/demo/src/app/connected/(tools)/SSRI/components/ParameterInput.tsx +++ b/packages/demo/src/app/connected/(tools)/SSRI/components/ParameterInput.tsx @@ -1,3 +1,5 @@ +"use client"; + import React from "react"; import { TextInput } from "@/src/components/Input"; import { Button } from "@/src/components/Button"; diff --git a/packages/demo/src/app/connected/(tools)/SSRI/components/ScriptAmountInput.tsx b/packages/demo/src/app/connected/(tools)/SSRI/components/ScriptAmountInput.tsx index 6a1c2f9a..28ca3d20 100644 --- a/packages/demo/src/app/connected/(tools)/SSRI/components/ScriptAmountInput.tsx +++ b/packages/demo/src/app/connected/(tools)/SSRI/components/ScriptAmountInput.tsx @@ -1,3 +1,5 @@ +"use client"; + import React, { useState, useEffect } from "react"; import { Button } from "@/src/components/Button"; import { TextInput } from "@/src/components/Input"; diff --git a/packages/demo/src/app/connected/(tools)/SSRI/components/TransactionSkeletonPanel.tsx b/packages/demo/src/app/connected/(tools)/SSRI/components/TransactionSkeletonPanel.tsx index 33eedfd6..13d781eb 100644 --- a/packages/demo/src/app/connected/(tools)/SSRI/components/TransactionSkeletonPanel.tsx +++ b/packages/demo/src/app/connected/(tools)/SSRI/components/TransactionSkeletonPanel.tsx @@ -1,3 +1,5 @@ +"use client"; + import React from "react"; import { Button } from "@/src/components/Button"; import { ccc } from "@ckb-ccc/connector-react"; diff --git a/packages/demo/src/app/connected/(tools)/SSRI/page.tsx b/packages/demo/src/app/connected/(tools)/SSRI/page.tsx index 54b9aa2e..8727bb68 100644 --- a/packages/demo/src/app/connected/(tools)/SSRI/page.tsx +++ b/packages/demo/src/app/connected/(tools)/SSRI/page.tsx @@ -6,20 +6,12 @@ import { TextInput } from "@/src/components/Input"; import { useApp } from "@/src/context"; import { ButtonsPanel } from "@/src/components/ButtonsPanel"; import { Dropdown } from "@/src/components/Dropdown"; -import { - ScriptAmountArrayInput, - ScriptAmountInput, - ScriptAmountType, -} from "@/src/app/connected/(tools)/SSRI/components/ScriptAmountInput"; +import { ScriptAmountType } from "@/src/app/connected/(tools)/SSRI/components/ScriptAmountInput"; import { ssri } from "@ckb-ccc/ssri"; import { ccc } from "@ckb-ccc/connector-react"; import JsonView from "@uiw/react-json-view"; import { darkTheme } from "@uiw/react-json-view/dark"; import Image from "next/image"; -import { - HexArrayInput, - HexInput, -} from "@/src/app/connected/(tools)/SSRI/components/HexArrayInput"; import { Icon } from "@/src/components/Icon"; import { MethodParamType, PARAM_TYPE_OPTIONS } from "./types"; import { ParamValue } from "./types"; @@ -35,12 +27,9 @@ const METHODS_OPTIONS = [ ]; export default function SSRI() { - const { signer, createSender } = useApp(); + const { signer, createSender, ssriExecutor } = useApp(); const { log, error } = createSender("SSRI"); - const [SSRIExecutorURL, setSSRIExecutorURL] = useState( - "http://localhost:9090", - ); const [contractOutPointTx, setContractOutPointTx] = useState(""); const [contractOutPointIndex, setContractOutPointIndex] = useState("0"); @@ -132,14 +121,16 @@ export default function SSRI() { ]); const makeSSRICall = async () => { + if (!ssriExecutor) { + return; + } + await ssriExecutor.confirmStarted(); if (!signer) return; setIsLoading(true); setMethodResult(undefined); setIconDataURL(""); - const testSSRIExecutor = new ssri.ExecutorJsonRpc(SSRIExecutorURL); - let contract: ssri.Trait | undefined; try { const targetOutPoint = { @@ -155,7 +146,7 @@ export default function SSRI() { if (!scriptCell.cellOutput.type?.hash()) { throw new Error("Script cell type hash not found"); } - contract = new ssri.Trait(scriptCell.outPoint, testSSRIExecutor); + contract = new ssri.Trait(scriptCell.outPoint, ssriExecutor); if (!contract) { throw new Error("Contract not initialized"); @@ -226,11 +217,11 @@ export default function SSRI() { e instanceof Error ? e.message : typeof e === "object" - ? "Check your SSRI server" + ? "Unexpected error. Please retry or post an issue on GitHub." : String(e) || "Unknown error"; if (String(errorMessage).length < 3) { errorMessage = - "Check your SSRI server or URL. Run `docker run -p 9090:9090 hanssen0/ckb-ssri-server` to start a local SSRI server."; + "Unexpected error. Please retry or post an issue on GitHub."; } setMethodResult(`Error: ${errorMessage}`); error(`Error: ${errorMessage}`); @@ -327,18 +318,6 @@ export default function SSRI() { 1 -
- - docker run -p 9090:9090 hanssen0/ckb-ssri-server - - to start a local SSRI server. -
- - -
- - 2 -
The default parameters are prepared to just work. Just click{" "} @@ -354,7 +333,7 @@ export default function SSRI() {
- 3 + 2
All Done! You called an SSRI method! Try playing with other @@ -373,11 +352,6 @@ export default function SSRI() {
<> -
; + declare context: React.ContextType; refBg: RefObject = createRef(); ref0: RefObject = createRef(); diff --git a/packages/demo/src/components/RandomWalk.tsx b/packages/demo/src/components/RandomWalk.tsx index a3d4b7cf..0020415b 100644 --- a/packages/demo/src/components/RandomWalk.tsx +++ b/packages/demo/src/components/RandomWalk.tsx @@ -9,7 +9,7 @@ export type RandomWalkProps = React.ComponentPropsWithoutRef<"div"> & { export class RandomWalk extends Component { static contextType = APP_CONTEXT; - context: React.ContextType; + declare context: React.ContextType; // position, speed, force physics: number[] = [0, 0, 0, 0, 0, 0]; diff --git a/packages/demo/src/context.tsx b/packages/demo/src/context.tsx index 4a3750bd..4507fcc7 100644 --- a/packages/demo/src/context.tsx +++ b/packages/demo/src/context.tsx @@ -1,7 +1,7 @@ "use client"; import React, { createContext, ReactNode, useEffect, useState } from "react"; -import { ccc } from "@ckb-ccc/connector-react"; +import { ccc, ssri } from "@ckb-ccc/connector-react"; import { Notifications } from "./components/Notifications"; import { formatString, useGetExplorerLink } from "./utils"; import { Key } from "lucide-react"; @@ -49,6 +49,7 @@ export const APP_CONTEXT = createContext< warn: (...msgs: ReactNode[]) => void; error: (...msgs: ReactNode[]) => void; }; + ssriExecutor: ssri.ExecutorWASM | undefined; } | undefined >(undefined); @@ -61,6 +62,9 @@ export function AppProvider({ children }: { children: React.ReactNode }) { const [enabledAnimate, setAnimate] = useState(true); const [backgroundLifted, setBackgroundLifted] = useState(false); + const [ssriExecutorWASM, setSsriExecutorWASM] = useState< + ssri.ExecutorWASM | undefined + >(undefined); const { wallet, @@ -73,6 +77,14 @@ export function AppProvider({ children }: { children: React.ReactNode }) { const { explorerAddress } = useGetExplorerLink(); + useEffect(() => { + if (!ssriExecutorWASM) { + setSsriExecutorWASM( + new ssri.ExecutorWASM("https://testnet.ckb.dev/", true, 10, 300), + ); + } + }, [ssriExecutorWASM]); + useEffect(() => { if ( !privateKeySigner || @@ -175,6 +187,7 @@ export function AppProvider({ children }: { children: React.ReactNode }) { warn: (...msgs) => sendMessage("warn", title, msgs), error: (...msgs) => sendMessage("error", title, msgs), }), + ssriExecutor: ssriExecutorWASM, }} > {children} diff --git a/packages/demo/tsconfig.json b/packages/demo/tsconfig.json index c97e06b1..9396e50b 100644 --- a/packages/demo/tsconfig.json +++ b/packages/demo/tsconfig.json @@ -1,6 +1,12 @@ { "compilerOptions": { - "lib": ["dom", "dom.iterable", "esnext"], + "lib": [ + "dom", + "dom.iterable", + "esnext", + "ES2024", + "WebWorker", + ], "allowJs": true, "skipLibCheck": true, "strict": true, @@ -18,10 +24,13 @@ } ], "paths": { - "@/*": ["./*"] + "@/*": [ + "./*" + ] }, "emitDecoratorMetadata": true, - "experimentalDecorators": true + "experimentalDecorators": true, + "target": "ES2024" }, "include": [ "next-env.d.ts", @@ -30,5 +39,7 @@ ".next/types/**/*.ts", "src/app/connected/(tools)/IssueXUdtSus" ], - "exclude": ["node_modules"] + "exclude": [ + "node_modules" + ] } diff --git a/packages/ssri-executor-wasm/.gitignore b/packages/ssri-executor-wasm/.gitignore new file mode 100644 index 00000000..a8137caf --- /dev/null +++ b/packages/ssri-executor-wasm/.gitignore @@ -0,0 +1,6 @@ +/dist +/package-lock.json +/yarn.lock +/node_modules +/pkg +/target \ No newline at end of file diff --git a/packages/ssri-executor-wasm/Cargo.lock b/packages/ssri-executor-wasm/Cargo.lock new file mode 100644 index 00000000..56958016 --- /dev/null +++ b/packages/ssri-executor-wasm/Cargo.lock @@ -0,0 +1,943 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "anyhow" +version = "1.0.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04" + +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + +[[package]] +name = "blake2b-ref" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "294d17c72e0ba59fad763caa112368d0672083779cdebbb97164f4bb4c1e339a" + +[[package]] +name = "blake2b-rs" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89a8565807f21b913288968e391819e7f9b2f0f46c7b89549c051cccf3a2771" +dependencies = [ + "cc", + "cty", +] + +[[package]] +name = "bumpalo" +version = "3.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f61dac84819c6588b558454b194026eb1f09c293b9036ae9b159e74e73ab6cf9" +dependencies = [ + "serde", +] + +[[package]] +name = "cc" +version = "1.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c3d1b2e905a3a7b00a6141adb0e4c0bb941d11caf55349d863942a1cc44e3c9" +dependencies = [ + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "ckb-channel" +version = "0.116.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "853f561e90ff59d858dc87c1ac385fae948984859c874fd8d3bd1bbab335889d" +dependencies = [ + "crossbeam-channel", +] + +[[package]] +name = "ckb-constant" +version = "0.116.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5baf91b16a3b8360c85211dfdff3d2adc0a1f3ae571ea6b1637d55d6b227e312" + +[[package]] +name = "ckb-error" +version = "0.116.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01041f8a1d7eeaf85caca3547bb78d929d6a4d62774509d7eb438b6bc310ba30" +dependencies = [ + "anyhow", + "ckb-occupied-capacity", + "derive_more", + "thiserror", +] + +[[package]] +name = "ckb-fixed-hash" +version = "0.116.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a7491f18717b84827923935cc5adb1bcdf9c924e377b478d089f4694e7c779b" +dependencies = [ + "ckb-fixed-hash-core", + "ckb-fixed-hash-macros", +] + +[[package]] +name = "ckb-fixed-hash-core" +version = "0.116.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9509f63fedb9b6e42cfd0db47d3dc5acb6b029da546d5d4451d08afc44c70cf8" +dependencies = [ + "ckb_schemars", + "faster-hex", + "serde", + "thiserror", +] + +[[package]] +name = "ckb-fixed-hash-macros" +version = "0.116.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdd89533a5da746f50798752a46f5f084f110c849335be94baf506790ebee931" +dependencies = [ + "ckb-fixed-hash-core", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ckb-gen-types" +version = "0.116.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a0f2d0f4224507a027d25d64824dd0dc8d367c8b5bead30289eaffe1381a7fb" +dependencies = [ + "cfg-if", + "ckb-error", + "ckb-fixed-hash", + "ckb-hash", + "ckb-occupied-capacity", + "molecule", + "numext-fixed-uint", +] + +[[package]] +name = "ckb-hash" +version = "0.116.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5754bc49cf76a7e8829fe6a7cf1eea1284cbca9777b521f072c76d6ae28d303" +dependencies = [ + "blake2b-ref", + "blake2b-rs", +] + +[[package]] +name = "ckb-jsonrpc-types" +version = "0.116.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef7e123043ca3701cf05ba4c3699b34f3b179609109a4c8c3afa68922f722be7" +dependencies = [ + "ckb-types", + "ckb_schemars", + "faster-hex", + "serde", + "serde_json", +] + +[[package]] +name = "ckb-merkle-mountain-range" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56ccb671c5921be8a84686e6212ca184cb1d7c51cadcdbfcbd1cc3f042f5dfb8" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "ckb-occupied-capacity" +version = "0.116.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee4aa07af7cec38d15cfe4c1ce150514fba5a4e78996bbbd098982106bee7d8d" +dependencies = [ + "ckb-occupied-capacity-core", + "ckb-occupied-capacity-macros", +] + +[[package]] +name = "ckb-occupied-capacity-core" +version = "0.116.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a63ed90996ba24ab26d5ac8ae22fd002a293f4a4e4526042e1adf84b1889e176" +dependencies = [ + "serde", +] + +[[package]] +name = "ckb-occupied-capacity-macros" +version = "0.116.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a6aae3f1f8d194cd5bd4328c9c7281f0d7acc73976b2771576cdc06a9ed608f" +dependencies = [ + "ckb-occupied-capacity-core", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ckb-rational" +version = "0.116.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed570e816c80fffdfafb58c7c895df8c08c64ba56ce79d824e5ff976dd1a7381" +dependencies = [ + "numext-fixed-uint", + "serde", +] + +[[package]] +name = "ckb-ssri-executor-wasm" +version = "0.1.0" +dependencies = [ + "ckb-hash", + "ckb-jsonrpc-types", + "ckb-types", + "ckb-vm", + "ckb_schemars", + "console_error_panic_hook", + "getrandom 0.2.15", + "hex", + "log", + "serde", + "serde-wasm-bindgen", + "serde_json", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-logger", + "web-sys", +] + +[[package]] +name = "ckb-types" +version = "0.116.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b05cc1c6aab0c40b323b233617b67860f9d679fac431a34d1f1b0853d700e9d" +dependencies = [ + "bit-vec", + "bytes", + "ckb-channel", + "ckb-constant", + "ckb-error", + "ckb-fixed-hash", + "ckb-gen-types", + "ckb-hash", + "ckb-merkle-mountain-range", + "ckb-occupied-capacity", + "ckb-rational", + "derive_more", + "golomb-coded-set", + "merkle-cbt", + "molecule", + "numext-fixed-uint", + "once_cell", + "paste", +] + +[[package]] +name = "ckb-vm" +version = "0.24.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2c3d68dc7f891e5555c7ebc054722b28ab005e51c5076f54c20d36002dc8e83" +dependencies = [ + "byteorder", + "bytes", + "cc", + "ckb-vm-definitions", + "derive_more", + "goblin 0.2.3", + "goblin 0.4.0", + "rand", + "scroll", + "serde", +] + +[[package]] +name = "ckb-vm-definitions" +version = "0.24.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2fdf9c8ee14409b2208d23b9ad88828242d7881153ddc04872b66d2e018a52f" +dependencies = [ + "paste", +] + +[[package]] +name = "ckb_schemars" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f21f99fca82a4eb8708e406e99246987b087ecc1e1babeece1a0b1d5238b1750" +dependencies = [ + "ckb_schemars_derive", + "dyn-clone", + "serde", + "serde_json", +] + +[[package]] +name = "ckb_schemars_derive" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40c813b4fadbdd9f33b1cf02a1ddfa9537d955c8d2fbe150d1fc1684dbf78e73" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn 1.0.109", +] + +[[package]] +name = "console_error_panic_hook" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +dependencies = [ + "cfg-if", + "wasm-bindgen", +] + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "crossbeam-channel" +version = "0.5.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ba6d68e24814cb8de6bb986db8222d3a027d15872cabc0d18817bc3c0e4471" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "cty" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35" + +[[package]] +name = "derive_more" +version = "0.99.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3da29a38df43d6f156149c9b43ded5e018ddff2a855cf2cfd62e8cd7d079c69f" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version", + "syn 2.0.98", +] + +[[package]] +name = "dyn-clone" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "feeef44e73baff3a26d371801df019877a9866a8c493d315ab00177843314f35" + +[[package]] +name = "faster-hex" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51e2ce894d53b295cf97b05685aa077950ff3e8541af83217fc720a6437169f8" + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "goblin" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d20fd25aa456527ce4f544271ae4fea65d2eda4a6561ea56f39fb3ee4f7e3884" +dependencies = [ + "log", + "plain", + "scroll", +] + +[[package]] +name = "goblin" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "532a09cd3df2c6bbfc795fb0434bff8f22255d1d07328180e918a2e6ce122d4d" +dependencies = [ + "log", + "plain", + "scroll", +] + +[[package]] +name = "golomb-coded-set" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "812f314a99fb5b7f0f9d0a8388539578f83f3aca6a65f588b8dbeefb731e2f98" +dependencies = [ + "siphasher", +] + +[[package]] +name = "heapsize" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1679e6ea370dee694f91f1dc469bf94cf8f52051d147aec3e1f9497c6fc22461" +dependencies = [ + "winapi", +] + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +dependencies = [ + "serde", +] + +[[package]] +name = "itoa" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" + +[[package]] +name = "js-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "libc" +version = "0.2.169" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" + +[[package]] +name = "log" +version = "0.4.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "merkle-cbt" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "171d2f700835121c3b04ccf0880882987a050fd5c7ae88148abf537d33dd3a56" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "molecule" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fd9767ab5e5f2ea40f71ff4c8bdb633c50509052e093c2fdd0e390a749dfa3" +dependencies = [ + "bytes", + "cfg-if", + "faster-hex", +] + +[[package]] +name = "numext-constructor" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "621fe0f044729f810c6815cdd77e8f5e0cd803ce4f6a38380ebfc1322af98661" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "numext-fixed-uint" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c68c76f96d589d1009a666c5072f37f3114d682696505f2cf445f27766c7d70" +dependencies = [ + "numext-fixed-uint-core", + "numext-fixed-uint-hack", +] + +[[package]] +name = "numext-fixed-uint-core" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6aab1d6457b97b49482f22a92f0f58a2f39bdd7f3b2f977eae67e8bc206aa980" +dependencies = [ + "heapsize", + "numext-constructor", + "rand", + "serde", + "thiserror", +] + +[[package]] +name = "numext-fixed-uint-hack" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0200f8d55c36ec1b6a8cf810115be85d4814f045e0097dfd50033ba25adb4c9e" +dependencies = [ + "numext-fixed-uint-core", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "once_cell" +version = "1.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e" + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "plain" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" + +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "proc-macro2" +version = "1.0.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha", + "rand_core", + "rand_hc", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core", +] + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rustversion" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4" + +[[package]] +name = "ryu" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd" + +[[package]] +name = "scroll" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fda28d4b4830b807a8b43f7b0e6b5df875311b3e7621d84577188c175b6ec1ec" +dependencies = [ + "scroll_derive", +] + +[[package]] +name = "scroll_derive" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aaaae8f38bb311444cfb7f1979af0bc9240d95795f75f9ceddf6a59b79ceffa0" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "semver" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f79dfe2d285b0488816f30e700a7438c5a73d816b5b7d3ac72fbc48b0d185e03" + +[[package]] +name = "serde" +version = "1.0.217" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde-wasm-bindgen" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8302e169f0eddcc139c70f139d19d6467353af16f9fce27e8c30158036a1e16b" +dependencies = [ + "js-sys", + "serde", + "wasm-bindgen", +] + +[[package]] +name = "serde_derive" +version = "1.0.217" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.98", +] + +[[package]] +name = "serde_derive_internals" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "serde_json" +version = "1.0.138" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d434192e7da787e94a6ea7e9670b26a036d0ca41e0b7efb2676dd32bae872949" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.98" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.98", +] + +[[package]] +name = "unicode-ident" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a210d160f08b701c8721ba1c726c11662f877ea6b7094007e1ca9a1041945034" + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" +dependencies = [ + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn 2.0.98", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" +dependencies = [ + "cfg-if", + "js-sys", + "once_cell", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.98", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "wasm-logger" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "074649a66bb306c8f2068c9016395fa65d8e08d2affcbf95acf3c24c3ab19718" +dependencies = [ + "log", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "web-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.98", +] diff --git a/packages/ssri-executor-wasm/Cargo.toml b/packages/ssri-executor-wasm/Cargo.toml new file mode 100644 index 00000000..4f7db046 --- /dev/null +++ b/packages/ssri-executor-wasm/Cargo.toml @@ -0,0 +1,39 @@ +[package] +name = "ckb-ssri-executor-wasm" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = ["cdylib", "rlib"] + +[dependencies] +wasm-bindgen = "0.2.100" +serde_json = { version = "1" } +serde = { version = "1", features = ["derive"] } +console_error_panic_hook = { version = "0.1.6", optional = true } +wasm-bindgen-futures = "0.4" +log = "0.4" +wasm-logger = "0.2" +serde-wasm-bindgen = "0.6.5" + +ckb-types = "0.116.1" +ckb-jsonrpc-types = "0.116.1" +ckb-vm = "=0.24.9" +ckb-hash = "0.116.1" + + +hex = { version = "0.4.3", features = ["serde"] } +web-sys = { version = "0.3.77", features = ["XmlHttpRequest", "Window", "Request", "RequestInit", "RequestMode", "Response", "TextEncoder", "BroadcastChannel", "Performance", "MessageEvent"] } +getrandom = { version = "0.2", features = ["js"] } + +[dependencies.schemars] +version = "0.8.19" +package = "ckb_schemars" + + +[features] +default = ["console_error_panic_hook"] + +# [profile.release] +# # Tell `rustc` to optimize for small code size. +# opt-level = "s" diff --git a/packages/ssri-executor-wasm/index.ts b/packages/ssri-executor-wasm/index.ts new file mode 100644 index 00000000..6ff1953a --- /dev/null +++ b/packages/ssri-executor-wasm/index.ts @@ -0,0 +1,5 @@ +import * as wasmModule from "./pkg/ckb-ssri-executor-wasm"; +import wasm from "./pkg/ckb-ssri-executor-wasm_bg.wasm"; +wasmModule.initSync({ module: wasm }); + +export default wasmModule; diff --git a/packages/ssri-executor-wasm/package.json b/packages/ssri-executor-wasm/package.json new file mode 100644 index 00000000..701f0d31 --- /dev/null +++ b/packages/ssri-executor-wasm/package.json @@ -0,0 +1,20 @@ +{ + "name": "@ckb-ccc/ssri-executor-wasm", + "scripts": { + "build-debug": "webpack --mode=development", + "build": "webpack --mode=production", + "serve": "webpack serve" + }, + "devDependencies": { + "@wasm-tool/wasm-pack-plugin": "1.5.0", + "arraybuffer-loader": "^1.0.8", + "buffer": "^6.0.3", + "ts-loader": "^9.5.1", + "typescript": "^5.7.2", + "wasm-loader": "^1.3.0", + "webpack": "^5.93.0", + "webpack-cli": "^5.1.4" + }, + "main": "dist/index.js", + "version": "0.1.0-alpha.1" +} diff --git a/packages/ssri-executor-wasm/src/error.rs b/packages/ssri-executor-wasm/src/error.rs new file mode 100644 index 00000000..6e191977 --- /dev/null +++ b/packages/ssri-executor-wasm/src/error.rs @@ -0,0 +1,20 @@ +use std::fmt::Display; + +#[derive(Debug)] +#[repr(i32)] +#[allow(clippy::enum_variant_names)] +pub enum Error { + Script(i8), + Vm(String), + Runtime(String), +} + +impl Display for Error { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Error::Script(code) => write!(f, "Script returns {}", code), + Error::Vm(msg) => write!(f, "VM error: {}", msg), + Error::Runtime(msg) => write!(f, "Runtime error: {}", msg), + } + } +} diff --git a/packages/ssri-executor-wasm/src/lib.rs b/packages/ssri-executor-wasm/src/lib.rs new file mode 100644 index 00000000..8bb09cb9 --- /dev/null +++ b/packages/ssri-executor-wasm/src/lib.rs @@ -0,0 +1,336 @@ +mod error; +mod ssri_vm; +mod types; + +use crate::error::Error; +use std::{cell::RefCell, collections::HashMap, str::FromStr}; + +use wasm_bindgen_futures::wasm_bindgen::prelude::*; +use web_sys::BroadcastChannel; + +use log::debug; +use serde::{de::DeserializeOwned, Deserialize, Serialize}; +use serde_wasm_bindgen::Serializer; +use ssri_vm::execute_riscv_binary; +use types::{ + BroadcastChannelMessagePacket, Cell, CellOutputWithData, GetCellsArguments, Hex, Order, + Pagination, SearchKey, VmResult +}; + +use ckb_jsonrpc_types::{ + CellOutput, Either, JsonBytes, Script, TransactionView, TransactionWithStatusResponse +}; +use ckb_types::H256; + +static SERIALIZER: Serializer = Serializer::new() + .serialize_large_number_types_as_bigints(true) + .serialize_maps_as_objects(true); + +thread_local! { + static CHANNEL: RefCell> = RefCell::new(None); + static GET_TRANSACTION_CACHE: RefCell> = RefCell::new(HashMap::with_capacity(10000)); + static GET_CELLS_CACHE: RefCell>> = RefCell::new(HashMap::with_capacity(10000)); +} + +#[wasm_bindgen] +pub fn put_get_transaction_cache(tx_hash: &str, transaction_with_status_response_string: &str) -> Result<(), JsValue> { + console_error_panic_hook::set_once(); + debug!("WASM putting get_transaction_cache"); + let tx_hash = H256::from_str(&tx_hash[2..]).map_err(|e| JsValue::from_str(&e.to_string()))?; + let transaction_with_status_response_object: serde_json::Value = serde_json::from_str(&transaction_with_status_response_string) + .map_err(|e| JsValue::from_str(&e.to_string()))?; + let transaction_with_status_response: TransactionWithStatusResponse = serde_json::from_value(transaction_with_status_response_object).map_err(|e| JsValue::from_str(&e.to_string()))?; + GET_TRANSACTION_CACHE.with(|v| v.borrow_mut().insert(tx_hash.clone(), transaction_with_status_response)); + Ok(()) +} + +#[wasm_bindgen] +pub fn put_get_cells_cache( + search_key: JsValue, + order: JsValue, + limit: JsValue, + after_cursor: JsValue, + cells_string: &str, +) -> Result<(), JsValue> { + console_error_panic_hook::set_once(); + debug!("WASM putting get_cells cache"); + let search_key: SearchKey = serde_wasm_bindgen::from_value(search_key)?; + let order: Order = serde_wasm_bindgen::from_value(order)?; + let limit: u32 = serde_wasm_bindgen::from_value(limit)?; + let after_cursor: Option> = serde_wasm_bindgen::from_value(after_cursor)?; + let cells_json: serde_json::Value = serde_json::from_str(&cells_string).map_err(|e| JsValue::from_str(&e.to_string()))?; + let cells: Pagination = serde_json::from_value(cells_json).map_err(|e| JsValue::from_str(&e.to_string()))?; + let cache_key_string = format!("{:?}", (search_key, order, limit, after_cursor)); + GET_CELLS_CACHE.with(|v| { + v.borrow_mut() + .insert(cache_key_string, cells) + }); + debug!("WASM put get cells cache successfully"); + Ok(()) +} + +#[wasm_bindgen] +pub async fn initiate( + log_level: String, + channel_name: Option, +) -> Result<(), JsValue> { + // Initialize logger + wasm_logger::init(wasm_logger::Config::new( + log::Level::from_str(&log_level).expect("Bad log level"), + )); + + // Initialize broadcast channel + debug!( + "Initializing broadcast channel with name: {}", + channel_name.clone().unwrap_or("ssri-executor".into()) + ); + let channel_name = channel_name.unwrap_or("ssri-executor".into()); + let channel = BroadcastChannel::new(&channel_name)?; + + CHANNEL.with(|v| *v.borrow_mut() = Some(channel)); + + debug!("Initiated!"); + Ok(()) +} + +#[wasm_bindgen] +pub fn run_script_level_code( + tx_hash: &str, + index: u32, + args: Vec, + script_debug: bool, +) -> Result { + let tx_hash = H256::from_str(&tx_hash[2..]).map_err(|e| JsValue::from_str(&e.to_string()))?; + let args: Vec = args + .into_iter() + .map(|v| serde_wasm_bindgen::from_value(v)) + .collect::>()?; + let result = run_script(script_debug, tx_hash, index, args, None, None, None) + .map_err(|e| JsValue::from_str(&e.to_string()))?; + Ok(result.serialize(&SERIALIZER)?) +} + +#[wasm_bindgen] +pub fn run_script_level_script( + tx_hash: &str, + index: u32, + args: Vec, + script: JsValue, + script_debug: bool, +) -> Result { + let tx_hash = H256::from_str(&tx_hash[2..]).map_err(|e| JsValue::from_str(&e.to_string()))?; + let args: Vec = args + .into_iter() + .map(|v| serde_wasm_bindgen::from_value(v)) + .collect::>()?; + let script: Script = serde_wasm_bindgen::from_value(script)?; + let result = run_script(script_debug, tx_hash, index, args, Some(script), None, None) + .map_err(|e| JsValue::from_str(&e.to_string()))?; + Ok(result.serialize(&SERIALIZER)?) +} + +#[wasm_bindgen] +pub fn run_script_level_cell( + tx_hash: &str, + index: u32, + args: Vec, + cell: JsValue, + script_debug: bool, +) -> Result { + let tx_hash = H256::from_str(&tx_hash[2..]).map_err(|e| JsValue::from_str(&e.to_string()))?; + let args: Vec = args + .into_iter() + .map(|v| serde_wasm_bindgen::from_value(v)) + .collect::>()?; + let cell: CellOutputWithData = serde_wasm_bindgen::from_value(cell)?; + let result = run_script(script_debug, tx_hash, index, args, None, Some(cell), None) + .map_err(|e| JsValue::from_str(&e.to_string()))?; + Ok(result.serialize(&SERIALIZER)?) +} + +#[wasm_bindgen] +pub fn run_script_level_tx( + tx_hash: &str, + index: u32, + args: Vec, + tx: JsValue, + script_debug: bool, +) -> Result { + let tx_hash = H256::from_str(&tx_hash[2..]).map_err(|e| JsValue::from_str(&e.to_string()))?; + let args: Vec = args + .into_iter() + .map(|v| serde_wasm_bindgen::from_value(v)) + .collect::>()?; + let tx: TransactionView = serde_wasm_bindgen::from_value(tx)?; + let result = run_script(script_debug, tx_hash, index, args, None, None, Some(tx)) + .map_err(|e| JsValue::from_str(&e.to_string()))?; + Ok(result.serialize(&SERIALIZER)?) +} + +pub fn get_cells( + search_key: SearchKey, + order: Order, + limit: u32, + after_cursor: Option>, +) -> Result, JsValue> { + let cache_key = ( + search_key.clone(), + order.clone(), + limit, + after_cursor.clone(), + ); + let cache_key_string = format!("{:?}", cache_key); + + let cached_cells = GET_CELLS_CACHE.with(|cache| { + // Try direct lookup first. Might fail. + if let Some(cells) = cache.borrow().get(&cache_key_string) { + let cells_json = serde_json::to_string(cells).ok()?; + let cells_owned: Pagination = serde_json::from_str(&cells_json).ok()?; + return Some(cells_owned); + } + + // Fall back to manual lookup if direct lookup fails + for (existing_key, cells) in cache.borrow().iter() { + if format!("{:?}", existing_key) == cache_key_string { + debug!("Found matching key based on string representation"); + let cells_json = serde_json::to_string(cells).ok()?; + let cells_owned: Pagination = serde_json::from_str(&cells_json).ok()?; + return Some(cells_owned); + } + } + + None + }); + + if let Some(cells) = cached_cells { + debug!("Get Cells Cache hit in WASM!"); + return Ok(cells); + }; + debug!("Get Cells Cache missed in WASM, sending update request message to ssriRpcWorker!"); + + let message = BroadcastChannelMessagePacket { + sender_name: "ssriExecutorWasm".to_string(), + target_name: "ssriRpcWorker".to_string(), + message_label: "getCells".to_string(), + data_type_hint: "GetCellsArguments".to_string(), + data: serde_json::to_value(&GetCellsArguments { + search_key, + order, + limit: limit.into(), + after_cursor: after_cursor + .map_or_else(|| JsonBytes::default(), |v| JsonBytes::from_vec(v)), + }) + .unwrap(), + }; + + CHANNEL.with(|v| { + if let Some(channel) = &*v.borrow() { + debug!("WASM posting message to get cells"); + channel.post_message(&serde_wasm_bindgen::to_value(&message).unwrap())?; + } + Ok::<_, JsValue>(()) + })?; + + Err(JsValue::from_str( + "GetCells message sent, shall be available in next iteration!", + )) +} + +fn run_script( + script_debug: bool, + tx_hash: H256, + index: u32, + args: Vec, + script: Option