@glyphteck/veyl 0.35.0 → 0.41.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/cli.js +411 -159
- package/dist/index.js +411 -159
- package/docs/validation.md +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6227,7 +6227,7 @@ var init_config = __esm(() => {
|
|
|
6227
6227
|
LOCAL_PROFILE_CACHE_MAX_AGE_MS = 30 * DAY_MS;
|
|
6228
6228
|
LOCAL_AVATAR_CACHE_MAX_BYTES = 128 * MIB_BYTES;
|
|
6229
6229
|
LOCAL_AVATAR_CACHE_MAX_AGE_MS = 30 * DAY_MS;
|
|
6230
|
-
AVATAR_IMAGE_MAX_BYTES =
|
|
6230
|
+
AVATAR_IMAGE_MAX_BYTES = 256 * KIB_BYTES;
|
|
6231
6231
|
CHAT_READY_DOWNLOAD_MAX_BYTES = 8 * MIB_BYTES;
|
|
6232
6232
|
CHAT_MESSAGE_FILE_CACHE_MAX_BYTES = 64 * MIB_BYTES;
|
|
6233
6233
|
CHAT_UNSAVED_TTL_MS = CHAT_UNSAVED_TTL_DAYS * DAY_MS;
|
|
@@ -106368,18 +106368,13 @@ var init_values = __esm(() => {
|
|
|
106368
106368
|
|
|
106369
106369
|
// ../../shared/avatar.js
|
|
106370
106370
|
function readAvatarVersion(value) {
|
|
106371
|
-
|
|
106372
|
-
|
|
106373
|
-
}
|
|
106374
|
-
const version = Number(value);
|
|
106375
|
-
return Number.isSafeInteger(version) && version >= 0 ? version : null;
|
|
106376
|
-
}
|
|
106377
|
-
function avatarUrlWithVersion(url, version) {
|
|
106378
|
-
if (!url)
|
|
106379
|
-
return null;
|
|
106380
|
-
return version == null ? url : `${url}${url.includes("?") ? "&" : "?"}v=${encodeURIComponent(String(version))}`;
|
|
106371
|
+
const version = typeof value === "string" ? value.trim().toLowerCase() : "";
|
|
106372
|
+
return AVATAR_VERSION_RE.test(version) ? version : null;
|
|
106381
106373
|
}
|
|
106382
|
-
var
|
|
106374
|
+
var AVATAR_VERSION_RE;
|
|
106375
|
+
var init_avatar = __esm(() => {
|
|
106376
|
+
AVATAR_VERSION_RE = /^[0-9a-f]{64}$/;
|
|
106377
|
+
});
|
|
106383
106378
|
|
|
106384
106379
|
// ../../shared/moderation.js
|
|
106385
106380
|
function banUntilMs(ban) {
|
|
@@ -106657,11 +106652,16 @@ function createUser({ cloud, network, avatarCache = null, diag = null, onSession
|
|
|
106657
106652
|
markDiag(diag, "user.avatar.fetch.start", { force: !!force, persist: !!persist, hasVersion: avatarVersion != null });
|
|
106658
106653
|
try {
|
|
106659
106654
|
const promise = (async () => {
|
|
106660
|
-
|
|
106661
|
-
|
|
106662
|
-
|
|
106655
|
+
if (persist && avatarVersion != null && avatarCache && typeof cloud.peer.avatar.read === "function") {
|
|
106656
|
+
try {
|
|
106657
|
+
const bytes = await cloud.peer.avatar.read(uid, { version: avatarVersion });
|
|
106658
|
+
const cachedAvatar = await writeCachedAvatar(uid, { version: avatarVersion, bytes });
|
|
106659
|
+
if (cachedAvatar) {
|
|
106660
|
+
return cachedAvatar;
|
|
106661
|
+
}
|
|
106662
|
+
} catch {}
|
|
106663
106663
|
}
|
|
106664
|
-
return
|
|
106664
|
+
return cloud.peer.avatar.url(uid, { version: avatarVersion });
|
|
106665
106665
|
})().then((nextAvatar) => {
|
|
106666
106666
|
markDone(diag, "user.avatar.fetch", startedAt, { found: !!nextAvatar, hasVersion: avatarVersion != null });
|
|
106667
106667
|
if (!nextAvatar || avatarFetch.uid !== uid || avatarFetch.key !== key) {
|
|
@@ -107001,10 +107001,12 @@ function createUser({ cloud, network, avatarCache = null, diag = null, onSession
|
|
|
107001
107001
|
}
|
|
107002
107002
|
function refetchAvatar(options = {}) {
|
|
107003
107003
|
const requestedVersion = readAvatarVersion(options?.version);
|
|
107004
|
-
const
|
|
107005
|
-
|
|
107006
|
-
|
|
107007
|
-
|
|
107004
|
+
const nextVersion = requestedVersion ?? state.avatarVersion;
|
|
107005
|
+
return fetchAvatar(state.uid, {
|
|
107006
|
+
force: options?.force === true || state.avatarVersion !== nextVersion || !state.avatar,
|
|
107007
|
+
persist: options?.persist !== false,
|
|
107008
|
+
version: nextVersion
|
|
107009
|
+
});
|
|
107008
107010
|
}
|
|
107009
107011
|
function setNetwork(nextNetwork) {
|
|
107010
107012
|
if (activeNetwork === nextNetwork)
|
|
@@ -109422,7 +109424,7 @@ function sameSigningKeys(left, right) {
|
|
|
109422
109424
|
function sameChatShape(a, b) {
|
|
109423
109425
|
if (!a || !b)
|
|
109424
109426
|
return a === b;
|
|
109425
|
-
return a.id === b.id && a.protocol === b.protocol && a.linkId === b.linkId && a.entryId === b.entryId && a.peerChatPK === b.peerChatPK && a.peerUid === b.peerUid && sameSigningKeys(a.signingKeysByChatKey, b.signingKeysByChatKey) && a.ts === b.ts && a.startMs === b.startMs && a.unseen === b.unseen && a.settings?.retention === b.settings?.retention && sameChatPreview(a.preview, b.preview);
|
|
109427
|
+
return a.id === b.id && a.protocol === b.protocol && a.linkId === b.linkId && a.entryId === b.entryId && a.peerChatPK === b.peerChatPK && a.peerUid === b.peerUid && sameSigningKeys(a.signingKeysByChatKey, b.signingKeysByChatKey) && a.signerShared === b.signerShared && a.ts === b.ts && a.startMs === b.startMs && a.unseen === b.unseen && a.settings?.retention === b.settings?.retention && sameChatPreview(a.preview, b.preview);
|
|
109426
109428
|
}
|
|
109427
109429
|
function sameChats(prev, next) {
|
|
109428
109430
|
if (prev.length !== next.length)
|
|
@@ -109781,8 +109783,10 @@ function emptyPayload() {
|
|
|
109781
109783
|
chatsById: {},
|
|
109782
109784
|
profilesByUid: {},
|
|
109783
109785
|
mediaByKey: {},
|
|
109786
|
+
walletBalance: null,
|
|
109784
109787
|
resumeRoute: null,
|
|
109785
|
-
lastCameraFacing: null
|
|
109788
|
+
lastCameraFacing: null,
|
|
109789
|
+
cloaked: false
|
|
109786
109790
|
};
|
|
109787
109791
|
}
|
|
109788
109792
|
function isObject3(value) {
|
|
@@ -109843,8 +109847,26 @@ function normalizePayload(value) {
|
|
|
109843
109847
|
chatsById: isObject3(input.chatsById) ? input.chatsById : {},
|
|
109844
109848
|
profilesByUid: isObject3(input.profilesByUid) ? input.profilesByUid : {},
|
|
109845
109849
|
mediaByKey: isObject3(input.mediaByKey) ? input.mediaByKey : {},
|
|
109850
|
+
walletBalance: cleanWalletBalance(input.walletBalance),
|
|
109846
109851
|
resumeRoute: cleanResumeRoute(input.resumeRoute),
|
|
109847
|
-
lastCameraFacing: cleanCameraFacing(input.lastCameraFacing)
|
|
109852
|
+
lastCameraFacing: cleanCameraFacing(input.lastCameraFacing),
|
|
109853
|
+
cloaked: input.cloaked === true
|
|
109854
|
+
};
|
|
109855
|
+
}
|
|
109856
|
+
function cleanWalletBalance(value) {
|
|
109857
|
+
if (!isObject3(value))
|
|
109858
|
+
return null;
|
|
109859
|
+
const walletPK = cleanText(value.walletPK).toLowerCase();
|
|
109860
|
+
const network = cleanText(value.network).toLowerCase();
|
|
109861
|
+
const balance = Number(value.balance);
|
|
109862
|
+
if (!walletPK || !network || !Number.isSafeInteger(balance) || balance < 0) {
|
|
109863
|
+
return null;
|
|
109864
|
+
}
|
|
109865
|
+
return {
|
|
109866
|
+
walletPK,
|
|
109867
|
+
network,
|
|
109868
|
+
balance,
|
|
109869
|
+
savedAt: Number.isFinite(value.savedAt) ? value.savedAt : 0
|
|
109848
109870
|
};
|
|
109849
109871
|
}
|
|
109850
109872
|
function cleanResumeRoute(route) {
|
|
@@ -110290,8 +110312,8 @@ function stateFromPayload(payload, { chatId, selfChatPublicKey, peerChatPublicKe
|
|
|
110290
110312
|
if (!cleanOlder.length && !cleanLive.length) {
|
|
110291
110313
|
return { rejectReason: "empty-message-cache" };
|
|
110292
110314
|
}
|
|
110293
|
-
const historyStartReached = payload.historyStartReached === true
|
|
110294
|
-
const payloadHasOlder =
|
|
110315
|
+
const historyStartReached = payload.historyStartReached === true;
|
|
110316
|
+
const payloadHasOlder = payload.hasOlder === true || payload.truncated === true;
|
|
110295
110317
|
const partialOlderThan = partial ? markerFromMessage(cleanOlder[0]) : null;
|
|
110296
110318
|
return {
|
|
110297
110319
|
historyMessages: cleanOlder,
|
|
@@ -110436,7 +110458,7 @@ function writeCachedMessageState(cache, { stateVersion = null, chatId, selfChatP
|
|
|
110436
110458
|
signingKeysVersion: cleanText(signingKeysVersion),
|
|
110437
110459
|
savedAt: Date.now(),
|
|
110438
110460
|
hasOlder: nextHasOlder === true || compacted.truncated,
|
|
110439
|
-
historyStartReached: nextHistoryStartReached === true
|
|
110461
|
+
historyStartReached: nextHistoryStartReached === true,
|
|
110440
110462
|
olderThan: serializeMarker(storedOlderThan),
|
|
110441
110463
|
olderLoaded: nextOlderLoaded === true || compacted.historyMessages.length > 0,
|
|
110442
110464
|
latestServerPage: batchFromLive(compacted.latestMessages, expiredKeys, deletedKeys, nextServerBatch),
|
|
@@ -110695,6 +110717,36 @@ var init_chats2 = __esm(() => {
|
|
|
110695
110717
|
"use client";
|
|
110696
110718
|
});
|
|
110697
110719
|
|
|
110720
|
+
// ../../shared/cache/localdata/balance.js
|
|
110721
|
+
function normalizedBalance(value) {
|
|
110722
|
+
const balance = Number(value);
|
|
110723
|
+
return Number.isSafeInteger(balance) && balance >= 0 ? balance : null;
|
|
110724
|
+
}
|
|
110725
|
+
function writeCachedWalletBalance(cache, { walletPK = null, network = null, balance = null } = {}) {
|
|
110726
|
+
const nextWalletPK = lowerText(walletPK);
|
|
110727
|
+
const nextNetwork = lowerText(network);
|
|
110728
|
+
const nextBalance = normalizedBalance(balance);
|
|
110729
|
+
if (!cache || !nextWalletPK || !nextNetwork || nextBalance == null) {
|
|
110730
|
+
return Promise.resolve(false);
|
|
110731
|
+
}
|
|
110732
|
+
const current = cache.read?.()?.walletBalance;
|
|
110733
|
+
if (sameText(current?.walletPK, nextWalletPK) && sameText(current?.network, nextNetwork) && normalizedBalance(current?.balance) === nextBalance) {
|
|
110734
|
+
return Promise.resolve(false);
|
|
110735
|
+
}
|
|
110736
|
+
return cache.patch((draft) => {
|
|
110737
|
+
draft.walletBalance = {
|
|
110738
|
+
walletPK: nextWalletPK,
|
|
110739
|
+
network: nextNetwork,
|
|
110740
|
+
balance: nextBalance,
|
|
110741
|
+
savedAt: Date.now()
|
|
110742
|
+
};
|
|
110743
|
+
return draft;
|
|
110744
|
+
}).then(() => true);
|
|
110745
|
+
}
|
|
110746
|
+
var init_balance = __esm(() => {
|
|
110747
|
+
"use client";
|
|
110748
|
+
});
|
|
110749
|
+
|
|
110698
110750
|
// ../../shared/cache/localdata/profiles.js
|
|
110699
110751
|
function isUsableProfile(profile, now = Date.now()) {
|
|
110700
110752
|
if (!profile?.uid || !profile.walletPK && !profile.chatPK) {
|
|
@@ -110935,24 +110987,26 @@ async function readCachedTransferHeadState(cache, { walletPK = null } = {}) {
|
|
|
110935
110987
|
const stored = cache ? await cache.readPart(TX_HEAD_PART).catch(() => null) : null;
|
|
110936
110988
|
return stateFromPayload2(stored, { walletPK, source: "head" });
|
|
110937
110989
|
}
|
|
110938
|
-
function
|
|
110939
|
-
if (!
|
|
110940
|
-
return
|
|
110990
|
+
function cachedTransferPayloads({ transfers, walletPK = null, serverEndReached = false, historyCount = null, nextOffset = null, oldestTxMs = null } = {}) {
|
|
110991
|
+
if (!Array.isArray(transfers)) {
|
|
110992
|
+
return null;
|
|
110941
110993
|
}
|
|
110942
110994
|
const nextWalletPK = lowerText(walletPK);
|
|
110943
110995
|
if (!nextWalletPK) {
|
|
110944
|
-
return
|
|
110996
|
+
return null;
|
|
110945
110997
|
}
|
|
110946
110998
|
const visible = [...transfers].filter((tx) => tx?.id && isVisibleTransfer(tx) && transferBelongsToWallet(tx, nextWalletPK)).sort((a, b) => txCreatedMs(b) - txCreatedMs(a));
|
|
110947
110999
|
const sorted2 = visible.slice(0, Math.max(1, WALLET_TRANSFER_CACHE_LIMIT)).map(jsonClean);
|
|
110948
111000
|
const capped = sorted2.length < visible.length;
|
|
111001
|
+
const knownHistoryCount = Math.max(sorted2.length, Math.floor(Number(historyCount) || 0));
|
|
111002
|
+
const complete = serverEndReached === true && !capped && sorted2.length >= knownHistoryCount;
|
|
110949
111003
|
const fullPayload = {
|
|
110950
111004
|
version: CACHE_VERSION,
|
|
110951
111005
|
walletPK: nextWalletPK,
|
|
110952
|
-
serverEndReached:
|
|
110953
|
-
historyCount:
|
|
111006
|
+
serverEndReached: complete,
|
|
111007
|
+
historyCount: knownHistoryCount,
|
|
110954
111008
|
nextOffset: Number.isFinite(nextOffset) ? nextOffset : sorted2.length,
|
|
110955
|
-
oldestTxMs:
|
|
111009
|
+
oldestTxMs: complete && Number.isFinite(oldestTxMs) ? oldestTxMs : null,
|
|
110956
111010
|
savedAt: Date.now(),
|
|
110957
111011
|
transfers: sorted2
|
|
110958
111012
|
};
|
|
@@ -110961,7 +111015,24 @@ function writeCachedTransferState(cache, { transfers, walletPK = null, serverEnd
|
|
|
110961
111015
|
...fullPayload,
|
|
110962
111016
|
transfers: headTransfers
|
|
110963
111017
|
};
|
|
110964
|
-
return
|
|
111018
|
+
return { fullPayload, headPayload };
|
|
111019
|
+
}
|
|
111020
|
+
function writeCachedTransferHeadState(cache, state = {}) {
|
|
111021
|
+
if (!cache) {
|
|
111022
|
+
return Promise.resolve(false);
|
|
111023
|
+
}
|
|
111024
|
+
const payloads = cachedTransferPayloads(state);
|
|
111025
|
+
return payloads ? cache.writePart(TX_HEAD_PART, payloads.headPayload) : Promise.resolve(false);
|
|
111026
|
+
}
|
|
111027
|
+
function writeCachedTransferState(cache, state = {}) {
|
|
111028
|
+
if (!cache) {
|
|
111029
|
+
return Promise.resolve(false);
|
|
111030
|
+
}
|
|
111031
|
+
const payloads = cachedTransferPayloads(state);
|
|
111032
|
+
if (!payloads) {
|
|
111033
|
+
return Promise.resolve(false);
|
|
111034
|
+
}
|
|
111035
|
+
return Promise.all([cache.writePart(TX_HEAD_PART, payloads.headPayload), cache.writePart(TX_PART, payloads.fullPayload)]).then((results) => results.some(Boolean));
|
|
110965
111036
|
}
|
|
110966
111037
|
var TX_PART = "wallet-transfers", TX_HEAD_PART = "wallet-transfers-head", CACHE_VERSION = 2, CACHE_HEAD_LIMIT;
|
|
110967
111038
|
var init_transfers = __esm(() => {
|
|
@@ -111437,6 +111508,7 @@ var init_vault2 = __esm(() => {
|
|
|
111437
111508
|
// ../../shared/cache/localdata.js
|
|
111438
111509
|
var init_localdata = __esm(() => {
|
|
111439
111510
|
init_chats2();
|
|
111511
|
+
init_balance();
|
|
111440
111512
|
init_media();
|
|
111441
111513
|
init_messages2();
|
|
111442
111514
|
init_profiles();
|
|
@@ -111514,7 +111586,8 @@ function makeOwnChatEntry(pair, fields = {}) {
|
|
|
111514
111586
|
preview: fields.preview || null,
|
|
111515
111587
|
saved: fields.saved || null,
|
|
111516
111588
|
readMs: Number.isFinite(fields.readMs) ? fields.readMs : null,
|
|
111517
|
-
startMs: Number.isFinite(fields.startMs) ? fields.startMs : null
|
|
111589
|
+
startMs: Number.isFinite(fields.startMs) ? fields.startMs : null,
|
|
111590
|
+
signerShared: fields.signerShared === true
|
|
111518
111591
|
};
|
|
111519
111592
|
}
|
|
111520
111593
|
var CHAT_ENTRY_VERSION = 1;
|
|
@@ -112279,7 +112352,25 @@ async function setChatRead(cloud, uid, chatPrivKey, chatId, readMs, options = {}
|
|
|
112279
112352
|
body: await sealOwnChatEntry(chatPrivKey, entryId, {
|
|
112280
112353
|
...entry,
|
|
112281
112354
|
readMs: Math.max(currentReadMs, nextReadMs),
|
|
112282
|
-
...hasPreviewPatch ? { preview: preview2 || null } : {}
|
|
112355
|
+
...hasPreviewPatch ? { preview: preview2 || null } : {},
|
|
112356
|
+
...options.signerShared === true ? { signerShared: true } : {}
|
|
112357
|
+
})
|
|
112358
|
+
});
|
|
112359
|
+
return true;
|
|
112360
|
+
}
|
|
112361
|
+
async function setChatSignerShared(cloud, uid, chatPrivKey, chatId) {
|
|
112362
|
+
if (!cloud || !uid || !chatPrivKey || !chatId) {
|
|
112363
|
+
return false;
|
|
112364
|
+
}
|
|
112365
|
+
const entryId = ownChatEntryId(chatPrivKey, chatId);
|
|
112366
|
+
const entry = await readOwnEntry(cloud, uid, chatPrivKey, entryId);
|
|
112367
|
+
if (!entry?.chatId || entry.signerShared === true) {
|
|
112368
|
+
return entry?.signerShared === true;
|
|
112369
|
+
}
|
|
112370
|
+
await cloud.user.chats.write(uid, entryId, {
|
|
112371
|
+
body: await sealOwnChatEntry(chatPrivKey, entryId, {
|
|
112372
|
+
...entry,
|
|
112373
|
+
signerShared: true
|
|
112283
112374
|
})
|
|
112284
112375
|
});
|
|
112285
112376
|
return true;
|
|
@@ -112322,7 +112413,8 @@ async function ownEntryWrite(cloud, uid, chatPrivKey, pair, fields = {}) {
|
|
|
112322
112413
|
preview: fields.preview || existing?.preview,
|
|
112323
112414
|
saved: existing?.saved || null,
|
|
112324
112415
|
readMs: existing?.readMs,
|
|
112325
|
-
startMs: existing?.startMs
|
|
112416
|
+
startMs: existing?.startMs,
|
|
112417
|
+
signerShared: fields.signerShared === true || existing?.signerShared === true
|
|
112326
112418
|
});
|
|
112327
112419
|
const tsMs = timestampMs(fields.ts, null);
|
|
112328
112420
|
return {
|
|
@@ -112417,10 +112509,22 @@ async function sendMsg(cloud, senderPubkey, senderPrivkey, receiverChatPK, messa
|
|
|
112417
112509
|
messageId,
|
|
112418
112510
|
message: msgData,
|
|
112419
112511
|
ownerEntry,
|
|
112420
|
-
inbox: ping ? { recipientUid: recipientProfile?.uid, ping } : null,
|
|
112512
|
+
inbox: ping ? { recipientUid: recipientProfile?.uid, ping, notify: options?.notify !== false } : null,
|
|
112421
112513
|
onCommitted: typeof options?.onCommitted === "function" ? (committed) => options.onCommitted({ ...committed, message: sentMessage, preview: preview2 }) : undefined
|
|
112422
112514
|
});
|
|
112423
|
-
|
|
112515
|
+
const delivered = options?.ping === true ? !!ping && write?.delivered !== false : write?.delivered !== false;
|
|
112516
|
+
if (ping && delivered && ownerEntry && options?.ownEntry?.signerShared !== true) {
|
|
112517
|
+
await setChatSignerShared(cloud, cleanText(options?.senderUid), senderPrivkey, chatId).catch(() => false);
|
|
112518
|
+
}
|
|
112519
|
+
return {
|
|
112520
|
+
chatId,
|
|
112521
|
+
msgId: messageId,
|
|
112522
|
+
cid: head.cid,
|
|
112523
|
+
message: sentMessage,
|
|
112524
|
+
preview: preview2,
|
|
112525
|
+
delivered,
|
|
112526
|
+
...write?.skipped ? { skipped: true } : {}
|
|
112527
|
+
};
|
|
112424
112528
|
});
|
|
112425
112529
|
}
|
|
112426
112530
|
async function sendReadReceipt(cloud, senderPubkey, senderPrivkey, receiverChatPK, target, options = {}) {
|
|
@@ -112429,7 +112533,13 @@ async function sendReadReceipt(cloud, senderPubkey, senderPrivkey, receiverChatP
|
|
|
112429
112533
|
cid: makeCid(),
|
|
112430
112534
|
s: senderPubkey
|
|
112431
112535
|
};
|
|
112432
|
-
return sendMsg(cloud, senderPubkey, senderPrivkey, receiverChatPK, receipt, {
|
|
112536
|
+
return sendMsg(cloud, senderPubkey, senderPrivkey, receiverChatPK, receipt, {
|
|
112537
|
+
...options,
|
|
112538
|
+
updatePreview: false,
|
|
112539
|
+
ping: options?.ping === true,
|
|
112540
|
+
pingKind: "read",
|
|
112541
|
+
notify: false
|
|
112542
|
+
});
|
|
112433
112543
|
}
|
|
112434
112544
|
async function sendReaction(cloud, senderPubkey, senderPrivkey, receiverChatPK, target, emoji, options = {}) {
|
|
112435
112545
|
const reaction = {
|
|
@@ -113046,7 +113156,7 @@ function messageExpiryGroups(messages, selfChatPublicKey, seenAt) {
|
|
|
113046
113156
|
{ messages: day, expiresAt: seenAt + AFTER_SEEN_MS }
|
|
113047
113157
|
].filter((group) => group.messages.length);
|
|
113048
113158
|
}
|
|
113049
|
-
function createChatSeen({ cloud, uid, chatBanned, chatPK, chatPrivateKey, localCache, pendingReadRef, readCacheRef, readWriteInterval, getChatRetention, setChats, diag }) {
|
|
113159
|
+
function createChatSeen({ cloud, uid, chatBanned, chatPK, chatPrivateKey, localCache, pendingReadRef, readCacheRef, readWriteInterval, getChatRetention, sendOptionsForPeer, setChats, diag }) {
|
|
113050
113160
|
const scheduleRead = (chatId, message, previewMs, sendReceipt, expiryMessages = []) => {
|
|
113051
113161
|
scheduleReadWrite({
|
|
113052
113162
|
pendingRead: pendingReadRef.current,
|
|
@@ -113057,24 +113167,37 @@ function createChatSeen({ cloud, uid, chatBanned, chatPK, chatPrivateKey, localC
|
|
|
113057
113167
|
expiryMessages: sendReceipt ? expiryMessages : [],
|
|
113058
113168
|
interval: readWriteInterval,
|
|
113059
113169
|
write: async (pending) => {
|
|
113170
|
+
let receiptError = null;
|
|
113171
|
+
let receiptResult = null;
|
|
113172
|
+
let introduceSigner = false;
|
|
113173
|
+
if (pending.receipt) {
|
|
113174
|
+
const sendOptions = sendOptionsForPeer(pending.receipt.peerChatPK);
|
|
113175
|
+
introduceSigner = sendOptions?.signerShared !== true;
|
|
113176
|
+
try {
|
|
113177
|
+
receiptResult = await sendReadReceipt(cloud, chatPK, chatPrivateKey, pending.receipt.peerChatPK, pending.receipt.target, {
|
|
113178
|
+
chatId,
|
|
113179
|
+
retention: getChatRetention(chatId),
|
|
113180
|
+
senderUid: uid,
|
|
113181
|
+
receiverUid: sendOptions?.receiverUid,
|
|
113182
|
+
ping: introduceSigner
|
|
113183
|
+
});
|
|
113184
|
+
} catch (error) {
|
|
113185
|
+
receiptError = error;
|
|
113186
|
+
}
|
|
113187
|
+
}
|
|
113060
113188
|
const writes = [
|
|
113061
113189
|
setChatRead(cloud, uid, chatPrivateKey, chatId, pending.previewMs, {
|
|
113062
|
-
preview: (currentPreview) => withChatPreviewOpened(currentPreview, pending.message, pending.previewMs, chatPK) || currentPreview
|
|
113190
|
+
preview: (currentPreview) => withChatPreviewOpened(currentPreview, pending.message, pending.previewMs, chatPK) || currentPreview,
|
|
113191
|
+
signerShared: introduceSigner && receiptResult?.delivered === true
|
|
113063
113192
|
})
|
|
113064
113193
|
];
|
|
113065
113194
|
if (pending.receipt) {
|
|
113066
|
-
writes.push(sendReadReceipt(cloud, chatPK, chatPrivateKey, pending.receipt.peerChatPK, pending.receipt.target, {
|
|
113067
|
-
chatId,
|
|
113068
|
-
retention: getChatRetention(chatId),
|
|
113069
|
-
senderUid: uid
|
|
113070
|
-
}));
|
|
113071
113195
|
for (const group of messageExpiryGroups(pending.expiryMessages, chatPK, pending.expirySeenAt)) {
|
|
113072
113196
|
writes.push(setMessageExpiry(cloud, chatId, group.messages, group.expiresAt));
|
|
113073
113197
|
}
|
|
113074
113198
|
}
|
|
113075
113199
|
const results = await Promise.allSettled(writes);
|
|
113076
113200
|
const ownerError = results[0]?.status === "rejected" ? results[0].reason : null;
|
|
113077
|
-
const receiptError = pending.receipt && results[1]?.status === "rejected" ? results[1].reason : null;
|
|
113078
113201
|
if (ownerError) {
|
|
113079
113202
|
markError(diag, "chat.read.state.write", Date.now(), ownerError);
|
|
113080
113203
|
}
|
|
@@ -113082,7 +113205,7 @@ function createChatSeen({ cloud, uid, chatBanned, chatPK, chatPrivateKey, localC
|
|
|
113082
113205
|
readCacheRef.current.delete(chatId);
|
|
113083
113206
|
markError(diag, "chat.read.receipt.write", Date.now(), receiptError);
|
|
113084
113207
|
}
|
|
113085
|
-
for (const result of results.slice(
|
|
113208
|
+
for (const result of results.slice(1)) {
|
|
113086
113209
|
if (result?.status === "rejected") {
|
|
113087
113210
|
markError(diag, "chat.message.expiry.write", Date.now(), result.reason);
|
|
113088
113211
|
}
|
|
@@ -115133,7 +115256,11 @@ function readableEntryWindow(entries, pageSize, chatPK, peerChatPK, options = {}
|
|
|
115133
115256
|
const limitCount = positiveInt(pageSize, MSG_BATCH_SIZE);
|
|
115134
115257
|
const projectedEntries = readableProjectedEntries(source, chatPK, peerChatPK, options);
|
|
115135
115258
|
if (!projectedEntries.length) {
|
|
115136
|
-
return {
|
|
115259
|
+
return {
|
|
115260
|
+
count: 0,
|
|
115261
|
+
entries: source.filter((entry) => isProjectionSupportMsg(entry?.message)),
|
|
115262
|
+
start: 0
|
|
115263
|
+
};
|
|
115137
115264
|
}
|
|
115138
115265
|
const indexes = projectedEntries.map((entry) => entry.index);
|
|
115139
115266
|
const projectedByIndex = new Map(projectedEntries.map((entry) => [entry.index, entry.message]));
|
|
@@ -117493,6 +117620,7 @@ function chatFromPing(ping, entryId, existing, preview2, userChatPK, ms, options
|
|
|
117493
117620
|
saved: existing?.saved || null,
|
|
117494
117621
|
readMs,
|
|
117495
117622
|
startMs,
|
|
117623
|
+
signerShared: existing?.signerShared === true,
|
|
117496
117624
|
preview: visiblePreview,
|
|
117497
117625
|
ts,
|
|
117498
117626
|
unseen: visiblePreview ? isChatUnseenForUser({ preview: visiblePreview, readMs }, userChatPK) : false
|
|
@@ -117551,7 +117679,8 @@ async function savePing(cloud, uid, userChatPK, userPrivKey, ping, options = {})
|
|
|
117551
117679
|
settings: chatSettingsFromPreview(existing?.settings, preview2),
|
|
117552
117680
|
preview: preview2 || existing?.preview,
|
|
117553
117681
|
readMs: existing?.readMs,
|
|
117554
|
-
startMs: existing ? existing.startMs : timestampMs(options.startPreview?.ts ?? preview2?.ts, null, { positive: true })
|
|
117682
|
+
startMs: existing ? existing.startMs : timestampMs(options.startPreview?.ts ?? preview2?.ts, null, { positive: true }),
|
|
117683
|
+
signerShared: existing?.signerShared === true
|
|
117555
117684
|
});
|
|
117556
117685
|
const body = await sealOwnChatEntry(userPrivKey, entryId, entry);
|
|
117557
117686
|
const record = { body };
|
|
@@ -117561,14 +117690,16 @@ async function savePing(cloud, uid, userChatPK, userPrivKey, ping, options = {})
|
|
|
117561
117690
|
await cloud.user.chats.write(uid, entryId, record);
|
|
117562
117691
|
return true;
|
|
117563
117692
|
}
|
|
117564
|
-
function chatWithReadPreview(existing, preview2, userChatPK) {
|
|
117565
|
-
if (!existing?.id
|
|
117693
|
+
function chatWithReadPreview(existing, preview2, userChatPK, fields = {}) {
|
|
117694
|
+
if (!existing?.id) {
|
|
117566
117695
|
return null;
|
|
117567
117696
|
}
|
|
117568
117697
|
return {
|
|
117569
117698
|
...existing,
|
|
117570
|
-
|
|
117571
|
-
|
|
117699
|
+
signingKeysByChatKey: fields.signingKeysByChatKey || existing.signingKeysByChatKey,
|
|
117700
|
+
peerUid: fields.peerUid || existing.peerUid,
|
|
117701
|
+
preview: preview2 || existing.preview,
|
|
117702
|
+
unseen: preview2 ? isChatUnseenForUser({ preview: preview2, readMs: existing.readMs }, userChatPK) : existing.unseen
|
|
117572
117703
|
};
|
|
117573
117704
|
}
|
|
117574
117705
|
function patchReadPingPreview(existing, receiptPreview, userChatPK) {
|
|
@@ -117649,6 +117780,8 @@ async function processInbox(cloud, uid, userChatPK, userPrivKey, options = {}) {
|
|
|
117649
117780
|
let current = chatsById.get(group.chatId) || null;
|
|
117650
117781
|
let wrote = false;
|
|
117651
117782
|
let handled = false;
|
|
117783
|
+
const identityPing = group.message?.ping || group.read?.ping || group.delete?.ping;
|
|
117784
|
+
const peerUid2 = await resolvePingUid(cloud, identityPing?.payload);
|
|
117652
117785
|
if (group.message) {
|
|
117653
117786
|
const item = group.message;
|
|
117654
117787
|
const entryId = ownChatEntryId(userPrivKey, item.chatId);
|
|
@@ -117669,7 +117802,8 @@ async function processInbox(cloud, uid, userChatPK, userPrivKey, options = {}) {
|
|
|
117669
117802
|
signingKeysByChatKey,
|
|
117670
117803
|
preview: preview2,
|
|
117671
117804
|
startPreview,
|
|
117672
|
-
tsMs: item.ms
|
|
117805
|
+
tsMs: item.ms,
|
|
117806
|
+
peerUid: peerUid2
|
|
117673
117807
|
});
|
|
117674
117808
|
}
|
|
117675
117809
|
if (group.read) {
|
|
@@ -117679,22 +117813,24 @@ async function processInbox(cloud, uid, userChatPK, userPrivKey, options = {}) {
|
|
|
117679
117813
|
const signingKeysByChatKey = pingSigningKeys(item.ping, existing);
|
|
117680
117814
|
const receiptPreview = await readPingMsg(cloud, userChatPK, userPrivKey, item.ping, signingKeysByChatKey);
|
|
117681
117815
|
const openedPreview = patchReadPingPreview(existing, receiptPreview, userChatPK);
|
|
117682
|
-
const chat = chatWithReadPreview(current, openedPreview, userChatPK
|
|
117816
|
+
const chat = chatWithReadPreview(current || existing, openedPreview, userChatPK, {
|
|
117817
|
+
signingKeysByChatKey,
|
|
117818
|
+
peerUid: peerUid2
|
|
117819
|
+
});
|
|
117683
117820
|
handled = true;
|
|
117684
|
-
if (
|
|
117685
|
-
|
|
117686
|
-
|
|
117687
|
-
|
|
117688
|
-
options.onPingChat?.(chat);
|
|
117689
|
-
}
|
|
117690
|
-
const writeExisting = chat || existing;
|
|
117691
|
-
wrote = await savePing(cloud, uid, userChatPK, userPrivKey, item.ping, {
|
|
117692
|
-
existing: writeExisting,
|
|
117693
|
-
signingKeysByChatKey,
|
|
117694
|
-
preview: openedPreview,
|
|
117695
|
-
writeTs: false
|
|
117696
|
-
}) || wrote;
|
|
117821
|
+
if (chat) {
|
|
117822
|
+
current = chat;
|
|
117823
|
+
chatsById.set(chat.id, chat);
|
|
117824
|
+
options.onPingChat?.(chat);
|
|
117697
117825
|
}
|
|
117826
|
+
const writeExisting = chat || existing;
|
|
117827
|
+
wrote = await savePing(cloud, uid, userChatPK, userPrivKey, item.ping, {
|
|
117828
|
+
existing: writeExisting,
|
|
117829
|
+
signingKeysByChatKey,
|
|
117830
|
+
preview: openedPreview || existing?.preview || null,
|
|
117831
|
+
writeTs: false,
|
|
117832
|
+
peerUid: peerUid2
|
|
117833
|
+
}) || wrote;
|
|
117698
117834
|
}
|
|
117699
117835
|
if (group.delete) {
|
|
117700
117836
|
const item = group.delete;
|
|
@@ -117715,7 +117851,8 @@ async function processInbox(cloud, uid, userChatPK, userPrivKey, options = {}) {
|
|
|
117715
117851
|
wrote = await savePing(cloud, uid, userChatPK, userPrivKey, item.ping, {
|
|
117716
117852
|
existing: writeExisting,
|
|
117717
117853
|
signingKeysByChatKey,
|
|
117718
|
-
preview: deletedPreview
|
|
117854
|
+
preview: deletedPreview,
|
|
117855
|
+
peerUid: peerUid2
|
|
117719
117856
|
}) || wrote;
|
|
117720
117857
|
}
|
|
117721
117858
|
}
|
|
@@ -118121,6 +118258,7 @@ async function decryptChatEntry(entryRecord, userChatPK, userPrivKey) {
|
|
|
118121
118258
|
saved: entry.saved || null,
|
|
118122
118259
|
readMs,
|
|
118123
118260
|
startMs,
|
|
118261
|
+
signerShared: entry.signerShared === true,
|
|
118124
118262
|
preview: visiblePreview,
|
|
118125
118263
|
ts,
|
|
118126
118264
|
unseen: visiblePreview ? isChatUnseenForUser({ preview: visiblePreview, readMs }, userChatPK) : false
|
|
@@ -118907,6 +119045,7 @@ function createChatList({
|
|
|
118907
119045
|
chatExists: !!peerChat?.id || hasServerChatForPeer(peerChatPK),
|
|
118908
119046
|
receiverUid: peerChat?.peerUid || "",
|
|
118909
119047
|
peerSigningPublicKey: peerChat?.signingKeysByChatKey?.[peerChatPK] || "",
|
|
119048
|
+
signerShared: peerChat?.signerShared === true,
|
|
118910
119049
|
ownEntry: peerChat?.entryId ? peerChat : null
|
|
118911
119050
|
};
|
|
118912
119051
|
};
|
|
@@ -119604,6 +119743,7 @@ function createChatSession({
|
|
|
119604
119743
|
readCacheRef,
|
|
119605
119744
|
readWriteInterval,
|
|
119606
119745
|
getChatRetention,
|
|
119746
|
+
sendOptionsForPeer,
|
|
119607
119747
|
setChats,
|
|
119608
119748
|
diag
|
|
119609
119749
|
});
|
|
@@ -120748,7 +120888,7 @@ function createPeersApi({ cloud, network, avatarCache = null }) {
|
|
|
120748
120888
|
}
|
|
120749
120889
|
if (avatarVersion != null && typeof cloud.peer.avatar.read === "function") {
|
|
120750
120890
|
try {
|
|
120751
|
-
const bytes = await cloud.peer.avatar.read(uid);
|
|
120891
|
+
const bytes = await cloud.peer.avatar.read(uid, { version: avatarVersion });
|
|
120752
120892
|
const cachedSource = await writeCachedAvatar(uid, avatarVersion, bytes);
|
|
120753
120893
|
if (cachedSource) {
|
|
120754
120894
|
return cachedSource;
|
|
@@ -121285,6 +121425,10 @@ function getSatsBalance(result) {
|
|
|
121285
121425
|
}
|
|
121286
121426
|
return satsBalance;
|
|
121287
121427
|
}
|
|
121428
|
+
function displayBalanceValue(value) {
|
|
121429
|
+
const balance = Number(value);
|
|
121430
|
+
return Number.isSafeInteger(balance) && balance >= 0 ? balance : null;
|
|
121431
|
+
}
|
|
121288
121432
|
function samePlainObject(a, b) {
|
|
121289
121433
|
if (a === b) {
|
|
121290
121434
|
return true;
|
|
@@ -121313,9 +121457,10 @@ function sameTokenBalances(a, b) {
|
|
|
121313
121457
|
}
|
|
121314
121458
|
return true;
|
|
121315
121459
|
}
|
|
121316
|
-
function createWalletBalance({ wallet, diag, onChange = null }) {
|
|
121460
|
+
function createWalletBalance({ wallet, diag, initialDisplayBalance = null, onBalance = null, onChange = null }) {
|
|
121317
121461
|
let snapshot = {
|
|
121318
121462
|
balance: null,
|
|
121463
|
+
displayBalance: displayBalanceValue(initialDisplayBalance),
|
|
121319
121464
|
satsBalance: null,
|
|
121320
121465
|
tokenBalances: new Map,
|
|
121321
121466
|
balanceReady: false,
|
|
@@ -121325,10 +121470,28 @@ function createWalletBalance({ wallet, diag, onChange = null }) {
|
|
|
121325
121470
|
snapshot = { ...snapshot, ...changes };
|
|
121326
121471
|
onChange?.();
|
|
121327
121472
|
};
|
|
121473
|
+
const publishDisplayBalance = (changes, value, trusted = false) => {
|
|
121474
|
+
const displayBalance = displayBalanceValue(value);
|
|
121475
|
+
if (displayBalance == null || !trusted && !snapshot.balanceReady) {
|
|
121476
|
+
return null;
|
|
121477
|
+
}
|
|
121478
|
+
if (!Object.is(snapshot.displayBalance, displayBalance)) {
|
|
121479
|
+
changes.displayBalance = displayBalance;
|
|
121480
|
+
}
|
|
121481
|
+
return displayBalance;
|
|
121482
|
+
};
|
|
121328
121483
|
const setBalance = (nextBalance) => {
|
|
121329
121484
|
const value = typeof nextBalance === "function" ? nextBalance(snapshot.balance) : nextBalance;
|
|
121485
|
+
const changes = {};
|
|
121330
121486
|
if (!Object.is(snapshot.balance, value)) {
|
|
121331
|
-
|
|
121487
|
+
changes.balance = value;
|
|
121488
|
+
}
|
|
121489
|
+
const displayBalance = publishDisplayBalance(changes, value);
|
|
121490
|
+
if (Object.keys(changes).length) {
|
|
121491
|
+
publish(changes);
|
|
121492
|
+
}
|
|
121493
|
+
if (displayBalance != null) {
|
|
121494
|
+
onBalance?.(displayBalance);
|
|
121332
121495
|
}
|
|
121333
121496
|
};
|
|
121334
121497
|
const setTokenBalances = (nextTokenBalances) => {
|
|
@@ -121337,12 +121500,13 @@ function createWalletBalance({ wallet, diag, onChange = null }) {
|
|
|
121337
121500
|
publish({ tokenBalances: new Map(source) });
|
|
121338
121501
|
}
|
|
121339
121502
|
};
|
|
121340
|
-
const setBalanceResult = (result) => {
|
|
121503
|
+
const setBalanceResult = (result, { ready = false } = {}) => {
|
|
121341
121504
|
const changes = {};
|
|
121342
121505
|
const nextBalance = getBalanceValue(result);
|
|
121343
121506
|
if (nextBalance != null && !Object.is(snapshot.balance, nextBalance)) {
|
|
121344
121507
|
changes.balance = nextBalance;
|
|
121345
121508
|
}
|
|
121509
|
+
const nextDisplayBalance = publishDisplayBalance(changes, nextBalance, true);
|
|
121346
121510
|
const nextSatsBalance = getSatsBalance(result);
|
|
121347
121511
|
if (nextSatsBalance && !samePlainObject(snapshot.satsBalance, nextSatsBalance)) {
|
|
121348
121512
|
changes.satsBalance = nextSatsBalance;
|
|
@@ -121351,9 +121515,15 @@ function createWalletBalance({ wallet, diag, onChange = null }) {
|
|
|
121351
121515
|
if (nextTokenBalances && !sameTokenBalances(snapshot.tokenBalances, nextTokenBalances)) {
|
|
121352
121516
|
changes.tokenBalances = new Map(nextTokenBalances);
|
|
121353
121517
|
}
|
|
121518
|
+
if (ready && !snapshot.balanceReady) {
|
|
121519
|
+
changes.balanceReady = true;
|
|
121520
|
+
}
|
|
121354
121521
|
if (Object.keys(changes).length) {
|
|
121355
121522
|
publish(changes);
|
|
121356
121523
|
}
|
|
121524
|
+
if (nextDisplayBalance != null) {
|
|
121525
|
+
onBalance?.(nextDisplayBalance);
|
|
121526
|
+
}
|
|
121357
121527
|
};
|
|
121358
121528
|
const setSatsBalanceResult = (nextSatsBalance) => {
|
|
121359
121529
|
if (!nextSatsBalance || typeof nextSatsBalance !== "object") {
|
|
@@ -121366,9 +121536,13 @@ function createWalletBalance({ wallet, diag, onChange = null }) {
|
|
|
121366
121536
|
if (nextSatsBalance.available != null && !Object.is(snapshot.balance, nextSatsBalance.available)) {
|
|
121367
121537
|
changes.balance = nextSatsBalance.available;
|
|
121368
121538
|
}
|
|
121539
|
+
const nextDisplayBalance = publishDisplayBalance(changes, nextSatsBalance.available);
|
|
121369
121540
|
if (Object.keys(changes).length) {
|
|
121370
121541
|
publish(changes);
|
|
121371
121542
|
}
|
|
121543
|
+
if (nextDisplayBalance != null) {
|
|
121544
|
+
onBalance?.(nextDisplayBalance);
|
|
121545
|
+
}
|
|
121372
121546
|
};
|
|
121373
121547
|
const getBalance = async () => {
|
|
121374
121548
|
if (!wallet) {
|
|
@@ -121382,7 +121556,7 @@ function createWalletBalance({ wallet, diag, onChange = null }) {
|
|
|
121382
121556
|
}
|
|
121383
121557
|
try {
|
|
121384
121558
|
const result = await wallet.getBalance();
|
|
121385
|
-
setBalanceResult(result);
|
|
121559
|
+
setBalanceResult(result, { ready: true });
|
|
121386
121560
|
markDone(diag, "wallet.balance", startedAt, { hasBalance: getBalanceValue(result) != null, hasSatsBalance: !!getSatsBalance(result), hasTokenBalances: !!getTokenBalances(result) });
|
|
121387
121561
|
} catch (error) {
|
|
121388
121562
|
markError(diag, "wallet.balance", startedAt, error);
|
|
@@ -121402,6 +121576,7 @@ function createWalletBalance({ wallet, diag, onChange = null }) {
|
|
|
121402
121576
|
const reset = () => {
|
|
121403
121577
|
snapshot = {
|
|
121404
121578
|
balance: null,
|
|
121579
|
+
displayBalance: null,
|
|
121405
121580
|
satsBalance: null,
|
|
121406
121581
|
tokenBalances: new Map,
|
|
121407
121582
|
balanceReady: false,
|
|
@@ -121418,7 +121593,7 @@ function createWalletBalance({ wallet, diag, onChange = null }) {
|
|
|
121418
121593
|
setSatsBalanceResult
|
|
121419
121594
|
};
|
|
121420
121595
|
}
|
|
121421
|
-
var
|
|
121596
|
+
var init_balance2 = () => {};
|
|
121422
121597
|
|
|
121423
121598
|
// ../../shared/wallet/deposits.js
|
|
121424
121599
|
async function getClaimableDepositUtxos(wallet, options = {}) {
|
|
@@ -123196,8 +123371,8 @@ function pendingTransfers(transfers = []) {
|
|
|
123196
123371
|
function pendingTransferIds(transfers = []) {
|
|
123197
123372
|
return pendingTransfers(transfers).map((tx) => String(tx.id));
|
|
123198
123373
|
}
|
|
123199
|
-
function
|
|
123200
|
-
return pendingTransfers(transfers).filter(
|
|
123374
|
+
function pendingIncomingTransfers(transfers = []) {
|
|
123375
|
+
return pendingTransfers(transfers).filter(isIncomingTransfer);
|
|
123201
123376
|
}
|
|
123202
123377
|
function uniqueIds(ids = []) {
|
|
123203
123378
|
return [...new Set((Array.isArray(ids) ? ids : [ids]).map((id) => String(id || "")).filter(Boolean))];
|
|
@@ -123292,7 +123467,7 @@ function adaptiveClaimBatchSize(maxBatchSize, queueDepth) {
|
|
|
123292
123467
|
}
|
|
123293
123468
|
return 1;
|
|
123294
123469
|
}
|
|
123295
|
-
function createWalletTransferSession({ wallet, walletPK, localCache, claimIncomingTransfers, pendingClaimBatchSize = null, eagerOutgoingStatusRefresh = false, eagerCacheHistory = true, transferStore, appState = null, deferBackgroundWork = null, backgroundSignal = null, diag }) {
|
|
123470
|
+
function createWalletTransferSession({ wallet, walletPK, localCache, claimIncomingTransfers, pendingClaimBatchSize = null, eagerOutgoingStatusRefresh = false, eagerCacheHistory = true, transferStore, appState = null, deferBackgroundWork = null, backgroundSignal = null, refreshBalance = null, diag }) {
|
|
123296
123471
|
if (!transferStore || typeof transferStore.subscribe !== "function" || typeof transferStore.getSnapshot !== "function" || typeof transferStore.getCacheState !== "function" || typeof transferStore.setHistory !== "function") {
|
|
123297
123472
|
throw new Error("createWalletTransferSession requires transferStore");
|
|
123298
123473
|
}
|
|
@@ -123357,7 +123532,7 @@ function createWalletTransferSession({ wallet, walletPK, localCache, claimIncomi
|
|
|
123357
123532
|
const cacheHydrateKeyRef = { current: "" };
|
|
123358
123533
|
const cacheHydratePromiseRef = { current: null };
|
|
123359
123534
|
const fullCacheHydratePromiseRef = { current: null };
|
|
123360
|
-
const cacheWriteRef = { current: { timer: null, cache: null, state: null } };
|
|
123535
|
+
const cacheWriteRef = { current: { timer: null, cache: null, state: null, fullHistory: false } };
|
|
123361
123536
|
const cacheDirtyRef = { current: false };
|
|
123362
123537
|
const lastFetchAtRef = { current: 0 };
|
|
123363
123538
|
const claimBatchSize = Math.max(1, Number(pendingClaimBatchSize) || PENDING_TRANSFER_CLAIM_BATCH_SIZE);
|
|
@@ -123685,9 +123860,9 @@ function createWalletTransferSession({ wallet, walletPK, localCache, claimIncomi
|
|
|
123685
123860
|
return false;
|
|
123686
123861
|
}
|
|
123687
123862
|
const cachedTransfers = filterTransfersForWallet(cached.transfers, walletPKRef.current);
|
|
123688
|
-
const
|
|
123689
|
-
const
|
|
123690
|
-
const
|
|
123863
|
+
const cachedPublishTransfers = !publish && historyTransfersRef.current.length ? mergeTransferPageForWallet(historyTransfersRef.current, cachedTransfers, walletPKRef.current, "append") : cachedTransfers;
|
|
123864
|
+
const cachedPendingIncoming = pendingIncomingTransfers(cachedPublishTransfers);
|
|
123865
|
+
const cachedPending = pendingTransfers(cachedPublishTransfers);
|
|
123691
123866
|
rememberPendingTransferIds(cachedPending.map((tx) => tx.id));
|
|
123692
123867
|
markDiag(diag, label, {
|
|
123693
123868
|
elapsedMs: Date.now() - startedAt,
|
|
@@ -123826,9 +124001,11 @@ function createWalletTransferSession({ wallet, walletPK, localCache, claimIncomi
|
|
|
123826
124001
|
pending.timer = null;
|
|
123827
124002
|
const cache = pending.cache;
|
|
123828
124003
|
const state = pending.state;
|
|
124004
|
+
const fullHistory = pending.fullHistory;
|
|
123829
124005
|
pending.state = null;
|
|
123830
124006
|
if (cache && state) {
|
|
123831
|
-
writeCachedTransferState
|
|
124007
|
+
const write = fullHistory ? writeCachedTransferState : writeCachedTransferHeadState;
|
|
124008
|
+
write(cache, state);
|
|
123832
124009
|
}
|
|
123833
124010
|
};
|
|
123834
124011
|
const queueWalletFetch = (read) => {
|
|
@@ -123933,7 +124110,7 @@ function createWalletTransferSession({ wallet, walletPK, localCache, claimIncomi
|
|
|
123933
124110
|
return pendingQueryPromiseRef.current;
|
|
123934
124111
|
};
|
|
123935
124112
|
const pendingIncomingClaimCandidates = (sourceTransfers = []) => {
|
|
123936
|
-
return
|
|
124113
|
+
return pendingIncomingTransfers(sourceTransfers).filter((tx) => {
|
|
123937
124114
|
const id = String(tx?.id || "");
|
|
123938
124115
|
return id && !claimedTransferIdsRef.current.has(id);
|
|
123939
124116
|
});
|
|
@@ -124149,6 +124326,9 @@ function createWalletTransferSession({ wallet, walletPK, localCache, claimIncomi
|
|
|
124149
124326
|
batchClaimedIds.push(...staged);
|
|
124150
124327
|
flushClaimed();
|
|
124151
124328
|
const uniqueBatchClaimedIds = uniqueIds(batchClaimedIds);
|
|
124329
|
+
if (uniqueBatchClaimedIds.length && typeof refreshBalance === "function") {
|
|
124330
|
+
await refreshBalance();
|
|
124331
|
+
}
|
|
124152
124332
|
const unclaimedIds = candidateIds.filter((id) => !uniqueBatchClaimedIds.includes(id) && !claimedTransferIdsRef.current.has(id));
|
|
124153
124333
|
if (unclaimedIds.length) {
|
|
124154
124334
|
const elapsedMs = Date.now() - startedAt;
|
|
@@ -124671,7 +124851,7 @@ function createWalletTransferSession({ wallet, walletPK, localCache, claimIncomi
|
|
|
124671
124851
|
try {
|
|
124672
124852
|
await yieldToUi();
|
|
124673
124853
|
const pendingTransfers2 = await getPendingTransfersSnapshot();
|
|
124674
|
-
const incomingTransfers =
|
|
124854
|
+
const incomingTransfers = pendingIncomingTransfers(pendingTransfers2);
|
|
124675
124855
|
const claimCandidates = pendingIncomingClaimCandidates(incomingTransfers);
|
|
124676
124856
|
if (!incomingTransfers.length) {
|
|
124677
124857
|
markDone(diag, "wallet.pendingTxs.active", startedAt, { pending: 0, claimed: 0, reason });
|
|
@@ -125016,7 +125196,7 @@ function createWalletTransferSession({ wallet, walletPK, localCache, claimIncomi
|
|
|
125016
125196
|
if (cacheWriteRef.current.timer) {
|
|
125017
125197
|
clearTimeout(cacheWriteRef.current.timer);
|
|
125018
125198
|
}
|
|
125019
|
-
cacheWriteRef.current = { timer: null, cache: null, state: null };
|
|
125199
|
+
cacheWriteRef.current = { timer: null, cache: null, state: null, fullHistory: false };
|
|
125020
125200
|
cacheDirtyRef.current = false;
|
|
125021
125201
|
};
|
|
125022
125202
|
const startCacheHydration = () => {
|
|
@@ -125074,12 +125254,10 @@ function createWalletTransferSession({ wallet, walletPK, localCache, claimIncomi
|
|
|
125074
125254
|
if (!cacheDirtyRef.current && !cacheWriteRef.current.timer) {
|
|
125075
125255
|
return;
|
|
125076
125256
|
}
|
|
125077
|
-
if (historyTransfersRef.current.length < knownHistoryCountRef.current) {
|
|
125078
|
-
return;
|
|
125079
|
-
}
|
|
125080
125257
|
cacheDirtyRef.current = false;
|
|
125081
125258
|
cacheWriteRef.current.cache = localCache;
|
|
125082
125259
|
cacheWriteRef.current.state = transferStore.getCacheState();
|
|
125260
|
+
cacheWriteRef.current.fullHistory = historyTransfersRef.current.length >= knownHistoryCountRef.current;
|
|
125083
125261
|
if (cacheWriteRef.current.timer) {
|
|
125084
125262
|
clearTimeout(cacheWriteRef.current.timer);
|
|
125085
125263
|
}
|
|
@@ -125108,7 +125286,7 @@ function createWalletTransferSession({ wallet, walletPK, localCache, claimIncomi
|
|
|
125108
125286
|
serverHistoryComplete: serverHistoryCompleteRef.current,
|
|
125109
125287
|
hasMoreTxs: !historyComplete,
|
|
125110
125288
|
hasPendingTxs,
|
|
125111
|
-
hasPendingIncomingTxs:
|
|
125289
|
+
hasPendingIncomingTxs: pendingIncomingTransfers(transfersRef.current).length > 0,
|
|
125112
125290
|
beginSdkActivity,
|
|
125113
125291
|
getRecentTxs,
|
|
125114
125292
|
claimPendingIncomingTransfers: claimPendingIncomingTransfers2,
|
|
@@ -125464,6 +125642,7 @@ function createWalletSession({
|
|
|
125464
125642
|
deferBackgroundWork = null,
|
|
125465
125643
|
appState = null,
|
|
125466
125644
|
transferStore,
|
|
125645
|
+
cachedBalance = null,
|
|
125467
125646
|
ghostWallet = true,
|
|
125468
125647
|
diag = null
|
|
125469
125648
|
}) {
|
|
@@ -125481,6 +125660,7 @@ function createWalletSession({
|
|
|
125481
125660
|
const txSubscriptions = createFieldSubscriptions(() => publishedSnapshot?.txValue);
|
|
125482
125661
|
let polling = null;
|
|
125483
125662
|
let readyDiag = null;
|
|
125663
|
+
let refreshWalletBalance = null;
|
|
125484
125664
|
const transferSession = createWalletTransferSession({
|
|
125485
125665
|
wallet,
|
|
125486
125666
|
walletPK,
|
|
@@ -125493,6 +125673,7 @@ function createWalletSession({
|
|
|
125493
125673
|
appState,
|
|
125494
125674
|
deferBackgroundWork,
|
|
125495
125675
|
backgroundSignal: backgroundAbort.signal,
|
|
125676
|
+
refreshBalance: () => refreshWalletBalance?.(),
|
|
125496
125677
|
diag
|
|
125497
125678
|
});
|
|
125498
125679
|
const getTransferState = () => transferSession.getSnapshot();
|
|
@@ -125512,7 +125693,16 @@ function createWalletSession({
|
|
|
125512
125693
|
listener();
|
|
125513
125694
|
}
|
|
125514
125695
|
};
|
|
125515
|
-
const balance = createWalletBalance({
|
|
125696
|
+
const balance = createWalletBalance({
|
|
125697
|
+
wallet,
|
|
125698
|
+
diag,
|
|
125699
|
+
initialDisplayBalance: cachedBalance,
|
|
125700
|
+
onBalance: (value) => {
|
|
125701
|
+
writeCachedWalletBalance(localCache, { walletPK, network, balance: value }).catch(() => {});
|
|
125702
|
+
},
|
|
125703
|
+
onChange: publish
|
|
125704
|
+
});
|
|
125705
|
+
refreshWalletBalance = balance.getBalance;
|
|
125516
125706
|
const funding = createFundingAddress({ wallet, network, diag, onChange: publish });
|
|
125517
125707
|
const updateWalletData = createWalletData({
|
|
125518
125708
|
wallet,
|
|
@@ -125593,6 +125783,7 @@ function createWalletSession({
|
|
|
125593
125783
|
wallet,
|
|
125594
125784
|
network,
|
|
125595
125785
|
balance: balanceState.balance,
|
|
125786
|
+
displayBalance: balanceState.displayBalance,
|
|
125596
125787
|
satsBalance: balanceState.satsBalance,
|
|
125597
125788
|
tokenBalances: balanceState.tokenBalances,
|
|
125598
125789
|
fundingAddress: funding.getSnapshot(),
|
|
@@ -125691,7 +125882,7 @@ function createWalletSession({
|
|
|
125691
125882
|
};
|
|
125692
125883
|
}
|
|
125693
125884
|
var init_session4 = __esm(() => {
|
|
125694
|
-
|
|
125885
|
+
init_balance2();
|
|
125695
125886
|
init_claims();
|
|
125696
125887
|
init_funding();
|
|
125697
125888
|
init_lightning();
|
|
@@ -125700,6 +125891,7 @@ var init_session4 = __esm(() => {
|
|
|
125700
125891
|
init_send2();
|
|
125701
125892
|
init_transfers2();
|
|
125702
125893
|
init_withdraw();
|
|
125894
|
+
init_localdata();
|
|
125703
125895
|
});
|
|
125704
125896
|
|
|
125705
125897
|
// ../../shared/wallet/transferstore.js
|
|
@@ -125908,6 +126100,7 @@ function createTransferStore() {
|
|
|
125908
126100
|
transfers: state.historyTransfers,
|
|
125909
126101
|
walletPK: state.walletPK,
|
|
125910
126102
|
serverEndReached: state.serverEndReached,
|
|
126103
|
+
historyCount: state.historyCount,
|
|
125911
126104
|
nextOffset: state.nextOffset,
|
|
125912
126105
|
oldestTxMs: state.serverEndReached ? state.oldestVerifiedTxMs : null
|
|
125913
126106
|
};
|
|
@@ -169391,9 +169584,13 @@ function peerRecordFromDoc(snap) {
|
|
|
169391
169584
|
function peerRecordsFromSnapshot(snapshot) {
|
|
169392
169585
|
return snapshot.docs.map(peerRecordFromDoc).filter(Boolean);
|
|
169393
169586
|
}
|
|
169394
|
-
function avatarPath(uid) {
|
|
169587
|
+
function avatarPath(uid, version8) {
|
|
169395
169588
|
requireUid(uid);
|
|
169396
|
-
|
|
169589
|
+
const avatarVersion = readAvatarVersion(version8);
|
|
169590
|
+
if (!avatarVersion) {
|
|
169591
|
+
throw new Error("avatar version required");
|
|
169592
|
+
}
|
|
169593
|
+
return `${uid}/avatars/${avatarVersion}.webp`;
|
|
169397
169594
|
}
|
|
169398
169595
|
function reportEvidencePath(reporter, targetUid, evidenceId) {
|
|
169399
169596
|
if (!reporter || !targetUid || !evidenceId) {
|
|
@@ -169459,6 +169656,7 @@ function createFirebaseCloud({ db, auth: auth2, getAuth: getAuth2, functions: fu
|
|
|
169459
169656
|
}
|
|
169460
169657
|
let activeVaultSigner = null;
|
|
169461
169658
|
const localSessionTerminations = new Set;
|
|
169659
|
+
const pendingAvatars = new Map;
|
|
169462
169660
|
function pageTs(value) {
|
|
169463
169661
|
if (value instanceof Timestamp2) {
|
|
169464
169662
|
return value;
|
|
@@ -169727,6 +169925,7 @@ function createFirebaseCloud({ db, auth: auth2, getAuth: getAuth2, functions: fu
|
|
|
169727
169925
|
}, onError);
|
|
169728
169926
|
}
|
|
169729
169927
|
async function logout() {
|
|
169928
|
+
pendingAvatars.clear();
|
|
169730
169929
|
await signOut(requireAuth());
|
|
169731
169930
|
return true;
|
|
169732
169931
|
}
|
|
@@ -169860,25 +170059,45 @@ function createFirebaseCloud({ db, auth: auth2, getAuth: getAuth2, functions: fu
|
|
|
169860
170059
|
await callFunction("acceptAgreement");
|
|
169861
170060
|
return true;
|
|
169862
170061
|
}
|
|
169863
|
-
async function
|
|
170062
|
+
async function setProfileAvatar(uid, data) {
|
|
169864
170063
|
requireUid(uid);
|
|
169865
|
-
|
|
169866
|
-
|
|
169867
|
-
|
|
169868
|
-
|
|
169869
|
-
|
|
169870
|
-
|
|
169871
|
-
|
|
169872
|
-
|
|
169873
|
-
|
|
169874
|
-
|
|
169875
|
-
|
|
169876
|
-
|
|
169877
|
-
|
|
169878
|
-
|
|
169879
|
-
|
|
169880
|
-
|
|
169881
|
-
|
|
170064
|
+
if (requireAuth().currentUser?.uid !== uid) {
|
|
170065
|
+
throw new Error("avatar account mismatch");
|
|
170066
|
+
}
|
|
170067
|
+
if (data == null) {
|
|
170068
|
+
pendingAvatars.delete(uid);
|
|
170069
|
+
const result = await callFunction("setAvatar", { body: null });
|
|
170070
|
+
if (result?.avatar != null) {
|
|
170071
|
+
throw new Error("avatar clear returned invalid state");
|
|
170072
|
+
}
|
|
170073
|
+
return { version: null };
|
|
170074
|
+
}
|
|
170075
|
+
const bytes = new Uint8Array(encryptedBytes(data, "avatar bytes"));
|
|
170076
|
+
const pending = { bytes, version: null, promise: null };
|
|
170077
|
+
const entries = pendingAvatars.get(uid) || [];
|
|
170078
|
+
pendingAvatars.set(uid, [...entries, pending]);
|
|
170079
|
+
pending.promise = callFunction("setAvatar", {
|
|
170080
|
+
body: cloudBytesBase64(bytes, "avatar bytes")
|
|
170081
|
+
}).then((result) => {
|
|
170082
|
+
const version8 = readAvatarVersion(result?.avatar);
|
|
170083
|
+
if (!version8) {
|
|
170084
|
+
throw new Error("avatar publish returned invalid version");
|
|
170085
|
+
}
|
|
170086
|
+
pending.version = version8;
|
|
170087
|
+
return version8;
|
|
170088
|
+
});
|
|
170089
|
+
try {
|
|
170090
|
+
return { version: await pending.promise };
|
|
170091
|
+
} catch (error) {
|
|
170092
|
+
const active = pendingAvatars.get(uid) || [];
|
|
170093
|
+
const remaining = active.filter((entry) => entry !== pending);
|
|
170094
|
+
if (remaining.length) {
|
|
170095
|
+
pendingAvatars.set(uid, remaining);
|
|
170096
|
+
} else {
|
|
170097
|
+
pendingAvatars.delete(uid);
|
|
170098
|
+
}
|
|
170099
|
+
throw error;
|
|
170100
|
+
}
|
|
169882
170101
|
}
|
|
169883
170102
|
async function writeProfileIdentity(identity) {
|
|
169884
170103
|
if (!identity || typeof identity !== "object" || Array.isArray(identity)) {
|
|
@@ -170015,13 +170234,28 @@ function createFirebaseCloud({ db, auth: auth2, getAuth: getAuth2, functions: fu
|
|
|
170015
170234
|
onUpdate?.(snap.exists() ? snap.data()?.active === true : false, { exists: snap.exists() });
|
|
170016
170235
|
}, onError);
|
|
170017
170236
|
}
|
|
170018
|
-
async function readPeerAvatar(uid) {
|
|
170019
|
-
|
|
170237
|
+
async function readPeerAvatar(uid, { version: version8 = null } = {}) {
|
|
170238
|
+
const avatarVersion = readAvatarVersion(version8);
|
|
170239
|
+
const entries = pendingAvatars.get(uid) || [];
|
|
170240
|
+
if (entries.length) {
|
|
170241
|
+
await Promise.allSettled(entries.map((entry) => entry.promise));
|
|
170242
|
+
const pending = entries.find((entry) => entry.version === avatarVersion);
|
|
170243
|
+
if (pending) {
|
|
170244
|
+
const active = pendingAvatars.get(uid) || [];
|
|
170245
|
+
const remaining = active.filter((entry) => entry !== pending);
|
|
170246
|
+
if (remaining.length) {
|
|
170247
|
+
pendingAvatars.set(uid, remaining);
|
|
170248
|
+
} else {
|
|
170249
|
+
pendingAvatars.delete(uid);
|
|
170250
|
+
}
|
|
170251
|
+
return new Uint8Array(pending.bytes);
|
|
170252
|
+
}
|
|
170253
|
+
}
|
|
170254
|
+
return readStorageFile(avatarPath(uid, avatarVersion));
|
|
170020
170255
|
}
|
|
170021
170256
|
async function peerAvatarUrl(uid, { version: version8 = null } = {}) {
|
|
170022
170257
|
const targetStorage = requireStorage2();
|
|
170023
|
-
|
|
170024
|
-
return avatarUrlWithVersion(url, version8);
|
|
170258
|
+
return getDownloadURL(ref(targetStorage, avatarPath(uid, version8)));
|
|
170025
170259
|
}
|
|
170026
170260
|
function profileQueryField(field2, { network } = {}) {
|
|
170027
170261
|
if (field2 === "walletPK") {
|
|
@@ -170480,12 +170714,13 @@ function createFirebaseCloud({ db, auth: auth2, getAuth: getAuth2, functions: fu
|
|
|
170480
170714
|
}
|
|
170481
170715
|
};
|
|
170482
170716
|
}
|
|
170483
|
-
async function pushInbox(recipientUid, ping) {
|
|
170717
|
+
async function pushInbox(recipientUid, ping, options2 = {}) {
|
|
170484
170718
|
requireUid(recipientUid);
|
|
170485
170719
|
if (!ping)
|
|
170486
170720
|
throw new Error("inbox ping required");
|
|
170487
170721
|
await callFunction("push", {
|
|
170488
170722
|
recipientUid,
|
|
170723
|
+
notify: options2?.notify !== false,
|
|
170489
170724
|
ping: {
|
|
170490
170725
|
v: ping.v,
|
|
170491
170726
|
epk: ping.epk,
|
|
@@ -170524,7 +170759,9 @@ function createFirebaseCloud({ db, auth: auth2, getAuth: getAuth2, functions: fu
|
|
|
170524
170759
|
payload.onCommitted?.({ chatId, messageId });
|
|
170525
170760
|
let delivered = true;
|
|
170526
170761
|
if (payload.inbox?.recipientUid && payload.inbox?.ping) {
|
|
170527
|
-
delivered = await pushInbox(payload.inbox.recipientUid, payload.inbox.ping
|
|
170762
|
+
delivered = await pushInbox(payload.inbox.recipientUid, payload.inbox.ping, {
|
|
170763
|
+
notify: payload.inbox.notify !== false
|
|
170764
|
+
}).then(() => true, () => false);
|
|
170528
170765
|
}
|
|
170529
170766
|
return { chatId, messageId, delivered };
|
|
170530
170767
|
}
|
|
@@ -170777,18 +171014,19 @@ function createFirebaseCloud({ db, auth: auth2, getAuth: getAuth2, functions: fu
|
|
|
170777
171014
|
}
|
|
170778
171015
|
async function banAdminUser(uid, feature = "chat") {
|
|
170779
171016
|
requireUid(uid);
|
|
170780
|
-
await setDoc(doc(db, "moderation", uid), { banned: { [feature]: { until: null } } }, { merge: true });
|
|
170781
171017
|
if (feature === "avatar") {
|
|
170782
|
-
await
|
|
170783
|
-
|
|
170784
|
-
throw error;
|
|
170785
|
-
}
|
|
170786
|
-
});
|
|
171018
|
+
await callFunction("setAvatarModeration", { uid, banned: true });
|
|
171019
|
+
return true;
|
|
170787
171020
|
}
|
|
171021
|
+
await setDoc(doc(db, "moderation", uid), { banned: { [feature]: { until: null } } }, { merge: true });
|
|
170788
171022
|
return true;
|
|
170789
171023
|
}
|
|
170790
171024
|
async function unbanAdminUser(uid, feature = "chat") {
|
|
170791
171025
|
requireUid(uid);
|
|
171026
|
+
if (feature === "avatar") {
|
|
171027
|
+
await callFunction("setAvatarModeration", { uid, banned: false });
|
|
171028
|
+
return true;
|
|
171029
|
+
}
|
|
170792
171030
|
await setDoc(doc(db, "moderation", uid), { banned: { [feature]: deleteField() } }, { merge: true });
|
|
170793
171031
|
return true;
|
|
170794
171032
|
}
|
|
@@ -170826,9 +171064,7 @@ function createFirebaseCloud({ db, auth: auth2, getAuth: getAuth2, functions: fu
|
|
|
170826
171064
|
write: writeProfileIdentity
|
|
170827
171065
|
},
|
|
170828
171066
|
avatar: {
|
|
170829
|
-
|
|
170830
|
-
upload: uploadProfileAvatar,
|
|
170831
|
-
delete: deleteProfileAvatar
|
|
171067
|
+
set: setProfileAvatar
|
|
170832
171068
|
}
|
|
170833
171069
|
},
|
|
170834
171070
|
private: {
|
|
@@ -173418,13 +173654,6 @@ function cleanMessage(value, limit2, label = "message") {
|
|
|
173418
173654
|
throw new Error(`${label} must be ${limit2} characters or fewer`);
|
|
173419
173655
|
return message;
|
|
173420
173656
|
}
|
|
173421
|
-
function readAvatarGeneration(value) {
|
|
173422
|
-
const version8 = Number(value);
|
|
173423
|
-
if (!Number.isSafeInteger(version8) || version8 <= 0) {
|
|
173424
|
-
throw new Error("avatar upload did not return a valid generation");
|
|
173425
|
-
}
|
|
173426
|
-
return version8;
|
|
173427
|
-
}
|
|
173428
173657
|
function passkeyRows(linksList, passkeys, currentPasskeyId) {
|
|
173429
173658
|
return [...linksList, ...passkeys].sort((left, right) => (right.createdAt || 0) - (left.createdAt || 0)).map((row) => ({
|
|
173430
173659
|
...row,
|
|
@@ -173512,23 +173741,17 @@ function createRuntimeProductActions({
|
|
|
173512
173741
|
const user = await getUser();
|
|
173513
173742
|
if (!data)
|
|
173514
173743
|
throw new Error("avatar data required");
|
|
173515
|
-
|
|
173516
|
-
|
|
173517
|
-
}
|
|
173518
|
-
const
|
|
173519
|
-
await
|
|
173520
|
-
|
|
173521
|
-
return { avatar:
|
|
173744
|
+
if (options2.contentType && options2.contentType !== "image/webp") {
|
|
173745
|
+
throw new Error("avatar content type must be image/webp");
|
|
173746
|
+
}
|
|
173747
|
+
const result = await cloud.user.profile.avatar.set(user.uid, data);
|
|
173748
|
+
await user.refetchAvatar?.({ version: result.version });
|
|
173749
|
+
const updated = await getUser();
|
|
173750
|
+
return { avatar: updated.avatar || null, avatarVersion: result.version };
|
|
173522
173751
|
},
|
|
173523
173752
|
async deleteAvatar() {
|
|
173524
173753
|
const user = await getUser();
|
|
173525
|
-
|
|
173526
|
-
await cloud.user.profile.avatar.delete(user.uid);
|
|
173527
|
-
} catch (error) {
|
|
173528
|
-
if (error?.code !== "storage/object-not-found")
|
|
173529
|
-
throw error;
|
|
173530
|
-
}
|
|
173531
|
-
await cloud.user.profile.avatar.write(user.uid, null);
|
|
173754
|
+
await cloud.user.profile.avatar.set(user.uid, null);
|
|
173532
173755
|
user.clearAvatar?.();
|
|
173533
173756
|
return { deleted: true };
|
|
173534
173757
|
}
|
|
@@ -174704,6 +174927,34 @@ class ProfileStore {
|
|
|
174704
174927
|
var FILE_MODE2 = 384, DIR_MODE2 = 448;
|
|
174705
174928
|
var init_storage = () => {};
|
|
174706
174929
|
|
|
174930
|
+
// ../../shared/actioncopy.js
|
|
174931
|
+
var ACCOUNT_DELETE_PREPARE = "you should export or empty your wallet first.", ACCOUNT_DELETE_CONDITION = "if you delete your account,", ACCOUNT_DELETE_CONSEQUENCE = "you will permanently lose access to your funds and chats.", PASSKEY_DELETE_PENDING = "deleting a pending link disables it.", PASSKEY_DELETE_VERIFIED = "deleting a verified passkey will log out any session currently using it.", PASSKEY_DELETE_LIMITS = "you can’t delete the passkey used by this session or the account’s last passkey.", ACCOUNT_DELETE_COPY, BLOCK_USER_BODY = "they will no longer be able to message you, and this chat will be permanently deleted.", UNBLOCK_USER_BODY = "they will be able to message you again.", CHAT_DELETE_BODY = "this chat will be permanently deleted.", PASSKEY_DELETE_COPY, WALLET_EXPORT_COPY, WITHDRAWAL_COPY, LOGOUT_ALL_DEVICES_BODY = "This will sign your account out on every connected device. If you suspect someone else has access, logging out may not be enough: they may already have copied your wallet recovery phrase or other sensitive information. Move your funds to a safe wallet only you control as soon as possible, then remove sensitive information from this account. Information already copied to another device cannot be erased remotely.";
|
|
174932
|
+
var init_actioncopy = __esm(() => {
|
|
174933
|
+
ACCOUNT_DELETE_COPY = Object.freeze({
|
|
174934
|
+
prepare: ACCOUNT_DELETE_PREPARE,
|
|
174935
|
+
condition: ACCOUNT_DELETE_CONDITION,
|
|
174936
|
+
consequence: ACCOUNT_DELETE_CONSEQUENCE,
|
|
174937
|
+
body: `${ACCOUNT_DELETE_PREPARE} ${ACCOUNT_DELETE_CONDITION} ${ACCOUNT_DELETE_CONSEQUENCE}`
|
|
174938
|
+
});
|
|
174939
|
+
PASSKEY_DELETE_COPY = Object.freeze({
|
|
174940
|
+
pendingBody: PASSKEY_DELETE_PENDING,
|
|
174941
|
+
body: PASSKEY_DELETE_VERIFIED,
|
|
174942
|
+
description: `${PASSKEY_DELETE_PENDING} ${PASSKEY_DELETE_VERIFIED}`,
|
|
174943
|
+
infoBody: `${PASSKEY_DELETE_PENDING} ${PASSKEY_DELETE_LIMITS} ${PASSKEY_DELETE_VERIFIED}`
|
|
174944
|
+
});
|
|
174945
|
+
WALLET_EXPORT_COPY = Object.freeze({
|
|
174946
|
+
networkLead: "this is not a bitcoin wallet.",
|
|
174947
|
+
networkBody: "you cannot use it like a normal bitcoin wallet. you can only use it with the spark network: with a new account on this platform, on a different platform that uses spark wallets, or directly through the spark sdk.",
|
|
174948
|
+
withdrawBody: "if you do not want to use this account anymore, withdraw your funds back to a bitcoin wallet instead.",
|
|
174949
|
+
secretBody: "the mnemonic gives full control of this Spark wallet. reveal it only somewhere private."
|
|
174950
|
+
});
|
|
174951
|
+
WITHDRAWAL_COPY = Object.freeze({
|
|
174952
|
+
feeBody: "you can withdraw your funds back to any bitcoin address. bitcoin transactions are not free. validators need to get paid.",
|
|
174953
|
+
reviewBody: "veyl gets a live Spark withdrawal quote after you press withdraw. review the destination address, the amount leaving your wallet, the quoted fee, and the amount that reaches the address before confirming.",
|
|
174954
|
+
irreversibleBody: "once confirmed, bitcoin withdrawals are irreversible."
|
|
174955
|
+
});
|
|
174956
|
+
});
|
|
174957
|
+
|
|
174707
174958
|
// src/commands.js
|
|
174708
174959
|
import { Buffer as Buffer4 } from "node:buffer";
|
|
174709
174960
|
import { chmod as chmod3, readFile as readFile3, writeFile as writeFile3 } from "node:fs/promises";
|
|
@@ -174871,6 +175122,7 @@ function cliHelpLines() {
|
|
|
174871
175122
|
}
|
|
174872
175123
|
var stringProp, numberProp, booleanProp, objectProp, stringArrayProp, MIME_BY_EXTENSION, TYPE_BY_MIME, optionsOnly = (_args, context) => ({ ...context.commandOptions }), firstArg = (key) => (args, context) => ({ ...context.commandOptions, [key]: args[0] }), peerInput, peerMessageInput = (args, context) => ({ ...context.commandOptions, peer: args[0], message: args.slice(1).join(" ") }), peerMessageIdInput = (args, context) => ({ ...context.commandOptions, peer: args[0], messageId: args[1] }), peerCidInput = (args, context) => ({ ...context.commandOptions, peer: args[0], cid: args[1] }), peerMessageActionInput = (args, context) => ({ ...context.commandOptions, peer: args[0], messageId: args[1], message: args.slice(2).join(" ") }), peerEmojiInput = (args, context) => ({ ...context.commandOptions, peer: args[0], messageId: args[1], emoji: args.slice(2).join(" ") }), peerSatsInput = (args, context) => ({ ...context.commandOptions, peer: args[0], sats: args[1] }), invoiceInput, requestInput, idInput, withdrawalInput = (args, context) => ({ ...context.commandOptions, address: args[0], sats: args[1] }), inviteLinkInput = (args, context) => ({ ...context.commandOptions, kind: args[0], sats: args[1] }), HEADLESS_COMMANDS, commandByName, cliPaths, MCP_TOOLS, groups, COMMANDS;
|
|
174873
175124
|
var init_commands = __esm(() => {
|
|
175125
|
+
init_actioncopy();
|
|
174874
175126
|
stringProp = Object.freeze({ type: "string" });
|
|
174875
175127
|
numberProp = Object.freeze({ type: "number" });
|
|
174876
175128
|
booleanProp = Object.freeze({ type: "boolean" });
|
|
@@ -174947,12 +175199,12 @@ var init_commands = __esm(() => {
|
|
|
174947
175199
|
invokeCli: async (client2, input, context) => client2.account.acceptTerms({ ...input, termsVersion: await context.acceptTerms(input.termsVersion) })
|
|
174948
175200
|
}),
|
|
174949
175201
|
command({ name: "account_logout", group: "account", apiName: "logout", description: "Lock and sign out this runtime.", usage: "account logout", cliInput: optionsOnly, access: "write", invoke: (client2) => client2.account.logout() }),
|
|
174950
|
-
command({ name: "account_logout_all", group: "account", apiName: "logoutAll", description:
|
|
174951
|
-
command({ name: "account_delete", group: "account", apiName: "delete", description:
|
|
175202
|
+
command({ name: "account_logout_all", group: "account", apiName: "logoutAll", description: LOGOUT_ALL_DEVICES_BODY, usage: "account logout-all", cliInput: optionsOnly, access: "destructive", invoke: (client2) => client2.account.logoutAll() }),
|
|
175203
|
+
command({ name: "account_delete", group: "account", apiName: "delete", description: ACCOUNT_DELETE_COPY.body, properties: { confirm: booleanProp }, required: ["confirm"], usage: "account delete", cliInput: optionsOnly, access: "destructive", invoke: (client2, input) => client2.account.delete(input) }),
|
|
174952
175204
|
command({ name: "vault_create", group: "vault", apiName: "create", description: "Create and upload a locally encrypted vault.", properties: { secret: stringProp, saveSecret: booleanProp }, usage: "vault create", cliInput: vaultInput, access: "write", secret: true, invoke: (client2, input) => client2.vault.create(input) }),
|
|
174953
175205
|
command({ name: "vault_unlock", group: "vault", apiName: "unlock", description: "Unlock the local vault.", properties: { secret: stringProp }, usage: "vault unlock", cliInput: vaultInput, access: "write", secret: true, invoke: (client2, input) => client2.vault.unlock(input) }),
|
|
174954
175206
|
command({ name: "vault_lock", group: "vault", apiName: "lock", description: "Lock wallet and chat state.", usage: "vault lock", cliInput: optionsOnly, access: "write", invoke: (client2) => client2.vault.lock() }),
|
|
174955
|
-
command({ name: "vault_export", group: "vault", apiName: "export", description:
|
|
175207
|
+
command({ name: "vault_export", group: "vault", apiName: "export", description: WALLET_EXPORT_COPY.secretBody, properties: { secret: stringProp }, usage: "vault export", cliInput: vaultInput, mcp: false, secret: true, invoke: (client2, input) => client2.vault.export(input) }),
|
|
174956
175208
|
command({ name: "profile_show", group: "profile", apiName: "show", description: "Show the public account profile.", usage: "profile show", cliInput: optionsOnly, invoke: (client2) => client2.profile.show() }),
|
|
174957
175209
|
command({
|
|
174958
175210
|
name: "profile_avatar_set",
|
|
@@ -174978,8 +175230,8 @@ var init_commands = __esm(() => {
|
|
|
174978
175230
|
command({ name: "peers_search", group: "peers", apiName: "search", description: "Search public Veyl profiles.", properties: { query: stringProp, count: numberProp }, required: ["query"], usage: "peers search <query>", cliInput: (args, context) => ({ ...context.commandOptions, query: args.join(" ") }), invoke: (client2, input) => client2.peers.search(input.query, input) }),
|
|
174979
175231
|
command({ name: "peers_list", group: "peers", apiName: "list", description: "List recent peers.", properties: { count: numberProp, recent: booleanProp }, usage: "peers list", cliInput: optionsOnly, invoke: (client2, input) => client2.peers.list(input) }),
|
|
174980
175232
|
command({ name: "peers_blocked", group: "peers", apiName: "blocked", description: "List blocked peers.", usage: "peers blocked", cliInput: optionsOnly, invoke: (client2) => client2.peers.blocked() }),
|
|
174981
|
-
command({ name: "peers_block", group: "peers", apiName: "block", description:
|
|
174982
|
-
command({ name: "peers_unblock", group: "peers", apiName: "unblock", description:
|
|
175233
|
+
command({ name: "peers_block", group: "peers", apiName: "block", description: BLOCK_USER_BODY, properties: { peer: stringProp }, required: ["peer"], usage: "peers block @name", cliInput: peerInput, access: "destructive", invoke: (client2, input) => client2.peers.block(input.peer) }),
|
|
175234
|
+
command({ name: "peers_unblock", group: "peers", apiName: "unblock", description: UNBLOCK_USER_BODY, properties: { peer: stringProp }, required: ["peer"], usage: "peers unblock @name", cliInput: peerInput, access: "write", invoke: (client2, input) => client2.peers.unblock(input.peer) }),
|
|
174983
175235
|
command({ name: "chat_list", group: "chat", apiName: "list", description: "List chats.", properties: { count: numberProp }, usage: "chat list", cliInput: optionsOnly, invoke: (client2, input) => client2.chat.list(input) }),
|
|
174984
175236
|
command({ name: "chat_messages", group: "chat", apiName: "messages", clientMethods: ["read"], description: "Read messages and mark the latest peer message as read.", properties: { peer: stringProp, count: numberProp }, required: ["peer"], usage: "chat messages @name", cliInput: peerInput, access: "write", invoke: (client2, input) => client2.chat.read(input.peer, input) }),
|
|
174985
175237
|
command({ name: "chat_mark_read", group: "chat", apiName: "markRead", description: "Mark the latest peer message as read.", properties: { peer: stringProp }, required: ["peer"], usage: "chat mark-read @name", cliInput: peerInput, access: "write", invoke: (client2, input) => client2.chat.markRead(input.peer, input) }),
|
|
@@ -174992,7 +175244,7 @@ var init_commands = __esm(() => {
|
|
|
174992
175244
|
command({ name: "chat_unsave", group: "chat", apiName: "unsave", description: "Return one message to temporary retention.", properties: { peer: stringProp, messageId: stringProp }, required: ["peer", "messageId"], usage: "chat unsave @name message-id", cliInput: peerMessageIdInput, access: "write", invoke: (client2, { peer, messageId, ...options2 }) => client2.chat.unsave(peer, messageId, options2) }),
|
|
174993
175245
|
command({ name: "chat_edit", group: "chat", apiName: "edit", clientMethods: ["update"], description: "Edit a text message you sent.", properties: { peer: stringProp, messageId: stringProp, message: stringProp }, required: ["peer", "messageId", "message"], usage: "chat edit @name message-id message", cliInput: peerMessageActionInput, access: "write", invoke: (client2, { peer, messageId, message, ...options2 }) => client2.chat.update(peer, messageId, message, options2) }),
|
|
174994
175246
|
command({ name: "chat_delete_message", group: "chat", apiName: "deleteMessage", clientMethods: ["delete"], description: "Delete one message immediately.", properties: { peer: stringProp, messageId: stringProp }, required: ["peer", "messageId"], usage: "chat delete-message @name message-id", cliInput: peerMessageIdInput, access: "destructive", invoke: (client2, { peer, messageId, ...options2 }) => client2.chat.delete(peer, messageId, options2) }),
|
|
174995
|
-
command({ name: "chat_delete", group: "chat", apiName: "deleteChat", description:
|
|
175247
|
+
command({ name: "chat_delete", group: "chat", apiName: "deleteChat", description: CHAT_DELETE_BODY, properties: { peer: stringProp, cleanup: booleanProp }, required: ["peer"], usage: "chat delete @name", cliInput: peerInput, access: "destructive", invoke: (client2, input) => client2.chat.deleteChat(input.peer, input) }),
|
|
174996
175248
|
command({ name: "chat_retention", group: "chat", apiName: "retention", description: "Set chat retention to seen or 24h.", properties: { peer: stringProp, retention: stringProp }, required: ["peer", "retention"], usage: "chat retention @name seen|24h", cliInput: (args, context) => ({ ...context.commandOptions, peer: args[0], retention: args[1] }), access: "write", invoke: (client2, input) => client2.chat.retention(input.peer, input.retention, input) }),
|
|
174997
175249
|
command({
|
|
174998
175250
|
name: "chat_send_file",
|
|
@@ -175077,12 +175329,12 @@ var init_commands = __esm(() => {
|
|
|
175077
175329
|
command({ name: "lightning_send", group: "lightning", apiName: "send", description: "Read a Lightning send request.", properties: { id: stringProp }, required: ["id"], usage: "lightning send id", cliInput: idInput, money: true, invoke: (client2, input) => client2.lightning.send(input.id, input) }),
|
|
175078
175330
|
command({ name: "withdrawal_quote", group: "withdrawal", apiName: "quote", description: "Quote an on-chain withdrawal.", properties: { address: stringProp, sats: numberProp }, required: ["address", "sats"], usage: "withdrawal quote address sats", cliInput: withdrawalInput, access: "write", money: true, invoke: (client2, input) => client2.withdrawal.quote(input.address, input.sats, input) }),
|
|
175079
175331
|
command({ name: "withdrawal_prepare", group: "withdrawal", apiName: "prepare", description: "Prepare an on-chain withdrawal review.", properties: { address: stringProp, sats: numberProp, speed: stringProp, deductFeeFromWithdrawalAmount: booleanProp }, required: ["address", "sats"], usage: "withdrawal prepare address sats", cliInput: withdrawalInput, access: "write", money: true, invoke: (client2, input) => client2.withdrawal.prepare(input.address, input.sats, input) }),
|
|
175080
|
-
command({ name: "withdrawal_confirm", group: "withdrawal", apiName: "confirm", description:
|
|
175332
|
+
command({ name: "withdrawal_confirm", group: "withdrawal", apiName: "confirm", description: WITHDRAWAL_COPY.irreversibleBody, properties: { address: stringProp, sats: numberProp, speed: stringProp, feeQuoteId: stringProp, feeAmountSats: numberProp, deductFeeFromWithdrawalAmount: booleanProp }, required: ["address", "sats"], usage: "withdrawal confirm address sats", cliInput: withdrawalInput, access: "destructive", money: true, invoke: (client2, input) => client2.withdrawal.confirm(input.address, input.sats, input) }),
|
|
175081
175333
|
command({ name: "invite_link", group: "invite", apiName: "link", description: "Create a join, chat, send, or request invite link.", properties: { kind: stringProp, sats: numberProp }, usage: "invite link [join|chat|send|request] [sats]", cliInput: inviteLinkInput, invoke: (client2, input) => client2.invite.link(input) }),
|
|
175082
175334
|
command({ name: "invite_read", group: "invite", apiName: "read", description: "Parse a Veyl invite URL.", properties: { value: stringProp }, required: ["value"], usage: "invite read url", cliInput: firstArg("value"), invoke: (client2, input) => client2.invite.read(input.value) }),
|
|
175083
175335
|
command({ name: "passkeys_list", group: "passkeys", apiName: "list", description: "List passkeys and pending links.", usage: "passkeys list", cliInput: optionsOnly, invoke: (client2, input) => client2.passkeys.list(input) }),
|
|
175084
175336
|
command({ name: "passkeys_link", group: "passkeys", apiName: "link", clientMethods: ["createLink"], description: "Create a one-time passkey link.", properties: { webUrl: stringProp }, usage: "passkeys link", cliInput: optionsOnly, mcp: false, access: "write", secret: true, invoke: (client2, input) => client2.passkeys.createLink(input) }),
|
|
175085
|
-
command({ name: "passkeys_delete", group: "passkeys", apiName: "delete", description:
|
|
175337
|
+
command({ name: "passkeys_delete", group: "passkeys", apiName: "delete", description: PASSKEY_DELETE_COPY.description, properties: { id: stringProp, webUrl: stringProp }, required: ["id"], usage: "passkeys delete id", cliInput: (args, context) => ({ ...context.commandOptions, id: args[0], webUrl: context.options.webUrl, onUrl: context.onPasskeyUrl }), access: "destructive", invoke: (client2, input) => client2.passkeys.delete(input.id, input) }),
|
|
175086
175338
|
command({ name: "support_feedback", group: "support", apiName: "feedback", description: "Send product feedback.", properties: { message: stringProp, type: stringProp, context: stringProp }, required: ["message"], usage: "support feedback message", cliInput: (args, context) => ({ ...context.commandOptions, message: args.join(" ") }), access: "write", invoke: (client2, input) => client2.support.feedback(input.message, input) }),
|
|
175087
175339
|
command({ name: "support_bug", group: "support", apiName: "bug", description: "Submit a bug report.", properties: { message: stringProp }, required: ["message"], usage: "support bug message", cliInput: (args, context) => ({ ...context.commandOptions, message: args.join(" ") }), access: "write", invoke: (client2, input) => client2.support.bug(input.message, input) }),
|
|
175088
175340
|
command({ name: "support_report", group: "support", apiName: "report", description: "Report a peer or one harmful message.", properties: { peer: stringProp, messageId: stringProp, note: stringProp, includeAttachment: booleanProp }, required: ["peer"], usage: "support report @name [message-id]", cliInput: (args, context) => ({ ...context.commandOptions, peer: args[0], messageId: args[1] }), access: "write", invoke: (client2, input) => client2.support.report(input.peer, input) }),
|
|
@@ -175121,7 +175373,7 @@ var package_default;
|
|
|
175121
175373
|
var init_package = __esm(() => {
|
|
175122
175374
|
package_default = {
|
|
175123
175375
|
name: "veyl",
|
|
175124
|
-
version: "0.
|
|
175376
|
+
version: "0.41.0",
|
|
175125
175377
|
private: true,
|
|
175126
175378
|
license: "Apache-2.0",
|
|
175127
175379
|
workspaces: {
|