@midnight-ntwrk/wallet-sdk-shielded 4.0.0-beta.1 → 4.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.
Files changed (60) hide show
  1. package/README.md +11 -6
  2. package/dist/Restore.d.ts +40 -0
  3. package/dist/Restore.js +63 -0
  4. package/dist/ShieldedWallet.d.ts +248 -62
  5. package/dist/ShieldedWallet.js +366 -76
  6. package/dist/ShieldedWalletAPI.d.ts +179 -0
  7. package/dist/ShieldedWalletAPI.js +75 -0
  8. package/dist/SingleVariantShieldedWallet.d.ts +35 -0
  9. package/dist/SingleVariantShieldedWallet.js +240 -0
  10. package/dist/index.d.ts +4 -1
  11. package/dist/index.js +4 -1
  12. package/dist/v1/CoinsAndBalances.d.ts +1 -1
  13. package/dist/v1/CoreWallet.d.ts +48 -1
  14. package/dist/v1/CoreWallet.js +54 -1
  15. package/dist/v1/Migration.d.ts +95 -0
  16. package/dist/v1/Migration.js +82 -0
  17. package/dist/v1/RunningV1Variant.d.ts +1 -1
  18. package/dist/v1/RunningV1Variant.js +37 -8
  19. package/dist/v1/Serialization.js +1 -1
  20. package/dist/v1/Sync.d.ts +132 -9
  21. package/dist/v1/Sync.js +244 -35
  22. package/dist/v1/Transacting.d.ts +1 -1
  23. package/dist/v1/Transacting.js +1 -1
  24. package/dist/v1/TransactionHistory.d.ts +9 -2
  25. package/dist/v1/TransactionHistory.js +26 -5
  26. package/dist/v1/TransactionOps.d.ts +1 -1
  27. package/dist/v1/V1Builder.d.ts +87 -26
  28. package/dist/v1/V1Builder.js +109 -8
  29. package/dist/v1/WalletError.d.ts +1 -1
  30. package/dist/v1/index.d.ts +2 -1
  31. package/dist/v1/index.js +5 -1
  32. package/dist/v2/CoinsAndBalances.d.ts +24 -0
  33. package/dist/v2/CoinsAndBalances.js +41 -0
  34. package/dist/v2/CoreWallet.d.ts +162 -0
  35. package/dist/v2/CoreWallet.js +305 -0
  36. package/dist/v2/Keys.d.ts +8 -0
  37. package/dist/v2/Keys.js +16 -0
  38. package/dist/v2/Migration.d.ts +112 -0
  39. package/dist/v2/Migration.js +96 -0
  40. package/dist/v2/RunningV2Variant.d.ts +40 -0
  41. package/dist/v2/RunningV2Variant.js +127 -0
  42. package/dist/v2/Serialization.d.ts +12 -0
  43. package/dist/v2/Serialization.js +93 -0
  44. package/dist/v2/Sync.d.ts +208 -0
  45. package/dist/v2/Sync.js +436 -0
  46. package/dist/v2/Transacting.d.ts +50 -0
  47. package/dist/v2/Transacting.js +258 -0
  48. package/dist/v2/TransactionHistory.d.ts +100 -0
  49. package/dist/v2/TransactionHistory.js +132 -0
  50. package/dist/v2/TransactionImbalances.d.ts +10 -0
  51. package/dist/v2/TransactionImbalances.js +30 -0
  52. package/dist/v2/TransactionOps.d.ts +17 -0
  53. package/dist/v2/TransactionOps.js +73 -0
  54. package/dist/v2/V2Builder.d.ts +154 -0
  55. package/dist/v2/V2Builder.js +273 -0
  56. package/dist/v2/WalletError.d.ts +74 -0
  57. package/dist/v2/WalletError.js +53 -0
  58. package/dist/v2/index.d.ts +13 -0
  59. package/dist/v2/index.js +26 -0
  60. package/package.json +16 -8
package/README.md CHANGED
@@ -32,18 +32,22 @@ while maintaining verifiability. It provides:
32
32
 
