@unicitylabs/sphere-sdk 0.1.4 → 0.1.6
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 +90 -8
- package/dist/core/index.cjs +542 -175
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +32 -6
- package/dist/core/index.d.ts +32 -6
- package/dist/core/index.js +542 -175
- package/dist/core/index.js.map +1 -1
- package/dist/impl/browser/index.cjs +141 -122
- package/dist/impl/browser/index.cjs.map +1 -1
- package/dist/impl/browser/index.js +143 -122
- package/dist/impl/browser/index.js.map +1 -1
- package/dist/impl/browser/ipfs.cjs +28 -33
- package/dist/impl/browser/ipfs.cjs.map +1 -1
- package/dist/impl/browser/ipfs.js +28 -33
- package/dist/impl/browser/ipfs.js.map +1 -1
- package/dist/impl/nodejs/index.cjs +160 -123
- package/dist/impl/nodejs/index.cjs.map +1 -1
- package/dist/impl/nodejs/index.d.cts +11 -2
- package/dist/impl/nodejs/index.d.ts +11 -2
- package/dist/impl/nodejs/index.js +160 -123
- package/dist/impl/nodejs/index.js.map +1 -1
- package/dist/index.cjs +584 -174
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +788 -218
- package/dist/index.d.ts +788 -218
- package/dist/index.js +575 -174
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/core/index.js
CHANGED
|
@@ -2153,50 +2153,56 @@ var NametagMinter = class {
|
|
|
2153
2153
|
};
|
|
2154
2154
|
|
|
2155
2155
|
// constants.ts
|
|
2156
|
-
var STORAGE_PREFIX = "sphere_";
|
|
2157
2156
|
var DEFAULT_ENCRYPTION_KEY = "sphere-default-key";
|
|
2158
|
-
var
|
|
2157
|
+
var STORAGE_KEYS_GLOBAL = {
|
|
2159
2158
|
/** Encrypted BIP39 mnemonic */
|
|
2160
|
-
MNEMONIC:
|
|
2159
|
+
MNEMONIC: "mnemonic",
|
|
2161
2160
|
/** Encrypted master private key */
|
|
2162
|
-
MASTER_KEY:
|
|
2161
|
+
MASTER_KEY: "master_key",
|
|
2163
2162
|
/** BIP32 chain code */
|
|
2164
|
-
CHAIN_CODE:
|
|
2163
|
+
CHAIN_CODE: "chain_code",
|
|
2165
2164
|
/** HD derivation path (full path like m/44'/0'/0'/0/0) */
|
|
2166
|
-
DERIVATION_PATH:
|
|
2165
|
+
DERIVATION_PATH: "derivation_path",
|
|
2167
2166
|
/** Base derivation path (like m/44'/0'/0' without chain/index) */
|
|
2168
|
-
BASE_PATH:
|
|
2167
|
+
BASE_PATH: "base_path",
|
|
2169
2168
|
/** Derivation mode: bip32, wif_hmac, legacy_hmac */
|
|
2170
|
-
DERIVATION_MODE:
|
|
2169
|
+
DERIVATION_MODE: "derivation_mode",
|
|
2171
2170
|
/** Wallet source: mnemonic, file, unknown */
|
|
2172
|
-
WALLET_SOURCE:
|
|
2171
|
+
WALLET_SOURCE: "wallet_source",
|
|
2173
2172
|
/** Wallet existence flag */
|
|
2174
|
-
WALLET_EXISTS:
|
|
2175
|
-
/** Registered nametag (legacy - single address) */
|
|
2176
|
-
NAMETAG: `${STORAGE_PREFIX}nametag`,
|
|
2173
|
+
WALLET_EXISTS: "wallet_exists",
|
|
2177
2174
|
/** Current active address index */
|
|
2178
|
-
CURRENT_ADDRESS_INDEX:
|
|
2179
|
-
/**
|
|
2180
|
-
ADDRESS_NAMETAGS:
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
/** Pending transfers */
|
|
2184
|
-
PENDING_TRANSFERS:
|
|
2185
|
-
/** Transfer outbox */
|
|
2186
|
-
OUTBOX:
|
|
2187
|
-
/** Conversations */
|
|
2188
|
-
CONVERSATIONS:
|
|
2189
|
-
/** Messages */
|
|
2190
|
-
MESSAGES:
|
|
2191
|
-
/** Transaction history */
|
|
2192
|
-
TRANSACTION_HISTORY:
|
|
2193
|
-
/** Archived tokens (spent token history) */
|
|
2194
|
-
ARCHIVED_TOKENS: `${STORAGE_PREFIX}archived_tokens`,
|
|
2195
|
-
/** Tombstones (records of deleted/spent tokens) */
|
|
2196
|
-
TOMBSTONES: `${STORAGE_PREFIX}tombstones`,
|
|
2197
|
-
/** Forked tokens (alternative histories) */
|
|
2198
|
-
FORKED_TOKENS: `${STORAGE_PREFIX}forked_tokens`
|
|
2175
|
+
CURRENT_ADDRESS_INDEX: "current_address_index",
|
|
2176
|
+
/** Index of address nametags (JSON: { "0": "alice", "1": "bob" }) - for discovery */
|
|
2177
|
+
ADDRESS_NAMETAGS: "address_nametags"
|
|
2178
|
+
};
|
|
2179
|
+
var STORAGE_KEYS_ADDRESS = {
|
|
2180
|
+
/** Pending transfers for this address */
|
|
2181
|
+
PENDING_TRANSFERS: "pending_transfers",
|
|
2182
|
+
/** Transfer outbox for this address */
|
|
2183
|
+
OUTBOX: "outbox",
|
|
2184
|
+
/** Conversations for this address */
|
|
2185
|
+
CONVERSATIONS: "conversations",
|
|
2186
|
+
/** Messages for this address */
|
|
2187
|
+
MESSAGES: "messages",
|
|
2188
|
+
/** Transaction history for this address */
|
|
2189
|
+
TRANSACTION_HISTORY: "transaction_history"
|
|
2199
2190
|
};
|
|
2191
|
+
var STORAGE_KEYS = {
|
|
2192
|
+
...STORAGE_KEYS_GLOBAL,
|
|
2193
|
+
...STORAGE_KEYS_ADDRESS
|
|
2194
|
+
};
|
|
2195
|
+
function getAddressId(directAddress) {
|
|
2196
|
+
let hash = directAddress;
|
|
2197
|
+
if (hash.startsWith("DIRECT://")) {
|
|
2198
|
+
hash = hash.slice(9);
|
|
2199
|
+
} else if (hash.startsWith("DIRECT:")) {
|
|
2200
|
+
hash = hash.slice(7);
|
|
2201
|
+
}
|
|
2202
|
+
const first = hash.slice(0, 6).toLowerCase();
|
|
2203
|
+
const last = hash.slice(-6).toLowerCase();
|
|
2204
|
+
return `DIRECT_${first}_${last}`;
|
|
2205
|
+
}
|
|
2200
2206
|
var DEFAULT_BASE_PATH = "m/44'/0'/0'";
|
|
2201
2207
|
var DEFAULT_DERIVATION_PATH2 = `${DEFAULT_BASE_PATH}/0/0`;
|
|
2202
2208
|
var LIMITS = {
|
|
@@ -2365,6 +2371,7 @@ function txfToToken(tokenId, txf) {
|
|
|
2365
2371
|
coinId,
|
|
2366
2372
|
symbol: isNft ? "NFT" : "UCT",
|
|
2367
2373
|
name: isNft ? "NFT" : "Token",
|
|
2374
|
+
decimals: isNft ? 0 : 8,
|
|
2368
2375
|
amount: totalAmount.toString(),
|
|
2369
2376
|
status: determineTokenStatus(txf),
|
|
2370
2377
|
createdAt: now,
|
|
@@ -2379,9 +2386,6 @@ async function buildTxfStorageData(tokens, meta, options) {
|
|
|
2379
2386
|
formatVersion: "2.0"
|
|
2380
2387
|
}
|
|
2381
2388
|
};
|
|
2382
|
-
if (options?.nametag) {
|
|
2383
|
-
storageData._nametag = options.nametag;
|
|
2384
|
-
}
|
|
2385
2389
|
if (options?.tombstones && options.tombstones.length > 0) {
|
|
2386
2390
|
storageData._tombstones = options.tombstones;
|
|
2387
2391
|
}
|
|
@@ -2521,6 +2525,300 @@ function getCurrentStateHash(txf) {
|
|
|
2521
2525
|
return void 0;
|
|
2522
2526
|
}
|
|
2523
2527
|
|
|
2528
|
+
// registry/token-registry.testnet.json
|
|
2529
|
+
var token_registry_testnet_default = [
|
|
2530
|
+
{
|
|
2531
|
+
network: "unicity:testnet",
|
|
2532
|
+
assetKind: "non-fungible",
|
|
2533
|
+
name: "unicity",
|
|
2534
|
+
description: "Unicity testnet token type",
|
|
2535
|
+
id: "f8aa13834268d29355ff12183066f0cb902003629bbc5eb9ef0efbe397867509"
|
|
2536
|
+
},
|
|
2537
|
+
{
|
|
2538
|
+
network: "unicity:testnet",
|
|
2539
|
+
assetKind: "fungible",
|
|
2540
|
+
name: "unicity",
|
|
2541
|
+
symbol: "UCT",
|
|
2542
|
+
decimals: 18,
|
|
2543
|
+
description: "Unicity testnet native coin",
|
|
2544
|
+
icons: [
|
|
2545
|
+
{ url: "https://raw.githubusercontent.com/unicitynetwork/unicity-ids/refs/heads/main/unicity_logo_32.png" }
|
|
2546
|
+
],
|
|
2547
|
+
id: "455ad8720656b08e8dbd5bac1f3c73eeea5431565f6c1c3af742b1aa12d41d89"
|
|
2548
|
+
},
|
|
2549
|
+
{
|
|
2550
|
+
network: "unicity:testnet",
|
|
2551
|
+
assetKind: "fungible",
|
|
2552
|
+
name: "unicity-usd",
|
|
2553
|
+
symbol: "USDU",
|
|
2554
|
+
decimals: 6,
|
|
2555
|
+
description: "Unicity testnet USD stablecoin",
|
|
2556
|
+
icons: [
|
|
2557
|
+
{ url: "https://raw.githubusercontent.com/unicitynetwork/unicity-ids/refs/heads/main/usdu_logo_32.png" }
|
|
2558
|
+
],
|
|
2559
|
+
id: "8f0f3d7a5e7297be0ee98c63b81bcebb2740f43f616566fc290f9823a54f52d7"
|
|
2560
|
+
},
|
|
2561
|
+
{
|
|
2562
|
+
network: "unicity:testnet",
|
|
2563
|
+
assetKind: "fungible",
|
|
2564
|
+
name: "unicity-eur",
|
|
2565
|
+
symbol: "EURU",
|
|
2566
|
+
decimals: 6,
|
|
2567
|
+
description: "Unicity testnet EUR stablecoin",
|
|
2568
|
+
icons: [
|
|
2569
|
+
{ url: "https://raw.githubusercontent.com/unicitynetwork/unicity-ids/refs/heads/main/euru_logo_32.png" }
|
|
2570
|
+
],
|
|
2571
|
+
id: "5e160d5e9fdbb03b553fb9c3f6e6c30efa41fa807be39fb4f18e43776e492925"
|
|
2572
|
+
},
|
|
2573
|
+
{
|
|
2574
|
+
network: "unicity:testnet",
|
|
2575
|
+
assetKind: "fungible",
|
|
2576
|
+
name: "solana",
|
|
2577
|
+
symbol: "SOL",
|
|
2578
|
+
decimals: 9,
|
|
2579
|
+
description: "Solana testnet coin on Unicity",
|
|
2580
|
+
icons: [
|
|
2581
|
+
{ url: "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/svg/icon/sol.svg" },
|
|
2582
|
+
{ url: "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/32/icon/sol.png" }
|
|
2583
|
+
],
|
|
2584
|
+
id: "dee5f8ce778562eec90e9c38a91296a023210ccc76ff4c29d527ac3eb64ade93"
|
|
2585
|
+
},
|
|
2586
|
+
{
|
|
2587
|
+
network: "unicity:testnet",
|
|
2588
|
+
assetKind: "fungible",
|
|
2589
|
+
name: "bitcoin",
|
|
2590
|
+
symbol: "BTC",
|
|
2591
|
+
decimals: 8,
|
|
2592
|
+
description: "Bitcoin testnet coin on Unicity",
|
|
2593
|
+
icons: [
|
|
2594
|
+
{ url: "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/svg/icon/btc.svg" },
|
|
2595
|
+
{ url: "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/32/icon/btc.png" }
|
|
2596
|
+
],
|
|
2597
|
+
id: "86bc190fcf7b2d07c6078de93db803578760148b16d4431aa2f42a3241ff0daa"
|
|
2598
|
+
},
|
|
2599
|
+
{
|
|
2600
|
+
network: "unicity:testnet",
|
|
2601
|
+
assetKind: "fungible",
|
|
2602
|
+
name: "ethereum",
|
|
2603
|
+
symbol: "ETH",
|
|
2604
|
+
decimals: 18,
|
|
2605
|
+
description: "Ethereum testnet coin on Unicity",
|
|
2606
|
+
icons: [
|
|
2607
|
+
{ url: "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/svg/icon/eth.svg" },
|
|
2608
|
+
{ url: "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/32/icon/eth.png" }
|
|
2609
|
+
],
|
|
2610
|
+
id: "3c2450f2fd867e7bb60c6a69d7ad0e53ce967078c201a3ecaa6074ed4c0deafb"
|
|
2611
|
+
},
|
|
2612
|
+
{
|
|
2613
|
+
network: "unicity:testnet",
|
|
2614
|
+
assetKind: "fungible",
|
|
2615
|
+
name: "alpha_test",
|
|
2616
|
+
symbol: "ALPHT",
|
|
2617
|
+
decimals: 8,
|
|
2618
|
+
description: "ALPHA testnet coin on Unicity",
|
|
2619
|
+
icons: [
|
|
2620
|
+
{ url: "https://raw.githubusercontent.com/unicitynetwork/unicity-ids/refs/heads/main/alpha_coin.png" }
|
|
2621
|
+
],
|
|
2622
|
+
id: "cde78ded16ef65818a51f43138031c4284e519300ab0cb60c30a8f9078080e5f"
|
|
2623
|
+
},
|
|
2624
|
+
{
|
|
2625
|
+
network: "unicity:testnet",
|
|
2626
|
+
assetKind: "fungible",
|
|
2627
|
+
name: "tether",
|
|
2628
|
+
symbol: "USDT",
|
|
2629
|
+
decimals: 6,
|
|
2630
|
+
description: "Tether (Ethereum) testnet coin on Unicity",
|
|
2631
|
+
icons: [
|
|
2632
|
+
{ url: "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/svg/icon/usdt.svg" },
|
|
2633
|
+
{ url: "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/32/icon/usdt.png" }
|
|
2634
|
+
],
|
|
2635
|
+
id: "40d25444648418fe7efd433e147187a3a6adf049ac62bc46038bda5b960bf690"
|
|
2636
|
+
},
|
|
2637
|
+
{
|
|
2638
|
+
network: "unicity:testnet",
|
|
2639
|
+
assetKind: "fungible",
|
|
2640
|
+
name: "usd-coin",
|
|
2641
|
+
symbol: "USDC",
|
|
2642
|
+
decimals: 6,
|
|
2643
|
+
description: "USDC (Ethereum) testnet coin on Unicity",
|
|
2644
|
+
icons: [
|
|
2645
|
+
{ url: "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/svg/icon/usdc.svg" },
|
|
2646
|
+
{ url: "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/32/icon/usdc.png" }
|
|
2647
|
+
],
|
|
2648
|
+
id: "2265121770fa6f41131dd9a6cc571e28679263d09a53eb2642e145b5b9a5b0a2"
|
|
2649
|
+
}
|
|
2650
|
+
];
|
|
2651
|
+
|
|
2652
|
+
// registry/TokenRegistry.ts
|
|
2653
|
+
var TokenRegistry = class _TokenRegistry {
|
|
2654
|
+
static instance = null;
|
|
2655
|
+
definitionsById;
|
|
2656
|
+
definitionsBySymbol;
|
|
2657
|
+
definitionsByName;
|
|
2658
|
+
constructor() {
|
|
2659
|
+
this.definitionsById = /* @__PURE__ */ new Map();
|
|
2660
|
+
this.definitionsBySymbol = /* @__PURE__ */ new Map();
|
|
2661
|
+
this.definitionsByName = /* @__PURE__ */ new Map();
|
|
2662
|
+
this.loadRegistry();
|
|
2663
|
+
}
|
|
2664
|
+
/**
|
|
2665
|
+
* Get singleton instance of TokenRegistry
|
|
2666
|
+
*/
|
|
2667
|
+
static getInstance() {
|
|
2668
|
+
if (!_TokenRegistry.instance) {
|
|
2669
|
+
_TokenRegistry.instance = new _TokenRegistry();
|
|
2670
|
+
}
|
|
2671
|
+
return _TokenRegistry.instance;
|
|
2672
|
+
}
|
|
2673
|
+
/**
|
|
2674
|
+
* Reset the singleton instance (useful for testing)
|
|
2675
|
+
*/
|
|
2676
|
+
static resetInstance() {
|
|
2677
|
+
_TokenRegistry.instance = null;
|
|
2678
|
+
}
|
|
2679
|
+
/**
|
|
2680
|
+
* Load registry data from bundled JSON
|
|
2681
|
+
*/
|
|
2682
|
+
loadRegistry() {
|
|
2683
|
+
const definitions = token_registry_testnet_default;
|
|
2684
|
+
for (const def of definitions) {
|
|
2685
|
+
const idLower = def.id.toLowerCase();
|
|
2686
|
+
this.definitionsById.set(idLower, def);
|
|
2687
|
+
if (def.symbol) {
|
|
2688
|
+
this.definitionsBySymbol.set(def.symbol.toUpperCase(), def);
|
|
2689
|
+
}
|
|
2690
|
+
this.definitionsByName.set(def.name.toLowerCase(), def);
|
|
2691
|
+
}
|
|
2692
|
+
}
|
|
2693
|
+
// ===========================================================================
|
|
2694
|
+
// Lookup Methods
|
|
2695
|
+
// ===========================================================================
|
|
2696
|
+
/**
|
|
2697
|
+
* Get token definition by hex coin ID
|
|
2698
|
+
* @param coinId - 64-character hex string
|
|
2699
|
+
* @returns Token definition or undefined if not found
|
|
2700
|
+
*/
|
|
2701
|
+
getDefinition(coinId) {
|
|
2702
|
+
if (!coinId) return void 0;
|
|
2703
|
+
return this.definitionsById.get(coinId.toLowerCase());
|
|
2704
|
+
}
|
|
2705
|
+
/**
|
|
2706
|
+
* Get token definition by symbol (e.g., "UCT", "BTC")
|
|
2707
|
+
* @param symbol - Token symbol (case-insensitive)
|
|
2708
|
+
* @returns Token definition or undefined if not found
|
|
2709
|
+
*/
|
|
2710
|
+
getDefinitionBySymbol(symbol) {
|
|
2711
|
+
if (!symbol) return void 0;
|
|
2712
|
+
return this.definitionsBySymbol.get(symbol.toUpperCase());
|
|
2713
|
+
}
|
|
2714
|
+
/**
|
|
2715
|
+
* Get token definition by name (e.g., "bitcoin", "ethereum")
|
|
2716
|
+
* @param name - Token name (case-insensitive)
|
|
2717
|
+
* @returns Token definition or undefined if not found
|
|
2718
|
+
*/
|
|
2719
|
+
getDefinitionByName(name) {
|
|
2720
|
+
if (!name) return void 0;
|
|
2721
|
+
return this.definitionsByName.get(name.toLowerCase());
|
|
2722
|
+
}
|
|
2723
|
+
/**
|
|
2724
|
+
* Get token symbol for a coin ID
|
|
2725
|
+
* @param coinId - 64-character hex string
|
|
2726
|
+
* @returns Symbol (e.g., "UCT") or truncated ID if not found
|
|
2727
|
+
*/
|
|
2728
|
+
getSymbol(coinId) {
|
|
2729
|
+
const def = this.getDefinition(coinId);
|
|
2730
|
+
if (def?.symbol) {
|
|
2731
|
+
return def.symbol;
|
|
2732
|
+
}
|
|
2733
|
+
return coinId.slice(0, 6).toUpperCase();
|
|
2734
|
+
}
|
|
2735
|
+
/**
|
|
2736
|
+
* Get token name for a coin ID
|
|
2737
|
+
* @param coinId - 64-character hex string
|
|
2738
|
+
* @returns Name (e.g., "Bitcoin") or coin ID if not found
|
|
2739
|
+
*/
|
|
2740
|
+
getName(coinId) {
|
|
2741
|
+
const def = this.getDefinition(coinId);
|
|
2742
|
+
if (def?.name) {
|
|
2743
|
+
return def.name.charAt(0).toUpperCase() + def.name.slice(1);
|
|
2744
|
+
}
|
|
2745
|
+
return coinId;
|
|
2746
|
+
}
|
|
2747
|
+
/**
|
|
2748
|
+
* Get decimal places for a coin ID
|
|
2749
|
+
* @param coinId - 64-character hex string
|
|
2750
|
+
* @returns Decimals or 0 if not found
|
|
2751
|
+
*/
|
|
2752
|
+
getDecimals(coinId) {
|
|
2753
|
+
const def = this.getDefinition(coinId);
|
|
2754
|
+
return def?.decimals ?? 0;
|
|
2755
|
+
}
|
|
2756
|
+
/**
|
|
2757
|
+
* Get icon URL for a coin ID
|
|
2758
|
+
* @param coinId - 64-character hex string
|
|
2759
|
+
* @param preferPng - Prefer PNG format over SVG
|
|
2760
|
+
* @returns Icon URL or null if not found
|
|
2761
|
+
*/
|
|
2762
|
+
getIconUrl(coinId, preferPng = true) {
|
|
2763
|
+
const def = this.getDefinition(coinId);
|
|
2764
|
+
if (!def?.icons || def.icons.length === 0) {
|
|
2765
|
+
return null;
|
|
2766
|
+
}
|
|
2767
|
+
if (preferPng) {
|
|
2768
|
+
const pngIcon = def.icons.find((i) => i.url.toLowerCase().includes(".png"));
|
|
2769
|
+
if (pngIcon) return pngIcon.url;
|
|
2770
|
+
}
|
|
2771
|
+
return def.icons[0].url;
|
|
2772
|
+
}
|
|
2773
|
+
/**
|
|
2774
|
+
* Check if a coin ID is known in the registry
|
|
2775
|
+
* @param coinId - 64-character hex string
|
|
2776
|
+
* @returns true if the coin is in the registry
|
|
2777
|
+
*/
|
|
2778
|
+
isKnown(coinId) {
|
|
2779
|
+
return this.definitionsById.has(coinId.toLowerCase());
|
|
2780
|
+
}
|
|
2781
|
+
/**
|
|
2782
|
+
* Get all token definitions
|
|
2783
|
+
* @returns Array of all token definitions
|
|
2784
|
+
*/
|
|
2785
|
+
getAllDefinitions() {
|
|
2786
|
+
return Array.from(this.definitionsById.values());
|
|
2787
|
+
}
|
|
2788
|
+
/**
|
|
2789
|
+
* Get all fungible token definitions
|
|
2790
|
+
* @returns Array of fungible token definitions
|
|
2791
|
+
*/
|
|
2792
|
+
getFungibleTokens() {
|
|
2793
|
+
return this.getAllDefinitions().filter((def) => def.assetKind === "fungible");
|
|
2794
|
+
}
|
|
2795
|
+
/**
|
|
2796
|
+
* Get all non-fungible token definitions
|
|
2797
|
+
* @returns Array of non-fungible token definitions
|
|
2798
|
+
*/
|
|
2799
|
+
getNonFungibleTokens() {
|
|
2800
|
+
return this.getAllDefinitions().filter((def) => def.assetKind === "non-fungible");
|
|
2801
|
+
}
|
|
2802
|
+
/**
|
|
2803
|
+
* Get coin ID by symbol
|
|
2804
|
+
* @param symbol - Token symbol (e.g., "UCT")
|
|
2805
|
+
* @returns Coin ID hex string or undefined if not found
|
|
2806
|
+
*/
|
|
2807
|
+
getCoinIdBySymbol(symbol) {
|
|
2808
|
+
const def = this.getDefinitionBySymbol(symbol);
|
|
2809
|
+
return def?.id;
|
|
2810
|
+
}
|
|
2811
|
+
/**
|
|
2812
|
+
* Get coin ID by name
|
|
2813
|
+
* @param name - Token name (e.g., "bitcoin")
|
|
2814
|
+
* @returns Coin ID hex string or undefined if not found
|
|
2815
|
+
*/
|
|
2816
|
+
getCoinIdByName(name) {
|
|
2817
|
+
const def = this.getDefinitionByName(name);
|
|
2818
|
+
return def?.id;
|
|
2819
|
+
}
|
|
2820
|
+
};
|
|
2821
|
+
|
|
2524
2822
|
// modules/payments/PaymentsModule.ts
|
|
2525
2823
|
import { Token as SdkToken2 } from "@unicitylabs/state-transition-sdk/lib/token/Token";
|
|
2526
2824
|
import { CoinId as CoinId3 } from "@unicitylabs/state-transition-sdk/lib/token/fungible/CoinId";
|
|
@@ -2531,11 +2829,26 @@ import { AddressScheme } from "@unicitylabs/state-transition-sdk/lib/address/Add
|
|
|
2531
2829
|
import { UnmaskedPredicate as UnmaskedPredicate3 } from "@unicitylabs/state-transition-sdk/lib/predicate/embedded/UnmaskedPredicate";
|
|
2532
2830
|
import { TokenState as TokenState3 } from "@unicitylabs/state-transition-sdk/lib/token/TokenState";
|
|
2533
2831
|
import { HashAlgorithm as HashAlgorithm3 } from "@unicitylabs/state-transition-sdk/lib/hash/HashAlgorithm";
|
|
2832
|
+
function enrichWithRegistry(info) {
|
|
2833
|
+
const registry = TokenRegistry.getInstance();
|
|
2834
|
+
const def = registry.getDefinition(info.coinId);
|
|
2835
|
+
if (def) {
|
|
2836
|
+
return {
|
|
2837
|
+
...info,
|
|
2838
|
+
symbol: def.symbol || info.symbol,
|
|
2839
|
+
name: def.name.charAt(0).toUpperCase() + def.name.slice(1),
|
|
2840
|
+
decimals: def.decimals ?? 0,
|
|
2841
|
+
iconUrl: registry.getIconUrl(info.coinId) ?? void 0
|
|
2842
|
+
};
|
|
2843
|
+
}
|
|
2844
|
+
return info;
|
|
2845
|
+
}
|
|
2534
2846
|
async function parseTokenInfo(tokenData) {
|
|
2535
2847
|
const defaultInfo = {
|
|
2536
2848
|
coinId: "ALPHA",
|
|
2537
2849
|
symbol: "ALPHA",
|
|
2538
2850
|
name: "Alpha Token",
|
|
2851
|
+
decimals: 0,
|
|
2539
2852
|
amount: "0"
|
|
2540
2853
|
};
|
|
2541
2854
|
try {
|
|
@@ -2556,23 +2869,25 @@ async function parseTokenInfo(tokenData) {
|
|
|
2556
2869
|
}
|
|
2557
2870
|
if (coinIdObj instanceof CoinId3) {
|
|
2558
2871
|
const coinIdHex = coinIdObj.toJSON();
|
|
2559
|
-
return {
|
|
2872
|
+
return enrichWithRegistry({
|
|
2560
2873
|
coinId: coinIdHex,
|
|
2561
2874
|
symbol: coinIdHex.slice(0, 8),
|
|
2562
2875
|
name: `Token ${coinIdHex.slice(0, 8)}`,
|
|
2876
|
+
decimals: 0,
|
|
2563
2877
|
amount: String(amount ?? "0"),
|
|
2564
2878
|
tokenId: defaultInfo.tokenId
|
|
2565
|
-
};
|
|
2879
|
+
});
|
|
2566
2880
|
} else if (coinIdObj && typeof coinIdObj === "object" && "bytes" in coinIdObj) {
|
|
2567
2881
|
const bytes = coinIdObj.bytes;
|
|
2568
2882
|
const coinIdHex = Buffer.isBuffer(bytes) ? bytes.toString("hex") : Array.isArray(bytes) ? Buffer.from(bytes).toString("hex") : String(bytes);
|
|
2569
|
-
return {
|
|
2883
|
+
return enrichWithRegistry({
|
|
2570
2884
|
coinId: coinIdHex,
|
|
2571
2885
|
symbol: coinIdHex.slice(0, 8),
|
|
2572
2886
|
name: `Token ${coinIdHex.slice(0, 8)}`,
|
|
2887
|
+
decimals: 0,
|
|
2573
2888
|
amount: String(amount ?? "0"),
|
|
2574
2889
|
tokenId: defaultInfo.tokenId
|
|
2575
|
-
};
|
|
2890
|
+
});
|
|
2576
2891
|
}
|
|
2577
2892
|
}
|
|
2578
2893
|
}
|
|
@@ -2587,13 +2902,14 @@ async function parseTokenInfo(tokenData) {
|
|
|
2587
2902
|
if (Array.isArray(firstEntry) && firstEntry.length === 2) {
|
|
2588
2903
|
const [coinIdHex, amount] = firstEntry;
|
|
2589
2904
|
const coinIdStr = typeof coinIdHex === "string" ? coinIdHex : String(coinIdHex);
|
|
2590
|
-
return {
|
|
2905
|
+
return enrichWithRegistry({
|
|
2591
2906
|
coinId: coinIdStr,
|
|
2592
2907
|
symbol: coinIdStr.slice(0, 8),
|
|
2593
2908
|
name: `Token ${coinIdStr.slice(0, 8)}`,
|
|
2909
|
+
decimals: 0,
|
|
2594
2910
|
amount: String(amount),
|
|
2595
2911
|
tokenId: defaultInfo.tokenId
|
|
2596
|
-
};
|
|
2912
|
+
});
|
|
2597
2913
|
}
|
|
2598
2914
|
}
|
|
2599
2915
|
}
|
|
@@ -2608,25 +2924,27 @@ async function parseTokenInfo(tokenData) {
|
|
|
2608
2924
|
const firstEntry = coinData[0];
|
|
2609
2925
|
if (Array.isArray(firstEntry) && firstEntry.length === 2) {
|
|
2610
2926
|
const [coinIdHex, amount] = firstEntry;
|
|
2611
|
-
return {
|
|
2927
|
+
return enrichWithRegistry({
|
|
2612
2928
|
coinId: String(coinIdHex),
|
|
2613
2929
|
symbol: String(coinIdHex).slice(0, 8),
|
|
2614
2930
|
name: `Token ${String(coinIdHex).slice(0, 8)}`,
|
|
2931
|
+
decimals: 0,
|
|
2615
2932
|
amount: String(amount),
|
|
2616
2933
|
tokenId: genesis.tokenId
|
|
2617
|
-
};
|
|
2934
|
+
});
|
|
2618
2935
|
}
|
|
2619
2936
|
} else if (typeof coinData === "object") {
|
|
2620
2937
|
const coinEntries = Object.entries(coinData);
|
|
2621
2938
|
if (coinEntries.length > 0) {
|
|
2622
2939
|
const [coinId, amount] = coinEntries[0];
|
|
2623
|
-
return {
|
|
2940
|
+
return enrichWithRegistry({
|
|
2624
2941
|
coinId,
|
|
2625
2942
|
symbol: coinId.slice(0, 8),
|
|
2626
2943
|
name: `Token ${coinId.slice(0, 8)}`,
|
|
2944
|
+
decimals: 0,
|
|
2627
2945
|
amount: String(amount),
|
|
2628
2946
|
tokenId: genesis.tokenId
|
|
2629
|
-
};
|
|
2947
|
+
});
|
|
2630
2948
|
}
|
|
2631
2949
|
}
|
|
2632
2950
|
}
|
|
@@ -2640,25 +2958,27 @@ async function parseTokenInfo(tokenData) {
|
|
|
2640
2958
|
const firstEntry = coinData[0];
|
|
2641
2959
|
if (Array.isArray(firstEntry) && firstEntry.length === 2) {
|
|
2642
2960
|
const [coinIdHex, amount] = firstEntry;
|
|
2643
|
-
return {
|
|
2961
|
+
return enrichWithRegistry({
|
|
2644
2962
|
coinId: String(coinIdHex),
|
|
2645
2963
|
symbol: String(coinIdHex).slice(0, 8),
|
|
2646
2964
|
name: `Token ${String(coinIdHex).slice(0, 8)}`,
|
|
2965
|
+
decimals: 0,
|
|
2647
2966
|
amount: String(amount),
|
|
2648
2967
|
tokenId: defaultInfo.tokenId
|
|
2649
|
-
};
|
|
2968
|
+
});
|
|
2650
2969
|
}
|
|
2651
2970
|
} else if (typeof coinData === "object") {
|
|
2652
2971
|
const coinEntries = Object.entries(coinData);
|
|
2653
2972
|
if (coinEntries.length > 0) {
|
|
2654
2973
|
const [coinId, amount] = coinEntries[0];
|
|
2655
|
-
return {
|
|
2974
|
+
return enrichWithRegistry({
|
|
2656
2975
|
coinId,
|
|
2657
2976
|
symbol: coinId.slice(0, 8),
|
|
2658
2977
|
name: `Token ${coinId.slice(0, 8)}`,
|
|
2978
|
+
decimals: 0,
|
|
2659
2979
|
amount: String(amount),
|
|
2660
2980
|
tokenId: defaultInfo.tokenId
|
|
2661
|
-
};
|
|
2981
|
+
});
|
|
2662
2982
|
}
|
|
2663
2983
|
}
|
|
2664
2984
|
}
|
|
@@ -2840,37 +3160,24 @@ var PaymentsModule = class {
|
|
|
2840
3160
|
*/
|
|
2841
3161
|
async load() {
|
|
2842
3162
|
this.ensureInitialized();
|
|
2843
|
-
const
|
|
2844
|
-
|
|
3163
|
+
const providers = this.getTokenStorageProviders();
|
|
3164
|
+
for (const [id, provider] of providers) {
|
|
2845
3165
|
try {
|
|
2846
|
-
const
|
|
2847
|
-
|
|
2848
|
-
|
|
2849
|
-
|
|
2850
|
-
|
|
2851
|
-
}
|
|
2852
|
-
if (Array.isArray(parsed.tombstones)) {
|
|
2853
|
-
this.tombstones = parsed.tombstones.filter(
|
|
2854
|
-
(t) => typeof t === "object" && t !== null && typeof t.tokenId === "string" && typeof t.stateHash === "string"
|
|
2855
|
-
);
|
|
2856
|
-
}
|
|
2857
|
-
if (parsed.archivedTokens && typeof parsed.archivedTokens === "object") {
|
|
2858
|
-
this.archivedTokens = new Map(Object.entries(parsed.archivedTokens));
|
|
2859
|
-
}
|
|
2860
|
-
if (parsed.forkedTokens && typeof parsed.forkedTokens === "object") {
|
|
2861
|
-
this.forkedTokens = new Map(Object.entries(parsed.forkedTokens));
|
|
2862
|
-
}
|
|
2863
|
-
if (parsed.nametag) {
|
|
2864
|
-
this.nametag = parsed.nametag;
|
|
3166
|
+
const result = await provider.load();
|
|
3167
|
+
if (result.success && result.data) {
|
|
3168
|
+
this.loadFromStorageData(result.data);
|
|
3169
|
+
this.log(`Loaded from provider ${id}: ${this.tokens.size} tokens`);
|
|
3170
|
+
break;
|
|
2865
3171
|
}
|
|
2866
|
-
this.log(`Loaded ${this.tokens.size} tokens, ${this.tombstones.length} tombstones, ${this.archivedTokens.size} archived`);
|
|
2867
3172
|
} catch (err) {
|
|
2868
|
-
console.error(
|
|
3173
|
+
console.error(`[Payments] Failed to load from provider ${id}:`, err);
|
|
2869
3174
|
}
|
|
2870
3175
|
}
|
|
2871
|
-
|
|
3176
|
+
if (this.tokens.size === 0) {
|
|
3177
|
+
await this.loadTokensFromFileStorage();
|
|
3178
|
+
}
|
|
2872
3179
|
await this.loadNametagFromFileStorage();
|
|
2873
|
-
const historyData = await this.deps.storage.get(
|
|
3180
|
+
const historyData = await this.deps.storage.get(STORAGE_KEYS_ADDRESS.TRANSACTION_HISTORY);
|
|
2874
3181
|
if (historyData) {
|
|
2875
3182
|
try {
|
|
2876
3183
|
this.transactionHistory = JSON.parse(historyData);
|
|
@@ -2878,7 +3185,7 @@ var PaymentsModule = class {
|
|
|
2878
3185
|
this.transactionHistory = [];
|
|
2879
3186
|
}
|
|
2880
3187
|
}
|
|
2881
|
-
const pending2 = await this.deps.storage.get(
|
|
3188
|
+
const pending2 = await this.deps.storage.get(STORAGE_KEYS_ADDRESS.PENDING_TRANSFERS);
|
|
2882
3189
|
if (pending2) {
|
|
2883
3190
|
const transfers = JSON.parse(pending2);
|
|
2884
3191
|
for (const transfer of transfers) {
|
|
@@ -2976,6 +3283,8 @@ var PaymentsModule = class {
|
|
|
2976
3283
|
coinId: request.coinId,
|
|
2977
3284
|
symbol: this.getCoinSymbol(request.coinId),
|
|
2978
3285
|
name: this.getCoinName(request.coinId),
|
|
3286
|
+
decimals: this.getCoinDecimals(request.coinId),
|
|
3287
|
+
iconUrl: this.getCoinIconUrl(request.coinId),
|
|
2979
3288
|
amount: splitPlan.remainderAmount.toString(),
|
|
2980
3289
|
status: "confirmed",
|
|
2981
3290
|
createdAt: Date.now(),
|
|
@@ -3044,20 +3353,25 @@ var PaymentsModule = class {
|
|
|
3044
3353
|
* Get coin symbol from coinId
|
|
3045
3354
|
*/
|
|
3046
3355
|
getCoinSymbol(coinId) {
|
|
3047
|
-
|
|
3048
|
-
"UCT": "UCT"
|
|
3049
|
-
// Add more as needed
|
|
3050
|
-
};
|
|
3051
|
-
return symbols[coinId] || coinId.slice(0, 6).toUpperCase();
|
|
3356
|
+
return TokenRegistry.getInstance().getSymbol(coinId);
|
|
3052
3357
|
}
|
|
3053
3358
|
/**
|
|
3054
3359
|
* Get coin name from coinId
|
|
3055
3360
|
*/
|
|
3056
3361
|
getCoinName(coinId) {
|
|
3057
|
-
|
|
3058
|
-
|
|
3059
|
-
|
|
3060
|
-
|
|
3362
|
+
return TokenRegistry.getInstance().getName(coinId);
|
|
3363
|
+
}
|
|
3364
|
+
/**
|
|
3365
|
+
* Get coin decimals from coinId
|
|
3366
|
+
*/
|
|
3367
|
+
getCoinDecimals(coinId) {
|
|
3368
|
+
return TokenRegistry.getInstance().getDecimals(coinId);
|
|
3369
|
+
}
|
|
3370
|
+
/**
|
|
3371
|
+
* Get coin icon URL from coinId
|
|
3372
|
+
*/
|
|
3373
|
+
getCoinIconUrl(coinId) {
|
|
3374
|
+
return TokenRegistry.getInstance().getIconUrl(coinId) ?? void 0;
|
|
3061
3375
|
}
|
|
3062
3376
|
// ===========================================================================
|
|
3063
3377
|
// Public API - Payment Requests
|
|
@@ -3532,6 +3846,8 @@ var PaymentsModule = class {
|
|
|
3532
3846
|
coinId: tokenInfo.coinId,
|
|
3533
3847
|
symbol: tokenInfo.symbol,
|
|
3534
3848
|
name: tokenInfo.name,
|
|
3849
|
+
decimals: tokenInfo.decimals,
|
|
3850
|
+
iconUrl: tokenInfo.iconUrl,
|
|
3535
3851
|
amount: tokenInfo.amount,
|
|
3536
3852
|
status: "confirmed",
|
|
3537
3853
|
createdAt: data.receivedAt || Date.now(),
|
|
@@ -3787,7 +4103,7 @@ var PaymentsModule = class {
|
|
|
3787
4103
|
};
|
|
3788
4104
|
this.transactionHistory.push(historyEntry);
|
|
3789
4105
|
await this.deps.storage.set(
|
|
3790
|
-
|
|
4106
|
+
STORAGE_KEYS_ADDRESS.TRANSACTION_HISTORY,
|
|
3791
4107
|
JSON.stringify(this.transactionHistory)
|
|
3792
4108
|
);
|
|
3793
4109
|
}
|
|
@@ -4327,6 +4643,8 @@ var PaymentsModule = class {
|
|
|
4327
4643
|
coinId: tokenInfo.coinId,
|
|
4328
4644
|
symbol: tokenInfo.symbol,
|
|
4329
4645
|
name: tokenInfo.name,
|
|
4646
|
+
decimals: tokenInfo.decimals,
|
|
4647
|
+
iconUrl: tokenInfo.iconUrl,
|
|
4330
4648
|
amount: tokenInfo.amount,
|
|
4331
4649
|
status: "confirmed",
|
|
4332
4650
|
createdAt: Date.now(),
|
|
@@ -4380,28 +4698,32 @@ var PaymentsModule = class {
|
|
|
4380
4698
|
// Private: Storage
|
|
4381
4699
|
// ===========================================================================
|
|
4382
4700
|
async save() {
|
|
4383
|
-
const
|
|
4384
|
-
|
|
4385
|
-
tokens
|
|
4386
|
-
|
|
4387
|
-
|
|
4388
|
-
|
|
4389
|
-
|
|
4390
|
-
|
|
4391
|
-
|
|
4701
|
+
const providers = this.getTokenStorageProviders();
|
|
4702
|
+
if (providers.size === 0) {
|
|
4703
|
+
this.log("No token storage providers - tokens not persisted");
|
|
4704
|
+
return;
|
|
4705
|
+
}
|
|
4706
|
+
const data = await this.createStorageData();
|
|
4707
|
+
for (const [id, provider] of providers) {
|
|
4708
|
+
try {
|
|
4709
|
+
await provider.save(data);
|
|
4710
|
+
} catch (err) {
|
|
4711
|
+
console.error(`[Payments] Failed to save to provider ${id}:`, err);
|
|
4712
|
+
}
|
|
4713
|
+
}
|
|
4392
4714
|
}
|
|
4393
4715
|
async saveToOutbox(transfer, recipient) {
|
|
4394
4716
|
const outbox = await this.loadOutbox();
|
|
4395
4717
|
outbox.push({ transfer, recipient, createdAt: Date.now() });
|
|
4396
|
-
await this.deps.storage.set(
|
|
4718
|
+
await this.deps.storage.set(STORAGE_KEYS_ADDRESS.OUTBOX, JSON.stringify(outbox));
|
|
4397
4719
|
}
|
|
4398
4720
|
async removeFromOutbox(transferId) {
|
|
4399
4721
|
const outbox = await this.loadOutbox();
|
|
4400
4722
|
const filtered = outbox.filter((e) => e.transfer.id !== transferId);
|
|
4401
|
-
await this.deps.storage.set(
|
|
4723
|
+
await this.deps.storage.set(STORAGE_KEYS_ADDRESS.OUTBOX, JSON.stringify(filtered));
|
|
4402
4724
|
}
|
|
4403
4725
|
async loadOutbox() {
|
|
4404
|
-
const data = await this.deps.storage.get(
|
|
4726
|
+
const data = await this.deps.storage.get(STORAGE_KEYS_ADDRESS.OUTBOX);
|
|
4405
4727
|
return data ? JSON.parse(data) : [];
|
|
4406
4728
|
}
|
|
4407
4729
|
async createStorageData() {
|
|
@@ -4414,7 +4736,6 @@ var PaymentsModule = class {
|
|
|
4414
4736
|
ipnsName: this.deps.identity.ipnsName ?? ""
|
|
4415
4737
|
},
|
|
4416
4738
|
{
|
|
4417
|
-
nametag: this.nametag || void 0,
|
|
4418
4739
|
tombstones: this.tombstones,
|
|
4419
4740
|
archivedTokens: this.archivedTokens,
|
|
4420
4741
|
forkedTokens: this.forkedTokens
|
|
@@ -5528,6 +5849,7 @@ var Sphere = class _Sphere {
|
|
|
5528
5849
|
_derivationMode = "bip32";
|
|
5529
5850
|
_basePath = DEFAULT_BASE_PATH;
|
|
5530
5851
|
_currentAddressIndex = 0;
|
|
5852
|
+
/** Map of addressId -> (nametagIndex -> nametag). Supports multiple nametags per address (e.g., from Nostr recovery) */
|
|
5531
5853
|
_addressNametags = /* @__PURE__ */ new Map();
|
|
5532
5854
|
// Providers
|
|
5533
5855
|
_storage;
|
|
@@ -5563,9 +5885,9 @@ var Sphere = class _Sphere {
|
|
|
5563
5885
|
if (!storage.isConnected()) {
|
|
5564
5886
|
await storage.connect();
|
|
5565
5887
|
}
|
|
5566
|
-
const mnemonic = await storage.get(
|
|
5888
|
+
const mnemonic = await storage.get(STORAGE_KEYS_GLOBAL.MNEMONIC);
|
|
5567
5889
|
if (mnemonic) return true;
|
|
5568
|
-
const masterKey = await storage.get(
|
|
5890
|
+
const masterKey = await storage.get(STORAGE_KEYS_GLOBAL.MASTER_KEY);
|
|
5569
5891
|
if (masterKey) return true;
|
|
5570
5892
|
return false;
|
|
5571
5893
|
} catch {
|
|
@@ -5736,20 +6058,20 @@ var Sphere = class _Sphere {
|
|
|
5736
6058
|
}
|
|
5737
6059
|
/**
|
|
5738
6060
|
* Clear wallet data from storage
|
|
6061
|
+
* Note: Token data is cleared via TokenStorageProvider, not here
|
|
5739
6062
|
*/
|
|
5740
6063
|
static async clear(storage) {
|
|
5741
|
-
await storage.remove(
|
|
5742
|
-
await storage.remove(
|
|
5743
|
-
await storage.remove(
|
|
5744
|
-
await storage.remove(
|
|
5745
|
-
await storage.remove(
|
|
5746
|
-
await storage.remove(
|
|
5747
|
-
await storage.remove(
|
|
5748
|
-
await storage.remove(
|
|
5749
|
-
await storage.remove(
|
|
5750
|
-
await storage.remove(
|
|
5751
|
-
await storage.remove(
|
|
5752
|
-
await storage.remove(STORAGE_KEYS.OUTBOX);
|
|
6064
|
+
await storage.remove(STORAGE_KEYS_GLOBAL.MNEMONIC);
|
|
6065
|
+
await storage.remove(STORAGE_KEYS_GLOBAL.MASTER_KEY);
|
|
6066
|
+
await storage.remove(STORAGE_KEYS_GLOBAL.CHAIN_CODE);
|
|
6067
|
+
await storage.remove(STORAGE_KEYS_GLOBAL.DERIVATION_PATH);
|
|
6068
|
+
await storage.remove(STORAGE_KEYS_GLOBAL.BASE_PATH);
|
|
6069
|
+
await storage.remove(STORAGE_KEYS_GLOBAL.DERIVATION_MODE);
|
|
6070
|
+
await storage.remove(STORAGE_KEYS_GLOBAL.WALLET_SOURCE);
|
|
6071
|
+
await storage.remove(STORAGE_KEYS_GLOBAL.WALLET_EXISTS);
|
|
6072
|
+
await storage.remove(STORAGE_KEYS_GLOBAL.ADDRESS_NAMETAGS);
|
|
6073
|
+
await storage.remove(STORAGE_KEYS_ADDRESS.PENDING_TRANSFERS);
|
|
6074
|
+
await storage.remove(STORAGE_KEYS_ADDRESS.OUTBOX);
|
|
5753
6075
|
if (_Sphere.instance) {
|
|
5754
6076
|
await _Sphere.instance.destroy();
|
|
5755
6077
|
}
|
|
@@ -6349,22 +6671,47 @@ var Sphere = class _Sphere {
|
|
|
6349
6671
|
return this._currentAddressIndex;
|
|
6350
6672
|
}
|
|
6351
6673
|
/**
|
|
6352
|
-
* Get nametag for a specific address
|
|
6674
|
+
* Get primary nametag for a specific address
|
|
6675
|
+
*
|
|
6676
|
+
* @param addressId - Address identifier (DIRECT://xxx), defaults to current address
|
|
6677
|
+
* @returns Primary nametag (index 0) or undefined if not registered
|
|
6678
|
+
*/
|
|
6679
|
+
getNametagForAddress(addressId) {
|
|
6680
|
+
const id = addressId ?? this.getCurrentAddressId();
|
|
6681
|
+
if (!id) return void 0;
|
|
6682
|
+
const nametagsMap = this._addressNametags.get(id);
|
|
6683
|
+
return nametagsMap?.get(0);
|
|
6684
|
+
}
|
|
6685
|
+
/**
|
|
6686
|
+
* Get all nametags for a specific address
|
|
6353
6687
|
*
|
|
6354
|
-
* @param
|
|
6355
|
-
* @returns
|
|
6688
|
+
* @param addressId - Address identifier (DIRECT://xxx), defaults to current address
|
|
6689
|
+
* @returns Map of nametagIndex to nametag, or undefined if no nametags
|
|
6356
6690
|
*/
|
|
6357
|
-
|
|
6358
|
-
const
|
|
6359
|
-
|
|
6691
|
+
getNametagsForAddress(addressId) {
|
|
6692
|
+
const id = addressId ?? this.getCurrentAddressId();
|
|
6693
|
+
if (!id) return void 0;
|
|
6694
|
+
const nametagsMap = this._addressNametags.get(id);
|
|
6695
|
+
return nametagsMap ? new Map(nametagsMap) : void 0;
|
|
6360
6696
|
}
|
|
6361
6697
|
/**
|
|
6362
6698
|
* Get all registered address nametags
|
|
6363
6699
|
*
|
|
6364
|
-
* @returns Map of
|
|
6700
|
+
* @returns Map of addressId to (nametagIndex -> nametag)
|
|
6365
6701
|
*/
|
|
6366
6702
|
getAllAddressNametags() {
|
|
6367
|
-
|
|
6703
|
+
const result = /* @__PURE__ */ new Map();
|
|
6704
|
+
this._addressNametags.forEach((nametagsMap, addressId) => {
|
|
6705
|
+
result.set(addressId, new Map(nametagsMap));
|
|
6706
|
+
});
|
|
6707
|
+
return result;
|
|
6708
|
+
}
|
|
6709
|
+
/**
|
|
6710
|
+
* Get current address identifier (DIRECT://xxx format)
|
|
6711
|
+
*/
|
|
6712
|
+
getCurrentAddressId() {
|
|
6713
|
+
if (!this._identity?.directAddress) return void 0;
|
|
6714
|
+
return getAddressId(this._identity.directAddress);
|
|
6368
6715
|
}
|
|
6369
6716
|
/**
|
|
6370
6717
|
* Switch to a different address by index
|
|
@@ -6396,7 +6743,9 @@ var Sphere = class _Sphere {
|
|
|
6396
6743
|
const addressInfo = this.deriveAddress(index, false);
|
|
6397
6744
|
const ipnsHash = sha256(addressInfo.publicKey, "hex").slice(0, 40);
|
|
6398
6745
|
const predicateAddress = await deriveL3PredicateAddress(addressInfo.privateKey);
|
|
6399
|
-
const
|
|
6746
|
+
const addressId = getAddressId(predicateAddress);
|
|
6747
|
+
const nametagsMap = this._addressNametags.get(addressId);
|
|
6748
|
+
const nametag = nametagsMap?.get(0);
|
|
6400
6749
|
this._identity = {
|
|
6401
6750
|
privateKey: addressInfo.privateKey,
|
|
6402
6751
|
chainPubkey: addressInfo.publicKey,
|
|
@@ -6406,7 +6755,7 @@ var Sphere = class _Sphere {
|
|
|
6406
6755
|
nametag
|
|
6407
6756
|
};
|
|
6408
6757
|
this._currentAddressIndex = index;
|
|
6409
|
-
await this._storage.set(
|
|
6758
|
+
await this._storage.set(STORAGE_KEYS_GLOBAL.CURRENT_ADDRESS_INDEX, index.toString());
|
|
6410
6759
|
this._storage.setIdentity(this._identity);
|
|
6411
6760
|
this._transport.setIdentity(this._identity);
|
|
6412
6761
|
for (const provider of this._tokenStorageProviders.values()) {
|
|
@@ -6645,8 +6994,15 @@ var Sphere = class _Sphere {
|
|
|
6645
6994
|
}
|
|
6646
6995
|
}
|
|
6647
6996
|
this._identity.nametag = cleanNametag;
|
|
6648
|
-
this.
|
|
6649
|
-
|
|
6997
|
+
const addressId = this.getCurrentAddressId();
|
|
6998
|
+
if (addressId) {
|
|
6999
|
+
let nametagsMap = this._addressNametags.get(addressId);
|
|
7000
|
+
if (!nametagsMap) {
|
|
7001
|
+
nametagsMap = /* @__PURE__ */ new Map();
|
|
7002
|
+
this._addressNametags.set(addressId, nametagsMap);
|
|
7003
|
+
}
|
|
7004
|
+
nametagsMap.set(0, cleanNametag);
|
|
7005
|
+
}
|
|
6650
7006
|
await this.persistAddressNametags();
|
|
6651
7007
|
if (!this._payments.hasNametag()) {
|
|
6652
7008
|
console.log(`[Sphere] Minting nametag token for @${cleanNametag}...`);
|
|
@@ -6665,13 +7021,18 @@ var Sphere = class _Sphere {
|
|
|
6665
7021
|
}
|
|
6666
7022
|
/**
|
|
6667
7023
|
* Persist address nametags to storage
|
|
7024
|
+
* Format: { "DIRECT://abc...xyz": { "0": "alice", "1": "alice2" }, ... }
|
|
6668
7025
|
*/
|
|
6669
7026
|
async persistAddressNametags() {
|
|
6670
|
-
const
|
|
6671
|
-
this._addressNametags.forEach((
|
|
6672
|
-
|
|
7027
|
+
const result = {};
|
|
7028
|
+
this._addressNametags.forEach((nametagsMap, addressId) => {
|
|
7029
|
+
const innerObj = {};
|
|
7030
|
+
nametagsMap.forEach((nametag, index) => {
|
|
7031
|
+
innerObj[index.toString()] = nametag;
|
|
7032
|
+
});
|
|
7033
|
+
result[addressId] = innerObj;
|
|
6673
7034
|
});
|
|
6674
|
-
await this._storage.set(
|
|
7035
|
+
await this._storage.set(STORAGE_KEYS_GLOBAL.ADDRESS_NAMETAGS, JSON.stringify(result));
|
|
6675
7036
|
}
|
|
6676
7037
|
/**
|
|
6677
7038
|
* Mint a nametag token on-chain (like Sphere wallet and lottery)
|
|
@@ -6706,15 +7067,24 @@ var Sphere = class _Sphere {
|
|
|
6706
7067
|
}
|
|
6707
7068
|
/**
|
|
6708
7069
|
* Load address nametags from storage
|
|
7070
|
+
* Supports new format: { "DIRECT://abc...xyz": { "0": "alice" } }
|
|
7071
|
+
* And legacy format: { "0": "alice" } (migrates to new format on save)
|
|
6709
7072
|
*/
|
|
6710
7073
|
async loadAddressNametags() {
|
|
6711
7074
|
try {
|
|
6712
|
-
const saved = await this._storage.get(
|
|
7075
|
+
const saved = await this._storage.get(STORAGE_KEYS_GLOBAL.ADDRESS_NAMETAGS);
|
|
6713
7076
|
if (saved) {
|
|
6714
|
-
const
|
|
7077
|
+
const parsed = JSON.parse(saved);
|
|
6715
7078
|
this._addressNametags.clear();
|
|
6716
|
-
for (const [
|
|
6717
|
-
|
|
7079
|
+
for (const [key, value] of Object.entries(parsed)) {
|
|
7080
|
+
if (typeof value === "object" && value !== null) {
|
|
7081
|
+
const nametagsMap = /* @__PURE__ */ new Map();
|
|
7082
|
+
for (const [indexStr, nametag] of Object.entries(value)) {
|
|
7083
|
+
nametagsMap.set(parseInt(indexStr, 10), nametag);
|
|
7084
|
+
}
|
|
7085
|
+
this._addressNametags.set(key, nametagsMap);
|
|
7086
|
+
} else if (typeof value === "string") {
|
|
7087
|
+
}
|
|
6718
7088
|
}
|
|
6719
7089
|
}
|
|
6720
7090
|
} catch {
|
|
@@ -6765,8 +7135,17 @@ var Sphere = class _Sphere {
|
|
|
6765
7135
|
if (this._identity) {
|
|
6766
7136
|
this._identity.nametag = recoveredNametag;
|
|
6767
7137
|
}
|
|
6768
|
-
this.
|
|
6769
|
-
|
|
7138
|
+
const addressId = this.getCurrentAddressId();
|
|
7139
|
+
if (addressId) {
|
|
7140
|
+
let nametagsMap = this._addressNametags.get(addressId);
|
|
7141
|
+
if (!nametagsMap) {
|
|
7142
|
+
nametagsMap = /* @__PURE__ */ new Map();
|
|
7143
|
+
this._addressNametags.set(addressId, nametagsMap);
|
|
7144
|
+
}
|
|
7145
|
+
const nextIndex = nametagsMap.size;
|
|
7146
|
+
nametagsMap.set(nextIndex, recoveredNametag);
|
|
7147
|
+
}
|
|
7148
|
+
await this.persistAddressNametags();
|
|
6770
7149
|
if (this._transport.registerNametag) {
|
|
6771
7150
|
await this._transport.registerNametag(
|
|
6772
7151
|
recoveredNametag,
|
|
@@ -6809,22 +7188,22 @@ var Sphere = class _Sphere {
|
|
|
6809
7188
|
// ===========================================================================
|
|
6810
7189
|
async storeMnemonic(mnemonic, derivationPath, basePath) {
|
|
6811
7190
|
const encrypted = this.encrypt(mnemonic);
|
|
6812
|
-
await this._storage.set(
|
|
7191
|
+
await this._storage.set(STORAGE_KEYS_GLOBAL.MNEMONIC, encrypted);
|
|
6813
7192
|
this._mnemonic = mnemonic;
|
|
6814
7193
|
this._source = "mnemonic";
|
|
6815
7194
|
this._derivationMode = "bip32";
|
|
6816
7195
|
if (derivationPath) {
|
|
6817
|
-
await this._storage.set(
|
|
7196
|
+
await this._storage.set(STORAGE_KEYS_GLOBAL.DERIVATION_PATH, derivationPath);
|
|
6818
7197
|
}
|
|
6819
7198
|
const effectiveBasePath = basePath ?? DEFAULT_BASE_PATH;
|
|
6820
7199
|
this._basePath = effectiveBasePath;
|
|
6821
|
-
await this._storage.set(
|
|
6822
|
-
await this._storage.set(
|
|
6823
|
-
await this._storage.set(
|
|
7200
|
+
await this._storage.set(STORAGE_KEYS_GLOBAL.BASE_PATH, effectiveBasePath);
|
|
7201
|
+
await this._storage.set(STORAGE_KEYS_GLOBAL.DERIVATION_MODE, this._derivationMode);
|
|
7202
|
+
await this._storage.set(STORAGE_KEYS_GLOBAL.WALLET_SOURCE, this._source);
|
|
6824
7203
|
}
|
|
6825
7204
|
async storeMasterKey(masterKey, chainCode, derivationPath, basePath, derivationMode) {
|
|
6826
7205
|
const encrypted = this.encrypt(masterKey);
|
|
6827
|
-
await this._storage.set(
|
|
7206
|
+
await this._storage.set(STORAGE_KEYS_GLOBAL.MASTER_KEY, encrypted);
|
|
6828
7207
|
this._source = "file";
|
|
6829
7208
|
this._mnemonic = null;
|
|
6830
7209
|
if (derivationMode) {
|
|
@@ -6833,16 +7212,16 @@ var Sphere = class _Sphere {
|
|
|
6833
7212
|
this._derivationMode = chainCode ? "bip32" : "wif_hmac";
|
|
6834
7213
|
}
|
|
6835
7214
|
if (chainCode) {
|
|
6836
|
-
await this._storage.set(
|
|
7215
|
+
await this._storage.set(STORAGE_KEYS_GLOBAL.CHAIN_CODE, chainCode);
|
|
6837
7216
|
}
|
|
6838
7217
|
if (derivationPath) {
|
|
6839
|
-
await this._storage.set(
|
|
7218
|
+
await this._storage.set(STORAGE_KEYS_GLOBAL.DERIVATION_PATH, derivationPath);
|
|
6840
7219
|
}
|
|
6841
7220
|
const effectiveBasePath = basePath ?? DEFAULT_BASE_PATH;
|
|
6842
7221
|
this._basePath = effectiveBasePath;
|
|
6843
|
-
await this._storage.set(
|
|
6844
|
-
await this._storage.set(
|
|
6845
|
-
await this._storage.set(
|
|
7222
|
+
await this._storage.set(STORAGE_KEYS_GLOBAL.BASE_PATH, effectiveBasePath);
|
|
7223
|
+
await this._storage.set(STORAGE_KEYS_GLOBAL.DERIVATION_MODE, this._derivationMode);
|
|
7224
|
+
await this._storage.set(STORAGE_KEYS_GLOBAL.WALLET_SOURCE, this._source);
|
|
6846
7225
|
}
|
|
6847
7226
|
/**
|
|
6848
7227
|
* Mark wallet as fully created (after successful initialization)
|
|
@@ -6850,20 +7229,20 @@ var Sphere = class _Sphere {
|
|
|
6850
7229
|
* marked as existing after all initialization steps succeed.
|
|
6851
7230
|
*/
|
|
6852
7231
|
async finalizeWalletCreation() {
|
|
6853
|
-
await this._storage.set(
|
|
7232
|
+
await this._storage.set(STORAGE_KEYS_GLOBAL.WALLET_EXISTS, "true");
|
|
6854
7233
|
}
|
|
6855
7234
|
// ===========================================================================
|
|
6856
7235
|
// Private: Identity Initialization
|
|
6857
7236
|
// ===========================================================================
|
|
6858
7237
|
async loadIdentityFromStorage() {
|
|
6859
|
-
const encryptedMnemonic = await this._storage.get(
|
|
6860
|
-
const encryptedMasterKey = await this._storage.get(
|
|
6861
|
-
const chainCode = await this._storage.get(
|
|
6862
|
-
const derivationPath = await this._storage.get(
|
|
6863
|
-
const savedBasePath = await this._storage.get(
|
|
6864
|
-
const savedDerivationMode = await this._storage.get(
|
|
6865
|
-
const savedSource = await this._storage.get(
|
|
6866
|
-
const savedAddressIndex = await this._storage.get(
|
|
7238
|
+
const encryptedMnemonic = await this._storage.get(STORAGE_KEYS_GLOBAL.MNEMONIC);
|
|
7239
|
+
const encryptedMasterKey = await this._storage.get(STORAGE_KEYS_GLOBAL.MASTER_KEY);
|
|
7240
|
+
const chainCode = await this._storage.get(STORAGE_KEYS_GLOBAL.CHAIN_CODE);
|
|
7241
|
+
const derivationPath = await this._storage.get(STORAGE_KEYS_GLOBAL.DERIVATION_PATH);
|
|
7242
|
+
const savedBasePath = await this._storage.get(STORAGE_KEYS_GLOBAL.BASE_PATH);
|
|
7243
|
+
const savedDerivationMode = await this._storage.get(STORAGE_KEYS_GLOBAL.DERIVATION_MODE);
|
|
7244
|
+
const savedSource = await this._storage.get(STORAGE_KEYS_GLOBAL.WALLET_SOURCE);
|
|
7245
|
+
const savedAddressIndex = await this._storage.get(STORAGE_KEYS_GLOBAL.CURRENT_ADDRESS_INDEX);
|
|
6867
7246
|
this._basePath = savedBasePath ?? DEFAULT_BASE_PATH;
|
|
6868
7247
|
this._derivationMode = savedDerivationMode ?? "bip32";
|
|
6869
7248
|
this._source = savedSource ?? "unknown";
|
|
@@ -6897,12 +7276,13 @@ var Sphere = class _Sphere {
|
|
|
6897
7276
|
this._storage.setIdentity(this._identity);
|
|
6898
7277
|
}
|
|
6899
7278
|
await this.loadAddressNametags();
|
|
6900
|
-
const savedNametag = await this._storage.get(STORAGE_KEYS.NAMETAG);
|
|
6901
7279
|
if (this._currentAddressIndex > 0 && this._masterKey) {
|
|
6902
7280
|
const addressInfo = this.deriveAddress(this._currentAddressIndex, false);
|
|
6903
7281
|
const ipnsHash = sha256(addressInfo.publicKey, "hex").slice(0, 40);
|
|
6904
7282
|
const predicateAddress = await deriveL3PredicateAddress(addressInfo.privateKey);
|
|
6905
|
-
const
|
|
7283
|
+
const addressId = getAddressId(predicateAddress);
|
|
7284
|
+
const nametagsMap = this._addressNametags.get(addressId);
|
|
7285
|
+
const nametag = nametagsMap?.get(0);
|
|
6906
7286
|
this._identity = {
|
|
6907
7287
|
privateKey: addressInfo.privateKey,
|
|
6908
7288
|
chainPubkey: addressInfo.publicKey,
|
|
@@ -6913,25 +7293,12 @@ var Sphere = class _Sphere {
|
|
|
6913
7293
|
};
|
|
6914
7294
|
this._storage.setIdentity(this._identity);
|
|
6915
7295
|
console.log(`[Sphere] Restored to address ${this._currentAddressIndex}:`, this._identity.l1Address);
|
|
6916
|
-
} else {
|
|
6917
|
-
|
|
6918
|
-
|
|
6919
|
-
|
|
6920
|
-
|
|
6921
|
-
const parsed = JSON.parse(savedNametag);
|
|
6922
|
-
nametag = parsed["0"] || parsed[0] || Object.values(parsed)[0];
|
|
6923
|
-
} catch {
|
|
6924
|
-
}
|
|
6925
|
-
}
|
|
7296
|
+
} else if (this._identity) {
|
|
7297
|
+
const addressId = this.getCurrentAddressId();
|
|
7298
|
+
const nametagsMap = addressId ? this._addressNametags.get(addressId) : void 0;
|
|
7299
|
+
const nametag = nametagsMap?.get(0);
|
|
7300
|
+
if (nametag) {
|
|
6926
7301
|
this._identity.nametag = nametag;
|
|
6927
|
-
if (!this._addressNametags.has(0)) {
|
|
6928
|
-
this._addressNametags.set(0, nametag);
|
|
6929
|
-
}
|
|
6930
|
-
} else if (this._identity) {
|
|
6931
|
-
const nametag = this._addressNametags.get(0);
|
|
6932
|
-
if (nametag) {
|
|
6933
|
-
this._identity.nametag = nametag;
|
|
6934
|
-
}
|
|
6935
7302
|
}
|
|
6936
7303
|
}
|
|
6937
7304
|
}
|