@unicitylabs/sphere-sdk 0.2.1 → 0.2.2
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/dist/core/index.cjs +810 -436
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +111 -1
- package/dist/core/index.d.ts +111 -1
- package/dist/core/index.js +699 -322
- package/dist/core/index.js.map +1 -1
- package/dist/impl/browser/index.cjs +27 -8
- package/dist/impl/browser/index.cjs.map +1 -1
- package/dist/impl/browser/index.js +27 -8
- package/dist/impl/browser/index.js.map +1 -1
- package/dist/impl/nodejs/index.cjs +8 -5
- package/dist/impl/nodejs/index.cjs.map +1 -1
- package/dist/impl/nodejs/index.d.cts +1 -0
- package/dist/impl/nodejs/index.d.ts +1 -0
- package/dist/impl/nodejs/index.js +8 -5
- package/dist/impl/nodejs/index.js.map +1 -1
- package/dist/index.cjs +950 -616
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +100 -1
- package/dist/index.d.ts +100 -1
- package/dist/index.js +860 -526
- package/dist/index.js.map +1 -1
- package/dist/l1/index.cjs +18 -0
- package/dist/l1/index.cjs.map +1 -1
- package/dist/l1/index.d.cts +4 -0
- package/dist/l1/index.d.ts +4 -0
- package/dist/l1/index.js +18 -0
- package/dist/l1/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -5,6 +5,9 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
|
5
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
6
|
var __getProtoOf = Object.getPrototypeOf;
|
|
7
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __esm = (fn, res) => function __init() {
|
|
9
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
10
|
+
};
|
|
8
11
|
var __export = (target, all) => {
|
|
9
12
|
for (var name in all)
|
|
10
13
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -27,218 +30,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
27
30
|
));
|
|
28
31
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
32
|
|
|
30
|
-
// index.ts
|
|
31
|
-
var index_exports = {};
|
|
32
|
-
__export(index_exports, {
|
|
33
|
-
COIN_TYPES: () => COIN_TYPES,
|
|
34
|
-
CoinGeckoPriceProvider: () => CoinGeckoPriceProvider,
|
|
35
|
-
CommunicationsModule: () => CommunicationsModule,
|
|
36
|
-
DEFAULT_AGGREGATOR_TIMEOUT: () => DEFAULT_AGGREGATOR_TIMEOUT,
|
|
37
|
-
DEFAULT_AGGREGATOR_URL: () => DEFAULT_AGGREGATOR_URL,
|
|
38
|
-
DEFAULT_DERIVATION_PATH: () => DEFAULT_DERIVATION_PATH,
|
|
39
|
-
DEFAULT_ELECTRUM_URL: () => DEFAULT_ELECTRUM_URL,
|
|
40
|
-
DEFAULT_IPFS_BOOTSTRAP_PEERS: () => DEFAULT_IPFS_BOOTSTRAP_PEERS,
|
|
41
|
-
DEFAULT_IPFS_GATEWAYS: () => DEFAULT_IPFS_GATEWAYS,
|
|
42
|
-
DEFAULT_NOSTR_RELAYS: () => DEFAULT_NOSTR_RELAYS,
|
|
43
|
-
DEV_AGGREGATOR_URL: () => DEV_AGGREGATOR_URL,
|
|
44
|
-
L1: () => l1_exports,
|
|
45
|
-
L1PaymentsModule: () => L1PaymentsModule,
|
|
46
|
-
LIMITS: () => LIMITS,
|
|
47
|
-
NETWORKS: () => NETWORKS,
|
|
48
|
-
NOSTR_EVENT_KINDS: () => NOSTR_EVENT_KINDS,
|
|
49
|
-
PaymentsModule: () => PaymentsModule,
|
|
50
|
-
STORAGE_KEYS: () => STORAGE_KEYS,
|
|
51
|
-
STORAGE_PREFIX: () => STORAGE_PREFIX,
|
|
52
|
-
Sphere: () => Sphere,
|
|
53
|
-
SphereError: () => SphereError,
|
|
54
|
-
TEST_AGGREGATOR_URL: () => TEST_AGGREGATOR_URL,
|
|
55
|
-
TEST_ELECTRUM_URL: () => TEST_ELECTRUM_URL,
|
|
56
|
-
TEST_NOSTR_RELAYS: () => TEST_NOSTR_RELAYS,
|
|
57
|
-
TIMEOUTS: () => TIMEOUTS,
|
|
58
|
-
TokenRegistry: () => TokenRegistry,
|
|
59
|
-
TokenValidator: () => TokenValidator,
|
|
60
|
-
archivedKeyFromTokenId: () => archivedKeyFromTokenId,
|
|
61
|
-
base58Decode: () => base58Decode,
|
|
62
|
-
base58Encode: () => base58Encode2,
|
|
63
|
-
buildTxfStorageData: () => buildTxfStorageData,
|
|
64
|
-
bytesToHex: () => bytesToHex2,
|
|
65
|
-
countCommittedTransactions: () => countCommittedTransactions,
|
|
66
|
-
createAddress: () => createAddress,
|
|
67
|
-
createCommunicationsModule: () => createCommunicationsModule,
|
|
68
|
-
createKeyPair: () => createKeyPair,
|
|
69
|
-
createL1PaymentsModule: () => createL1PaymentsModule,
|
|
70
|
-
createPaymentSession: () => createPaymentSession,
|
|
71
|
-
createPaymentSessionError: () => createPaymentSessionError,
|
|
72
|
-
createPaymentsModule: () => createPaymentsModule,
|
|
73
|
-
createPriceProvider: () => createPriceProvider,
|
|
74
|
-
createSphere: () => createSphere,
|
|
75
|
-
createSplitPaymentSession: () => createSplitPaymentSession,
|
|
76
|
-
createTokenValidator: () => createTokenValidator,
|
|
77
|
-
decodeBech32: () => decodeBech32,
|
|
78
|
-
decryptCMasterKey: () => decryptCMasterKey,
|
|
79
|
-
decryptPrivateKey: () => decryptPrivateKey,
|
|
80
|
-
decryptTextFormatKey: () => decryptTextFormatKey,
|
|
81
|
-
deriveAddressInfo: () => deriveAddressInfo,
|
|
82
|
-
deriveChildKey: () => deriveChildKey,
|
|
83
|
-
deriveKeyAtPath: () => deriveKeyAtPath,
|
|
84
|
-
doubleSha256: () => doubleSha256,
|
|
85
|
-
encodeBech32: () => encodeBech32,
|
|
86
|
-
extractFromText: () => extractFromText,
|
|
87
|
-
findPattern: () => findPattern,
|
|
88
|
-
forkedKeyFromTokenIdAndState: () => forkedKeyFromTokenIdAndState,
|
|
89
|
-
formatAmount: () => formatAmount,
|
|
90
|
-
generateMasterKey: () => generateMasterKey,
|
|
91
|
-
generateMnemonic: () => generateMnemonic2,
|
|
92
|
-
getAddressHrp: () => getAddressHrp,
|
|
93
|
-
getCoinIdByName: () => getCoinIdByName,
|
|
94
|
-
getCoinIdBySymbol: () => getCoinIdBySymbol,
|
|
95
|
-
getCurrentStateHash: () => getCurrentStateHash,
|
|
96
|
-
getPublicKey: () => getPublicKey,
|
|
97
|
-
getSphere: () => getSphere,
|
|
98
|
-
getTokenDecimals: () => getTokenDecimals,
|
|
99
|
-
getTokenDefinition: () => getTokenDefinition,
|
|
100
|
-
getTokenIconUrl: () => getTokenIconUrl,
|
|
101
|
-
getTokenId: () => getTokenId,
|
|
102
|
-
getTokenName: () => getTokenName,
|
|
103
|
-
getTokenSymbol: () => getTokenSymbol,
|
|
104
|
-
hasMissingNewStateHash: () => hasMissingNewStateHash,
|
|
105
|
-
hasUncommittedTransactions: () => hasUncommittedTransactions,
|
|
106
|
-
hasValidTxfData: () => hasValidTxfData,
|
|
107
|
-
hash160: () => hash160,
|
|
108
|
-
hexToBytes: () => hexToBytes,
|
|
109
|
-
identityFromMnemonicSync: () => identityFromMnemonicSync,
|
|
110
|
-
initSphere: () => initSphere,
|
|
111
|
-
isArchivedKey: () => isArchivedKey,
|
|
112
|
-
isForkedKey: () => isForkedKey,
|
|
113
|
-
isInstantSplitBundle: () => isInstantSplitBundle,
|
|
114
|
-
isInstantSplitBundleV4: () => isInstantSplitBundleV4,
|
|
115
|
-
isInstantSplitBundleV5: () => isInstantSplitBundleV5,
|
|
116
|
-
isKnownToken: () => isKnownToken,
|
|
117
|
-
isPaymentSessionTerminal: () => isPaymentSessionTerminal,
|
|
118
|
-
isPaymentSessionTimedOut: () => isPaymentSessionTimedOut,
|
|
119
|
-
isSQLiteDatabase: () => isSQLiteDatabase,
|
|
120
|
-
isTextWalletEncrypted: () => isTextWalletEncrypted,
|
|
121
|
-
isTokenKey: () => isTokenKey,
|
|
122
|
-
isValidBech32: () => isValidBech32,
|
|
123
|
-
isValidPrivateKey: () => isValidPrivateKey,
|
|
124
|
-
isValidTokenId: () => isValidTokenId,
|
|
125
|
-
isWalletDatEncrypted: () => isWalletDatEncrypted,
|
|
126
|
-
isWalletTextFormat: () => isWalletTextFormat,
|
|
127
|
-
keyFromTokenId: () => keyFromTokenId,
|
|
128
|
-
loadSphere: () => loadSphere,
|
|
129
|
-
mnemonicToSeedSync: () => mnemonicToSeedSync2,
|
|
130
|
-
normalizeSdkTokenToStorage: () => normalizeSdkTokenToStorage,
|
|
131
|
-
objectToTxf: () => objectToTxf,
|
|
132
|
-
parseAndDecryptWalletDat: () => parseAndDecryptWalletDat,
|
|
133
|
-
parseAndDecryptWalletText: () => parseAndDecryptWalletText,
|
|
134
|
-
parseForkedKey: () => parseForkedKey,
|
|
135
|
-
parseTxfStorageData: () => parseTxfStorageData,
|
|
136
|
-
parseWalletDat: () => parseWalletDat,
|
|
137
|
-
parseWalletText: () => parseWalletText,
|
|
138
|
-
randomBytes: () => randomBytes,
|
|
139
|
-
randomHex: () => randomHex,
|
|
140
|
-
randomUUID: () => randomUUID,
|
|
141
|
-
ripemd160: () => ripemd160,
|
|
142
|
-
sha256: () => sha256,
|
|
143
|
-
sleep: () => sleep,
|
|
144
|
-
sphereExists: () => sphereExists,
|
|
145
|
-
toHumanReadable: () => toHumanReadable,
|
|
146
|
-
toSmallestUnit: () => toSmallestUnit,
|
|
147
|
-
tokenIdFromArchivedKey: () => tokenIdFromArchivedKey,
|
|
148
|
-
tokenIdFromKey: () => tokenIdFromKey,
|
|
149
|
-
tokenToTxf: () => tokenToTxf,
|
|
150
|
-
txfToToken: () => txfToToken,
|
|
151
|
-
validateMnemonic: () => validateMnemonic2
|
|
152
|
-
});
|
|
153
|
-
module.exports = __toCommonJS(index_exports);
|
|
154
|
-
|
|
155
|
-
// l1/index.ts
|
|
156
|
-
var l1_exports = {};
|
|
157
|
-
__export(l1_exports, {
|
|
158
|
-
CHARSET: () => CHARSET,
|
|
159
|
-
VESTING_THRESHOLD: () => VESTING_THRESHOLD,
|
|
160
|
-
WalletAddressHelper: () => WalletAddressHelper,
|
|
161
|
-
addressToScriptHash: () => addressToScriptHash,
|
|
162
|
-
broadcast: () => broadcast,
|
|
163
|
-
buildSegWitTransaction: () => buildSegWitTransaction,
|
|
164
|
-
collectUtxosForAmount: () => collectUtxosForAmount,
|
|
165
|
-
computeHash160: () => computeHash160,
|
|
166
|
-
connect: () => connect,
|
|
167
|
-
convertBits: () => convertBits,
|
|
168
|
-
createAndSignTransaction: () => createAndSignTransaction,
|
|
169
|
-
createBech32: () => createBech32,
|
|
170
|
-
createScriptPubKey: () => createScriptPubKey,
|
|
171
|
-
createTransactionPlan: () => createTransactionPlan,
|
|
172
|
-
decodeBech32: () => decodeBech32,
|
|
173
|
-
decrypt: () => decrypt,
|
|
174
|
-
decryptWallet: () => decryptWallet,
|
|
175
|
-
deriveChildKey: () => deriveChildKey2,
|
|
176
|
-
deriveChildKeyBIP32: () => deriveChildKeyBIP32,
|
|
177
|
-
deriveKeyAtPath: () => deriveKeyAtPath2,
|
|
178
|
-
disconnect: () => disconnect,
|
|
179
|
-
domIdToPath: () => domIdToPath,
|
|
180
|
-
ec: () => ec,
|
|
181
|
-
encodeBech32: () => encodeBech32,
|
|
182
|
-
encrypt: () => encrypt,
|
|
183
|
-
encryptWallet: () => encryptWallet,
|
|
184
|
-
generateAddressFromMasterKey: () => generateAddressFromMasterKey,
|
|
185
|
-
generateAddressInfo: () => generateAddressInfo,
|
|
186
|
-
generateHDAddress: () => generateHDAddress,
|
|
187
|
-
generateHDAddressBIP32: () => generateHDAddressBIP32,
|
|
188
|
-
generateMasterKeyFromSeed: () => generateMasterKeyFromSeed,
|
|
189
|
-
generatePrivateKey: () => generatePrivateKey,
|
|
190
|
-
getBalance: () => getBalance,
|
|
191
|
-
getBlockHeader: () => getBlockHeader,
|
|
192
|
-
getCurrentBlockHeight: () => getCurrentBlockHeight,
|
|
193
|
-
getIndexFromPath: () => getIndexFromPath,
|
|
194
|
-
getTransaction: () => getTransaction,
|
|
195
|
-
getTransactionHistory: () => getTransactionHistory,
|
|
196
|
-
getUtxo: () => getUtxo,
|
|
197
|
-
hash160: () => hash160,
|
|
198
|
-
hash160ToBytes: () => hash160ToBytes,
|
|
199
|
-
hexToWIF: () => hexToWIF,
|
|
200
|
-
isChangePath: () => isChangePath,
|
|
201
|
-
isWebSocketConnected: () => isWebSocketConnected,
|
|
202
|
-
parsePathComponents: () => parsePathComponents,
|
|
203
|
-
pathToDOMId: () => pathToDOMId,
|
|
204
|
-
privateKeyToAddressInfo: () => privateKeyToAddressInfo,
|
|
205
|
-
publicKeyToAddress: () => publicKeyToAddress,
|
|
206
|
-
rpc: () => rpc,
|
|
207
|
-
sendAlpha: () => sendAlpha,
|
|
208
|
-
subscribeBlocks: () => subscribeBlocks,
|
|
209
|
-
vestingClassifier: () => vestingClassifier,
|
|
210
|
-
vestingState: () => vestingState,
|
|
211
|
-
waitForConnection: () => waitForConnection
|
|
212
|
-
});
|
|
213
|
-
|
|
214
|
-
// l1/types.ts
|
|
215
|
-
function parsePathComponents(path) {
|
|
216
|
-
const match = path.match(/m\/\d+'\/\d+'\/\d+'\/(\d+)\/(\d+)/);
|
|
217
|
-
if (!match) return null;
|
|
218
|
-
return { chain: parseInt(match[1], 10), index: parseInt(match[2], 10) };
|
|
219
|
-
}
|
|
220
|
-
function isChangePath(path) {
|
|
221
|
-
const parsed = parsePathComponents(path);
|
|
222
|
-
return parsed?.chain === 1;
|
|
223
|
-
}
|
|
224
|
-
function getIndexFromPath(path) {
|
|
225
|
-
const parsed = parsePathComponents(path);
|
|
226
|
-
return parsed?.index ?? 0;
|
|
227
|
-
}
|
|
228
|
-
function pathToDOMId(path) {
|
|
229
|
-
return path.replace(/'/g, "h").replace(/\//g, "-");
|
|
230
|
-
}
|
|
231
|
-
function domIdToPath(encoded) {
|
|
232
|
-
const parts = encoded.split("-");
|
|
233
|
-
return parts.map((part, idx) => {
|
|
234
|
-
if (idx === 0) return part;
|
|
235
|
-
return part.endsWith("h") ? `${part.slice(0, -1)}'` : part;
|
|
236
|
-
}).join("/");
|
|
237
|
-
}
|
|
238
|
-
|
|
239
33
|
// core/bech32.ts
|
|
240
|
-
var CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l";
|
|
241
|
-
var GENERATOR = [996825010, 642813549, 513874426, 1027748829, 705979059];
|
|
242
34
|
function convertBits(data, fromBits, toBits, pad) {
|
|
243
35
|
let acc = 0;
|
|
244
36
|
let bits = 0;
|
|
@@ -345,10 +137,17 @@ function getAddressHrp(addr) {
|
|
|
345
137
|
const result = decodeBech32(addr);
|
|
346
138
|
return result?.hrp ?? null;
|
|
347
139
|
}
|
|
348
|
-
var
|
|
140
|
+
var CHARSET, GENERATOR, createBech32;
|
|
141
|
+
var init_bech32 = __esm({
|
|
142
|
+
"core/bech32.ts"() {
|
|
143
|
+
"use strict";
|
|
144
|
+
CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l";
|
|
145
|
+
GENERATOR = [996825010, 642813549, 513874426, 1027748829, 705979059];
|
|
146
|
+
createBech32 = encodeBech32;
|
|
147
|
+
}
|
|
148
|
+
});
|
|
349
149
|
|
|
350
150
|
// l1/addressToScriptHash.ts
|
|
351
|
-
var import_crypto_js = __toESM(require("crypto-js"), 1);
|
|
352
151
|
function bytesToHex(buf) {
|
|
353
152
|
return Array.from(buf).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
354
153
|
}
|
|
@@ -359,301 +158,34 @@ function addressToScriptHash(address) {
|
|
|
359
158
|
const sha = import_crypto_js.default.SHA256(import_crypto_js.default.enc.Hex.parse(scriptHex)).toString();
|
|
360
159
|
return sha.match(/../g).reverse().join("");
|
|
361
160
|
}
|
|
161
|
+
var import_crypto_js;
|
|
162
|
+
var init_addressToScriptHash = __esm({
|
|
163
|
+
"l1/addressToScriptHash.ts"() {
|
|
164
|
+
"use strict";
|
|
165
|
+
init_bech32();
|
|
166
|
+
import_crypto_js = __toESM(require("crypto-js"), 1);
|
|
167
|
+
}
|
|
168
|
+
});
|
|
362
169
|
|
|
363
|
-
//
|
|
364
|
-
var
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
)
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
const I = import_crypto_js2.default.HmacSHA512(
|
|
383
|
-
import_crypto_js2.default.enc.Hex.parse(seedHex),
|
|
384
|
-
import_crypto_js2.default.enc.Utf8.parse("Bitcoin seed")
|
|
385
|
-
).toString();
|
|
386
|
-
const IL = I.substring(0, 64);
|
|
387
|
-
const IR = I.substring(64);
|
|
388
|
-
const masterKeyBigInt = BigInt("0x" + IL);
|
|
389
|
-
if (masterKeyBigInt === 0n || masterKeyBigInt >= CURVE_ORDER) {
|
|
390
|
-
throw new Error("Invalid master key generated");
|
|
391
|
-
}
|
|
392
|
-
return {
|
|
393
|
-
privateKey: IL,
|
|
394
|
-
chainCode: IR
|
|
395
|
-
};
|
|
396
|
-
}
|
|
397
|
-
function deriveChildKey(parentPrivKey, parentChainCode, index) {
|
|
398
|
-
const isHardened = index >= 2147483648;
|
|
399
|
-
let data;
|
|
400
|
-
if (isHardened) {
|
|
401
|
-
const indexHex = index.toString(16).padStart(8, "0");
|
|
402
|
-
data = "00" + parentPrivKey + indexHex;
|
|
403
|
-
} else {
|
|
404
|
-
const keyPair = ec.keyFromPrivate(parentPrivKey, "hex");
|
|
405
|
-
const compressedPubKey = keyPair.getPublic(true, "hex");
|
|
406
|
-
const indexHex = index.toString(16).padStart(8, "0");
|
|
407
|
-
data = compressedPubKey + indexHex;
|
|
408
|
-
}
|
|
409
|
-
const I = import_crypto_js2.default.HmacSHA512(
|
|
410
|
-
import_crypto_js2.default.enc.Hex.parse(data),
|
|
411
|
-
import_crypto_js2.default.enc.Hex.parse(parentChainCode)
|
|
412
|
-
).toString();
|
|
413
|
-
const IL = I.substring(0, 64);
|
|
414
|
-
const IR = I.substring(64);
|
|
415
|
-
const ilBigInt = BigInt("0x" + IL);
|
|
416
|
-
const parentKeyBigInt = BigInt("0x" + parentPrivKey);
|
|
417
|
-
if (ilBigInt >= CURVE_ORDER) {
|
|
418
|
-
throw new Error("Invalid key: IL >= curve order");
|
|
419
|
-
}
|
|
420
|
-
const childKeyBigInt = (ilBigInt + parentKeyBigInt) % CURVE_ORDER;
|
|
421
|
-
if (childKeyBigInt === 0n) {
|
|
422
|
-
throw new Error("Invalid key: child key is zero");
|
|
423
|
-
}
|
|
424
|
-
const childPrivKey = childKeyBigInt.toString(16).padStart(64, "0");
|
|
425
|
-
return {
|
|
426
|
-
privateKey: childPrivKey,
|
|
427
|
-
chainCode: IR
|
|
428
|
-
};
|
|
429
|
-
}
|
|
430
|
-
function deriveKeyAtPath(masterPrivKey, masterChainCode, path) {
|
|
431
|
-
const pathParts = path.replace("m/", "").split("/");
|
|
432
|
-
let currentKey = masterPrivKey;
|
|
433
|
-
let currentChainCode = masterChainCode;
|
|
434
|
-
for (const part of pathParts) {
|
|
435
|
-
const isHardened = part.endsWith("'") || part.endsWith("h");
|
|
436
|
-
const indexStr = part.replace(/['h]$/, "");
|
|
437
|
-
let index = parseInt(indexStr, 10);
|
|
438
|
-
if (isHardened) {
|
|
439
|
-
index += 2147483648;
|
|
440
|
-
}
|
|
441
|
-
const derived = deriveChildKey(currentKey, currentChainCode, index);
|
|
442
|
-
currentKey = derived.privateKey;
|
|
443
|
-
currentChainCode = derived.chainCode;
|
|
444
|
-
}
|
|
445
|
-
return {
|
|
446
|
-
privateKey: currentKey,
|
|
447
|
-
chainCode: currentChainCode
|
|
448
|
-
};
|
|
449
|
-
}
|
|
450
|
-
function getPublicKey(privateKey, compressed = true) {
|
|
451
|
-
const keyPair = ec.keyFromPrivate(privateKey, "hex");
|
|
452
|
-
return keyPair.getPublic(compressed, "hex");
|
|
453
|
-
}
|
|
454
|
-
function createKeyPair(privateKey) {
|
|
455
|
-
return {
|
|
456
|
-
privateKey,
|
|
457
|
-
publicKey: getPublicKey(privateKey)
|
|
458
|
-
};
|
|
459
|
-
}
|
|
460
|
-
function sha256(data, inputEncoding = "hex") {
|
|
461
|
-
const parsed = inputEncoding === "hex" ? import_crypto_js2.default.enc.Hex.parse(data) : import_crypto_js2.default.enc.Utf8.parse(data);
|
|
462
|
-
return import_crypto_js2.default.SHA256(parsed).toString();
|
|
463
|
-
}
|
|
464
|
-
function ripemd160(data, inputEncoding = "hex") {
|
|
465
|
-
const parsed = inputEncoding === "hex" ? import_crypto_js2.default.enc.Hex.parse(data) : import_crypto_js2.default.enc.Utf8.parse(data);
|
|
466
|
-
return import_crypto_js2.default.RIPEMD160(parsed).toString();
|
|
467
|
-
}
|
|
468
|
-
function hash160(data) {
|
|
469
|
-
const sha = sha256(data, "hex");
|
|
470
|
-
return ripemd160(sha, "hex");
|
|
471
|
-
}
|
|
472
|
-
function doubleSha256(data, inputEncoding = "hex") {
|
|
473
|
-
const first = sha256(data, inputEncoding);
|
|
474
|
-
return sha256(first, "hex");
|
|
475
|
-
}
|
|
476
|
-
var computeHash160 = hash160;
|
|
477
|
-
function hash160ToBytes(hash160Hex) {
|
|
478
|
-
const matches = hash160Hex.match(/../g);
|
|
479
|
-
if (!matches) return new Uint8Array(0);
|
|
480
|
-
return Uint8Array.from(matches.map((x) => parseInt(x, 16)));
|
|
481
|
-
}
|
|
482
|
-
function publicKeyToAddress(publicKey, prefix = "alpha", witnessVersion = 0) {
|
|
483
|
-
const pubKeyHash = hash160(publicKey);
|
|
484
|
-
const programBytes = hash160ToBytes(pubKeyHash);
|
|
485
|
-
return encodeBech32(prefix, witnessVersion, programBytes);
|
|
486
|
-
}
|
|
487
|
-
function privateKeyToAddressInfo(privateKey, prefix = "alpha") {
|
|
488
|
-
const publicKey = getPublicKey(privateKey);
|
|
489
|
-
const address = publicKeyToAddress(publicKey, prefix);
|
|
490
|
-
return { address, publicKey };
|
|
491
|
-
}
|
|
492
|
-
function hexToBytes(hex) {
|
|
493
|
-
const matches = hex.match(/../g);
|
|
494
|
-
if (!matches) {
|
|
495
|
-
return new Uint8Array(0);
|
|
496
|
-
}
|
|
497
|
-
return Uint8Array.from(matches.map((x) => parseInt(x, 16)));
|
|
498
|
-
}
|
|
499
|
-
function bytesToHex2(bytes) {
|
|
500
|
-
return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
501
|
-
}
|
|
502
|
-
function randomBytes(length) {
|
|
503
|
-
const words = import_crypto_js2.default.lib.WordArray.random(length);
|
|
504
|
-
return words.toString(import_crypto_js2.default.enc.Hex);
|
|
505
|
-
}
|
|
506
|
-
function identityFromMnemonicSync(mnemonic, passphrase = "") {
|
|
507
|
-
if (!validateMnemonic2(mnemonic)) {
|
|
508
|
-
throw new Error("Invalid mnemonic phrase");
|
|
509
|
-
}
|
|
510
|
-
const seedHex = mnemonicToSeedSync2(mnemonic, passphrase);
|
|
511
|
-
return generateMasterKey(seedHex);
|
|
512
|
-
}
|
|
513
|
-
function deriveAddressInfo(masterKey, basePath, index, isChange = false, prefix = "alpha") {
|
|
514
|
-
const chain = isChange ? 1 : 0;
|
|
515
|
-
const fullPath = `${basePath}/${chain}/${index}`;
|
|
516
|
-
const derived = deriveKeyAtPath(masterKey.privateKey, masterKey.chainCode, fullPath);
|
|
517
|
-
const publicKey = getPublicKey(derived.privateKey);
|
|
518
|
-
const address = publicKeyToAddress(publicKey, prefix);
|
|
519
|
-
return {
|
|
520
|
-
privateKey: derived.privateKey,
|
|
521
|
-
publicKey,
|
|
522
|
-
address,
|
|
523
|
-
path: fullPath,
|
|
524
|
-
index
|
|
525
|
-
};
|
|
526
|
-
}
|
|
527
|
-
function generateAddressInfo(privateKey, index, path, prefix = "alpha") {
|
|
528
|
-
const { address, publicKey } = privateKeyToAddressInfo(privateKey, prefix);
|
|
529
|
-
return {
|
|
530
|
-
privateKey,
|
|
531
|
-
publicKey,
|
|
532
|
-
address,
|
|
533
|
-
path,
|
|
534
|
-
index
|
|
535
|
-
};
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
// l1/crypto.ts
|
|
539
|
-
var import_crypto_js3 = __toESM(require("crypto-js"), 1);
|
|
540
|
-
var SALT = "alpha_wallet_salt";
|
|
541
|
-
var PBKDF2_ITERATIONS = 1e5;
|
|
542
|
-
function encrypt(text, password) {
|
|
543
|
-
return import_crypto_js3.default.AES.encrypt(text, password).toString();
|
|
544
|
-
}
|
|
545
|
-
function decrypt(encrypted, password) {
|
|
546
|
-
const bytes = import_crypto_js3.default.AES.decrypt(encrypted, password);
|
|
547
|
-
return bytes.toString(import_crypto_js3.default.enc.Utf8);
|
|
548
|
-
}
|
|
549
|
-
function generatePrivateKey() {
|
|
550
|
-
return import_crypto_js3.default.lib.WordArray.random(32).toString();
|
|
551
|
-
}
|
|
552
|
-
function encryptWallet(masterPrivateKey, password) {
|
|
553
|
-
const passwordKey = import_crypto_js3.default.PBKDF2(password, SALT, {
|
|
554
|
-
keySize: 256 / 32,
|
|
555
|
-
iterations: PBKDF2_ITERATIONS
|
|
556
|
-
}).toString();
|
|
557
|
-
const encrypted = import_crypto_js3.default.AES.encrypt(
|
|
558
|
-
masterPrivateKey,
|
|
559
|
-
passwordKey
|
|
560
|
-
).toString();
|
|
561
|
-
return encrypted;
|
|
562
|
-
}
|
|
563
|
-
function decryptWallet(encryptedData, password) {
|
|
564
|
-
const passwordKey = import_crypto_js3.default.PBKDF2(password, SALT, {
|
|
565
|
-
keySize: 256 / 32,
|
|
566
|
-
iterations: PBKDF2_ITERATIONS
|
|
567
|
-
}).toString();
|
|
568
|
-
const decrypted = import_crypto_js3.default.AES.decrypt(encryptedData, passwordKey);
|
|
569
|
-
return decrypted.toString(import_crypto_js3.default.enc.Utf8);
|
|
570
|
-
}
|
|
571
|
-
function hexToWIF(hexKey) {
|
|
572
|
-
const versionByte = "80";
|
|
573
|
-
const extendedKey = versionByte + hexKey;
|
|
574
|
-
const hash1 = import_crypto_js3.default.SHA256(import_crypto_js3.default.enc.Hex.parse(extendedKey)).toString();
|
|
575
|
-
const hash2 = import_crypto_js3.default.SHA256(import_crypto_js3.default.enc.Hex.parse(hash1)).toString();
|
|
576
|
-
const checksum = hash2.substring(0, 8);
|
|
577
|
-
const finalHex = extendedKey + checksum;
|
|
578
|
-
return base58Encode(finalHex);
|
|
579
|
-
}
|
|
580
|
-
function base58Encode(hex) {
|
|
581
|
-
const ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
582
|
-
let num = BigInt("0x" + hex);
|
|
583
|
-
let encoded = "";
|
|
584
|
-
while (num > 0n) {
|
|
585
|
-
const remainder = Number(num % 58n);
|
|
586
|
-
num = num / 58n;
|
|
587
|
-
encoded = ALPHABET[remainder] + encoded;
|
|
588
|
-
}
|
|
589
|
-
for (let i = 0; i < hex.length && hex.substring(i, i + 2) === "00"; i += 2) {
|
|
590
|
-
encoded = "1" + encoded;
|
|
591
|
-
}
|
|
592
|
-
return encoded;
|
|
593
|
-
}
|
|
594
|
-
|
|
595
|
-
// l1/address.ts
|
|
596
|
-
var import_crypto_js4 = __toESM(require("crypto-js"), 1);
|
|
597
|
-
var deriveChildKeyBIP32 = deriveChildKey;
|
|
598
|
-
var deriveKeyAtPath2 = deriveKeyAtPath;
|
|
599
|
-
function generateMasterKeyFromSeed(seedHex) {
|
|
600
|
-
const result = generateMasterKey(seedHex);
|
|
601
|
-
return {
|
|
602
|
-
masterPrivateKey: result.privateKey,
|
|
603
|
-
masterChainCode: result.chainCode
|
|
604
|
-
};
|
|
605
|
-
}
|
|
606
|
-
function generateHDAddressBIP32(masterPriv, chainCode, index, basePath = "m/44'/0'/0'", isChange = false) {
|
|
607
|
-
const chain = isChange ? 1 : 0;
|
|
608
|
-
const fullPath = `${basePath}/${chain}/${index}`;
|
|
609
|
-
const derived = deriveKeyAtPath(masterPriv, chainCode, fullPath);
|
|
610
|
-
return generateAddressInfo(derived.privateKey, index, fullPath);
|
|
611
|
-
}
|
|
612
|
-
function generateAddressFromMasterKey(masterPrivateKey, index) {
|
|
613
|
-
const derivationPath = `m/44'/0'/${index}'`;
|
|
614
|
-
const hmacInput = import_crypto_js4.default.enc.Hex.parse(masterPrivateKey);
|
|
615
|
-
const hmacKey = import_crypto_js4.default.enc.Utf8.parse(derivationPath);
|
|
616
|
-
const hmacOutput = import_crypto_js4.default.HmacSHA512(hmacInput, hmacKey).toString();
|
|
617
|
-
const childPrivateKey = hmacOutput.substring(0, 64);
|
|
618
|
-
return generateAddressInfo(childPrivateKey, index, derivationPath);
|
|
619
|
-
}
|
|
620
|
-
function deriveChildKey2(masterPriv, chainCode, index) {
|
|
621
|
-
const data = masterPriv + index.toString(16).padStart(8, "0");
|
|
622
|
-
const I = import_crypto_js4.default.HmacSHA512(
|
|
623
|
-
import_crypto_js4.default.enc.Hex.parse(data),
|
|
624
|
-
import_crypto_js4.default.enc.Hex.parse(chainCode)
|
|
625
|
-
).toString();
|
|
626
|
-
return {
|
|
627
|
-
privateKey: I.substring(0, 64),
|
|
628
|
-
nextChainCode: I.substring(64)
|
|
629
|
-
};
|
|
630
|
-
}
|
|
631
|
-
function generateHDAddress(masterPriv, chainCode, index) {
|
|
632
|
-
const child = deriveChildKey2(masterPriv, chainCode, index);
|
|
633
|
-
const path = `m/44'/0'/0'/${index}`;
|
|
634
|
-
return generateAddressInfo(child.privateKey, index, path);
|
|
635
|
-
}
|
|
636
|
-
|
|
637
|
-
// l1/network.ts
|
|
638
|
-
var DEFAULT_ENDPOINT = "wss://fulcrum.unicity.network:50004";
|
|
639
|
-
var ws = null;
|
|
640
|
-
var isConnected = false;
|
|
641
|
-
var isConnecting = false;
|
|
642
|
-
var requestId = 0;
|
|
643
|
-
var intentionalClose = false;
|
|
644
|
-
var reconnectAttempts = 0;
|
|
645
|
-
var isBlockSubscribed = false;
|
|
646
|
-
var lastBlockHeader = null;
|
|
647
|
-
var pending = {};
|
|
648
|
-
var blockSubscribers = [];
|
|
649
|
-
var connectionCallbacks = [];
|
|
650
|
-
var MAX_RECONNECT_ATTEMPTS = 10;
|
|
651
|
-
var BASE_DELAY = 2e3;
|
|
652
|
-
var MAX_DELAY = 6e4;
|
|
653
|
-
var RPC_TIMEOUT = 3e4;
|
|
654
|
-
var CONNECTION_TIMEOUT = 3e4;
|
|
655
|
-
function isWebSocketConnected() {
|
|
656
|
-
return isConnected && ws !== null && ws.readyState === WebSocket.OPEN;
|
|
170
|
+
// l1/network.ts
|
|
171
|
+
var network_exports = {};
|
|
172
|
+
__export(network_exports, {
|
|
173
|
+
broadcast: () => broadcast,
|
|
174
|
+
connect: () => connect,
|
|
175
|
+
disconnect: () => disconnect,
|
|
176
|
+
getBalance: () => getBalance,
|
|
177
|
+
getBlockHeader: () => getBlockHeader,
|
|
178
|
+
getCurrentBlockHeight: () => getCurrentBlockHeight,
|
|
179
|
+
getTransaction: () => getTransaction,
|
|
180
|
+
getTransactionHistory: () => getTransactionHistory,
|
|
181
|
+
getUtxo: () => getUtxo,
|
|
182
|
+
isWebSocketConnected: () => isWebSocketConnected,
|
|
183
|
+
rpc: () => rpc,
|
|
184
|
+
subscribeBlocks: () => subscribeBlocks,
|
|
185
|
+
waitForConnection: () => waitForConnection
|
|
186
|
+
});
|
|
187
|
+
function isWebSocketConnected() {
|
|
188
|
+
return isConnected && ws !== null && ws.readyState === WebSocket.OPEN;
|
|
657
189
|
}
|
|
658
190
|
function waitForConnection() {
|
|
659
191
|
if (isWebSocketConnected()) {
|
|
@@ -839,83 +371,601 @@ async function getBalance(address) {
|
|
|
839
371
|
const alpha = totalSats / 1e8;
|
|
840
372
|
return alpha;
|
|
841
373
|
}
|
|
842
|
-
async function broadcast(rawHex) {
|
|
843
|
-
return await rpc("blockchain.transaction.broadcast", [rawHex]);
|
|
374
|
+
async function broadcast(rawHex) {
|
|
375
|
+
return await rpc("blockchain.transaction.broadcast", [rawHex]);
|
|
376
|
+
}
|
|
377
|
+
async function subscribeBlocks(cb) {
|
|
378
|
+
if (!isConnected && !isConnecting) {
|
|
379
|
+
await connect();
|
|
380
|
+
}
|
|
381
|
+
if (!isWebSocketConnected()) {
|
|
382
|
+
await waitForConnection();
|
|
383
|
+
}
|
|
384
|
+
blockSubscribers.push(cb);
|
|
385
|
+
if (!isBlockSubscribed) {
|
|
386
|
+
isBlockSubscribed = true;
|
|
387
|
+
const header = await rpc("blockchain.headers.subscribe", []);
|
|
388
|
+
if (header) {
|
|
389
|
+
lastBlockHeader = header;
|
|
390
|
+
blockSubscribers.forEach((subscriber) => subscriber(header));
|
|
391
|
+
}
|
|
392
|
+
} else if (lastBlockHeader) {
|
|
393
|
+
cb(lastBlockHeader);
|
|
394
|
+
}
|
|
395
|
+
return () => {
|
|
396
|
+
const index = blockSubscribers.indexOf(cb);
|
|
397
|
+
if (index > -1) {
|
|
398
|
+
blockSubscribers.splice(index, 1);
|
|
399
|
+
}
|
|
400
|
+
};
|
|
401
|
+
}
|
|
402
|
+
async function getTransactionHistory(address) {
|
|
403
|
+
const scriptHash = addressToScriptHash(address);
|
|
404
|
+
const result = await rpc("blockchain.scripthash.get_history", [scriptHash]);
|
|
405
|
+
if (!Array.isArray(result)) {
|
|
406
|
+
console.warn("get_history returned non-array:", result);
|
|
407
|
+
return [];
|
|
408
|
+
}
|
|
409
|
+
return result;
|
|
410
|
+
}
|
|
411
|
+
async function getTransaction(txid) {
|
|
412
|
+
return await rpc("blockchain.transaction.get", [txid, true]);
|
|
413
|
+
}
|
|
414
|
+
async function getBlockHeader(height) {
|
|
415
|
+
return await rpc("blockchain.block.header", [height, height]);
|
|
416
|
+
}
|
|
417
|
+
async function getCurrentBlockHeight() {
|
|
418
|
+
try {
|
|
419
|
+
const header = await rpc("blockchain.headers.subscribe", []);
|
|
420
|
+
return header?.height || 0;
|
|
421
|
+
} catch (err) {
|
|
422
|
+
console.error("Error getting current block height:", err);
|
|
423
|
+
return 0;
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
function disconnect() {
|
|
427
|
+
if (ws) {
|
|
428
|
+
intentionalClose = true;
|
|
429
|
+
ws.close();
|
|
430
|
+
ws = null;
|
|
431
|
+
}
|
|
432
|
+
isConnected = false;
|
|
433
|
+
isConnecting = false;
|
|
434
|
+
reconnectAttempts = 0;
|
|
435
|
+
isBlockSubscribed = false;
|
|
436
|
+
Object.values(pending).forEach((req) => {
|
|
437
|
+
if (req.timeoutId) clearTimeout(req.timeoutId);
|
|
438
|
+
});
|
|
439
|
+
Object.keys(pending).forEach((key) => delete pending[Number(key)]);
|
|
440
|
+
connectionCallbacks.forEach((cb) => {
|
|
441
|
+
if (cb.timeoutId) clearTimeout(cb.timeoutId);
|
|
442
|
+
});
|
|
443
|
+
connectionCallbacks.length = 0;
|
|
444
|
+
}
|
|
445
|
+
var DEFAULT_ENDPOINT, ws, isConnected, isConnecting, requestId, intentionalClose, reconnectAttempts, isBlockSubscribed, lastBlockHeader, pending, blockSubscribers, connectionCallbacks, MAX_RECONNECT_ATTEMPTS, BASE_DELAY, MAX_DELAY, RPC_TIMEOUT, CONNECTION_TIMEOUT;
|
|
446
|
+
var init_network = __esm({
|
|
447
|
+
"l1/network.ts"() {
|
|
448
|
+
"use strict";
|
|
449
|
+
init_addressToScriptHash();
|
|
450
|
+
DEFAULT_ENDPOINT = "wss://fulcrum.unicity.network:50004";
|
|
451
|
+
ws = null;
|
|
452
|
+
isConnected = false;
|
|
453
|
+
isConnecting = false;
|
|
454
|
+
requestId = 0;
|
|
455
|
+
intentionalClose = false;
|
|
456
|
+
reconnectAttempts = 0;
|
|
457
|
+
isBlockSubscribed = false;
|
|
458
|
+
lastBlockHeader = null;
|
|
459
|
+
pending = {};
|
|
460
|
+
blockSubscribers = [];
|
|
461
|
+
connectionCallbacks = [];
|
|
462
|
+
MAX_RECONNECT_ATTEMPTS = 10;
|
|
463
|
+
BASE_DELAY = 2e3;
|
|
464
|
+
MAX_DELAY = 6e4;
|
|
465
|
+
RPC_TIMEOUT = 3e4;
|
|
466
|
+
CONNECTION_TIMEOUT = 3e4;
|
|
467
|
+
}
|
|
468
|
+
});
|
|
469
|
+
|
|
470
|
+
// index.ts
|
|
471
|
+
var index_exports = {};
|
|
472
|
+
__export(index_exports, {
|
|
473
|
+
COIN_TYPES: () => COIN_TYPES,
|
|
474
|
+
CoinGeckoPriceProvider: () => CoinGeckoPriceProvider,
|
|
475
|
+
CommunicationsModule: () => CommunicationsModule,
|
|
476
|
+
DEFAULT_AGGREGATOR_TIMEOUT: () => DEFAULT_AGGREGATOR_TIMEOUT,
|
|
477
|
+
DEFAULT_AGGREGATOR_URL: () => DEFAULT_AGGREGATOR_URL,
|
|
478
|
+
DEFAULT_DERIVATION_PATH: () => DEFAULT_DERIVATION_PATH,
|
|
479
|
+
DEFAULT_ELECTRUM_URL: () => DEFAULT_ELECTRUM_URL,
|
|
480
|
+
DEFAULT_IPFS_BOOTSTRAP_PEERS: () => DEFAULT_IPFS_BOOTSTRAP_PEERS,
|
|
481
|
+
DEFAULT_IPFS_GATEWAYS: () => DEFAULT_IPFS_GATEWAYS,
|
|
482
|
+
DEFAULT_NOSTR_RELAYS: () => DEFAULT_NOSTR_RELAYS,
|
|
483
|
+
DEV_AGGREGATOR_URL: () => DEV_AGGREGATOR_URL,
|
|
484
|
+
L1: () => l1_exports,
|
|
485
|
+
L1PaymentsModule: () => L1PaymentsModule,
|
|
486
|
+
LIMITS: () => LIMITS,
|
|
487
|
+
NETWORKS: () => NETWORKS,
|
|
488
|
+
NOSTR_EVENT_KINDS: () => NOSTR_EVENT_KINDS,
|
|
489
|
+
PaymentsModule: () => PaymentsModule,
|
|
490
|
+
STORAGE_KEYS: () => STORAGE_KEYS,
|
|
491
|
+
STORAGE_PREFIX: () => STORAGE_PREFIX,
|
|
492
|
+
Sphere: () => Sphere,
|
|
493
|
+
SphereError: () => SphereError,
|
|
494
|
+
TEST_AGGREGATOR_URL: () => TEST_AGGREGATOR_URL,
|
|
495
|
+
TEST_ELECTRUM_URL: () => TEST_ELECTRUM_URL,
|
|
496
|
+
TEST_NOSTR_RELAYS: () => TEST_NOSTR_RELAYS,
|
|
497
|
+
TIMEOUTS: () => TIMEOUTS,
|
|
498
|
+
TokenRegistry: () => TokenRegistry,
|
|
499
|
+
TokenValidator: () => TokenValidator,
|
|
500
|
+
archivedKeyFromTokenId: () => archivedKeyFromTokenId,
|
|
501
|
+
base58Decode: () => base58Decode,
|
|
502
|
+
base58Encode: () => base58Encode2,
|
|
503
|
+
buildTxfStorageData: () => buildTxfStorageData,
|
|
504
|
+
bytesToHex: () => bytesToHex2,
|
|
505
|
+
countCommittedTransactions: () => countCommittedTransactions,
|
|
506
|
+
createAddress: () => createAddress,
|
|
507
|
+
createCommunicationsModule: () => createCommunicationsModule,
|
|
508
|
+
createKeyPair: () => createKeyPair,
|
|
509
|
+
createL1PaymentsModule: () => createL1PaymentsModule,
|
|
510
|
+
createPaymentSession: () => createPaymentSession,
|
|
511
|
+
createPaymentSessionError: () => createPaymentSessionError,
|
|
512
|
+
createPaymentsModule: () => createPaymentsModule,
|
|
513
|
+
createPriceProvider: () => createPriceProvider,
|
|
514
|
+
createSphere: () => createSphere,
|
|
515
|
+
createSplitPaymentSession: () => createSplitPaymentSession,
|
|
516
|
+
createTokenValidator: () => createTokenValidator,
|
|
517
|
+
decodeBech32: () => decodeBech32,
|
|
518
|
+
decryptCMasterKey: () => decryptCMasterKey,
|
|
519
|
+
decryptPrivateKey: () => decryptPrivateKey,
|
|
520
|
+
decryptTextFormatKey: () => decryptTextFormatKey,
|
|
521
|
+
deriveAddressInfo: () => deriveAddressInfo,
|
|
522
|
+
deriveChildKey: () => deriveChildKey,
|
|
523
|
+
deriveKeyAtPath: () => deriveKeyAtPath,
|
|
524
|
+
doubleSha256: () => doubleSha256,
|
|
525
|
+
encodeBech32: () => encodeBech32,
|
|
526
|
+
extractFromText: () => extractFromText,
|
|
527
|
+
findPattern: () => findPattern,
|
|
528
|
+
forkedKeyFromTokenIdAndState: () => forkedKeyFromTokenIdAndState,
|
|
529
|
+
formatAmount: () => formatAmount,
|
|
530
|
+
generateMasterKey: () => generateMasterKey,
|
|
531
|
+
generateMnemonic: () => generateMnemonic2,
|
|
532
|
+
getAddressHrp: () => getAddressHrp,
|
|
533
|
+
getCoinIdByName: () => getCoinIdByName,
|
|
534
|
+
getCoinIdBySymbol: () => getCoinIdBySymbol,
|
|
535
|
+
getCurrentStateHash: () => getCurrentStateHash,
|
|
536
|
+
getPublicKey: () => getPublicKey,
|
|
537
|
+
getSphere: () => getSphere,
|
|
538
|
+
getTokenDecimals: () => getTokenDecimals,
|
|
539
|
+
getTokenDefinition: () => getTokenDefinition,
|
|
540
|
+
getTokenIconUrl: () => getTokenIconUrl,
|
|
541
|
+
getTokenId: () => getTokenId,
|
|
542
|
+
getTokenName: () => getTokenName,
|
|
543
|
+
getTokenSymbol: () => getTokenSymbol,
|
|
544
|
+
hasMissingNewStateHash: () => hasMissingNewStateHash,
|
|
545
|
+
hasUncommittedTransactions: () => hasUncommittedTransactions,
|
|
546
|
+
hasValidTxfData: () => hasValidTxfData,
|
|
547
|
+
hash160: () => hash160,
|
|
548
|
+
hexToBytes: () => hexToBytes,
|
|
549
|
+
identityFromMnemonicSync: () => identityFromMnemonicSync,
|
|
550
|
+
initSphere: () => initSphere,
|
|
551
|
+
isArchivedKey: () => isArchivedKey,
|
|
552
|
+
isForkedKey: () => isForkedKey,
|
|
553
|
+
isInstantSplitBundle: () => isInstantSplitBundle,
|
|
554
|
+
isInstantSplitBundleV4: () => isInstantSplitBundleV4,
|
|
555
|
+
isInstantSplitBundleV5: () => isInstantSplitBundleV5,
|
|
556
|
+
isKnownToken: () => isKnownToken,
|
|
557
|
+
isPaymentSessionTerminal: () => isPaymentSessionTerminal,
|
|
558
|
+
isPaymentSessionTimedOut: () => isPaymentSessionTimedOut,
|
|
559
|
+
isSQLiteDatabase: () => isSQLiteDatabase,
|
|
560
|
+
isTextWalletEncrypted: () => isTextWalletEncrypted,
|
|
561
|
+
isTokenKey: () => isTokenKey,
|
|
562
|
+
isValidBech32: () => isValidBech32,
|
|
563
|
+
isValidPrivateKey: () => isValidPrivateKey,
|
|
564
|
+
isValidTokenId: () => isValidTokenId,
|
|
565
|
+
isWalletDatEncrypted: () => isWalletDatEncrypted,
|
|
566
|
+
isWalletTextFormat: () => isWalletTextFormat,
|
|
567
|
+
keyFromTokenId: () => keyFromTokenId,
|
|
568
|
+
loadSphere: () => loadSphere,
|
|
569
|
+
mnemonicToSeedSync: () => mnemonicToSeedSync2,
|
|
570
|
+
normalizeSdkTokenToStorage: () => normalizeSdkTokenToStorage,
|
|
571
|
+
objectToTxf: () => objectToTxf,
|
|
572
|
+
parseAndDecryptWalletDat: () => parseAndDecryptWalletDat,
|
|
573
|
+
parseAndDecryptWalletText: () => parseAndDecryptWalletText,
|
|
574
|
+
parseForkedKey: () => parseForkedKey,
|
|
575
|
+
parseTxfStorageData: () => parseTxfStorageData,
|
|
576
|
+
parseWalletDat: () => parseWalletDat,
|
|
577
|
+
parseWalletText: () => parseWalletText,
|
|
578
|
+
randomBytes: () => randomBytes,
|
|
579
|
+
randomHex: () => randomHex,
|
|
580
|
+
randomUUID: () => randomUUID,
|
|
581
|
+
ripemd160: () => ripemd160,
|
|
582
|
+
sha256: () => sha256,
|
|
583
|
+
sleep: () => sleep,
|
|
584
|
+
sphereExists: () => sphereExists,
|
|
585
|
+
toHumanReadable: () => toHumanReadable,
|
|
586
|
+
toSmallestUnit: () => toSmallestUnit,
|
|
587
|
+
tokenIdFromArchivedKey: () => tokenIdFromArchivedKey,
|
|
588
|
+
tokenIdFromKey: () => tokenIdFromKey,
|
|
589
|
+
tokenToTxf: () => tokenToTxf,
|
|
590
|
+
txfToToken: () => txfToToken,
|
|
591
|
+
validateMnemonic: () => validateMnemonic2
|
|
592
|
+
});
|
|
593
|
+
module.exports = __toCommonJS(index_exports);
|
|
594
|
+
|
|
595
|
+
// l1/index.ts
|
|
596
|
+
var l1_exports = {};
|
|
597
|
+
__export(l1_exports, {
|
|
598
|
+
CHARSET: () => CHARSET,
|
|
599
|
+
VESTING_THRESHOLD: () => VESTING_THRESHOLD,
|
|
600
|
+
WalletAddressHelper: () => WalletAddressHelper,
|
|
601
|
+
addressToScriptHash: () => addressToScriptHash,
|
|
602
|
+
broadcast: () => broadcast,
|
|
603
|
+
buildSegWitTransaction: () => buildSegWitTransaction,
|
|
604
|
+
collectUtxosForAmount: () => collectUtxosForAmount,
|
|
605
|
+
computeHash160: () => computeHash160,
|
|
606
|
+
connect: () => connect,
|
|
607
|
+
convertBits: () => convertBits,
|
|
608
|
+
createAndSignTransaction: () => createAndSignTransaction,
|
|
609
|
+
createBech32: () => createBech32,
|
|
610
|
+
createScriptPubKey: () => createScriptPubKey,
|
|
611
|
+
createTransactionPlan: () => createTransactionPlan,
|
|
612
|
+
decodeBech32: () => decodeBech32,
|
|
613
|
+
decrypt: () => decrypt,
|
|
614
|
+
decryptWallet: () => decryptWallet,
|
|
615
|
+
deriveChildKey: () => deriveChildKey2,
|
|
616
|
+
deriveChildKeyBIP32: () => deriveChildKeyBIP32,
|
|
617
|
+
deriveKeyAtPath: () => deriveKeyAtPath2,
|
|
618
|
+
disconnect: () => disconnect,
|
|
619
|
+
domIdToPath: () => domIdToPath,
|
|
620
|
+
ec: () => ec,
|
|
621
|
+
encodeBech32: () => encodeBech32,
|
|
622
|
+
encrypt: () => encrypt,
|
|
623
|
+
encryptWallet: () => encryptWallet,
|
|
624
|
+
generateAddressFromMasterKey: () => generateAddressFromMasterKey,
|
|
625
|
+
generateAddressInfo: () => generateAddressInfo,
|
|
626
|
+
generateHDAddress: () => generateHDAddress,
|
|
627
|
+
generateHDAddressBIP32: () => generateHDAddressBIP32,
|
|
628
|
+
generateMasterKeyFromSeed: () => generateMasterKeyFromSeed,
|
|
629
|
+
generatePrivateKey: () => generatePrivateKey,
|
|
630
|
+
getBalance: () => getBalance,
|
|
631
|
+
getBlockHeader: () => getBlockHeader,
|
|
632
|
+
getCurrentBlockHeight: () => getCurrentBlockHeight,
|
|
633
|
+
getIndexFromPath: () => getIndexFromPath,
|
|
634
|
+
getTransaction: () => getTransaction,
|
|
635
|
+
getTransactionHistory: () => getTransactionHistory,
|
|
636
|
+
getUtxo: () => getUtxo,
|
|
637
|
+
hash160: () => hash160,
|
|
638
|
+
hash160ToBytes: () => hash160ToBytes,
|
|
639
|
+
hexToWIF: () => hexToWIF,
|
|
640
|
+
isChangePath: () => isChangePath,
|
|
641
|
+
isWebSocketConnected: () => isWebSocketConnected,
|
|
642
|
+
parsePathComponents: () => parsePathComponents,
|
|
643
|
+
pathToDOMId: () => pathToDOMId,
|
|
644
|
+
privateKeyToAddressInfo: () => privateKeyToAddressInfo,
|
|
645
|
+
publicKeyToAddress: () => publicKeyToAddress,
|
|
646
|
+
rpc: () => rpc,
|
|
647
|
+
sendAlpha: () => sendAlpha,
|
|
648
|
+
subscribeBlocks: () => subscribeBlocks,
|
|
649
|
+
vestingClassifier: () => vestingClassifier,
|
|
650
|
+
vestingState: () => vestingState,
|
|
651
|
+
waitForConnection: () => waitForConnection
|
|
652
|
+
});
|
|
653
|
+
|
|
654
|
+
// l1/types.ts
|
|
655
|
+
function parsePathComponents(path) {
|
|
656
|
+
const match = path.match(/m\/\d+'\/\d+'\/\d+'\/(\d+)\/(\d+)/);
|
|
657
|
+
if (!match) return null;
|
|
658
|
+
return { chain: parseInt(match[1], 10), index: parseInt(match[2], 10) };
|
|
659
|
+
}
|
|
660
|
+
function isChangePath(path) {
|
|
661
|
+
const parsed = parsePathComponents(path);
|
|
662
|
+
return parsed?.chain === 1;
|
|
663
|
+
}
|
|
664
|
+
function getIndexFromPath(path) {
|
|
665
|
+
const parsed = parsePathComponents(path);
|
|
666
|
+
return parsed?.index ?? 0;
|
|
667
|
+
}
|
|
668
|
+
function pathToDOMId(path) {
|
|
669
|
+
return path.replace(/'/g, "h").replace(/\//g, "-");
|
|
670
|
+
}
|
|
671
|
+
function domIdToPath(encoded) {
|
|
672
|
+
const parts = encoded.split("-");
|
|
673
|
+
return parts.map((part, idx) => {
|
|
674
|
+
if (idx === 0) return part;
|
|
675
|
+
return part.endsWith("h") ? `${part.slice(0, -1)}'` : part;
|
|
676
|
+
}).join("/");
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
// l1/index.ts
|
|
680
|
+
init_bech32();
|
|
681
|
+
init_addressToScriptHash();
|
|
682
|
+
|
|
683
|
+
// core/crypto.ts
|
|
684
|
+
var bip39 = __toESM(require("bip39"), 1);
|
|
685
|
+
var import_crypto_js2 = __toESM(require("crypto-js"), 1);
|
|
686
|
+
var import_elliptic = __toESM(require("elliptic"), 1);
|
|
687
|
+
init_bech32();
|
|
688
|
+
var ec = new import_elliptic.default.ec("secp256k1");
|
|
689
|
+
var CURVE_ORDER = BigInt(
|
|
690
|
+
"0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141"
|
|
691
|
+
);
|
|
692
|
+
function generateMnemonic2(strength = 128) {
|
|
693
|
+
return bip39.generateMnemonic(strength);
|
|
694
|
+
}
|
|
695
|
+
function validateMnemonic2(mnemonic) {
|
|
696
|
+
return bip39.validateMnemonic(mnemonic);
|
|
697
|
+
}
|
|
698
|
+
function mnemonicToSeedSync2(mnemonic, passphrase = "") {
|
|
699
|
+
const seedBuffer = bip39.mnemonicToSeedSync(mnemonic, passphrase);
|
|
700
|
+
return Buffer.from(seedBuffer).toString("hex");
|
|
701
|
+
}
|
|
702
|
+
function generateMasterKey(seedHex) {
|
|
703
|
+
const I = import_crypto_js2.default.HmacSHA512(
|
|
704
|
+
import_crypto_js2.default.enc.Hex.parse(seedHex),
|
|
705
|
+
import_crypto_js2.default.enc.Utf8.parse("Bitcoin seed")
|
|
706
|
+
).toString();
|
|
707
|
+
const IL = I.substring(0, 64);
|
|
708
|
+
const IR = I.substring(64);
|
|
709
|
+
const masterKeyBigInt = BigInt("0x" + IL);
|
|
710
|
+
if (masterKeyBigInt === 0n || masterKeyBigInt >= CURVE_ORDER) {
|
|
711
|
+
throw new Error("Invalid master key generated");
|
|
712
|
+
}
|
|
713
|
+
return {
|
|
714
|
+
privateKey: IL,
|
|
715
|
+
chainCode: IR
|
|
716
|
+
};
|
|
717
|
+
}
|
|
718
|
+
function deriveChildKey(parentPrivKey, parentChainCode, index) {
|
|
719
|
+
const isHardened = index >= 2147483648;
|
|
720
|
+
let data;
|
|
721
|
+
if (isHardened) {
|
|
722
|
+
const indexHex = index.toString(16).padStart(8, "0");
|
|
723
|
+
data = "00" + parentPrivKey + indexHex;
|
|
724
|
+
} else {
|
|
725
|
+
const keyPair = ec.keyFromPrivate(parentPrivKey, "hex");
|
|
726
|
+
const compressedPubKey = keyPair.getPublic(true, "hex");
|
|
727
|
+
const indexHex = index.toString(16).padStart(8, "0");
|
|
728
|
+
data = compressedPubKey + indexHex;
|
|
729
|
+
}
|
|
730
|
+
const I = import_crypto_js2.default.HmacSHA512(
|
|
731
|
+
import_crypto_js2.default.enc.Hex.parse(data),
|
|
732
|
+
import_crypto_js2.default.enc.Hex.parse(parentChainCode)
|
|
733
|
+
).toString();
|
|
734
|
+
const IL = I.substring(0, 64);
|
|
735
|
+
const IR = I.substring(64);
|
|
736
|
+
const ilBigInt = BigInt("0x" + IL);
|
|
737
|
+
const parentKeyBigInt = BigInt("0x" + parentPrivKey);
|
|
738
|
+
if (ilBigInt >= CURVE_ORDER) {
|
|
739
|
+
throw new Error("Invalid key: IL >= curve order");
|
|
740
|
+
}
|
|
741
|
+
const childKeyBigInt = (ilBigInt + parentKeyBigInt) % CURVE_ORDER;
|
|
742
|
+
if (childKeyBigInt === 0n) {
|
|
743
|
+
throw new Error("Invalid key: child key is zero");
|
|
744
|
+
}
|
|
745
|
+
const childPrivKey = childKeyBigInt.toString(16).padStart(64, "0");
|
|
746
|
+
return {
|
|
747
|
+
privateKey: childPrivKey,
|
|
748
|
+
chainCode: IR
|
|
749
|
+
};
|
|
750
|
+
}
|
|
751
|
+
function deriveKeyAtPath(masterPrivKey, masterChainCode, path) {
|
|
752
|
+
const pathParts = path.replace("m/", "").split("/");
|
|
753
|
+
let currentKey = masterPrivKey;
|
|
754
|
+
let currentChainCode = masterChainCode;
|
|
755
|
+
for (const part of pathParts) {
|
|
756
|
+
const isHardened = part.endsWith("'") || part.endsWith("h");
|
|
757
|
+
const indexStr = part.replace(/['h]$/, "");
|
|
758
|
+
let index = parseInt(indexStr, 10);
|
|
759
|
+
if (isHardened) {
|
|
760
|
+
index += 2147483648;
|
|
761
|
+
}
|
|
762
|
+
const derived = deriveChildKey(currentKey, currentChainCode, index);
|
|
763
|
+
currentKey = derived.privateKey;
|
|
764
|
+
currentChainCode = derived.chainCode;
|
|
765
|
+
}
|
|
766
|
+
return {
|
|
767
|
+
privateKey: currentKey,
|
|
768
|
+
chainCode: currentChainCode
|
|
769
|
+
};
|
|
770
|
+
}
|
|
771
|
+
function getPublicKey(privateKey, compressed = true) {
|
|
772
|
+
const keyPair = ec.keyFromPrivate(privateKey, "hex");
|
|
773
|
+
return keyPair.getPublic(compressed, "hex");
|
|
774
|
+
}
|
|
775
|
+
function createKeyPair(privateKey) {
|
|
776
|
+
return {
|
|
777
|
+
privateKey,
|
|
778
|
+
publicKey: getPublicKey(privateKey)
|
|
779
|
+
};
|
|
780
|
+
}
|
|
781
|
+
function sha256(data, inputEncoding = "hex") {
|
|
782
|
+
const parsed = inputEncoding === "hex" ? import_crypto_js2.default.enc.Hex.parse(data) : import_crypto_js2.default.enc.Utf8.parse(data);
|
|
783
|
+
return import_crypto_js2.default.SHA256(parsed).toString();
|
|
784
|
+
}
|
|
785
|
+
function ripemd160(data, inputEncoding = "hex") {
|
|
786
|
+
const parsed = inputEncoding === "hex" ? import_crypto_js2.default.enc.Hex.parse(data) : import_crypto_js2.default.enc.Utf8.parse(data);
|
|
787
|
+
return import_crypto_js2.default.RIPEMD160(parsed).toString();
|
|
788
|
+
}
|
|
789
|
+
function hash160(data) {
|
|
790
|
+
const sha = sha256(data, "hex");
|
|
791
|
+
return ripemd160(sha, "hex");
|
|
792
|
+
}
|
|
793
|
+
function doubleSha256(data, inputEncoding = "hex") {
|
|
794
|
+
const first = sha256(data, inputEncoding);
|
|
795
|
+
return sha256(first, "hex");
|
|
796
|
+
}
|
|
797
|
+
var computeHash160 = hash160;
|
|
798
|
+
function hash160ToBytes(hash160Hex) {
|
|
799
|
+
const matches = hash160Hex.match(/../g);
|
|
800
|
+
if (!matches) return new Uint8Array(0);
|
|
801
|
+
return Uint8Array.from(matches.map((x) => parseInt(x, 16)));
|
|
802
|
+
}
|
|
803
|
+
function publicKeyToAddress(publicKey, prefix = "alpha", witnessVersion = 0) {
|
|
804
|
+
const pubKeyHash = hash160(publicKey);
|
|
805
|
+
const programBytes = hash160ToBytes(pubKeyHash);
|
|
806
|
+
return encodeBech32(prefix, witnessVersion, programBytes);
|
|
807
|
+
}
|
|
808
|
+
function privateKeyToAddressInfo(privateKey, prefix = "alpha") {
|
|
809
|
+
const publicKey = getPublicKey(privateKey);
|
|
810
|
+
const address = publicKeyToAddress(publicKey, prefix);
|
|
811
|
+
return { address, publicKey };
|
|
812
|
+
}
|
|
813
|
+
function hexToBytes(hex) {
|
|
814
|
+
const matches = hex.match(/../g);
|
|
815
|
+
if (!matches) {
|
|
816
|
+
return new Uint8Array(0);
|
|
817
|
+
}
|
|
818
|
+
return Uint8Array.from(matches.map((x) => parseInt(x, 16)));
|
|
819
|
+
}
|
|
820
|
+
function bytesToHex2(bytes) {
|
|
821
|
+
return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
822
|
+
}
|
|
823
|
+
function randomBytes(length) {
|
|
824
|
+
const words = import_crypto_js2.default.lib.WordArray.random(length);
|
|
825
|
+
return words.toString(import_crypto_js2.default.enc.Hex);
|
|
826
|
+
}
|
|
827
|
+
function identityFromMnemonicSync(mnemonic, passphrase = "") {
|
|
828
|
+
if (!validateMnemonic2(mnemonic)) {
|
|
829
|
+
throw new Error("Invalid mnemonic phrase");
|
|
830
|
+
}
|
|
831
|
+
const seedHex = mnemonicToSeedSync2(mnemonic, passphrase);
|
|
832
|
+
return generateMasterKey(seedHex);
|
|
833
|
+
}
|
|
834
|
+
function deriveAddressInfo(masterKey, basePath, index, isChange = false, prefix = "alpha") {
|
|
835
|
+
const chain = isChange ? 1 : 0;
|
|
836
|
+
const fullPath = `${basePath}/${chain}/${index}`;
|
|
837
|
+
const derived = deriveKeyAtPath(masterKey.privateKey, masterKey.chainCode, fullPath);
|
|
838
|
+
const publicKey = getPublicKey(derived.privateKey);
|
|
839
|
+
const address = publicKeyToAddress(publicKey, prefix);
|
|
840
|
+
return {
|
|
841
|
+
privateKey: derived.privateKey,
|
|
842
|
+
publicKey,
|
|
843
|
+
address,
|
|
844
|
+
path: fullPath,
|
|
845
|
+
index
|
|
846
|
+
};
|
|
847
|
+
}
|
|
848
|
+
function generateAddressInfo(privateKey, index, path, prefix = "alpha") {
|
|
849
|
+
const { address, publicKey } = privateKeyToAddressInfo(privateKey, prefix);
|
|
850
|
+
return {
|
|
851
|
+
privateKey,
|
|
852
|
+
publicKey,
|
|
853
|
+
address,
|
|
854
|
+
path,
|
|
855
|
+
index
|
|
856
|
+
};
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
// l1/crypto.ts
|
|
860
|
+
var import_crypto_js3 = __toESM(require("crypto-js"), 1);
|
|
861
|
+
var SALT = "alpha_wallet_salt";
|
|
862
|
+
var PBKDF2_ITERATIONS = 1e5;
|
|
863
|
+
function encrypt(text, password) {
|
|
864
|
+
return import_crypto_js3.default.AES.encrypt(text, password).toString();
|
|
865
|
+
}
|
|
866
|
+
function decrypt(encrypted, password) {
|
|
867
|
+
const bytes = import_crypto_js3.default.AES.decrypt(encrypted, password);
|
|
868
|
+
return bytes.toString(import_crypto_js3.default.enc.Utf8);
|
|
869
|
+
}
|
|
870
|
+
function generatePrivateKey() {
|
|
871
|
+
return import_crypto_js3.default.lib.WordArray.random(32).toString();
|
|
872
|
+
}
|
|
873
|
+
function encryptWallet(masterPrivateKey, password) {
|
|
874
|
+
const passwordKey = import_crypto_js3.default.PBKDF2(password, SALT, {
|
|
875
|
+
keySize: 256 / 32,
|
|
876
|
+
iterations: PBKDF2_ITERATIONS
|
|
877
|
+
}).toString();
|
|
878
|
+
const encrypted = import_crypto_js3.default.AES.encrypt(
|
|
879
|
+
masterPrivateKey,
|
|
880
|
+
passwordKey
|
|
881
|
+
).toString();
|
|
882
|
+
return encrypted;
|
|
883
|
+
}
|
|
884
|
+
function decryptWallet(encryptedData, password) {
|
|
885
|
+
const passwordKey = import_crypto_js3.default.PBKDF2(password, SALT, {
|
|
886
|
+
keySize: 256 / 32,
|
|
887
|
+
iterations: PBKDF2_ITERATIONS
|
|
888
|
+
}).toString();
|
|
889
|
+
const decrypted = import_crypto_js3.default.AES.decrypt(encryptedData, passwordKey);
|
|
890
|
+
return decrypted.toString(import_crypto_js3.default.enc.Utf8);
|
|
891
|
+
}
|
|
892
|
+
function hexToWIF(hexKey) {
|
|
893
|
+
const versionByte = "80";
|
|
894
|
+
const extendedKey = versionByte + hexKey;
|
|
895
|
+
const hash1 = import_crypto_js3.default.SHA256(import_crypto_js3.default.enc.Hex.parse(extendedKey)).toString();
|
|
896
|
+
const hash2 = import_crypto_js3.default.SHA256(import_crypto_js3.default.enc.Hex.parse(hash1)).toString();
|
|
897
|
+
const checksum = hash2.substring(0, 8);
|
|
898
|
+
const finalHex = extendedKey + checksum;
|
|
899
|
+
return base58Encode(finalHex);
|
|
844
900
|
}
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
901
|
+
function base58Encode(hex) {
|
|
902
|
+
const ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
903
|
+
let num = BigInt("0x" + hex);
|
|
904
|
+
let encoded = "";
|
|
905
|
+
while (num > 0n) {
|
|
906
|
+
const remainder = Number(num % 58n);
|
|
907
|
+
num = num / 58n;
|
|
908
|
+
encoded = ALPHABET[remainder] + encoded;
|
|
851
909
|
}
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
isBlockSubscribed = true;
|
|
855
|
-
const header = await rpc("blockchain.headers.subscribe", []);
|
|
856
|
-
if (header) {
|
|
857
|
-
lastBlockHeader = header;
|
|
858
|
-
blockSubscribers.forEach((subscriber) => subscriber(header));
|
|
859
|
-
}
|
|
860
|
-
} else if (lastBlockHeader) {
|
|
861
|
-
cb(lastBlockHeader);
|
|
910
|
+
for (let i = 0; i < hex.length && hex.substring(i, i + 2) === "00"; i += 2) {
|
|
911
|
+
encoded = "1" + encoded;
|
|
862
912
|
}
|
|
863
|
-
return
|
|
864
|
-
const index = blockSubscribers.indexOf(cb);
|
|
865
|
-
if (index > -1) {
|
|
866
|
-
blockSubscribers.splice(index, 1);
|
|
867
|
-
}
|
|
868
|
-
};
|
|
913
|
+
return encoded;
|
|
869
914
|
}
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
return
|
|
915
|
+
|
|
916
|
+
// l1/address.ts
|
|
917
|
+
var import_crypto_js4 = __toESM(require("crypto-js"), 1);
|
|
918
|
+
var deriveChildKeyBIP32 = deriveChildKey;
|
|
919
|
+
var deriveKeyAtPath2 = deriveKeyAtPath;
|
|
920
|
+
function generateMasterKeyFromSeed(seedHex) {
|
|
921
|
+
const result = generateMasterKey(seedHex);
|
|
922
|
+
return {
|
|
923
|
+
masterPrivateKey: result.privateKey,
|
|
924
|
+
masterChainCode: result.chainCode
|
|
925
|
+
};
|
|
878
926
|
}
|
|
879
|
-
|
|
880
|
-
|
|
927
|
+
function generateHDAddressBIP32(masterPriv, chainCode, index, basePath = "m/44'/0'/0'", isChange = false) {
|
|
928
|
+
const chain = isChange ? 1 : 0;
|
|
929
|
+
const fullPath = `${basePath}/${chain}/${index}`;
|
|
930
|
+
const derived = deriveKeyAtPath(masterPriv, chainCode, fullPath);
|
|
931
|
+
return generateAddressInfo(derived.privateKey, index, fullPath);
|
|
881
932
|
}
|
|
882
|
-
|
|
883
|
-
|
|
933
|
+
function generateAddressFromMasterKey(masterPrivateKey, index) {
|
|
934
|
+
const derivationPath = `m/44'/0'/${index}'`;
|
|
935
|
+
const hmacInput = import_crypto_js4.default.enc.Hex.parse(masterPrivateKey);
|
|
936
|
+
const hmacKey = import_crypto_js4.default.enc.Utf8.parse(derivationPath);
|
|
937
|
+
const hmacOutput = import_crypto_js4.default.HmacSHA512(hmacInput, hmacKey).toString();
|
|
938
|
+
const childPrivateKey = hmacOutput.substring(0, 64);
|
|
939
|
+
return generateAddressInfo(childPrivateKey, index, derivationPath);
|
|
884
940
|
}
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
941
|
+
function deriveChildKey2(masterPriv, chainCode, index) {
|
|
942
|
+
const data = masterPriv + index.toString(16).padStart(8, "0");
|
|
943
|
+
const I = import_crypto_js4.default.HmacSHA512(
|
|
944
|
+
import_crypto_js4.default.enc.Hex.parse(data),
|
|
945
|
+
import_crypto_js4.default.enc.Hex.parse(chainCode)
|
|
946
|
+
).toString();
|
|
947
|
+
return {
|
|
948
|
+
privateKey: I.substring(0, 64),
|
|
949
|
+
nextChainCode: I.substring(64)
|
|
950
|
+
};
|
|
893
951
|
}
|
|
894
|
-
function
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
ws = null;
|
|
899
|
-
}
|
|
900
|
-
isConnected = false;
|
|
901
|
-
isConnecting = false;
|
|
902
|
-
reconnectAttempts = 0;
|
|
903
|
-
isBlockSubscribed = false;
|
|
904
|
-
Object.values(pending).forEach((req) => {
|
|
905
|
-
if (req.timeoutId) clearTimeout(req.timeoutId);
|
|
906
|
-
});
|
|
907
|
-
Object.keys(pending).forEach((key) => delete pending[Number(key)]);
|
|
908
|
-
connectionCallbacks.forEach((cb) => {
|
|
909
|
-
if (cb.timeoutId) clearTimeout(cb.timeoutId);
|
|
910
|
-
});
|
|
911
|
-
connectionCallbacks.length = 0;
|
|
952
|
+
function generateHDAddress(masterPriv, chainCode, index) {
|
|
953
|
+
const child = deriveChildKey2(masterPriv, chainCode, index);
|
|
954
|
+
const path = `m/44'/0'/0'/${index}`;
|
|
955
|
+
return generateAddressInfo(child.privateKey, index, path);
|
|
912
956
|
}
|
|
913
957
|
|
|
958
|
+
// l1/index.ts
|
|
959
|
+
init_network();
|
|
960
|
+
|
|
914
961
|
// l1/tx.ts
|
|
962
|
+
init_network();
|
|
963
|
+
init_bech32();
|
|
915
964
|
var import_crypto_js5 = __toESM(require("crypto-js"), 1);
|
|
916
965
|
var import_elliptic2 = __toESM(require("elliptic"), 1);
|
|
917
966
|
|
|
918
967
|
// l1/vesting.ts
|
|
968
|
+
init_network();
|
|
919
969
|
var VESTING_THRESHOLD = 28e4;
|
|
920
970
|
var currentBlockHeight = null;
|
|
921
971
|
var VestingClassifier = class {
|
|
@@ -1134,6 +1184,24 @@ var VestingClassifier = class {
|
|
|
1134
1184
|
tx.objectStore(this.storeName).clear();
|
|
1135
1185
|
}
|
|
1136
1186
|
}
|
|
1187
|
+
/**
|
|
1188
|
+
* Destroy caches and delete the IndexedDB database entirely.
|
|
1189
|
+
*/
|
|
1190
|
+
async destroy() {
|
|
1191
|
+
this.memoryCache.clear();
|
|
1192
|
+
if (this.db) {
|
|
1193
|
+
this.db.close();
|
|
1194
|
+
this.db = null;
|
|
1195
|
+
}
|
|
1196
|
+
if (typeof indexedDB !== "undefined") {
|
|
1197
|
+
await new Promise((resolve) => {
|
|
1198
|
+
const req = indexedDB.deleteDatabase(this.dbName);
|
|
1199
|
+
req.onsuccess = () => resolve();
|
|
1200
|
+
req.onerror = () => resolve();
|
|
1201
|
+
req.onblocked = () => resolve();
|
|
1202
|
+
});
|
|
1203
|
+
}
|
|
1204
|
+
}
|
|
1137
1205
|
};
|
|
1138
1206
|
var vestingClassifier = new VestingClassifier();
|
|
1139
1207
|
|
|
@@ -4551,7 +4619,7 @@ var PaymentsModule = class _PaymentsModule {
|
|
|
4551
4619
|
memo: request.memo
|
|
4552
4620
|
});
|
|
4553
4621
|
console.log(`[Payments] Split token sent successfully`);
|
|
4554
|
-
await this.removeToken(splitPlan.tokenToSplit.uiToken.id, recipientNametag);
|
|
4622
|
+
await this.removeToken(splitPlan.tokenToSplit.uiToken.id, recipientNametag, true);
|
|
4555
4623
|
result.txHash = "split-" + Date.now().toString(16);
|
|
4556
4624
|
this.log(`Split transfer completed`);
|
|
4557
4625
|
}
|
|
@@ -4577,7 +4645,7 @@ var PaymentsModule = class _PaymentsModule {
|
|
|
4577
4645
|
});
|
|
4578
4646
|
console.log(`[Payments] Direct token sent successfully`);
|
|
4579
4647
|
this.log(`Token ${token.id} transferred, txHash: ${result.txHash}`);
|
|
4580
|
-
await this.removeToken(token.id, recipientNametag);
|
|
4648
|
+
await this.removeToken(token.id, recipientNametag, true);
|
|
4581
4649
|
}
|
|
4582
4650
|
result.status = "delivered";
|
|
4583
4651
|
await this.save();
|
|
@@ -4726,7 +4794,7 @@ var PaymentsModule = class _PaymentsModule {
|
|
|
4726
4794
|
);
|
|
4727
4795
|
if (result.success) {
|
|
4728
4796
|
const recipientNametag = request.recipient.startsWith("@") ? request.recipient.slice(1) : void 0;
|
|
4729
|
-
await this.removeToken(tokenToSplit.id, recipientNametag);
|
|
4797
|
+
await this.removeToken(tokenToSplit.id, recipientNametag, true);
|
|
4730
4798
|
await this.addToHistory({
|
|
4731
4799
|
type: "SENT",
|
|
4732
4800
|
amount: request.amount,
|
|
@@ -5232,35 +5300,39 @@ var PaymentsModule = class _PaymentsModule {
|
|
|
5232
5300
|
const rawAssets = Array.from(assetsMap.values());
|
|
5233
5301
|
let priceMap = null;
|
|
5234
5302
|
if (this.priceProvider && rawAssets.length > 0) {
|
|
5235
|
-
|
|
5236
|
-
|
|
5237
|
-
|
|
5238
|
-
const
|
|
5239
|
-
|
|
5240
|
-
|
|
5241
|
-
|
|
5242
|
-
existing
|
|
5243
|
-
|
|
5244
|
-
|
|
5303
|
+
try {
|
|
5304
|
+
const registry = TokenRegistry.getInstance();
|
|
5305
|
+
const nameToCoins = /* @__PURE__ */ new Map();
|
|
5306
|
+
for (const asset of rawAssets) {
|
|
5307
|
+
const def = registry.getDefinition(asset.coinId);
|
|
5308
|
+
if (def?.name) {
|
|
5309
|
+
const existing = nameToCoins.get(def.name);
|
|
5310
|
+
if (existing) {
|
|
5311
|
+
existing.push(asset.coinId);
|
|
5312
|
+
} else {
|
|
5313
|
+
nameToCoins.set(def.name, [asset.coinId]);
|
|
5314
|
+
}
|
|
5245
5315
|
}
|
|
5246
5316
|
}
|
|
5247
|
-
|
|
5248
|
-
|
|
5249
|
-
|
|
5250
|
-
|
|
5251
|
-
|
|
5252
|
-
|
|
5253
|
-
|
|
5254
|
-
|
|
5255
|
-
|
|
5256
|
-
|
|
5257
|
-
|
|
5258
|
-
|
|
5259
|
-
|
|
5260
|
-
}
|
|
5317
|
+
if (nameToCoins.size > 0) {
|
|
5318
|
+
const tokenNames = Array.from(nameToCoins.keys());
|
|
5319
|
+
const prices = await this.priceProvider.getPrices(tokenNames);
|
|
5320
|
+
priceMap = /* @__PURE__ */ new Map();
|
|
5321
|
+
for (const [name, coinIds] of nameToCoins) {
|
|
5322
|
+
const price = prices.get(name);
|
|
5323
|
+
if (price) {
|
|
5324
|
+
for (const cid of coinIds) {
|
|
5325
|
+
priceMap.set(cid, {
|
|
5326
|
+
priceUsd: price.priceUsd,
|
|
5327
|
+
priceEur: price.priceEur,
|
|
5328
|
+
change24h: price.change24h
|
|
5329
|
+
});
|
|
5330
|
+
}
|
|
5261
5331
|
}
|
|
5262
5332
|
}
|
|
5263
5333
|
}
|
|
5334
|
+
} catch (error) {
|
|
5335
|
+
console.warn("[Payments] Failed to fetch prices, returning assets without price data:", error);
|
|
5264
5336
|
}
|
|
5265
5337
|
}
|
|
5266
5338
|
return rawAssets.map((raw) => {
|
|
@@ -5463,6 +5535,12 @@ var PaymentsModule = class _PaymentsModule {
|
|
|
5463
5535
|
updatedAt: Date.now(),
|
|
5464
5536
|
sdkData: typeof tokenJson === "string" ? tokenJson : JSON.stringify(tokenJson)
|
|
5465
5537
|
};
|
|
5538
|
+
const loadedTokenId = extractTokenIdFromSdkData(token.sdkData);
|
|
5539
|
+
const loadedStateHash = extractStateHashFromSdkData(token.sdkData);
|
|
5540
|
+
if (loadedTokenId && loadedStateHash && this.isStateTombstoned(loadedTokenId, loadedStateHash)) {
|
|
5541
|
+
this.log(`Skipping tombstoned token file ${tokenId} (${loadedTokenId.slice(0, 8)}...)`);
|
|
5542
|
+
continue;
|
|
5543
|
+
}
|
|
5466
5544
|
this.tokens.set(token.id, token);
|
|
5467
5545
|
this.log(`Loaded token from file: ${tokenId}`);
|
|
5468
5546
|
} catch (tokenError) {
|
|
@@ -5520,6 +5598,7 @@ var PaymentsModule = class _PaymentsModule {
|
|
|
5520
5598
|
this.log(`Warning: Could not create tombstone for token ${tokenId.slice(0, 8)}... (missing tokenId or stateHash)`);
|
|
5521
5599
|
}
|
|
5522
5600
|
this.tokens.delete(tokenId);
|
|
5601
|
+
await this.deleteTokenFiles(token);
|
|
5523
5602
|
if (!skipHistory && token.coinId && token.amount) {
|
|
5524
5603
|
await this.addToHistory({
|
|
5525
5604
|
type: "SENT",
|
|
@@ -5532,6 +5611,31 @@ var PaymentsModule = class _PaymentsModule {
|
|
|
5532
5611
|
}
|
|
5533
5612
|
await this.save();
|
|
5534
5613
|
}
|
|
5614
|
+
/**
|
|
5615
|
+
* Delete physical token file(s) from all storage providers.
|
|
5616
|
+
* Finds files by matching the SDK token ID prefix in the filename.
|
|
5617
|
+
*/
|
|
5618
|
+
async deleteTokenFiles(token) {
|
|
5619
|
+
const sdkTokenId = extractTokenIdFromSdkData(token.sdkData);
|
|
5620
|
+
if (!sdkTokenId) return;
|
|
5621
|
+
const tokenIdPrefix = sdkTokenId.slice(0, 16);
|
|
5622
|
+
const providers = this.getTokenStorageProviders();
|
|
5623
|
+
for (const [providerId, provider] of providers) {
|
|
5624
|
+
if (!provider.listTokenIds || !provider.deleteToken) continue;
|
|
5625
|
+
try {
|
|
5626
|
+
const allIds = await provider.listTokenIds();
|
|
5627
|
+
const matchingFiles = allIds.filter(
|
|
5628
|
+
(id) => id.startsWith(`token-${tokenIdPrefix}`)
|
|
5629
|
+
);
|
|
5630
|
+
for (const fileId of matchingFiles) {
|
|
5631
|
+
await provider.deleteToken(fileId);
|
|
5632
|
+
this.log(`Deleted token file ${fileId} from ${providerId}`);
|
|
5633
|
+
}
|
|
5634
|
+
} catch (error) {
|
|
5635
|
+
console.warn(`[Payments] Failed to delete token files from ${providerId}:`, error);
|
|
5636
|
+
}
|
|
5637
|
+
}
|
|
5638
|
+
}
|
|
5535
5639
|
// ===========================================================================
|
|
5536
5640
|
// Public API - Tombstones
|
|
5537
5641
|
// ===========================================================================
|
|
@@ -6977,6 +7081,95 @@ function decryptSimple(ciphertext, password) {
|
|
|
6977
7081
|
}
|
|
6978
7082
|
return result;
|
|
6979
7083
|
}
|
|
7084
|
+
function decryptWithSalt(ciphertext, password, salt) {
|
|
7085
|
+
try {
|
|
7086
|
+
const key = import_crypto_js6.default.PBKDF2(password, salt, {
|
|
7087
|
+
keySize: 256 / 32,
|
|
7088
|
+
iterations: 1e5,
|
|
7089
|
+
hasher: import_crypto_js6.default.algo.SHA256
|
|
7090
|
+
}).toString();
|
|
7091
|
+
const decrypted = import_crypto_js6.default.AES.decrypt(ciphertext, key);
|
|
7092
|
+
const result = decrypted.toString(import_crypto_js6.default.enc.Utf8);
|
|
7093
|
+
return result || null;
|
|
7094
|
+
} catch {
|
|
7095
|
+
return null;
|
|
7096
|
+
}
|
|
7097
|
+
}
|
|
7098
|
+
|
|
7099
|
+
// core/scan.ts
|
|
7100
|
+
async function scanAddressesImpl(deriveAddress, options = {}) {
|
|
7101
|
+
const maxAddresses = options.maxAddresses ?? 50;
|
|
7102
|
+
const gapLimit = options.gapLimit ?? 20;
|
|
7103
|
+
const includeChange = options.includeChange ?? true;
|
|
7104
|
+
const { onProgress, signal, resolveNametag } = options;
|
|
7105
|
+
const { connect: connect2, getBalance: getBalance2 } = await Promise.resolve().then(() => (init_network(), network_exports));
|
|
7106
|
+
await connect2();
|
|
7107
|
+
const foundAddresses = [];
|
|
7108
|
+
let totalBalance = 0;
|
|
7109
|
+
let totalScanned = 0;
|
|
7110
|
+
let nametagsFoundCount = 0;
|
|
7111
|
+
const chains = includeChange ? [false, true] : [false];
|
|
7112
|
+
const totalToScan = maxAddresses * chains.length;
|
|
7113
|
+
for (const isChange of chains) {
|
|
7114
|
+
let consecutiveEmpty = 0;
|
|
7115
|
+
for (let index = 0; index < maxAddresses; index++) {
|
|
7116
|
+
if (signal?.aborted) break;
|
|
7117
|
+
const addrInfo = deriveAddress(index, isChange);
|
|
7118
|
+
totalScanned++;
|
|
7119
|
+
onProgress?.({
|
|
7120
|
+
scanned: totalScanned,
|
|
7121
|
+
total: totalToScan,
|
|
7122
|
+
currentAddress: addrInfo.address,
|
|
7123
|
+
foundCount: foundAddresses.length,
|
|
7124
|
+
currentGap: consecutiveEmpty,
|
|
7125
|
+
nametagsFoundCount
|
|
7126
|
+
});
|
|
7127
|
+
try {
|
|
7128
|
+
const balance = await getBalance2(addrInfo.address);
|
|
7129
|
+
if (balance > 0) {
|
|
7130
|
+
let nametag;
|
|
7131
|
+
if (resolveNametag) {
|
|
7132
|
+
try {
|
|
7133
|
+
const tag = await resolveNametag(addrInfo.address);
|
|
7134
|
+
if (tag) {
|
|
7135
|
+
nametag = tag;
|
|
7136
|
+
nametagsFoundCount++;
|
|
7137
|
+
}
|
|
7138
|
+
} catch {
|
|
7139
|
+
}
|
|
7140
|
+
}
|
|
7141
|
+
foundAddresses.push({
|
|
7142
|
+
index,
|
|
7143
|
+
address: addrInfo.address,
|
|
7144
|
+
path: addrInfo.path,
|
|
7145
|
+
balance,
|
|
7146
|
+
isChange,
|
|
7147
|
+
nametag
|
|
7148
|
+
});
|
|
7149
|
+
totalBalance += balance;
|
|
7150
|
+
consecutiveEmpty = 0;
|
|
7151
|
+
} else {
|
|
7152
|
+
consecutiveEmpty++;
|
|
7153
|
+
}
|
|
7154
|
+
} catch (err) {
|
|
7155
|
+
console.warn(`[scanAddresses] Error checking ${addrInfo.address}:`, err);
|
|
7156
|
+
consecutiveEmpty++;
|
|
7157
|
+
}
|
|
7158
|
+
if (consecutiveEmpty >= gapLimit) {
|
|
7159
|
+
break;
|
|
7160
|
+
}
|
|
7161
|
+
if (totalScanned % 5 === 0) {
|
|
7162
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
7163
|
+
}
|
|
7164
|
+
}
|
|
7165
|
+
if (signal?.aborted) break;
|
|
7166
|
+
}
|
|
7167
|
+
return {
|
|
7168
|
+
addresses: foundAddresses,
|
|
7169
|
+
totalBalance,
|
|
7170
|
+
scannedCount: totalScanned
|
|
7171
|
+
};
|
|
7172
|
+
}
|
|
6980
7173
|
|
|
6981
7174
|
// serialization/wallet-text.ts
|
|
6982
7175
|
var import_crypto_js7 = __toESM(require("crypto-js"), 1);
|
|
@@ -7234,10 +7427,11 @@ function parseWalletText(content) {
|
|
|
7234
7427
|
);
|
|
7235
7428
|
const descriptorPath = extractFromText(content, /DESCRIPTOR PATH:\s*([^\n]+)/);
|
|
7236
7429
|
const isBIP32 = content.includes("WALLET TYPE: BIP32 hierarchical deterministic wallet") || content.includes("WALLET TYPE: Alpha descriptor wallet") || !!chainCode;
|
|
7430
|
+
const effectiveDescriptorPath = descriptorPath ?? (isBIP32 ? "84'/1'/0'" : void 0);
|
|
7237
7431
|
const data = {
|
|
7238
7432
|
masterKey,
|
|
7239
7433
|
chainCode: chainCode ?? void 0,
|
|
7240
|
-
descriptorPath:
|
|
7434
|
+
descriptorPath: effectiveDescriptorPath,
|
|
7241
7435
|
derivationMode: isBIP32 ? "bip32" : "wif_hmac"
|
|
7242
7436
|
};
|
|
7243
7437
|
return {
|
|
@@ -7280,10 +7474,11 @@ function parseAndDecryptWalletText(content, password) {
|
|
|
7280
7474
|
);
|
|
7281
7475
|
const descriptorPath = extractFromText(content, /DESCRIPTOR PATH:\s*([^\n]+)/);
|
|
7282
7476
|
const isBIP32 = content.includes("WALLET TYPE: BIP32 hierarchical deterministic wallet") || content.includes("WALLET TYPE: Alpha descriptor wallet") || !!chainCode;
|
|
7477
|
+
const effectiveDescriptorPath = descriptorPath ?? (isBIP32 ? "84'/1'/0'" : void 0);
|
|
7283
7478
|
const data = {
|
|
7284
7479
|
masterKey,
|
|
7285
7480
|
chainCode: chainCode ?? void 0,
|
|
7286
|
-
descriptorPath:
|
|
7481
|
+
descriptorPath: effectiveDescriptorPath,
|
|
7287
7482
|
derivationMode: isBIP32 ? "bip32" : "wif_hmac"
|
|
7288
7483
|
};
|
|
7289
7484
|
return {
|
|
@@ -7873,6 +8068,9 @@ var Sphere = class _Sphere {
|
|
|
7873
8068
|
throw new Error("Either mnemonic or masterKey is required");
|
|
7874
8069
|
}
|
|
7875
8070
|
await _Sphere.clear({ storage: options.storage, tokenStorage: options.tokenStorage });
|
|
8071
|
+
if (!options.storage.isConnected()) {
|
|
8072
|
+
await options.storage.connect();
|
|
8073
|
+
}
|
|
7876
8074
|
const sphere = new _Sphere(
|
|
7877
8075
|
options.storage,
|
|
7878
8076
|
options.transport,
|
|
@@ -7952,6 +8150,7 @@ var Sphere = class _Sphere {
|
|
|
7952
8150
|
if (tokenStorage?.clear) {
|
|
7953
8151
|
await tokenStorage.clear();
|
|
7954
8152
|
}
|
|
8153
|
+
await vestingClassifier.destroy();
|
|
7955
8154
|
if (_Sphere.instance) {
|
|
7956
8155
|
await _Sphere.instance.destroy();
|
|
7957
8156
|
}
|
|
@@ -8134,7 +8333,7 @@ var Sphere = class _Sphere {
|
|
|
8134
8333
|
return {
|
|
8135
8334
|
source: this._source,
|
|
8136
8335
|
hasMnemonic: this._mnemonic !== null,
|
|
8137
|
-
hasChainCode: this._masterKey?.chainCode
|
|
8336
|
+
hasChainCode: !!this._masterKey?.chainCode,
|
|
8138
8337
|
derivationMode: this._derivationMode,
|
|
8139
8338
|
basePath: this._basePath,
|
|
8140
8339
|
address0
|
|
@@ -8187,7 +8386,7 @@ var Sphere = class _Sphere {
|
|
|
8187
8386
|
let chainCode;
|
|
8188
8387
|
if (this._masterKey) {
|
|
8189
8388
|
masterPrivateKey = this._masterKey.privateKey;
|
|
8190
|
-
chainCode = this._masterKey.chainCode;
|
|
8389
|
+
chainCode = this._masterKey.chainCode || void 0;
|
|
8191
8390
|
}
|
|
8192
8391
|
let mnemonic;
|
|
8193
8392
|
let encrypted = false;
|
|
@@ -8264,7 +8463,7 @@ var Sphere = class _Sphere {
|
|
|
8264
8463
|
}
|
|
8265
8464
|
}
|
|
8266
8465
|
const masterPrivateKey = this._masterKey?.privateKey || "";
|
|
8267
|
-
const chainCode = this._masterKey?.chainCode;
|
|
8466
|
+
const chainCode = this._masterKey?.chainCode || void 0;
|
|
8268
8467
|
const isBIP32 = this._derivationMode === "bip32";
|
|
8269
8468
|
const descriptorPath = this._basePath.replace(/^m\//, "");
|
|
8270
8469
|
if (options.password) {
|
|
@@ -8472,19 +8671,84 @@ var Sphere = class _Sphere {
|
|
|
8472
8671
|
}
|
|
8473
8672
|
if (fileType === "json") {
|
|
8474
8673
|
const content = typeof fileContent === "string" ? fileContent : new TextDecoder().decode(fileContent);
|
|
8475
|
-
|
|
8476
|
-
|
|
8477
|
-
|
|
8674
|
+
let parsed;
|
|
8675
|
+
try {
|
|
8676
|
+
parsed = JSON.parse(content);
|
|
8677
|
+
} catch {
|
|
8678
|
+
return { success: false, error: "Invalid JSON file" };
|
|
8679
|
+
}
|
|
8680
|
+
if (parsed.type === "sphere-wallet") {
|
|
8681
|
+
const result = await _Sphere.importFromJSON({
|
|
8682
|
+
jsonContent: content,
|
|
8683
|
+
password,
|
|
8684
|
+
storage: options.storage,
|
|
8685
|
+
transport: options.transport,
|
|
8686
|
+
oracle: options.oracle,
|
|
8687
|
+
tokenStorage: options.tokenStorage
|
|
8688
|
+
});
|
|
8689
|
+
if (result.success) {
|
|
8690
|
+
const sphere2 = _Sphere.getInstance();
|
|
8691
|
+
return { success: true, sphere: sphere2, mnemonic: result.mnemonic };
|
|
8692
|
+
}
|
|
8693
|
+
if (!password && result.error?.includes("Password required")) {
|
|
8694
|
+
return { success: false, needsPassword: true, error: result.error };
|
|
8695
|
+
}
|
|
8696
|
+
return { success: false, error: result.error };
|
|
8697
|
+
}
|
|
8698
|
+
let masterKey;
|
|
8699
|
+
let mnemonic;
|
|
8700
|
+
if (parsed.encrypted && typeof parsed.encrypted === "object") {
|
|
8701
|
+
if (!password) {
|
|
8702
|
+
return { success: false, needsPassword: true, error: "Password required for encrypted wallet" };
|
|
8703
|
+
}
|
|
8704
|
+
const enc = parsed.encrypted;
|
|
8705
|
+
if (!enc.salt || !enc.masterPrivateKey) {
|
|
8706
|
+
return { success: false, error: "Invalid encrypted wallet format" };
|
|
8707
|
+
}
|
|
8708
|
+
const decryptedKey = decryptWithSalt(enc.masterPrivateKey, password, enc.salt);
|
|
8709
|
+
if (!decryptedKey) {
|
|
8710
|
+
return { success: false, error: "Failed to decrypt - incorrect password?" };
|
|
8711
|
+
}
|
|
8712
|
+
masterKey = decryptedKey;
|
|
8713
|
+
if (enc.mnemonic) {
|
|
8714
|
+
mnemonic = decryptWithSalt(enc.mnemonic, password, enc.salt) ?? void 0;
|
|
8715
|
+
}
|
|
8716
|
+
} else {
|
|
8717
|
+
masterKey = parsed.masterPrivateKey;
|
|
8718
|
+
mnemonic = parsed.mnemonic;
|
|
8719
|
+
}
|
|
8720
|
+
if (!masterKey) {
|
|
8721
|
+
return { success: false, error: "No master key found in wallet JSON" };
|
|
8722
|
+
}
|
|
8723
|
+
const chainCode = parsed.chainCode;
|
|
8724
|
+
const descriptorPath = parsed.descriptorPath;
|
|
8725
|
+
const derivationMode = parsed.derivationMode;
|
|
8726
|
+
const isBIP32 = derivationMode === "bip32" || !!chainCode;
|
|
8727
|
+
const basePath = descriptorPath ? `m/${descriptorPath}` : isBIP32 ? "m/84'/1'/0'" : DEFAULT_BASE_PATH;
|
|
8728
|
+
if (mnemonic) {
|
|
8729
|
+
const sphere2 = await _Sphere.import({
|
|
8730
|
+
mnemonic,
|
|
8731
|
+
basePath,
|
|
8732
|
+
storage: options.storage,
|
|
8733
|
+
transport: options.transport,
|
|
8734
|
+
oracle: options.oracle,
|
|
8735
|
+
tokenStorage: options.tokenStorage,
|
|
8736
|
+
nametag: options.nametag
|
|
8737
|
+
});
|
|
8738
|
+
return { success: true, sphere: sphere2, mnemonic };
|
|
8739
|
+
}
|
|
8740
|
+
const sphere = await _Sphere.import({
|
|
8741
|
+
masterKey,
|
|
8742
|
+
chainCode,
|
|
8743
|
+
basePath,
|
|
8744
|
+
derivationMode: derivationMode || (chainCode ? "bip32" : "wif_hmac"),
|
|
8478
8745
|
storage: options.storage,
|
|
8479
8746
|
transport: options.transport,
|
|
8480
8747
|
oracle: options.oracle,
|
|
8481
|
-
tokenStorage: options.tokenStorage
|
|
8748
|
+
tokenStorage: options.tokenStorage,
|
|
8749
|
+
nametag: options.nametag
|
|
8482
8750
|
});
|
|
8483
|
-
|
|
8484
|
-
const sphere = _Sphere.getInstance();
|
|
8485
|
-
return { success: true, sphere, mnemonic: result.mnemonic };
|
|
8486
|
-
}
|
|
8487
|
-
return result;
|
|
8751
|
+
return { success: true, sphere };
|
|
8488
8752
|
}
|
|
8489
8753
|
return { success: false, error: "Unsupported file type" };
|
|
8490
8754
|
}
|
|
@@ -8782,7 +9046,7 @@ var Sphere = class _Sphere {
|
|
|
8782
9046
|
transport: this._transport,
|
|
8783
9047
|
oracle: this._oracle,
|
|
8784
9048
|
emitEvent,
|
|
8785
|
-
chainCode: this._masterKey?.chainCode,
|
|
9049
|
+
chainCode: this._masterKey?.chainCode || void 0,
|
|
8786
9050
|
price: this._priceProvider ?? void 0
|
|
8787
9051
|
});
|
|
8788
9052
|
this._communications.initialize({
|
|
@@ -8827,6 +9091,9 @@ var Sphere = class _Sphere {
|
|
|
8827
9091
|
if (!this._masterKey) {
|
|
8828
9092
|
throw new Error("HD derivation requires master key with chain code");
|
|
8829
9093
|
}
|
|
9094
|
+
if (this._derivationMode === "wif_hmac") {
|
|
9095
|
+
return generateAddressFromMasterKey(this._masterKey.privateKey, index);
|
|
9096
|
+
}
|
|
8830
9097
|
const info = deriveAddressInfo(
|
|
8831
9098
|
this._masterKey,
|
|
8832
9099
|
this._basePath,
|
|
@@ -8898,6 +9165,66 @@ var Sphere = class _Sphere {
|
|
|
8898
9165
|
}
|
|
8899
9166
|
return addresses;
|
|
8900
9167
|
}
|
|
9168
|
+
/**
|
|
9169
|
+
* Scan blockchain addresses to discover used addresses with balances.
|
|
9170
|
+
* Derives addresses sequentially and checks L1 balance via Fulcrum.
|
|
9171
|
+
* Uses gap limit to stop after N consecutive empty addresses.
|
|
9172
|
+
*
|
|
9173
|
+
* @param options - Scanning options
|
|
9174
|
+
* @returns Scan results with found addresses and total balance
|
|
9175
|
+
*
|
|
9176
|
+
* @example
|
|
9177
|
+
* ```ts
|
|
9178
|
+
* const result = await sphere.scanAddresses({
|
|
9179
|
+
* maxAddresses: 100,
|
|
9180
|
+
* gapLimit: 20,
|
|
9181
|
+
* onProgress: (p) => console.log(`Scanned ${p.scanned}/${p.total}, found ${p.foundCount}`),
|
|
9182
|
+
* });
|
|
9183
|
+
* console.log(`Found ${result.addresses.length} addresses, total: ${result.totalBalance} ALPHA`);
|
|
9184
|
+
* ```
|
|
9185
|
+
*/
|
|
9186
|
+
async scanAddresses(options = {}) {
|
|
9187
|
+
this.ensureReady();
|
|
9188
|
+
if (!this._masterKey) {
|
|
9189
|
+
throw new Error("Address scanning requires HD master key");
|
|
9190
|
+
}
|
|
9191
|
+
const resolveNametag = options.resolveNametag ?? (this._transport.resolveAddressInfo ? async (l1Address) => {
|
|
9192
|
+
try {
|
|
9193
|
+
const info = await this._transport.resolveAddressInfo(l1Address);
|
|
9194
|
+
return info?.nametag ?? null;
|
|
9195
|
+
} catch {
|
|
9196
|
+
return null;
|
|
9197
|
+
}
|
|
9198
|
+
} : void 0);
|
|
9199
|
+
return scanAddressesImpl(
|
|
9200
|
+
(index, isChange) => this._deriveAddressInternal(index, isChange),
|
|
9201
|
+
{ ...options, resolveNametag }
|
|
9202
|
+
);
|
|
9203
|
+
}
|
|
9204
|
+
/**
|
|
9205
|
+
* Bulk-track scanned addresses with visibility and nametag data.
|
|
9206
|
+
* Selected addresses get `hidden: false`, unselected get `hidden: true`.
|
|
9207
|
+
* Performs only 2 storage writes total (tracked addresses + nametags).
|
|
9208
|
+
*/
|
|
9209
|
+
async trackScannedAddresses(entries) {
|
|
9210
|
+
this.ensureReady();
|
|
9211
|
+
for (const { index, hidden, nametag } of entries) {
|
|
9212
|
+
const tracked = await this.ensureAddressTracked(index);
|
|
9213
|
+
if (nametag) {
|
|
9214
|
+
let nametags = this._addressNametags.get(tracked.addressId);
|
|
9215
|
+
if (!nametags) {
|
|
9216
|
+
nametags = /* @__PURE__ */ new Map();
|
|
9217
|
+
this._addressNametags.set(tracked.addressId, nametags);
|
|
9218
|
+
}
|
|
9219
|
+
if (!nametags.has(0)) nametags.set(0, nametag);
|
|
9220
|
+
}
|
|
9221
|
+
if (tracked.hidden !== hidden) {
|
|
9222
|
+
tracked.hidden = hidden;
|
|
9223
|
+
}
|
|
9224
|
+
}
|
|
9225
|
+
await this.persistTrackedAddresses();
|
|
9226
|
+
await this.persistAddressNametags();
|
|
9227
|
+
}
|
|
8901
9228
|
// ===========================================================================
|
|
8902
9229
|
// Public Methods - Status
|
|
8903
9230
|
// ===========================================================================
|
|
@@ -9479,8 +9806,8 @@ var Sphere = class _Sphere {
|
|
|
9479
9806
|
};
|
|
9480
9807
|
this._masterKey = masterKey;
|
|
9481
9808
|
}
|
|
9482
|
-
async initializeIdentityFromMasterKey(masterKey, chainCode,
|
|
9483
|
-
const basePath =
|
|
9809
|
+
async initializeIdentityFromMasterKey(masterKey, chainCode, _derivationPath) {
|
|
9810
|
+
const basePath = this._basePath;
|
|
9484
9811
|
const fullPath = `${basePath}/0/0`;
|
|
9485
9812
|
let privateKey;
|
|
9486
9813
|
if (chainCode) {
|
|
@@ -9491,8 +9818,12 @@ var Sphere = class _Sphere {
|
|
|
9491
9818
|
chainCode
|
|
9492
9819
|
};
|
|
9493
9820
|
} else {
|
|
9494
|
-
|
|
9495
|
-
|
|
9821
|
+
const addr0 = generateAddressFromMasterKey(masterKey, 0);
|
|
9822
|
+
privateKey = addr0.privateKey;
|
|
9823
|
+
this._masterKey = {
|
|
9824
|
+
privateKey: masterKey,
|
|
9825
|
+
chainCode: ""
|
|
9826
|
+
};
|
|
9496
9827
|
}
|
|
9497
9828
|
const publicKey = getPublicKey(privateKey);
|
|
9498
9829
|
const address = publicKeyToAddress(publicKey, "alpha");
|
|
@@ -9532,7 +9863,7 @@ var Sphere = class _Sphere {
|
|
|
9532
9863
|
oracle: this._oracle,
|
|
9533
9864
|
emitEvent,
|
|
9534
9865
|
// Pass chain code for L1 HD derivation
|
|
9535
|
-
chainCode: this._masterKey?.chainCode,
|
|
9866
|
+
chainCode: this._masterKey?.chainCode || void 0,
|
|
9536
9867
|
price: this._priceProvider ?? void 0
|
|
9537
9868
|
});
|
|
9538
9869
|
this._communications.initialize({
|
|
@@ -9615,6 +9946,9 @@ function formatAmount(amount, options = {}) {
|
|
|
9615
9946
|
return symbol ? `${readable} ${symbol}` : readable;
|
|
9616
9947
|
}
|
|
9617
9948
|
|
|
9949
|
+
// core/index.ts
|
|
9950
|
+
init_bech32();
|
|
9951
|
+
|
|
9618
9952
|
// types/payment-session.ts
|
|
9619
9953
|
function createPaymentSession(params) {
|
|
9620
9954
|
const now = Date.now();
|