33
33
  ```typescript
34
34
  import { ShieldedWallet } from '@midnight-ntwrk/wallet-sdk-shielded';
35
- import * as ledger from '@midnight-ntwrk/ledger-v7';
35
+ import { InMemoryTransactionHistoryStorage, ProtocolVersion } from '@midnight-ntwrk/wallet-sdk-abstractions';
36
+ import { TransactionHistory } from '@midnight-ntwrk/wallet-sdk-shielded/v2';
37
+ import * as ledger from '@midnightntwrk/ledger-v9';
36
38
  import { randomBytes } from 'node:crypto';
37
39
 
38
40
  // Configuration for the wallet
39
41
  const configuration = {
40
42
  networkId: 'preview',
41
- provingServerUrl: new URL('http://localhost:6300'),
42
- relayURL: new URL('ws://localhost:9944'),
43
43
  indexerClientConnection: {
44
- indexerHttpUrl: 'http://localhost:8088/api/v3/graphql',
45
- indexerWsUrl: 'ws://localhost:8088/api/v3/graphql/ws',
44
+ indexerHttpUrl: 'http://localhost:8088/api/v4/graphql',
45
+ indexerWsUrl: 'ws://localhost:8088/api/v4/graphql/ws',
46
46
  },
47
+ txHistoryStorage: new InMemoryTransactionHistoryStorage(TransactionHistory.ShieldedTransactionHistoryEntrySchema),
48
+ // Where this chain hands over to ledger-v9: the schedule of a chain born on ledger-v9, as a 2.x node runs. The
49
+ // final mainnet fork constant is not yet fixed, so a chain that hands over elsewhere states `{ v9: ... }` here.
50
+ forks: ProtocolVersion.V9NativeForkSchedule,
47
51
  };
48
52
 
49
53
  // Create secret keys from a shielded seed
@@ -124,7 +128,8 @@ While still proving:
124
128
 
125
129
  - `ShieldedWallet` - Main wallet class
126
130
  - `ShieldedWalletState` - Wallet state type
127
- - Version 1 exports via `@midnight-ntwrk/wallet-sdk-shielded/v1`
131
+ - V2 (ledger-v9) variant internals via `@midnight-ntwrk/wallet-sdk-shielded/v2`
132
+ - V1 (ledger-v8) variant internals via `@midnight-ntwrk/wallet-sdk-shielded/v1`
128
133
 
129
134
  ## License
130
135
 
@@ -0,0 +1,40 @@
1
+ import { ProtocolVersion } from '@midnight-ntwrk/wallet-sdk-abstractions';
2
+ import { Either, Option } from 'effect';
3
+ declare const UnsupportedSnapshotVersionError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
4
+ readonly _tag: "@midnight-ntwrk/wallet-sdk-shielded/Restore/UnsupportedSnapshotVersionError";
5
+ } & Readonly<A>;
6
+ /**
7
+ * Raised when a snapshot declares a protocol version that no registered variant is able to read.
8
+ *
9
+ * @remarks
10
+ * A wallet built for one range of protocol versions cannot invent a reader for a snapshot written outside it, and
11
+ * guessing — handing the bytes to whichever variant happens to be registered — would decode them with the wrong
12
+ * ledger. The version is carried on the error so an application can say which one it was.
13
+ */
14
+ export declare class UnsupportedSnapshotVersionError extends UnsupportedSnapshotVersionError_base<{
15
+ readonly message: string;
16
+ readonly protocolVersion: ProtocolVersion.ProtocolVersion;
17
+ }> {
18
+ }
19
+ /**
20
+ * Reads the protocol version a serialized wallet snapshot declares.
21
+ *
22
+ * @param serialized The serialized wallet state.
23
+ * @returns The declared version, or `Option.none()` when the snapshot declares none or cannot be read at all.
24
+ */
25
+ export declare const peekProtocolVersion: (serialized: string) => Option.Option<ProtocolVersion.ProtocolVersion>;
26
+ /**
27
+ * Chooses the variant that should read a serialized wallet snapshot.
28
+ *
29
+ * @remarks
30
+ * A snapshot that declares no version predates snapshots declaring one, and can only have been written by the variant
31
+ * that shipped before the question arose — the head variant. The same fallback covers an envelope this function
32
+ * cannot read at all: refusing it here would replace the deserializer's precise error with a vaguer one.
33
+ * @param serialized The serialized wallet state.
34
+ * @param variantFor Resolves the variant registered for a protocol version.
35
+ * @param headVariant The variant a snapshot with no declared version is restored into.
36
+ * @returns The variant to restore with, or {@link UnsupportedSnapshotVersionError} when the declared version is one no
37
+ * registered variant owns.
38
+ */
39
+ export declare const variantForSnapshot: <TVariant>(serialized: string, variantFor: (version: ProtocolVersion.ProtocolVersion) => Option.Option<TVariant>, headVariant: TVariant) => Either.Either<TVariant, UnsupportedSnapshotVersionError>;
40
+ export {};
@@ -0,0 +1,63 @@
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 { ProtocolVersion } from '@midnight-ntwrk/wallet-sdk-abstractions';
14
+ import { Data, Either, Option, Schema } from 'effect';
15
+ /**
16
+ * Raised when a snapshot declares a protocol version that no registered variant is able to read.
17
+ *
18
+ * @remarks
19
+ * A wallet built for one range of protocol versions cannot invent a reader for a snapshot written outside it, and
20
+ * guessing — handing the bytes to whichever variant happens to be registered — would decode them with the wrong
21
+ * ledger. The version is carried on the error so an application can say which one it was.
22
+ */
23
+ export class UnsupportedSnapshotVersionError extends Data.TaggedError('@midnight-ntwrk/wallet-sdk-shielded/Restore/UnsupportedSnapshotVersionError') {
24
+ }
25
+ /**
26
+ * The envelope the peek reads.
27
+ *
28
+ * @remarks
29
+ * Deliberately the smallest possible description of a snapshot: one optional field, every other ignored. It has to read
30
+ * snapshots written by _any_ variant, including ones whose full schema this build does not have, so it must not
31
+ * assert anything it does not need. Everything it cannot make sense of is reported as "no version declared", leaving
32
+ * the real diagnosis to the deserializer that eventually reads the whole thing.
33
+ */
34
+ const EnvelopeSchema = Schema.Struct({
35
+ protocolVersion: Schema.optional(ProtocolVersion.ProtocolVersionSchema),
36
+ });
37
+ /**
38
+ * Reads the protocol version a serialized wallet snapshot declares.
39
+ *
40
+ * @param serialized The serialized wallet state.
41
+ * @returns The declared version, or `Option.none()` when the snapshot declares none or cannot be read at all.
42
+ */
43
+ export const peekProtocolVersion = (serialized) => Schema.decodeUnknownOption(Schema.parseJson(EnvelopeSchema))(serialized).pipe(Option.flatMap((envelope) => Option.fromNullable(envelope.protocolVersion)));
44
+ /**
45
+ * Chooses the variant that should read a serialized wallet snapshot.
46
+ *
47
+ * @remarks
48
+ * A snapshot that declares no version predates snapshots declaring one, and can only have been written by the variant
49
+ * that shipped before the question arose — the head variant. The same fallback covers an envelope this function
50
+ * cannot read at all: refusing it here would replace the deserializer's precise error with a vaguer one.
51
+ * @param serialized The serialized wallet state.
52
+ * @param variantFor Resolves the variant registered for a protocol version.
53
+ * @param headVariant The variant a snapshot with no declared version is restored into.
54
+ * @returns The variant to restore with, or {@link UnsupportedSnapshotVersionError} when the declared version is one no
55
+ * registered variant owns.
56
+ */
57
+ export const variantForSnapshot = (serialized, variantFor, headVariant) => Option.match(peekProtocolVersion(serialized), {
58
+ onNone: () => Either.right(headVariant),
59
+ onSome: (protocolVersion) => Either.fromOption(variantFor(protocolVersion), () => new UnsupportedSnapshotVersionError({
60
+ message: `No registered variant reads shielded wallet snapshots of protocol version ${protocolVersion}.`,
61
+ protocolVersion,
62
+ })),
63
+ });
@@ -1,65 +1,251 @@
1
- import { type ProtocolState, ProtocolVersion, type SyncProgress } from '@midnight-ntwrk/wallet-sdk-abstractions';
2
- import { type BaseV1Configuration, type DefaultV1Configuration, type V1Variant, CoreWallet } from './v1/index.js';
3
- import * as ledger from '@midnightntwrk/ledger-v9';
4
- import * as rx from 'rxjs';
5
- import { type BalancingResult } from './v1/Transacting.js';
6
- import { type SerializationCapability } from './v1/Serialization.js';
7
- import { type TransactionHistoryService } from './v1/TransactionHistory.js';
8
- import { type AvailableCoin, type CoinsAndBalancesCapability, type PendingCoin } from './v1/CoinsAndBalances.js';
9
- import { type KeysCapability } from './v1/Keys.js';
10
- import { type ShieldedAddress, type ShieldedCoinPublicKey, type ShieldedEncryptionPublicKey } from '@midnight-ntwrk/wallet-sdk-address-format';
11
- import { type TokenTransfer } from './v1/Transacting.js';
12
- import { type WalletSyncUpdate } from './v1/Sync.js';
13
- import { type Variant, type VariantBuilder, type WalletLike } from '@midnight-ntwrk/wallet-sdk-runtime/abstractions';
14
- export type ShieldedWalletCapabilities<TSerialized = string> = {
15
- serialization: SerializationCapability<CoreWallet, null, TSerialized>;
16
- coinsAndBalances: CoinsAndBalancesCapability<CoreWallet>;
17
- keys: KeysCapability<CoreWallet>;
1
+ /**
2
+ * A shielded wallet that registers a variant either side of a protocol boundary and follows the chain across it.
3
+ *
4
+ * @remarks
5
+ * One wallet, two ledger versions. Before the boundary the V1 variant reads the chain with the ledger version that
6
+ * produced it; from the boundary the V2 variant does, having been handed identity and a place in the timeline and
7
+ * nothing else. Which one is running is the runtime's business, not the application's: the wallet's public API speaks
8
+ * ledger-v9 throughout, and where the two sides genuinely differ — the key material each variant's synchronization
9
+ * needs — the wallet resolves it per variant from what it retained.
10
+ *
11
+ * `ShieldedWallet(configuration)` at the bottom is how this package ships it. `CustomForkingShieldedWallet` is the same
12
+ * wallet over builders the caller chooses, and `SingleVariantShieldedWallet.ts` is the composition that gives up the
13
+ * crossing to run one variant only.
14
+ */
15
+ import type * as ledgerV8 from '@midnight-ntwrk/ledger-v8';
16
+ import type * as ledgerV9 from '@midnightntwrk/ledger-v9';
17
+ import { type NetworkId, ProtocolVersion } from '@midnight-ntwrk/wallet-sdk-abstractions';
18
+ import { type ChainVersionProbe } from '@midnight-ntwrk/wallet-sdk-capabilities/chainVersion';
19
+ import { Variant, type VariantBuilder, type WalletLike } from '@midnight-ntwrk/wallet-sdk-runtime/abstractions';
20
+ import { Either } from 'effect';
21
+ import { type UnsupportedSnapshotVersionError } from './Restore.js';
22
+ import { type DefaultShieldedConfiguration, type ShieldedWalletAPI } from './ShieldedWalletAPI.js';
23
+ import { type V1Variant } from './v1/index.js';
24
+ import { type WalletSyncUpdate as V1SyncUpdate } from './v1/Sync.js';
25
+ import { Migration, type V2Variant } from './v2/index.js';
26
+ import { type WalletSyncUpdate as V2SyncUpdate } from './v2/Sync.js';
27
+ import { type WalletError as V1WalletError } from './v1/WalletError.js';
28
+ import { type WalletError } from './v2/WalletError.js';
29
+ /**
30
+ * What restoring a shielded wallet from a snapshot can fail with.
31
+ *
32
+ * @remarks
33
+ * Two failures, and they mean different things. The snapshot may declare a protocol version no registered variant
34
+ * reads, which is a fact about this build of the SDK rather than about the snapshot; or the variant that owns it may
35
+ * be unable to make sense of the bytes, which is a fact about the snapshot. Either is an ordinary thing to meet when
36
+ * restoring something a user supplied, which is why `tryRestore` reports them rather than throwing.
37
+ */
38
+ export type ShieldedRestoreError = UnsupportedSnapshotVersionError | V1WalletError | WalletError;
39
+ /** The V1 variant a forking shielded wallet registers: the one that reads the chain before the boundary. */
40
+ export type V1ShieldedVariant<TSyncUpdate> = V1Variant<string, TSyncUpdate, ledgerV8.FinalizedTransaction, ledgerV8.ZswapSecretKeys>;
41
+ /** The V2 variant a forking shielded wallet registers: the one the V1 wallet is migrated into. */
42
+ export type V2ShieldedVariant<TSyncUpdate> = V2Variant<string, TSyncUpdate, ledgerV9.FinalizedTransaction, ledgerV9.ZswapSecretKeys, Migration.PreviousLedgerWallet>;
43
+ /** The two variants a forking shielded wallet runs, in registration order. */
44
+ export type ForkingShieldedVariants<TV1SyncUpdate, TV2SyncUpdate> = [
45
+ Variant.VersionedVariant<V1ShieldedVariant<TV1SyncUpdate>>,
46
+ Variant.VersionedVariant<V2ShieldedVariant<TV2SyncUpdate>>
47
+ ];
48
+ /**
49
+ * A variant builder registered together with the configuration it alone is built from.
50
+ *
51
+ * @remarks
52
+ * Per-variant rather than shared, because two variants either side of a protocol boundary can mean different and
53
+ * mutually unassignable things by the same configuration key — a `simulator` or an indexer connection belonging to
54
+ * one ledger version or the other. A wallet-wide intersection of those is a configuration no single variant can
55
+ * consume.
56
+ */
57
+ export type SelfConfiguredShieldedVariant<TVariant extends Variant.AnyVariant, TConfiguration extends object> = Readonly<{
58
+ builder: VariantBuilder.VariantBuilder<TVariant, TConfiguration>;
59
+ configuration: TConfiguration;
60
+ }>;
61
+ /** What a forking shielded wallet needs to know about itself, whatever its variants are built from. */
62
+ export type ForkingShieldedConfiguration = {
63
+ networkId: NetworkId.NetworkId;
64
+ /** Where each ledger version begins on this chain — see {@link ProtocolVersion.ForkSchedule}. */
65
+ forks: ProtocolVersion.ForkSchedule;
66
+ /**
67
+ * How the wallet asks the chain which protocol version it is on, before it chooses a variant to start at.
68
+ *
69
+ * @remarks
70
+ * Optional, and best-effort where present: a wallet with no probe — or one whose probe does not answer in time —
71
+ * starts on the V1 variant and learns the version from the first event it sees, which is what a wallet with no
72
+ * history has always done. What a probe buys is the two things that guess costs: a hand-over per start on a chain
73
+ * entirely past the boundary, and, on a chain that has shown this wallet no events at all, an epoch that never gets
74
+ * corrected.
75
+ *
76
+ * Nothing about it can make a start fail. A rejection, a timeout, a version no registered variant covers: each leaves
77
+ * the wallet exactly where a wallet that never asked would be.
78
+ */
79
+ chainVersionProbe?: ChainVersionProbe;
18
80
  };
19
- export type ShieldedWalletServices = {
20
- transactionHistory: TransactionHistoryService;
81
+ /**
82
+ * One ledger version's shielded key objects per side of a protocol boundary.
83
+ *
84
+ * @remarks
85
+ * Both sides are required. A caller holding key objects rather than a seed has to hold both, because the two belong to
86
+ * different ledger runtimes and neither can be derived from the other; a product with one side optional would let a
87
+ * wallet be built that cannot read half the chain, which is the shape this replaced.
88
+ */
89
+ export type ShieldedKeysByEpoch = Readonly<{
90
+ /** The ledger-v8's Zswap secret keys. */
91
+ v8: ledgerV8.ZswapSecretKeys;
92
+ /** The ledger-v9's Zswap secret keys. */
93
+ v9: ledgerV9.ZswapSecretKeys;
94
+ }>;
95
+ /**
96
+ * A running shielded wallet that spans a protocol boundary.
97
+ *
98
+ * @remarks
99
+ * Its two extra starts are the instance counterparts of the class-level ones, and they are here rather than on
100
+ * {@link ShieldedWalletAPI} because only a wallet with a variant either side of a boundary has anything to do with
101
+ * them: a single-variant wallet speaks one ledger version, and the key material `start` takes is always the right
102
+ * one.
103
+ */
104
+ export type ForkingShieldedWallet<TV1SyncUpdate, TV2SyncUpdate> = ShieldedWalletAPI<ledgerV9.ZswapSecretKeys, ledgerV9.FinalizedTransaction, string> & WalletLike.WalletLike<ForkingShieldedVariants<TV1SyncUpdate, TV2SyncUpdate>> & {
105
+ /**
106
+ * Starts this wallet from a seed, which answers for the variant either side of the boundary.
107
+ *
108
+ * @remarks
109
+ * The instance counterpart of {@link ForkingShieldedWalletClass.startWithSeed}, and what a wallet restored from a
110
+ * snapshot written below the boundary is started with. A snapshot carries no key material by design, and the
111
+ * variant it restores onto is the ledger-v8 one, whose synchronization the ledger-v9 keys
112
+ * {@link ShieldedWalletAPI.start} takes cannot serve. The class-level start answers for both sides too — but it
113
+ * builds a _fresh_ wallet, which is the opposite of what a caller who has just restored one wants.
114
+ *
115
+ * The seed itself is not kept: both ledger versions' keys are derived from it here and retained instead, which is
116
+ * the same capability with a shorter-lived secret.
117
+ * @example
118
+ * ```typescript
119
+ * const wallet = ShieldedWallet(configuration).restore(snapshot);
120
+ * await wallet.startWithSeed(seed);
121
+ * ```;
122
+ *
123
+ * @param seed The seed to derive both ledger versions' keys from.
124
+ * @returns Nothing; resolves once synchronization has been started on whichever variant is current.
125
+ */
126
+ startWithSeed(seed: Uint8Array): Promise<void>;
127
+ /**
128
+ * Starts this wallet from key objects of both ledger versions.
129
+ *
130
+ * @remarks
131
+ * The instance counterpart of {@link ForkingShieldedWalletClass.startWithKeys}, for a caller that will not part with
132
+ * a seed. Both sides are required for the same reason they are there: key objects belong to one ledger version's
133
+ * runtime, so a wallet given one side alone could not read the other side of the chain.
134
+ * @example
135
+ * ```typescript
136
+ * const wallet = ShieldedWallet(configuration).restore(snapshot);
137
+ * await wallet.startWithKeys({ v8: v8Keys, v9: v9Keys });
138
+ * ```;
139
+ *
140
+ * @param keys One ledger version's Zswap secret keys per side of the boundary.
141
+ * @returns Nothing; resolves once synchronization has been started on whichever variant is current.
142
+ */
143
+ startWithKeys(keys: ShieldedKeysByEpoch): Promise<void>;
21
144
  };
22
- export type UnboundTransaction = ledger.Transaction<ledger.SignatureEnabled, ledger.Proof, ledger.PreBinding>;
23
- export declare class ShieldedWalletState<TSerialized = string, _TTransaction = ledger.FinalizedTransaction> {
24
- static readonly mapState: <TSerialized_1 = string>(variant: ShieldedWalletCapabilities<TSerialized_1> & ShieldedWalletServices) => (state: ProtocolState.ProtocolState<CoreWallet>) => ShieldedWalletState<TSerialized_1>;
25
- readonly protocolVersion: ProtocolVersion.ProtocolVersion;
26
- readonly state: CoreWallet;
27
- readonly capabilities: ShieldedWalletCapabilities<TSerialized>;
28
- readonly services: ShieldedWalletServices;
29
- get balances(): Record<ledger.RawTokenType, bigint>;
30
- get totalCoins(): readonly (AvailableCoin | PendingCoin)[];
31
- get availableCoins(): readonly AvailableCoin[];
32
- get pendingCoins(): readonly PendingCoin[];
33
- get coinPublicKey(): ShieldedCoinPublicKey;
34
- get encryptionPublicKey(): ShieldedEncryptionPublicKey;
35
- get address(): ShieldedAddress;
36
- get progress(): SyncProgress.SyncProgress;
37
- constructor(state: ProtocolState.ProtocolState<CoreWallet>, capabilities: ShieldedWalletCapabilities<TSerialized>, services: ShieldedWalletServices);
38
- serialize(): TSerialized;
145
+ /** The class a forking shielded wallet is started from. */
146
+ export interface ForkingShieldedWalletClass<TV1SyncUpdate, TV2SyncUpdate, TConfiguration extends ForkingShieldedConfiguration = ForkingShieldedConfiguration> extends WalletLike.BaseWalletClass<ForkingShieldedVariants<TV1SyncUpdate, TV2SyncUpdate>, TConfiguration> {
147
+ /**
148
+ * Builds a wallet from a seed, and remembers the seed.
149
+ *
150
+ * @remarks
151
+ * The only start that can follow the chain the whole way. The seed is the one piece of key material that crosses a
152
+ * protocol boundary — each variant derives its own from it — so a wallet built this way can synchronize on either
153
+ * side of the fork.
154
+ *
155
+ * Asynchronous because choosing where to begin can mean asking the chain: with a
156
+ * {@link ForkingShieldedConfiguration.chainVersionProbe} configured, the wallet starts at the variant that owns the
157
+ * version the chain reports, which on a chain already past the boundary is the ledger-v9 one from the first moment.
158
+ * Without one, or when the question goes unanswered, it begins on the V1 variant and is handed over when the chain
159
+ * reports a version the V2 variant owns — on a chain that has already forked, the first batch it sees.
160
+ * @param seed The seed to derive both ledger versions' keys from.
161
+ * @returns A wallet started at the variant the chain is on, or on the V1 variant when the chain was not asked or did
162
+ * not say.
163
+ */
164
+ startWithSeed(seed: Uint8Array): Promise<ForkingShieldedWallet<TV1SyncUpdate, TV2SyncUpdate>>;
165
+ /**
166
+ * Builds a wallet from key objects of both ledger versions.
167
+ *
168
+ * @remarks
169
+ * The escape hatch for a caller that will not hand over a seed. Both sides are required, and that is the whole point:
170
+ * key objects belong to one ledger version's runtime, so a wallet given one side alone could not read the other
171
+ * side of the chain — and a partial product here would be exactly the foot-gun the single-key start was. It costs
172
+ * the caller an import of both ledger packages and the same derivation done twice; a seed costs neither.
173
+ * @param keys One ledger version's Zswap secret keys per side of the boundary.
174
+ * @returns A wallet started at the variant the chain is on, or on the V1 variant — where a wallet with no history
175
+ * belongs — when the chain was not asked or did not say.
176
+ */
177
+ startWithKeys(keys: ShieldedKeysByEpoch): Promise<ForkingShieldedWallet<TV1SyncUpdate, TV2SyncUpdate>>;
178
+ /**
179
+ * Restores a wallet from a snapshot, into whichever registered variant wrote it.
180
+ *
181
+ * @param serializedState The serialized wallet state.
182
+ * @returns A wallet started from that state, on the variant that owns its protocol version.
183
+ * @throws UnsupportedSnapshotVersionError if the snapshot declares a version no registered variant reads.
184
+ */
185
+ restore(serializedState: string): ForkingShieldedWallet<TV1SyncUpdate, TV2SyncUpdate>;
186
+ /**
187
+ * Restores a wallet from a snapshot, reporting what it could not read rather than throwing.
188
+ *
189
+ * @remarks
190
+ * Additive alongside {@link restore}, which is unchanged and still the right shape for a snapshot the application has
191
+ * just written itself. This is the shape for one it has not: a snapshot a user supplied, or one written by a build
192
+ * of the SDK that is no longer the one running, where "I cannot read this" is an ordinary answer rather than a bug.
193
+ * The two cannot disagree — `restore` is this, with the reason thrown.
194
+ * @param serializedState The serialized wallet state.
195
+ * @returns A wallet started from that state, or the reason the snapshot could not be read. See
196
+ * {@link ShieldedRestoreError}.
197
+ */
198
+ tryRestore(serializedState: string): Either.Either<ForkingShieldedWallet<TV1SyncUpdate, TV2SyncUpdate>, ShieldedRestoreError>;
39
199
  }
40
- export type ShieldedWallet = CustomizedShieldedWallet<ledger.ZswapSecretKeys, ledger.FinalizedTransaction, WalletSyncUpdate, string>;
41
- export type ShieldedWalletClass = CustomizedShieldedWalletClass<ledger.ZswapSecretKeys, ledger.FinalizedTransaction, WalletSyncUpdate, string>;
42
- export type ShieldedWalletAPI<TStartAux = ledger.ZswapSecretKeys, TTransaction = ledger.FinalizedTransaction, TSerialized = string> = {
43
- readonly state: rx.Observable<ShieldedWalletState<TSerialized, TTransaction>>;
44
- start(secretKeys: TStartAux): Promise<void>;
45
- balanceTransaction(secretKeys: ledger.ZswapSecretKeys, tx: ledger.Transaction<ledger.Signaturish, ledger.Proofish, ledger.Bindingish>): Promise<BalancingResult>;
46
- transferTransaction(secretKeys: ledger.ZswapSecretKeys, outputs: readonly TokenTransfer[]): Promise<ledger.UnprovenTransaction>;
47
- initSwap(secretKeys: ledger.ZswapSecretKeys, desiredInputs: Record<ledger.RawTokenType, bigint>, desiredOutputs: readonly TokenTransfer[]): Promise<ledger.UnprovenTransaction>;
48
- serializeState(): Promise<TSerialized>;
49
- waitForSyncedState(allowedGap?: bigint): Promise<ShieldedWalletState<TSerialized, TTransaction>>;
50
- getAddress(): Promise<ShieldedAddress>;
51
- revertTransaction(transaction: ledger.Transaction<ledger.Signaturish, ledger.Proofish, ledger.Bindingish>): Promise<void>;
52
- stop(): Promise<void>;
53
- };
54
- export type CustomizedShieldedWallet<TStartAux = ledger.ZswapSecretKeys, TTransaction = ledger.FinalizedTransaction, TSyncUpdate = WalletSyncUpdate, TSerialized = string> = ShieldedWalletAPI<TStartAux, TTransaction, TSerialized> & WalletLike.WalletLike<[Variant.VersionedVariant<V1Variant<TSerialized, TSyncUpdate, TTransaction, TStartAux>>]>;
55
- export type DefaultShieldedConfiguration = DefaultV1Configuration;
56
- export interface CustomizedShieldedWalletClass<TStartAux = ledger.ZswapSecretKeys, TTransaction = ledger.FinalizedTransaction, TSyncUpdate = WalletSyncUpdate, TSerialized = string, TConfig extends BaseV1Configuration = DefaultShieldedConfiguration> extends WalletLike.BaseWalletClass<[
57
- Variant.VersionedVariant<V1Variant<TSerialized, TSyncUpdate, TTransaction, TStartAux>>
58
- ]> {
59
- configuration: TConfig;
60
- startWithSeed(seed: Uint8Array): CustomizedShieldedWallet<TStartAux, TTransaction, TSyncUpdate, TSerialized>;
61
- startWithSecretKeys(secretKeys: ledger.ZswapSecretKeys): CustomizedShieldedWallet<TStartAux, TTransaction, TSyncUpdate, TSerialized>;
62
- restore(serializedState: TSerialized): CustomizedShieldedWallet<TStartAux, TTransaction, TSyncUpdate, TSerialized>;
63
- }
64
- export declare function ShieldedWallet(configuration: DefaultV1Configuration): ShieldedWalletClass;
65
- export declare function CustomShieldedWallet<TConfig extends BaseV1Configuration = DefaultV1Configuration, TStartAux = ledger.ZswapSecretKeys, TTransaction = ledger.FinalizedTransaction, TSyncUpdate = WalletSyncUpdate, TSerialized = string>(configuration: TConfig, builder: VariantBuilder.VariantBuilder<V1Variant<TSerialized, TSyncUpdate, TTransaction, TStartAux>, TConfig>): CustomizedShieldedWalletClass<TStartAux, TTransaction, TSyncUpdate, TSerialized, TConfig>;
200
+ /**
201
+ * Builds a shielded wallet class over a variant either side of a protocol boundary.
202
+ *
203
+ * @remarks
204
+ * The boundary is `configuration.forks.v9` and nothing else: the V1 variant is registered from the minimum supported
205
+ * version and the ledger-v9 one from the fork version, so the version at which the runtime hands over and the version
206
+ * at which each variant stops applying are the same number, taken from one place.
207
+ *
208
+ * Each variant is built from its own configuration. What the wallet layer needs — the network it is on and where the
209
+ * boundary lies — it takes separately, because neither variant knows there is another one.
210
+ * @example
211
+ * ```typescript
212
+ * const Wallet = CustomForkingShieldedWallet(
213
+ * { networkId, forks },
214
+ * { builder: new V1Builder().withDefaults(), configuration: v1Configuration },
215
+ * { builder: new V2Builder().withDefaults().withMigration(makeCrossLedgerMigration), configuration: v2Configuration },
216
+ * );
217
+ * const wallet = Wallet.startWithSeed(seed);
218
+ * ```;
219
+ *
220
+ * @param configuration What the wallet layer needs: the network, and where the boundary lies.
221
+ * @param v1 The variant that reads the chain below the boundary, with the configuration it is built from.
222
+ * @param v2 The variant that reads it from the boundary, with the configuration it is built from.
223
+ * @returns The wallet class.
224
+ */
225
+ export declare function CustomForkingShieldedWallet<TV1SyncUpdate, TV2SyncUpdate, TV1Config extends object, TV2Config extends object, TConfiguration extends ForkingShieldedConfiguration = ForkingShieldedConfiguration>(configuration: TConfiguration, v1: SelfConfiguredShieldedVariant<V1ShieldedVariant<TV1SyncUpdate>, TV1Config>, v2: SelfConfiguredShieldedVariant<V2ShieldedVariant<TV2SyncUpdate>, TV2Config>): ForkingShieldedWalletClass<TV1SyncUpdate, TV2SyncUpdate, TConfiguration>;
226
+ /** A shielded wallet built the way this package ships it: one variant either side of the protocol boundary. */
227
+ export type ShieldedWallet = ForkingShieldedWallet<V1SyncUpdate, V2SyncUpdate>;
228
+ /** The class {@link ShieldedWallet} builds. */
229
+ export type ShieldedWalletClass = ForkingShieldedWalletClass<V1SyncUpdate, V2SyncUpdate, DefaultShieldedConfiguration>;
230
+ /**
231
+ * Builds the shielded wallet this package ships: the default variant either side of `configuration.forks.v9`.
232
+ *
233
+ * @remarks
234
+ * Both variants read the chain through the indexer and record transaction history in the same storage; each is built
235
+ * from the same application configuration, because what they ask for happens to coincide. The V2 variant is
236
+ * registered with the cross-ledger migration, which is what makes the hand-over carry identity and a cursor onto a
237
+ * fresh state rather than start a wallet from nothing.
238
+ *
239
+ * **Transacting works on either side of the boundary**: the active variant builds with its own ledger and its own
240
+ * derived keys, and every result travels as a handle stamped with the epoch that built it. Proving a ledger-v8
241
+ * transaction still requires a proving server registered below the boundary.
242
+ *
243
+ * **The chain is asked where it is before a variant is chosen.** The indexer this wallet already syncs from answers
244
+ * which protocol version the chain is on, so a start on a chain past the boundary begins on V2 rather than handing
245
+ * over immediately. An application that would rather ask something else — a cache, a value it already holds —
246
+ * supplies its own `chainVersionProbe`; one whose chain cannot be reached loses nothing, because the answer is
247
+ * best-effort and its absence is the behaviour this wallet had before.
248
+ * @param configuration What the wallet and both its variants are built from, including where the boundary lies.
249
+ * @returns The wallet class.
250
+ */
251
+ export declare function ShieldedWallet(configuration: DefaultShieldedConfiguration): ShieldedWalletClass;