@unicitylabs/sphere-sdk 0.2.5 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/index.cjs +2143 -795
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +248 -46
- package/dist/core/index.d.ts +248 -46
- package/dist/core/index.js +2144 -792
- package/dist/core/index.js.map +1 -1
- package/dist/impl/browser/index.cjs +58 -111
- package/dist/impl/browser/index.cjs.map +1 -1
- package/dist/impl/browser/index.js +58 -111
- package/dist/impl/browser/index.js.map +1 -1
- package/dist/impl/browser/ipfs.cjs +33 -85
- package/dist/impl/browser/ipfs.cjs.map +1 -1
- package/dist/impl/browser/ipfs.js +33 -85
- package/dist/impl/browser/ipfs.js.map +1 -1
- package/dist/impl/nodejs/index.cjs +58 -116
- package/dist/impl/nodejs/index.cjs.map +1 -1
- package/dist/impl/nodejs/index.d.cts +23 -20
- package/dist/impl/nodejs/index.d.ts +23 -20
- package/dist/impl/nodejs/index.js +58 -116
- package/dist/impl/nodejs/index.js.map +1 -1
- package/dist/index.cjs +5647 -4329
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +304 -50
- package/dist/index.d.ts +304 -50
- package/dist/index.js +5634 -4318
- package/dist/index.js.map +1 -1
- package/package.json +5 -3
|
@@ -26,7 +26,17 @@ var STORAGE_KEYS_GLOBAL = {
|
|
|
26
26
|
/** Active addresses registry (JSON: TrackedAddressesStorage) */
|
|
27
27
|
TRACKED_ADDRESSES: "tracked_addresses",
|
|
28
28
|
/** Last processed Nostr wallet event timestamp (unix seconds), keyed per pubkey */
|
|
29
|
-
LAST_WALLET_EVENT_TS: "last_wallet_event_ts"
|
|
29
|
+
LAST_WALLET_EVENT_TS: "last_wallet_event_ts",
|
|
30
|
+
/** Group chat: joined groups */
|
|
31
|
+
GROUP_CHAT_GROUPS: "group_chat_groups",
|
|
32
|
+
/** Group chat: messages */
|
|
33
|
+
GROUP_CHAT_MESSAGES: "group_chat_messages",
|
|
34
|
+
/** Group chat: members */
|
|
35
|
+
GROUP_CHAT_MEMBERS: "group_chat_members",
|
|
36
|
+
/** Group chat: processed event IDs for deduplication */
|
|
37
|
+
GROUP_CHAT_PROCESSED_EVENTS: "group_chat_processed_events",
|
|
38
|
+
/** Group chat: last used relay URL (stale data detection) */
|
|
39
|
+
GROUP_CHAT_RELAY_URL: "group_chat_relay_url"
|
|
30
40
|
};
|
|
31
41
|
var STORAGE_KEYS_ADDRESS = {
|
|
32
42
|
/** Pending transfers for this address */
|
|
@@ -107,27 +117,33 @@ var TEST_ELECTRUM_URL = "wss://fulcrum.alpha.testnet.unicity.network:50004";
|
|
|
107
117
|
var TEST_NOSTR_RELAYS = [
|
|
108
118
|
"wss://nostr-relay.testnet.unicity.network"
|
|
109
119
|
];
|
|
120
|
+
var DEFAULT_GROUP_RELAYS = [
|
|
121
|
+
"wss://sphere-relay.unicity.network"
|
|
122
|
+
];
|
|
110
123
|
var NETWORKS = {
|
|
111
124
|
mainnet: {
|
|
112
125
|
name: "Mainnet",
|
|
113
126
|
aggregatorUrl: DEFAULT_AGGREGATOR_URL,
|
|
114
127
|
nostrRelays: DEFAULT_NOSTR_RELAYS,
|
|
115
128
|
ipfsGateways: DEFAULT_IPFS_GATEWAYS,
|
|
116
|
-
electrumUrl: DEFAULT_ELECTRUM_URL
|
|
129
|
+
electrumUrl: DEFAULT_ELECTRUM_URL,
|
|
130
|
+
groupRelays: DEFAULT_GROUP_RELAYS
|
|
117
131
|
},
|
|
118
132
|
testnet: {
|
|
119
133
|
name: "Testnet",
|
|
120
134
|
aggregatorUrl: TEST_AGGREGATOR_URL,
|
|
121
135
|
nostrRelays: TEST_NOSTR_RELAYS,
|
|
122
136
|
ipfsGateways: DEFAULT_IPFS_GATEWAYS,
|
|
123
|
-
electrumUrl: TEST_ELECTRUM_URL
|
|
137
|
+
electrumUrl: TEST_ELECTRUM_URL,
|
|
138
|
+
groupRelays: DEFAULT_GROUP_RELAYS
|
|
124
139
|
},
|
|
125
140
|
dev: {
|
|
126
141
|
name: "Development",
|
|
127
142
|
aggregatorUrl: DEV_AGGREGATOR_URL,
|
|
128
143
|
nostrRelays: TEST_NOSTR_RELAYS,
|
|
129
144
|
ipfsGateways: DEFAULT_IPFS_GATEWAYS,
|
|
130
|
-
electrumUrl: TEST_ELECTRUM_URL
|
|
145
|
+
electrumUrl: TEST_ELECTRUM_URL,
|
|
146
|
+
groupRelays: DEFAULT_GROUP_RELAYS
|
|
131
147
|
}
|
|
132
148
|
};
|
|
133
149
|
var TIMEOUTS = {
|
|
@@ -547,29 +563,6 @@ var IndexedDBTokenStorageProvider = class {
|
|
|
547
563
|
}
|
|
548
564
|
}
|
|
549
565
|
// =========================================================================
|
|
550
|
-
// Helper methods for individual token operations
|
|
551
|
-
// =========================================================================
|
|
552
|
-
async deleteToken(tokenId) {
|
|
553
|
-
if (this.db) {
|
|
554
|
-
await this.deleteFromStore(STORE_TOKENS, tokenId);
|
|
555
|
-
}
|
|
556
|
-
}
|
|
557
|
-
async saveToken(tokenId, tokenData) {
|
|
558
|
-
if (this.db) {
|
|
559
|
-
await this.putToStore(STORE_TOKENS, tokenId, { id: tokenId, data: tokenData });
|
|
560
|
-
}
|
|
561
|
-
}
|
|
562
|
-
async getToken(tokenId) {
|
|
563
|
-
if (!this.db) return null;
|
|
564
|
-
const result = await this.getFromStore(STORE_TOKENS, tokenId);
|
|
565
|
-
return result?.data ?? null;
|
|
566
|
-
}
|
|
567
|
-
async listTokenIds() {
|
|
568
|
-
if (!this.db) return [];
|
|
569
|
-
const tokens = await this.getAllFromStore(STORE_TOKENS);
|
|
570
|
-
return tokens.map((t) => t.id);
|
|
571
|
-
}
|
|
572
|
-
// =========================================================================
|
|
573
566
|
// Private IndexedDB helpers
|
|
574
567
|
// =========================================================================
|
|
575
568
|
openDatabase() {
|
|
@@ -3851,9 +3844,13 @@ function mergeTxfData(local, remote) {
|
|
|
3851
3844
|
remote._invalid ?? [],
|
|
3852
3845
|
"tokenId"
|
|
3853
3846
|
);
|
|
3847
|
+
const localNametags = local._nametags ?? [];
|
|
3848
|
+
const remoteNametags = remote._nametags ?? [];
|
|
3849
|
+
const mergedNametags = mergeNametagsByName(localNametags, remoteNametags);
|
|
3854
3850
|
const merged = {
|
|
3855
3851
|
_meta: mergedMeta,
|
|
3856
3852
|
_tombstones: mergedTombstones.length > 0 ? mergedTombstones : void 0,
|
|
3853
|
+
_nametags: mergedNametags.length > 0 ? mergedNametags : void 0,
|
|
3857
3854
|
_outbox: mergedOutbox.length > 0 ? mergedOutbox : void 0,
|
|
3858
3855
|
_sent: mergedSent.length > 0 ? mergedSent : void 0,
|
|
3859
3856
|
_invalid: mergedInvalid.length > 0 ? mergedInvalid : void 0,
|
|
@@ -3880,6 +3877,7 @@ function getTokenKeys(data) {
|
|
|
3880
3877
|
"_sent",
|
|
3881
3878
|
"_invalid",
|
|
3882
3879
|
"_nametag",
|
|
3880
|
+
"_nametags",
|
|
3883
3881
|
"_mintOutbox",
|
|
3884
3882
|
"_invalidatedNametags",
|
|
3885
3883
|
"_integrity"
|
|
@@ -3887,7 +3885,7 @@ function getTokenKeys(data) {
|
|
|
3887
3885
|
const keys = /* @__PURE__ */ new Set();
|
|
3888
3886
|
for (const key of Object.keys(data)) {
|
|
3889
3887
|
if (reservedKeys.has(key)) continue;
|
|
3890
|
-
if (key.startsWith("archived-") || key.startsWith("_forked_")
|
|
3888
|
+
if (key.startsWith("archived-") || key.startsWith("_forked_")) continue;
|
|
3891
3889
|
keys.add(key);
|
|
3892
3890
|
}
|
|
3893
3891
|
return keys;
|
|
@@ -3902,6 +3900,18 @@ function isTokenTombstoned(tokenId, localToken, remoteToken, tombstoneKeys) {
|
|
|
3902
3900
|
void remoteToken;
|
|
3903
3901
|
return false;
|
|
3904
3902
|
}
|
|
3903
|
+
function mergeNametagsByName(local, remote) {
|
|
3904
|
+
const seen = /* @__PURE__ */ new Map();
|
|
3905
|
+
for (const item of local) {
|
|
3906
|
+
if (item.name) seen.set(item.name, item);
|
|
3907
|
+
}
|
|
3908
|
+
for (const item of remote) {
|
|
3909
|
+
if (item.name && !seen.has(item.name)) {
|
|
3910
|
+
seen.set(item.name, item);
|
|
3911
|
+
}
|
|
3912
|
+
}
|
|
3913
|
+
return Array.from(seen.values());
|
|
3914
|
+
}
|
|
3905
3915
|
function mergeArrayById(local, remote, idField) {
|
|
3906
3916
|
const seen = /* @__PURE__ */ new Map();
|
|
3907
3917
|
for (const item of local) {
|
|
@@ -4256,14 +4266,11 @@ var AsyncSerialQueue = class {
|
|
|
4256
4266
|
var WriteBuffer = class {
|
|
4257
4267
|
/** Full TXF data from save() calls — latest wins */
|
|
4258
4268
|
txfData = null;
|
|
4259
|
-
/** Individual token mutations: key -> { op: 'save'|'delete', data? } */
|
|
4260
|
-
tokenMutations = /* @__PURE__ */ new Map();
|
|
4261
4269
|
get isEmpty() {
|
|
4262
|
-
return this.txfData === null
|
|
4270
|
+
return this.txfData === null;
|
|
4263
4271
|
}
|
|
4264
4272
|
clear() {
|
|
4265
4273
|
this.txfData = null;
|
|
4266
|
-
this.tokenMutations.clear();
|
|
4267
4274
|
}
|
|
4268
4275
|
/**
|
|
4269
4276
|
* Merge another buffer's contents into this one (for rollback).
|
|
@@ -4273,11 +4280,6 @@ var WriteBuffer = class {
|
|
|
4273
4280
|
if (other.txfData && !this.txfData) {
|
|
4274
4281
|
this.txfData = other.txfData;
|
|
4275
4282
|
}
|
|
4276
|
-
for (const [id, mutation] of other.tokenMutations) {
|
|
4277
|
-
if (!this.tokenMutations.has(id)) {
|
|
4278
|
-
this.tokenMutations.set(id, mutation);
|
|
4279
|
-
}
|
|
4280
|
-
}
|
|
4281
4283
|
}
|
|
4282
4284
|
};
|
|
4283
4285
|
|
|
@@ -4317,9 +4319,6 @@ var IpfsStorageProvider = class {
|
|
|
4317
4319
|
subscriptionClient = null;
|
|
4318
4320
|
/** Unsubscribe function from subscription client */
|
|
4319
4321
|
subscriptionUnsubscribe = null;
|
|
4320
|
-
/** In-memory buffer for individual token save/delete calls */
|
|
4321
|
-
tokenBuffer = /* @__PURE__ */ new Map();
|
|
4322
|
-
deletedTokenIds = /* @__PURE__ */ new Set();
|
|
4323
4322
|
/** Write-behind buffer: serializes flush / sync / shutdown */
|
|
4324
4323
|
flushQueue = new AsyncSerialQueue();
|
|
4325
4324
|
/** Pending mutations not yet flushed to IPFS */
|
|
@@ -4508,14 +4507,6 @@ var IpfsStorageProvider = class {
|
|
|
4508
4507
|
metaUpdate.lastCid = this.remoteCid;
|
|
4509
4508
|
}
|
|
4510
4509
|
const updatedData = { ...data, _meta: metaUpdate };
|
|
4511
|
-
for (const [tokenId, tokenData] of this.tokenBuffer) {
|
|
4512
|
-
if (!this.deletedTokenIds.has(tokenId)) {
|
|
4513
|
-
updatedData[tokenId] = tokenData;
|
|
4514
|
-
}
|
|
4515
|
-
}
|
|
4516
|
-
for (const tokenId of this.deletedTokenIds) {
|
|
4517
|
-
delete updatedData[tokenId];
|
|
4518
|
-
}
|
|
4519
4510
|
const { cid } = await this.httpClient.upload(updatedData);
|
|
4520
4511
|
this.log(`Content uploaded: CID=${cid}`);
|
|
4521
4512
|
const baseSeq = this.ipnsSequenceNumber > this.lastKnownRemoteSequence ? this.ipnsSequenceNumber : this.lastKnownRemoteSequence;
|
|
@@ -4554,7 +4545,6 @@ var IpfsStorageProvider = class {
|
|
|
4554
4545
|
lastCid: cid,
|
|
4555
4546
|
version: this.dataVersion
|
|
4556
4547
|
});
|
|
4557
|
-
this.deletedTokenIds.clear();
|
|
4558
4548
|
this.emitEvent({
|
|
4559
4549
|
type: "storage:saved",
|
|
4560
4550
|
timestamp: Date.now(),
|
|
@@ -4666,7 +4656,6 @@ var IpfsStorageProvider = class {
|
|
|
4666
4656
|
if (typeof remoteVersion === "number" && remoteVersion > this.dataVersion) {
|
|
4667
4657
|
this.dataVersion = remoteVersion;
|
|
4668
4658
|
}
|
|
4669
|
-
this.populateTokenBuffer(data);
|
|
4670
4659
|
this.emitEvent({
|
|
4671
4660
|
type: "storage:loaded",
|
|
4672
4661
|
timestamp: Date.now(),
|
|
@@ -4712,7 +4701,7 @@ var IpfsStorageProvider = class {
|
|
|
4712
4701
|
this.emitEvent({ type: "sync:completed", timestamp: Date.now() });
|
|
4713
4702
|
return {
|
|
4714
4703
|
success: saveResult2.success,
|
|
4715
|
-
merged:
|
|
4704
|
+
merged: localData,
|
|
4716
4705
|
added: 0,
|
|
4717
4706
|
removed: 0,
|
|
4718
4707
|
conflicts: 0,
|
|
@@ -4727,7 +4716,7 @@ var IpfsStorageProvider = class {
|
|
|
4727
4716
|
this.emitEvent({ type: "sync:completed", timestamp: Date.now() });
|
|
4728
4717
|
return {
|
|
4729
4718
|
success: true,
|
|
4730
|
-
merged:
|
|
4719
|
+
merged: localData,
|
|
4731
4720
|
added: 0,
|
|
4732
4721
|
removed: 0,
|
|
4733
4722
|
conflicts: 0
|
|
@@ -4750,7 +4739,7 @@ var IpfsStorageProvider = class {
|
|
|
4750
4739
|
});
|
|
4751
4740
|
return {
|
|
4752
4741
|
success: saveResult.success,
|
|
4753
|
-
merged
|
|
4742
|
+
merged,
|
|
4754
4743
|
added,
|
|
4755
4744
|
removed,
|
|
4756
4745
|
conflicts,
|
|
@@ -4776,21 +4765,6 @@ var IpfsStorageProvider = class {
|
|
|
4776
4765
|
// ---------------------------------------------------------------------------
|
|
4777
4766
|
// Private Helpers
|
|
4778
4767
|
// ---------------------------------------------------------------------------
|
|
4779
|
-
/**
|
|
4780
|
-
* Enrich TXF data with individually-buffered tokens before returning to caller.
|
|
4781
|
-
* PaymentsModule.createStorageData() passes empty tokens (they're stored via
|
|
4782
|
-
* saveToken()), but loadFromStorageData() needs them in the merged result.
|
|
4783
|
-
*/
|
|
4784
|
-
enrichWithTokenBuffer(data) {
|
|
4785
|
-
if (this.tokenBuffer.size === 0) return data;
|
|
4786
|
-
const enriched = { ...data };
|
|
4787
|
-
for (const [tokenId, tokenData] of this.tokenBuffer) {
|
|
4788
|
-
if (!this.deletedTokenIds.has(tokenId)) {
|
|
4789
|
-
enriched[tokenId] = tokenData;
|
|
4790
|
-
}
|
|
4791
|
-
}
|
|
4792
|
-
return enriched;
|
|
4793
|
-
}
|
|
4794
4768
|
// ---------------------------------------------------------------------------
|
|
4795
4769
|
// Optional Methods
|
|
4796
4770
|
// ---------------------------------------------------------------------------
|
|
@@ -4820,8 +4794,6 @@ var IpfsStorageProvider = class {
|
|
|
4820
4794
|
const result = await this._doSave(emptyData);
|
|
4821
4795
|
if (result.success) {
|
|
4822
4796
|
this.cache.clear();
|
|
4823
|
-
this.tokenBuffer.clear();
|
|
4824
|
-
this.deletedTokenIds.clear();
|
|
4825
4797
|
await this.statePersistence.clear(this.ipnsName);
|
|
4826
4798
|
}
|
|
4827
4799
|
return result.success;
|
|
@@ -4832,27 +4804,6 @@ var IpfsStorageProvider = class {
|
|
|
4832
4804
|
this.eventCallbacks.delete(callback);
|
|
4833
4805
|
};
|
|
4834
4806
|
}
|
|
4835
|
-
async saveToken(tokenId, tokenData) {
|
|
4836
|
-
this.pendingBuffer.tokenMutations.set(tokenId, { op: "save", data: tokenData });
|
|
4837
|
-
this.tokenBuffer.set(tokenId, tokenData);
|
|
4838
|
-
this.deletedTokenIds.delete(tokenId);
|
|
4839
|
-
this.scheduleFlush();
|
|
4840
|
-
}
|
|
4841
|
-
async getToken(tokenId) {
|
|
4842
|
-
if (this.deletedTokenIds.has(tokenId)) return null;
|
|
4843
|
-
return this.tokenBuffer.get(tokenId) ?? null;
|
|
4844
|
-
}
|
|
4845
|
-
async listTokenIds() {
|
|
4846
|
-
return Array.from(this.tokenBuffer.keys()).filter(
|
|
4847
|
-
(id) => !this.deletedTokenIds.has(id)
|
|
4848
|
-
);
|
|
4849
|
-
}
|
|
4850
|
-
async deleteToken(tokenId) {
|
|
4851
|
-
this.pendingBuffer.tokenMutations.set(tokenId, { op: "delete" });
|
|
4852
|
-
this.tokenBuffer.delete(tokenId);
|
|
4853
|
-
this.deletedTokenIds.add(tokenId);
|
|
4854
|
-
this.scheduleFlush();
|
|
4855
|
-
}
|
|
4856
4807
|
// ---------------------------------------------------------------------------
|
|
4857
4808
|
// Public Accessors
|
|
4858
4809
|
// ---------------------------------------------------------------------------
|
|
@@ -4944,26 +4895,6 @@ var IpfsStorageProvider = class {
|
|
|
4944
4895
|
console.log(`[IPFS-Storage] ${message}`);
|
|
4945
4896
|
}
|
|
4946
4897
|
}
|
|
4947
|
-
META_KEYS = /* @__PURE__ */ new Set([
|
|
4948
|
-
"_meta",
|
|
4949
|
-
"_tombstones",
|
|
4950
|
-
"_outbox",
|
|
4951
|
-
"_sent",
|
|
4952
|
-
"_invalid",
|
|
4953
|
-
"_nametag",
|
|
4954
|
-
"_mintOutbox",
|
|
4955
|
-
"_invalidatedNametags",
|
|
4956
|
-
"_integrity"
|
|
4957
|
-
]);
|
|
4958
|
-
populateTokenBuffer(data) {
|
|
4959
|
-
this.tokenBuffer.clear();
|
|
4960
|
-
this.deletedTokenIds.clear();
|
|
4961
|
-
for (const key of Object.keys(data)) {
|
|
4962
|
-
if (!this.META_KEYS.has(key)) {
|
|
4963
|
-
this.tokenBuffer.set(key, data[key]);
|
|
4964
|
-
}
|
|
4965
|
-
}
|
|
4966
|
-
}
|
|
4967
4898
|
};
|
|
4968
4899
|
|
|
4969
4900
|
// impl/browser/ipfs/browser-ipfs-state-persistence.ts
|
|
@@ -5202,6 +5133,20 @@ function resolveArrayConfig(defaults, replace, additional) {
|
|
|
5202
5133
|
}
|
|
5203
5134
|
return result;
|
|
5204
5135
|
}
|
|
5136
|
+
function resolveGroupChatConfig(network, config) {
|
|
5137
|
+
if (!config) return void 0;
|
|
5138
|
+
if (config === true) {
|
|
5139
|
+
const netConfig2 = getNetworkConfig(network);
|
|
5140
|
+
return { relays: [...netConfig2.groupRelays] };
|
|
5141
|
+
}
|
|
5142
|
+
if (typeof config === "object" && config.enabled === false) {
|
|
5143
|
+
return void 0;
|
|
5144
|
+
}
|
|
5145
|
+
const netConfig = getNetworkConfig(network);
|
|
5146
|
+
return {
|
|
5147
|
+
relays: config.relays ?? [...netConfig.groupRelays]
|
|
5148
|
+
};
|
|
5149
|
+
}
|
|
5205
5150
|
|
|
5206
5151
|
// impl/browser/index.ts
|
|
5207
5152
|
if (typeof globalThis.Buffer === "undefined") {
|
|
@@ -5267,8 +5212,10 @@ function createBrowserProviders(config) {
|
|
|
5267
5212
|
debug: config?.tokenSync?.ipfs?.useDht
|
|
5268
5213
|
// reuse debug-like flag
|
|
5269
5214
|
}) : void 0;
|
|
5215
|
+
const groupChat = resolveGroupChatConfig(network, config?.groupChat);
|
|
5270
5216
|
return {
|
|
5271
5217
|
storage,
|
|
5218
|
+
groupChat,
|
|
5272
5219
|
transport: createNostrTransportProvider({
|
|
5273
5220
|
relays: transportConfig.relays,
|
|
5274
5221
|
timeout: transportConfig.timeout,
|