@ecency/sdk 1.0.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.
package/Readme.md ADDED
@@ -0,0 +1,36 @@
1
+ # Ecency wallets – manage Hive account and attach external wallets to it in Ecency system
2
+
3
+ [![NPM](https://img.shields.io/npm/v/@ecency/wallets.svg)](https://www.npmjs.com/package/@ecency/wallets) [![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com)
4
+
5
+ ## Overview
6
+
7
+ `@ecency/wallets` provides an API for managing Hive blockchain wallets and external cryptocurrency wallets within the Ecency ecosystem.
8
+
9
+ ## Installation
10
+
11
+ ```sh
12
+ yarn add @ecency/wallets
13
+ # or
14
+ npm install @ecency/wallets
15
+ ```
16
+
17
+ ## Setup
18
+
19
+ 1. Install `react @tanstack/react-query @hiveio/dhive`
20
+ 2. Use!
21
+
22
+ ## Features
23
+
24
+ This package built on top of [@hiveio/dhive](https://www.npmjs.com/package/@hiveio/dhive) and [okweb3](http://okx.github.io/) packages.
25
+
26
+ Main functionality is creating wallets based on seed phrase([BIP39](https://www.npmjs.com/package/bip39)) and generating addresses with keys on device. Seed phrases and private keys are never sent to any API, all operations happen locally.
27
+
28
+ Supportings tokens: BTC, ETH, SOL, TRX, TON, ATOM, APT – theoretically all child tokens of these systems. Make forks for it.
29
+
30
+ ## Roadmap
31
+
32
+ - Add more Hive wallets operations
33
+ - Allow to sign transactions with external wallets
34
+ - Allow to import existing wallets by phrase or private keys
35
+ - Support of DASH
36
+ - Support of DOGE
@@ -0,0 +1,96 @@
1
+ import { BaseWallet } from '@okxweb3/coin-base';
2
+ import { UseMutationResult } from '@tanstack/react-query';
3
+ import { UseQueryResult } from '@tanstack/react-query';
4
+
5
+ export declare function delay(ms: number): Promise<unknown>;
6
+
7
+ export declare interface EcencyCreateWalletInformation {
8
+ address: string;
9
+ privateKey: string;
10
+ publicKey: string;
11
+ username: string;
12
+ currency: EcencyWalletCurrency;
13
+ custom?: boolean;
14
+ }
15
+
16
+ export declare interface EcencyHiveKeys {
17
+ username: string;
18
+ owner: string;
19
+ active: string;
20
+ posting: string;
21
+ memo: string;
22
+ masterPassword: string;
23
+ ownerPubkey: string;
24
+ activePubkey: string;
25
+ postingPubkey: string;
26
+ memoPubkey: string;
27
+ }
28
+
29
+ export declare enum EcencyWalletCurrency {
30
+ BTC = "btc",
31
+ ETH = "eth",
32
+ APT = "aptos",
33
+ ATOM = "cosmos",
34
+ TON = "ton",
35
+ TRON = "tron",
36
+ SOL = "solana"
37
+ }
38
+
39
+ declare namespace EcencyWalletsPrivateApi {
40
+ export {
41
+ useCreateAccountWithWallets,
42
+ useCheckWalletExistence
43
+ }
44
+ }
45
+ export { EcencyWalletsPrivateApi }
46
+
47
+ export declare function getWallet(currency: EcencyWalletCurrency): BaseWallet | undefined;
48
+
49
+ export declare function mnemonicToSeedBip39(value: string): string;
50
+
51
+ declare interface Payload {
52
+ currency: EcencyWalletCurrency;
53
+ address: string;
54
+ }
55
+
56
+ declare interface Payload_2 {
57
+ address: string;
58
+ currency: EcencyWalletCurrency;
59
+ }
60
+
61
+ declare interface Payload_3 {
62
+ privateKeyOrSeed: string;
63
+ }
64
+
65
+ declare function useCheckWalletExistence(): UseMutationResult<boolean, Error, Payload_2, unknown>;
66
+
67
+ export declare function useCoinGeckoPriceQuery(currency?: EcencyWalletCurrency): UseQueryResult<number, Error>;
68
+
69
+ declare function useCreateAccountWithWallets(username: string): UseMutationResult<Response, Error, Payload, unknown>;
70
+
71
+ /**
72
+ * Returns information about the actual balance of the given currency address
73
+ * using various of public APIs
74
+ * todo extract URLs to configs
75
+ * @param currency
76
+ * @param address
77
+ * @returns
78
+ */
79
+ export declare function useGetExternalWalletBalanceQuery(currency: EcencyWalletCurrency, address: string): UseQueryResult<number, Error>;
80
+
81
+ export declare function useHiveKeysQuery(username: string): UseQueryResult<EcencyHiveKeys, Error>;
82
+
83
+ export declare function useImportWallet(username: string, currency: EcencyWalletCurrency): UseMutationResult< {
84
+ privateKey: string;
85
+ address: any;
86
+ publicKey: string;
87
+ }, Error, Payload_3, unknown>;
88
+
89
+ export declare function useSeedPhrase(username: string): UseQueryResult<string, Error>;
90
+
91
+ export declare function useWalletCreate(username: string, currency: EcencyWalletCurrency): {
92
+ createWallet: UseMutationResult<EcencyCreateWalletInformation, Error, void, unknown>;
93
+ importWallet: () => void;
94
+ };
95
+
96
+ export { }
@@ -0,0 +1,373 @@
1
+ import { useCallback as R } from "react";
2
+ import { useQuery as p, useQueryClient as y, useMutation as m } from "@tanstack/react-query";
3
+ import { BtcWallet as O } from "@okxweb3/coin-bitcoin";
4
+ import { EthWallet as v } from "@okxweb3/coin-ethereum";
5
+ import { TrxWallet as k } from "@okxweb3/coin-tron";
6
+ import { TonWallet as A } from "@okxweb3/coin-ton";
7
+ import { SolWallet as N } from "@okxweb3/coin-solana";
8
+ import { AtomWallet as K } from "@okxweb3/coin-cosmos";
9
+ import { AptosWallet as D } from "@okxweb3/coin-aptos";
10
+ import j, { mnemonicToSeedSync as C } from "bip39";
11
+ import { LRUCache as H } from "lru-cache";
12
+ import { PrivateKey as u } from "@hiveio/dhive";
13
+ var o = /* @__PURE__ */ ((e) => (e.BTC = "btc", e.ETH = "eth", e.APT = "aptos", e.ATOM = "cosmos", e.TON = "ton", e.TRON = "tron", e.SOL = "solana", e))(o || {});
14
+ function x(e) {
15
+ return new Promise((t) => setTimeout(t, e));
16
+ }
17
+ function h(e) {
18
+ switch (e) {
19
+ case o.BTC:
20
+ return new O();
21
+ case o.ETH:
22
+ return new v();
23
+ case o.TRON:
24
+ return new k();
25
+ case o.TON:
26
+ return new A();
27
+ case o.SOL:
28
+ return new N();
29
+ case o.ATOM:
30
+ return new K();
31
+ case o.APT:
32
+ return new D();
33
+ default:
34
+ return;
35
+ }
36
+ }
37
+ function ce(e) {
38
+ return C(e).toString("hex");
39
+ }
40
+ function ie(e, t) {
41
+ return p({
42
+ queryKey: ["ecency-wallets", "external-wallet-balance", e, t],
43
+ queryFn: async () => {
44
+ switch (e) {
45
+ case o.BTC:
46
+ const r = await (await fetch(
47
+ `https://mempool.space/api/address/${t}`
48
+ )).json();
49
+ return (r.chain_stats.funded_txo_sum - r.chain_stats.spent_txo_sum) / 1e8;
50
+ case o.ETH:
51
+ return +(await (await fetch("https://eth.llamarpc.com", {
52
+ method: "POST",
53
+ body: JSON.stringify({
54
+ jsonrpc: "2.0",
55
+ id: "1",
56
+ method: "eth_getBalance",
57
+ params: [t, "latest"]
58
+ })
59
+ })).json()).result / 1e18;
60
+ case o.SOL:
61
+ return (await (await fetch(
62
+ "https://api.mainnet-beta.solana.com",
63
+ {
64
+ method: "POST",
65
+ body: JSON.stringify({
66
+ jsonrpc: "2.0",
67
+ id: "1",
68
+ method: "getBalance",
69
+ params: [t]
70
+ })
71
+ }
72
+ )).json()).result.value / 1e9;
73
+ case o.TRON:
74
+ return (await (await fetch(
75
+ `https://api.trongrid.io/v1/accounts/${t}`
76
+ )).json()).data[0].balance / 1e6;
77
+ case o.TON:
78
+ return (await (await fetch(
79
+ `https://tonapi.io/v1/blockchain/getAccount?account=${t}`
80
+ )).json()).balance / 1e9;
81
+ case o.APT:
82
+ const d = (await (await fetch(
83
+ `https://fullnode.mainnet.aptoslabs.com/v1/accounts/${t}/resources`
84
+ )).json()).find(
85
+ (S) => S.type.includes("coin::CoinStore")
86
+ );
87
+ return d ? parseInt(d.data.coin.value) / 1e8 : 0;
88
+ case o.ATOM:
89
+ return +(await (await fetch(
90
+ `https://rest.cosmos.directory/cosmoshub/auth/accounts/${t}`
91
+ )).json()).result.value.coins[0].amount / 1e6;
92
+ }
93
+ }
94
+ });
95
+ }
96
+ function f(e) {
97
+ return p({
98
+ queryKey: ["ecency-wallets", "seed", e],
99
+ queryFn: async () => j.generateMnemonic(128)
100
+ });
101
+ }
102
+ const W = {
103
+ max: 500,
104
+ // how long to live in ms
105
+ ttl: 1e3 * 60 * 5,
106
+ // return stale items before removing from cache?
107
+ allowStale: !1,
108
+ updateAgeOnGet: !1,
109
+ updateAgeOnHas: !1
110
+ }, b = new H(W), w = Symbol("undefined"), _ = (e, t) => b.set(e, t === void 0 ? w : t), E = (e) => {
111
+ const t = b.get(e);
112
+ return t === w ? void 0 : t;
113
+ };
114
+ function le(e) {
115
+ return p({
116
+ queryKey: ["ecency-wallets", "coingecko-price", e],
117
+ queryFn: async () => {
118
+ let t = e;
119
+ switch (e) {
120
+ case o.BTC:
121
+ t = "binance-wrapped-btc";
122
+ break;
123
+ case o.ETH:
124
+ t = "ethereum";
125
+ break;
126
+ case o.SOL:
127
+ t = "solana";
128
+ break;
129
+ case o.TON:
130
+ t = "trx";
131
+ break;
132
+ default:
133
+ t = e;
134
+ }
135
+ let n = E("gecko"), r;
136
+ if (n)
137
+ r = n;
138
+ else {
139
+ const a = await (await fetch(
140
+ "https://api.coingecko.com/api/v3/simple/price",
141
+ {
142
+ method: "POST",
143
+ body: JSON.stringify({
144
+ params: {
145
+ ids: [t],
146
+ vs_currencies: "usd"
147
+ }
148
+ })
149
+ }
150
+ )).json();
151
+ _("gecko", a === void 0 ? w : a), r = a;
152
+ }
153
+ return 1 / +r[Object.keys(r)[0]].usd;
154
+ },
155
+ enabled: !!e
156
+ });
157
+ }
158
+ function q(e) {
159
+ const { data: t } = f(e);
160
+ return p({
161
+ queryKey: ["ecencу-wallets", "hive-keys", e, t],
162
+ queryFn: async () => {
163
+ if (!t)
164
+ throw new Error("[Ecency][Wallets] - no seed to create Hive account");
165
+ const n = u.fromLogin(e, t, "owner"), r = u.fromLogin(e, t, "active"), s = u.fromLogin(e, t, "posting"), i = u.fromLogin(e, t, "memo");
166
+ return {
167
+ username: e,
168
+ owner: n.toString(),
169
+ active: r.toString(),
170
+ posting: s.toString(),
171
+ memo: i.toString(),
172
+ ownerPubkey: n.createPublic().toString(),
173
+ activePubkey: r.createPublic().toString(),
174
+ postingPubkey: s.createPublic().toString(),
175
+ memoPubkey: i.createPublic().toString()
176
+ };
177
+ }
178
+ });
179
+ }
180
+ const B = {
181
+ [o.BTC]: "m/44'/0'/0'/0/0",
182
+ // Bitcoin (BIP44)
183
+ [o.ETH]: "m/44'/60'/0'/0/0",
184
+ // Ethereum (BIP44)
185
+ [o.SOL]: "m/44'/501'/0'/0'",
186
+ // Solana (BIP44)
187
+ [o.TON]: "m/44'/607'/0'",
188
+ // TON (BIP44)
189
+ [o.TRON]: "m/44'/195'/0'/0/0",
190
+ // Tron (BIP44)
191
+ [o.APT]: "m/44'/637'/0'/0'/0'",
192
+ // Aptos (BIP44)
193
+ [o.ATOM]: "m/44'/118'/0'/0/0"
194
+ // Cosmos (BIP44)
195
+ };
196
+ function pe(e, t) {
197
+ const { data: n } = f(e), r = y(), s = m({
198
+ mutationKey: ["ecency-wallets", "create-wallet", e, t],
199
+ mutationFn: async () => {
200
+ if (!n)
201
+ throw new Error("[Ecency][Wallets] - No seed to create a wallet");
202
+ const a = h(t), c = await (a == null ? void 0 : a.getDerivedPrivateKey({
203
+ mnemonic: n,
204
+ hdPath: B[t]
205
+ }));
206
+ await x(1e3);
207
+ const l = await (a == null ? void 0 : a.getNewAddress({
208
+ privateKey: c
209
+ }));
210
+ return {
211
+ privateKey: c,
212
+ address: l.address,
213
+ publicKey: l.publicKey,
214
+ username: e,
215
+ currency: t
216
+ };
217
+ },
218
+ onSuccess: (a) => {
219
+ r.setQueryData(
220
+ ["ecency-wallets", "wallets", a.username],
221
+ (c) => new Map(c ? Array.from(c.entries()) : []).set(a.currency, a)
222
+ );
223
+ }
224
+ }), i = R(() => {
225
+ }, []);
226
+ return {
227
+ createWallet: s,
228
+ importWallet: i
229
+ };
230
+ }
231
+ const g = { privateApiHost: "https://ecency.com" };
232
+ function L(e) {
233
+ const { data: t } = p({
234
+ queryKey: ["ecency-wallets", "wallets", e]
235
+ }), { data: n } = q(e);
236
+ return m({
237
+ mutationKey: ["ecency-wallets", "create-account-with-wallets", e],
238
+ mutationFn: ({ currency: r, address: s }) => fetch(g.privateApiHost + "/private-api/wallets-add", {
239
+ method: "POST",
240
+ headers: {
241
+ "Content-Type": "application/json"
242
+ },
243
+ body: JSON.stringify({
244
+ username: e,
245
+ token: r,
246
+ address: s,
247
+ meta: {
248
+ ownerPublicKey: n == null ? void 0 : n.ownerPubkey,
249
+ activePublicKey: n == null ? void 0 : n.activePubkey,
250
+ postingPublicKey: n == null ? void 0 : n.postingPubkey,
251
+ memoPublicKey: n == null ? void 0 : n.memoPubkey,
252
+ ...Array.from((t == null ? void 0 : t.entries()) ?? []).reduce(
253
+ (i, [a, c]) => ({
254
+ ...i,
255
+ [a]: c.address
256
+ }),
257
+ {}
258
+ )
259
+ }
260
+ })
261
+ })
262
+ });
263
+ }
264
+ function T() {
265
+ return m({
266
+ mutationKey: ["ecency-wallets", "check-wallet-existence"],
267
+ mutationFn: async ({ address: e, currency: t }) => (await (await fetch(
268
+ g.privateApiHost + "/private-api/wallets-exist",
269
+ {
270
+ method: "POST",
271
+ headers: {
272
+ "Content-Type": "application/json"
273
+ },
274
+ body: JSON.stringify({
275
+ address: e,
276
+ token: t
277
+ })
278
+ }
279
+ )).json()).length === 0
280
+ });
281
+ }
282
+ const ue = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
283
+ __proto__: null,
284
+ useCheckWalletExistence: T,
285
+ useCreateAccountWithWallets: L
286
+ }, Symbol.toStringTag, { value: "Module" })), F = {
287
+ [o.BTC]: ["m/84'/0'/0'/0/0"],
288
+ [o.ETH]: ["m/84'/60'/0'/0/0"],
289
+ // its not working for Trust, Exodus, todo: check others below
290
+ [o.SOL]: ["m/84'/501'/0'/0/0"],
291
+ [o.TRON]: ["m/84'/195'/0'/0/0"],
292
+ [o.APT]: ["m/84'/637'/0'/0/0"],
293
+ [o.TON]: [],
294
+ // Disabled
295
+ [o.ATOM]: ["m/84'/118'/0'/0'/0"]
296
+ };
297
+ async function M(e, t, n) {
298
+ for (const r of F[n] || [])
299
+ try {
300
+ const s = await t.getDerivedPrivateKey({
301
+ mnemonic: e,
302
+ hdPath: r
303
+ }), i = await t.getNewAddress({
304
+ privateKey: s,
305
+ addressType: "segwit_native"
306
+ });
307
+ return [s.toString(), i.address];
308
+ } catch {
309
+ return [];
310
+ }
311
+ return [];
312
+ }
313
+ function me(e, t) {
314
+ const n = y(), { mutateAsync: r } = T();
315
+ return m({
316
+ mutationKey: ["ecency-wallets", "import-wallet", e, t],
317
+ mutationFn: async ({ privateKeyOrSeed: s }) => {
318
+ const i = h(t);
319
+ if (!i)
320
+ throw new Error("Cannot find token for this currency");
321
+ const a = s.split(" ").length === 12;
322
+ let c, l = s;
323
+ if (a ? [l, c] = await M(
324
+ s,
325
+ i,
326
+ t
327
+ ) : c = (await i.getNewAddress({
328
+ privateKey: s
329
+ })).address, !c || !s)
330
+ throw new Error(
331
+ "Private key/seed phrase isn't matching with public key or token"
332
+ );
333
+ if (!await r({
334
+ address: c,
335
+ currency: t
336
+ }))
337
+ throw new Error(
338
+ "This wallet has already in use by Hive account. Please, try another one"
339
+ );
340
+ return {
341
+ privateKey: l,
342
+ address: c,
343
+ publicKey: ""
344
+ };
345
+ },
346
+ onSuccess: ({ privateKey: s, publicKey: i, address: a }) => {
347
+ n.setQueryData(
348
+ ["ecency-wallets", "wallets", e],
349
+ (c) => new Map(c ? Array.from(c.entries()) : []).set(t, {
350
+ privateKey: s,
351
+ publicKey: i,
352
+ address: a,
353
+ username: e,
354
+ currency: t,
355
+ custom: !0
356
+ })
357
+ );
358
+ }
359
+ });
360
+ }
361
+ export {
362
+ o as EcencyWalletCurrency,
363
+ ue as EcencyWalletsPrivateApi,
364
+ x as delay,
365
+ h as getWallet,
366
+ ce as mnemonicToSeedBip39,
367
+ le as useCoinGeckoPriceQuery,
368
+ ie as useGetExternalWalletBalanceQuery,
369
+ q as useHiveKeysQuery,
370
+ me as useImportWallet,
371
+ f as useSeedPhrase,
372
+ pe as useWalletCreate
373
+ };
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "@ecency/sdk",
3
+ "private": false,
4
+ "version": "1.0.0",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "main": "./dist/ecency-sdk.umd.js",
8
+ "module": "./dist/ecency-sdk.es.js",
9
+ "typings": "./dist/ecency-sdk.es.d.ts",
10
+ "files": [
11
+ "dist",
12
+ "README.md"
13
+ ],
14
+ "scripts": {
15
+ "dev": "vite",
16
+ "build": "tsc && vite build",
17
+ "preview": "vite preview"
18
+ },
19
+ "devDependencies": {
20
+ "@hiveio/dhive": "^1.3.2",
21
+ "@tanstack/react-query": "^5.66.11",
22
+ "@types/node": "^22.13.8",
23
+ "@types/react": "^19.0.10",
24
+ "@vitejs/plugin-react": "^4.3.4",
25
+ "eslint": "^9.21.0",
26
+ "lru-cache": "^11.0.2",
27
+ "prettier": "^3.5.2",
28
+ "react": "^19.0.0",
29
+ "typescript": "~5.7.2",
30
+ "vite": "^6.2.0",
31
+ "vite-plugin-dts": "^4.5.1",
32
+ "vite-plugin-node-polyfills": "^0.23.0"
33
+ },
34
+ "dependencies": {
35
+ "@okxweb3/coin-aptos": "^1.2.0",
36
+ "@okxweb3/coin-base": "^1.1.2",
37
+ "@okxweb3/coin-bitcoin": "^1.2.0",
38
+ "@okxweb3/coin-cosmos": "^1.1.0",
39
+ "@okxweb3/coin-ethereum": "^1.0.12",
40
+ "@okxweb3/coin-solana": "^1.1.0",
41
+ "@okxweb3/coin-ton": "^1.1.1-beta.1",
42
+ "@okxweb3/coin-tron": "^1.1.0",
43
+ "@okxweb3/crypto-lib": "^1.0.10",
44
+ "bip39": "^3.1.0"
45
+ }
46
+ }