@midnight-ntwrk/wallet-sdk-facade 1.0.0-beta.14 → 1.0.0-beta.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +38 -11
- package/dist/index.js +165 -100
- package/package.json +7 -6
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,24 @@
|
|
|
1
1
|
import { Observable } from 'rxjs';
|
|
2
2
|
import { ShieldedWalletState, type ShieldedWallet } from '@midnight-ntwrk/wallet-sdk-shielded';
|
|
3
3
|
import { type UnshieldedWallet, UnshieldedWalletState } from '@midnight-ntwrk/wallet-sdk-unshielded-wallet';
|
|
4
|
-
import { AnyTransaction, DustWallet, DustWalletState } from '@midnight-ntwrk/wallet-sdk-dust-wallet';
|
|
5
|
-
import { ProvingRecipe } from '@midnight-ntwrk/wallet-sdk-shielded/v1';
|
|
4
|
+
import { AnyTransaction, DustWallet, DustWalletState, CoinsAndBalances as DustCoinsAndBalances } from '@midnight-ntwrk/wallet-sdk-dust-wallet';
|
|
6
5
|
import * as ledger from '@midnight-ntwrk/ledger-v7';
|
|
6
|
+
export type UnboundTransaction = ledger.Transaction<ledger.SignatureEnabled, ledger.Proof, ledger.PreBinding>;
|
|
7
|
+
export type FinalizedTransactionRecipe = {
|
|
8
|
+
type: 'FINALIZED_TRANSACTION';
|
|
9
|
+
originalTransaction: ledger.FinalizedTransaction;
|
|
10
|
+
balancingTransaction: ledger.UnprovenTransaction;
|
|
11
|
+
};
|
|
12
|
+
export type UnboundTransactionRecipe = {
|
|
13
|
+
type: 'UNBOUND_TRANSACTION';
|
|
14
|
+
baseTransaction: UnboundTransaction;
|
|
15
|
+
balancingTransaction: ledger.UnprovenTransaction;
|
|
16
|
+
};
|
|
17
|
+
export type UnprovenTransactionRecipe = {
|
|
18
|
+
type: 'UNPROVEN_TRANSACTION';
|
|
19
|
+
transaction: ledger.UnprovenTransaction;
|
|
20
|
+
};
|
|
21
|
+
export type BalancingRecipe = FinalizedTransactionRecipe | UnboundTransactionRecipe | UnprovenTransactionRecipe;
|
|
7
22
|
export interface TokenTransfer {
|
|
8
23
|
type: ledger.RawTokenType;
|
|
9
24
|
receiverAddress: string;
|
|
@@ -33,20 +48,32 @@ export declare class FacadeState {
|
|
|
33
48
|
constructor(shielded: ShieldedWalletState, unshielded: UnshieldedWalletState, dust: DustWalletState);
|
|
34
49
|
}
|
|
35
50
|
export declare class WalletFacade {
|
|
36
|
-
shielded: ShieldedWallet;
|
|
37
|
-
unshielded: UnshieldedWallet;
|
|
38
|
-
dust: DustWallet;
|
|
51
|
+
readonly shielded: ShieldedWallet;
|
|
52
|
+
readonly unshielded: UnshieldedWallet;
|
|
53
|
+
readonly dust: DustWallet;
|
|
39
54
|
constructor(shieldedWallet: ShieldedWallet, unshieldedWallet: UnshieldedWallet, dustWallet: DustWallet);
|
|
55
|
+
private defaultTtl;
|
|
56
|
+
private mergeUnprovenTransactions;
|
|
57
|
+
private createDustActionTransaction;
|
|
40
58
|
state(): Observable<FacadeState>;
|
|
59
|
+
waitForSyncedState(): Promise<FacadeState>;
|
|
41
60
|
submitTransaction(tx: ledger.FinalizedTransaction): Promise<TransactionIdentifier>;
|
|
42
|
-
|
|
43
|
-
|
|
61
|
+
balanceFinalizedTransaction(zswapSecretKeys: ledger.ZswapSecretKeys, dustSecretKeys: ledger.DustSecretKey, tx: ledger.FinalizedTransaction, ttl: Date): Promise<FinalizedTransactionRecipe>;
|
|
62
|
+
balanceUnboundTransaction(zswapSecretKeys: ledger.ZswapSecretKeys, dustSecretKeys: ledger.DustSecretKey, tx: UnboundTransaction, ttl: Date): Promise<UnboundTransactionRecipe>;
|
|
63
|
+
balanceUnprovenTransaction(zswapSecretKeys: ledger.ZswapSecretKeys, dustSecretKeys: ledger.DustSecretKey, tx: ledger.UnprovenTransaction, ttl: Date): Promise<UnprovenTransactionRecipe>;
|
|
64
|
+
finalizeRecipe(recipe: BalancingRecipe): Promise<ledger.FinalizedTransaction>;
|
|
65
|
+
signRecipe(recipe: BalancingRecipe, signSegment: (data: Uint8Array) => ledger.Signature): Promise<BalancingRecipe>;
|
|
44
66
|
signTransaction(tx: ledger.UnprovenTransaction, signSegment: (data: Uint8Array) => ledger.Signature): Promise<ledger.UnprovenTransaction>;
|
|
67
|
+
finalizeTransaction(tx: ledger.UnprovenTransaction): Promise<ledger.FinalizedTransaction>;
|
|
45
68
|
calculateTransactionFee(tx: AnyTransaction): Promise<bigint>;
|
|
46
|
-
transferTransaction(zswapSecretKeys: ledger.ZswapSecretKeys, dustSecretKey: ledger.DustSecretKey, outputs: CombinedTokenTransfer[], ttl: Date): Promise<
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
69
|
+
transferTransaction(zswapSecretKeys: ledger.ZswapSecretKeys, dustSecretKey: ledger.DustSecretKey, outputs: CombinedTokenTransfer[], ttl: Date): Promise<UnprovenTransactionRecipe>;
|
|
70
|
+
estimateRegistration(nightUtxos: readonly UtxoWithMeta[]): Promise<{
|
|
71
|
+
fee: bigint;
|
|
72
|
+
dustGenerationEstimations: ReadonlyArray<DustCoinsAndBalances.UtxoWithFullDustDetails>;
|
|
73
|
+
}>;
|
|
74
|
+
initSwap(zswapSecretKeys: ledger.ZswapSecretKeys, desiredInputs: CombinedSwapInputs, desiredOutputs: CombinedSwapOutputs[], ttl: Date): Promise<UnprovenTransactionRecipe>;
|
|
75
|
+
registerNightUtxosForDustGeneration(nightUtxos: readonly UtxoWithMeta[], nightVerifyingKey: ledger.SignatureVerifyingKey, signDustRegistration: (payload: Uint8Array) => ledger.Signature, dustReceiverAddress?: string): Promise<UnprovenTransactionRecipe>;
|
|
76
|
+
deregisterFromDustGeneration(nightUtxos: UtxoWithMeta[], nightVerifyingKey: ledger.SignatureVerifyingKey, signDustRegistration: (payload: Uint8Array) => ledger.Signature): Promise<UnprovenTransactionRecipe>;
|
|
50
77
|
start(zswapSecretKeys: ledger.ZswapSecretKeys, dustSecretKey: ledger.DustSecretKey): Promise<void>;
|
|
51
78
|
stop(): Promise<void>;
|
|
52
79
|
}
|
package/dist/index.js
CHANGED
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
// See the License for the specific language governing permissions and
|
|
12
12
|
// limitations under the License.
|
|
13
13
|
import { combineLatest, map } from 'rxjs';
|
|
14
|
-
import {
|
|
14
|
+
import { Array as Arr, pipe } from 'effect';
|
|
15
|
+
import * as ledger from '@midnight-ntwrk/ledger-v7';
|
|
15
16
|
export class FacadeState {
|
|
16
17
|
shielded;
|
|
17
18
|
unshielded;
|
|
@@ -27,6 +28,7 @@ export class FacadeState {
|
|
|
27
28
|
this.dust = dust;
|
|
28
29
|
}
|
|
29
30
|
}
|
|
31
|
+
const DEFAULT_TTL_MS = 60 * 60 * 1000; // 1 hour
|
|
30
32
|
export class WalletFacade {
|
|
31
33
|
shielded;
|
|
32
34
|
unshielded;
|
|
@@ -36,45 +38,140 @@ export class WalletFacade {
|
|
|
36
38
|
this.unshielded = unshieldedWallet;
|
|
37
39
|
this.dust = dustWallet;
|
|
38
40
|
}
|
|
41
|
+
defaultTtl() {
|
|
42
|
+
return new Date(Date.now() + DEFAULT_TTL_MS);
|
|
43
|
+
}
|
|
44
|
+
mergeUnprovenTransactions(a, b) {
|
|
45
|
+
if (a && b)
|
|
46
|
+
return a.merge(b);
|
|
47
|
+
return a ?? b;
|
|
48
|
+
}
|
|
49
|
+
async createDustActionTransaction(action, nightUtxos, nightVerifyingKey, signDustRegistration) {
|
|
50
|
+
const ttl = this.defaultTtl();
|
|
51
|
+
const transaction = await this.dust.createDustGenerationTransaction(undefined, ttl, nightUtxos.map(({ utxo, meta }) => ({ ...utxo, ctime: meta.ctime })), nightVerifyingKey, action.type === 'registration' ? action.dustReceiverAddress : undefined);
|
|
52
|
+
const intent = transaction.intents?.get(1);
|
|
53
|
+
if (!intent) {
|
|
54
|
+
throw Error('Dust generation transaction is missing intent segment 1.');
|
|
55
|
+
}
|
|
56
|
+
const signatureData = intent.signatureData(1);
|
|
57
|
+
const signature = await Promise.resolve(signDustRegistration(signatureData));
|
|
58
|
+
return await this.dust.addDustGenerationSignature(transaction, signature);
|
|
59
|
+
}
|
|
39
60
|
state() {
|
|
40
61
|
return combineLatest([this.shielded.state, this.unshielded.state, this.dust.state]).pipe(map(([shieldedState, unshieldedState, dustState]) => new FacadeState(shieldedState, unshieldedState, dustState)));
|
|
41
62
|
}
|
|
63
|
+
async waitForSyncedState() {
|
|
64
|
+
const [shieldedState, unshieldedState, dustState] = await Promise.all([
|
|
65
|
+
this.shielded.waitForSyncedState(),
|
|
66
|
+
this.unshielded.waitForSyncedState(),
|
|
67
|
+
this.dust.waitForSyncedState(),
|
|
68
|
+
]);
|
|
69
|
+
return new FacadeState(shieldedState, unshieldedState, dustState);
|
|
70
|
+
}
|
|
42
71
|
async submitTransaction(tx) {
|
|
43
72
|
await this.shielded.submitTransaction(tx, 'Finalized');
|
|
44
73
|
return tx.identifiers().at(-1);
|
|
45
74
|
}
|
|
46
|
-
async
|
|
47
|
-
const
|
|
48
|
-
const
|
|
75
|
+
async balanceFinalizedTransaction(zswapSecretKeys, dustSecretKeys, tx, ttl) {
|
|
76
|
+
const unshieldedBalancing = await this.unshielded.balanceFinalizedTransaction(tx);
|
|
77
|
+
const shieldedBalancing = await this.shielded.balanceTransaction(zswapSecretKeys, tx);
|
|
78
|
+
const mergedBalancing = this.mergeUnprovenTransactions(shieldedBalancing, unshieldedBalancing);
|
|
79
|
+
const feeBalancingTransaction = await this.dust.balanceTransactions(dustSecretKeys, mergedBalancing ? [tx, mergedBalancing] : [tx], ttl);
|
|
80
|
+
const balancingTransaction = mergedBalancing
|
|
81
|
+
? mergedBalancing.merge(feeBalancingTransaction)
|
|
82
|
+
: feeBalancingTransaction;
|
|
83
|
+
return {
|
|
84
|
+
type: 'FINALIZED_TRANSACTION',
|
|
85
|
+
originalTransaction: tx,
|
|
86
|
+
balancingTransaction,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
async balanceUnboundTransaction(zswapSecretKeys, dustSecretKeys, tx, ttl) {
|
|
90
|
+
// For unbound transactions, unshielded balancing happens in place not with a balancing transaction
|
|
91
|
+
const balancedUnshieldedTx = await this.unshielded.balanceUnboundTransaction(tx);
|
|
92
|
+
const shieldedBalancingTx = await this.shielded.balanceTransaction(zswapSecretKeys, tx);
|
|
93
|
+
// unbound unshielded tx are balanced in place, check if balancedUnshieldedTx is present and use it as base tx
|
|
94
|
+
const baseTx = balancedUnshieldedTx ?? tx;
|
|
95
|
+
// Add fee payment - pass shielded balancing if present, otherwise just calculate fee for base tx
|
|
96
|
+
const transactionsToPayFeesFor = shieldedBalancingTx ? [baseTx, shieldedBalancingTx] : [baseTx];
|
|
97
|
+
const feeBalancingTransaction = await this.dust.balanceTransactions(dustSecretKeys, transactionsToPayFeesFor, ttl);
|
|
98
|
+
// Create the final balancing transaction
|
|
99
|
+
const balancingTransaction = shieldedBalancingTx
|
|
100
|
+
? shieldedBalancingTx.merge(feeBalancingTransaction)
|
|
101
|
+
: feeBalancingTransaction;
|
|
102
|
+
return {
|
|
103
|
+
type: 'UNBOUND_TRANSACTION',
|
|
104
|
+
baseTransaction: baseTx,
|
|
105
|
+
balancingTransaction,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
async balanceUnprovenTransaction(zswapSecretKeys, dustSecretKeys, tx, ttl) {
|
|
109
|
+
// For unproven transactions, unshielded balancing happens in place
|
|
110
|
+
const balancedUnshieldedTx = await this.unshielded.balanceUnprovenTransaction(tx);
|
|
111
|
+
const shieldedBalancingTx = await this.shielded.balanceTransaction(zswapSecretKeys, tx);
|
|
112
|
+
// Use the balanced unshielded tx if present, otherwise use the original tx
|
|
113
|
+
const baseTx = balancedUnshieldedTx ?? tx;
|
|
114
|
+
// Merge shielded balancing into base tx if present
|
|
115
|
+
const mergedTx = shieldedBalancingTx ? baseTx.merge(shieldedBalancingTx) : baseTx;
|
|
116
|
+
// Add fee payment
|
|
117
|
+
const feeBalancingTransaction = await this.dust.balanceTransactions(dustSecretKeys, [mergedTx], ttl);
|
|
118
|
+
const balancedTransaction = mergedTx.merge(feeBalancingTransaction);
|
|
119
|
+
return {
|
|
120
|
+
type: 'UNPROVEN_TRANSACTION',
|
|
121
|
+
transaction: balancedTransaction,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
async finalizeRecipe(recipe) {
|
|
49
125
|
switch (recipe.type) {
|
|
50
|
-
case
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
126
|
+
case 'FINALIZED_TRANSACTION': {
|
|
127
|
+
const finalizedBalancing = await this.finalizeTransaction(recipe.balancingTransaction);
|
|
128
|
+
return recipe.originalTransaction.merge(finalizedBalancing);
|
|
129
|
+
}
|
|
130
|
+
case 'UNBOUND_TRANSACTION': {
|
|
131
|
+
const finalizedBalancingTx = await this.finalizeTransaction(recipe.balancingTransaction);
|
|
132
|
+
const finalizedTransaction = recipe.baseTransaction.bind();
|
|
133
|
+
return finalizedTransaction.merge(finalizedBalancingTx);
|
|
134
|
+
}
|
|
135
|
+
case 'UNPROVEN_TRANSACTION': {
|
|
136
|
+
return await this.finalizeTransaction(recipe.transaction);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
async signRecipe(recipe, signSegment) {
|
|
141
|
+
switch (recipe.type) {
|
|
142
|
+
case 'FINALIZED_TRANSACTION': {
|
|
143
|
+
const signedBalancing = await this.signTransaction(recipe.balancingTransaction, signSegment);
|
|
144
|
+
return {
|
|
145
|
+
type: 'FINALIZED_TRANSACTION',
|
|
146
|
+
originalTransaction: recipe.originalTransaction,
|
|
147
|
+
balancingTransaction: signedBalancing,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
case 'UNBOUND_TRANSACTION': {
|
|
151
|
+
const signedBalancing = await this.signTransaction(recipe.balancingTransaction, signSegment);
|
|
58
152
|
return {
|
|
59
|
-
|
|
60
|
-
|
|
153
|
+
type: 'UNBOUND_TRANSACTION',
|
|
154
|
+
baseTransaction: recipe.baseTransaction,
|
|
155
|
+
balancingTransaction: signedBalancing,
|
|
61
156
|
};
|
|
62
157
|
}
|
|
63
|
-
case
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
158
|
+
case 'UNPROVEN_TRANSACTION': {
|
|
159
|
+
const signedTransaction = await this.signTransaction(recipe.transaction, signSegment);
|
|
160
|
+
return {
|
|
161
|
+
type: 'UNPROVEN_TRANSACTION',
|
|
162
|
+
transaction: signedTransaction,
|
|
163
|
+
};
|
|
67
164
|
}
|
|
68
165
|
}
|
|
69
166
|
}
|
|
70
|
-
async finalizeTransaction(recipe) {
|
|
71
|
-
return await this.shielded.finalizeTransaction(recipe);
|
|
72
|
-
}
|
|
73
167
|
async signTransaction(tx, signSegment) {
|
|
74
168
|
return await this.unshielded.signTransaction(tx, signSegment);
|
|
75
169
|
}
|
|
170
|
+
async finalizeTransaction(tx) {
|
|
171
|
+
return await this.shielded.finalizeTransaction(tx);
|
|
172
|
+
}
|
|
76
173
|
async calculateTransactionFee(tx) {
|
|
77
|
-
return await this.dust.calculateFee(tx);
|
|
174
|
+
return await this.dust.calculateFee([tx]);
|
|
78
175
|
}
|
|
79
176
|
async transferTransaction(zswapSecretKeys, dustSecretKey, outputs, ttl) {
|
|
80
177
|
const unshieldedOutputs = outputs
|
|
@@ -84,66 +181,35 @@ export class WalletFacade {
|
|
|
84
181
|
if (unshieldedOutputs.length === 0 && shieldedOutputs.length === 0) {
|
|
85
182
|
throw Error('At least one shielded or unshielded output is required.');
|
|
86
183
|
}
|
|
87
|
-
let
|
|
88
|
-
let unshieldedTx
|
|
184
|
+
let shieldedTx;
|
|
185
|
+
let unshieldedTx;
|
|
89
186
|
if (unshieldedOutputs.length > 0) {
|
|
90
187
|
unshieldedTx = await this.unshielded.transferTransaction(unshieldedOutputs, ttl);
|
|
91
188
|
}
|
|
92
189
|
if (shieldedOutputs.length > 0) {
|
|
93
|
-
|
|
94
|
-
}
|
|
95
|
-
// if there's a shielded tx only, return it as it's already balanced
|
|
96
|
-
if (shieldedTxRecipe !== undefined && unshieldedTx === undefined) {
|
|
97
|
-
if (shieldedTxRecipe.type !== 'TransactionToProve') {
|
|
98
|
-
throw Error('Unexpected transaction type.');
|
|
99
|
-
}
|
|
100
|
-
const recipe = await this.dust.addFeePayment(dustSecretKey, shieldedTxRecipe.transaction, ttl);
|
|
101
|
-
if (recipe.type !== 'TransactionToProve') {
|
|
102
|
-
throw Error('Unexpected transaction type after adding fee payment.');
|
|
103
|
-
}
|
|
104
|
-
return recipe;
|
|
105
|
-
}
|
|
106
|
-
// if there's an unshielded tx only, pay fees (balance) with shielded wallet
|
|
107
|
-
if (shieldedTxRecipe === undefined && unshieldedTx !== undefined) {
|
|
108
|
-
const recipe = await this.dust.addFeePayment(dustSecretKey, unshieldedTx, ttl);
|
|
109
|
-
if (recipe.type !== 'TransactionToProve') {
|
|
110
|
-
throw Error('Unexpected transaction type after adding fee payment.');
|
|
111
|
-
}
|
|
112
|
-
return recipe;
|
|
190
|
+
shieldedTx = await this.shielded.transferTransaction(zswapSecretKeys, shieldedOutputs);
|
|
113
191
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
if (recipe.type !== 'TransactionToProve') {
|
|
122
|
-
throw Error('Unexpected transaction type after adding fee payment.');
|
|
123
|
-
}
|
|
124
|
-
return recipe;
|
|
125
|
-
}
|
|
126
|
-
throw Error('Unexpected transaction state.');
|
|
192
|
+
const mergedTxs = this.mergeUnprovenTransactions(shieldedTx, unshieldedTx);
|
|
193
|
+
// Add fee payment
|
|
194
|
+
const feeBalancingTransaction = await this.dust.balanceTransactions(dustSecretKey, [mergedTxs], ttl);
|
|
195
|
+
return {
|
|
196
|
+
type: 'UNPROVEN_TRANSACTION',
|
|
197
|
+
transaction: mergedTxs.merge(feeBalancingTransaction),
|
|
198
|
+
};
|
|
127
199
|
}
|
|
128
|
-
async
|
|
129
|
-
|
|
130
|
-
throw Error('At least one Night UTXO is required.');
|
|
131
|
-
}
|
|
200
|
+
async estimateRegistration(nightUtxos) {
|
|
201
|
+
const now = new Date();
|
|
132
202
|
const dustState = await this.dust.waitForSyncedState();
|
|
133
|
-
const
|
|
134
|
-
const
|
|
135
|
-
const
|
|
136
|
-
const
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
if (recipe.type !== ProvingRecipe.TRANSACTION_TO_PROVE) {
|
|
144
|
-
throw Error('Unexpected recipe type returned when registering Night UTXOs.');
|
|
145
|
-
}
|
|
146
|
-
return recipe;
|
|
203
|
+
const dustGenerationEstimations = pipe(nightUtxos, Arr.map(({ utxo, meta }) => ({ ...utxo, ctime: meta.ctime })), (utxosWithMeta) => dustState.estimateDustGeneration(utxosWithMeta, now), (estimatedUtxos) => dustState.capabilities.coinsAndBalances.splitNightUtxos(estimatedUtxos), (split) => split.guaranteed);
|
|
204
|
+
const fakeSigningKey = ledger.sampleSigningKey();
|
|
205
|
+
const fakeVerifyingKey = ledger.signatureVerifyingKey(fakeSigningKey);
|
|
206
|
+
const fakeRegistrationRecipe = await this.registerNightUtxosForDustGeneration(nightUtxos, fakeVerifyingKey, (payload) => ledger.signData(fakeSigningKey, payload), dustState.dustAddress);
|
|
207
|
+
const finalizedFakeTx = fakeRegistrationRecipe.transaction.mockProve().bind();
|
|
208
|
+
const fee = await this.calculateTransactionFee(finalizedFakeTx);
|
|
209
|
+
return {
|
|
210
|
+
fee,
|
|
211
|
+
dustGenerationEstimations,
|
|
212
|
+
};
|
|
147
213
|
}
|
|
148
214
|
async initSwap(zswapSecretKeys, desiredInputs, desiredOutputs, ttl) {
|
|
149
215
|
const { shielded: shieldedInputs, unshielded: unshieldedInputs } = desiredInputs;
|
|
@@ -158,40 +224,39 @@ export class WalletFacade {
|
|
|
158
224
|
if (!hasShieldedPart && !hasUnshieldedPart) {
|
|
159
225
|
throw Error('At least one shielded or unshielded swap is required.');
|
|
160
226
|
}
|
|
161
|
-
const
|
|
227
|
+
const shieldedTx = hasShieldedPart && shieldedInputs !== undefined
|
|
162
228
|
? await this.shielded.initSwap(zswapSecretKeys, shieldedInputs, shieldedOutputs)
|
|
163
229
|
: undefined;
|
|
164
230
|
const unshieldedTx = hasUnshieldedPart && unshieldedInputs !== undefined
|
|
165
231
|
? await this.unshielded.initSwap(unshieldedInputs, unshieldedOutputs, ttl)
|
|
166
232
|
: undefined;
|
|
167
|
-
|
|
168
|
-
|
|
233
|
+
const combinedTx = this.mergeUnprovenTransactions(shieldedTx, unshieldedTx);
|
|
234
|
+
if (!combinedTx) {
|
|
235
|
+
throw Error('Unexpected transaction state.');
|
|
169
236
|
}
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
if (
|
|
177
|
-
|
|
237
|
+
return {
|
|
238
|
+
type: 'UNPROVEN_TRANSACTION',
|
|
239
|
+
transaction: combinedTx,
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
async registerNightUtxosForDustGeneration(nightUtxos, nightVerifyingKey, signDustRegistration, dustReceiverAddress) {
|
|
243
|
+
if (nightUtxos.length === 0) {
|
|
244
|
+
throw Error('At least one Night UTXO is required.');
|
|
178
245
|
}
|
|
179
|
-
|
|
246
|
+
const dustState = await this.dust.waitForSyncedState();
|
|
247
|
+
const receiverAddress = dustReceiverAddress ?? dustState.dustAddress;
|
|
248
|
+
const dustRegistrationTx = await this.createDustActionTransaction({ type: 'registration', dustReceiverAddress: receiverAddress }, nightUtxos, nightVerifyingKey, signDustRegistration);
|
|
249
|
+
return {
|
|
250
|
+
type: 'UNPROVEN_TRANSACTION',
|
|
251
|
+
transaction: dustRegistrationTx,
|
|
252
|
+
};
|
|
180
253
|
}
|
|
181
254
|
async deregisterFromDustGeneration(nightUtxos, nightVerifyingKey, signDustRegistration) {
|
|
182
|
-
const
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
}
|
|
188
|
-
const signatureData = intent.signatureData(1);
|
|
189
|
-
const signature = await Promise.resolve(signDustRegistration(signatureData));
|
|
190
|
-
const recipe = await this.dust.addDustGenerationSignature(transaction, signature);
|
|
191
|
-
if (recipe.type !== ProvingRecipe.TRANSACTION_TO_PROVE) {
|
|
192
|
-
throw Error('Unexpected recipe type returned when registering Night UTXOs.');
|
|
193
|
-
}
|
|
194
|
-
return recipe;
|
|
255
|
+
const dustDeregistrationTx = await this.createDustActionTransaction({ type: 'deregistration' }, nightUtxos, nightVerifyingKey, signDustRegistration);
|
|
256
|
+
return {
|
|
257
|
+
type: 'UNPROVEN_TRANSACTION',
|
|
258
|
+
transaction: dustDeregistrationTx,
|
|
259
|
+
};
|
|
195
260
|
}
|
|
196
261
|
async start(zswapSecretKeys, dustSecretKey) {
|
|
197
262
|
await Promise.all([this.shielded.start(zswapSecretKeys), this.unshielded.start(), this.dust.start(dustSecretKey)]);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@midnight-ntwrk/wallet-sdk-facade",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.16",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -24,16 +24,17 @@
|
|
|
24
24
|
}
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@midnight-ntwrk/ledger-v7": "7.0.0-
|
|
27
|
+
"@midnight-ntwrk/ledger-v7": "7.0.0-rc.1",
|
|
28
28
|
"@midnight-ntwrk/wallet-sdk-abstractions": "1.0.0-beta.10",
|
|
29
|
-
"@midnight-ntwrk/wallet-sdk-address-format": "3.0.0-beta.
|
|
30
|
-
"@midnight-ntwrk/wallet-sdk-dust-wallet": "1.0.0-beta.
|
|
29
|
+
"@midnight-ntwrk/wallet-sdk-address-format": "3.0.0-beta.11",
|
|
30
|
+
"@midnight-ntwrk/wallet-sdk-dust-wallet": "1.0.0-beta.15",
|
|
31
31
|
"@midnight-ntwrk/wallet-sdk-hd": "3.0.0-beta.8",
|
|
32
|
-
"@midnight-ntwrk/wallet-sdk-shielded": "1.0.0-beta.
|
|
33
|
-
"@midnight-ntwrk/wallet-sdk-unshielded-wallet": "1.0.0-beta.
|
|
32
|
+
"@midnight-ntwrk/wallet-sdk-shielded": "1.0.0-beta.16",
|
|
33
|
+
"@midnight-ntwrk/wallet-sdk-unshielded-wallet": "1.0.0-beta.18",
|
|
34
34
|
"rxjs": "^7.5"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
|
+
"@midnight-ntwrk/wallet-sdk-prover-client": "1.0.0-beta.13",
|
|
37
38
|
"eslint": "^9.37.0",
|
|
38
39
|
"prettier": "^3.7.0",
|
|
39
40
|
"publint": "~0.3.14",
|