zano_web3 6.13.0 → 6.15.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 CHANGED
@@ -204,6 +204,7 @@ export interface Wallet {
204
204
  - `sendTransfer(assetId: string, address: string, amount: string)`: Sends a transfer to an address.
205
205
  - `getBalances()`: Retrieves the balances.
206
206
  - `validateWallet(rpcUrl: string, authData: AuthData)`: Validates the wallet.
207
+ - `getAliasDetails(alias:string)` : Retrieves information about a specific address alias.
207
208
 
208
209
 
209
210
  #### 1. **Updating Wallet RPC URL**
@@ -370,6 +371,28 @@ import { AuthData } from "./types";
370
371
  })();
371
372
  ```
372
373
 
374
+ #### 9. **Get Alias details**
375
+
376
+ ```javascript
377
+ import { ServerWallet } from "zano_web3/server";
378
+
379
+ const alias = "alias";
380
+
381
+ (async (alias) => {
382
+ const zanoServerAPI = new ServerWallet({
383
+ walletUrl: "http://127.0.0.1:11211/json_rpc",
384
+ daemonUrl: "http://127.0.0.1:11211/json_rpc"
385
+ });
386
+
387
+ try {
388
+ const aliasDetails = await zanoServerAPI.getAliasDetails(alias);
389
+ console.log(aliasDetails);
390
+ } catch (error) {
391
+ console.error(error.message);
392
+ }
393
+ })(alias);
394
+ ```
395
+
373
396
  ## Requirements
374
397
 
375
398
  - Correct RPC URLs for the wallet and daemon.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zano_web3",
3
- "version": "6.13.0",
3
+ "version": "6.15.0",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -1,290 +1,316 @@
1
- import axios from 'axios';
1
+ import axios from "axios";
2
2
  import Big from "big.js";
3
3
  import {
4
- AuthData,
5
- AliasAuth,
6
- PkeyAuth,
7
- ValidationParams,
8
- BalanceInfo,
9
- TxInfo,
10
- } from './types';
11
-
12
- import { ZANO_ASSET_ID, ZanoError } from './utils';
13
- import { APIAsset, APIBalance } from './types';
14
-
4
+ AuthData,
5
+ AliasAuth,
6
+ PkeyAuth,
7
+ ValidationParams,
8
+ BalanceInfo,
9
+ TxInfo,
10
+ AliasDetails,
11
+ } from "./types";
12
+
13
+ import { ZANO_ASSET_ID, ZanoError } from "./utils";
14
+ import { APIAsset, APIBalance } from "./types";
15
15
 
16
16
  interface ConstructorParams {
17
- walletUrl: string;
18
- daemonUrl: string;
17
+ walletUrl: string;
18
+ daemonUrl: string;
19
19
  }
20
20
 
21
21
  interface GetTxsParams {
22
- count: number;
23
- offset: number;
24
- exclude_mining_txs?: boolean;
25
- exclude_unconfirmed?: boolean;
26
- order?: string;
27
- update_provision_info?: boolean;
22
+ count: number;
23
+ offset: number;
24
+ exclude_mining_txs?: boolean;
25
+ exclude_unconfirmed?: boolean;
26
+ order?: string;
27
+ update_provision_info?: boolean;
28
28
  }
29
29
 
30
30
  class ServerWallet {
31
- private walletUrl: string;
32
- private daemonUrl: string;
31
+ private walletUrl: string;
32
+ private daemonUrl: string;
33
+
34
+ constructor(params: ConstructorParams) {
35
+ this.walletUrl = params.walletUrl;
36
+ this.daemonUrl = params.daemonUrl;
37
+ }
38
+
39
+ private async fetchDaemon(method: string, params: any) {
40
+ const headers = { "Content-Type": "application/json" };
41
+
42
+ const data = {
43
+ jsonrpc: "2.0",
44
+ id: 0,
45
+ method: method,
46
+ params: params,
47
+ };
33
48
 
34
- constructor(params: ConstructorParams) {
35
- this.walletUrl = params.walletUrl;
36
- this.daemonUrl = params.daemonUrl;
37
- }
49
+ return axios.post(this.daemonUrl, data, { headers });
50
+ }
51
+
52
+ private async fetchWallet(method: string, params: any) {
53
+ const headers = { "Content-Type": "application/json" };
54
+
55
+ const data = {
56
+ jsonrpc: "2.0",
57
+ id: 0,
58
+ method: method,
59
+ params: params,
60
+ };
38
61
 
39
- private async fetchDaemon(method: string, params: any) {
40
- const headers = { "Content-Type": "application/json" };
62
+ return axios.post(this.walletUrl, data, { headers });
63
+ }
41
64
 
42
- const data = {
43
- jsonrpc: "2.0",
44
- id: 0,
45
- method: method,
46
- params: params
47
- };
65
+ async updateWalletRpcUrl(rpcUrl: string) {
66
+ this.walletUrl = rpcUrl;
67
+ }
48
68
 
49
- return axios.post(this.daemonUrl, data, { headers })
69
+ async updateDaemonRpcUrl(rpcUrl: string) {
70
+ this.daemonUrl = rpcUrl;
71
+ }
72
+
73
+ async getAssetsList() {
74
+ const count = 100;
75
+ let offset = 0;
76
+ let allAssets: APIAsset[] = [];
77
+ let keepFetching = true;
78
+
79
+ while (keepFetching) {
80
+ try {
81
+ const response = await this.fetchDaemon("get_assets_list", {
82
+ count,
83
+ offset,
84
+ });
85
+
86
+ const assets = response.data.result.assets;
87
+ if (assets.length < count) {
88
+ keepFetching = false;
89
+ }
90
+ allAssets = allAssets.concat(assets);
91
+ offset += count;
92
+ } catch (error) {
93
+ throw new ZanoError(
94
+ "Failed to fetch assets list",
95
+ "ASSETS_FETCH_ERROR"
96
+ );
97
+ }
50
98
  }
51
99
 
52
- private async fetchWallet(method: string, params: any) {
53
- const headers = { "Content-Type": "application/json" };
100
+ return allAssets as APIAsset[];
101
+ }
54
102
 
55
- const data = {
56
- jsonrpc: "2.0",
57
- id: 0,
58
- method: method,
59
- params: params
60
- };
103
+ async getAssetDetails(assetId: string) {
104
+ const assets = await this.getAssetsList();
105
+ const asset = assets.find((a) => a.asset_id === assetId);
61
106
 
62
- return axios.post(this.walletUrl, data, { headers })
107
+ if (!asset) {
108
+ throw new ZanoError(
109
+ `Asset with ID ${assetId} not found`,
110
+ "ASSET_NOT_FOUND"
111
+ );
63
112
  }
64
113
 
65
- async updateWalletRpcUrl(rpcUrl: string) {
66
- this.walletUrl = rpcUrl;
114
+ return asset as APIAsset;
115
+ }
116
+
117
+ async getAssetInfo(assetId: string) {
118
+ try {
119
+ const response = await this.fetchDaemon("get_asset_info", {
120
+ asset_id: assetId,
121
+ });
122
+
123
+ if (response.data.result) {
124
+ return response.data.result;
125
+ } else {
126
+ throw new ZanoError(
127
+ `Error fetching info for asset ID ${assetId}`,
128
+ "ASSET_INFO_ERROR"
129
+ );
130
+ }
131
+ } catch (error) {
132
+ console.error(error);
133
+ throw new ZanoError(
134
+ "Failed to fetch asset info",
135
+ "ASSET_INFO_FETCH_ERROR"
136
+ );
67
137
  }
138
+ }
139
+
140
+ async sendTransfer(assetId: string, address: string, amount: string) {
141
+ let decimalPoint: number;
142
+ let auditable: boolean;
68
143
 
69
- async updateDaemonRpcUrl(rpcUrl: string) {
70
- this.daemonUrl = rpcUrl;
144
+ if (assetId === ZANO_ASSET_ID) {
145
+ decimalPoint = 12;
146
+ } else {
147
+ const asset = await this.getAssetDetails(assetId);
148
+ decimalPoint = asset.decimal_point;
71
149
  }
72
150
 
73
- async getAssetsList() {
74
- const count = 100; // Number of items to fetch per request
75
- let offset = 0;
76
- let allAssets: APIAsset[] = [];
77
- let keepFetching = true;
78
-
79
- while (keepFetching) {
80
- try {
81
- const response = await this.fetchDaemon("get_assets_list", { count, offset });
82
-
83
- const assets = response.data.result.assets;
84
- if (assets.length < count) {
85
- keepFetching = false;
86
- }
87
- allAssets = allAssets.concat(assets);
88
- offset += count;
89
- } catch (error) {
90
- throw new ZanoError("Failed to fetch assets list", "ASSETS_FETCH_ERROR");
91
- }
92
- }
151
+ try {
152
+ const response = await this.fetchWallet("getaddress", {});
153
+ auditable = response.data.result.address.startsWith("a");
154
+ } catch (error) {
155
+ throw new ZanoError("Failed to fetch address", "ADDRESS_FETCH_ERROR");
156
+ }
93
157
 
94
- return allAssets as APIAsset[];
95
- };
158
+ const bigAmount = new Big(amount)
159
+ .times(new Big(10).pow(decimalPoint))
160
+ .toString();
161
+
162
+ try {
163
+ const response = await this.fetchWallet("transfer", {
164
+ destinations: [{ address, amount: bigAmount, asset_id: assetId }],
165
+ fee: "10000000000",
166
+ mixin: auditable ? 0 : 15,
167
+ });
168
+
169
+ if (response.data.result) {
170
+ return response.data.result;
171
+ } else if (
172
+ response.data.error &&
173
+ response.data.error.message === "WALLET_RPC_ERROR_CODE_NOT_ENOUGH_MONEY"
174
+ ) {
175
+ throw new ZanoError("Not enough funds", "NOT_ENOUGH_FUNDS");
176
+ } else {
177
+ throw new ZanoError("Error sending transfer", "TRANSFER_ERROR");
178
+ }
179
+ } catch (error) {
180
+ if (error instanceof ZanoError) {
181
+ throw error;
182
+ } else {
183
+ throw new ZanoError("Failed to send transfer", "TRANSFER_SEND_ERROR");
184
+ }
185
+ }
186
+ }
187
+
188
+ async getAliasByAddress(address: string) {
189
+ try {
190
+ const response = await this.fetchDaemon("get_alias_by_address", address);
191
+
192
+ if (response.data.result) {
193
+ return response.data.result;
194
+ } else {
195
+ throw new ZanoError(
196
+ `Error fetching alias for address ${address}`,
197
+ "ALIAS_FETCH_ERROR"
198
+ );
199
+ }
200
+ } catch (error) {
201
+ throw new ZanoError("Failed to fetch alias", "ALIAS_FETCH_ERROR");
202
+ }
203
+ }
204
+
205
+ async getBalances() {
206
+ try {
207
+ const response = await this.fetchWallet("getbalance", {});
208
+ const balancesData = response.data.result.balances as APIBalance[];
209
+
210
+ const balances = balancesData.map((asset) => ({
211
+ name: asset.asset_info.full_name,
212
+ ticker: asset.asset_info.ticker,
213
+ id: asset.asset_info.asset_id,
214
+ amount: new Big(asset.unlocked)
215
+ .div(new Big(10).pow(asset.asset_info.decimal_point))
216
+ .toString(),
217
+ awaiting_in: new Big(asset.awaiting_in).toString(),
218
+ awaiting_out: new Big(asset.awaiting_out).toString(),
219
+ total: new Big(asset.total).toString(),
220
+ unlocked: new Big(asset.unlocked).toString(),
221
+ asset_info: asset.asset_info,
222
+ }));
223
+
224
+ return balances.sort((a, b) => {
225
+ if (a.id === ZANO_ASSET_ID) return -1;
226
+ if (b.id === ZANO_ASSET_ID) return 1;
227
+ return 0;
228
+ }) as BalanceInfo[];
229
+ } catch (error) {
230
+ throw new ZanoError("Failed to fetch balances", "BALANCES_FETCH_ERROR");
231
+ }
232
+ }
96
233
 
97
- async getAssetDetails(assetId: string) {
98
- const assets = await this.getAssetsList();
99
- const asset = assets.find((a) => a.asset_id === assetId);
234
+ async validateWallet(authData: AuthData) {
235
+ const { message, address, signature } = authData;
100
236
 
101
- if (!asset) {
102
- throw new ZanoError(
103
- `Asset with ID ${assetId} not found`,
104
- "ASSET_NOT_FOUND"
105
- );
106
- }
237
+ const alias = (authData as AliasAuth).alias || undefined;
238
+ const pkey = (authData as PkeyAuth).pkey || undefined;
107
239
 
108
- return asset as APIAsset;
240
+ if (!message || (!alias && !pkey) || !signature) {
241
+ return false;
109
242
  }
110
243
 
111
-
112
- async getAssetInfo(assetId: string) {
113
- try {
114
- const response = await this.fetchDaemon("get_asset_info", { asset_id: assetId });
115
-
116
- if (response.data.result) {
117
- return response.data.result;
118
- } else {
119
- throw new ZanoError(
120
- `Error fetching info for asset ID ${assetId}`,
121
- "ASSET_INFO_ERROR"
122
- );
123
- }
124
- } catch (error) {
125
- console.error(error);
126
- throw new ZanoError("Failed to fetch asset info", "ASSET_INFO_FETCH_ERROR");
127
- }
244
+ const validationParams: ValidationParams = {
245
+ buff: Buffer.from(message).toString("base64"),
246
+ sig: signature,
128
247
  };
129
248
 
130
- async sendTransfer(assetId: string, address: string, amount: string) {
131
- let decimalPoint: number;
249
+ if (alias) {
250
+ validationParams["alias"] = alias;
251
+ } else {
252
+ validationParams["pkey"] = pkey;
253
+ }
132
254
 
133
- if (assetId === ZANO_ASSET_ID) {
134
- decimalPoint = 12;
135
- } else {
136
- const asset = await this.getAssetDetails(assetId);
137
- decimalPoint = asset.decimal_point;
138
- }
255
+ const response = await this.fetchDaemon(
256
+ "validate_signature",
257
+ validationParams
258
+ );
139
259
 
140
- const bigAmount = new Big(amount)
141
- .times(new Big(10).pow(decimalPoint))
142
- .toString();
143
-
144
- try {
145
- const response = await this.fetchWallet("transfer", {
146
- destinations: [{ address, amount: bigAmount, asset_id: assetId }],
147
- fee: "10000000000",
148
- mixin: 15,
149
- });
150
-
151
- if (response.data.result) {
152
- return response.data.result;
153
- } else if (
154
- response.data.error &&
155
- response.data.error.message === "WALLET_RPC_ERROR_CODE_NOT_ENOUGH_MONEY"
156
- ) {
157
- throw new ZanoError("Not enough funds", "NOT_ENOUGH_FUNDS");
158
- } else {
159
- throw new ZanoError("Error sending transfer", "TRANSFER_ERROR");
160
- }
161
-
162
- } catch (error) {
163
- if (error instanceof ZanoError) {
164
- throw error; // Re-throw the custom error
165
- } else {
166
- throw new ZanoError("Failed to send transfer", "TRANSFER_SEND_ERROR");
167
- }
168
- }
169
- };
260
+ const valid = response?.data?.result?.status === "OK";
170
261
 
171
- async getAliasByAddress(address: string) {
172
- try {
173
- const response = await this.fetchDaemon("get_alias_by_address", address);
174
-
175
- if (response.data.result) {
176
- return response.data.result;
177
- } else {
178
- throw new ZanoError(
179
- `Error fetching alias for address ${address}`,
180
- "ALIAS_FETCH_ERROR"
181
- );
182
- }
183
- } catch (error) {
184
- throw new ZanoError("Failed to fetch alias", "ALIAS_FETCH_ERROR");
185
- }
262
+ if (!valid) {
263
+ return false;
186
264
  }
187
265
 
188
- async getBalances() {
189
- try {
190
- const response = await this.fetchWallet("getbalance", {});
191
- const balancesData = response.data.result.balances as APIBalance[];
192
-
193
-
194
- const balances = balancesData.map((asset) => ({
195
- name: asset.asset_info.full_name,
196
- ticker: asset.asset_info.ticker,
197
- id: asset.asset_info.asset_id,
198
- amount: new Big(asset.unlocked)
199
- .div(new Big(10).pow(asset.asset_info.decimal_point))
200
- .toString(),
201
- awaiting_in: new Big(asset.awaiting_in).toString(),
202
- awaiting_out: new Big(asset.awaiting_out).toString(),
203
- total: new Big(asset.total).toString(),
204
- unlocked: new Big(asset.unlocked).toString(),
205
- asset_info: asset.asset_info
206
- }));
207
-
208
- return balances.sort((a, b) => {
209
- if (a.id === ZANO_ASSET_ID)
210
- return -1;
211
- if (b.id === ZANO_ASSET_ID )
212
- return 1;
213
- return 0;
214
- }) as BalanceInfo[];
215
-
216
- } catch (error) {
217
- throw new ZanoError("Failed to fetch balances", "BALANCES_FETCH_ERROR");
218
- }
219
- };
266
+ if (alias) {
267
+ const aliasDetailsResponse = await this.fetchDaemon("get_alias_details", {
268
+ alias: alias,
269
+ });
220
270
 
221
- async validateWallet(authData: AuthData) {
222
-
223
- const { message, address, signature } = authData;
224
-
225
- const alias = (authData as AliasAuth).alias || undefined;
226
- const pkey = (authData as PkeyAuth).pkey || undefined;
227
-
228
- if (!message || (!alias && !pkey) || !signature) {
229
- return false;
230
- }
231
-
232
- const validationParams: ValidationParams = {
233
- "buff": Buffer.from(message).toString("base64"),
234
- "sig": signature
235
- };
236
-
237
- if (alias) {
238
- validationParams['alias'] = alias;
239
- } else {
240
- validationParams['pkey'] = pkey;
241
- }
242
-
243
- const response = await this.fetchDaemon(
244
- 'validate_signature',
245
- validationParams
246
- );
247
-
248
- const valid = response?.data?.result?.status === 'OK';
249
-
250
- if (!valid) {
251
- return false;
252
- }
253
-
254
- if (alias) {
255
- const aliasDetailsResponse = await this.fetchDaemon(
256
- 'get_alias_details',
257
- {
258
- "alias": alias,
259
- }
260
- );
261
-
262
- const aliasDetails = aliasDetailsResponse?.data?.result?.alias_details;
263
- const aliasAddress = aliasDetails?.address;
264
-
265
- const addressValid = !!aliasAddress && aliasAddress === address;
266
-
267
- if (!addressValid) {
268
- return false;
269
- }
270
- }
271
-
272
- return valid;
271
+ const aliasDetails = aliasDetailsResponse?.data?.result?.alias_details;
272
+ const aliasAddress = aliasDetails?.address;
273
+
274
+ const addressValid = !!aliasAddress && aliasAddress === address;
275
+
276
+ if (!addressValid) {
277
+ return false;
278
+ }
273
279
  }
274
280
 
275
- async getTxs(params: GetTxsParams) {
276
- const txs = await this.fetchWallet("get_recent_txs_and_info2", {
277
- "count": params.count,
278
- "exclude_mining_txs": params.exclude_mining_txs || false,
279
- "exclude_unconfirmed": params.exclude_unconfirmed || false,
280
- "offset": params.offset,
281
- "order": params.order || "FROM_END_TO_BEGIN",
282
- "update_provision_info": params.update_provision_info || true
281
+ return valid;
282
+ }
283
+
284
+ async getTxs(params: GetTxsParams) {
285
+ const txs = await this.fetchWallet("get_recent_txs_and_info2", {
286
+ count: params.count,
287
+ exclude_mining_txs: params.exclude_mining_txs || false,
288
+ exclude_unconfirmed: params.exclude_unconfirmed || false,
289
+ offset: params.offset,
290
+ order: params.order || "FROM_END_TO_BEGIN",
291
+ update_provision_info: params.update_provision_info || true,
292
+ });
293
+
294
+ return txs.data.result as TxInfo;
295
+ }
296
+ async getAliasDetails(alias: string) {
297
+ try {
298
+ const response = await this.fetchDaemon("get_alias_details", {
299
+ alias,
283
300
  });
284
-
285
- return txs.data.result as TxInfo;
301
+ if (response.data.result) {
302
+ return response.data.result as AliasDetails;
303
+ } else {
304
+ throw new ZanoError(
305
+ `Error fetching alias ${alias}`,
306
+ "ALIAS_FETCH_ERROR"
307
+ );
308
+ }
309
+ } catch {
310
+ throw new ZanoError("Failed to fetch alias", "ALIAS_FETCH_ERROR");
286
311
  }
287
312
  }
288
313
 
314
+ }
289
315
 
290
- export default ServerWallet;
316
+ export default ServerWallet;
@@ -100,4 +100,10 @@ export interface TxInfo {
100
100
  };
101
101
  total_transfers: number;
102
102
  transfers: Transfer[];
103
+ }
104
+
105
+ export interface AliasDetails {
106
+ address: string;
107
+ comment: string;
108
+ tracking_key: string;
103
109
  }