@glyphteck/veyl 0.35.0 → 1.0.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/cli.js
CHANGED
|
@@ -447,6 +447,34 @@ var init_legal = __esm(() => {
|
|
|
447
447
|
};
|
|
448
448
|
});
|
|
449
449
|
|
|
450
|
+
// ../../shared/actioncopy.js
|
|
451
|
+
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.";
|
|
452
|
+
var init_actioncopy = __esm(() => {
|
|
453
|
+
ACCOUNT_DELETE_COPY = Object.freeze({
|
|
454
|
+
prepare: ACCOUNT_DELETE_PREPARE,
|
|
455
|
+
condition: ACCOUNT_DELETE_CONDITION,
|
|
456
|
+
consequence: ACCOUNT_DELETE_CONSEQUENCE,
|
|
457
|
+
body: `${ACCOUNT_DELETE_PREPARE} ${ACCOUNT_DELETE_CONDITION} ${ACCOUNT_DELETE_CONSEQUENCE}`
|
|
458
|
+
});
|
|
459
|
+
PASSKEY_DELETE_COPY = Object.freeze({
|
|
460
|
+
pendingBody: PASSKEY_DELETE_PENDING,
|
|
461
|
+
body: PASSKEY_DELETE_VERIFIED,
|
|
462
|
+
description: `${PASSKEY_DELETE_PENDING} ${PASSKEY_DELETE_VERIFIED}`,
|
|
463
|
+
infoBody: `${PASSKEY_DELETE_PENDING} ${PASSKEY_DELETE_LIMITS} ${PASSKEY_DELETE_VERIFIED}`
|
|
464
|
+
});
|
|
465
|
+
WALLET_EXPORT_COPY = Object.freeze({
|
|
466
|
+
networkLead: "this is not a bitcoin wallet.",
|
|
467
|
+
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.",
|
|
468
|
+
withdrawBody: "if you do not want to use this account anymore, withdraw your funds back to a bitcoin wallet instead.",
|
|
469
|
+
secretBody: "the mnemonic gives full control of this Spark wallet. reveal it only somewhere private."
|
|
470
|
+
});
|
|
471
|
+
WITHDRAWAL_COPY = Object.freeze({
|
|
472
|
+
feeBody: "you can withdraw your funds back to any bitcoin address. bitcoin transactions are not free. validators need to get paid.",
|
|
473
|
+
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.",
|
|
474
|
+
irreversibleBody: "once confirmed, bitcoin withdrawals are irreversible."
|
|
475
|
+
});
|
|
476
|
+
});
|
|
477
|
+
|
|
450
478
|
// src/commands.js
|
|
451
479
|
import { Buffer as Buffer2 } from "node:buffer";
|
|
452
480
|
import { chmod, readFile, writeFile } from "node:fs/promises";
|
|
@@ -614,6 +642,7 @@ function cliHelpLines() {
|
|
|
614
642
|
}
|
|
615
643
|
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;
|
|
616
644
|
var init_commands = __esm(() => {
|
|
645
|
+
init_actioncopy();
|
|
617
646
|
stringProp = Object.freeze({ type: "string" });
|
|
618
647
|
numberProp = Object.freeze({ type: "number" });
|
|
619
648
|
booleanProp = Object.freeze({ type: "boolean" });
|
|
@@ -690,12 +719,12 @@ var init_commands = __esm(() => {
|
|
|
690
719
|
invokeCli: async (client, input, context) => client.account.acceptTerms({ ...input, termsVersion: await context.acceptTerms(input.termsVersion) })
|
|
691
720
|
}),
|
|
692
721
|
command({ name: "account_logout", group: "account", apiName: "logout", description: "Lock and sign out this runtime.", usage: "account logout", cliInput: optionsOnly, access: "write", invoke: (client) => client.account.logout() }),
|
|
693
|
-
command({ name: "account_logout_all", group: "account", apiName: "logoutAll", description:
|
|
694
|
-
command({ name: "account_delete", group: "account", apiName: "delete", description:
|
|
722
|
+
command({ name: "account_logout_all", group: "account", apiName: "logoutAll", description: LOGOUT_ALL_DEVICES_BODY, usage: "account logout-all", cliInput: optionsOnly, access: "destructive", invoke: (client) => client.account.logoutAll() }),
|
|
723
|
+
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: (client, input) => client.account.delete(input) }),
|
|
695
724
|
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: (client, input) => client.vault.create(input) }),
|
|
696
725
|
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: (client, input) => client.vault.unlock(input) }),
|
|
697
726
|
command({ name: "vault_lock", group: "vault", apiName: "lock", description: "Lock wallet and chat state.", usage: "vault lock", cliInput: optionsOnly, access: "write", invoke: (client) => client.vault.lock() }),
|
|
698
|
-
command({ name: "vault_export", group: "vault", apiName: "export", description:
|
|
727
|
+
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: (client, input) => client.vault.export(input) }),
|
|
699
728
|
command({ name: "profile_show", group: "profile", apiName: "show", description: "Show the public account profile.", usage: "profile show", cliInput: optionsOnly, invoke: (client) => client.profile.show() }),
|
|
700
729
|
command({
|
|
701
730
|
name: "profile_avatar_set",
|
|
@@ -721,8 +750,8 @@ var init_commands = __esm(() => {
|
|
|
721
750
|
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: (client, input) => client.peers.search(input.query, input) }),
|
|
722
751
|
command({ name: "peers_list", group: "peers", apiName: "list", description: "List recent peers.", properties: { count: numberProp, recent: booleanProp }, usage: "peers list", cliInput: optionsOnly, invoke: (client, input) => client.peers.list(input) }),
|
|
723
752
|
command({ name: "peers_blocked", group: "peers", apiName: "blocked", description: "List blocked peers.", usage: "peers blocked", cliInput: optionsOnly, invoke: (client) => client.peers.blocked() }),
|
|
724
|
-
command({ name: "peers_block", group: "peers", apiName: "block", description:
|
|
725
|
-
command({ name: "peers_unblock", group: "peers", apiName: "unblock", description:
|
|
753
|
+
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: (client, input) => client.peers.block(input.peer) }),
|
|
754
|
+
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: (client, input) => client.peers.unblock(input.peer) }),
|
|
726
755
|
command({ name: "chat_list", group: "chat", apiName: "list", description: "List chats.", properties: { count: numberProp }, usage: "chat list", cliInput: optionsOnly, invoke: (client, input) => client.chat.list(input) }),
|
|
727
756
|
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: (client, input) => client.chat.read(input.peer, input) }),
|
|
728
757
|
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: (client, input) => client.chat.markRead(input.peer, input) }),
|
|
@@ -735,7 +764,7 @@ var init_commands = __esm(() => {
|
|
|
735
764
|
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: (client, { peer, messageId, ...options }) => client.chat.unsave(peer, messageId, options) }),
|
|
736
765
|
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: (client, { peer, messageId, message, ...options }) => client.chat.update(peer, messageId, message, options) }),
|
|
737
766
|
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: (client, { peer, messageId, ...options }) => client.chat.delete(peer, messageId, options) }),
|
|
738
|
-
command({ name: "chat_delete", group: "chat", apiName: "deleteChat", description:
|
|
767
|
+
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: (client, input) => client.chat.deleteChat(input.peer, input) }),
|
|
739
768
|
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: (client, input) => client.chat.retention(input.peer, input.retention, input) }),
|
|
740
769
|
command({
|
|
741
770
|
name: "chat_send_file",
|
|
@@ -820,12 +849,12 @@ var init_commands = __esm(() => {
|
|
|
820
849
|
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: (client, input) => client.lightning.send(input.id, input) }),
|
|
821
850
|
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: (client, input) => client.withdrawal.quote(input.address, input.sats, input) }),
|
|
822
851
|
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: (client, input) => client.withdrawal.prepare(input.address, input.sats, input) }),
|
|
823
|
-
command({ name: "withdrawal_confirm", group: "withdrawal", apiName: "confirm", description:
|
|
852
|
+
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: (client, input) => client.withdrawal.confirm(input.address, input.sats, input) }),
|
|
824
853
|
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: (client, input) => client.invite.link(input) }),
|
|
825
854
|
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: (client, input) => client.invite.read(input.value) }),
|
|
826
855
|
command({ name: "passkeys_list", group: "passkeys", apiName: "list", description: "List passkeys and pending links.", usage: "passkeys list", cliInput: optionsOnly, invoke: (client, input) => client.passkeys.list(input) }),
|
|
827
856
|
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: (client, input) => client.passkeys.createLink(input) }),
|
|
828
|
-
command({ name: "passkeys_delete", group: "passkeys", apiName: "delete", description:
|
|
857
|
+
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: (client, input) => client.passkeys.delete(input.id, input) }),
|
|
829
858
|
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: (client, input) => client.support.feedback(input.message, input) }),
|
|
830
859
|
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: (client, input) => client.support.bug(input.message, input) }),
|
|
831
860
|
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: (client, input) => client.support.report(input.peer, input) }),
|
|
@@ -980,7 +1009,7 @@ var package_default;
|
|
|
980
1009
|
var init_package = __esm(() => {
|
|
981
1010
|
package_default = {
|
|
982
1011
|
name: "veyl",
|
|
983
|
-
version: "0.
|
|
1012
|
+
version: "1.0.0",
|
|
984
1013
|
private: true,
|
|
985
1014
|
license: "Apache-2.0",
|
|
986
1015
|
workspaces: {
|
|
@@ -104546,7 +104575,7 @@ var init_config = __esm(() => {
|
|
|
104546
104575
|
LOCAL_PROFILE_CACHE_MAX_AGE_MS = 30 * DAY_MS;
|
|
104547
104576
|
LOCAL_AVATAR_CACHE_MAX_BYTES = 128 * MIB_BYTES;
|
|
104548
104577
|
LOCAL_AVATAR_CACHE_MAX_AGE_MS = 30 * DAY_MS;
|
|
104549
|
-
AVATAR_IMAGE_MAX_BYTES =
|
|
104578
|
+
AVATAR_IMAGE_MAX_BYTES = 256 * KIB_BYTES;
|
|
104550
104579
|
CHAT_READY_DOWNLOAD_MAX_BYTES = 8 * MIB_BYTES;
|
|
104551
104580
|
CHAT_MESSAGE_FILE_CACHE_MAX_BYTES = 64 * MIB_BYTES;
|
|
104552
104581
|
CHAT_UNSAVED_TTL_MS = CHAT_UNSAVED_TTL_DAYS * DAY_MS;
|
|
@@ -106991,18 +107020,13 @@ var init_values = __esm(() => {
|
|
|
106991
107020
|
|
|
106992
107021
|
// ../../shared/avatar.js
|
|
106993
107022
|
function readAvatarVersion(value) {
|
|
106994
|
-
|
|
106995
|
-
|
|
106996
|
-
}
|
|
106997
|
-
const version = Number(value);
|
|
106998
|
-
return Number.isSafeInteger(version) && version >= 0 ? version : null;
|
|
107023
|
+
const version = typeof value === "string" ? value.trim().toLowerCase() : "";
|
|
107024
|
+
return AVATAR_VERSION_RE.test(version) ? version : null;
|
|
106999
107025
|
}
|
|
107000
|
-
|
|
107001
|
-
|
|
107002
|
-
|
|
107003
|
-
|
|
107004
|
-
}
|
|
107005
|
-
var init_avatar = () => {};
|
|
107026
|
+
var AVATAR_VERSION_RE;
|
|
107027
|
+
var init_avatar = __esm(() => {
|
|
107028
|
+
AVATAR_VERSION_RE = /^[0-9a-f]{64}$/;
|
|
107029
|
+
});
|
|
107006
107030
|
|
|
107007
107031
|
// ../../shared/moderation.js
|
|
107008
107032
|
function banUntilMs(ban) {
|
|
@@ -107280,11 +107304,16 @@ function createUser({ cloud, network, avatarCache = null, diag = null, onSession
|
|
|
107280
107304
|
markDiag(diag, "user.avatar.fetch.start", { force: !!force, persist: !!persist, hasVersion: avatarVersion != null });
|
|
107281
107305
|
try {
|
|
107282
107306
|
const promise = (async () => {
|
|
107283
|
-
|
|
107284
|
-
|
|
107285
|
-
|
|
107307
|
+
if (persist && avatarVersion != null && avatarCache && typeof cloud.peer.avatar.read === "function") {
|
|
107308
|
+
try {
|
|
107309
|
+
const bytes = await cloud.peer.avatar.read(uid, { version: avatarVersion });
|
|
107310
|
+
const cachedAvatar = await writeCachedAvatar(uid, { version: avatarVersion, bytes });
|
|
107311
|
+
if (cachedAvatar) {
|
|
107312
|
+
return cachedAvatar;
|
|
107313
|
+
}
|
|
107314
|
+
} catch {}
|
|
107286
107315
|
}
|
|
107287
|
-
return
|
|
107316
|
+
return cloud.peer.avatar.url(uid, { version: avatarVersion });
|
|
107288
107317
|
})().then((nextAvatar) => {
|
|
107289
107318
|
markDone(diag, "user.avatar.fetch", startedAt, { found: !!nextAvatar, hasVersion: avatarVersion != null });
|
|
107290
107319
|
if (!nextAvatar || avatarFetch.uid !== uid || avatarFetch.key !== key) {
|
|
@@ -107624,10 +107653,12 @@ function createUser({ cloud, network, avatarCache = null, diag = null, onSession
|
|
|
107624
107653
|
}
|
|
107625
107654
|
function refetchAvatar(options = {}) {
|
|
107626
107655
|
const requestedVersion = readAvatarVersion(options?.version);
|
|
107627
|
-
const
|
|
107628
|
-
|
|
107629
|
-
|
|
107630
|
-
|
|
107656
|
+
const nextVersion = requestedVersion ?? state.avatarVersion;
|
|
107657
|
+
return fetchAvatar(state.uid, {
|
|
107658
|
+
force: options?.force === true || state.avatarVersion !== nextVersion || !state.avatar,
|
|
107659
|
+
persist: options?.persist !== false,
|
|
107660
|
+
version: nextVersion
|
|
107661
|
+
});
|
|
107631
107662
|
}
|
|
107632
107663
|
function setNetwork(nextNetwork) {
|
|
107633
107664
|
if (activeNetwork === nextNetwork)
|
|
@@ -110045,7 +110076,7 @@ function sameSigningKeys(left, right) {
|
|
|
110045
110076
|
function sameChatShape(a, b) {
|
|
110046
110077
|
if (!a || !b)
|
|
110047
110078
|
return a === b;
|
|
110048
|
-
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);
|
|
110079
|
+
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);
|
|
110049
110080
|
}
|
|
110050
110081
|
function sameChats(prev, next) {
|
|
110051
110082
|
if (prev.length !== next.length)
|
|
@@ -110404,8 +110435,10 @@ function emptyPayload() {
|
|
|
110404
110435
|
chatsById: {},
|
|
110405
110436
|
profilesByUid: {},
|
|
110406
110437
|
mediaByKey: {},
|
|
110438
|
+
walletBalance: null,
|
|
110407
110439
|
resumeRoute: null,
|
|
110408
|
-
lastCameraFacing: null
|
|
110440
|
+
lastCameraFacing: null,
|
|
110441
|
+
cloaked: false
|
|
110409
110442
|
};
|
|
110410
110443
|
}
|
|
110411
110444
|
function isObject3(value) {
|
|
@@ -110466,8 +110499,26 @@ function normalizePayload(value) {
|
|
|
110466
110499
|
chatsById: isObject3(input.chatsById) ? input.chatsById : {},
|
|
110467
110500
|
profilesByUid: isObject3(input.profilesByUid) ? input.profilesByUid : {},
|
|
110468
110501
|
mediaByKey: isObject3(input.mediaByKey) ? input.mediaByKey : {},
|
|
110502
|
+
walletBalance: cleanWalletBalance(input.walletBalance),
|
|
110469
110503
|
resumeRoute: cleanResumeRoute(input.resumeRoute),
|
|
110470
|
-
lastCameraFacing: cleanCameraFacing(input.lastCameraFacing)
|
|
110504
|
+
lastCameraFacing: cleanCameraFacing(input.lastCameraFacing),
|
|
110505
|
+
cloaked: input.cloaked === true
|
|
110506
|
+
};
|
|
110507
|
+
}
|
|
110508
|
+
function cleanWalletBalance(value) {
|
|
110509
|
+
if (!isObject3(value))
|
|
110510
|
+
return null;
|
|
110511
|
+
const walletPK = cleanText(value.walletPK).toLowerCase();
|
|
110512
|
+
const network = cleanText(value.network).toLowerCase();
|
|
110513
|
+
const balance = Number(value.balance);
|
|
110514
|
+
if (!walletPK || !network || !Number.isSafeInteger(balance) || balance < 0) {
|
|
110515
|
+
return null;
|
|
110516
|
+
}
|
|
110517
|
+
return {
|
|
110518
|
+
walletPK,
|
|
110519
|
+
network,
|
|
110520
|
+
balance,
|
|
110521
|
+
savedAt: Number.isFinite(value.savedAt) ? value.savedAt : 0
|
|
110471
110522
|
};
|
|
110472
110523
|
}
|
|
110473
110524
|
function cleanResumeRoute(route) {
|
|
@@ -110913,8 +110964,8 @@ function stateFromPayload(payload, { chatId, selfChatPublicKey, peerChatPublicKe
|
|
|
110913
110964
|
if (!cleanOlder.length && !cleanLive.length) {
|
|
110914
110965
|
return { rejectReason: "empty-message-cache" };
|
|
110915
110966
|
}
|
|
110916
|
-
const historyStartReached = payload.historyStartReached === true
|
|
110917
|
-
const payloadHasOlder =
|
|
110967
|
+
const historyStartReached = payload.historyStartReached === true;
|
|
110968
|
+
const payloadHasOlder = payload.hasOlder === true || payload.truncated === true;
|
|
110918
110969
|
const partialOlderThan = partial ? markerFromMessage(cleanOlder[0]) : null;
|
|
110919
110970
|
return {
|
|
110920
110971
|
historyMessages: cleanOlder,
|
|
@@ -111059,7 +111110,7 @@ function writeCachedMessageState(cache, { stateVersion = null, chatId, selfChatP
|
|
|
111059
111110
|
signingKeysVersion: cleanText(signingKeysVersion),
|
|
111060
111111
|
savedAt: Date.now(),
|
|
111061
111112
|
hasOlder: nextHasOlder === true || compacted.truncated,
|
|
111062
|
-
historyStartReached: nextHistoryStartReached === true
|
|
111113
|
+
historyStartReached: nextHistoryStartReached === true,
|
|
111063
111114
|
olderThan: serializeMarker(storedOlderThan),
|
|
111064
111115
|
olderLoaded: nextOlderLoaded === true || compacted.historyMessages.length > 0,
|
|
111065
111116
|
latestServerPage: batchFromLive(compacted.latestMessages, expiredKeys, deletedKeys, nextServerBatch),
|
|
@@ -111318,6 +111369,36 @@ var init_chats2 = __esm(() => {
|
|
|
111318
111369
|
"use client";
|
|
111319
111370
|
});
|
|
111320
111371
|
|
|
111372
|
+
// ../../shared/cache/localdata/balance.js
|
|
111373
|
+
function normalizedBalance(value) {
|
|
111374
|
+
const balance = Number(value);
|
|
111375
|
+
return Number.isSafeInteger(balance) && balance >= 0 ? balance : null;
|
|
111376
|
+
}
|
|
111377
|
+
function writeCachedWalletBalance(cache, { walletPK = null, network = null, balance = null } = {}) {
|
|
111378
|
+
const nextWalletPK = lowerText(walletPK);
|
|
111379
|
+
const nextNetwork = lowerText(network);
|
|
111380
|
+
const nextBalance = normalizedBalance(balance);
|
|
111381
|
+
if (!cache || !nextWalletPK || !nextNetwork || nextBalance == null) {
|
|
111382
|
+
return Promise.resolve(false);
|
|
111383
|
+
}
|
|
111384
|
+
const current = cache.read?.()?.walletBalance;
|
|
111385
|
+
if (sameText(current?.walletPK, nextWalletPK) && sameText(current?.network, nextNetwork) && normalizedBalance(current?.balance) === nextBalance) {
|
|
111386
|
+
return Promise.resolve(false);
|
|
111387
|
+
}
|
|
111388
|
+
return cache.patch((draft) => {
|
|
111389
|
+
draft.walletBalance = {
|
|
111390
|
+
walletPK: nextWalletPK,
|
|
111391
|
+
network: nextNetwork,
|
|
111392
|
+
balance: nextBalance,
|
|
111393
|
+
savedAt: Date.now()
|
|
111394
|
+
};
|
|
111395
|
+
return draft;
|
|
111396
|
+
}).then(() => true);
|
|
111397
|
+
}
|
|
111398
|
+
var init_balance = __esm(() => {
|
|
111399
|
+
"use client";
|
|
111400
|
+
});
|
|
111401
|
+
|
|
111321
111402
|
// ../../shared/cache/localdata/profiles.js
|
|
111322
111403
|
function isUsableProfile(profile, now = Date.now()) {
|
|
111323
111404
|
if (!profile?.uid || !profile.walletPK && !profile.chatPK) {
|
|
@@ -111558,24 +111639,26 @@ async function readCachedTransferHeadState(cache, { walletPK = null } = {}) {
|
|
|
111558
111639
|
const stored = cache ? await cache.readPart(TX_HEAD_PART).catch(() => null) : null;
|
|
111559
111640
|
return stateFromPayload2(stored, { walletPK, source: "head" });
|
|
111560
111641
|
}
|
|
111561
|
-
function
|
|
111562
|
-
if (!
|
|
111563
|
-
return
|
|
111642
|
+
function cachedTransferPayloads({ transfers, walletPK = null, serverEndReached = false, historyCount = null, nextOffset = null, oldestTxMs = null } = {}) {
|
|
111643
|
+
if (!Array.isArray(transfers)) {
|
|
111644
|
+
return null;
|
|
111564
111645
|
}
|
|
111565
111646
|
const nextWalletPK = lowerText(walletPK);
|
|
111566
111647
|
if (!nextWalletPK) {
|
|
111567
|
-
return
|
|
111648
|
+
return null;
|
|
111568
111649
|
}
|
|
111569
111650
|
const visible = [...transfers].filter((tx) => tx?.id && isVisibleTransfer(tx) && transferBelongsToWallet(tx, nextWalletPK)).sort((a, b) => txCreatedMs(b) - txCreatedMs(a));
|
|
111570
111651
|
const sorted2 = visible.slice(0, Math.max(1, WALLET_TRANSFER_CACHE_LIMIT)).map(jsonClean);
|
|
111571
111652
|
const capped = sorted2.length < visible.length;
|
|
111653
|
+
const knownHistoryCount = Math.max(sorted2.length, Math.floor(Number(historyCount) || 0));
|
|
111654
|
+
const complete = serverEndReached === true && !capped && sorted2.length >= knownHistoryCount;
|
|
111572
111655
|
const fullPayload = {
|
|
111573
111656
|
version: CACHE_VERSION,
|
|
111574
111657
|
walletPK: nextWalletPK,
|
|
111575
|
-
serverEndReached:
|
|
111576
|
-
historyCount:
|
|
111658
|
+
serverEndReached: complete,
|
|
111659
|
+
historyCount: knownHistoryCount,
|
|
111577
111660
|
nextOffset: Number.isFinite(nextOffset) ? nextOffset : sorted2.length,
|
|
111578
|
-
oldestTxMs:
|
|
111661
|
+
oldestTxMs: complete && Number.isFinite(oldestTxMs) ? oldestTxMs : null,
|
|
111579
111662
|
savedAt: Date.now(),
|
|
111580
111663
|
transfers: sorted2
|
|
111581
111664
|
};
|
|
@@ -111584,7 +111667,24 @@ function writeCachedTransferState(cache, { transfers, walletPK = null, serverEnd
|
|
|
111584
111667
|
...fullPayload,
|
|
111585
111668
|
transfers: headTransfers
|
|
111586
111669
|
};
|
|
111587
|
-
return
|
|
111670
|
+
return { fullPayload, headPayload };
|
|
111671
|
+
}
|
|
111672
|
+
function writeCachedTransferHeadState(cache, state = {}) {
|
|
111673
|
+
if (!cache) {
|
|
111674
|
+
return Promise.resolve(false);
|
|
111675
|
+
}
|
|
111676
|
+
const payloads = cachedTransferPayloads(state);
|
|
111677
|
+
return payloads ? cache.writePart(TX_HEAD_PART, payloads.headPayload) : Promise.resolve(false);
|
|
111678
|
+
}
|
|
111679
|
+
function writeCachedTransferState(cache, state = {}) {
|
|
111680
|
+
if (!cache) {
|
|
111681
|
+
return Promise.resolve(false);
|
|
111682
|
+
}
|
|
111683
|
+
const payloads = cachedTransferPayloads(state);
|
|
111684
|
+
if (!payloads) {
|
|
111685
|
+
return Promise.resolve(false);
|
|
111686
|
+
}
|
|
111687
|
+
return Promise.all([cache.writePart(TX_HEAD_PART, payloads.headPayload), cache.writePart(TX_PART, payloads.fullPayload)]).then((results) => results.some(Boolean));
|
|
111588
111688
|
}
|
|
111589
111689
|
var TX_PART = "wallet-transfers", TX_HEAD_PART = "wallet-transfers-head", CACHE_VERSION = 2, CACHE_HEAD_LIMIT;
|
|
111590
111690
|
var init_transfers = __esm(() => {
|
|
@@ -112060,6 +112160,7 @@ var init_vault2 = __esm(() => {
|
|
|
112060
112160
|
// ../../shared/cache/localdata.js
|
|
112061
112161
|
var init_localdata = __esm(() => {
|
|
112062
112162
|
init_chats2();
|
|
112163
|
+
init_balance();
|
|
112063
112164
|
init_media();
|
|
112064
112165
|
init_messages2();
|
|
112065
112166
|
init_profiles();
|
|
@@ -112137,7 +112238,8 @@ function makeOwnChatEntry(pair, fields = {}) {
|
|
|
112137
112238
|
preview: fields.preview || null,
|
|
112138
112239
|
saved: fields.saved || null,
|
|
112139
112240
|
readMs: Number.isFinite(fields.readMs) ? fields.readMs : null,
|
|
112140
|
-
startMs: Number.isFinite(fields.startMs) ? fields.startMs : null
|
|
112241
|
+
startMs: Number.isFinite(fields.startMs) ? fields.startMs : null,
|
|
112242
|
+
signerShared: fields.signerShared === true
|
|
112141
112243
|
};
|
|
112142
112244
|
}
|
|
112143
112245
|
var CHAT_ENTRY_VERSION = 1;
|
|
@@ -112902,7 +113004,25 @@ async function setChatRead(cloud, uid, chatPrivKey, chatId, readMs, options = {}
|
|
|
112902
113004
|
body: await sealOwnChatEntry(chatPrivKey, entryId, {
|
|
112903
113005
|
...entry,
|
|
112904
113006
|
readMs: Math.max(currentReadMs, nextReadMs),
|
|
112905
|
-
...hasPreviewPatch ? { preview: preview2 || null } : {}
|
|
113007
|
+
...hasPreviewPatch ? { preview: preview2 || null } : {},
|
|
113008
|
+
...options.signerShared === true ? { signerShared: true } : {}
|
|
113009
|
+
})
|
|
113010
|
+
});
|
|
113011
|
+
return true;
|
|
113012
|
+
}
|
|
113013
|
+
async function setChatSignerShared(cloud, uid, chatPrivKey, chatId) {
|
|
113014
|
+
if (!cloud || !uid || !chatPrivKey || !chatId) {
|
|
113015
|
+
return false;
|
|
113016
|
+
}
|
|
113017
|
+
const entryId = ownChatEntryId(chatPrivKey, chatId);
|
|
113018
|
+
const entry = await readOwnEntry(cloud, uid, chatPrivKey, entryId);
|
|
113019
|
+
if (!entry?.chatId || entry.signerShared === true) {
|
|
113020
|
+
return entry?.signerShared === true;
|
|
113021
|
+
}
|
|
113022
|
+
await cloud.user.chats.write(uid, entryId, {
|
|
113023
|
+
body: await sealOwnChatEntry(chatPrivKey, entryId, {
|
|
113024
|
+
...entry,
|
|
113025
|
+
signerShared: true
|
|
112906
113026
|
})
|
|
112907
113027
|
});
|
|
112908
113028
|
return true;
|
|
@@ -112945,7 +113065,8 @@ async function ownEntryWrite(cloud, uid, chatPrivKey, pair, fields = {}) {
|
|
|
112945
113065
|
preview: fields.preview || existing?.preview,
|
|
112946
113066
|
saved: existing?.saved || null,
|
|
112947
113067
|
readMs: existing?.readMs,
|
|
112948
|
-
startMs: existing?.startMs
|
|
113068
|
+
startMs: existing?.startMs,
|
|
113069
|
+
signerShared: fields.signerShared === true || existing?.signerShared === true
|
|
112949
113070
|
});
|
|
112950
113071
|
const tsMs = timestampMs(fields.ts, null);
|
|
112951
113072
|
return {
|
|
@@ -113040,10 +113161,22 @@ async function sendMsg(cloud, senderPubkey, senderPrivkey, receiverChatPK, messa
|
|
|
113040
113161
|
messageId,
|
|
113041
113162
|
message: msgData,
|
|
113042
113163
|
ownerEntry,
|
|
113043
|
-
inbox: ping ? { recipientUid: recipientProfile?.uid, ping } : null,
|
|
113164
|
+
inbox: ping ? { recipientUid: recipientProfile?.uid, ping, notify: options?.notify !== false } : null,
|
|
113044
113165
|
onCommitted: typeof options?.onCommitted === "function" ? (committed) => options.onCommitted({ ...committed, message: sentMessage, preview: preview2 }) : undefined
|
|
113045
113166
|
});
|
|
113046
|
-
|
|
113167
|
+
const delivered = options?.ping === true ? !!ping && write?.delivered !== false : write?.delivered !== false;
|
|
113168
|
+
if (ping && delivered && ownerEntry && options?.ownEntry?.signerShared !== true) {
|
|
113169
|
+
await setChatSignerShared(cloud, cleanText(options?.senderUid), senderPrivkey, chatId).catch(() => false);
|
|
113170
|
+
}
|
|
113171
|
+
return {
|
|
113172
|
+
chatId,
|
|
113173
|
+
msgId: messageId,
|
|
113174
|
+
cid: head.cid,
|
|
113175
|
+
message: sentMessage,
|
|
113176
|
+
preview: preview2,
|
|
113177
|
+
delivered,
|
|
113178
|
+
...write?.skipped ? { skipped: true } : {}
|
|
113179
|
+
};
|
|
113047
113180
|
});
|
|
113048
113181
|
}
|
|
113049
113182
|
async function sendReadReceipt(cloud, senderPubkey, senderPrivkey, receiverChatPK, target, options = {}) {
|
|
@@ -113052,7 +113185,13 @@ async function sendReadReceipt(cloud, senderPubkey, senderPrivkey, receiverChatP
|
|
|
113052
113185
|
cid: makeCid(),
|
|
113053
113186
|
s: senderPubkey
|
|
113054
113187
|
};
|
|
113055
|
-
return sendMsg(cloud, senderPubkey, senderPrivkey, receiverChatPK, receipt, {
|
|
113188
|
+
return sendMsg(cloud, senderPubkey, senderPrivkey, receiverChatPK, receipt, {
|
|
113189
|
+
...options,
|
|
113190
|
+
updatePreview: false,
|
|
113191
|
+
ping: options?.ping === true,
|
|
113192
|
+
pingKind: "read",
|
|
113193
|
+
notify: false
|
|
113194
|
+
});
|
|
113056
113195
|
}
|
|
113057
113196
|
async function sendReaction(cloud, senderPubkey, senderPrivkey, receiverChatPK, target, emoji, options = {}) {
|
|
113058
113197
|
const reaction = {
|
|
@@ -113669,7 +113808,7 @@ function messageExpiryGroups(messages, selfChatPublicKey, seenAt) {
|
|
|
113669
113808
|
{ messages: day, expiresAt: seenAt + AFTER_SEEN_MS }
|
|
113670
113809
|
].filter((group) => group.messages.length);
|
|
113671
113810
|
}
|
|
113672
|
-
function createChatSeen({ cloud, uid, chatBanned, chatPK, chatPrivateKey, localCache, pendingReadRef, readCacheRef, readWriteInterval, getChatRetention, setChats, diag }) {
|
|
113811
|
+
function createChatSeen({ cloud, uid, chatBanned, chatPK, chatPrivateKey, localCache, pendingReadRef, readCacheRef, readWriteInterval, getChatRetention, sendOptionsForPeer, setChats, diag }) {
|
|
113673
113812
|
const scheduleRead = (chatId, message, previewMs, sendReceipt, expiryMessages = []) => {
|
|
113674
113813
|
scheduleReadWrite({
|
|
113675
113814
|
pendingRead: pendingReadRef.current,
|
|
@@ -113680,24 +113819,37 @@ function createChatSeen({ cloud, uid, chatBanned, chatPK, chatPrivateKey, localC
|
|
|
113680
113819
|
expiryMessages: sendReceipt ? expiryMessages : [],
|
|
113681
113820
|
interval: readWriteInterval,
|
|
113682
113821
|
write: async (pending) => {
|
|
113822
|
+
let receiptError = null;
|
|
113823
|
+
let receiptResult = null;
|
|
113824
|
+
let introduceSigner = false;
|
|
113825
|
+
if (pending.receipt) {
|
|
113826
|
+
const sendOptions = sendOptionsForPeer(pending.receipt.peerChatPK);
|
|
113827
|
+
introduceSigner = sendOptions?.signerShared !== true;
|
|
113828
|
+
try {
|
|
113829
|
+
receiptResult = await sendReadReceipt(cloud, chatPK, chatPrivateKey, pending.receipt.peerChatPK, pending.receipt.target, {
|
|
113830
|
+
chatId,
|
|
113831
|
+
retention: getChatRetention(chatId),
|
|
113832
|
+
senderUid: uid,
|
|
113833
|
+
receiverUid: sendOptions?.receiverUid,
|
|
113834
|
+
ping: introduceSigner
|
|
113835
|
+
});
|
|
113836
|
+
} catch (error) {
|
|
113837
|
+
receiptError = error;
|
|
113838
|
+
}
|
|
113839
|
+
}
|
|
113683
113840
|
const writes = [
|
|
113684
113841
|
setChatRead(cloud, uid, chatPrivateKey, chatId, pending.previewMs, {
|
|
113685
|
-
preview: (currentPreview) => withChatPreviewOpened(currentPreview, pending.message, pending.previewMs, chatPK) || currentPreview
|
|
113842
|
+
preview: (currentPreview) => withChatPreviewOpened(currentPreview, pending.message, pending.previewMs, chatPK) || currentPreview,
|
|
113843
|
+
signerShared: introduceSigner && receiptResult?.delivered === true
|
|
113686
113844
|
})
|
|
113687
113845
|
];
|
|
113688
113846
|
if (pending.receipt) {
|
|
113689
|
-
writes.push(sendReadReceipt(cloud, chatPK, chatPrivateKey, pending.receipt.peerChatPK, pending.receipt.target, {
|
|
113690
|
-
chatId,
|
|
113691
|
-
retention: getChatRetention(chatId),
|
|
113692
|
-
senderUid: uid
|
|
113693
|
-
}));
|
|
113694
113847
|
for (const group of messageExpiryGroups(pending.expiryMessages, chatPK, pending.expirySeenAt)) {
|
|
113695
113848
|
writes.push(setMessageExpiry(cloud, chatId, group.messages, group.expiresAt));
|
|
113696
113849
|
}
|
|
113697
113850
|
}
|
|
113698
113851
|
const results = await Promise.allSettled(writes);
|
|
113699
113852
|
const ownerError = results[0]?.status === "rejected" ? results[0].reason : null;
|
|
113700
|
-
const receiptError = pending.receipt && results[1]?.status === "rejected" ? results[1].reason : null;
|
|
113701
113853
|
if (ownerError) {
|
|
113702
113854
|
markError(diag, "chat.read.state.write", Date.now(), ownerError);
|
|
113703
113855
|
}
|
|
@@ -113705,7 +113857,7 @@ function createChatSeen({ cloud, uid, chatBanned, chatPK, chatPrivateKey, localC
|
|
|
113705
113857
|
readCacheRef.current.delete(chatId);
|
|
113706
113858
|
markError(diag, "chat.read.receipt.write", Date.now(), receiptError);
|
|
113707
113859
|
}
|
|
113708
|
-
for (const result of results.slice(
|
|
113860
|
+
for (const result of results.slice(1)) {
|
|
113709
113861
|
if (result?.status === "rejected") {
|
|
113710
113862
|
markError(diag, "chat.message.expiry.write", Date.now(), result.reason);
|
|
113711
113863
|
}
|
|
@@ -115756,7 +115908,11 @@ function readableEntryWindow(entries, pageSize, chatPK, peerChatPK, options = {}
|
|
|
115756
115908
|
const limitCount = positiveInt(pageSize, MSG_BATCH_SIZE);
|
|
115757
115909
|
const projectedEntries = readableProjectedEntries(source, chatPK, peerChatPK, options);
|
|
115758
115910
|
if (!projectedEntries.length) {
|
|
115759
|
-
return {
|
|
115911
|
+
return {
|
|
115912
|
+
count: 0,
|
|
115913
|
+
entries: source.filter((entry) => isProjectionSupportMsg(entry?.message)),
|
|
115914
|
+
start: 0
|
|
115915
|
+
};
|
|
115760
115916
|
}
|
|
115761
115917
|
const indexes = projectedEntries.map((entry) => entry.index);
|
|
115762
115918
|
const projectedByIndex = new Map(projectedEntries.map((entry) => [entry.index, entry.message]));
|
|
@@ -118116,6 +118272,7 @@ function chatFromPing(ping, entryId, existing, preview2, userChatPK, ms, options
|
|
|
118116
118272
|
saved: existing?.saved || null,
|
|
118117
118273
|
readMs,
|
|
118118
118274
|
startMs,
|
|
118275
|
+
signerShared: existing?.signerShared === true,
|
|
118119
118276
|
preview: visiblePreview,
|
|
118120
118277
|
ts,
|
|
118121
118278
|
unseen: visiblePreview ? isChatUnseenForUser({ preview: visiblePreview, readMs }, userChatPK) : false
|
|
@@ -118174,7 +118331,8 @@ async function savePing(cloud, uid, userChatPK, userPrivKey, ping, options = {})
|
|
|
118174
118331
|
settings: chatSettingsFromPreview(existing?.settings, preview2),
|
|
118175
118332
|
preview: preview2 || existing?.preview,
|
|
118176
118333
|
readMs: existing?.readMs,
|
|
118177
|
-
startMs: existing ? existing.startMs : timestampMs(options.startPreview?.ts ?? preview2?.ts, null, { positive: true })
|
|
118334
|
+
startMs: existing ? existing.startMs : timestampMs(options.startPreview?.ts ?? preview2?.ts, null, { positive: true }),
|
|
118335
|
+
signerShared: existing?.signerShared === true
|
|
118178
118336
|
});
|
|
118179
118337
|
const body = await sealOwnChatEntry(userPrivKey, entryId, entry);
|
|
118180
118338
|
const record = { body };
|
|
@@ -118184,14 +118342,16 @@ async function savePing(cloud, uid, userChatPK, userPrivKey, ping, options = {})
|
|
|
118184
118342
|
await cloud.user.chats.write(uid, entryId, record);
|
|
118185
118343
|
return true;
|
|
118186
118344
|
}
|
|
118187
|
-
function chatWithReadPreview(existing, preview2, userChatPK) {
|
|
118188
|
-
if (!existing?.id
|
|
118345
|
+
function chatWithReadPreview(existing, preview2, userChatPK, fields = {}) {
|
|
118346
|
+
if (!existing?.id) {
|
|
118189
118347
|
return null;
|
|
118190
118348
|
}
|
|
118191
118349
|
return {
|
|
118192
118350
|
...existing,
|
|
118193
|
-
|
|
118194
|
-
|
|
118351
|
+
signingKeysByChatKey: fields.signingKeysByChatKey || existing.signingKeysByChatKey,
|
|
118352
|
+
peerUid: fields.peerUid || existing.peerUid,
|
|
118353
|
+
preview: preview2 || existing.preview,
|
|
118354
|
+
unseen: preview2 ? isChatUnseenForUser({ preview: preview2, readMs: existing.readMs }, userChatPK) : existing.unseen
|
|
118195
118355
|
};
|
|
118196
118356
|
}
|
|
118197
118357
|
function patchReadPingPreview(existing, receiptPreview, userChatPK) {
|
|
@@ -118272,6 +118432,8 @@ async function processInbox(cloud, uid, userChatPK, userPrivKey, options = {}) {
|
|
|
118272
118432
|
let current = chatsById.get(group.chatId) || null;
|
|
118273
118433
|
let wrote = false;
|
|
118274
118434
|
let handled = false;
|
|
118435
|
+
const identityPing = group.message?.ping || group.read?.ping || group.delete?.ping;
|
|
118436
|
+
const peerUid2 = await resolvePingUid(cloud, identityPing?.payload);
|
|
118275
118437
|
if (group.message) {
|
|
118276
118438
|
const item = group.message;
|
|
118277
118439
|
const entryId = ownChatEntryId(userPrivKey, item.chatId);
|
|
@@ -118292,7 +118454,8 @@ async function processInbox(cloud, uid, userChatPK, userPrivKey, options = {}) {
|
|
|
118292
118454
|
signingKeysByChatKey,
|
|
118293
118455
|
preview: preview2,
|
|
118294
118456
|
startPreview,
|
|
118295
|
-
tsMs: item.ms
|
|
118457
|
+
tsMs: item.ms,
|
|
118458
|
+
peerUid: peerUid2
|
|
118296
118459
|
});
|
|
118297
118460
|
}
|
|
118298
118461
|
if (group.read) {
|
|
@@ -118302,22 +118465,24 @@ async function processInbox(cloud, uid, userChatPK, userPrivKey, options = {}) {
|
|
|
118302
118465
|
const signingKeysByChatKey = pingSigningKeys(item.ping, existing);
|
|
118303
118466
|
const receiptPreview = await readPingMsg(cloud, userChatPK, userPrivKey, item.ping, signingKeysByChatKey);
|
|
118304
118467
|
const openedPreview = patchReadPingPreview(existing, receiptPreview, userChatPK);
|
|
118305
|
-
const chat = chatWithReadPreview(current, openedPreview, userChatPK
|
|
118468
|
+
const chat = chatWithReadPreview(current || existing, openedPreview, userChatPK, {
|
|
118469
|
+
signingKeysByChatKey,
|
|
118470
|
+
peerUid: peerUid2
|
|
118471
|
+
});
|
|
118306
118472
|
handled = true;
|
|
118307
|
-
if (
|
|
118308
|
-
|
|
118309
|
-
|
|
118310
|
-
|
|
118311
|
-
options.onPingChat?.(chat);
|
|
118312
|
-
}
|
|
118313
|
-
const writeExisting = chat || existing;
|
|
118314
|
-
wrote = await savePing(cloud, uid, userChatPK, userPrivKey, item.ping, {
|
|
118315
|
-
existing: writeExisting,
|
|
118316
|
-
signingKeysByChatKey,
|
|
118317
|
-
preview: openedPreview,
|
|
118318
|
-
writeTs: false
|
|
118319
|
-
}) || wrote;
|
|
118473
|
+
if (chat) {
|
|
118474
|
+
current = chat;
|
|
118475
|
+
chatsById.set(chat.id, chat);
|
|
118476
|
+
options.onPingChat?.(chat);
|
|
118320
118477
|
}
|
|
118478
|
+
const writeExisting = chat || existing;
|
|
118479
|
+
wrote = await savePing(cloud, uid, userChatPK, userPrivKey, item.ping, {
|
|
118480
|
+
existing: writeExisting,
|
|
118481
|
+
signingKeysByChatKey,
|
|
118482
|
+
preview: openedPreview || existing?.preview || null,
|
|
118483
|
+
writeTs: false,
|
|
118484
|
+
peerUid: peerUid2
|
|
118485
|
+
}) || wrote;
|
|
118321
118486
|
}
|
|
118322
118487
|
if (group.delete) {
|
|
118323
118488
|
const item = group.delete;
|
|
@@ -118338,7 +118503,8 @@ async function processInbox(cloud, uid, userChatPK, userPrivKey, options = {}) {
|
|
|
118338
118503
|
wrote = await savePing(cloud, uid, userChatPK, userPrivKey, item.ping, {
|
|
118339
118504
|
existing: writeExisting,
|
|
118340
118505
|
signingKeysByChatKey,
|
|
118341
|
-
preview: deletedPreview
|
|
118506
|
+
preview: deletedPreview,
|
|
118507
|
+
peerUid: peerUid2
|
|
118342
118508
|
}) || wrote;
|
|
118343
118509
|
}
|
|
118344
118510
|
}
|
|
@@ -118744,6 +118910,7 @@ async function decryptChatEntry(entryRecord, userChatPK, userPrivKey) {
|
|
|
118744
118910
|
saved: entry.saved || null,
|
|
118745
118911
|
readMs,
|
|
118746
118912
|
startMs,
|
|
118913
|
+
signerShared: entry.signerShared === true,
|
|
118747
118914
|
preview: visiblePreview,
|
|
118748
118915
|
ts,
|
|
118749
118916
|
unseen: visiblePreview ? isChatUnseenForUser({ preview: visiblePreview, readMs }, userChatPK) : false
|
|
@@ -119530,6 +119697,7 @@ function createChatList({
|
|
|
119530
119697
|
chatExists: !!peerChat?.id || hasServerChatForPeer(peerChatPK),
|
|
119531
119698
|
receiverUid: peerChat?.peerUid || "",
|
|
119532
119699
|
peerSigningPublicKey: peerChat?.signingKeysByChatKey?.[peerChatPK] || "",
|
|
119700
|
+
signerShared: peerChat?.signerShared === true,
|
|
119533
119701
|
ownEntry: peerChat?.entryId ? peerChat : null
|
|
119534
119702
|
};
|
|
119535
119703
|
};
|
|
@@ -120227,6 +120395,7 @@ function createChatSession({
|
|
|
120227
120395
|
readCacheRef,
|
|
120228
120396
|
readWriteInterval,
|
|
120229
120397
|
getChatRetention,
|
|
120398
|
+
sendOptionsForPeer,
|
|
120230
120399
|
setChats,
|
|
120231
120400
|
diag
|
|
120232
120401
|
});
|
|
@@ -121371,7 +121540,7 @@ function createPeersApi({ cloud, network, avatarCache = null }) {
|
|
|
121371
121540
|
}
|
|
121372
121541
|
if (avatarVersion != null && typeof cloud.peer.avatar.read === "function") {
|
|
121373
121542
|
try {
|
|
121374
|
-
const bytes = await cloud.peer.avatar.read(uid);
|
|
121543
|
+
const bytes = await cloud.peer.avatar.read(uid, { version: avatarVersion });
|
|
121375
121544
|
const cachedSource = await writeCachedAvatar(uid, avatarVersion, bytes);
|
|
121376
121545
|
if (cachedSource) {
|
|
121377
121546
|
return cachedSource;
|
|
@@ -121908,6 +122077,10 @@ function getSatsBalance(result) {
|
|
|
121908
122077
|
}
|
|
121909
122078
|
return satsBalance;
|
|
121910
122079
|
}
|
|
122080
|
+
function displayBalanceValue(value) {
|
|
122081
|
+
const balance = Number(value);
|
|
122082
|
+
return Number.isSafeInteger(balance) && balance >= 0 ? balance : null;
|
|
122083
|
+
}
|
|
121911
122084
|
function samePlainObject(a, b) {
|
|
121912
122085
|
if (a === b) {
|
|
121913
122086
|
return true;
|
|
@@ -121936,9 +122109,10 @@ function sameTokenBalances(a, b) {
|
|
|
121936
122109
|
}
|
|
121937
122110
|
return true;
|
|
121938
122111
|
}
|
|
121939
|
-
function createWalletBalance({ wallet, diag, onChange = null }) {
|
|
122112
|
+
function createWalletBalance({ wallet, diag, initialDisplayBalance = null, onBalance = null, onChange = null }) {
|
|
121940
122113
|
let snapshot = {
|
|
121941
122114
|
balance: null,
|
|
122115
|
+
displayBalance: displayBalanceValue(initialDisplayBalance),
|
|
121942
122116
|
satsBalance: null,
|
|
121943
122117
|
tokenBalances: new Map,
|
|
121944
122118
|
balanceReady: false,
|
|
@@ -121948,10 +122122,28 @@ function createWalletBalance({ wallet, diag, onChange = null }) {
|
|
|
121948
122122
|
snapshot = { ...snapshot, ...changes };
|
|
121949
122123
|
onChange?.();
|
|
121950
122124
|
};
|
|
122125
|
+
const publishDisplayBalance = (changes, value, trusted = false) => {
|
|
122126
|
+
const displayBalance = displayBalanceValue(value);
|
|
122127
|
+
if (displayBalance == null || !trusted && !snapshot.balanceReady) {
|
|
122128
|
+
return null;
|
|
122129
|
+
}
|
|
122130
|
+
if (!Object.is(snapshot.displayBalance, displayBalance)) {
|
|
122131
|
+
changes.displayBalance = displayBalance;
|
|
122132
|
+
}
|
|
122133
|
+
return displayBalance;
|
|
122134
|
+
};
|
|
121951
122135
|
const setBalance = (nextBalance) => {
|
|
121952
122136
|
const value = typeof nextBalance === "function" ? nextBalance(snapshot.balance) : nextBalance;
|
|
122137
|
+
const changes = {};
|
|
121953
122138
|
if (!Object.is(snapshot.balance, value)) {
|
|
121954
|
-
|
|
122139
|
+
changes.balance = value;
|
|
122140
|
+
}
|
|
122141
|
+
const displayBalance = publishDisplayBalance(changes, value);
|
|
122142
|
+
if (Object.keys(changes).length) {
|
|
122143
|
+
publish(changes);
|
|
122144
|
+
}
|
|
122145
|
+
if (displayBalance != null) {
|
|
122146
|
+
onBalance?.(displayBalance);
|
|
121955
122147
|
}
|
|
121956
122148
|
};
|
|
121957
122149
|
const setTokenBalances = (nextTokenBalances) => {
|
|
@@ -121960,12 +122152,13 @@ function createWalletBalance({ wallet, diag, onChange = null }) {
|
|
|
121960
122152
|
publish({ tokenBalances: new Map(source) });
|
|
121961
122153
|
}
|
|
121962
122154
|
};
|
|
121963
|
-
const setBalanceResult = (result) => {
|
|
122155
|
+
const setBalanceResult = (result, { ready = false } = {}) => {
|
|
121964
122156
|
const changes = {};
|
|
121965
122157
|
const nextBalance = getBalanceValue(result);
|
|
121966
122158
|
if (nextBalance != null && !Object.is(snapshot.balance, nextBalance)) {
|
|
121967
122159
|
changes.balance = nextBalance;
|
|
121968
122160
|
}
|
|
122161
|
+
const nextDisplayBalance = publishDisplayBalance(changes, nextBalance, true);
|
|
121969
122162
|
const nextSatsBalance = getSatsBalance(result);
|
|
121970
122163
|
if (nextSatsBalance && !samePlainObject(snapshot.satsBalance, nextSatsBalance)) {
|
|
121971
122164
|
changes.satsBalance = nextSatsBalance;
|
|
@@ -121974,9 +122167,15 @@ function createWalletBalance({ wallet, diag, onChange = null }) {
|
|
|
121974
122167
|
if (nextTokenBalances && !sameTokenBalances(snapshot.tokenBalances, nextTokenBalances)) {
|
|
121975
122168
|
changes.tokenBalances = new Map(nextTokenBalances);
|
|
121976
122169
|
}
|
|
122170
|
+
if (ready && !snapshot.balanceReady) {
|
|
122171
|
+
changes.balanceReady = true;
|
|
122172
|
+
}
|
|
121977
122173
|
if (Object.keys(changes).length) {
|
|
121978
122174
|
publish(changes);
|
|
121979
122175
|
}
|
|
122176
|
+
if (nextDisplayBalance != null) {
|
|
122177
|
+
onBalance?.(nextDisplayBalance);
|
|
122178
|
+
}
|
|
121980
122179
|
};
|
|
121981
122180
|
const setSatsBalanceResult = (nextSatsBalance) => {
|
|
121982
122181
|
if (!nextSatsBalance || typeof nextSatsBalance !== "object") {
|
|
@@ -121989,9 +122188,13 @@ function createWalletBalance({ wallet, diag, onChange = null }) {
|
|
|
121989
122188
|
if (nextSatsBalance.available != null && !Object.is(snapshot.balance, nextSatsBalance.available)) {
|
|
121990
122189
|
changes.balance = nextSatsBalance.available;
|
|
121991
122190
|
}
|
|
122191
|
+
const nextDisplayBalance = publishDisplayBalance(changes, nextSatsBalance.available);
|
|
121992
122192
|
if (Object.keys(changes).length) {
|
|
121993
122193
|
publish(changes);
|
|
121994
122194
|
}
|
|
122195
|
+
if (nextDisplayBalance != null) {
|
|
122196
|
+
onBalance?.(nextDisplayBalance);
|
|
122197
|
+
}
|
|
121995
122198
|
};
|
|
121996
122199
|
const getBalance = async () => {
|
|
121997
122200
|
if (!wallet) {
|
|
@@ -122005,7 +122208,7 @@ function createWalletBalance({ wallet, diag, onChange = null }) {
|
|
|
122005
122208
|
}
|
|
122006
122209
|
try {
|
|
122007
122210
|
const result = await wallet.getBalance();
|
|
122008
|
-
setBalanceResult(result);
|
|
122211
|
+
setBalanceResult(result, { ready: true });
|
|
122009
122212
|
markDone(diag, "wallet.balance", startedAt, { hasBalance: getBalanceValue(result) != null, hasSatsBalance: !!getSatsBalance(result), hasTokenBalances: !!getTokenBalances(result) });
|
|
122010
122213
|
} catch (error) {
|
|
122011
122214
|
markError(diag, "wallet.balance", startedAt, error);
|
|
@@ -122025,6 +122228,7 @@ function createWalletBalance({ wallet, diag, onChange = null }) {
|
|
|
122025
122228
|
const reset = () => {
|
|
122026
122229
|
snapshot = {
|
|
122027
122230
|
balance: null,
|
|
122231
|
+
displayBalance: null,
|
|
122028
122232
|
satsBalance: null,
|
|
122029
122233
|
tokenBalances: new Map,
|
|
122030
122234
|
balanceReady: false,
|
|
@@ -122041,7 +122245,7 @@ function createWalletBalance({ wallet, diag, onChange = null }) {
|
|
|
122041
122245
|
setSatsBalanceResult
|
|
122042
122246
|
};
|
|
122043
122247
|
}
|
|
122044
|
-
var
|
|
122248
|
+
var init_balance2 = () => {};
|
|
122045
122249
|
|
|
122046
122250
|
// ../../shared/wallet/deposits.js
|
|
122047
122251
|
async function getClaimableDepositUtxos(wallet, options = {}) {
|
|
@@ -123819,8 +124023,8 @@ function pendingTransfers(transfers = []) {
|
|
|
123819
124023
|
function pendingTransferIds(transfers = []) {
|
|
123820
124024
|
return pendingTransfers(transfers).map((tx) => String(tx.id));
|
|
123821
124025
|
}
|
|
123822
|
-
function
|
|
123823
|
-
return pendingTransfers(transfers).filter(
|
|
124026
|
+
function pendingIncomingTransfers(transfers = []) {
|
|
124027
|
+
return pendingTransfers(transfers).filter(isIncomingTransfer);
|
|
123824
124028
|
}
|
|
123825
124029
|
function uniqueIds(ids = []) {
|
|
123826
124030
|
return [...new Set((Array.isArray(ids) ? ids : [ids]).map((id) => String(id || "")).filter(Boolean))];
|
|
@@ -123915,7 +124119,7 @@ function adaptiveClaimBatchSize(maxBatchSize, queueDepth) {
|
|
|
123915
124119
|
}
|
|
123916
124120
|
return 1;
|
|
123917
124121
|
}
|
|
123918
|
-
function createWalletTransferSession({ wallet, walletPK, localCache, claimIncomingTransfers, pendingClaimBatchSize = null, eagerOutgoingStatusRefresh = false, eagerCacheHistory = true, transferStore, appState = null, deferBackgroundWork = null, backgroundSignal = null, diag }) {
|
|
124122
|
+
function createWalletTransferSession({ wallet, walletPK, localCache, claimIncomingTransfers, pendingClaimBatchSize = null, eagerOutgoingStatusRefresh = false, eagerCacheHistory = true, transferStore, appState = null, deferBackgroundWork = null, backgroundSignal = null, refreshBalance = null, diag }) {
|
|
123919
124123
|
if (!transferStore || typeof transferStore.subscribe !== "function" || typeof transferStore.getSnapshot !== "function" || typeof transferStore.getCacheState !== "function" || typeof transferStore.setHistory !== "function") {
|
|
123920
124124
|
throw new Error("createWalletTransferSession requires transferStore");
|
|
123921
124125
|
}
|
|
@@ -123980,7 +124184,7 @@ function createWalletTransferSession({ wallet, walletPK, localCache, claimIncomi
|
|
|
123980
124184
|
const cacheHydrateKeyRef = { current: "" };
|
|
123981
124185
|
const cacheHydratePromiseRef = { current: null };
|
|
123982
124186
|
const fullCacheHydratePromiseRef = { current: null };
|
|
123983
|
-
const cacheWriteRef = { current: { timer: null, cache: null, state: null } };
|
|
124187
|
+
const cacheWriteRef = { current: { timer: null, cache: null, state: null, fullHistory: false } };
|
|
123984
124188
|
const cacheDirtyRef = { current: false };
|
|
123985
124189
|
const lastFetchAtRef = { current: 0 };
|
|
123986
124190
|
const claimBatchSize = Math.max(1, Number(pendingClaimBatchSize) || PENDING_TRANSFER_CLAIM_BATCH_SIZE);
|
|
@@ -124308,9 +124512,9 @@ function createWalletTransferSession({ wallet, walletPK, localCache, claimIncomi
|
|
|
124308
124512
|
return false;
|
|
124309
124513
|
}
|
|
124310
124514
|
const cachedTransfers = filterTransfersForWallet(cached.transfers, walletPKRef.current);
|
|
124311
|
-
const
|
|
124312
|
-
const
|
|
124313
|
-
const
|
|
124515
|
+
const cachedPublishTransfers = !publish && historyTransfersRef.current.length ? mergeTransferPageForWallet(historyTransfersRef.current, cachedTransfers, walletPKRef.current, "append") : cachedTransfers;
|
|
124516
|
+
const cachedPendingIncoming = pendingIncomingTransfers(cachedPublishTransfers);
|
|
124517
|
+
const cachedPending = pendingTransfers(cachedPublishTransfers);
|
|
124314
124518
|
rememberPendingTransferIds(cachedPending.map((tx) => tx.id));
|
|
124315
124519
|
markDiag(diag, label, {
|
|
124316
124520
|
elapsedMs: Date.now() - startedAt,
|
|
@@ -124449,9 +124653,11 @@ function createWalletTransferSession({ wallet, walletPK, localCache, claimIncomi
|
|
|
124449
124653
|
pending.timer = null;
|
|
124450
124654
|
const cache = pending.cache;
|
|
124451
124655
|
const state = pending.state;
|
|
124656
|
+
const fullHistory = pending.fullHistory;
|
|
124452
124657
|
pending.state = null;
|
|
124453
124658
|
if (cache && state) {
|
|
124454
|
-
writeCachedTransferState
|
|
124659
|
+
const write = fullHistory ? writeCachedTransferState : writeCachedTransferHeadState;
|
|
124660
|
+
write(cache, state);
|
|
124455
124661
|
}
|
|
124456
124662
|
};
|
|
124457
124663
|
const queueWalletFetch = (read) => {
|
|
@@ -124556,7 +124762,7 @@ function createWalletTransferSession({ wallet, walletPK, localCache, claimIncomi
|
|
|
124556
124762
|
return pendingQueryPromiseRef.current;
|
|
124557
124763
|
};
|
|
124558
124764
|
const pendingIncomingClaimCandidates = (sourceTransfers = []) => {
|
|
124559
|
-
return
|
|
124765
|
+
return pendingIncomingTransfers(sourceTransfers).filter((tx) => {
|
|
124560
124766
|
const id = String(tx?.id || "");
|
|
124561
124767
|
return id && !claimedTransferIdsRef.current.has(id);
|
|
124562
124768
|
});
|
|
@@ -124772,6 +124978,9 @@ function createWalletTransferSession({ wallet, walletPK, localCache, claimIncomi
|
|
|
124772
124978
|
batchClaimedIds.push(...staged);
|
|
124773
124979
|
flushClaimed();
|
|
124774
124980
|
const uniqueBatchClaimedIds = uniqueIds(batchClaimedIds);
|
|
124981
|
+
if (uniqueBatchClaimedIds.length && typeof refreshBalance === "function") {
|
|
124982
|
+
await refreshBalance();
|
|
124983
|
+
}
|
|
124775
124984
|
const unclaimedIds = candidateIds.filter((id) => !uniqueBatchClaimedIds.includes(id) && !claimedTransferIdsRef.current.has(id));
|
|
124776
124985
|
if (unclaimedIds.length) {
|
|
124777
124986
|
const elapsedMs = Date.now() - startedAt;
|
|
@@ -125294,7 +125503,7 @@ function createWalletTransferSession({ wallet, walletPK, localCache, claimIncomi
|
|
|
125294
125503
|
try {
|
|
125295
125504
|
await yieldToUi();
|
|
125296
125505
|
const pendingTransfers2 = await getPendingTransfersSnapshot();
|
|
125297
|
-
const incomingTransfers =
|
|
125506
|
+
const incomingTransfers = pendingIncomingTransfers(pendingTransfers2);
|
|
125298
125507
|
const claimCandidates = pendingIncomingClaimCandidates(incomingTransfers);
|
|
125299
125508
|
if (!incomingTransfers.length) {
|
|
125300
125509
|
markDone(diag, "wallet.pendingTxs.active", startedAt, { pending: 0, claimed: 0, reason });
|
|
@@ -125639,7 +125848,7 @@ function createWalletTransferSession({ wallet, walletPK, localCache, claimIncomi
|
|
|
125639
125848
|
if (cacheWriteRef.current.timer) {
|
|
125640
125849
|
clearTimeout(cacheWriteRef.current.timer);
|
|
125641
125850
|
}
|
|
125642
|
-
cacheWriteRef.current = { timer: null, cache: null, state: null };
|
|
125851
|
+
cacheWriteRef.current = { timer: null, cache: null, state: null, fullHistory: false };
|
|
125643
125852
|
cacheDirtyRef.current = false;
|
|
125644
125853
|
};
|
|
125645
125854
|
const startCacheHydration = () => {
|
|
@@ -125697,12 +125906,10 @@ function createWalletTransferSession({ wallet, walletPK, localCache, claimIncomi
|
|
|
125697
125906
|
if (!cacheDirtyRef.current && !cacheWriteRef.current.timer) {
|
|
125698
125907
|
return;
|
|
125699
125908
|
}
|
|
125700
|
-
if (historyTransfersRef.current.length < knownHistoryCountRef.current) {
|
|
125701
|
-
return;
|
|
125702
|
-
}
|
|
125703
125909
|
cacheDirtyRef.current = false;
|
|
125704
125910
|
cacheWriteRef.current.cache = localCache;
|
|
125705
125911
|
cacheWriteRef.current.state = transferStore.getCacheState();
|
|
125912
|
+
cacheWriteRef.current.fullHistory = historyTransfersRef.current.length >= knownHistoryCountRef.current;
|
|
125706
125913
|
if (cacheWriteRef.current.timer) {
|
|
125707
125914
|
clearTimeout(cacheWriteRef.current.timer);
|
|
125708
125915
|
}
|
|
@@ -125731,7 +125938,7 @@ function createWalletTransferSession({ wallet, walletPK, localCache, claimIncomi
|
|
|
125731
125938
|
serverHistoryComplete: serverHistoryCompleteRef.current,
|
|
125732
125939
|
hasMoreTxs: !historyComplete,
|
|
125733
125940
|
hasPendingTxs,
|
|
125734
|
-
hasPendingIncomingTxs:
|
|
125941
|
+
hasPendingIncomingTxs: pendingIncomingTransfers(transfersRef.current).length > 0,
|
|
125735
125942
|
beginSdkActivity,
|
|
125736
125943
|
getRecentTxs,
|
|
125737
125944
|
claimPendingIncomingTransfers: claimPendingIncomingTransfers2,
|
|
@@ -126087,6 +126294,7 @@ function createWalletSession({
|
|
|
126087
126294
|
deferBackgroundWork = null,
|
|
126088
126295
|
appState = null,
|
|
126089
126296
|
transferStore,
|
|
126297
|
+
cachedBalance = null,
|
|
126090
126298
|
ghostWallet = true,
|
|
126091
126299
|
diag = null
|
|
126092
126300
|
}) {
|
|
@@ -126104,6 +126312,7 @@ function createWalletSession({
|
|
|
126104
126312
|
const txSubscriptions = createFieldSubscriptions(() => publishedSnapshot?.txValue);
|
|
126105
126313
|
let polling = null;
|
|
126106
126314
|
let readyDiag = null;
|
|
126315
|
+
let refreshWalletBalance = null;
|
|
126107
126316
|
const transferSession = createWalletTransferSession({
|
|
126108
126317
|
wallet,
|
|
126109
126318
|
walletPK,
|
|
@@ -126116,6 +126325,7 @@ function createWalletSession({
|
|
|
126116
126325
|
appState,
|
|
126117
126326
|
deferBackgroundWork,
|
|
126118
126327
|
backgroundSignal: backgroundAbort.signal,
|
|
126328
|
+
refreshBalance: () => refreshWalletBalance?.(),
|
|
126119
126329
|
diag
|
|
126120
126330
|
});
|
|
126121
126331
|
const getTransferState = () => transferSession.getSnapshot();
|
|
@@ -126135,7 +126345,16 @@ function createWalletSession({
|
|
|
126135
126345
|
listener();
|
|
126136
126346
|
}
|
|
126137
126347
|
};
|
|
126138
|
-
const balance = createWalletBalance({
|
|
126348
|
+
const balance = createWalletBalance({
|
|
126349
|
+
wallet,
|
|
126350
|
+
diag,
|
|
126351
|
+
initialDisplayBalance: cachedBalance,
|
|
126352
|
+
onBalance: (value) => {
|
|
126353
|
+
writeCachedWalletBalance(localCache, { walletPK, network, balance: value }).catch(() => {});
|
|
126354
|
+
},
|
|
126355
|
+
onChange: publish
|
|
126356
|
+
});
|
|
126357
|
+
refreshWalletBalance = balance.getBalance;
|
|
126139
126358
|
const funding = createFundingAddress({ wallet, network, diag, onChange: publish });
|
|
126140
126359
|
const updateWalletData = createWalletData({
|
|
126141
126360
|
wallet,
|
|
@@ -126216,6 +126435,7 @@ function createWalletSession({
|
|
|
126216
126435
|
wallet,
|
|
126217
126436
|
network,
|
|
126218
126437
|
balance: balanceState.balance,
|
|
126438
|
+
displayBalance: balanceState.displayBalance,
|
|
126219
126439
|
satsBalance: balanceState.satsBalance,
|
|
126220
126440
|
tokenBalances: balanceState.tokenBalances,
|
|
126221
126441
|
fundingAddress: funding.getSnapshot(),
|
|
@@ -126314,7 +126534,7 @@ function createWalletSession({
|
|
|
126314
126534
|
};
|
|
126315
126535
|
}
|
|
126316
126536
|
var init_session4 = __esm(() => {
|
|
126317
|
-
|
|
126537
|
+
init_balance2();
|
|
126318
126538
|
init_claims();
|
|
126319
126539
|
init_funding();
|
|
126320
126540
|
init_lightning();
|
|
@@ -126323,6 +126543,7 @@ var init_session4 = __esm(() => {
|
|
|
126323
126543
|
init_send2();
|
|
126324
126544
|
init_transfers2();
|
|
126325
126545
|
init_withdraw();
|
|
126546
|
+
init_localdata();
|
|
126326
126547
|
});
|
|
126327
126548
|
|
|
126328
126549
|
// ../../shared/wallet/transferstore.js
|
|
@@ -126531,6 +126752,7 @@ function createTransferStore() {
|
|
|
126531
126752
|
transfers: state.historyTransfers,
|
|
126532
126753
|
walletPK: state.walletPK,
|
|
126533
126754
|
serverEndReached: state.serverEndReached,
|
|
126755
|
+
historyCount: state.historyCount,
|
|
126534
126756
|
nextOffset: state.nextOffset,
|
|
126535
126757
|
oldestTxMs: state.serverEndReached ? state.oldestVerifiedTxMs : null
|
|
126536
126758
|
};
|
|
@@ -170014,9 +170236,13 @@ function peerRecordFromDoc(snap) {
|
|
|
170014
170236
|
function peerRecordsFromSnapshot(snapshot) {
|
|
170015
170237
|
return snapshot.docs.map(peerRecordFromDoc).filter(Boolean);
|
|
170016
170238
|
}
|
|
170017
|
-
function avatarPath(uid) {
|
|
170239
|
+
function avatarPath(uid, version8) {
|
|
170018
170240
|
requireUid(uid);
|
|
170019
|
-
|
|
170241
|
+
const avatarVersion = readAvatarVersion(version8);
|
|
170242
|
+
if (!avatarVersion) {
|
|
170243
|
+
throw new Error("avatar version required");
|
|
170244
|
+
}
|
|
170245
|
+
return `${uid}/avatars/${avatarVersion}.webp`;
|
|
170020
170246
|
}
|
|
170021
170247
|
function reportEvidencePath(reporter, targetUid, evidenceId) {
|
|
170022
170248
|
if (!reporter || !targetUid || !evidenceId) {
|
|
@@ -170082,6 +170308,7 @@ function createFirebaseCloud({ db, auth: auth2, getAuth: getAuth2, functions: fu
|
|
|
170082
170308
|
}
|
|
170083
170309
|
let activeVaultSigner = null;
|
|
170084
170310
|
const localSessionTerminations = new Set;
|
|
170311
|
+
const pendingAvatars = new Map;
|
|
170085
170312
|
function pageTs(value) {
|
|
170086
170313
|
if (value instanceof Timestamp2) {
|
|
170087
170314
|
return value;
|
|
@@ -170350,6 +170577,7 @@ function createFirebaseCloud({ db, auth: auth2, getAuth: getAuth2, functions: fu
|
|
|
170350
170577
|
}, onError);
|
|
170351
170578
|
}
|
|
170352
170579
|
async function logout() {
|
|
170580
|
+
pendingAvatars.clear();
|
|
170353
170581
|
await signOut(requireAuth());
|
|
170354
170582
|
return true;
|
|
170355
170583
|
}
|
|
@@ -170483,25 +170711,45 @@ function createFirebaseCloud({ db, auth: auth2, getAuth: getAuth2, functions: fu
|
|
|
170483
170711
|
await callFunction("acceptAgreement");
|
|
170484
170712
|
return true;
|
|
170485
170713
|
}
|
|
170486
|
-
async function
|
|
170714
|
+
async function setProfileAvatar(uid, data) {
|
|
170487
170715
|
requireUid(uid);
|
|
170488
|
-
|
|
170489
|
-
|
|
170490
|
-
|
|
170491
|
-
|
|
170492
|
-
|
|
170493
|
-
|
|
170494
|
-
|
|
170495
|
-
|
|
170496
|
-
|
|
170497
|
-
|
|
170498
|
-
|
|
170499
|
-
|
|
170500
|
-
|
|
170501
|
-
|
|
170502
|
-
|
|
170503
|
-
|
|
170504
|
-
|
|
170716
|
+
if (requireAuth().currentUser?.uid !== uid) {
|
|
170717
|
+
throw new Error("avatar account mismatch");
|
|
170718
|
+
}
|
|
170719
|
+
if (data == null) {
|
|
170720
|
+
pendingAvatars.delete(uid);
|
|
170721
|
+
const result = await callFunction("setAvatar", { body: null });
|
|
170722
|
+
if (result?.avatar != null) {
|
|
170723
|
+
throw new Error("avatar clear returned invalid state");
|
|
170724
|
+
}
|
|
170725
|
+
return { version: null };
|
|
170726
|
+
}
|
|
170727
|
+
const bytes = new Uint8Array(encryptedBytes(data, "avatar bytes"));
|
|
170728
|
+
const pending = { bytes, version: null, promise: null };
|
|
170729
|
+
const entries = pendingAvatars.get(uid) || [];
|
|
170730
|
+
pendingAvatars.set(uid, [...entries, pending]);
|
|
170731
|
+
pending.promise = callFunction("setAvatar", {
|
|
170732
|
+
body: cloudBytesBase64(bytes, "avatar bytes")
|
|
170733
|
+
}).then((result) => {
|
|
170734
|
+
const version8 = readAvatarVersion(result?.avatar);
|
|
170735
|
+
if (!version8) {
|
|
170736
|
+
throw new Error("avatar publish returned invalid version");
|
|
170737
|
+
}
|
|
170738
|
+
pending.version = version8;
|
|
170739
|
+
return version8;
|
|
170740
|
+
});
|
|
170741
|
+
try {
|
|
170742
|
+
return { version: await pending.promise };
|
|
170743
|
+
} catch (error) {
|
|
170744
|
+
const active = pendingAvatars.get(uid) || [];
|
|
170745
|
+
const remaining = active.filter((entry) => entry !== pending);
|
|
170746
|
+
if (remaining.length) {
|
|
170747
|
+
pendingAvatars.set(uid, remaining);
|
|
170748
|
+
} else {
|
|
170749
|
+
pendingAvatars.delete(uid);
|
|
170750
|
+
}
|
|
170751
|
+
throw error;
|
|
170752
|
+
}
|
|
170505
170753
|
}
|
|
170506
170754
|
async function writeProfileIdentity(identity) {
|
|
170507
170755
|
if (!identity || typeof identity !== "object" || Array.isArray(identity)) {
|
|
@@ -170638,13 +170886,28 @@ function createFirebaseCloud({ db, auth: auth2, getAuth: getAuth2, functions: fu
|
|
|
170638
170886
|
onUpdate?.(snap.exists() ? snap.data()?.active === true : false, { exists: snap.exists() });
|
|
170639
170887
|
}, onError);
|
|
170640
170888
|
}
|
|
170641
|
-
async function readPeerAvatar(uid) {
|
|
170642
|
-
|
|
170889
|
+
async function readPeerAvatar(uid, { version: version8 = null } = {}) {
|
|
170890
|
+
const avatarVersion = readAvatarVersion(version8);
|
|
170891
|
+
const entries = pendingAvatars.get(uid) || [];
|
|
170892
|
+
if (entries.length) {
|
|
170893
|
+
await Promise.allSettled(entries.map((entry) => entry.promise));
|
|
170894
|
+
const pending = entries.find((entry) => entry.version === avatarVersion);
|
|
170895
|
+
if (pending) {
|
|
170896
|
+
const active = pendingAvatars.get(uid) || [];
|
|
170897
|
+
const remaining = active.filter((entry) => entry !== pending);
|
|
170898
|
+
if (remaining.length) {
|
|
170899
|
+
pendingAvatars.set(uid, remaining);
|
|
170900
|
+
} else {
|
|
170901
|
+
pendingAvatars.delete(uid);
|
|
170902
|
+
}
|
|
170903
|
+
return new Uint8Array(pending.bytes);
|
|
170904
|
+
}
|
|
170905
|
+
}
|
|
170906
|
+
return readStorageFile(avatarPath(uid, avatarVersion));
|
|
170643
170907
|
}
|
|
170644
170908
|
async function peerAvatarUrl(uid, { version: version8 = null } = {}) {
|
|
170645
170909
|
const targetStorage = requireStorage2();
|
|
170646
|
-
|
|
170647
|
-
return avatarUrlWithVersion(url, version8);
|
|
170910
|
+
return getDownloadURL(ref(targetStorage, avatarPath(uid, version8)));
|
|
170648
170911
|
}
|
|
170649
170912
|
function profileQueryField(field2, { network } = {}) {
|
|
170650
170913
|
if (field2 === "walletPK") {
|
|
@@ -171103,12 +171366,13 @@ function createFirebaseCloud({ db, auth: auth2, getAuth: getAuth2, functions: fu
|
|
|
171103
171366
|
}
|
|
171104
171367
|
};
|
|
171105
171368
|
}
|
|
171106
|
-
async function pushInbox(recipientUid, ping) {
|
|
171369
|
+
async function pushInbox(recipientUid, ping, options2 = {}) {
|
|
171107
171370
|
requireUid(recipientUid);
|
|
171108
171371
|
if (!ping)
|
|
171109
171372
|
throw new Error("inbox ping required");
|
|
171110
171373
|
await callFunction("push", {
|
|
171111
171374
|
recipientUid,
|
|
171375
|
+
notify: options2?.notify !== false,
|
|
171112
171376
|
ping: {
|
|
171113
171377
|
v: ping.v,
|
|
171114
171378
|
epk: ping.epk,
|
|
@@ -171147,7 +171411,9 @@ function createFirebaseCloud({ db, auth: auth2, getAuth: getAuth2, functions: fu
|
|
|
171147
171411
|
payload.onCommitted?.({ chatId, messageId });
|
|
171148
171412
|
let delivered = true;
|
|
171149
171413
|
if (payload.inbox?.recipientUid && payload.inbox?.ping) {
|
|
171150
|
-
delivered = await pushInbox(payload.inbox.recipientUid, payload.inbox.ping
|
|
171414
|
+
delivered = await pushInbox(payload.inbox.recipientUid, payload.inbox.ping, {
|
|
171415
|
+
notify: payload.inbox.notify !== false
|
|
171416
|
+
}).then(() => true, () => false);
|
|
171151
171417
|
}
|
|
171152
171418
|
return { chatId, messageId, delivered };
|
|
171153
171419
|
}
|
|
@@ -171400,18 +171666,19 @@ function createFirebaseCloud({ db, auth: auth2, getAuth: getAuth2, functions: fu
|
|
|
171400
171666
|
}
|
|
171401
171667
|
async function banAdminUser(uid, feature = "chat") {
|
|
171402
171668
|
requireUid(uid);
|
|
171403
|
-
await setDoc(doc(db, "moderation", uid), { banned: { [feature]: { until: null } } }, { merge: true });
|
|
171404
171669
|
if (feature === "avatar") {
|
|
171405
|
-
await
|
|
171406
|
-
|
|
171407
|
-
throw error;
|
|
171408
|
-
}
|
|
171409
|
-
});
|
|
171670
|
+
await callFunction("setAvatarModeration", { uid, banned: true });
|
|
171671
|
+
return true;
|
|
171410
171672
|
}
|
|
171673
|
+
await setDoc(doc(db, "moderation", uid), { banned: { [feature]: { until: null } } }, { merge: true });
|
|
171411
171674
|
return true;
|
|
171412
171675
|
}
|
|
171413
171676
|
async function unbanAdminUser(uid, feature = "chat") {
|
|
171414
171677
|
requireUid(uid);
|
|
171678
|
+
if (feature === "avatar") {
|
|
171679
|
+
await callFunction("setAvatarModeration", { uid, banned: false });
|
|
171680
|
+
return true;
|
|
171681
|
+
}
|
|
171415
171682
|
await setDoc(doc(db, "moderation", uid), { banned: { [feature]: deleteField() } }, { merge: true });
|
|
171416
171683
|
return true;
|
|
171417
171684
|
}
|
|
@@ -171449,9 +171716,7 @@ function createFirebaseCloud({ db, auth: auth2, getAuth: getAuth2, functions: fu
|
|
|
171449
171716
|
write: writeProfileIdentity
|
|
171450
171717
|
},
|
|
171451
171718
|
avatar: {
|
|
171452
|
-
|
|
171453
|
-
upload: uploadProfileAvatar,
|
|
171454
|
-
delete: deleteProfileAvatar
|
|
171719
|
+
set: setProfileAvatar
|
|
171455
171720
|
}
|
|
171456
171721
|
},
|
|
171457
171722
|
private: {
|
|
@@ -174041,13 +174306,6 @@ function cleanMessage(value, limit2, label = "message") {
|
|
|
174041
174306
|
throw new Error(`${label} must be ${limit2} characters or fewer`);
|
|
174042
174307
|
return message;
|
|
174043
174308
|
}
|
|
174044
|
-
function readAvatarGeneration(value) {
|
|
174045
|
-
const version8 = Number(value);
|
|
174046
|
-
if (!Number.isSafeInteger(version8) || version8 <= 0) {
|
|
174047
|
-
throw new Error("avatar upload did not return a valid generation");
|
|
174048
|
-
}
|
|
174049
|
-
return version8;
|
|
174050
|
-
}
|
|
174051
174309
|
function passkeyRows(linksList, passkeys, currentPasskeyId) {
|
|
174052
174310
|
return [...linksList, ...passkeys].sort((left, right) => (right.createdAt || 0) - (left.createdAt || 0)).map((row) => ({
|
|
174053
174311
|
...row,
|
|
@@ -174135,23 +174393,17 @@ function createRuntimeProductActions({
|
|
|
174135
174393
|
const user = await getUser();
|
|
174136
174394
|
if (!data)
|
|
174137
174395
|
throw new Error("avatar data required");
|
|
174138
|
-
|
|
174139
|
-
|
|
174140
|
-
}
|
|
174141
|
-
const
|
|
174142
|
-
await
|
|
174143
|
-
|
|
174144
|
-
return { avatar:
|
|
174396
|
+
if (options2.contentType && options2.contentType !== "image/webp") {
|
|
174397
|
+
throw new Error("avatar content type must be image/webp");
|
|
174398
|
+
}
|
|
174399
|
+
const result = await cloud.user.profile.avatar.set(user.uid, data);
|
|
174400
|
+
await user.refetchAvatar?.({ version: result.version });
|
|
174401
|
+
const updated = await getUser();
|
|
174402
|
+
return { avatar: updated.avatar || null, avatarVersion: result.version };
|
|
174145
174403
|
},
|
|
174146
174404
|
async deleteAvatar() {
|
|
174147
174405
|
const user = await getUser();
|
|
174148
|
-
|
|
174149
|
-
await cloud.user.profile.avatar.delete(user.uid);
|
|
174150
|
-
} catch (error) {
|
|
174151
|
-
if (error?.code !== "storage/object-not-found")
|
|
174152
|
-
throw error;
|
|
174153
|
-
}
|
|
174154
|
-
await cloud.user.profile.avatar.write(user.uid, null);
|
|
174406
|
+
await cloud.user.profile.avatar.set(user.uid, null);
|
|
174155
174407
|
user.clearAvatar?.();
|
|
174156
174408
|
return { deleted: true };
|
|
174157
174409
|
}
|