@midnight-ntwrk/wallet-sdk-abstractions 2.0.0 → 2.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.
@@ -0,0 +1,27 @@
1
+ import { Schema } from 'effect';
2
+ import { type TransactionHistoryStorage, type TransactionHash, type TransactionHistoryCommon, type SerializedTransactionHistory } from './TransactionHistoryStorage.js';
3
+ /**
4
+ * In-memory implementation of the TransactionHistoryStorage interface.
5
+ *
6
+ * An optional `merge` function can be provided to control how existing and incoming entries are combined during
7
+ * {@link upsert}. When omitted the default behaviour is a shallow spread (`{ ...existing, ...incoming }`).
8
+ *
9
+ * Because the merge runs **synchronously** inside `upsert`, the single-threaded nature of JavaScript guarantees
10
+ * atomicity — no external semaphore is needed.
11
+ */
12
+ export declare class InMemoryTransactionHistoryStorage<T extends {
13
+ hash: TransactionHash;
14
+ } = TransactionHistoryCommon, I = T> implements TransactionHistoryStorage<T> {
15
+ private storage;
16
+ private readonly schema;
17
+ private readonly merge;
18
+ constructor(schema: Schema.Schema<T, I>, merge?: (existing: T, incoming: T) => T);
19
+ upsert(entry: T): Promise<void>;
20
+ getAll(): Promise<readonly T[]>;
21
+ get(hash: TransactionHash): Promise<T | undefined>;
22
+ reset(): void;
23
+ serialize(): Promise<SerializedTransactionHistory>;
24
+ static restore<T extends {
25
+ hash: string;
26
+ }, I>(serialized: SerializedTransactionHistory, schema: Schema.Schema<T, I>, merge?: (existing: T, incoming: T) => T): InMemoryTransactionHistoryStorage<T, I>;
27
+ }
@@ -0,0 +1,60 @@
1
+ // This file is part of MIDNIGHT-WALLET-SDK.
2
+ // Copyright (C) Midnight Foundation
3
+ // SPDX-License-Identifier: Apache-2.0
4
+ // Licensed under the Apache License, Version 2.0 (the "License");
5
+ // You may not use this file except in compliance with the License.
6
+ // You may obtain a copy of the License at
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ // Unless required by applicable law or agreed to in writing, software
9
+ // distributed under the License is distributed on an "AS IS" BASIS,
10
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ // See the License for the specific language governing permissions and
12
+ // limitations under the License.
13
+ import { Schema } from 'effect';
14
+ /**
15
+ * In-memory implementation of the TransactionHistoryStorage interface.
16
+ *
17
+ * An optional `merge` function can be provided to control how existing and incoming entries are combined during
18
+ * {@link upsert}. When omitted the default behaviour is a shallow spread (`{ ...existing, ...incoming }`).
19
+ *
20
+ * Because the merge runs **synchronously** inside `upsert`, the single-threaded nature of JavaScript guarantees
21
+ * atomicity — no external semaphore is needed.
22
+ */
23
+ export class InMemoryTransactionHistoryStorage {
24
+ storage;
25
+ schema;
26
+ merge;
27
+ constructor(schema, merge) {
28
+ this.storage = new Map();
29
+ this.schema = schema;
30
+ this.merge = merge ?? ((existing, incoming) => ({ ...existing, ...incoming }));
31
+ }
32
+ upsert(entry) {
33
+ const existing = this.storage.get(entry.hash);
34
+ this.storage.set(entry.hash, existing ? this.merge(existing, entry) : entry);
35
+ return Promise.resolve();
36
+ }
37
+ getAll() {
38
+ return Array.fromAsync(this.storage.values());
39
+ }
40
+ get(hash) {
41
+ return Promise.resolve(this.storage.get(hash));
42
+ }
43
+ reset() {
44
+ this.storage.clear();
45
+ }
46
+ async serialize() {
47
+ const allEntries = await this.getAll();
48
+ const encode = Schema.encodeSync(Schema.Array(this.schema));
49
+ return JSON.stringify(encode([...allEntries]));
50
+ }
51
+ static restore(serialized, schema, merge) {
52
+ const decode = Schema.decodeUnknownSync(Schema.Array(schema));
53
+ const decoded = decode(JSON.parse(serialized));
54
+ const storage = new InMemoryTransactionHistoryStorage(schema, merge);
55
+ for (const entry of decoded) {
56
+ storage.storage.set(entry.hash, entry);
57
+ }
58
+ return storage;
59
+ }
60
+ }
@@ -0,0 +1,9 @@
1
+ import { type TransactionHistoryStorage, type TransactionHash, type TransactionHistoryCommon, type SerializedTransactionHistory } from './TransactionHistoryStorage.js';
2
+ export declare class NoOpTransactionHistoryStorage<T extends {
3
+ hash: TransactionHash;
4
+ } = TransactionHistoryCommon> implements TransactionHistoryStorage<T> {
5
+ upsert(_entry: T): Promise<void>;
6
+ getAll(): Promise<readonly T[]>;
7
+ get(_hash: TransactionHash): Promise<T | undefined>;
8
+ serialize(): Promise<SerializedTransactionHistory>;
9
+ }
@@ -0,0 +1,14 @@
1
+ export class NoOpTransactionHistoryStorage {
2
+ upsert(_entry) {
3
+ return Promise.resolve();
4
+ }
5
+ getAll() {
6
+ return Promise.resolve([]);
7
+ }
8
+ get(_hash) {
9
+ return Promise.resolve(undefined);
10
+ }
11
+ serialize() {
12
+ return Promise.resolve('[]');
13
+ }
14
+ }
@@ -1,4 +1,4 @@
1
- import * as ProtocolVersion from './ProtocolVersion.js';
1
+ import type * as ProtocolVersion from './ProtocolVersion.js';
2
2
  /**
3
3
  * A type that associates some state with a given version of the Midnight protocol.
4
4
  *
@@ -1,17 +1,11 @@
1
1
  import * as Brand from 'effect/Brand';
2
2
  import * as Schema from 'effect/Schema';
3
- /**
4
- * A branded `bigint` that represents a protocol version.
5
- */
3
+ /** A branded `bigint` that represents a protocol version. */
6
4
  export type ProtocolVersion = Brand.Branded<bigint, 'ProtocolVersion'>;
