@midnightntwrk/wallet-sdk-facade 5.0.0-beta.0 → 5.0.0-beta.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/dist/index.d.ts +48 -16
- package/dist/index.js +86 -26
- package/dist/transaction.d.ts +18 -0
- package/dist/transaction.js +24 -0
- package/package.json +10 -10
package/dist/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { type DefaultProvingConfiguration, type ProvingService, type UnboundTran
|
|
|
4
4
|
import { type DefaultDustConfiguration, type DustWalletAPI, type DustWalletState } from '@midnightntwrk/wallet-sdk-dust-wallet';
|
|
5
5
|
import { type AnyTransaction, type CoinsAndBalances as DustCoinsAndBalances } from '@midnightntwrk/wallet-sdk-dust-wallet/v1';
|
|
6
6
|
import { type DefaultShieldedConfiguration, type ShieldedWalletAPI, type ShieldedWalletState } from '@midnightntwrk/wallet-sdk-shielded';
|
|
7
|
-
import type { DefaultUnshieldedConfiguration, UnshieldedWalletAPI } from '@midnightntwrk/wallet-sdk-unshielded-wallet';
|
|
7
|
+
import type { DefaultUnshieldedConfiguration, SignSegment, UnshieldedWalletAPI } from '@midnightntwrk/wallet-sdk-unshielded-wallet';
|
|
8
8
|
import { type UnshieldedWalletState } from '@midnightntwrk/wallet-sdk-unshielded-wallet';
|
|
9
9
|
import { Clock } from '@midnightntwrk/wallet-sdk-utilities';
|
|
10
10
|
import { Schema } from 'effect';
|
|
@@ -14,10 +14,33 @@ import { type DefaultPendingTransactionsServiceConfiguration, PendingTransaction
|
|
|
14
14
|
import { type BlockData, type BlockDataFetcher, type ValidateTxOptions, ValidationFetchError, type ValidationService, WellFormedError, type WellFormedStrictnessFlags } from '@midnightntwrk/wallet-sdk-capabilities/validation';
|
|
15
15
|
import { type DustAddress, type ShieldedAddress, type UnshieldedAddress } from '@midnightntwrk/wallet-sdk-address-format';
|
|
16
16
|
/**
|
|
17
|
-
* Full entry schema for transaction history
|
|
18
|
-
* `
|
|
17
|
+
* Full entry schema for transaction history. The common entry data and wallet-specific sections (`shielded`,
|
|
18
|
+
* `unshielded`, `dust`) live on every entry regardless of lifecycle; the `lifecycle` field is the only discriminator.
|
|
19
|
+
* Pass this to `InMemoryTransactionHistoryStorage` to enable serialize/restore.
|
|
19
20
|
*/
|
|
20
|
-
export declare const WalletEntrySchema: Schema.Struct<{
|
|
21
|
+
export declare const WalletEntrySchema: Schema.Struct<Readonly<{
|
|
22
|
+
hash: typeof Schema.String;
|
|
23
|
+
identifiers: Schema.Array$<typeof Schema.String>;
|
|
24
|
+
protocolVersion: Schema.optional<typeof Schema.Number>;
|
|
25
|
+
status: Schema.optional<Schema.Literal<["SUCCESS", "FAILURE", "PARTIAL_SUCCESS"]>>;
|
|
26
|
+
timestamp: Schema.optional<typeof Schema.Date>;
|
|
27
|
+
fees: Schema.optional<Schema.NullOr<typeof Schema.BigInt>>;
|
|
28
|
+
lifecycle: Schema.Union<[Schema.Struct<{
|
|
29
|
+
status: Schema.Literal<["pending"]>;
|
|
30
|
+
submittedAt: typeof Schema.Date;
|
|
31
|
+
}>, Schema.Struct<{
|
|
32
|
+
status: Schema.Literal<["finalized"]>;
|
|
33
|
+
finalizedBlock: Schema.Struct<{
|
|
34
|
+
hash: typeof Schema.String;
|
|
35
|
+
height: typeof Schema.Number;
|
|
36
|
+
timestamp: typeof Schema.Date;
|
|
37
|
+
}>;
|
|
38
|
+
}>, Schema.Struct<{
|
|
39
|
+
status: Schema.Literal<["rejected"]>;
|
|
40
|
+
rejectedAt: typeof Schema.Date;
|
|
41
|
+
reason: Schema.optional<typeof Schema.String>;
|
|
42
|
+
}>]>;
|
|
43
|
+
}> & {
|
|
21
44
|
shielded: Schema.optional<Schema.Struct<{
|
|
22
45
|
receivedCoins: Schema.Array$<Schema.Struct<{
|
|
23
46
|
type: typeof Schema.String;
|
|
@@ -65,15 +88,19 @@ export declare const WalletEntrySchema: Schema.Struct<{
|
|
|
65
88
|
mtIndex: typeof Schema.BigInt;
|
|
66
89
|
}>>;
|
|
67
90
|
}>>;
|
|
68
|
-
hash: typeof Schema.String;
|
|
69
|
-
protocolVersion: typeof Schema.Number;
|
|
70
|
-
status: Schema.Literal<["SUCCESS", "FAILURE", "PARTIAL_SUCCESS"]>;
|
|
71
|
-
identifiers: Schema.optional<Schema.Array$<typeof Schema.String>>;
|
|
72
|
-
timestamp: Schema.optional<typeof Schema.Date>;
|
|
73
|
-
fees: Schema.optional<Schema.NullOr<typeof Schema.BigInt>>;
|
|
74
91
|
}>;
|
|
75
92
|
export type WalletEntry = Schema.Schema.Type<typeof WalletEntrySchema>;
|
|
76
|
-
|
|
93
|
+
/** A `WalletEntry` whose lifecycle is `pending`. */
|
|
94
|
+
export type PendingWalletEntry = WalletEntry & {
|
|
95
|
+
readonly lifecycle: TransactionHistoryStorage.PendingLifecycle;
|
|
96
|
+
};
|
|
97
|
+
/** A `WalletEntry` whose lifecycle is `finalized`. */
|
|
98
|
+
export type FinalizedWalletEntry = WalletEntry & {
|
|
99
|
+
readonly lifecycle: TransactionHistoryStorage.FinalizedLifecycle;
|
|
100
|
+
};
|
|
101
|
+
export declare const isPendingWalletEntry: (entry: WalletEntry) => entry is PendingWalletEntry;
|
|
102
|
+
export declare const isFinalizedWalletEntry: (entry: WalletEntry) => entry is FinalizedWalletEntry;
|
|
103
|
+
export declare function mergeWalletEntries(existing: WalletEntry, incoming: WalletEntry): WalletEntry;
|
|
77
104
|
type TokenKind = 'dust' | 'shielded' | 'unshielded';
|
|
78
105
|
type TokenKindsToBalance = 'all' | TokenKind[];
|
|
79
106
|
declare const TokenKindsToBalance: {
|
|
@@ -152,6 +179,11 @@ export declare class FacadeState {
|
|
|
152
179
|
* without a circular dependency.
|
|
153
180
|
*/
|
|
154
181
|
export { Clock };
|
|
182
|
+
/**
|
|
183
|
+
* The asynchronous signer callback used by every signing entry point. A `Promise`-returning callback so out-of-process
|
|
184
|
+
* signers (MPC, HSM) can be plugged in directly; an in-process keystore resolves immediately.
|
|
185
|
+
*/
|
|
186
|
+
export type { SignSegment };
|
|
155
187
|
/**
|
|
156
188
|
* The Terms and Conditions returned by the indexer, containing a URL for display and a SHA-256 hash for content
|
|
157
189
|
* verification.
|
|
@@ -381,9 +413,9 @@ export declare class WalletFacade {
|
|
|
381
413
|
tokenKindsToBalance?: TokenKindsToBalance;
|
|
382
414
|
}): Promise<UnprovenTransactionRecipe>;
|
|
383
415
|
finalizeRecipe(recipe: BalancingRecipe): Promise<ledger.FinalizedTransaction>;
|
|
384
|
-
signRecipe(recipe: BalancingRecipe, signSegment:
|
|
385
|
-
signUnprovenTransaction(tx: ledger.UnprovenTransaction, signSegment:
|
|
386
|
-
signUnboundTransaction(tx: UnboundTransaction, signSegment:
|
|
416
|
+
signRecipe(recipe: BalancingRecipe, signSegment: SignSegment): Promise<BalancingRecipe>;
|
|
417
|
+
signUnprovenTransaction(tx: ledger.UnprovenTransaction, signSegment: SignSegment): Promise<ledger.UnprovenTransaction>;
|
|
418
|
+
signUnboundTransaction(tx: UnboundTransaction, signSegment: SignSegment): Promise<UnboundTransaction>;
|
|
387
419
|
finalizeTransaction(tx: ledger.UnprovenTransaction): Promise<ledger.FinalizedTransaction>;
|
|
388
420
|
/** Estimates the fee for the given transaction only. This lacks the fees of the balancing transaction. */
|
|
389
421
|
calculateTransactionFee(tx: AnyTransaction): Promise<bigint>;
|
|
@@ -417,7 +449,7 @@ export declare class WalletFacade {
|
|
|
417
449
|
ttl: Date;
|
|
418
450
|
payFees?: boolean;
|
|
419
451
|
}): Promise<UnprovenTransactionRecipe>;
|
|
420
|
-
registerNightUtxosForDustGeneration(nightUtxos: readonly UtxoWithMeta[], nightVerifyingKey: ledger.SignatureVerifyingKey, signDustRegistration:
|
|
452
|
+
registerNightUtxosForDustGeneration(nightUtxos: readonly UtxoWithMeta[], nightVerifyingKey: ledger.SignatureVerifyingKey, signDustRegistration: SignSegment, dustReceiverAddress?: DustAddress): Promise<UnprovenTransactionRecipe>;
|
|
421
453
|
/**
|
|
422
454
|
* Waits until the dust projected to be generated by the given Night UTxOs reaches `requiredAmount`, re-checking every
|
|
423
455
|
* second. Pair with {@link estimateRegistration} to pick `requiredAmount`, then call before
|
|
@@ -431,7 +463,7 @@ export declare class WalletFacade {
|
|
|
431
463
|
waitForGeneratedDust(nightUtxos: readonly UtxoWithMeta[], requiredAmount: bigint, opts?: {
|
|
432
464
|
timeoutMs?: number;
|
|
433
465
|
}): Promise<void>;
|
|
434
|
-
deregisterFromDustGeneration(nightUtxos: UtxoWithMeta[], nightVerifyingKey: ledger.SignatureVerifyingKey, signDustRegistration:
|
|
466
|
+
deregisterFromDustGeneration(nightUtxos: UtxoWithMeta[], nightVerifyingKey: ledger.SignatureVerifyingKey, signDustRegistration: SignSegment): Promise<UnprovenTransactionRecipe>;
|
|
435
467
|
revert(txOrRecipe: AnyTransaction | BalancingRecipe): Promise<void>;
|
|
436
468
|
revertTransaction(tx: AnyTransaction): Promise<void>;
|
|
437
469
|
start(shieldedSecretKeys: ledger.ZswapSecretKeys, dustSecretKey: ledger.DustSecretKey): Promise<void>;
|
package/dist/index.js
CHANGED
|
@@ -14,7 +14,7 @@ import * as ledger from '@midnightntwrk/ledger-v9';
|
|
|
14
14
|
import { makeDefaultSubmissionService, } from '@midnightntwrk/wallet-sdk-capabilities';
|
|
15
15
|
import { makeDefaultProvingService, } from '@midnightntwrk/wallet-sdk-capabilities/proving';
|
|
16
16
|
import { ShieldedSectionSchema, mergeShieldedSections, } from '@midnightntwrk/wallet-sdk-shielded';
|
|
17
|
-
import { UnshieldedSectionSchema } from '@midnightntwrk/wallet-sdk-unshielded-wallet';
|
|
17
|
+
import { UnshieldedSectionSchema, mergeUnshieldedSections, } from '@midnightntwrk/wallet-sdk-unshielded-wallet';
|
|
18
18
|
import { DustSectionSchema, mergeDustSections } from '@midnightntwrk/wallet-sdk-dust-wallet';
|
|
19
19
|
import { Clock } from '@midnightntwrk/wallet-sdk-utilities';
|
|
20
20
|
import { FetchTermsAndConditions as FetchTermsAndConditionsQuery } from '@midnightntwrk/wallet-sdk-indexer-client';
|
|
@@ -24,31 +24,81 @@ import { TransactionHistoryStorage } from '@midnightntwrk/wallet-sdk-abstraction
|
|
|
24
24
|
import { combineLatest, map, firstValueFrom, concatMap } from 'rxjs';
|
|
25
25
|
import { PendingTransactions, PendingTransactionsServiceImpl, } from '@midnightntwrk/wallet-sdk-capabilities';
|
|
26
26
|
import { makeDefaultBlockDataFetcher, makeDefaultValidationService, ValidationFetchError, WellFormedError, } from '@midnightntwrk/wallet-sdk-capabilities/validation';
|
|
27
|
-
import { finalizedTransactionTrait } from './transaction.js';
|
|
27
|
+
import { finalizedTransactionTrait, txHistoryHash } from './transaction.js';
|
|
28
28
|
/**
|
|
29
|
-
* Full entry schema for transaction history
|
|
30
|
-
* `
|
|
29
|
+
* Full entry schema for transaction history. The common entry data and wallet-specific sections (`shielded`,
|
|
30
|
+
* `unshielded`, `dust`) live on every entry regardless of lifecycle; the `lifecycle` field is the only discriminator.
|
|
31
|
+
* Pass this to `InMemoryTransactionHistoryStorage` to enable serialize/restore.
|
|
31
32
|
*/
|
|
32
|
-
export const WalletEntrySchema =
|
|
33
|
-
...TransactionHistoryStorage.TransactionHistoryCommonSchema.fields,
|
|
33
|
+
export const WalletEntrySchema = TransactionHistoryStorage.extendEntrySchema({
|
|
34
34
|
shielded: Schema.optional(ShieldedSectionSchema),
|
|
35
35
|
unshielded: Schema.optional(UnshieldedSectionSchema),
|
|
36
36
|
dust: Schema.optional(DustSectionSchema),
|
|
37
37
|
});
|
|
38
|
-
export const
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
38
|
+
export const isPendingWalletEntry = (entry) => entry.lifecycle.status === 'pending';
|
|
39
|
+
export const isFinalizedWalletEntry = (entry) => entry.lifecycle.status === 'finalized';
|
|
40
|
+
/**
|
|
41
|
+
* Merge two wallet entries arriving under the same hash. Treats the entry as `T × lifecycle` per the storage model:
|
|
42
|
+
*
|
|
43
|
+
* - **Shared scalar facts about the tx** (`protocolVersion`, `status`, `timestamp`, `fees`) — first writer wins. Once any
|
|
44
|
+
* wallet has set the value, later writes are no-ops for these fields. This is correct because the value is the same
|
|
45
|
+
* across all wallets (it's a property of the on-chain tx, not the wallet's view of it).
|
|
46
|
+
* - **`identifiers`** — unioned (each wallet may surface a different identifier subset).
|
|
47
|
+
* - **`lifecycle`** — incoming wins (this is how `pending → finalized` transitions are recorded).
|
|
48
|
+
* - **Wallet sections** (`shielded`, `unshielded`, `dust`) — combined via per-section merge when both sides have them;
|
|
49
|
+
* otherwise whichever side is present is used.
|
|
50
|
+
*/
|
|
51
|
+
/**
|
|
52
|
+
* Combine two optional values under a merge function: if both sides have it, delegate to `merge`; otherwise return
|
|
53
|
+
* whichever side is present (or `undefined` if neither). Encapsulates the four-way pattern used for every wallet
|
|
54
|
+
* section in {@link mergeWalletEntries}.
|
|
55
|
+
*/
|
|
56
|
+
const mergeOptionalSection = (existing, incoming, merge) => {
|
|
57
|
+
if (existing !== undefined && incoming !== undefined)
|
|
58
|
+
return merge(existing, incoming);
|
|
59
|
+
return existing ?? incoming;
|
|
60
|
+
};
|
|
61
|
+
export function mergeWalletEntries(existing, incoming) {
|
|
62
|
+
// identifiers: each wallet may surface a different subset, so union them
|
|
63
|
+
const identifiers = Array.from(new Set([...existing.identifiers, ...incoming.identifiers]));
|
|
64
|
+
// wallet sections: per-section merge when both sides have it; whichever side is present otherwise
|
|
65
|
+
const shielded = mergeOptionalSection(existing.shielded, incoming.shielded, mergeShieldedSections);
|
|
66
|
+
const unshielded = mergeOptionalSection(existing.unshielded, incoming.unshielded, mergeUnshieldedSections);
|
|
67
|
+
const dust = mergeOptionalSection(existing.dust, incoming.dust, mergeDustSections);
|
|
68
|
+
return {
|
|
69
|
+
hash: existing.hash,
|
|
70
|
+
identifiers,
|
|
71
|
+
// shared scalar facts about the on-chain tx — first writer wins (same value across all wallets)
|
|
72
|
+
protocolVersion: existing.protocolVersion ?? incoming.protocolVersion,
|
|
73
|
+
status: existing.status ?? incoming.status,
|
|
74
|
+
timestamp: existing.timestamp ?? incoming.timestamp,
|
|
75
|
+
fees: existing.fees ?? incoming.fees,
|
|
76
|
+
// lifecycle: incoming wins — this is how pending → finalized/rejected transitions are recorded
|
|
77
|
+
lifecycle: incoming.lifecycle,
|
|
78
|
+
...(shielded !== undefined ? { shielded } : {}),
|
|
79
|
+
...(unshielded !== undefined ? { unshielded } : {}),
|
|
80
|
+
...(dust !== undefined ? { dust } : {}),
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Storage key for a tx we're about to submit (record as pending). The hash comes from {@link txHistoryHash}, which the
|
|
85
|
+
* revert side uses too — so a tx keyed here while pending resolves to the same key when later confirmed or reverted.
|
|
86
|
+
*/
|
|
87
|
+
const submitTxHistoryKey = (tx) => ({
|
|
88
|
+
hash: txHistoryHash(tx),
|
|
89
|
+
identifiers: tx.identifiers(),
|
|
50
90
|
});
|
|
51
|
-
|
|
91
|
+
/**
|
|
92
|
+
* Storage key for a tx we're about to revert (record as rejected). Shares {@link txHistoryHash} with the submit side so
|
|
93
|
+
* the rejected entry lands on the pending entry in place. Returns `undefined` only when the tx has no identifiers at
|
|
94
|
+
* all (nothing to revert).
|
|
95
|
+
*/
|
|
96
|
+
const revertTxHistoryKey = (tx) => {
|
|
97
|
+
const identifiers = tx.identifiers();
|
|
98
|
+
if (identifiers.length === 0)
|
|
99
|
+
return undefined;
|
|
100
|
+
return { hash: txHistoryHash(tx), identifiers };
|
|
101
|
+
};
|
|
52
102
|
const TokenKindsToBalance = new (class {
|
|
53
103
|
allTokenKinds = ['shielded', 'unshielded', 'dust'];
|
|
54
104
|
toFlags = (tokenKinds) => {
|
|
@@ -391,10 +441,15 @@ export class WalletFacade {
|
|
|
391
441
|
* @throws {@link WellFormedError} — call {@link validateTransaction} first to get this error early.
|
|
392
442
|
*/
|
|
393
443
|
async submitTransaction(tx) {
|
|
444
|
+
const identifiers = tx.identifiers();
|
|
394
445
|
try {
|
|
395
446
|
await this.pendingTransactionsService.addPendingTransaction(tx);
|
|
447
|
+
// Insert before awaiting submission so the entry exists while the tx is in flight — the per-wallet sync
|
|
448
|
+
// handlers' gotFinalized call clears the pending entry on confirmation.
|
|
449
|
+
const key = submitTxHistoryKey(tx);
|
|
450
|
+
await this.#txHistoryStorage.gotPending({ ...key, submittedAt: this.clock.now() });
|
|
396
451
|
await this.submissionService.submitTransaction(tx, 'Finalized');
|
|
397
|
-
return
|
|
452
|
+
return identifiers.at(-1);
|
|
398
453
|
}
|
|
399
454
|
catch (error) {
|
|
400
455
|
await this.revert(tx);
|
|
@@ -594,7 +649,7 @@ export class WalletFacade {
|
|
|
594
649
|
if (!intent || registrations.length === 0) {
|
|
595
650
|
return tx;
|
|
596
651
|
}
|
|
597
|
-
const signature = signSegment(intent.signatureData(1));
|
|
652
|
+
const signature = await signSegment(intent.signatureData(1));
|
|
598
653
|
return await this.dust.addDustRegistrationSignature(tx, signature);
|
|
599
654
|
}
|
|
600
655
|
async signUnprovenTransaction(tx, signSegment) {
|
|
@@ -774,7 +829,13 @@ export class WalletFacade {
|
|
|
774
829
|
this.shielded.revertTransaction(tx),
|
|
775
830
|
this.unshielded.revertTransaction(tx),
|
|
776
831
|
this.dust.revertTransaction(tx),
|
|
777
|
-
]).then(() =>
|
|
832
|
+
]).then(async () => {
|
|
833
|
+
await this.pendingTransactionsService.clear(tx);
|
|
834
|
+
const key = revertTxHistoryKey(tx);
|
|
835
|
+
if (key !== undefined) {
|
|
836
|
+
await this.#txHistoryStorage.gotRejected({ ...key, rejectedAt: this.clock.now() });
|
|
837
|
+
}
|
|
838
|
+
});
|
|
778
839
|
}
|
|
779
840
|
async start(shieldedSecretKeys, dustSecretKey) {
|
|
780
841
|
await Promise.all([
|
|
@@ -795,11 +856,10 @@ export class WalletFacade {
|
|
|
795
856
|
]);
|
|
796
857
|
}
|
|
797
858
|
async queryTxHistoryByHash(hash) {
|
|
798
|
-
|
|
799
|
-
return raw && isWalletEntry(raw) ? raw : undefined;
|
|
859
|
+
return this.#txHistoryStorage.get(hash);
|
|
800
860
|
}
|
|
801
861
|
async getAllFromTxHistory() {
|
|
802
|
-
const
|
|
803
|
-
return [...
|
|
862
|
+
const all = await this.#txHistoryStorage.getAll();
|
|
863
|
+
return [...all];
|
|
804
864
|
}
|
|
805
865
|
}
|
package/dist/transaction.d.ts
CHANGED
|
@@ -1,3 +1,21 @@
|
|
|
1
1
|
import { type PendingTransactions } from '@midnightntwrk/wallet-sdk-capabilities';
|
|
2
2
|
import * as ledger from '@midnightntwrk/ledger-v9';
|
|
3
|
+
import { type AnyTransaction } from '@midnightntwrk/wallet-sdk-dust-wallet/v1';
|
|
4
|
+
/**
|
|
5
|
+
* The key under which a transaction's history entry is stored.
|
|
6
|
+
*
|
|
7
|
+
* Prefer the ledger transaction hash — it's the canonical chain identifier and the value the indexer reports a
|
|
8
|
+
* confirmed tx under. `transactionHash()` is only defined for proven + signed + bound transactions, though; it throws
|
|
9
|
+
* for the other variants, notably the proof-erased transactions the simulator produces. In that case fall back to the
|
|
10
|
+
* hex of the tx's serialized bytes: `serialize()` is total over every variant (it's the same encoding used to submit
|
|
11
|
+
* the tx), so a key is always available — unlike `identifiers[0]`, which is an identifier, not a hash of the
|
|
12
|
+
* transaction.
|
|
13
|
+
*
|
|
14
|
+
* Both the submit (pending) and revert (rejected) sides route through this one function so they can never disagree on
|
|
15
|
+
* the key. The fallback is deterministic: the same transaction object yields the same bytes every time, and the
|
|
16
|
+
* auto-revert path reverts the very object it submitted, so the rejected entry lands on the pending entry in place.
|
|
17
|
+
* (Serialization differs across lifecycle states, so this is only stable for a fixed tx — which is exactly the
|
|
18
|
+
* submit→revert flow.)
|
|
19
|
+
*/
|
|
20
|
+
export declare const txHistoryHash: (tx: AnyTransaction) => string;
|
|
3
21
|
export declare const finalizedTransactionTrait: PendingTransactions.TransactionTrait<ledger.FinalizedTransaction>;
|
package/dist/transaction.js
CHANGED
|
@@ -14,6 +14,30 @@
|
|
|
14
14
|
*/
|
|
15
15
|
import { Array as Arr, DateTime, Duration, HashSet, Option, Order, pipe } from 'effect';
|
|
16
16
|
import * as ledger from '@midnightntwrk/ledger-v9';
|
|
17
|
+
/**
|
|
18
|
+
* The key under which a transaction's history entry is stored.
|
|
19
|
+
*
|
|
20
|
+
* Prefer the ledger transaction hash — it's the canonical chain identifier and the value the indexer reports a
|
|
21
|
+
* confirmed tx under. `transactionHash()` is only defined for proven + signed + bound transactions, though; it throws
|
|
22
|
+
* for the other variants, notably the proof-erased transactions the simulator produces. In that case fall back to the
|
|
23
|
+
* hex of the tx's serialized bytes: `serialize()` is total over every variant (it's the same encoding used to submit
|
|
24
|
+
* the tx), so a key is always available — unlike `identifiers[0]`, which is an identifier, not a hash of the
|
|
25
|
+
* transaction.
|
|
26
|
+
*
|
|
27
|
+
* Both the submit (pending) and revert (rejected) sides route through this one function so they can never disagree on
|
|
28
|
+
* the key. The fallback is deterministic: the same transaction object yields the same bytes every time, and the
|
|
29
|
+
* auto-revert path reverts the very object it submitted, so the rejected entry lands on the pending entry in place.
|
|
30
|
+
* (Serialization differs across lifecycle states, so this is only stable for a fixed tx — which is exactly the
|
|
31
|
+
* submit→revert flow.)
|
|
32
|
+
*/
|
|
33
|
+
export const txHistoryHash = (tx) => {
|
|
34
|
+
try {
|
|
35
|
+
return tx.transactionHash().toString();
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
return Buffer.from(tx.serialize()).toString('hex');
|
|
39
|
+
}
|
|
40
|
+
};
|
|
17
41
|
export const finalizedTransactionTrait = {
|
|
18
42
|
areAllTxIdsIncluded(tx, txIds) {
|
|
19
43
|
const txIdsSet = HashSet.fromIterable(tx.identifiers());
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@midnightntwrk/wallet-sdk-facade",
|
|
3
|
-
"version": "5.0.0-beta.
|
|
3
|
+
"version": "5.0.0-beta.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -26,19 +26,19 @@
|
|
|
26
26
|
}
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@midnightntwrk/ledger-v9": "1.0.0-rc.
|
|
30
|
-
"@midnightntwrk/wallet-sdk-abstractions": "
|
|
31
|
-
"@midnightntwrk/wallet-sdk-address-format": "
|
|
32
|
-
"@midnightntwrk/wallet-sdk-capabilities": "
|
|
33
|
-
"@midnightntwrk/wallet-sdk-dust-wallet": "
|
|
34
|
-
"@midnightntwrk/wallet-sdk-indexer-client": "
|
|
35
|
-
"@midnightntwrk/wallet-sdk-shielded": "
|
|
36
|
-
"@midnightntwrk/wallet-sdk-unshielded-wallet": "
|
|
29
|
+
"@midnightntwrk/ledger-v9": "1.0.0-rc.3",
|
|
30
|
+
"@midnightntwrk/wallet-sdk-abstractions": "3.0.0-beta.0",
|
|
31
|
+
"@midnightntwrk/wallet-sdk-address-format": "4.0.0-beta.2",
|
|
32
|
+
"@midnightntwrk/wallet-sdk-capabilities": "4.0.0-beta.2",
|
|
33
|
+
"@midnightntwrk/wallet-sdk-dust-wallet": "5.0.0-beta.2",
|
|
34
|
+
"@midnightntwrk/wallet-sdk-indexer-client": "1.3.0-beta.1",
|
|
35
|
+
"@midnightntwrk/wallet-sdk-shielded": "4.0.0-beta.2",
|
|
36
|
+
"@midnightntwrk/wallet-sdk-unshielded-wallet": "4.0.0-beta.2",
|
|
37
37
|
"effect": "^3.19.19",
|
|
38
38
|
"rxjs": "^7.8.2"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
|
-
"@midnightntwrk/wallet-sdk-hd": "^3.1.0-beta.
|
|
41
|
+
"@midnightntwrk/wallet-sdk-hd": "^3.1.0-beta.1",
|
|
42
42
|
"@midnightntwrk/wallet-sdk-utilities": "^1.2.0"
|
|
43
43
|
},
|
|
44
44
|
"scripts": {
|