@arkade-os/sdk 0.3.13 → 0.4.0-next.1

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 (270) hide show
  1. package/README.md +586 -54
  2. package/dist/cjs/asset/assetGroup.js +141 -0
  3. package/dist/cjs/asset/assetId.js +88 -0
  4. package/dist/cjs/asset/assetInput.js +204 -0
  5. package/dist/cjs/asset/assetOutput.js +159 -0
  6. package/dist/cjs/asset/assetRef.js +82 -0
  7. package/dist/cjs/asset/index.js +24 -0
  8. package/dist/cjs/asset/metadata.js +172 -0
  9. package/dist/cjs/asset/packet.js +164 -0
  10. package/dist/cjs/asset/types.js +25 -0
  11. package/dist/cjs/asset/utils.js +105 -0
  12. package/dist/cjs/bip322/index.js +270 -0
  13. package/dist/cjs/contracts/arkcontract.js +148 -0
  14. package/dist/cjs/contracts/contractManager.js +436 -0
  15. package/dist/cjs/contracts/contractWatcher.js +567 -0
  16. package/dist/cjs/contracts/handlers/default.js +85 -0
  17. package/dist/cjs/contracts/handlers/delegate.js +89 -0
  18. package/dist/cjs/contracts/handlers/helpers.js +105 -0
  19. package/dist/cjs/contracts/handlers/index.js +19 -0
  20. package/dist/cjs/contracts/handlers/registry.js +89 -0
  21. package/dist/cjs/contracts/handlers/vhtlc.js +193 -0
  22. package/dist/cjs/contracts/index.js +41 -0
  23. package/dist/cjs/contracts/types.js +2 -0
  24. package/dist/cjs/forfeit.js +12 -8
  25. package/dist/cjs/identity/index.js +1 -0
  26. package/dist/cjs/identity/seedIdentity.js +255 -0
  27. package/dist/cjs/index.js +72 -14
  28. package/dist/cjs/intent/index.js +47 -11
  29. package/dist/cjs/providers/ark.js +7 -0
  30. package/dist/cjs/providers/delegator.js +66 -0
  31. package/dist/cjs/providers/expoIndexer.js +5 -0
  32. package/dist/cjs/providers/indexer.js +68 -1
  33. package/dist/cjs/providers/utils.js +1 -0
  34. package/dist/cjs/repositories/contractRepository.js +0 -103
  35. package/dist/cjs/repositories/inMemory/contractRepository.js +55 -0
  36. package/dist/cjs/repositories/inMemory/walletRepository.js +80 -0
  37. package/dist/cjs/repositories/index.js +16 -0
  38. package/dist/cjs/repositories/indexedDB/contractRepository.js +187 -0
  39. package/dist/cjs/repositories/indexedDB/db.js +19 -0
  40. package/dist/cjs/repositories/indexedDB/manager.js +97 -0
  41. package/dist/cjs/repositories/indexedDB/schema.js +159 -0
  42. package/dist/cjs/repositories/indexedDB/walletRepository.js +338 -0
  43. package/dist/cjs/repositories/indexedDB/websqlAdapter.js +144 -0
  44. package/dist/cjs/repositories/migrations/contractRepositoryImpl.js +127 -0
  45. package/dist/cjs/repositories/migrations/fromStorageAdapter.js +66 -0
  46. package/dist/cjs/repositories/migrations/walletRepositoryImpl.js +180 -0
  47. package/dist/cjs/repositories/realm/contractRepository.js +120 -0
  48. package/dist/cjs/repositories/realm/index.js +9 -0
  49. package/dist/cjs/repositories/realm/schemas.js +108 -0
  50. package/dist/cjs/repositories/realm/types.js +7 -0
  51. package/dist/cjs/repositories/realm/walletRepository.js +273 -0
  52. package/dist/cjs/repositories/serialization.js +49 -0
  53. package/dist/cjs/repositories/sqlite/contractRepository.js +139 -0
  54. package/dist/cjs/repositories/sqlite/index.js +7 -0
  55. package/dist/cjs/repositories/sqlite/types.js +2 -0
  56. package/dist/cjs/repositories/sqlite/walletRepository.js +328 -0
  57. package/dist/cjs/repositories/walletRepository.js +0 -169
  58. package/dist/cjs/script/base.js +54 -0
  59. package/dist/cjs/script/delegate.js +49 -0
  60. package/dist/cjs/storage/asyncStorage.js +4 -1
  61. package/dist/cjs/storage/fileSystem.js +3 -0
  62. package/dist/cjs/storage/inMemory.js +3 -0
  63. package/dist/cjs/storage/indexedDB.js +5 -1
  64. package/dist/cjs/storage/localStorage.js +3 -0
  65. package/dist/cjs/utils/arkTransaction.js +16 -0
  66. package/dist/cjs/utils/transactionHistory.js +50 -0
  67. package/dist/cjs/wallet/asset-manager.js +338 -0
  68. package/dist/cjs/wallet/asset.js +117 -0
  69. package/dist/cjs/wallet/batch.js +1 -1
  70. package/dist/cjs/wallet/delegator.js +235 -0
  71. package/dist/cjs/wallet/expo/background.js +133 -0
  72. package/dist/cjs/wallet/expo/index.js +9 -0
  73. package/dist/cjs/wallet/expo/wallet.js +231 -0
  74. package/dist/cjs/wallet/serviceWorker/wallet-message-handler.js +568 -0
  75. package/dist/cjs/wallet/serviceWorker/wallet.js +383 -102
  76. package/dist/cjs/wallet/utils.js +58 -0
  77. package/dist/cjs/wallet/validation.js +151 -0
  78. package/dist/cjs/wallet/vtxo-manager.js +8 -1
  79. package/dist/cjs/wallet/wallet.js +702 -260
  80. package/dist/cjs/worker/browser/service-worker-manager.js +82 -0
  81. package/dist/cjs/{wallet/serviceWorker → worker/browser}/utils.js +2 -1
  82. package/dist/cjs/worker/expo/asyncStorageTaskQueue.js +78 -0
  83. package/dist/cjs/worker/expo/index.js +12 -0
  84. package/dist/cjs/worker/expo/processors/contractPollProcessor.js +61 -0
  85. package/dist/cjs/worker/expo/processors/index.js +6 -0
  86. package/dist/cjs/worker/expo/taskQueue.js +41 -0
  87. package/dist/cjs/worker/expo/taskRunner.js +57 -0
  88. package/dist/cjs/worker/messageBus.js +252 -0
  89. package/dist/esm/asset/assetGroup.js +137 -0
  90. package/dist/esm/asset/assetId.js +84 -0
  91. package/dist/esm/asset/assetInput.js +199 -0
  92. package/dist/esm/asset/assetOutput.js +154 -0
  93. package/dist/esm/asset/assetRef.js +78 -0
  94. package/dist/esm/asset/index.js +8 -0
  95. package/dist/esm/asset/metadata.js +167 -0
  96. package/dist/esm/asset/packet.js +159 -0
  97. package/dist/esm/asset/types.js +22 -0
  98. package/dist/esm/asset/utils.js +99 -0
  99. package/dist/esm/bip322/index.js +267 -0
  100. package/dist/esm/contracts/arkcontract.js +141 -0
  101. package/dist/esm/contracts/contractManager.js +432 -0
  102. package/dist/esm/contracts/contractWatcher.js +563 -0
  103. package/dist/esm/contracts/handlers/default.js +82 -0
  104. package/dist/esm/contracts/handlers/delegate.js +86 -0
  105. package/dist/esm/contracts/handlers/helpers.js +66 -0
  106. package/dist/esm/contracts/handlers/index.js +12 -0
  107. package/dist/esm/contracts/handlers/registry.js +86 -0
  108. package/dist/esm/contracts/handlers/vhtlc.js +190 -0
  109. package/dist/esm/contracts/index.js +13 -0
  110. package/dist/esm/contracts/types.js +1 -0
  111. package/dist/esm/forfeit.js +11 -8
  112. package/dist/esm/identity/index.js +1 -0
  113. package/dist/esm/identity/seedIdentity.js +249 -0
  114. package/dist/esm/index.js +28 -15
  115. package/dist/esm/intent/index.js +44 -9
  116. package/dist/esm/providers/ark.js +7 -0
  117. package/dist/esm/providers/delegator.js +62 -0
  118. package/dist/esm/providers/expoIndexer.js +5 -0
  119. package/dist/esm/providers/indexer.js +68 -1
  120. package/dist/esm/providers/utils.js +1 -0
  121. package/dist/esm/repositories/contractRepository.js +1 -101
  122. package/dist/esm/repositories/inMemory/contractRepository.js +51 -0
  123. package/dist/esm/repositories/inMemory/walletRepository.js +76 -0
  124. package/dist/esm/repositories/index.js +8 -0
  125. package/dist/esm/repositories/indexedDB/contractRepository.js +183 -0
  126. package/dist/esm/repositories/indexedDB/db.js +4 -0
  127. package/dist/esm/repositories/indexedDB/manager.js +92 -0
  128. package/dist/esm/repositories/indexedDB/schema.js +155 -0
  129. package/dist/esm/repositories/indexedDB/walletRepository.js +334 -0
  130. package/dist/esm/repositories/indexedDB/websqlAdapter.js +138 -0
  131. package/dist/esm/repositories/migrations/contractRepositoryImpl.js +121 -0
  132. package/dist/esm/repositories/migrations/fromStorageAdapter.js +58 -0
  133. package/dist/esm/repositories/migrations/walletRepositoryImpl.js +176 -0
  134. package/dist/esm/repositories/realm/contractRepository.js +116 -0
  135. package/dist/esm/repositories/realm/index.js +3 -0
  136. package/dist/esm/repositories/realm/schemas.js +105 -0
  137. package/dist/esm/repositories/realm/types.js +6 -0
  138. package/dist/esm/repositories/realm/walletRepository.js +269 -0
  139. package/dist/esm/repositories/serialization.js +40 -0
  140. package/dist/esm/repositories/sqlite/contractRepository.js +135 -0
  141. package/dist/esm/repositories/sqlite/index.js +2 -0
  142. package/dist/esm/repositories/sqlite/types.js +1 -0
  143. package/dist/esm/repositories/sqlite/walletRepository.js +324 -0
  144. package/dist/esm/repositories/walletRepository.js +1 -167
  145. package/dist/esm/script/base.js +21 -1
  146. package/dist/esm/script/delegate.js +46 -0
  147. package/dist/esm/storage/asyncStorage.js +4 -1
  148. package/dist/esm/storage/fileSystem.js +3 -0
  149. package/dist/esm/storage/inMemory.js +3 -0
  150. package/dist/esm/storage/indexedDB.js +5 -1
  151. package/dist/esm/storage/localStorage.js +3 -0
  152. package/dist/esm/utils/arkTransaction.js +15 -0
  153. package/dist/esm/utils/transactionHistory.js +50 -0
  154. package/dist/esm/wallet/asset-manager.js +333 -0
  155. package/dist/esm/wallet/asset.js +111 -0
  156. package/dist/esm/wallet/batch.js +1 -1
  157. package/dist/esm/wallet/delegator.js +231 -0
  158. package/dist/esm/wallet/expo/background.js +128 -0
  159. package/dist/esm/wallet/expo/index.js +2 -0
  160. package/dist/esm/wallet/expo/wallet.js +194 -0
  161. package/dist/esm/wallet/serviceWorker/wallet-message-handler.js +564 -0
  162. package/dist/esm/wallet/serviceWorker/wallet.js +382 -101
  163. package/dist/esm/wallet/utils.js +54 -0
  164. package/dist/esm/wallet/validation.js +139 -0
  165. package/dist/esm/wallet/vtxo-manager.js +8 -1
  166. package/dist/esm/wallet/wallet.js +704 -229
  167. package/dist/esm/worker/browser/service-worker-manager.js +76 -0
  168. package/dist/esm/{wallet/serviceWorker → worker/browser}/utils.js +2 -1
  169. package/dist/esm/worker/expo/asyncStorageTaskQueue.js +74 -0
  170. package/dist/esm/worker/expo/index.js +4 -0
  171. package/dist/esm/worker/expo/processors/contractPollProcessor.js +58 -0
  172. package/dist/esm/worker/expo/processors/index.js +1 -0
  173. package/dist/esm/worker/expo/taskQueue.js +37 -0
  174. package/dist/esm/worker/expo/taskRunner.js +54 -0
  175. package/dist/esm/worker/messageBus.js +248 -0
  176. package/dist/types/asset/assetGroup.d.ts +28 -0
  177. package/dist/types/asset/assetId.d.ts +19 -0
  178. package/dist/types/asset/assetInput.d.ts +46 -0
  179. package/dist/types/asset/assetOutput.d.ts +39 -0
  180. package/dist/types/asset/assetRef.d.ts +25 -0
  181. package/dist/types/asset/index.d.ts +8 -0
  182. package/dist/types/asset/metadata.d.ts +37 -0
  183. package/dist/types/asset/packet.d.ts +27 -0
  184. package/dist/types/asset/types.d.ts +18 -0
  185. package/dist/types/asset/utils.d.ts +21 -0
  186. package/dist/types/bip322/index.d.ts +55 -0
  187. package/dist/types/contracts/arkcontract.d.ts +101 -0
  188. package/dist/types/contracts/contractManager.d.ts +331 -0
  189. package/dist/types/contracts/contractWatcher.d.ts +192 -0
  190. package/dist/types/contracts/handlers/default.d.ts +19 -0
  191. package/dist/types/contracts/handlers/delegate.d.ts +21 -0
  192. package/dist/types/contracts/handlers/helpers.d.ts +18 -0
  193. package/dist/types/contracts/handlers/index.d.ts +7 -0
  194. package/dist/types/contracts/handlers/registry.d.ts +65 -0
  195. package/dist/types/contracts/handlers/vhtlc.d.ts +32 -0
  196. package/dist/types/contracts/index.d.ts +14 -0
  197. package/dist/types/contracts/types.d.ts +222 -0
  198. package/dist/types/forfeit.d.ts +2 -1
  199. package/dist/types/identity/index.d.ts +1 -0
  200. package/dist/types/identity/seedIdentity.d.ts +128 -0
  201. package/dist/types/index.d.ts +22 -12
  202. package/dist/types/intent/index.d.ts +15 -1
  203. package/dist/types/providers/ark.d.ts +11 -2
  204. package/dist/types/providers/delegator.d.ts +29 -0
  205. package/dist/types/providers/indexer.d.ts +11 -1
  206. package/dist/types/repositories/contractRepository.d.ts +30 -19
  207. package/dist/types/repositories/inMemory/contractRepository.d.ts +17 -0
  208. package/dist/types/repositories/inMemory/walletRepository.d.ts +26 -0
  209. package/dist/types/repositories/index.d.ts +7 -0
  210. package/dist/types/repositories/indexedDB/contractRepository.d.ts +21 -0
  211. package/dist/types/repositories/indexedDB/db.d.ts +4 -0
  212. package/dist/types/repositories/indexedDB/manager.d.ts +22 -0
  213. package/dist/types/repositories/indexedDB/schema.d.ts +8 -0
  214. package/dist/types/repositories/indexedDB/walletRepository.d.ts +25 -0
  215. package/dist/types/repositories/indexedDB/websqlAdapter.d.ts +49 -0
  216. package/dist/types/repositories/migrations/contractRepositoryImpl.d.ts +24 -0
  217. package/dist/types/repositories/migrations/fromStorageAdapter.d.ts +19 -0
  218. package/dist/types/repositories/migrations/walletRepositoryImpl.d.ts +27 -0
  219. package/dist/types/repositories/realm/contractRepository.d.ts +24 -0
  220. package/dist/types/repositories/realm/index.d.ts +4 -0
  221. package/dist/types/repositories/realm/schemas.d.ts +208 -0
  222. package/dist/types/repositories/realm/types.d.ts +16 -0
  223. package/dist/types/repositories/realm/walletRepository.d.ts +31 -0
  224. package/dist/types/repositories/serialization.d.ts +40 -0
  225. package/dist/types/repositories/sqlite/contractRepository.d.ts +33 -0
  226. package/dist/types/repositories/sqlite/index.d.ts +3 -0
  227. package/dist/types/repositories/sqlite/types.d.ts +18 -0
  228. package/dist/types/repositories/sqlite/walletRepository.d.ts +40 -0
  229. package/dist/types/repositories/walletRepository.d.ts +13 -24
  230. package/dist/types/script/base.d.ts +1 -0
  231. package/dist/types/script/delegate.d.ts +36 -0
  232. package/dist/types/storage/asyncStorage.d.ts +4 -0
  233. package/dist/types/storage/fileSystem.d.ts +3 -0
  234. package/dist/types/storage/inMemory.d.ts +3 -0
  235. package/dist/types/storage/index.d.ts +3 -0
  236. package/dist/types/storage/indexedDB.d.ts +3 -0
  237. package/dist/types/storage/localStorage.d.ts +3 -0
  238. package/dist/types/utils/arkTransaction.d.ts +6 -0
  239. package/dist/types/wallet/asset-manager.d.ts +78 -0
  240. package/dist/types/wallet/asset.d.ts +21 -0
  241. package/dist/types/wallet/batch.d.ts +1 -1
  242. package/dist/types/wallet/delegator.d.ts +24 -0
  243. package/dist/types/wallet/expo/background.d.ts +66 -0
  244. package/dist/types/wallet/expo/index.d.ts +4 -0
  245. package/dist/types/wallet/expo/wallet.d.ts +97 -0
  246. package/dist/types/wallet/index.d.ts +75 -2
  247. package/dist/types/wallet/serviceWorker/wallet-message-handler.d.ts +366 -0
  248. package/dist/types/wallet/serviceWorker/wallet.d.ts +20 -11
  249. package/dist/types/wallet/utils.d.ts +12 -1
  250. package/dist/types/wallet/validation.d.ts +24 -0
  251. package/dist/types/wallet/wallet.d.ts +111 -17
  252. package/dist/types/worker/browser/service-worker-manager.d.ts +21 -0
  253. package/dist/types/{wallet/serviceWorker → worker/browser}/utils.d.ts +2 -1
  254. package/dist/types/worker/expo/asyncStorageTaskQueue.d.ts +46 -0
  255. package/dist/types/worker/expo/index.d.ts +7 -0
  256. package/dist/types/worker/expo/processors/contractPollProcessor.d.ts +14 -0
  257. package/dist/types/worker/expo/processors/index.d.ts +1 -0
  258. package/dist/types/worker/expo/taskQueue.d.ts +50 -0
  259. package/dist/types/worker/expo/taskRunner.d.ts +42 -0
  260. package/dist/types/worker/messageBus.d.ts +109 -0
  261. package/package.json +69 -11
  262. package/dist/cjs/wallet/serviceWorker/request.js +0 -78
  263. package/dist/cjs/wallet/serviceWorker/response.js +0 -222
  264. package/dist/cjs/wallet/serviceWorker/worker.js +0 -655
  265. package/dist/esm/wallet/serviceWorker/request.js +0 -75
  266. package/dist/esm/wallet/serviceWorker/response.js +0 -219
  267. package/dist/esm/wallet/serviceWorker/worker.js +0 -651
  268. package/dist/types/wallet/serviceWorker/request.d.ts +0 -74
  269. package/dist/types/wallet/serviceWorker/response.d.ts +0 -123
  270. package/dist/types/wallet/serviceWorker/worker.d.ts +0 -53