7
- /**
8
- * Constructs a branded `bigint` represents a protocol version.
9
- */
5
+ /** Constructs a branded `bigint` represents a protocol version. */
10
6
  export declare const ProtocolVersion: Brand.Brand.Constructor<ProtocolVersion>;
11
7
  export declare namespace ProtocolVersion {
12
- /**
13
- * A tuple type that represents a start and ending protocol version.
14
- */
8
+ /** A tuple type that represents a start and ending protocol version. */
15
9
  type Range = readonly [start: ProtocolVersion, end: ProtocolVersion];
16
10
  }
17
11
  /**
@@ -20,9 +14,7 @@ export declare namespace ProtocolVersion {
20
14
  * @param start The start value.
21
15
  * @param end The end value.
22
16
  * @returns A {@link ProtocolVersion.Range} defined by `start` and `end`.
23
- *
24
- * @throws `TypeError`
25
- * Thrown when `start` is after `end`, or the difference between them is less than one.
17
+ * @throws `TypeError` Thrown when `start` is after `end`, or the difference between them is less than one.
26
18
  */
27
19
  export declare const makeRange: (start: ProtocolVersion, end: ProtocolVersion) => ProtocolVersion.Range;
28
20
  /**
@@ -33,9 +25,7 @@ export declare const makeRange: (start: ProtocolVersion, end: ProtocolVersion) =
33
25
  * @returns `true` if `version` is within the range defined by `range`.
34
26
  */
35
27
  export declare const withinRange: (version: ProtocolVersion, range: ProtocolVersion.Range) => boolean;
36
- /**
37
- * A schema that transforms a `bigint` into a {@link ProtocolVersion}.
38
- */
28
+ /** A schema that transforms a `bigint` into a {@link ProtocolVersion}. */
39
29
  export declare const ProtocolVersionSchema: Schema.BrandSchema<bigint & Brand.Brand<"ProtocolVersion">, string, never>;
40
30
  /**
41
31
  * A type predicate that determines if a given value is a {@link ProtocolVersion}.
@@ -44,11 +34,7 @@ export declare const ProtocolVersionSchema: Schema.BrandSchema<bigint & Brand.Br
44
34
  * @returns `true` if `u` has the type {@link ProtocolVersion}.
45
35
  */
46
36
  export declare const is: (u: unknown, overrideOptions?: import("effect/SchemaAST").ParseOptions | number) => u is bigint & Brand.Brand<"ProtocolVersion">;
