init(motr-enclave): Setup motr-enclave package

This commit is contained in:
2026-01-07 18:34:00 -05:00
parent 9dc64814b4
commit 2a0fa9ebf8
9 changed files with 756 additions and 0 deletions

32
bun.lock Normal file
View File

@@ -0,0 +1,32 @@
{
"lockfileVersion": 1,
"configVersion": 1,
"workspaces": {
"": {
"name": "@sonr/motr-enclave",
"dependencies": {
"@extism/extism": "^2.0.0-rc13",
},
"devDependencies": {
"@types/bun": "latest",
"typescript": "^5.0.0",
},
"peerDependencies": {
"@extism/extism": "^2.0.0-rc13",
},
},
},
"packages": {
"@extism/extism": ["@extism/extism@2.0.0-rc13", "", {}, "sha512-iQ3mrPKOC0WMZ94fuJrKbJmMyz4LQ9Abf8gd4F5ShxKWa+cRKcVzk0EqRQsp5xXsQ2dO3zJTiA6eTc4Ihf7k+A=="],
"@types/bun": ["@types/bun@1.3.5", "", { "dependencies": { "bun-types": "1.3.5" } }, "sha512-RnygCqNrd3srIPEWBd5LFeUYG7plCoH2Yw9WaZGyNmdTEei+gWaHqydbaIRkIkcbXwhBT94q78QljxN0Sk838w=="],
"@types/node": ["@types/node@25.0.3", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-W609buLVRVmeW693xKfzHeIV6nJGGz98uCPfeXI1ELMLXVeKYZ9m15fAMSaUPBHYLGFsVRcMmSCksQOrZV9BYA=="],
"bun-types": ["bun-types@1.3.5", "", { "dependencies": { "@types/node": "*" } }, "sha512-inmAYe2PFLs0SUbFOWSVD24sg1jFlMPxOjOSSCYqUgn4Hsc3rDc7dFvfVYjFPNHtov6kgUeulV4SxbuIV/stPw=="],
"typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
"undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="],
}
}

132
example/bun.lock Normal file
View File