@@ -0,0 +1,167 @@
1
+ import { schnorr } from "@noble/curves/secp256k1.js";
2
+ import { hex } from "@scure/base";
3
+ import { compareBytes } from "@scure/btc-signer/utils.js";
4
+ import { BufferReader, BufferWriter } from './utils.js';
5
+ /**
6
+ * Metadata represents a key-value pair.
7
+ * @param key - the key
8
+ * @param value - the value
9
+ */
10
+ export class Metadata {
11
+ constructor(key, value) {
12
+ this.key = key;
13
+ this.value = value;
14
+ }
15
+ static create(key, value) {
16
+ const md = new Metadata(key, value);
17
+ md.validate();
18
+ return md;
19
+ }
20
+ static fromString(s) {
21
+ let buf;
22
+ try {
23
+ buf = hex.decode(s);
24
+ }
25
+ catch {
26
+ throw new Error("invalid metadata format, must be hex");
27
+ }
28
+ return Metadata.fromBytes(buf);
29
+ }
30
+ static fromBytes(buf) {
31
+ if (!buf || buf.length === 0) {
32
+ throw new Error("missing metadata");
33
+ }
34
+ const reader = new BufferReader(buf);
35
+ return Metadata.fromReader(reader);
36
+ }
37
+ serialize() {
38
+ const writer = new BufferWriter();
39
+ this.serializeTo(writer);
40
+ return writer.toBytes();
41
+ }
42
+ toString() {
43
+ return hex.encode(this.serialize());
44
+ }
45
+ get keyString() {
46
+ return new TextDecoder().decode(this.key);
47
+ }
48
+ get valueString() {
49
+ return new TextDecoder().decode(this.value);
50
+ }
51
+ validate() {
52
+ if (this.key.length === 0) {
53
+ throw new Error("missing metadata key");
54
+ }
55
+ if (this.value.length === 0) {
56
+ throw new Error("missing metadata value");
57
+ }
58
+ }
59
+ static fromReader(reader) {
60
+ let key;
61
+ let value;
62
+ try {
63
+ key = reader.readVarSlice();
64
+ }
65
+ catch {
66
+ throw new Error("invalid metadata length");
67
+ }
68
+ try {
69
+ value = reader.readVarSlice();
70
+ }
71
+ catch {
72
+ throw new Error("invalid metadata length");
73
+ }
74
+ const md = new Metadata(key, value);
75
+ md.validate();
76
+ return md;
77
+ }
78
+ serializeTo(writer) {
79
+ writer.writeVarSlice(this.key);
80
+ writer.writeVarSlice(this.value);
81
+ }
82
+ }
83
+ export class MetadataList {
84
+ constructor(items) {
85
+ this.items = items;
86
+ }
87
+ static fromString(s) {
88
+ let buf;
89
+ try {
90
+ buf = hex.decode(s);
91
+ }
92
+ catch {
93
+ throw new Error("invalid metadata list format");
94
+ }
95
+ return MetadataList.fromBytes(buf);
96
+ }
97
+ static fromBytes(buf) {
98
+ if (!buf || buf.length === 0) {
99
+ throw new Error("missing metadata list");
100
+ }
101
+ const reader = new BufferReader(buf);
102
+ return MetadataList.fromReader(reader);
103
+ }
104
+ static fromReader(reader) {
105
+ const count = Number(reader.readVarUint());
106
+ const items = Array.from({ length: count }, () => Metadata.fromReader(reader));
107
+ return new MetadataList(items);
108
+ }
109
+ serializeTo(writer) {
110
+ writer.writeVarUint(this.items.length);
111
+ for (const item of this) {
112
+ item.serializeTo(writer);
113
+ }
114
+ }
115
+ serialize() {
116
+ const writer = new BufferWriter();
117
+ this.serializeTo(writer);
118
+ return writer.toBytes();
119
+ }
120
+ [Symbol.iterator]() {
121
+ return this.items[Symbol.iterator]();
122
+ }
123
+ get length() {
124
+ return this.items.length;
125
+ }
126
+ hash() {
127
+ if (this.items.length === 0)
128
+ throw new Error("missing metadata list");
129
+ const levels = buildMetadataMerkleTree(this.items);
130
+ return levels[levels.length - 1][0]; // the last level is the root
131
+ }
132
+ }
133
+ MetadataList.ARK_LEAF_TAG = "ArkadeAssetLeaf";
134
+ MetadataList.ARK_BRANCH_TAG = "ArkadeAssetBranch";
135
+ MetadataList.ARK_LEAF_VERSION = 0x00;
136
+ function computeMetadataLeafHash(md) {
137
+ const writer = new BufferWriter();
138
+ writer.writeByte(MetadataList.ARK_LEAF_VERSION);
139
+ writer.writeVarSlice(md.key);
140
+ writer.writeVarSlice(md.value);
141
+ return schnorr.utils.taggedHash(MetadataList.ARK_LEAF_TAG, writer.toBytes());
142
+ }
143
+ function computeMetadataBranchHash(a, b) {
144
+ const [smaller, larger] = compareBytes(a, b) === -1 ? [a, b] : [b, a];
145
+ return schnorr.utils.taggedHash(MetadataList.ARK_BRANCH_TAG, smaller, larger);
146
+ }
147
+ function buildMetadataMerkleTree(leaves) {
148
+ if (leaves.length === 0)
149
+ return [];
150
+ const leafHashes = leaves.map(computeMetadataLeafHash);
151
+ const levels = [leafHashes];
152
+ let current = leafHashes;
153
+ while (current.length > 1) {
154
+ const next = [];
155
+ for (let i = 0; i < current.length; i += 2) {
156
+ if (i + 1 < current.length) {
157
+ next.push(computeMetadataBranchHash(current[i], current[i + 1]));
158
+ }
159
+ else {
160
+ next.push(current[i]);
161
+ }
162
+ }
163
+ levels.push(next);
164
+ current = next;
165
+ }
166
+ return levels;
167
+ }
@@ -0,0 +1,159 @@
1
+ import { hex } from "@scure/base";
2
+ import { Script } from "@scure/btc-signer";
3
+ import { concatBytes, equalBytes } from "@scure/btc-signer/utils.js";
4
+ import { ARKADE_MAGIC, MARKER_ASSET_PAYLOAD, AssetRefType } from './types.js';
5
+ import { AssetGroup } from './assetGroup.js';
6
+ import { BufferReader, BufferWriter } from './utils.js';
7
+ export class AssetPacketNotFoundError extends Error {
8
+ constructor(txid) {
9
+ super(`asset packet not found in tx ${txid}`);
10
+ this.name = "AssetPacketNotFoundError";
11
+ }
12
+ }
13
+ /**
14
+ * Packet represents a collection of asset groups.
15
+ * A packet is encoded in OP_RETURN output of an asset transaction.
16
+ * @param groups - the asset groups in the packet
17
+ */
18
+ export class Packet {
19
+ constructor(groups) {
20
+ this.groups = groups;
21
+ }
22
+ static create(groups) {
23
+ const p = new Packet(groups);
24
+ p.validate();
25
+ return p;
26
+ }
27
+ static fromString(s) {
28
+ let buf;
29
+ try {
30
+ buf = hex.decode(s);
31
+ }
32
+ catch {
33
+ throw new Error("invalid output script format, must be hex");
34
+ }
35
+ return Packet.fromScript(buf);
36
+ }
37
+ static fromScript(script) {
38
+ const rawPacket = extractRawPacketFromScript(script);
39
+ const reader = new BufferReader(rawPacket);
40
+ return Packet.fromReader(reader);
41
+ }
42
+ static fromTxOut(pkScript) {
43
+ return Packet.fromScript(pkScript);
44
+ }
45
+ static fromTx(tx) {
46
+ for (let i = 0; i < tx.outputsLength; i++) {
47
+ try {
48
+ const output = tx.getOutput(i);
49
+ if (!output?.script) {
50
+ continue;
51
+ }
52
+ return Packet.fromScript(output.script);
53
+ }
54
+ catch (error) {
55
+ continue;
56
+ }
57
+ }
58
+ throw new AssetPacketNotFoundError(tx.id);
59
+ }
60
+ static isAssetPacket(script) {
61
+ try {
62
+ extractRawPacketFromScript(script);
63
+ return true;
64
+ }
65
+ catch {
66
+ return false;
67
+ }
68
+ }
69
+ leafTxPacket(intentTxid) {
70
+ const leafGroups = this.groups.map((group) => group.toBatchLeafAssetGroup(intentTxid));
71
+ return new Packet(leafGroups);
72
+ }
73
+ txOut() {
74
+ return {
75
+ script: this.serialize(),
76
+ amount: 0n,
77
+ };
78
+ }
79
+ serialize() {
80
+ const writer = new BufferWriter();
81
+ writer.writeVarUint(this.groups.length);
82
+ for (const group of this.groups) {
83
+ group.serializeTo(writer);
84
+ }
85
+ const packetData = writer.toBytes();
86
+ const data = concatBytes(ARKADE_MAGIC, new Uint8Array([MARKER_ASSET_PAYLOAD]), packetData);
87
+ return buildOpReturnScript(data);
88
+ }
89
+ toString() {
90
+ return hex.encode(this.serialize());
91
+ }
92
+ validate() {
93
+ if (this.groups.length === 0) {
94
+ throw new Error("missing assets");
95
+ }
96
+ for (const group of this.groups) {
97
+ if (group.controlAsset !== null &&
98
+ group.controlAsset.ref.type === AssetRefType.ByGroup &&
99
+ group.controlAsset.ref.groupIndex >= this.groups.length) {
100
+ throw new Error(`invalid control asset group index, ${group.controlAsset.ref.groupIndex} out of range [0, ${this.groups.length - 1}]`);
101
+ }
102
+ }
103
+ }
104
+ static fromReader(reader) {
105
+ const count = Number(reader.readVarUint());
106
+ const groups = [];
107
+ for (let i = 0; i < count; i++) {
108
+ groups.push(AssetGroup.fromReader(reader));
109
+ }
110
+ if (reader.remaining() > 0) {
111
+ throw new Error(`invalid packet length, left ${reader.remaining()} unknown bytes to read`);
112
+ }
113
+ const packet = new Packet(groups);
114
+ packet.validate();
115
+ return packet;
116
+ }
117
+ }
118
+ function extractRawPacketFromScript(script) {
119
+ if (!script || script.length === 0) {
120
+ throw new Error("missing output script");
121
+ }
122
+ let decoded;
123
+ try {
124
+ decoded = Script.decode(script);
125
+ }
126
+ catch {
127
+ throw new Error("invalid OP_RETURN output script");
128
+ }
129
+ if (decoded.length === 0 || decoded[0] !== "RETURN") {
130
+ throw new Error("OP_RETURN not found in output script");
131
+ }
132
+ // concat all data pushes after RETURN
133
+ const dataPushes = decoded
134
+ .slice(1)
135
+ .filter((item) => item instanceof Uint8Array);
136
+ if (dataPushes.length === 0) {
137
+ throw new Error("missing OP_RETURN data");
138
+ }
139
+ const payload = concatBytes(...dataPushes);
140
+ if (payload.length < ARKADE_MAGIC.length + 1) {
141
+ throw new Error("invalid script length");
142
+ }
143
+ const magicSlice = new Uint8Array(payload.slice(0, ARKADE_MAGIC.length));
144
+ if (!equalBytes(magicSlice, ARKADE_MAGIC)) {
145
+ throw new Error(`invalid magic prefix, got ${hex.encode(magicSlice)} want ${hex.encode(ARKADE_MAGIC)}`);
146
+ }
147
+ const marker = payload[ARKADE_MAGIC.length];
148
+ if (marker !== MARKER_ASSET_PAYLOAD) {
149
+ throw new Error(`invalid asset marker, got ${marker} want ${MARKER_ASSET_PAYLOAD}`);
150
+ }
151
+ const packetData = new Uint8Array(payload.slice(ARKADE_MAGIC.length + 1));
152
+ if (packetData.length === 0) {
153
+ throw new Error("missing packet data");
154
+ }
155
+ return packetData;
156
+ }
157
+ function buildOpReturnScript(data) {
158
+ return Script.encode(["RETURN", data]);
159
+ }
@@ -0,0 +1,22 @@
1
+ export const TX_HASH_SIZE = 32;
2
+ export const ASSET_ID_SIZE = 34;
3
+ export const ASSET_VERSION = 0x01;
4
+ export var AssetInputType;
5
+ (function (AssetInputType) {
6
+ AssetInputType[AssetInputType["Unspecified"] = 0] = "Unspecified";
7
+ AssetInputType[AssetInputType["Local"] = 1] = "Local";
8
+ AssetInputType[AssetInputType["Intent"] = 2] = "Intent";
9
+ })(AssetInputType || (AssetInputType = {}));
10
+ export var AssetRefType;
11
+ (function (AssetRefType) {
12
+ AssetRefType[AssetRefType["Unspecified"] = 0] = "Unspecified";
13
+ AssetRefType[AssetRefType["ByID"] = 1] = "ByID";
14
+ AssetRefType[AssetRefType["ByGroup"] = 2] = "ByGroup";
15
+ })(AssetRefType || (AssetRefType = {}));
16
+ // Presence byte masks for AssetGroup
17
+ export const MASK_ASSET_ID = 0x01;
18
+ export const MASK_CONTROL_ASSET = 0x02;
19
+ export const MASK_METADATA = 0x04;
20
+ // ARK magic bytes and marker
21
+ export const ARKADE_MAGIC = new Uint8Array([0x41, 0x52, 0x4b]); // "ARK"
22
+ export const MARKER_ASSET_PAYLOAD = 0x00;
@@ -0,0 +1,99 @@
1
+ export class BufferWriter {
2
+ constructor() {
3
+ this.buffer = [];
4
+ }
5
+ write(data) {
6
+ for (const byte of data) {
7
+ this.buffer.push(byte);
8
+ }
9
+ }
10
+ writeByte(byte) {
11
+ this.buffer.push(byte & 0xff);
12
+ }
13
+ writeUint16LE(value) {
14
+ const buf = new Uint8Array(2);
15
+ new DataView(buf.buffer).setUint16(0, value, true); // true = little endian
16
+ this.write(buf);
17
+ }
18
+ writeVarUint(value) {
19
+ if (typeof value === "number") {
20
+ if (!Number.isInteger(value) || value < 0) {
21
+ throw new RangeError("writeVarUint: value must be a non-negative integer");
22
+ }
23
+ }
24
+ else if (value < 0n) {
25
+ throw new RangeError("writeVarUint: value must be a non-negative integer");
26
+ }
27
+ const val = typeof value === "number" ? BigInt(value) : value;
28
+ const bytes = [];
29
+ let remaining = val;
30
+ do {
31
+ let byte = Number(remaining & 0x7fn);
32
+ remaining >>= 7n;
33
+ if (remaining > 0n) {
34
+ byte |= 0x80;
35
+ }
36
+ bytes.push(byte);
37
+ } while (remaining > 0n);
38
+ this.write(new Uint8Array(bytes));
39
+ }
40
+ writeVarSlice(data) {
41
+ this.writeVarUint(data.length);
42
+ this.write(data);
43
+ }
44
+ toBytes() {
45
+ return new Uint8Array(this.buffer);
46
+ }
47
+ }
48
+ export class BufferReader {
49
+ constructor(data) {
50
+ this.offset = 0;
51
+ this.view = new DataView(data.buffer, data.byteOffset, data.byteLength);
52
+ }
53
+ remaining() {
54
+ return this.view.byteLength - this.offset;
55
+ }
56
+ readByte() {
57
+ if (this.offset >= this.view.byteLength) {
58
+ throw new Error("unexpected end of buffer");
59
+ }
60
+ return this.view.getUint8(this.offset++);
61
+ }
62
+ readSlice(size) {
63
+ if (this.offset + size > this.view.byteLength) {
64
+ throw new Error("unexpected end of buffer");
65
+ }
66
+ const result = new Uint8Array(this.view.buffer, this.view.byteOffset + this.offset, size);
67
+ this.offset += size;
68
+ return result;
69
+ }
70
+ readUint16LE() {
71
+ if (this.offset + 2 > this.view.byteLength) {
72
+ throw new Error("unexpected end of buffer");
73
+ }
74
+ const value = this.view.getUint16(this.offset, true);
75
+ this.offset += 2;
76
+ return value;
77
+ }
78
+ readVarUint() {
79
+ let result = 0n;
80
+ let shift = 0n;
81
+ let byte;
82
+ do {
83
+ if (this.offset >= this.view.byteLength) {
84
+ throw new Error("unexpected end of buffer");
85
+ }
86
+ byte = this.view.getUint8(this.offset++);
87
+ result |= BigInt(byte & 0x7f) << shift;
88
+ shift += 7n;
89
+ } while (byte & 0x80);
90
+ return result;
91
+ }
92
+ readVarSlice() {
93
+ const length = Number(this.readVarUint());
94
+ return this.readSlice(length);
95
+ }
96
+ }
97
+ export function isZeroBytes(bytes) {
98
+ return bytes.every((byte) => byte === 0);
99
+ }