@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.
Files changed (74) hide show
  1. package/README.md +95 -12
  2. package/dist/cjs/contracts/arkcontract.js +2 -1
  3. package/dist/cjs/identity/descriptor.js +75 -4
  4. package/dist/cjs/identity/hdCapableIdentity.js +2 -0
  5. package/dist/cjs/identity/seedIdentity.js +225 -103
  6. package/dist/cjs/identity/serialize.js +5 -0
  7. package/dist/cjs/identity/staticDescriptorProvider.js +1 -1
  8. package/dist/cjs/index.js +12 -3
  9. package/dist/cjs/providers/electrum.js +285 -79
  10. package/dist/cjs/providers/expoIndexer.js +1 -1
  11. package/dist/cjs/providers/indexer.js +2 -2
  12. package/dist/cjs/providers/onchain.js +9 -3
  13. package/dist/cjs/repositories/migrations/walletRepositoryImpl.js +6 -2
  14. package/dist/cjs/repositories/realm/walletRepository.js +2 -2
  15. package/dist/cjs/repositories/serialization.js +34 -1
  16. package/dist/cjs/repositories/sqlite/walletRepository.js +4 -2
  17. package/dist/cjs/script/address.js +2 -1
  18. package/dist/cjs/utils/transactionHistory.js +4 -4
  19. package/dist/cjs/wallet/asset-manager.js +18 -18
  20. package/dist/cjs/wallet/asset.js +10 -8
  21. package/dist/cjs/wallet/delegator.js +2 -2
  22. package/dist/cjs/wallet/hdDescriptorProvider.js +159 -0
  23. package/dist/cjs/wallet/index.js +5 -1
  24. package/dist/cjs/wallet/onchain.js +2 -1
  25. package/dist/cjs/wallet/serviceWorker/wallet-message-handler.js +1 -1
  26. package/dist/cjs/wallet/serviceWorker/wallet.js +5 -4
  27. package/dist/cjs/wallet/validation.js +2 -3
  28. package/dist/cjs/wallet/wallet.js +13 -14
  29. package/dist/esm/contracts/arkcontract.js +2 -1
  30. package/dist/esm/identity/descriptor.js +74 -5
  31. package/dist/esm/identity/hdCapableIdentity.js +1 -0
  32. package/dist/esm/identity/seedIdentity.js +225 -103
  33. package/dist/esm/identity/serialize.js +5 -0
  34. package/dist/esm/identity/staticDescriptorProvider.js +1 -1
  35. package/dist/esm/index.js +7 -4
  36. package/dist/esm/providers/electrum.js +284 -78
  37. package/dist/esm/providers/expoIndexer.js +1 -1
  38. package/dist/esm/providers/indexer.js +2 -2
  39. package/dist/esm/providers/onchain.js +9 -3
  40. package/dist/esm/repositories/migrations/walletRepositoryImpl.js +6 -2
  41. package/dist/esm/repositories/realm/walletRepository.js +3 -3
  42. package/dist/esm/repositories/serialization.js +27 -0
  43. package/dist/esm/repositories/sqlite/walletRepository.js +5 -3
  44. package/dist/esm/script/address.js +2 -1
  45. package/dist/esm/utils/transactionHistory.js +4 -4
  46. package/dist/esm/wallet/asset-manager.js +18 -18
  47. package/dist/esm/wallet/asset.js +10 -8
  48. package/dist/esm/wallet/delegator.js +2 -2
  49. package/dist/esm/wallet/hdDescriptorProvider.js +155 -0
  50. package/dist/esm/wallet/index.js +4 -0
  51. package/dist/esm/wallet/onchain.js +2 -1
  52. package/dist/esm/wallet/serviceWorker/wallet-message-handler.js +1 -1
  53. package/dist/esm/wallet/serviceWorker/wallet.js +5 -4
  54. package/dist/esm/wallet/validation.js +2 -3
  55. package/dist/esm/wallet/wallet.js +12 -14
  56. package/dist/types/contracts/arkcontract.d.ts +1 -1
  57. package/dist/types/identity/descriptor.d.ts +26 -0
  58. package/dist/types/identity/descriptorProvider.d.ts +11 -4
  59. package/dist/types/identity/hdCapableIdentity.d.ts +44 -0
  60. package/dist/types/identity/index.d.ts +1 -0
  61. package/dist/types/identity/seedIdentity.d.ts +113 -29
  62. package/dist/types/identity/serialize.d.ts +12 -0
  63. package/dist/types/identity/staticDescriptorProvider.d.ts +1 -1
  64. package/dist/types/index.d.ts +6 -3
  65. package/dist/types/providers/electrum.d.ts +115 -15
  66. package/dist/types/providers/onchain.d.ts +6 -0
  67. package/dist/types/repositories/serialization.d.ts +26 -2
  68. package/dist/types/script/address.d.ts +1 -1
  69. package/dist/types/wallet/hdDescriptorProvider.d.ts +93 -0
  70. package/dist/types/wallet/index.d.ts +19 -10
  71. package/dist/types/wallet/onchain.d.ts +1 -1
  72. package/dist/types/wallet/serviceWorker/wallet.d.ts +1 -1
  73. package/dist/types/wallet/wallet.d.ts +4 -1
  74. package/package.json +1 -1
