@arkade-os/sdk 0.4.15 → 0.4.16

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 (197) hide show
  1. package/README.md +102 -96
  2. package/dist/cjs/arkfee/estimator.js +1 -1
  3. package/dist/cjs/arkfee/types.js +2 -1
  4. package/dist/cjs/arknote/index.js +43 -4
  5. package/dist/cjs/bip322/index.js +1 -1
  6. package/dist/cjs/contracts/arkcontract.js +1 -1
  7. package/dist/cjs/contracts/contractManager.js +40 -24
  8. package/dist/cjs/contracts/contractWatcher.js +29 -22
  9. package/dist/cjs/contracts/handlers/default.js +1 -1
  10. package/dist/cjs/contracts/handlers/delegate.js +1 -1
  11. package/dist/cjs/contracts/handlers/helpers.js +1 -1
  12. package/dist/cjs/extension/asset/assetGroup.js +92 -5
  13. package/dist/cjs/extension/asset/assetId.js +67 -3
  14. package/dist/cjs/extension/asset/assetInput.js +18 -0
  15. package/dist/cjs/extension/asset/assetOutput.js +15 -0
  16. package/dist/cjs/extension/asset/assetRef.js +66 -0
  17. package/dist/cjs/extension/asset/metadata.js +15 -0
  18. package/dist/cjs/extension/asset/packet.js +4 -1
  19. package/dist/cjs/extension/index.js +1 -1
  20. package/dist/cjs/forfeit.js +14 -0
  21. package/dist/cjs/identity/seedIdentity.js +2 -2
  22. package/dist/cjs/identity/singleKey.js +4 -0
  23. package/dist/cjs/intent/index.js +28 -12
  24. package/dist/cjs/providers/ark.js +3 -2
  25. package/dist/cjs/providers/delegator.js +20 -1
  26. package/dist/cjs/providers/expoArk.js +2 -2
  27. package/dist/cjs/providers/indexer.js +2 -2
  28. package/dist/cjs/providers/onchain.js +2 -1
  29. package/dist/cjs/repositories/realm/schemas.js +2 -2
  30. package/dist/cjs/repositories/realm/types.js +1 -1
  31. package/dist/cjs/script/address.js +37 -6
  32. package/dist/cjs/script/base.js +70 -1
  33. package/dist/cjs/script/default.js +3 -0
  34. package/dist/cjs/script/delegate.js +4 -0
  35. package/dist/cjs/script/tapscript.js +17 -2
  36. package/dist/cjs/script/vhtlc.js +35 -27
  37. package/dist/cjs/storage/fileSystem.js +1 -1
  38. package/dist/cjs/storage/inMemory.js +1 -1
  39. package/dist/cjs/storage/indexedDB.js +1 -1
  40. package/dist/cjs/storage/localStorage.js +1 -1
  41. package/dist/cjs/tree/validation.js +1 -1
  42. package/dist/cjs/utils/arkTransaction.js +5 -5
  43. package/dist/cjs/utils/bip21.js +16 -3
  44. package/dist/cjs/utils/syncCursors.js +4 -4
  45. package/dist/cjs/utils/transaction.js +1 -1
  46. package/dist/cjs/utils/transactionHistory.js +11 -11
  47. package/dist/cjs/utils/unknownFields.js +3 -3
  48. package/dist/cjs/wallet/asset-manager.js +4 -4
  49. package/dist/cjs/wallet/batch.js +5 -5
  50. package/dist/cjs/wallet/delegator.js +9 -8
  51. package/dist/cjs/wallet/expo/background.js +3 -3
  52. package/dist/cjs/wallet/expo/wallet.js +7 -7
  53. package/dist/cjs/wallet/index.js +43 -0
  54. package/dist/cjs/wallet/onchain.js +43 -5
  55. package/dist/cjs/wallet/ramps.js +44 -14
  56. package/dist/cjs/wallet/serviceWorker/wallet-message-handler.js +22 -22
  57. package/dist/cjs/wallet/serviceWorker/wallet.js +28 -24
  58. package/dist/cjs/wallet/unroll.js +12 -8
  59. package/dist/cjs/wallet/utils.js +1 -1
  60. package/dist/cjs/wallet/vtxo-manager.js +122 -82
  61. package/dist/cjs/wallet/wallet.js +125 -67
  62. package/dist/cjs/worker/expo/asyncStorageTaskQueue.js +1 -1
  63. package/dist/cjs/worker/expo/processors/contractPollProcessor.js +2 -2
  64. package/dist/cjs/worker/expo/taskRunner.js +3 -3
  65. package/dist/cjs/worker/messageBus.js +3 -0
  66. package/dist/esm/arkfee/estimator.js +1 -1
  67. package/dist/esm/arkfee/types.js +2 -1
  68. package/dist/esm/arknote/index.js +43 -4
  69. package/dist/esm/bip322/index.js +1 -1
  70. package/dist/esm/contracts/arkcontract.js +1 -1
  71. package/dist/esm/contracts/contractManager.js +40 -24
  72. package/dist/esm/contracts/contractWatcher.js +29 -22
  73. package/dist/esm/contracts/handlers/default.js +1 -1
  74. package/dist/esm/contracts/handlers/delegate.js +1 -1
  75. package/dist/esm/contracts/handlers/helpers.js +1 -1
  76. package/dist/esm/extension/asset/assetGroup.js +92 -5
  77. package/dist/esm/extension/asset/assetId.js +67 -3
  78. package/dist/esm/extension/asset/assetInput.js +18 -0
  79. package/dist/esm/extension/asset/assetOutput.js +15 -0
  80. package/dist/esm/extension/asset/assetRef.js +66 -0
  81. package/dist/esm/extension/asset/metadata.js +15 -0
  82. package/dist/esm/extension/asset/packet.js +4 -1
  83. package/dist/esm/extension/index.js +1 -1
  84. package/dist/esm/forfeit.js +14 -0
  85. package/dist/esm/identity/seedIdentity.js +2 -2
  86. package/dist/esm/identity/singleKey.js +4 -0
  87. package/dist/esm/index.js +1 -1
  88. package/dist/esm/intent/index.js +28 -12
  89. package/dist/esm/providers/ark.js +3 -2
  90. package/dist/esm/providers/delegator.js +20 -1
  91. package/dist/esm/providers/expoArk.js +2 -2
  92. package/dist/esm/providers/indexer.js +2 -2
  93. package/dist/esm/providers/onchain.js +2 -1
  94. package/dist/esm/repositories/realm/schemas.js +2 -2
  95. package/dist/esm/repositories/realm/types.js +1 -1
  96. package/dist/esm/script/address.js +37 -6
  97. package/dist/esm/script/base.js +70 -1
  98. package/dist/esm/script/default.js +3 -0
  99. package/dist/esm/script/delegate.js +4 -0
  100. package/dist/esm/script/tapscript.js +17 -2
  101. package/dist/esm/script/vhtlc.js +35 -27
  102. package/dist/esm/storage/fileSystem.js +1 -1
  103. package/dist/esm/storage/inMemory.js +1 -1
  104. package/dist/esm/storage/indexedDB.js +1 -1
  105. package/dist/esm/storage/localStorage.js +1 -1
  106. package/dist/esm/tree/validation.js +1 -1
  107. package/dist/esm/utils/arkTransaction.js +5 -5
  108. package/dist/esm/utils/bip21.js +16 -3
  109. package/dist/esm/utils/syncCursors.js +4 -4
  110. package/dist/esm/utils/transaction.js +1 -1
  111. package/dist/esm/utils/transactionHistory.js +11 -11
  112. package/dist/esm/utils/unknownFields.js +3 -3
  113. package/dist/esm/wallet/asset-manager.js +4 -4
  114. package/dist/esm/wallet/batch.js +5 -5
  115. package/dist/esm/wallet/delegator.js +9 -8
  116. package/dist/esm/wallet/expo/background.js +3 -3
  117. package/dist/esm/wallet/expo/wallet.js +7 -7
  118. package/dist/esm/wallet/index.js +43 -0
  119. package/dist/esm/wallet/onchain.js +43 -5
  120. package/dist/esm/wallet/ramps.js +44 -14
  121. package/dist/esm/wallet/serviceWorker/wallet-message-handler.js +22 -22
  122. package/dist/esm/wallet/serviceWorker/wallet.js +28 -24
  123. package/dist/esm/wallet/unroll.js +12 -8
  124. package/dist/esm/wallet/utils.js +1 -1
  125. package/dist/esm/wallet/vtxo-manager.js +121 -81
  126. package/dist/esm/wallet/wallet.js +125 -67
  127. package/dist/esm/worker/expo/asyncStorageTaskQueue.js +1 -1
  128. package/dist/esm/worker/expo/processors/contractPollProcessor.js +2 -2
  129. package/dist/esm/worker/expo/taskRunner.js +3 -3
  130. package/dist/esm/worker/messageBus.js +3 -0
  131. package/dist/types/arkfee/estimator.d.ts +1 -1
  132. package/dist/types/arkfee/types.d.ts +2 -1
  133. package/dist/types/arknote/index.d.ts +44 -4
  134. package/dist/types/bip322/index.d.ts +1 -1
  135. package/dist/types/contracts/arkcontract.d.ts +1 -1
  136. package/dist/types/contracts/contractManager.d.ts +40 -63
  137. package/dist/types/contracts/contractWatcher.d.ts +39 -18
  138. package/dist/types/contracts/handlers/default.d.ts +1 -1
  139. package/dist/types/contracts/handlers/delegate.d.ts +1 -1
  140. package/dist/types/contracts/handlers/helpers.d.ts +1 -1
  141. package/dist/types/contracts/types.d.ts +36 -26
  142. package/dist/types/extension/asset/assetGroup.d.ts +92 -1
  143. package/dist/types/extension/asset/assetId.d.ts +67 -3
  144. package/dist/types/extension/asset/assetInput.d.ts +18 -0
  145. package/dist/types/extension/asset/assetOutput.d.ts +15 -0
  146. package/dist/types/extension/asset/assetRef.d.ts +66 -0
  147. package/dist/types/extension/asset/metadata.d.ts +15 -0
  148. package/dist/types/extension/asset/packet.d.ts +4 -1
  149. package/dist/types/extension/index.d.ts +1 -1
  150. package/dist/types/forfeit.d.ts +14 -0
  151. package/dist/types/identity/index.d.ts +16 -0
  152. package/dist/types/identity/seedIdentity.d.ts +8 -6
  153. package/dist/types/identity/singleKey.d.ts +4 -0
  154. package/dist/types/intent/index.d.ts +19 -6
  155. package/dist/types/providers/ark.d.ts +40 -2
  156. package/dist/types/providers/delegator.d.ts +54 -1
  157. package/dist/types/providers/expoArk.d.ts +2 -2
  158. package/dist/types/providers/indexer.d.ts +105 -2
  159. package/dist/types/providers/onchain.d.ts +62 -1
  160. package/dist/types/repositories/realm/schemas.d.ts +2 -2
  161. package/dist/types/repositories/realm/types.d.ts +2 -2
  162. package/dist/types/repositories/walletRepository.d.ts +16 -0
  163. package/dist/types/script/address.d.ts +35 -2
  164. package/dist/types/script/base.d.ts +66 -1
  165. package/dist/types/script/default.d.ts +3 -0
  166. package/dist/types/script/delegate.d.ts +4 -0
  167. package/dist/types/script/tapscript.d.ts +17 -2
  168. package/dist/types/script/vhtlc.d.ts +35 -27
  169. package/dist/types/storage/fileSystem.d.ts +1 -1
  170. package/dist/types/storage/inMemory.d.ts +1 -1
  171. package/dist/types/storage/index.d.ts +1 -1
  172. package/dist/types/storage/indexedDB.d.ts +1 -1
  173. package/dist/types/storage/localStorage.d.ts +1 -1
  174. package/dist/types/utils/arkTransaction.d.ts +3 -3
  175. package/dist/types/utils/bip21.d.ts +17 -0
  176. package/dist/types/utils/syncCursors.d.ts +4 -4
  177. package/dist/types/utils/transaction.d.ts +1 -1
  178. package/dist/types/utils/transactionHistory.d.ts +3 -3
  179. package/dist/types/utils/unknownFields.d.ts +5 -5
  180. package/dist/types/wallet/asset-manager.d.ts +3 -3
  181. package/dist/types/wallet/batch.d.ts +27 -7
  182. package/dist/types/wallet/delegator.d.ts +10 -0
  183. package/dist/types/wallet/expo/background.d.ts +4 -4
  184. package/dist/types/wallet/expo/wallet.d.ts +10 -10
  185. package/dist/types/wallet/index.d.ts +457 -25
  186. package/dist/types/wallet/onchain.d.ts +42 -4
  187. package/dist/types/wallet/ramps.d.ts +40 -10
  188. package/dist/types/wallet/serviceWorker/wallet-message-handler.d.ts +4 -4
  189. package/dist/types/wallet/serviceWorker/wallet.d.ts +71 -33
  190. package/dist/types/wallet/unroll.d.ts +8 -6
  191. package/dist/types/wallet/vtxo-manager.d.ts +146 -93
  192. package/dist/types/wallet/wallet.d.ts +91 -33
  193. package/dist/types/worker/expo/asyncStorageTaskQueue.d.ts +1 -1
  194. package/dist/types/worker/expo/processors/contractPollProcessor.d.ts +1 -1
  195. package/dist/types/worker/expo/taskRunner.d.ts +6 -6
  196. package/dist/types/worker/messageBus.d.ts +5 -3
  197. package/package.json +1 -1
