@otoplo/wallet-common 0.2.2 → 0.4.0

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 (90) hide show
  1. package/dist/index.js +1798 -1986
  2. package/dist/index.js.map +1 -1
  3. package/dist/types/index.d.ts +0 -1
  4. package/dist/types/index.d.ts.map +1 -1
  5. package/dist/types/persistence/index.d.ts +1 -1
  6. package/dist/types/persistence/index.d.ts.map +1 -1
  7. package/dist/types/persistence/{datastore/db.d.ts → repository.d.ts} +8 -5
  8. package/dist/types/persistence/repository.d.ts.map +1 -0
  9. package/dist/types/persistence/wallet-db.d.ts +17 -25
  10. package/dist/types/persistence/wallet-db.d.ts.map +1 -1
  11. package/dist/types/services/asset.d.ts +6 -0
  12. package/dist/types/services/asset.d.ts.map +1 -1
  13. package/dist/types/services/cache.d.ts +0 -2
  14. package/dist/types/services/cache.d.ts.map +1 -1
  15. package/dist/types/services/discovery.d.ts +3 -3
  16. package/dist/types/services/discovery.d.ts.map +1 -1
  17. package/dist/types/services/index.d.ts +1 -0
  18. package/dist/types/services/index.d.ts.map +1 -1
  19. package/dist/types/services/key.d.ts +3 -0
  20. package/dist/types/services/key.d.ts.map +1 -1
  21. package/dist/types/services/market.d.ts +33 -0
  22. package/dist/types/services/market.d.ts.map +1 -0
  23. package/dist/types/services/rostrum.d.ts +5 -3
  24. package/dist/types/services/rostrum.d.ts.map +1 -1
  25. package/dist/types/services/transaction.d.ts.map +1 -1
  26. package/dist/types/services/wallet.d.ts +13 -6
  27. package/dist/types/services/wallet.d.ts.map +1 -1
  28. package/dist/types/types/db.types.d.ts +4 -0
  29. package/dist/types/types/db.types.d.ts.map +1 -1
  30. package/dist/types/utils/asset.d.ts +1 -2
  31. package/dist/types/utils/asset.d.ts.map +1 -1
  32. package/dist/types/utils/market.d.ts +0 -3
  33. package/dist/types/utils/market.d.ts.map +1 -1
  34. package/package.json +13 -17
  35. package/src/index.ts +0 -1
  36. package/src/persistence/index.ts +1 -1
  37. package/src/persistence/{datastore/db.ts → repository.ts} +9 -5
  38. package/src/persistence/wallet-db.ts +95 -91
  39. package/src/services/asset.ts +60 -26
  40. package/src/services/cache.ts +4 -14
  41. package/src/services/discovery.ts +54 -42
  42. package/src/services/index.ts +2 -1
  43. package/src/services/key.ts +8 -2
  44. package/src/services/market.ts +143 -0
  45. package/src/services/rostrum.ts +14 -6
  46. package/src/services/transaction.ts +3 -10
  47. package/src/services/wallet.ts +66 -42
  48. package/src/types/db.types.ts +6 -1
  49. package/src/utils/asset.ts +2 -21
  50. package/src/utils/market.ts +0 -54
  51. package/dist/types/persistence/datastore/db.d.ts.map +0 -1
  52. package/dist/types/persistence/datastore/index.d.ts +0 -3
  53. package/dist/types/persistence/datastore/index.d.ts.map +0 -1
  54. package/dist/types/persistence/datastore/kv.d.ts +0 -34
  55. package/dist/types/persistence/datastore/kv.d.ts.map +0 -1
  56. package/dist/types/state/hooks.d.ts +0 -17
  57. package/dist/types/state/hooks.d.ts.map +0 -1
  58. package/dist/types/state/index.d.ts +0 -4
  59. package/dist/types/state/index.d.ts.map +0 -1
  60. package/dist/types/state/slices/auth.d.ts +0 -17
  61. package/dist/types/state/slices/auth.d.ts.map +0 -1
  62. package/dist/types/state/slices/dapp.d.ts +0 -29
  63. package/dist/types/state/slices/dapp.d.ts.map +0 -1
  64. package/dist/types/state/slices/index.d.ts +0 -8
  65. package/dist/types/state/slices/index.d.ts.map +0 -1
  66. package/dist/types/state/slices/loader.d.ts +0 -15
  67. package/dist/types/state/slices/loader.d.ts.map +0 -1
  68. package/dist/types/state/slices/market.d.ts +0 -54
  69. package/dist/types/state/slices/market.d.ts.map +0 -1
  70. package/dist/types/state/slices/notifications.d.ts +0 -142
  71. package/dist/types/state/slices/notifications.d.ts.map +0 -1
  72. package/dist/types/state/slices/status.d.ts +0 -35
  73. package/dist/types/state/slices/status.d.ts.map +0 -1
  74. package/dist/types/state/slices/wallet.d.ts +0 -833
  75. package/dist/types/state/slices/wallet.d.ts.map +0 -1
  76. package/dist/types/state/store.d.ts +0 -26
  77. package/dist/types/state/store.d.ts.map +0 -1
  78. package/src/persistence/datastore/index.ts +0 -2
  79. package/src/persistence/datastore/kv.ts +0 -129
  80. package/src/state/hooks.ts +0 -47
  81. package/src/state/index.ts +0 -3
  82. package/src/state/slices/auth.ts +0 -28
  83. package/src/state/slices/dapp.ts +0 -32
  84. package/src/state/slices/index.ts +0 -7
  85. package/src/state/slices/loader.ts +0 -31
  86. package/src/state/slices/market.ts +0 -47
  87. package/src/state/slices/notifications.ts +0 -44
  88. package/src/state/slices/status.ts +0 -41
  89. package/src/state/slices/wallet.ts +0 -107
  90. package/src/state/store.ts +0 -27
