@midnight-ntwrk/wallet-sdk-shielded 4.0.0-beta.2 → 4.0.0-beta.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -9
- package/dist/Restore.d.ts +40 -0
- package/dist/Restore.js +63 -0
- package/dist/ShieldedWallet.d.ts +248 -62
- package/dist/ShieldedWallet.js +366 -76
- package/dist/ShieldedWalletAPI.d.ts +179 -0
- package/dist/ShieldedWalletAPI.js +75 -0
- package/dist/SingleVariantShieldedWallet.d.ts +35 -0
- package/dist/SingleVariantShieldedWallet.js +240 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.js +4 -1
- package/dist/v1/CoinsAndBalances.d.ts +1 -1
- package/dist/v1/CoreWallet.d.ts +48 -1
- package/dist/v1/CoreWallet.js +54 -1
- package/dist/v1/Migration.d.ts +95 -0
- package/dist/v1/Migration.js +82 -0
- package/dist/v1/RunningV1Variant.d.ts +1 -1
- package/dist/v1/RunningV1Variant.js +37 -8
- package/dist/v1/Serialization.js +1 -1
- package/dist/v1/Sync.d.ts +132 -9
- package/dist/v1/Sync.js +272 -36
- package/dist/v1/Transacting.d.ts +1 -1
- package/dist/v1/Transacting.js +3 -2
- package/dist/v1/TransactionHistory.d.ts +9 -2
- package/dist/v1/TransactionHistory.js +26 -5
- package/dist/v1/TransactionOps.d.ts +1 -1
- package/dist/v1/V1Builder.d.ts +87 -26
- package/dist/v1/V1Builder.js +109 -8
- package/dist/v1/WalletError.d.ts +27 -2
- package/dist/v1/WalletError.js +16 -0
- package/dist/v1/index.d.ts +2 -1
- package/dist/v1/index.js +5 -1
- package/dist/v2/CoinsAndBalances.d.ts +24 -0
- package/dist/v2/CoinsAndBalances.js +41 -0
- package/dist/v2/CoreWallet.d.ts +162 -0
- package/dist/v2/CoreWallet.js +305 -0
- package/dist/v2/Keys.d.ts +8 -0
- package/dist/v2/Keys.js +16 -0
- package/dist/v2/Migration.d.ts +112 -0
- package/dist/v2/Migration.js +96 -0
- package/dist/v2/RunningV2Variant.d.ts +40 -0
- package/dist/v2/RunningV2Variant.js +127 -0
- package/dist/v2/Serialization.d.ts +12 -0
- package/dist/v2/Serialization.js +93 -0
- package/dist/v2/Sync.d.ts +208 -0
- package/dist/v2/Sync.js +463 -0
- package/dist/v2/Transacting.d.ts +50 -0
- package/dist/v2/Transacting.js +259 -0
- package/dist/v2/TransactionHistory.d.ts +100 -0
- package/dist/v2/TransactionHistory.js +132 -0
- package/dist/v2/TransactionImbalances.d.ts +10 -0
- package/dist/v2/TransactionImbalances.js +30 -0
- package/dist/v2/TransactionOps.d.ts +17 -0
- package/dist/v2/TransactionOps.js +73 -0
- package/dist/v2/V2Builder.d.ts +154 -0
- package/dist/v2/V2Builder.js +273 -0
- package/dist/v2/WalletError.d.ts +99 -0
- package/dist/v2/WalletError.js +69 -0
- package/dist/v2/index.d.ts +13 -0
- package/dist/v2/index.js +26 -0
- 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
|
|
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/
|
|
45
|
-
indexerWsUrl: 'ws://localhost:8088/api/
|
|
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
|
|
@@ -85,8 +89,10 @@ wallet.state.subscribe((state) => {
|
|
|
85
89
|
### Creating Transfer Transactions
|
|
86
90
|
|
|
87
91
|
```typescript
|
|
92
|
+
// tokenType: the shielded token type (raw hex) of a token you hold,
|
|
93
|
+
// e.g. one minted by a contract — NIGHT is unshielded and cannot appear here
|
|
88
94
|
const tx = await wallet.transferTransaction(shieldedSecretKeys, [
|
|
89
|
-
{ type:
|
|
95
|
+
{ type: tokenType, receiverAddress: 'mn_shield-addr1...', amount: 1000n },
|
|
90
96
|
]);
|
|
91
97
|
```
|
|
92
98
|
|
|
@@ -99,10 +105,12 @@ const balancingTx = await wallet.balanceTransaction(shieldedSecretKeys, transact
|
|
|
99
105
|
### Creating Swap Offers
|
|
100
106
|
|
|
101
107
|
```typescript
|
|
108
|
+
// tokenTypeA / tokenTypeB: shielded token types (raw hex) — both sides of a
|
|
109
|
+
// shielded swap are shielded tokens; NIGHT is unshielded and cannot appear here
|
|
102
110
|
const swapTx = await wallet.initSwap(
|
|
103
111
|
shieldedSecretKeys,
|
|
104
|
-
{
|
|
105
|
-
[{ type:
|
|
112
|
+
{ [tokenTypeA]: 500n }, // inputs
|
|
113
|
+
[{ type: tokenTypeB, receiverAddress: shieldedAddress, amount: 100n }], // outputs
|
|
106
114
|
);
|
|
107
115
|
```
|
|
108
116
|
|
|
@@ -124,7 +132,8 @@ While still proving:
|
|
|
124
132
|
|
|
125
133
|
- `ShieldedWallet` - Main wallet class
|
|
126
134
|
- `ShieldedWalletState` - Wallet state type
|
|
127
|
-
-
|
|
135
|
+
- V2 (ledger-v9) variant internals via `@midnight-ntwrk/wallet-sdk-shielded/v2`
|
|
136
|
+
- V1 (ledger-v8) variant internals via `@midnight-ntwrk/wallet-sdk-shielded/v1`
|
|
128
137
|
|
|
129
138
|
## License
|
|
130
139
|
|
|
@@ -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 {};
|
package/dist/Restore.js
ADDED
|
@@ -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
|
+
});
|
package/dist/ShieldedWallet.d.ts
CHANGED
|
@@ -1,65 +1,251 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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
|
-
|
|
20
|
-
|
|
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
|
-
|
|
23
|
-
export
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
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
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
export declare function
|
|
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;
|