@@ -8,10 +8,11 @@ import { getSequence, VtxoScript } from '../script/base.js';
8
8
  * Intent proof implementation for Bitcoin message signing.
9
9
  *
10
10
  * Intent proof defines a standard for signing Bitcoin messages as well as proving
11
- * ownership of coins. This namespace provides utilities for creating and
12
- * validating Intent proof.
11
+ * ownership of outputs.
13
12
  *
14
- * it is greatly inspired by BIP322.
13
+ * This namespace provides utilities for creating and validating Intent proof.
14
+ *
15
+ * It is greatly inspired by BIP322.
15
16
  * @see https://github.com/bitcoin/bips/blob/master/bip-0322.mediawiki
16
17
  *
17
18
  * @example
@@ -33,11 +34,11 @@ export var Intent;
33
34
  * Creates a new Intent proof unsigned transaction.
34
35
  *
35
36
  * This function constructs a special transaction that can be signed to prove
36
- * ownership of VTXOs and UTXOs. The proof includes the message to be
37
+ * ownership of onchain and virtual outputs. The proof includes the message to be
37
38
  * signed and the inputs/outputs that demonstrate ownership.
38
39
  *
39
40
  * @param message - The Intent message to be signed, either raw string of Message object
40
- * @param inputs - Array of transaction inputs to prove ownership of
41
+ * @param ins - Array of transaction inputs to prove ownership of
41
42
  * @param outputs - Optional array of transaction outputs
