@arkade-os/sdk 0.4.22 → 0.4.23
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 +95 -12
- package/dist/cjs/contracts/arkcontract.js +2 -1
- package/dist/cjs/identity/descriptor.js +75 -4
- package/dist/cjs/identity/hdCapableIdentity.js +2 -0
- package/dist/cjs/identity/seedIdentity.js +225 -103
- package/dist/cjs/identity/serialize.js +5 -0
- package/dist/cjs/identity/staticDescriptorProvider.js +1 -1
- package/dist/cjs/index.js +12 -3
- package/dist/cjs/providers/electrum.js +285 -79
- package/dist/cjs/providers/expoIndexer.js +1 -1
- package/dist/cjs/providers/indexer.js +2 -2
- package/dist/cjs/providers/onchain.js +9 -3
- package/dist/cjs/repositories/migrations/walletRepositoryImpl.js +6 -2
- package/dist/cjs/repositories/realm/walletRepository.js +2 -2
- package/dist/cjs/repositories/serialization.js +34 -1
- package/dist/cjs/repositories/sqlite/walletRepository.js +4 -2
- package/dist/cjs/script/address.js +2 -1
- package/dist/cjs/utils/transactionHistory.js +4 -4
- package/dist/cjs/wallet/asset-manager.js +18 -18
- package/dist/cjs/wallet/asset.js +10 -8
- package/dist/cjs/wallet/delegator.js +2 -2
- package/dist/cjs/wallet/hdDescriptorProvider.js +159 -0
- package/dist/cjs/wallet/index.js +5 -1
- package/dist/cjs/wallet/onchain.js +2 -1
- package/dist/cjs/wallet/serviceWorker/wallet-message-handler.js +1 -1
- package/dist/cjs/wallet/serviceWorker/wallet.js +5 -4
- package/dist/cjs/wallet/validation.js +2 -3
- package/dist/cjs/wallet/wallet.js +13 -14
- package/dist/esm/contracts/arkcontract.js +2 -1
- package/dist/esm/identity/descriptor.js +74 -5
- package/dist/esm/identity/hdCapableIdentity.js +1 -0
- package/dist/esm/identity/seedIdentity.js +225 -103
- package/dist/esm/identity/serialize.js +5 -0
- package/dist/esm/identity/staticDescriptorProvider.js +1 -1
- package/dist/esm/index.js +7 -4
- package/dist/esm/providers/electrum.js +284 -78
- package/dist/esm/providers/expoIndexer.js +1 -1
- package/dist/esm/providers/indexer.js +2 -2
- package/dist/esm/providers/onchain.js +9 -3
- package/dist/esm/repositories/migrations/walletRepositoryImpl.js +6 -2
- package/dist/esm/repositories/realm/walletRepository.js +3 -3
- package/dist/esm/repositories/serialization.js +27 -0
- package/dist/esm/repositories/sqlite/walletRepository.js +5 -3
- package/dist/esm/script/address.js +2 -1
- package/dist/esm/utils/transactionHistory.js +4 -4
- package/dist/esm/wallet/asset-manager.js +18 -18
- package/dist/esm/wallet/asset.js +10 -8
- package/dist/esm/wallet/delegator.js +2 -2
- package/dist/esm/wallet/hdDescriptorProvider.js +155 -0
- package/dist/esm/wallet/index.js +4 -0
- package/dist/esm/wallet/onchain.js +2 -1
- package/dist/esm/wallet/serviceWorker/wallet-message-handler.js +1 -1
- package/dist/esm/wallet/serviceWorker/wallet.js +5 -4
- package/dist/esm/wallet/validation.js +2 -3
- package/dist/esm/wallet/wallet.js +12 -14
- package/dist/types/contracts/arkcontract.d.ts +1 -1
- package/dist/types/identity/descriptor.d.ts +26 -0
- package/dist/types/identity/descriptorProvider.d.ts +11 -4
- package/dist/types/identity/hdCapableIdentity.d.ts +44 -0
- package/dist/types/identity/index.d.ts +1 -0
- package/dist/types/identity/seedIdentity.d.ts +113 -29
- package/dist/types/identity/serialize.d.ts +12 -0
- package/dist/types/identity/staticDescriptorProvider.d.ts +1 -1
- package/dist/types/index.d.ts +6 -3
- package/dist/types/providers/electrum.d.ts +115 -15
- package/dist/types/providers/onchain.d.ts +6 -0
- package/dist/types/repositories/serialization.d.ts +26 -2
- package/dist/types/script/address.d.ts +1 -1
- package/dist/types/wallet/hdDescriptorProvider.d.ts +93 -0
- package/dist/types/wallet/index.d.ts +19 -10
- package/dist/types/wallet/onchain.d.ts +1 -1
- package/dist/types/wallet/serviceWorker/wallet.d.ts +1 -1
- package/dist/types/wallet/wallet.d.ts +4 -1
- package/package.json +1 -1
|
@@ -1,3 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* True iff `descriptor` is a Bitcoin mainnet descriptor (xpub-prefixed
|
|
3
|
+
* BIP32 key).
|
|
4
|
+
*
|
|
5
|
+
* Note: testnet, signet, regtest, mutinynet, and other non-mainnet
|
|
6
|
+
* networks all share the same `tpub` BIP32 version bytes — they cannot
|
|
7
|
+
* be distinguished from one another at the descriptor level. Callers
|
|
8
|
+
* that need a `Network` constants object for `expand()` pick
|
|
9
|
+
* `networks.bitcoin` vs `networks.testnet` themselves; callers that
|
|
10
|
+
* need the *actual* network the wallet is on must track that
|
|
11
|
+
* out-of-band.
|
|
12
|
+
*/
|
|
13
|
+
export declare function isMainnetDescriptor(descriptor: string): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Shared "does `candidate` belong to the identity backed by
|
|
16
|
+
* `ourDescriptor`?" predicate.
|
|
17
|
+
*
|
|
18
|
+
* - HD descriptors (expanding to a `bip32` key) match by account xpub
|
|
19
|
+
* on both sides — index-agnostic, so a wildcard template and any
|
|
20
|
+
* concrete index under it all collapse to the same xpub.
|
|
21
|
+
* - Bare `tr(pubkey)` candidates fall back to comparing the candidate
|
|
22
|
+
* pubkey against `ourXOnlyPubkey` (the cached pubkey on the identity
|
|
23
|
+
* side, since pulling it from `ourDescriptor` would require an index
|
|
24
|
+
* substitution the caller already performed).
|
|
25
|
+
*/
|
|
26
|
+
export declare function descriptorIsOurs(candidate: string, ourDescriptor: string, ourXOnlyPubkey: Uint8Array): boolean;
|
|
1
27
|
/**
|
|
2
28
|
* Check if a string is a descriptor of the shape `tr(...)`.
|
|
3
29
|
*
|
|
@@ -13,12 +13,19 @@ export interface DescriptorSigningRequest {
|
|
|
13
13
|
*
|
|
14
14
|
* Implementations include:
|
|
15
15
|
* - {@link StaticDescriptorProvider}: wraps a legacy {@link Identity} with a single key.
|
|
16
|
-
* -
|
|
17
|
-
*
|
|
16
|
+
* - {@link HDDescriptorProvider}: rotates through HD-derived descriptors.
|
|
17
|
+
*
|
|
18
|
+
* The provider has no read accessor for "current" — it is a pure descriptor
|
|
19
|
+
* allocator. "What addresses am I currently bound to?" is a question the
|
|
20
|
+
* contract repository answers, not the provider.
|
|
18
21
|
*/
|
|
19
22
|
export interface DescriptorProvider {
|
|
20
|
-
/**
|
|
21
|
-
|
|
23
|
+
/**
|
|
24
|
+
* Allocate a new signing descriptor. For HD providers each call advances
|
|
25
|
+
* the internal index and returns a fresh descriptor; for single-key
|
|
26
|
+
* providers each call returns the same descriptor.
|
|
27
|
+
*/
|
|
28
|
+
getNextSigningDescriptor(): Promise<string>;
|
|
22
29
|
/** Checks if a descriptor belongs to this provider. */
|
|
23
30
|
isOurs(descriptor: string): boolean;
|
|
24
31
|
/** Signs transactions, each with its own descriptor-derived key. */
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Identity, ReadonlyIdentity } from ".";
|
|
2
|
+
import { DescriptorSigningRequest } from "./descriptorProvider";
|
|
3
|
+
import { Transaction } from "../utils/transaction";
|
|
4
|
+
/**
|
|
5
|
+
* Read-side HD capability marker. Exposes the wildcard-suffixed account
|
|
6
|
+
* descriptor *template* and the descriptor-membership predicate, but no
|
|
7
|
+
* signing primitives — suitable for watch-only identities backed by an
|
|
8
|
+
* xpub.
|
|
9
|
+
*
|
|
10
|
+
* Extracted from {@link HDCapableIdentity} so that
|
|
11
|
+
* `ReadonlyDescriptorIdentity` can stand in for an HD wallet's read-only
|
|
12
|
+
* surface (template-aware, derives pubkeys at any index) without having
|
|
13
|
+
* to claim signing capability it cannot honour.
|
|
14
|
+
*/
|
|
15
|
+
export interface ReadonlyHDCapableIdentity extends ReadonlyIdentity {
|
|
16
|
+
/**
|
|
17
|
+
* The wildcard-suffixed account descriptor template
|
|
18
|
+
* (e.g. `tr([fp/86'/0'/0']xpub/0/*)`). Consumers materialize a
|
|
19
|
+
* concrete descriptor by replacing the `*` with a derivation index.
|
|
20
|
+
*/
|
|
21
|
+
readonly descriptor: string;
|
|
22
|
+
/** True iff `descriptor` derives from this identity's xpub/seed. */
|
|
23
|
+
isOurs(descriptor: string): boolean;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Capability marker for identities that can be rotated through an HD
|
|
27
|
+
* derivation tree AND can sign at each rotated index.
|
|
28
|
+
*
|
|
29
|
+
* Deliberately does NOT extend `DescriptorProvider`: if an HD-capable
|
|
30
|
+
* identity were silently usable as a concrete descriptor source, callers
|
|
31
|
+
* could bypass receive rotation and unknowingly reuse a single address
|
|
32
|
+
* forever. To use this identity as a wallet's descriptor source, wrap
|
|
33
|
+
* it explicitly:
|
|
34
|
+
*
|
|
35
|
+
* - `HDDescriptorProvider` — rotating, recommended for new wallets.
|
|
36
|
+
* - `StaticDescriptorProvider` — pinned to a single key, for legacy or
|
|
37
|
+
* explicitly-non-rotating use cases.
|
|
38
|
+
*/
|
|
39
|
+
export interface HDCapableIdentity extends ReadonlyHDCapableIdentity, Identity {
|
|
40
|
+
/** Signs each request with the key derived from its descriptor. */
|
|
41
|
+
signWithDescriptor(requests: DescriptorSigningRequest[]): Promise<Transaction[]>;
|
|
42
|
+
/** Signs a message using the key derived from `descriptor`. */
|
|
43
|
+
signMessageWithDescriptor(descriptor: string, message: Uint8Array, signatureType?: "schnorr" | "ecdsa"): Promise<Uint8Array>;
|
|
44
|
+
}
|
|
@@ -52,4 +52,5 @@ export * from "./serialize";
|
|
|
52
52
|
export { isDescriptor, normalizeToDescriptor, extractPubKey, parseHDDescriptor, } from "./descriptor";
|
|
53
53
|
export type { ParsedHDDescriptor } from "./descriptor";
|
|
54
54
|
export type { DescriptorProvider, DescriptorSigningRequest, } from "./descriptorProvider";
|
|
55
|
+
export type { HDCapableIdentity, ReadonlyHDCapableIdentity, } from "./hdCapableIdentity";
|
|
55
56
|
export { StaticDescriptorProvider } from "./staticDescriptorProvider";
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { Identity, ReadonlyIdentity } from ".";
|
|
2
1
|
import { Transaction } from "../utils/transaction";
|
|
3
2
|
import { SignerSession } from "../tree/signingSession";
|
|
4
3
|
import type { SerializedSigningIdentity, SerializedReadonlyIdentity } from "./serialize";
|
|
4
|
+
import { DescriptorSigningRequest } from "./descriptorProvider";
|
|
5
|
+
import { HDCapableIdentity, ReadonlyHDCapableIdentity } from "./hdCapableIdentity";
|
|
5
6
|
/** Used for default BIP86 derivation with network selection. */
|
|
6
7
|
export interface NetworkOptions {
|
|
7
8
|
/**
|
|
@@ -11,12 +12,16 @@ export interface NetworkOptions {
|
|
|
11
12
|
*/
|
|
12
13
|
isMainnet?: boolean;
|
|
13
14
|
}
|
|
14
|
-
/** Used for
|
|
15
|
+
/** Used for a caller-supplied account-descriptor template. */
|
|
15
16
|
export interface DescriptorOptions {
|
|
16
|
-
/**
|
|
17
|
+
/**
|
|
18
|
+
* Account-descriptor *template* — must end with the BIP-32 wildcard
|
|
19
|
+
* suffix `/*)`. Stored as-is on {@link SeedIdentity.descriptor} and
|
|
20
|
+
* read by HD providers to rotate through derivation indices.
|
|
21
|
+
*/
|
|
17
22
|
descriptor: string;
|
|
18
23
|
}
|
|
19
|
-
/** Either default BIP86 derivation (with optional network selection) or a
|
|
24
|
+
/** Either default BIP86 derivation (with optional network selection) or a caller-supplied template. */
|
|
20
25
|
export type SeedIdentityOptions = NetworkOptions | DescriptorOptions;
|
|
21
26
|
/** Used for deriving an identity from a BIP39 mnemonic. */
|
|
22
27
|
export type MnemonicOptions = SeedIdentityOptions & {
|
|
@@ -24,44 +29,77 @@ export type MnemonicOptions = SeedIdentityOptions & {
|
|
|
24
29
|
passphrase?: string;
|
|
25
30
|
};
|
|
26
31
|
/**
|
|
27
|
-
* Seed-based identity derived from a raw seed and an
|
|
32
|
+
* Seed-based identity derived from a raw seed and an account descriptor
|
|
33
|
+
* *template*.
|
|
28
34
|
*
|
|
29
35
|
* This is the recommended identity type for most applications. It uses
|
|
30
|
-
* standard BIP86 (Taproot) derivation by default
|
|
31
|
-
*
|
|
36
|
+
* standard BIP86 (Taproot) derivation by default; callers that need a
|
|
37
|
+
* different path supply the wildcard template directly.
|
|
32
38
|
*
|
|
33
39
|
* Prefer this (or @see MnemonicIdentity) over `SingleKey` for new
|
|
34
40
|
* integrations — `SingleKey` exists for backward compatibility with
|
|
35
41
|
* raw nsec-style keys.
|
|
36
42
|
*
|
|
37
|
-
*
|
|
43
|
+
* The identity holds the wildcard *template* (e.g.
|
|
44
|
+
* `tr([fp/86'/0'/0']xpub/0/*)`) on its public {@link descriptor}
|
|
45
|
+
* field. HD rotation reads it directly; consumers that need a
|
|
46
|
+
* concrete descriptor at a specific index materialize it themselves
|
|
47
|
+
* (see `HDDescriptorProvider` in the wallet layer).
|
|
48
|
+
*
|
|
49
|
+
* Exposes seed-level primitives (signing, derivation, the template)
|
|
50
|
+
* but is deliberately NOT a `DescriptorProvider`. Wrap it explicitly
|
|
51
|
+
* to get one:
|
|
52
|
+
* - `HDDescriptorProvider` for rotating receive addresses.
|
|
53
|
+
* - {@link StaticDescriptorProvider} for legacy, single-key behaviour.
|
|
54
|
+
*
|
|
55
|
+
* The split prevents a SeedIdentity from being silently used as a
|
|
56
|
+
* concrete descriptor source, which would defeat HD rotation without
|
|
57
|
+
* any compile-time signal that something was wrong.
|
|
38
58
|
*
|
|
39
59
|
* @example
|
|
40
60
|
* ```typescript
|
|
41
61
|
* const seed = mnemonicToSeedSync(mnemonic);
|
|
42
62
|
*
|
|
43
|
-
* // Testnet (BIP86
|
|
63
|
+
* // Testnet (BIP86 wildcard descriptor m/86'/1'/0'/0/*)
|
|
44
64
|
* const identity = SeedIdentity.fromSeed(seed, { isMainnet: false });
|
|
45
65
|
*
|
|
46
|
-
* // Mainnet (BIP86
|
|
66
|
+
* // Mainnet (BIP86 wildcard descriptor m/86'/0'/0'/0/*)
|
|
47
67
|
* const identity = SeedIdentity.fromSeed(seed, { isMainnet: true });
|
|
48
68
|
*
|
|
49
|
-
* //
|
|
69
|
+
* // Caller-supplied wildcard descriptor (must end in `/*)`).
|
|
50
70
|
* const identity = SeedIdentity.fromSeed(seed, { descriptor });
|
|
51
71
|
* ```
|
|
52
72
|
*/
|
|
53
|
-
export declare class SeedIdentity implements
|
|
73
|
+
export declare class SeedIdentity implements HDCapableIdentity {
|
|
54
74
|
private readonly derivedKey;
|
|
75
|
+
/**
|
|
76
|
+
* Wildcard account-descriptor template (e.g.
|
|
77
|
+
* `tr([fp/86'/0'/0']xpub/0/*)`). The canonical thing to pass
|
|
78
|
+
* through the system; consumers materialize a concrete descriptor
|
|
79
|
+
* at a specific index themselves (see `HDDescriptorProvider` in
|
|
80
|
+
* the wallet layer for the rotating-counter use case).
|
|
81
|
+
*/
|
|
55
82
|
readonly descriptor: string;
|
|
56
|
-
|
|
83
|
+
/**
|
|
84
|
+
* Constructs a SeedIdentity from a 64-byte seed and either a
|
|
85
|
+
* caller-supplied wildcard descriptor (`{ descriptor }`) or the
|
|
86
|
+
* default BIP86 path at the requested network (`{ isMainnet }`).
|
|
87
|
+
* Prefer the {@link fromSeed} factory for symmetry with
|
|
88
|
+
* {@link MnemonicIdentity.fromMnemonic}.
|
|
89
|
+
*
|
|
90
|
+
* Throws on a non-wildcard descriptor, an xpub mismatch with the
|
|
91
|
+
* seed, or a missing derivation path.
|
|
92
|
+
*/
|
|
93
|
+
constructor(seed: Uint8Array, opts?: SeedIdentityOptions);
|
|
57
94
|
/**
|
|
58
95
|
* Creates a SeedIdentity from a raw 64-byte seed.
|
|
59
96
|
*
|
|
60
97
|
* Pass `{ isMainnet }` for default BIP86 derivation, or
|
|
61
|
-
* `{ descriptor }` for a
|
|
98
|
+
* `{ descriptor }` for a caller-supplied account-descriptor
|
|
99
|
+
* template (the option's value must end with `/*)`).
|
|
62
100
|
*
|
|
63
101
|
* @param seed - 64-byte seed (typically from mnemonicToSeedSync)
|
|
64
|
-
* @param opts - Network selection or
|
|
102
|
+
* @param opts - Network selection or descriptor template.
|
|
65
103
|
*/
|
|
66
104
|
static fromSeed(seed: Uint8Array, opts?: SeedIdentityOptions): SeedIdentity;
|
|
67
105
|
xOnlyPublicKey(): Promise<Uint8Array>;
|
|
@@ -70,9 +108,29 @@ export declare class SeedIdentity implements Identity {
|
|
|
70
108
|
signMessage(message: Uint8Array, signatureType?: "schnorr" | "ecdsa"): Promise<Uint8Array>;
|
|
71
109
|
signerSession(): SignerSession;
|
|
72
110
|
/**
|
|
73
|
-
* Converts to a watch-only identity that cannot sign.
|
|
111
|
+
* Converts to a watch-only identity that cannot sign. Carries the
|
|
112
|
+
* template forward, so the readonly side stays HD-capable (can
|
|
113
|
+
* derive descriptors at any index without seed access).
|
|
74
114
|
*/
|
|
75
115
|
toReadonly(): Promise<ReadonlyDescriptorIdentity>;
|
|
116
|
+
/**
|
|
117
|
+
* Returns true when `descriptor` is derived from this identity's seed.
|
|
118
|
+
* HD descriptors match by account xpub; bare `tr(pubkey)` descriptors
|
|
119
|
+
* match by raw pubkey. See {@link descriptorIsOurs}.
|
|
120
|
+
*/
|
|
121
|
+
isOurs(descriptor: string): boolean;
|
|
122
|
+
/**
|
|
123
|
+
* Signs each request with the key derived from its descriptor.
|
|
124
|
+
* Each descriptor must share this identity's seed ({@link isOurs}).
|
|
125
|
+
*/
|
|
126
|
+
signWithDescriptor(requests: DescriptorSigningRequest[]): Promise<Transaction[]>;
|
|
127
|
+
/**
|
|
128
|
+
* Signs a message with the key derived from `descriptor`.
|
|
129
|
+
*/
|
|
130
|
+
signMessageWithDescriptor(descriptor: string, message: Uint8Array, signatureType?: "schnorr" | "ecdsa"): Promise<Uint8Array>;
|
|
131
|
+
private derivePrivateKeyForDescriptor;
|
|
132
|
+
private signTxWithKey;
|
|
133
|
+
private signMessageWithKey;
|
|
76
134
|
}
|
|
77
135
|
/**
|
|
78
136
|
* Mnemonic-based identity derived from a BIP39 phrase.
|
|
@@ -96,40 +154,66 @@ export declare class MnemonicIdentity extends SeedIdentity {
|
|
|
96
154
|
* Creates a MnemonicIdentity from a BIP39 mnemonic phrase.
|
|
97
155
|
*
|
|
98
156
|
* Pass `{ isMainnet }` for default BIP86 derivation, or
|
|
99
|
-
* `{ descriptor }` for a
|
|
157
|
+
* `{ descriptor }` for a caller-supplied account-descriptor
|
|
158
|
+
* template (the option's value must end with `/*)`).
|
|
100
159
|
*
|
|
101
160
|
* @param phrase - BIP39 mnemonic phrase (12 or 24 words)
|
|
102
|
-
* @param opts - Network selection or
|
|
161
|
+
* @param opts - Network selection or descriptor template, plus optional passphrase
|
|
103
162
|
*/
|
|
104
163
|
static fromMnemonic(phrase: string, opts?: MnemonicOptions): MnemonicIdentity;
|
|
105
164
|
}
|
|
106
165
|
/**
|
|
107
|
-
* Watch-only identity from
|
|
166
|
+
* Watch-only HD identity from a descriptor *template*.
|
|
108
167
|
*
|
|
109
168
|
* Can derive public keys but cannot sign transactions. Use this for
|
|
110
|
-
* watch-only wallets
|
|
111
|
-
*
|
|
169
|
+
* watch-only wallets — given just an xpub-based template, the readonly
|
|
170
|
+
* side still rotates through HD indices.
|
|
171
|
+
*
|
|
172
|
+
* Constructed from a wildcard template (e.g.
|
|
173
|
+
* `tr([fp/86'/0'/0']xpub.../0/*)`); the {@link descriptor} field
|
|
174
|
+
* holds it for HD providers to consume.
|
|
112
175
|
*
|
|
113
176
|
* @example
|
|
114
177
|
* ```typescript
|
|
115
|
-
* const
|
|
116
|
-
*
|
|
117
|
-
*
|
|
178
|
+
* const ro = ReadonlyDescriptorIdentity.fromDescriptor(
|
|
179
|
+
* "tr([fp/86'/0'/0']xpub.../0/*)"
|
|
180
|
+
* );
|
|
181
|
+
* ro.descriptor;
|
|
182
|
+
* // => "tr([fp/86'/0'/0']xpub.../0/*)" — the template
|
|
118
183
|
* ```
|
|
119
184
|
*/
|
|
120
|
-
export declare class ReadonlyDescriptorIdentity implements
|
|
185
|
+
export declare class ReadonlyDescriptorIdentity implements ReadonlyHDCapableIdentity {
|
|
186
|
+
/**
|
|
187
|
+
* Index-0 expansion of {@link descriptor}. Both the x-only pubkey
|
|
188
|
+
* (taproot, returned by the library as 32 bytes) and the compressed
|
|
189
|
+
* pubkey (derived through the bip32 node when needed) are read off
|
|
190
|
+
* this on demand — no separate caches.
|
|
191
|
+
*/
|
|
192
|
+
private readonly indexZero;
|
|
193
|
+
/**
|
|
194
|
+
* Wildcard account-descriptor template (e.g.
|
|
195
|
+
* `tr([fp/86'/0'/0']xpub/0/*)`). HD rotation consumers materialize
|
|
196
|
+
* a concrete descriptor at a specific index themselves.
|
|
197
|
+
*/
|
|
121
198
|
readonly descriptor: string;
|
|
122
|
-
private readonly xOnlyPubKey;
|
|
123
|
-
private readonly compressedPubKey;
|
|
124
199
|
private constructor();
|
|
125
200
|
/**
|
|
126
|
-
* Creates a ReadonlyDescriptorIdentity from an
|
|
201
|
+
* Creates a ReadonlyDescriptorIdentity from an account-descriptor
|
|
202
|
+
* *template* (must end with the BIP-32 wildcard suffix `/*)`).
|
|
127
203
|
*
|
|
128
|
-
* @param descriptor - Taproot
|
|
204
|
+
* @param descriptor - Wildcard-suffixed Taproot template
|
|
205
|
+
* (`tr([fp/path']xpub.../child/*)`).
|
|
129
206
|
*/
|
|
130
207
|
static fromDescriptor(descriptor: string): ReadonlyDescriptorIdentity;
|
|
131
208
|
xOnlyPublicKey(): Promise<Uint8Array>;
|
|
132
209
|
compressedPublicKey(): Promise<Uint8Array>;
|
|
210
|
+
/**
|
|
211
|
+
* Returns true when `descriptor` derives from this identity's xpub.
|
|
212
|
+
* HD descriptors match by account xpub; bare `tr(pubkey)` descriptors
|
|
213
|
+
* fall back to comparing against the index-0 x-only pubkey. See
|
|
214
|
+
* {@link descriptorIsOurs}.
|
|
215
|
+
*/
|
|
216
|
+
isOurs(descriptor: string): boolean;
|
|
133
217
|
}
|
|
134
218
|
/**
|
|
135
219
|
* Serialize a seed-backed signing identity into a
|
|
@@ -4,6 +4,11 @@ import type { Identity, ReadonlyIdentity } from ".";
|
|
|
4
4
|
* service-worker boundary. All variants are structured-clone safe
|
|
5
5
|
* (plain strings only — no functions or prototypes).
|
|
6
6
|
*
|
|
7
|
+
* `descriptor` carries the wildcard *template* (e.g.
|
|
8
|
+
* `tr([fp/86'/0'/0']xpub.../0/*)`), not a concrete index — the
|
|
9
|
+
* receiving factories require a template, and storing it directly
|
|
10
|
+
* means nothing here has to convert concrete → template on rehydrate.
|
|
11
|
+
*
|
|
7
12
|
* Adding a new variant is a source change in every worker build; keep
|
|
8
13
|
* old variants around until all deployed workers handle them.
|
|
9
14
|
*/
|
|
@@ -23,6 +28,8 @@ export type SerializedSigningIdentity = {
|
|
|
23
28
|
/**
|
|
24
29
|
* Tagged envelope for a readonly identity transported across the
|
|
25
30
|
* service-worker boundary. All variants are structured-clone safe.
|
|
31
|
+
* `descriptor` is the wildcard template (see
|
|
32
|
+
* {@link SerializedSigningIdentity}).
|
|
26
33
|
*/
|
|
27
34
|
export type SerializedReadonlyIdentity = {
|
|
28
35
|
type: "readonly-single-key";
|
|
@@ -57,6 +64,11 @@ export declare function serializeReadonlyIdentity(identity: ReadonlyIdentity): P
|
|
|
57
64
|
* The return type is the union of signing and readonly; use
|
|
58
65
|
* {@link isSigningSerialized} on the envelope before hydration if the caller
|
|
59
66
|
* needs to know which side it ends up on.
|
|
67
|
+
*
|
|
68
|
+
* Envelopes store the wildcard template directly (see
|
|
69
|
+
* `serializeSeedOwnedSigningIdentity` / `serializeSeedOwnedReadonlyIdentity`),
|
|
70
|
+
* so the `descriptor` field is passed straight through to the
|
|
71
|
+
* template-only factories.
|
|
60
72
|
*/
|
|
61
73
|
export declare function hydrateIdentity(s: SerializedIdentity): Identity | ReadonlyIdentity;
|
|
62
74
|
/**
|
|
@@ -11,7 +11,7 @@ export declare class StaticDescriptorProvider implements DescriptorProvider {
|
|
|
11
11
|
private readonly pubKeyHex;
|
|
12
12
|
constructor(identity: Identity, pubKeyHex: string);
|
|
13
13
|
static create(identity: Identity): Promise<StaticDescriptorProvider>;
|
|
14
|
-
|
|
14
|
+
getNextSigningDescriptor(): Promise<string>;
|
|
15
15
|
isOurs(descriptor: string): boolean;
|
|
16
16
|
signWithDescriptor(requests: DescriptorSigningRequest[]): Promise<Transaction[]>;
|
|
17
17
|
signMessageWithDescriptor(descriptor: string, message: Uint8Array, type?: "schnorr" | "ecdsa"): Promise<Uint8Array>;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -15,6 +15,7 @@ import { Wallet, ReadonlyWallet, waitForIncomingFunds, IncomingFunds } from "./w
|
|
|
15
15
|
import { TxTree, TxTreeNode } from "./tree/txTree";
|
|
16
16
|
import { SignerSession, TreeNonces, TreePartialSigs } from "./tree/signingSession";
|
|
17
17
|
import { Ramps } from "./wallet/ramps";
|
|
18
|
+
import { HDDescriptorProvider } from "./wallet/hdDescriptorProvider";
|
|
18
19
|
import { isVtxoExpiringSoon, VtxoManager } from "./wallet/vtxo-manager";
|
|
19
20
|
import type { IVtxoManager, SettlementConfig } from "./wallet/vtxo-manager";
|
|
20
21
|
import { ServiceWorkerWallet, ServiceWorkerReadonlyWallet, DEFAULT_MESSAGE_TIMEOUTS } from "./wallet/serviceWorker/wallet";
|
|
@@ -22,7 +23,7 @@ import type { MessageTimeouts } from "./wallet/serviceWorker/wallet";
|
|
|
22
23
|
import { OnchainWallet } from "./wallet/onchain";
|
|
23
24
|
import { setupServiceWorker } from "./worker/browser/utils";
|
|
24
25
|
import { ESPLORA_URL, EsploraProvider, OnchainProvider, ExplorerTransaction } from "./providers/onchain";
|
|
25
|
-
import { ElectrumOnchainProvider, WsElectrumChainSource } from "./providers/electrum";
|
|
26
|
+
import { ELECTRUM_TCP_HOST, ELECTRUM_WS_URL, ElectrumOnchainProvider, WsElectrumChainSource } from "./providers/electrum";
|
|
26
27
|
import type { TransactionHistory as ElectrumTransactionHistory, BlockHeader as ElectrumBlockHeader, Unspent as ElectrumUnspent } from "./providers/electrum";
|
|
27
28
|
import { RestArkProvider, ArkProvider, SettlementEvent, SettlementEventType, ArkInfo, SignedIntent, Output, TxNotification, BatchFinalizationEvent, BatchFinalizedEvent, BatchFailedEvent, TreeSigningStartedEvent, TreeNoncesEvent, BatchStartedEvent, TreeTxEvent, TreeSignatureEvent, ScheduledSession, FeeInfo } from "./providers/ark";
|
|
28
29
|
import { DelegatorProvider, DelegateInfo, DelegateOptions, RestDelegatorProvider } from "./providers/delegator";
|
|
@@ -37,6 +38,7 @@ import { RestIndexerProvider, IndexerProvider, IndexerTxType, ChainTxType, PageR
|
|
|
37
38
|
import { Nonces } from "./musig2/nonces";
|
|
38
39
|
import { PartialSig } from "./musig2/sign";
|
|
39
40
|
import { AnchorBumper, P2A } from "./utils/anchor";
|
|
41
|
+
import { TxWeightEstimator, type VSize } from "./utils/txSizeEstimator";
|
|
40
42
|
import { Unroll } from "./wallet/unroll";
|
|
41
43
|
import { ArkError, maybeArkError } from "./providers/errors";
|
|
42
44
|
import { validateVtxoTxGraph, validateConnectorsTxGraph } from "./tree/validation";
|
|
@@ -49,8 +51,9 @@ export * as asset from "./extension/asset";
|
|
|
49
51
|
import { ContractManager, ContractWatcher, contractHandlers, DefaultContractHandler, DelegateContractHandler, VHTLCContractHandler, encodeArkContract, decodeArkContract, contractFromArkContract, contractFromArkContractWithAddress, isArkContract } from "./contracts";
|
|
50
52
|
import type { Contract, ContractVtxo, ContractState, ContractEvent, ContractEventCallback, ContractBalance, ContractWithVtxos, ContractHandler, PathSelection, PathContext, ContractManagerConfig, CreateContractParams, ContractWatcherConfig, ParsedArkContract, DefaultContractParams, DelegateContractParams, VHTLCContractParams } from "./contracts";
|
|
51
53
|
import { IContractManager } from "./contracts/contractManager";
|
|
54
|
+
import { timelockToSequence, sequenceToTimelock } from "./contracts/handlers/helpers";
|
|
52
55
|
import { closeDatabase, openDatabase } from "./repositories/indexedDB/manager";
|
|
53
56
|
import { WalletMessageHandler, WalletNotInitializedError, ReadonlyWalletError, DelegatorNotConfiguredError } from "./wallet/serviceWorker/wallet-message-handler";
|
|
54
57
|
import { MESSAGE_BUS_NOT_INITIALIZED, MessageBusNotInitializedError, ServiceWorkerTimeoutError } from "./worker/errors";
|
|
55
|
-
export { Wallet, ReadonlyWallet, SingleKey, ReadonlySingleKey, SeedIdentity, MnemonicIdentity, ReadonlyDescriptorIdentity, isBatchSignable, OnchainWallet, Ramps, VtxoManager, DelegatorManagerImpl, RestDelegatorProvider, ESPLORA_URL, EsploraProvider, ElectrumOnchainProvider, WsElectrumChainSource, RestArkProvider, RestIndexerProvider, ArkAddress, DefaultVtxo, DelegateVtxo, VtxoScript, VHTLC, TxType, IndexerTxType, ChainTxType, SettlementEventType, setupServiceWorker, MessageBus, WalletMessageHandler, WalletNotInitializedError, ReadonlyWalletError, DelegatorNotConfiguredError, MESSAGE_BUS_NOT_INITIALIZED, MessageBusNotInitializedError, ServiceWorkerTimeoutError, ServiceWorkerWallet, ServiceWorkerReadonlyWallet, DEFAULT_MESSAGE_TIMEOUTS, decodeTapscript, MultisigTapscript, CSVMultisigTapscript, ConditionCSVMultisigTapscript, ConditionMultisigTapscript, CLTVMultisigTapscript, TapTreeCoder, ArkPsbtFieldKey, ArkPsbtFieldKeyType, setArkPsbtField, getArkPsbtFields, CosignerPublicKey, VtxoTreeExpiry, VtxoTaprootTree, ConditionWitness, buildOffchainTx, verifyTapscriptSignatures, waitForIncomingFunds, hasBoardingTxExpired, combineTapscriptSigs, isVtxoExpiringSoon, isValidArkAddress, ArkNote, networks, closeDatabase, openDatabase, IndexedDBWalletRepository, IndexedDBContractRepository, InMemoryWalletRepository, InMemoryContractRepository, MIGRATION_KEY, migrateWalletRepository, requiresMigration, getMigrationStatus, rollbackMigration, WalletRepositoryImpl, ContractRepositoryImpl, Intent, BIP322, TxTree, P2A, Unroll, Transaction, ArkError, maybeArkError, Batch, validateVtxoTxGraph, validateConnectorsTxGraph, buildForfeitTx, isRecoverable, isSpendable, isSubdust, isExpired, getSequence, ContractManager, ContractWatcher, contractHandlers, DefaultContractHandler, DelegateContractHandler, VHTLCContractHandler, encodeArkContract, decodeArkContract, contractFromArkContract, contractFromArkContractWithAddress, isArkContract, };
|
|
56
|
-
export type { Identity, ReadonlyIdentity, BatchSignableIdentity, SignRequest, IWallet, IReadonlyWallet, BaseWalletConfig, WalletConfig, ReadonlyWalletConfig, ProviderClass, ArkTransaction, Coin, ExtendedCoin, ExtendedVirtualCoin, WalletBalance, SendBitcoinParams, SettleParams, Status, VirtualStatus, Outpoint, VirtualCoin, TxKey, TapscriptType, ArkTxInput, OffchainTx, TapLeaves, IncomingFunds, SeedIdentityOptions, MnemonicOptions, NetworkOptions, DescriptorOptions, IndexerProvider, PageResponse, BatchInfo, ChainTx, CommitmentTx, TxHistoryRecord, Vtxo, VtxoChain, Tx, OnchainProvider, ArkProvider, SettlementEvent, FeeInfo, ArkInfo, SignedIntent, Output, TxNotification, ExplorerTransaction, ElectrumTransactionHistory, ElectrumBlockHeader, ElectrumUnspent, BatchFinalizationEvent, BatchFinalizedEvent, BatchFailedEvent, TreeSigningStartedEvent, TreeNoncesEvent, BatchStartedEvent, TreeTxEvent, TreeSignatureEvent, ScheduledSession, PaginationOptions, SubscriptionResponse, SubscriptionHeartbeat, SubscriptionEvent, Network, NetworkName, ArkTapscript, RelativeTimelock, EncodedVtxoScript, TapLeafScript, SignerSession, TreeNonces, TreePartialSigs, GetVtxosFilter, SettlementConfig, IVtxoManager, Asset, Recipient, IssuanceParams, IssuanceResult, ReissuanceParams, BurnParams, AssetDetails, AssetMetadata, KnownMetadata, Nonces, PartialSig, ArkPsbtFieldCoder, TxTreeNode, AnchorBumper, StorageConfig, Contract, ContractVtxo, ContractState, ContractEvent, ContractEventCallback, ContractBalance, ContractWithVtxos, ContractHandler, IContractManager, PathSelection, PathContext, ContractManagerConfig, CreateContractParams, ContractWatcherConfig, ParsedArkContract, DefaultContractParams, DelegateContractParams, VHTLCContractParams, MessageHandler, RequestEnvelope, ResponseEnvelope, MessageTimeouts, IDelegatorManager, DelegatorProvider, DelegateInfo, DelegateOptions, WalletRepository, ContractRepository, MigrationStatus, };
|
|
58
|
+
export { Wallet, ReadonlyWallet, SingleKey, ReadonlySingleKey, SeedIdentity, MnemonicIdentity, ReadonlyDescriptorIdentity, isBatchSignable, OnchainWallet, Ramps, VtxoManager, HDDescriptorProvider, DelegatorManagerImpl, RestDelegatorProvider, ESPLORA_URL, EsploraProvider, ELECTRUM_WS_URL, ELECTRUM_TCP_HOST, ElectrumOnchainProvider, WsElectrumChainSource, RestArkProvider, RestIndexerProvider, ArkAddress, DefaultVtxo, DelegateVtxo, VtxoScript, VHTLC, TxType, IndexerTxType, ChainTxType, SettlementEventType, setupServiceWorker, MessageBus, WalletMessageHandler, WalletNotInitializedError, ReadonlyWalletError, DelegatorNotConfiguredError, MESSAGE_BUS_NOT_INITIALIZED, MessageBusNotInitializedError, ServiceWorkerTimeoutError, ServiceWorkerWallet, ServiceWorkerReadonlyWallet, DEFAULT_MESSAGE_TIMEOUTS, decodeTapscript, MultisigTapscript, CSVMultisigTapscript, ConditionCSVMultisigTapscript, ConditionMultisigTapscript, CLTVMultisigTapscript, TapTreeCoder, ArkPsbtFieldKey, ArkPsbtFieldKeyType, setArkPsbtField, getArkPsbtFields, CosignerPublicKey, VtxoTreeExpiry, VtxoTaprootTree, ConditionWitness, buildOffchainTx, verifyTapscriptSignatures, waitForIncomingFunds, hasBoardingTxExpired, combineTapscriptSigs, isVtxoExpiringSoon, isValidArkAddress, ArkNote, networks, closeDatabase, openDatabase, IndexedDBWalletRepository, IndexedDBContractRepository, InMemoryWalletRepository, InMemoryContractRepository, MIGRATION_KEY, migrateWalletRepository, requiresMigration, getMigrationStatus, rollbackMigration, WalletRepositoryImpl, ContractRepositoryImpl, Intent, BIP322, TxTree, P2A, Unroll, Transaction, TxWeightEstimator, timelockToSequence, sequenceToTimelock, ArkError, maybeArkError, Batch, validateVtxoTxGraph, validateConnectorsTxGraph, buildForfeitTx, isRecoverable, isSpendable, isSubdust, isExpired, getSequence, ContractManager, ContractWatcher, contractHandlers, DefaultContractHandler, DelegateContractHandler, VHTLCContractHandler, encodeArkContract, decodeArkContract, contractFromArkContract, contractFromArkContractWithAddress, isArkContract, };
|
|
59
|
+
export type { Identity, ReadonlyIdentity, BatchSignableIdentity, SignRequest, IWallet, IReadonlyWallet, BaseWalletConfig, WalletConfig, ReadonlyWalletConfig, ProviderClass, ArkTransaction, Coin, ExtendedCoin, ExtendedVirtualCoin, WalletBalance, SendBitcoinParams, SettleParams, Status, VirtualStatus, Outpoint, VirtualCoin, TxKey, TapscriptType, ArkTxInput, OffchainTx, TapLeaves, IncomingFunds, SeedIdentityOptions, MnemonicOptions, NetworkOptions, DescriptorOptions, IndexerProvider, PageResponse, BatchInfo, ChainTx, CommitmentTx, TxHistoryRecord, Vtxo, VtxoChain, Tx, OnchainProvider, ArkProvider, SettlementEvent, FeeInfo, ArkInfo, SignedIntent, Output, TxNotification, ExplorerTransaction, ElectrumTransactionHistory, ElectrumBlockHeader, ElectrumUnspent, BatchFinalizationEvent, BatchFinalizedEvent, BatchFailedEvent, TreeSigningStartedEvent, TreeNoncesEvent, BatchStartedEvent, TreeTxEvent, TreeSignatureEvent, ScheduledSession, PaginationOptions, SubscriptionResponse, SubscriptionHeartbeat, SubscriptionEvent, Network, NetworkName, ArkTapscript, RelativeTimelock, EncodedVtxoScript, TapLeafScript, SignerSession, TreeNonces, TreePartialSigs, GetVtxosFilter, SettlementConfig, IVtxoManager, Asset, Recipient, IssuanceParams, IssuanceResult, ReissuanceParams, BurnParams, AssetDetails, AssetMetadata, KnownMetadata, Nonces, PartialSig, ArkPsbtFieldCoder, TxTreeNode, AnchorBumper, VSize, StorageConfig, Contract, ContractVtxo, ContractState, ContractEvent, ContractEventCallback, ContractBalance, ContractWithVtxos, ContractHandler, IContractManager, PathSelection, PathContext, ContractManagerConfig, CreateContractParams, ContractWatcherConfig, ParsedArkContract, DefaultContractParams, DelegateContractParams, VHTLCContractParams, MessageHandler, RequestEnvelope, ResponseEnvelope, MessageTimeouts, IDelegatorManager, DelegatorProvider, DelegateInfo, DelegateOptions, WalletRepository, ContractRepository, MigrationStatus, };
|
|
@@ -1,7 +1,39 @@
|
|
|
1
1
|
import type { ElectrumWS } from "ws-electrumx-client";
|
|
2
|
-
import type { Network } from "../networks";
|
|
2
|
+
import type { Network, NetworkName } from "../networks";
|
|
3
3
|
import type { Coin } from "../wallet";
|
|
4
4
|
import type { ExplorerTransaction, OnchainProvider } from "./onchain";
|
|
5
|
+
/**
|
|
6
|
+
* Default WebSocket Electrum endpoints. Mainnet, mutinynet, and signet
|
|
7
|
+
* point at Ark Labs–operated Fulcrum 2.1 deployments (which support
|
|
8
|
+
* `blockchain.transaction.broadcast_package` for atomic 1P1C TRUC
|
|
9
|
+
* relay; see `ElectrumOnchainProvider.broadcastTransaction`). Testnet
|
|
10
|
+
* defaults to Blockstream's public Fulcrum because Ark doesn't host
|
|
11
|
+
* it. Regtest assumes the `electrum-ws` websocat bridge from
|
|
12
|
+
* `vulpemventures/nigiri`.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* import { ElectrumWS } from "ws-electrumx-client";
|
|
17
|
+
* import { ELECTRUM_WS_URL, ElectrumOnchainProvider, networks } from "@arkade-os/sdk";
|
|
18
|
+
*
|
|
19
|
+
* const ws = new ElectrumWS(ELECTRUM_WS_URL.bitcoin);
|
|
20
|
+
* const provider = new ElectrumOnchainProvider(ws, networks.bitcoin);
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export declare const ELECTRUM_WS_URL: Record<NetworkName, string>;
|
|
24
|
+
/**
|
|
25
|
+
* Hostnames for Electrum endpoints reachable over raw TCP. Provided as
|
|
26
|
+
* a reference for Node-side consumers — the SDK's
|
|
27
|
+
* {@link ElectrumOnchainProvider} only speaks WebSocket because it has
|
|
28
|
+
* to run in browsers, so this map is informational only and not
|
|
29
|
+
* consumed by any built-in provider.
|
|
30
|
+
*
|
|
31
|
+
* Public Ark Labs Fulcrum instances expose:
|
|
32
|
+
* - port 50001 — plain TCP (Electrum protocol)
|
|
33
|
+
* - port 50002 — TCP + TLS (Electrum protocol)
|
|
34
|
+
* - port 50003 — WebSocket (Electrum-over-WS, see {@link ELECTRUM_WS_URL})
|
|
35
|
+
*/
|
|
36
|
+
export declare const ELECTRUM_TCP_HOST: Record<NetworkName, string | null>;
|
|
5
37
|
export type TransactionHistory = {
|
|
6
38
|
tx_hash: string;
|
|
7
39
|
height: number;
|
|
@@ -70,12 +102,46 @@ export declare class WsElectrumChainSource {
|
|
|
70
102
|
private cachedTip;
|
|
71
103
|
private headersSubscribePromise;
|
|
72
104
|
constructor(ws: ElectrumWS, network: Network);
|
|
105
|
+
/**
|
|
106
|
+
* Send N requests in parallel and aggregate the results, replacement
|
|
107
|
+
* for `ws.batchRequest`. The library's batchRequest is implemented as
|
|
108
|
+
* `Promise.all` over individual request promises — when one element
|
|
109
|
+
* rejects, the others remain pending. When their (often error)
|
|
110
|
+
* responses arrive later, the library rejects them too, and nobody is
|
|
111
|
+
* awaiting them: the rejections become unhandled and crash the test
|
|
112
|
+
* runner / pollute production logs.
|
|
113
|
+
*
|
|
114
|
+
* `safeBatchRequest` issues each request through `ws.request` (so each
|
|
115
|
+
* has its own request-promise lifecycle), waits for all of them via
|
|
116
|
+
* `Promise.allSettled` (every promise gets an explicit handler), and
|
|
117
|
+
* then surfaces the first error if any failed. Same wall-clock cost
|
|
118
|
+
* as the library's batch (parallel send), no orphan rejections.
|
|
119
|
+
*
|
|
120
|
+
* Use this in place of `ws.batchRequest` for any call where one or
|
|
121
|
+
* more elements may legitimately error (e.g. electrs index lag
|
|
122
|
+
* surfacing as `missingheight` for a subset of heights/txids).
|
|
123
|
+
*/
|
|
124
|
+
safeBatchRequest<T>(requests: {
|
|
125
|
+
method: string;
|
|
126
|
+
params: unknown[];
|
|
127
|
+
}[]): Promise<T[]>;
|
|
73
128
|
fetchTransactions(txids: string[]): Promise<{
|
|
74
129
|
txID: string;
|
|
75
130
|
hex: string;
|
|
76
131
|
}[]>;
|
|
77
132
|
fetchVerboseTransaction(txid: string): Promise<VerboseTransaction>;
|
|
78
133
|
fetchVerboseTransactions(txids: string[]): Promise<VerboseTransaction[]>;
|
|
134
|
+
/**
|
|
135
|
+
* Look up the block height of a confirmed transaction without relying
|
|
136
|
+
* on the verbose-tx endpoint. `blockchain.transaction.get_merkle` is
|
|
137
|
+
* part of the standard SPV protocol and is supported by both Fulcrum
|
|
138
|
+
* and electrs (whereas `blockchain.transaction.get` with verbose=true
|
|
139
|
+
* is Fulcrum-only). Returns `null` when the tx is in the mempool —
|
|
140
|
+
* electrs in that case rejects with a "not yet in a block" error.
|
|
141
|
+
*/
|
|
142
|
+
fetchTxMerkle(txid: string): Promise<{
|
|
143
|
+
blockHeight: number;
|
|
144
|
+
} | null>;
|
|
79
145
|
unsubscribeScriptStatus(script: Uint8Array): Promise<void>;
|
|
80
146
|
subscribeScriptStatus(script: Uint8Array, callback: (scripthash: string, status: string | null) => void): Promise<void>;
|
|
81
147
|
fetchHistories(scripts: Uint8Array[]): Promise<TransactionHistory[][]>;
|
|
@@ -130,19 +196,45 @@ export declare class WsElectrumChainSource {
|
|
|
130
196
|
addressForScript(scriptHex: string): string | undefined;
|
|
131
197
|
}
|
|
132
198
|
/**
|
|
133
|
-
* Electrum-based implementation of the OnchainProvider interface.
|
|
134
|
-
* Replaces esplora polling with electrum subscriptions where possible.
|
|
199
|
+
* Electrum-based implementation of the {@link OnchainProvider} interface.
|
|
135
200
|
*
|
|
136
|
-
*
|
|
201
|
+
* Built around the subset of the Electrum protocol that both **Fulcrum**
|
|
202
|
+
* and **electrs** support — listunspent, get_history, transaction.get
|
|
203
|
+
* (non-verbose), transaction.get_merkle, block.header,
|
|
204
|
+
* headers.subscribe, scripthash.subscribe, estimatefee, relayfee, and
|
|
205
|
+
* broadcast. The verbose form of `transaction.get` is **not** used (it's
|
|
206
|
+
* Fulcrum-only and rejected by electrs); confirmation status is derived
|
|
207
|
+
* from `transaction.get_merkle` plus parsed block headers.
|
|
208
|
+
*
|
|
209
|
+
* Output amounts are derived from parsed raw transaction bytes (exact
|
|
210
|
+
* bigints), never the floating-point `value` fields some servers return.
|
|
211
|
+
*
|
|
212
|
+
* Atomic 1P1C package broadcast (TRUC / BIP 431) is supported via
|
|
213
|
+
* Fulcrum's `blockchain.transaction.broadcast_package`. There is **no
|
|
214
|
+
* fallback** to sequential parent-then-child broadcasts — TRUC packages
|
|
215
|
+
* with a zero-fee parent would silently fail, so the call surfaces an
|
|
216
|
+
* error against servers that don't support the method.
|
|
217
|
+
*
|
|
218
|
+
* @example Default URL via {@link ELECTRUM_WS_URL}
|
|
137
219
|
* ```typescript
|
|
138
220
|
* import { ElectrumWS } from "ws-electrumx-client";
|
|
139
|
-
* import {
|
|
140
|
-
*
|
|
221
|
+
* import {
|
|
222
|
+
* ElectrumOnchainProvider,
|
|
223
|
+
* ELECTRUM_WS_URL,
|
|
224
|
+
* networks,
|
|
225
|
+
* } from "@arkade-os/sdk";
|
|
141
226
|
*
|
|
142
|
-
* const ws = new ElectrumWS(
|
|
227
|
+
* const ws = new ElectrumWS(ELECTRUM_WS_URL.bitcoin);
|
|
143
228
|
* const provider = new ElectrumOnchainProvider(ws, networks.bitcoin);
|
|
144
229
|
*
|
|
145
230
|
* const coins = await provider.getCoins("bc1q...");
|
|
231
|
+
* await provider.close();
|
|
232
|
+
* ```
|
|
233
|
+
*
|
|
234
|
+
* @example Custom server
|
|
235
|
+
* ```typescript
|
|
236
|
+
* const ws = new ElectrumWS("wss://my-fulcrum.example:50004");
|
|
237
|
+
* const provider = new ElectrumOnchainProvider(ws, networks.bitcoin);
|
|
146
238
|
* ```
|
|
147
239
|
*/
|
|
148
240
|
export declare class ElectrumOnchainProvider implements OnchainProvider {
|
|
@@ -178,15 +270,23 @@ export declare class ElectrumOnchainProvider implements OnchainProvider {
|
|
|
178
270
|
}[]>;
|
|
179
271
|
getTransactions(address: string): Promise<ExplorerTransaction[]>;
|
|
180
272
|
/**
|
|
181
|
-
*
|
|
182
|
-
*
|
|
183
|
-
*
|
|
184
|
-
*
|
|
185
|
-
*
|
|
186
|
-
*
|
|
187
|
-
*
|
|
273
|
+
* Resolve a list of `{tx_hash, height}` entries (as returned by the
|
|
274
|
+
* scripthash history endpoint) into ExplorerTransaction shape **without
|
|
275
|
+
* using the verbose-tx endpoint**, which only Fulcrum implements. We
|
|
276
|
+
* reconstruct everything the verbose response would have given us:
|
|
277
|
+
* - vouts ← parse the raw tx (exact sat amounts, no float precision risk)
|
|
278
|
+
* - block_time ← batch-fetch the block headers for the heights present
|
|
279
|
+
* - addresses ← decode each output's scriptPubKey via @scure/btc-signer
|
|
280
|
+
*/
|
|
281
|
+
private historyToExplorerTxs;
|
|
282
|
+
/**
|
|
283
|
+
* Build an ExplorerTransaction from a history entry plus the raw tx hex
|
|
284
|
+
* (when known) and a height→block_time map. Parse errors propagate —
|
|
285
|
+
* silently returning an empty vout would hide real outputs (e.g. a
|
|
286
|
+
* deposit) and is far worse for protocol-level money handling than
|
|
287
|
+
* failing the whole batch.
|
|
188
288
|
*/
|
|
189
|
-
private
|
|
289
|
+
private buildExplorerTx;
|
|
190
290
|
/**
|
|
191
291
|
* Decode `address` into its scriptPubKey, throwing a clear error if the
|
|
192
292
|
* input is malformed. @scure/btc-signer raises a generic decode error
|
|
@@ -2,6 +2,12 @@ import type { NetworkName } from "../networks";
|
|
|
2
2
|
import { Coin } from "../wallet";
|
|
3
3
|
/**
|
|
4
4
|
* The default base URLs for esplora API providers.
|
|
5
|
+
*
|
|
6
|
+
* Mainnet, mutinynet, and signet point at Ark Labs–operated
|
|
7
|
+
* mempool deployments (mempool.space-compatible esplora API).
|
|
8
|
+
* Testnet falls back to the public mempool.space deployment
|
|
9
|
+
* because Ark doesn't host it. Regtest assumes a local nigiri
|
|
10
|
+
* stack on the standard port.
|
|
5
11
|
*/
|
|
6
12
|
export declare const ESPLORA_URL: Record<NetworkName, string>;
|
|
7
13
|
export type ExplorerTransaction = {
|