@@ -0,0 +1,132 @@
{
"lockfileVersion": 1,
"configVersion": 0,
"workspaces": {
"": {
"name": "motr-enclave-example",
"dependencies": {
"@extism/extism": "^2.0.0-rc13",
},
"devDependencies": {
"vite": "^5.4.0",
},
},
},
"packages": {
"@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.21.5", "", { "os": "aix", "cpu": "ppc64" }, "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ=="],
"@esbuild/android-arm": ["@esbuild/android-arm@0.21.5", "", { "os": "android", "cpu": "arm" }, "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg=="],
"@esbuild/android-arm64": ["@esbuild/android-arm64@0.21.5", "", { "os": "android", "cpu": "arm64" }, "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A=="],
"@esbuild/android-x64": ["@esbuild/android-x64@0.21.5", "", { "os": "android", "cpu": "x64" }, "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA=="],
"@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.21.5", "", { "os": "darwin", "cpu": "arm64" }, "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ=="],
"@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.21.5", "", { "os": "darwin", "cpu": "x64" }, "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw=="],
"@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.21.5", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g=="],
"@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.21.5", "", { "os": "freebsd", "cpu": "x64" }, "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ=="],
"@esbuild/linux-arm": ["@esbuild/linux-arm@0.21.5", "", { "os": "linux", "cpu": "arm" }, "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA=="],
"@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.21.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q=="],
"@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.21.5", "", { "os": "linux", "cpu": "ia32" }, "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg=="],
"@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.21.5", "", { "os": "linux", "cpu": "none" }, "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg=="],
"@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.21.5", "", { "os": "linux", "cpu": "none" }, "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg=="],
"@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.21.5", "", { "os": "linux", "cpu": "ppc64" }, "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w=="],
"@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.21.5", "", { "os": "linux", "cpu": "none" }, "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA=="],
"@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.21.5", "", { "os": "linux", "cpu": "s390x" }, "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A=="],
"@esbuild/linux-x64": ["@esbuild/linux-x64@0.21.5", "", { "os": "linux", "cpu": "x64" }, "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ=="],
"@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.21.5", "", { "os": "none", "cpu": "x64" }, "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg=="],
"@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.21.5", "", { "os": "openbsd", "cpu": "x64" }, "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow=="],
"@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.21.5", "", { "os": "sunos", "cpu": "x64" }, "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg=="],
"@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.21.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A=="],
"@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.21.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA=="],
"@esbuild/win32-x64": ["@esbuild/win32-x64@0.21.5", "", { "os": "win32", "cpu": "x64" }, "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw=="],
"@extism/extism": ["@extism/extism@2.0.0-rc13", "", {}, "sha512-iQ3mrPKOC0WMZ94fuJrKbJmMyz4LQ9Abf8gd4F5ShxKWa+cRKcVzk0EqRQsp5xXsQ2dO3zJTiA6eTc4Ihf7k+A=="],
"@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.55.1", "", { "os": "android", "cpu": "arm" }, "sha512-9R0DM/ykwfGIlNu6+2U09ga0WXeZ9MRC2Ter8jnz8415VbuIykVuc6bhdrbORFZANDmTDvq26mJrEVTl8TdnDg=="],
"@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.55.1", "", { "os": "android", "cpu": "arm64" }, "sha512-eFZCb1YUqhTysgW3sj/55du5cG57S7UTNtdMjCW7LwVcj3dTTcowCsC8p7uBdzKsZYa8J7IDE8lhMI+HX1vQvg=="],
"@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.55.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-p3grE2PHcQm2e8PSGZdzIhCKbMCw/xi9XvMPErPhwO17vxtvCN5FEA2mSLgmKlCjHGMQTP6phuQTYWUnKewwGg=="],
"@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.55.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-rDUjG25C9qoTm+e02Esi+aqTKSBYwVTaoS1wxcN47/Luqef57Vgp96xNANwt5npq9GDxsH7kXxNkJVEsWEOEaQ=="],
"@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.55.1", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-+JiU7Jbp5cdxekIgdte0jfcu5oqw4GCKr6i3PJTlXTCU5H5Fvtkpbs4XJHRmWNXF+hKmn4v7ogI5OQPaupJgOg=="],
"@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.55.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-V5xC1tOVWtLLmr3YUk2f6EJK4qksksOYiz/TCsFHu/R+woubcLWdC9nZQmwjOAbmExBIVKsm1/wKmEy4z4u4Bw=="],
"@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.55.1", "", { "os": "linux", "cpu": "arm" }, "sha512-Rn3n+FUk2J5VWx+ywrG/HGPTD9jXNbicRtTM11e/uorplArnXZYsVifnPPqNNP5BsO3roI4n8332ukpY/zN7rQ=="],
"@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.55.1", "", { "os": "linux", "cpu": "arm" }, "sha512-grPNWydeKtc1aEdrJDWk4opD7nFtQbMmV7769hiAaYyUKCT1faPRm2av8CX1YJsZ4TLAZcg9gTR1KvEzoLjXkg=="],
"@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.55.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-a59mwd1k6x8tXKcUxSyISiquLwB5pX+fJW9TkWU46lCqD/GRDe9uDN31jrMmVP3feI3mhAdvcCClhV8V5MhJFQ=="],
"@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.55.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-puS1MEgWX5GsHSoiAsF0TYrpomdvkaXm0CofIMG5uVkP6IBV+ZO9xhC5YEN49nsgYo1DuuMquF9+7EDBVYu4uA=="],
"@rollup/rollup-linux-loong64-gnu": ["@rollup/rollup-linux-loong64-gnu@4.55.1", "", { "os": "linux", "cpu": "none" }, "sha512-r3Wv40in+lTsULSb6nnoudVbARdOwb2u5fpeoOAZjFLznp6tDU8kd+GTHmJoqZ9lt6/Sys33KdIHUaQihFcu7g=="],
"@rollup/rollup-linux-loong64-musl": ["@rollup/rollup-linux-loong64-musl@4.55.1", "", { "os": "linux", "cpu": "none" }, "sha512-MR8c0+UxAlB22Fq4R+aQSPBayvYa3+9DrwG/i1TKQXFYEaoW3B5b/rkSRIypcZDdWjWnpcvxbNaAJDcSbJU3Lw=="],
"@rollup/rollup-linux-ppc64-gnu": ["@rollup/rollup-linux-ppc64-gnu@4.55.1", "", { "os": "linux", "cpu": "ppc64" }, "sha512-3KhoECe1BRlSYpMTeVrD4sh2Pw2xgt4jzNSZIIPLFEsnQn9gAnZagW9+VqDqAHgm1Xc77LzJOo2LdigS5qZ+gw=="],
"@rollup/rollup-linux-ppc64-musl": ["@rollup/rollup-linux-ppc64-musl@4.55.1", "", { "os": "linux", "cpu": "ppc64" }, "sha512-ziR1OuZx0vdYZZ30vueNZTg73alF59DicYrPViG0NEgDVN8/Jl87zkAPu4u6VjZST2llgEUjaiNl9JM6HH1Vdw=="],
"@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.55.1", "", { "os": "linux", "cpu": "none" }, "sha512-uW0Y12ih2XJRERZ4jAfKamTyIHVMPQnTZcQjme2HMVDAHY4amf5u414OqNYC+x+LzRdRcnIG1YodLrrtA8xsxw=="],
"@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.55.1", "", { "os": "linux", "cpu": "none" }, "sha512-u9yZ0jUkOED1BFrqu3BwMQoixvGHGZ+JhJNkNKY/hyoEgOwlqKb62qu+7UjbPSHYjiVy8kKJHvXKv5coH4wDeg=="],
"@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.55.1", "", { "os": "linux", "cpu": "s390x" }, "sha512-/0PenBCmqM4ZUd0190j7J0UsQ/1nsi735iPRakO8iPciE7BQ495Y6msPzaOmvx0/pn+eJVVlZrNrSh4WSYLxNg=="],
"@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.55.1", "", { "os": "linux", "cpu": "x64" }, "sha512-a8G4wiQxQG2BAvo+gU6XrReRRqj+pLS2NGXKm8io19goR+K8lw269eTrPkSdDTALwMmJp4th2Uh0D8J9bEV1vg=="],
"@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.55.1", "", { "os": "linux", "cpu": "x64" }, "sha512-bD+zjpFrMpP/hqkfEcnjXWHMw5BIghGisOKPj+2NaNDuVT+8Ds4mPf3XcPHuat1tz89WRL+1wbcxKY3WSbiT7w=="],
"@rollup/rollup-openbsd-x64": ["@rollup/rollup-openbsd-x64@4.55.1", "", { "os": "openbsd", "cpu": "x64" }, "sha512-eLXw0dOiqE4QmvikfQ6yjgkg/xDM+MdU9YJuP4ySTibXU0oAvnEWXt7UDJmD4UkYialMfOGFPJnIHSe/kdzPxg=="],
"@rollup/rollup-openharmony-arm64": ["@rollup/rollup-openharmony-arm64@4.55.1", "", { "os": "none", "cpu": "arm64" }, "sha512-xzm44KgEP11te3S2HCSyYf5zIzWmx3n8HDCc7EE59+lTcswEWNpvMLfd9uJvVX8LCg9QWG67Xt75AuHn4vgsXw=="],
"@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.55.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-yR6Bl3tMC/gBok5cz/Qi0xYnVbIxGx5Fcf/ca0eB6/6JwOY+SRUcJfI0OpeTpPls7f194as62thCt/2BjxYN8g=="],
"@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.55.1", "", { "os": "win32", "cpu": "ia32" }, "sha512-3fZBidchE0eY0oFZBnekYCfg+5wAB0mbpCBuofh5mZuzIU/4jIVkbESmd2dOsFNS78b53CYv3OAtwqkZZmU5nA=="],
"@rollup/rollup-win32-x64-gnu": ["@rollup/rollup-win32-x64-gnu@4.55.1", "", { "os": "win32", "cpu": "x64" }, "sha512-xGGY5pXj69IxKb4yv/POoocPy/qmEGhimy/FoTpTSVju3FYXUQQMFCaZZXJVidsmGxRioZAwpThl/4zX41gRKg=="],
"@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.55.1", "", { "os": "win32", "cpu": "x64" }, "sha512-SPEpaL6DX4rmcXtnhdrQYgzQ5W2uW3SCJch88lB2zImhJRhIIK44fkUrgIV/Q8yUNfw5oyZ5vkeQsZLhCb06lw=="],
"@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="],
"esbuild": ["esbuild@0.21.5", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.21.5", "@esbuild/android-arm": "0.21.5", "@esbuild/android-arm64": "0.21.5", "@esbuild/android-x64": "0.21.5", "@esbuild/darwin-arm64": "0.21.5", "@esbuild/darwin-x64": "0.21.5", "@esbuild/freebsd-arm64": "0.21.5", "@esbuild/freebsd-x64": "0.21.5", "@esbuild/linux-arm": "0.21.5", "@esbuild/linux-arm64": "0.21.5", "@esbuild/linux-ia32": "0.21.5", "@esbuild/linux-loong64": "0.21.5", "@esbuild/linux-mips64el": "0.21.5", "@esbuild/linux-ppc64": "0.21.5", "@esbuild/linux-riscv64": "0.21.5", "@esbuild/linux-s390x": "0.21.5", "@esbuild/linux-x64": "0.21.5", "@esbuild/netbsd-x64": "0.21.5", "@esbuild/openbsd-x64": "0.21.5", "@esbuild/sunos-x64": "0.21.5", "@esbuild/win32-arm64": "0.21.5", "@esbuild/win32-ia32": "0.21.5", "@esbuild/win32-x64": "0.21.5" }, "bin": "bin/esbuild" }, "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw=="],
"fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
"nanoid": ["nanoid@3.3.11", "", { "bin": "bin/nanoid.cjs" }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
"picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
"postcss": ["postcss@8.5.6", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="],
"rollup": ["rollup@4.55.1", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.55.1", "@rollup/rollup-android-arm64": "4.55.1", "@rollup/rollup-darwin-arm64": "4.55.1", "@rollup/rollup-darwin-x64": "4.55.1", "@rollup/rollup-freebsd-arm64": "4.55.1", "@rollup/rollup-freebsd-x64": "4.55.1", "@rollup/rollup-linux-arm-gnueabihf": "4.55.1", "@rollup/rollup-linux-arm-musleabihf": "4.55.1", "@rollup/rollup-linux-arm64-gnu": "4.55.1", "@rollup/rollup-linux-arm64-musl": "4.55.1", "@rollup/rollup-linux-loong64-gnu": "4.55.1", "@rollup/rollup-linux-loong64-musl": "4.55.1", "@rollup/rollup-linux-ppc64-gnu": "4.55.1", "@rollup/rollup-linux-ppc64-musl": "4.55.1", "@rollup/rollup-linux-riscv64-gnu": "4.55.1", "@rollup/rollup-linux-riscv64-musl": "4.55.1", "@rollup/rollup-linux-s390x-gnu": "4.55.1", "@rollup/rollup-linux-x64-gnu": "4.55.1", "@rollup/rollup-linux-x64-musl": "4.55.1", "@rollup/rollup-openbsd-x64": "4.55.1", "@rollup/rollup-openharmony-arm64": "4.55.1", "@rollup/rollup-win32-arm64-msvc": "4.55.1", "@rollup/rollup-win32-ia32-msvc": "4.55.1", "@rollup/rollup-win32-x64-gnu": "4.55.1", "@rollup/rollup-win32-x64-msvc": "4.55.1", "fsevents": "~2.3.2" }, "bin": "dist/bin/rollup" }, "sha512-wDv/Ht1BNHB4upNbK74s9usvl7hObDnvVzknxqY/E/O3X6rW1U1rV1aENEfJ54eFZDTNo7zv1f5N4edCluH7+A=="],
"source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
"vite": ["vite@5.4.21", "", { "dependencies": { "esbuild": "^0.21.3", "postcss": "^8.4.43", "rollup": "^4.20.0" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || >=20.0.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.4.0" }, "optionalPeers": ["@types/node", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser"], "bin": "bin/vite.js" }, "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw=="],
}
}

150
example/main.js Normal file
View File

@@ -0,0 +1,150 @@
import { createEnclave } from '../dist/enclave.js';
let enclave = null;
let lastDatabase = null;
const LogLevel = { INFO: 'info', OK: 'ok', ERR: 'err', DATA: 'data' };
function log(level, method, message, data = null) {
const el = document.getElementById('log');
const time = new Date().toISOString().slice(11, 23);
const prefix = method ? `[${method}]` : '';
let entry = `<div class="log-entry"><span class="log-time">${time}</span> <span class="log-${level}">${prefix} ${message}</span>`;
if (data !== null) {
entry += `\n<span class="log-data">${JSON.stringify(data, null, 2)}</span>`;
}
entry += '</div>';
el.innerHTML += entry;
el.scrollTop = el.scrollHeight;
console.log(`[${time}] ${prefix} ${message}`, data ?? '');
}
function setStatus(ok, message) {
const el = document.getElementById('status');
el.textContent = message;
el.className = `status ${ok ? 'ok' : 'err'}`;
}
async function init() {
try {
log(LogLevel.INFO, null, 'Loading enclave.wasm...');
enclave = await createEnclave('./enclave.wasm', { debug: true });
setStatus(true, 'Ready');
log(LogLevel.OK, null, 'Plugin loaded');
} catch (err) {
setStatus(false, 'Failed');
log(LogLevel.ERR, null, `Load failed: ${err.message}`);
}
}
window.testGenerate = async function() {
if (!enclave) return log(LogLevel.ERR, 'generate', 'Plugin not loaded');
const credential = document.getElementById('credential').value;
log(LogLevel.INFO, 'generate', `credential=${credential.slice(0, 16)}...`);
try {
const result = await enclave.generate(credential);
log(LogLevel.OK, 'generate', `DID created: ${result.did}`, result);
if (result.database) {
lastDatabase = result.database;
document.getElementById('database').value = btoa(String.fromCharCode(...result.database));
log(LogLevel.INFO, 'generate', 'Database saved for load() test');
}
return result;
} catch (err) {
log(LogLevel.ERR, 'generate', err.message);
throw err;
}
};
window.testLoad = async function() {
if (!enclave) return log(LogLevel.ERR, 'load', 'Plugin not loaded');
const b64 = document.getElementById('database').value;
if (!b64) return log(LogLevel.ERR, 'load', 'Database required');
log(LogLevel.INFO, 'load', `database.length=${b64.length}`);
try {
const database = Uint8Array.from(atob(b64), c => c.charCodeAt(0));
const result = await enclave.load(database);
if (result.success) {
log(LogLevel.OK, 'load', `Loaded DID: ${result.did}`, result);
} else {
log(LogLevel.ERR, 'load', result.error, result);
}
return result;
} catch (err) {
log(LogLevel.ERR, 'load', err.message);
throw err;
}
};
window.testExec = async function() {
if (!enclave) return log(LogLevel.ERR, 'exec', 'Plugin not loaded');
const filter = document.getElementById('filter').value;
if (!filter) return log(LogLevel.ERR, 'exec', 'Filter required');
log(LogLevel.INFO, 'exec', `filter="${filter}"`);
try {
const result = await enclave.exec(filter);
if (result.success) {
log(LogLevel.OK, 'exec', 'Success', result);
} else {
log(LogLevel.ERR, 'exec', result.error, result);
}
return result;
} catch (err) {
log(LogLevel.ERR, 'exec', err.message);
throw err;
}
};
window.testQuery = async function() {
if (!enclave) return log(LogLevel.ERR, 'query', 'Plugin not loaded');
const did = document.getElementById('did').value;
log(LogLevel.INFO, 'query', did ? `did="${did}"` : 'did=(current)');
try {
const result = await enclave.query(did);
log(LogLevel.OK, 'query', `Resolved: ${result.did}`, result);
return result;
} catch (err) {
log(LogLevel.ERR, 'query', err.message);
throw err;
}
};
window.setFilter = function(filter) {
document.getElementById('filter').value = filter;
};
window.clearLog = function() {
document.getElementById('log').innerHTML = '';
};
window.runAllTests = async function() {
log(LogLevel.INFO, null, '=== Running all tests ===');
try {
await testGenerate();
await testLoad();
await testExec();
await testQuery();
log(LogLevel.OK, null, '=== All tests passed ===');
} catch (err) {
log(LogLevel.ERR, null, `=== Tests failed: ${err.message} ===`);
}
};
init();

32
package.json Normal file
View File

@@ -0,0 +1,32 @@
{
"name": "@sonr/motr-enclave",
"version": "0.1.0",
"type": "module",
"main": "./dist/enclave.js",
"module": "./dist/enclave.js",
"types": "./dist/index.d.ts",
"exports": {
".": {
"import": "./dist/enclave.js",
"types": "./dist/index.d.ts"
}
},
"files": [
"dist"
],
"scripts": {
"build": "bun run scripts/build.ts",
"typecheck": "tsc --noEmit -p src/tsconfig.json",
"clean": "rm -rf dist"
},
"dependencies": {
"@extism/extism": "^2.0.0-rc13"
},
"devDependencies": {
"@types/bun": "latest",
"typescript": "^5.0.0"
},
"peerDependencies": {
"@extism/extism": "^2.0.0-rc13"
}
}

30
scripts/build.ts Normal file
View File

@@ -0,0 +1,30 @@
import { $ } from 'bun';
const result = await Bun.build({
entrypoints: ['./src/index.ts'],
outdir: './dist',
format: 'esm',
target: 'browser',
minify: false,
sourcemap: 'external',
external: ['@extism/extism'],
naming: {
entry: 'enclave.js',
},
});
if (!result.success) {
console.error('Build failed:');
for (const log of result.logs) {
console.error(log);
}
process.exit(1);
}
console.log('Build successful:');
for (const output of result.outputs) {
console.log(` ${output.path}`);
}
await $`bun run tsc --emitDeclarationOnly --declaration -p src/tsconfig.json --outDir dist`;
console.log('Type declarations generated');

203
src/enclave.ts Normal file
View File

@@ -0,0 +1,203 @@
import createPlugin, { type Plugin } from '@extism/extism';
import type {
EnclaveOptions,
GenerateOutput,
LoadOutput,
ExecOutput,
QueryOutput,
Resource,
} from './types';
/**
* Motr Enclave - WebAssembly plugin wrapper for encrypted key storage
*
* @example
* ```typescript
* import { createEnclave } from '@sonr/motr-enclave';
*
* const enclave = await createEnclave('/enclave.wasm');
* const { did, database } = await enclave.generate(credential);
* ```
*/
export class Enclave {
private plugin: Plugin;
private logger: EnclaveOptions['logger'];
private debug: boolean;
private constructor(plugin: Plugin, options: EnclaveOptions = {}) {
this.plugin = plugin;
this.logger = options.logger ?? console;
this.debug = options.debug ?? false;
}
/**
* Create an Enclave instance from a WASM source
*
* @param wasm - URL string, file path, or Uint8Array of WASM bytes
* @param options - Configuration options
*/
static async create(
wasm: string | Uint8Array,
options: EnclaveOptions = {}
): Promise<Enclave> {
const manifest =
typeof wasm === 'string'
? { wasm: [{ url: wasm }] }
: { wasm: [{ data: wasm }] };
const plugin = await createPlugin(manifest, {
useWasi: true,
logger: options.debug ? (options.logger as Console) : undefined,
});
return new Enclave(plugin, options);
}
/**
* Initialize database with WebAuthn credential
*
* @param credential - Base64-encoded PublicKeyCredential from WebAuthn registration
* @returns DID and serialized database buffer
*/
async generate(credential: string): Promise<GenerateOutput> {
this.log('generate: starting with credential');
const input = JSON.stringify({ credential });
const result = await this.plugin.call('generate', input);
if (!result) throw new Error('generate: plugin returned no output');
const output = result.json() as GenerateOutput;
this.log(`generate: created DID ${output.did}`);
return output;
}
/**
* Load database from serialized buffer
*
* @param database - Raw database bytes (from IPFS or storage)
* @returns Success status and loaded DID
*/
async load(database: Uint8Array | number[]): Promise<LoadOutput> {
this.log('load: loading database from buffer');
const dbArray = database instanceof Uint8Array ? Array.from(database) : database;
const input = JSON.stringify({ database: dbArray });
const result = await this.plugin.call('load', input);
if (!result) throw new Error('load: plugin returned no output');
const output = result.json() as LoadOutput;
if (output.success) {
this.log(`load: loaded database for DID ${output.did}`);
} else {
this.log(`load: failed - ${output.error}`, 'error');
}
return output;
}
/**
* Execute action with filter syntax
*
* @param filter - GitHub-style filter (e.g., "resource:accounts action:list")
* @param token - Optional UCAN token for authorization
* @returns Action result
*/
async exec(filter: string, token?: string): Promise<ExecOutput> {
this.log(`exec: executing filter "${filter}"`);
const input = JSON.stringify({ filter, token });
const result = await this.plugin.call('exec', input);
if (!result) throw new Error('exec: plugin returned no output');
const output = result.json() as ExecOutput;
if (output.success) {
this.log('exec: completed successfully');
} else {
this.log(`exec: failed - ${output.error}`, 'error');
}
return output;
}
/**
* Execute action with typed parameters
*
* @param resource - Resource type (accounts, credentials, sessions, grants)
* @param action - Action to perform
* @param options - Additional options
*/
async execute(
resource: Resource,
action: string,
options: { subject?: string; token?: string } = {}
): Promise<ExecOutput> {
let filter = `resource:${resource} action:${action}`;
if (options.subject) {
filter += ` subject:${options.subject}`;
}
return this.exec(filter, options.token);
}
/**
* Query DID document and associated resources
*
* @param did - DID to resolve (empty for current DID)
* @returns Resolved DID document with resources
*/
async query(did: string = ''): Promise<QueryOutput> {
this.log(`query: resolving DID ${did || '(current)'}`);
const input = JSON.stringify({ did });
const result = await this.plugin.call('query', input);
if (!result) throw new Error('query: plugin returned no output');
const output = result.json() as QueryOutput;
this.log(`query: resolved DID ${output.did}`);
return output;
}
/**
* Reset plugin state
*/
async reset(): Promise<void> {
this.log('reset: clearing plugin state');
await this.plugin.reset();
}
/**
* Close and cleanup plugin resources
*/
async close(): Promise<void> {
this.log('close: releasing plugin resources');
await this.plugin.close();
}
private log(message: string, level: 'log' | 'error' | 'warn' | 'info' | 'debug' = 'debug'): void {
if (this.debug && this.logger) {
this.logger[level](`[Enclave] ${message}`);
}
}
}
/**
* Create an Enclave instance
*
* @param wasm - URL string, file path, or Uint8Array of WASM bytes
* @param options - Configuration options
*
* @example
* ```typescript
* // From URL
* const enclave = await createEnclave('/enclave.wasm');
*
* // From bytes
* const wasmBytes = await fetch('/enclave.wasm').then(r => r.arrayBuffer());
* const enclave = await createEnclave(new Uint8Array(wasmBytes));
* ```
*/
export async function createEnclave(
wasm: string | Uint8Array,
options: EnclaveOptions = {}
): Promise<Enclave> {
return Enclave.create(wasm, options);
}

31
src/index.ts Normal file
View File

@@ -0,0 +1,31 @@
/**
* Motr Enclave - ESM wrapper for the Extism WebAssembly plugin
*
* @packageDocumentation
*/
export { Enclave, createEnclave } from './enclave';
export type {
// Input/Output types
GenerateInput,
GenerateOutput,
LoadInput,
LoadOutput,
ExecInput,
ExecOutput,
QueryInput,
QueryOutput,
// Shared types
VerificationMethod,
Account,
Credential,
// Options
EnclaveOptions,
// Filter types
Resource,
AccountAction,
CredentialAction,
SessionAction,
GrantAction,
FilterBuilder,
} from './types';

17
src/tsconfig.json Normal file
View File

@@ -0,0 +1,17 @@
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "bundler",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"declaration": true,
"declarationMap": true,
"outDir": "../dist",
"rootDir": ".",
"types": ["bun-types"]
},
"include": ["*.ts"],
"exclude": ["node_modules", "dist"]
}

