@midnightntwrk/wallet-sdk-shielded 3.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +124 -0
- package/dist/ShieldedWallet.d.ts +65 -0
- package/dist/ShieldedWallet.js +132 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +14 -0
- package/dist/v1/CoinsAndBalances.d.ts +24 -0
- package/dist/v1/CoinsAndBalances.js +46 -0
- package/dist/v1/CoreWallet.d.ts +47 -0
- package/dist/v1/CoreWallet.js +153 -0
- package/dist/v1/Keys.d.ts +8 -0
- package/dist/v1/Keys.js +16 -0
- package/dist/v1/RunningV1Variant.d.ts +40 -0
- package/dist/v1/RunningV1Variant.js +98 -0
- package/dist/v1/Serialization.d.ts +12 -0
- package/dist/v1/Serialization.js +79 -0
- package/dist/v1/Sync.d.ts +83 -0
- package/dist/v1/Sync.js +206 -0
- package/dist/v1/Transacting.d.ts +50 -0
- package/dist/v1/Transacting.js +258 -0
- package/dist/v1/TransactionHistory.d.ts +64 -0
- package/dist/v1/TransactionHistory.js +98 -0
- package/dist/v1/TransactionImbalances.d.ts +10 -0
- package/dist/v1/TransactionImbalances.js +30 -0
- package/dist/v1/TransactionOps.d.ts +17 -0
- package/dist/v1/TransactionOps.js +73 -0
- package/dist/v1/V1Builder.d.ts +93 -0
- package/dist/v1/V1Builder.js +172 -0
- package/dist/v1/WalletError.d.ts +74 -0
- package/dist/v1/WalletError.js +53 -0
- package/dist/v1/index.d.ts +12 -0
- package/dist/v1/index.js +24 -0
- package/package.json +54 -0
|
@@ -0,0 +1,258 @@
|
|
|
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 * as ledger from '@midnight-ntwrk/ledger-v8';
|
|
14
|
+
import { Array as Arr, Either, Option, pipe, Record } from 'effect';
|
|
15
|
+
import { ArrayOps } from '@midnightntwrk/wallet-sdk-utilities';
|
|
16
|
+
import { CoreWallet } from './CoreWallet.js';
|
|
17
|
+
import { InsufficientFundsError, OtherWalletError } from './WalletError.js';
|
|
18
|
+
import { getBalanceRecipe, Imbalances, InsufficientFundsError as BalancingInsufficientFundsError, } from '@midnightntwrk/wallet-sdk-capabilities';
|
|
19
|
+
import { ShieldedCostModel, TransactionImbalances } from './TransactionImbalances.js';
|
|
20
|
+
import { TransactionOps } from './TransactionOps.js';
|
|
21
|
+
export const makeDefaultTransactingCapability = (config, getContext) => {
|
|
22
|
+
return new TransactingCapabilityImplementation(config.networkId, () => getContext().coinSelection, () => getContext().coinsAndBalancesCapability, () => getContext().keysCapability, TransactionOps.default);
|
|
23
|
+
};
|
|
24
|
+
export const makeSimulatorTransactingCapability = (config, getContext) => {
|
|
25
|
+
return new TransactingCapabilityImplementation(config.networkId, () => getContext().coinSelection, () => getContext().coinsAndBalancesCapability, () => getContext().keysCapability, TransactionOps.proofErased);
|
|
26
|
+
};
|
|
27
|
+
export class TransactingCapabilityImplementation {
|
|
28
|
+
networkId;
|
|
29
|
+
getCoinSelection;
|
|
30
|
+
txOps;
|
|
31
|
+
getCoins;
|
|
32
|
+
getKeys;
|
|
33
|
+
constructor(networkId, getCoinSelection, getCoins, getKeys, txOps) {
|
|
34
|
+
this.getCoins = getCoins;
|
|
35
|
+
this.networkId = networkId;
|
|
36
|
+
this.getCoinSelection = getCoinSelection;
|
|
37
|
+
this.getKeys = getKeys;
|
|
38
|
+
this.txOps = txOps;
|
|
39
|
+
}
|
|
40
|
+
balanceTransaction(secretKeys, state, tx) {
|
|
41
|
+
return Either.gen(this, function* () {
|
|
42
|
+
const coinSelection = this.getCoinSelection();
|
|
43
|
+
const initialImbalances = this.txOps.getImbalances(tx);
|
|
44
|
+
if (TransactionImbalances.areBalanced(initialImbalances)) {
|
|
45
|
+
return [undefined, state];
|
|
46
|
+
}
|
|
47
|
+
const { newState: afterFallible, fallibleOffers } = yield* this.balanceFallibleSection(secretKeys, state, initialImbalances, coinSelection);
|
|
48
|
+
const { newState: afterGuaranteed, offer: guaranteed } = yield* this.#balanceGuaranteedSection(secretKeys, afterFallible, initialImbalances, coinSelection, Imbalances.empty());
|
|
49
|
+
const balancedTx = Array.from(fallibleOffers.entries()).reduce((tx, [segment, offer]) => tx.addZswapOffer({ tag: 'specific', value: segment }, offer), ledger.Transaction.fromParts(this.networkId, guaranteed));
|
|
50
|
+
return [balancedTx, afterGuaranteed];
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
makeTransfer(secretKeys, state, transfers) {
|
|
54
|
+
return Either.gen(this, function* () {
|
|
55
|
+
const positiveTransfers = yield* pipe(transfers, Arr.filter((t) => t.amount > 0n), Arr.match({
|
|
56
|
+
onEmpty: () => Either.left(new OtherWalletError({
|
|
57
|
+
message: 'The amount needs to be positive',
|
|
58
|
+
})),
|
|
59
|
+
onNonEmpty: (nonEmpty) => Either.right(nonEmpty),
|
|
60
|
+
}));
|
|
61
|
+
const networkId = this.networkId;
|
|
62
|
+
const { initialOffersAndCoins, selfCoins } = yield* this.#processDesiredOutputs(state, positiveTransfers);
|
|
63
|
+
const offerToBalance = pipe(initialOffersAndCoins, Arr.map((o) => o.outputOffer), ArrayOps.fold((a, b) => a.merge(b)));
|
|
64
|
+
const unprovenTxToBalance = ledger.Transaction.fromParts(networkId, offerToBalance);
|
|
65
|
+
const imbalances = TransactionOps.unproven.getImbalances(unprovenTxToBalance);
|
|
66
|
+
const { offer, newState } = yield* this.#balanceGuaranteedSection(secretKeys, state, imbalances, this.getCoinSelection(), Imbalances.empty());
|
|
67
|
+
const finalState = CoreWallet.watchCoins(newState, secretKeys, selfCoins);
|
|
68
|
+
const finalTx = unprovenTxToBalance.merge(ledger.Transaction.fromParts(networkId, offer));
|
|
69
|
+
return [finalTx, finalState];
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
initSwap(secretKeys, state, desiredInputs, desiredOutputs) {
|
|
73
|
+
return Either.gen(this, function* () {
|
|
74
|
+
const outputsValid = desiredOutputs.every((output) => output.amount > 0n);
|
|
75
|
+
if (!outputsValid) {
|
|
76
|
+
return yield* Either.left(new OtherWalletError({
|
|
77
|
+
message: 'The amount needs to be positive',
|
|
78
|
+
}));
|
|
79
|
+
}
|
|
80
|
+
const inputsValid = Object.entries(desiredInputs).every(([, amount]) => amount > 0n);
|
|
81
|
+
if (!inputsValid) {
|
|
82
|
+
return yield* Either.left(new OtherWalletError({
|
|
83
|
+
message: 'The input amounts need to be positive',
|
|
84
|
+
}));
|
|
85
|
+
}
|
|
86
|
+
const outputsParseResult = yield* this.#processDesiredOutputsPossiblyEmpty(state, desiredOutputs);
|
|
87
|
+
const inputsParseResult = Imbalances.fromEntries(Record.toEntries(desiredInputs));
|
|
88
|
+
const networkId = this.networkId;
|
|
89
|
+
const { offer, newState } = yield* this.#balanceGuaranteedSection(secretKeys, state, TransactionImbalances.empty(), this.getCoinSelection(), inputsParseResult);
|
|
90
|
+
const finalState = CoreWallet.watchCoins(newState, secretKeys, outputsParseResult.selfCoins);
|
|
91
|
+
const balancingTx = ledger.Transaction.fromParts(networkId, offer);
|
|
92
|
+
const finalTx = outputsParseResult.unprovenTxToBalance
|
|
93
|
+
? outputsParseResult.unprovenTxToBalance.merge(balancingTx)
|
|
94
|
+
: balancingTx;
|
|
95
|
+
return [finalTx, finalState];
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
revertTransaction(state, transaction) {
|
|
99
|
+
return Either.try({
|
|
100
|
+
try: () => {
|
|
101
|
+
return CoreWallet.revertTransaction(state, transaction);
|
|
102
|
+
},
|
|
103
|
+
catch: (err) => {
|
|
104
|
+
return new OtherWalletError({
|
|
105
|
+
message: `Error while reverting transaction ${transaction.identifiers().at(0)}`,
|
|
106
|
+
cause: err,
|
|
107
|
+
});
|
|
108
|
+
},
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
#prepareOffer(secretKeys, state, recipe, segment) {
|
|
112
|
+
const [inputOffers, stateAfterSpends] = CoreWallet.spendCoins(state, secretKeys, recipe.inputs, segment);
|
|
113
|
+
const stateAfterWatches = CoreWallet.watchCoins(stateAfterSpends, secretKeys, recipe.outputs);
|
|
114
|
+
const outputOffers = recipe.outputs.map((coin) => {
|
|
115
|
+
const output = ledger.ZswapOutput.new(coin, segment, this.getKeys().getCoinPublicKey(state).toHexString(), this.getKeys().getEncryptionPublicKey(state).toHexString());
|
|
116
|
+
return ledger.ZswapOffer.fromOutput(output, coin.type, coin.value);
|
|
117
|
+
});
|
|
118
|
+
return pipe(Arr.appendAll(inputOffers, outputOffers), Arr.match({
|
|
119
|
+
onEmpty: () => Option.none(),
|
|
120
|
+
onNonEmpty: (nonEmpty) => pipe(nonEmpty, ArrayOps.fold((a, b) => a.merge(b)), Option.some),
|
|
121
|
+
}), Option.map((offer) => ({ offer, newState: stateAfterWatches })));
|
|
122
|
+
}
|
|
123
|
+
balanceFallibleSection(secretKeys, state, imbalances, coinSelection) {
|
|
124
|
+
return Array.from(imbalances.fallible.entries()).reduce((acc, [segment, segmentImbalances]) => Either.flatMap(acc, ({ fallibleOffers, newState }) => pipe(Either.try({
|
|
125
|
+
try: () => {
|
|
126
|
+
const fallibleBalanceRecipe = getBalanceRecipe({
|
|
127
|
+
coins: this.getCoins()
|
|
128
|
+
.getAvailableCoins(newState)
|
|
129
|
+
.map((c) => c.coin),
|
|
130
|
+
initialImbalances: segmentImbalances,
|
|
131
|
+
transactionCostModel: ShieldedCostModel,
|
|
132
|
+
feeTokenType: '',
|
|
133
|
+
coinSelection,
|
|
134
|
+
createOutput: (coin) => ledger.createShieldedCoinInfo(coin.type, coin.value),
|
|
135
|
+
isCoinEqual: (a, b) => a.type === b.type && a.value === b.value,
|
|
136
|
+
});
|
|
137
|
+
return this.#prepareOffer(secretKeys, newState, fallibleBalanceRecipe, segment);
|
|
138
|
+
},
|
|
139
|
+
catch: (err) => {
|
|
140
|
+
if (err instanceof BalancingInsufficientFundsError) {
|
|
141
|
+
return new InsufficientFundsError({
|
|
142
|
+
message: `Insufficient funds for fallible segment ${segment}`,
|
|
143
|
+
tokenType: err.tokenType,
|
|
144
|
+
amount: segmentImbalances.get(err.tokenType) ?? 0n,
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
return new OtherWalletError({
|
|
148
|
+
message: `Balancing fallible segment ${segment} failed`,
|
|
149
|
+
cause: err,
|
|
150
|
+
});
|
|
151
|
+
},
|
|
152
|
+
}), Either.map(Option.match({
|
|
153
|
+
onNone: () => ({ fallibleOffers, newState }),
|
|
154
|
+
onSome: (res) => ({
|
|
155
|
+
fallibleOffers: new Map([...fallibleOffers, [segment, res.offer]]),
|
|
156
|
+
newState: res.newState,
|
|
157
|
+
}),
|
|
158
|
+
})))), Either.right({
|
|
159
|
+
fallibleOffers: new Map(),
|
|
160
|
+
newState: state,
|
|
161
|
+
}));
|
|
162
|
+
}
|
|
163
|
+
#balanceGuaranteedSection(secretKeys, state, imbalances, coinSelection, targetImbalances) {
|
|
164
|
+
return Either.gen(this, function* () {
|
|
165
|
+
const balanceRecipe = yield* Either.try({
|
|
166
|
+
try: () => getBalanceRecipe({
|
|
167
|
+
coins: this.getCoins()
|
|
168
|
+
.getAvailableCoins(state)
|
|
169
|
+
.map((c) => c.coin),
|
|
170
|
+
initialImbalances: imbalances.guaranteed,
|
|
171
|
+
transactionCostModel: ShieldedCostModel,
|
|
172
|
+
feeTokenType: '',
|
|
173
|
+
coinSelection,
|
|
174
|
+
createOutput: (coin) => ledger.createShieldedCoinInfo(coin.type, coin.value),
|
|
175
|
+
isCoinEqual: (a, b) => a.nonce === b.nonce,
|
|
176
|
+
targetImbalances,
|
|
177
|
+
}),
|
|
178
|
+
catch: (err) => {
|
|
179
|
+
if (err instanceof BalancingInsufficientFundsError) {
|
|
180
|
+
return new InsufficientFundsError({
|
|
181
|
+
message: 'Insufficient funds',
|
|
182
|
+
tokenType: err.tokenType,
|
|
183
|
+
amount: imbalances.guaranteed.get(err.tokenType) ?? 0n,
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
return new OtherWalletError({
|
|
188
|
+
message: 'Balancing guaranteed section failed',
|
|
189
|
+
cause: err,
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
},
|
|
193
|
+
});
|
|
194
|
+
// An empty recipe (e.g. the guaranteed section is already balanced) yields no offer.
|
|
195
|
+
// Treat that as "nothing to add" rather than a failure, mirroring the fallible section.
|
|
196
|
+
return pipe(this.#prepareOffer(secretKeys, state, balanceRecipe, 0), Option.match({
|
|
197
|
+
onNone: () => ({ offer: undefined, newState: state }),
|
|
198
|
+
onSome: (result) => result,
|
|
199
|
+
}));
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
#processDesiredOutputs(state, transfers) {
|
|
203
|
+
return Either.try({
|
|
204
|
+
try: () => {
|
|
205
|
+
const initialOffersAndCoins = pipe(transfers, Arr.map((transfer) => {
|
|
206
|
+
const { receiverAddress, type, amount } = transfer;
|
|
207
|
+
const coin = ledger.createShieldedCoinInfo(type, amount);
|
|
208
|
+
const output = ledger.ZswapOutput.new(coin, 0, receiverAddress.coinPublicKey.toHexString(), receiverAddress.encryptionPublicKey.toHexString());
|
|
209
|
+
const outputOffer = ledger.ZswapOffer.fromOutput(output, type, amount);
|
|
210
|
+
return {
|
|
211
|
+
coin,
|
|
212
|
+
outputOffer,
|
|
213
|
+
isForSelf: receiverAddress.coinPublicKey.equals(this.getKeys().getCoinPublicKey(state)),
|
|
214
|
+
};
|
|
215
|
+
}));
|
|
216
|
+
const selfCoins = Arr.flatMap(initialOffersAndCoins, ({ coin, isForSelf }) => {
|
|
217
|
+
if (isForSelf) {
|
|
218
|
+
return [coin];
|
|
219
|
+
}
|
|
220
|
+
else {
|
|
221
|
+
return [];
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
return { initialOffersAndCoins, selfCoins };
|
|
225
|
+
},
|
|
226
|
+
catch: (err) => {
|
|
227
|
+
return new OtherWalletError({
|
|
228
|
+
message: 'Failed to process desired outputs',
|
|
229
|
+
cause: err,
|
|
230
|
+
});
|
|
231
|
+
},
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
#processDesiredOutputsPossiblyEmpty(state, desiredOutputs) {
|
|
235
|
+
return pipe(desiredOutputs, Arr.match({
|
|
236
|
+
onEmpty: () => {
|
|
237
|
+
return Either.right({
|
|
238
|
+
imbalances: TransactionImbalances.empty(),
|
|
239
|
+
selfCoins: [],
|
|
240
|
+
unprovenTxToBalance: null,
|
|
241
|
+
});
|
|
242
|
+
},
|
|
243
|
+
onNonEmpty: (desiredOutputs) => {
|
|
244
|
+
return pipe(this.#processDesiredOutputs(state, desiredOutputs), Either.map(({ initialOffersAndCoins, selfCoins }) => {
|
|
245
|
+
const networkId = this.networkId;
|
|
246
|
+
const offerToBalance = pipe(initialOffersAndCoins, Arr.map((o) => o.outputOffer), ArrayOps.fold((a, b) => a.merge(b)));
|
|
247
|
+
const unprovenTxToBalance = ledger.Transaction.fromParts(networkId, offerToBalance);
|
|
248
|
+
const imbalances = TransactionOps.unproven.getImbalances(unprovenTxToBalance);
|
|
249
|
+
return {
|
|
250
|
+
imbalances,
|
|
251
|
+
selfCoins,
|
|
252
|
+
unprovenTxToBalance,
|
|
253
|
+
};
|
|
254
|
+
}));
|
|
255
|
+
},
|
|
256
|
+
}));
|
|
257
|
+
}
|
|
258
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { TransactionHistoryStorage } from '@midnightntwrk/wallet-sdk-abstractions';
|
|
2
|
+
import type * as ledger from '@midnight-ntwrk/ledger-v8';
|
|
3
|
+
import { Effect, Schema } from 'effect';
|
|
4
|
+
import { TransactionHistoryError } from './WalletError.js';
|
|
5
|
+
export declare const QualifiedShieldedCoinInfoSchema: Schema.Struct<{
|
|
6
|
+
type: typeof Schema.String;
|
|
7
|
+
nonce: typeof Schema.String;
|
|
8
|
+
value: typeof Schema.BigInt;
|
|
9
|
+
mtIndex: typeof Schema.BigInt;
|
|
10
|
+
}>;
|
|
11
|
+
export declare const ShieldedSectionSchema: Schema.Struct<{
|
|
12
|
+
receivedCoins: Schema.Array$<Schema.Struct<{
|
|
13
|
+
type: typeof Schema.String;
|
|
14
|
+
nonce: typeof Schema.String;
|
|
15
|
+
value: typeof Schema.BigInt;
|
|
16
|
+
mtIndex: typeof Schema.BigInt;
|
|
17
|
+
}>>;
|
|
18
|
+
spentCoins: Schema.Array$<Schema.Struct<{
|
|
19
|
+
type: typeof Schema.String;
|
|
20
|
+
nonce: typeof Schema.String;
|
|
21
|
+
value: typeof Schema.BigInt;
|
|
22
|
+
mtIndex: typeof Schema.BigInt;
|
|
23
|
+
}>>;
|
|
24
|
+
}>;
|
|
25
|
+
type ShieldedSection = Schema.Schema.Type<typeof ShieldedSectionSchema>;
|
|
26
|
+
export declare const ShieldedTransactionHistoryEntrySchema: Schema.Struct<{
|
|
27
|
+
hash: typeof Schema.String;
|
|
28
|
+
protocolVersion: typeof Schema.Number;
|
|
29
|
+
status: Schema.Literal<["SUCCESS", "FAILURE", "PARTIAL_SUCCESS"]>;
|
|
30
|
+
shielded: Schema.Struct<{
|
|
31
|
+
receivedCoins: Schema.Array$<Schema.Struct<{
|
|
32
|
+
type: typeof Schema.String;
|
|
33
|
+
nonce: typeof Schema.String;
|
|
34
|
+
value: typeof Schema.BigInt;
|
|
35
|
+
mtIndex: typeof Schema.BigInt;
|
|
36
|
+
}>>;
|
|
37
|
+
spentCoins: Schema.Array$<Schema.Struct<{
|
|
38
|
+
type: typeof Schema.String;
|
|
39
|
+
nonce: typeof Schema.String;
|
|
40
|
+
value: typeof Schema.BigInt;
|
|
41
|
+
mtIndex: typeof Schema.BigInt;
|
|
42
|
+
}>>;
|
|
43
|
+
}>;
|
|
44
|
+
}>;
|
|
45
|
+
export type ShieldedTransactionHistoryEntry = Schema.Schema.Type<typeof ShieldedTransactionHistoryEntrySchema>;
|
|
46
|
+
export type DefaultTransactionHistoryConfiguration = {
|
|
47
|
+
txHistoryStorage: TransactionHistoryStorage.TransactionHistoryStorage<TransactionHistoryStorage.TransactionHistoryEntryWithHash>;
|
|
48
|
+
indexerClientConnection: {
|
|
49
|
+
indexerHttpUrl: string;
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
export type TransactionDetails = {
|
|
53
|
+
hash: string;
|
|
54
|
+
timestamp: number;
|
|
55
|
+
status: 'SUCCESS' | 'FAILURE' | 'PARTIAL_SUCCESS';
|
|
56
|
+
};
|
|
57
|
+
export type TransactionHistoryService = {
|
|
58
|
+
put(changes: ledger.ZswapStateChanges, metadata: TransactionDetails, protocolVersion: number): Effect.Effect<void, TransactionHistoryError>;
|
|
59
|
+
getTransactionDetails(hash: TransactionHistoryStorage.TransactionHash): Effect.Effect<TransactionDetails, TransactionHistoryError>;
|
|
60
|
+
};
|
|
61
|
+
export declare const mergeShieldedSections: (existing: ShieldedSection, incoming: ShieldedSection) => ShieldedSection;
|
|
62
|
+
export declare const makeDefaultTransactionHistoryService: (config: DefaultTransactionHistoryConfiguration, _getContext: () => unknown) => TransactionHistoryService;
|
|
63
|
+
export declare const makeSimulatorTransactionHistoryService: (config: DefaultTransactionHistoryConfiguration, _getContext: () => unknown) => TransactionHistoryService;
|
|
64
|
+
export {};
|
|
@@ -0,0 +1,98 @@
|
|
|
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 { TransactionHistoryStorage } from '@midnightntwrk/wallet-sdk-abstractions';
|
|
14
|
+
import { Duration, Array as EArray, Effect, Schedule, Schema } from 'effect';
|
|
15
|
+
import { TransactionHistoryDetail } from '@midnightntwrk/wallet-sdk-indexer-client';
|
|
16
|
+
import { HttpQueryClient } from '@midnightntwrk/wallet-sdk-indexer-client/effect';
|
|
17
|
+
import { TransactionHistoryError } from './WalletError.js';
|
|
18
|
+
export const QualifiedShieldedCoinInfoSchema = Schema.Struct({
|
|
19
|
+
type: Schema.String,
|
|
20
|
+
nonce: Schema.String,
|
|
21
|
+
value: Schema.BigInt,
|
|
22
|
+
mtIndex: Schema.BigInt,
|
|
23
|
+
});
|
|
24
|
+
export const ShieldedSectionSchema = Schema.Struct({
|
|
25
|
+
receivedCoins: Schema.Array(QualifiedShieldedCoinInfoSchema),
|
|
26
|
+
spentCoins: Schema.Array(QualifiedShieldedCoinInfoSchema),
|
|
27
|
+
});
|
|
28
|
+
export const ShieldedTransactionHistoryEntrySchema = Schema.Struct({
|
|
29
|
+
hash: TransactionHistoryStorage.TransactionHashSchema,
|
|
30
|
+
protocolVersion: Schema.Number,
|
|
31
|
+
status: TransactionHistoryStorage.TransactionHistoryStatusSchema,
|
|
32
|
+
shielded: ShieldedSectionSchema,
|
|
33
|
+
});
|
|
34
|
+
const coinEquals = Schema.equivalence(QualifiedShieldedCoinInfoSchema);
|
|
35
|
+
export const mergeShieldedSections = (existing, incoming) => ({
|
|
36
|
+
receivedCoins: EArray.unionWith(existing.receivedCoins, incoming.receivedCoins, coinEquals),
|
|
37
|
+
spentCoins: EArray.unionWith(existing.spentCoins, incoming.spentCoins, coinEquals),
|
|
38
|
+
});
|
|
39
|
+
const convertUpdateToStorageEntry = (changes, metadata, protocolVersion) => ({
|
|
40
|
+
hash: changes.source,
|
|
41
|
+
protocolVersion,
|
|
42
|
+
status: metadata.status,
|
|
43
|
+
shielded: {
|
|
44
|
+
receivedCoins: changes.receivedCoins.map(({ mt_index, ...rest }) => ({ ...rest, mtIndex: mt_index })),
|
|
45
|
+
spentCoins: changes.spentCoins.map(({ mt_index, ...rest }) => ({ ...rest, mtIndex: mt_index })),
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
const upsertShieldedEntry = (txHistoryStorage, entry) => Effect.tryPromise({
|
|
49
|
+
try: () => txHistoryStorage.upsert(entry),
|
|
50
|
+
catch: (e) => new TransactionHistoryError({ message: `Failed to upsert history entry for ${entry.hash}`, cause: e }),
|
|
51
|
+
});
|
|
52
|
+
export const makeDefaultTransactionHistoryService = (config, _getContext) => {
|
|
53
|
+
const txHistoryStorage = config.txHistoryStorage;
|
|
54
|
+
const queryClientLayer = HttpQueryClient.layer({ url: config.indexerClientConnection.indexerHttpUrl });
|
|
55
|
+
return {
|
|
56
|
+
put: (changes, metadata, protocolVersion) => {
|
|
57
|
+
const entry = convertUpdateToStorageEntry(changes, metadata, protocolVersion);
|
|
58
|
+
return upsertShieldedEntry(txHistoryStorage, entry);
|
|
59
|
+
},
|
|
60
|
+
getTransactionDetails: (hash) => Effect.gen(function* () {
|
|
61
|
+
const statusQuery = yield* TransactionHistoryDetail;
|
|
62
|
+
const result = yield* statusQuery({ transactionHash: hash });
|
|
63
|
+
const tx = result.transactions[0];
|
|
64
|
+
const rawStatus = tx.__typename === 'RegularTransaction' ? tx.transactionResult.status : undefined;
|
|
65
|
+
const status = rawStatus === 'FAILURE' || rawStatus === 'PARTIAL_SUCCESS' ? rawStatus : 'SUCCESS';
|
|
66
|
+
return {
|
|
67
|
+
hash: tx.hash,
|
|
68
|
+
timestamp: tx.block.timestamp,
|
|
69
|
+
status,
|
|
70
|
+
};
|
|
71
|
+
}).pipe(Effect.provide(queryClientLayer), Effect.scoped, Effect.retry(Schedule.exponential(Duration.seconds(1)).pipe(Schedule.compose(Schedule.recurs(3)))), Effect.mapError((cause) => new TransactionHistoryError({
|
|
72
|
+
message: `Failed to fetch transaction metadata for ${hash}`,
|
|
73
|
+
cause,
|
|
74
|
+
}))),
|
|
75
|
+
};
|
|
76
|
+
};
|
|
77
|
+
export const makeSimulatorTransactionHistoryService = (config, _getContext) => {
|
|
78
|
+
const txHistoryStorage = config.txHistoryStorage;
|
|
79
|
+
return {
|
|
80
|
+
put: (changes, metadata, protocolVersion) => {
|
|
81
|
+
const entry = convertUpdateToStorageEntry(changes, metadata, protocolVersion);
|
|
82
|
+
return upsertShieldedEntry(txHistoryStorage, {
|
|
83
|
+
...entry,
|
|
84
|
+
timestamp: new Date(metadata.timestamp),
|
|
85
|
+
});
|
|
86
|
+
},
|
|
87
|
+
getTransactionDetails: (hash) => Effect.tryPromise({
|
|
88
|
+
try: () => txHistoryStorage.get(hash),
|
|
89
|
+
catch: (e) => new TransactionHistoryError({ message: `Failed to get transaction details for ${hash}`, cause: e }),
|
|
90
|
+
}).pipe(Effect.flatMap((entry) => entry
|
|
91
|
+
? Effect.succeed({
|
|
92
|
+
hash: entry.hash,
|
|
93
|
+
timestamp: entry.timestamp ? entry.timestamp.getTime() : Date.now(),
|
|
94
|
+
status: entry.status,
|
|
95
|
+
})
|
|
96
|
+
: Effect.fail(new TransactionHistoryError({ message: `No transaction found in storage for hash: ${hash}` })))),
|
|
97
|
+
};
|
|
98
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Imbalances, type TransactionCostModel } from '@midnightntwrk/wallet-sdk-capabilities';
|
|
2
|
+
export declare const ShieldedCostModel: TransactionCostModel;
|
|
3
|
+
export type TransactionImbalances = Readonly<{
|
|
4
|
+
guaranteed: Imbalances;
|
|
5
|
+
fallible: ReadonlyMap<number, Imbalances>;
|
|
6
|
+
}>;
|
|
7
|
+
export declare const TransactionImbalances: {
|
|
8
|
+
empty: () => TransactionImbalances;
|
|
9
|
+
areBalanced: (imbalances: TransactionImbalances) => boolean;
|
|
10
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
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 { Imbalances } from '@midnightntwrk/wallet-sdk-capabilities';
|
|
14
|
+
export const ShieldedCostModel = {
|
|
15
|
+
inputFeeOverhead: 0n,
|
|
16
|
+
outputFeeOverhead: 0n,
|
|
17
|
+
};
|
|
18
|
+
export const TransactionImbalances = new (class {
|
|
19
|
+
empty = () => {
|
|
20
|
+
return {
|
|
21
|
+
guaranteed: Imbalances.empty(),
|
|
22
|
+
fallible: new Map(),
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
areBalanced = (imbalances) => {
|
|
26
|
+
const areGuaranteedAllZeroes = imbalances.guaranteed.entries().every(([, value]) => value === 0n);
|
|
27
|
+
const areFallibleAllZeroes = Array.from(imbalances.fallible.values()).every((segmentImbalances) => segmentImbalances.entries().every(([, value]) => value === 0n));
|
|
28
|
+
return areGuaranteedAllZeroes && areFallibleAllZeroes;
|
|
29
|
+
};
|
|
30
|
+
})();
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Imbalances } from '@midnightntwrk/wallet-sdk-capabilities';
|
|
2
|
+
import { type TransactionImbalances } from './TransactionImbalances.js';
|
|
3
|
+
import type * as ledger from '@midnight-ntwrk/ledger-v8';
|
|
4
|
+
export type TransactionOps<Tx> = {
|
|
5
|
+
getImbalances(tx: Tx): TransactionImbalances;
|
|
6
|
+
id(tx: Tx): string;
|
|
7
|
+
};
|
|
8
|
+
export declare const TransactionOps: {
|
|
9
|
+
default: TransactionOps<ledger.FinalizedTransaction>;
|
|
10
|
+
proofErased: TransactionOps<ledger.ProofErasedTransaction>;
|
|
11
|
+
unproven: TransactionOps<ledger.UnprovenTransaction>;
|
|
12
|
+
shared: {
|
|
13
|
+
getImbalances(tx: ledger.FinalizedTransaction | ledger.UnprovenTransaction | ledger.ProofErasedTransaction): TransactionImbalances;
|
|
14
|
+
getGuaranteedImbalances: (tx: ledger.FinalizedTransaction | ledger.UnprovenTransaction | ledger.ProofErasedTransaction) => Imbalances;
|
|
15
|
+
getFallibleImbalances: (tx: ledger.FinalizedTransaction | ledger.UnprovenTransaction | ledger.ProofErasedTransaction) => ReadonlyMap<number, Imbalances>;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
@@ -0,0 +1,73 @@
|
|
|
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 { Imbalances } from '@midnightntwrk/wallet-sdk-capabilities';
|
|
14
|
+
export const TransactionOps = new (class {
|
|
15
|
+
default = {
|
|
16
|
+
getImbalances(tx) {
|
|
17
|
+
return TransactionOps.shared.getImbalances(tx);
|
|
18
|
+
},
|
|
19
|
+
id(tx) {
|
|
20
|
+
return tx.identifiers().at(0);
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
proofErased = {
|
|
24
|
+
getImbalances(tx) {
|
|
25
|
+
return TransactionOps.shared.getImbalances(tx);
|
|
26
|
+
},
|
|
27
|
+
id(tx) {
|
|
28
|
+
return tx.identifiers().at(0);
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
unproven = {
|
|
32
|
+
getImbalances(tx) {
|
|
33
|
+
return TransactionOps.shared.getImbalances(tx);
|
|
34
|
+
},
|
|
35
|
+
id(tx) {
|
|
36
|
+
return tx.identifiers().at(0);
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
shared = {
|
|
40
|
+
getImbalances(tx) {
|
|
41
|
+
const guaranteedImbalances = TransactionOps.shared.getGuaranteedImbalances(tx);
|
|
42
|
+
const fallibleImbalances = TransactionOps.shared.getFallibleImbalances(tx);
|
|
43
|
+
return {
|
|
44
|
+
guaranteed: guaranteedImbalances,
|
|
45
|
+
fallible: fallibleImbalances,
|
|
46
|
+
};
|
|
47
|
+
},
|
|
48
|
+
getGuaranteedImbalances: (tx) => {
|
|
49
|
+
const rawGuaranteedImbalances = tx
|
|
50
|
+
.imbalances(0)
|
|
51
|
+
.entries()
|
|
52
|
+
.filter(([token]) => token.tag === 'shielded')
|
|
53
|
+
.map(([token, value]) => {
|
|
54
|
+
return [token.raw, value];
|
|
55
|
+
});
|
|
56
|
+
return Imbalances.fromEntries(rawGuaranteedImbalances);
|
|
57
|
+
},
|
|
58
|
+
getFallibleImbalances: (tx) => {
|
|
59
|
+
const segments = Array.from(tx.fallibleOffer?.keys() ?? []);
|
|
60
|
+
const fallibleImbalances = segments.flatMap((segment) => {
|
|
61
|
+
const rawImbalances = tx
|
|
62
|
+
.imbalances(segment)
|
|
63
|
+
.entries()
|
|
64
|
+
.filter(([token]) => token.tag === 'shielded')
|
|
65
|
+
.map(([token, value]) => {
|
|
66
|
+
return [token.raw, value];
|
|
67
|
+
});
|
|
68
|
+
return [[segment, Imbalances.fromEntries(rawImbalances)]];
|
|
69
|
+
});
|
|
70
|
+
return new Map(fallibleImbalances);
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
})();
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import * as ledger from '@midnight-ntwrk/ledger-v8';
|
|
2
|
+
import { type Either, type Types } from 'effect';
|
|
3
|
+
import { type NetworkId } from '@midnightntwrk/wallet-sdk-abstractions';
|
|
4
|
+
import { type Variant, type VariantBuilder } from '@midnightntwrk/wallet-sdk-runtime/abstractions';
|
|
5
|
+
import { RunningV1Variant, V1Tag } from './RunningV1Variant.js';
|
|
6
|
+
import { type SerializationCapability } from './Serialization.js';
|
|
7
|
+
import { type DefaultSyncContext, type DefaultSyncConfiguration, type ChangesResult, type SyncCapability, type SyncService, type WalletSyncUpdate } from './Sync.js';
|
|
8
|
+
import { type DefaultTransactingConfiguration, type DefaultTransactingContext, type TransactingCapability } from './Transacting.js';
|
|
9
|
+
import { type WalletError } from './WalletError.js';
|
|
10
|
+
import { type CoinsAndBalancesCapability } from './CoinsAndBalances.js';
|
|
11
|
+
import { type KeysCapability } from './Keys.js';
|
|
12
|
+
import { type CoinSelection } from '@midnightntwrk/wallet-sdk-capabilities';
|
|
13
|
+
import { CoreWallet } from './CoreWallet.js';
|
|
14
|
+
import { type DefaultTransactionHistoryConfiguration, type TransactionHistoryService } from './TransactionHistory.js';
|
|
15
|
+
export type BaseV1Configuration = {
|
|
16
|
+
networkId: NetworkId.NetworkId;
|
|
17
|
+
};
|
|
18
|
+
export type DefaultV1Configuration = BaseV1Configuration & DefaultSyncConfiguration & DefaultTransactingConfiguration & DefaultTransactionHistoryConfiguration;
|
|
19
|
+
declare const V1BuilderSymbol: {
|
|
20
|
+
readonly typeId: unique symbol;
|
|
21
|
+
};
|
|
22
|
+
export type V1Variant<TSerialized, TSyncUpdate, TTransaction, TAuxData> = Variant.Variant<typeof V1Tag, CoreWallet, null, RunningV1Variant<TSerialized, TSyncUpdate, TTransaction, TAuxData>> & {
|
|
23
|
+
deserializeState: (serialized: TSerialized) => Either.Either<CoreWallet, WalletError>;
|
|
24
|
+
coinsAndBalances: CoinsAndBalancesCapability<CoreWallet>;
|
|
25
|
+
keys: KeysCapability<CoreWallet>;
|
|
26
|
+
serialization: SerializationCapability<CoreWallet, null, TSerialized>;
|
|
27
|
+
transactionHistory: TransactionHistoryService;
|
|
28
|
+
};
|
|
29
|
+
export type AnyV1Variant = V1Variant<any, any, any, any>;
|
|
30
|
+
export type DefaultV1Variant = V1Variant<string, WalletSyncUpdate, ledger.FinalizedTransaction, ledger.ZswapSecretKeys>;
|
|
31
|
+
export type TransactionOf<T extends AnyV1Variant> = T extends V1Variant<any, any, infer TTransaction, any> ? TTransaction : never;
|
|
32
|
+
export type AuxDataOf<T extends AnyV1Variant> = T extends V1Variant<any, any, any, infer TAuxData> ? TAuxData : never;
|
|
33
|
+
export type SerializedStateOf<T extends AnyV1Variant> = T extends V1Variant<infer TSerialized, any, any, any> ? TSerialized : never;
|
|
34
|
+
export type DefaultV1Builder = V1Builder<DefaultV1Configuration, RunningV1Variant.Context<string, WalletSyncUpdate, ledger.FinalizedTransaction, ledger.ZswapSecretKeys>, string, WalletSyncUpdate, ledger.FinalizedTransaction, ledger.ZswapSecretKeys>;
|
|
35
|
+
export declare class V1Builder<TConfig extends BaseV1Configuration = BaseV1Configuration, TContext extends Partial<RunningV1Variant.AnyContext> = object, TSerialized = never, TSyncUpdate = never, TTransaction = never, TStartAux extends object = object> implements VariantBuilder.VariantBuilder<V1Variant<TSerialized, TSyncUpdate, TTransaction, TStartAux>, TConfig> {
|
|
36
|
+
#private;
|
|
37
|
+
constructor(buildState?: V1Builder.PartialBuildState<TConfig, TContext, TSerialized, TSyncUpdate, TTransaction, TStartAux>);
|
|
38
|
+
withDefaults(): DefaultV1Builder;
|
|
39
|
+
withTransactionType<Transaction>(): V1Builder<TConfig, TContext, TSerialized, TSyncUpdate, Transaction, TStartAux>;
|
|
40
|
+
withDefaultTransactionType(): V1Builder<TConfig, TContext, TSerialized, TSyncUpdate, ledger.FinalizedTransaction, TStartAux>;
|
|
41
|
+
withSyncDefaults(): V1Builder<TConfig & DefaultSyncConfiguration, TContext & DefaultSyncContext, TSerialized, WalletSyncUpdate, TTransaction, ledger.ZswapSecretKeys>;
|
|
42
|
+
withSync<TSyncConfig, TSyncContext extends Partial<RunningV1Variant.AnyContext>, TSyncUpdate, TStartAux extends object>(syncService: (configuration: TSyncConfig, getContext: () => TSyncContext) => SyncService<CoreWallet, TStartAux, TSyncUpdate>, syncCapability: (configuration: TSyncConfig, getContext: () => TSyncContext) => SyncCapability<CoreWallet, TSyncUpdate, ChangesResult>): V1Builder<TConfig & TSyncConfig, TContext & TSyncContext, TSerialized, TSyncUpdate, TTransaction, TStartAux>;
|
|
43
|
+
withSerializationDefaults(): V1Builder<TConfig, TContext, string, TSyncUpdate, TTransaction, TStartAux>;
|
|
44
|
+
withSerialization<TSerializationConfig, TSerializationContext extends Partial<RunningV1Variant.AnyContext>, TSerialized>(serializationCapability: (configuration: TSerializationConfig, getContext: () => TSerializationContext) => SerializationCapability<CoreWallet, null, TSerialized>): V1Builder<TConfig & TSerializationConfig, TContext & TSerializationContext, TSerialized, TSyncUpdate, TTransaction, TStartAux>;
|
|
45
|
+
withTransactingDefaults(this: V1Builder<TConfig, TContext, TSerialized, TSyncUpdate, ledger.FinalizedTransaction, TStartAux>): V1Builder<TConfig & DefaultTransactingConfiguration, TContext & DefaultTransactingContext, TSerialized, TSyncUpdate, ledger.FinalizedTransaction, TStartAux>;
|
|
46
|
+
withTransacting<TTransactingConfig, TTransactingContext extends Partial<RunningV1Variant.AnyContext>>(transactingCapability: (config: TTransactingConfig, getContext: () => TTransactingContext) => TransactingCapability<ledger.ZswapSecretKeys, CoreWallet, TTransaction>): V1Builder<TConfig & TTransactingConfig, TContext & TTransactingContext, TSerialized, TSyncUpdate, TTransaction, TStartAux>;
|
|
47
|
+
withCoinSelection<TCoinSelectionConfig, TCoinSelectionContext extends Partial<RunningV1Variant.AnyContext>>(coinSelection: (config: TCoinSelectionConfig, getContext: () => TCoinSelectionContext) => CoinSelection<ledger.QualifiedShieldedCoinInfo>): V1Builder<TConfig & TCoinSelectionConfig, TContext & TCoinSelectionContext, TSerialized, TSyncUpdate, TTransaction, TStartAux>;
|
|
48
|
+
withCoinSelectionDefaults(): V1Builder<TConfig, TContext, TSerialized, TSyncUpdate, TTransaction, TStartAux>;
|
|
49
|
+
withCoinsAndBalancesDefaults(): V1Builder<TConfig, TContext, TSerialized, TSyncUpdate, TTransaction, TStartAux>;
|
|
50
|
+
withCoinsAndBalances<TBalancesConfig, TBalancesContext extends Partial<RunningV1Variant.AnyContext>>(coinsAndBalancesCapability: (configuration: TBalancesConfig, getContext: () => TBalancesContext) => CoinsAndBalancesCapability<CoreWallet>): V1Builder<TConfig & TBalancesConfig, TContext & TBalancesContext, TSerialized, TSyncUpdate, TTransaction, TStartAux>;
|
|
51
|
+
withTransactionHistoryDefaults(this: V1Builder<TConfig, TContext, TSerialized, TSyncUpdate, ledger.FinalizedTransaction, TStartAux>): V1Builder<TConfig & DefaultTransactionHistoryConfiguration, TContext, TSerialized, TSyncUpdate, ledger.FinalizedTransaction, TStartAux>;
|
|
52
|
+
withTransactionHistory<TTransactionHistoryConfig, TTransactionHistoryContext extends Partial<RunningV1Variant.AnyContext>>(transactionHistoryService: (configuration: TTransactionHistoryConfig, getContext: () => TTransactionHistoryContext) => TransactionHistoryService): V1Builder<TConfig & TTransactionHistoryConfig, TContext & TTransactionHistoryContext, TSerialized, TSyncUpdate, TTransaction, TStartAux>;
|
|
53
|
+
withKeysDefaults(): V1Builder<TConfig, TContext, TSerialized, TSyncUpdate, TTransaction, TStartAux>;
|
|
54
|
+
withKeys<TKeysConfig, TKeysContext extends Partial<RunningV1Variant.AnyContext>>(keysCapability: (configuration: TKeysConfig, getContext: () => TKeysContext) => KeysCapability<CoreWallet>): V1Builder<TConfig & TKeysConfig, TContext & TKeysContext, TSerialized, TSyncUpdate, TTransaction, TStartAux>;
|
|
55
|
+
build(this: V1Builder<TConfig, RunningV1Variant.Context<TSerialized, TSyncUpdate, TTransaction, TStartAux>, TSerialized, TSyncUpdate, TTransaction, TStartAux>, configuration: TConfig): V1Variant<TSerialized, TSyncUpdate, TTransaction, TStartAux>;
|
|
56
|
+
}
|
|
57
|
+
/** @internal */
|
|
58
|
+
declare namespace V1Builder {
|
|
59
|
+
type HasSync<TConfig, TContext, TSyncUpdate, TStartAux> = {
|
|
60
|
+
readonly syncService: (configuration: TConfig, getContext: () => TContext) => SyncService<CoreWallet, TStartAux, TSyncUpdate>;
|
|
61
|
+
readonly syncCapability: (configuration: TConfig, getContext: () => TContext) => SyncCapability<CoreWallet, TSyncUpdate, ChangesResult>;
|
|
62
|
+
};
|
|
63
|
+
type HasTransacting<TConfig, TContext, TTransaction> = {
|
|
64
|
+
readonly transactingCapability: (configuration: TConfig, getContext: () => TContext) => TransactingCapability<ledger.ZswapSecretKeys, CoreWallet, TTransaction>;
|
|
65
|
+
};
|
|
66
|
+
type HasCoinSelection<TConfig, TContext> = {
|
|
67
|
+
readonly coinSelection: (configuration: TConfig, getContext: () => TContext) => CoinSelection<ledger.QualifiedShieldedCoinInfo>;
|
|
68
|
+
};
|
|
69
|
+
type HasSerialization<TConfig, TContext, TSerialized> = {
|
|
70
|
+
readonly serializationCapability: (configuration: TConfig, getContext: () => TContext) => SerializationCapability<CoreWallet, null, TSerialized>;
|
|
71
|
+
};
|
|
72
|
+
type HasCoinsAndBalances<TConfig, TContext> = {
|
|
73
|
+
readonly coinsAndBalancesCapability: (configuration: TConfig, getContext: () => TContext) => CoinsAndBalancesCapability<CoreWallet>;
|
|
74
|
+
};
|
|
75
|
+
type HasTransactionHistory<TConfig, TContext> = {
|
|
76
|
+
readonly transactionHistoryService: (configuration: TConfig, getContext: () => TContext) => TransactionHistoryService;
|
|
77
|
+
};
|
|
78
|
+
type HasKeys<TConfig, TContext> = {
|
|
79
|
+
readonly keysCapability: (configuration: TConfig, getContext: () => TContext) => KeysCapability<CoreWallet>;
|
|
80
|
+
};
|
|
81
|
+
/** The internal build state of {@link V1Builder}. */
|
|
82
|
+
type FullBuildState<TConfig, TContext, TSerialized, TSyncUpdate, TTransaction, TStartAux> = Types.Simplify<HasSync<TConfig, TContext, TSyncUpdate, TStartAux> & HasSerialization<TConfig, TContext, TSerialized> & HasTransacting<TConfig, TContext, TTransaction> & HasCoinSelection<TConfig, TContext> & HasCoinsAndBalances<TConfig, TContext> & HasKeys<TConfig, TContext> & HasTransactionHistory<TConfig, TContext>>;
|
|
83
|
+
type PartialBuildState<TConfig = object, TContext = object, TSerialized = never, TSyncUpdate = never, TTransaction = never, TStartAux = object> = {
|
|
84
|
+
[K in keyof FullBuildState<never, never, never, never, never, never>]?: FullBuildState<TConfig, TContext, TSerialized, TSyncUpdate, TTransaction, TStartAux>[K] | undefined;
|
|
85
|
+
};
|
|
86
|
+
/** Utility interface that manages the type variance of {@link V1Builder}. */
|
|
87
|
+
interface Variance<R> {
|
|
88
|
+
readonly [V1BuilderSymbol.typeId]: {
|
|
89
|
+
readonly _R: Types.Covariant<R>;
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
export {};
|