@hazae41/bobine 0.0.6 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +66 -16
- package/out/mod.d.ts +2 -0
- package/out/mod.js +39 -0
- package/out/mods/server/bin.d.ts +1 -1
- package/out/mods/server/bin.js +64 -29
- package/out/mods/server/mod.d.ts +1 -1
- package/package.json +5 -16
package/README.md
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
A blockchain in your garage
|
|
4
4
|
|
|
5
|
+
https://bobine.tech/
|
|
6
|
+
|
|
7
|
+
[**📦 NPM**](https://www.npmjs.com/package/@hazae41/bobine) • [**📦 JSR**](https://jsr.io/@hazae41/bobine)
|
|
8
|
+
|
|
5
9
|
## Features
|
|
6
10
|
|
|
7
11
|
- Ultra simple
|
|
@@ -17,10 +21,41 @@ A blockchain in your garage
|
|
|
17
21
|
|
|
18
22
|
### Binary
|
|
19
23
|
|
|
20
|
-
|
|
24
|
+
Install the binary with Deno
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
deno install -gf -A jsr:@hazae41/bobine
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Generate an Ed25519 keypair by running the following code in your browser/deno/node/bun console
|
|
31
|
+
|
|
32
|
+
```typescript
|
|
33
|
+
const keypair = await crypto.subtle.generateKey("Ed25519", true, ["sign", "verify"])
|
|
34
|
+
|
|
35
|
+
const privateKey = await crypto.subtle.exportKey("pkcs8", keypair.privateKey)
|
|
36
|
+
|
|
37
|
+
const publicKey = await crypto.subtle.exportKey("raw", keypair.publicKey)
|
|
38
|
+
|
|
39
|
+
console.log(`ED25519_PRIVATE_KEY_HEX=${new Uint8Array(privateKey).toHex()}`)
|
|
40
|
+
|
|
41
|
+
console.log(`ED25519_PUBLIC_KEY_HEX=${new Uint8Array(publicKey).toHex()}`)
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Create an `.env.local` file and replace your Ed25519 values
|
|
45
|
+
|
|
46
|
+
```env
|
|
47
|
+
DATABASE_PATH=./local/database.db
|
|
48
|
+
|
|
49
|
+
SCRIPTS_PATH=./local/scripts
|
|
50
|
+
|
|
51
|
+
ED25519_PRIVATE_KEY_HEX=302e020100300506032b657004220420edff8b2503b91f58bc0f0435ca17de549f89d6a7cde4c277161e031669395005
|
|
52
|
+
ED25519_PUBLIC_KEY_HEX=90dcd81a473a4e59a84df6cb8f77af3d34c7fd6171ed959ca04a75f07a57b4b9
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Run the server
|
|
21
56
|
|
|
22
57
|
```bash
|
|
23
|
-
|
|
58
|
+
bobine serve --env=./.env.local
|
|
24
59
|
```
|
|
25
60
|
|
|
26
61
|
### Library
|
|
@@ -71,16 +106,29 @@ Accepts a form data with the following fields
|
|
|
71
106
|
|
|
72
107
|
## WebAssembly API
|
|
73
108
|
|
|
74
|
-
|
|
109
|
+
The WebAssembly VM extensively uses reference types for its API and for module-to-module communication
|
|
110
|
+
|
|
111
|
+
### AssemblyScript
|
|
112
|
+
|
|
113
|
+
You can use [stdbob](https://github.com/hazae41/stdbob) to easily import AssemblyScript declarations for all internal modules
|
|
75
114
|
|
|
76
|
-
|
|
115
|
+
Or you can declare internal modules manually with the module name and method name
|
|
116
|
+
|
|
117
|
+
```tsx
|
|
118
|
+
@external("bigints", "add")
|
|
119
|
+
declare function add(x: externref, y: externref): externref
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
And you can declare external modules by using the module address as hex
|
|
77
123
|
|
|
78
124
|
```tsx
|
|
79
125
|
@external("5feeee846376f6436990aa2757bc67fbc4498bcc9993b647788e273ad6fde474", "add")
|
|
80
|
-
declare function add(x:
|
|
126
|
+
declare function add(x: externref, y: externref): externref
|
|
81
127
|
```
|
|
82
128
|
|
|
83
|
-
###
|
|
129
|
+
### All internal modules
|
|
130
|
+
|
|
131
|
+
#### blobs
|
|
84
132
|
|
|
85
133
|
You can pass bytes between modules by storing them in the blob storage and loading them via reference
|
|
86
134
|
|
|
@@ -94,7 +142,7 @@ You can pass bytes between modules by storing them in the blob storage and loadi
|
|
|
94
142
|
|
|
95
143
|
- `blob.to_hex/from_hex/to_base64/from_base64(blob: blobref): blobref` = convert blobs to/from hex/base64 without loading them into memory
|
|
96
144
|
|
|
97
|
-
|
|
145
|
+
#### bigints
|
|
98
146
|
|
|
99
147
|
You can work with infinite-precision bigints
|
|
100
148
|
|
|
@@ -120,7 +168,7 @@ You can work with infinite-precision bigints
|
|
|
120
168
|
|
|
121
169
|
- `bigints.from_base10(base16: blobref): bigintref` = convert base10 utf8 bytes to bigint
|
|
122
170
|
|
|
123
|
-
|
|
171
|
+
#### packs
|
|
124
172
|
|
|
125
173
|
You can pack various arguments (numbers, refs) into a pack which can be passed between modules and/or encoded/decoded into bytes
|
|
126
174
|
|
|
@@ -175,7 +223,9 @@ function writePack(pack: packref) {
|
|
|
175
223
|
|
|
176
224
|
- `packs.get<T>(pack: packref, index: i32): T` = get the value of a pack at `index` (throws if not found)
|
|
177
225
|
|
|
178
|
-
|
|
226
|
+
- `packs.length(pack: packref): i32` = get the length of a pack
|
|
227
|
+
|
|
228
|
+
#### env
|
|
179
229
|
|
|
180
230
|
Get infos about the executing environment
|
|
181
231
|
|
|
@@ -183,7 +233,7 @@ Get infos about the executing environment
|
|
|
183
233
|
|
|
184
234
|
- `env.uuid(): blobref` = get the unique uuid of this environment (similar to a chain id)
|
|
185
235
|
|
|
186
|
-
|
|
236
|
+
#### modules
|
|
187
237
|
|
|
188
238
|
Modules are identified by their address as a blob of bytes (pure sha256-output 32-length bytes without any encoding)
|
|
189
239
|
|
|
@@ -195,7 +245,7 @@ Modules are identified by their address as a blob of bytes (pure sha256-output 3
|
|
|
195
245
|
|
|
196
246
|
- `modules.self(): blobref` = get your module address as blob
|
|
197
247
|
|
|
198
|
-
|
|
248
|
+
#### storage
|
|
199
249
|
|
|
200
250
|
You can use a private storage (it works like storage and events at the same time)
|
|
201
251
|
|
|
@@ -203,13 +253,13 @@ You can use a private storage (it works like storage and events at the same time
|
|
|
203
253
|
|
|
204
254
|
- `storage.get(key: blobref): blobref` = get the latest value from storage at key
|
|
205
255
|
|
|
206
|
-
|
|
256
|
+
#### sha256
|
|
207
257
|
|
|
208
258
|
Use the SHA-256 hashing algorithm
|
|
209
259
|
|
|
210
260
|
- `sha256.digest(payload: blobref): blobref` = hash the payload and returns the digest
|
|
211
261
|
|
|
212
|
-
|
|
262
|
+
#### ed25519
|
|
213
263
|
|
|
214
264
|
Use the Ed25519 signing algorithm
|
|
215
265
|
|
|
@@ -217,11 +267,11 @@ Use the Ed25519 signing algorithm
|
|
|
217
267
|
|
|
218
268
|
- `ed25519.sign(payload: blobref): blobref` = (experimental) sign payload using the miner's private key
|
|
219
269
|
|
|
220
|
-
|
|
270
|
+
#### symbols (experimental)
|
|
221
271
|
|
|
222
272
|
- `symbols.create(): symbolref` = create a unique reference that can be passed around
|
|
223
273
|
|
|
224
|
-
|
|
274
|
+
#### refs (experimental)
|
|
225
275
|
|
|
226
276
|
- `refs.numerize(ref: symbolref/blobref/packref): i32` = translate any reference into a unique private pointer that can be stored into data structures
|
|
227
277
|
|
|
@@ -245,4 +295,4 @@ export function verify(session: symbolref) {
|
|
|
245
295
|
}
|
|
246
296
|
```
|
|
247
297
|
|
|
248
|
-
You should never accept a pointer instead of a real reference because they can be easily guessed by an attacking module
|
|
298
|
+
You should never accept a pointer instead of a real reference because they can be easily guessed by an attacking module
|
package/out/mod.d.ts
CHANGED
package/out/mod.js
CHANGED
|
@@ -1 +1,40 @@
|
|
|
1
|
+
#!/usr/bin/env deno
|
|
1
2
|
export * from "./mods/mod.js";
|
|
3
|
+
import process from "node:process";
|
|
4
|
+
import * as server from "./mods/server/bin.js";
|
|
5
|
+
export async function main(args) {
|
|
6
|
+
const subargs = new Array();
|
|
7
|
+
for (let i = 0; i < args.length; i++) {
|
|
8
|
+
const arg = args[i];
|
|
9
|
+
if (arg.startsWith("--")) {
|
|
10
|
+
subargs.push(arg);
|
|
11
|
+
continue;
|
|
12
|
+
}
|
|
13
|
+
if (arg === "serve") {
|
|
14
|
+
subargs.push(...args.slice(i + 1));
|
|
15
|
+
await server.main(subargs);
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
if (arg === "create") {
|
|
19
|
+
console.log("Create command is not implemented yet.");
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
if (arg === "execute") {
|
|
23
|
+
console.log("Execute command is not implemented yet.");
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
if (arg === "simulate") {
|
|
27
|
+
console.log("Simulate command is not implemented yet.");
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
break;
|
|
31
|
+
}
|
|
32
|
+
console.log("- serve [--env=<env file as path>] [--port=<port>] [--dev]");
|
|
33
|
+
console.log("- create <wasm file as path> [salt as hex]");
|
|
34
|
+
console.log("- execute <module as hex> <function name> [args as pack as hex]");
|
|
35
|
+
console.log("- simulate <module as hex> <function name> [args as pack as hex]");
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
if (import.meta.main) {
|
|
39
|
+
await main(process.argv.slice(2));
|
|
40
|
+
}
|
package/out/mods/server/bin.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export
|
|
1
|
+
export declare function main(args: string[]): Promise<void>;
|
package/out/mods/server/bin.js
CHANGED
|
@@ -1,34 +1,69 @@
|
|
|
1
1
|
import { readFileSync } from "node:fs";
|
|
2
2
|
import process from "node:process";
|
|
3
3
|
import { serveWithEnv } from "./mod.js";
|
|
4
|
-
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
4
|
+
export async function main(args) {
|
|
5
|
+
const config = {};
|
|
6
|
+
for (let i = 0; i < args.length; i++) {
|
|
7
|
+
const arg = args[i];
|
|
8
|
+
if (arg.startsWith("--env=")) {
|
|
9
|
+
process.loadEnvFile(arg.slice("--env=".length));
|
|
10
|
+
continue;
|
|
11
|
+
}
|
|
12
|
+
if (arg.startsWith("--port=")) {
|
|
13
|
+
config.port = Number(arg.slice("--port=".length));
|
|
14
|
+
continue;
|
|
15
|
+
}
|
|
16
|
+
if (arg.startsWith("--cert=")) {
|
|
17
|
+
config.cert = readFileSync(arg.slice("--cert=".length), "utf8");
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
if (arg.startsWith("--key=")) {
|
|
21
|
+
config.key = readFileSync(arg.slice("--key=".length), "utf8");
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
if (arg === "--dev=true") {
|
|
25
|
+
process.env.NODE_ENV = "development";
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
if (arg === "--dev=false") {
|
|
29
|
+
process.env.NODE_ENV = "production";
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
if (arg === "--dev") {
|
|
33
|
+
process.env.NODE_ENV = "development";
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
throw new Error(`Unknown argument: ${arg}`);
|
|
16
37
|
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
if (
|
|
38
|
+
const { port = Number(process.env.PORT) || 8080, cert = process.env.CERT != null ? readFileSync(process.env.CERT, "utf8") : undefined, key = process.env.KEY != null ? readFileSync(process.env.KEY, "utf8") : undefined, } = config;
|
|
39
|
+
const server = await serveWithEnv();
|
|
40
|
+
const route = async (request) => {
|
|
41
|
+
if (request.method === "OPTIONS")
|
|
42
|
+
return new Response(null, { status: 204 });
|
|
43
|
+
if (request.headers.get("Upgrade") === "websocket") {
|
|
44
|
+
const { socket, response } = Deno.upgradeWebSocket(request);
|
|
45
|
+
await server.onWebSocketRequest(request, socket);
|
|
23
46
|
return response;
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
47
|
+
}
|
|
48
|
+
return await server.onHttpRequest(request);
|
|
49
|
+
};
|
|
50
|
+
const onHttpRequest = async (request) => {
|
|
51
|
+
try {
|
|
52
|
+
const response = await route(request);
|
|
53
|
+
if (response.status === 101)
|
|
54
|
+
return response;
|
|
55
|
+
response.headers.set("Access-Control-Allow-Origin", "*");
|
|
56
|
+
response.headers.set("Access-Control-Allow-Methods", "*");
|
|
57
|
+
response.headers.set("Access-Control-Allow-Headers", "*");
|
|
58
|
+
return response;
|
|
59
|
+
}
|
|
60
|
+
catch (cause) {
|
|
61
|
+
console.error(cause);
|
|
62
|
+
return new Response("Error", { status: 500 });
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
Deno.serve({ hostname: "0.0.0.0", port, cert, key }, onHttpRequest);
|
|
66
|
+
}
|
|
67
|
+
if (import.meta.main) {
|
|
68
|
+
await main(process.argv.slice(2));
|
|
69
|
+
}
|
package/out/mods/server/mod.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Config } from "../config/mod.ts";
|
|
1
|
+
import type { Config } from "../config/mod.ts";
|
|
2
2
|
export declare function serveWithEnv(prefix?: string): Promise<{
|
|
3
3
|
onHttpRequest(request: Request): Promise<Response>;
|
|
4
4
|
onWebSocketRequest(request: Request, socket: WebSocket): Promise<void>;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@hazae41/bobine",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.8",
|
|
5
5
|
"description": "A blockchain in your garage",
|
|
6
6
|
"repository": "github:hazae41/bobine",
|
|
7
7
|
"author": "hazae41",
|
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
"version": "deno -RW ./x.vsync.ts && git add deno.json",
|
|
12
12
|
"prepare": "deno -RW ./x.dsync.ts && deno install",
|
|
13
13
|
"prepack": "rm -rf ./out && tsc && tscousin",
|
|
14
|
-
"
|
|
14
|
+
"produce": "deno run -A ./src/bin.ts serve --env=./.env.local",
|
|
15
|
+
"develop": "deno run -A ./src/bin.ts serve --env=./.env.local --dev"
|
|
15
16
|
},
|
|
16
17
|
"files": [
|
|
17
18
|
"./out"
|
|
@@ -20,18 +21,6 @@
|
|
|
20
21
|
".": {
|
|
21
22
|
"types": "./out/mod.d.ts",
|
|
22
23
|
"import": "./out/mod.js"
|
|
23
|
-
},
|
|
24
|
-
"./server": {
|
|
25
|
-
"types": "./out/mods/server/bin.d.ts",
|
|
26
|
-
"import": "./out/mods/server/bin.js"
|
|
27
|
-
},
|
|
28
|
-
"./worker": {
|
|
29
|
-
"types": "./out/mods/worker/bin.d.ts",
|
|
30
|
-
"import": "./out/mods/worker/bin.js"
|
|
31
|
-
},
|
|
32
|
-
"./helper": {
|
|
33
|
-
"types": "./out/mods/helper/bin.d.ts",
|
|
34
|
-
"import": "./out/mods/helper/bin.js"
|
|
35
24
|
}
|
|
36
25
|
},
|
|
37
26
|
"dependencies": {
|
|
@@ -45,7 +34,7 @@
|
|
|
45
34
|
"devDependencies": {
|
|
46
35
|
"@hazae41/phobos": "^2.0.16",
|
|
47
36
|
"@hazae41/tscousin": "^1.0.28",
|
|
48
|
-
"@types/node": "^
|
|
37
|
+
"@types/node": "^25.0.2",
|
|
49
38
|
"typescript": "^5.9.3"
|
|
50
39
|
},
|
|
51
40
|
"keywords": [
|
|
@@ -57,6 +46,6 @@
|
|
|
57
46
|
"unit-tested"
|
|
58
47
|
],
|
|
59
48
|
"bin": {
|
|
60
|
-
"bobine": "./out/
|
|
49
|
+
"bobine": "./out/mod.js"
|
|
61
50
|
}
|
|
62
51
|
}
|