47
- /**
48
- * Represents the minimum supported protocol version.
49
- */
37
+ /** Represents the minimum supported protocol version. */
50
38
  export declare const MinSupportedVersion: ProtocolVersion;
51
- /**
52
- * Represents the maximum supported protocol version.
53
- */
39
+ /** Represents the maximum supported protocol version. */
54
40
  export declare const MaxSupportedVersion: ProtocolVersion;
@@ -12,9 +12,7 @@
12
12
  // limitations under the License.
13
13
  import * as Brand from 'effect/Brand';
14
14
  import * as Schema from 'effect/Schema';
15
- /**
16
- * Constructs a branded `bigint` represents a protocol version.
17
- */
15
+ /** Constructs a branded `bigint` represents a protocol version. */
18
16
  export const ProtocolVersion = Brand.nominal();
19
17
  /**
20
18
  * Creates a new protocol version range.
@@ -22,9 +20,7 @@ export const ProtocolVersion = Brand.nominal();
22
20
  * @param start The start value.
23
21
  * @param end The end value.
24
22
  * @returns A {@link ProtocolVersion.Range} defined by `start` and `end`.
25
- *
26
- * @throws `TypeError`
27
- * Thrown when `start` is after `end`, or the difference between them is less than one.
23
+ * @throws `TypeError` Thrown when `start` is after `end`, or the difference between them is less than one.
28
24
  */
29
25
  // TODO: make it possible to represent an open range on the end side to remove special "MaxSupportedVersion"
