@midnight-ntwrk/wallet-sdk-node-client 1.0.0-beta.10

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,21 @@
1
+ import { Context, Effect, Stream } from 'effect';
2
+ import * as SubmissionEvent from './SubmissionEvent.js';
3
+ import * as NodeClientError from './NodeClientError.js';
4
+ export type SerializedMnTransaction = Uint8Array;
5
+ export type Genesis = {
6
+ readonly transactions: readonly SerializedMnTransaction[];
7
+ };
8
+ export interface Service {
9
+ sendMidnightTransaction(serializedTransaction: SerializedMnTransaction): Stream.Stream<SubmissionEvent.SubmissionEvent, NodeClientError.NodeClientError>;
10
+ getGenesis(): Effect.Effect<Genesis, NodeClientError.NodeClientError>;
11
+ }
12
+ declare const NodeClient_base: Context.TagClass<NodeClient, "@midnight-ntwrk/wallet-node-client#NodeClient", Service>;
13
+ export declare class NodeClient extends NodeClient_base {
14
+ }
15
+ export declare const getGenesisTransactions: () => Effect.Effect<Genesis, NodeClientError.NodeClientError, NodeClient>;
16
+ export declare const sendMidnightTransaction: (serializedTransaction: SerializedMnTransaction) => Stream.Stream<SubmissionEvent.SubmissionEvent, NodeClientError.NodeClientError, NodeClient>;
17
+ export declare function sendMidnightTransactionAndWait(serializedTransaction: SerializedMnTransaction, waitFor: SubmissionEvent.Cases.Submitted['_tag']): Effect.Effect<SubmissionEvent.Cases.Submitted, NodeClientError.NodeClientError, NodeClient>;
18
+ export declare function sendMidnightTransactionAndWait(serializedTransaction: SerializedMnTransaction, waitFor: SubmissionEvent.Cases.InBlock['_tag']): Effect.Effect<SubmissionEvent.Cases.InBlock, NodeClientError.NodeClientError, NodeClient>;
19
+ export declare function sendMidnightTransactionAndWait(serializedTransaction: SerializedMnTransaction, waitFor: SubmissionEvent.Cases.Finalized['_tag']): Effect.Effect<SubmissionEvent.Cases.Finalized, NodeClientError.NodeClientError, NodeClient>;
20
+ export declare function sendMidnightTransactionAndWait(serializedTransaction: SerializedMnTransaction, waitFor: SubmissionEvent.SubmissionEvent['_tag']): Effect.Effect<SubmissionEvent.SubmissionEvent, NodeClientError.NodeClientError, NodeClient>;
21
+ export {};
@@ -0,0 +1,29 @@
1
+ // This file is part of MIDNIGHT-WALLET-SDK.
2
+ // Copyright (C) 2025 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 { Context, Effect, Option, Stream } from 'effect';
14
+ import * as SubmissionEvent from './SubmissionEvent.js';
15
+ import * as NodeClientError from './NodeClientError.js';
16
+ export class NodeClient extends Context.Tag('@midnight-ntwrk/wallet-node-client#NodeClient')() {
17
+ }
18
+ export const getGenesisTransactions = () => NodeClient.pipe(Effect.flatMap((client) => client.getGenesis()));
19
+ export const sendMidnightTransaction = (serializedTransaction) => NodeClient.pipe(Stream.fromEffect, Stream.flatMap((client) => client.sendMidnightTransaction(serializedTransaction)));
20
+ export function sendMidnightTransactionAndWait(serializedTransaction, waitFor) {
21
+ return sendMidnightTransaction(serializedTransaction).pipe(Stream.find(SubmissionEvent.is(waitFor)), Stream.runHead, Effect.flatMap(Option.match({
22
+ onNone: () => Effect.fail(new NodeClientError.TransactionProgressError({
23
+ message: 'Transaction did not reach desired stage and no other error was reported',
24
+ txData: serializedTransaction,
25
+ desiredStage: waitFor,
26
+ })),
27
+ onSome: (event) => Effect.succeed(event),
28
+ })));
29
+ }
@@ -0,0 +1,62 @@
1
+ import { SubmissionEvent } from './SubmissionEvent.js';
2
+ declare const SubmissionError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => import("effect/Cause").YieldableError & {
3
+ readonly _tag: "SubmissionError";
4
+ } & Readonly<A>;
5
+ export declare class SubmissionError extends SubmissionError_base<{
6
+ message: string;
7
+ txData: Uint8Array;
8
+ cause?: unknown;
9
+ }> {
10
+ }
11
+ declare const ConnectionError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => import("effect/Cause").YieldableError & {
12
+ readonly _tag: "ConnectionError";
13
+ } & Readonly<A>;
14
+ export declare class ConnectionError extends ConnectionError_base<{
15
+ message: string;
16
+ cause?: unknown;
17
+ }> {
18
+ }
19
+ declare const TransactionProgressError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => import("effect/Cause").YieldableError & {
20
+ readonly _tag: "TransactionProgressError";
21
+ } & Readonly<A>;
22
+ export declare class TransactionProgressError extends TransactionProgressError_base<{
23
+ message: string;
24
+ txData: Uint8Array;
25
+ desiredStage: SubmissionEvent['_tag'];
26
+ }> {
27
+ }
28
+ declare const ParseError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => import("effect/Cause").YieldableError & {
29
+ readonly _tag: "ParseError";
30
+ } & Readonly<A>;
31
+ export declare class ParseError extends ParseError_base<{
32
+ message: string;
33
+ cause?: unknown;
34
+ }> {
35
+ }
36
+ declare const TransactionUsurpedError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => import("effect/Cause").YieldableError & {
37
+ readonly _tag: "TransactionUsurpedError";
38
+ } & Readonly<A>;
39
+ export declare class TransactionUsurpedError extends TransactionUsurpedError_base<{
40
+ message: string;
41
+ txData: Uint8Array;
42
+ }> {
43
+ }
44
+ declare const TransactionDroppedError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => import("effect/Cause").YieldableError & {
45
+ readonly _tag: "TransactionDroppedError";
46
+ } & Readonly<A>;
47
+ export declare class TransactionDroppedError extends TransactionDroppedError_base<{
48
+ message: string;
49
+ txData: Uint8Array;
50
+ }> {
51
+ }
52
+ declare const TransactionInvalidError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => import("effect/Cause").YieldableError & {
53
+ readonly _tag: "TransactionInvalidError";
54
+ } & Readonly<A>;
55
+ export declare class TransactionInvalidError extends TransactionInvalidError_base<{
56
+ message: string;
57
+ txData: Uint8Array;
58
+ cause?: unknown;
59
+ }> {
60
+ }
61
+ export type NodeClientError = SubmissionError | ConnectionError | TransactionProgressError | ParseError | TransactionUsurpedError | TransactionDroppedError | TransactionInvalidError;
62
+ export {};
@@ -0,0 +1,27 @@
1
+ // This file is part of MIDNIGHT-WALLET-SDK.
2
+ // Copyright (C) 2025 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 { Data } from 'effect';
14
+ export class SubmissionError extends Data.TaggedError('SubmissionError') {
15
+ }
16
+ export class ConnectionError extends Data.TaggedError('ConnectionError') {
17
+ }
18
+ export class TransactionProgressError extends Data.TaggedError('TransactionProgressError') {
19
+ }
20
+ export class ParseError extends Data.TaggedError('ParseError') {
21
+ }
22
+ export class TransactionUsurpedError extends Data.TaggedError('TransactionUsurpedError') {
23
+ }
24
+ export class TransactionDroppedError extends Data.TaggedError('TransactionDroppedError') {
25
+ }
26
+ export class TransactionInvalidError extends Data.TaggedError('TransactionInvalidError') {
27
+ }
@@ -0,0 +1,29 @@
1
+ import '../gen/augment-api.js';
2
+ import { ApiPromise } from '@polkadot/api';
3
+ import { Duration, Effect, Layer, Scope, Stream } from 'effect';
4
+ import * as NodeClient from './NodeClient.js';
5
+ import * as SubmissionEvent from './SubmissionEvent.js';
6
+ import * as NodeClientError from './NodeClientError.js';
7
+ export type Config = {
8
+ nodeURL: URL;
9
+ reconnectionTimeout: Duration.Duration;
10
+ reconnectionDelay: Duration.Duration;
11
+ };
12
+ export declare const DEFAULT_CONFIG: {
13
+ reconnectionTimeout: Duration.Duration;
14
+ reconnectionDelay: Duration.Duration;
15
+ };
16
+ export declare const makeConfig: (input: Partial<Config> & Pick<Config, "nodeURL">) => Config;
17
+ export declare class PolkadotNodeClient implements NodeClient.Service {
18
+ #private;
19
+ static make(configInput: Partial<Config> & Pick<Config, 'nodeURL'>): Effect.Effect<PolkadotNodeClient, NodeClientError.NodeClientError, Scope.Scope>;
20
+ static layer(configInput: Partial<Config> & Pick<Config, 'nodeURL'>): Layer.Layer<NodeClient.NodeClient, NodeClientError.NodeClientError, Scope.Scope>;
21
+ readonly config: Config;
22
+ readonly api: ApiPromise;
23
+ constructor(config: Config, api: ApiPromise);
24
+ ensureConnection(): Effect.Effect<void, NodeClientError.NodeClientError>;
25
+ sendMidnightTransaction(serializedTransaction: NodeClient.SerializedMnTransaction): Stream.Stream<SubmissionEvent.SubmissionEvent, NodeClientError.NodeClientError>;
26
+ getGenesis(): Effect.Effect<{
27
+ readonly transactions: readonly NodeClient.SerializedMnTransaction[];
28
+ }, NodeClientError.NodeClientError>;
29
+ }
@@ -0,0 +1,171 @@
1
+ // This file is part of MIDNIGHT-WALLET-SDK.
2
+ // Copyright (C) 2025 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 '../gen/augment-api.js';
14
+ import { ApiPromise, WsProvider } from '@polkadot/api';
15
+ import { Duration, Effect, Either, Layer, pipe, Schedule, Schema, Stream, } from 'effect';
16
+ import * as NodeClient from './NodeClient.js';
17
+ import * as SubmissionEvent from './SubmissionEvent.js';
18
+ import * as NodeClientError from './NodeClientError.js';
19
+ import BN from 'bn.js';
20
+ import { u8aToHex } from '@polkadot/util';
21
+ export const DEFAULT_CONFIG = {
22
+ reconnectionTimeout: Duration.infinity,
23
+ reconnectionDelay: Duration.seconds(1),
24
+ };
25
+ export const makeConfig = (input) => ({
26
+ ...DEFAULT_CONFIG,
27
+ ...input,
28
+ });
29
+ export class PolkadotNodeClient {
30
+ static make(configInput) {
31
+ const config = makeConfig(configInput);
32
+ return Effect.acquireRelease(Effect.promise(() => ApiPromise.create({
33
+ // @ts-expect-error -- exactOptionalPropertyTypes cause an incompatibility here
34
+ provider: new WsProvider(config.nodeURL.toString()),
35
+ throwOnConnect: false,
36
+ noInitWarn: true,
37
+ })), (api) => Effect.promise(() => api.disconnect())).pipe(Effect.map((api) => new PolkadotNodeClient(config, api)));
38
+ }
39
+ static layer(configInput) {
40
+ return Layer.effect(NodeClient.NodeClient, PolkadotNodeClient.make(configInput));
41
+ }
42
+ config;
43
+ api;
44
+ constructor(config, api) {
45
+ this.config = config;
46
+ this.api = api;
47
+ }
48
+ ensureConnection() {
49
+ return pipe(Effect.promise(async () => {
50
+ if (!this.api.isConnected) {
51
+ await this.api.connect();
52
+ }
53
+ }), Effect.andThen(Effect.sync(() => this.api.isConnected)), Effect.repeat({
54
+ until: (value) => value,
55
+ schedule: Schedule.spaced(this.config.reconnectionDelay),
56
+ }), Effect.timeout(this.config.reconnectionTimeout), Effect.asVoid, Effect.mapError((timeout) => new NodeClientError.ConnectionError({
57
+ message: 'Could not connect within specified time range (5s)',
58
+ cause: timeout,
59
+ })));
60
+ }
61
+ sendMidnightTransaction(serializedTransaction) {
62
+ const outputStream = Stream.async((emit) => {
63
+ const callUnsubscribe = () => unsubscribeP.then((thunk) => thunk());
64
+ const unsubscribeP = this.api.tx.midnight
65
+ .sendMnTransaction(u8aToHex(serializedTransaction))
66
+ .send(this.#handleSubmissionResult(serializedTransaction, emit, callUnsubscribe))
67
+ .catch((err) => {
68
+ return emit
69
+ .fail(new NodeClientError.SubmissionError({
70
+ message: 'Transaction submission failed',
71
+ txData: serializedTransaction,
72
+ cause: err,
73
+ }))
74
+ .then(() => () => { });
75
+ });
76
+ return Effect.promise(callUnsubscribe);
77
+ });
78
+ return pipe(Stream.fromEffect(this.ensureConnection()), Stream.flatMap(() => outputStream));
79
+ }
80
+ getGenesis() {
81
+ return Effect.promise(() => this.api.rpc.chain.getBlock(this.api.genesisHash)).pipe(Effect.map((block) => {
82
+ // https://polkadot.js.org/docs/api/cookbook/blocks/#how-do-i-view-extrinsic-information
83
+ return {
84
+ transactions: block.block.extrinsics
85
+ .filter((extrinsic) => extrinsic.method.section === 'midnight' && extrinsic.method.method === 'sendMnTransaction')
86
+ .map((extrinsic) => extrinsic.method.args[0].toU8a()),
87
+ };
88
+ }), Effect.mapError((error) => new NodeClientError.ConnectionError({
89
+ message: 'Failed to retrieve genesis transactions',
90
+ cause: error,
91
+ })));
92
+ }
93
+ #handleSubmissionResult = (serializedTransaction, emit, unsubscribe) => {
94
+ const WithBNBlockNumber = Schema.Struct({
95
+ blockNumber: Schema.instanceOf(BN),
96
+ });
97
+ const emitParseError = (error) => emit.fail(new NodeClientError.ParseError({
98
+ message: 'Failed to parse result provided by node',
99
+ cause: error,
100
+ }));
101
+ const decodeBlockNumber = Schema.decodeUnknownEither(WithBNBlockNumber, {
102
+ errors: 'all',
103
+ onExcessProperty: 'ignore',
104
+ });
105
+ return async (result) => {
106
+ //Here's a detailed documentation about the result: https://github.com/paritytech/polkadot-sdk/blob/9b4cfe66188aa6f4408ca0463d373f0121bc1a8c/substrate/client/transaction-pool/api/src/lib.rs#L132
107
+ const status = result.status;
108
+ if (status.isReady || status.isFuture || status.isBroadcast || status.isRetracted) {
109
+ // The retracted status means the original block was rolled back, so transaction went back to mempool
110
+ await emit.single(SubmissionEvent.Submitted({ tx: serializedTransaction, txHash: result.txHash.toString() }));
111
+ }
112
+ else if (status.isInBlock) {
113
+ await pipe(decodeBlockNumber(result), Either.match({
114
+ onLeft: emitParseError,
115
+ onRight: (parsed) => {
116
+ return emit.single(SubmissionEvent.InBlock({
117
+ tx: serializedTransaction,
118
+ blockHash: status.asInBlock.toString(),
119
+ blockHeight: BigInt(parsed.blockNumber.toString(10)),
120
+ txHash: result.txHash.toString(),
121
+ }));
122
+ },
123
+ }));
124
+ }
125
+ else if (status.isFinalized) {
126
+ await pipe(decodeBlockNumber(result), Either.match({
127
+ onLeft: emitParseError,
128
+ onRight: (parsed) => {
129
+ return emit.single(SubmissionEvent.Finalized({
130
+ tx: serializedTransaction,
131
+ blockHash: status.asFinalized.toString(),
132
+ blockHeight: BigInt(parsed.blockNumber.toString(10)),
133
+ txHash: result.txHash.toString(),
134
+ }));
135
+ },
136
+ }));
137
+ await emit.end();
138
+ await unsubscribe();
139
+ }
140
+ else if (status.isFinalityTimeout) {
141
+ await emit.fail(new NodeClientError.TransactionProgressError({
142
+ message: 'Transaction did not reach finality within expected time, likely consensus issues arised',
143
+ desiredStage: 'Finalized',
144
+ txData: serializedTransaction,
145
+ }));
146
+ await unsubscribe();
147
+ }
148
+ else if (status.isUsurped) {
149
+ await emit.fail(new NodeClientError.TransactionUsurpedError({
150
+ message: 'Transaction got usurped (replaced by another one matching its discriminators like sender or nonce)',
151
+ txData: serializedTransaction,
152
+ }));
153
+ await unsubscribe();
154
+ }
155
+ else if (status.isDropped) {
156
+ await emit.fail(new NodeClientError.TransactionDroppedError({
157
+ message: 'Transaction got dropped, the mempool likely is full and network congested',
158
+ txData: serializedTransaction,
159
+ }));
160
+ await unsubscribe();
161
+ }
162
+ else if (status.isInvalid) {
163
+ await emit.fail(new NodeClientError.TransactionInvalidError({
164
+ message: 'Transaction got dropped, the mempool likely is full and network congested',
165
+ txData: serializedTransaction,
166
+ }));
167
+ await unsubscribe();
168
+ }
169
+ };
170
+ };
171
+ }
@@ -0,0 +1,43 @@
1
+ import { Data } from 'effect';
2
+ import { SerializedMnTransaction } from './NodeClient.js';
3
+ export type HexString = string;
4
+ export type SubmissionEvent = Cases.Submitted | Cases.InBlock | Cases.Finalized;
5
+ export declare const Submitted: Data.Case.Constructor<Cases.Submitted, "_tag">, InBlock: Data.Case.Constructor<Cases.InBlock, "_tag">, Finalized: Data.Case.Constructor<Cases.Finalized, "_tag">, match: {
6
+ <const Cases extends {
7
+ readonly Submitted: (args: Cases.Submitted) => any;
8
+ readonly InBlock: (args: Cases.InBlock) => any;
9
+ readonly Finalized: (args: Cases.Finalized) => any;
10
+ }>(cases: Cases & { [K in Exclude<keyof Cases, "Submitted" | "InBlock" | "Finalized">]: never; }): (value: SubmissionEvent) => import("effect/Unify").Unify<ReturnType<Cases["Submitted" | "InBlock" | "Finalized"]>>;
11
+ <const Cases extends {
12
+ readonly Submitted: (args: Cases.Submitted) => any;
13
+ readonly InBlock: (args: Cases.InBlock) => any;
14
+ readonly Finalized: (args: Cases.Finalized) => any;
15
+ }>(value: SubmissionEvent, cases: Cases & { [K in Exclude<keyof Cases, "Submitted" | "InBlock" | "Finalized">]: never; }): import("effect/Unify").Unify<ReturnType<Cases["Submitted" | "InBlock" | "Finalized"]>>;
16
+ }, is: <Tag extends "Submitted" | "InBlock" | "Finalized">(tag: Tag) => (u: unknown) => u is Extract<Cases.Submitted, {
17
+ readonly _tag: Tag;
18
+ }> | Extract<Cases.InBlock, {
19
+ readonly _tag: Tag;
20
+ }> | Extract<Cases.Finalized, {
21
+ readonly _tag: Tag;
22
+ }>;
23
+ export declare namespace Cases {
24
+ type Submitted = {
25
+ _tag: 'Submitted';
26
+ tx: SerializedMnTransaction;
27
+ txHash: HexString;
28
+ };
29
+ type InBlock = {
30
+ _tag: 'InBlock';
31
+ blockHash: HexString;
32
+ blockHeight: bigint;
33
+ tx: SerializedMnTransaction;
34
+ txHash: HexString;
35
+ };
36
+ type Finalized = {
37
+ _tag: 'Finalized';
38
+ blockHash: HexString;
39
+ blockHeight: bigint;
40
+ tx: SerializedMnTransaction;
41
+ txHash: HexString;
42
+ };
43
+ }
@@ -0,0 +1,14 @@
1
+ // This file is part of MIDNIGHT-WALLET-SDK.
2
+ // Copyright (C) 2025 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 { Data } from 'effect';
14
+ export const { Submitted, InBlock, Finalized, $match: match, $is: is } = Data.taggedEnum();
@@ -0,0 +1,4 @@
1
+ export * as NodeClient from './NodeClient.js';
2
+ export * from './PolkadotNodeClient.js';
3
+ export * as SubmissionEvent from './SubmissionEvent.js';
4
+ export * as NodeClientError from './NodeClientError.js';
@@ -0,0 +1,16 @@
1
+ // This file is part of MIDNIGHT-WALLET-SDK.
2
+ // Copyright (C) 2025 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
+ export * as NodeClient from './NodeClient.js';
14
+ export * from './PolkadotNodeClient.js';
15
+ export * as SubmissionEvent from './SubmissionEvent.js';
16
+ export * as NodeClientError from './NodeClientError.js';
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Auto-generated with scripts/generate-types.ts
3
+ * Then manually modified to only expose types and endpoints of interest
4
+ */
5
+ import '@polkadot/api-base/types/errors';
6
+ import type { ApiTypes, AugmentedError } from '@polkadot/api-base/types';
7
+ export type __AugmentedError<ApiType extends ApiTypes> = AugmentedError<ApiType>;
8
+ declare module '@polkadot/api-base/types/errors' {
9
+ interface AugmentedErrors<ApiType extends ApiTypes> {
10
+ midnight: {
11
+ ContractCallCostError: AugmentedError<ApiType>;
12
+ Deserialization: AugmentedError<ApiType>;
13
+ LedgerCacheError: AugmentedError<ApiType>;
14
+ LedgerStateScaleDecodingError: AugmentedError<ApiType>;
15
+ NewStateOutOfBounds: AugmentedError<ApiType>;
16
+ NoLedgerState: AugmentedError<ApiType>;
17
+ Serialization: AugmentedError<ApiType>;
18
+ Transaction: AugmentedError<ApiType>;
19
+ };
20
+ }
21
+ }
@@ -0,0 +1,20 @@
1
+ // This file is part of MIDNIGHT-WALLET-SDK.
2
+ // Copyright (C) 2025 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
+ /* eslint-disable */
14
+ /**
15
+ * Auto-generated with scripts/generate-types.ts
16
+ * Then manually modified to only expose types and endpoints of interest
17
+ */
18
+ // import type lookup before we augment - in some environments
19
+ // this is required to allow for ambient/previous definitions
20
+ import '@polkadot/api-base/types/errors';
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Auto-generated with scripts/generate-types.ts
3
+ * Then manually modified to only expose types and endpoints of interest
4
+ */
5
+ import '@polkadot/api-base/types/storage';
6
+ import type { ApiTypes, AugmentedQuery, QueryableStorageEntry } from '@polkadot/api-base/types';
7
+ import type { Bytes, Option } from '@polkadot/types-codec';
8
+ import type { Observable } from '@polkadot/types/types';
9
+ export type __AugmentedQuery<ApiType extends ApiTypes> = AugmentedQuery<ApiType, () => unknown>;
10
+ export type __QueryableStorageEntry<ApiType extends ApiTypes> = QueryableStorageEntry<ApiType>;
11
+ declare module '@polkadot/api-base/types/storage' {
12
+ interface AugmentedQueries<ApiType extends ApiTypes> {
13
+ midnight: {
14
+ networkId: AugmentedQuery<ApiType, () => Observable<Option<Bytes>>, []>;
15
+ stateKey: AugmentedQuery<ApiType, () => Observable<Option<Bytes>>, []>;
16
+ };
17
+ }
18
+ }
@@ -0,0 +1,20 @@
1
+ // This file is part of MIDNIGHT-WALLET-SDK.
2
+ // Copyright (C) 2025 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
+ /* eslint-disable */
14
+ /**
15
+ * Auto-generated with scripts/generate-types.ts
16
+ * Then manually modified to only expose types and endpoints of interest
17
+ */
18
+ // import type lookup before we augment - in some environments
19
+ // this is required to allow for ambient/previous definitions
20
+ import '@polkadot/api-base/types/storage';
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Auto-generated with scripts/generate-types.ts
3
+ * Then manually modified to only expose types and endpoints of interest
4
+ */
5
+ import '@polkadot/api-base/types/submittable';
6
+ import type { ApiTypes, AugmentedSubmittable, SubmittableExtrinsic, SubmittableExtrinsicFunction } from '@polkadot/api-base/types';
7
+ import type { Bytes } from '@polkadot/types-codec';
8
+ export type __AugmentedSubmittable = AugmentedSubmittable<() => unknown>;
9
+ export type __SubmittableExtrinsic<ApiType extends ApiTypes> = SubmittableExtrinsic<ApiType>;
10
+ export type __SubmittableExtrinsicFunction<ApiType extends ApiTypes> = SubmittableExtrinsicFunction<ApiType>;
11
+ declare module '@polkadot/api-base/types/submittable' {
12
+ interface AugmentedSubmittables<ApiType extends ApiTypes> {
13
+ midnight: {
14
+ sendMnTransaction: AugmentedSubmittable<(midnightTx: Bytes | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [
15
+ Bytes
16
+ ]>;
17
+ };
18
+ }
19
+ }
@@ -0,0 +1,20 @@
1
+ // This file is part of MIDNIGHT-WALLET-SDK.
2
+ // Copyright (C) 2025 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
+ /* eslint-disable */
14
+ /**
15
+ * Auto-generated with scripts/generate-types.ts
16
+ * Then manually modified to only expose types and endpoints of interest
17
+ */
18
+ // import type lookup before we augment - in some environments
19
+ // this is required to allow for ambient/previous definitions
20
+ import '@polkadot/api-base/types/submittable';
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Auto-generated with scripts/generate-types.ts
3
+ * Then manually modified to only expose types and endpoints of interest
4
+ */
5
+ import './augment-api-errors.js';
6
+ import './augment-api-query.js';
7
+ import './augment-api-tx.js';
@@ -0,0 +1,20 @@
1
+ // This file is part of MIDNIGHT-WALLET-SDK.
2
+ // Copyright (C) 2025 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
+ /* eslint-disable */
14
+ /**
15
+ * Auto-generated with scripts/generate-types.ts
16
+ * Then manually modified to only expose types and endpoints of interest
17
+ */
18
+ import './augment-api-errors.js';
19
+ import './augment-api-query.js';
20
+ import './augment-api-tx.js';
@@ -0,0 +1,13 @@
1
+ import { NodeClient, SubmissionEvent, Config } from './effect/index.js';
2
+ import { Observable } from '@polkadot/types/types';
3
+ export { Config, makeConfig, DEFAULT_CONFIG } from './effect/PolkadotNodeClient.js';
4
+ export declare class PolkadotNodeClient {
5
+ #private;
6
+ static init(config: Config): Promise<PolkadotNodeClient>;
7
+ private constructor();
8
+ sendMidnightTransaction(serializedTransaction: NodeClient.SerializedMnTransaction): Observable<SubmissionEvent.SubmissionEvent>;
9
+ sendMidnightTransactionAndWait(serializedTransaction: NodeClient.SerializedMnTransaction, waitFor: SubmissionEvent.Cases.Submitted['_tag']): Promise<SubmissionEvent.Cases.Submitted>;
10
+ sendMidnightTransactionAndWait(serializedTransaction: NodeClient.SerializedMnTransaction, waitFor: SubmissionEvent.Cases.InBlock['_tag']): Promise<SubmissionEvent.Cases.InBlock>;
11
+ sendMidnightTransactionAndWait(serializedTransaction: NodeClient.SerializedMnTransaction, waitFor: SubmissionEvent.Cases.Finalized['_tag']): Promise<SubmissionEvent.Cases.Finalized>;
12
+ close(): Promise<void>;
13
+ }
package/dist/index.js ADDED
@@ -0,0 +1,41 @@
1
+ // This file is part of MIDNIGHT-WALLET-SDK.
2
+ // Copyright (C) 2025 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 { NodeClient, PolkadotNodeClient as EffectNodeClient, } from './effect/index.js';
14
+ import { Effect, Exit, pipe, Scope } from 'effect';
15
+ import { ObservableOps } from '@midnight-ntwrk/wallet-sdk-utilities';
16
+ export { makeConfig, DEFAULT_CONFIG } from './effect/PolkadotNodeClient.js';
17
+ export class PolkadotNodeClient {
18
+ static init(config) {
19
+ return Effect.gen(function* () {
20
+ const scope = yield* Scope.make();
21
+ const client = yield* NodeClient.NodeClient.pipe(Effect.provide(EffectNodeClient.layer(config)), Effect.provideService(Scope.Scope, scope));
22
+ return new PolkadotNodeClient(client, scope);
23
+ }).pipe(Effect.runPromise);
24
+ }
25
+ #effectClient;
26
+ #scope;
27
+ constructor(effectClient, scope) {
28
+ this.#effectClient = effectClient;
29
+ this.#scope = scope;
30
+ }
31
+ sendMidnightTransaction(serializedTransaction) {
32
+ return ObservableOps.fromStream(this.#effectClient.sendMidnightTransaction(serializedTransaction));
33
+ }
34
+ sendMidnightTransactionAndWait(serializedTransaction, waitFor) {
35
+ const runRequest = (request) => pipe(request, Effect.provideService(NodeClient.NodeClient, this.#effectClient), Effect.runPromise);
36
+ return NodeClient.sendMidnightTransactionAndWait(serializedTransaction, waitFor).pipe(runRequest);
37
+ }
38
+ close() {
39
+ return Scope.close(this.#scope, Exit.void).pipe(Effect.runPromise);
40
+ }
41
+ }
@@ -0,0 +1 @@
1
+ export * as TestTransactions from './test-transactions.js';
@@ -0,0 +1,13 @@
1
+ // This file is part of MIDNIGHT-WALLET-SDK.
2
+ // Copyright (C) 2025 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
+ export * as TestTransactions from './test-transactions.js';
@@ -0,0 +1,4 @@
1
+ export declare function normalizeTxs(tx: string): {
2
+ initial_tx: string;
3
+ batches: string[];
4
+ };
@@ -0,0 +1,48 @@
1
+ // This file is part of MIDNIGHT-WALLET-SDK.
2
+ // Copyright (C) 2025 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 { Encoding } from 'effect';
14
+ export function normalizeTxs(tx) {
15
+ const normalizedTxs = {
16
+ initial_tx: '',
17
+ batches: [],
18
+ };
19
+ const data = JSON.parse(tx);
20
+ if (data.initial_tx) {
21
+ try {
22
+ const inner = JSON.parse(data.initial_tx);
23
+ if (inner.tx)
24
+ normalizedTxs.initial_tx = Encoding.encodeHex(inner.tx);
25
+ }
26
+ catch {
27
+ throw Error('Failed to parse initial_tx');
28
+ }
29
+ }
30
+ else {
31
+ throw Error('initial_tx is missing');
32
+ }
33
+ for (const batch of data.batches ?? []) {
34
+ for (const bufferTx of batch.txs ?? []) {
35
+ try {
36
+ const inner = JSON.parse(bufferTx);
37
+ if (inner.tx) {
38
+ const txHex = Encoding.encodeHex(inner.tx);
39
+ normalizedTxs.batches.push(txHex);
40
+ }
41
+ }
42
+ catch {
43
+ throw Error('Failed to parse batch tx');
44
+ }
45
+ }
46
+ }
47
+ return normalizedTxs;
48
+ }
@@ -0,0 +1,20 @@
1
+ import { Error, FileSystem } from '@effect/platform';
2
+ import * as ledger from '@midnight-ntwrk/ledger-v6';
3
+ import { SerializedTransaction } from '@midnight-ntwrk/wallet-sdk-abstractions';
4
+ import { ProverClient } from '@midnight-ntwrk/wallet-sdk-prover-client/effect';
5
+ import { ClientError, ServerError } from '@midnight-ntwrk/wallet-sdk-utilities/networking';
6
+ import { Effect, ParseResult, Schema, Stream } from 'effect';
7
+ import { Scope } from 'effect/Scope';
8
+ import { StartedNetwork } from 'testcontainers';
9
+ export type FinalizedTransaction = ledger.Transaction<ledger.SignatureEnabled, ledger.Proof, ledger.Binding>;
10
+ declare const TestTransactionsSchema: Schema.Struct<{
11
+ initial_tx: Schema.Schema<FinalizedTransaction, string, never>;
12
+ unbalanced_tx: Schema.Schema<FinalizedTransaction, string, never>;
13
+ batches: Schema.Array$<Schema.Schema<FinalizedTransaction, string, never>>;
14
+ }>;
15
+ export type TestTransactions = Schema.Schema.Type<typeof TestTransactionsSchema>;
16
+ export declare const load: (file: string) => Effect.Effect<TestTransactions, ParseResult.ParseError | Error.PlatformError, FileSystem.FileSystem>;
17
+ export declare const streamAllValid: (txs: TestTransactions) => Stream.Stream<FinalizedTransaction>;
18
+ export declare const genUnbalancedTx: () => Effect.Effect<SerializedTransaction, ClientError | ServerError, ProverClient.ProverClient>;
19
+ export declare const generateTestTransactions: (nodeUrl: string, proofServerUrl: string, network: StartedNetwork, outputPath: string, fileName: string) => Effect.Effect<void, Error | Error.PlatformError, FileSystem.FileSystem | Scope>;
20
+ export {};
@@ -0,0 +1,88 @@
1
+ // This file is part of MIDNIGHT-WALLET-SDK.
2
+ // Copyright (C) 2025 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 { FileSystem } from '@effect/platform';
14
+ import * as ledger from '@midnight-ntwrk/ledger-v6';
15
+ import { SerializedTransaction } from '@midnight-ntwrk/wallet-sdk-abstractions';
16
+ import { HttpProverClient, ProverClient } from '@midnight-ntwrk/wallet-sdk-prover-client/effect';
17
+ import { TestContainers } from '@midnight-ntwrk/wallet-sdk-utilities/testing';
18
+ import { Effect, Encoding, ParseResult, pipe, Random, Schema, Stream } from 'effect';
19
+ import { normalizeTxs } from './normalize-txs.js';
20
+ const TxSchema = Schema.declare((input) => input instanceof ledger.Transaction).annotations({
21
+ identifier: 'ledger.Transaction',
22
+ });
23
+ const Uint8ArraySchema = Schema.declare((input) => input instanceof Uint8Array).annotations({
24
+ identifier: 'Uint8Array',
25
+ });
26
+ const TxFromUint8Array = Schema.asSchema(Schema.transformOrFail(Uint8ArraySchema, TxSchema, {
27
+ encode: (tx) => Effect.sync(() => tx.serialize()),
28
+ decode: (bytes) => Effect.try({
29
+ try: () => ledger.Transaction.deserialize('signature', 'proof', 'binding', bytes),
30
+ catch: (err) => new ParseResult.Unexpected(err, 'Could not deserialize transaction'),
31
+ }),
32
+ }));
33
+ const HexedTx = pipe(Schema.Uint8ArrayFromHex, Schema.compose(TxFromUint8Array));
34
+ const TestTransactionsSchema = Schema.Struct({
35
+ initial_tx: HexedTx,
36
+ unbalanced_tx: HexedTx,
37
+ batches: Schema.Array(HexedTx),
38
+ });
39
+ export const load = (file) => pipe(FileSystem.FileSystem.pipe(Effect.flatMap((fs) => fs.readFileString(file))), Effect.map((str) => JSON.parse(str)), Effect.andThen(Schema.decodeUnknown(TestTransactionsSchema, { errors: 'all' })), Effect.cached, Effect.flatten);
40
+ export const streamAllValid = (txs) => {
41
+ const initial = Stream.succeed(txs.initial_tx);
42
+ const batches = Stream.fromIterable(txs.batches);
43
+ return Stream.concat(initial, batches);
44
+ };
45
+ export const genUnbalancedTx = () => Effect.Do.pipe(Effect.bind('value', () => Random.nextIntBetween(1, 100_000_000).pipe(Effect.map((nr) => BigInt(nr)))), Effect.bind('shieldedTokenType', () => Effect.succeed(ledger.shieldedToken())), Effect.let('unprovenTx', ({ value, shieldedTokenType }) => {
46
+ const recipient = ledger.ZswapSecretKeys.fromSeed(new Uint8Array(32).fill(0));
47
+ const coin = ledger.createShieldedCoinInfo(shieldedTokenType.raw, value);
48
+ const unprovenOutput = ledger.ZswapOutput.new(coin, 0, recipient.coinPublicKey, recipient.encryptionPublicKey);
49
+ const unprovenOffer = ledger.ZswapOffer.fromOutput(unprovenOutput, shieldedTokenType.raw, value);
50
+ return ledger.Transaction.fromParts('undeployed', unprovenOffer);
51
+ }), Effect.flatMap(({ unprovenTx }) => Effect.gen(function* () {
52
+ const proverClient = yield* ProverClient.ProverClient;
53
+ const provedTx = yield* proverClient.proveTransaction(unprovenTx, ledger.CostModel.initialCostModel());
54
+ return SerializedTransaction(provedTx.bind().serialize());
55
+ })));
56
+ const normalizeAndSaveUnbalancedTx = (txsPath, tx) => {
57
+ /* eslint-disable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-explicit-any */
58
+ return Effect.gen(function* () {
59
+ const fs = yield* FileSystem.FileSystem;
60
+ const outputFileData = yield* fs.readFileString(txsPath, 'utf8').pipe(Effect.map((str) => normalizeTxs(str)));
61
+ const augmentedOutput = {
62
+ ...outputFileData,
63
+ unbalanced_tx: Encoding.encodeHex(tx),
64
+ };
65
+ yield* fs.writeFileString(txsPath, JSON.stringify(augmentedOutput));
66
+ });
67
+ /* eslint-enable */
68
+ };
69
+ const generateUnbalancedTransaction = (proofServerUrl) => {
70
+ // Originally written with `Effect.gen`, but rewritten to Do notation to debug some typing issue
71
+ // It seems to be a somewhat regular issue
72
+ return Effect.Do.pipe(Effect.bind('tx', () => genUnbalancedTx()), Effect.map(({ tx }) => tx), Effect.provide(HttpProverClient.layer({
73
+ url: new URL(proofServerUrl),
74
+ })));
75
+ };
76
+ export const generateTestTransactions = (nodeUrl, proofServerUrl, network, outputPath, fileName) => Effect.gen(function* () {
77
+ const [, unbalancedTx] = yield* Effect.all([
78
+ TestContainers.runTxGenerator({
79
+ nodeUrl: nodeUrl,
80
+ destPath: outputPath,
81
+ fileName: fileName,
82
+ txsPerBatch: 1,
83
+ batches: 1,
84
+ }, (c) => c.withNetwork(network)),
85
+ generateUnbalancedTransaction(proofServerUrl),
86
+ ]);
87
+ yield* normalizeAndSaveUnbalancedTx(`${outputPath}/${fileName}`, unbalancedTx);
88
+ });
package/package.json ADDED
@@ -0,0 +1,85 @@
1
+ {
2
+ "name": "@midnight-ntwrk/wallet-sdk-node-client",
3
+ "version": "1.0.0-beta.10",
4
+ "type": "module",
5
+ "module": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "author": "Midnight Foundation",
8
+ "license": "Apache-2.0",
9
+ "publishConfig": {
10
+ "registry": "https://npm.pkg.github.com/"
11
+ },
12
+ "files": [
13
+ "dist/"
14
+ ],
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "git+https://github.com/midnight-ntwrk/artifacts.git"
18
+ },
19
+ "exports": {
20
+ ".": {
21
+ "types": "./dist/index.d.ts",
22
+ "import": "./dist/index.js"
23
+ },
24
+ "./effect": {
25
+ "types": "./dist/effect/index.d.ts",
26
+ "import": "./dist/effect/index.js"
27
+ },
28
+ "./testing": {
29
+ "types": "./dist/testing/index.d.ts",
30
+ "import": "./dist/testing/index.js"
31
+ }
32
+ },
33
+ "dependencies": {
34
+ "@polkadot/api": "^16.3.1",
35
+ "@polkadot/api-augment": "^16.3.1",
36
+ "@polkadot/api-base": "^16.3.1",
37
+ "@polkadot/rpc-augment": "^16.3.1",
38
+ "@polkadot/rpc-core": "^16.3.1",
39
+ "@polkadot/types": "^16.3.1",
40
+ "@polkadot/types-augment": "^16.3.1",
41
+ "@polkadot/types-codec": "^16.3.1",
42
+ "@polkadot/types-known": "^16.3.1",
43
+ "@polkadot/types-support": "^16.3.1",
44
+ "@types/bn.js": "^5.2.0",
45
+ "bn.js": "^5.2.2",
46
+ "effect": "^3.17.3",
47
+ "rxjs": "^7.5",
48
+ "testcontainers": "^11.8.1"
49
+ },
50
+ "devDependencies": {
51
+ "@effect/cluster": "^0.46.2",
52
+ "@effect/experimental": "^0.54.2",
53
+ "@effect/platform": "^0.90.0",
54
+ "@effect/platform-node": "^0.94.0",
55
+ "@effect/rpc": "^0.68.0",
56
+ "@effect/sql": "^0.44.0",
57
+ "@effect/workflow": "^0.8.1",
58
+ "@midnight-ntwrk/ledger-v6": "6.1.0-alpha.6",
59
+ "@midnight-ntwrk/wallet-sdk-abstractions": "1.0.0-beta.9",
60
+ "@midnight-ntwrk/wallet-sdk-prover-client": "1.0.0-beta.10",
61
+ "@midnight-ntwrk/wallet-sdk-utilities": "1.0.0-beta.7",
62
+ "@polkadot/typegen": "^16.3.1",
63
+ "@types/yargs": "^17.0.33",
64
+ "eslint": "^9.37.0",
65
+ "publint": "~0.3.14",
66
+ "rimraf": "^6.0.1",
67
+ "tsx": "^4.20.4",
68
+ "typescript": "^5.9.3",
69
+ "vitest": "^3.2.4",
70
+ "yargs": "^18.0.0"
71
+ },
72
+ "scripts": {
73
+ "typecheck-script": "tsc -b ./tsconfig.script.json --noEmit",
74
+ "polkadot-typegen": "tsx ./scripts/generate-types.ts",
75
+ "typecheck": "tsc -b ./tsconfig.json --noEmit",
76
+ "test": "vitest run",
77
+ "lint": "eslint --max-warnings 0",
78
+ "format": "prettier --write \"**/*.{ts,js,json,yaml,yml}\"",
79
+ "format:check": "prettier --check \"**/*.{ts,js,json,yaml,yml}\"",
80
+ "dist": "tsc -b ./tsconfig.build.json",
81
+ "dist:publish": "tsc -b ./tsconfig.publish.json",
82
+ "clean": "rimraf --glob dist 'tsconfig.*.tsbuildinfo' && date +%s > .clean-timestamp",
83
+ "publint": "publint --strict"
84
+ }
85
+ }