package/dist/index.js CHANGED
@@ -1,2030 +1,1842 @@
1
- import { AddressType as O, Networks as E, Address as I, CommonUtils as W, BufferUtils as m, HDPrivateKey as j, TransactionBuilder as z, Transaction as x, UnitUtils as q, Script as b, Opcode as A, Hash as _, ScriptOpcode as L, BNExtended as F, Output as we, TxSigner as X, SighashType as Y, ScriptFactory as Ae, OutputSighashType as Z, BufferWriter as ve } from "libnexa-ts";
2
- import B from "js-big-decimal";
3
- import { ElectrumClient as be, TransportScheme as H, ConnectionStatus as Se } from "@otoplo/electrum-client";
4
- import { mnemonicToSeedSync as ke, generateMnemonic as Te, validateMnemonic as Ie } from "@scure/bip39";
5
- import { DAppProvider as xe } from "wallet-comms-sdk";
6
- import { wordlist as se } from "@scure/bip39/wordlists/english.js";
7
- import { createSlice as S, createAsyncThunk as Ne, createSelector as G } from "@reduxjs/toolkit";
8
- import { useSelector as Me } from "react-redux";
9
- const w = -1, Q = 9223372036854775807n, Ee = 274710, yt = "0014461ad25081cb0119d034385ff154c8d3ad6bdd76";
10
- function C() {
11
- return E.defaultNetwork == E.testnet;
1
+ import { Address as e, AddressType as t, BNExtended as n, BufferUtils as r, BufferWriter as i, CommonUtils as a, HDPrivateKey as o, Hash as s, Networks as c, Opcode as l, Output as u, OutputSighashType as d, Script as f, ScriptFactory as ee, ScriptOpcode as p, SighashType as m, Transaction as h, TransactionBuilder as g, TxSigner as _, UnitUtils as v } from "libnexa-ts";
2
+ import y from "js-big-decimal";
3
+ import { ConnectionStatus as te, ElectrumClient as ne, TransportScheme as b } from "@otoplo/electrum-client";
4
+ import { generateMnemonic as re, mnemonicToSeedSync as ie, validateMnemonic as ae } from "@scure/bip39";
5
+ import { DAppProvider as oe } from "wallet-comms-sdk";
6
+ import { wordlist as x } from "@scure/bip39/wordlists/english.js";
7
+ // src/utils/enums.ts
8
+ var S = /* @__PURE__ */ function(e) {
9
+ return e[e.MAIN = 0] = "MAIN", e[e.VAULT = 1] = "VAULT", e[e.DAPP = 2] = "DAPP", e;
10
+ }({}), C = /* @__PURE__ */ function(e) {
11
+ return e[e.RECEIVE = 0] = "RECEIVE", e[e.CHANGE = 1] = "CHANGE", e;
12
+ }({}), w = /* @__PURE__ */ function(e) {
13
+ return e.SignMessage = "signMessage", e.AddToken = "addToken", e.SignTransaction = "signTransaction", e.SendTransaction = "sendTransaction", e;
14
+ }({}), se = -1, ce = 9223372036854775807n, T = 274710, le = "0014461ad25081cb0119d034385ff154c8d3ad6bdd76";
15
+ function E() {
16
+ return c.defaultNetwork == c.testnet;
12
17
  }
13
- function wt(a) {
14
- return C() ? a == "508c843a4b98fb25f57cf9ebafb245a5c16468f06519cdd467059a91e7b79d52" : a == "edc7144fe1ba4edd0edf35d7eea90f6cb1dba42314aa85da8207e97c5339c801";
18
+ function ue(e) {
19
+ return E() ? e == "508c843a4b98fb25f57cf9ebafb245a5c16468f06519cdd467059a91e7b79d52" : e == "edc7144fe1ba4edd0edf35d7eea90f6cb1dba42314aa85da8207e97c5339c801";
15
20
  }
16
- function R(a, e = O.PayToScriptTemplate) {
17
- return I.isValid(a, E.defaultNetwork, e);
21
+ function D(n, r = t.PayToScriptTemplate) {
22
+ return e.isValid(n, c.defaultNetwork, r);
18
23
  }
19
- function At() {
20
- return `https://${C() ? "testnet-" : ""}explorer.nexa.org`;
24
+ function de() {
25
+ return `https://${E() ? "testnet-" : ""}explorer.nexa.org`;
21
26
  }
22
- function J() {
23
- return Math.floor(Date.now() / 1e3);
27
+ function O() {
28
+ return Math.floor(Date.now() / 1e3);
24
29
  }
25
- function vt(a, e) {
26
- const t = (e - a) * 2, s = /* @__PURE__ */ new Date();
27
- return s.setMinutes(s.getMinutes() + t), s.toLocaleDateString();
30
+ function fe(e, t) {
31
+ let n = (t - e) * 2, r = /* @__PURE__ */ new Date();
32
+ return r.setMinutes(r.getMinutes() + n), r.toLocaleDateString();
28
33
  }
29
- function M(a) {
30
- return !a || a.length === 0;
34
+ function k(e) {
35
+ return !e || e.length === 0;
31
36
  }
32
- function bt(a, e = 0) {
33
- if (!a || a.length <= e)
34
- return a || "";
35
- const t = "...", s = Math.floor((e - t.length) / 2), n = a.slice(0, s), i = a.slice(a.length - s);
36
- return n + t + i;
37
+ function pe(e, t = 0) {
38
+ if (!e || e.length <= t) return e || "";
39
+ let n = Math.floor((t - 3) / 2), r = e.slice(0, n), i = e.slice(e.length - n);
40
+ return r + "..." + i;
37
41
  }
38
- function St(a) {
39
- return a.length === 0 ? "" : a.charAt(0).toUpperCase() + a.substring(1);
42
+ function me(e) {
43
+ return e.length === 0 ? "" : e.charAt(0).toUpperCase() + e.substring(1);
40
44
  }
41
- function ae(a) {
42
- return W.isHexa(a) ? m.hexToBuffer(a) : I.fromString(a).data;
45
+ function A(t) {
46
+ return a.isHexa(t) ? r.hexToBuffer(t) : e.fromString(t).data;
43
47
  }
44
- function v(a) {
45
- return W.isHexa(a) ? a : m.bufferToHex(ae(a));
48
+ function j(e) {
49
+ return a.isHexa(e) ? e : r.bufferToHex(A(e));
46
50
  }
47
- function kt(a) {
48
- return W.isHexa(a) ? new I(ae(a), E.defaultNetwork, O.GroupIdAddress).toString() : a;
51
+ function he(n) {
52
+ return a.isHexa(n) ? new e(A(n), c.defaultNetwork, t.GroupIdAddress).toString() : n;
49
53
  }
50
- function U(a) {
51
- return a == null || a === "" ? "" : BigInt(a) <= 0n ? "0" : a.toString();
54
+ function M(e) {
55
+ return e == null || e === "" ? "" : BigInt(e) <= 0n ? "0" : e.toString();
52
56
  }
53
- function ee(a) {
54
- let e = BigInt(0), t = BigInt(0);
55
- return a.forEach((s) => {
56
- e += BigInt(s.confirmed), t += BigInt(s.unconfirmed);
57
- }), { confirmed: e.toString(), unconfirmed: t.toString() };
57
+ function N(e) {
58
+ let t = BigInt(0), n = BigInt(0);
59
+ return e.forEach((e) => {
60
+ t += BigInt(e.confirmed), n += BigInt(e.unconfirmed);
61
+ }), {
62
+ confirmed: t.toString(),
63
+ unconfirmed: n.toString()
64
+ };
58
65
  }
59
- function K(a) {
60
- const e = {};
61
- return a.forEach((t) => {
62
- for (const s in t)
63
- e[s] ? (e[s].confirmed = (BigInt(e[s].confirmed) + BigInt(t[s].confirmed)).toString(), e[s].unconfirmed = (BigInt(e[s].unconfirmed) + BigInt(t[s].unconfirmed)).toString()) : e[s] = { confirmed: BigInt(t[s].confirmed).toString(), unconfirmed: BigInt(t[s].unconfirmed).toString() };
64
- }), e;
66
+ function P(e) {
67
+ let t = {};
68
+ return e.forEach((e) => {
69
+ for (let n in e) t[n] ? (t[n].confirmed = (BigInt(t[n].confirmed) + BigInt(e[n].confirmed)).toString(), t[n].unconfirmed = (BigInt(t[n].unconfirmed) + BigInt(e[n].unconfirmed)).toString()) : t[n] = {
70
+ confirmed: BigInt(e[n].confirmed).toString(),
71
+ unconfirmed: BigInt(e[n].unconfirmed).toString()
72
+ };
73
+ }), t;
65
74
  }
66
- const ne = {
67
- // Images
68
- //'.svg': { media: 'image', mime: 'image/svg+xml' },
69
- ".gif": { media: "image", mime: "image/gif" },
70
- ".png": { media: "image", mime: "image/png" },
71
- ".apng": { media: "image", mime: "image/apng" },
72
- ".jpg": { media: "image", mime: "image/jpeg" },
73
- ".jpeg": { media: "image", mime: "image/jpeg" },
74
- ".avif": { media: "image", mime: "image/avif" },
75
- ".webp": { media: "image", mime: "image/webp" },
76
- ".bmp": { media: "image", mime: "image/bmp" },
77
- // Videos
78
- ".mp4": { media: "video", mime: "video/mp4" },
79
- ".mpeg": { media: "video", mime: "video/mpeg" },
80
- ".mpg": { media: "video", mime: "video/mpeg" },
81
- ".webm": { media: "video", mime: "video/webm" },
82
- ".mov": { media: "video", mime: "video/quicktime" },
83
- // Audio
84
- ".mp3": { media: "audio", mime: "audio/mpeg" },
85
- ".ogg": { media: "audio", mime: "audio/ogg" },
86
- ".wav": { media: "audio", mime: "audio/wav" },
87
- ".m4a": { media: "audio", mime: "audio/mp4" }
75
+ var F = {
76
+ ".gif": {
77
+ media: "image",
78
+ mime: "image/gif"
79
+ },
80
+ ".png": {
81
+ media: "image",
82
+ mime: "image/png"
83
+ },
84
+ ".apng": {
85
+ media: "image",
86
+ mime: "image/apng"
87
+ },
88
+ ".jpg": {
89
+ media: "image",
90
+ mime: "image/jpeg"
91
+ },
92
+ ".jpeg": {
93
+ media: "image",
94
+ mime: "image/jpeg"
95
+ },
96
+ ".avif": {
97
+ media: "image",
98
+ mime: "image/avif"
99
+ },
100
+ ".webp": {
101
+ media: "image",
102
+ mime: "image/webp"
103
+ },
104
+ ".bmp": {
105
+ media: "image",
106
+ mime: "image/bmp"
107
+ },
108
+ ".mp4": {
109
+ media: "video",
110
+ mime: "video/mp4"
111
+ },
112
+ ".mpeg": {
113
+ media: "video",
114
+ mime: "video/mpeg"
115
+ },
116
+ ".mpg": {
117
+ media: "video",
118
+ mime: "video/mpeg"
119
+ },
120
+ ".webm": {
121
+ media: "video",
122
+ mime: "video/webm"
123
+ },
124
+ ".mov": {
125
+ media: "video",
126
+ mime: "video/quicktime"
127
+ },
128
+ ".mp3": {
129
+ media: "audio",
130
+ mime: "audio/mpeg"
131
+ },
132
+ ".ogg": {
133
+ media: "audio",
134
+ mime: "audio/ogg"
135
+ },
136
+ ".wav": {
137
+ media: "audio",
138
+ mime: "audio/wav"
139
+ },
140
+ ".m4a": {
141
+ media: "audio",
142
+ mime: "audio/mp4"
143
+ }
88
144
  };
89
- function Tt(a) {
90
- const e = a.lastIndexOf(".");
91
- if (e === -1) return "unknown";
92
- const t = a.slice(e).toLowerCase();
93
- return ne[t]?.media ?? "unknown";
94
- }
95
- function It(a) {
96
- const e = a.lastIndexOf(".");
97
- if (e === -1) return "application/octet-stream";
98
- const t = a.slice(e).toLowerCase();
99
- return ne[t]?.mime ?? "application/octet-stream";
100
- }
101
- function xt(a) {
102
- return new Promise((e) => setTimeout(e, a));
103
- }
104
- function Nt(a) {
105
- let e = B.getPrettyValue(a);
106
- return e.match(/\./) && (e = e.replace(/\.?0+$/, "")), e;
107
- }
108
- class Mt {
109
- getPrefix() {
110
- return C() ? "testnet-" : "";
111
- }
112
- async getEncryptedSeed() {
113
- return this.getValue("seed");
114
- }
115
- async saveEncryptedSeed(e) {
116
- return this.setValue("seed", e);
117
- }
118
- async getVersionCode() {
119
- return this.getValue("version-code");
120
- }
121
- async setVersionCode(e) {
122
- return this.setValue("version-code", e);
123
- }
124
- async getReleaseNumber() {
125
- return this.getValue("release-number");
126
- }
127
- async setReleaseNumber(e) {
128
- return this.setValue("release-number", e);
129
- }
130
- async getRostrumParams() {
131
- const e = await this.getValue(this.getPrefix() + "rostrum-params");
132
- if (e)
133
- return JSON.parse(e);
134
- }
135
- async saveRostrumParams(e) {
136
- return this.setValue(this.getPrefix() + "rostrum-params", JSON.stringify(e));
137
- }
138
- async removeRostrumParams() {
139
- return this.removeValue(this.getPrefix() + "rostrum-params");
140
- }
141
- async setHideZeroTokenConfig(e) {
142
- return this.setValue("zero-tokens", JSON.stringify(e));
143
- }
144
- async getHideZeroTokenConfig() {
145
- return await this.getValue("zero-tokens") === "true";
146
- }
147
- async setHideZeroVaultsConfig(e) {
148
- return this.setValue("zero-vaults", JSON.stringify(e));
149
- }
150
- async getHideZeroVaultsConfig() {
151
- return await this.getValue("zero-vaults") === "true";
152
- }
153
- async getSelectedCurrency() {
154
- return await this.getValue("selectedCurrency") || "usd";
155
- }
156
- async setSelectedCurrency(e) {
157
- return this.setValue("selectedCurrency", e);
158
- }
159
- async getUseBiometric() {
160
- return await this.getValue("biometrics") === "true";
161
- }
162
- async setUseBiometric(e) {
163
- return this.setValue("biometrics", JSON.stringify(e));
164
- }
165
- async getRequireAuth() {
166
- const e = await this.getValue("auth");
167
- return M(e) || e === "true";
168
- }
169
- async setRequireAuth(e) {
170
- await this.setValue("auth", JSON.stringify(e));
171
- }
172
- async getReleaseNotesTime() {
173
- const e = await this.getValue("show-notes");
174
- return e ? Number(e) : void 0;
175
- }
176
- async setReleaseNotesTime(e) {
177
- M(e) ? await this.removeValue("show-notes") : await this.setValue("show-notes", e);
178
- }
179
- async getIsTestnet() {
180
- return await this.getValue("testnet") === "1";
181
- }
182
- async setIsTestnet(e) {
183
- await this.setValue("testnet", e ? "1" : "0");
184
- }
185
- async getAutoLockSeconds() {
186
- const e = await this.getValue("auto-lock");
187
- return e ? parseInt(e) : 60;
188
- }
189
- async setAutoLockSeconds(e) {
190
- await this.setValue("auto-lock", `${e}`);
191
- }
192
- }
193
- var h = /* @__PURE__ */ ((a) => (a[a.MAIN = 0] = "MAIN", a[a.VAULT = 1] = "VAULT", a[a.DAPP = 2] = "DAPP", a))(h || {}), y = /* @__PURE__ */ ((a) => (a[a.RECEIVE = 0] = "RECEIVE", a[a.CHANGE = 1] = "CHANGE", a))(y || {}), N = /* @__PURE__ */ ((a) => (a.SignMessage = "signMessage", a.AddToken = "addToken", a.SignTransaction = "signTransaction", a.SendTransaction = "sendTransaction", a))(N || {});
194
- class Et {
195
- store;
196
- updateCallback;
197
- constructor(e) {
198
- this.store = e;
199
- }
200
- onUpdate(e) {
201
- this.updateCallback = e;
202
- }
203
- notify(e) {
204
- this.updateCallback?.(e);
205
- }
206
- async initSchema() {
207
- return this.store.initSchema();
208
- }
209
- async clearData() {
210
- return this.store.clearData();
211
- }
212
- async addLocalTransaction(e) {
213
- try {
214
- await this.store.upsertTransaction(e), this.notify({ type: "tx_refresh" });
215
- } catch (t) {
216
- console.error(t);
217
- }
218
- }
219
- async addAssetTransaction(e) {
220
- return this.store.upsertAssetTransaction(e);
221
- }
222
- async getLocalTransactions(e, t) {
223
- return this.store.getTransactions(e, t);
224
- }
225
- async getPageLocalTransactions(e, t, s, n) {
226
- return this.store.getPageTransactions(e, t, s, n);
227
- }
228
- async countLocalTransactions(e, t) {
229
- return this.store.countTransactions(e, t);
230
- }
231
- async clearLocalTransactions(e) {
232
- await this.store.clearTransactions(e), this.notify({ type: "tx_refresh" });
233
- }
234
- async saveToken(e, t) {
235
- const s = {
236
- accountId: e,
237
- tokenIdHex: t.tokenIdHex,
238
- type: "token",
239
- addedTime: J()
240
- };
241
- await this.store.upsertToken(t), await this.saveAsset(s), this.notify({ type: "token_refresh" });
242
- }
243
- async getLocalTokens(e, t, s) {
244
- return this.store.getTokens(e, t, s);
245
- }
246
- async getToken(e) {
247
- return this.store.getToken(e);
248
- }
249
- async deleteToken(e, t) {
250
- await this.removeAsset(e, t), await this.store.countAssetsById(t) == 0 && await this.store.deleteToken(t), this.notify({ type: "token_refresh" });
251
- }
252
- async saveNft(e, t, s) {
253
- const n = {
254
- accountId: e,
255
- tokenIdHex: t.tokenIdHex,
256
- type: "nft",
257
- addedTime: s
258
- };
259
- await this.store.upsertNft(t), await this.saveAsset(n), this.notify({ type: "nft_refresh" });
260
- }
261
- async getLocalNfts(e, t, s) {
262
- return this.store.getNfts(e, t, s);
263
- }
264
- async getLocalNft(e) {
265
- return this.store.getNft(e);
266
- }
267
- async deleteNft(e, t) {
268
- await this.removeAsset(e, t), await this.store.countAssetsById(t) == 0 && await this.store.deleteNft(t), this.notify({ type: "nft_refresh" });
269
- }
270
- async countLocalNfts(e) {
271
- return this.store.countNfts(e);
272
- }
273
- async getAssets(e, t) {
274
- return this.store.getAssets(e, t);
275
- }
276
- async saveAsset(e) {
277
- await this.store.upsertAsset(e);
278
- }
279
- async removeAsset(e, t) {
280
- return this.store.deleteAsset(e, t);
281
- }
282
- async saveAccount(e) {
283
- const t = {
284
- id: e.id,
285
- address: e.address,
286
- name: e.name,
287
- height: e.height,
288
- hidden: e.hidden,
289
- statusHash: e.statusHash,
290
- balance: JSON.stringify(e.balance),
291
- tokensBalance: JSON.stringify(e.tokensBalance)
292
- };
293
- return this.store.upsertAccount(t);
294
- }
295
- async getAccounts() {
296
- return (await this.store.getAccounts()).map((t) => ({
297
- ...t,
298
- type: h.DAPP,
299
- balance: JSON.parse(t.balance),
300
- tokensBalance: JSON.parse(t.tokensBalance)
301
- }));
302
- }
303
- async countAccounts() {
304
- return this.store.countAccounts();
305
- }
306
- async updateAccountName(e, t) {
307
- return this.store.updateAccountName(e, t);
308
- }
309
- async saveSession(e) {
310
- return this.store.upsertSession(e);
311
- }
312
- async getAccountSessions(e) {
313
- return this.store.getSessionsByAccount(e);
314
- }
315
- async removeSession(e) {
316
- return this.store.deleteSession(e);
317
- }
318
- async saveAddress(e) {
319
- const t = {
320
- address: e.address,
321
- idx: e.idx,
322
- space: e.space,
323
- height: e.height,
324
- statusHash: e.statusHash,
325
- used: e.used,
326
- balance: JSON.stringify(e.balance),
327
- tokensBalance: JSON.stringify(e.tokensBalance)
328
- };
329
- return this.store.upsertAddress(t);
330
- }
331
- async getReceiveAddresses() {
332
- return (await this.store.getReceiveAddresses()).map((t) => ({
333
- ...t,
334
- type: h.MAIN,
335
- balance: JSON.parse(t.balance),
336
- tokensBalance: JSON.parse(t.tokensBalance)
337
- }));
338
- }
339
- async getChangeAddresses() {
340
- return (await this.store.getChangeAddresses()).map((t) => ({
341
- ...t,
342
- type: h.MAIN,
343
- balance: JSON.parse(t.balance),
344
- tokensBalance: JSON.parse(t.tokensBalance)
345
- }));
346
- }
347
- async countAddresses() {
348
- return this.store.countAddresses();
349
- }
350
- async getVaults() {
351
- return (await this.store.getVaults()).map((t) => ({
352
- ...t,
353
- type: h.VAULT,
354
- balance: JSON.parse(t.balance),
355
- tokensBalance: JSON.parse(t.tokensBalance)
356
- }));
357
- }
358
- async saveVault(e) {
359
- const t = {
360
- address: e.address,
361
- idx: e.idx,
362
- block: e.block,
363
- height: e.height,
364
- statusHash: e.statusHash,
365
- balance: JSON.stringify(e.balance),
366
- tokensBalance: JSON.stringify(e.tokensBalance)
367
- };
368
- return this.store.upsertVault(t);
369
- }
370
- }
371
- class Ct {
372
- walletDb;
373
- tokens = /* @__PURE__ */ new Map();
374
- nfts = /* @__PURE__ */ new Map();
375
- constructor(e) {
376
- this.walletDb = e;
377
- }
378
- clear() {
379
- this.tokens.clear(), this.nfts.clear();
380
- }
381
- hasToken(e) {
382
- return e = v(e), this.tokens.has(e);
383
- }
384
- hasNft(e) {
385
- return e = v(e), this.nfts.has(e);
386
- }
387
- async getToken(e) {
388
- if (e = v(e), this.tokens.has(e))
389
- return this.tokens.get(e);
390
- const t = await this.walletDb.getToken(e);
391
- return t && this.tokens.set(e, t), t;
392
- }
393
- async getNft(e) {
394
- if (e = v(e), this.nfts.has(e))
395
- return this.nfts.get(e);
396
- const t = await this.walletDb.getLocalNft(e);
397
- return t && this.nfts.set(e, t), t;
398
- }
399
- removeToken(e) {
400
- this.tokens.delete(v(e));
401
- }
402
- removeNft(e) {
403
- this.nfts.delete(v(e));
404
- }
405
- }
406
- class ie {
407
- kvStore;
408
- client;
409
- constructor(e) {
410
- this.kvStore = e;
411
- }
412
- getFeatures() {
413
- return this.execute("server.features");
414
- }
415
- getBlockTip() {
416
- return this.execute("blockchain.headers.tip");
417
- }
418
- getBalance(e) {
419
- return this.execute("blockchain.address.get_balance", e, "exclude_tokens");
420
- }
421
- getTransactionsHistory(e, t = 0) {
422
- return this.execute("blockchain.address.get_history", e, { from_height: t });
423
- }
424
- getFirstUse(e) {
425
- return this.execute("blockchain.address.get_first_use", e);
426
- }
427
- async isAddressUsed(e) {
428
- try {
429
- const t = await this.getFirstUse(e);
430
- return !!(t.tx_hash && t.tx_hash !== "");
431
- } catch (t) {
432
- if (t instanceof Error && t.message.includes("not found"))
433
- return !1;
434
- throw t;
435
- }
436
- }
437
- getTransaction(e, t = !0) {
438
- return this.execute("blockchain.transaction.get", e, t);
439
- }
440
- getUtxo(e) {
441
- return this.execute("blockchain.utxo.get", e);
442
- }
443
- getNexaUtxos(e) {
444
- return this.execute("blockchain.address.listunspent", e, "exclude_tokens");
445
- }
446
- async getTokenUtxos(e, t) {
447
- return (await this.execute("token.address.listunspent", e, null, t)).unspent;
448
- }
449
- async getTokensBalance(e) {
450
- const t = await this.execute("token.address.get_balance", e), s = {};
451
- for (const n in t.confirmed)
452
- t.confirmed[n] != 0 && (s[n] = { confirmed: BigInt(t.confirmed[n]).toString(), unconfirmed: "0" });
453
- for (const n in t.unconfirmed)
454
- t.unconfirmed[n] != 0 && (s[n] ? s[n].unconfirmed = BigInt(t.unconfirmed[n]).toString() : s[n] = { confirmed: "0", unconfirmed: BigInt(t.unconfirmed[n]).toString() });
455
- return s;
456
- }
457
- getTokenGenesis(e) {
458
- return this.execute("token.genesis.info", e);
459
- }
460
- broadcast(e) {
461
- return this.execute("blockchain.transaction.broadcast", e);
462
- }
463
- subscribeHeaders(e) {
464
- return this.client.subscribe((t) => {
465
- const s = Array.isArray(t) ? t[0] : t, n = typeof s?.height == "number" ? s.height : 0;
466
- e(n);
467
- }, "blockchain.headers.subscribe");
468
- }
469
- subscribeAddress(e, t) {
470
- return this.client.subscribe(t, "blockchain.address.subscribe", e);
471
- }
472
- async getLatency() {
473
- try {
474
- const e = Date.now();
475
- return await this.getBlockTip() ? Date.now() - e : 0;
476
- } catch {
477
- return 0;
478
- }
479
- }
480
- async connect(e) {
481
- try {
482
- e || (e = await this.getCurrentInstance()), this.client = new be("com.otoplo.wallet", "1.4.3", e.host, e.port, e.scheme, 45 * 1e3, 10 * 1e3), await this.client.connect();
483
- } catch (t) {
484
- throw t instanceof Error ? console.info(t.message) : console.error(t), t;
485
- }
486
- }
487
- async disconnect(e) {
488
- try {
489
- return await this.client?.disconnect(e) ?? !1;
490
- } catch (t) {
491
- return console.error(t), !1;
492
- }
493
- }
494
- async execute(e, ...t) {
495
- await this.waitForConnection();
496
- const s = await this.client.request(e, ...t);
497
- if (s instanceof Error)
498
- throw s;
499
- return s;
500
- }
501
- waitForConnection(e = 5e3) {
502
- const t = Date.now();
503
- return new Promise((s, n) => {
504
- const i = () => {
505
- if (this.client?.connectionStatus == Se.CONNECTED)
506
- return s();
507
- if (Date.now() - t > e)
508
- return n(new Error("Rostrum Connection timeout"));
509
- setTimeout(i, 250);
510
- };
511
- i();
512
- });
513
- }
514
- async getCurrentInstance() {
515
- const e = await this.kvStore.getRostrumParams();
516
- return e || ie.getPredefinedInstances()[0];
517
- }
518
- static getPredefinedInstances() {
519
- return C() ? [
520
- {
521
- scheme: H.WSS,
522
- host: "testnet-electrum.nexa.org",
523
- port: 30004,
524
- label: "NexaOrg"
525
- }
526
- ] : [
527
- {
528
- scheme: H.WSS,
529
- host: "rostrum.otoplo.com",
530
- port: 443,
531
- label: "Otoplo"
532
- },
533
- {
534
- scheme: H.WSS,
535
- host: "electrum.nexa.org",
536
- port: 20004,
537
- label: "NexaOrg"
538
- }
539
- ];
540
- }
541
- }
542
- function k(a, e, t) {
543
- return `${a}'/${e}/${t}`;
544
- }
545
- function Ce(a) {
546
- const e = a.split("/");
547
- return {
548
- account: parseInt(e[0].replace("'", "")),
549
- type: parseInt(e[1]),
550
- index: parseInt(e[2])
551
- };
145
+ function ge(e) {
146
+ let t = e.lastIndexOf(".");
147
+ return t === -1 ? "unknown" : F[e.slice(t).toLowerCase()]?.media ?? "unknown";
552
148
  }
553
- class Pt {
554
- seed;
555
- masterKey;
556
- accountKeys = /* @__PURE__ */ new Map();
557
- walletKeys = /* @__PURE__ */ new Map();
558
- init(e) {
559
- this.seed = typeof e == "string" ? ke(e) : e, this.masterKey = j.fromSeed(this.seed).deriveChild(44, !0).deriveChild(29223, !0);
560
- }
561
- reset() {
562
- if (!this.seed)
563
- throw new Error("KeysManager not initialized");
564
- this.masterKey = j.fromSeed(this.seed).deriveChild(44, !0).deriveChild(29223, !0), this.accountKeys.clear(), this.walletKeys.clear();
565
- }
566
- getAccountKey(e) {
567
- let t = this.accountKeys.get(e);
568
- return t || (t = this.masterKey.deriveChild(e, !0), this.accountKeys.set(e, t)), t;
569
- }
570
- getKey(e) {
571
- const t = typeof e == "string" ? e : k(e.account, e.type, e.index);
572
- let s = this.walletKeys.get(t);
573
- if (!s) {
574
- const { account: n, type: i, index: o } = typeof e == "string" ? Ce(e) : e;
575
- s = this.getAccountKey(n).deriveChild(i, !1).deriveChild(o, !1), this.walletKeys.set(t, s);
576
- }
577
- return s;
578
- }
149
+ function _e(e) {
150
+ let t = e.lastIndexOf(".");
151
+ return t === -1 ? "application/octet-stream" : F[e.slice(t).toLowerCase()]?.mime ?? "application/octet-stream";
579
152
  }
580
- function Bt(a, e) {
581
- return a && typeof a == "string" ? a.startsWith("http") ? a.replace("http://", "https://") : a.startsWith("ipfs://") ? a : `${new URL(e).origin}${a}` : "";
153
+ function ve(e) {
154
+ return new Promise((t) => setTimeout(t, e));
582
155
  }
583
- function Ot(a) {
584
- return a ? Pe(a) : null;
156
+ function ye(e) {
157
+ let t = y.getPrettyValue(e);
158
+ return t.match(/\./) && (t = t.replace(/\.?0+$/, "")), t;
585
159
  }
586
- function Pe(a, e = "https://ipfs.nebula.markets/") {
587
- return a?.startsWith("ipfs://") ? e + a.substring(7) : a;
588
- }
589
- function Be(a) {
590
- return Oe(`${re()}/metadata/${a}`, "json");
591
- }
592
- function _t(a, e) {
593
- return `${re()}/assets/${a}/${e}`;
594
- }
595
- function re() {
596
- return `https://${C() ? "testapi" : "api"}.otoplo.com`;
597
- }
598
- async function Oe(a, e) {
599
- try {
600
- const t = await fetch(a);
601
- if (!t.ok)
602
- throw new Error(`Failed to perform GET. status: ${t.status}`);
603
- if (e !== "raw") return await t.json();
604
- } catch (t) {
605
- throw new Error(`Unexpected Error: ${t}`);
606
- }
607
- }
608
- class Ut {
609
- walletDb;
610
- walletCache;
611
- constructor(e, t) {
612
- this.walletDb = e, this.walletCache = t;
613
- }
614
- async getAssetInfo(e) {
615
- try {
616
- if (this.walletCache.hasToken(e)) {
617
- const t = await this.walletCache.getToken(e);
618
- return {
619
- type: "token",
620
- parent: t.parent,
621
- token: t.token,
622
- tokenIdHex: t.tokenIdHex,
623
- data: {
624
- name: t.name,
625
- ticker: t.ticker,
626
- decimals: t.decimals,
627
- iconUrl: t.iconUrl
628
- }
629
- };
630
- }
631
- if (this.walletCache.hasNft(e)) {
632
- const t = await this.walletCache.getNft(e);
633
- return {
634
- type: "nft",
635
- parent: t.parent,
636
- token: t.token,
637
- tokenIdHex: t.tokenIdHex,
638
- data: {
639
- name: t.name,
640
- series: t.series,
641
- collection: t.collection,
642
- author: t.author,
643
- public: t.public,
644
- front: t.front,
645
- back: t.back
646
- }
647
- };
648
- }
649
- return await Be(e);
650
- } catch (t) {
651
- console.error(t);
652
- return;
653
- }
654
- }
655
- async handleNftReceive(e, t, s) {
656
- const n = await this.getAssetInfo(t);
657
- if (n && n.type == "nft") {
658
- const i = {
659
- token: n.token,
660
- tokenIdHex: n.tokenIdHex,
661
- parent: n.parent,
662
- ...n.data
663
- };
664
- await this.walletDb.saveNft(e, i, s);
665
- }
666
- }
667
- async syncTokens(e, t) {
668
- for (const s in t) {
669
- const n = t[s];
670
- if (n && BigInt(n.confirmed) + BigInt(n.unconfirmed) > 0n) {
671
- const i = await this.getAssetInfo(s);
672
- if (i && i.type == "token") {
673
- const o = {
674
- token: i.token,
675
- tokenIdHex: i.tokenIdHex,
676
- parent: i.parent,
677
- ...i.data
678
- };
679
- await this.walletDb.saveToken(e, o);
680
- }
681
- }
682
- }
683
- }
684
- async syncNfts(e, t) {
685
- const s = Object.keys(t), n = await this.walletDb.getAssets(e, "nft"), i = n?.filter((o) => !s.includes(o.tokenIdHex)) ?? [];
686
- for (const o of i)
687
- await this.deleteNft(e, o.tokenIdHex);
688
- for (const [o, r] of Object.entries(t)) {
689
- const c = v(o), d = r && BigInt(r.confirmed) + BigInt(r.unconfirmed) > 0n, u = n?.some((l) => l.tokenIdHex == c);
690
- !d && !u || d && u || (!d && u ? await this.deleteNft(e, c) : await this.handleNftReceive(e, c, J()));
691
- }
692
- }
693
- async deleteToken(e, t) {
694
- await this.walletDb.deleteToken(e, t), this.walletCache.removeToken(t);
695
- }
696
- async deleteNft(e, t) {
697
- await this.walletDb.deleteNft(e, t), this.walletCache.removeNft(t);
698
- }
160
+ // src/persistence/wallet-db.ts
161
+ var be = class {
162
+ constructor(e) {
163
+ this.repository = e;
164
+ }
165
+ initSchema() {
166
+ return this.repository.initSchema();
167
+ }
168
+ clearData() {
169
+ return this.repository.clearData();
170
+ }
171
+ upsertTransaction(e) {
172
+ let t = {
173
+ ...e,
174
+ othersOutputs: JSON.stringify(e.othersOutputs),
175
+ myOutputs: JSON.stringify(e.myOutputs),
176
+ myInputs: JSON.stringify(e.myInputs)
177
+ };
178
+ return this.repository.upsertTransaction(t);
179
+ }
180
+ upsertAssetTransaction(e) {
181
+ return this.repository.upsertAssetTransaction(e);
182
+ }
183
+ async getTransactions(e, t) {
184
+ return (await this.repository.getTransactions(e, t)).map((e) => ({
185
+ ...e,
186
+ othersOutputs: JSON.parse(e.othersOutputs),
187
+ myOutputs: JSON.parse(e.myOutputs),
188
+ myInputs: JSON.parse(e.myInputs)
189
+ }));
190
+ }
191
+ async getPageTransactions(e, t, n, r) {
192
+ return (await this.repository.getPageTransactions(e, t, n, r)).map((e) => ({
193
+ ...e,
194
+ othersOutputs: JSON.parse(e.othersOutputs),
195
+ myOutputs: JSON.parse(e.myOutputs),
196
+ myInputs: JSON.parse(e.myInputs)
197
+ }));
198
+ }
199
+ countTransactions(e, t) {
200
+ return this.repository.countTransactions(e, t);
201
+ }
202
+ clearTransactions(e) {
203
+ return this.repository.clearTransactions(e);
204
+ }
205
+ async saveToken(e, t) {
206
+ let n = {
207
+ accountId: e,
208
+ tokenIdHex: t.tokenIdHex,
209
+ type: "token",
210
+ addedTime: O()
211
+ };
212
+ await this.repository.upsertToken(t), await this.saveAsset(n);
213
+ }
214
+ getTokens(e, t, n) {
215
+ return this.repository.getTokens(e, t, n);
216
+ }
217
+ getToken(e) {
218
+ return this.repository.getToken(e);
219
+ }
220
+ async deleteToken(e, t) {
221
+ await this.removeAsset(e, t), await this.repository.countAssetsById(t) == 0 && await this.repository.deleteToken(t);
222
+ }
223
+ async saveNft(e, t, n) {
224
+ let r = {
225
+ accountId: e,
226
+ tokenIdHex: t.tokenIdHex,
227
+ type: "nft",
228
+ addedTime: n
229
+ };
230
+ await this.repository.upsertNft(t), await this.saveAsset(r);
231
+ }
232
+ getNfts(e, t, n) {
233
+ return this.repository.getNfts(e, t, n);
234
+ }
235
+ getNft(e) {
236
+ return this.repository.getNft(e);
237
+ }
238
+ async deleteNft(e, t) {
239
+ await this.removeAsset(e, t), await this.repository.countAssetsById(t) == 0 && await this.repository.deleteNft(t);
240
+ }
241
+ countNfts(e) {
242
+ return this.repository.countNfts(e);
243
+ }
244
+ getAssets(e, t) {
245
+ return this.repository.getAssets(e, t);
246
+ }
247
+ saveAsset(e) {
248
+ return this.repository.upsertAsset(e);
249
+ }
250
+ removeAsset(e, t) {
251
+ return this.repository.deleteAsset(e, t);
252
+ }
253
+ saveAccount(e) {
254
+ let t = {
255
+ id: e.id,
256
+ address: e.address,
257
+ name: e.name,
258
+ height: e.height,
259
+ hidden: e.hidden,
260
+ statusHash: e.statusHash,
261
+ balance: JSON.stringify(e.balance),
262
+ tokensBalance: JSON.stringify(e.tokensBalance)
263
+ };
264
+ return this.repository.upsertAccount(t);
265
+ }
266
+ async getAccounts() {
267
+ return (await this.repository.getAccounts()).map((e) => ({
268
+ ...e,
269
+ type: S.DAPP,
270
+ balance: JSON.parse(e.balance),
271
+ tokensBalance: JSON.parse(e.tokensBalance)
272
+ }));
273
+ }
274
+ countAccounts() {
275
+ return this.repository.countAccounts();
276
+ }
277
+ updateAccountName(e, t) {
278
+ return this.repository.updateAccountName(e, t);
279
+ }
280
+ saveSession(e) {
281
+ return this.repository.upsertSession(e);
282
+ }
283
+ getAccountSessions(e) {
284
+ return this.repository.getSessionsByAccount(e);
285
+ }
286
+ removeSession(e) {
287
+ return this.repository.deleteSession(e);
288
+ }
289
+ saveAddress(e) {
290
+ let t = {
291
+ address: e.address,
292
+ idx: e.idx,
293
+ space: e.space,
294
+ height: e.height,
295
+ statusHash: e.statusHash,
296
+ used: e.used,
297
+ balance: JSON.stringify(e.balance),
298
+ tokensBalance: JSON.stringify(e.tokensBalance)
299
+ };
300
+ return this.repository.upsertAddress(t);
301
+ }
302
+ async getReceiveAddresses() {
303
+ return (await this.repository.getReceiveAddresses()).map((e) => ({
304
+ ...e,
305
+ type: S.MAIN,
306
+ balance: JSON.parse(e.balance),
307
+ tokensBalance: JSON.parse(e.tokensBalance)
308
+ }));
309
+ }
310
+ async getChangeAddresses() {
311
+ return (await this.repository.getChangeAddresses()).map((e) => ({
312
+ ...e,
313
+ type: S.MAIN,
314
+ balance: JSON.parse(e.balance),
315
+ tokensBalance: JSON.parse(e.tokensBalance)
316
+ }));
317
+ }
318
+ countAddresses() {
319
+ return this.repository.countAddresses();
320
+ }
321
+ async getVaults() {
322
+ return (await this.repository.getVaults()).map((e) => ({
323
+ ...e,
324
+ type: S.VAULT,
325
+ balance: JSON.parse(e.balance),
326
+ tokensBalance: JSON.parse(e.tokensBalance)
327
+ }));
328
+ }
329
+ saveVault(e) {
330
+ let t = {
331
+ address: e.address,
332
+ idx: e.idx,
333
+ block: e.block,
334
+ height: e.height,
335
+ statusHash: e.statusHash,
336
+ balance: JSON.stringify(e.balance),
337
+ tokensBalance: JSON.stringify(e.tokensBalance)
338
+ };
339
+ return this.repository.upsertVault(t);
340
+ }
341
+ getSetting(e) {
342
+ return this.repository.getSetting(e);
343
+ }
344
+ saveSetting(e, t) {
345
+ return this.repository.saveSetting(e, t);
346
+ }
347
+ removeSetting(e) {
348
+ return this.repository.deleteSetting(e);
349
+ }
350
+ }, xe = class {
351
+ constructor(e) {
352
+ this.tokens = /* @__PURE__ */ new Map(), this.nfts = /* @__PURE__ */ new Map(), this.walletDb = e;
353
+ }
354
+ clear() {
355
+ this.tokens.clear(), this.nfts.clear();
356
+ }
357
+ async getToken(e) {
358
+ if (e = j(e), this.tokens.has(e)) return this.tokens.get(e);
359
+ let t = await this.walletDb.getToken(e);
360
+ return t && this.tokens.set(e, t), t;
361
+ }
362
+ async getNft(e) {
363
+ if (e = j(e), this.nfts.has(e)) return this.nfts.get(e);
364
+ let t = await this.walletDb.getNft(e);
365
+ return t && this.nfts.set(e, t), t;
366
+ }
367
+ removeToken(e) {
368
+ this.tokens.delete(j(e));
369
+ }
370
+ removeNft(e) {
371
+ this.nfts.delete(j(e));
372
+ }
373
+ }, Se = class e {
374
+ constructor(e) {
375
+ this.walletDb = e;
376
+ }
377
+ getFeatures() {
378
+ return this.execute("server.features");
379
+ }
380
+ getBlockTip() {
381
+ return this.execute("blockchain.headers.tip");
382
+ }
383
+ getBalance(e) {
384
+ return this.execute("blockchain.address.get_balance", e, "exclude_tokens");
385
+ }
386
+ getTransactionsHistory(e, t = 0) {
387
+ return this.execute("blockchain.address.get_history", e, { from_height: t });
388
+ }
389
+ getFirstUse(e) {
390
+ return this.execute("blockchain.address.get_first_use", e);
391
+ }
392
+ async isAddressUsed(e) {
393
+ try {
394
+ let t = await this.getFirstUse(e);
395
+ return !!(t.tx_hash && t.tx_hash !== "");
396
+ } catch (e) {
397
+ if (e instanceof Error && e.message.includes("not found")) return !1;
398
+ throw e;
399
+ }
400
+ }
401
+ getTransaction(e, t = !0) {
402
+ return this.execute("blockchain.transaction.get", e, t);
403
+ }
404
+ getUtxo(e) {
405
+ return this.execute("blockchain.utxo.get", e);
406
+ }
407
+ getNexaUtxos(e) {
408
+ return this.execute("blockchain.address.listunspent", e, "exclude_tokens");
409
+ }
410
+ async getTokenUtxos(e, t) {
411
+ return (await this.execute("token.address.listunspent", e, null, t)).unspent;
412
+ }
413
+ async getTokensBalance(e) {
414
+ let t = await this.execute("token.address.get_balance", e), n = {};
415
+ for (let e in t.confirmed) t.confirmed[e] != 0 && (n[e] = {
416
+ confirmed: BigInt(t.confirmed[e]).toString(),
417
+ unconfirmed: "0"
418
+ });
419
+ for (let e in t.unconfirmed) t.unconfirmed[e] != 0 && (n[e] ? n[e].unconfirmed = BigInt(t.unconfirmed[e]).toString() : n[e] = {
420
+ confirmed: "0",
421
+ unconfirmed: BigInt(t.unconfirmed[e]).toString()
422
+ });
423
+ return n;
424
+ }
425
+ getTokenGenesis(e) {
426
+ return this.execute("token.genesis.info", e);
427
+ }
428
+ broadcast(e) {
429
+ return this.execute("blockchain.transaction.broadcast", e);
430
+ }
431
+ subscribeHeaders(e) {
432
+ return this.client.subscribe((t) => {
433
+ let n = Array.isArray(t) ? t[0] : t;
434
+ e(typeof n?.height == "number" ? n.height : 0);
435
+ }, "blockchain.headers.subscribe");
436
+ }
437
+ subscribeAddress(e, t) {
438
+ return this.client.subscribe(t, "blockchain.address.subscribe", e);
439
+ }
440
+ async getLatency() {
441
+ try {
442
+ let e = Date.now();
443
+ return await this.getBlockTip() ? Date.now() - e : 0;
444
+ } catch {
445
+ return 0;
446
+ }
447
+ }
448
+ async connect(e) {
449
+ try {
450
+ e ||= await this.getCurrentInstance(), this.client = new ne("com.otoplo.wallet", "1.4.3", e.host, e.port, e.scheme, 45e3, 1e4), await this.client.connect();
451
+ } catch (e) {
452
+ throw e instanceof Error ? console.info(e.message) : console.error(e), e;
453
+ }
454
+ }
455
+ async disconnect(e) {
456
+ try {
457
+ return await this.client?.disconnect(e) ?? !1;
458
+ } catch (e) {
459
+ return console.error(e), !1;
460
+ }
461
+ }
462
+ async execute(e, ...t) {
463
+ await this.waitForConnection();
464
+ let n = await this.client.request(e, ...t);
465
+ if (n instanceof Error) throw n;
466
+ return n;
467
+ }
468
+ waitForConnection(e = 5e3) {
469
+ let t = Date.now();
470
+ return new Promise((n, r) => {
471
+ let i = () => {
472
+ if (this.client?.connectionStatus == te.CONNECTED) return n();
473
+ if (Date.now() - t > e) return r(/* @__PURE__ */ Error("Rostrum Connection timeout"));
474
+ setTimeout(i, 250);
475
+ };
476
+ i();
477
+ });
478
+ }
479
+ setCurrentInstance(e) {
480
+ return this.walletDb.saveSetting("rostrum-params", JSON.stringify(e));
481
+ }
482
+ resetCurrentInstance() {
483
+ return this.walletDb.removeSetting("rostrum-params");
484
+ }
485
+ async getCurrentInstance() {
486
+ let t = await this.walletDb.getSetting("rostrum-params");
487
+ return t ? JSON.parse(t) : e.getPredefinedInstances()[0];
488
+ }
489
+ static getPredefinedInstances() {
490
+ return E() ? [{
491
+ scheme: b.WSS,
492
+ host: "testnet-electrum.nexa.org",
493
+ port: 30004,
494
+ label: "NexaOrg"
495
+ }] : [{
496
+ scheme: b.WSS,
497
+ host: "rostrum.otoplo.com",
498
+ port: 443,
499
+ label: "Otoplo"
500
+ }, {
501
+ scheme: b.WSS,
502
+ host: "electrum.nexa.org",
503
+ port: 20004,
504
+ label: "NexaOrg"
505
+ }];
506
+ }
507
+ };
508
+ // src/utils/keypath.ts
509
+ function I(e, t, n) {
510
+ return `${e}'/${t}/${n}`;
699
511
  }
700
- class Dt {
701
- rostrumService;
702
- keyManager;
703
- walletDb;
704
- MAX_INPUTS_OUTPUTS = 250;
705
- constructor(e, t, s) {
706
- this.rostrumService = e, this.keyManager = t, this.walletDb = s;
707
- }
708
- async broadcastTransaction(e) {
709
- return this.rostrumService.broadcast(e);
710
- }
711
- async fetchTransactionsHistory(e, t) {
712
- let s = t;
713
- const n = t > 0 ? t + 1 : 0, i = await this.rostrumService.getTransactionsHistory(e, n);
714
- for (const o of i)
715
- s = Math.max(s, o.height);
716
- return { txs: i, lastHeight: s };
717
- }
718
- async fetchVaultTransactions(e) {
719
- const t = await this.rostrumService.getTransactionsHistory(e, Ee), s = [];
720
- for (const n of t) {
721
- const i = this.classifyTransaction(n.tx_hash, [e]);
722
- s.push(i);
723
- }
724
- return Promise.all(s);
725
- }
726
- async classifyAndSaveTransaction(e, t, s) {
727
- const n = await this.classifyTransaction(t, s);
728
- n.accountId = e;
729
- const i = {
730
- ...n,
731
- othersOutputs: JSON.stringify(n.othersOutputs),
732
- myOutputs: JSON.stringify(n.myOutputs),
733
- myInputs: JSON.stringify(n.myInputs)
734
- }, o = /* @__PURE__ */ new Set();
735
- n.myInputs.forEach((r) => r.assetId && o.add(r.assetId)), n.myOutputs.forEach((r) => r.assetId && o.add(r.assetId));
736
- for (const r of o)
737
- await this.walletDb.addAssetTransaction({
738
- accountId: e,
739
- assetId: r,
740
- txIdem: n.txIdem,
741
- time: n.time
742
- });
743
- await this.walletDb.addLocalTransaction(i);
744
- }
745
- async classifyTransaction(e, t) {
746
- const s = await this.rostrumService.getTransaction(e), n = [], i = [], o = [], r = [];
747
- for (const l of s.vin) {
748
- const p = {
749
- address: l.addresses[0],
750
- nexaAmount: l.value_satoshi.toString(),
751
- assetId: l.token_id_hex ?? "",
752
- assetAmount: U(l.groupQuantity)
753
- };
754
- t.includes(p.address) ? n.push(p) : i.push(p);
755
- }
756
- for (const l of s.vout) {
757
- if (M(l.scriptPubKey.addresses)) continue;
758
- const p = {
759
- address: l.scriptPubKey.addresses[0],
760
- nexaAmount: l.value_satoshi.toString(),
761
- assetId: l.scriptPubKey.token_id_hex ?? "",
762
- assetAmount: U(l.scriptPubKey.groupQuantity)
763
- };
764
- t.includes(p.address) ? o.push(p) : r.push(p);
765
- }
766
- let c;
767
- n.length === 0 ? c = "receive" : o.length === 0 ? c = "send" : i.length === 0 && r.length === 0 ? c = "self" : i.length === 0 && r.length > 0 ? c = "send" : i.length > 0 && r.length === 0 ? c = "receive" : c = "swap";
768
- const d = s.height > 0;
769
- return {
770
- accountId: 0,
771
- // Will be set in classifyAndSaveTransaction
772
- txId: s.txid,
773
- txIdem: s.txidem,
774
- time: d ? s.time : J(),
775
- height: d ? s.height : 0,
776
- type: c,
777
- fee: s.fee_satoshi.toString(),
778
- othersOutputs: c == "send" || c == "swap" ? r : [],
779
- myOutputs: o,
780
- myInputs: n
781
- };
782
- }
783
- async buildAndSignTransferTransaction(e, t, s, n, i, o, r, c) {
784
- const d = {
785
- feeFromAmount: i
786
- }, u = this.prepareTransaction(t, n, o, c);
787
- r && u.feePerByte(r);
788
- let l = /* @__PURE__ */ new Map();
789
- o && (l = await this.populateTokenInputsAndChange(u, e, s, o, BigInt(n)));
790
- const p = await this.populateNexaInputsAndChange(u, e, s, d);
791
- return l.forEach((f, P) => p.set(P, f)), await this.finalizeTransaction(u, Array.from(p.values()));
792
- }
793
- async buildAndSignConsolidateTransaction(e, t, s) {
794
- const n = {
795
- isConsolidate: !0,
796
- templateData: s
797
- }, i = new z(), o = await this.populateNexaInputsAndChange(i, e, t, n);
798
- return this.finalizeTransaction(i, Array.from(o.values()));
799
- }
800
- prepareTransaction(e, t, s, n) {
801
- if (!R(e) && !R(e, O.PayToPublicKeyHash))
802
- throw new Error("Invalid Address.");
803
- if (s && BigInt(t) < 1n || !s && parseInt(t) < x.DUST_AMOUNT)
804
- throw new Error("The amount is too low.");
805
- if (s && BigInt(t) > Q || !s && parseInt(t) > x.MAX_MONEY)
806
- throw new Error("The amount is too high.");
807
- const i = new z();
808
- if (n && i.addData(n), s) {
809
- if (!R(s, O.GroupIdAddress))
810
- throw new Error("Invalid Token ID");
811
- if (I.getOutputType(e) === 0)
812
- throw new Error("Token must be sent to script template address");
813
- i.to(e, x.DUST_AMOUNT, s, BigInt(t));
814
- } else
815
- i.to(e, t);
816
- return i;
817
- }
818
- async populateNexaInputsAndChange(e, t, s, n) {
819
- const i = t.filter((d) => BigInt(d.balance.confirmed) + BigInt(d.balance.unconfirmed) > 0n);
820
- if (M(i))
821
- throw new Error("Not enough Nexa balance.");
822
- const o = /* @__PURE__ */ new Map(), r = n.isConsolidate ? 0 : Number(e.transaction.outputs.find((d) => d.value > 0n).value);
823
- for (const d of i) {
824
- const u = await this.rostrumService.getNexaUtxos(d.address);
825
- for (const l of u) {
826
- const p = {
827
- outpoint: l.outpoint_hash,
828
- address: d.address,
829
- satoshis: l.value,
830
- templateData: n.templateData
831
- };
832
- if (e.from(p), !o.has(d.address)) {
833
- const f = this.keyManager.getKey(d.keyPath);
834
- o.set(d.address, f.privateKey);
835
- }
836
- if (n.isConsolidate) {
837
- if (e.change(s), e.transaction.inputs.length > this.MAX_INPUTS_OUTPUTS)
838
- return o;
839
- } else {
840
- const f = e.transaction;
841
- if (f.inputs.length > this.MAX_INPUTS_OUTPUTS)
842
- throw new Error("Too many inputs. Consider consolidate transactions or reduce the send amount.");
843
- const P = f.getUnspentValue();
844
- if (P < 0n)
845
- continue;
846
- if (P == 0n && n.feeFromAmount) {
847
- const D = f.estimateRequiredFee();
848
- return f.updateOutputAmount(0, r - D), o;
849
- }
850
- if (e.change(s), n.feeFromAmount) {
851
- const D = f.getChangeOutput();
852
- let V = f.estimateRequiredFee();
853
- f.updateOutputAmount(0, r - V), !D && f.getChangeOutput() && (V = f.estimateRequiredFee(), f.updateOutputAmount(0, r - V));
854
- }
855
- if (f.getUnspentValue() < f.estimateRequiredFee())
856
- continue;
857
- return o;
858
- }
859
- }
860
- }
861
- if (n.isConsolidate) {
862
- if (o.size > 0)
863
- return o;
864
- throw new Error("Not enough Nexa balance.");
865
- }
866
- const c = {
867
- errorMsg: "Not enough Nexa balance.",
868
- amount: q.formatNEXA(e.transaction.outputs[0].value),
869
- fee: q.formatNEXA(e.transaction.estimateRequiredFee())
870
- };
871
- throw new Error(JSON.stringify(c));
872
- }
873
- async populateTokenInputsAndChange(e, t, s, n, i) {
874
- const o = v(n), r = t.filter((u) => Object.keys(u.tokensBalance).includes(o));
875
- if (M(r))
876
- throw new Error("Not enough token balance.");
877
- const c = /* @__PURE__ */ new Map();
878
- let d = 0n;
879
- for (const u of r) {
880
- const l = await this.rostrumService.getTokenUtxos(u.address, n);
881
- for (const p of l)
882
- if (!(BigInt(p.token_amount) < 0n)) {
883
- if (e.from({
884
- outpoint: p.outpoint_hash,
885
- address: u.address,
886
- satoshis: p.value,
887
- groupId: p.group,
888
- groupAmount: BigInt(p.token_amount)
889
- }), d = d + BigInt(p.token_amount), !c.has(u.address)) {
890
- const f = this.keyManager.getKey(u.keyPath);
891
- c.set(u.address, f.privateKey);
892
- }
893
- if (d > Q)
894
- throw new Error("Token inputs exceeded max amount. Consider sending in small chunks");
895
- if (e.transaction.inputs.length > this.MAX_INPUTS_OUTPUTS)
896
- throw new Error("Too many inputs. Consider consolidating transactions or reduce the send amount.");
897
- if (d == i)
898
- return c;
899
- if (d > i)
900
- return e.to(s, x.DUST_AMOUNT, n, d - i), c;
901
- }
902
- }
903
- throw new Error("Not enough token balance");
904
- }
905
- async finalizeTransaction(e, t) {
906
- const s = await this.rostrumService.getBlockTip();
907
- return e.lockUntilBlockHeight(s.height).sign(t).build();
908
- }
909
- printTransactionJson(e) {
910
- if (!e)
911
- return "";
912
- const t = {
913
- ...e.toObject(),
914
- hex: e.toString()
915
- };
916
- return JSON.stringify(t, null, 2);
917
- }
512
+ function L(e) {
513
+ let t = e.split("/");
514
+ return {
515
+ account: parseInt(t[0].replace("'", "")),
516
+ type: parseInt(t[1]),
517
+ index: parseInt(t[2])
518
+ };
918
519
  }
919
- function Vt(a = 12) {
920
- return Te(se, a === 24 ? 256 : 128);
520
+ // src/services/key.ts
521
+ var R = class {
522
+ constructor() {
523
+ this.accountKeys = /* @__PURE__ */ new Map(), this.walletKeys = /* @__PURE__ */ new Map();
524
+ }
525
+ static {
526
+ this.GAP_LIMIT = 20;
527
+ }
528
+ init(e) {
529
+ this.seed = typeof e == "string" ? ie(e) : e, this.masterKey = o.fromSeed(this.seed).deriveChild(44, !0).deriveChild(29223, !0);
530
+ }
531
+ reset() {
532
+ if (!this.seed) throw Error("KeysManager not initialized");
533
+ this.masterKey = o.fromSeed(this.seed).deriveChild(44, !0).deriveChild(29223, !0), this.accountKeys.clear(), this.walletKeys.clear();
534
+ }
535
+ getAccountKey(e) {
536
+ let t = this.accountKeys.get(e);
537
+ return t || (t = this.masterKey.deriveChild(e, !0), this.accountKeys.set(e, t)), t;
538
+ }
539
+ deriveAddress(e, t, n) {
540
+ return this.getKey({
541
+ account: e,
542
+ type: t,
543
+ index: n
544
+ }).privateKey.toAddress().toString();
545
+ }
546
+ getKey(e) {
547
+ let t = typeof e == "string" ? e : I(e.account, e.type, e.index), n = this.walletKeys.get(t);
548
+ if (!n) {
549
+ let { account: r, type: i, index: a } = typeof e == "string" ? L(e) : e;
550
+ n = this.getAccountKey(r).deriveChild(i, !1).deriveChild(a, !1), this.walletKeys.set(t, n);
551
+ }
552
+ return n;
553
+ }
554
+ };
555
+ // src/utils/asset.ts
556
+ function Ce(e, t) {
557
+ return e && typeof e == "string" ? e.startsWith("http") ? e.replace("http://", "https://") : e.startsWith("ipfs://") ? e : `${new URL(t).origin}${e}` : "";
921
558
  }
922
- function _e(a) {
923
- return Ie(a, se);
559
+ function we(e) {
560
+ return e ? Te(e) : null;
924
561
  }
925
- async function oe(a, e) {
926
- const t = await crypto.subtle.importKey(
927
- "raw",
928
- new Uint8Array(a),
929
- "PBKDF2",
930
- !1,
931
- ["deriveKey"]
932
- );
933
- return crypto.subtle.deriveKey(
934
- {
935
- name: "PBKDF2",
936
- salt: new Uint8Array(e),
937
- iterations: 21e4,
938
- hash: "SHA-256"
939
- },
940
- t,
941
- {
942
- name: "AES-GCM",
943
- length: 256
944
- },
945
- !1,
946
- ["encrypt", "decrypt"]
947
- );
562
+ function Te(e, t = "https://ipfs.nebula.markets/") {
563
+ return e?.startsWith("ipfs://") ? t + e.substring(7) : e;
948
564
  }
949
- async function Ht(a, e) {
950
- const t = m.utf8ToBuffer(e), s = m.getRandomBuffer(16), n = m.getRandomBuffer(12), i = m.utf8ToBuffer(a), o = await oe(t, s), r = await crypto.subtle.encrypt(
951
- {
952
- name: "AES-GCM",
953
- iv: new Uint8Array(n)
954
- },
955
- o,
956
- new Uint8Array(i)
957
- ), c = m.concat([s, n, new Uint8Array(r)]);
958
- return m.bufferToBase64(c);
565
+ function z(e) {
566
+ return `${V()}/metadata/${e}`;
959
567
  }
960
- async function Ue(a, e) {
961
- const t = m.utf8ToBuffer(e), s = m.base64ToBuffer(a), n = s.slice(0, 16), i = s.slice(16, 28), o = s.slice(28), r = await oe(t, n), c = await crypto.subtle.decrypt(
962
- {
963
- name: "AES-GCM",
964
- iv: i
965
- },
966
- r,
967
- o
968
- );
969
- return m.bufferToUtf8(new Uint8Array(c));
568
+ function B(e, t) {
569
+ return `${V()}/assets/${e}/${t}`;
970
570
  }
971
- async function Rt(a, e) {
972
- try {
973
- if (a) {
974
- const t = await Ue(a, e);
975
- if (t && _e(t))
976
- return t;
977
- }
978
- return !1;
979
- } catch {
980
- return !1;
981
- }
571
+ function V() {
572
+ return `https://${E() ? "testapi" : "api"}.otoplo.com`;
982
573
  }
983
- const ce = [
984
- { code: "usd", symbol: "$", name: "US Dollar" },
985
- { code: "eur", symbol: "€", name: "Euro" },
986
- { code: "gbp", symbol: "£", name: "British Pound" },
987
- { code: "aud", symbol: "A$", name: "Australian Dollar" },
988
- { code: "cad", symbol: "C$", name: "Canadian Dollar" },
989
- { code: "chf", symbol: "Fr", name: "Swiss Franc" },
990
- { code: "inr", symbol: "₹", name: "Indian Rupee" },
991
- { code: "cny", symbol: "¥", name: "Chinese Yuan" },
992
- { code: "jpy", symbol: "¥", name: "Japanese Yen" }
993
- ], De = Object.fromEntries(
994
- ce.map((a) => [a.code, a.symbol])
995
- ), Kt = ce.map((a) => a.code), te = {
996
- nexacoin: "nexa"
574
+ // src/services/asset.ts
575
+ var Ee = class {
576
+ constructor(e, t) {
577
+ this.walletDb = e, this.walletCache = t;
578
+ }
579
+ async getAssetInfo(e) {
580
+ try {
581
+ let t = await this.walletCache.getToken(e);
582
+ if (t) return {
583
+ type: "token",
584
+ parent: t.parent,
585
+ token: t.token,
586
+ tokenIdHex: t.tokenIdHex,
587
+ data: {
588
+ name: t.name,
589
+ ticker: t.ticker,
590
+ decimals: t.decimals,
591
+ iconUrl: t.iconUrl
592
+ }
593
+ };
594
+ let n = await this.walletCache.getNft(e);
595
+ return n ? {
596
+ type: "nft",
597
+ parent: n.parent,
598
+ token: n.token,
599
+ tokenIdHex: n.tokenIdHex,
600
+ data: {
601
+ name: n.name,
602
+ series: n.series,
603
+ collection: n.collection,
604
+ author: n.author,
605
+ public: n.public,
606
+ front: n.front,
607
+ back: n.back
608
+ }
609
+ } : await this.getAssetMetadata(e);
610
+ } catch (e) {
611
+ console.error(e);
612
+ return;
613
+ }
614
+ }
615
+ async handleNftReceive(e, t, n) {
616
+ let r = await this.getAssetInfo(t);
617
+ if (r && r.type == "nft") {
618
+ let t = {
619
+ token: r.token,
620
+ tokenIdHex: r.tokenIdHex,
621
+ parent: r.parent,
622
+ ...r.data
623
+ };
624
+ await this.saveNft(e, t, n);
625
+ }
626
+ }
627
+ async syncTokens(e, t) {
628
+ for (let n in t) {
629
+ let r = t[n];
630
+ if (r && BigInt(r.confirmed) + BigInt(r.unconfirmed) > 0n) {
631
+ let t = await this.getAssetInfo(n);
632
+ if (t && t.type == "token") {
633
+ let n = {
634
+ token: t.token,
635
+ tokenIdHex: t.tokenIdHex,
636
+ parent: t.parent,
637
+ ...t.data
638
+ };
639
+ await this.saveToken(e, n);
640
+ }
641
+ }
642
+ }
643
+ }
644
+ async syncNfts(e, t) {
645
+ let n = Object.keys(t), r = await this.walletDb.getAssets(e, "nft"), i = r?.filter((e) => !n.includes(e.tokenIdHex)) ?? [];
646
+ for (let t of i) await this.deleteNft(e, t.tokenIdHex);
647
+ for (let [n, i] of Object.entries(t)) {
648
+ let t = j(n), a = i && BigInt(i.confirmed) + BigInt(i.unconfirmed) > 0n, o = r?.some((e) => e.tokenIdHex == t);
649
+ !a && !o || a && o || (!a && o ? await this.deleteNft(e, t) : await this.handleNftReceive(e, t, O()));
650
+ }
651
+ }
652
+ async saveToken(e, t) {
653
+ await this.walletDb.saveToken(e, t);
654
+ }
655
+ async deleteToken(e, t) {
656
+ await this.walletDb.deleteToken(e, t), this.walletCache.removeToken(t);
657
+ }
658
+ async saveNft(e, t, n) {
659
+ await this.walletDb.saveNft(e, t, n);
660
+ }
661
+ async deleteNft(e, t) {
662
+ await this.walletDb.deleteNft(e, t), this.walletCache.removeNft(t);
663
+ }
664
+ getAssetFile(e, t) {
665
+ return this.performGet(B(e, t), "raw");
666
+ }
667
+ getAssetMetadata(e) {
668
+ return this.performGet(z(e), "json");
669
+ }
670
+ async performGet(e, t) {
671
+ try {
672
+ let n = await fetch(e);
673
+ if (!n.ok) throw Error(`Failed to perform GET. status: ${n.status}`);
674
+ if (t === "raw") {
675
+ let e = await n.arrayBuffer();
676
+ return new Uint8Array(e);
677
+ }
678
+ return await n.json();
679
+ } catch (e) {
680
+ throw Error(`Unexpected Error: ${e}`);
681
+ }
682
+ }
683
+ }, De = class {
684
+ constructor(e, t, n) {
685
+ this.MAX_INPUTS_OUTPUTS = 250, this.rostrumService = e, this.keyManager = t, this.walletDb = n;
686
+ }
687
+ async broadcastTransaction(e) {
688
+ return this.rostrumService.broadcast(e);
689
+ }
690
+ async fetchTransactionsHistory(e, t) {
691
+ let n = t, r = t > 0 ? t + 1 : 0, i = await this.rostrumService.getTransactionsHistory(e, r);
692
+ for (let e of i) n = Math.max(n, e.height);
693
+ return {
694
+ txs: i,
695
+ lastHeight: n
696
+ };
697
+ }
698
+ async fetchVaultTransactions(e) {
699
+ let t = await this.rostrumService.getTransactionsHistory(e, T), n = [];
700
+ for (let r of t) {
701
+ let t = this.classifyTransaction(r.tx_hash, [e]);
702
+ n.push(t);
703
+ }
704
+ return Promise.all(n);
705
+ }
706
+ async classifyAndSaveTransaction(e, t, n) {
707
+ let r = await this.classifyTransaction(t, n);
708
+ r.accountId = e;
709
+ let i = /* @__PURE__ */ new Set();
710
+ r.myInputs.forEach((e) => e.assetId && i.add(e.assetId)), r.myOutputs.forEach((e) => e.assetId && i.add(e.assetId));
711
+ for (let t of i) await this.walletDb.upsertAssetTransaction({
712
+ accountId: e,
713
+ assetId: t,
714
+ txIdem: r.txIdem,
715
+ time: r.time
716
+ });
717
+ await this.walletDb.upsertTransaction(r);
718
+ }
719
+ async classifyTransaction(e, t) {
720
+ let n = await this.rostrumService.getTransaction(e), r = [], i = [], a = [], o = [];
721
+ for (let e of n.vin) {
722
+ let n = {
723
+ address: e.addresses[0],
724
+ nexaAmount: e.value_satoshi.toString(),
725
+ assetId: e.token_id_hex ?? "",
726
+ assetAmount: M(e.groupQuantity)
727
+ };
728
+ t.includes(n.address) ? r.push(n) : i.push(n);
729
+ }
730
+ for (let e of n.vout) {
731
+ if (k(e.scriptPubKey.addresses)) continue;
732
+ let n = {
733
+ address: e.scriptPubKey.addresses[0],
734
+ nexaAmount: e.value_satoshi.toString(),
735
+ assetId: e.scriptPubKey.token_id_hex ?? "",
736
+ assetAmount: M(e.scriptPubKey.groupQuantity)
737
+ };
738
+ t.includes(n.address) ? a.push(n) : o.push(n);
739
+ }
740
+ let s;
741
+ s = r.length === 0 ? "receive" : a.length === 0 ? "send" : i.length === 0 && o.length === 0 ? "self" : i.length === 0 && o.length > 0 ? "send" : i.length > 0 && o.length === 0 ? "receive" : "swap";
742
+ let c = n.height > 0;
743
+ return {
744
+ accountId: 0,
745
+ txId: n.txid,
746
+ txIdem: n.txidem,
747
+ time: c ? n.time : O(),
748
+ height: c ? n.height : 0,
749
+ type: s,
750
+ fee: n.fee_satoshi.toString(),
751
+ othersOutputs: s == "send" || s == "swap" ? o : [],
752
+ myOutputs: a,
753
+ myInputs: r
754
+ };
755
+ }
756
+ async buildAndSignTransferTransaction(e, t, n, r, i, a, o, s) {
757
+ let c = { feeFromAmount: i }, l = this.prepareTransaction(t, r, a, s);
758
+ o && l.feePerByte(o);
759
+ let u = /* @__PURE__ */ new Map();
760
+ a && (u = await this.populateTokenInputsAndChange(l, e, n, a, BigInt(r)));
761
+ let d = await this.populateNexaInputsAndChange(l, e, n, c);
762
+ return u.forEach((e, t) => d.set(t, e)), await this.finalizeTransaction(l, Array.from(d.values()));
763
+ }
764
+ async buildAndSignConsolidateTransaction(e, t, n) {
765
+ let r = {
766
+ isConsolidate: !0,
767
+ templateData: n
768
+ }, i = new g(), a = await this.populateNexaInputsAndChange(i, e, t, r);
769
+ return this.finalizeTransaction(i, Array.from(a.values()));
770
+ }
771
+ prepareTransaction(n, r, i, a) {
772
+ if (!D(n) && !D(n, t.PayToPublicKeyHash)) throw Error("Invalid Address.");
773
+ if (i && BigInt(r) < 1n || !i && parseInt(r) < h.DUST_AMOUNT) throw Error("The amount is too low.");
774
+ if (i && BigInt(r) > 9223372036854775807n || !i && parseInt(r) > h.MAX_MONEY) throw Error("The amount is too high.");
775
+ let o = new g();
776
+ if (a && o.addData(a), i) {
777
+ if (!D(i, t.GroupIdAddress)) throw Error("Invalid Token ID");
778
+ if (e.getOutputType(n) === 0) throw Error("Token must be sent to script template address");
779
+ o.to(n, h.DUST_AMOUNT, i, BigInt(r));
780
+ } else o.to(n, r);
781
+ return o;
782
+ }
783
+ async populateNexaInputsAndChange(e, t, n, r) {
784
+ let i = t.filter((e) => BigInt(e.balance.confirmed) + BigInt(e.balance.unconfirmed) > 0n);
785
+ if (k(i)) throw Error("Not enough Nexa balance.");
786
+ let a = /* @__PURE__ */ new Map(), o = r.isConsolidate ? 0 : Number(e.transaction.outputs.find((e) => e.value > 0n).value);
787
+ for (let t of i) {
788
+ let i = await this.rostrumService.getNexaUtxos(t.address);
789
+ for (let s of i) {
790
+ let i = {
791
+ outpoint: s.outpoint_hash,
792
+ address: t.address,
793
+ satoshis: s.value,
794
+ templateData: r.templateData
795
+ };
796
+ if (e.from(i), !a.has(t.address)) {
797
+ let e = this.keyManager.getKey(t.keyPath);
798
+ a.set(t.address, e.privateKey);
799
+ }
800
+ if (r.isConsolidate) {
801
+ if (e.change(n), e.transaction.inputs.length > this.MAX_INPUTS_OUTPUTS) return a;
802
+ } else {
803
+ let t = e.transaction;
804
+ if (t.inputs.length > this.MAX_INPUTS_OUTPUTS) throw Error("Too many inputs. Consider consolidate transactions or reduce the send amount.");
805
+ let i = t.getUnspentValue();
806
+ if (i < 0n) continue;
807
+ if (i == 0n && r.feeFromAmount) {
808
+ let e = t.estimateRequiredFee();
809
+ return t.updateOutputAmount(0, o - e), a;
810
+ }
811
+ if (e.change(n), r.feeFromAmount) {
812
+ let e = t.getChangeOutput(), n = t.estimateRequiredFee();
813
+ t.updateOutputAmount(0, o - n), !e && t.getChangeOutput() && (n = t.estimateRequiredFee(), t.updateOutputAmount(0, o - n));
814
+ }
815
+ if (t.getUnspentValue() < t.estimateRequiredFee()) continue;
816
+ return a;
817
+ }
818
+ }
819
+ }
820
+ if (r.isConsolidate) {
821
+ if (a.size > 0) return a;
822
+ throw Error("Not enough Nexa balance.");
823
+ }
824
+ let s = {
825
+ errorMsg: "Not enough Nexa balance.",
826
+ amount: v.formatNEXA(e.transaction.outputs[0].value),
827
+ fee: v.formatNEXA(e.transaction.estimateRequiredFee())
828
+ };
829
+ throw Error(JSON.stringify(s));
830
+ }
831
+ async populateTokenInputsAndChange(e, t, n, r, i) {
832
+ let a = j(r), o = t.filter((e) => Object.keys(e.tokensBalance).includes(a));
833
+ if (k(o)) throw Error("Not enough token balance.");
834
+ let s = /* @__PURE__ */ new Map(), c = 0n;
835
+ for (let t of o) {
836
+ let a = await this.rostrumService.getTokenUtxos(t.address, r);
837
+ for (let o of a) if (!(BigInt(o.token_amount) < 0n)) {
838
+ if (e.from({
839
+ outpoint: o.outpoint_hash,
840
+ address: t.address,
841
+ satoshis: o.value,
842
+ groupId: o.group,
843
+ groupAmount: BigInt(o.token_amount)
844
+ }), c += BigInt(o.token_amount), !s.has(t.address)) {
845
+ let e = this.keyManager.getKey(t.keyPath);
846
+ s.set(t.address, e.privateKey);
847
+ }
848
+ if (c > 9223372036854775807n) throw Error("Token inputs exceeded max amount. Consider sending in small chunks");
849
+ if (e.transaction.inputs.length > this.MAX_INPUTS_OUTPUTS) throw Error("Too many inputs. Consider consolidating transactions or reduce the send amount.");
850
+ if (c == i) return s;
851
+ if (c > i) return e.to(n, h.DUST_AMOUNT, r, c - i), s;
852
+ }
853
+ }
854
+ throw Error("Not enough token balance");
855
+ }
856
+ async finalizeTransaction(e, t) {
857
+ let n = await this.rostrumService.getBlockTip();
858
+ return e.lockUntilBlockHeight(n.height).sign(t).build();
859
+ }
860
+ printTransactionJson(e) {
861
+ if (!e) return "";
862
+ let t = {
863
+ ...e.toObject(),
864
+ hex: e.toString()
865
+ };
866
+ return JSON.stringify(t, null, 2);
867
+ }
997
868
  };
998
- async function Ve(a) {
999
- const e = Object.keys(te).join(","), t = await fetch(`https://api.coingecko.com/api/v3/coins/markets?ids=${e}&vs_currency=${a}`);
1000
- if (!t.ok)
1001
- throw new Error("Failed to fetch market data");
1002
- const s = await t.json(), n = {};
1003
- return s.forEach((i) => {
1004
- n[te[i.id]] = {
1005
- id: i.id,
1006
- name: i.name ?? "",
1007
- symbol: i.symbol ?? "",
1008
- image: i.image ?? "",
1009
- price: i.current_price ?? 0,
1010
- priceChange: i.price_change_24h,
1011
- priceChangePercentage: i.price_change_percentage_24h,
1012
- marketCap: i.market_cap,
1013
- fdv: i.fully_diluted_valuation,
1014
- circSupply: i.circulating_supply,
1015
- totalSupply: i.total_supply,
1016
- maxSupply: i.max_supply,
1017
- totalVolume: i.total_volume
1018
- };
1019
- }), n;
869
+ // src/utils/seed.ts
870
+ function Oe(e = 12) {
871
+ return re(x, e === 24 ? 256 : 128);
1020
872
  }
1021
- function Lt(a) {
1022
- return De[a] || a;
873
+ function H(e) {
874
+ return ae(e, x);
1023
875
  }
1024
- function Ft(a, e, t) {
1025
- const s = B.multiply(a, e), n = B.round(s, 2, B.RoundingModes.HALF_DOWN);
1026
- return t ? He(n, t) : n;
876
+ async function U(e, t) {
877
+ let n = await crypto.subtle.importKey("raw", new Uint8Array(e), "PBKDF2", !1, ["deriveKey"]);
878
+ return crypto.subtle.deriveKey({
879
+ name: "PBKDF2",
880
+ salt: new Uint8Array(t),
881
+ iterations: 21e4,
882
+ hash: "SHA-256"
883
+ }, n, {
884
+ name: "AES-GCM",
885
+ length: 256
886
+ }, !1, ["encrypt", "decrypt"]);
1027
887
  }
1028
- function He(a, e, t = "en-US") {
1029
- return new Intl.NumberFormat(t, {
1030
- style: "currency",
1031
- currency: e,
1032
- maximumFractionDigits: 2,
1033
- minimumFractionDigits: 2
1034
- }).format(Number(a));
888
+ async function ke(e, t) {
889
+ let n = r.utf8ToBuffer(t), i = r.getRandomBuffer(16), a = r.getRandomBuffer(12), o = r.utf8ToBuffer(e), s = await U(n, i), c = await crypto.subtle.encrypt({
890
+ name: "AES-GCM",
891
+ iv: new Uint8Array(a)
892
+ }, s, new Uint8Array(o)), l = r.concat([
893
+ i,
894
+ a,
895
+ new Uint8Array(c)
896
+ ]);
897
+ return r.bufferToBase64(l);
1035
898
  }
1036
- function Re() {
1037
- return b.empty().add(A.OP_FROMALTSTACK).add(A.OP_DROP).add(A.OP_FROMALTSTACK).add(A.OP_CHECKLOCKTIMEVERIFY).add(A.OP_DROP).add(A.OP_FROMALTSTACK).add(A.OP_CHECKSIGVERIFY);
899
+ async function Ae(e, t) {
900
+ let n = r.utf8ToBuffer(t), i = r.base64ToBuffer(e), a = i.slice(0, 16), o = i.slice(16, 28), s = i.slice(28), c = await U(n, a), l = await crypto.subtle.decrypt({
901
+ name: "AES-GCM",
902
+ iv: o
903
+ }, c, s);
904
+ return r.bufferToUtf8(new Uint8Array(l));
1038
905
  }
1039
- function Ke() {
1040
- const a = Re();
1041
- return _.sha256ripemd160(a.toBuffer());
906
+ async function je(e, t) {
907
+ try {
908
+ if (e) {
909
+ let n = await Ae(e, t);
910
+ if (n && H(n)) return n;
911
+ }
912
+ return !1;
913
+ } catch {
914
+ return !1;
915
+ }
1042
916
  }
1043
- function Le(a) {
1044
- return b.empty().add(a.toBuffer());
917
+ // src/utils/market.ts
918
+ var W = [
919
+ {
920
+ code: "usd",
921
+ symbol: "$",
922
+ name: "US Dollar"
923
+ },
924
+ {
925
+ code: "eur",
926
+ symbol: "€",
927
+ name: "Euro"
928
+ },
929
+ {
930
+ code: "gbp",
931
+ symbol: "£",
932
+ name: "British Pound"
933
+ },
934
+ {
935
+ code: "aud",
936
+ symbol: "A$",
937
+ name: "Australian Dollar"
938
+ },
939
+ {
940
+ code: "cad",
941
+ symbol: "C$",
942
+ name: "Canadian Dollar"
943
+ },
944
+ {
945
+ code: "chf",
946
+ symbol: "Fr",
947
+ name: "Swiss Franc"
948
+ },
949
+ {
950
+ code: "inr",
951
+ symbol: "₹",
952
+ name: "Indian Rupee"
953
+ },
954
+ {
955
+ code: "cny",
956
+ symbol: "¥",
957
+ name: "Chinese Yuan"
958
+ },
959
+ {
960
+ code: "jpy",
961
+ symbol: "¥",
962
+ name: "Japanese Yen"
963
+ }
964
+ ], G = Object.fromEntries(W.map((e) => [e.code, e.symbol])), K = W.map((e) => e.code);
965
+ function Me(e) {
966
+ return G[e] || e;
1045
967
  }
1046
- function Fe(a) {
1047
- const e = Le(a);
1048
- return _.sha256ripemd160(e.toBuffer());
968
+ function Ne(e, t, n) {
969
+ let r = y.multiply(e, t), i = y.round(r, 2, y.RoundingModes.HALF_DOWN);
970
+ return n ? q(i, n) : i;
1049
971
  }
1050
- function $e(a) {
1051
- return a.map((e) => e <= 16 ? L.smallInt(e) : F.fromNumber(e).toScriptNumBuffer());
972
+ function q(e, t, n = "en-US") {
973
+ return new Intl.NumberFormat(n, {
974
+ style: "currency",
975
+ currency: t,
976
+ maximumFractionDigits: 2,
977
+ minimumFractionDigits: 2
978
+ }).format(Number(e));
979
+ }
980
+ // src/utils/vault.ts
981
+ function J() {
982
+ return f.empty().add(l.OP_FROMALTSTACK).add(l.OP_DROP).add(l.OP_FROMALTSTACK).add(l.OP_CHECKLOCKTIMEVERIFY).add(l.OP_DROP).add(l.OP_FROMALTSTACK).add(l.OP_CHECKSIGVERIFY);
1052
983
  }
1053
- function We(a, e) {
1054
- if (e.length !== 2)
1055
- return;
1056
- const t = Ke(), s = Fe(a), n = $e(e);
1057
- return I.fromScriptTemplate(t, s, n).toString();
984
+ function Y() {
985
+ let e = J();
986
+ return s.sha256ripemd160(e.toBuffer());
1058
987
  }
1059
- class $t {
1060
- walletDb;
1061
- keyManager;
1062
- providers;
1063
- handlers;
1064
- removeOnClose;
1065
- updateCallback;
1066
- constructor(e, t) {
1067
- this.walletDb = e, this.keyManager = t, this.providers = /* @__PURE__ */ new Map(), this.handlers = /* @__PURE__ */ new Map(), this.removeOnClose = !0;
1068
- }
1069
- onUpdate(e) {
1070
- this.updateCallback = e;
1071
- }
1072
- notify(e) {
1073
- this.updateCallback?.(e);
1074
- }
1075
- getHandler(e) {
1076
- return this.handlers.get(e);
1077
- }
1078
- add(e, t, s) {
1079
- this.providers.has(e.id) || this.providers.set(e.id, /* @__PURE__ */ new Map());
1080
- const n = s.details.sessionId, i = this.providers.get(e.id);
1081
- this.registerHandlers(e, t, n), i.set(n, t), this.notify({ type: "session_added", accountId: e.id, sessionInfo: s });
1082
- }
1083
- remove(e, t) {
1084
- const s = this.providers.get(e);
1085
- if (s) {
1086
- const n = s.get(t);
1087
- n && (n.disconnect(), s.delete(t)), s.size === 0 && this.providers.delete(e);
1088
- }
1089
- this.notify({ type: "session_removed", accountId: e, sessionId: t });
1090
- }
1091
- async reload(e) {
1092
- for (const t of e.values()) {
1093
- if (t.id == w)
1094
- continue;
1095
- const s = await this.walletDb.getAccountSessions(t.id), n = this.providers.get(t.id), i = s.map(async (r) => {
1096
- if (n?.has(r.sessionId))
1097
- return;
1098
- let c;
1099
- try {
1100
- c = new xe(r.uri);
1101
- const d = c.getSessionInfo();
1102
- await c.connect(3e3);
1103
- const u = await c.getAppInfo(2e3);
1104
- await c.joinSession(t.address, 2e3);
1105
- const l = await c.fetchPendingMessages();
1106
- for (const p of l)
1107
- this.notify({
1108
- type: "new_notification",
1109
- notification: {
1110
- id: crypto.randomUUID(),
1111
- createdAt: p.createdAt,
1112
- type: "web3",
1113
- title: "Request pending approval",
1114
- message: `A connected dApp (${u.name}) has requested an action from your Account: ${t.name}. Review the request details before approving or rejecting.`,
1115
- action: {
1116
- type: "DAPP_REQUEST",
1117
- account: t.id,
1118
- sessionId: d.sessionId,
1119
- payload: p.message
1120
- }
1121
- }
1122
- });
1123
- return { account: t, provider: c, metadata: { details: d, appInfo: u } };
1124
- } catch (d) {
1125
- console.error(`Failed to reload session ${r.sessionId}`, d), c?.disconnect(), await this.walletDb.removeSession(r.sessionId);
1126
- }
1127
- }), o = await Promise.allSettled(i);
1128
- for (const r of o)
1129
- r.status === "fulfilled" && r.value && this.add(r.value.account, r.value.provider, r.value.metadata);
1130
- }
1131
- }
1132
- clear() {
1133
- try {
1134
- this.removeOnClose = !1;
1135
- for (const [e, t] of this.providers) {
1136
- for (const [, s] of t)
1137
- s.disconnect();
1138
- t.clear(), this.notify({ type: "sessions_cleared", accountId: e });
1139
- }
1140
- this.providers.clear();
1141
- } finally {
1142
- this.removeOnClose = !0;
1143
- }
1144
- }
1145
- async revoke(e, t) {
1146
- const s = this.providers.get(e);
1147
- if (s) {
1148
- const n = s.get(t);
1149
- n && await n.revokeSession();
1150
- }
1151
- }
1152
- async replayMessage(e, t, s) {
1153
- const n = this.providers.get(e);
1154
- if (n) {
1155
- const i = n.get(t);
1156
- i && await i.replayMessage(s);
1157
- }
1158
- }
1159
- registerHandlers(e, t, s) {
1160
- t.onSessionDelete(() => this.walletDb.removeSession(s)), t.onClose(() => {
1161
- this.removeOnClose && this.remove(e.id, s);
1162
- });
1163
- const n = (i, o) => new Promise((r, c) => {
1164
- this.handlers.set(i, { resolve: r, reject: c }), this.notify({ type: "new_request", request: { type: i, accountId: e.id, sessionId: s, request: o } });
1165
- });
1166
- t.onSignMessage((i) => n(N.SignMessage, i)), t.onAddToken((i) => n(N.AddToken, i)), t.onSendTransaction((i) => n(N.SendTransaction, i)), t.onSignTransaction((i) => n(N.SignTransaction, i)), t.onGetAccount(() => {
1167
- const i = { account: h.DAPP, type: y.RECEIVE, index: e.id };
1168
- return {
1169
- name: e.name,
1170
- address: e.address,
1171
- pubkey: this.keyManager.getKey(i).publicKey.toString(),
1172
- blockchain: "nexa",
1173
- network: E.defaultNetwork.name,
1174
- capabilities: {
1175
- addToken: !0,
1176
- sendTransaction: !0,
1177
- signMessage: !0,
1178
- signTransaction: !0
1179
- }
1180
- };
1181
- });
1182
- }
988
+ function X(e) {
989
+ return f.empty().add(e.toBuffer());
1183
990
  }
1184
- class Wt {
1185
- rostrumService;
1186
- keyManager;
1187
- assetService;
1188
- constructor(e, t, s) {
1189
- this.rostrumService = e, this.keyManager = t, this.assetService = s;
1190
- }
1191
- async transformRawTransaction(e, t) {
1192
- const s = this.createContext(e, t);
1193
- return await this.processInputs(s), this.processOutputs(s), this.signInputs(s), await this.processAssetMovements(s), s.txDetails;
1194
- }
1195
- createContext(e, t) {
1196
- try {
1197
- return {
1198
- address: t.address,
1199
- privateKey: this.keyManager.getKey(t.keyPath).privateKey,
1200
- txDetails: {
1201
- tx: new x(e),
1202
- send: [],
1203
- receive: []
1204
- },
1205
- myInputs: /* @__PURE__ */ new Map(),
1206
- myOutputs: /* @__PURE__ */ new Map(),
1207
- involvedAssets: /* @__PURE__ */ new Set(),
1208
- inputsToSign: /* @__PURE__ */ new Set(),
1209
- coveredOutputs: /* @__PURE__ */ new Set(),
1210
- allMyOutputsCovered: !1
1211
- };
1212
- } catch {
1213
- throw new Error("Invalid transaction format.");
1214
- }
1215
- }
1216
- async processInputs(e) {
1217
- const t = [];
1218
- for (let s = 0; s < e.txDetails.tx.inputs.length; s++) {
1219
- const n = this.processInput(e, s);
1220
- t.push(n);
1221
- }
1222
- await Promise.all(t);
1223
- }
1224
- async processInput(e, t) {
1225
- const s = e.txDetails.tx.inputs[t], n = await this.rostrumService.getUtxo(m.bufferToHex(s.outpoint));
1226
- if (n.status == "spent")
1227
- throw new Error("Input UTXO is already spent.");
1228
- if (s.output = new we(n.amount, n.scriptpubkey), s.output.address == e.address) {
1229
- const i = n.token_id_hex || "NEXA";
1230
- e.myInputs.set(t, {
1231
- address: e.address,
1232
- nexaAmount: n.amount.toString(),
1233
- assetId: i,
1234
- assetAmount: U(n.group_quantity) || n.amount.toString()
1235
- }), e.involvedAssets.add(i), s.scriptSig.isEmpty() && e.inputsToSign.add(t);
1236
- }
1237
- s.scriptSig.findPlaceholder() > 0 && e.inputsToSign.add(t);
1238
- }
1239
- processOutputs(e) {
1240
- for (let t = 0; t < e.txDetails.tx.outputs.length; t++) {
1241
- const s = e.txDetails.tx.outputs[t].toObject();
1242
- if (s.address !== e.address)
1243
- continue;
1244
- const n = s.groupId ? v(s.groupId) : "NEXA", i = {
1245
- address: s.address,
1246
- nexaAmount: s.value.toString(),
1247
- assetId: n,
1248
- assetAmount: U(s.groupAmount) || s.value.toString()
1249
- };
1250
- e.involvedAssets.add(n), e.myOutputs.set(t, i);
1251
- }
1252
- }
1253
- signInputs(e) {
1254
- if (e.inputsToSign.size == 0)
1255
- throw new Error("No inputs to sign.");
1256
- for (const t of e.inputsToSign) {
1257
- const s = e.txDetails.tx.inputs[t], n = this.validateAndGetSubscript(s);
1258
- if (s.scriptSig.isEmpty()) {
1259
- e.allMyOutputsCovered = !0;
1260
- const i = X.sign(e.txDetails.tx, t, Y.ALL, n, e.privateKey).toTxFormat(), o = b.empty().add(e.privateKey.publicKey.toBuffer());
1261
- s.scriptSig = Ae.buildScriptTemplateIn(void 0, o, b.empty().add(i));
1262
- } else {
1263
- const i = s.scriptSig.findPlaceholder(), r = s.scriptSig.chunks[i].buf.subarray(64), c = Y.fromBuffer(r);
1264
- this.processSignatureCoverage(e, c);
1265
- const d = X.sign(e.txDetails.tx, t, c, n, e.privateKey).toTxFormat(r);
1266
- s.scriptSig.replaceChunk(i, b.empty().add(d));
1267
- }
1268
- }
1269
- if (!e.allMyOutputsCovered)
1270
- throw new Error("Some of interested outputs are not covered by signatures.");
1271
- }
1272
- validateAndGetSubscript(e) {
1273
- if (e.output.scriptPubKey.isPublicKeyTemplateOut()) {
1274
- if (e.scriptSig.isEmpty() || e.scriptSig.isPublicKeyTemplateIn())
1275
- return b.empty().add(A.OP_FROMALTSTACK).add(A.OP_CHECKSIGVERIFY);
1276
- throw new Error("Invalid input script type.");
1277
- }
1278
- if (e.output.scriptPubKey.isScriptTemplateOut()) {
1279
- if (!e.scriptSig.isScriptTemplateIn())
1280
- throw new Error("Unsupported input script type.");
1281
- const t = e.output.scriptPubKey.getTemplateHash(), s = e.scriptSig.chunks[0].buf;
1282
- if (m.equals(t, _.sha256ripemd160(s)) || m.equals(t, _.sha256sha256(s)))
1283
- return b.fromBuffer(s);
1284
- throw new Error("Invalid input script template.");
1285
- }
1286
- throw new Error("Unsupported prevout script type.");
1287
- }
1288
- processSignatureCoverage(e, t) {
1289
- if (!e.allMyOutputsCovered)
1290
- if (t.outType == Z.TWO)
1291
- e.coveredOutputs.add(t.outData[0]), e.coveredOutputs.add(t.outData[1]), this.checkSignatureCoverage(e);
1292
- else if (t.outType == Z.FIRSTN) {
1293
- const s = t.outData[0];
1294
- for (let n = 0; n < s; n++)
1295
- e.coveredOutputs.add(n);
1296
- this.checkSignatureCoverage(e);
1297
- } else
1298
- e.allMyOutputsCovered = !0;
1299
- }
1300
- checkSignatureCoverage(e) {
1301
- if (!e.allMyOutputsCovered) {
1302
- for (const t of e.myOutputs.keys())
1303
- if (!e.coveredOutputs.has(t))
1304
- return;
1305
- e.allMyOutputsCovered = !0;
1306
- }
1307
- }
1308
- async processAssetMovements(e) {
1309
- const t = Array.from(e.myInputs.values()), s = Array.from(e.myOutputs.values()), n = [];
1310
- for (const i of e.involvedAssets) {
1311
- const o = this.processAssetMovement(e, i, t, s);
1312
- n.push(o);
1313
- }
1314
- await Promise.all(n);
1315
- }
1316
- async processAssetMovement(e, t, s, n) {
1317
- const i = s.reduce((r, c) => c.assetId === t ? r + BigInt(c.assetAmount) : r, 0n), o = n.reduce((r, c) => c.assetId === t ? r + BigInt(c.assetAmount) : r, 0n);
1318
- if (i > 0n || o > 0n) {
1319
- const r = { amount: o - i };
1320
- t !== "NEXA" && (r.asset = await this.assetService.getAssetInfo(t)), r.amount > 0n ? e.txDetails.receive.push(r) : r.amount < 0n && e.txDetails.send.push(r);
1321
- }
1322
- }
991
+ function Z(e) {
992
+ let t = X(e);
993
+ return s.sha256ripemd160(t.toBuffer());
1323
994
  }
1324
- const Ge = 274710, Je = "0014461ad25081cb0119d034385ff154c8d3ad6bdd76";
1325
- class je {
1326
- rostrumService;
1327
- keyManager;
1328
- constructor(e, t) {
1329
- this.rostrumService = e, this.keyManager = t;
1330
- }
1331
- async discoverWalletIndex(e, t) {
1332
- let s = 0, n = !1, i = 0;
1333
- do {
1334
- n = !0;
1335
- for (let o = i; o < i + 20; o++) {
1336
- const r = { account: e, type: t, index: o }, c = this.keyManager.getKey(r).privateKey.toAddress().toString();
1337
- await this.rostrumService.isAddressUsed(c) && (s = o, n = !1);
1338
- }
1339
- i += 20;
1340
- } while (!n);
1341
- return s;
1342
- }
1343
- async discoverVaults(e) {
1344
- const t = [];
1345
- for (const i of e) {
1346
- const o = this.checkVaultsForAddress(i);
1347
- t.push(o);
1348
- }
1349
- const s = await Promise.all(t), n = /* @__PURE__ */ new Map();
1350
- return s.forEach((i) => {
1351
- i.forEach((o) => {
1352
- const r = this.parseVaultDetails(o);
1353
- r && n.set(r.address, r);
1354
- });
1355
- }), n;
1356
- }
1357
- async checkVaultsForAddress(e) {
1358
- const t = /* @__PURE__ */ new Set(), s = await this.rostrumService.getTransactionsHistory(e, Ge);
1359
- for (const n of s) {
1360
- const o = (await this.rostrumService.getTransaction(n.tx_hash)).vout.filter((r) => r.scriptPubKey.hex.startsWith(Je));
1361
- for (const r of o)
1362
- t.add(r.scriptPubKey.hex);
1363
- }
1364
- return t;
1365
- }
1366
- parseVaultDetails(e) {
1367
- const t = b.fromHex(e), s = new ve().writeVarLengthBuf(t.toBuffer()).toBuffer(), n = new I(s).toString(), i = t.getVisibleArgs(), o = F.fromScriptNumBuffer(i.chunks[0].buf).toNumber(), r = L.isSmallIntOp(i.chunks[1].opcodenum) ? L.decodeOP_N(i.chunks[1].opcodenum) : F.fromScriptNumBuffer(i.chunks[1].buf).toNumber(), c = [o, r], d = this.keyManager.getKey({ account: h.VAULT, type: y.RECEIVE, index: r }), u = We(d.publicKey, c);
1368
- return n != u ? void 0 : {
1369
- address: n,
1370
- block: o,
1371
- idx: r,
1372
- statusHash: "",
1373
- balance: { confirmed: "0", unconfirmed: "0" },
1374
- tokensBalance: {},
1375
- height: 0,
1376
- type: h.VAULT
1377
- };
1378
- }
995
+ function Q(e) {
996
+ return e.map((e) => e <= 16 ? p.smallInt(e) : n.fromNumber(e).toScriptNumBuffer());
1379
997
  }
1380
- class T {
1381
- constructor(e, t, s, n, i, o, r) {
1382
- this.keyManager = e, this.kvStore = t, this.walletDb = s, this.rostrumService = n, this.assetService = i, this.transactionService = o, this.sessionManager = r, this.discoveryService = new je(this.rostrumService, this.keyManager), this.accounts = /* @__PURE__ */ new Map(), this.accountsAddressToId = /* @__PURE__ */ new Map(), this.receiveAddresses = [], this.changeAddresses = [], this.vaults = /* @__PURE__ */ new Map(), this.pendingUpdates = /* @__PURE__ */ new Map(), this.addressResolvers = /* @__PURE__ */ new Map();
1383
- }
1384
- static GAP_LIMIT = 20;
1385
- static DEBOUNCE_MS = 1e3;
1386
- addressResolvers;
1387
- accounts;
1388
- accountsAddressToId;
1389
- receiveAddresses;
1390
- changeAddresses;
1391
- vaults;
1392
- pendingUpdates;
1393
- updateTimer;
1394
- updateCallback;
1395
- discoveryService;
1396
- onUpdate(e) {
1397
- this.updateCallback = e;
1398
- }
1399
- notify(e) {
1400
- this.updateCallback?.(e);
1401
- }
1402
- getAllAddresses() {
1403
- return [...this.receiveAddresses, ...this.changeAddresses, ...this.accounts.values(), ...this.vaults.values()];
1404
- }
1405
- getMainAddresses() {
1406
- return [...this.receiveAddresses, ...this.changeAddresses];
1407
- }
1408
- getReceiveAddress() {
1409
- return this.receiveAddresses.find((e) => !e.used).address;
1410
- }
1411
- getChangeAddress(e = w) {
1412
- return e != w ? this.accounts.get(e).address : this.changeAddresses.find((t) => !t.used).address;
1413
- }
1414
- getUsedAddressKeys(e = w) {
1415
- if (e != w) {
1416
- const t = this.accounts.get(e);
1417
- return [{
1418
- address: t.address,
1419
- keyPath: k(h.DAPP, 0, t.id),
1420
- balance: t.balance,
1421
- tokensBalance: t.tokensBalance
1422
- }];
1423
- }
1424
- return this.getMainAddresses().filter((t) => t.used).map((t) => ({
1425
- address: t.address,
1426
- keyPath: k(h.MAIN, t.space, t.idx),
1427
- balance: t.balance,
1428
- tokensBalance: t.tokensBalance
1429
- }));
1430
- }
1431
- async reloadRostrum(e) {
1432
- await this.kvStore.saveRostrumParams(e), await this.rostrumService.disconnect(!0), await this.initRostrum(), await this.subscribeAddresses(this.getAllAddresses());
1433
- }
1434
- async initRostrum() {
1435
- await this.rostrumService.connect(), await this.rostrumService.subscribeHeaders((e) => this.notify({ type: "new_tip", tip: e }));
1436
- }
1437
- async initialize() {
1438
- await this.initRostrum(), await this.walletDb.countAddresses() ? await this.loadWallet() : await this.discoverWallet();
1439
- }
1440
- async discoverWallet() {
1441
- this.notify({ type: "discover_wallet", loading: !0 });
1442
- const e = this.discoveryService.discoverWalletIndex(h.MAIN, y.RECEIVE), t = this.discoveryService.discoverWalletIndex(h.MAIN, y.CHANGE), s = this.discoveryService.discoverWalletIndex(h.DAPP, y.RECEIVE), [n, i, o] = await Promise.all([e, t, s]);
1443
- this.receiveAddresses = this.deriveAddresses(y.RECEIVE, 0, n + T.GAP_LIMIT), this.changeAddresses = this.deriveAddresses(y.CHANGE, 0, i + T.GAP_LIMIT), this.accounts = this.deriveAccounts(0, o + 1), this.accounts.forEach((r) => this.accountsAddressToId.set(r.address, r.id)), await this.saveAddresses(this.receiveAddresses), await this.saveAddresses(this.changeAddresses), await this.saveAccounts(this.accounts), this.initState(), await this.initialSync(), this.notify({ type: "discover_wallet", loading: !1 }), this.notify({ type: "load_wallet", loading: !1 }), await this.rescanVaults();
1444
- }
1445
- async loadWallet() {
1446
- this.receiveAddresses = await this.walletDb.getReceiveAddresses(), this.changeAddresses = await this.walletDb.getChangeAddresses();
1447
- const e = await this.walletDb.getAccounts();
1448
- this.accounts = new Map(e.map((s) => [s.id, s])), this.accountsAddressToId = new Map(e.map((s) => [s.address, s.id]));
1449
- const t = await this.walletDb.getVaults();
1450
- this.vaults = new Map(t.map((s) => [s.address, s])), this.initState(), this.notify({ type: "load_wallet", loading: !1 }), await this.reconnectSync();
1451
- }
1452
- async initialSync() {
1453
- await this.subscribeAddresses(this.getAllAddresses(), !0);
1454
- const e = [];
1455
- e.push(this.assetService.syncTokens(w, K(this.getMainAddresses().map((t) => t.tokensBalance))));
1456
- for (const t of this.accounts.values())
1457
- e.push(this.assetService.syncTokens(t.id, t.tokensBalance));
1458
- await Promise.all(e);
1459
- }
1460
- async reconnectSync() {
1461
- await Promise.all([
1462
- this.sessionManager.reload(this.accounts),
1463
- this.subscribeAddresses(this.getAllAddresses())
1464
- ]);
1465
- }
1466
- initState() {
1467
- const e = this.getMainAddresses();
1468
- this.notify({
1469
- type: "new_account",
1470
- account: {
1471
- id: w,
1472
- name: "Main Wallet",
1473
- address: this.getReceiveAddress(),
1474
- balance: ee(e.map((t) => t.balance)),
1475
- tokensBalance: K(e.map((t) => t.tokensBalance)),
1476
- sessions: {}
1477
- }
1478
- });
1479
- for (const t of this.accounts.values())
1480
- this.notify({
1481
- type: "new_account",
1482
- account: {
1483
- id: t.id,
1484
- name: t.name,
1485
- address: t.address,
1486
- balance: t.balance,
1487
- tokensBalance: t.tokensBalance,
1488
- sessions: {}
1489
- }
1490
- });
1491
- for (const t of this.vaults.values())
1492
- this.notify({
1493
- type: "new_vault",
1494
- vault: {
1495
- address: t.address,
1496
- balance: t.balance,
1497
- block: t.block,
1498
- index: t.idx
1499
- }
1500
- });
1501
- }
1502
- deriveAddresses(e, t, s) {
1503
- const n = [];
1504
- for (let i = t; i < t + s; i++) {
1505
- const o = k(h.MAIN, e, i), c = {
1506
- address: this.keyManager.getKey(o).privateKey.toAddress().toString(),
1507
- space: e,
1508
- idx: i,
1509
- used: !1,
1510
- height: 0,
1511
- statusHash: "",
1512
- balance: { confirmed: "0", unconfirmed: "0" },
1513
- tokensBalance: {},
1514
- type: h.MAIN
1515
- };
1516
- n.push(c);
1517
- }
1518
- return n;
1519
- }
1520
- deriveAccounts(e, t) {
1521
- const s = /* @__PURE__ */ new Map();
1522
- for (let n = e; n < e + t; n++) {
1523
- const i = k(h.DAPP, 0, n), o = this.keyManager.getKey(i).privateKey.toAddress().toString(), r = {
1524
- id: n,
1525
- name: `Account ${n + 1}`,
1526
- address: o,
1527
- height: 0,
1528
- hidden: 0,
1529
- statusHash: "",
1530
- balance: { confirmed: "0", unconfirmed: "0" },
1531
- tokensBalance: {},
1532
- type: h.DAPP
1533
- };
1534
- s.set(r.id, r);
1535
- }
1536
- return s;
1537
- }
1538
- async saveAddresses(e) {
1539
- for (const t of e)
1540
- await this.walletDb.saveAddress(t);
1541
- }
1542
- async saveAccounts(e) {
1543
- for (const t of e.values())
1544
- await this.walletDb.saveAccount(t);
1545
- }
1546
- async subscribeAddresses(e, t = !1) {
1547
- const s = e.map(async (o) => {
1548
- const r = await this.rostrumService.subscribeAddress(o.address, this.onSubscribeEvent);
1549
- return { addr: o, result: r };
1550
- }), n = [], i = await Promise.all(s);
1551
- for (const { addr: o, result: r } of i)
1552
- if (r && typeof r == "string" && o.statusHash != r) {
1553
- if (t) {
1554
- const c = new Promise((d) => {
1555
- this.addressResolvers.set(o.address, d);
1556
- });
1557
- n.push(c);
1558
- }
1559
- this.registerUpdate({ address: o, result: r });
1560
- }
1561
- await Promise.all(n);
1562
- }
1563
- onSubscribeEvent = (e) => {
1564
- if (!Array.isArray(e) || e.length < 2)
1565
- return;
1566
- const [t, s] = e, i = this.getAllAddresses().find((o) => o.address === t);
1567
- i && i.statusHash !== s && this.registerUpdate({ address: i, result: s });
1568
- };
1569
- registerUpdate(e) {
1570
- this.pendingUpdates.set(e.address.address, e), clearTimeout(this.updateTimer), this.updateTimer = setTimeout(() => {
1571
- this.processPendingUpdates();
1572
- }, T.DEBOUNCE_MS);
1573
- }
1574
- async processPendingUpdates() {
1575
- if (this.pendingUpdates.size !== 0)
1576
- try {
1577
- this.notify({ type: "sync_wallet", loading: !0 }), console.log(`Processing ${this.pendingUpdates.size} pending updates...`);
1578
- const e = Array.from(this.pendingUpdates);
1579
- this.pendingUpdates.clear();
1580
- const t = [], s = [], n = [];
1581
- for (const [, r] of e)
1582
- if (this.isAccountAddress(r.address)) {
1583
- const c = this.fetchAndUpdateAccount(r.address, r.result);
1584
- t.push(c);
1585
- } else if (this.isVaultAddress(r.address)) {
1586
- const c = this.fetchAndUpdateVault(r.address, r.result);
1587
- s.push(c);
1588
- } else {
1589
- const c = this.fetchAndUpdateAddress(r.address, r.result);
1590
- n.push(c);
1591
- }
1592
- const i = await Promise.all(t);
1593
- await Promise.all(s);
1594
- const o = await Promise.all(n);
1595
- if (this.addressResolvers.size > 0)
1596
- for (const [r] of e) {
1597
- const c = this.addressResolvers.get(r);
1598
- c && (c(), this.addressResolvers.delete(r));
1599
- }
1600
- await Promise.all([this.postProcessWalletUpdate(o), this.postProcessAccountsUpdate(i)]);
1601
- } catch (e) {
1602
- console.error("Error processing pending updates:", e);
1603
- } finally {
1604
- this.notify({ type: "sync_wallet", loading: !1 });
1605
- }
1606
- }
1607
- async postProcessWalletUpdate(e) {
1608
- if (e.length === 0)
1609
- return;
1610
- const t = /* @__PURE__ */ new Map();
1611
- for (const { txs: o } of e)
1612
- for (const r of o)
1613
- t.set(r.tx_hash, r);
1614
- await this.checkGapLimit(y.RECEIVE), await this.checkGapLimit(y.CHANGE);
1615
- const s = this.getMainAddresses(), n = ee(s.map((o) => o.balance)), i = K(s.map((o) => o.tokensBalance));
1616
- this.notify({ type: "account_balance_updated", accountId: w, balance: n, tokensBalance: i }), this.notify({ type: "main_address_updated", address: this.getReceiveAddress() }), await this.postProcessActivity(w, Array.from(t.values()), s.map((o) => o.address), i);
1617
- }
1618
- async postProcessAccountsUpdate(e) {
1619
- if (e.length === 0)
1620
- return;
1621
- const t = [];
1622
- for (const { address: s, txs: n } of e) {
1623
- const i = s;
1624
- this.notify({ type: "account_balance_updated", accountId: i.id, balance: i.balance, tokensBalance: i.tokensBalance });
1625
- const o = this.postProcessActivity(i.id, n, [i.address], i.tokensBalance);
1626
- t.push(o);
1627
- }
1628
- await Promise.all(t);
1629
- }
1630
- async postProcessActivity(e, t, s, n) {
1631
- const i = [], o = this.assetService.syncNfts(e, n);
1632
- for (const r of t) {
1633
- const c = this.transactionService.classifyAndSaveTransaction(e, r.tx_hash, s);
1634
- i.push(c);
1635
- }
1636
- i.push(o), await Promise.all(i);
1637
- }
1638
- async fetchAndUpdateAddress(e, t) {
1639
- e.statusHash = t, e.balance = await this.rostrumService.getBalance(e.address), e.tokensBalance = await this.rostrumService.getTokensBalance(e.address);
1640
- const s = await this.transactionService.fetchTransactionsHistory(e.address, e.height);
1641
- return e.height = s.lastHeight, e.used || (e.used = s.txs.length > 0), await this.walletDb.saveAddress(e), { address: e, txs: s.txs };
1642
- }
1643
- async fetchAndUpdateAccount(e, t) {
1644
- e.statusHash = t, e.balance = await this.rostrumService.getBalance(e.address), e.tokensBalance = await this.rostrumService.getTokensBalance(e.address);
1645
- const s = await this.transactionService.fetchTransactionsHistory(e.address, e.height);
1646
- return e.height = s.lastHeight, await this.walletDb.saveAccount(e), { address: e, txs: s.txs };
1647
- }
1648
- async fetchAndUpdateVault(e, t) {
1649
- e.statusHash = t, e.balance = await this.rostrumService.getBalance(e.address);
1650
- const s = await this.transactionService.fetchTransactionsHistory(e.address, e.height);
1651
- return e.height = s.lastHeight, await this.walletDb.saveVault(e), this.notify({ type: "vault_balance_updated", address: e.address, balance: e.balance }), { address: e, txs: s.txs };
1652
- }
1653
- async checkGapLimit(e) {
1654
- const t = e === y.RECEIVE ? this.receiveAddresses : this.changeAddresses, s = e === y.RECEIVE ? "Receive" : "Change", n = t.filter((i) => !i.used).length;
1655
- if (n < T.GAP_LIMIT) {
1656
- const i = T.GAP_LIMIT - n, o = t[t.length - 1].idx;
1657
- console.log(`Deriving ${i} more ${s} addresses...`);
1658
- const r = this.deriveAddresses(e, o + 1, i);
1659
- e === y.RECEIVE ? this.receiveAddresses.push(...r) : this.changeAddresses.push(...r), await this.saveAddresses(r), await this.subscribeAddresses(r);
1660
- }
1661
- }
1662
- async addNewAccount(e, t) {
1663
- const s = k(h.DAPP, 0, e), n = this.keyManager.getKey(s).privateKey.toAddress().toString(), i = {
1664
- id: e,
1665
- name: t,
1666
- address: n,
1667
- height: 0,
1668
- hidden: 0,
1669
- statusHash: "",
1670
- balance: { confirmed: "0", unconfirmed: "0" },
1671
- tokensBalance: {},
1672
- type: h.DAPP
1673
- };
1674
- this.accounts.set(e, i), this.accountsAddressToId.set(n, e), await this.walletDb.saveAccount(i), this.notify({
1675
- type: "new_account",
1676
- account: {
1677
- id: i.id,
1678
- name: i.name,
1679
- address: i.address,
1680
- balance: i.balance,
1681
- tokensBalance: i.tokensBalance,
1682
- sessions: {}
1683
- }
1684
- }), await this.subscribeAddresses([i]);
1685
- }
1686
- async updateAccountName(e, t) {
1687
- if (!t)
1688
- return;
1689
- const s = this.accounts.get(e);
1690
- s.name = t, await this.walletDb.updateAccountName(e, t);
1691
- }
1692
- rescanAccount(e) {
1693
- if (e == w) {
1694
- const t = this.getMainAddresses();
1695
- for (const s of t)
1696
- s.height = 0, this.registerUpdate({ address: s, result: s.statusHash });
1697
- } else {
1698
- const t = this.accounts.get(e);
1699
- t.height = 0, this.registerUpdate({ address: t, result: t.statusHash });
1700
- }
1701
- }
1702
- getVaultNextIndex() {
1703
- return this.vaults.size == 0 ? 0 : Math.max(...Array.from(this.vaults.values(), (e) => e.idx)) + 1;
1704
- }
1705
- async addNewVault(e, t, s) {
1706
- const n = {
1707
- address: e,
1708
- block: t,
1709
- idx: s,
1710
- height: 0,
1711
- statusHash: "",
1712
- balance: { confirmed: "0", unconfirmed: "0" },
1713
- tokensBalance: {},
1714
- type: h.VAULT
1715
- };
1716
- await this.addVault(n);
1717
- }
1718
- async addVault(e) {
1719
- this.vaults.set(e.address, e), await this.walletDb.saveVault(e), this.notify({
1720
- type: "new_vault",
1721
- vault: {
1722
- address: e.address,
1723
- balance: e.balance,
1724
- block: e.block,
1725
- index: e.idx
1726
- }
1727
- }), await this.subscribeAddresses([e]);
1728
- }
1729
- async rescanVaults() {
1730
- let e = !1;
1731
- const t = await this.discoveryService.discoverVaults(this.getMainAddresses().map((n) => n.address)), s = [];
1732
- for (const [n, i] of t)
1733
- this.vaults.has(n) || (e = !0, s.push(this.addVault(i)));
1734
- return await Promise.all(s), e;
1735
- }
1736
- isVaultAddress(e) {
1737
- return e.type == h.VAULT;
1738
- }
1739
- isAccountAddress(e) {
1740
- return e.type == h.DAPP;
1741
- }
1742
- isMainAddress(e) {
1743
- return e.type == h.MAIN;
1744
- }
998
+ function $(t, n) {
999
+ if (n.length !== 2) return;
1000
+ let r = Y(), i = Z(t), a = Q(n);
1001
+ return e.fromScriptTemplate(r, i, a).toString();
1745
1002
  }
1746
- const ze = {
1747
- isWalletExist: !1,
1748
- isAuthorized: !1
1749
- }, de = S({
1750
- name: "auth",
1751
- initialState: ze,
1752
- reducers: {
1753
- setWalletExist: (a, e) => {
1754
- a.isWalletExist = e.payload;
1755
- },
1756
- setAuthorized: (a, e) => {
1757
- a.isAuthorized = e.payload;
1758
- }
1759
- }
1760
- }), Gt = de.actions, qe = de.reducer, Xe = {
1761
- modalType: null,
1762
- currentRequest: null
1763
- }, ue = S({
1764
- name: "dappModal",
1765
- initialState: Xe,
1766
- reducers: {
1767
- showRequest(a, e) {
1768
- a.modalType = e.payload.type, a.currentRequest = e.payload;
1769
- },
1770
- clear(a) {
1771
- a.modalType = null, a.currentRequest = null;
1772
- }
1773
- }
1774
- }), Jt = ue.actions, Ye = ue.reducer, Ze = {
1775
- counter: 0,
1776
- loading: !1
1777
- }, le = S({
1778
- name: "loader",
1779
- initialState: Ze,
1780
- reducers: {
1781
- setLoader: (a, e) => {
1782
- const t = e.payload.loading ? a.counter + 1 : Math.max(0, a.counter - 1);
1783
- a.counter = t, a.loading = t > 0, a.text = e.payload.text;
1784
- }
1785
- }
1786
- }), jt = le.actions, Qe = le.reducer, et = {
1787
- currency: "usd",
1788
- data: {}
1789
- }, $ = Ne("market/updateMarketData", async (a, e) => {
1790
- const t = e.getState();
1791
- return await Ve(t.market.currency);
1792
- }), he = S({
1793
- name: "market",
1794
- initialState: et,
1795
- reducers: {
1796
- setCurrency: (a, e) => {
1797
- a.currency = e.payload;
1798
- },
1799
- setMarketData: (a, e) => {
1800
- a.data = e.payload;
1801
- }
1802
- },
1803
- extraReducers: (a) => {
1804
- a.addCase($.fulfilled, (e, t) => {
1805
- e.data = t.payload;
1806
- }).addCase($.rejected, (e, t) => {
1807
- console.error(t.error.message);
1808
- });
1809
- }
1810
- }), zt = { updateMarketData: $ }, qt = he.actions, tt = he.reducer, st = {
1811
- wallet: {},
1812
- web3: {}
1813
- }, pe = S({
1814
- name: "notifications",
1815
- initialState: st,
1816
- reducers: {
1817
- addNotification: (a, e) => {
1818
- e.payload.type == "wallet" ? a.wallet[e.payload.id] = e.payload : e.payload.type == "web3" && (a.web3[e.payload.id] = e.payload);
1819
- },
1820
- removeNotification: (a, e) => {
1821
- delete a.wallet[e.payload], delete a.web3[e.payload];
1822
- },
1823
- clearAll: (a, e) => {
1824
- e.payload === "wallet" ? a.wallet = {} : e.payload === "web3" ? a.web3 = {} : e.payload === "all" && (a.wallet = {}, a.web3 = {});
1825
- }
1826
- }
1827
- }), Xt = pe.actions, at = pe.reducer, nt = {
1828
- status: "Offline",
1829
- height: 0,
1830
- hasNetwork: !0,
1831
- isSuspended: !1
1832
- }, fe = S({
1833
- name: "status",
1834
- initialState: nt,
1835
- reducers: {
1836
- setHeight: (a, e) => {
1837
- e.payload > 0 && (a.status = "Online"), a.height = e.payload;
1838
- },
1839
- setOffline: (a) => {
1840
- a.status = "Offline";
1841
- },
1842
- setHasNetwork: (a, e) => {
1843
- a.hasNetwork = e.payload;
1844
- },
1845
- setIsSuspended: (a, e) => {
1846
- a.isSuspended = e.payload;
1847
- }
1848
- }
1849
- }), Yt = fe.actions, it = fe.reducer, rt = {
1850
- isAuthorized: !1,
1851
- selectedAccount: w,
1852
- accounts: {
1853
- "-1": {
1854
- id: w,
1855
- name: "Main Wallet",
1856
- address: "",
1857
- balance: { confirmed: "0", unconfirmed: "0" },
1858
- tokensBalance: {},
1859
- sessions: {}
1860
- }
1861
- },
1862
- vaults: {},
1863
- sync: !1,
1864
- initLoad: !0,
1865
- txUpdateTrigger: 0,
1866
- nftsUpdateTrigger: 0,
1867
- tokensUpdateTrigger: 0
1868
- }, me = S({
1869
- name: "wallet",
1870
- initialState: rt,
1871
- reducers: {
1872
- setInitLoad: (a, e) => {
1873
- a.initLoad = e.payload;
1874
- },
1875
- setSelectedAccount: (a, e) => {
1876
- a.selectedAccount = e.payload;
1877
- },
1878
- setSync: (a, e) => {
1879
- a.sync = e.payload;
1880
- },
1881
- setVault: (a, e) => {
1882
- a.vaults[e.payload.address] = e.payload;
1883
- },
1884
- setVaultBalance: (a, e) => {
1885
- a.vaults[e.payload.address].balance = e.payload.balance;
1886
- },
1887
- setAccount: (a, e) => {
1888
- a.accounts[e.payload.id] = e.payload;
1889
- },
1890
- setMainAddress: (a, e) => {
1891
- a.accounts[w].address = e.payload;
1892
- },
1893
- setAccountBalance: (a, e) => {
1894
- a.accounts[e.payload.id].balance = e.payload.balance, a.accounts[e.payload.id].tokensBalance = e.payload.tokensBalance;
1895
- },
1896
- setAccountName: (a, e) => {
1897
- a.accounts[e.payload.id].name = e.payload.name;
1898
- },
1899
- refreshTxs: (a) => {
1900
- a.txUpdateTrigger++;
1901
- },
1902
- refreshNfts: (a) => {
1903
- a.nftsUpdateTrigger++;
1904
- },
1905
- refreshTokens: (a) => {
1906
- a.tokensUpdateTrigger++;
1907
- },
1908
- addSession(a, e) {
1909
- const { accountId: t, sessionInfo: s } = e.payload;
1910
- a.accounts[t].sessions[s.details.sessionId] = s;
1911
- },
1912
- removeSession(a, e) {
1913
- const { accountId: t, sessionId: s } = e.payload;
1914
- a.accounts[t].sessions[s] && delete a.accounts[t].sessions[s];
1915
- },
1916
- clearSessions(a, e) {
1917
- a.accounts[e.payload.accountId].sessions = {};
1918
- }
1919
- }
1920
- }), Zt = me.actions, ot = me.reducer, Qt = {
1921
- loader: Qe,
1922
- dapp: Ye,
1923
- status: it,
1924
- wallet: ot,
1925
- auth: qe,
1926
- notifications: at,
1927
- market: tt
1928
- }, g = Me.withTypes(), es = () => g((a) => a.auth), ts = (a) => g((e) => e.market.data[a]), ss = () => g((a) => a.status.height), as = (a) => g((e) => e.wallet.accounts[a]), ns = () => g((a) => a.wallet.selectedAccount), is = () => g((a) => Math.max(...Object.keys(a.wallet.accounts).map(Number))), rs = (a) => g((e) => e.wallet.accounts[a].address), os = (a) => g((e) => e.wallet.accounts[a].balance), cs = (a, e) => g((t) => t.wallet.accounts[a].tokensBalance[e]), ds = (a, e) => g((t) => t.wallet.accounts[a].sessions[e]), us = () => g((a) => a.wallet.vaults), ge = G(
1929
- [(a) => a.notifications.wallet],
1930
- (a) => Object.values(a).sort((e, t) => t.createdAt - e.createdAt)
1931
- ), ye = G(
1932
- [(a) => a.notifications.web3],
1933
- (a) => Object.values(a).sort((e, t) => t.createdAt - e.createdAt)
1934
- ), ct = G(
1935
- [ge, ye],
1936
- (a, e) => [...a, ...e].sort((t, s) => s.createdAt - t.createdAt)
1937
- ), ls = () => g(ge), hs = () => g(ye), ps = () => g(ct);
1938
- export {
1939
- h as AccountType,
1940
- Ut as AssetService,
1941
- ce as CURRENCIES,
1942
- Mt as KVStore,
1943
- Pt as KeyManager,
1944
- y as KeySpace,
1945
- w as MAIN_WALLET_ID,
1946
- Q as MAX_INT64,
1947
- ie as RostrumService,
1948
- te as SUPPORTED_TOKENS,
1949
- $t as SessionManager,
1950
- N as SessionRequestType,
1951
- Dt as TransactionService,
1952
- Wt as TransactionTransformer,
1953
- Ee as VAULT_FIRST_BLOCK,
1954
- yt as VAULT_SCRIPT_PREFIX,
1955
- Ct as WalletCache,
1956
- Et as WalletDB,
1957
- T as WalletManager,
1958
- Gt as authActions,
1959
- qe as authReducer,
1960
- Ft as calculateFiatValue,
1961
- St as capitalizeFirstLetter,
1962
- Kt as currencyCodes,
1963
- De as currencySymbols,
1964
- J as currentTimestamp,
1965
- Jt as dappModalActions,
1966
- Ye as dappModalReducer,
1967
- Ht as encryptMnemonic,
1968
- vt as estimateDateByFutureBlock,
1969
- He as formatMoney,
1970
- Vt as generateNewMnemonic,
1971
- We as generateVaultAddress,
1972
- Le as generateVaultConstraint,
1973
- $e as generateVaultVisibleArgs,
1974
- ae as getAddressBuffer,
1975
- _t as getAssetFileUrl,
1976
- Be as getAssetMetadata,
1977
- Lt as getCurrencySymbol,
1978
- At as getExplorerUrl,
1979
- Tt as getFileMediaType,
1980
- It as getFileMimeType,
1981
- Ve as getMarketData,
1982
- Fe as getVaultConstraintHash,
1983
- Re as getVaultTemplate,
1984
- Ke as getVaultTemplateHash,
1985
- wt as isGenesisHashValid,
1986
- _e as isMnemonicValid,
1987
- M as isNullOrEmpty,
1988
- C as isTestnet,
1989
- R as isValidNexaAddress,
1990
- k as keyPathToString,
1991
- jt as loaderActions,
1992
- Qe as loaderReducer,
1993
- qt as marketActions,
1994
- tt as marketReducer,
1995
- zt as marketThunks,
1996
- Xt as notificationsActions,
1997
- at as notificationsReducer,
1998
- Ot as parseTokenDataUrl,
1999
- Nt as prettifyAmount,
2000
- Qt as sharedReducers,
2001
- xt as sleep,
2002
- Yt as statusActions,
2003
- it as statusReducer,
2004
- Ce as stringToKeyPath,
2005
- ee as sumBalance,
2006
- K as sumTokensBalance,
2007
- U as tokenAmountToAssetAmount,
2008
- kt as tokenHexToAddr,
2009
- v as tokenIdToHex,
2010
- Bt as transformTokenIconUrl,
2011
- bt as truncateStringMiddle,
2012
- as as useAccount,
2013
- ps as useAllNotifications,
2014
- es as useAuth,
2015
- ss as useBlockHeight,
2016
- ds as useDAppSession,
2017
- is as useLastAccountId,
2018
- rs as useMainReceiveAddress,
2019
- ts as useMarketData,
2020
- ns as useSelectedAccount,
2021
- cs as useTokenBalance,
2022
- us as useVaults,
2023
- os as useWalletBalance,
2024
- ls as useWalletNotifications,
2025
- hs as useWeb3Notifications,
2026
- Rt as validateAndDecryptMnemonic,
2027
- Zt as walletActions,
2028
- ot as walletReducer
1003
+ // src/services/session.ts
1004
+ var Pe = class {
1005
+ constructor(e, t) {
1006
+ this.walletDb = e, this.keyManager = t, this.providers = /* @__PURE__ */ new Map(), this.handlers = /* @__PURE__ */ new Map(), this.removeOnClose = !0;
1007
+ }
1008
+ onUpdate(e) {
1009
+ this.updateCallback = e;
1010
+ }
1011
+ notify(e) {
1012
+ this.updateCallback?.(e);
1013
+ }
1014
+ getHandler(e) {
1015
+ return this.handlers.get(e);
1016
+ }
1017
+ add(e, t, n) {
1018
+ this.providers.has(e.id) || this.providers.set(e.id, /* @__PURE__ */ new Map());
1019
+ let r = n.details.sessionId, i = this.providers.get(e.id);
1020
+ this.registerHandlers(e, t, r), i.set(r, t), this.notify({
1021
+ type: "session_added",
1022
+ accountId: e.id,
1023
+ sessionInfo: n
1024
+ });
1025
+ }
1026
+ remove(e, t) {
1027
+ let n = this.providers.get(e);
1028
+ if (n) {
1029
+ let r = n.get(t);
1030
+ r && (r.disconnect(), n.delete(t)), n.size === 0 && this.providers.delete(e);
1031
+ }
1032
+ this.notify({
1033
+ type: "session_removed",
1034
+ accountId: e,
1035
+ sessionId: t
1036
+ });
1037
+ }
1038
+ async reload(e) {
1039
+ for (let t of e.values()) {
1040
+ if (t.id == -1) continue;
1041
+ let e = await this.walletDb.getAccountSessions(t.id), n = this.providers.get(t.id), r = e.map(async (e) => {
1042
+ if (n?.has(e.sessionId)) return;
1043
+ let r;
1044
+ try {
1045
+ r = new oe(e.uri);
1046
+ let n = r.getSessionInfo();
1047
+ await r.connect(3e3);
1048
+ let i = await r.getAppInfo(2e3);
1049
+ await r.joinSession(t.address, 2e3);
1050
+ let a = await r.fetchPendingMessages();
1051
+ for (let e of a) this.notify({
1052
+ type: "new_notification",
1053
+ notification: {
1054
+ id: crypto.randomUUID(),
1055
+ createdAt: e.createdAt,
1056
+ type: "web3",
1057
+ title: "Request pending approval",
1058
+ message: `A connected dApp (${i.name}) has requested an action from your Account: ${t.name}. Review the request details before approving or rejecting.`,
1059
+ action: {
1060
+ type: "DAPP_REQUEST",
1061
+ account: t.id,
1062
+ sessionId: n.sessionId,
1063
+ payload: e.message
1064
+ }
1065
+ }
1066
+ });
1067
+ return {
1068
+ account: t,
1069
+ provider: r,
1070
+ metadata: {
1071
+ details: n,
1072
+ appInfo: i
1073
+ }
1074
+ };
1075
+ } catch (t) {
1076
+ console.error(`Failed to reload session ${e.sessionId}`, t), r?.disconnect(), await this.walletDb.removeSession(e.sessionId);
1077
+ }
1078
+ }), i = await Promise.allSettled(r);
1079
+ for (let e of i) e.status === "fulfilled" && e.value && this.add(e.value.account, e.value.provider, e.value.metadata);
1080
+ }
1081
+ }
1082
+ clear() {
1083
+ try {
1084
+ this.removeOnClose = !1;
1085
+ for (let [e, t] of this.providers) {
1086
+ for (let [, e] of t) e.disconnect();
1087
+ t.clear(), this.notify({
1088
+ type: "sessions_cleared",
1089
+ accountId: e
1090
+ });
1091
+ }
1092
+ this.providers.clear();
1093
+ } finally {
1094
+ this.removeOnClose = !0;
1095
+ }
1096
+ }
1097
+ async revoke(e, t) {
1098
+ let n = this.providers.get(e);
1099
+ if (n) {
1100
+ let e = n.get(t);
1101
+ e && await e.revokeSession();
1102
+ }
1103
+ }
1104
+ async replayMessage(e, t, n) {
1105
+ let r = this.providers.get(e);
1106
+ if (r) {
1107
+ let e = r.get(t);
1108
+ e && await e.replayMessage(n);
1109
+ }
1110
+ }
1111
+ registerHandlers(e, t, n) {
1112
+ t.onSessionDelete(() => this.walletDb.removeSession(n)), t.onClose(() => {
1113
+ this.removeOnClose && this.remove(e.id, n);
1114
+ });
1115
+ let r = (t, r) => new Promise((i, a) => {
1116
+ this.handlers.set(t, {
1117
+ resolve: i,
1118
+ reject: a
1119
+ }), this.notify({
1120
+ type: "new_request",
1121
+ request: {
1122
+ type: t,
1123
+ accountId: e.id,
1124
+ sessionId: n,
1125
+ request: r
1126
+ }
1127
+ });
1128
+ });
1129
+ t.onSignMessage((e) => r(w.SignMessage, e)), t.onAddToken((e) => r(w.AddToken, e)), t.onSendTransaction((e) => r(w.SendTransaction, e)), t.onSignTransaction((e) => r(w.SignTransaction, e)), t.onGetAccount(() => {
1130
+ let t = {
1131
+ account: S.DAPP,
1132
+ type: C.RECEIVE,
1133
+ index: e.id
1134
+ };
1135
+ return {
1136
+ name: e.name,
1137
+ address: e.address,
1138
+ pubkey: this.keyManager.getKey(t).publicKey.toString(),
1139
+ blockchain: "nexa",
1140
+ network: c.defaultNetwork.name,
1141
+ capabilities: {
1142
+ addToken: !0,
1143
+ sendTransaction: !0,
1144
+ signMessage: !0,
1145
+ signTransaction: !0
1146
+ }
1147
+ };
1148
+ });
1149
+ }
1150
+ }, Fe = class {
1151
+ constructor(e, t, n) {
1152
+ this.rostrumService = e, this.keyManager = t, this.assetService = n;
1153
+ }
1154
+ async transformRawTransaction(e, t) {
1155
+ let n = this.createContext(e, t);
1156
+ return await this.processInputs(n), this.processOutputs(n), this.signInputs(n), await this.processAssetMovements(n), n.txDetails;
1157
+ }
1158
+ createContext(e, t) {
1159
+ try {
1160
+ return {
1161
+ address: t.address,
1162
+ privateKey: this.keyManager.getKey(t.keyPath).privateKey,
1163
+ txDetails: {
1164
+ tx: new h(e),
1165
+ send: [],
1166
+ receive: []
1167
+ },
1168
+ myInputs: /* @__PURE__ */ new Map(),
1169
+ myOutputs: /* @__PURE__ */ new Map(),
1170
+ involvedAssets: /* @__PURE__ */ new Set(),
1171
+ inputsToSign: /* @__PURE__ */ new Set(),
1172
+ coveredOutputs: /* @__PURE__ */ new Set(),
1173
+ allMyOutputsCovered: !1
1174
+ };
1175
+ } catch {
1176
+ throw Error("Invalid transaction format.");
1177
+ }
1178
+ }
1179
+ async processInputs(e) {
1180
+ let t = [];
1181
+ for (let n = 0; n < e.txDetails.tx.inputs.length; n++) {
1182
+ let r = this.processInput(e, n);
1183
+ t.push(r);
1184
+ }
1185
+ await Promise.all(t);
1186
+ }
1187
+ async processInput(e, t) {
1188
+ let n = e.txDetails.tx.inputs[t], i = await this.rostrumService.getUtxo(r.bufferToHex(n.outpoint));
1189
+ if (i.status == "spent") throw Error("Input UTXO is already spent.");
1190
+ if (n.output = new u(i.amount, i.scriptpubkey), n.output.address == e.address) {
1191
+ let r = i.token_id_hex || "NEXA";
1192
+ e.myInputs.set(t, {
1193
+ address: e.address,
1194
+ nexaAmount: i.amount.toString(),
1195
+ assetId: r,
1196
+ assetAmount: M(i.group_quantity) || i.amount.toString()
1197
+ }), e.involvedAssets.add(r), n.scriptSig.isEmpty() && e.inputsToSign.add(t);
1198
+ }
1199
+ n.scriptSig.findPlaceholder() > 0 && e.inputsToSign.add(t);
1200
+ }
1201
+ processOutputs(e) {
1202
+ for (let t = 0; t < e.txDetails.tx.outputs.length; t++) {
1203
+ let n = e.txDetails.tx.outputs[t].toObject();
1204
+ if (n.address !== e.address) continue;
1205
+ let r = n.groupId ? j(n.groupId) : "NEXA", i = {
1206
+ address: n.address,
1207
+ nexaAmount: n.value.toString(),
1208
+ assetId: r,
1209
+ assetAmount: M(n.groupAmount) || n.value.toString()
1210
+ };
1211
+ e.involvedAssets.add(r), e.myOutputs.set(t, i);
1212
+ }
1213
+ }
1214
+ signInputs(e) {
1215
+ if (e.inputsToSign.size == 0) throw Error("No inputs to sign.");
1216
+ for (let t of e.inputsToSign) {
1217
+ let n = e.txDetails.tx.inputs[t], r = this.validateAndGetSubscript(n);
1218
+ if (n.scriptSig.isEmpty()) {
1219
+ e.allMyOutputsCovered = !0;
1220
+ let i = _.sign(e.txDetails.tx, t, m.ALL, r, e.privateKey).toTxFormat(), a = f.empty().add(e.privateKey.publicKey.toBuffer());
1221
+ n.scriptSig = ee.buildScriptTemplateIn(void 0, a, f.empty().add(i));
1222
+ } else {
1223
+ let i = n.scriptSig.findPlaceholder(), a = n.scriptSig.chunks[i].buf.subarray(64), o = m.fromBuffer(a);
1224
+ this.processSignatureCoverage(e, o);
1225
+ let s = _.sign(e.txDetails.tx, t, o, r, e.privateKey).toTxFormat(a);
1226
+ n.scriptSig.replaceChunk(i, f.empty().add(s));
1227
+ }
1228
+ }
1229
+ if (!e.allMyOutputsCovered) throw Error("Some of interested outputs are not covered by signatures.");
1230
+ }
1231
+ validateAndGetSubscript(e) {
1232
+ if (e.output.scriptPubKey.isPublicKeyTemplateOut()) {
1233
+ if (e.scriptSig.isEmpty() || e.scriptSig.isPublicKeyTemplateIn()) return f.empty().add(l.OP_FROMALTSTACK).add(l.OP_CHECKSIGVERIFY);
1234
+ throw Error("Invalid input script type.");
1235
+ }
1236
+ if (e.output.scriptPubKey.isScriptTemplateOut()) {
1237
+ if (!e.scriptSig.isScriptTemplateIn()) throw Error("Unsupported input script type.");
1238
+ let t = e.output.scriptPubKey.getTemplateHash(), n = e.scriptSig.chunks[0].buf;
1239
+ if (r.equals(t, s.sha256ripemd160(n)) || r.equals(t, s.sha256sha256(n))) return f.fromBuffer(n);
1240
+ throw Error("Invalid input script template.");
1241
+ }
1242
+ throw Error("Unsupported prevout script type.");
1243
+ }
1244
+ processSignatureCoverage(e, t) {
1245
+ if (!e.allMyOutputsCovered) {
1246
+ if (t.outType == d.TWO) e.coveredOutputs.add(t.outData[0]), e.coveredOutputs.add(t.outData[1]), this.checkSignatureCoverage(e);
1247
+ else if (t.outType == d.FIRSTN) {
1248
+ let n = t.outData[0];
1249
+ for (let t = 0; t < n; t++) e.coveredOutputs.add(t);
1250
+ this.checkSignatureCoverage(e);
1251
+ } else e.allMyOutputsCovered = !0;
1252
+ }
1253
+ }
1254
+ checkSignatureCoverage(e) {
1255
+ if (!e.allMyOutputsCovered) {
1256
+ for (let t of e.myOutputs.keys()) if (!e.coveredOutputs.has(t)) return;
1257
+ e.allMyOutputsCovered = !0;
1258
+ }
1259
+ }
1260
+ async processAssetMovements(e) {
1261
+ let t = Array.from(e.myInputs.values()), n = Array.from(e.myOutputs.values()), r = [];
1262
+ for (let i of e.involvedAssets) {
1263
+ let a = this.processAssetMovement(e, i, t, n);
1264
+ r.push(a);
1265
+ }
1266
+ await Promise.all(r);
1267
+ }
1268
+ async processAssetMovement(e, t, n, r) {
1269
+ let i = n.reduce((e, n) => n.assetId === t ? e + BigInt(n.assetAmount) : e, 0n), a = r.reduce((e, n) => n.assetId === t ? e + BigInt(n.assetAmount) : e, 0n);
1270
+ if (i > 0n || a > 0n) {
1271
+ let n = { amount: a - i };
1272
+ t !== "NEXA" && (n.asset = await this.assetService.getAssetInfo(t)), n.amount > 0n ? e.txDetails.receive.push(n) : n.amount < 0n && e.txDetails.send.push(n);
1273
+ }
1274
+ }
1275
+ }, Ie = 274710, Le = "0014461ad25081cb0119d034385ff154c8d3ad6bdd76", Re = class {
1276
+ constructor(e, t) {
1277
+ this.rostrumService = e, this.keyManager = t;
1278
+ }
1279
+ async discoverWalletIndex(e, t) {
1280
+ let n = 0, r = -1, i = [];
1281
+ for (;;) {
1282
+ let a = await Promise.all(Array.from({ length: R.GAP_LIMIT }, (r, i) => this.rostrumService.isAddressUsed(this.keyManager.deriveAddress(e, t, n + i))));
1283
+ if (a.some((e) => e)) r = n, i = a, n += R.GAP_LIMIT;
1284
+ else break;
1285
+ }
1286
+ if (r === -1) return -1;
1287
+ for (let e = R.GAP_LIMIT - 1; e >= 0; e--) if (i[e]) return r + e;
1288
+ return r;
1289
+ }
1290
+ async discoverVaults(e) {
1291
+ let t = await this.checkForVaults(e), n = /* @__PURE__ */ new Map();
1292
+ return t.forEach((e) => {
1293
+ let t = this.parseVaultDetails(e);
1294
+ t && n.set(t.address, t);
1295
+ }), n;
1296
+ }
1297
+ async checkForVaults(e) {
1298
+ let t = /* @__PURE__ */ new Set();
1299
+ return await Promise.all(e.map(async (e) => {
1300
+ if (e.height > 0 && e.height < Ie) return;
1301
+ let n = await this.rostrumService.getTransaction(e.tx_hash);
1302
+ for (let e of n.vout) e.scriptPubKey.hex.startsWith(Le) && t.add(e.scriptPubKey.hex);
1303
+ })), t;
1304
+ }
1305
+ parseVaultDetails(t) {
1306
+ let r = f.fromHex(t), a = new i().writeVarLengthBuf(r.toBuffer()).toBuffer(), o = new e(a).toString(), s = r.getVisibleArgs(), c = n.fromScriptNumBuffer(s.chunks[0].buf).toNumber(), l = p.isSmallIntOp(s.chunks[1].opcodenum) ? p.decodeOP_N(s.chunks[1].opcodenum) : n.fromScriptNumBuffer(s.chunks[1].buf).toNumber(), u = [c, l];
1307
+ if (o == $(this.keyManager.getKey({
1308
+ account: S.VAULT,
1309
+ type: C.RECEIVE,
1310
+ index: l
1311
+ }).publicKey, u)) return {
1312
+ address: o,
1313
+ block: c,
1314
+ idx: l,
1315
+ statusHash: "",
1316
+ balance: {
1317
+ confirmed: "0",
1318
+ unconfirmed: "0"
1319
+ },
1320
+ tokensBalance: {},
1321
+ height: 0,
1322
+ type: S.VAULT
1323
+ };
1324
+ }
1325
+ }, ze = class e {
1326
+ static {
1327
+ this.DEBOUNCE_MS = 2e3;
1328
+ }
1329
+ constructor(e, t, n, r, i, a) {
1330
+ this.keyManager = e, this.walletDb = t, this.rostrumService = n, this.assetService = r, this.transactionService = i, this.sessionManager = a, this.onSubscribeEvent = (e) => {
1331
+ if (!Array.isArray(e) || e.length < 2) return;
1332
+ let [t, n] = e, r = this.getAllAddresses().find((e) => e.address === t);
1333
+ r && r.statusHash !== n && this.registerUpdate({
1334
+ address: r,
1335
+ result: n
1336
+ });
1337
+ }, this.discoveryService = new Re(this.rostrumService, this.keyManager), this.accounts = /* @__PURE__ */ new Map(), this.accountsAddressToId = /* @__PURE__ */ new Map(), this.receiveAddresses = [], this.changeAddresses = [], this.vaults = /* @__PURE__ */ new Map(), this.pendingUpdates = /* @__PURE__ */ new Map(), this.addressResolvers = /* @__PURE__ */ new Map();
1338
+ }
1339
+ onUpdate(e) {
1340
+ this.updateCallback = e;
1341
+ }
1342
+ notify(e) {
1343
+ this.updateCallback?.(e);
1344
+ }
1345
+ getAllAddresses() {
1346
+ return [
1347
+ ...this.receiveAddresses,
1348
+ ...this.changeAddresses,
1349
+ ...this.accounts.values(),
1350
+ ...this.vaults.values()
1351
+ ];
1352
+ }
1353
+ getMainAddresses() {
1354
+ return [...this.receiveAddresses, ...this.changeAddresses];
1355
+ }
1356
+ getReceiveAddress() {
1357
+ return this.receiveAddresses.find((e) => !e.used).address;
1358
+ }
1359
+ getChangeAddress(e = -1) {
1360
+ return e == -1 ? this.changeAddresses.find((e) => !e.used).address : this.accounts.get(e).address;
1361
+ }
1362
+ getUsedAddressKeys(e = -1) {
1363
+ if (e != -1) {
1364
+ let t = this.accounts.get(e);
1365
+ return [{
1366
+ address: t.address,
1367
+ keyPath: I(S.DAPP, 0, t.id),
1368
+ balance: t.balance,
1369
+ tokensBalance: t.tokensBalance
1370
+ }];
1371
+ }
1372
+ return this.getMainAddresses().filter((e) => e.used).map((e) => ({
1373
+ address: e.address,
1374
+ keyPath: I(S.MAIN, e.space, e.idx),
1375
+ balance: e.balance,
1376
+ tokensBalance: e.tokensBalance
1377
+ }));
1378
+ }
1379
+ async reloadRostrum(e) {
1380
+ await this.rostrumService.setCurrentInstance(e), await this.rostrumService.disconnect(!0), await this.initRostrum(), await this.subscribeAddresses(this.getAllAddresses());
1381
+ }
1382
+ async initRostrum() {
1383
+ await this.rostrumService.connect(), await this.rostrumService.subscribeHeaders((e) => this.notify({
1384
+ type: "new_tip",
1385
+ tip: e
1386
+ }));
1387
+ }
1388
+ async initialize() {
1389
+ await this.initRostrum(), await this.walletDb.countAddresses() ? await this.loadWallet() : await this.discoverWallet();
1390
+ }
1391
+ async discoverWallet() {
1392
+ this.notify({
1393
+ type: "discover_wallet",
1394
+ loading: !0
1395
+ });
1396
+ let e = this.discoveryService.discoverWalletIndex(S.MAIN, C.RECEIVE), t = this.discoveryService.discoverWalletIndex(S.MAIN, C.CHANGE), n = this.discoveryService.discoverWalletIndex(S.DAPP, C.RECEIVE), [r, i, a] = await Promise.all([
1397
+ e,
1398
+ t,
1399
+ n
1400
+ ]);
1401
+ this.receiveAddresses = this.deriveAddresses(C.RECEIVE, 0, r + R.GAP_LIMIT + 1), this.changeAddresses = this.deriveAddresses(C.CHANGE, 0, i + R.GAP_LIMIT + 1), this.accounts = this.deriveAccounts(0, a < 0 ? 1 : a + 1), this.accounts.forEach((e) => this.accountsAddressToId.set(e.address, e.id)), await this.saveAddresses(this.receiveAddresses), await this.saveAddresses(this.changeAddresses), await this.saveAccounts(this.accounts), this.initState(), await this.initialSync(), this.notify({
1402
+ type: "discover_wallet",
1403
+ loading: !1
1404
+ }), this.notify({
1405
+ type: "load_wallet",
1406
+ loading: !1
1407
+ });
1408
+ }
1409
+ async loadWallet() {
1410
+ this.receiveAddresses = await this.walletDb.getReceiveAddresses(), this.changeAddresses = await this.walletDb.getChangeAddresses();
1411
+ let e = await this.walletDb.getAccounts();
1412
+ this.accounts = new Map(e.map((e) => [e.id, e])), this.accountsAddressToId = new Map(e.map((e) => [e.address, e.id]));
1413
+ let t = await this.walletDb.getVaults();
1414
+ this.vaults = new Map(t.map((e) => [e.address, e])), this.initState(), this.notify({
1415
+ type: "load_wallet",
1416
+ loading: !1
1417
+ }), await this.reconnectSync();
1418
+ }
1419
+ async initialSync() {
1420
+ await this.subscribeAddresses(this.getAllAddresses(), !0);
1421
+ }
1422
+ async reconnectSync() {
1423
+ await Promise.all([this.sessionManager.reload(this.accounts), this.subscribeAddresses(this.getAllAddresses())]);
1424
+ }
1425
+ initState() {
1426
+ let e = this.getMainAddresses();
1427
+ this.notify({
1428
+ type: "new_account",
1429
+ account: {
1430
+ id: -1,
1431
+ name: "HD Wallet",
1432
+ address: this.getReceiveAddress(),
1433
+ balance: N(e.map((e) => e.balance)),
1434
+ tokensBalance: P(e.map((e) => e.tokensBalance)),
1435
+ sessions: {}
1436
+ }
1437
+ });
1438
+ for (let e of this.accounts.values()) this.notify({
1439
+ type: "new_account",
1440
+ account: {
1441
+ id: e.id,
1442
+ name: e.name,
1443
+ address: e.address,
1444
+ balance: e.balance,
1445
+ tokensBalance: e.tokensBalance,
1446
+ sessions: {}
1447
+ }
1448
+ });
1449
+ for (let e of this.vaults.values()) this.notify({
1450
+ type: "new_vault",
1451
+ vault: {
1452
+ address: e.address,
1453
+ balance: e.balance,
1454
+ block: e.block,
1455
+ index: e.idx
1456
+ }
1457
+ });
1458
+ }
1459
+ deriveAddresses(e, t, n) {
1460
+ let r = [];
1461
+ for (let i = t; i < t + n; i++) {
1462
+ let t = {
1463
+ address: this.keyManager.deriveAddress(S.MAIN, e, i),
1464
+ space: e,
1465
+ idx: i,
1466
+ used: !1,
1467
+ height: 0,
1468
+ statusHash: "",
1469
+ balance: {
1470
+ confirmed: "0",
1471
+ unconfirmed: "0"
1472
+ },
1473
+ tokensBalance: {},
1474
+ type: S.MAIN
1475
+ };
1476
+ r.push(t);
1477
+ }
1478
+ return r;
1479
+ }
1480
+ deriveAccounts(e, t) {
1481
+ let n = /* @__PURE__ */ new Map();
1482
+ for (let r = e; r < e + t; r++) {
1483
+ let e = {
1484
+ id: r,
1485
+ name: `Account ${r + 1}`,
1486
+ address: this.keyManager.deriveAddress(S.DAPP, C.RECEIVE, r),
1487
+ height: 0,
1488
+ hidden: 0,
1489
+ statusHash: "",
1490
+ balance: {
1491
+ confirmed: "0",
1492
+ unconfirmed: "0"
1493
+ },
1494
+ tokensBalance: {},
1495
+ type: S.DAPP
1496
+ };
1497
+ n.set(e.id, e);
1498
+ }
1499
+ return n;
1500
+ }
1501
+ async saveAddresses(e) {
1502
+ for (let t of e) await this.walletDb.saveAddress(t);
1503
+ }
1504
+ async saveAccounts(e) {
1505
+ for (let t of e.values()) await this.walletDb.saveAccount(t);
1506
+ }
1507
+ async subscribeAddresses(e, t = !1) {
1508
+ let n = e.map(async (e) => ({
1509
+ addr: e,
1510
+ result: await this.rostrumService.subscribeAddress(e.address, this.onSubscribeEvent)
1511
+ })), r = [], i = await Promise.all(n);
1512
+ for (let { addr: e, result: n } of i) if (n && typeof n == "string" && e.statusHash != n) {
1513
+ if (t) {
1514
+ let t = new Promise((t) => {
1515
+ this.addressResolvers.set(e.address, t);
1516
+ });
1517
+ if (r.push(t), !this.discoveryResolver) {
1518
+ let e = new Promise((e) => {
1519
+ this.discoveryResolver = e;
1520
+ });
1521
+ r.push(e);
1522
+ }
1523
+ }
1524
+ this.registerUpdate({
1525
+ address: e,
1526
+ result: n
1527
+ });
1528
+ }
1529
+ await Promise.all(r);
1530
+ }
1531
+ registerUpdate(t) {
1532
+ this.pendingUpdates.set(t.address.address, t), clearTimeout(this.updateTimer), this.updateTimer = setTimeout(() => {
1533
+ this.processPendingUpdates();
1534
+ }, e.DEBOUNCE_MS);
1535
+ }
1536
+ async processPendingUpdates() {
1537
+ if (this.pendingUpdates.size !== 0) try {
1538
+ this.notify({
1539
+ type: "sync_wallet",
1540
+ loading: !0
1541
+ }), console.log(`Processing ${this.pendingUpdates.size} pending updates...`);
1542
+ let e = Array.from(this.pendingUpdates);
1543
+ this.pendingUpdates.clear();
1544
+ let t = [], n = [], r = [];
1545
+ for (let [, i] of e) if (this.isAccountAddress(i.address)) {
1546
+ let e = this.fetchAndUpdateAccount(i.address, i.result);
1547
+ t.push(e);
1548
+ } else if (this.isVaultAddress(i.address)) {
1549
+ let e = this.fetchAndUpdateVault(i.address, i.result);
1550
+ n.push(e);
1551
+ } else {
1552
+ let e = this.fetchAndUpdateAddress(i.address, i.result);
1553
+ r.push(e);
1554
+ }
1555
+ let i = !1;
1556
+ if (this.addressResolvers.size > 0) {
1557
+ for (let [t] of e) {
1558
+ let e = this.addressResolvers.get(t);
1559
+ e && (e(), this.addressResolvers.delete(t));
1560
+ }
1561
+ i = this.addressResolvers.size === 0;
1562
+ }
1563
+ let a = await Promise.all(t);
1564
+ await Promise.all(n);
1565
+ let o = await Promise.all(r), s = [this.postProcessWalletUpdate(o, i), this.postProcessAccountsUpdate(a)];
1566
+ i && s.push(this.recoverTokens()), await Promise.all(s), i && this.discoveryResolver && (this.discoveryResolver(), this.discoveryResolver = void 0);
1567
+ } catch (e) {
1568
+ console.error("Error processing pending updates:", e);
1569
+ } finally {
1570
+ this.notify({
1571
+ type: "sync_wallet",
1572
+ loading: !1
1573
+ });
1574
+ }
1575
+ }
1576
+ async postProcessWalletUpdate(e, t) {
1577
+ if (e.length === 0) return;
1578
+ let n = /* @__PURE__ */ new Map();
1579
+ for (let { txs: t } of e) for (let e of t) n.set(e.tx_hash, e);
1580
+ let r = Array.from(n.values());
1581
+ t && this.recoverVaults(r), await this.checkGapLimit(C.RECEIVE), await this.checkGapLimit(C.CHANGE);
1582
+ let i = this.getMainAddresses(), a = N(i.map((e) => e.balance)), o = P(i.map((e) => e.tokensBalance));
1583
+ this.notify({
1584
+ type: "account_balance_updated",
1585
+ accountId: -1,
1586
+ balance: a,
1587
+ tokensBalance: o
1588
+ }), this.notify({
1589
+ type: "main_address_updated",
1590
+ address: this.getReceiveAddress()
1591
+ }), await this.postProcessActivity(-1, r, i.map((e) => e.address), o);
1592
+ }
1593
+ async postProcessAccountsUpdate(e) {
1594
+ if (e.length === 0) return;
1595
+ let t = [];
1596
+ for (let { address: n, txs: r } of e) {
1597
+ let e = n;
1598
+ this.notify({
1599
+ type: "account_balance_updated",
1600
+ accountId: e.id,
1601
+ balance: e.balance,
1602
+ tokensBalance: e.tokensBalance
1603
+ });
1604
+ let i = this.postProcessActivity(e.id, r, [e.address], e.tokensBalance);
1605
+ t.push(i);
1606
+ }
1607
+ await Promise.all(t);
1608
+ }
1609
+ async postProcessActivity(e, t, n, r) {
1610
+ let i = [], a = this.assetService.syncNfts(e, r);
1611
+ for (let r of t) {
1612
+ let t = this.transactionService.classifyAndSaveTransaction(e, r.tx_hash, n);
1613
+ i.push(t);
1614
+ }
1615
+ i.push(a), await Promise.all(i);
1616
+ }
1617
+ async fetchAndUpdateAddress(e, t) {
1618
+ e.statusHash = t, e.balance = await this.rostrumService.getBalance(e.address), e.tokensBalance = await this.rostrumService.getTokensBalance(e.address);
1619
+ let n = await this.transactionService.fetchTransactionsHistory(e.address, e.height);
1620
+ return e.height = n.lastHeight, e.used ||= n.txs.length > 0, await this.walletDb.saveAddress(e), {
1621
+ address: e,
1622
+ txs: n.txs
1623
+ };
1624
+ }
1625
+ async fetchAndUpdateAccount(e, t) {
1626
+ e.statusHash = t, e.balance = await this.rostrumService.getBalance(e.address), e.tokensBalance = await this.rostrumService.getTokensBalance(e.address);
1627
+ let n = await this.transactionService.fetchTransactionsHistory(e.address, e.height);
1628
+ return e.height = n.lastHeight, await this.walletDb.saveAccount(e), {
1629
+ address: e,
1630
+ txs: n.txs
1631
+ };
1632
+ }
1633
+ async fetchAndUpdateVault(e, t) {
1634
+ e.statusHash = t, e.balance = await this.rostrumService.getBalance(e.address);
1635
+ let n = await this.transactionService.fetchTransactionsHistory(e.address, e.height);
1636
+ return e.height = n.lastHeight, await this.walletDb.saveVault(e), this.notify({
1637
+ type: "vault_balance_updated",
1638
+ address: e.address,
1639
+ balance: e.balance
1640
+ }), {
1641
+ address: e,
1642
+ txs: n.txs
1643
+ };
1644
+ }
1645
+ async checkGapLimit(e) {
1646
+ let t = e === C.RECEIVE ? this.receiveAddresses : this.changeAddresses, n = e === C.RECEIVE ? "Receive" : "Change", r = t.filter((e) => !e.used).length;
1647
+ if (r < R.GAP_LIMIT) {
1648
+ let i = R.GAP_LIMIT - r, a = t[t.length - 1].idx;
1649
+ console.log(`Deriving ${i} more ${n} addresses...`);
1650
+ let o = this.deriveAddresses(e, a + 1, i);
1651
+ e === C.RECEIVE ? this.receiveAddresses.push(...o) : this.changeAddresses.push(...o), await this.saveAddresses(o), await this.subscribeAddresses(o);
1652
+ }
1653
+ }
1654
+ async addNewAccount(e, t) {
1655
+ let n = this.keyManager.deriveAddress(S.DAPP, C.RECEIVE, e), r = {
1656
+ id: e,
1657
+ name: t,
1658
+ address: n,
1659
+ height: 0,
1660
+ hidden: 0,
1661
+ statusHash: "",
1662
+ balance: {
1663
+ confirmed: "0",
1664
+ unconfirmed: "0"
1665
+ },
1666
+ tokensBalance: {},
1667
+ type: S.DAPP
1668
+ };
1669
+ this.accounts.set(e, r), this.accountsAddressToId.set(n, e), await this.walletDb.saveAccount(r), this.notify({
1670
+ type: "new_account",
1671
+ account: {
1672
+ id: r.id,
1673
+ name: r.name,
1674
+ address: r.address,
1675
+ balance: r.balance,
1676
+ tokensBalance: r.tokensBalance,
1677
+ sessions: {}
1678
+ }
1679
+ }), await this.subscribeAddresses([r]);
1680
+ }
1681
+ async updateAccountName(e, t) {
1682
+ if (!t) return;
1683
+ let n = this.accounts.get(e);
1684
+ n.name = t, await this.walletDb.updateAccountName(e, t);
1685
+ }
1686
+ rescanAccount(e) {
1687
+ if (e == -1) {
1688
+ let e = this.getMainAddresses();
1689
+ for (let t of e) t.height = 0, this.registerUpdate({
1690
+ address: t,
1691
+ result: t.statusHash
1692
+ });
1693
+ } else {
1694
+ let t = this.accounts.get(e);
1695
+ t.height = 0, this.registerUpdate({
1696
+ address: t,
1697
+ result: t.statusHash
1698
+ });
1699
+ }
1700
+ }
1701
+ rescanVaults() {
1702
+ let e = [];
1703
+ for (let t of this.vaults.values()) {
1704
+ let n = this.fetchAndUpdateVault(t, t.statusHash);
1705
+ e.push(n);
1706
+ }
1707
+ return Promise.all(e);
1708
+ }
1709
+ getVaultNextIndex() {
1710
+ return this.vaults.size == 0 ? 0 : Math.max(...Array.from(this.vaults.values(), (e) => e.idx)) + 1;
1711
+ }
1712
+ async addNewVault(e, t, n) {
1713
+ let r = {
1714
+ address: e,
1715
+ block: t,
1716
+ idx: n,
1717
+ height: 0,
1718
+ statusHash: "",
1719
+ balance: {
1720
+ confirmed: "0",
1721
+ unconfirmed: "0"
1722
+ },
1723
+ tokensBalance: {},
1724
+ type: S.VAULT
1725
+ };
1726
+ await this.addVault(r);
1727
+ }
1728
+ async addVault(e) {
1729
+ this.vaults.set(e.address, e), await this.walletDb.saveVault(e), this.notify({
1730
+ type: "new_vault",
1731
+ vault: {
1732
+ address: e.address,
1733
+ balance: e.balance,
1734
+ block: e.block,
1735
+ index: e.idx
1736
+ }
1737
+ }), await this.subscribeAddresses([e]);
1738
+ }
1739
+ async recoverVaults(e) {
1740
+ let t = !1, n = await this.discoveryService.discoverVaults(e), r = [];
1741
+ for (let [e, i] of n) this.vaults.has(e) || (t = !0, r.push(this.addVault(i)));
1742
+ return await Promise.all(r), t;
1743
+ }
1744
+ async recoverTokens() {
1745
+ let e = [];
1746
+ e.push(this.assetService.syncTokens(-1, P(this.getMainAddresses().map((e) => e.tokensBalance))));
1747
+ for (let t of this.accounts.values()) e.push(this.assetService.syncTokens(t.id, t.tokensBalance));
1748
+ await Promise.all(e);
1749
+ }
1750
+ isVaultAddress(e) {
1751
+ return e.type == S.VAULT;
1752
+ }
1753
+ isAccountAddress(e) {
1754
+ return e.type == S.DAPP;
1755
+ }
1756
+ isMainAddress(e) {
1757
+ return e.type == S.MAIN;
1758
+ }
1759
+ }, Be = class e {
1760
+ static {
1761
+ this.POLL_INTERVAL_MS = 12e4;
1762
+ }
1763
+ static {
1764
+ this.CURRENCY_SETTING = "market-currency";
1765
+ }
1766
+ static {
1767
+ this.SUPPORTED_TOKENS = { nexacoin: "nexa" };
1768
+ }
1769
+ constructor(e) {
1770
+ this.currency = "usd", this.running = !1, this.walletDb = e;
1771
+ }
1772
+ onUpdate(e) {
1773
+ this.updateCallback = e;
1774
+ }
1775
+ notify(e) {
1776
+ this.updateCallback?.(e);
1777
+ }
1778
+ async init() {
1779
+ this.stop();
1780
+ let t = await this.walletDb.getSetting(e.CURRENCY_SETTING);
1781
+ this.currency = K.includes(t) ? t : "usd", this.notify({
1782
+ type: "currency_updated",
1783
+ currency: this.currency
1784
+ }), this.running = !0, this.poll();
1785
+ }
1786
+ stop() {
1787
+ this.running = !1, clearTimeout(this.pollTimer), this.pollTimer = void 0;
1788
+ }
1789
+ getCurrency() {
1790
+ return this.currency;
1791
+ }
1792
+ async setCurrency(t) {
1793
+ t !== this.currency && (await this.walletDb.saveSetting(e.CURRENCY_SETTING, t), this.currency = t, this.notify({
1794
+ type: "currency_updated",
1795
+ currency: t
1796
+ }), this.poll());
1797
+ }
1798
+ async poll() {
1799
+ clearTimeout(this.pollTimer);
1800
+ let e = this.currency;
1801
+ try {
1802
+ let t = await this.fetchMarketData(e);
1803
+ e === this.currency && this.notify({
1804
+ type: "market_data_updated",
1805
+ currency: e,
1806
+ data: t
1807
+ });
1808
+ } catch (e) {
1809
+ console.error(e);
1810
+ } finally {
1811
+ this.scheduleNext();
1812
+ }
1813
+ }
1814
+ scheduleNext() {
1815
+ clearTimeout(this.pollTimer), this.running && (this.pollTimer = setTimeout(() => this.poll(), e.POLL_INTERVAL_MS));
1816
+ }
1817
+ async fetchMarketData(t) {
1818
+ let n = Object.keys(e.SUPPORTED_TOKENS).join(","), r = await fetch(`https://api.coingecko.com/api/v3/coins/markets?ids=${n}&vs_currency=${t}`);
1819
+ if (!r.ok) throw Error("Failed to fetch market data");
1820
+ let i = await r.json(), a = {};
1821
+ return i.forEach((t) => {
1822
+ a[e.SUPPORTED_TOKENS[t.id]] = {
1823
+ id: t.id,
1824
+ name: t.name ?? "",
1825
+ symbol: t.symbol ?? "",
1826
+ image: t.image ?? "",
1827
+ price: t.current_price ?? 0,
1828
+ priceChange: t.price_change_24h,
1829
+ priceChangePercentage: t.price_change_percentage_24h,
1830
+ marketCap: t.market_cap,
1831
+ fdv: t.fully_diluted_valuation,
1832
+ circSupply: t.circulating_supply,
1833
+ totalSupply: t.total_supply,
1834
+ maxSupply: t.max_supply,
1835
+ totalVolume: t.total_volume
1836
+ };
1837
+ }), a;
1838
+ }
2029
1839
  };
2030
- //# sourceMappingURL=index.js.map
1840
+ export { S as AccountType, Ee as AssetService, W as CURRENCIES, R as KeyManager, C as KeySpace, se as MAIN_WALLET_ID, ce as MAX_INT64, Be as MarketService, Se as RostrumService, Pe as SessionManager, w as SessionRequestType, De as TransactionService, Fe as TransactionTransformer, T as VAULT_FIRST_BLOCK, le as VAULT_SCRIPT_PREFIX, xe as WalletCache, be as WalletDB, ze as WalletManager, Ne as calculateFiatValue, me as capitalizeFirstLetter, K as currencyCodes, G as currencySymbols, O as currentTimestamp, ke as encryptMnemonic, fe as estimateDateByFutureBlock, q as formatMoney, Oe as generateNewMnemonic, $ as generateVaultAddress, X as generateVaultConstraint, Q as generateVaultVisibleArgs, A as getAddressBuffer, B as getAssetFileUrl, z as getAssetMetadataUrl, Me as getCurrencySymbol, de as getExplorerUrl, ge as getFileMediaType, _e as getFileMimeType, Z as getVaultConstraintHash, J as getVaultTemplate, Y as getVaultTemplateHash, ue as isGenesisHashValid, H as isMnemonicValid, k as isNullOrEmpty, E as isTestnet, D as isValidNexaAddress, I as keyPathToString, we as parseTokenDataUrl, ye as prettifyAmount, ve as sleep, L as stringToKeyPath, N as sumBalance, P as sumTokensBalance, M as tokenAmountToAssetAmount, he as tokenHexToAddr, j as tokenIdToHex, Ce as transformTokenIconUrl, pe as truncateStringMiddle, je as validateAndDecryptMnemonic };
1841
+
1842
+ //# sourceMappingURL=index.js.map