42
43
  * @returns An unsigned Intent proof transaction
43
44
  */
@@ -52,12 +53,18 @@ export var Intent;
52
53
  throw new Error("invalid inputs");
53
54
  if (!validateOutputs(outputs))
54
55
  throw new Error("invalid outputs");
55
- // create the initial transaction to spend
56
+ // Create the initial transaction to spend.
56
57
  const toSpend = craftToSpendTx(message, inputs[0].witnessUtxo.script);
57
- // create the transaction to sign
58
+ // Create the transaction to sign.
58
59
  return craftToSignTx(toSpend, inputs, outputs);
59
60
  }
60
61
  Intent.create = create;
62
+ /**
63
+ * Compute the fee paid by an intent proof transaction.
64
+ *
65
+ * @param proof - Intent proof transaction
66
+ * @returns The fee in satoshis
67
+ */
61
68
  function fee(proof) {
62
69
  let sumOfInputs = 0n;
63
70
  for (let i = 0; i < proof.inputsLength; i++) {
@@ -79,6 +86,12 @@ export var Intent;
79
86
  return Number(sumOfInputs - sumOfOutputs);
80
87
  }
81
88
  Intent.fee = fee;
89
+ /**
90
+ * Serialize an intent message to the canonical JSON string used for signing.
91
+ *
92
+ * @param message - Intent message payload
93
+ * @returns Canonical string form of the message
94
+ */
82
95
  function encodeMessage(message) {
83
96
  switch (message.type) {
84
97
  case "register":
@@ -139,7 +152,7 @@ function validateOutputs(outputs) {
139
152
  *
140
153
  * @param message - The message to embed
141
154
  * @param pkScript - The scriptPubKey of the signer's address
142
- * @param tag - Tagged-hash tag (defaults to the Ark intent proof tag)
155
+ * @param tag - Tagged-hash tag (defaults to the Arkade intent proof tag)
143
156
  */
144
157
  export function craftToSpendTx(message, pkScript, tag = TAG_INTENT_PROOF) {
145
158
  const messageHash = hashMessage(message, tag);
@@ -165,12 +178,15 @@ export function craftToSpendTx(message, pkScript, tag = TAG_INTENT_PROOF) {
165
178
  // craftToSignTx creates the transaction that will be signed for the proof
166
179
  function craftToSignTx(toSpend, inputs, outputs) {
167
180
  const firstInput = inputs[0];
168
- const lockTime = inputs
169
- .map((input) => input.sequence || 0)
170
- .reduce((a, b) => Math.max(a, b), 0);
181
+ // Proof tx is never broadcast onchain — toSpend references a zero-hash
182
+ // outpoint (see BIP-322). The tx exists only as a sighash commitment
183
+ // the server verifies signatures against; nLockTime and nSequence carry
184
+ // no consensus meaning here, they only need to match between signer and
185
+ // verifier. Use lockTime = 0 (BIP-322 convention) and leave each input's
186
+ // nSequence untouched.
171
187
  const tx = new Transaction({
172
188
  version: 2,
173
- lockTime,
189
+ lockTime: 0,
174
190
  });
175
191
  // add the first "toSpend" input
176
192
  tx.addInput({
@@ -15,11 +15,12 @@ export var SettlementEventType;
15
15
  SettlementEventType["StreamStarted"] = "stream_started";
16
16
  })(SettlementEventType || (SettlementEventType = {}));
17
17
  /**
18
- * REST-based Ark provider implementation.
18
+ * REST-based Arkade provider implementation.
19
+ *
19
20
  * @see https://buf.build/arkade-os/arkd/docs/main:ark.v1#ark.v1.ArkService
20
21
  * @example
21
22
  * ```typescript
22
- * const provider = new RestArkProvider('https://ark.example.com');
23
+ * const provider = new RestArkProvider('https://arkade.computer');
23
24
  * const info = await provider.getInfo();
24
25
  * ```
25
26
  */
@@ -1,6 +1,6 @@
1
1
  import { Intent } from '../intent/index.js';
2
2
  /**
3
- * REST-based Delegator provider implementation.
3
+ * REST-based delegation provider implementation.
4
4
  * @example
5
5
  * ```typescript
6
6
  * const provider = new RestDelegatorProvider('https://delegator.example.com');
@@ -9,9 +9,22 @@ import { Intent } from '../intent/index.js';
9
9
  * ```
10
10
  */
11
11
  export class RestDelegatorProvider {
12
+ /**
13
+ * Create a REST delegation provider targeting the given base URL.
14
+ *
15
+ * @param url - Base URL of the delegation service
16
+ */
12
17
  constructor(url) {
13
18
  this.url = url;
14
19
  }
20
+ /**
21
+ * Submit a delegation request to the remote delegation service.
22
+ *
23
+ * @param intent - Signed register intent to delegate
24
+ * @param forfeitTxs - Forfeit transactions associated with the delegation request
25
+ * @param options - Optional delegate behavior flags
26
+ * @throws Error if the remote service rejects the request
27
+ */
15
28
  async delegate(intent, forfeitTxs, options) {
16
29
  const url = `${this.url}/v1/delegate`;
17
30
  const response = await fetch(url, {
@@ -33,6 +46,12 @@ export class RestDelegatorProvider {
33
46
  throw new Error(`Failed to delegate: ${errorText}`);
34
47
  }
35
48
  }
49
+ /**
50
+ * Fetch delegate metadata exposed by the remote delegation service.
51
+ *
52
+ * @returns Delegate identity and fee information
53
+ * @throws Error if the remote service returns invalid data
54
+ */
36
55
  async getDelegateInfo() {
37
56
  const url = `${this.url}/v1/delegator/info`;
38
57
  const response = await fetch(url);
@@ -1,7 +1,7 @@
1
1
  import { RestArkProvider, isFetchTimeoutError, } from './ark.js';
2
2
  import { getExpoFetch, sseStreamIterator } from './expoUtils.js';
3
3
  /**
4
- * Expo-compatible Ark provider implementation using expo/fetch for SSE support.
4
+ * Expo-compatible Arkade provider implementation using expo/fetch for SSE support.
5
5
  * This provider works specifically in React Native/Expo environments where
6
6
  * standard EventSource is not available but expo/fetch provides SSE capabilities.
7
7
  *
@@ -9,7 +9,7 @@ import { getExpoFetch, sseStreamIterator } from './expoUtils.js';
9
9
  * ```typescript
10
10
  * import { ExpoArkProvider } from '@arkade-os/sdk/providers/expo';
11
11
  *
12
- * const provider = new ExpoArkProvider('https://ark.example.com');
12
+ * const provider = new ExpoArkProvider('https://arkade.computer');
13
13
  * const info = await provider.getInfo();
14
14
  * ```
15
15
  */
@@ -17,11 +17,11 @@ export var ChainTxType;
17
17
  ChainTxType["CHECKPOINT"] = "INDEXER_CHAINED_TX_TYPE_CHECKPOINT";
18
18
  })(ChainTxType || (ChainTxType = {}));
19
19
  /**
20
- * REST-based Indexer provider implementation.
20
+ * REST-based indexer provider implementation.
21
21
  * @see https://buf.build/arkade-os/arkd/docs/main:ark.v1#ark.v1.IndexerService
22
22
  * @example
23
23
  * ```typescript
24
- * const provider = new RestIndexerProvider('https://ark.indexer.example.com');
24
+ * const provider = new RestIndexerProvider('https://arkade.computer');
25
25
  * const commitmentTx = await provider.getCommitmentTx("6686af8f3be3517880821f62e6c3d749b9d6713736a1d8e229a55daa659446b2");
26
26
  * ```
27
27
  */
@@ -10,11 +10,12 @@ export const ESPLORA_URL = {
10
10
  };
11
11
  /**
12
12
  * Implementation of the onchain provider interface for esplora REST API.
13
+ *
13
14
  * @see https://mempool.space/docs/api/rest
14
15
  * @example
15
16
  * ```typescript
16
17
  * const provider = new EsploraProvider("https://mempool.space/api");
17
- * const utxos = await provider.getCoins("bcrt1q679zsd45msawvr7782r0twvmukns3drlstjt77");
18
+ * const outputs = await provider.getCoins("bcrt1q679zsd45msawvr7782r0twvmukns3drlstjt77");
18
19
  * ```
19
20
  */
20
21
  export class EsploraProvider {
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Realm object schemas for the Ark wallet.
2
+ * Realm object schemas for the Arkade wallet.
3
3
  *
4
4
  * All schema names are prefixed with "Ark" to avoid collisions with
5
5
  * other Realm schemas in the consuming application.
@@ -93,7 +93,7 @@ export const ArkContractSchema = {
93
93
  },
94
94
  };
95
95
  /**
96
- * All Realm schemas needed by the Ark wallet repositories.
96
+ * All Realm schemas needed by the Arkade wallet repositories.
97
97
  * Pass this array to your Realm configuration's `schema` property.
98
98
  */
99
99
  export const ArkRealmSchemas = [
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Minimal interface for the subset of the Realm API used by the
3
- * Ark repositories. Consumers pass their real Realm instance and
3
+ * Arkade repositories. Consumers pass their real Realm instance and
4
4
  * the compiler validates it satisfies this shape.
5
5
  */
6
6
  export {};
@@ -1,13 +1,20 @@
1
1
  import { bech32m } from "@scure/base";
2
2
  import { Script } from "@scure/btc-signer/script.js";
3
3
  /**
4
- * ArkAddress allows to create and decode bech32m encoded ark address.
5
- * An ark address is composed of:
4
+ * ArkAddress allows creating and decoding bech32m-encoded Arkade addresses.
5
+ *
6
+ * An Arkade address is composed of:
6
7
  * - a human readable prefix (hrp)
7
8
  * - a version byte (1 byte)
8
9
  * - a server public key (32 bytes)
9
10
  * - a vtxo taproot public key (32 bytes)
10
11
  *
12
+ * @remarks
13
+ * This is an Arkade-specific address format.
14
+ * It is distinct from the Taproot onchain address returned by `VtxoScript.onchainAddress`.
15
+ *
16
+ * @see VtxoScript
17
+ *
11
18
  * @example
12
19
  * ```typescript
13
20
  * const address = new ArkAddress(
@@ -23,6 +30,16 @@ import { Script } from "@scure/btc-signer/script.js";
23
30
  * ```
24
31
  */
25
32
  export class ArkAddress {
33
+ /**
34
+ * Create an Arkade address from its server key, vtxo taproot public key, and prefix.
35
+ *
36
+ * @param serverPubKey - 32-byte Arkade server public key
37
+ * @param vtxoTaprootKey - 32-byte tweaked vtxo taproot public key
38
+ * @param hrp - Bech32 human-readable prefix
39
+ * @param version - Address version byte
40
+ * @defaultValue `version = 0`
41
+ * @throws Error if either public key is not 32 bytes long
42
+ */
26
43
  constructor(serverPubKey, vtxoTaprootKey, hrp, version = 0) {
27
44
  this.serverPubKey = serverPubKey;
28
45
  this.vtxoTaprootKey = vtxoTaprootKey;
@@ -37,13 +54,21 @@ export class ArkAddress {
37
54
  vtxoTaprootKey.length);
38
55
  }
39
56
  }
57
+ /**
58
+ * Decode an Arkade address from its bech32m string form.
59
+ *
60
+ * @param address - Bech32m-encoded Arkade address
61
+ * @returns Decoded Arkade address
62
+ * @throws Error if the address is malformed or has an invalid payload length
63
+ * @see encode
64
+ */
40
65
  static decode(address) {
41
66
  const decoded = bech32m.decodeUnsafe(address, 1023);
42
67
  if (!decoded) {
43
68
  throw new Error("Invalid address");
44
69
  }
45
70
  const data = new Uint8Array(bech32m.fromWords(decoded.words));
46
- // First the version byte, then 32 bytes server pubkey, then 32 bytes vtxo taproot pubkey
71
+ // First the version byte, then 32 bytes server pubkey, then 32 bytes vtxo taproot public key.
47
72
  if (data.length !== 1 + 32 + 32) {
48
73
  throw new Error("Invalid data length, expected 65 bytes, got " + data.length);
49
74
  }
@@ -52,8 +77,14 @@ export class ArkAddress {
52
77
  const vtxoTaprootPubKey = data.slice(33, 65);
53
78
  return new ArkAddress(serverPubKey, vtxoTaprootPubKey, decoded.prefix, version);
54
79
  }
80
+ /**
81
+ * Encode the address to its bech32m string form.
82
+ *
83
+ * @returns Bech32m-encoded Arkade address
84
+ * @see decode
85
+ */
55
86
  encode() {
56
- // Combine version byte, server pubkey, and vtxo taproot pubkey
87
+ // Combine version byte, server pubkey, and vtxo taproot public key.
57
88
  const data = new Uint8Array(1 + 32 + 32);
58
89
  data[0] = this.version;
59
90
  data.set(this.serverPubKey, 1);
@@ -61,11 +92,11 @@ export class ArkAddress {
61
92
  const words = bech32m.toWords(data);
62
93
  return bech32m.encode(this.hrp, words, 1023);
63
94
  }
64
- // pkScript is the script that should be used to send non-dust funds to the address
95
+ /** ScriptPubKey used to send non-dust funds to the address. */
65
96
  get pkScript() {
66
97
  return Script.encode(["OP_1", this.vtxoTaprootKey]);
67
98
  }
68
- // subdustPkScript is the script that should be used to send sub-dust funds to the address
99
+ /** ScriptPubKey used to send sub-dust funds to the address. */
69
100
  get subdustPkScript() {
70
101
  return Script.encode(["RETURN", this.vtxoTaprootKey]);
71
102
  }
@@ -11,18 +11,35 @@ export function scriptFromTapLeafScript(leaf) {
11
11
  }
12
12
  /**
13
13
  * VtxoScript is a script that contains a list of tapleaf scripts.
14
- * It is used to create vtxo scripts.
14
+ * It is used to create virtual output scripts.
15
+ *
16
+ * @see ArkAddress
15
17
  *
16
18
  * @example
17
19
  * ```typescript
18
20
  * const vtxoScript = new VtxoScript([new Uint8Array(32), new Uint8Array(32)]);
21
+ * ```
19
22
  */
20
23
  export class VtxoScript {
24
+ /**
25
+ * Decode a virtual output script from an encoded TapTree.
26
+ *
27
+ * @param tapTree - Encoded TapTree bytes
28
+ * @returns Decoded virtual output script
29
+ * @throws Error if the TapTree cannot be decoded into a valid script set
30
+ * @see encode
31
+ */
21
32
  static decode(tapTree) {
22
33
  const leaves = TapTreeCoder.decode(tapTree);
23
34
  const scripts = leaves.map((leaf) => leaf.script);
24
35
  return new VtxoScript(scripts);
25
36
  }
37
+ /**
38
+ * Create a virtual output script from its tapleaf scripts.
39
+ *
40
+ * @param scripts - Raw tapscript bytes for each leaf
41
+ * @throws Error if the provided leaves cannot produce a valid Taproot tree
42
+ */
26
43
  constructor(scripts) {
27
44
  this.scripts = scripts;
28
45
  // reverse the scripts if the number of scripts is odd
@@ -43,6 +60,12 @@ export class VtxoScript {
43
60
  this.leaves = payment.tapLeafScript;
44
61
  this.tweakedPublicKey = payment.tweakedPubkey;
45
62
  }
63
+ /**
64
+ * Encode the virtual output script to a TapTree byte representation.
65
+ *
66
+ * @returns Encoded TapTree bytes
67
+ * @see decode
68
+ */
46
69
  encode() {
47
70
  const tapTree = TapTreeCoder.encode(this.scripts.map((script) => ({
48
71
  depth: 1,
@@ -51,18 +74,40 @@ export class VtxoScript {
51
74
  })));
52
75
  return tapTree;
53
76
  }
77
+ /**
78
+ * Build the Arkade address corresponding to this virtual output script.
79
+ *
80
+ * @param prefix - Bech32 human-readable prefix
81
+ * @param serverPubKey - 32-byte Arkade server public key
82
+ * @returns Arkade address for this script
83
+ * @see ArkAddress
84
+ */
54
85
  address(prefix, serverPubKey) {
55
86
  return new ArkAddress(serverPubKey, this.tweakedPublicKey, prefix);
56
87
  }
57
88
  get pkScript() {
58
89
  return Script.encode(["OP_1", this.tweakedPublicKey]);
59
90
  }
91
+ /**
92
+ * Build the Taproot onchain address corresponding to this virtual output script.
93
+ *
94
+ * @param network - Bitcoin network descriptor
95
+ * @returns Taproot onchain address
96
+ * @see address
97
+ */
60
98
  onchainAddress(network) {
61
99
  return Address(network).encode({
62
100
  type: "tr",
63
101
  pubkey: this.tweakedPublicKey,
64
102
  });
65
103
  }
104
+ /**
105
+ * Look up a tapleaf script by its hex-encoded tapscript body.
106
+ *
107
+ * @param scriptHex - Hex-encoded tapscript body without the leaf version byte
108
+ * @returns Matching tapleaf script
109
+ * @throws Error if no matching leaf exists
110
+ */
66
111
  findLeaf(scriptHex) {
67
112
  const leaf = this.leaves.find((leaf) => hex.encode(scriptFromTapLeafScript(leaf)) === scriptHex);
68
113
  if (!leaf) {
@@ -70,6 +115,12 @@ export class VtxoScript {
70
115
  }
71
116
  return leaf;
72
117
  }
118
+ /**
119
+ * Return all unilateral exit paths embedded in the virtual output script.
120
+ *
121
+ * @returns CSV-based exit paths found in the leaves
122
+ * @see getSequence
123
+ */
73
124
  exitPaths() {
74
125
  const paths = [];
75
126
  for (const leaf of this.leaves) {
@@ -91,6 +142,24 @@ export class VtxoScript {
91
142
  return paths;
92
143
  }
93
144
  }
145
+ /**
146
+ * Extract the timelock value encoded in a timelocked tapleaf, if any.
147
+ *
148
+ * The return value is unit-ambiguous: for a CSV leaf it is a BIP-68
149
+ * nSequence (relative timelock); for a CLTV leaf it is an absolute
150
+ * nLockTime. Callers must know which leaf shape they are inspecting to
151
+ * interpret the number correctly, and must not copy a CSV result into
152
+ * `Transaction.lockTime` (or vice versa).
153
+ *
154
+ * @param tapLeafScript - Tapleaf script to inspect
155
+ * @returns The encoded timelock value, or `undefined` when neither a CSV
156
+ * nor CLTV path is present
157
+ * @see VtxoScript.exitPaths
158
+ */
159
+ // TODO(next-major): return a discriminated union
160
+ // (`{ kind: "relative", nSequence } | { kind: "absolute", lockTime }`)
161
+ // so callers can't conflate the two. Deferred because changing the
162
+ // return type is a breaking change.
94
163
  export function getSequence(tapLeafScript) {
95
164
  let sequence = undefined;
96
165
  try {
@@ -22,6 +22,7 @@ export var DefaultVtxo;
22
22
  * ```
23
23
  */
24
24
  class Script extends VtxoScript {
25
+ /** Create the default virtual output script with one forfeit path and one exit path. */
25
26
  constructor(options) {
26
27
  const { pubKey, serverPubKey, csvTimelock = Script.DEFAULT_TIMELOCK, } = options;
27
28
  const forfeitScript = MultisigTapscript.encode({
@@ -36,9 +37,11 @@ export var DefaultVtxo;
36
37
  this.forfeitScript = hex.encode(forfeitScript);
37
38
  this.exitScript = hex.encode(exitScript);
38
39
  }
40
+ /** Return the forfeit tapleaf script. */
39
41
  forfeit() {
40
42
  return this.findLeaf(this.forfeitScript);
41
43
  }
44
+ /** Return the unilateral exit tapleaf script. */
42
45
  exit() {
43
46
  return this.findLeaf(this.exitScript);
44
47
  }
@@ -21,6 +21,7 @@ export var DelegateVtxo;
21
21
  * ```
22
22
  */
23
23
  class Script extends VtxoScript {
24
+ /** Create a delegated virtual output script with forfeit, exit, and delegate paths. */
24
25
  constructor(options) {
25
26
  const defaultVtxo = new DefaultVtxo.Script(options);
26
27
  const { delegatePubKey, pubKey, serverPubKey } = options;
@@ -32,12 +33,15 @@ export var DelegateVtxo;
32
33
  this.defaultVtxo = defaultVtxo;
33
34
  this.delegateScript = hex.encode(delegateScript);
34
35
  }
36
+ /** Return the forfeit tapleaf script. */
35
37
  forfeit() {
36
38
  return this.findLeaf(this.defaultVtxo.forfeitScript);
37
39
  }
40
+ /** Return the unilateral exit tapleaf script. */
38
41
  exit() {
39
42
  return this.findLeaf(this.defaultVtxo.exitScript);
40
43
  }
44
+ /** Return the delegate tapleaf script. */
41
45
  delegate() {
42
46
  return this.findLeaf(this.delegateScript);
43
47
  }
@@ -11,9 +11,9 @@ export var TapscriptType;
11
11
  TapscriptType["CLTVMultisig"] = "cltv-multisig";
12
12
  })(TapscriptType || (TapscriptType = {}));
13
13
  /**
14
- * decodeTapscript is a function that decodes an ark tapsript from a raw script.
14
+ * decodeTapscript is a function that decodes an Arkade tapscript from a raw script.
15
15
  *
16
- * @throws {Error} if the script is not a valid ark tapscript
16
+ * @throws {Error} if the script is not a valid Arkade tapscript
17
17
  * @example
18
18
  * ```typescript
19
19
  * const arkTapscript = decodeTapscript(new Uint8Array(32));
@@ -55,6 +55,7 @@ export var MultisigTapscript;
55
55
  MultisigType[MultisigType["CHECKSIG"] = 0] = "CHECKSIG";
56
56
  MultisigType[MultisigType["CHECKSIGADD"] = 1] = "CHECKSIGADD";
57
57
  })(MultisigType = MultisigTapscript.MultisigType || (MultisigTapscript.MultisigType = {}));
58
+ /** Encode a plain multisig tapscript. */
58
59
  function encode(params) {
59
60
  if (params.pubkeys.length === 0) {
60
61
  throw new Error("At least 1 pubkey is required");
@@ -92,6 +93,7 @@ export var MultisigTapscript;
92
93
  };
93
94
  }
94
95
  MultisigTapscript.encode = encode;
96
+ /** Decode a plain multisig tapscript from raw script bytes. */
95
97
  function decode(script) {
96
98
  if (script.length === 0) {
97
99
  throw new Error("Failed to decode: script is empty");
@@ -204,6 +206,7 @@ export var MultisigTapscript;
204
206
  script,
205
207
  };
206
208
  }
209
+ /** Return true when the tapscript is a plain multisig tapscript. */
207
210
  function is(tapscript) {
208
211
  return tapscript.type === TapscriptType.Multisig;
209
212
  }
@@ -224,6 +227,7 @@ export var MultisigTapscript;
224
227
  */
225
228
  export var CSVMultisigTapscript;
226
229
  (function (CSVMultisigTapscript) {
230
+ /** Encode a CSV multisig tapscript. */
227
231
  function encode(params) {
228
232
  for (const pubkey of params.pubkeys) {
229
233
  if (pubkey.length !== 32) {
@@ -250,6 +254,7 @@ export var CSVMultisigTapscript;
250
254
  };
251
255
  }
252
256
  CSVMultisigTapscript.encode = encode;
257
+ /** Decode a CSV multisig tapscript from raw script bytes. */
253
258
  function decode(script) {
254
259
  if (script.length === 0) {
255
260
  throw new Error("Failed to decode: script is empty");
@@ -301,6 +306,7 @@ export var CSVMultisigTapscript;
301
306
  };
302
307
  }
303
308
  CSVMultisigTapscript.decode = decode;
309
+ /** Return true when the tapscript is a CSV multisig tapscript. */
304
310
  function is(tapscript) {
305
311
  return tapscript.type === TapscriptType.CSVMultisig;
306
312
  }
@@ -320,6 +326,7 @@ export var CSVMultisigTapscript;
320
326
  */
321
327
  export var ConditionCSVMultisigTapscript;
322
328
  (function (ConditionCSVMultisigTapscript) {
329
+ /** Encode a condition + CSV multisig tapscript. */
323
330
  function encode(params) {
324
331
  const script = new Uint8Array([
325
332
  ...params.conditionScript,
@@ -333,6 +340,7 @@ export var ConditionCSVMultisigTapscript;
333
340
  };
334
341
  }
335
342
  ConditionCSVMultisigTapscript.encode = encode;
343
+ /** Decode a condition + CSV multisig tapscript from raw script bytes. */
336
344
  function decode(script) {
337
345
  if (script.length === 0) {
338
346
  throw new Error("Failed to decode: script is empty");
@@ -376,6 +384,7 @@ export var ConditionCSVMultisigTapscript;
376
384
  };
377
385
  }
378
386
  ConditionCSVMultisigTapscript.decode = decode;
387
+ /** Return true when the tapscript is a condition + CSV multisig tapscript. */
379
388
  function is(tapscript) {
380
389
  return tapscript.type === TapscriptType.ConditionCSVMultisig;
381
390
  }
@@ -395,6 +404,7 @@ export var ConditionCSVMultisigTapscript;
395
404
  */
396
405
  export var ConditionMultisigTapscript;
397
406
  (function (ConditionMultisigTapscript) {
407
+ /** Encode a condition + multisig tapscript. */
398
408
  function encode(params) {
399
409
  const script = new Uint8Array([
400
410
  ...params.conditionScript,
@@ -408,6 +418,7 @@ export var ConditionMultisigTapscript;
408
418
  };
409
419
  }
410
420
  ConditionMultisigTapscript.encode = encode;
421
+ /** Decode a condition + multisig tapscript from raw script bytes. */
411
422
  function decode(script) {
412
423
  if (script.length === 0) {
413
424
  throw new Error("Failed to decode: script is empty");
@@ -451,6 +462,7 @@ export var ConditionMultisigTapscript;
451
462
  };
452
463
  }
453
464
  ConditionMultisigTapscript.decode = decode;
465
+ /** Return true when the tapscript is a condition + multisig tapscript. */
454
466
  function is(tapscript) {
455
467
  return tapscript.type === TapscriptType.ConditionMultisig;
456
468
  }
@@ -470,6 +482,7 @@ export var ConditionMultisigTapscript;
470
482
  */
471
483
  export var CLTVMultisigTapscript;
472
484
  (function (CLTVMultisigTapscript) {
485
+ /** Encode a CLTV multisig tapscript. */
473
486
  function encode(params) {
474
487
  const locktime = MinimalScriptNum.encode(params.absoluteTimelock);
475
488
  const asm = [
@@ -489,6 +502,7 @@ export var CLTVMultisigTapscript;
489
502
  };
490
503
  }
491
504
  CLTVMultisigTapscript.encode = encode;
505
+ /** Decode a CLTV multisig tapscript from raw script bytes. */
492
506
  function decode(script) {
493
507
  if (script.length === 0) {
494
508
  throw new Error("Failed to decode: script is empty");
@@ -536,6 +550,7 @@ export var CLTVMultisigTapscript;
536
550
  };
537
551
  }
538
552
  CLTVMultisigTapscript.decode = decode;
553
+ /** Return true when the tapscript is a CLTV multisig tapscript. */
539
554
  function is(tapscript) {
540
555
  return tapscript.type === TapscriptType.CLTVMultisig;
541
556
  }