@unicitylabs/sphere-sdk 0.1.3 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +110 -15
- package/dist/core/index.cjs +829 -236
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +332 -210
- package/dist/core/index.d.ts +332 -210
- package/dist/core/index.js +829 -236
- package/dist/core/index.js.map +1 -1
- package/dist/impl/browser/index.cjs +1224 -339
- package/dist/impl/browser/index.cjs.map +1 -1
- package/dist/impl/browser/index.js +1221 -342
- package/dist/impl/browser/index.js.map +1 -1
- package/dist/impl/browser/ipfs.cjs +471 -37
- package/dist/impl/browser/ipfs.cjs.map +1 -1
- package/dist/impl/browser/ipfs.js +470 -36
- package/dist/impl/browser/ipfs.js.map +1 -1
- package/dist/impl/nodejs/index.cjs +1238 -345
- package/dist/impl/nodejs/index.cjs.map +1 -1
- package/dist/impl/nodejs/index.d.cts +142 -57
- package/dist/impl/nodejs/index.d.ts +142 -57
- package/dist/impl/nodejs/index.js +1245 -348
- package/dist/impl/nodejs/index.js.map +1 -1
- package/dist/index.cjs +871 -235
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1395 -503
- package/dist/index.d.ts +1395 -503
- package/dist/index.js +862 -235
- package/dist/index.js.map +1 -1
- package/package.json +6 -1
package/dist/core/index.cjs
CHANGED
|
@@ -1445,6 +1445,7 @@ var L1PaymentsModule = class {
|
|
|
1445
1445
|
_chainCode;
|
|
1446
1446
|
_addresses = [];
|
|
1447
1447
|
_wallet;
|
|
1448
|
+
_transport;
|
|
1448
1449
|
constructor(config) {
|
|
1449
1450
|
this._config = {
|
|
1450
1451
|
electrumUrl: config?.electrumUrl ?? "wss://fulcrum.alpha.unicity.network:50004",
|
|
@@ -1457,13 +1458,14 @@ var L1PaymentsModule = class {
|
|
|
1457
1458
|
this._identity = deps.identity;
|
|
1458
1459
|
this._chainCode = deps.chainCode;
|
|
1459
1460
|
this._addresses = deps.addresses ?? [];
|
|
1461
|
+
this._transport = deps.transport;
|
|
1460
1462
|
this._wallet = {
|
|
1461
1463
|
masterPrivateKey: deps.identity.privateKey,
|
|
1462
1464
|
chainCode: deps.chainCode,
|
|
1463
1465
|
addresses: [
|
|
1464
1466
|
{
|
|
1465
|
-
address: deps.identity.
|
|
1466
|
-
publicKey: deps.identity.
|
|
1467
|
+
address: deps.identity.l1Address,
|
|
1468
|
+
publicKey: deps.identity.chainPubkey,
|
|
1467
1469
|
privateKey: deps.identity.privateKey,
|
|
1468
1470
|
path: "m/0",
|
|
1469
1471
|
index: 0
|
|
@@ -1471,7 +1473,7 @@ var L1PaymentsModule = class {
|
|
|
1471
1473
|
]
|
|
1472
1474
|
};
|
|
1473
1475
|
for (const addr of this._addresses) {
|
|
1474
|
-
if (addr !== deps.identity.
|
|
1476
|
+
if (addr !== deps.identity.l1Address) {
|
|
1475
1477
|
this._wallet.addresses.push({
|
|
1476
1478
|
address: addr,
|
|
1477
1479
|
path: null,
|
|
@@ -1494,18 +1496,64 @@ var L1PaymentsModule = class {
|
|
|
1494
1496
|
this._addresses = [];
|
|
1495
1497
|
this._wallet = void 0;
|
|
1496
1498
|
}
|
|
1499
|
+
/**
|
|
1500
|
+
* Check if a string looks like an L1 address (alpha1... or alphat1...)
|
|
1501
|
+
*/
|
|
1502
|
+
isL1Address(value) {
|
|
1503
|
+
return value.startsWith("alpha1") || value.startsWith("alphat1");
|
|
1504
|
+
}
|
|
1505
|
+
/**
|
|
1506
|
+
* Resolve recipient to L1 address
|
|
1507
|
+
* Supports: L1 address (alpha1...), nametag (with or without @)
|
|
1508
|
+
*/
|
|
1509
|
+
async resolveL1Address(recipient) {
|
|
1510
|
+
if (recipient.startsWith("@")) {
|
|
1511
|
+
const nametag = recipient.slice(1);
|
|
1512
|
+
return this.resolveNametagToL1Address(nametag);
|
|
1513
|
+
}
|
|
1514
|
+
if (this.isL1Address(recipient)) {
|
|
1515
|
+
return recipient;
|
|
1516
|
+
}
|
|
1517
|
+
try {
|
|
1518
|
+
const l1Address = await this.resolveNametagToL1Address(recipient);
|
|
1519
|
+
return l1Address;
|
|
1520
|
+
} catch {
|
|
1521
|
+
throw new Error(
|
|
1522
|
+
`Recipient "${recipient}" is not a valid nametag or L1 address. Use @nametag for explicit nametag or a valid alpha1... address.`
|
|
1523
|
+
);
|
|
1524
|
+
}
|
|
1525
|
+
}
|
|
1526
|
+
/**
|
|
1527
|
+
* Resolve nametag to L1 address using transport provider
|
|
1528
|
+
*/
|
|
1529
|
+
async resolveNametagToL1Address(nametag) {
|
|
1530
|
+
if (!this._transport?.resolveNametagInfo) {
|
|
1531
|
+
throw new Error("Transport provider does not support nametag resolution");
|
|
1532
|
+
}
|
|
1533
|
+
const info = await this._transport.resolveNametagInfo(nametag);
|
|
1534
|
+
if (!info) {
|
|
1535
|
+
throw new Error(`Nametag not found: ${nametag}`);
|
|
1536
|
+
}
|
|
1537
|
+
if (!info.l1Address) {
|
|
1538
|
+
throw new Error(
|
|
1539
|
+
`Nametag @${nametag} does not have L1 address information. The owner needs to update their nametag registration.`
|
|
1540
|
+
);
|
|
1541
|
+
}
|
|
1542
|
+
return info.l1Address;
|
|
1543
|
+
}
|
|
1497
1544
|
async send(request) {
|
|
1498
1545
|
this.ensureInitialized();
|
|
1499
1546
|
if (!this._wallet || !this._identity) {
|
|
1500
1547
|
return { success: false, error: "No wallet available" };
|
|
1501
1548
|
}
|
|
1502
1549
|
try {
|
|
1550
|
+
const recipientAddress = await this.resolveL1Address(request.to);
|
|
1503
1551
|
const amountAlpha = parseInt(request.amount, 10) / 1e8;
|
|
1504
1552
|
const results = await sendAlpha(
|
|
1505
1553
|
this._wallet,
|
|
1506
|
-
|
|
1554
|
+
recipientAddress,
|
|
1507
1555
|
amountAlpha,
|
|
1508
|
-
this._identity.
|
|
1556
|
+
this._identity.l1Address
|
|
1509
1557
|
);
|
|
1510
1558
|
if (results && results.length > 0) {
|
|
1511
1559
|
const txids = results.map((r) => r.txid);
|
|
@@ -1727,8 +1775,8 @@ var L1PaymentsModule = class {
|
|
|
1727
1775
|
}
|
|
1728
1776
|
_getWatchedAddresses() {
|
|
1729
1777
|
const addresses = [...this._addresses];
|
|
1730
|
-
if (this._identity?.
|
|
1731
|
-
addresses.unshift(this._identity.
|
|
1778
|
+
if (this._identity?.l1Address && !addresses.includes(this._identity.l1Address)) {
|
|
1779
|
+
addresses.unshift(this._identity.l1Address);
|
|
1732
1780
|
}
|
|
1733
1781
|
return addresses;
|
|
1734
1782
|
}
|
|
@@ -2200,50 +2248,56 @@ var NametagMinter = class {
|
|
|
2200
2248
|
};
|
|
2201
2249
|
|
|
2202
2250
|
// constants.ts
|
|
2203
|
-
var STORAGE_PREFIX = "sphere_";
|
|
2204
2251
|
var DEFAULT_ENCRYPTION_KEY = "sphere-default-key";
|
|
2205
|
-
var
|
|
2252
|
+
var STORAGE_KEYS_GLOBAL = {
|
|
2206
2253
|
/** Encrypted BIP39 mnemonic */
|
|
2207
|
-
MNEMONIC:
|
|
2254
|
+
MNEMONIC: "mnemonic",
|
|
2208
2255
|
/** Encrypted master private key */
|
|
2209
|
-
MASTER_KEY:
|
|
2256
|
+
MASTER_KEY: "master_key",
|
|
2210
2257
|
/** BIP32 chain code */
|
|
2211
|
-
CHAIN_CODE:
|
|
2258
|
+
CHAIN_CODE: "chain_code",
|
|
2212
2259
|
/** HD derivation path (full path like m/44'/0'/0'/0/0) */
|
|
2213
|
-
DERIVATION_PATH:
|
|
2260
|
+
DERIVATION_PATH: "derivation_path",
|
|
2214
2261
|
/** Base derivation path (like m/44'/0'/0' without chain/index) */
|
|
2215
|
-
BASE_PATH:
|
|
2262
|
+
BASE_PATH: "base_path",
|
|
2216
2263
|
/** Derivation mode: bip32, wif_hmac, legacy_hmac */
|
|
2217
|
-
DERIVATION_MODE:
|
|
2264
|
+
DERIVATION_MODE: "derivation_mode",
|
|
2218
2265
|
/** Wallet source: mnemonic, file, unknown */
|
|
2219
|
-
WALLET_SOURCE:
|
|
2266
|
+
WALLET_SOURCE: "wallet_source",
|
|
2220
2267
|
/** Wallet existence flag */
|
|
2221
|
-
WALLET_EXISTS:
|
|
2222
|
-
/** Registered nametag (legacy - single address) */
|
|
2223
|
-
NAMETAG: `${STORAGE_PREFIX}nametag`,
|
|
2268
|
+
WALLET_EXISTS: "wallet_exists",
|
|
2224
2269
|
/** Current active address index */
|
|
2225
|
-
CURRENT_ADDRESS_INDEX:
|
|
2226
|
-
/**
|
|
2227
|
-
ADDRESS_NAMETAGS:
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
/** Pending transfers */
|
|
2231
|
-
PENDING_TRANSFERS:
|
|
2232
|
-
/** Transfer outbox */
|
|
2233
|
-
OUTBOX:
|
|
2234
|
-
/** Conversations */
|
|
2235
|
-
CONVERSATIONS:
|
|
2236
|
-
/** Messages */
|
|
2237
|
-
MESSAGES:
|
|
2238
|
-
/** Transaction history */
|
|
2239
|
-
TRANSACTION_HISTORY:
|
|
2240
|
-
/** Archived tokens (spent token history) */
|
|
2241
|
-
ARCHIVED_TOKENS: `${STORAGE_PREFIX}archived_tokens`,
|
|
2242
|
-
/** Tombstones (records of deleted/spent tokens) */
|
|
2243
|
-
TOMBSTONES: `${STORAGE_PREFIX}tombstones`,
|
|
2244
|
-
/** Forked tokens (alternative histories) */
|
|
2245
|
-
FORKED_TOKENS: `${STORAGE_PREFIX}forked_tokens`
|
|
2270
|
+
CURRENT_ADDRESS_INDEX: "current_address_index",
|
|
2271
|
+
/** Index of address nametags (JSON: { "0": "alice", "1": "bob" }) - for discovery */
|
|
2272
|
+
ADDRESS_NAMETAGS: "address_nametags"
|
|
2273
|
+
};
|
|
2274
|
+
var STORAGE_KEYS_ADDRESS = {
|
|
2275
|
+
/** Pending transfers for this address */
|
|
2276
|
+
PENDING_TRANSFERS: "pending_transfers",
|
|
2277
|
+
/** Transfer outbox for this address */
|
|
2278
|
+
OUTBOX: "outbox",
|
|
2279
|
+
/** Conversations for this address */
|
|
2280
|
+
CONVERSATIONS: "conversations",
|
|
2281
|
+
/** Messages for this address */
|
|
2282
|
+
MESSAGES: "messages",
|
|
2283
|
+
/** Transaction history for this address */
|
|
2284
|
+
TRANSACTION_HISTORY: "transaction_history"
|
|
2246
2285
|
};
|
|
2286
|
+
var STORAGE_KEYS = {
|
|
2287
|
+
...STORAGE_KEYS_GLOBAL,
|
|
2288
|
+
...STORAGE_KEYS_ADDRESS
|
|
2289
|
+
};
|
|
2290
|
+
function getAddressId(directAddress) {
|
|
2291
|
+
let hash = directAddress;
|
|
2292
|
+
if (hash.startsWith("DIRECT://")) {
|
|
2293
|
+
hash = hash.slice(9);
|
|
2294
|
+
} else if (hash.startsWith("DIRECT:")) {
|
|
2295
|
+
hash = hash.slice(7);
|
|
2296
|
+
}
|
|
2297
|
+
const first = hash.slice(0, 6).toLowerCase();
|
|
2298
|
+
const last = hash.slice(-6).toLowerCase();
|
|
2299
|
+
return `DIRECT_${first}_${last}`;
|
|
2300
|
+
}
|
|
2247
2301
|
var DEFAULT_BASE_PATH = "m/44'/0'/0'";
|
|
2248
2302
|
var DEFAULT_DERIVATION_PATH2 = `${DEFAULT_BASE_PATH}/0/0`;
|
|
2249
2303
|
var LIMITS = {
|
|
@@ -2412,6 +2466,7 @@ function txfToToken(tokenId, txf) {
|
|
|
2412
2466
|
coinId,
|
|
2413
2467
|
symbol: isNft ? "NFT" : "UCT",
|
|
2414
2468
|
name: isNft ? "NFT" : "Token",
|
|
2469
|
+
decimals: isNft ? 0 : 8,
|
|
2415
2470
|
amount: totalAmount.toString(),
|
|
2416
2471
|
status: determineTokenStatus(txf),
|
|
2417
2472
|
createdAt: now,
|
|
@@ -2426,9 +2481,6 @@ async function buildTxfStorageData(tokens, meta, options) {
|
|
|
2426
2481
|
formatVersion: "2.0"
|
|
2427
2482
|
}
|
|
2428
2483
|
};
|
|
2429
|
-
if (options?.nametag) {
|
|
2430
|
-
storageData._nametag = options.nametag;
|
|
2431
|
-
}
|
|
2432
2484
|
if (options?.tombstones && options.tombstones.length > 0) {
|
|
2433
2485
|
storageData._tombstones = options.tombstones;
|
|
2434
2486
|
}
|
|
@@ -2568,23 +2620,330 @@ function getCurrentStateHash(txf) {
|
|
|
2568
2620
|
return void 0;
|
|
2569
2621
|
}
|
|
2570
2622
|
|
|
2623
|
+
// registry/token-registry.testnet.json
|
|
2624
|
+
var token_registry_testnet_default = [
|
|
2625
|
+
{
|
|
2626
|
+
network: "unicity:testnet",
|
|
2627
|
+
assetKind: "non-fungible",
|
|
2628
|
+
name: "unicity",
|
|
2629
|
+
description: "Unicity testnet token type",
|
|
2630
|
+
id: "f8aa13834268d29355ff12183066f0cb902003629bbc5eb9ef0efbe397867509"
|
|
2631
|
+
},
|
|
2632
|
+
{
|
|
2633
|
+
network: "unicity:testnet",
|
|
2634
|
+
assetKind: "fungible",
|
|
2635
|
+
name: "unicity",
|
|
2636
|
+
symbol: "UCT",
|
|
2637
|
+
decimals: 18,
|
|
2638
|
+
description: "Unicity testnet native coin",
|
|
2639
|
+
icons: [
|
|
2640
|
+
{ url: "https://raw.githubusercontent.com/unicitynetwork/unicity-ids/refs/heads/main/unicity_logo_32.png" }
|
|
2641
|
+
],
|
|
2642
|
+
id: "455ad8720656b08e8dbd5bac1f3c73eeea5431565f6c1c3af742b1aa12d41d89"
|
|
2643
|
+
},
|
|
2644
|
+
{
|
|
2645
|
+
network: "unicity:testnet",
|
|
2646
|
+
assetKind: "fungible",
|
|
2647
|
+
name: "unicity-usd",
|
|
2648
|
+
symbol: "USDU",
|
|
2649
|
+
decimals: 6,
|
|
2650
|
+
description: "Unicity testnet USD stablecoin",
|
|
2651
|
+
icons: [
|
|
2652
|
+
{ url: "https://raw.githubusercontent.com/unicitynetwork/unicity-ids/refs/heads/main/usdu_logo_32.png" }
|
|
2653
|
+
],
|
|
2654
|
+
id: "8f0f3d7a5e7297be0ee98c63b81bcebb2740f43f616566fc290f9823a54f52d7"
|
|
2655
|
+
},
|
|
2656
|
+
{
|
|
2657
|
+
network: "unicity:testnet",
|
|
2658
|
+
assetKind: "fungible",
|
|
2659
|
+
name: "unicity-eur",
|
|
2660
|
+
symbol: "EURU",
|
|
2661
|
+
decimals: 6,
|
|
2662
|
+
description: "Unicity testnet EUR stablecoin",
|
|
2663
|
+
icons: [
|
|
2664
|
+
{ url: "https://raw.githubusercontent.com/unicitynetwork/unicity-ids/refs/heads/main/euru_logo_32.png" }
|
|
2665
|
+
],
|
|
2666
|
+
id: "5e160d5e9fdbb03b553fb9c3f6e6c30efa41fa807be39fb4f18e43776e492925"
|
|
2667
|
+
},
|
|
2668
|
+
{
|
|
2669
|
+
network: "unicity:testnet",
|
|
2670
|
+
assetKind: "fungible",
|
|
2671
|
+
name: "solana",
|
|
2672
|
+
symbol: "SOL",
|
|
2673
|
+
decimals: 9,
|
|
2674
|
+
description: "Solana testnet coin on Unicity",
|
|
2675
|
+
icons: [
|
|
2676
|
+
{ url: "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/svg/icon/sol.svg" },
|
|
2677
|
+
{ url: "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/32/icon/sol.png" }
|
|
2678
|
+
],
|
|
2679
|
+
id: "dee5f8ce778562eec90e9c38a91296a023210ccc76ff4c29d527ac3eb64ade93"
|
|
2680
|
+
},
|
|
2681
|
+
{
|
|
2682
|
+
network: "unicity:testnet",
|
|
2683
|
+
assetKind: "fungible",
|
|
2684
|
+
name: "bitcoin",
|
|
2685
|
+
symbol: "BTC",
|
|
2686
|
+
decimals: 8,
|
|
2687
|
+
description: "Bitcoin testnet coin on Unicity",
|
|
2688
|
+
icons: [
|
|
2689
|
+
{ url: "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/svg/icon/btc.svg" },
|
|
2690
|
+
{ url: "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/32/icon/btc.png" }
|
|
2691
|
+
],
|
|
2692
|
+
id: "86bc190fcf7b2d07c6078de93db803578760148b16d4431aa2f42a3241ff0daa"
|
|
2693
|
+
},
|
|
2694
|
+
{
|
|
2695
|
+
network: "unicity:testnet",
|
|
2696
|
+
assetKind: "fungible",
|
|
2697
|
+
name: "ethereum",
|
|
2698
|
+
symbol: "ETH",
|
|
2699
|
+
decimals: 18,
|
|
2700
|
+
description: "Ethereum testnet coin on Unicity",
|
|
2701
|
+
icons: [
|
|
2702
|
+
{ url: "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/svg/icon/eth.svg" },
|
|
2703
|
+
{ url: "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/32/icon/eth.png" }
|
|
2704
|
+
],
|
|
2705
|
+
id: "3c2450f2fd867e7bb60c6a69d7ad0e53ce967078c201a3ecaa6074ed4c0deafb"
|
|
2706
|
+
},
|
|
2707
|
+
{
|
|
2708
|
+
network: "unicity:testnet",
|
|
2709
|
+
assetKind: "fungible",
|
|
2710
|
+
name: "alpha_test",
|
|
2711
|
+
symbol: "ALPHT",
|
|
2712
|
+
decimals: 8,
|
|
2713
|
+
description: "ALPHA testnet coin on Unicity",
|
|
2714
|
+
icons: [
|
|
2715
|
+
{ url: "https://raw.githubusercontent.com/unicitynetwork/unicity-ids/refs/heads/main/alpha_coin.png" }
|
|
2716
|
+
],
|
|
2717
|
+
id: "cde78ded16ef65818a51f43138031c4284e519300ab0cb60c30a8f9078080e5f"
|
|
2718
|
+
},
|
|
2719
|
+
{
|
|
2720
|
+
network: "unicity:testnet",
|
|
2721
|
+
assetKind: "fungible",
|
|
2722
|
+
name: "tether",
|
|
2723
|
+
symbol: "USDT",
|
|
2724
|
+
decimals: 6,
|
|
2725
|
+
description: "Tether (Ethereum) testnet coin on Unicity",
|
|
2726
|
+
icons: [
|
|
2727
|
+
{ url: "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/svg/icon/usdt.svg" },
|
|
2728
|
+
{ url: "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/32/icon/usdt.png" }
|
|
2729
|
+
],
|
|
2730
|
+
id: "40d25444648418fe7efd433e147187a3a6adf049ac62bc46038bda5b960bf690"
|
|
2731
|
+
},
|
|
2732
|
+
{
|
|
2733
|
+
network: "unicity:testnet",
|
|
2734
|
+
assetKind: "fungible",
|
|
2735
|
+
name: "usd-coin",
|
|
2736
|
+
symbol: "USDC",
|
|
2737
|
+
decimals: 6,
|
|
2738
|
+
description: "USDC (Ethereum) testnet coin on Unicity",
|
|
2739
|
+
icons: [
|
|
2740
|
+
{ url: "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/svg/icon/usdc.svg" },
|
|
2741
|
+
{ url: "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/32/icon/usdc.png" }
|
|
2742
|
+
],
|
|
2743
|
+
id: "2265121770fa6f41131dd9a6cc571e28679263d09a53eb2642e145b5b9a5b0a2"
|
|
2744
|
+
}
|
|
2745
|
+
];
|
|
2746
|
+
|
|
2747
|
+
// registry/TokenRegistry.ts
|
|
2748
|
+
var TokenRegistry = class _TokenRegistry {
|
|
2749
|
+
static instance = null;
|
|
2750
|
+
definitionsById;
|
|
2751
|
+
definitionsBySymbol;
|
|
2752
|
+
definitionsByName;
|
|
2753
|
+
constructor() {
|
|
2754
|
+
this.definitionsById = /* @__PURE__ */ new Map();
|
|
2755
|
+
this.definitionsBySymbol = /* @__PURE__ */ new Map();
|
|
2756
|
+
this.definitionsByName = /* @__PURE__ */ new Map();
|
|
2757
|
+
this.loadRegistry();
|
|
2758
|
+
}
|
|
2759
|
+
/**
|
|
2760
|
+
* Get singleton instance of TokenRegistry
|
|
2761
|
+
*/
|
|
2762
|
+
static getInstance() {
|
|
2763
|
+
if (!_TokenRegistry.instance) {
|
|
2764
|
+
_TokenRegistry.instance = new _TokenRegistry();
|
|
2765
|
+
}
|
|
2766
|
+
return _TokenRegistry.instance;
|
|
2767
|
+
}
|
|
2768
|
+
/**
|
|
2769
|
+
* Reset the singleton instance (useful for testing)
|
|
2770
|
+
*/
|
|
2771
|
+
static resetInstance() {
|
|
2772
|
+
_TokenRegistry.instance = null;
|
|
2773
|
+
}
|
|
2774
|
+
/**
|
|
2775
|
+
* Load registry data from bundled JSON
|
|
2776
|
+
*/
|
|
2777
|
+
loadRegistry() {
|
|
2778
|
+
const definitions = token_registry_testnet_default;
|
|
2779
|
+
for (const def of definitions) {
|
|
2780
|
+
const idLower = def.id.toLowerCase();
|
|
2781
|
+
this.definitionsById.set(idLower, def);
|
|
2782
|
+
if (def.symbol) {
|
|
2783
|
+
this.definitionsBySymbol.set(def.symbol.toUpperCase(), def);
|
|
2784
|
+
}
|
|
2785
|
+
this.definitionsByName.set(def.name.toLowerCase(), def);
|
|
2786
|
+
}
|
|
2787
|
+
}
|
|
2788
|
+
// ===========================================================================
|
|
2789
|
+
// Lookup Methods
|
|
2790
|
+
// ===========================================================================
|
|
2791
|
+
/**
|
|
2792
|
+
* Get token definition by hex coin ID
|
|
2793
|
+
* @param coinId - 64-character hex string
|
|
2794
|
+
* @returns Token definition or undefined if not found
|
|
2795
|
+
*/
|
|
2796
|
+
getDefinition(coinId) {
|
|
2797
|
+
if (!coinId) return void 0;
|
|
2798
|
+
return this.definitionsById.get(coinId.toLowerCase());
|
|
2799
|
+
}
|
|
2800
|
+
/**
|
|
2801
|
+
* Get token definition by symbol (e.g., "UCT", "BTC")
|
|
2802
|
+
* @param symbol - Token symbol (case-insensitive)
|
|
2803
|
+
* @returns Token definition or undefined if not found
|
|
2804
|
+
*/
|
|
2805
|
+
getDefinitionBySymbol(symbol) {
|
|
2806
|
+
if (!symbol) return void 0;
|
|
2807
|
+
return this.definitionsBySymbol.get(symbol.toUpperCase());
|
|
2808
|
+
}
|
|
2809
|
+
/**
|
|
2810
|
+
* Get token definition by name (e.g., "bitcoin", "ethereum")
|
|
2811
|
+
* @param name - Token name (case-insensitive)
|
|
2812
|
+
* @returns Token definition or undefined if not found
|
|
2813
|
+
*/
|
|
2814
|
+
getDefinitionByName(name) {
|
|
2815
|
+
if (!name) return void 0;
|
|
2816
|
+
return this.definitionsByName.get(name.toLowerCase());
|
|
2817
|
+
}
|
|
2818
|
+
/**
|
|
2819
|
+
* Get token symbol for a coin ID
|
|
2820
|
+
* @param coinId - 64-character hex string
|
|
2821
|
+
* @returns Symbol (e.g., "UCT") or truncated ID if not found
|
|
2822
|
+
*/
|
|
2823
|
+
getSymbol(coinId) {
|
|
2824
|
+
const def = this.getDefinition(coinId);
|
|
2825
|
+
if (def?.symbol) {
|
|
2826
|
+
return def.symbol;
|
|
2827
|
+
}
|
|
2828
|
+
return coinId.slice(0, 6).toUpperCase();
|
|
2829
|
+
}
|
|
2830
|
+
/**
|
|
2831
|
+
* Get token name for a coin ID
|
|
2832
|
+
* @param coinId - 64-character hex string
|
|
2833
|
+
* @returns Name (e.g., "Bitcoin") or coin ID if not found
|
|
2834
|
+
*/
|
|
2835
|
+
getName(coinId) {
|
|
2836
|
+
const def = this.getDefinition(coinId);
|
|
2837
|
+
if (def?.name) {
|
|
2838
|
+
return def.name.charAt(0).toUpperCase() + def.name.slice(1);
|
|
2839
|
+
}
|
|
2840
|
+
return coinId;
|
|
2841
|
+
}
|
|
2842
|
+
/**
|
|
2843
|
+
* Get decimal places for a coin ID
|
|
2844
|
+
* @param coinId - 64-character hex string
|
|
2845
|
+
* @returns Decimals or 0 if not found
|
|
2846
|
+
*/
|
|
2847
|
+
getDecimals(coinId) {
|
|
2848
|
+
const def = this.getDefinition(coinId);
|
|
2849
|
+
return def?.decimals ?? 0;
|
|
2850
|
+
}
|
|
2851
|
+
/**
|
|
2852
|
+
* Get icon URL for a coin ID
|
|
2853
|
+
* @param coinId - 64-character hex string
|
|
2854
|
+
* @param preferPng - Prefer PNG format over SVG
|
|
2855
|
+
* @returns Icon URL or null if not found
|
|
2856
|
+
*/
|
|
2857
|
+
getIconUrl(coinId, preferPng = true) {
|
|
2858
|
+
const def = this.getDefinition(coinId);
|
|
2859
|
+
if (!def?.icons || def.icons.length === 0) {
|
|
2860
|
+
return null;
|
|
2861
|
+
}
|
|
2862
|
+
if (preferPng) {
|
|
2863
|
+
const pngIcon = def.icons.find((i) => i.url.toLowerCase().includes(".png"));
|
|
2864
|
+
if (pngIcon) return pngIcon.url;
|
|
2865
|
+
}
|
|
2866
|
+
return def.icons[0].url;
|
|
2867
|
+
}
|
|
2868
|
+
/**
|
|
2869
|
+
* Check if a coin ID is known in the registry
|
|
2870
|
+
* @param coinId - 64-character hex string
|
|
2871
|
+
* @returns true if the coin is in the registry
|
|
2872
|
+
*/
|
|
2873
|
+
isKnown(coinId) {
|
|
2874
|
+
return this.definitionsById.has(coinId.toLowerCase());
|
|
2875
|
+
}
|
|
2876
|
+
/**
|
|
2877
|
+
* Get all token definitions
|
|
2878
|
+
* @returns Array of all token definitions
|
|
2879
|
+
*/
|
|
2880
|
+
getAllDefinitions() {
|
|
2881
|
+
return Array.from(this.definitionsById.values());
|
|
2882
|
+
}
|
|
2883
|
+
/**
|
|
2884
|
+
* Get all fungible token definitions
|
|
2885
|
+
* @returns Array of fungible token definitions
|
|
2886
|
+
*/
|
|
2887
|
+
getFungibleTokens() {
|
|
2888
|
+
return this.getAllDefinitions().filter((def) => def.assetKind === "fungible");
|
|
2889
|
+
}
|
|
2890
|
+
/**
|
|
2891
|
+
* Get all non-fungible token definitions
|
|
2892
|
+
* @returns Array of non-fungible token definitions
|
|
2893
|
+
*/
|
|
2894
|
+
getNonFungibleTokens() {
|
|
2895
|
+
return this.getAllDefinitions().filter((def) => def.assetKind === "non-fungible");
|
|
2896
|
+
}
|
|
2897
|
+
/**
|
|
2898
|
+
* Get coin ID by symbol
|
|
2899
|
+
* @param symbol - Token symbol (e.g., "UCT")
|
|
2900
|
+
* @returns Coin ID hex string or undefined if not found
|
|
2901
|
+
*/
|
|
2902
|
+
getCoinIdBySymbol(symbol) {
|
|
2903
|
+
const def = this.getDefinitionBySymbol(symbol);
|
|
2904
|
+
return def?.id;
|
|
2905
|
+
}
|
|
2906
|
+
/**
|
|
2907
|
+
* Get coin ID by name
|
|
2908
|
+
* @param name - Token name (e.g., "bitcoin")
|
|
2909
|
+
* @returns Coin ID hex string or undefined if not found
|
|
2910
|
+
*/
|
|
2911
|
+
getCoinIdByName(name) {
|
|
2912
|
+
const def = this.getDefinitionByName(name);
|
|
2913
|
+
return def?.id;
|
|
2914
|
+
}
|
|
2915
|
+
};
|
|
2916
|
+
|
|
2571
2917
|
// modules/payments/PaymentsModule.ts
|
|
2572
2918
|
var import_Token4 = require("@unicitylabs/state-transition-sdk/lib/token/Token");
|
|
2573
|
-
var import_TokenId3 = require("@unicitylabs/state-transition-sdk/lib/token/TokenId");
|
|
2574
2919
|
var import_CoinId3 = require("@unicitylabs/state-transition-sdk/lib/token/fungible/CoinId");
|
|
2575
2920
|
var import_TransferCommitment2 = require("@unicitylabs/state-transition-sdk/lib/transaction/TransferCommitment");
|
|
2576
2921
|
var import_TransferTransaction = require("@unicitylabs/state-transition-sdk/lib/transaction/TransferTransaction");
|
|
2577
2922
|
var import_SigningService = require("@unicitylabs/state-transition-sdk/lib/sign/SigningService");
|
|
2578
|
-
var import_ProxyAddress = require("@unicitylabs/state-transition-sdk/lib/address/ProxyAddress");
|
|
2579
2923
|
var import_AddressScheme = require("@unicitylabs/state-transition-sdk/lib/address/AddressScheme");
|
|
2580
2924
|
var import_UnmaskedPredicate3 = require("@unicitylabs/state-transition-sdk/lib/predicate/embedded/UnmaskedPredicate");
|
|
2581
2925
|
var import_TokenState3 = require("@unicitylabs/state-transition-sdk/lib/token/TokenState");
|
|
2582
2926
|
var import_HashAlgorithm3 = require("@unicitylabs/state-transition-sdk/lib/hash/HashAlgorithm");
|
|
2927
|
+
function enrichWithRegistry(info) {
|
|
2928
|
+
const registry = TokenRegistry.getInstance();
|
|
2929
|
+
const def = registry.getDefinition(info.coinId);
|
|
2930
|
+
if (def) {
|
|
2931
|
+
return {
|
|
2932
|
+
...info,
|
|
2933
|
+
symbol: def.symbol || info.symbol,
|
|
2934
|
+
name: def.name.charAt(0).toUpperCase() + def.name.slice(1),
|
|
2935
|
+
decimals: def.decimals ?? 0,
|
|
2936
|
+
iconUrl: registry.getIconUrl(info.coinId) ?? void 0
|
|
2937
|
+
};
|
|
2938
|
+
}
|
|
2939
|
+
return info;
|
|
2940
|
+
}
|
|
2583
2941
|
async function parseTokenInfo(tokenData) {
|
|
2584
2942
|
const defaultInfo = {
|
|
2585
2943
|
coinId: "ALPHA",
|
|
2586
2944
|
symbol: "ALPHA",
|
|
2587
2945
|
name: "Alpha Token",
|
|
2946
|
+
decimals: 0,
|
|
2588
2947
|
amount: "0"
|
|
2589
2948
|
};
|
|
2590
2949
|
try {
|
|
@@ -2605,23 +2964,25 @@ async function parseTokenInfo(tokenData) {
|
|
|
2605
2964
|
}
|
|
2606
2965
|
if (coinIdObj instanceof import_CoinId3.CoinId) {
|
|
2607
2966
|
const coinIdHex = coinIdObj.toJSON();
|
|
2608
|
-
return {
|
|
2967
|
+
return enrichWithRegistry({
|
|
2609
2968
|
coinId: coinIdHex,
|
|
2610
2969
|
symbol: coinIdHex.slice(0, 8),
|
|
2611
2970
|
name: `Token ${coinIdHex.slice(0, 8)}`,
|
|
2971
|
+
decimals: 0,
|
|
2612
2972
|
amount: String(amount ?? "0"),
|
|
2613
2973
|
tokenId: defaultInfo.tokenId
|
|
2614
|
-
};
|
|
2974
|
+
});
|
|
2615
2975
|
} else if (coinIdObj && typeof coinIdObj === "object" && "bytes" in coinIdObj) {
|
|
2616
2976
|
const bytes = coinIdObj.bytes;
|
|
2617
2977
|
const coinIdHex = Buffer.isBuffer(bytes) ? bytes.toString("hex") : Array.isArray(bytes) ? Buffer.from(bytes).toString("hex") : String(bytes);
|
|
2618
|
-
return {
|
|
2978
|
+
return enrichWithRegistry({
|
|
2619
2979
|
coinId: coinIdHex,
|
|
2620
2980
|
symbol: coinIdHex.slice(0, 8),
|
|
2621
2981
|
name: `Token ${coinIdHex.slice(0, 8)}`,
|
|
2982
|
+
decimals: 0,
|
|
2622
2983
|
amount: String(amount ?? "0"),
|
|
2623
2984
|
tokenId: defaultInfo.tokenId
|
|
2624
|
-
};
|
|
2985
|
+
});
|
|
2625
2986
|
}
|
|
2626
2987
|
}
|
|
2627
2988
|
}
|
|
@@ -2636,13 +2997,14 @@ async function parseTokenInfo(tokenData) {
|
|
|
2636
2997
|
if (Array.isArray(firstEntry) && firstEntry.length === 2) {
|
|
2637
2998
|
const [coinIdHex, amount] = firstEntry;
|
|
2638
2999
|
const coinIdStr = typeof coinIdHex === "string" ? coinIdHex : String(coinIdHex);
|
|
2639
|
-
return {
|
|
3000
|
+
return enrichWithRegistry({
|
|
2640
3001
|
coinId: coinIdStr,
|
|
2641
3002
|
symbol: coinIdStr.slice(0, 8),
|
|
2642
3003
|
name: `Token ${coinIdStr.slice(0, 8)}`,
|
|
3004
|
+
decimals: 0,
|
|
2643
3005
|
amount: String(amount),
|
|
2644
3006
|
tokenId: defaultInfo.tokenId
|
|
2645
|
-
};
|
|
3007
|
+
});
|
|
2646
3008
|
}
|
|
2647
3009
|
}
|
|
2648
3010
|
}
|
|
@@ -2657,25 +3019,27 @@ async function parseTokenInfo(tokenData) {
|
|
|
2657
3019
|
const firstEntry = coinData[0];
|
|
2658
3020
|
if (Array.isArray(firstEntry) && firstEntry.length === 2) {
|
|
2659
3021
|
const [coinIdHex, amount] = firstEntry;
|
|
2660
|
-
return {
|
|
3022
|
+
return enrichWithRegistry({
|
|
2661
3023
|
coinId: String(coinIdHex),
|
|
2662
3024
|
symbol: String(coinIdHex).slice(0, 8),
|
|
2663
3025
|
name: `Token ${String(coinIdHex).slice(0, 8)}`,
|
|
3026
|
+
decimals: 0,
|
|
2664
3027
|
amount: String(amount),
|
|
2665
3028
|
tokenId: genesis.tokenId
|
|
2666
|
-
};
|
|
3029
|
+
});
|
|
2667
3030
|
}
|
|
2668
3031
|
} else if (typeof coinData === "object") {
|
|
2669
3032
|
const coinEntries = Object.entries(coinData);
|
|
2670
3033
|
if (coinEntries.length > 0) {
|
|
2671
3034
|
const [coinId, amount] = coinEntries[0];
|
|
2672
|
-
return {
|
|
3035
|
+
return enrichWithRegistry({
|
|
2673
3036
|
coinId,
|
|
2674
3037
|
symbol: coinId.slice(0, 8),
|
|
2675
3038
|
name: `Token ${coinId.slice(0, 8)}`,
|
|
3039
|
+
decimals: 0,
|
|
2676
3040
|
amount: String(amount),
|
|
2677
3041
|
tokenId: genesis.tokenId
|
|
2678
|
-
};
|
|
3042
|
+
});
|
|
2679
3043
|
}
|
|
2680
3044
|
}
|
|
2681
3045
|
}
|
|
@@ -2689,25 +3053,27 @@ async function parseTokenInfo(tokenData) {
|
|
|
2689
3053
|
const firstEntry = coinData[0];
|
|
2690
3054
|
if (Array.isArray(firstEntry) && firstEntry.length === 2) {
|
|
2691
3055
|
const [coinIdHex, amount] = firstEntry;
|
|
2692
|
-
return {
|
|
3056
|
+
return enrichWithRegistry({
|
|
2693
3057
|
coinId: String(coinIdHex),
|
|
2694
3058
|
symbol: String(coinIdHex).slice(0, 8),
|
|
2695
3059
|
name: `Token ${String(coinIdHex).slice(0, 8)}`,
|
|
3060
|
+
decimals: 0,
|
|
2696
3061
|
amount: String(amount),
|
|
2697
3062
|
tokenId: defaultInfo.tokenId
|
|
2698
|
-
};
|
|
3063
|
+
});
|
|
2699
3064
|
}
|
|
2700
3065
|
} else if (typeof coinData === "object") {
|
|
2701
3066
|
const coinEntries = Object.entries(coinData);
|
|
2702
3067
|
if (coinEntries.length > 0) {
|
|
2703
3068
|
const [coinId, amount] = coinEntries[0];
|
|
2704
|
-
return {
|
|
3069
|
+
return enrichWithRegistry({
|
|
2705
3070
|
coinId,
|
|
2706
3071
|
symbol: coinId.slice(0, 8),
|
|
2707
3072
|
name: `Token ${coinId.slice(0, 8)}`,
|
|
3073
|
+
decimals: 0,
|
|
2708
3074
|
amount: String(amount),
|
|
2709
3075
|
tokenId: defaultInfo.tokenId
|
|
2710
|
-
};
|
|
3076
|
+
});
|
|
2711
3077
|
}
|
|
2712
3078
|
}
|
|
2713
3079
|
}
|
|
@@ -2866,7 +3232,8 @@ var PaymentsModule = class {
|
|
|
2866
3232
|
this.l1.initialize({
|
|
2867
3233
|
identity: deps.identity,
|
|
2868
3234
|
chainCode: deps.chainCode,
|
|
2869
|
-
addresses: deps.l1Addresses
|
|
3235
|
+
addresses: deps.l1Addresses,
|
|
3236
|
+
transport: deps.transport
|
|
2870
3237
|
});
|
|
2871
3238
|
}
|
|
2872
3239
|
this.unsubscribeTransfers = deps.transport.onTokenTransfer((transfer) => {
|
|
@@ -2888,37 +3255,24 @@ var PaymentsModule = class {
|
|
|
2888
3255
|
*/
|
|
2889
3256
|
async load() {
|
|
2890
3257
|
this.ensureInitialized();
|
|
2891
|
-
const
|
|
2892
|
-
|
|
3258
|
+
const providers = this.getTokenStorageProviders();
|
|
3259
|
+
for (const [id, provider] of providers) {
|
|
2893
3260
|
try {
|
|
2894
|
-
const
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
|
|
2898
|
-
|
|
2899
|
-
}
|
|
2900
|
-
if (Array.isArray(parsed.tombstones)) {
|
|
2901
|
-
this.tombstones = parsed.tombstones.filter(
|
|
2902
|
-
(t) => typeof t === "object" && t !== null && typeof t.tokenId === "string" && typeof t.stateHash === "string"
|
|
2903
|
-
);
|
|
2904
|
-
}
|
|
2905
|
-
if (parsed.archivedTokens && typeof parsed.archivedTokens === "object") {
|
|
2906
|
-
this.archivedTokens = new Map(Object.entries(parsed.archivedTokens));
|
|
2907
|
-
}
|
|
2908
|
-
if (parsed.forkedTokens && typeof parsed.forkedTokens === "object") {
|
|
2909
|
-
this.forkedTokens = new Map(Object.entries(parsed.forkedTokens));
|
|
2910
|
-
}
|
|
2911
|
-
if (parsed.nametag) {
|
|
2912
|
-
this.nametag = parsed.nametag;
|
|
3261
|
+
const result = await provider.load();
|
|
3262
|
+
if (result.success && result.data) {
|
|
3263
|
+
this.loadFromStorageData(result.data);
|
|
3264
|
+
this.log(`Loaded from provider ${id}: ${this.tokens.size} tokens`);
|
|
3265
|
+
break;
|
|
2913
3266
|
}
|
|
2914
|
-
this.log(`Loaded ${this.tokens.size} tokens, ${this.tombstones.length} tombstones, ${this.archivedTokens.size} archived`);
|
|
2915
3267
|
} catch (err) {
|
|
2916
|
-
console.error(
|
|
3268
|
+
console.error(`[Payments] Failed to load from provider ${id}:`, err);
|
|
2917
3269
|
}
|
|
2918
3270
|
}
|
|
2919
|
-
|
|
3271
|
+
if (this.tokens.size === 0) {
|
|
3272
|
+
await this.loadTokensFromFileStorage();
|
|
3273
|
+
}
|
|
2920
3274
|
await this.loadNametagFromFileStorage();
|
|
2921
|
-
const historyData = await this.deps.storage.get(
|
|
3275
|
+
const historyData = await this.deps.storage.get(STORAGE_KEYS_ADDRESS.TRANSACTION_HISTORY);
|
|
2922
3276
|
if (historyData) {
|
|
2923
3277
|
try {
|
|
2924
3278
|
this.transactionHistory = JSON.parse(historyData);
|
|
@@ -2926,7 +3280,7 @@ var PaymentsModule = class {
|
|
|
2926
3280
|
this.transactionHistory = [];
|
|
2927
3281
|
}
|
|
2928
3282
|
}
|
|
2929
|
-
const pending2 = await this.deps.storage.get(
|
|
3283
|
+
const pending2 = await this.deps.storage.get(STORAGE_KEYS_ADDRESS.PENDING_TRANSFERS);
|
|
2930
3284
|
if (pending2) {
|
|
2931
3285
|
const transfers = JSON.parse(pending2);
|
|
2932
3286
|
for (const transfer of transfers) {
|
|
@@ -3024,6 +3378,8 @@ var PaymentsModule = class {
|
|
|
3024
3378
|
coinId: request.coinId,
|
|
3025
3379
|
symbol: this.getCoinSymbol(request.coinId),
|
|
3026
3380
|
name: this.getCoinName(request.coinId),
|
|
3381
|
+
decimals: this.getCoinDecimals(request.coinId),
|
|
3382
|
+
iconUrl: this.getCoinIconUrl(request.coinId),
|
|
3027
3383
|
amount: splitPlan.remainderAmount.toString(),
|
|
3028
3384
|
status: "confirmed",
|
|
3029
3385
|
createdAt: Date.now(),
|
|
@@ -3092,20 +3448,25 @@ var PaymentsModule = class {
|
|
|
3092
3448
|
* Get coin symbol from coinId
|
|
3093
3449
|
*/
|
|
3094
3450
|
getCoinSymbol(coinId) {
|
|
3095
|
-
|
|
3096
|
-
"UCT": "UCT"
|
|
3097
|
-
// Add more as needed
|
|
3098
|
-
};
|
|
3099
|
-
return symbols[coinId] || coinId.slice(0, 6).toUpperCase();
|
|
3451
|
+
return TokenRegistry.getInstance().getSymbol(coinId);
|
|
3100
3452
|
}
|
|
3101
3453
|
/**
|
|
3102
3454
|
* Get coin name from coinId
|
|
3103
3455
|
*/
|
|
3104
3456
|
getCoinName(coinId) {
|
|
3105
|
-
|
|
3106
|
-
|
|
3107
|
-
|
|
3108
|
-
|
|
3457
|
+
return TokenRegistry.getInstance().getName(coinId);
|
|
3458
|
+
}
|
|
3459
|
+
/**
|
|
3460
|
+
* Get coin decimals from coinId
|
|
3461
|
+
*/
|
|
3462
|
+
getCoinDecimals(coinId) {
|
|
3463
|
+
return TokenRegistry.getInstance().getDecimals(coinId);
|
|
3464
|
+
}
|
|
3465
|
+
/**
|
|
3466
|
+
* Get coin icon URL from coinId
|
|
3467
|
+
*/
|
|
3468
|
+
getCoinIconUrl(coinId) {
|
|
3469
|
+
return TokenRegistry.getInstance().getIconUrl(coinId) ?? void 0;
|
|
3109
3470
|
}
|
|
3110
3471
|
// ===========================================================================
|
|
3111
3472
|
// Public API - Payment Requests
|
|
@@ -3263,7 +3624,7 @@ var PaymentsModule = class {
|
|
|
3263
3624
|
}
|
|
3264
3625
|
const request = {
|
|
3265
3626
|
id: transportRequest.id,
|
|
3266
|
-
senderPubkey: transportRequest.
|
|
3627
|
+
senderPubkey: transportRequest.senderTransportPubkey,
|
|
3267
3628
|
amount: transportRequest.request.amount,
|
|
3268
3629
|
coinId: transportRequest.request.coinId,
|
|
3269
3630
|
symbol: transportRequest.request.coinId,
|
|
@@ -3375,7 +3736,7 @@ var PaymentsModule = class {
|
|
|
3375
3736
|
}
|
|
3376
3737
|
const response = {
|
|
3377
3738
|
id: transportResponse.id,
|
|
3378
|
-
responderPubkey: transportResponse.
|
|
3739
|
+
responderPubkey: transportResponse.responderTransportPubkey,
|
|
3379
3740
|
requestId: transportResponse.response.requestId,
|
|
3380
3741
|
responseType: transportResponse.response.responseType,
|
|
3381
3742
|
message: transportResponse.response.message,
|
|
@@ -3580,6 +3941,8 @@ var PaymentsModule = class {
|
|
|
3580
3941
|
coinId: tokenInfo.coinId,
|
|
3581
3942
|
symbol: tokenInfo.symbol,
|
|
3582
3943
|
name: tokenInfo.name,
|
|
3944
|
+
decimals: tokenInfo.decimals,
|
|
3945
|
+
iconUrl: tokenInfo.iconUrl,
|
|
3583
3946
|
amount: tokenInfo.amount,
|
|
3584
3947
|
status: "confirmed",
|
|
3585
3948
|
createdAt: data.receivedAt || Date.now(),
|
|
@@ -3835,7 +4198,7 @@ var PaymentsModule = class {
|
|
|
3835
4198
|
};
|
|
3836
4199
|
this.transactionHistory.push(historyEntry);
|
|
3837
4200
|
await this.deps.storage.set(
|
|
3838
|
-
|
|
4201
|
+
STORAGE_KEYS_ADDRESS.TRANSACTION_HISTORY,
|
|
3839
4202
|
JSON.stringify(this.transactionHistory)
|
|
3840
4203
|
);
|
|
3841
4204
|
}
|
|
@@ -4129,6 +4492,23 @@ var PaymentsModule = class {
|
|
|
4129
4492
|
// ===========================================================================
|
|
4130
4493
|
// Private: Transfer Operations
|
|
4131
4494
|
// ===========================================================================
|
|
4495
|
+
/**
|
|
4496
|
+
* Detect if a string is an L3 address (not a nametag)
|
|
4497
|
+
* Returns true for: hex pubkeys (64+ chars), PROXY:, DIRECT: prefixed addresses
|
|
4498
|
+
*/
|
|
4499
|
+
isL3Address(value) {
|
|
4500
|
+
if (value.startsWith("PROXY:") || value.startsWith("DIRECT:")) {
|
|
4501
|
+
return true;
|
|
4502
|
+
}
|
|
4503
|
+
if (value.length >= 64 && /^[0-9a-fA-F]+$/.test(value)) {
|
|
4504
|
+
return true;
|
|
4505
|
+
}
|
|
4506
|
+
return false;
|
|
4507
|
+
}
|
|
4508
|
+
/**
|
|
4509
|
+
* Resolve recipient to Nostr pubkey for messaging
|
|
4510
|
+
* Supports: nametag (with or without @), hex pubkey
|
|
4511
|
+
*/
|
|
4132
4512
|
async resolveRecipient(recipient) {
|
|
4133
4513
|
if (recipient.startsWith("@")) {
|
|
4134
4514
|
const nametag = recipient.slice(1);
|
|
@@ -4138,7 +4518,19 @@ var PaymentsModule = class {
|
|
|
4138
4518
|
}
|
|
4139
4519
|
return pubkey;
|
|
4140
4520
|
}
|
|
4141
|
-
|
|
4521
|
+
if (this.isL3Address(recipient)) {
|
|
4522
|
+
return recipient;
|
|
4523
|
+
}
|
|
4524
|
+
if (this.deps?.transport.resolveNametag) {
|
|
4525
|
+
const pubkey = await this.deps.transport.resolveNametag(recipient);
|
|
4526
|
+
if (pubkey) {
|
|
4527
|
+
this.log(`Resolved "${recipient}" as nametag to pubkey`);
|
|
4528
|
+
return pubkey;
|
|
4529
|
+
}
|
|
4530
|
+
}
|
|
4531
|
+
throw new Error(
|
|
4532
|
+
`Recipient "${recipient}" is not a valid nametag or address. Use @nametag for explicit nametag or a valid hex pubkey/PROXY:/DIRECT: address.`
|
|
4533
|
+
);
|
|
4142
4534
|
}
|
|
4143
4535
|
/**
|
|
4144
4536
|
* Create SDK TransferCommitment for a token transfer
|
|
@@ -4170,19 +4562,74 @@ var PaymentsModule = class {
|
|
|
4170
4562
|
return import_SigningService.SigningService.createFromSecret(privateKeyBytes);
|
|
4171
4563
|
}
|
|
4172
4564
|
/**
|
|
4173
|
-
*
|
|
4565
|
+
* Create DirectAddress from a public key using UnmaskedPredicateReference
|
|
4566
|
+
*/
|
|
4567
|
+
async createDirectAddressFromPubkey(pubkeyHex) {
|
|
4568
|
+
const { UnmaskedPredicateReference: UnmaskedPredicateReference3 } = await import("@unicitylabs/state-transition-sdk/lib/predicate/embedded/UnmaskedPredicateReference");
|
|
4569
|
+
const { TokenType: TokenType3 } = await import("@unicitylabs/state-transition-sdk/lib/token/TokenType");
|
|
4570
|
+
const UNICITY_TOKEN_TYPE_HEX3 = "f8aa13834268d29355ff12183066f0cb902003629bbc5eb9ef0efbe397867509";
|
|
4571
|
+
const tokenType = new TokenType3(Buffer.from(UNICITY_TOKEN_TYPE_HEX3, "hex"));
|
|
4572
|
+
const pubkeyBytes = new Uint8Array(
|
|
4573
|
+
pubkeyHex.match(/.{1,2}/g).map((byte) => parseInt(byte, 16))
|
|
4574
|
+
);
|
|
4575
|
+
const addressRef = await UnmaskedPredicateReference3.create(
|
|
4576
|
+
tokenType,
|
|
4577
|
+
"secp256k1",
|
|
4578
|
+
pubkeyBytes,
|
|
4579
|
+
import_HashAlgorithm3.HashAlgorithm.SHA256
|
|
4580
|
+
);
|
|
4581
|
+
return addressRef.toAddress();
|
|
4582
|
+
}
|
|
4583
|
+
/**
|
|
4584
|
+
* Resolve nametag to 33-byte compressed public key using resolveNametagInfo
|
|
4585
|
+
* Returns null if nametag not found or publicKey not available
|
|
4586
|
+
*/
|
|
4587
|
+
async resolveNametagToPublicKey(nametag) {
|
|
4588
|
+
if (!this.deps?.transport.resolveNametagInfo) {
|
|
4589
|
+
this.log("resolveNametagInfo not available on transport");
|
|
4590
|
+
return null;
|
|
4591
|
+
}
|
|
4592
|
+
const info = await this.deps.transport.resolveNametagInfo(nametag);
|
|
4593
|
+
if (!info) {
|
|
4594
|
+
this.log(`Nametag "${nametag}" not found`);
|
|
4595
|
+
return null;
|
|
4596
|
+
}
|
|
4597
|
+
if (!info.chainPubkey) {
|
|
4598
|
+
this.log(`Nametag "${nametag}" has no 33-byte chainPubkey (legacy event)`);
|
|
4599
|
+
return null;
|
|
4600
|
+
}
|
|
4601
|
+
return info.chainPubkey;
|
|
4602
|
+
}
|
|
4603
|
+
/**
|
|
4604
|
+
* Resolve recipient to IAddress for L3 transfers
|
|
4605
|
+
* Supports: nametag (with or without @), PROXY:, DIRECT:, hex pubkey
|
|
4174
4606
|
*/
|
|
4175
4607
|
async resolveRecipientAddress(recipient) {
|
|
4608
|
+
const { AddressFactory } = await import("@unicitylabs/state-transition-sdk/lib/address/AddressFactory");
|
|
4176
4609
|
if (recipient.startsWith("@")) {
|
|
4177
4610
|
const nametag = recipient.slice(1);
|
|
4178
|
-
const
|
|
4179
|
-
|
|
4611
|
+
const publicKey2 = await this.resolveNametagToPublicKey(nametag);
|
|
4612
|
+
if (publicKey2) {
|
|
4613
|
+
this.log(`Resolved @${nametag} to 33-byte publicKey for DirectAddress`);
|
|
4614
|
+
return this.createDirectAddressFromPubkey(publicKey2);
|
|
4615
|
+
}
|
|
4616
|
+
throw new Error(`Nametag "${nametag}" not found or missing publicKey`);
|
|
4180
4617
|
}
|
|
4181
|
-
|
|
4182
|
-
|
|
4618
|
+
if (recipient.startsWith("PROXY:") || recipient.startsWith("DIRECT:")) {
|
|
4619
|
+
return AddressFactory.createAddress(recipient);
|
|
4620
|
+
}
|
|
4621
|
+
if (recipient.length === 66 && /^[0-9a-fA-F]+$/.test(recipient)) {
|
|
4622
|
+
this.log(`Creating DirectAddress from 33-byte compressed pubkey`);
|
|
4623
|
+
return this.createDirectAddressFromPubkey(recipient);
|
|
4624
|
+
}
|
|
4625
|
+
const publicKey = await this.resolveNametagToPublicKey(recipient);
|
|
4626
|
+
if (publicKey) {
|
|
4627
|
+
this.log(`Resolved "${recipient}" as nametag to 33-byte publicKey for DirectAddress`);
|
|
4628
|
+
return this.createDirectAddressFromPubkey(publicKey);
|
|
4629
|
+
}
|
|
4630
|
+
throw new Error(
|
|
4631
|
+
`Recipient "${recipient}" is not a valid nametag or L3 address. Use @nametag for explicit nametag or a valid 33-byte hex pubkey/PROXY:/DIRECT: address.`
|
|
4183
4632
|
);
|
|
4184
|
-
const tokenId = new import_TokenId3.TokenId(pubkeyBytes.slice(0, 32));
|
|
4185
|
-
return import_ProxyAddress.ProxyAddress.fromTokenId(tokenId);
|
|
4186
4633
|
}
|
|
4187
4634
|
async handleIncomingTransfer(transfer) {
|
|
4188
4635
|
try {
|
|
@@ -4240,7 +4687,39 @@ var PaymentsModule = class {
|
|
|
4240
4687
|
}
|
|
4241
4688
|
}
|
|
4242
4689
|
} else {
|
|
4243
|
-
|
|
4690
|
+
this.log("Finalizing DIRECT address transfer for state tracking...");
|
|
4691
|
+
try {
|
|
4692
|
+
const signingService = await this.createSigningService();
|
|
4693
|
+
const transferSalt = transferTx.data.salt;
|
|
4694
|
+
const recipientPredicate = await import_UnmaskedPredicate3.UnmaskedPredicate.create(
|
|
4695
|
+
sourceToken.id,
|
|
4696
|
+
sourceToken.type,
|
|
4697
|
+
signingService,
|
|
4698
|
+
import_HashAlgorithm3.HashAlgorithm.SHA256,
|
|
4699
|
+
transferSalt
|
|
4700
|
+
);
|
|
4701
|
+
const recipientState = new import_TokenState3.TokenState(recipientPredicate, null);
|
|
4702
|
+
const stClient = this.deps.oracle.getStateTransitionClient?.();
|
|
4703
|
+
const trustBase = this.deps.oracle.getTrustBase?.();
|
|
4704
|
+
if (!stClient || !trustBase) {
|
|
4705
|
+
this.log("Cannot finalize DIRECT transfer - missing client, using source token");
|
|
4706
|
+
tokenData = sourceTokenInput;
|
|
4707
|
+
} else {
|
|
4708
|
+
finalizedSdkToken = await stClient.finalizeTransaction(
|
|
4709
|
+
trustBase,
|
|
4710
|
+
sourceToken,
|
|
4711
|
+
recipientState,
|
|
4712
|
+
transferTx,
|
|
4713
|
+
[]
|
|
4714
|
+
// No nametag tokens needed for DIRECT
|
|
4715
|
+
);
|
|
4716
|
+
tokenData = finalizedSdkToken.toJSON();
|
|
4717
|
+
this.log("DIRECT transfer finalized successfully");
|
|
4718
|
+
}
|
|
4719
|
+
} catch (finalizeError) {
|
|
4720
|
+
this.log("DIRECT finalization failed, using source token:", finalizeError);
|
|
4721
|
+
tokenData = sourceTokenInput;
|
|
4722
|
+
}
|
|
4244
4723
|
}
|
|
4245
4724
|
} else if (payload.token) {
|
|
4246
4725
|
tokenData = payload.token;
|
|
@@ -4259,6 +4738,8 @@ var PaymentsModule = class {
|
|
|
4259
4738
|
coinId: tokenInfo.coinId,
|
|
4260
4739
|
symbol: tokenInfo.symbol,
|
|
4261
4740
|
name: tokenInfo.name,
|
|
4741
|
+
decimals: tokenInfo.decimals,
|
|
4742
|
+
iconUrl: tokenInfo.iconUrl,
|
|
4262
4743
|
amount: tokenInfo.amount,
|
|
4263
4744
|
status: "confirmed",
|
|
4264
4745
|
createdAt: Date.now(),
|
|
@@ -4274,7 +4755,7 @@ var PaymentsModule = class {
|
|
|
4274
4755
|
await this.addToken(token);
|
|
4275
4756
|
const incomingTransfer = {
|
|
4276
4757
|
id: transfer.id,
|
|
4277
|
-
senderPubkey: transfer.
|
|
4758
|
+
senderPubkey: transfer.senderTransportPubkey,
|
|
4278
4759
|
tokens: [token],
|
|
4279
4760
|
memo: payload.memo,
|
|
4280
4761
|
receivedAt: transfer.timestamp
|
|
@@ -4312,28 +4793,32 @@ var PaymentsModule = class {
|
|
|
4312
4793
|
// Private: Storage
|
|
4313
4794
|
// ===========================================================================
|
|
4314
4795
|
async save() {
|
|
4315
|
-
const
|
|
4316
|
-
|
|
4317
|
-
tokens
|
|
4318
|
-
|
|
4319
|
-
|
|
4320
|
-
|
|
4321
|
-
|
|
4322
|
-
|
|
4323
|
-
|
|
4796
|
+
const providers = this.getTokenStorageProviders();
|
|
4797
|
+
if (providers.size === 0) {
|
|
4798
|
+
this.log("No token storage providers - tokens not persisted");
|
|
4799
|
+
return;
|
|
4800
|
+
}
|
|
4801
|
+
const data = await this.createStorageData();
|
|
4802
|
+
for (const [id, provider] of providers) {
|
|
4803
|
+
try {
|
|
4804
|
+
await provider.save(data);
|
|
4805
|
+
} catch (err) {
|
|
4806
|
+
console.error(`[Payments] Failed to save to provider ${id}:`, err);
|
|
4807
|
+
}
|
|
4808
|
+
}
|
|
4324
4809
|
}
|
|
4325
4810
|
async saveToOutbox(transfer, recipient) {
|
|
4326
4811
|
const outbox = await this.loadOutbox();
|
|
4327
4812
|
outbox.push({ transfer, recipient, createdAt: Date.now() });
|
|
4328
|
-
await this.deps.storage.set(
|
|
4813
|
+
await this.deps.storage.set(STORAGE_KEYS_ADDRESS.OUTBOX, JSON.stringify(outbox));
|
|
4329
4814
|
}
|
|
4330
4815
|
async removeFromOutbox(transferId) {
|
|
4331
4816
|
const outbox = await this.loadOutbox();
|
|
4332
4817
|
const filtered = outbox.filter((e) => e.transfer.id !== transferId);
|
|
4333
|
-
await this.deps.storage.set(
|
|
4818
|
+
await this.deps.storage.set(STORAGE_KEYS_ADDRESS.OUTBOX, JSON.stringify(filtered));
|
|
4334
4819
|
}
|
|
4335
4820
|
async loadOutbox() {
|
|
4336
|
-
const data = await this.deps.storage.get(
|
|
4821
|
+
const data = await this.deps.storage.get(STORAGE_KEYS_ADDRESS.OUTBOX);
|
|
4337
4822
|
return data ? JSON.parse(data) : [];
|
|
4338
4823
|
}
|
|
4339
4824
|
async createStorageData() {
|
|
@@ -4342,11 +4827,10 @@ var PaymentsModule = class {
|
|
|
4342
4827
|
tokens,
|
|
4343
4828
|
{
|
|
4344
4829
|
version: 1,
|
|
4345
|
-
address: this.deps.identity.
|
|
4830
|
+
address: this.deps.identity.l1Address,
|
|
4346
4831
|
ipnsName: this.deps.identity.ipnsName ?? ""
|
|
4347
4832
|
},
|
|
4348
4833
|
{
|
|
4349
|
-
nametag: this.nametag || void 0,
|
|
4350
4834
|
tombstones: this.tombstones,
|
|
4351
4835
|
archivedTokens: this.archivedTokens,
|
|
4352
4836
|
forkedTokens: this.forkedTokens
|
|
@@ -4446,7 +4930,7 @@ var CommunicationsModule = class {
|
|
|
4446
4930
|
const eventId = await this.deps.transport.sendMessage(recipientPubkey, content);
|
|
4447
4931
|
const message = {
|
|
4448
4932
|
id: eventId,
|
|
4449
|
-
senderPubkey: this.deps.identity.
|
|
4933
|
+
senderPubkey: this.deps.identity.chainPubkey,
|
|
4450
4934
|
senderNametag: this.deps.identity.nametag,
|
|
4451
4935
|
recipientPubkey,
|
|
4452
4936
|
content,
|
|
@@ -4473,7 +4957,7 @@ var CommunicationsModule = class {
|
|
|
4473
4957
|
getConversations() {
|
|
4474
4958
|
const conversations = /* @__PURE__ */ new Map();
|
|
4475
4959
|
for (const message of this.messages.values()) {
|
|
4476
|
-
const peer = message.senderPubkey === this.deps?.identity.
|
|
4960
|
+
const peer = message.senderPubkey === this.deps?.identity.chainPubkey ? message.recipientPubkey : message.senderPubkey;
|
|
4477
4961
|
if (!conversations.has(peer)) {
|
|
4478
4962
|
conversations.set(peer, []);
|
|
4479
4963
|
}
|
|
@@ -4503,7 +4987,7 @@ var CommunicationsModule = class {
|
|
|
4503
4987
|
*/
|
|
4504
4988
|
getUnreadCount(peerPubkey) {
|
|
4505
4989
|
let messages = Array.from(this.messages.values()).filter(
|
|
4506
|
-
(m) => !m.isRead && m.senderPubkey !== this.deps?.identity.
|
|
4990
|
+
(m) => !m.isRead && m.senderPubkey !== this.deps?.identity.chainPubkey
|
|
4507
4991
|
);
|
|
4508
4992
|
if (peerPubkey) {
|
|
4509
4993
|
messages = messages.filter((m) => m.senderPubkey === peerPubkey);
|
|
@@ -4528,7 +5012,7 @@ var CommunicationsModule = class {
|
|
|
4528
5012
|
const eventId = await this.deps.transport.publishBroadcast?.(content, tags);
|
|
4529
5013
|
const message = {
|
|
4530
5014
|
id: eventId ?? crypto.randomUUID(),
|
|
4531
|
-
authorPubkey: this.deps.identity.
|
|
5015
|
+
authorPubkey: this.deps.identity.chainPubkey,
|
|
4532
5016
|
authorNametag: this.deps.identity.nametag,
|
|
4533
5017
|
content,
|
|
4534
5018
|
timestamp: Date.now(),
|
|
@@ -4579,11 +5063,12 @@ var CommunicationsModule = class {
|
|
|
4579
5063
|
// Private: Message Handling
|
|
4580
5064
|
// ===========================================================================
|
|
4581
5065
|
handleIncomingMessage(msg) {
|
|
4582
|
-
if (msg.
|
|
5066
|
+
if (msg.senderTransportPubkey === this.deps?.identity.chainPubkey) return;
|
|
4583
5067
|
const message = {
|
|
4584
5068
|
id: msg.id,
|
|
4585
|
-
senderPubkey: msg.
|
|
4586
|
-
|
|
5069
|
+
senderPubkey: msg.senderTransportPubkey,
|
|
5070
|
+
senderNametag: msg.senderNametag,
|
|
5071
|
+
recipientPubkey: this.deps.identity.chainPubkey,
|
|
4587
5072
|
content: msg.content,
|
|
4588
5073
|
timestamp: msg.timestamp,
|
|
4589
5074
|
isRead: false
|
|
@@ -4605,7 +5090,7 @@ var CommunicationsModule = class {
|
|
|
4605
5090
|
handleIncomingBroadcast(incoming) {
|
|
4606
5091
|
const message = {
|
|
4607
5092
|
id: incoming.id,
|
|
4608
|
-
authorPubkey: incoming.
|
|
5093
|
+
authorPubkey: incoming.authorTransportPubkey,
|
|
4609
5094
|
content: incoming.content,
|
|
4610
5095
|
timestamp: incoming.timestamp,
|
|
4611
5096
|
tags: incoming.tags
|
|
@@ -5432,6 +5917,7 @@ var import_SigningService2 = require("@unicitylabs/state-transition-sdk/lib/sign
|
|
|
5432
5917
|
var import_TokenType2 = require("@unicitylabs/state-transition-sdk/lib/token/TokenType");
|
|
5433
5918
|
var import_HashAlgorithm4 = require("@unicitylabs/state-transition-sdk/lib/hash/HashAlgorithm");
|
|
5434
5919
|
var import_UnmaskedPredicateReference2 = require("@unicitylabs/state-transition-sdk/lib/predicate/embedded/UnmaskedPredicateReference");
|
|
5920
|
+
var import_nostr_js_sdk = require("@unicitylabs/nostr-js-sdk");
|
|
5435
5921
|
var UNICITY_TOKEN_TYPE_HEX2 = "f8aa13834268d29355ff12183066f0cb902003629bbc5eb9ef0efbe397867509";
|
|
5436
5922
|
async function deriveL3PredicateAddress(privateKey) {
|
|
5437
5923
|
const secret = Buffer.from(privateKey, "hex");
|
|
@@ -5458,6 +5944,7 @@ var Sphere = class _Sphere {
|
|
|
5458
5944
|
_derivationMode = "bip32";
|
|
5459
5945
|
_basePath = DEFAULT_BASE_PATH;
|
|
5460
5946
|
_currentAddressIndex = 0;
|
|
5947
|
+
/** Map of addressId -> (nametagIndex -> nametag). Supports multiple nametags per address (e.g., from Nostr recovery) */
|
|
5461
5948
|
_addressNametags = /* @__PURE__ */ new Map();
|
|
5462
5949
|
// Providers
|
|
5463
5950
|
_storage;
|
|
@@ -5493,9 +5980,9 @@ var Sphere = class _Sphere {
|
|
|
5493
5980
|
if (!storage.isConnected()) {
|
|
5494
5981
|
await storage.connect();
|
|
5495
5982
|
}
|
|
5496
|
-
const mnemonic = await storage.get(
|
|
5983
|
+
const mnemonic = await storage.get(STORAGE_KEYS_GLOBAL.MNEMONIC);
|
|
5497
5984
|
if (mnemonic) return true;
|
|
5498
|
-
const masterKey = await storage.get(
|
|
5985
|
+
const masterKey = await storage.get(STORAGE_KEYS_GLOBAL.MASTER_KEY);
|
|
5499
5986
|
if (masterKey) return true;
|
|
5500
5987
|
return false;
|
|
5501
5988
|
} catch {
|
|
@@ -5589,6 +6076,8 @@ var Sphere = class _Sphere {
|
|
|
5589
6076
|
_Sphere.instance = sphere;
|
|
5590
6077
|
if (options.nametag) {
|
|
5591
6078
|
await sphere.registerNametag(options.nametag);
|
|
6079
|
+
} else {
|
|
6080
|
+
await sphere.recoverNametagFromNostr();
|
|
5592
6081
|
}
|
|
5593
6082
|
return sphere;
|
|
5594
6083
|
}
|
|
@@ -5651,6 +6140,9 @@ var Sphere = class _Sphere {
|
|
|
5651
6140
|
}
|
|
5652
6141
|
await sphere.initializeProviders();
|
|
5653
6142
|
await sphere.initializeModules();
|
|
6143
|
+
if (!options.nametag) {
|
|
6144
|
+
await sphere.recoverNametagFromNostr();
|
|
6145
|
+
}
|
|
5654
6146
|
await sphere.finalizeWalletCreation();
|
|
5655
6147
|
sphere._initialized = true;
|
|
5656
6148
|
_Sphere.instance = sphere;
|
|
@@ -5661,20 +6153,20 @@ var Sphere = class _Sphere {
|
|
|
5661
6153
|
}
|
|
5662
6154
|
/**
|
|
5663
6155
|
* Clear wallet data from storage
|
|
6156
|
+
* Note: Token data is cleared via TokenStorageProvider, not here
|
|
5664
6157
|
*/
|
|
5665
6158
|
static async clear(storage) {
|
|
5666
|
-
await storage.remove(
|
|
5667
|
-
await storage.remove(
|
|
5668
|
-
await storage.remove(
|
|
5669
|
-
await storage.remove(
|
|
5670
|
-
await storage.remove(
|
|
5671
|
-
await storage.remove(
|
|
5672
|
-
await storage.remove(
|
|
5673
|
-
await storage.remove(
|
|
5674
|
-
await storage.remove(
|
|
5675
|
-
await storage.remove(
|
|
5676
|
-
await storage.remove(
|
|
5677
|
-
await storage.remove(STORAGE_KEYS.OUTBOX);
|
|
6159
|
+
await storage.remove(STORAGE_KEYS_GLOBAL.MNEMONIC);
|
|
6160
|
+
await storage.remove(STORAGE_KEYS_GLOBAL.MASTER_KEY);
|
|
6161
|
+
await storage.remove(STORAGE_KEYS_GLOBAL.CHAIN_CODE);
|
|
6162
|
+
await storage.remove(STORAGE_KEYS_GLOBAL.DERIVATION_PATH);
|
|
6163
|
+
await storage.remove(STORAGE_KEYS_GLOBAL.BASE_PATH);
|
|
6164
|
+
await storage.remove(STORAGE_KEYS_GLOBAL.DERIVATION_MODE);
|
|
6165
|
+
await storage.remove(STORAGE_KEYS_GLOBAL.WALLET_SOURCE);
|
|
6166
|
+
await storage.remove(STORAGE_KEYS_GLOBAL.WALLET_EXISTS);
|
|
6167
|
+
await storage.remove(STORAGE_KEYS_GLOBAL.ADDRESS_NAMETAGS);
|
|
6168
|
+
await storage.remove(STORAGE_KEYS_ADDRESS.PENDING_TRANSFERS);
|
|
6169
|
+
await storage.remove(STORAGE_KEYS_ADDRESS.OUTBOX);
|
|
5678
6170
|
if (_Sphere.instance) {
|
|
5679
6171
|
await _Sphere.instance.destroy();
|
|
5680
6172
|
}
|
|
@@ -5724,9 +6216,9 @@ var Sphere = class _Sphere {
|
|
|
5724
6216
|
get identity() {
|
|
5725
6217
|
if (!this._identity) return null;
|
|
5726
6218
|
return {
|
|
5727
|
-
|
|
5728
|
-
|
|
5729
|
-
|
|
6219
|
+
chainPubkey: this._identity.chainPubkey,
|
|
6220
|
+
l1Address: this._identity.l1Address,
|
|
6221
|
+
directAddress: this._identity.directAddress,
|
|
5730
6222
|
ipnsName: this._identity.ipnsName,
|
|
5731
6223
|
nametag: this._identity.nametag
|
|
5732
6224
|
};
|
|
@@ -5843,7 +6335,7 @@ var Sphere = class _Sphere {
|
|
|
5843
6335
|
if (this._masterKey) {
|
|
5844
6336
|
address0 = this.deriveAddress(0).address;
|
|
5845
6337
|
} else if (this._identity) {
|
|
5846
|
-
address0 = this._identity.
|
|
6338
|
+
address0 = this._identity.l1Address;
|
|
5847
6339
|
}
|
|
5848
6340
|
} catch {
|
|
5849
6341
|
}
|
|
@@ -5890,8 +6382,8 @@ var Sphere = class _Sphere {
|
|
|
5890
6382
|
} catch {
|
|
5891
6383
|
if (i === 0 && this._identity) {
|
|
5892
6384
|
addresses.push({
|
|
5893
|
-
address: this._identity.
|
|
5894
|
-
publicKey: this._identity.
|
|
6385
|
+
address: this._identity.l1Address,
|
|
6386
|
+
publicKey: this._identity.chainPubkey,
|
|
5895
6387
|
path: this.getDefaultAddressPath(),
|
|
5896
6388
|
index: 0
|
|
5897
6389
|
});
|
|
@@ -5970,7 +6462,7 @@ var Sphere = class _Sphere {
|
|
|
5970
6462
|
} catch {
|
|
5971
6463
|
if (i === 0 && this._identity) {
|
|
5972
6464
|
addresses.push({
|
|
5973
|
-
address: this._identity.
|
|
6465
|
+
address: this._identity.l1Address,
|
|
5974
6466
|
path: this.getDefaultAddressPath(),
|
|
5975
6467
|
index: 0,
|
|
5976
6468
|
isChange: false
|
|
@@ -6274,22 +6766,47 @@ var Sphere = class _Sphere {
|
|
|
6274
6766
|
return this._currentAddressIndex;
|
|
6275
6767
|
}
|
|
6276
6768
|
/**
|
|
6277
|
-
* Get nametag for a specific address
|
|
6769
|
+
* Get primary nametag for a specific address
|
|
6278
6770
|
*
|
|
6279
|
-
* @param
|
|
6280
|
-
* @returns
|
|
6771
|
+
* @param addressId - Address identifier (DIRECT://xxx), defaults to current address
|
|
6772
|
+
* @returns Primary nametag (index 0) or undefined if not registered
|
|
6281
6773
|
*/
|
|
6282
|
-
getNametagForAddress(
|
|
6283
|
-
const
|
|
6284
|
-
|
|
6774
|
+
getNametagForAddress(addressId) {
|
|
6775
|
+
const id = addressId ?? this.getCurrentAddressId();
|
|
6776
|
+
if (!id) return void 0;
|
|
6777
|
+
const nametagsMap = this._addressNametags.get(id);
|
|
6778
|
+
return nametagsMap?.get(0);
|
|
6779
|
+
}
|
|
6780
|
+
/**
|
|
6781
|
+
* Get all nametags for a specific address
|
|
6782
|
+
*
|
|
6783
|
+
* @param addressId - Address identifier (DIRECT://xxx), defaults to current address
|
|
6784
|
+
* @returns Map of nametagIndex to nametag, or undefined if no nametags
|
|
6785
|
+
*/
|
|
6786
|
+
getNametagsForAddress(addressId) {
|
|
6787
|
+
const id = addressId ?? this.getCurrentAddressId();
|
|
6788
|
+
if (!id) return void 0;
|
|
6789
|
+
const nametagsMap = this._addressNametags.get(id);
|
|
6790
|
+
return nametagsMap ? new Map(nametagsMap) : void 0;
|
|
6285
6791
|
}
|
|
6286
6792
|
/**
|
|
6287
6793
|
* Get all registered address nametags
|
|
6288
6794
|
*
|
|
6289
|
-
* @returns Map of
|
|
6795
|
+
* @returns Map of addressId to (nametagIndex -> nametag)
|
|
6290
6796
|
*/
|
|
6291
6797
|
getAllAddressNametags() {
|
|
6292
|
-
|
|
6798
|
+
const result = /* @__PURE__ */ new Map();
|
|
6799
|
+
this._addressNametags.forEach((nametagsMap, addressId) => {
|
|
6800
|
+
result.set(addressId, new Map(nametagsMap));
|
|
6801
|
+
});
|
|
6802
|
+
return result;
|
|
6803
|
+
}
|
|
6804
|
+
/**
|
|
6805
|
+
* Get current address identifier (DIRECT://xxx format)
|
|
6806
|
+
*/
|
|
6807
|
+
getCurrentAddressId() {
|
|
6808
|
+
if (!this._identity?.directAddress) return void 0;
|
|
6809
|
+
return getAddressId(this._identity.directAddress);
|
|
6293
6810
|
}
|
|
6294
6811
|
/**
|
|
6295
6812
|
* Switch to a different address by index
|
|
@@ -6321,17 +6838,19 @@ var Sphere = class _Sphere {
|
|
|
6321
6838
|
const addressInfo = this.deriveAddress(index, false);
|
|
6322
6839
|
const ipnsHash = sha256(addressInfo.publicKey, "hex").slice(0, 40);
|
|
6323
6840
|
const predicateAddress = await deriveL3PredicateAddress(addressInfo.privateKey);
|
|
6324
|
-
const
|
|
6841
|
+
const addressId = getAddressId(predicateAddress);
|
|
6842
|
+
const nametagsMap = this._addressNametags.get(addressId);
|
|
6843
|
+
const nametag = nametagsMap?.get(0);
|
|
6325
6844
|
this._identity = {
|
|
6326
6845
|
privateKey: addressInfo.privateKey,
|
|
6327
|
-
|
|
6328
|
-
|
|
6329
|
-
predicateAddress,
|
|
6846
|
+
chainPubkey: addressInfo.publicKey,
|
|
6847
|
+
l1Address: addressInfo.address,
|
|
6848
|
+
directAddress: predicateAddress,
|
|
6330
6849
|
ipnsName: "12D3KooW" + ipnsHash,
|
|
6331
6850
|
nametag
|
|
6332
6851
|
};
|
|
6333
6852
|
this._currentAddressIndex = index;
|
|
6334
|
-
await this._storage.set(
|
|
6853
|
+
await this._storage.set(STORAGE_KEYS_GLOBAL.CURRENT_ADDRESS_INDEX, index.toString());
|
|
6335
6854
|
this._storage.setIdentity(this._identity);
|
|
6336
6855
|
this._transport.setIdentity(this._identity);
|
|
6337
6856
|
for (const provider of this._tokenStorageProviders.values()) {
|
|
@@ -6339,13 +6858,13 @@ var Sphere = class _Sphere {
|
|
|
6339
6858
|
}
|
|
6340
6859
|
await this.reinitializeModulesForNewAddress();
|
|
6341
6860
|
this.emitEvent("identity:changed", {
|
|
6342
|
-
|
|
6343
|
-
|
|
6344
|
-
|
|
6861
|
+
l1Address: this._identity.l1Address,
|
|
6862
|
+
directAddress: this._identity.directAddress,
|
|
6863
|
+
chainPubkey: this._identity.chainPubkey,
|
|
6345
6864
|
nametag: this._identity.nametag,
|
|
6346
6865
|
addressIndex: index
|
|
6347
6866
|
});
|
|
6348
|
-
console.log(`[Sphere] Switched to address ${index}:`, this._identity.
|
|
6867
|
+
console.log(`[Sphere] Switched to address ${index}:`, this._identity.l1Address);
|
|
6349
6868
|
}
|
|
6350
6869
|
/**
|
|
6351
6870
|
* Re-initialize modules after address switch
|
|
@@ -6403,7 +6922,7 @@ var Sphere = class _Sphere {
|
|
|
6403
6922
|
);
|
|
6404
6923
|
return {
|
|
6405
6924
|
...info,
|
|
6406
|
-
address:
|
|
6925
|
+
address: publicKeyToAddress(info.publicKey, "alpha")
|
|
6407
6926
|
};
|
|
6408
6927
|
}
|
|
6409
6928
|
/**
|
|
@@ -6430,11 +6949,10 @@ var Sphere = class _Sphere {
|
|
|
6430
6949
|
path
|
|
6431
6950
|
);
|
|
6432
6951
|
const publicKey = getPublicKey(derived.privateKey);
|
|
6433
|
-
const addressHash = hash160(publicKey);
|
|
6434
6952
|
return {
|
|
6435
6953
|
privateKey: derived.privateKey,
|
|
6436
6954
|
publicKey,
|
|
6437
|
-
address:
|
|
6955
|
+
address: publicKeyToAddress(publicKey, "alpha"),
|
|
6438
6956
|
path,
|
|
6439
6957
|
index
|
|
6440
6958
|
};
|
|
@@ -6522,6 +7040,17 @@ var Sphere = class _Sphere {
|
|
|
6522
7040
|
hasNametag() {
|
|
6523
7041
|
return !!this._identity?.nametag;
|
|
6524
7042
|
}
|
|
7043
|
+
/**
|
|
7044
|
+
* Get the PROXY address for the current nametag
|
|
7045
|
+
* PROXY addresses are derived from the nametag hash and require
|
|
7046
|
+
* the nametag token to claim funds sent to them
|
|
7047
|
+
* @returns PROXY address string or undefined if no nametag
|
|
7048
|
+
*/
|
|
7049
|
+
getProxyAddress() {
|
|
7050
|
+
const nametag = this._identity?.nametag;
|
|
7051
|
+
if (!nametag) return void 0;
|
|
7052
|
+
return `PROXY:${(0, import_nostr_js_sdk.hashNametag)(nametag)}`;
|
|
7053
|
+
}
|
|
6525
7054
|
/**
|
|
6526
7055
|
* Register a nametag for the current active address
|
|
6527
7056
|
* Each address can have its own independent nametag
|
|
@@ -6550,14 +7079,25 @@ var Sphere = class _Sphere {
|
|
|
6550
7079
|
throw new Error(`Nametag already registered for address ${this._currentAddressIndex}: @${this._identity.nametag}`);
|
|
6551
7080
|
}
|
|
6552
7081
|
if (this._transport.registerNametag) {
|
|
6553
|
-
const success = await this._transport.registerNametag(
|
|
7082
|
+
const success = await this._transport.registerNametag(
|
|
7083
|
+
cleanNametag,
|
|
7084
|
+
this._identity.chainPubkey,
|
|
7085
|
+
this._identity.directAddress || ""
|
|
7086
|
+
);
|
|
6554
7087
|
if (!success) {
|
|
6555
7088
|
throw new Error("Failed to register nametag. It may already be taken.");
|
|
6556
7089
|
}
|
|
6557
7090
|
}
|
|
6558
7091
|
this._identity.nametag = cleanNametag;
|
|
6559
|
-
this.
|
|
6560
|
-
|
|
7092
|
+
const addressId = this.getCurrentAddressId();
|
|
7093
|
+
if (addressId) {
|
|
7094
|
+
let nametagsMap = this._addressNametags.get(addressId);
|
|
7095
|
+
if (!nametagsMap) {
|
|
7096
|
+
nametagsMap = /* @__PURE__ */ new Map();
|
|
7097
|
+
this._addressNametags.set(addressId, nametagsMap);
|
|
7098
|
+
}
|
|
7099
|
+
nametagsMap.set(0, cleanNametag);
|
|
7100
|
+
}
|
|
6561
7101
|
await this.persistAddressNametags();
|
|
6562
7102
|
if (!this._payments.hasNametag()) {
|
|
6563
7103
|
console.log(`[Sphere] Minting nametag token for @${cleanNametag}...`);
|
|
@@ -6576,13 +7116,18 @@ var Sphere = class _Sphere {
|
|
|
6576
7116
|
}
|
|
6577
7117
|
/**
|
|
6578
7118
|
* Persist address nametags to storage
|
|
7119
|
+
* Format: { "DIRECT://abc...xyz": { "0": "alice", "1": "alice2" }, ... }
|
|
6579
7120
|
*/
|
|
6580
7121
|
async persistAddressNametags() {
|
|
6581
|
-
const
|
|
6582
|
-
this._addressNametags.forEach((
|
|
6583
|
-
|
|
7122
|
+
const result = {};
|
|
7123
|
+
this._addressNametags.forEach((nametagsMap, addressId) => {
|
|
7124
|
+
const innerObj = {};
|
|
7125
|
+
nametagsMap.forEach((nametag, index) => {
|
|
7126
|
+
innerObj[index.toString()] = nametag;
|
|
7127
|
+
});
|
|
7128
|
+
result[addressId] = innerObj;
|
|
6584
7129
|
});
|
|
6585
|
-
await this._storage.set(
|
|
7130
|
+
await this._storage.set(STORAGE_KEYS_GLOBAL.ADDRESS_NAMETAGS, JSON.stringify(result));
|
|
6586
7131
|
}
|
|
6587
7132
|
/**
|
|
6588
7133
|
* Mint a nametag token on-chain (like Sphere wallet and lottery)
|
|
@@ -6617,15 +7162,24 @@ var Sphere = class _Sphere {
|
|
|
6617
7162
|
}
|
|
6618
7163
|
/**
|
|
6619
7164
|
* Load address nametags from storage
|
|
7165
|
+
* Supports new format: { "DIRECT://abc...xyz": { "0": "alice" } }
|
|
7166
|
+
* And legacy format: { "0": "alice" } (migrates to new format on save)
|
|
6620
7167
|
*/
|
|
6621
7168
|
async loadAddressNametags() {
|
|
6622
7169
|
try {
|
|
6623
|
-
const saved = await this._storage.get(
|
|
7170
|
+
const saved = await this._storage.get(STORAGE_KEYS_GLOBAL.ADDRESS_NAMETAGS);
|
|
6624
7171
|
if (saved) {
|
|
6625
|
-
const
|
|
7172
|
+
const parsed = JSON.parse(saved);
|
|
6626
7173
|
this._addressNametags.clear();
|
|
6627
|
-
for (const [
|
|
6628
|
-
|
|
7174
|
+
for (const [key, value] of Object.entries(parsed)) {
|
|
7175
|
+
if (typeof value === "object" && value !== null) {
|
|
7176
|
+
const nametagsMap = /* @__PURE__ */ new Map();
|
|
7177
|
+
for (const [indexStr, nametag] of Object.entries(value)) {
|
|
7178
|
+
nametagsMap.set(parseInt(indexStr, 10), nametag);
|
|
7179
|
+
}
|
|
7180
|
+
this._addressNametags.set(key, nametagsMap);
|
|
7181
|
+
} else if (typeof value === "string") {
|
|
7182
|
+
}
|
|
6629
7183
|
}
|
|
6630
7184
|
}
|
|
6631
7185
|
} catch {
|
|
@@ -6644,7 +7198,11 @@ var Sphere = class _Sphere {
|
|
|
6644
7198
|
return;
|
|
6645
7199
|
}
|
|
6646
7200
|
try {
|
|
6647
|
-
const success = await this._transport.registerNametag(
|
|
7201
|
+
const success = await this._transport.registerNametag(
|
|
7202
|
+
nametag,
|
|
7203
|
+
this._identity.chainPubkey,
|
|
7204
|
+
this._identity.directAddress || ""
|
|
7205
|
+
);
|
|
6648
7206
|
if (success) {
|
|
6649
7207
|
console.log(`[Sphere] Nametag @${nametag} synced with Nostr`);
|
|
6650
7208
|
} else {
|
|
@@ -6654,6 +7212,47 @@ var Sphere = class _Sphere {
|
|
|
6654
7212
|
console.warn(`[Sphere] Nametag sync failed:`, error);
|
|
6655
7213
|
}
|
|
6656
7214
|
}
|
|
7215
|
+
/**
|
|
7216
|
+
* Recover nametag from Nostr after wallet import
|
|
7217
|
+
* Searches for encrypted nametag events authored by this wallet's pubkey
|
|
7218
|
+
* and decrypts them to restore the nametag association
|
|
7219
|
+
*/
|
|
7220
|
+
async recoverNametagFromNostr() {
|
|
7221
|
+
if (this._identity?.nametag) {
|
|
7222
|
+
return;
|
|
7223
|
+
}
|
|
7224
|
+
if (!this._transport.recoverNametag) {
|
|
7225
|
+
return;
|
|
7226
|
+
}
|
|
7227
|
+
try {
|
|
7228
|
+
const recoveredNametag = await this._transport.recoverNametag();
|
|
7229
|
+
if (recoveredNametag) {
|
|
7230
|
+
if (this._identity) {
|
|
7231
|
+
this._identity.nametag = recoveredNametag;
|
|
7232
|
+
}
|
|
7233
|
+
const addressId = this.getCurrentAddressId();
|
|
7234
|
+
if (addressId) {
|
|
7235
|
+
let nametagsMap = this._addressNametags.get(addressId);
|
|
7236
|
+
if (!nametagsMap) {
|
|
7237
|
+
nametagsMap = /* @__PURE__ */ new Map();
|
|
7238
|
+
this._addressNametags.set(addressId, nametagsMap);
|
|
7239
|
+
}
|
|
7240
|
+
const nextIndex = nametagsMap.size;
|
|
7241
|
+
nametagsMap.set(nextIndex, recoveredNametag);
|
|
7242
|
+
}
|
|
7243
|
+
await this.persistAddressNametags();
|
|
7244
|
+
if (this._transport.registerNametag) {
|
|
7245
|
+
await this._transport.registerNametag(
|
|
7246
|
+
recoveredNametag,
|
|
7247
|
+
this._identity.chainPubkey,
|
|
7248
|
+
this._identity.directAddress || ""
|
|
7249
|
+
);
|
|
7250
|
+
}
|
|
7251
|
+
this.emitEvent("nametag:recovered", { nametag: recoveredNametag });
|
|
7252
|
+
}
|
|
7253
|
+
} catch {
|
|
7254
|
+
}
|
|
7255
|
+
}
|
|
6657
7256
|
/**
|
|
6658
7257
|
* Validate nametag format
|
|
6659
7258
|
*/
|
|
@@ -6684,22 +7283,22 @@ var Sphere = class _Sphere {
|
|
|
6684
7283
|
// ===========================================================================
|
|
6685
7284
|
async storeMnemonic(mnemonic, derivationPath, basePath) {
|
|
6686
7285
|
const encrypted = this.encrypt(mnemonic);
|
|
6687
|
-
await this._storage.set(
|
|
7286
|
+
await this._storage.set(STORAGE_KEYS_GLOBAL.MNEMONIC, encrypted);
|
|
6688
7287
|
this._mnemonic = mnemonic;
|
|
6689
7288
|
this._source = "mnemonic";
|
|
6690
7289
|
this._derivationMode = "bip32";
|
|
6691
7290
|
if (derivationPath) {
|
|
6692
|
-
await this._storage.set(
|
|
7291
|
+
await this._storage.set(STORAGE_KEYS_GLOBAL.DERIVATION_PATH, derivationPath);
|
|
6693
7292
|
}
|
|
6694
7293
|
const effectiveBasePath = basePath ?? DEFAULT_BASE_PATH;
|
|
6695
7294
|
this._basePath = effectiveBasePath;
|
|
6696
|
-
await this._storage.set(
|
|
6697
|
-
await this._storage.set(
|
|
6698
|
-
await this._storage.set(
|
|
7295
|
+
await this._storage.set(STORAGE_KEYS_GLOBAL.BASE_PATH, effectiveBasePath);
|
|
7296
|
+
await this._storage.set(STORAGE_KEYS_GLOBAL.DERIVATION_MODE, this._derivationMode);
|
|
7297
|
+
await this._storage.set(STORAGE_KEYS_GLOBAL.WALLET_SOURCE, this._source);
|
|
6699
7298
|
}
|
|
6700
7299
|
async storeMasterKey(masterKey, chainCode, derivationPath, basePath, derivationMode) {
|
|
6701
7300
|
const encrypted = this.encrypt(masterKey);
|
|
6702
|
-
await this._storage.set(
|
|
7301
|
+
await this._storage.set(STORAGE_KEYS_GLOBAL.MASTER_KEY, encrypted);
|
|
6703
7302
|
this._source = "file";
|
|
6704
7303
|
this._mnemonic = null;
|
|
6705
7304
|
if (derivationMode) {
|
|
@@ -6708,16 +7307,16 @@ var Sphere = class _Sphere {
|
|
|
6708
7307
|
this._derivationMode = chainCode ? "bip32" : "wif_hmac";
|
|
6709
7308
|
}
|
|
6710
7309
|
if (chainCode) {
|
|
6711
|
-
await this._storage.set(
|
|
7310
|
+
await this._storage.set(STORAGE_KEYS_GLOBAL.CHAIN_CODE, chainCode);
|
|
6712
7311
|
}
|
|
6713
7312
|
if (derivationPath) {
|
|
6714
|
-
await this._storage.set(
|
|
7313
|
+
await this._storage.set(STORAGE_KEYS_GLOBAL.DERIVATION_PATH, derivationPath);
|
|
6715
7314
|
}
|
|
6716
7315
|
const effectiveBasePath = basePath ?? DEFAULT_BASE_PATH;
|
|
6717
7316
|
this._basePath = effectiveBasePath;
|
|
6718
|
-
await this._storage.set(
|
|
6719
|
-
await this._storage.set(
|
|
6720
|
-
await this._storage.set(
|
|
7317
|
+
await this._storage.set(STORAGE_KEYS_GLOBAL.BASE_PATH, effectiveBasePath);
|
|
7318
|
+
await this._storage.set(STORAGE_KEYS_GLOBAL.DERIVATION_MODE, this._derivationMode);
|
|
7319
|
+
await this._storage.set(STORAGE_KEYS_GLOBAL.WALLET_SOURCE, this._source);
|
|
6721
7320
|
}
|
|
6722
7321
|
/**
|
|
6723
7322
|
* Mark wallet as fully created (after successful initialization)
|
|
@@ -6725,20 +7324,20 @@ var Sphere = class _Sphere {
|
|
|
6725
7324
|
* marked as existing after all initialization steps succeed.
|
|
6726
7325
|
*/
|
|
6727
7326
|
async finalizeWalletCreation() {
|
|
6728
|
-
await this._storage.set(
|
|
7327
|
+
await this._storage.set(STORAGE_KEYS_GLOBAL.WALLET_EXISTS, "true");
|
|
6729
7328
|
}
|
|
6730
7329
|
// ===========================================================================
|
|
6731
7330
|
// Private: Identity Initialization
|
|
6732
7331
|
// ===========================================================================
|
|
6733
7332
|
async loadIdentityFromStorage() {
|
|
6734
|
-
const encryptedMnemonic = await this._storage.get(
|
|
6735
|
-
const encryptedMasterKey = await this._storage.get(
|
|
6736
|
-
const chainCode = await this._storage.get(
|
|
6737
|
-
const derivationPath = await this._storage.get(
|
|
6738
|
-
const savedBasePath = await this._storage.get(
|
|
6739
|
-
const savedDerivationMode = await this._storage.get(
|
|
6740
|
-
const savedSource = await this._storage.get(
|
|
6741
|
-
const savedAddressIndex = await this._storage.get(
|
|
7333
|
+
const encryptedMnemonic = await this._storage.get(STORAGE_KEYS_GLOBAL.MNEMONIC);
|
|
7334
|
+
const encryptedMasterKey = await this._storage.get(STORAGE_KEYS_GLOBAL.MASTER_KEY);
|
|
7335
|
+
const chainCode = await this._storage.get(STORAGE_KEYS_GLOBAL.CHAIN_CODE);
|
|
7336
|
+
const derivationPath = await this._storage.get(STORAGE_KEYS_GLOBAL.DERIVATION_PATH);
|
|
7337
|
+
const savedBasePath = await this._storage.get(STORAGE_KEYS_GLOBAL.BASE_PATH);
|
|
7338
|
+
const savedDerivationMode = await this._storage.get(STORAGE_KEYS_GLOBAL.DERIVATION_MODE);
|
|
7339
|
+
const savedSource = await this._storage.get(STORAGE_KEYS_GLOBAL.WALLET_SOURCE);
|
|
7340
|
+
const savedAddressIndex = await this._storage.get(STORAGE_KEYS_GLOBAL.CURRENT_ADDRESS_INDEX);
|
|
6742
7341
|
this._basePath = savedBasePath ?? DEFAULT_BASE_PATH;
|
|
6743
7342
|
this._derivationMode = savedDerivationMode ?? "bip32";
|
|
6744
7343
|
this._source = savedSource ?? "unknown";
|
|
@@ -6772,65 +7371,60 @@ var Sphere = class _Sphere {
|
|
|
6772
7371
|
this._storage.setIdentity(this._identity);
|
|
6773
7372
|
}
|
|
6774
7373
|
await this.loadAddressNametags();
|
|
6775
|
-
const savedNametag = await this._storage.get(STORAGE_KEYS.NAMETAG);
|
|
6776
7374
|
if (this._currentAddressIndex > 0 && this._masterKey) {
|
|
6777
7375
|
const addressInfo = this.deriveAddress(this._currentAddressIndex, false);
|
|
6778
7376
|
const ipnsHash = sha256(addressInfo.publicKey, "hex").slice(0, 40);
|
|
6779
7377
|
const predicateAddress = await deriveL3PredicateAddress(addressInfo.privateKey);
|
|
6780
|
-
const
|
|
7378
|
+
const addressId = getAddressId(predicateAddress);
|
|
7379
|
+
const nametagsMap = this._addressNametags.get(addressId);
|
|
7380
|
+
const nametag = nametagsMap?.get(0);
|
|
6781
7381
|
this._identity = {
|
|
6782
7382
|
privateKey: addressInfo.privateKey,
|
|
6783
|
-
|
|
6784
|
-
|
|
6785
|
-
predicateAddress,
|
|
7383
|
+
chainPubkey: addressInfo.publicKey,
|
|
7384
|
+
l1Address: addressInfo.address,
|
|
7385
|
+
directAddress: predicateAddress,
|
|
6786
7386
|
ipnsName: "12D3KooW" + ipnsHash,
|
|
6787
7387
|
nametag
|
|
6788
7388
|
};
|
|
6789
7389
|
this._storage.setIdentity(this._identity);
|
|
6790
|
-
console.log(`[Sphere] Restored to address ${this._currentAddressIndex}:`, this._identity.
|
|
6791
|
-
} else {
|
|
6792
|
-
|
|
6793
|
-
|
|
6794
|
-
|
|
6795
|
-
|
|
6796
|
-
|
|
6797
|
-
console.log("[Sphere] Restored nametag:", savedNametag);
|
|
6798
|
-
} else if (this._identity) {
|
|
6799
|
-
const nametag = this._addressNametags.get(0);
|
|
6800
|
-
if (nametag) {
|
|
6801
|
-
this._identity.nametag = nametag;
|
|
6802
|
-
console.log("[Sphere] Restored nametag from map:", nametag);
|
|
6803
|
-
}
|
|
7390
|
+
console.log(`[Sphere] Restored to address ${this._currentAddressIndex}:`, this._identity.l1Address);
|
|
7391
|
+
} else if (this._identity) {
|
|
7392
|
+
const addressId = this.getCurrentAddressId();
|
|
7393
|
+
const nametagsMap = addressId ? this._addressNametags.get(addressId) : void 0;
|
|
7394
|
+
const nametag = nametagsMap?.get(0);
|
|
7395
|
+
if (nametag) {
|
|
7396
|
+
this._identity.nametag = nametag;
|
|
6804
7397
|
}
|
|
6805
7398
|
}
|
|
6806
7399
|
}
|
|
6807
7400
|
async initializeIdentityFromMnemonic(mnemonic, derivationPath) {
|
|
6808
|
-
const
|
|
7401
|
+
const basePath = derivationPath ?? DEFAULT_BASE_PATH;
|
|
7402
|
+
const fullPath = `${basePath}/0/0`;
|
|
6809
7403
|
const masterKey = identityFromMnemonicSync(mnemonic);
|
|
6810
7404
|
const derivedKey = deriveKeyAtPath(
|
|
6811
7405
|
masterKey.privateKey,
|
|
6812
7406
|
masterKey.chainCode,
|
|
6813
|
-
|
|
7407
|
+
fullPath
|
|
6814
7408
|
);
|
|
6815
7409
|
const publicKey = getPublicKey(derivedKey.privateKey);
|
|
6816
|
-
const
|
|
7410
|
+
const address = publicKeyToAddress(publicKey, "alpha");
|
|
6817
7411
|
const ipnsHash = sha256(publicKey, "hex").slice(0, 40);
|
|
6818
7412
|
const predicateAddress = await deriveL3PredicateAddress(derivedKey.privateKey);
|
|
6819
7413
|
this._identity = {
|
|
6820
7414
|
privateKey: derivedKey.privateKey,
|
|
6821
|
-
publicKey,
|
|
6822
|
-
|
|
6823
|
-
predicateAddress,
|
|
7415
|
+
chainPubkey: publicKey,
|
|
7416
|
+
l1Address: address,
|
|
7417
|
+
directAddress: predicateAddress,
|
|
6824
7418
|
ipnsName: "12D3KooW" + ipnsHash
|
|
6825
7419
|
};
|
|
6826
7420
|
this._masterKey = masterKey;
|
|
6827
|
-
console.log("[Sphere] Identity initialized from mnemonic, path:", path);
|
|
6828
7421
|
}
|
|
6829
7422
|
async initializeIdentityFromMasterKey(masterKey, chainCode, derivationPath) {
|
|
6830
|
-
const
|
|
7423
|
+
const basePath = derivationPath ?? DEFAULT_BASE_PATH;
|
|
7424
|
+
const fullPath = `${basePath}/0/0`;
|
|
6831
7425
|
let privateKey;
|
|
6832
7426
|
if (chainCode) {
|
|
6833
|
-
const derivedKey = deriveKeyAtPath(masterKey, chainCode,
|
|
7427
|
+
const derivedKey = deriveKeyAtPath(masterKey, chainCode, fullPath);
|
|
6834
7428
|
privateKey = derivedKey.privateKey;
|
|
6835
7429
|
this._masterKey = {
|
|
6836
7430
|
privateKey: masterKey,
|
|
@@ -6841,17 +7435,16 @@ var Sphere = class _Sphere {
|
|
|
6841
7435
|
this._masterKey = null;
|
|
6842
7436
|
}
|
|
6843
7437
|
const publicKey = getPublicKey(privateKey);
|
|
6844
|
-
const
|
|
7438
|
+
const address = publicKeyToAddress(publicKey, "alpha");
|
|
6845
7439
|
const ipnsHash = sha256(publicKey, "hex").slice(0, 40);
|
|
6846
7440
|
const predicateAddress = await deriveL3PredicateAddress(privateKey);
|
|
6847
7441
|
this._identity = {
|
|
6848
7442
|
privateKey,
|
|
6849
|
-
publicKey,
|
|
6850
|
-
|
|
6851
|
-
predicateAddress,
|
|
7443
|
+
chainPubkey: publicKey,
|
|
7444
|
+
l1Address: address,
|
|
7445
|
+
directAddress: predicateAddress,
|
|
6852
7446
|
ipnsName: "12D3KooW" + ipnsHash
|
|
6853
7447
|
};
|
|
6854
|
-
console.log("[Sphere] Identity initialized from master key, path:", path, "chainCode:", !!chainCode);
|
|
6855
7448
|
}
|
|
6856
7449
|
// ===========================================================================
|
|
6857
7450
|
// Private: Provider & Module Initialization
|