@midnight-ntwrk/wallet-sdk-facade 5.0.0-beta.2 → 5.0.0-beta.3

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.
@@ -1,6 +1,5 @@
1
1
  import { type PendingTransactions } from '@midnight-ntwrk/wallet-sdk-capabilities';
2
- import * as ledger from '@midnightntwrk/ledger-v9';
3
- import { type AnyTransaction } from '@midnight-ntwrk/wallet-sdk-dust-wallet/v1';
2
+ import { ProtocolVersion, type FinalizedTx } from '@midnight-ntwrk/wallet-sdk-abstractions';
4
3
  /**
5
4
  * The key under which a transaction's history entry is stored.
6
5
  *
@@ -17,5 +16,18 @@ import { type AnyTransaction } from '@midnight-ntwrk/wallet-sdk-dust-wallet/v1';
17
16
  * (Serialization differs across lifecycle states, so this is only stable for a fixed tx — which is exactly the
18
17
  * submit→revert flow.)
19
18
  */
20
- export declare const txHistoryHash: (tx: AnyTransaction) => string;
21
- export declare const finalizedTransactionTrait: PendingTransactions.TransactionTrait<ledger.FinalizedTransaction>;
19
+ export declare const txHistoryHash: (tx: {
20
+ transactionHash: () => unknown;
21
+ serialize: () => Uint8Array;
22
+ }) => string;
23
+ /**
24
+ * The traits pending transactions are read with, split at the protocol version this chain forks at.
25
+ *
26
+ * @remarks
27
+ * One trait per ledger version, each reading the handle it is registered for and refusing the other's. That is what
28
+ * lets a transaction authored before the v9 fork be recognised as stranded once the wallets cross — its bytes can
29
+ * never be included afterwards — instead of waiting out a TTL for an inclusion that can never happen.
30
+ * @param forkVersion The protocol version this chain forks at.
31
+ * @returns The registry the pending transaction service reads with.
32
+ */
33
+ export declare const finalizedTransactionTraits: (forkVersion: ProtocolVersion.ProtocolVersion) => PendingTransactions.VersionedTransactionTrait<FinalizedTx>;
@@ -12,8 +12,10 @@
12
12
  * See the License for the specific language governing permissions and
13
13
  * limitations under the License.
14
14
  */
15
- import { Array as Arr, DateTime, Duration, HashSet, Option, Order, pipe } from 'effect';
16
- import * as ledger from '@midnightntwrk/ledger-v9';
15
+ import { Array as Arr, DateTime, Duration, Either, HashSet, Option, Order, pipe } from 'effect';
16
+ import { ProtocolVersion, WalletTransaction, } from '@midnight-ntwrk/wallet-sdk-abstractions';
17
+ import * as ledgerV8 from '@midnight-ntwrk/ledger-v8';
18
+ import * as ledgerV9 from '@midnightntwrk/ledger-v9';
17
19
  /**
18
20
  * The key under which a transaction's history entry is stored.
19
21
  *
@@ -32,26 +34,26 @@ import * as ledger from '@midnightntwrk/ledger-v9';
32
34
  */
33
35
  export const txHistoryHash = (tx) => {
34
36
  try {
35
- return tx.transactionHash().toString();
37
+ return String(tx.transactionHash());
36
38
  }
37
39
  catch {
38
40
  return Buffer.from(tx.serialize()).toString('hex');
39
41
  }
40
42
  };
