@riseandshaheen/libcma 0.1.0-alpha.0
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/ARCHITECTURE.md +348 -0
- package/LICENSE +21 -0
- package/README.md +157 -0
- package/binding.gyp +52 -0
- package/deps/machine-asset-tools/LICENSE +202 -0
- package/deps/machine-asset-tools/README.md +237 -0
- package/deps/machine-asset-tools/include/libcma/ledger.h +161 -0
- package/deps/machine-asset-tools/include/libcma/parser.h +305 -0
- package/deps/machine-asset-tools/include/libcma/types.h +22 -0
- package/deps/machine-guest-tools/LICENSE +202 -0
- package/deps/machine-guest-tools/README.md +57 -0
- package/deps/machine-guest-tools/sys-utils/libcmt/README.md +130 -0
- package/deps/machine-guest-tools/sys-utils/libcmt/include/libcmt/abi.h +578 -0
- package/deps/machine-guest-tools/sys-utils/libcmt/include/libcmt/buf.h +82 -0
- package/deps/machine-guest-tools/sys-utils/libcmt/include/libcmt/io.h +168 -0
- package/deps/machine-guest-tools/sys-utils/libcmt/include/libcmt/keccak.h +131 -0
- package/deps/machine-guest-tools/sys-utils/libcmt/include/libcmt/merkle.h +118 -0
- package/deps/machine-guest-tools/sys-utils/libcmt/include/libcmt/rollup.h +260 -0
- package/deps/machine-guest-tools/sys-utils/libcmt/include/libcmt/util.h +34 -0
- package/lib/index.cjs +445 -0
- package/lib/index.cjs.map +1 -0
- package/lib/index.d.cts +156 -0
- package/lib/index.d.ts +156 -0
- package/lib/index.js +428 -0
- package/lib/index.js.map +1 -0
- package/native/addon.cc +268 -0
- package/native/ledger_backend.h +28 -0
- package/native/mock/ledger_mock.cc +185 -0
- package/native/real/ledger_real.cc +271 -0
- package/package.json +74 -0
- package/scripts/build-libcma-riscv64.sh +80 -0
- package/scripts/build-native-riscv64.sh +40 -0
- package/scripts/install-native.mjs +94 -0
package/lib/index.cjs
ADDED
|
@@ -0,0 +1,445 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var module$1 = require('module');
|
|
4
|
+
var path = require('path');
|
|
5
|
+
var url = require('url');
|
|
6
|
+
|
|
7
|
+
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
8
|
+
// src/types.ts
|
|
9
|
+
var ADDRESS_LENGTH = 20;
|
|
10
|
+
var U256_LENGTH = 32;
|
|
11
|
+
var ACCOUNTS_DRIVE_PATH = "/dev/pmem1";
|
|
12
|
+
var ACCOUNTS_DRIVE_SIZE_4MIB = 4194304;
|
|
13
|
+
var LOG2_MAX_NUM_OF_ACCOUNTS_DEFAULT = 17;
|
|
14
|
+
var LEDGER_MIN_MEM_LENGTH = 262144;
|
|
15
|
+
var DEFAULT_ETHER_CONFIG = {
|
|
16
|
+
memoryLength: ACCOUNTS_DRIVE_SIZE_4MIB,
|
|
17
|
+
maxAccounts: 2 ** LOG2_MAX_NUM_OF_ACCOUNTS_DEFAULT
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
// src/errors.ts
|
|
21
|
+
var LedgerErrorCode = {
|
|
22
|
+
SUCCESS: 0,
|
|
23
|
+
UNKNOWN: -1001,
|
|
24
|
+
EXCEPTION: -1002,
|
|
25
|
+
INSUFFICIENT_FUNDS: -1003,
|
|
26
|
+
ACCOUNT_NOT_FOUND: -1004,
|
|
27
|
+
ASSET_NOT_FOUND: -1005,
|
|
28
|
+
BALANCE_NOT_FOUND: -1006,
|
|
29
|
+
SUPPLY_OVERFLOW: -1007,
|
|
30
|
+
BALANCE_OVERFLOW: -1008,
|
|
31
|
+
INVALID_ACCOUNT: -1009,
|
|
32
|
+
INSERTION_ERROR: -1010,
|
|
33
|
+
MAX_ASSETS_REACHED: -1011,
|
|
34
|
+
MAX_ACCOUNTS_REACHED: -1012,
|
|
35
|
+
MAX_BALANCES_REACHED: -1013,
|
|
36
|
+
ASSET_SUPPLY: -1014,
|
|
37
|
+
ACCOUNT_BALANCE: -1015,
|
|
38
|
+
REMOVE: -1016
|
|
39
|
+
};
|
|
40
|
+
var CODE_NAMES = Object.fromEntries(
|
|
41
|
+
Object.entries(LedgerErrorCode).map(([k, v]) => [v, k])
|
|
42
|
+
);
|
|
43
|
+
var LedgerError = class _LedgerError extends Error {
|
|
44
|
+
name = "LedgerError";
|
|
45
|
+
code;
|
|
46
|
+
constructor(code, message) {
|
|
47
|
+
const label = CODE_NAMES[code] ?? "UNKNOWN";
|
|
48
|
+
super(message ?? `libcma ledger error ${label} (${code})`);
|
|
49
|
+
this.code = code;
|
|
50
|
+
}
|
|
51
|
+
static fromCode(code, detail) {
|
|
52
|
+
return new _LedgerError(code, detail);
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
// src/bytes.ts
|
|
57
|
+
var HEX_RE = /^0x[0-9a-fA-F]*$/;
|
|
58
|
+
function isHex(value) {
|
|
59
|
+
return HEX_RE.test(value) && value.length % 2 === 0;
|
|
60
|
+
}
|
|
61
|
+
function toBytes(value, name = "value") {
|
|
62
|
+
if (value instanceof Uint8Array) {
|
|
63
|
+
return value;
|
|
64
|
+
}
|
|
65
|
+
if (typeof value !== "string" || !isHex(value)) {
|
|
66
|
+
throw new TypeError(`${name} must be a 0x-hex string or Uint8Array`);
|
|
67
|
+
}
|
|
68
|
+
const hex = value.slice(2);
|
|
69
|
+
if (hex.length % 2 !== 0) {
|
|
70
|
+
throw new TypeError(`${name} hex length must be even`);
|
|
71
|
+
}
|
|
72
|
+
const out = new Uint8Array(hex.length / 2);
|
|
73
|
+
for (let i = 0; i < out.length; i++) {
|
|
74
|
+
out[i] = Number.parseInt(hex.slice(i * 2, i * 2 + 2), 16);
|
|
75
|
+
}
|
|
76
|
+
return out;
|
|
77
|
+
}
|
|
78
|
+
function toHex(bytes) {
|
|
79
|
+
let s = "0x";
|
|
80
|
+
for (const b of bytes) {
|
|
81
|
+
s += b.toString(16).padStart(2, "0");
|
|
82
|
+
}
|
|
83
|
+
return s;
|
|
84
|
+
}
|
|
85
|
+
function normalizeAddress(address) {
|
|
86
|
+
const bytes = toBytes(address, "address");
|
|
87
|
+
if (bytes.length !== ADDRESS_LENGTH) {
|
|
88
|
+
throw new TypeError(
|
|
89
|
+
`address must be ${ADDRESS_LENGTH} bytes, got ${bytes.length}`
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
return toHex(bytes).toLowerCase();
|
|
93
|
+
}
|
|
94
|
+
function assertAmount(amount, name = "amount") {
|
|
95
|
+
if (typeof amount !== "bigint") {
|
|
96
|
+
throw new TypeError(`${name} must be a bigint`);
|
|
97
|
+
}
|
|
98
|
+
if (amount < 0n) {
|
|
99
|
+
throw new RangeError(`${name} must be non-negative`);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
function parseEtherPortalDeposit(payload) {
|
|
103
|
+
const bytes = toBytes(payload, "payload");
|
|
104
|
+
if (bytes.length < ADDRESS_LENGTH + 32) {
|
|
105
|
+
throw LedgerError.fromCode(
|
|
106
|
+
LedgerErrorCode.UNKNOWN,
|
|
107
|
+
`ether deposit payload too short: ${bytes.length} bytes`
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
const sender = normalizeAddress(bytes.subarray(0, ADDRESS_LENGTH));
|
|
111
|
+
let value = 0n;
|
|
112
|
+
for (let i = 0; i < 32; i++) {
|
|
113
|
+
value = value << 8n | BigInt(bytes[ADDRESS_LENGTH + i]);
|
|
114
|
+
}
|
|
115
|
+
const rest = bytes.subarray(ADDRESS_LENGTH + 32);
|
|
116
|
+
if (rest.length === 0) {
|
|
117
|
+
return { sender, value };
|
|
118
|
+
}
|
|
119
|
+
return { sender, value, execLayerData: toHex(rest) };
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// src/memory-backend.ts
|
|
123
|
+
var MemoryBackend = class _MemoryBackend {
|
|
124
|
+
kind = "memory";
|
|
125
|
+
#balances = /* @__PURE__ */ new Map();
|
|
126
|
+
#closed = false;
|
|
127
|
+
maxAccounts;
|
|
128
|
+
constructor(options) {
|
|
129
|
+
this.maxAccounts = options.maxAccounts;
|
|
130
|
+
}
|
|
131
|
+
static openEther(maxAccounts) {
|
|
132
|
+
return new _MemoryBackend({ maxAccounts });
|
|
133
|
+
}
|
|
134
|
+
#ensureOpen() {
|
|
135
|
+
if (this.#closed) {
|
|
136
|
+
throw LedgerError.fromCode(
|
|
137
|
+
LedgerErrorCode.UNKNOWN,
|
|
138
|
+
"ledger is closed"
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
#get(key) {
|
|
143
|
+
return this.#balances.get(key) ?? 0n;
|
|
144
|
+
}
|
|
145
|
+
#set(key, value) {
|
|
146
|
+
if (value === 0n) {
|
|
147
|
+
this.#balances.delete(key);
|
|
148
|
+
} else {
|
|
149
|
+
this.#balances.set(key, value);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
#ensureCapacityForNew(key) {
|
|
153
|
+
if (!this.#balances.has(key) && this.#balances.size >= this.maxAccounts) {
|
|
154
|
+
throw LedgerError.fromCode(LedgerErrorCode.MAX_ACCOUNTS_REACHED);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
depositEther(account, amount) {
|
|
158
|
+
this.#ensureOpen();
|
|
159
|
+
assertAmount(amount);
|
|
160
|
+
if (amount === 0n) {
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
const key = normalizeAddress(account);
|
|
164
|
+
this.#ensureCapacityForNew(key);
|
|
165
|
+
this.#set(key, this.#get(key) + amount);
|
|
166
|
+
}
|
|
167
|
+
transferEther(from, to, amount) {
|
|
168
|
+
this.#ensureOpen();
|
|
169
|
+
assertAmount(amount);
|
|
170
|
+
if (amount === 0n) {
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
const fromKey = normalizeAddress(from);
|
|
174
|
+
const toKey = normalizeAddress(to);
|
|
175
|
+
const balance = this.#get(fromKey);
|
|
176
|
+
if (balance < amount) {
|
|
177
|
+
throw LedgerError.fromCode(
|
|
178
|
+
LedgerErrorCode.INSUFFICIENT_FUNDS,
|
|
179
|
+
`insufficient balance of ${fromKey}`
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
if (fromKey !== toKey) {
|
|
183
|
+
this.#ensureCapacityForNew(toKey);
|
|
184
|
+
}
|
|
185
|
+
this.#set(fromKey, balance - amount);
|
|
186
|
+
this.#set(toKey, this.#get(toKey) + amount);
|
|
187
|
+
}
|
|
188
|
+
withdrawEther(account, amount) {
|
|
189
|
+
this.#ensureOpen();
|
|
190
|
+
assertAmount(amount);
|
|
191
|
+
if (amount === 0n) {
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
const key = normalizeAddress(account);
|
|
195
|
+
const balance = this.#get(key);
|
|
196
|
+
if (balance < amount) {
|
|
197
|
+
throw LedgerError.fromCode(
|
|
198
|
+
LedgerErrorCode.INSUFFICIENT_FUNDS,
|
|
199
|
+
`insufficient balance of ${key}: ${amount} > ${balance}`
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
this.#set(key, balance - amount);
|
|
203
|
+
}
|
|
204
|
+
getEtherBalance(account) {
|
|
205
|
+
this.#ensureOpen();
|
|
206
|
+
return this.#get(normalizeAddress(account));
|
|
207
|
+
}
|
|
208
|
+
close() {
|
|
209
|
+
this.#closed = true;
|
|
210
|
+
this.#balances.clear();
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
var cached;
|
|
214
|
+
function tryLoadNative() {
|
|
215
|
+
if (cached !== void 0) {
|
|
216
|
+
return cached;
|
|
217
|
+
}
|
|
218
|
+
try {
|
|
219
|
+
const require2 = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)));
|
|
220
|
+
const root = path.join(path.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)))), "..");
|
|
221
|
+
const binding = require2("node-gyp-build")(root);
|
|
222
|
+
cached = binding;
|
|
223
|
+
return binding;
|
|
224
|
+
} catch {
|
|
225
|
+
cached = null;
|
|
226
|
+
return null;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
function isNativeAvailable() {
|
|
230
|
+
return tryLoadNative() !== null;
|
|
231
|
+
}
|
|
232
|
+
var NativeBackend = class _NativeBackend {
|
|
233
|
+
kind;
|
|
234
|
+
#handle;
|
|
235
|
+
#closed = false;
|
|
236
|
+
constructor(handle) {
|
|
237
|
+
this.#handle = handle;
|
|
238
|
+
this.kind = handle.kind === "native-libcma" ? "native-libcma" : "native-mock";
|
|
239
|
+
}
|
|
240
|
+
static openEtherBuffer(maxAccounts) {
|
|
241
|
+
const native = tryLoadNative();
|
|
242
|
+
if (!native) {
|
|
243
|
+
return null;
|
|
244
|
+
}
|
|
245
|
+
return new _NativeBackend(native.openEtherBuffer(maxAccounts));
|
|
246
|
+
}
|
|
247
|
+
static openEtherFile(path, offset, memoryLength, maxAccounts) {
|
|
248
|
+
const native = tryLoadNative();
|
|
249
|
+
if (!native) {
|
|
250
|
+
return null;
|
|
251
|
+
}
|
|
252
|
+
return new _NativeBackend(
|
|
253
|
+
native.openEtherFile(path, offset, memoryLength, maxAccounts)
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
#ensureOpen() {
|
|
257
|
+
if (this.#closed) {
|
|
258
|
+
throw LedgerError.fromCode(LedgerErrorCode.UNKNOWN, "ledger is closed");
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
#addr(account) {
|
|
262
|
+
return toBytes(normalizeAddress(account));
|
|
263
|
+
}
|
|
264
|
+
depositEther(account, amount) {
|
|
265
|
+
this.#ensureOpen();
|
|
266
|
+
assertAmount(amount);
|
|
267
|
+
this.#handle.depositEther(this.#addr(account), amount);
|
|
268
|
+
}
|
|
269
|
+
transferEther(from, to, amount) {
|
|
270
|
+
this.#ensureOpen();
|
|
271
|
+
assertAmount(amount);
|
|
272
|
+
this.#handle.transferEther(this.#addr(from), this.#addr(to), amount);
|
|
273
|
+
}
|
|
274
|
+
withdrawEther(account, amount) {
|
|
275
|
+
this.#ensureOpen();
|
|
276
|
+
assertAmount(amount);
|
|
277
|
+
this.#handle.withdrawEther(this.#addr(account), amount);
|
|
278
|
+
}
|
|
279
|
+
getEtherBalance(account) {
|
|
280
|
+
this.#ensureOpen();
|
|
281
|
+
return this.#handle.getEtherBalance(this.#addr(account));
|
|
282
|
+
}
|
|
283
|
+
close() {
|
|
284
|
+
if (!this.#closed) {
|
|
285
|
+
this.#handle.close();
|
|
286
|
+
this.#closed = true;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
};
|
|
290
|
+
|
|
291
|
+
// src/ledger.ts
|
|
292
|
+
var Ledger = class _Ledger {
|
|
293
|
+
#backend;
|
|
294
|
+
constructor(backend) {
|
|
295
|
+
this.#backend = backend;
|
|
296
|
+
}
|
|
297
|
+
/** Which implementation is serving this instance. */
|
|
298
|
+
get backendKind() {
|
|
299
|
+
return this.#backend.kind;
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Open a single-asset Ether ledger over an in-memory buffer (host tests).
|
|
303
|
+
*/
|
|
304
|
+
static openEtherBuffer(config = DEFAULT_ETHER_CONFIG, options = {}) {
|
|
305
|
+
const maxAccounts = config.maxAccounts;
|
|
306
|
+
if (maxAccounts <= 0) {
|
|
307
|
+
throw new RangeError("maxAccounts must be positive");
|
|
308
|
+
}
|
|
309
|
+
return _Ledger.#openEther(
|
|
310
|
+
maxAccounts,
|
|
311
|
+
options,
|
|
312
|
+
() => NativeBackend.openEtherBuffer(maxAccounts)
|
|
313
|
+
);
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Open a multi-asset buffer ledger; Phase 1 only exposes Ether helpers on top.
|
|
317
|
+
*/
|
|
318
|
+
static openBuffer(config, options = {}) {
|
|
319
|
+
return _Ledger.openEtherBuffer(
|
|
320
|
+
{
|
|
321
|
+
memoryLength: config.memoryLength,
|
|
322
|
+
maxAccounts: config.maxAccounts
|
|
323
|
+
},
|
|
324
|
+
options
|
|
325
|
+
);
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Open a single-asset Ether ledger on a file or block device.
|
|
329
|
+
* Inside the machine use {@link ACCOUNTS_DRIVE_PATH} (`/dev/pmem1`).
|
|
330
|
+
*/
|
|
331
|
+
static openEtherFile(path, config = DEFAULT_ETHER_CONFIG, options = {}) {
|
|
332
|
+
const maxAccounts = config.maxAccounts;
|
|
333
|
+
const offset = config.offset ?? 0;
|
|
334
|
+
const memoryLength = config.memoryLength ?? ACCOUNTS_DRIVE_SIZE_4MIB;
|
|
335
|
+
if (maxAccounts <= 0) {
|
|
336
|
+
throw new RangeError("maxAccounts must be positive");
|
|
337
|
+
}
|
|
338
|
+
const prefer = options.backend ?? "auto";
|
|
339
|
+
if (prefer === "memory") {
|
|
340
|
+
return new _Ledger(MemoryBackend.openEther(maxAccounts));
|
|
341
|
+
}
|
|
342
|
+
const native = NativeBackend.openEtherFile(
|
|
343
|
+
path,
|
|
344
|
+
offset,
|
|
345
|
+
memoryLength,
|
|
346
|
+
maxAccounts
|
|
347
|
+
);
|
|
348
|
+
if (native) {
|
|
349
|
+
return new _Ledger(native);
|
|
350
|
+
}
|
|
351
|
+
if (prefer === "native") {
|
|
352
|
+
throw LedgerError.fromCode(
|
|
353
|
+
LedgerErrorCode.UNKNOWN,
|
|
354
|
+
"native libcma addon is not available; run npm run build:native"
|
|
355
|
+
);
|
|
356
|
+
}
|
|
357
|
+
return new _Ledger(MemoryBackend.openEther(maxAccounts));
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* File-backed multi-asset entry; Phase 1 routes to Ether single-asset helpers.
|
|
361
|
+
*/
|
|
362
|
+
static openFile(path, config, options = {}) {
|
|
363
|
+
return _Ledger.openEtherFile(
|
|
364
|
+
path,
|
|
365
|
+
{
|
|
366
|
+
maxAccounts: config.maxAccounts,
|
|
367
|
+
offset: config.offset,
|
|
368
|
+
memoryLength: config.memoryLength
|
|
369
|
+
},
|
|
370
|
+
options
|
|
371
|
+
);
|
|
372
|
+
}
|
|
373
|
+
static #openEther(maxAccounts, options, openNative) {
|
|
374
|
+
const prefer = options.backend ?? "auto";
|
|
375
|
+
if (prefer === "memory") {
|
|
376
|
+
return new _Ledger(MemoryBackend.openEther(maxAccounts));
|
|
377
|
+
}
|
|
378
|
+
const native = openNative();
|
|
379
|
+
if (native) {
|
|
380
|
+
return new _Ledger(native);
|
|
381
|
+
}
|
|
382
|
+
if (prefer === "native") {
|
|
383
|
+
throw LedgerError.fromCode(
|
|
384
|
+
LedgerErrorCode.UNKNOWN,
|
|
385
|
+
"native libcma addon is not available; run npm run build:native"
|
|
386
|
+
);
|
|
387
|
+
}
|
|
388
|
+
return new _Ledger(MemoryBackend.openEther(maxAccounts));
|
|
389
|
+
}
|
|
390
|
+
depositEther(account, amount) {
|
|
391
|
+
this.#backend.depositEther(normalizeAddress(account), amount);
|
|
392
|
+
}
|
|
393
|
+
/**
|
|
394
|
+
* Credit from a packed EtherPortal advance payload.
|
|
395
|
+
* @returns decoded sender and value (exec layer data is ignored here)
|
|
396
|
+
*/
|
|
397
|
+
creditEtherDeposit(payload) {
|
|
398
|
+
const { sender, value } = parseEtherPortalDeposit(payload);
|
|
399
|
+
this.depositEther(sender, value);
|
|
400
|
+
return { sender, value };
|
|
401
|
+
}
|
|
402
|
+
transferEther(from, to, amount) {
|
|
403
|
+
this.#backend.transferEther(
|
|
404
|
+
normalizeAddress(from),
|
|
405
|
+
normalizeAddress(to),
|
|
406
|
+
amount
|
|
407
|
+
);
|
|
408
|
+
}
|
|
409
|
+
/**
|
|
410
|
+
* Debit Ether. Does **not** emit a rollup voucher — the dApp must call
|
|
411
|
+
* `POST /voucher` or `@deroll/cmio.emitVoucher` separately.
|
|
412
|
+
*/
|
|
413
|
+
withdrawEther(account, amount) {
|
|
414
|
+
assertAmount(amount);
|
|
415
|
+
this.#backend.withdrawEther(normalizeAddress(account), amount);
|
|
416
|
+
}
|
|
417
|
+
getEtherBalance(account) {
|
|
418
|
+
return this.#backend.getEtherBalance(normalizeAddress(account));
|
|
419
|
+
}
|
|
420
|
+
/** Alias matching Deroll naming. */
|
|
421
|
+
getBalance(account) {
|
|
422
|
+
return this.getEtherBalance(account);
|
|
423
|
+
}
|
|
424
|
+
close() {
|
|
425
|
+
this.#backend.close();
|
|
426
|
+
}
|
|
427
|
+
};
|
|
428
|
+
|
|
429
|
+
exports.ACCOUNTS_DRIVE_PATH = ACCOUNTS_DRIVE_PATH;
|
|
430
|
+
exports.ACCOUNTS_DRIVE_SIZE_4MIB = ACCOUNTS_DRIVE_SIZE_4MIB;
|
|
431
|
+
exports.ADDRESS_LENGTH = ADDRESS_LENGTH;
|
|
432
|
+
exports.DEFAULT_ETHER_CONFIG = DEFAULT_ETHER_CONFIG;
|
|
433
|
+
exports.LEDGER_MIN_MEM_LENGTH = LEDGER_MIN_MEM_LENGTH;
|
|
434
|
+
exports.LOG2_MAX_NUM_OF_ACCOUNTS_DEFAULT = LOG2_MAX_NUM_OF_ACCOUNTS_DEFAULT;
|
|
435
|
+
exports.Ledger = Ledger;
|
|
436
|
+
exports.LedgerError = LedgerError;
|
|
437
|
+
exports.LedgerErrorCode = LedgerErrorCode;
|
|
438
|
+
exports.U256_LENGTH = U256_LENGTH;
|
|
439
|
+
exports.isNativeAvailable = isNativeAvailable;
|
|
440
|
+
exports.normalizeAddress = normalizeAddress;
|
|
441
|
+
exports.parseEtherPortalDeposit = parseEtherPortalDeposit;
|
|
442
|
+
exports.toBytes = toBytes;
|
|
443
|
+
exports.toHex = toHex;
|
|
444
|
+
//# sourceMappingURL=index.cjs.map
|
|
445
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/types.ts","../src/errors.ts","../src/bytes.ts","../src/memory-backend.ts","../src/native-backend.ts","../src/ledger.ts"],"names":["require","createRequire","join","dirname","fileURLToPath"],"mappings":"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","file":"index.cjs","sourcesContent":["/** 0x-prefixed hex string. Compatible with viem `Hex` / `Address`. */\nexport type Hex = `0x${string}`;\n\n/** EVM address as checksummed or lowercase 0x hex. */\nexport type Address = Hex;\n\n/** Bytes input accepted at API boundaries. */\nexport type BytesLike = Hex | Uint8Array;\n\nexport const ADDRESS_LENGTH = 20;\nexport const U256_LENGTH = 32;\n\n/** Default accounts-drive path inside the Cartesi Machine. */\nexport const ACCOUNTS_DRIVE_PATH = \"/dev/pmem1\";\n\n/**\n * 4 MiB = 2^17 account slots × 32-byte records (contracts v3 convention when\n * `log2_max_num_of_accounts = 17`).\n */\nexport const ACCOUNTS_DRIVE_SIZE_4MIB = 4_194_304;\n\nexport const LOG2_MAX_NUM_OF_ACCOUNTS_DEFAULT = 17;\n\n/** Minimum mem length required by libcma (`CMA_LEDGER_MIN_MEM_LENGTH`). */\nexport const LEDGER_MIN_MEM_LENGTH = 262_144;\n\nexport type LedgerMemoryMode = \"create-only\" | \"open-only\";\n\n/**\n * File-backed ledger config (machine: `/dev/pmem1`, or a host test file).\n * Sizes must be consistent with `cartesi.toml` `[withdrawal.config]`.\n */\nexport type LedgerFileConfig = {\n mode?: LedgerMemoryMode;\n offset?: number;\n memoryLength: number;\n maxAccounts: number;\n maxAssets: number;\n maxBalances: number;\n};\n\n/** Buffer-backed (non-persistent) ledger config for host tests. */\nexport type LedgerBufferConfig = {\n memoryLength?: number;\n maxAccounts: number;\n maxAssets: number;\n maxBalances: number;\n};\n\n/**\n * Single-asset Ether ledger config — maps to `cma_ledger_init_single_*`.\n * Preferred for Ether-only dApps.\n */\nexport type LedgerEtherConfig = {\n memoryLength?: number;\n /** Account capacity; typically `2 ** log2_max_num_of_accounts`. */\n maxAccounts: number;\n};\n\nexport const DEFAULT_ETHER_CONFIG: Required<LedgerEtherConfig> = {\n memoryLength: ACCOUNTS_DRIVE_SIZE_4MIB,\n maxAccounts: 2 ** LOG2_MAX_NUM_OF_ACCOUNTS_DEFAULT,\n};\n\nexport type BackendKind = \"memory\" | \"native-mock\" | \"native-libcma\";\n","/** libcma-style error codes (see `include/libcma/ledger.h`). */\nexport const LedgerErrorCode = {\n SUCCESS: 0,\n UNKNOWN: -1001,\n EXCEPTION: -1002,\n INSUFFICIENT_FUNDS: -1003,\n ACCOUNT_NOT_FOUND: -1004,\n ASSET_NOT_FOUND: -1005,\n BALANCE_NOT_FOUND: -1006,\n SUPPLY_OVERFLOW: -1007,\n BALANCE_OVERFLOW: -1008,\n INVALID_ACCOUNT: -1009,\n INSERTION_ERROR: -1010,\n MAX_ASSETS_REACHED: -1011,\n MAX_ACCOUNTS_REACHED: -1012,\n MAX_BALANCES_REACHED: -1013,\n ASSET_SUPPLY: -1014,\n ACCOUNT_BALANCE: -1015,\n REMOVE: -1016,\n} as const;\n\nexport type LedgerErrorCodeValue =\n (typeof LedgerErrorCode)[keyof typeof LedgerErrorCode];\n\nconst CODE_NAMES: Record<number, string> = Object.fromEntries(\n Object.entries(LedgerErrorCode).map(([k, v]) => [v, k]),\n);\n\nexport class LedgerError extends Error {\n readonly name = \"LedgerError\";\n readonly code: number;\n\n constructor(code: number, message?: string) {\n const label = CODE_NAMES[code] ?? \"UNKNOWN\";\n super(message ?? `libcma ledger error ${label} (${code})`);\n this.code = code;\n }\n\n static fromCode(code: number, detail?: string): LedgerError {\n return new LedgerError(code, detail);\n }\n}\n","import { ADDRESS_LENGTH, type Address, type BytesLike, type Hex } from \"./types.js\";\nimport { LedgerError, LedgerErrorCode } from \"./errors.js\";\n\nconst HEX_RE = /^0x[0-9a-fA-F]*$/;\n\nexport function isHex(value: string): value is Hex {\n return HEX_RE.test(value) && value.length % 2 === 0;\n}\n\nexport function toBytes(value: BytesLike, name = \"value\"): Uint8Array {\n if (value instanceof Uint8Array) {\n return value;\n }\n if (typeof value !== \"string\" || !isHex(value)) {\n throw new TypeError(`${name} must be a 0x-hex string or Uint8Array`);\n }\n const hex = value.slice(2);\n if (hex.length % 2 !== 0) {\n throw new TypeError(`${name} hex length must be even`);\n }\n const out = new Uint8Array(hex.length / 2);\n for (let i = 0; i < out.length; i++) {\n out[i] = Number.parseInt(hex.slice(i * 2, i * 2 + 2), 16);\n }\n return out;\n}\n\nexport function toHex(bytes: Uint8Array): Hex {\n let s = \"0x\";\n for (const b of bytes) {\n s += b.toString(16).padStart(2, \"0\");\n }\n return s as Hex;\n}\n\n/** Normalize to lowercase 0x-address (20 bytes). */\nexport function normalizeAddress(address: BytesLike): Address {\n const bytes = toBytes(address, \"address\");\n if (bytes.length !== ADDRESS_LENGTH) {\n throw new TypeError(\n `address must be ${ADDRESS_LENGTH} bytes, got ${bytes.length}`,\n );\n }\n return toHex(bytes).toLowerCase() as Address;\n}\n\nexport function assertAmount(amount: bigint, name = \"amount\"): void {\n if (typeof amount !== \"bigint\") {\n throw new TypeError(`${name} must be a bigint`);\n }\n if (amount < 0n) {\n throw new RangeError(`${name} must be non-negative`);\n }\n}\n\n/**\n * Decode packed EtherPortal deposit payload (Rollups v2):\n * `sender (20) || value (32) || execLayerData?`\n */\nexport function parseEtherPortalDeposit(payload: BytesLike): {\n sender: Address;\n value: bigint;\n execLayerData?: Hex;\n} {\n const bytes = toBytes(payload, \"payload\");\n if (bytes.length < ADDRESS_LENGTH + 32) {\n throw LedgerError.fromCode(\n LedgerErrorCode.UNKNOWN,\n `ether deposit payload too short: ${bytes.length} bytes`,\n );\n }\n const sender = normalizeAddress(bytes.subarray(0, ADDRESS_LENGTH));\n let value = 0n;\n for (let i = 0; i < 32; i++) {\n value = (value << 8n) | BigInt(bytes[ADDRESS_LENGTH + i]!);\n }\n const rest = bytes.subarray(ADDRESS_LENGTH + 32);\n if (rest.length === 0) {\n return { sender, value };\n }\n return { sender, value, execLayerData: toHex(rest) };\n}\n","import type { Address } from \"./types.js\";\nimport { LedgerError, LedgerErrorCode } from \"./errors.js\";\nimport { assertAmount, normalizeAddress } from \"./bytes.js\";\n\n/**\n * Internal ledger operations shared by memory and native backends.\n *\n * Host `MemoryBackend` is **behavioral only** — not proof-identical to C++ libcma.\n * Production / emergency-withdrawal must use the native addon linked to real libcma.\n */\nexport interface LedgerBackend {\n readonly kind: \"memory\" | \"native-mock\" | \"native-libcma\";\n depositEther(account: Address, amount: bigint): void;\n transferEther(from: Address, to: Address, amount: bigint): void;\n withdrawEther(account: Address, amount: bigint): void;\n getEtherBalance(account: Address): bigint;\n close(): void;\n}\n\n/**\n * In-process Ether ledger for host unit tests and local development.\n *\n * NOT suitable for emergency-withdrawal proofs.\n */\nexport class MemoryBackend implements LedgerBackend {\n readonly kind = \"memory\" as const;\n #balances = new Map<string, bigint>();\n #closed = false;\n readonly maxAccounts: number;\n\n constructor(options: { maxAccounts: number }) {\n this.maxAccounts = options.maxAccounts;\n }\n\n static openEther(maxAccounts: number): MemoryBackend {\n return new MemoryBackend({ maxAccounts });\n }\n\n #ensureOpen(): void {\n if (this.#closed) {\n throw LedgerError.fromCode(\n LedgerErrorCode.UNKNOWN,\n \"ledger is closed\",\n );\n }\n }\n\n #get(key: string): bigint {\n return this.#balances.get(key) ?? 0n;\n }\n\n #set(key: string, value: bigint): void {\n if (value === 0n) {\n this.#balances.delete(key);\n } else {\n this.#balances.set(key, value);\n }\n }\n\n #ensureCapacityForNew(key: string): void {\n if (!this.#balances.has(key) && this.#balances.size >= this.maxAccounts) {\n throw LedgerError.fromCode(LedgerErrorCode.MAX_ACCOUNTS_REACHED);\n }\n }\n\n depositEther(account: Address, amount: bigint): void {\n this.#ensureOpen();\n assertAmount(amount);\n if (amount === 0n) {\n return;\n }\n const key = normalizeAddress(account);\n this.#ensureCapacityForNew(key);\n this.#set(key, this.#get(key) + amount);\n }\n\n transferEther(from: Address, to: Address, amount: bigint): void {\n this.#ensureOpen();\n assertAmount(amount);\n if (amount === 0n) {\n return;\n }\n const fromKey = normalizeAddress(from);\n const toKey = normalizeAddress(to);\n const balance = this.#get(fromKey);\n if (balance < amount) {\n throw LedgerError.fromCode(\n LedgerErrorCode.INSUFFICIENT_FUNDS,\n `insufficient balance of ${fromKey}`,\n );\n }\n if (fromKey !== toKey) {\n this.#ensureCapacityForNew(toKey);\n }\n this.#set(fromKey, balance - amount);\n this.#set(toKey, this.#get(toKey) + amount);\n }\n\n withdrawEther(account: Address, amount: bigint): void {\n this.#ensureOpen();\n assertAmount(amount);\n if (amount === 0n) {\n return;\n }\n const key = normalizeAddress(account);\n const balance = this.#get(key);\n if (balance < amount) {\n throw LedgerError.fromCode(\n LedgerErrorCode.INSUFFICIENT_FUNDS,\n `insufficient balance of ${key}: ${amount} > ${balance}`,\n );\n }\n this.#set(key, balance - amount);\n }\n\n getEtherBalance(account: Address): bigint {\n this.#ensureOpen();\n return this.#get(normalizeAddress(account));\n }\n\n close(): void {\n this.#closed = true;\n this.#balances.clear();\n }\n}\n","import { createRequire } from \"node:module\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nimport type { Address } from \"./types.js\";\nimport type { LedgerBackend } from \"./memory-backend.js\";\nimport { LedgerError, LedgerErrorCode } from \"./errors.js\";\nimport { assertAmount, normalizeAddress, toBytes } from \"./bytes.js\";\n\ntype NativeLedgerHandle = {\n depositEther(account: Uint8Array, amount: bigint): void;\n transferEther(from: Uint8Array, to: Uint8Array, amount: bigint): void;\n withdrawEther(account: Uint8Array, amount: bigint): void;\n getEtherBalance(account: Uint8Array): bigint;\n close(): void;\n readonly kind: string;\n};\n\ntype NativeBinding = {\n openEtherBuffer(maxAccounts: number): NativeLedgerHandle;\n openEtherFile(\n path: string,\n offset: number,\n memoryLength: number,\n maxAccounts: number,\n ): NativeLedgerHandle;\n};\n\nlet cached: NativeBinding | null | undefined;\n\nfunction tryLoadNative(): NativeBinding | null {\n if (cached !== undefined) {\n return cached;\n }\n try {\n const require = createRequire(import.meta.url);\n const root = join(dirname(fileURLToPath(import.meta.url)), \"..\");\n const binding = require(\"node-gyp-build\")(root) as NativeBinding;\n cached = binding;\n return binding;\n } catch {\n cached = null;\n return null;\n }\n}\n\nexport function isNativeAvailable(): boolean {\n return tryLoadNative() !== null;\n}\n\nexport class NativeBackend implements LedgerBackend {\n readonly kind: \"native-mock\" | \"native-libcma\";\n #handle: NativeLedgerHandle;\n #closed = false;\n\n private constructor(handle: NativeLedgerHandle) {\n this.#handle = handle;\n this.kind =\n handle.kind === \"native-libcma\" ? \"native-libcma\" : \"native-mock\";\n }\n\n static openEtherBuffer(maxAccounts: number): NativeBackend | null {\n const native = tryLoadNative();\n if (!native) {\n return null;\n }\n return new NativeBackend(native.openEtherBuffer(maxAccounts));\n }\n\n static openEtherFile(\n path: string,\n offset: number,\n memoryLength: number,\n maxAccounts: number,\n ): NativeBackend | null {\n const native = tryLoadNative();\n if (!native) {\n return null;\n }\n return new NativeBackend(\n native.openEtherFile(path, offset, memoryLength, maxAccounts),\n );\n }\n\n #ensureOpen(): void {\n if (this.#closed) {\n throw LedgerError.fromCode(LedgerErrorCode.UNKNOWN, \"ledger is closed\");\n }\n }\n\n #addr(account: Address): Uint8Array {\n return toBytes(normalizeAddress(account));\n }\n\n depositEther(account: Address, amount: bigint): void {\n this.#ensureOpen();\n assertAmount(amount);\n this.#handle.depositEther(this.#addr(account), amount);\n }\n\n transferEther(from: Address, to: Address, amount: bigint): void {\n this.#ensureOpen();\n assertAmount(amount);\n this.#handle.transferEther(this.#addr(from), this.#addr(to), amount);\n }\n\n withdrawEther(account: Address, amount: bigint): void {\n this.#ensureOpen();\n assertAmount(amount);\n this.#handle.withdrawEther(this.#addr(account), amount);\n }\n\n getEtherBalance(account: Address): bigint {\n this.#ensureOpen();\n return this.#handle.getEtherBalance(this.#addr(account));\n }\n\n close(): void {\n if (!this.#closed) {\n this.#handle.close();\n this.#closed = true;\n }\n }\n}\n","import type { Address, BackendKind, LedgerBufferConfig, LedgerEtherConfig, LedgerFileConfig } from \"./types.js\";\nimport {\n ACCOUNTS_DRIVE_PATH,\n ACCOUNTS_DRIVE_SIZE_4MIB,\n DEFAULT_ETHER_CONFIG,\n LOG2_MAX_NUM_OF_ACCOUNTS_DEFAULT,\n} from \"./types.js\";\nimport { LedgerError, LedgerErrorCode } from \"./errors.js\";\nimport { assertAmount, normalizeAddress, parseEtherPortalDeposit } from \"./bytes.js\";\nimport { MemoryBackend, type LedgerBackend } from \"./memory-backend.js\";\nimport { NativeBackend, isNativeAvailable } from \"./native-backend.js\";\n\nexport type OpenLedgerOptions = {\n /**\n * Prefer native addon when available.\n * - `\"auto\"` (default): native if built, else memory backend\n * - `\"memory\"`: force host memory backend (never proof-identical)\n * - `\"native\"`: require native addon or throw\n */\n backend?: \"auto\" | \"memory\" | \"native\";\n};\n\n/**\n * Proveable-oriented asset ledger (Ether MVP).\n *\n * On the Cartesi Machine, open the accounts drive via {@link Ledger.openEtherFile}\n * with path {@link ACCOUNTS_DRIVE_PATH}. On the host, {@link Ledger.openEtherBuffer}\n * uses the native mock when built, otherwise the TypeScript memory backend.\n */\nexport class Ledger {\n #backend: LedgerBackend;\n\n private constructor(backend: LedgerBackend) {\n this.#backend = backend;\n }\n\n /** Which implementation is serving this instance. */\n get backendKind(): BackendKind {\n return this.#backend.kind;\n }\n\n /**\n * Open a single-asset Ether ledger over an in-memory buffer (host tests).\n */\n static openEtherBuffer(\n config: LedgerEtherConfig = DEFAULT_ETHER_CONFIG,\n options: OpenLedgerOptions = {},\n ): Ledger {\n const maxAccounts = config.maxAccounts;\n if (maxAccounts <= 0) {\n throw new RangeError(\"maxAccounts must be positive\");\n }\n return Ledger.#openEther(maxAccounts, options, () =>\n NativeBackend.openEtherBuffer(maxAccounts),\n );\n }\n\n /**\n * Open a multi-asset buffer ledger; Phase 1 only exposes Ether helpers on top.\n */\n static openBuffer(\n config: LedgerBufferConfig,\n options: OpenLedgerOptions = {},\n ): Ledger {\n return Ledger.openEtherBuffer(\n {\n memoryLength: config.memoryLength,\n maxAccounts: config.maxAccounts,\n },\n options,\n );\n }\n\n /**\n * Open a single-asset Ether ledger on a file or block device.\n * Inside the machine use {@link ACCOUNTS_DRIVE_PATH} (`/dev/pmem1`).\n */\n static openEtherFile(\n path: string,\n config: LedgerEtherConfig & { offset?: number; memoryLength?: number } = DEFAULT_ETHER_CONFIG,\n options: OpenLedgerOptions = {},\n ): Ledger {\n const maxAccounts = config.maxAccounts;\n const offset = config.offset ?? 0;\n const memoryLength = config.memoryLength ?? ACCOUNTS_DRIVE_SIZE_4MIB;\n if (maxAccounts <= 0) {\n throw new RangeError(\"maxAccounts must be positive\");\n }\n\n const prefer = options.backend ?? \"auto\";\n if (prefer === \"memory\") {\n // Memory backend cannot mmap a drive — still useful for API dry-runs.\n return new Ledger(MemoryBackend.openEther(maxAccounts));\n }\n\n const native = NativeBackend.openEtherFile(\n path,\n offset,\n memoryLength,\n maxAccounts,\n );\n if (native) {\n return new Ledger(native);\n }\n if (prefer === \"native\") {\n throw LedgerError.fromCode(\n LedgerErrorCode.UNKNOWN,\n \"native libcma addon is not available; run npm run build:native\",\n );\n }\n // Host fallback: memory (not drive-backed).\n return new Ledger(MemoryBackend.openEther(maxAccounts));\n }\n\n /**\n * File-backed multi-asset entry; Phase 1 routes to Ether single-asset helpers.\n */\n static openFile(\n path: string,\n config: LedgerFileConfig,\n options: OpenLedgerOptions = {},\n ): Ledger {\n return Ledger.openEtherFile(\n path,\n {\n maxAccounts: config.maxAccounts,\n offset: config.offset,\n memoryLength: config.memoryLength,\n },\n options,\n );\n }\n\n static #openEther(\n maxAccounts: number,\n options: OpenLedgerOptions,\n openNative: () => NativeBackend | null,\n ): Ledger {\n const prefer = options.backend ?? \"auto\";\n if (prefer === \"memory\") {\n return new Ledger(MemoryBackend.openEther(maxAccounts));\n }\n const native = openNative();\n if (native) {\n return new Ledger(native);\n }\n if (prefer === \"native\") {\n throw LedgerError.fromCode(\n LedgerErrorCode.UNKNOWN,\n \"native libcma addon is not available; run npm run build:native\",\n );\n }\n return new Ledger(MemoryBackend.openEther(maxAccounts));\n }\n\n depositEther(account: Address, amount: bigint): void {\n this.#backend.depositEther(normalizeAddress(account), amount);\n }\n\n /**\n * Credit from a packed EtherPortal advance payload.\n * @returns decoded sender and value (exec layer data is ignored here)\n */\n creditEtherDeposit(payload: `0x${string}` | Uint8Array): {\n sender: Address;\n value: bigint;\n } {\n const { sender, value } = parseEtherPortalDeposit(payload);\n this.depositEther(sender, value);\n return { sender, value };\n }\n\n transferEther(from: Address, to: Address, amount: bigint): void {\n this.#backend.transferEther(\n normalizeAddress(from),\n normalizeAddress(to),\n amount,\n );\n }\n\n /**\n * Debit Ether. Does **not** emit a rollup voucher — the dApp must call\n * `POST /voucher` or `@deroll/cmio.emitVoucher` separately.\n */\n withdrawEther(account: Address, amount: bigint): void {\n assertAmount(amount);\n this.#backend.withdrawEther(normalizeAddress(account), amount);\n }\n\n getEtherBalance(account: Address): bigint {\n return this.#backend.getEtherBalance(normalizeAddress(account));\n }\n\n /** Alias matching Deroll naming. */\n getBalance(account: Address): bigint {\n return this.getEtherBalance(account);\n }\n\n close(): void {\n this.#backend.close();\n }\n}\n\nexport {\n ACCOUNTS_DRIVE_PATH,\n ACCOUNTS_DRIVE_SIZE_4MIB,\n DEFAULT_ETHER_CONFIG,\n LOG2_MAX_NUM_OF_ACCOUNTS_DEFAULT,\n isNativeAvailable,\n};\n"]}
|
package/lib/index.d.cts
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/** 0x-prefixed hex string. Compatible with viem `Hex` / `Address`. */
|
|
2
|
+
type Hex = `0x${string}`;
|
|
3
|
+
/** EVM address as checksummed or lowercase 0x hex. */
|
|
4
|
+
type Address = Hex;
|
|
5
|
+
/** Bytes input accepted at API boundaries. */
|
|
6
|
+
type BytesLike = Hex | Uint8Array;
|
|
7
|
+
declare const ADDRESS_LENGTH = 20;
|
|
8
|
+
declare const U256_LENGTH = 32;
|
|
9
|
+
/** Default accounts-drive path inside the Cartesi Machine. */
|
|
10
|
+
declare const ACCOUNTS_DRIVE_PATH = "/dev/pmem1";
|
|
11
|
+
/**
|
|
12
|
+
* 4 MiB = 2^17 account slots × 32-byte records (contracts v3 convention when
|
|
13
|
+
* `log2_max_num_of_accounts = 17`).
|
|
14
|
+
*/
|
|
15
|
+
declare const ACCOUNTS_DRIVE_SIZE_4MIB = 4194304;
|
|
16
|
+
declare const LOG2_MAX_NUM_OF_ACCOUNTS_DEFAULT = 17;
|
|
17
|
+
/** Minimum mem length required by libcma (`CMA_LEDGER_MIN_MEM_LENGTH`). */
|
|
18
|
+
declare const LEDGER_MIN_MEM_LENGTH = 262144;
|
|
19
|
+
type LedgerMemoryMode = "create-only" | "open-only";
|
|
20
|
+
/**
|
|
21
|
+
* File-backed ledger config (machine: `/dev/pmem1`, or a host test file).
|
|
22
|
+
* Sizes must be consistent with `cartesi.toml` `[withdrawal.config]`.
|
|
23
|
+
*/
|
|
24
|
+
type LedgerFileConfig = {
|
|
25
|
+
mode?: LedgerMemoryMode;
|
|
26
|
+
offset?: number;
|
|
27
|
+
memoryLength: number;
|
|
28
|
+
maxAccounts: number;
|
|
29
|
+
maxAssets: number;
|
|
30
|
+
maxBalances: number;
|
|
31
|
+
};
|
|
32
|
+
/** Buffer-backed (non-persistent) ledger config for host tests. */
|
|
33
|
+
type LedgerBufferConfig = {
|
|
34
|
+
memoryLength?: number;
|
|
35
|
+
maxAccounts: number;
|
|
36
|
+
maxAssets: number;
|
|
37
|
+
maxBalances: number;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Single-asset Ether ledger config — maps to `cma_ledger_init_single_*`.
|
|
41
|
+
* Preferred for Ether-only dApps.
|
|
42
|
+
*/
|
|
43
|
+
type LedgerEtherConfig = {
|
|
44
|
+
memoryLength?: number;
|
|
45
|
+
/** Account capacity; typically `2 ** log2_max_num_of_accounts`. */
|
|
46
|
+
maxAccounts: number;
|
|
47
|
+
};
|
|
48
|
+
declare const DEFAULT_ETHER_CONFIG: Required<LedgerEtherConfig>;
|
|
49
|
+
type BackendKind = "memory" | "native-mock" | "native-libcma";
|
|
50
|
+
|
|
51
|
+
declare function isNativeAvailable(): boolean;
|
|
52
|
+
|
|
53
|
+
type OpenLedgerOptions = {
|
|
54
|
+
/**
|
|
55
|
+
* Prefer native addon when available.
|
|
56
|
+
* - `"auto"` (default): native if built, else memory backend
|
|
57
|
+
* - `"memory"`: force host memory backend (never proof-identical)
|
|
58
|
+
* - `"native"`: require native addon or throw
|
|
59
|
+
*/
|
|
60
|
+
backend?: "auto" | "memory" | "native";
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* Proveable-oriented asset ledger (Ether MVP).
|
|
64
|
+
*
|
|
65
|
+
* On the Cartesi Machine, open the accounts drive via {@link Ledger.openEtherFile}
|
|
66
|
+
* with path {@link ACCOUNTS_DRIVE_PATH}. On the host, {@link Ledger.openEtherBuffer}
|
|
67
|
+
* uses the native mock when built, otherwise the TypeScript memory backend.
|
|
68
|
+
*/
|
|
69
|
+
declare class Ledger {
|
|
70
|
+
#private;
|
|
71
|
+
private constructor();
|
|
72
|
+
/** Which implementation is serving this instance. */
|
|
73
|
+
get backendKind(): BackendKind;
|
|
74
|
+
/**
|
|
75
|
+
* Open a single-asset Ether ledger over an in-memory buffer (host tests).
|
|
76
|
+
*/
|
|
77
|
+
static openEtherBuffer(config?: LedgerEtherConfig, options?: OpenLedgerOptions): Ledger;
|
|
78
|
+
/**
|
|
79
|
+
* Open a multi-asset buffer ledger; Phase 1 only exposes Ether helpers on top.
|
|
80
|
+
*/
|
|
81
|
+
static openBuffer(config: LedgerBufferConfig, options?: OpenLedgerOptions): Ledger;
|
|
82
|
+
/**
|
|
83
|
+
* Open a single-asset Ether ledger on a file or block device.
|
|
84
|
+
* Inside the machine use {@link ACCOUNTS_DRIVE_PATH} (`/dev/pmem1`).
|
|
85
|
+
*/
|
|
86
|
+
static openEtherFile(path: string, config?: LedgerEtherConfig & {
|
|
87
|
+
offset?: number;
|
|
88
|
+
memoryLength?: number;
|
|
89
|
+
}, options?: OpenLedgerOptions): Ledger;
|
|
90
|
+
/**
|
|
91
|
+
* File-backed multi-asset entry; Phase 1 routes to Ether single-asset helpers.
|
|
92
|
+
*/
|
|
93
|
+
static openFile(path: string, config: LedgerFileConfig, options?: OpenLedgerOptions): Ledger;
|
|
94
|
+
depositEther(account: Address, amount: bigint): void;
|
|
95
|
+
/**
|
|
96
|
+
* Credit from a packed EtherPortal advance payload.
|
|
97
|
+
* @returns decoded sender and value (exec layer data is ignored here)
|
|
98
|
+
*/
|
|
99
|
+
creditEtherDeposit(payload: `0x${string}` | Uint8Array): {
|
|
100
|
+
sender: Address;
|
|
101
|
+
value: bigint;
|
|
102
|
+
};
|
|
103
|
+
transferEther(from: Address, to: Address, amount: bigint): void;
|
|
104
|
+
/**
|
|
105
|
+
* Debit Ether. Does **not** emit a rollup voucher — the dApp must call
|
|
106
|
+
* `POST /voucher` or `@deroll/cmio.emitVoucher` separately.
|
|
107
|
+
*/
|
|
108
|
+
withdrawEther(account: Address, amount: bigint): void;
|
|
109
|
+
getEtherBalance(account: Address): bigint;
|
|
110
|
+
/** Alias matching Deroll naming. */
|
|
111
|
+
getBalance(account: Address): bigint;
|
|
112
|
+
close(): void;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/** libcma-style error codes (see `include/libcma/ledger.h`). */
|
|
116
|
+
declare const LedgerErrorCode: {
|
|
117
|
+
readonly SUCCESS: 0;
|
|
118
|
+
readonly UNKNOWN: -1001;
|
|
119
|
+
readonly EXCEPTION: -1002;
|
|
120
|
+
readonly INSUFFICIENT_FUNDS: -1003;
|
|
121
|
+
readonly ACCOUNT_NOT_FOUND: -1004;
|
|
122
|
+
readonly ASSET_NOT_FOUND: -1005;
|
|
123
|
+
readonly BALANCE_NOT_FOUND: -1006;
|
|
124
|
+
readonly SUPPLY_OVERFLOW: -1007;
|
|
125
|
+
readonly BALANCE_OVERFLOW: -1008;
|
|
126
|
+
readonly INVALID_ACCOUNT: -1009;
|
|
127
|
+
readonly INSERTION_ERROR: -1010;
|
|
128
|
+
readonly MAX_ASSETS_REACHED: -1011;
|
|
129
|
+
readonly MAX_ACCOUNTS_REACHED: -1012;
|
|
130
|
+
readonly MAX_BALANCES_REACHED: -1013;
|
|
131
|
+
readonly ASSET_SUPPLY: -1014;
|
|
132
|
+
readonly ACCOUNT_BALANCE: -1015;
|
|
133
|
+
readonly REMOVE: -1016;
|
|
134
|
+
};
|
|
135
|
+
declare class LedgerError extends Error {
|
|
136
|
+
readonly name = "LedgerError";
|
|
137
|
+
readonly code: number;
|
|
138
|
+
constructor(code: number, message?: string);
|
|
139
|
+
static fromCode(code: number, detail?: string): LedgerError;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
declare function toBytes(value: BytesLike, name?: string): Uint8Array;
|
|
143
|
+
declare function toHex(bytes: Uint8Array): Hex;
|
|
144
|
+
/** Normalize to lowercase 0x-address (20 bytes). */
|
|
145
|
+
declare function normalizeAddress(address: BytesLike): Address;
|
|
146
|
+
/**
|
|
147
|
+
* Decode packed EtherPortal deposit payload (Rollups v2):
|
|
148
|
+
* `sender (20) || value (32) || execLayerData?`
|
|
149
|
+
*/
|
|
150
|
+
declare function parseEtherPortalDeposit(payload: BytesLike): {
|
|
151
|
+
sender: Address;
|
|
152
|
+
value: bigint;
|
|
153
|
+
execLayerData?: Hex;
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
export { ACCOUNTS_DRIVE_PATH, ACCOUNTS_DRIVE_SIZE_4MIB, ADDRESS_LENGTH, type Address, type BackendKind, type BytesLike, DEFAULT_ETHER_CONFIG, type Hex, LEDGER_MIN_MEM_LENGTH, LOG2_MAX_NUM_OF_ACCOUNTS_DEFAULT, Ledger, type LedgerBufferConfig, LedgerError, LedgerErrorCode, type LedgerEtherConfig, type LedgerFileConfig, type LedgerMemoryMode, type OpenLedgerOptions, U256_LENGTH, isNativeAvailable, normalizeAddress, parseEtherPortalDeposit, toBytes, toHex };
|