zano-native 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +90 -0
- package/LICENSE +27 -0
- package/README.md +24 -0
- package/android/build.gradle +40 -0
- package/android/src/main/java/app/edge/rnzano/RnZanoModule.java +73 -0
- package/android/src/main/java/app/edge/rnzano/RnZanoPackage.java +21 -0
- package/android/src/main/jniLibs/arm64-v8a/librnzano.so +0 -0
- package/ios/ZanoModule.h +4 -0
- package/ios/ZanoModule.mm +138 -0
- package/ios/ZanoModule.xcframework/Info.plist +43 -0
- package/ios/ZanoModule.xcframework/ios-arm64/libzano-module.a +0 -0
- package/ios/ZanoModule.xcframework/ios-arm64-simulator/libzano-module.a +0 -0
- package/ios/react-native-zano.xcodeproj/project.pbxproj +1 -0
- package/lib/scripts/build-native-host.d.ts +1 -0
- package/lib/scripts/build-native-host.js +175 -0
- package/lib/scripts/smoke-node.d.ts +1 -0
- package/lib/scripts/smoke-node.js +33 -0
- package/lib/scripts/update-sources.d.ts +1 -0
- package/lib/scripts/update-sources.js +412 -0
- package/lib/scripts/utils/android-tools.d.ts +1 -0
- package/lib/scripts/utils/android-tools.js +25 -0
- package/lib/scripts/utils/closeWalletPatch.d.ts +23 -0
- package/lib/scripts/utils/closeWalletPatch.js +215 -0
- package/lib/scripts/utils/common.d.ts +37 -0
- package/lib/scripts/utils/common.js +186 -0
- package/lib/scripts/utils/ios-tools.d.ts +8 -0
- package/lib/scripts/utils/ios-tools.js +26 -0
- package/lib/scripts/utils/sdkFolders.d.ts +27 -0
- package/lib/scripts/utils/sdkFolders.js +43 -0
- package/lib/src/CppBridge.d.ts +142 -0
- package/lib/src/CppBridge.js +668 -0
- package/lib/src/index.d.ts +4 -0
- package/lib/src/index.js +28 -0
- package/lib/src/load-addon.d.ts +5 -0
- package/lib/src/load-addon.js +50 -0
- package/lib/src/node.d.ts +11 -0
- package/lib/src/node.js +25 -0
- package/lib/src/types.d.ts +292 -0
- package/lib/src/types.js +40 -0
- package/lib/src/walletFilePassword.d.ts +14 -0
- package/lib/src/walletFilePassword.js +74 -0
- package/node.d.ts +5 -0
- package/node.js +2 -0
- package/package.json +105 -0
- package/prebuilds/darwin-arm64/zano.node +0 -0
- package/src/node/zano-napi.cpp +176 -0
- package/src/zano-wrapper/zano-methods.hpp +15 -0
- package/zano-native.podspec +27 -0
package/lib/src/index.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.makeZano = void 0;
|
|
18
|
+
const react_native_1 = require("react-native");
|
|
19
|
+
const CppBridge_1 = require("./CppBridge");
|
|
20
|
+
function makeZano() {
|
|
21
|
+
const { ZanoModule } = react_native_1.NativeModules;
|
|
22
|
+
if (ZanoModule == null) {
|
|
23
|
+
throw new Error('zano-native native module not linked');
|
|
24
|
+
}
|
|
25
|
+
return new CppBridge_1.CppBridge(ZanoModule);
|
|
26
|
+
}
|
|
27
|
+
exports.makeZano = makeZano;
|
|
28
|
+
__exportStar(require("./types"), exports);
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.loadNativeAddon = void 0;
|
|
4
|
+
const fs_1 = require("fs");
|
|
5
|
+
const path_1 = require("path");
|
|
6
|
+
function candidatePaths() {
|
|
7
|
+
const here = __dirname;
|
|
8
|
+
const platform = `${process.platform}-${process.arch}`;
|
|
9
|
+
const out = [];
|
|
10
|
+
let dir = here;
|
|
11
|
+
for (let i = 0; i < 6; i++) {
|
|
12
|
+
out.push((0, path_1.join)(dir, 'prebuilds', platform, 'zano.node'));
|
|
13
|
+
out.push((0, path_1.join)(dir, 'build', 'Release', 'zano.node'));
|
|
14
|
+
const parent = (0, path_1.join)(dir, '..');
|
|
15
|
+
if (parent === dir)
|
|
16
|
+
break;
|
|
17
|
+
dir = parent;
|
|
18
|
+
}
|
|
19
|
+
return out;
|
|
20
|
+
}
|
|
21
|
+
let cached;
|
|
22
|
+
function loadNativeAddon() {
|
|
23
|
+
if (cached != null)
|
|
24
|
+
return cached;
|
|
25
|
+
const errors = [];
|
|
26
|
+
const missing = [];
|
|
27
|
+
for (const candidate of candidatePaths()) {
|
|
28
|
+
try {
|
|
29
|
+
if (!(0, fs_1.existsSync)(candidate)) {
|
|
30
|
+
missing.push(candidate);
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
// Native addon loaded at runtime when the .node binary exists.
|
|
34
|
+
const mod = require(candidate);
|
|
35
|
+
if (typeof mod.callZano !== 'function')
|
|
36
|
+
continue;
|
|
37
|
+
cached = mod;
|
|
38
|
+
return cached;
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
42
|
+
errors.push(`${candidate}: ${message}`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
throw new Error('zano-native addon not found. Run `npm run build-native-host`. ' +
|
|
46
|
+
(errors.length > 0
|
|
47
|
+
? errors.join('; ')
|
|
48
|
+
: `Looked in: ${missing.join(', ')}`));
|
|
49
|
+
}
|
|
50
|
+
exports.loadNativeAddon = loadNativeAddon;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { NativeZanoModule } from './CppBridge';
|
|
2
|
+
export type { NativeZanoModule } from './CppBridge';
|
|
3
|
+
export interface MakeNodeZanoModuleOpts {
|
|
4
|
+
documentDirectory: string;
|
|
5
|
+
}
|
|
6
|
+
export type NodeZanoModule = NativeZanoModule;
|
|
7
|
+
/**
|
|
8
|
+
* Node N-API implementation of the native Zano module.
|
|
9
|
+
* Same `callZano` contract as `NativeModules.ZanoModule`.
|
|
10
|
+
*/
|
|
11
|
+
export declare function makeNodeZanoModule(opts: MakeNodeZanoModuleOpts): NodeZanoModule;
|
package/lib/src/node.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.makeNodeZanoModule = void 0;
|
|
4
|
+
const fs_1 = require("fs");
|
|
5
|
+
const load_addon_1 = require("./load-addon");
|
|
6
|
+
/** Directories the Zano SDK expects under documentDirectory. */
|
|
7
|
+
const sdkFolders = ['app_config', 'logs', 'wallets'];
|
|
8
|
+
/**
|
|
9
|
+
* Node N-API implementation of the native Zano module.
|
|
10
|
+
* Same `callZano` contract as `NativeModules.ZanoModule`.
|
|
11
|
+
*/
|
|
12
|
+
function makeNodeZanoModule(opts) {
|
|
13
|
+
const addon = (0, load_addon_1.loadNativeAddon)();
|
|
14
|
+
(0, fs_1.mkdirSync)(opts.documentDirectory, { recursive: true });
|
|
15
|
+
for (const name of sdkFolders) {
|
|
16
|
+
(0, fs_1.mkdirSync)(`${opts.documentDirectory}/${name}`, { recursive: true });
|
|
17
|
+
}
|
|
18
|
+
const methodNames = addon.methodNames();
|
|
19
|
+
return {
|
|
20
|
+
callZano: async (name, jsonArguments) => await addon.callZano(name, jsonArguments),
|
|
21
|
+
methodNames,
|
|
22
|
+
documentDirectory: opts.documentDirectory
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
exports.makeNodeZanoModule = makeNodeZanoModule;
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
interface JsonRpcResponseBase {
|
|
2
|
+
id: number;
|
|
3
|
+
jsonrpc: string;
|
|
4
|
+
}
|
|
5
|
+
interface JsonRpcResponseSuccess<T> extends JsonRpcResponseBase {
|
|
6
|
+
result: T;
|
|
7
|
+
}
|
|
8
|
+
interface JsonRpcResponseError extends JsonRpcResponseBase {
|
|
9
|
+
error: {
|
|
10
|
+
code: string | number;
|
|
11
|
+
message: string;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
export type JsonRpc<T> = JsonRpcResponseSuccess<T> | JsonRpcResponseError;
|
|
15
|
+
/**
|
|
16
|
+
* An error from the native Zano library, carrying its API return code.
|
|
17
|
+
*
|
|
18
|
+
* The message keeps the exact `<code> <detail>` shape this library has
|
|
19
|
+
* always thrown, so callers matching on `error.message` substrings keep
|
|
20
|
+
* working.
|
|
21
|
+
*/
|
|
22
|
+
export declare class ZanoError extends Error {
|
|
23
|
+
/** The bare return code, with any packed detail stripped. */
|
|
24
|
+
readonly code: string;
|
|
25
|
+
constructor(rawCode: string, detail?: string);
|
|
26
|
+
}
|
|
27
|
+
export interface ReturnCode {
|
|
28
|
+
return_code: string;
|
|
29
|
+
}
|
|
30
|
+
export interface WalletFiles {
|
|
31
|
+
items: string[];
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* The shape `plain_wallet::get_address_info` actually returns. Note that
|
|
35
|
+
* `payment_id` is a boolean presence flag, not the id itself, and there is
|
|
36
|
+
* no `is_integrated` field -- the earlier declaration of both was fiction
|
|
37
|
+
* that no native version ever produced.
|
|
38
|
+
*/
|
|
39
|
+
export interface AddressInfo {
|
|
40
|
+
valid: boolean;
|
|
41
|
+
auditable: boolean;
|
|
42
|
+
payment_id: boolean;
|
|
43
|
+
wrap: boolean;
|
|
44
|
+
}
|
|
45
|
+
export interface ConnectivityStatus {
|
|
46
|
+
is_online: boolean;
|
|
47
|
+
is_remote_node_mode: boolean;
|
|
48
|
+
is_server_busy: boolean;
|
|
49
|
+
last_daemon_is_disconnected: boolean;
|
|
50
|
+
last_proxy_communicate_timestamp: number;
|
|
51
|
+
}
|
|
52
|
+
interface AssetInfo {
|
|
53
|
+
asset_id: string;
|
|
54
|
+
current_supply: number;
|
|
55
|
+
decimal_point: number;
|
|
56
|
+
full_name: string;
|
|
57
|
+
hidden_supply: boolean;
|
|
58
|
+
meta_info: string;
|
|
59
|
+
owner: string;
|
|
60
|
+
owner_eth_pub_key: string;
|
|
61
|
+
ticker: string;
|
|
62
|
+
total_max_supply: number;
|
|
63
|
+
}
|
|
64
|
+
interface AssetBalance {
|
|
65
|
+
asset_info: AssetInfo;
|
|
66
|
+
awaiting_in: number;
|
|
67
|
+
awaiting_out: number;
|
|
68
|
+
outs_amount_max: number;
|
|
69
|
+
outs_amount_min: number;
|
|
70
|
+
outs_count: number;
|
|
71
|
+
total: number;
|
|
72
|
+
unlocked: number;
|
|
73
|
+
}
|
|
74
|
+
export interface WalletDetails {
|
|
75
|
+
name: string;
|
|
76
|
+
pass: string;
|
|
77
|
+
private_spend_key: string;
|
|
78
|
+
private_view_key: string;
|
|
79
|
+
public_spend_key: string;
|
|
80
|
+
public_view_key: string;
|
|
81
|
+
recent_history: {
|
|
82
|
+
last_item_index: number;
|
|
83
|
+
total_history_items: number;
|
|
84
|
+
};
|
|
85
|
+
recovered: boolean;
|
|
86
|
+
seed: string;
|
|
87
|
+
wallet_file_size: number;
|
|
88
|
+
wallet_id: number;
|
|
89
|
+
wallet_local_bc_size: number;
|
|
90
|
+
wi: {
|
|
91
|
+
address: string;
|
|
92
|
+
balances: AssetBalance[];
|
|
93
|
+
has_bare_unspent_outputs: boolean;
|
|
94
|
+
is_auditable: boolean;
|
|
95
|
+
is_watch_only: boolean;
|
|
96
|
+
mined_total: number;
|
|
97
|
+
path: string;
|
|
98
|
+
view_sec_key: string;
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
declare enum WalletState {
|
|
102
|
+
SYNCING = 1,
|
|
103
|
+
SYNCED = 2,
|
|
104
|
+
ERROR = 3
|
|
105
|
+
}
|
|
106
|
+
export interface WalletStatus {
|
|
107
|
+
current_daemon_height: number;
|
|
108
|
+
current_wallet_height: number;
|
|
109
|
+
is_daemon_connected: boolean;
|
|
110
|
+
is_in_long_refresh: boolean;
|
|
111
|
+
progress: number;
|
|
112
|
+
wallet_state: WalletState;
|
|
113
|
+
}
|
|
114
|
+
export interface CloseResponse {
|
|
115
|
+
response: string;
|
|
116
|
+
}
|
|
117
|
+
export interface AsyncCallResponse {
|
|
118
|
+
job_id: number;
|
|
119
|
+
}
|
|
120
|
+
export type TryPullResultResponse<T> = {
|
|
121
|
+
status: 'canceled';
|
|
122
|
+
} | {
|
|
123
|
+
status: 'idle';
|
|
124
|
+
} | {
|
|
125
|
+
status: 'delivered';
|
|
126
|
+
result: T | {
|
|
127
|
+
error: {
|
|
128
|
+
code: number;
|
|
129
|
+
message: string;
|
|
130
|
+
};
|
|
131
|
+
};
|
|
132
|
+
};
|
|
133
|
+
export declare const asMaybeBusy: import("cleaners").Cleaner<{
|
|
134
|
+
error: {
|
|
135
|
+
message: any;
|
|
136
|
+
};
|
|
137
|
+
} | undefined>;
|
|
138
|
+
export interface WalletInfoExtended {
|
|
139
|
+
seed: string;
|
|
140
|
+
spend_private_key: string;
|
|
141
|
+
spend_public_key: string;
|
|
142
|
+
view_private_key: string;
|
|
143
|
+
view_public_key: string;
|
|
144
|
+
}
|
|
145
|
+
export declare enum FeePriority {
|
|
146
|
+
DEFAULT = 0,
|
|
147
|
+
UNIMPORTANT = 1,
|
|
148
|
+
NORMAL = 2,
|
|
149
|
+
ELEVATED = 3,
|
|
150
|
+
PRIORITY = 4
|
|
151
|
+
}
|
|
152
|
+
export interface GetSeedPhraseInfo {
|
|
153
|
+
error_code: string;
|
|
154
|
+
response_data: {
|
|
155
|
+
address: string;
|
|
156
|
+
hash_sum_matched: boolean;
|
|
157
|
+
require_password: boolean;
|
|
158
|
+
syntax_correct: boolean;
|
|
159
|
+
tracking: boolean;
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
interface AssetInfo {
|
|
163
|
+
asset_id: string;
|
|
164
|
+
current_supply: number;
|
|
165
|
+
decimal_point: number;
|
|
166
|
+
full_name: string;
|
|
167
|
+
hidden_supply: boolean;
|
|
168
|
+
meta_info: string;
|
|
169
|
+
owner: string;
|
|
170
|
+
owner_eth_pub_key: string;
|
|
171
|
+
ticker: string;
|
|
172
|
+
total_max_supply: number;
|
|
173
|
+
}
|
|
174
|
+
interface AssetBalance {
|
|
175
|
+
asset_info: AssetInfo;
|
|
176
|
+
awaiting_in: number;
|
|
177
|
+
awaiting_out: number;
|
|
178
|
+
outs_amount_max: number;
|
|
179
|
+
outs_amount_min: number;
|
|
180
|
+
outs_count: number;
|
|
181
|
+
total: number;
|
|
182
|
+
unlocked: number;
|
|
183
|
+
}
|
|
184
|
+
export interface GetBalancesResponse {
|
|
185
|
+
balance: number;
|
|
186
|
+
balances: AssetBalance[];
|
|
187
|
+
unlocked_balance: number;
|
|
188
|
+
}
|
|
189
|
+
export interface RecentTransaction {
|
|
190
|
+
comment?: string;
|
|
191
|
+
employed_entries: {
|
|
192
|
+
receive?: Array<{
|
|
193
|
+
amount: number;
|
|
194
|
+
asset_id: string;
|
|
195
|
+
index: number;
|
|
196
|
+
/**
|
|
197
|
+
* The intrinsic payment id as a raw integer, zero when absent. Treat
|
|
198
|
+
* it as a presence signal only: the value is a uint64 that can pass
|
|
199
|
+
* 2^53 and lose precision in JSON. Read actual ids from
|
|
200
|
+
* `subtransfers_by_pid`, which carries them as hex strings.
|
|
201
|
+
*/
|
|
202
|
+
payment_id?: number;
|
|
203
|
+
}>;
|
|
204
|
+
spent?: Array<{
|
|
205
|
+
amount: number;
|
|
206
|
+
asset_id: string;
|
|
207
|
+
index: number;
|
|
208
|
+
payment_id?: number;
|
|
209
|
+
}>;
|
|
210
|
+
};
|
|
211
|
+
fee: number;
|
|
212
|
+
height: number;
|
|
213
|
+
is_mining: boolean;
|
|
214
|
+
is_mixing: boolean;
|
|
215
|
+
is_service: boolean;
|
|
216
|
+
/**
|
|
217
|
+
* Destination addresses recorded by the sending wallet, empty for
|
|
218
|
+
* incoming transfers. Wallet-local history, not chain data: a wallet
|
|
219
|
+
* restored from its seed has none of these.
|
|
220
|
+
*/
|
|
221
|
+
remote_addresses?: string[];
|
|
222
|
+
show_sender: boolean;
|
|
223
|
+
/**
|
|
224
|
+
* Amounts grouped by intrinsic payment id and then by asset, the
|
|
225
|
+
* essential part of the entry since HF6. `payment_id` is hex, or the
|
|
226
|
+
* empty string for amounts that carry no id - a sender's own spent
|
|
227
|
+
* inputs and change always land in the empty-id group, so a sent
|
|
228
|
+
* transfer's recipient ids never appear here.
|
|
229
|
+
*/
|
|
230
|
+
subtransfers_by_pid?: Array<{
|
|
231
|
+
payment_id: string;
|
|
232
|
+
subtransfers: Array<{
|
|
233
|
+
amount: number;
|
|
234
|
+
asset_id: string;
|
|
235
|
+
is_income: boolean;
|
|
236
|
+
}>;
|
|
237
|
+
}>;
|
|
238
|
+
timestamp: number;
|
|
239
|
+
transfer_internal_index: number;
|
|
240
|
+
tx_blob_size: number;
|
|
241
|
+
tx_hash: string;
|
|
242
|
+
tx_type: number;
|
|
243
|
+
unlock_time: number;
|
|
244
|
+
}
|
|
245
|
+
export interface GetRecentTransactionsResponse {
|
|
246
|
+
last_item_index: number;
|
|
247
|
+
pi: {
|
|
248
|
+
balance: number;
|
|
249
|
+
curent_height: number;
|
|
250
|
+
transfer_entries_count: number;
|
|
251
|
+
transfers_count: number;
|
|
252
|
+
unlocked_balance: number;
|
|
253
|
+
};
|
|
254
|
+
total_transfers: number;
|
|
255
|
+
transfers?: RecentTransaction[];
|
|
256
|
+
}
|
|
257
|
+
export interface WhitelistAssetsResponse {
|
|
258
|
+
global_whitelist: AssetInfo[];
|
|
259
|
+
local_whitelist: AssetInfo[];
|
|
260
|
+
own_assets: AssetInfo[];
|
|
261
|
+
}
|
|
262
|
+
export interface TransferParams {
|
|
263
|
+
transfers: Array<{
|
|
264
|
+
assetId: string;
|
|
265
|
+
nativeAmount: number;
|
|
266
|
+
recipient: string;
|
|
267
|
+
}>;
|
|
268
|
+
comment?: string;
|
|
269
|
+
fee: number;
|
|
270
|
+
}
|
|
271
|
+
export interface TransferResponse {
|
|
272
|
+
tx_hash: string;
|
|
273
|
+
tx_size: number;
|
|
274
|
+
tx_unsigned_hex: '';
|
|
275
|
+
}
|
|
276
|
+
export interface BurnAssetParams {
|
|
277
|
+
assetId: string;
|
|
278
|
+
burnAmount: number;
|
|
279
|
+
nativeAmount?: number;
|
|
280
|
+
pointTxToAddress?: string;
|
|
281
|
+
serviceEntries?: Array<{
|
|
282
|
+
body: string;
|
|
283
|
+
flags?: number;
|
|
284
|
+
instruction: string;
|
|
285
|
+
security?: string;
|
|
286
|
+
service_id: string;
|
|
287
|
+
}>;
|
|
288
|
+
}
|
|
289
|
+
export interface BurnAssetResponse {
|
|
290
|
+
tx_id: string;
|
|
291
|
+
}
|
|
292
|
+
export {};
|
package/lib/src/types.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FeePriority = exports.asMaybeBusy = exports.ZanoError = void 0;
|
|
4
|
+
const cleaners_1 = require("cleaners");
|
|
5
|
+
/**
|
|
6
|
+
* An error from the native Zano library, carrying its API return code.
|
|
7
|
+
*
|
|
8
|
+
* The message keeps the exact `<code> <detail>` shape this library has
|
|
9
|
+
* always thrown, so callers matching on `error.message` substrings keep
|
|
10
|
+
* working.
|
|
11
|
+
*/
|
|
12
|
+
class ZanoError extends Error {
|
|
13
|
+
constructor(rawCode, detail = '') {
|
|
14
|
+
super(`${rawCode} ${detail}`);
|
|
15
|
+
this.name = 'ZanoError';
|
|
16
|
+
// The native layer packs detail into the code itself, as `FAIL:<what>`
|
|
17
|
+
// or `INTERNAL_ERROR, DESCRIPTION: <what>`:
|
|
18
|
+
this.code = rawCode.split(/[\s,:]/)[0];
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
exports.ZanoError = ZanoError;
|
|
22
|
+
var WalletState;
|
|
23
|
+
(function (WalletState) {
|
|
24
|
+
WalletState[WalletState["SYNCING"] = 1] = "SYNCING";
|
|
25
|
+
WalletState[WalletState["SYNCED"] = 2] = "SYNCED";
|
|
26
|
+
WalletState[WalletState["ERROR"] = 3] = "ERROR";
|
|
27
|
+
})(WalletState || (WalletState = {}));
|
|
28
|
+
exports.asMaybeBusy = (0, cleaners_1.asMaybe)((0, cleaners_1.asObject)({
|
|
29
|
+
error: (0, cleaners_1.asObject)({
|
|
30
|
+
message: (0, cleaners_1.asValue)('BUSY')
|
|
31
|
+
})
|
|
32
|
+
}));
|
|
33
|
+
var FeePriority;
|
|
34
|
+
(function (FeePriority) {
|
|
35
|
+
FeePriority[FeePriority["DEFAULT"] = 0] = "DEFAULT";
|
|
36
|
+
FeePriority[FeePriority["UNIMPORTANT"] = 1] = "UNIMPORTANT";
|
|
37
|
+
FeePriority[FeePriority["NORMAL"] = 2] = "NORMAL";
|
|
38
|
+
FeePriority[FeePriority["ELEVATED"] = 3] = "ELEVATED";
|
|
39
|
+
FeePriority[FeePriority["PRIORITY"] = 4] = "PRIORITY";
|
|
40
|
+
})(FeePriority = exports.FeePriority || (exports.FeePriority = {}));
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Derives the password used to encrypt the wallet file on disk.
|
|
3
|
+
*
|
|
4
|
+
* Versions 0.3.0 and earlier encrypted the file with the seed passphrase,
|
|
5
|
+
* which is the empty string for most wallets, leaving the seed and spend
|
|
6
|
+
* keys effectively unencrypted on disk. The file is a local cache that can
|
|
7
|
+
* always be rebuilt from the mnemonic, so the only requirement here is
|
|
8
|
+
* stability: the same mnemonic must derive the same password on every
|
|
9
|
+
* device, forever.
|
|
10
|
+
*
|
|
11
|
+
* The mnemonic is normalized before hashing because callers store and pass
|
|
12
|
+
* whatever spacing the user or a scanner produced.
|
|
13
|
+
*/
|
|
14
|
+
export declare function deriveWalletFilePassword(mnemonic: string): string;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.deriveWalletFilePassword = void 0;
|
|
7
|
+
const rfc4648_1 = require("rfc4648");
|
|
8
|
+
const tweetnacl_1 = __importDefault(require("tweetnacl"));
|
|
9
|
+
/**
|
|
10
|
+
* Domain separator for the wallet-file password.
|
|
11
|
+
*
|
|
12
|
+
* Changing this value (or anything else about the derivation) orphans every
|
|
13
|
+
* wallet file already encrypted with it, forcing a delete-and-restore. If
|
|
14
|
+
* the derivation must ever change, bump the version suffix and keep the old
|
|
15
|
+
* derivation in `startWallet`'s legacy-password list.
|
|
16
|
+
*/
|
|
17
|
+
const DOMAIN = 'react-native-zano:file-password:v1';
|
|
18
|
+
/**
|
|
19
|
+
* Zano caps wallet-file passwords at 40 characters over a restricted
|
|
20
|
+
* alphabet (`PASSWORD_REGEXP` in Zano core, enforced by `wallet2::generate`).
|
|
21
|
+
* 16 bytes of hex is 32 characters, inside both limits.
|
|
22
|
+
*/
|
|
23
|
+
const PASSWORD_BYTES = 16;
|
|
24
|
+
/**
|
|
25
|
+
* Encodes a string as UTF-8 without relying on Buffer or TextEncoder.
|
|
26
|
+
*
|
|
27
|
+
* This module runs both on the React Native JS thread and inside
|
|
28
|
+
* edge-currency-accountbased's plugin WebView, and `TextEncoder` is not
|
|
29
|
+
* guaranteed in every engine and polyfill combination those present. The
|
|
30
|
+
* derivation must produce identical bytes everywhere, forever, so it does
|
|
31
|
+
* not depend on a host global that may be absent.
|
|
32
|
+
*/
|
|
33
|
+
function utf8Bytes(text) {
|
|
34
|
+
const out = [];
|
|
35
|
+
for (let i = 0; i < text.length; ++i) {
|
|
36
|
+
let code = text.charCodeAt(i);
|
|
37
|
+
if (code >= 0xd800 && code <= 0xdbff && i + 1 < text.length) {
|
|
38
|
+
// Surrogate pair:
|
|
39
|
+
code = 0x10000 + ((code - 0xd800) << 10) + (text.charCodeAt(++i) - 0xdc00);
|
|
40
|
+
}
|
|
41
|
+
if (code < 0x80) {
|
|
42
|
+
out.push(code);
|
|
43
|
+
}
|
|
44
|
+
else if (code < 0x800) {
|
|
45
|
+
out.push(0xc0 | (code >> 6), 0x80 | (code & 0x3f));
|
|
46
|
+
}
|
|
47
|
+
else if (code < 0x10000) {
|
|
48
|
+
out.push(0xe0 | (code >> 12), 0x80 | ((code >> 6) & 0x3f), 0x80 | (code & 0x3f));
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
out.push(0xf0 | (code >> 18), 0x80 | ((code >> 12) & 0x3f), 0x80 | ((code >> 6) & 0x3f), 0x80 | (code & 0x3f));
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return Uint8Array.from(out);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Derives the password used to encrypt the wallet file on disk.
|
|
58
|
+
*
|
|
59
|
+
* Versions 0.3.0 and earlier encrypted the file with the seed passphrase,
|
|
60
|
+
* which is the empty string for most wallets, leaving the seed and spend
|
|
61
|
+
* keys effectively unencrypted on disk. The file is a local cache that can
|
|
62
|
+
* always be rebuilt from the mnemonic, so the only requirement here is
|
|
63
|
+
* stability: the same mnemonic must derive the same password on every
|
|
64
|
+
* device, forever.
|
|
65
|
+
*
|
|
66
|
+
* The mnemonic is normalized before hashing because callers store and pass
|
|
67
|
+
* whatever spacing the user or a scanner produced.
|
|
68
|
+
*/
|
|
69
|
+
function deriveWalletFilePassword(mnemonic) {
|
|
70
|
+
const normalized = mnemonic.trim().replace(/\s+/g, ' ');
|
|
71
|
+
const digest = tweetnacl_1.default.hash(utf8Bytes(`${DOMAIN}|${normalized}`));
|
|
72
|
+
return rfc4648_1.base16.stringify(digest.subarray(0, PASSWORD_BYTES)).toLowerCase();
|
|
73
|
+
}
|
|
74
|
+
exports.deriveWalletFilePassword = deriveWalletFilePassword;
|
package/node.d.ts
ADDED
package/node.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "zano-native",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Native Zano wallet library for React Native and Node.js",
|
|
5
|
+
"homepage": "https://github.com/EdgeApp/zano-native",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git@github.com:EdgeApp/zano-native.git"
|
|
9
|
+
},
|
|
10
|
+
"license": "MIT",
|
|
11
|
+
"author": "Airbitz Inc dba Edge",
|
|
12
|
+
"main": "lib/src/index.js",
|
|
13
|
+
"types": "lib/src/index.d.ts",
|
|
14
|
+
"files": [
|
|
15
|
+
"/android/build.gradle",
|
|
16
|
+
"/android/src/",
|
|
17
|
+
"/CHANGELOG.md",
|
|
18
|
+
"/ios/",
|
|
19
|
+
"/lib/",
|
|
20
|
+
"/LICENSE",
|
|
21
|
+
"/node.d.ts",
|
|
22
|
+
"/node.js",
|
|
23
|
+
"/package.json",
|
|
24
|
+
"/prebuilds/",
|
|
25
|
+
"/README.md",
|
|
26
|
+
"/src/node/",
|
|
27
|
+
"/src/zano-wrapper/zano-methods.hpp",
|
|
28
|
+
"/zano-native.podspec",
|
|
29
|
+
"!/android/src/main/jniLibs/armeabi-v7a"
|
|
30
|
+
],
|
|
31
|
+
"lint-staged": {
|
|
32
|
+
"*.{js,ts}": "eslint"
|
|
33
|
+
},
|
|
34
|
+
"scripts": {
|
|
35
|
+
"build-native-arm64": "ZERO_AR_DATE=1 node -r sucrase/register ./scripts/update-sources.ts --arm64",
|
|
36
|
+
"build-native-host": "ZERO_AR_DATE=1 node -r sucrase/register ./scripts/build-native-host.ts",
|
|
37
|
+
"fix": "npm run lint -- --fix",
|
|
38
|
+
"lint": "eslint .",
|
|
39
|
+
"prepare": "husky install && rimraf lib && tsc",
|
|
40
|
+
"prepublishOnly": "npm run build-native-arm64 && npm run build-native-host",
|
|
41
|
+
"smoke-node": "node -r sucrase/register ./scripts/smoke-node.ts",
|
|
42
|
+
"test": "mocha",
|
|
43
|
+
"update-sources": "ZERO_AR_DATE=1 node -r sucrase/register ./scripts/update-sources.ts",
|
|
44
|
+
"verify": "npm run lint && npm test && tsc --noEmit -p tsconfig.eslint.json"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"@types/mocha": "^10.0.1",
|
|
48
|
+
"@types/node": "^14.14.7",
|
|
49
|
+
"@typescript-eslint/eslint-plugin": "^5.36.2",
|
|
50
|
+
"@typescript-eslint/parser": "^5.36.2",
|
|
51
|
+
"disklet": "^0.4.6",
|
|
52
|
+
"eslint": "^8.57.0",
|
|
53
|
+
"eslint-config-standard-kit": "0.15.1",
|
|
54
|
+
"eslint-plugin-import": "^2.22.1",
|
|
55
|
+
"eslint-plugin-prettier": "^3.1.4",
|
|
56
|
+
"eslint-plugin-promise": "^4.2.1",
|
|
57
|
+
"eslint-plugin-simple-import-sort": "^6.0.1",
|
|
58
|
+
"eslint-plugin-standard": "^4.0.1",
|
|
59
|
+
"husky": "^7.0.0",
|
|
60
|
+
"lint-staged": "^10.5.3",
|
|
61
|
+
"mocha": "^10.2.0",
|
|
62
|
+
"prettier": "^2.8.8",
|
|
63
|
+
"rimraf": "^3.0.2",
|
|
64
|
+
"sucrase": "^3.16.0",
|
|
65
|
+
"typescript": "5.0.4",
|
|
66
|
+
"node-gyp": "^11.5.0"
|
|
67
|
+
},
|
|
68
|
+
"dependencies": {
|
|
69
|
+
"cleaners": "^0.3.17",
|
|
70
|
+
"rfc4648": "^1.5.4",
|
|
71
|
+
"tweetnacl": "^1.0.3",
|
|
72
|
+
"node-addon-api": "^8.9.1"
|
|
73
|
+
},
|
|
74
|
+
"exports": {
|
|
75
|
+
".": {
|
|
76
|
+
"types": "./lib/src/index.d.ts",
|
|
77
|
+
"react-native": "./lib/src/index.js",
|
|
78
|
+
"default": "./lib/src/index.js"
|
|
79
|
+
},
|
|
80
|
+
"./node": {
|
|
81
|
+
"types": "./lib/src/node.d.ts",
|
|
82
|
+
"default": "./lib/src/node.js"
|
|
83
|
+
},
|
|
84
|
+
"./package.json": "./package.json",
|
|
85
|
+
"./lib/src/CppBridge": {
|
|
86
|
+
"types": "./lib/src/CppBridge.d.ts",
|
|
87
|
+
"default": "./lib/src/CppBridge.js"
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
"typesVersions": {
|
|
91
|
+
"*": {
|
|
92
|
+
"node": [
|
|
93
|
+
"lib/src/node.d.ts"
|
|
94
|
+
]
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
"peerDependencies": {
|
|
98
|
+
"react-native": ">=0.47.0 <1.0.0"
|
|
99
|
+
},
|
|
100
|
+
"peerDependenciesMeta": {
|
|
101
|
+
"react-native": {
|
|
102
|
+
"optional": true
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
Binary file
|