41
- export const finalizedTransactionTrait = {
43
+ const v9FinalizedTransactionTrait = {
42
44
  areAllTxIdsIncluded(tx, txIds) {
43
45
  const txIdsSet = HashSet.fromIterable(tx.identifiers());
44
46
  const expectedIdSet = HashSet.fromIterable(txIds);
45
47
  return HashSet.isSubset(txIdsSet, expectedIdSet);
46
48
  },
47
49
  deserialize(serialized) {
48
- return ledger.Transaction.deserialize('signature', 'proof', 'binding', serialized);
50
+ return ledgerV9.Transaction.deserialize('signature', 'proof', 'binding', serialized);
49
51
  },
50
52
  firstId(tx) {
51
53
  return tx.identifiers()[0];
52
54
  },
53
55
  hasTTLExpired(tx, creationTime, now) {
54
- const defaultShieldedGracePeriod = ledger.LedgerParameters.initialParameters().dust.dustGracePeriodSeconds;
56
+ const defaultShieldedGracePeriod = ledgerV9.LedgerParameters.initialParameters().dust.dustGracePeriodSeconds;
55
57
  const intentTTLs = pipe(tx.intents?.values().toArray() ?? [], Arr.map((i) => i.ttl), Arr.filterMap(DateTime.make));
56
58
  const hasDustPayments = pipe(tx.intents?.values().toArray() ?? [], Arr.flatMap((i) => i.dustActions?.spends ?? []), Arr.isNonEmptyArray);
57
59
  const hasShieldedOffers = tx.guaranteedOffer != null || (tx.fallibleOffer?.size ?? 0) == 0;
@@ -76,9 +78,115 @@ export const finalizedTransactionTrait = {
76
78
  return HashSet.size(intersection) == smallerSize;
77
79
  },
78
80
  isTx(tx) {
79
- return tx instanceof ledger.Transaction;
81
+ return tx instanceof ledgerV9.Transaction;
80
82
  },
81
83
  serialize(tx) {
82
84
  return tx.serialize();
83
85
  },
84
86
  };
87
+ /**
88
+ * The ledger-v8's reading of a pending transaction.
89
+ *
90
+ * @remarks
91
+ * Structurally the same as ledger-v9's — identifiers, a TTL, bytes — against a different ledger version's classes. It
92
+ * is the classes that make this a separate trait: `instanceof` distinguishes them, each deserializer refuses the
93
+ * other's bytes, and a grace period is read off that version's own initial parameters.
94
+ */
95
+ const v8FinalizedTransactionTrait = {
96
+ areAllTxIdsIncluded(tx, txIds) {
97
+ return HashSet.isSubset(HashSet.fromIterable(tx.identifiers()), HashSet.fromIterable(txIds));
98
+ },
99
+ deserialize(serialized) {
100
+ return ledgerV8.Transaction.deserialize('signature', 'proof', 'binding', serialized);
101
+ },
102
+ firstId(tx) {
103
+ return tx.identifiers()[0];
104
+ },
105
+ hasTTLExpired(tx, creationTime, now) {
106
+ const defaultShieldedGracePeriod = ledgerV8.LedgerParameters.initialParameters().dust.dustGracePeriodSeconds;
107
+ const intentTTLs = pipe(tx.intents?.values().toArray() ?? [], Arr.map((i) => i.ttl), Arr.filterMap(DateTime.make));
108
+ const hasDustPayments = pipe(tx.intents?.values().toArray() ?? [], Arr.flatMap((i) => i.dustActions?.spends ?? []), Arr.isNonEmptyArray);
109
+ const hasShieldedOffers = tx.guaranteedOffer != null || (tx.fallibleOffer?.size ?? 0) == 0;
110
+ const maybeShieldedTTL = hasDustPayments || hasShieldedOffers
111
+ ? pipe(creationTime, DateTime.addDuration(Duration.seconds(Number(defaultShieldedGracePeriod))), Arr.of)
112
+ : Arr.empty();
113
+ return pipe(intentTTLs, Arr.appendAll(maybeShieldedTTL), (arr) => Arr.isNonEmptyReadonlyArray(arr)
114
+ ? Option.some(Arr.min(arr, Order.mapInput(Order.Date, DateTime.toDate)))
115
+ : Option.none(), Option.match({
116
+ onNone: () => false,
117
+ onSome: (finalTTL) => DateTime.distance(finalTTL, now) > 0,
118
+ }));
119
+ },
120
+ ids(tx) {
121
+ return tx.identifiers();
122
+ },
123
+ isOneIncludedInOther(tx, otherTx) {
124
+ const txIds = HashSet.fromIterable(tx.identifiers());
125
+ const otherTxIds = HashSet.fromIterable(otherTx.identifiers());
126
+ const smallerSize = Order.min(Order.number)(HashSet.size(txIds), HashSet.size(otherTxIds));
127
+ return HashSet.size(HashSet.intersection(txIds, otherTxIds)) == smallerSize;
128
+ },
129
+ isTx(tx) {
130
+ return tx instanceof ledgerV8.Transaction;
131
+ },
132
+ serialize(tx) {
133
+ return tx.serialize();
134
+ },
135
+ };
136
+ /**
137
+ * Lifts one ledger version's trait onto the handle the facade actually carries.
138
+ *
139
+ * @remarks
140
+ * The router has already chosen this trait by the version stamped on the handle, so unwrapping at the same epoch is a
141
+ * restatement of the choice rather than a second one — but it is where a handle that does not belong is refused
142
+ * rather than handed to a reader that would misread it. A handle it cannot read is reported as not being its
143
+ * transaction at all, which is precisely what `isTx` is for.
144
+ * @param trait The ledger version's own reading of a transaction.
145
+ * @param epoch The range of protocol versions that ledger version answers for.
146
+ * @returns The same reading, in terms of handles.
147
+ */
148
+ const overHandles = (trait, epoch) => {
149
+ const [stamp] = epoch;
150
+ const carried = (handle) => Either.getOrThrow(WalletTransaction.unwrapWithin(handle, epoch));
151
+ return {
152
+ ids: (tx) => trait.ids(carried(tx)),
153
+ firstId: (tx) => trait.firstId(carried(tx)),
154
+ areAllTxIdsIncluded: (tx, txIds) => trait.areAllTxIdsIncluded(carried(tx), txIds),
155
+ isOneIncludedInOther: (tx, otherTx) => trait.isOneIncludedInOther(carried(tx), carried(otherTx)),
156
+ hasTTLExpired: (tx, creationTime, now) => trait.hasTTLExpired(carried(tx), creationTime, now),
157
+ serialize: (tx) => trait.serialize(carried(tx)),
158
+ deserialize: (serialized) => WalletTransaction.adopt('Finalized', trait.deserialize(serialized), stamp),
159
+ isTx: (tx) => WalletTransaction.is(tx) &&
160
+ Either.match(WalletTransaction.unwrapWithin(tx, epoch), {
161
+ onLeft: () => false,
162
+ onRight: (carried) => trait.isTx(carried),
163
+ }),
164
+ };
165
+ };
166
+ /**
167
+ * The traits pending transactions are read with, split at the protocol version this chain forks at.
168
+ *
169
+ * @remarks
170
+ * One trait per ledger version, each reading the handle it is registered for and refusing the other's. That is what
171
+ * lets a transaction authored before the v9 fork be recognised as stranded once the wallets cross — its bytes can
172
+ * never be included afterwards — instead of waiting out a TTL for an inclusion that can never happen.
173
+ * @param forkVersion The protocol version this chain forks at.
174
+ * @returns The registry the pending transaction service reads with.
175
+ */
176
+ export const finalizedTransactionTraits = (forkVersion) => Either.getOrThrow(ProtocolVersion.makeRegistryFromActivations(forkVersion > ProtocolVersion.MinSupportedVersion
177
+ ? [
178
+ {
179
+ sinceVersion: ProtocolVersion.MinSupportedVersion,
180
+ value: overHandles(v8FinalizedTransactionTrait, ProtocolVersion.epochOf(ProtocolVersion.MinSupportedVersion, forkVersion)),
181
+ },
182
+ {
183
+ sinceVersion: forkVersion,
184
+ value: overHandles(v9FinalizedTransactionTrait, ProtocolVersion.epochOf(forkVersion, forkVersion)),
185
+ },
186
+ ]
187
+ : [
188
+ {
189
+ sinceVersion: ProtocolVersion.MinSupportedVersion,
190
+ value: overHandles(v9FinalizedTransactionTrait, ProtocolVersion.epochOf(ProtocolVersion.MinSupportedVersion, ProtocolVersion.MinSupportedVersion)),
191
+ },
192
+ ]));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@midnight-ntwrk/wallet-sdk-facade",
3
- "version": "5.0.0-beta.2",
3
+ "version": "5.0.0-beta.3",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",
@@ -26,20 +26,20 @@
26
26
  }
27
27
  },