30
26
  export const makeRange = (start, end) => {
@@ -43,9 +39,7 @@ export const withinRange = (version, range) => {
43
39
  const [min, max] = range;
44
40
  return version >= min && version < max;
45
41
  };
46
- /**
47
- * A schema that transforms a `bigint` into a {@link ProtocolVersion}.
48
- */
42
+ /** A schema that transforms a `bigint` into a {@link ProtocolVersion}. */
49
43
  export const ProtocolVersionSchema = Schema.BigInt.pipe(Schema.fromBrand(ProtocolVersion));
50
44
  /**
51
45
  * A type predicate that determines if a given value is a {@link ProtocolVersion}.
@@ -54,11 +48,7 @@ export const ProtocolVersionSchema = Schema.BigInt.pipe(Schema.fromBrand(Protoco
54
48
  * @returns `true` if `u` has the type {@link ProtocolVersion}.
55
49
  */
56
50
  export const is = Schema.is(ProtocolVersionSchema);
57
- /**
58
- * Represents the minimum supported protocol version.
59
- */
51
+ /** Represents the minimum supported protocol version. */
60
52
  export const MinSupportedVersion = ProtocolVersion(0n);
61
- /**
62
- * Represents the maximum supported protocol version.
63
- */
53
+ /** Represents the maximum supported protocol version. */
64
54
  export const MaxSupportedVersion = ProtocolVersion(BigInt(Number.MAX_SAFE_INTEGER));
@@ -1,11 +1,7 @@
1
1
  import * as Brand from 'effect/Brand';
2
- /**
3
- * A branded `Uint8Array` representing serialized transaction data.
4
- */
2
+ /** A branded `Uint8Array` representing serialized transaction data. */
5
3
  export type SerializedTransaction = Brand.Branded<Uint8Array, 'SerializedTransaction'>;
6
- /**
7
- * Constructs a branded `Uint8Array` representing serialized transaction data.
8
- */
4
+ /** Constructs a branded `Uint8Array` representing serialized transaction data. */
9
5
  export declare const SerializedTransaction: Brand.Brand.Constructor<SerializedTransaction>;
10
6
  export declare const of: (serialized: Uint8Array) => SerializedTransaction;
11
7
  export declare const from: <T extends {
@@ -11,9 +11,7 @@
11
11
  // See the License for the specific language governing permissions and
12
12
  // limitations under the License.
13
13
  import * as Brand from 'effect/Brand';
14
- /**
15
- * Constructs a branded `Uint8Array` representing serialized transaction data.
16
- */
14
+ /** Constructs a branded `Uint8Array` representing serialized transaction data. */
17
15
  export const SerializedTransaction = Brand.nominal();
18
16
  export const of = (serialized) => {
19
17
  return SerializedTransaction(serialized);
@@ -0,0 +1,33 @@
1
+ import { Schema } from 'effect';
2
+ export declare const TransactionHashSchema: typeof Schema.String;
3
+ export type TransactionHash = Schema.Schema.Type<typeof TransactionHashSchema>;
4
+ export declare const TransactionHistoryStatusSchema: Schema.Literal<["SUCCESS", "FAILURE", "PARTIAL_SUCCESS"]>;
5
+ export type TransactionHistoryStatus = Schema.Schema.Type<typeof TransactionHistoryStatusSchema>;
6
+ export declare const TransactionHistoryCommonSchema: Schema.Struct<{
7
+ hash: typeof Schema.String;
8
+ protocolVersion: typeof Schema.Number;
9
+ status: Schema.Literal<["SUCCESS", "FAILURE", "PARTIAL_SUCCESS"]>;
10
+ identifiers: Schema.optional<Schema.Array$<typeof Schema.String>>;
11
+ timestamp: Schema.optional<typeof Schema.Date>;
12
+ fees: Schema.optional<Schema.NullOr<typeof Schema.BigInt>>;
13
+ }>;
14
+ export type TransactionHistoryCommon = Schema.Schema.Type<typeof TransactionHistoryCommonSchema>;
15
+ export type SerializedTransactionHistory = string;
16
+ /**
17
+ * An entry with common fields plus any additional properties (wallet sections). Used by wallet packages for
18
+ * projection/filtering when the exact type is not known.
19
+ */
20
+ export type TransactionHistoryEntryWithHash = TransactionHistoryCommon & Record<string, unknown>;
21
+ /**
22
+ * Storage interface for transaction history entries keyed by their `hash` property.
23
+ *
24
+ * Pass a full entry schema to the implementation constructor to enable serialization.
25
+ */
26
+ export interface TransactionHistoryStorage<T extends {
27
+ hash: TransactionHash;
28
+ } = TransactionHistoryCommon> {
29
+ upsert(entry: T): Promise<void>;
30
+ getAll(): Promise<readonly T[]>;
31
+ get(hash: TransactionHash): Promise<T | undefined>;
32
+ serialize(): Promise<SerializedTransactionHistory>;
33
+ }
@@ -0,0 +1,23 @@
1
+ // This file is part of MIDNIGHT-WALLET-SDK.
2
+ // Copyright (C) Midnight Foundation
3
+ // SPDX-License-Identifier: Apache-2.0
4
+ // Licensed under the Apache License, Version 2.0 (the "License");
5
+ // You may not use this file except in compliance with the License.
6
+ // You may obtain a copy of the License at
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ // Unless required by applicable law or agreed to in writing, software
9
+ // distributed under the License is distributed on an "AS IS" BASIS,
10
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ // See the License for the specific language governing permissions and
12
+ // limitations under the License.
13
+ import { Schema } from 'effect';
14
+ export const TransactionHashSchema = Schema.String;
15
+ export const TransactionHistoryStatusSchema = Schema.Literal('SUCCESS', 'FAILURE', 'PARTIAL_SUCCESS');
16
+ export const TransactionHistoryCommonSchema = Schema.Struct({
17
+ hash: TransactionHashSchema,
18
+ protocolVersion: Schema.Number,
19
+ status: TransactionHistoryStatusSchema,
20
+ identifiers: Schema.optional(Schema.Array(Schema.String)),
21
+ timestamp: Schema.optional(Schema.Date),
22
+ fees: Schema.optional(Schema.NullOr(Schema.BigInt)),
23
+ });
@@ -1,16 +1,10 @@
1
1
  import * as Brand from 'effect/Brand';
2
2
  import * as Schema from 'effect/Schema';
3
- /**
4
- * A branded `Uint8Array` that represents a BIP32 compatible seed phrase.
5
- */
3
+ /** A branded `Uint8Array` that represents a BIP32 compatible seed phrase. */
6
4
  export type WalletSeed = Brand.Branded<Uint8Array, 'WalletSeed'>;
7
- /**
8
- * Constructs a branded `Uint8Array` representing a BIP32 compatible seed phrase.
9
- */
5
+ /** Constructs a branded `Uint8Array` representing a BIP32 compatible seed phrase. */
10
6
  export declare const WalletSeed: Brand.Brand.Constructor<WalletSeed>;
11
- /**
12
- * A schema that transforms an array of numbers into a {@link WalletSeed}.
13
- */
7
+ /** A schema that transforms an array of numbers into a {@link WalletSeed}. */
14
8
  export declare const WalletSeedSchema: Schema.BrandSchema<Uint8Array<ArrayBufferLike> & Uint8Array<ArrayBufferLike> & Brand.Brand<"WalletSeed">, readonly number[], never>;
15
9
  /**
16
10
  * A type predicate that determines if a given value is a {@link WalletSeed}.
@@ -12,13 +12,9 @@
12
12
  // limitations under the License.
13
13
  import * as Brand from 'effect/Brand';
14
14
  import * as Schema from 'effect/Schema';
15
- /**
16
- * Constructs a branded `Uint8Array` representing a BIP32 compatible seed phrase.
17
- */
15
+ /** Constructs a branded `Uint8Array` representing a BIP32 compatible seed phrase. */
18
16
  export const WalletSeed = Brand.nominal();
19
- /**
20
- * A schema that transforms an array of numbers into a {@link WalletSeed}.
21
- */
17
+ /** A schema that transforms an array of numbers into a {@link WalletSeed}. */
22
18
  export const WalletSeedSchema = Schema.Uint8Array.pipe(Schema.fromBrand(WalletSeed));
23
19
  /**
24
20
  * A type predicate that determines if a given value is a {@link WalletSeed}.
@@ -1,17 +1,13 @@
1
1
  import * as Brand from 'effect/Brand';
2
2
  import * as Schema from 'effect/Schema';
3
3
  /**
4
- * A branded `string` representing serialized (JSON) wallet state made up of local state, transaction history,
5
- * and block height.
4
+ * A branded `string` representing serialized (JSON) wallet state made up of local state, transaction history, and block
5
+ * height.
6
6
  */
7
7
  export type WalletState = Brand.Branded<string, 'WalletState'>;
8
- /**
9
- * Constructs a branded `string` representing serialized (JSON) wallet state.
10
- */
8
+ /** Constructs a branded `string` representing serialized (JSON) wallet state. */
11
9
  export declare const WalletState: Brand.Brand.Constructor<WalletState>;
12
- /**
13
- * A schema that transforms a string into a {@link WalletState}.
14
- */
10
+ /** A schema that transforms a string into a {@link WalletState}. */
15
11
  export declare const WalletStateSchema: Schema.BrandSchema<string & Brand.Brand<"WalletState">, string, never>;
16
12
  /**
17
13
  * A type predicate that determines if a given value is a {@link WalletState}.
@@ -12,13 +12,9 @@
12
12
  // limitations under the License.
13
13
  import * as Brand from 'effect/Brand';
14
14
  import * as Schema from 'effect/Schema';
15
- /**
16
- * Constructs a branded `string` representing serialized (JSON) wallet state.
17
- */
15
+ /** Constructs a branded `string` representing serialized (JSON) wallet state. */
18
16
  export const WalletState = Brand.nominal();
19
- /**
20
- * A schema that transforms a string into a {@link WalletState}.
21
- */
17
+ /** A schema that transforms a string into a {@link WalletState}. */
22
18
  export const WalletStateSchema = Schema.String.pipe(Schema.fromBrand(WalletState));
23
19
  /**
24
20
  * A type predicate that determines if a given value is a {@link WalletState}.
package/dist/index.d.ts CHANGED
@@ -5,3 +5,6 @@ export * as ProtocolState from './ProtocolState.js';
5
5
  export * as ProtocolVersion from './ProtocolVersion.js';
6
6
  export * as NetworkId from './NetworkId.js';
7
7
  export * as SyncProgress from './SyncProgress.js';
8
+ export * from './InMemoryTransactionHistoryStorage.js';
9
+ export * from './NoOpTransactionHistoryStorage.js';
10
+ export * as TransactionHistoryStorage from './TransactionHistoryStorage.js';
package/dist/index.js CHANGED
@@ -17,3 +17,6 @@ export * as ProtocolState from './ProtocolState.js';
17
17
  export * as ProtocolVersion from './ProtocolVersion.js';
18
18
  export * as NetworkId from './NetworkId.js';
19
19
  export * as SyncProgress from './SyncProgress.js';
20
+ export * from './InMemoryTransactionHistoryStorage.js';
21
+ export * from './NoOpTransactionHistoryStorage.js';
22
+ export * as TransactionHistoryStorage from './TransactionHistoryStorage.js';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@midnight-ntwrk/wallet-sdk-abstractions",
3
3
  "description": "Domain-specific abstractions for the wallet SDK",
4
- "version": "2.0.0",
4
+ "version": "2.1.0",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
7
7
  "module": "./dist/index.js",