@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 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
- Run the server with Deno
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
- deno run --env-file=./.env.local -A npm:@hazae41/bobine
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
- ### <module>
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
- You can use any module method by using the module address as hex
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: i32, y: i32): i32
126
+ declare function add(x: externref, y: externref): externref
81
127
  ```
82
128
 
83
- ### blobs
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
- ### bigints
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
- ### packs
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
- ### env
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
- ### modules
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
- ### storage
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
- ### sha256
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
- ### ed25519
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
- ### symbols (experimental)
270
+ #### symbols (experimental)
221
271
 
222
272
  - `symbols.create(): symbolref` = create a unique reference that can be passed around
223
273
 
224
- ### refs (experimental)
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
@@ -1 +1,3 @@
1
+ #!/usr/bin/env deno
1
2
  export * from "./mods/mod.ts";
3
+ export declare function main(args: string[]): Promise<void>;
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
+ }
@@ -1 +1 @@
1
- export {};
1
+ export declare function main(args: string[]): Promise<void>;
@@ -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
- const { PORT = process.env.PORT || "8080", CERT = process.env.CERT, KEY = process.env.KEY, } = process.env;
5
- const port = Number(PORT);
6
- const cert = CERT != null ? readFileSync(CERT, "utf8") : undefined;
7
- const key = KEY != null ? readFileSync(KEY, "utf8") : undefined;
8
- const server = await serveWithEnv();
9
- const route = async (request) => {
10
- if (request.method === "OPTIONS")
11
- return new Response(null, { status: 204 });
12
- if (request.headers.get("Upgrade") === "websocket") {
13
- const { socket, response } = Deno.upgradeWebSocket(request);
14
- await server.onWebSocketRequest(request, socket);
15
- return response;
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
- return await server.onHttpRequest(request);
18
- };
19
- const onHttpRequest = async (request) => {
20
- try {
21
- const response = await route(request);
22
- if (response.status === 101)
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
- response.headers.set("Access-Control-Allow-Origin", "*");
25
- response.headers.set("Access-Control-Allow-Methods", "*");
26
- response.headers.set("Access-Control-Allow-Headers", "*");
27
- return response;
28
- }
29
- catch (cause) {
30
- console.error(cause);
31
- return new Response("Error", { status: 500 });
32
- }
33
- };
34
- Deno.serve({ hostname: "0.0.0.0", port, cert, key }, onHttpRequest);
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
+ }
@@ -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.6",
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
- "develop": "NODE_ENV=development deno --env-file=./.env.local -A ./src/mods/server/bin.ts"
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": "^24.10.1",
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/mods/server/bin.js"
49
+ "bobine": "./out/mod.js"
61
50
  }
62
51
  }