28
28
  "dependencies": {
29
- "@midnightntwrk/ledger-v9": "1.0.0-rc.3",
30
- "@midnight-ntwrk/wallet-sdk-abstractions": "3.0.0-beta.0",
31
- "@midnight-ntwrk/wallet-sdk-address-format": "4.0.0-beta.2",
32
- "@midnight-ntwrk/wallet-sdk-capabilities": "4.0.0-beta.2",
33
- "@midnight-ntwrk/wallet-sdk-dust-wallet": "5.0.0-beta.2",
34
- "@midnight-ntwrk/wallet-sdk-indexer-client": "1.3.0-beta.1",
35
- "@midnight-ntwrk/wallet-sdk-shielded": "4.0.0-beta.2",
36
- "@midnight-ntwrk/wallet-sdk-unshielded-wallet": "4.0.0-beta.2",
29
+ "@midnightntwrk/ledger-v9": "1.0.0-rc.4",
30
+ "@midnight-ntwrk/wallet-sdk-abstractions": "3.0.0-beta.1",
31
+ "@midnight-ntwrk/wallet-sdk-address-format": "4.0.0-beta.3",
32
+ "@midnight-ntwrk/wallet-sdk-capabilities": "4.0.0-beta.3",
33
+ "@midnight-ntwrk/wallet-sdk-dust-wallet": "5.0.0-beta.3",
34
+ "@midnight-ntwrk/wallet-sdk-indexer-client": "2.0.0-beta.2",
35
+ "@midnight-ntwrk/wallet-sdk-shielded": "4.0.0-beta.3",
36
+ "@midnight-ntwrk/wallet-sdk-unshielded-wallet": "4.0.0-beta.3",
37
37
  "effect": "^3.19.19",
38
38
  "rxjs": "^7.8.2"
39
39
  },
40
40
  "devDependencies": {
41
- "@midnight-ntwrk/wallet-sdk-hd": "^3.1.0-beta.1",
42
- "@midnight-ntwrk/wallet-sdk-utilities": "^1.2.0"
41
+ "@midnight-ntwrk/wallet-sdk-hd": "^3.1.0-beta.2",
42
+ "@midnight-ntwrk/wallet-sdk-utilities": "^1.2.2-beta.0"
43
43
  },
44
44
  "scripts": {
45
45
  "typecheck": "tsc -b ./tsconfig.json --noEmit --force",