@@ -1,17 +1,33 @@
1
1
  import { TapLeafScript } from "../script/base";
2
- import { ExtendedCoin, ExtendedVirtualCoin } from "../wallet";
2
+ import { ArkTransaction, Asset, ExtendedCoin, ExtendedVirtualCoin } from "../wallet";
3
3
  export type SerializedTapLeaf = {
4
4
  cb: string;
5
5
  s: string;
6
6
  };
7
7
  export type SerializedVtxo = ReturnType<typeof serializeVtxo>;
8
8
  export type SerializedUtxo = ReturnType<typeof serializeUtxo>;
9
+ export type SerializedTransaction = ReturnType<typeof serializeTransaction>;
10
+ export type SerializedAsset = {
11
+ assetId: string;
12
+ amount: string;
13
+ };
9
14
  export declare const serializeTapLeaf: ([cb, s,]: TapLeafScript) => SerializedTapLeaf;
15
+ export declare const serializeAsset: (a: Asset) => SerializedAsset;
16
+ export declare const deserializeAsset: (a: {
17
+ assetId: string;
18
+ amount: string | number | bigint;
19
+ }) => Asset;
20
+ export declare const serializeAssets: (assets: Asset[] | undefined) => SerializedAsset[] | undefined;
21
+ export declare const deserializeAssets: (assets: Array<{
22
+ assetId: string;
23
+ amount: string | number | bigint;
24
+ }> | undefined) => Asset[] | undefined;
10
25
  export declare const serializeVtxo: (v: ExtendedVirtualCoin) => {
11
26
  tapTree: string;
12
27
  forfeitTapLeafScript: SerializedTapLeaf;
13
28
  intentTapLeafScript: SerializedTapLeaf;
14
29
  extraWitness: string[] | undefined;
30
+ assets: SerializedAsset[] | undefined;
15
31
  virtualStatus: import("../wallet").VirtualStatus;
16
32
  spentBy?: string;
17
33
  settledBy?: string;
@@ -19,7 +35,6 @@ export declare const serializeVtxo: (v: ExtendedVirtualCoin) => {
19
35
  createdAt: Date;
20
36
  isUnrolled: boolean;
21
37
  isSpent?: boolean;
22
- assets?: import("../wallet").Asset[];
23
38
  script: string;
24
39
  value: number;
25
40
  status: import("../wallet").Status;
@@ -36,6 +51,15 @@ export declare const serializeUtxo: (u: ExtendedCoin) => {
36
51
  txid: string;
37
52
  vout: number;
38
53
  };
54
+ export declare const serializeTransaction: (t: ArkTransaction) => {
55
+ assets: SerializedAsset[] | undefined;
56
+ key: import("../wallet").TxKey;
57
+ type: import("../wallet").TxType;
58
+ amount: number;
59
+ settled: boolean;
60
+ createdAt: number;
61
+ };
39
62
  export declare const deserializeTapLeaf: (t: SerializedTapLeaf) => TapLeafScript;
40
63
  export declare const deserializeVtxo: (o: SerializedVtxo) => ExtendedVirtualCoin;
41
64
  export declare const deserializeUtxo: (o: SerializedUtxo) => ExtendedCoin;
65
+ export declare const deserializeTransaction: (o: SerializedTransaction) => ArkTransaction;
@@ -43,7 +43,7 @@ export declare class ArkAddress {
43
43
  * @defaultValue `version = 0`
44
44
  * @throws Error if either public key is not 32 bytes long
45
45
  */
46
- constructor(serverPubKey: Bytes, vtxoTaprootKey: Bytes, hrp: string, version?: number);
46
+ constructor(serverPubKey: Bytes, vtxoTaprootKey: Bytes, hrp?: string, version?: number);
47
47
  /**
48
48
  * Decode an Arkade address from its bech32m string form.
49
49
  *
@@ -0,0 +1,93 @@
1
+ import { DescriptorProvider, DescriptorSigningRequest } from "../identity/descriptorProvider";
2
+ import { HDCapableIdentity } from "../identity/hdCapableIdentity";
3
+ import { WalletRepository } from "../repositories/walletRepository";
4
+ import { Transaction } from "../utils/transaction";
5
+ /**
6
+ * HD-wallet {@link DescriptorProvider} that allocates a fresh signing
7
+ * descriptor on every call. The provider holds no notion of "current" — it
8
+ * is a pure rotating allocator. The question of "which descriptor is the
9
+ * wallet currently bound to?" is answered by querying the contract
10
+ * repository for active contracts, not by asking this provider.
11
+ *
12
+ * State is persisted under `WalletRepository.getWalletState().settings.hd` so
13
+ * that no storage-schema migration is required when switching a wallet from
14
+ * single-key to HD. The provider is backed by an {@link HDCapableIdentity},
15
+ * which carries the wildcard account descriptor template (for derivation)
16
+ * and the signing primitives.
17
+ *
18
+ * The read-modify-write of the persisted index runs inside the shared per-
19
+ * repo `updateWalletState` mutex, so two `getNextSigningDescriptor` callers
20
+ * — including those driving separate `HDDescriptorProvider` instances on
21
+ * the same repo — can never observe the same index.
22
+ *
23
+ * @example
24
+ * ```ts
25
+ * const provider = await HDDescriptorProvider.create(identity, walletRepo);
26
+ * const descriptor = await provider.getNextSigningDescriptor();
27
+ * // descriptor: tr([fp/86'/0'/0']xpub/0/0)
28
+ * const next = await provider.getNextSigningDescriptor();
29
+ * // next: tr([fp/86'/0'/0']xpub/0/1)
30
+ * ```
31
+ */
32
+ export declare class HDDescriptorProvider implements DescriptorProvider {
33
+ private readonly identity;
34
+ private readonly walletRepository;
35
+ private constructor();
36
+ /**
37
+ * Construct an HDDescriptorProvider. No I/O is performed here;
38
+ * persisted state is read lazily on the first call to
39
+ * `getNextSigningDescriptor`. A descriptor-mismatch error surfaces on
40
+ * first use rather than at boot.
41
+ */
42
+ static create(identity: HDCapableIdentity, walletRepository: WalletRepository): Promise<HDDescriptorProvider>;
43
+ /**
44
+ * Allocate the next descriptor and return it. The first call on a fresh
45
+ * wallet returns descriptor at index 0; subsequent calls return 1, 2, 3,
46
+ * ... in order. Each call is atomic with respect to other rotations on
47
+ * the same repo: two concurrent callers can never observe the same
48
+ * index.
49
+ */
50
+ getNextSigningDescriptor(): Promise<string>;
51
+ /**
52
+ * Returns true when the given descriptor is derivable from this wallet's
53
+ * seed. Delegates to the underlying identity, which handles both HD and
54
+ * simple `tr(pubkey)` descriptors.
55
+ */
56
+ isOurs(descriptor: string): boolean;
57
+ /**
58
+ * Signs each request with the key derived from its descriptor. Delegates
59
+ * to the identity's signing primitives — the identity, not the provider,
60
+ * holds the seed.
61
+ */
62
+ signWithDescriptor(requests: DescriptorSigningRequest[]): Promise<Transaction[]>;
63
+ /** Signs a message using the key derived from `descriptor`. */
64
+ signMessageWithDescriptor(descriptor: string, message: Uint8Array, signatureType?: "schnorr" | "ecdsa"): Promise<Uint8Array>;
65
+ /**
66
+ * Substitute the wildcard in the identity's account-descriptor template
67
+ * with a concrete index, going through the descriptors-scure parser
68
+ * rather than ad-hoc string substitution. The parser's `expand({ index })`
69
+ * call validates that the input is a ranged template AND produces a
70
+ * canonical materialized key expression at the given index.
71
+ */
72
+ private materializeAt;
73
+ /**
74
+ * Run the read-modify-write of HD settings inside the shared per-repo
75
+ * wallet-state mutex. The closure receives a freshly-validated settings
76
+ * snapshot, mutates it, and returns whatever value the caller wants to
77
+ * surface; the mutated settings are then persisted as part of the same
78
+ * atomic update.
79
+ *
80
+ * Doing the read inside the lock is what prevents two providers (or two
81
+ * concurrent callers on the same provider) from racing on a stale index.
82
+ */
83
+ private mutate;
84
+ /**
85
+ * Validate the persisted HD settings (or initialize a fresh record when
86
+ * absent) and return a clone safe for the caller to mutate.
87
+ *
88
+ * The cast to `HDWalletSettings` trusts storage; a corrupted or
89
+ * partially-migrated repo could otherwise produce `NaN` descriptors.
90
+ * Fail loud rather than silently derive garbage.
91
+ */
92
+ private parseSettings;
93
+ }
@@ -11,6 +11,10 @@ import { ContractRepository, WalletRepository } from "../repositories";
11
11
  import { IContractManager } from "../contracts/contractManager";
12
12
  import { IDelegatorManager } from "./delegator";
13
13
  import { DelegatorProvider } from "../providers/delegator";
14
+ /** Defaults */
15
+ export declare const DEFAULT_ARKADE_SERVER_URL: "https://arkade.computer";
16
+ export declare const DEFAULT_ARKADE_HRP = "ark";
17
+ export declare const DEFAULT_NETWORK_NAME = "bitcoin";
14
18
  /**
15
19
  * Base configuration options shared by all wallet types.
16
20
  *
@@ -22,9 +26,6 @@ import { DelegatorProvider } from "../providers/delegator";
22
26
  * Provider-based configuration supplies concrete provider instances directly,
23
27
  * including the ArkProvider, IndexerProvider, OnchainProvider, and DelegatorProvider.
24
28
  *
25
- * At least one of the following must be provided:
26
- * - arkServerUrl OR arkProvider
27
- *
28
29
  * The wallet will use provided URLs to create default providers if custom provider
29
30
  * instances are not supplied. If optional parameters are not provided, the wallet
30
31
  * will fetch configuration from the Arkade server.
@@ -255,8 +256,12 @@ export interface SendBitcoinParams {
255
256
  export interface Asset {
256
257
  /** Asset identifier. */
257
258
  assetId: string;
258
- /** Asset amount in base units. */
259
- amount: number;
259
+ /**
260
+ * Asset amount in base units. Typed as `bigint` because asset
261
+ * supplies routinely exceed `Number.MAX_SAFE_INTEGER` (2^53 - 1)
262
+ * and silently truncating in arithmetic would corrupt balances.
263
+ */
264
+ amount: bigint;
260
265
  }
261
266
  /**
262
267
  * Recipient accepted by `IWallet.send`.
@@ -310,8 +315,12 @@ export type AssetMetadata = KnownMetadata & Record<string, unknown>;
310
315
  export type AssetDetails = {
311
316
  /** Asset identifier. */
312
317
  assetId: string;
313
- /** Total issued supply in base units. */
314
- supply: number;
318
+ /**
319
+ * Total issued supply in base units. Typed as `bigint` for the
320
+ * same reason as {@link Asset.amount} — supplies often exceed
321
+ * `Number.MAX_SAFE_INTEGER`.
322
+ */
323
+ supply: bigint;
315
324
  /** Optional immutable metadata associated with the asset. */
316
325
  metadata?: AssetMetadata;
317
326
  /** Optional control asset id required for future reissuance. */
@@ -325,7 +334,7 @@ export type AssetDetails = {
325
334
  */
326
335
  export interface IssuanceParams {
327
336
  /** Initial amount of asset to issue */
328
- amount: number;
337
+ amount: bigint;
329
338
  /** Optional control asset ID that can be used for future reissuance */
330
339
  controlAssetId?: string;
331
340
  /** Immutable asset metadata including `ticker`, `decimals`, `icon` */
@@ -352,7 +361,7 @@ export interface ReissuanceParams {
352
361
  /** Existing asset ID, made up of genesis (Arkade) transaction ID and zero-based asset group index */
353
362
  assetId: string;
354
363
  /** Amount of asset to issue */
355
- amount: number;
364
+ amount: bigint;
356
365
  }
357
366
  /**
358
367
  * Parameters accepted by `IAssetManager.burn`.
@@ -363,7 +372,7 @@ export interface BurnParams {
363
372
  /** Existing asset ID, made up of genesis (Arkade) transaction ID and zero-based asset group index */
364
373
  assetId: string;
365
374
  /** Amount of asset to burn */
366
- amount: number;
375
+ amount: bigint;
367
376
  }
368
377
  /**
369
378
  * Explicit inputs and outputs accepted by `IWallet.settle`.
@@ -39,7 +39,7 @@ export declare class OnchainWallet implements AnchorBumper {
39
39
  * @defaultValue `provider = new EsploraProvider('https://mempool.space/api')`
40
40
  * @throws Error if the configured identity cannot produce a valid x-only public key
41
41
  */
42
- static create(identity: Identity, networkName: NetworkName, provider?: OnchainProvider): Promise<OnchainWallet>;
42
+ static create(identity: Identity, networkName?: NetworkName, provider?: OnchainProvider): Promise<OnchainWallet>;
43
43
  get address(): string;
44
44
  /**
45
45
  * Fetch spendable onchain outputs for the wallet address.
@@ -45,7 +45,7 @@ interface ServiceWorkerWalletOptions {
45
45
  /** Optional Arkade server public key used to construct and validate Arkade addresses. */
46
46
  arkServerPublicKey?: string;
47
47
  /** Base URL of the Arkade server. */
48
- arkServerUrl: string;
48
+ arkServerUrl?: string;
49
49
  /** Optional override for the indexer URL. */
50
50
  indexerUrl?: string;
51
51
  /** Optional override for the Esplora API URL. */
@@ -19,6 +19,9 @@ import { DelegatorProvider } from "../providers/delegator";
19
19
  import { DelegateVtxo } from "../script/delegate";
20
20
  import { IDelegatorManager } from "./delegator";
21
21
  import { ContractManager } from "../contracts/contractManager";
22
+ export declare const getArkadeServerUrl: ({ arkServerUrl, }: {
23
+ arkServerUrl?: string;
24
+ }) => string;
22
25
  export type IncomingFunds = {
23
26
  type: "utxo";
24
27
  coins: Coin[];
@@ -321,7 +324,7 @@ export declare class Wallet extends ReadonlyWallet implements IWallet {
321
324
  * const txid = await wallet.send({
322
325
  * address: 'ark1q...',
323
326
  * amount: 1000, // (optional, default to dust) btc amount to send to the output
324
- * assets: [{ assetId: 'abc123...', amount: 50 }] // (optional) list of assets to send
327
+ * assets: [{ assetId: 'abc123...', amount: 50n }] // (optional) list of assets to send
325
328
  * });
326
329
  * ```
327
330
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arkade-os/sdk",
3
- "version": "0.4.22",
3
+ "version": "0.4.23",
4
4
  "description": "TypeScript SDK for building Bitcoin wallets using the Arkade protocol",
5
5
  "type": "module",
6
6
  "main": "./dist/cjs/index.js",