129
src/types.ts Normal file
View File

@@ -0,0 +1,129 @@
/**
* TypeScript types for Motr Enclave plugin
* These types match the Go structs in main.go
*/
// ============================================================================
// Generate
// ============================================================================
export interface GenerateInput {
/** Base64-encoded PublicKeyCredential from WebAuthn registration */
credential: string;
}
export interface GenerateOutput {
/** The generated DID (e.g., "did:sonr:abc123") */
did: string;
/** Serialized database buffer for storage */
database: number[];
}
// ============================================================================
// Load
// ============================================================================
export interface LoadInput {
/** Raw database bytes (typically from IPFS CID resolution) */
database: number[];
}
export interface LoadOutput {
success: boolean;
did?: string;
error?: string;
}
// ============================================================================
// Exec
// ============================================================================
export interface ExecInput {
/** GitHub-style filter: "resource:accounts action:sign subject:did:sonr:abc" */
filter: string;
/** UCAN token for authorization (optional) */
token?: string;
}
export interface ExecOutput {
success: boolean;
result?: unknown;
error?: string;
}
// ============================================================================
// Query
// ============================================================================
export interface QueryInput {
/** DID to resolve (empty string uses current DID) */
did: string;
}
export interface QueryOutput {
did: string;
controller: string;
verification_methods: VerificationMethod[];
accounts: Account[];
credentials: Credential[];
}
// ============================================================================
// Shared Types
// ============================================================================
export interface VerificationMethod {
id: string;
type: string;
controller: string;
public_key: string;
purpose: string;
}
export interface Account {
address: string;
chain_id: string;
coin_type: number;
account_index: number;
address_index: number;
label: string;
is_default: boolean;
}
export interface Credential {
credential_id: string;
device_name: string;
device_type: string;
authenticator: string;
transports: string[];
created_at: string;
last_used: string;
}
// ============================================================================
// Enclave Options
// ============================================================================
export interface EnclaveOptions {
/** Custom logger (defaults to console) */
logger?: Pick<Console, 'log' | 'error' | 'warn' | 'info' | 'debug'>;
/** Enable debug logging */
debug?: boolean;
}
// ============================================================================
// Filter Builder Types
// ============================================================================
export type Resource = 'accounts' | 'credentials' | 'sessions' | 'grants';
export type AccountAction = 'list' | 'sign';
export type CredentialAction = 'list';
export type SessionAction = 'list' | 'create' | 'revoke';
export type GrantAction = 'list' | 'create' | 'revoke';
export interface FilterBuilder {
resource(r: Resource): this;
action(a: string): this;
subject(s: string): this;
build(): string;
}