@totemsdk/omnia-vtxo 0.1.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/dist/exit.js ADDED
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.markExiting = markExiting;
4
+ exports.markExited = markExited;
5
+ exports.createExitDraft = createExitDraft;
6
+ const errors_js_1 = require("./errors.js");
7
+ const constants_js_1 = require("./constants.js");
8
+ const commitment_js_1 = require("./commitment.js");
9
+ /**
10
+ * Transitions an active VTXO to 'exiting' status.
11
+ * @param now - Timestamp in ms. Defaults to Date.now() if omitted — pass explicitly for determinism.
12
+ */
13
+ function markExiting(vtxo, now) {
14
+ const ts = now !== undefined ? now : Date.now();
15
+ if (vtxo.status !== 'active') {
16
+ throw new errors_js_1.VtxoStatusError(`Cannot initiate exit for VTXO ${vtxo.vtxoId}: status is '${vtxo.status}'`, vtxo.status);
17
+ }
18
+ return {
19
+ ...vtxo,
20
+ status: 'exiting',
21
+ updatedAt: ts,
22
+ history: [
23
+ ...vtxo.history,
24
+ { op: 'exit_initiated', at: ts },
25
+ ],
26
+ };
27
+ }
28
+ /**
29
+ * Transitions an exiting VTXO to 'exited' status.
30
+ * @param now - Timestamp in ms. Defaults to Date.now() if omitted — pass explicitly for determinism.
31
+ */
32
+ function markExited(vtxo, now) {
33
+ const ts = now !== undefined ? now : Date.now();
34
+ if (vtxo.status !== 'exiting') {
35
+ throw new errors_js_1.VtxoStatusError(`Cannot mark VTXO ${vtxo.vtxoId} as exited: status is '${vtxo.status}'`, vtxo.status);
36
+ }
37
+ return {
38
+ ...vtxo,
39
+ status: 'exited',
40
+ updatedAt: ts,
41
+ history: [
42
+ ...vtxo.history,
43
+ { op: 'exit_complete', at: ts },
44
+ ],
45
+ };
46
+ }
47
+ /**
48
+ * Validates the VTXO's proof leaf integrity before creating an exit draft.
49
+ * Throws VtxoProofError if the proof leaf is present but does not match the VTXO fields.
50
+ */
51
+ function assertProofLeafValid(vtxo) {
52
+ if (!vtxo.proof.leaf)
53
+ return;
54
+ const expectedLeaf = (0, commitment_js_1.computeVtxoLeaf)(vtxo);
55
+ if (vtxo.proof.leaf !== expectedLeaf) {
56
+ throw new errors_js_1.VtxoProofError(`Exit draft rejected: VTXO ${vtxo.vtxoId} proof leaf mismatch. ` +
57
+ `Expected ${expectedLeaf}, got ${vtxo.proof.leaf}`);
58
+ }
59
+ }
60
+ /**
61
+ * Creates a mock exit draft for a VTXO. Validates the proof leaf before drafting.
62
+ * @param now - Timestamp in ms. Defaults to Date.now() if omitted — pass explicitly for determinism.
63
+ */
64
+ function createExitDraft(vtxo, now) {
65
+ const ts = now !== undefined ? now : Date.now();
66
+ if (vtxo.status !== 'active' && vtxo.status !== 'exiting') {
67
+ throw new errors_js_1.VtxoExitError(`Cannot create exit draft for VTXO ${vtxo.vtxoId}: status is '${vtxo.status}'`);
68
+ }
69
+ assertProofLeafValid(vtxo);
70
+ const draft = {
71
+ vtxoId: vtxo.vtxoId,
72
+ poolId: vtxo.poolId,
73
+ owner: vtxo.owner,
74
+ amount: vtxo.amount,
75
+ tokenId: vtxo.tokenId,
76
+ draftType: 'mock-exit',
77
+ timelockSeconds: 86400,
78
+ createdAt: ts,
79
+ };
80
+ const receiptId = (0, commitment_js_1.computeReceiptId)(vtxo.poolId, 'exit_initiated', [vtxo.vtxoId], [], ts);
81
+ const receipt = {
82
+ receiptId,
83
+ poolId: vtxo.poolId,
84
+ op: 'exit_initiated',
85
+ inputIds: [vtxo.vtxoId],
86
+ outputIds: [],
87
+ epoch: vtxo.epoch,
88
+ at: ts,
89
+ signature: constants_js_1.MOCK_OPERATOR_SIGNATURE,
90
+ draftType: 'mock-exit',
91
+ };
92
+ return { draft, receipt };
93
+ }
@@ -0,0 +1,15 @@
1
+ export * from './types.js';
2
+ export * from './errors.js';
3
+ export * from './constants.js';
4
+ export * from './commitment.js';
5
+ export * from './pool.js';
6
+ export * from './vtxo.js';
7
+ export * from './transfer.js';
8
+ export * from './split.js';
9
+ export * from './merge.js';
10
+ export * from './refresh.js';
11
+ export * from './exit.js';
12
+ export * from './verify.js';
13
+ export * from './memory-store.js';
14
+ export * from './serialization.js';
15
+ export * from './policy.js';
package/dist/index.js ADDED
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./types.js"), exports);
18
+ __exportStar(require("./errors.js"), exports);
19
+ __exportStar(require("./constants.js"), exports);
20
+ __exportStar(require("./commitment.js"), exports);
21
+ __exportStar(require("./pool.js"), exports);
22
+ __exportStar(require("./vtxo.js"), exports);
23
+ __exportStar(require("./transfer.js"), exports);
24
+ __exportStar(require("./split.js"), exports);
25
+ __exportStar(require("./merge.js"), exports);
26
+ __exportStar(require("./refresh.js"), exports);
27
+ __exportStar(require("./exit.js"), exports);
28
+ __exportStar(require("./verify.js"), exports);
29
+ __exportStar(require("./memory-store.js"), exports);
30
+ __exportStar(require("./serialization.js"), exports);
31
+ __exportStar(require("./policy.js"), exports);
@@ -0,0 +1,17 @@
1
+ import { OmniaVtxo, OmniaVtxoPool, OmniaVtxoStore, VtxoId } from './types.js';
2
+ export declare class MemoryOmniaVtxoStore implements OmniaVtxoStore {
3
+ private readonly pools;
4
+ private readonly vtxos;
5
+ savePool(pool: OmniaVtxoPool): Promise<void>;
6
+ getPool(poolId: string): Promise<OmniaVtxoPool | undefined>;
7
+ saveVtxo(vtxo: OmniaVtxo): Promise<void>;
8
+ getVtxo(vtxoId: VtxoId): Promise<OmniaVtxo | undefined>;
9
+ listVtxos(poolId?: string): Promise<OmniaVtxo[]>;
10
+ /**
11
+ * Marks a VTXO as spent. Accepts an optional `now` timestamp for deterministic testing.
12
+ * When `now` is omitted the store falls back to `Date.now()` — this is intentional
13
+ * and explicitly documented: the store is a persistence layer, not a pure function,
14
+ * so wall-clock time is an acceptable default for production use. Pass `now` in tests.
15
+ */
16
+ markVtxoSpent(vtxoId: VtxoId, now?: number): Promise<void>;
17
+ }
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MemoryOmniaVtxoStore = void 0;
4
+ const errors_js_1 = require("./errors.js");
5
+ class MemoryOmniaVtxoStore {
6
+ constructor() {
7
+ this.pools = new Map();
8
+ this.vtxos = new Map();
9
+ }
10
+ async savePool(pool) {
11
+ this.pools.set(pool.poolId, pool);
12
+ }
13
+ async getPool(poolId) {
14
+ return this.pools.get(poolId);
15
+ }
16
+ async saveVtxo(vtxo) {
17
+ this.vtxos.set(vtxo.vtxoId, vtxo);
18
+ }
19
+ async getVtxo(vtxoId) {
20
+ return this.vtxos.get(vtxoId);
21
+ }
22
+ async listVtxos(poolId) {
23
+ const all = Array.from(this.vtxos.values());
24
+ if (poolId === undefined)
25
+ return all;
26
+ return all.filter(v => v.poolId === poolId);
27
+ }
28
+ /**
29
+ * Marks a VTXO as spent. Accepts an optional `now` timestamp for deterministic testing.
30
+ * When `now` is omitted the store falls back to `Date.now()` — this is intentional
31
+ * and explicitly documented: the store is a persistence layer, not a pure function,
32
+ * so wall-clock time is an acceptable default for production use. Pass `now` in tests.
33
+ */
34
+ async markVtxoSpent(vtxoId, now) {
35
+ const vtxo = this.vtxos.get(vtxoId);
36
+ if (!vtxo)
37
+ throw new Error(`VTXO ${vtxoId} not found`);
38
+ if (vtxo.status !== 'active') {
39
+ throw new errors_js_1.VtxoStatusError(`Cannot mark VTXO ${vtxoId} as spent: status is '${vtxo.status}'`, vtxo.status);
40
+ }
41
+ // NOTE: Date.now() fallback is intentional and documented above.
42
+ const ts = now !== undefined ? now : Date.now();
43
+ this.vtxos.set(vtxoId, {
44
+ ...vtxo,
45
+ status: 'spent',
46
+ updatedAt: ts,
47
+ history: [...vtxo.history, { op: 'spent', at: ts }],
48
+ });
49
+ }
50
+ }
51
+ exports.MemoryOmniaVtxoStore = MemoryOmniaVtxoStore;
@@ -0,0 +1,8 @@
1
+ import { OmniaVtxo, MergeVtxosParams, MergeResult, VtxoOperatorReceipt } from './types.js';
2
+ /**
3
+ * Merges multiple VTXOs into one.
4
+ * @param now - Timestamp in ms. Defaults to Date.now() if omitted — pass explicitly for determinism.
5
+ */
6
+ export declare function mergeVtxos(vtxos: OmniaVtxo[], params: MergeVtxosParams, now?: number): MergeResult & {
7
+ receipt: VtxoOperatorReceipt;
8
+ };
package/dist/merge.js ADDED
@@ -0,0 +1,107 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.mergeVtxos = mergeVtxos;
4
+ const errors_js_1 = require("./errors.js");
5
+ const commitment_js_1 = require("./commitment.js");
6
+ const constants_js_1 = require("./constants.js");
7
+ /**
8
+ * Merges multiple VTXOs into one.
9
+ * @param now - Timestamp in ms. Defaults to Date.now() if omitted — pass explicitly for determinism.
10
+ */
11
+ function mergeVtxos(vtxos, params, now) {
12
+ const ts = now !== undefined ? now : Date.now();
13
+ if (vtxos.length < 2) {
14
+ throw new errors_js_1.VtxoMergeError('Merge requires at least 2 VTXOs');
15
+ }
16
+ const ids = vtxos.map(v => v.vtxoId);
17
+ const uniqueIds = new Set(ids);
18
+ if (uniqueIds.size !== ids.length) {
19
+ throw new errors_js_1.VtxoMergeError('Duplicate VTXO IDs detected in merge — double-counting prevented');
20
+ }
21
+ for (const vtxo of vtxos) {
22
+ if (vtxo.status !== 'active') {
23
+ throw new errors_js_1.VtxoStatusError(`Cannot merge VTXO ${vtxo.vtxoId}: status is '${vtxo.status}'`, vtxo.status);
24
+ }
25
+ }
26
+ const poolId = vtxos[0].poolId;
27
+ const tokenId = vtxos[0].tokenId;
28
+ const inputOwner = vtxos[0].owner;
29
+ for (const vtxo of vtxos) {
30
+ if (vtxo.poolId !== poolId) {
31
+ throw new errors_js_1.VtxoMergeError(`Cannot merge VTXOs from different pools: ${vtxo.poolId} vs ${poolId}`);
32
+ }
33
+ if (vtxo.tokenId !== tokenId) {
34
+ throw new errors_js_1.VtxoMergeError(`Cannot merge VTXOs with different tokenIds: ${vtxo.tokenId} vs ${tokenId}`);
35
+ }
36
+ if (vtxo.owner !== inputOwner) {
37
+ throw new errors_js_1.VtxoOwnershipError(`Cannot merge VTXOs with different owners: ${vtxo.owner} vs ${inputOwner}`);
38
+ }
39
+ }
40
+ if (params.owner !== inputOwner) {
41
+ throw new errors_js_1.VtxoOwnershipError(`Merge output owner '${params.owner}' must match input owner '${inputOwner}'`);
42
+ }
43
+ const totalAmount = vtxos.reduce((sum, v) => sum + v.amount, BigInt(0));
44
+ const outputId = (0, commitment_js_1.computeVtxoId)({
45
+ poolId,
46
+ owner: params.owner,
47
+ amount: totalAmount,
48
+ tokenId,
49
+ nonce: params.nonce,
50
+ });
51
+ const inputVtxos = vtxos.map(vtxo => ({
52
+ ...vtxo,
53
+ status: 'merged',
54
+ updatedAt: ts,
55
+ history: [
56
+ ...vtxo.history,
57
+ {
58
+ op: 'merge',
59
+ at: ts,
60
+ relatedIds: [outputId],
61
+ },
62
+ ],
63
+ }));
64
+ const rawOutput = {
65
+ vtxoId: outputId,
66
+ poolId,
67
+ owner: params.owner,
68
+ amount: totalAmount,
69
+ tokenId,
70
+ status: 'active',
71
+ epoch: vtxos[0].epoch,
72
+ proof: {
73
+ leaf: '',
74
+ root: '',
75
+ siblings: [],
76
+ positions: [],
77
+ epoch: vtxos[0].epoch,
78
+ batchId: constants_js_1.MOCK_BATCH_ID,
79
+ },
80
+ history: [
81
+ {
82
+ op: 'merge',
83
+ at: ts,
84
+ relatedIds: ids,
85
+ },
86
+ ],
87
+ createdAt: ts,
88
+ updatedAt: ts,
89
+ };
90
+ const { proofs } = (0, commitment_js_1.buildVtxoProofSet)([rawOutput]);
91
+ const output = { ...rawOutput, proof: proofs[outputId] };
92
+ const receiptId = (0, commitment_js_1.computeReceiptId)(poolId, 'merge', ids, [outputId], ts);
93
+ return {
94
+ inputs: inputVtxos,
95
+ output,
96
+ receipt: {
97
+ receiptId,
98
+ poolId,
99
+ op: 'merge',
100
+ inputIds: ids,
101
+ outputIds: [outputId],
102
+ epoch: vtxos[0].epoch,
103
+ at: ts,
104
+ signature: constants_js_1.MOCK_OPERATOR_SIGNATURE,
105
+ },
106
+ };
107
+ }
@@ -0,0 +1,22 @@
1
+ import { OmniaVtxo, VtxoId } from './types.js';
2
+ export interface VtxoTransferIntent {
3
+ type: 'vtxo-transfer';
4
+ poolId: string;
5
+ inputId: VtxoId;
6
+ recipient: string;
7
+ amount: bigint;
8
+ tokenId: string;
9
+ nonce: string;
10
+ changeNonce?: string;
11
+ }
12
+ export interface VtxoExitIntent {
13
+ type: 'vtxo-exit';
14
+ poolId: string;
15
+ vtxoId: VtxoId;
16
+ owner: string;
17
+ amount: bigint;
18
+ tokenId: string;
19
+ draftType: 'mock-exit';
20
+ }
21
+ export declare function buildVtxoTransferIntent(vtxo: OmniaVtxo, recipient: string, amount: bigint, nonce: string, changeNonce?: string): VtxoTransferIntent;
22
+ export declare function buildVtxoExitIntent(vtxo: OmniaVtxo): VtxoExitIntent;
package/dist/policy.js ADDED
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildVtxoTransferIntent = buildVtxoTransferIntent;
4
+ exports.buildVtxoExitIntent = buildVtxoExitIntent;
5
+ function buildVtxoTransferIntent(vtxo, recipient, amount, nonce, changeNonce) {
6
+ return {
7
+ type: 'vtxo-transfer',
8
+ poolId: vtxo.poolId,
9
+ inputId: vtxo.vtxoId,
10
+ recipient,
11
+ amount,
12
+ tokenId: vtxo.tokenId,
13
+ nonce,
14
+ changeNonce,
15
+ };
16
+ }
17
+ function buildVtxoExitIntent(vtxo) {
18
+ return {
19
+ type: 'vtxo-exit',
20
+ poolId: vtxo.poolId,
21
+ vtxoId: vtxo.vtxoId,
22
+ owner: vtxo.owner,
23
+ amount: vtxo.amount,
24
+ tokenId: vtxo.tokenId,
25
+ draftType: 'mock-exit',
26
+ };
27
+ }
package/dist/pool.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ import { OmniaVtxoPool, CreatePoolParams } from './types.js';
2
+ export declare function createPool(params: CreatePoolParams, now: number): OmniaVtxoPool;
3
+ export declare function assertPoolCanMint(pool: OmniaVtxoPool, amount: bigint): void;
4
+ export declare function updatePoolRoot(pool: OmniaVtxoPool, root: string): OmniaVtxoPool;
5
+ export declare function advancePoolEpoch(pool: OmniaVtxoPool, newEpoch: number): OmniaVtxoPool;
package/dist/pool.js ADDED
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createPool = createPool;
4
+ exports.assertPoolCanMint = assertPoolCanMint;
5
+ exports.updatePoolRoot = updatePoolRoot;
6
+ exports.advancePoolEpoch = advancePoolEpoch;
7
+ const errors_js_1 = require("./errors.js");
8
+ const constants_js_1 = require("./constants.js");
9
+ const commitment_js_1 = require("./commitment.js");
10
+ function createPool(params, now) {
11
+ const policy = {
12
+ minAmount: params.policy?.minAmount ?? constants_js_1.DEFAULT_POLICY.minAmount,
13
+ maxAmount: params.policy?.maxAmount ?? constants_js_1.DEFAULT_POLICY.maxAmount,
14
+ maxMergeInputs: params.policy?.maxMergeInputs ?? constants_js_1.DEFAULT_POLICY.maxMergeInputs,
15
+ maxSplitOutputs: params.policy?.maxSplitOutputs ?? constants_js_1.DEFAULT_POLICY.maxSplitOutputs,
16
+ exitTimelockSeconds: params.policy?.exitTimelockSeconds ?? constants_js_1.DEFAULT_POLICY.exitTimelockSeconds,
17
+ };
18
+ if (params.totalCapacity <= BigInt(0)) {
19
+ throw new errors_js_1.VtxoPolicyError('Pool totalCapacity must be > 0');
20
+ }
21
+ const poolId = (0, commitment_js_1.computePoolId)({
22
+ operator: params.operator,
23
+ tokenId: params.tokenId,
24
+ nonce: params.nonce,
25
+ });
26
+ return {
27
+ poolId,
28
+ operator: params.operator,
29
+ tokenId: params.tokenId,
30
+ totalCapacity: params.totalCapacity,
31
+ availableCapacity: params.totalCapacity,
32
+ epoch: constants_js_1.EPOCH_ZERO,
33
+ commitmentRoot: constants_js_1.EMPTY_TREE_ROOT,
34
+ createdAt: now,
35
+ policy,
36
+ };
37
+ }
38
+ function assertPoolCanMint(pool, amount) {
39
+ if (amount <= BigInt(0)) {
40
+ throw new errors_js_1.VtxoPolicyError(`Mint amount must be > 0, got ${amount}`);
41
+ }
42
+ if (amount < pool.policy.minAmount) {
43
+ throw new errors_js_1.VtxoPolicyError(`Mint amount ${amount} is below pool minimum ${pool.policy.minAmount}`);
44
+ }
45
+ if (amount > pool.policy.maxAmount) {
46
+ throw new errors_js_1.VtxoPolicyError(`Mint amount ${amount} exceeds pool maximum ${pool.policy.maxAmount}`);
47
+ }
48
+ if (amount > pool.availableCapacity) {
49
+ throw new errors_js_1.VtxoPoolCapacityError(`Insufficient pool capacity: requested ${amount}, available ${pool.availableCapacity}`, amount, pool.availableCapacity);
50
+ }
51
+ }
52
+ function updatePoolRoot(pool, root) {
53
+ return { ...pool, commitmentRoot: root };
54
+ }
55
+ function advancePoolEpoch(pool, newEpoch) {
56
+ if (newEpoch <= pool.epoch) {
57
+ throw new errors_js_1.VtxoPolicyError(`New epoch ${newEpoch} must be greater than current epoch ${pool.epoch}`);
58
+ }
59
+ return { ...pool, epoch: newEpoch };
60
+ }
@@ -0,0 +1,8 @@
1
+ import { OmniaVtxo, RefreshVtxoParams, RefreshResult, VtxoOperatorReceipt } from './types.js';
2
+ /**
3
+ * Refreshes a VTXO to a new epoch.
4
+ * @param now - Timestamp in ms. Defaults to Date.now() if omitted — pass explicitly for determinism.
5
+ */
6
+ export declare function refreshVtxo(vtxo: OmniaVtxo, params: RefreshVtxoParams, now?: number): RefreshResult & {
7
+ receipt: VtxoOperatorReceipt;
8
+ };
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.refreshVtxo = refreshVtxo;
4
+ const errors_js_1 = require("./errors.js");
5
+ const commitment_js_1 = require("./commitment.js");
6
+ const constants_js_1 = require("./constants.js");
7
+ /**
8
+ * Refreshes a VTXO to a new epoch.
9
+ * @param now - Timestamp in ms. Defaults to Date.now() if omitted — pass explicitly for determinism.
10
+ */
11
+ function refreshVtxo(vtxo, params, now) {
12
+ const ts = now !== undefined ? now : Date.now();
13
+ if (vtxo.status !== 'active') {
14
+ throw new errors_js_1.VtxoStatusError(`Cannot refresh VTXO ${vtxo.vtxoId}: status is '${vtxo.status}'`, vtxo.status);
15
+ }
16
+ if (params.newEpoch <= vtxo.epoch) {
17
+ throw new errors_js_1.VtxoPolicyError(`Refresh epoch ${params.newEpoch} must be strictly greater than current epoch ${vtxo.epoch}`);
18
+ }
19
+ const refreshedId = (0, commitment_js_1.computeVtxoId)({
20
+ poolId: vtxo.poolId,
21
+ owner: vtxo.owner,
22
+ amount: vtxo.amount,
23
+ tokenId: vtxo.tokenId,
24
+ nonce: params.nonce,
25
+ });
26
+ const oldVtxo = {
27
+ ...vtxo,
28
+ status: 'refreshed',
29
+ updatedAt: ts,
30
+ history: [
31
+ ...vtxo.history,
32
+ {
33
+ op: 'refresh',
34
+ at: ts,
35
+ relatedIds: [refreshedId],
36
+ meta: { newEpoch: params.newEpoch },
37
+ },
38
+ ],
39
+ };
40
+ const rawRefreshed = {
41
+ vtxoId: refreshedId,
42
+ poolId: vtxo.poolId,
43
+ owner: vtxo.owner,
44
+ amount: vtxo.amount,
45
+ tokenId: vtxo.tokenId,
46
+ status: 'active',
47
+ epoch: params.newEpoch,
48
+ proof: {
49
+ leaf: '',
50
+ root: '',
51
+ siblings: [],
52
+ positions: [],
53
+ epoch: params.newEpoch,
54
+ batchId: constants_js_1.MOCK_BATCH_ID,
55
+ },
56
+ history: [
57
+ {
58
+ op: 'refresh',
59
+ at: ts,
60
+ relatedIds: [vtxo.vtxoId],
61
+ meta: { prevEpoch: vtxo.epoch, newEpoch: params.newEpoch },
62
+ },
63
+ ],
64
+ createdAt: ts,
65
+ updatedAt: ts,
66
+ expiresAt: vtxo.expiresAt,
67
+ };
68
+ const { proofs } = (0, commitment_js_1.buildVtxoProofSet)([rawRefreshed]);
69
+ const refreshedVtxo = { ...rawRefreshed, proof: proofs[refreshedId] };
70
+ const receiptId = (0, commitment_js_1.computeReceiptId)(vtxo.poolId, 'refresh', [vtxo.vtxoId], [refreshedId], ts);
71
+ return {
72
+ old: oldVtxo,
73
+ refreshed: refreshedVtxo,
74
+ receipt: {
75
+ receiptId,
76
+ poolId: vtxo.poolId,
77
+ op: 'refresh',
78
+ inputIds: [vtxo.vtxoId],
79
+ outputIds: [refreshedId],
80
+ epoch: params.newEpoch,
81
+ at: ts,
82
+ signature: constants_js_1.MOCK_OPERATOR_SIGNATURE,
83
+ },
84
+ };
85
+ }
@@ -0,0 +1,5 @@
1
+ import { OmniaVtxo, OmniaVtxoPool } from './types.js';
2
+ export declare function serializeVtxo(vtxo: OmniaVtxo): string;
3
+ export declare function deserializeVtxo(json: string): OmniaVtxo;
4
+ export declare function serializePool(pool: OmniaVtxoPool): string;
5
+ export declare function deserializePool(json: string): OmniaVtxoPool;
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.serializeVtxo = serializeVtxo;
4
+ exports.deserializeVtxo = deserializeVtxo;
5
+ exports.serializePool = serializePool;
6
+ exports.deserializePool = deserializePool;
7
+ const BIGINT_PREFIX = '__bigint__:';
8
+ function replacer(_key, value) {
9
+ if (typeof value === 'bigint') {
10
+ return `${BIGINT_PREFIX}${value.toString()}`;
11
+ }
12
+ return value;
13
+ }
14
+ function reviver(_key, value) {
15
+ if (typeof value === 'string' && value.startsWith(BIGINT_PREFIX)) {
16
+ return BigInt(value.slice(BIGINT_PREFIX.length));
17
+ }
18
+ return value;
19
+ }
20
+ function serializeVtxo(vtxo) {
21
+ return JSON.stringify(vtxo, replacer);
22
+ }
23
+ function deserializeVtxo(json) {
24
+ return JSON.parse(json, reviver);
25
+ }
26
+ function serializePool(pool) {
27
+ return JSON.stringify(pool, replacer);
28
+ }
29
+ function deserializePool(json) {
30
+ return JSON.parse(json, reviver);
31
+ }
@@ -0,0 +1,8 @@
1
+ import { OmniaVtxo, SplitVtxoParams, SplitResult, VtxoOperatorReceipt } from './types.js';
2
+ /**
3
+ * Splits a VTXO into multiple outputs.
4
+ * @param now - Timestamp in ms. Defaults to Date.now() if omitted — pass explicitly for determinism.
5
+ */
6
+ export declare function splitVtxo(vtxo: OmniaVtxo, params: SplitVtxoParams, now?: number): SplitResult & {
7
+ receipt: VtxoOperatorReceipt;
8
+ };