@glyphteck/veyl 0.31.1 → 0.35.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 +649 -383
- package/dist/index.js +649 -383
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -5906,9 +5906,8 @@ var init_vaultsignature = __esm(() => {
|
|
|
5906
5906
|
DELETE_ACCOUNT: "delete-account",
|
|
5907
5907
|
DELETE_PASSKEY: "delete-passkey",
|
|
5908
5908
|
LOGOUT_ALL_DEVICES: "logout-all-devices",
|
|
5909
|
-
|
|
5910
|
-
SET_SETTINGS: "set-settings"
|
|
5911
|
-
SET_WALLET_IDENTITY: "set-wallet-identity"
|
|
5909
|
+
SET_IDENTITIES: "set-identities",
|
|
5910
|
+
SET_SETTINGS: "set-settings"
|
|
5912
5911
|
});
|
|
5913
5912
|
});
|
|
5914
5913
|
|
|
@@ -6217,7 +6216,7 @@ var init_seed = __esm(() => {
|
|
|
6217
6216
|
});
|
|
6218
6217
|
|
|
6219
6218
|
// ../../shared/config.js
|
|
6220
|
-
var MS_PER_SECOND = 1000, MINUTE_MS, HOUR_MS, DAY_MS, KIB_BYTES = 1024, MIB_BYTES, SATS_PER_BITCOIN = 100000000n, USERNAME_MAX_CHARS = 12, PASSWORD_MIN_CHARS = 12, PASSWORD_MAX_CHARS = 64, AUTOLOCK_MIN_MINUTES = 1, AUTOLOCK_MAX_MINUTES = 60, LOCAL_CACHE_WRITE_DELAY_MS = 350, LOCAL_MEDIA_CACHE_MAX_BYTES, LOCAL_MEDIA_CACHE_MAX_ITEMS = 1000, LOCAL_MEDIA_ACCESS_TOUCH_MIN_MS, LOCAL_PROFILE_CACHE_MAX_ITEMS = 500, LOCAL_PROFILE_CACHE_MAX_AGE_MS, LOCAL_CHAT_CACHE_MAX_ITEMS = 1000, LOCAL_CHAT_MESSAGE_CACHE_MAX_VISIBLE = 1000, LOCAL_AVATAR_CACHE_MAX_BYTES, LOCAL_AVATAR_CACHE_MAX_AGE_MS, AVATAR_IMAGE_MAX_BYTES, CHAT_READY_DOWNLOAD_MAX_BYTES, CHAT_MESSAGE_FILE_CACHE_MAX_BYTES, IDLE_CALLBACK_MIN_TIMEOUT_MS = 50, ATTACHMENT_CACHE_IDLE_TIMEOUT_MS = 2500, ATTACHMENT_CACHE_FALLBACK_DELAY_MS = 250, CHAT_UNSAVED_TTL_DAYS = 21, CHAT_UNSAVED_TTL_MS, CHAT_AFTER_SEEN_MS, CHAT_MEDIA_TTL_DAYS, CHAT_MEDIA_TTL_MS, CHAT_UPLOAD_MAX_BYTES, CHAT_AUDIO_TRANSCODE_BITRATE_BPS = 128000, CHAT_VIDEO_TRANSCODE_VIDEO_BITRATE_BPS =
|
|
6219
|
+
var MS_PER_SECOND = 1000, MINUTE_MS, HOUR_MS, DAY_MS, KIB_BYTES = 1024, MIB_BYTES, SATS_PER_BITCOIN = 100000000n, USERNAME_MAX_CHARS = 12, PASSWORD_MIN_CHARS = 12, PASSWORD_MAX_CHARS = 64, AUTOLOCK_MIN_MINUTES = 1, AUTOLOCK_MAX_MINUTES = 60, LOCAL_CACHE_WRITE_DELAY_MS = 350, LOCAL_MEDIA_CACHE_MAX_BYTES, LOCAL_MEDIA_CACHE_MAX_ITEMS = 1000, LOCAL_MEDIA_ACCESS_TOUCH_MIN_MS, LOCAL_PROFILE_CACHE_MAX_ITEMS = 500, LOCAL_PROFILE_CACHE_MAX_AGE_MS, LOCAL_CHAT_CACHE_MAX_ITEMS = 1000, LOCAL_CHAT_MESSAGE_CACHE_MAX_VISIBLE = 1000, LOCAL_AVATAR_CACHE_MAX_BYTES, LOCAL_AVATAR_CACHE_MAX_AGE_MS, AVATAR_IMAGE_MAX_BYTES, CHAT_READY_DOWNLOAD_MAX_BYTES, CHAT_MESSAGE_FILE_CACHE_MAX_BYTES, IDLE_CALLBACK_MIN_TIMEOUT_MS = 50, ATTACHMENT_CACHE_IDLE_TIMEOUT_MS = 2500, ATTACHMENT_CACHE_FALLBACK_DELAY_MS = 250, CHAT_UNSAVED_TTL_DAYS = 21, CHAT_UNSAVED_TTL_MS, CHAT_AFTER_SEEN_MS, CHAT_MEDIA_TTL_DAYS, CHAT_MEDIA_TTL_MS, CHAT_UPLOAD_MAX_BYTES, CHAT_AUDIO_TRANSCODE_BITRATE_BPS = 128000, CHAT_VIDEO_TRANSCODE_VIDEO_BITRATE_BPS = 3000000, CHAT_VIDEO_TRANSCODE_AUDIO_BITRATE_BPS, CHAT_MESSAGE_BATCH_SIZE = 40, CHAT_MESSAGE_QUERY_MAX_DOCS = 120, CHAT_TTL_CLIENT_DELETE_GRACE_MS, CHAT_TTL_DELETE_CHUNK_SIZE = 40, CHAT_DELETE_SCAN_BATCH_SIZE = 200, CHAT_TTL_WRITE_BATCH_SIZE = 400, CHAT_DELETE_WRITE_BATCH_SIZE = 400, CHAT_BATCH_CLEANUP_IDLE_TIMEOUT_MS = 1500, CHAT_BATCH_CLEANUP_IDLE_DELAY_MS = 250, CHAT_LIST_PAGE_SIZE = 20, CHAT_LIST_LIVE_COUNT, CHAT_INBOX_PING_PAGE_SIZE = 25, CHAT_LIST_CACHE_WRITE_DELAY_MS = 1500, CHAT_LIST_SNAPSHOT_COALESCE_MS = 80, CHAT_LIST_STATUS_CACHE_MS, CHAT_LIST_LISTENER_RETRY_MS = 1000, CHAT_TOP_WARM_COUNT = 0, CHAT_EAGER_WARM_COUNT = 0, CHAT_WARM_DELAY_MS = 3000, CHAT_WARM_BATCH_SIZE, CHAT_MESSAGE_VIEW_CACHE_SIZE = 30, CHAT_MEDIA_WARM_MESSAGES_PER_CHAT, CHAT_MEDIA_WARM_START_DELAY_MS = 600, CHAT_MEDIA_WARM_STEP_DELAY_MS = 120, CHAT_MEDIA_WARM_TYPES, CHAT_MEDIA_WARM_MAX_BYTES = 0, CHAT_READ_WRITE_INTERVAL_MS, CHAT_SEND_QUEUE_RATE_LIMIT_COUNT = 12, CHAT_SEND_QUEUE_RATE_LIMIT_WINDOW_MS, CHAT_MESSAGE_BODY_MAX_BYTES, CHAT_LAST_MESSAGE_BODY_MAX_BYTES, CHAT_SETTINGS_BODY_MAX_BYTES, BOT_WALLET_CLAIM_POLL_MS, BOT_WALLET_IDLE_CLAIM_POLL_MS, CHAT_MAX_TEXT_CHARS = 2048, CHAT_MAX_REACTIONS = 2, CHAT_PAIR_CACHE_LIMIT = 256, SEARCH_DEBOUNCE_MS = 300, SEARCH_USERNAME_LIMIT = 15, SEARCH_ROLE_LIMIT = 15, RECENT_PEER_REFRESH_LIMIT = 50, RECENT_PEER_REFRESH_DELAY_MS = 250, RECENT_PEER_REFRESH_INTERVAL_MS, RECENT_PEER_REFRESH_THROTTLE_MS = 120, BAN_REFRESH_GRACE_MS = 50, REQUEST_MONEY_MAX_SATS, WALLET_TRANSFER_POLL_MS, WALLET_ACTIVE_TRANSFER_REFRESH_MS, WALLET_IDLE_ACTIVE_TRANSFER_REFRESH_MS, WALLET_VISIBLE_TRANSFER_DISCOVERY_WINDOW_MS, WALLET_ACTIVE_TRANSFER_EMPTY_SCAN_LIMIT = 8, WALLET_CACHE_HYDRATE_DELAY_MS = 0, WALLET_BOOT_REFRESH_DELAY_MS = 500, WALLET_BOOT_CACHED_REFRESH_DELAY_MS = 2500, WALLET_REGTEST_DEPOSIT_CLAIM_POLL_MS, WALLET_MAINNET_DEPOSIT_CLAIM_POLL_MS, WALLET_BALANCE_EVENT_COALESCE_MS, WALLET_INCOMING_UPDATE_COALESCE_MS = 250, WALLET_AUTO_CLAIM_MAX_FEE_SATS = 5000, WALLET_CLAIM_PAGE_SIZE = 100, WALLET_PENDING_TRANSFER_CLAIM_BATCH_SIZE = 50, WALLET_PENDING_TRANSFER_STATUS_BATCH_SIZE = 2, WALLET_PENDING_TRANSFER_COLD_REFRESH_BATCH_SIZE = 50, WALLET_PENDING_TRANSFER_COLD_REFRESH_INTERVAL_MS, WALLET_PENDING_TRANSFER_ADAPTIVE_BATCH_SMALL_QUEUE = 3, WALLET_PENDING_TRANSFER_ADAPTIVE_BATCH_LARGE_QUEUE = 10, WALLET_PENDING_TRANSFER_ADAPTIVE_BATCH_SMALL_SIZE = 2, WALLET_PENDING_TRANSFER_ADAPTIVE_BATCH_LARGE_SIZE = 3, WALLET_PENDING_TRANSFER_SLOW_CLAIM_MS, WALLET_PENDING_TRANSFER_CLAIM_COOLDOWN_MS, WALLET_SDK_BACKGROUND_QUIET_MS, WALLET_RECENT_TRANSFER_LIMIT = 100, WALLET_TRANSFER_CACHE_LIMIT = 1e4, WALLET_TRANSFER_PAGE_LIMIT = 100, WALLET_TRANSFER_FETCH_THROTTLE_MS = 150, WALLET_PENDING_TRANSFER_CLAIM_RETRY_MS, WALLET_SENT_TRANSFER_REFRESH_DELAY_MS, WALLET_PENDING_TRANSFER_BOOT_GRACE_MS, WALLET_PENDING_TRANSFER_HOT_AGE_MS, WALLET_PENDING_TRANSFER_WARM_AGE_MS, WALLET_PENDING_TRANSFER_WARM_RETRY_MS, WALLET_PENDING_TRANSFER_STALE_RETRY_MS, WALLET_PENDING_TRANSFER_STUCK_RETRY_MS, WALLET_PENDING_TRANSFER_DORMANT_RETRY_MS, WALLET_TRANSFER_CACHE_WRITE_DELAY_MS;
|
|
6221
6220
|
var init_config = __esm(() => {
|
|
6222
6221
|
MINUTE_MS = 60 * MS_PER_SECOND;
|
|
6223
6222
|
HOUR_MS = 60 * MINUTE_MS;
|
|
@@ -7744,20 +7743,17 @@ function expectedSigningKeys(pair, signingKeysByChatKey) {
|
|
|
7744
7743
|
}
|
|
7745
7744
|
return values;
|
|
7746
7745
|
}
|
|
7747
|
-
async function
|
|
7746
|
+
async function preverifyExpectedSigner(pair, sig, bytes, options = {}) {
|
|
7748
7747
|
if (!options?.crypto?.preverifyBeforeOpen) {
|
|
7749
|
-
return
|
|
7750
|
-
}
|
|
7751
|
-
const signingKeysByChatKey = expectedSigningKeys(pair, options?.signingKeysByChatKey);
|
|
7752
|
-
if (signingKeysByChatKey.length < 2) {
|
|
7753
|
-
return true;
|
|
7748
|
+
return "";
|
|
7754
7749
|
}
|
|
7755
|
-
|
|
7750
|
+
const signingPublicKeys = expectedSigningKeys(pair, options?.signingKeysByChatKey);
|
|
7751
|
+
for (const signingPublicKey of signingPublicKeys) {
|
|
7756
7752
|
if (await verifyMsgSignature(signingPublicKey, sig, bytes, options)) {
|
|
7757
|
-
return
|
|
7753
|
+
return signingPublicKey;
|
|
7758
7754
|
}
|
|
7759
7755
|
}
|
|
7760
|
-
return
|
|
7756
|
+
return null;
|
|
7761
7757
|
}
|
|
7762
7758
|
async function sealMsg(pair, message, options = {}) {
|
|
7763
7759
|
const head = getHead(pair, message);
|
|
@@ -7778,14 +7774,16 @@ async function openMsg(pair, data, options = {}) {
|
|
|
7778
7774
|
const { suite, flags, nonce, sig, ct } = unpackMsgBody(data.body);
|
|
7779
7775
|
const aad = getMsgAad(pair, head, suite, flags);
|
|
7780
7776
|
const signatureInput = getSignatureInput(aad, nonce, ct);
|
|
7781
|
-
|
|
7777
|
+
const preverifiedSigner = await preverifyExpectedSigner(pair, sig, signatureInput, options);
|
|
7778
|
+
if (preverifiedSigner == null) {
|
|
7782
7779
|
throw new Error("invalid chat action signature");
|
|
7783
7780
|
}
|
|
7784
7781
|
const plaintext = await openMsgPlaintext(pair, nonce, ct, aad, options);
|
|
7785
7782
|
try {
|
|
7786
7783
|
const action = JSON.parse(decoder.decode(plaintext));
|
|
7787
7784
|
const normalized = normalizeOpenedAction(pair, head, action, options);
|
|
7788
|
-
|
|
7785
|
+
const validSignature = preverifiedSigner ? normalized.signingPublicKey === preverifiedSigner : await verifyMsgSignature(normalized.signingPublicKey, sig, signatureInput, options);
|
|
7786
|
+
if (!validSignature) {
|
|
7789
7787
|
throw new Error("invalid chat action signature");
|
|
7790
7788
|
}
|
|
7791
7789
|
return {
|
|
@@ -7859,40 +7857,120 @@ var init_protocol = __esm(() => {
|
|
|
7859
7857
|
});
|
|
7860
7858
|
|
|
7861
7859
|
// ../../shared/chat/pairs.js
|
|
7860
|
+
function accountGeneration(chatPK) {
|
|
7861
|
+
return accountGenerations.get(cleanText(chatPK)) || 0;
|
|
7862
|
+
}
|
|
7862
7863
|
function getChatPairKey(chatPK, peerChatPK, chatId = "") {
|
|
7863
7864
|
if (!chatPK || !peerChatPK)
|
|
7864
7865
|
return null;
|
|
7865
7866
|
return `${cleanText(chatPK)}|${cleanText(peerChatPK)}|${cleanText(chatId)}`;
|
|
7866
7867
|
}
|
|
7867
|
-
function
|
|
7868
|
-
|
|
7869
|
-
|
|
7868
|
+
function closeEntry(entry) {
|
|
7869
|
+
if (!entry || entry.closed || entry.leases > 0) {
|
|
7870
|
+
return;
|
|
7871
|
+
}
|
|
7872
|
+
entry.closed = true;
|
|
7873
|
+
closeChatPair(entry.pair);
|
|
7874
|
+
}
|
|
7875
|
+
function retireEntry(entry) {
|
|
7876
|
+
if (!entry || entry.retired) {
|
|
7877
|
+
return;
|
|
7878
|
+
}
|
|
7879
|
+
entry.retired = true;
|
|
7880
|
+
closeEntry(entry);
|
|
7881
|
+
}
|
|
7882
|
+
function releaseEntry(entry) {
|
|
7883
|
+
if (!entry || entry.leases <= 0) {
|
|
7884
|
+
return;
|
|
7885
|
+
}
|
|
7886
|
+
entry.leases -= 1;
|
|
7887
|
+
if (entry.retired) {
|
|
7888
|
+
closeEntry(entry);
|
|
7870
7889
|
}
|
|
7871
|
-
pairCache.clear();
|
|
7872
7890
|
}
|
|
7873
|
-
|
|
7891
|
+
function evictOverflow() {
|
|
7892
|
+
while (pairCache.size > MAX_PAIR_CACHE) {
|
|
7893
|
+
const firstKey = pairCache.keys().next().value;
|
|
7894
|
+
if (!firstKey) {
|
|
7895
|
+
return;
|
|
7896
|
+
}
|
|
7897
|
+
const entry = pairCache.get(firstKey);
|
|
7898
|
+
pairCache.delete(firstKey);
|
|
7899
|
+
retireEntry(entry);
|
|
7900
|
+
}
|
|
7901
|
+
}
|
|
7902
|
+
function clearChatPairCache(chatPK = "") {
|
|
7903
|
+
const account = cleanText(chatPK);
|
|
7904
|
+
if (!account) {
|
|
7905
|
+
cacheGeneration += 1;
|
|
7906
|
+
accountGenerations.clear();
|
|
7907
|
+
for (const entry of pairCache.values()) {
|
|
7908
|
+
retireEntry(entry);
|
|
7909
|
+
}
|
|
7910
|
+
pairCache.clear();
|
|
7911
|
+
return;
|
|
7912
|
+
}
|
|
7913
|
+
accountGenerations.set(account, accountGeneration(account) + 1);
|
|
7914
|
+
for (const [key, entry] of pairCache) {
|
|
7915
|
+
if (entry.account !== account) {
|
|
7916
|
+
continue;
|
|
7917
|
+
}
|
|
7918
|
+
pairCache.delete(key);
|
|
7919
|
+
retireEntry(entry);
|
|
7920
|
+
}
|
|
7921
|
+
}
|
|
7922
|
+
async function acquireCachedPair(chatPK, chatPrivKey, peerChatPK, options = {}) {
|
|
7923
|
+
const account = cleanText(chatPK);
|
|
7874
7924
|
const chatId = cleanText(options?.chatId);
|
|
7875
7925
|
const key = getChatPairKey(chatPK, peerChatPK, chatId);
|
|
7926
|
+
const generation = cacheGeneration;
|
|
7927
|
+
const accountVersion = accountGeneration(account);
|
|
7876
7928
|
if (!key) {
|
|
7877
|
-
|
|
7929
|
+
const pair = await openChatPair(chatPK, chatPrivKey, peerChatPK, { chatId });
|
|
7930
|
+
const entry2 = { pair, leases: 1, retired: true, closed: false };
|
|
7931
|
+
return {
|
|
7932
|
+
pair,
|
|
7933
|
+
release: () => releaseEntry(entry2)
|
|
7934
|
+
};
|
|
7878
7935
|
}
|
|
7879
|
-
|
|
7880
|
-
if (
|
|
7881
|
-
|
|
7882
|
-
|
|
7883
|
-
|
|
7884
|
-
|
|
7885
|
-
|
|
7886
|
-
|
|
7887
|
-
|
|
7888
|
-
pairCache.delete(firstKey);
|
|
7936
|
+
let entry = pairCache.get(key);
|
|
7937
|
+
if (!entry) {
|
|
7938
|
+
const pair = await openChatPair(chatPK, chatPrivKey, peerChatPK, { chatId });
|
|
7939
|
+
if (generation !== cacheGeneration || accountVersion !== accountGeneration(account)) {
|
|
7940
|
+
const staleEntry = { pair, leases: 1, retired: true, closed: false };
|
|
7941
|
+
return {
|
|
7942
|
+
pair,
|
|
7943
|
+
release: () => releaseEntry(staleEntry)
|
|
7944
|
+
};
|
|
7889
7945
|
}
|
|
7946
|
+
entry = pairCache.get(key);
|
|
7947
|
+
if (entry) {
|
|
7948
|
+
closeChatPair(pair);
|
|
7949
|
+
} else {
|
|
7950
|
+
entry = { account, pair, leases: 0, retired: false, closed: false };
|
|
7951
|
+
pairCache.set(key, entry);
|
|
7952
|
+
evictOverflow();
|
|
7953
|
+
}
|
|
7954
|
+
} else {
|
|
7955
|
+
pairCache.delete(key);
|
|
7956
|
+
pairCache.set(key, entry);
|
|
7957
|
+
}
|
|
7958
|
+
entry.leases += 1;
|
|
7959
|
+
return {
|
|
7960
|
+
pair: entry.pair,
|
|
7961
|
+
release: () => releaseEntry(entry)
|
|
7962
|
+
};
|
|
7963
|
+
}
|
|
7964
|
+
async function withCachedPair(chatPK, chatPrivKey, peerChatPK, options, runWithPair) {
|
|
7965
|
+
const { pair, release } = await acquireCachedPair(chatPK, chatPrivKey, peerChatPK, options);
|
|
7966
|
+
try {
|
|
7967
|
+
return await runWithPair(pair);
|
|
7968
|
+
} finally {
|
|
7969
|
+
release();
|
|
7890
7970
|
}
|
|
7891
|
-
return pair;
|
|
7892
7971
|
}
|
|
7893
7972
|
async function resolveLinkId(chatPK, chatPrivKey, peerChatPK) {
|
|
7894
|
-
|
|
7895
|
-
return pair?.linkId || null;
|
|
7973
|
+
return withCachedPair(chatPK, chatPrivKey, peerChatPK, {}, (pair) => pair?.linkId || null);
|
|
7896
7974
|
}
|
|
7897
7975
|
async function resolvePeerChat(cloud, chatPK, chatPrivateKey, peerChatPK, options = {}) {
|
|
7898
7976
|
const existingChatId = cleanText(options?.chatId);
|
|
@@ -7923,13 +8001,14 @@ async function resolvePeerChat(cloud, chatPK, chatPrivateKey, peerChatPK, option
|
|
|
7923
8001
|
exists: linkChat?.exists === true
|
|
7924
8002
|
};
|
|
7925
8003
|
}
|
|
7926
|
-
var pairCache, MAX_PAIR_CACHE;
|
|
8004
|
+
var pairCache, MAX_PAIR_CACHE, cacheGeneration = 0, accountGenerations;
|
|
7927
8005
|
var init_pairs = __esm(() => {
|
|
7928
8006
|
init_config();
|
|
7929
8007
|
init_chat();
|
|
7930
8008
|
init_protocol();
|
|
7931
8009
|
pairCache = new Map;
|
|
7932
8010
|
MAX_PAIR_CACHE = CHAT_PAIR_CACHE_LIMIT;
|
|
8011
|
+
accountGenerations = new Map;
|
|
7933
8012
|
});
|
|
7934
8013
|
|
|
7935
8014
|
// ../../shared/utils/diagnostics.js
|
|
@@ -7998,11 +8077,9 @@ function getBootWalletClass(SparkWallet, { enableTokenSync = false } = {}) {
|
|
|
7998
8077
|
function bytesToHex4(bytes) {
|
|
7999
8078
|
return Array.from(bytes || []).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
8000
8079
|
}
|
|
8001
|
-
async function bootWallet(walletMnemonic, user, { SparkWallet,
|
|
8080
|
+
async function bootWallet(walletMnemonic, user, { SparkWallet, network, enableTokenSync = false, diag = null } = {}) {
|
|
8002
8081
|
if (!SparkWallet)
|
|
8003
8082
|
throw new Error("SparkWallet missing");
|
|
8004
|
-
if (!cloud)
|
|
8005
|
-
throw new Error("cloud missing");
|
|
8006
8083
|
if (!network)
|
|
8007
8084
|
throw new Error("network missing");
|
|
8008
8085
|
const startedAt = Date.now();
|
|
@@ -8037,53 +8114,41 @@ async function bootWallet(walletMnemonic, user, { SparkWallet, cloud, network, e
|
|
|
8037
8114
|
const walletPK = lowerText(idPk);
|
|
8038
8115
|
const expectedWalletPK = resolveWalletPK(user, network);
|
|
8039
8116
|
markDone(diag, "vault.bootWallet.identity", identityStartedAt);
|
|
8040
|
-
|
|
8117
|
+
let walletPKNeedsWrite = false;
|
|
8041
8118
|
if (!expectedWalletPK) {
|
|
8042
|
-
|
|
8043
|
-
await cloud.user.profile.walletpk.write(idPk, { network });
|
|
8044
|
-
markDone(diag, "vault.bootWallet.setup", setupStartedAt, { wrote: true });
|
|
8119
|
+
walletPKNeedsWrite = true;
|
|
8045
8120
|
} else if (!sameText(expectedWalletPK, walletPK)) {
|
|
8046
8121
|
throw new Error("wallet identity mismatch for account");
|
|
8047
8122
|
} else if (!hasWalletPKForNetwork(user, network)) {
|
|
8048
|
-
|
|
8049
|
-
await cloud.user.profile.walletpk.write(idPk, { network });
|
|
8050
|
-
markDone(diag, "vault.bootWallet.setup", setupStartedAt, { wrote: true });
|
|
8051
|
-
} else {
|
|
8052
|
-
markDiag(diag, "vault.bootWallet.setup.skip", { elapsedMs: Date.now() - setupStartedAt });
|
|
8123
|
+
walletPKNeedsWrite = true;
|
|
8053
8124
|
}
|
|
8054
8125
|
markDone(diag, "vault.bootWallet", startedAt);
|
|
8055
|
-
return { wallet, walletPK };
|
|
8126
|
+
return { wallet, walletPK, walletPKNeedsWrite };
|
|
8056
8127
|
} catch (error) {
|
|
8057
8128
|
markError(diag, "vault.bootWallet", startedAt, error);
|
|
8058
8129
|
throw error;
|
|
8059
8130
|
}
|
|
8060
8131
|
}
|
|
8061
|
-
async function bootChat(chatSeed, user, {
|
|
8132
|
+
async function bootChat(chatSeed, user, { diag = null } = {}) {
|
|
8062
8133
|
const startedAt = Date.now();
|
|
8063
8134
|
markDiag(diag, "vault.bootChat.start", { hasChatPK: !!user?.chatPK });
|
|
8064
8135
|
try {
|
|
8065
|
-
if (!cloud)
|
|
8066
|
-
throw new Error("cloud missing");
|
|
8067
8136
|
const keyStartedAt = Date.now();
|
|
8068
8137
|
const chatKeyPair = getKeyPair(chatSeed);
|
|
8069
8138
|
chatSeed.fill(0);
|
|
8070
8139
|
const chatPKHex = bytesToHex4(chatKeyPair.pub);
|
|
8071
8140
|
markDone(diag, "vault.bootChat.derive", keyStartedAt);
|
|
8141
|
+
let chatPKNeedsWrite = false;
|
|
8072
8142
|
if (!user.chatPK) {
|
|
8073
|
-
|
|
8074
|
-
markDiag(diag, "vault.bootChat.setup.start", { reason: "missing-chat-pk" });
|
|
8075
|
-
await cloud.user.profile.chatpk.write(chatPKHex);
|
|
8076
|
-
markDone(diag, "vault.bootChat.setup", setupStartedAt, { wrote: true });
|
|
8143
|
+
chatPKNeedsWrite = true;
|
|
8077
8144
|
} else if (!sameText(user.chatPK, chatPKHex)) {
|
|
8078
8145
|
chatKeyPair.priv.fill(0);
|
|
8079
8146
|
chatKeyPair.pub.fill(0);
|
|
8080
8147
|
throw new Error("chat identity mismatch for account");
|
|
8081
|
-
} else {
|
|
8082
|
-
markDiag(diag, "vault.bootChat.setup.skip", {});
|
|
8083
8148
|
}
|
|
8084
8149
|
chatKeyPair.pub.fill(0);
|
|
8085
8150
|
markDone(diag, "vault.bootChat", startedAt);
|
|
8086
|
-
return { chatPrivateKey: chatKeyPair.priv, chatPK: chatPKHex };
|
|
8151
|
+
return { chatPrivateKey: chatKeyPair.priv, chatPK: chatPKHex, chatPKNeedsWrite };
|
|
8087
8152
|
} catch (error) {
|
|
8088
8153
|
markError(diag, "vault.bootChat", startedAt, error);
|
|
8089
8154
|
chatSeed.fill(0);
|
|
@@ -8096,14 +8161,16 @@ function lockWallet(wallet) {
|
|
|
8096
8161
|
cleanup?.catch?.(() => {});
|
|
8097
8162
|
} catch {}
|
|
8098
8163
|
}
|
|
8099
|
-
function lockChat(chatPrivateKey) {
|
|
8164
|
+
function lockChat(chatPrivateKey, chatPK = "") {
|
|
8100
8165
|
try {
|
|
8101
8166
|
if (chatPrivateKey) {
|
|
8102
8167
|
chatPrivateKey.fill(0);
|
|
8103
8168
|
}
|
|
8104
8169
|
} catch {}
|
|
8105
8170
|
try {
|
|
8106
|
-
|
|
8171
|
+
if (chatPK) {
|
|
8172
|
+
clearChatPairCache(chatPK);
|
|
8173
|
+
}
|
|
8107
8174
|
} catch {}
|
|
8108
8175
|
}
|
|
8109
8176
|
var init_vault = __esm(() => {
|
|
@@ -8123,7 +8190,7 @@ function walletPubkey(value) {
|
|
|
8123
8190
|
}
|
|
8124
8191
|
return key;
|
|
8125
8192
|
}
|
|
8126
|
-
function closeSessionResources({ wallet, chatPrivateKey, localCache, vaultAccess, vaultSigner } = {}) {
|
|
8193
|
+
function closeSessionResources({ wallet, chatPK, chatPrivateKey, localCache, vaultAccess, vaultSigner } = {}) {
|
|
8127
8194
|
try {
|
|
8128
8195
|
vaultAccess?.close?.();
|
|
8129
8196
|
} catch {}
|
|
@@ -8134,7 +8201,7 @@ function closeSessionResources({ wallet, chatPrivateKey, localCache, vaultAccess
|
|
|
8134
8201
|
localCache?.close?.();
|
|
8135
8202
|
} catch {}
|
|
8136
8203
|
lockWallet(wallet);
|
|
8137
|
-
lockChat(chatPrivateKey);
|
|
8204
|
+
lockChat(chatPrivateKey, chatPK);
|
|
8138
8205
|
}
|
|
8139
8206
|
function createAccountSession(resources = {}) {
|
|
8140
8207
|
let closed = false;
|
|
@@ -8225,6 +8292,32 @@ function notifySeedDecrypted(callback, markDiag2, source) {
|
|
|
8225
8292
|
failed(error);
|
|
8226
8293
|
}
|
|
8227
8294
|
}
|
|
8295
|
+
function startWalletBoot(bootWallet2, walletMnemonic, user, options) {
|
|
8296
|
+
let closed = false;
|
|
8297
|
+
let handedOff = false;
|
|
8298
|
+
let wallet = null;
|
|
8299
|
+
const result = Promise.resolve().then(() => bootWallet2(walletMnemonic, user, options)).then((identity) => {
|
|
8300
|
+
wallet = identity?.wallet || null;
|
|
8301
|
+
if (closed && wallet) {
|
|
8302
|
+
lockWallet(wallet);
|
|
8303
|
+
}
|
|
8304
|
+
return identity;
|
|
8305
|
+
});
|
|
8306
|
+
return {
|
|
8307
|
+
result,
|
|
8308
|
+
handoff() {
|
|
8309
|
+
handedOff = true;
|
|
8310
|
+
},
|
|
8311
|
+
close() {
|
|
8312
|
+
if (closed)
|
|
8313
|
+
return;
|
|
8314
|
+
closed = true;
|
|
8315
|
+
if (wallet && !handedOff) {
|
|
8316
|
+
lockWallet(wallet);
|
|
8317
|
+
}
|
|
8318
|
+
}
|
|
8319
|
+
};
|
|
8320
|
+
}
|
|
8228
8321
|
async function openVaultAccountSession(vault, password, options = {}) {
|
|
8229
8322
|
const {
|
|
8230
8323
|
uid,
|
|
@@ -8266,6 +8359,7 @@ async function openVaultAccountSession(vault, password, options = {}) {
|
|
|
8266
8359
|
throw new Error("unlockSettings missing");
|
|
8267
8360
|
const { decryptSeed: decryptSeed2, unpackVaultSeedData } = vaultCrypto;
|
|
8268
8361
|
let wallet = null;
|
|
8362
|
+
let chatPK = "";
|
|
8269
8363
|
let chatPrivateKey = null;
|
|
8270
8364
|
let localCache = null;
|
|
8271
8365
|
let masterSeed = null;
|
|
@@ -8276,14 +8370,24 @@ async function openVaultAccountSession(vault, password, options = {}) {
|
|
|
8276
8370
|
let vaultSigner = null;
|
|
8277
8371
|
let vaultAccess = null;
|
|
8278
8372
|
let vaultAccessResult = null;
|
|
8373
|
+
let walletBoot = null;
|
|
8279
8374
|
let network;
|
|
8280
8375
|
try {
|
|
8281
8376
|
onStage?.("unlocking");
|
|
8282
8377
|
const authStartedAt = Date.now();
|
|
8283
8378
|
mark(diag, "vault.unlock.session.start", { source });
|
|
8284
|
-
|
|
8285
|
-
|
|
8286
|
-
|
|
8379
|
+
const authResult = cloud.auth.user.getIdToken(true).then(() => {
|
|
8380
|
+
mark(diag, "vault.unlock.session.done", { elapsedMs: Date.now() - authStartedAt, source });
|
|
8381
|
+
return { error: null };
|
|
8382
|
+
}, (error) => {
|
|
8383
|
+
mark(diag, "vault.unlock.session.error", {
|
|
8384
|
+
elapsedMs: Date.now() - authStartedAt,
|
|
8385
|
+
source,
|
|
8386
|
+
code: error?.code || "",
|
|
8387
|
+
message: error?.message || String(error)
|
|
8388
|
+
});
|
|
8389
|
+
return { error };
|
|
8390
|
+
});
|
|
8287
8391
|
const unpackStartedAt = Date.now();
|
|
8288
8392
|
const unpacked = unpackVaultSeedData(vault);
|
|
8289
8393
|
const { salt, iv, ct, kdf, registry: registryEnvelope } = unpacked;
|
|
@@ -8312,6 +8416,9 @@ async function openVaultAccountSession(vault, password, options = {}) {
|
|
|
8312
8416
|
cleanBytes(walletEntropy, masterSeed);
|
|
8313
8417
|
walletEntropy = null;
|
|
8314
8418
|
masterSeed = null;
|
|
8419
|
+
const sessionResult = await authResult;
|
|
8420
|
+
if (sessionResult.error)
|
|
8421
|
+
throw sessionResult.error;
|
|
8315
8422
|
requireCurrent(isCurrent);
|
|
8316
8423
|
const vaultSignatureStartedAt = Date.now();
|
|
8317
8424
|
mark(diag, "vault.unlock.signature.start", { source });
|
|
@@ -8332,17 +8439,13 @@ async function openVaultAccountSession(vault, password, options = {}) {
|
|
|
8332
8439
|
onStage?.("wallet");
|
|
8333
8440
|
const walletStartedAt = Date.now();
|
|
8334
8441
|
mark(diag, "vault.unlock.wallet.start", { source });
|
|
8335
|
-
|
|
8336
|
-
wallet = walletIdentity?.wallet;
|
|
8337
|
-
const walletPK = walletPubkey(walletIdentity?.walletPK);
|
|
8338
|
-
mark(diag, "vault.unlock.wallet.done", { elapsedMs: Date.now() - walletStartedAt, source });
|
|
8339
|
-
requireCurrent(isCurrent);
|
|
8442
|
+
walletBoot = startWalletBoot(bootWallet2, walletMnemonic, user, { network, diag });
|
|
8340
8443
|
onStage?.("chat");
|
|
8341
8444
|
const chatStartedAt = Date.now();
|
|
8342
8445
|
mark(diag, "vault.unlock.chat.start", { source });
|
|
8343
|
-
const chatIdentity = await bootChat2(chatSeed, user);
|
|
8446
|
+
const chatIdentity = await bootChat2(chatSeed, user, { diag });
|
|
8344
8447
|
chatPrivateKey = chatIdentity?.chatPrivateKey;
|
|
8345
|
-
|
|
8448
|
+
chatPK = cleanText(chatIdentity?.chatPK);
|
|
8346
8449
|
if (!chatPrivateKey || !chatPK)
|
|
8347
8450
|
throw new Error("chat identity missing");
|
|
8348
8451
|
chatSeed = null;
|
|
@@ -8360,11 +8463,11 @@ async function openVaultAccountSession(vault, password, options = {}) {
|
|
|
8360
8463
|
throw signatureResult.error;
|
|
8361
8464
|
vaultAccess = signatureResult.access;
|
|
8362
8465
|
requireCurrent(isCurrent);
|
|
8363
|
-
|
|
8466
|
+
const session = createAccountSession({
|
|
8364
8467
|
uid,
|
|
8365
8468
|
network,
|
|
8366
|
-
wallet,
|
|
8367
|
-
walletPK,
|
|
8469
|
+
wallet: null,
|
|
8470
|
+
walletPK: null,
|
|
8368
8471
|
chatPK,
|
|
8369
8472
|
chatPrivateKey,
|
|
8370
8473
|
localCache,
|
|
@@ -8372,12 +8475,56 @@ async function openVaultAccountSession(vault, password, options = {}) {
|
|
|
8372
8475
|
vaultAccess,
|
|
8373
8476
|
vaultPK: vaultSigner.publicKey
|
|
8374
8477
|
});
|
|
8478
|
+
session.own(walletBoot);
|
|
8479
|
+
const walletReady = walletBoot.result.then(async (walletIdentity) => {
|
|
8480
|
+
if (session.closed)
|
|
8481
|
+
throw new Error("account session closed");
|
|
8482
|
+
const readyWallet = walletIdentity?.wallet;
|
|
8483
|
+
const walletPK = walletPubkey(walletIdentity?.walletPK);
|
|
8484
|
+
if (!readyWallet)
|
|
8485
|
+
throw new Error("wallet missing");
|
|
8486
|
+
mark(diag, "vault.unlock.wallet.done", { elapsedMs: Date.now() - walletStartedAt, source });
|
|
8487
|
+
const identityPayload = {};
|
|
8488
|
+
if (walletIdentity?.walletPKNeedsWrite) {
|
|
8489
|
+
identityPayload.walletPK = walletPK;
|
|
8490
|
+
identityPayload.network = network;
|
|
8491
|
+
}
|
|
8492
|
+
if (chatIdentity?.chatPKNeedsWrite) {
|
|
8493
|
+
identityPayload.chatPK = chatPK;
|
|
8494
|
+
}
|
|
8495
|
+
const identityFields = Object.keys(identityPayload);
|
|
8496
|
+
if (identityFields.length) {
|
|
8497
|
+
const identitiesStartedAt = Date.now();
|
|
8498
|
+
mark(diag, "vault.unlock.identities.start", { source, fields: identityFields });
|
|
8499
|
+
await cloud.user.profile.identity.write(identityPayload);
|
|
8500
|
+
mark(diag, "vault.unlock.identities.done", {
|
|
8501
|
+
elapsedMs: Date.now() - identitiesStartedAt,
|
|
8502
|
+
source,
|
|
8503
|
+
fields: identityFields
|
|
8504
|
+
});
|
|
8505
|
+
} else {
|
|
8506
|
+
mark(diag, "vault.unlock.identities.skip", { source });
|
|
8507
|
+
}
|
|
8508
|
+
if (session.closed)
|
|
8509
|
+
throw new Error("account session closed");
|
|
8510
|
+
walletBoot.handoff();
|
|
8511
|
+
session.wallet = readyWallet;
|
|
8512
|
+
session.walletPK = walletPK;
|
|
8513
|
+
return { wallet: readyWallet, walletPK };
|
|
8514
|
+
}).catch((error) => {
|
|
8515
|
+
walletBoot.close();
|
|
8516
|
+
throw error;
|
|
8517
|
+
});
|
|
8518
|
+
walletReady.catch(() => {});
|
|
8519
|
+
session.walletReady = walletReady;
|
|
8520
|
+
return session;
|
|
8375
8521
|
} catch (error) {
|
|
8522
|
+
walletBoot?.close();
|
|
8376
8523
|
if (vaultAccessResult && !vaultAccess) {
|
|
8377
8524
|
const signatureResult = await vaultAccessResult;
|
|
8378
8525
|
vaultAccess = signatureResult.access;
|
|
8379
8526
|
}
|
|
8380
|
-
closeSessionResources({ wallet, chatPrivateKey, localCache, vaultAccess, vaultSigner });
|
|
8527
|
+
closeSessionResources({ wallet, chatPK, chatPrivateKey, localCache, vaultAccess, vaultSigner });
|
|
8381
8528
|
throw error;
|
|
8382
8529
|
} finally {
|
|
8383
8530
|
cleanBytes(masterSeed, walletEntropy, chatSeed, cacheKey, settingsKey);
|
|
@@ -8392,6 +8539,7 @@ async function openAccountSessionFromSecrets(walletEntropy, chatSeed, masterSeed
|
|
|
8392
8539
|
}
|
|
8393
8540
|
const walletMnemonic = mnemonicFromWalletEntropy(walletEntropy);
|
|
8394
8541
|
let wallet = null;
|
|
8542
|
+
let chatPK = "";
|
|
8395
8543
|
let chatPrivateKey = null;
|
|
8396
8544
|
let chatPubKey = null;
|
|
8397
8545
|
let vaultSigner = null;
|
|
@@ -8420,10 +8568,11 @@ async function openAccountSessionFromSecrets(walletEntropy, chatSeed, masterSeed
|
|
|
8420
8568
|
throw new Error("vault signature uid missing");
|
|
8421
8569
|
vaultAccess = await cloud.auth.vaultSignature.open(vaultSigner);
|
|
8422
8570
|
}
|
|
8571
|
+
chatPK = toHex(chatPubKey);
|
|
8423
8572
|
return createAccountSession({
|
|
8424
8573
|
wallet,
|
|
8425
8574
|
walletPK,
|
|
8426
|
-
chatPK
|
|
8575
|
+
chatPK,
|
|
8427
8576
|
chatPrivateKey,
|
|
8428
8577
|
localCache,
|
|
8429
8578
|
network,
|
|
@@ -8432,7 +8581,7 @@ async function openAccountSessionFromSecrets(walletEntropy, chatSeed, masterSeed
|
|
|
8432
8581
|
vaultPK: vaultSigner.publicKey
|
|
8433
8582
|
});
|
|
8434
8583
|
} catch (error) {
|
|
8435
|
-
closeSessionResources({ wallet, chatPrivateKey, localCache, vaultAccess, vaultSigner });
|
|
8584
|
+
closeSessionResources({ wallet, chatPK, chatPrivateKey, localCache, vaultAccess, vaultSigner });
|
|
8436
8585
|
throw error;
|
|
8437
8586
|
} finally {
|
|
8438
8587
|
cleanBytes(chatSeed, chatPubKey);
|
|
@@ -8459,9 +8608,10 @@ var init_session = __esm(() => {
|
|
|
8459
8608
|
});
|
|
8460
8609
|
|
|
8461
8610
|
// ../../shared/community.js
|
|
8462
|
-
var COMMUNITY_RULES_VERSION = "2026-05-11.1", COMMUNITY_SECTIONS;
|
|
8611
|
+
var COMMUNITY_RULES_VERSION = "2026-05-11.1", COMMUNITY_SUPPORT_EMAIL, COMMUNITY_SECTIONS;
|
|
8463
8612
|
var init_community = __esm(() => {
|
|
8464
8613
|
init_links();
|
|
8614
|
+
COMMUNITY_SUPPORT_EMAIL = links.contact.replace("mailto:", "");
|
|
8465
8615
|
COMMUNITY_SECTIONS = [
|
|
8466
8616
|
{
|
|
8467
8617
|
title: "Use veyl directly and lawfully",
|
|
@@ -8501,7 +8651,7 @@ var init_community = __esm(() => {
|
|
|
8501
8651
|
{
|
|
8502
8652
|
title: "Reporting and support",
|
|
8503
8653
|
body: [
|
|
8504
|
-
`If someone is abusing veyl, contact us at ${
|
|
8654
|
+
`If someone is abusing veyl, contact us at ${COMMUNITY_SUPPORT_EMAIL} and include the username, profile details, screenshots, or any evidence you choose to provide from your own device.`,
|
|
8505
8655
|
"Because veyl uses end-to-end encryption, we may rely on reports, account-level signals, and evidence you submit when reviewing abuse."
|
|
8506
8656
|
]
|
|
8507
8657
|
}
|
|
@@ -106357,6 +106507,7 @@ function createUser({ cloud, network, avatarCache = null, diag = null, onSession
|
|
|
106357
106507
|
let authSession = 0;
|
|
106358
106508
|
let userUid = null;
|
|
106359
106509
|
let settingsKey = null;
|
|
106510
|
+
let settingsStored = null;
|
|
106360
106511
|
let avatarFetch = { uid: null, key: null, promise: null };
|
|
106361
106512
|
let blockedSource = state.blocked;
|
|
106362
106513
|
let blockedSet = new Set(blockedSource);
|
|
@@ -106576,6 +106727,7 @@ function createUser({ cloud, network, avatarCache = null, diag = null, onSession
|
|
|
106576
106727
|
userUid = null;
|
|
106577
106728
|
clearSettingsKey(settingsKey);
|
|
106578
106729
|
settingsKey = null;
|
|
106730
|
+
settingsStored = null;
|
|
106579
106731
|
if (signedOutUid) {
|
|
106580
106732
|
keepOnlyCachedAvatar(null);
|
|
106581
106733
|
}
|
|
@@ -106589,6 +106741,7 @@ function createUser({ cloud, network, avatarCache = null, diag = null, onSession
|
|
|
106589
106741
|
if (authUidChanged) {
|
|
106590
106742
|
clearSettingsKey(settingsKey);
|
|
106591
106743
|
settingsKey = null;
|
|
106744
|
+
settingsStored = null;
|
|
106592
106745
|
}
|
|
106593
106746
|
setState((user) => authUidChanged ? { ...defaultUser, authReady: true, uid: authUser.uid } : { ...user, authReady: true, isAdmin: false, adminReady: false });
|
|
106594
106747
|
readCachedAvatar(authUser.uid).then((cached) => {
|
|
@@ -106645,6 +106798,9 @@ function createUser({ cloud, network, avatarCache = null, diag = null, onSession
|
|
|
106645
106798
|
fromCache: !!info.fromCache,
|
|
106646
106799
|
pending: !!info.pending
|
|
106647
106800
|
});
|
|
106801
|
+
if (!info.fromCache) {
|
|
106802
|
+
settingsStored = Object.prototype.hasOwnProperty.call(privateData, "settings");
|
|
106803
|
+
}
|
|
106648
106804
|
setState((user) => ({
|
|
106649
106805
|
...user,
|
|
106650
106806
|
agreement: privateData.agreement ?? null,
|
|
@@ -106652,6 +106808,7 @@ function createUser({ cloud, network, avatarCache = null, diag = null, onSession
|
|
|
106652
106808
|
}));
|
|
106653
106809
|
}), current((error) => {
|
|
106654
106810
|
markError(diag, "user.settings.snapshot", authStartedAt, error);
|
|
106811
|
+
settingsStored = null;
|
|
106655
106812
|
setState((user) => ({
|
|
106656
106813
|
...user,
|
|
106657
106814
|
settingsReady: true,
|
|
@@ -106755,6 +106912,7 @@ function createUser({ cloud, network, avatarCache = null, diag = null, onSession
|
|
|
106755
106912
|
}
|
|
106756
106913
|
clearSettingsKey(settingsKey);
|
|
106757
106914
|
settingsKey = null;
|
|
106915
|
+
settingsStored = null;
|
|
106758
106916
|
userUid = null;
|
|
106759
106917
|
avatarFetch = { uid: null, key: null, promise: null };
|
|
106760
106918
|
state = defaultUser;
|
|
@@ -106805,7 +106963,7 @@ function createUser({ cloud, network, avatarCache = null, diag = null, onSession
|
|
|
106805
106963
|
throw new Error("auth");
|
|
106806
106964
|
if (!key)
|
|
106807
106965
|
throw new Error("settings key required");
|
|
106808
|
-
const nextSettings = await cloud.user.settings.read(uid, key);
|
|
106966
|
+
const nextSettings = settingsStored === false ? settingsState() : await cloud.user.settings.read(uid, key);
|
|
106809
106967
|
if (!isCurrentUser(uid, session))
|
|
106810
106968
|
return nextSettings;
|
|
106811
106969
|
setSettingsKey(key);
|
|
@@ -106829,6 +106987,7 @@ function createUser({ cloud, network, avatarCache = null, diag = null, onSession
|
|
|
106829
106987
|
const nextSettings = await cloud.user.settings.write(uid, patch, { currentSettings: state.settings, key: settingsKey });
|
|
106830
106988
|
if (!isCurrentUser(uid, session))
|
|
106831
106989
|
return nextSettings;
|
|
106990
|
+
settingsStored = true;
|
|
106832
106991
|
setState((user) => ({
|
|
106833
106992
|
...user,
|
|
106834
106993
|
settingsReady: true,
|
|
@@ -107113,7 +107272,7 @@ function getSubtleCrypto() {
|
|
|
107113
107272
|
async function importAesKey(key, usages) {
|
|
107114
107273
|
return getSubtleCrypto().importKey("raw", toBytes32(key, "file key"), { name: "AES-GCM" }, false, usages);
|
|
107115
107274
|
}
|
|
107116
|
-
async function sealFile(
|
|
107275
|
+
async function sealFile(key, bytes, scope) {
|
|
107117
107276
|
const fileKey = new Uint8Array(toBytes32(key, "file key"));
|
|
107118
107277
|
try {
|
|
107119
107278
|
const cryptoKey = await importAesKey(fileKey, ["encrypt"]);
|
|
@@ -107276,20 +107435,22 @@ async function toUploadBytes(data) {
|
|
|
107276
107435
|
}
|
|
107277
107436
|
return toBytes(data, "upload bytes");
|
|
107278
107437
|
}
|
|
107279
|
-
async function makeChatFileUploadPayload(
|
|
107280
|
-
const
|
|
107438
|
+
async function makeChatFileUploadPayload(chatId, cid, data, { cacheControl = "private, max-age=0, no-transform" } = {}) {
|
|
107439
|
+
const nextChatId = cleanMediaChatId(chatId);
|
|
107281
107440
|
const mediaId = makeChatMediaId();
|
|
107282
|
-
const path = mediaFilePath(
|
|
107441
|
+
const path = mediaFilePath(nextChatId, mediaId);
|
|
107283
107442
|
const expiresAt = Date.now() + CHAT_MEDIA_TTL_MS2;
|
|
107284
107443
|
const key = createFileKey();
|
|
107285
107444
|
try {
|
|
107286
107445
|
const uploadBytes = await toUploadBytes(data);
|
|
107287
107446
|
assertChatUploadByteSize(uploadBytes);
|
|
107447
|
+
const body = await sealFile(key, uploadBytes, path);
|
|
107448
|
+
assertChatUploadByteSize(body);
|
|
107288
107449
|
return {
|
|
107289
|
-
chatId,
|
|
107450
|
+
chatId: nextChatId,
|
|
107290
107451
|
mediaId,
|
|
107291
107452
|
path,
|
|
107292
|
-
body
|
|
107453
|
+
body,
|
|
107293
107454
|
metadata: {
|
|
107294
107455
|
contentType: "application/octet-stream",
|
|
107295
107456
|
cacheControl
|
|
@@ -107318,10 +107479,12 @@ async function makeSharedFileUploadPayload(data, { contentType = "application/oc
|
|
|
107318
107479
|
try {
|
|
107319
107480
|
const uploadBytes = await toUploadBytes(data);
|
|
107320
107481
|
assertChatUploadByteSize(uploadBytes);
|
|
107482
|
+
const body = await sealFile(key, uploadBytes, path);
|
|
107483
|
+
assertChatUploadByteSize(body);
|
|
107321
107484
|
return {
|
|
107322
107485
|
sharedId,
|
|
107323
107486
|
path,
|
|
107324
|
-
body
|
|
107487
|
+
body,
|
|
107325
107488
|
metadata: {
|
|
107326
107489
|
contentType,
|
|
107327
107490
|
cacheControl
|
|
@@ -109247,10 +109410,19 @@ function sortedUniqueValues(items) {
|
|
|
109247
109410
|
}
|
|
109248
109411
|
|
|
109249
109412
|
// ../../shared/chat/chats.js
|
|
109413
|
+
function sameSigningKeys(left, right) {
|
|
109414
|
+
if (left === right)
|
|
109415
|
+
return true;
|
|
109416
|
+
const leftKeys = Object.keys(left || {});
|
|
109417
|
+
const rightKeys = Object.keys(right || {});
|
|
109418
|
+
if (leftKeys.length !== rightKeys.length)
|
|
109419
|
+
return false;
|
|
109420
|
+
return leftKeys.every((key) => left[key] === right[key]);
|
|
109421
|
+
}
|
|
109250
109422
|
function sameChatShape(a, b) {
|
|
109251
109423
|
if (!a || !b)
|
|
109252
109424
|
return a === b;
|
|
109253
|
-
return a.id === b.id && a.protocol === b.protocol && a.linkId === b.linkId && a.ts === b.ts && a.startMs === b.startMs && a.unseen === b.unseen && a.settings?.retention === b.settings?.retention && sameChatPreview(a.preview, b.preview);
|
|
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);
|
|
109254
109426
|
}
|
|
109255
109427
|
function sameChats(prev, next) {
|
|
109256
109428
|
if (prev.length !== next.length)
|
|
@@ -110813,8 +110985,14 @@ function mediaAad(uid, network, id) {
|
|
|
110813
110985
|
function partAad(uid, network, part) {
|
|
110814
110986
|
return encoder.encode(JSON.stringify(["veyl-local-cache-part", CACHE_PART_ENVELOPE_VERSION, String(uid || ""), String(network || ""), String(part || "")]));
|
|
110815
110987
|
}
|
|
110988
|
+
function encodePayloadData(payload) {
|
|
110989
|
+
return encoder.encode(JSON.stringify({ ...normalizePayload(payload), savedAt: Date.now() }));
|
|
110990
|
+
}
|
|
110991
|
+
function decodePayloadData(raw) {
|
|
110992
|
+
return JSON.parse(decoder.decode(toBytes(raw, "cache payload")));
|
|
110993
|
+
}
|
|
110816
110994
|
async function sealPayload(key, payload, uid, network) {
|
|
110817
|
-
const body =
|
|
110995
|
+
const body = encodePayloadData(payload);
|
|
110818
110996
|
try {
|
|
110819
110997
|
const { iv, ct } = await sealAes(key, body, cacheAad(uid, network));
|
|
110820
110998
|
return JSON.stringify({
|
|
@@ -110836,7 +111014,7 @@ async function openPayloadData(key, raw, uid, network) {
|
|
|
110836
111014
|
}
|
|
110837
111015
|
const plain = await openAes(key, fromHexBytes(envelope.iv, "cache iv"), fromHexBytes(envelope.ct, "cache ciphertext"), cacheAad(uid, network));
|
|
110838
111016
|
try {
|
|
110839
|
-
return
|
|
111017
|
+
return decodePayloadData(plain);
|
|
110840
111018
|
} finally {
|
|
110841
111019
|
cleanBytes(plain);
|
|
110842
111020
|
}
|
|
@@ -110897,6 +111075,14 @@ function mediaCrypto(uid, network, id, keyBytes) {
|
|
|
110897
111075
|
ivBytes: AES_IV_BYTES
|
|
110898
111076
|
};
|
|
110899
111077
|
}
|
|
111078
|
+
function payloadCrypto(uid, network, keyBytes) {
|
|
111079
|
+
return {
|
|
111080
|
+
key: keyBytes,
|
|
111081
|
+
aad: cacheAad(uid, network),
|
|
111082
|
+
version: LOCAL_DATA_CACHE_VERSION,
|
|
111083
|
+
ivBytes: AES_IV_BYTES
|
|
111084
|
+
};
|
|
111085
|
+
}
|
|
110900
111086
|
var MEDIA_ENVELOPE_VERSION = 1, CACHE_PART_ENVELOPE_VERSION = 1;
|
|
110901
111087
|
var init_crypto = __esm(() => {
|
|
110902
111088
|
init_aes2();
|
|
@@ -110932,11 +111118,32 @@ async function openVaultCache({ key, storage, uid, network }) {
|
|
|
110932
111118
|
let writeTimer = null;
|
|
110933
111119
|
let writeTask = Promise.resolve();
|
|
110934
111120
|
const partWriteTasks = new Map;
|
|
111121
|
+
let storedPayload = null;
|
|
110935
111122
|
try {
|
|
110936
|
-
|
|
110937
|
-
|
|
111123
|
+
storedPayload = await storage.read();
|
|
111124
|
+
if (!storedPayload) {
|
|
111125
|
+
payload = emptyPayload();
|
|
111126
|
+
} else if (typeof storage.openPayload === "function") {
|
|
111127
|
+
const readKey = new Uint8Array(cacheKey);
|
|
111128
|
+
let plain;
|
|
111129
|
+
try {
|
|
111130
|
+
plain = await storage.openPayload(storedPayload, payloadCrypto(uid, network, readKey));
|
|
111131
|
+
payload = normalizePayload(decodePayloadData(plain));
|
|
111132
|
+
} finally {
|
|
111133
|
+
cleanBytes(plain, readKey);
|
|
111134
|
+
}
|
|
111135
|
+
} else {
|
|
111136
|
+
payload = normalizePayload(await openPayloadData(cacheKey, storedPayload, uid, network));
|
|
111137
|
+
}
|
|
110938
111138
|
} catch {
|
|
110939
111139
|
payload = emptyPayload();
|
|
111140
|
+
if (storedPayload) {
|
|
111141
|
+
await Promise.all([
|
|
111142
|
+
storage.remove().catch(() => {}),
|
|
111143
|
+
storage.removeAllMedia().catch(() => {}),
|
|
111144
|
+
storage.removeAllParts().catch(() => {})
|
|
111145
|
+
]);
|
|
111146
|
+
}
|
|
110940
111147
|
}
|
|
110941
111148
|
const writeNow = () => {
|
|
110942
111149
|
if (closed) {
|
|
@@ -110954,10 +111161,12 @@ async function openVaultCache({ key, storage, uid, network }) {
|
|
|
110954
111161
|
return;
|
|
110955
111162
|
}
|
|
110956
111163
|
const writeKey = new Uint8Array(cacheKey);
|
|
111164
|
+
let body;
|
|
110957
111165
|
try {
|
|
110958
|
-
await storage.
|
|
111166
|
+
const raw = typeof storage.sealPayload === "function" ? await storage.sealPayload(body = encodePayloadData(payload), payloadCrypto(uid, network, writeKey)) : await sealPayload(writeKey, payload, uid, network);
|
|
111167
|
+
await storage.write(raw);
|
|
110959
111168
|
} finally {
|
|
110960
|
-
cleanBytes(writeKey);
|
|
111169
|
+
cleanBytes(body, writeKey);
|
|
110961
111170
|
}
|
|
110962
111171
|
}).catch(() => {});
|
|
110963
111172
|
return writeTask;
|
|
@@ -111760,9 +111969,9 @@ function setErrorStage(error, stage, extra = {}) {
|
|
|
111760
111969
|
Object.assign(error, extra);
|
|
111761
111970
|
return error;
|
|
111762
111971
|
}
|
|
111763
|
-
async function makeChatFileUpload(
|
|
111972
|
+
async function makeChatFileUpload(chatId, cid, data, { cacheControl = "private, max-age=0, no-transform" } = {}) {
|
|
111764
111973
|
try {
|
|
111765
|
-
return await makeChatFileUploadPayload(
|
|
111974
|
+
return await makeChatFileUploadPayload(chatId, cid, data, {
|
|
111766
111975
|
cacheControl
|
|
111767
111976
|
});
|
|
111768
111977
|
} catch (error) {
|
|
@@ -111772,8 +111981,8 @@ async function makeChatFileUpload(pair, cid, data, { cacheControl = "private, ma
|
|
|
111772
111981
|
});
|
|
111773
111982
|
}
|
|
111774
111983
|
}
|
|
111775
|
-
async function putChatFile(
|
|
111776
|
-
const upload = await makeChatFileUpload(
|
|
111984
|
+
async function putChatFile(chatId, cid, data, options) {
|
|
111985
|
+
const upload = await makeChatFileUpload(chatId, cid, data, options);
|
|
111777
111986
|
try {
|
|
111778
111987
|
if (typeof options?.uploadChatMedia !== "function") {
|
|
111779
111988
|
throw new Error("chat media upload required");
|
|
@@ -111808,7 +112017,7 @@ async function putSharedFile(data, options = {}) {
|
|
|
111808
112017
|
throw setErrorStage(error, "upload", { path: upload.path });
|
|
111809
112018
|
}
|
|
111810
112019
|
}
|
|
111811
|
-
async function readChatFile(readChatMedia,
|
|
112020
|
+
async function readChatFile(readChatMedia, file) {
|
|
111812
112021
|
let body;
|
|
111813
112022
|
try {
|
|
111814
112023
|
if (typeof readChatMedia !== "function") {
|
|
@@ -111866,8 +112075,8 @@ function buildAttachmentMsg(type, file) {
|
|
|
111866
112075
|
return makeAttachment(type, file);
|
|
111867
112076
|
}
|
|
111868
112077
|
}
|
|
111869
|
-
async function putAttachment(
|
|
111870
|
-
const file = await putChatFile(
|
|
112078
|
+
async function putAttachment(chatId, cid, type, data, meta = {}) {
|
|
112079
|
+
const file = await putChatFile(chatId, cid, data, meta);
|
|
111871
112080
|
return buildAttachmentMsg(type, {
|
|
111872
112081
|
...file,
|
|
111873
112082
|
...pickAttachmentMeta(meta)
|
|
@@ -111880,26 +112089,26 @@ async function putSharedAttachment(type, data, meta = {}) {
|
|
|
111880
112089
|
...pickAttachmentMeta(meta)
|
|
111881
112090
|
});
|
|
111882
112091
|
}
|
|
111883
|
-
async function putImg(
|
|
111884
|
-
return putAttachment(
|
|
112092
|
+
async function putImg(chatId, cid, data, meta = {}) {
|
|
112093
|
+
return putAttachment(chatId, cid, "img", data, meta);
|
|
111885
112094
|
}
|
|
111886
|
-
async function putGif(
|
|
111887
|
-
return putAttachment(
|
|
112095
|
+
async function putGif(chatId, cid, data, meta = {}) {
|
|
112096
|
+
return putAttachment(chatId, cid, "gif", data, meta);
|
|
111888
112097
|
}
|
|
111889
|
-
async function putM4a(
|
|
111890
|
-
return putAttachment(
|
|
112098
|
+
async function putM4a(chatId, cid, data, meta = {}) {
|
|
112099
|
+
return putAttachment(chatId, cid, "m4a", data, meta);
|
|
111891
112100
|
}
|
|
111892
|
-
async function putMp4(
|
|
111893
|
-
return putAttachment(
|
|
112101
|
+
async function putMp4(chatId, cid, data, meta = {}) {
|
|
112102
|
+
return putAttachment(chatId, cid, "mp4", data, meta);
|
|
111894
112103
|
}
|
|
111895
|
-
async function putFile(
|
|
111896
|
-
return putAttachment(
|
|
112104
|
+
async function putFile(chatId, cid, data, meta = {}) {
|
|
112105
|
+
return putAttachment(chatId, cid, "file", data, meta);
|
|
111897
112106
|
}
|
|
111898
|
-
function readMsgAttachment(readChatMedia,
|
|
111899
|
-
return readChatFile(readChatMedia,
|
|
112107
|
+
function readMsgAttachment(readChatMedia, msg) {
|
|
112108
|
+
return readChatFile(readChatMedia, msg);
|
|
111900
112109
|
}
|
|
111901
|
-
function readMsgFile(readChatMedia,
|
|
111902
|
-
return readMsgAttachment(readChatMedia,
|
|
112110
|
+
function readMsgFile(readChatMedia, msg) {
|
|
112111
|
+
return readMsgAttachment(readChatMedia, msg);
|
|
111903
112112
|
}
|
|
111904
112113
|
var init_media2 = __esm(() => {
|
|
111905
112114
|
init_files2();
|
|
@@ -112148,14 +112357,6 @@ function ownerEditedPreview(senderPubkey, message) {
|
|
|
112148
112357
|
failed: false
|
|
112149
112358
|
};
|
|
112150
112359
|
}
|
|
112151
|
-
function messageFileChatId(message) {
|
|
112152
|
-
try {
|
|
112153
|
-
const ref = getMediaFileRef(message?.p);
|
|
112154
|
-
return ref?.type === "chat" ? ref.chatId : "";
|
|
112155
|
-
} catch {
|
|
112156
|
-
return "";
|
|
112157
|
-
}
|
|
112158
|
-
}
|
|
112159
112360
|
async function recipientForSend(cloud, receiverChatPK, options, needed) {
|
|
112160
112361
|
if (!needed) {
|
|
112161
112362
|
return null;
|
|
@@ -112176,50 +112377,51 @@ async function sendMsg(cloud, senderPubkey, senderPrivkey, receiverChatPK, messa
|
|
|
112176
112377
|
if (!chatId) {
|
|
112177
112378
|
throw new Error("chat id required");
|
|
112178
112379
|
}
|
|
112179
|
-
|
|
112180
|
-
|
|
112181
|
-
|
|
112182
|
-
|
|
112183
|
-
|
|
112184
|
-
|
|
112185
|
-
|
|
112186
|
-
|
|
112187
|
-
|
|
112188
|
-
|
|
112189
|
-
|
|
112190
|
-
|
|
112191
|
-
|
|
112192
|
-
|
|
112193
|
-
|
|
112194
|
-
|
|
112195
|
-
|
|
112196
|
-
|
|
112197
|
-
|
|
112198
|
-
|
|
112199
|
-
|
|
112200
|
-
|
|
112201
|
-
|
|
112202
|
-
|
|
112203
|
-
|
|
112204
|
-
|
|
112205
|
-
|
|
112206
|
-
|
|
112207
|
-
|
|
112208
|
-
|
|
112209
|
-
|
|
112210
|
-
|
|
112211
|
-
|
|
112212
|
-
|
|
112213
|
-
|
|
112214
|
-
|
|
112215
|
-
|
|
112216
|
-
|
|
112217
|
-
|
|
112218
|
-
|
|
112219
|
-
|
|
112220
|
-
|
|
112380
|
+
return withCachedPair(senderPubkey, senderPrivkey, receiverChatPK, { chatId }, async (pair) => {
|
|
112381
|
+
if (options?.linkId && cleanText(options.linkId) !== pair.linkId) {
|
|
112382
|
+
throw new Error("link mismatch");
|
|
112383
|
+
}
|
|
112384
|
+
const retention = cleanChatRetention(options?.retention ?? options?.ttlMode);
|
|
112385
|
+
const tsMs = Date.now();
|
|
112386
|
+
const messagePayload = withMessageRetention(message, retention);
|
|
112387
|
+
const actionOp = actionOpForPayload(messagePayload);
|
|
112388
|
+
const { head, body } = await sealMsg(pair, messagePayload, { op: actionOp, ts: tsMs });
|
|
112389
|
+
const ttlMs = actionOp === CHAT_ACTION_OPS.CREATE ? newStorageTtlMs() : null;
|
|
112390
|
+
const messageId = head.cid;
|
|
112391
|
+
const msgData = {
|
|
112392
|
+
head,
|
|
112393
|
+
body,
|
|
112394
|
+
ttlMs
|
|
112395
|
+
};
|
|
112396
|
+
const recipientProfile = await recipientForSend(cloud, receiverChatPK, options, updatePreview || options?.ping === true);
|
|
112397
|
+
const sentMessage = ownerPreview(senderPubkey, messagePayload, messageId, head, tsMs, ttlMs);
|
|
112398
|
+
const preview2 = updatePreview ? sentMessage : null;
|
|
112399
|
+
const ownerEntry = updatePreview ? await ownEntryWrite(cloud, cleanText(options?.senderUid), senderPrivkey, pair, {
|
|
112400
|
+
peerUid: recipientProfile?.uid || cleanText(options?.receiverUid),
|
|
112401
|
+
peerSigningPublicKey: recipientProfile?.signingPublicKey,
|
|
112402
|
+
entry: options?.ownEntry,
|
|
112403
|
+
settings: options?.chatSettings,
|
|
112404
|
+
preview: preview2,
|
|
112405
|
+
ts: tsMs
|
|
112406
|
+
}) : null;
|
|
112407
|
+
const pingKind = updatePreview ? "message" : cleanText(options?.pingKind) || "ping";
|
|
112408
|
+
const ping = recipientProfile?.uid && (updatePreview || options?.ping === true) ? await sealPing(senderPubkey, senderPrivkey, receiverChatPK, {
|
|
112409
|
+
kind: pingKind,
|
|
112410
|
+
chatId,
|
|
112411
|
+
senderUid: cleanText(options?.senderUid),
|
|
112412
|
+
messageId,
|
|
112413
|
+
ts: tsMs
|
|
112414
|
+
}) : null;
|
|
112415
|
+
const write = await cloud.chat.messages.send({
|
|
112416
|
+
chatId,
|
|
112417
|
+
messageId,
|
|
112418
|
+
message: msgData,
|
|
112419
|
+
ownerEntry,
|
|
112420
|
+
inbox: ping ? { recipientUid: recipientProfile?.uid, ping } : null,
|
|
112421
|
+
onCommitted: typeof options?.onCommitted === "function" ? (committed) => options.onCommitted({ ...committed, message: sentMessage, preview: preview2 }) : undefined
|
|
112422
|
+
});
|
|
112423
|
+
return { chatId, msgId: messageId, cid: head.cid, message: sentMessage, preview: preview2, ...write?.skipped ? { skipped: true } : {} };
|
|
112221
112424
|
});
|
|
112222
|
-
return { chatId, msgId: messageId, cid: head.cid, message: sentMessage, preview: preview2, ...write?.skipped ? { skipped: true } : {} };
|
|
112223
112425
|
}
|
|
112224
112426
|
async function sendReadReceipt(cloud, senderPubkey, senderPrivkey, receiverChatPK, target, options = {}) {
|
|
112225
112427
|
const receipt = {
|
|
@@ -112329,27 +112531,28 @@ async function setChatRetention(cloud, chatId, senderPubkey, senderPrivkey, peer
|
|
|
112329
112531
|
throw new Error("vault locked");
|
|
112330
112532
|
}
|
|
112331
112533
|
const nextRetention = cleanChatRetention(retention);
|
|
112332
|
-
|
|
112333
|
-
|
|
112334
|
-
|
|
112335
|
-
|
|
112336
|
-
|
|
112337
|
-
|
|
112338
|
-
|
|
112339
|
-
|
|
112340
|
-
|
|
112341
|
-
|
|
112342
|
-
|
|
112343
|
-
|
|
112344
|
-
|
|
112345
|
-
|
|
112346
|
-
|
|
112347
|
-
|
|
112348
|
-
|
|
112349
|
-
|
|
112350
|
-
|
|
112534
|
+
return withCachedPair(senderPubkey, senderPrivkey, peerChatPK, { chatId }, async (pair) => {
|
|
112535
|
+
if (chatId && pair.chatId !== chatId) {
|
|
112536
|
+
throw new Error("chat mismatch");
|
|
112537
|
+
}
|
|
112538
|
+
const systemMessage = {
|
|
112539
|
+
...makeRetentionSystemMsg(nextRetention),
|
|
112540
|
+
cid: cleanText(options?.cid) || makeCid(),
|
|
112541
|
+
s: senderPubkey
|
|
112542
|
+
};
|
|
112543
|
+
await sendMsg(cloud, senderPubkey, senderPrivkey, peerChatPK, systemMessage, {
|
|
112544
|
+
chatId,
|
|
112545
|
+
linkId: pair.linkId,
|
|
112546
|
+
updatePreview: true,
|
|
112547
|
+
retention: nextRetention,
|
|
112548
|
+
chatExists: true,
|
|
112549
|
+
senderUid: options?.senderUid,
|
|
112550
|
+
ownEntry: options?.ownEntry,
|
|
112551
|
+
chatSettings: { retention: nextRetention },
|
|
112552
|
+
onCommitted: options?.onCommitted
|
|
112553
|
+
});
|
|
112554
|
+
return nextRetention;
|
|
112351
112555
|
});
|
|
112352
|
-
return nextRetention;
|
|
112353
112556
|
}
|
|
112354
112557
|
async function uploadAttachmentMsg(_cloud, senderPubkey, senderPrivkey, receiverChatPK, attachment = {}) {
|
|
112355
112558
|
if (!senderPrivkey || !senderPubkey) {
|
|
@@ -112363,95 +112566,96 @@ async function uploadAttachmentMsg(_cloud, senderPubkey, senderPrivkey, receiver
|
|
|
112363
112566
|
if (!chatId) {
|
|
112364
112567
|
throw new Error("chat id required");
|
|
112365
112568
|
}
|
|
112366
|
-
const pair = await getCachedPair(senderPubkey, senderPrivkey, receiverChatPK, { chatId });
|
|
112367
112569
|
const type = cleanText(attachment?.type) || "file";
|
|
112368
112570
|
const data = attachment?.data;
|
|
112369
112571
|
const meta = attachment?.meta || {};
|
|
112370
112572
|
switch (type) {
|
|
112371
112573
|
case "img":
|
|
112372
|
-
return putImg(
|
|
112574
|
+
return putImg(chatId, nextCid, data, meta);
|
|
112373
112575
|
case "gif":
|
|
112374
|
-
return putGif(
|
|
112576
|
+
return putGif(chatId, nextCid, data, meta);
|
|
112375
112577
|
case "m4a":
|
|
112376
|
-
return putM4a(
|
|
112578
|
+
return putM4a(chatId, nextCid, data, meta);
|
|
112377
112579
|
case "mp4":
|
|
112378
|
-
return putMp4(
|
|
112580
|
+
return putMp4(chatId, nextCid, data, meta);
|
|
112379
112581
|
case "file":
|
|
112380
|
-
return putFile(
|
|
112582
|
+
return putFile(chatId, nextCid, data, meta);
|
|
112381
112583
|
default:
|
|
112382
|
-
return putAttachment(
|
|
112584
|
+
return putAttachment(chatId, nextCid, type, data, meta);
|
|
112383
112585
|
}
|
|
112384
112586
|
}
|
|
112385
112587
|
async function updateMsg(cloud, chatId, msgId, senderPubkey, senderPrivkey, receiverChatPK, newMessage, options = {}) {
|
|
112386
112588
|
if (!senderPubkey || !senderPrivkey)
|
|
112387
112589
|
throw new Error("vault locked");
|
|
112388
|
-
|
|
112389
|
-
|
|
112390
|
-
|
|
112391
|
-
|
|
112392
|
-
|
|
112393
|
-
|
|
112394
|
-
|
|
112395
|
-
|
|
112396
|
-
|
|
112397
|
-
|
|
112398
|
-
|
|
112399
|
-
|
|
112400
|
-
|
|
112401
|
-
|
|
112402
|
-
|
|
112403
|
-
|
|
112404
|
-
|
|
112405
|
-
|
|
112406
|
-
|
|
112407
|
-
|
|
112408
|
-
|
|
112409
|
-
|
|
112410
|
-
|
|
112411
|
-
|
|
112412
|
-
|
|
112413
|
-
|
|
112414
|
-
|
|
112415
|
-
|
|
112416
|
-
|
|
112417
|
-
|
|
112418
|
-
|
|
112419
|
-
|
|
112420
|
-
|
|
112421
|
-
|
|
112422
|
-
|
|
112423
|
-
|
|
112590
|
+
return withCachedPair(senderPubkey, senderPrivkey, receiverChatPK, { chatId }, async (pair) => {
|
|
112591
|
+
if (pair.chatId !== chatId) {
|
|
112592
|
+
throw new Error("chat mismatch");
|
|
112593
|
+
}
|
|
112594
|
+
const target = cleanText(newMessage?.cid) || cleanText(msgId);
|
|
112595
|
+
if (!target) {
|
|
112596
|
+
throw new Error("message target required");
|
|
112597
|
+
}
|
|
112598
|
+
const op = newMessage?.t === "req" && cleanText(newMessage?.tx) ? CHAT_ACTION_OPS.PAY_CONFIRM : CHAT_ACTION_OPS.EDIT;
|
|
112599
|
+
const tsMs = Date.now();
|
|
112600
|
+
const action = {
|
|
112601
|
+
...newMessage || {},
|
|
112602
|
+
cid: makeCid(),
|
|
112603
|
+
s: senderPubkey
|
|
112604
|
+
};
|
|
112605
|
+
const { head, body } = await sealMsg(pair, action, { op, target, ts: tsMs });
|
|
112606
|
+
const messageId = head.cid;
|
|
112607
|
+
const updatePreview = options?.updatePreview === true;
|
|
112608
|
+
const preview2 = updatePreview ? ownerEditedPreview(senderPubkey, newMessage) : null;
|
|
112609
|
+
const ownerEntry = updatePreview ? await ownEntryWrite(cloud, cleanText(options?.senderUid), senderPrivkey, pair, {
|
|
112610
|
+
peerUid: cleanText(options?.receiverUid),
|
|
112611
|
+
peerSigningPublicKey: cleanText(options?.peerSigningPublicKey),
|
|
112612
|
+
entry: options?.ownEntry,
|
|
112613
|
+
preview: preview2,
|
|
112614
|
+
ts: preview2?.ts ?? tsMs
|
|
112615
|
+
}) : null;
|
|
112616
|
+
await cloud.chat.messages.send({
|
|
112617
|
+
chatId,
|
|
112618
|
+
messageId,
|
|
112619
|
+
message: {
|
|
112620
|
+
head,
|
|
112621
|
+
body,
|
|
112622
|
+
ttlMs: null
|
|
112623
|
+
},
|
|
112624
|
+
ownerEntry,
|
|
112625
|
+
inbox: null
|
|
112626
|
+
});
|
|
112627
|
+
return {
|
|
112628
|
+
chatId,
|
|
112629
|
+
msgId: messageId,
|
|
112630
|
+
cid: head.cid,
|
|
112631
|
+
preview: preview2
|
|
112632
|
+
};
|
|
112424
112633
|
});
|
|
112425
|
-
return {
|
|
112426
|
-
chatId,
|
|
112427
|
-
msgId: messageId,
|
|
112428
|
-
cid: head.cid,
|
|
112429
|
-
preview: preview2
|
|
112430
|
-
};
|
|
112431
112634
|
}
|
|
112432
112635
|
async function deleteMsg(cloud, chatId, messageOrId, senderPubkey, senderPrivkey, peerChatPK, options = {}) {
|
|
112433
112636
|
if (!cloud || !chatId || !messageOrId || !senderPubkey || !senderPrivkey || !peerChatPK) {
|
|
112434
112637
|
return false;
|
|
112435
112638
|
}
|
|
112436
|
-
|
|
112437
|
-
|
|
112438
|
-
|
|
112439
|
-
|
|
112440
|
-
|
|
112441
|
-
|
|
112442
|
-
|
|
112443
|
-
|
|
112444
|
-
|
|
112445
|
-
|
|
112446
|
-
|
|
112447
|
-
|
|
112448
|
-
|
|
112449
|
-
|
|
112450
|
-
|
|
112451
|
-
|
|
112452
|
-
|
|
112639
|
+
return withCachedPair(senderPubkey, senderPrivkey, peerChatPK, { chatId }, async (pair) => {
|
|
112640
|
+
if (pair.chatId !== chatId) {
|
|
112641
|
+
return false;
|
|
112642
|
+
}
|
|
112643
|
+
const item = messageDeleteItems([messageOrId])[0];
|
|
112644
|
+
const target = cleanText(options?.docId) || cleanText(item?.id);
|
|
112645
|
+
if (!target || target.startsWith("local:")) {
|
|
112646
|
+
return false;
|
|
112647
|
+
}
|
|
112648
|
+
const deleteTarget = cleanText(options?.target) || cleanText(getMessageKey(messageOrId)) || target;
|
|
112649
|
+
await sendDeleteAction(cloud, senderPubkey, senderPrivkey, peerChatPK, deleteTarget, {
|
|
112650
|
+
chatId,
|
|
112651
|
+
linkId: options?.linkId,
|
|
112652
|
+
senderUid: options?.senderUid
|
|
112653
|
+
});
|
|
112654
|
+
await cloud.chat.messages.delete(chatId, target, {
|
|
112655
|
+
mediaPaths: item?.mediaPath ? [item.mediaPath] : []
|
|
112656
|
+
});
|
|
112657
|
+
return true;
|
|
112453
112658
|
});
|
|
112454
|
-
return true;
|
|
112455
112659
|
}
|
|
112456
112660
|
async function deleteMsgs(cloud, chatId, messages, senderPubkey, senderPrivkey, peerChatPK) {
|
|
112457
112661
|
if (!cloud || !chatId || !senderPubkey || !senderPrivkey || !peerChatPK) {
|
|
@@ -112461,31 +112665,31 @@ async function deleteMsgs(cloud, chatId, messages, senderPubkey, senderPrivkey,
|
|
|
112461
112665
|
if (!items.length) {
|
|
112462
112666
|
return 0;
|
|
112463
112667
|
}
|
|
112464
|
-
|
|
112465
|
-
|
|
112466
|
-
|
|
112467
|
-
|
|
112468
|
-
|
|
112469
|
-
|
|
112470
|
-
|
|
112471
|
-
|
|
112472
|
-
|
|
112473
|
-
|
|
112474
|
-
|
|
112475
|
-
|
|
112668
|
+
return withCachedPair(senderPubkey, senderPrivkey, peerChatPK, { chatId }, async (pair) => {
|
|
112669
|
+
if (pair.chatId !== chatId) {
|
|
112670
|
+
return 0;
|
|
112671
|
+
}
|
|
112672
|
+
let deleted = 0;
|
|
112673
|
+
for (let index = 0;index < items.length; index += DELETE_WRITE_BATCH_SIZE) {
|
|
112674
|
+
const chunk = items.slice(index, index + DELETE_WRITE_BATCH_SIZE);
|
|
112675
|
+
const targets = chunk.map((item) => cleanText(item.id)).filter((target) => target && !target.startsWith("local:"));
|
|
112676
|
+
const mediaPaths = chunk.map((item) => cleanText(item.mediaPath)).filter(Boolean);
|
|
112677
|
+
deleted += await cloud.chat.messages.deleteMany(chatId, targets, { mediaPaths });
|
|
112678
|
+
}
|
|
112679
|
+
return deleted;
|
|
112680
|
+
});
|
|
112476
112681
|
}
|
|
112477
|
-
async function readMsgMedia(readChatMedia,
|
|
112478
|
-
return readMsgAttachment2(readChatMedia,
|
|
112682
|
+
async function readMsgMedia(readChatMedia, msg) {
|
|
112683
|
+
return readMsgAttachment2(readChatMedia, msg);
|
|
112479
112684
|
}
|
|
112480
|
-
async function readMsgAttachment2(readChatMedia,
|
|
112685
|
+
async function readMsgAttachment2(readChatMedia, msg) {
|
|
112481
112686
|
if (typeof readChatMedia !== "function") {
|
|
112482
112687
|
throw new Error("chat media read required");
|
|
112483
112688
|
}
|
|
112484
|
-
if (!
|
|
112689
|
+
if (!msg) {
|
|
112485
112690
|
return null;
|
|
112486
112691
|
}
|
|
112487
|
-
|
|
112488
|
-
return readMsgFile(readChatMedia, pair, msg);
|
|
112692
|
+
return readMsgFile(readChatMedia, msg);
|
|
112489
112693
|
}
|
|
112490
112694
|
var DELETE_WRITE_BATCH_SIZE;
|
|
112491
112695
|
var init_write = __esm(() => {
|
|
@@ -112728,14 +112932,14 @@ function hasInvalidStoredMediaRef(message) {
|
|
|
112728
112932
|
return true;
|
|
112729
112933
|
}
|
|
112730
112934
|
}
|
|
112731
|
-
function readMessageMedia(cloud, media,
|
|
112935
|
+
function readMessageMedia(cloud, media, message) {
|
|
112732
112936
|
const readChatMedia = cloud?.chat?.media?.read;
|
|
112733
112937
|
if (typeof media?.readMessageFile === "function") {
|
|
112734
|
-
return media.readMessageFile(readChatMedia,
|
|
112938
|
+
return media.readMessageFile(readChatMedia, message);
|
|
112735
112939
|
}
|
|
112736
|
-
return readMsgMedia(readChatMedia,
|
|
112940
|
+
return readMsgMedia(readChatMedia, message);
|
|
112737
112941
|
}
|
|
112738
|
-
function createChatSave({ cloud, media = {}, chatBanned,
|
|
112942
|
+
function createChatSave({ cloud, media = {}, chatBanned, localCache }) {
|
|
112739
112943
|
const makeMessagePermanent = async (chatId, message) => {
|
|
112740
112944
|
if (chatBanned) {
|
|
112741
112945
|
throw makeChatUnavailableError();
|
|
@@ -112753,7 +112957,7 @@ function createChatSave({ cloud, media = {}, chatBanned, chatPK, chatPrivateKey,
|
|
|
112753
112957
|
const updated = await makeMsgTemporary(cloud, chatId, list, ttl);
|
|
112754
112958
|
return { updated, ttl };
|
|
112755
112959
|
};
|
|
112756
|
-
const readMessageFile = async (
|
|
112960
|
+
const readMessageFile = async (_peerChatPK, message) => {
|
|
112757
112961
|
if (chatBanned) {
|
|
112758
112962
|
throw makeChatUnavailableError();
|
|
112759
112963
|
}
|
|
@@ -112775,7 +112979,7 @@ function createChatSave({ cloud, media = {}, chatBanned, chatPK, chatPrivateKey,
|
|
|
112775
112979
|
throw makeFileGoneError();
|
|
112776
112980
|
}
|
|
112777
112981
|
try {
|
|
112778
|
-
const bytes = await readMessageMedia(cloud, media,
|
|
112982
|
+
const bytes = await readMessageMedia(cloud, media, message);
|
|
112779
112983
|
saveMedia(localCache, message, bytes, message);
|
|
112780
112984
|
return bytes;
|
|
112781
112985
|
} catch (error) {
|
|
@@ -113421,8 +113625,11 @@ function withSharedMediaUpload(cloud, media, meta = {}) {
|
|
|
113421
113625
|
};
|
|
113422
113626
|
}
|
|
113423
113627
|
function uploadMessageAttachment(cloud, media, senderPubkey, senderPrivkey, receiverChatPK, attachment = {}) {
|
|
113628
|
+
if (!senderPubkey || !senderPrivkey) {
|
|
113629
|
+
throw new Error("vault locked");
|
|
113630
|
+
}
|
|
113424
113631
|
if (typeof media?.uploadAttachment === "function") {
|
|
113425
|
-
return media.uploadAttachment(
|
|
113632
|
+
return media.uploadAttachment(attachment);
|
|
113426
113633
|
}
|
|
113427
113634
|
return uploadAttachmentMsg(cloud, senderPubkey, senderPrivkey, receiverChatPK, withMediaUpload(cloud, media, attachment));
|
|
113428
113635
|
}
|
|
@@ -113720,17 +113927,21 @@ ${cid}` : "";
|
|
|
113720
113927
|
const requiredPreview = previewRequired || sendOptions.chatExists !== true;
|
|
113721
113928
|
let local = await showLocalMessage(peerChatPK, message, sendOptions);
|
|
113722
113929
|
let committed = false;
|
|
113930
|
+
let sent = false;
|
|
113931
|
+
const markSent = () => {
|
|
113932
|
+
if (sent)
|
|
113933
|
+
return;
|
|
113934
|
+
sent = true;
|
|
113935
|
+
sentChatIdsRef.current.add(local.chatId);
|
|
113936
|
+
markLocalStatus(local.chatId, local.cid, LOCAL_SENT);
|
|
113937
|
+
};
|
|
113723
113938
|
const markCommitted = () => {
|
|
113724
113939
|
if (committed)
|
|
113725
113940
|
return;
|
|
113726
113941
|
committed = true;
|
|
113727
|
-
|
|
113942
|
+
markSent();
|
|
113728
113943
|
markDone(diag, "chat.send.commit", startedAt, { type: local?.t || "txt", previewRequired: !!requiredPreview });
|
|
113729
113944
|
};
|
|
113730
|
-
const markSent = () => {
|
|
113731
|
-
sentChatIdsRef.current.add(local.chatId);
|
|
113732
|
-
markLocalStatus(local.chatId, local.cid, LOCAL_SENT);
|
|
113733
|
-
};
|
|
113734
113945
|
return await new Promise((resolve, reject) => {
|
|
113735
113946
|
const job = {
|
|
113736
113947
|
previewKey: local.chatId,
|
|
@@ -113948,7 +114159,8 @@ ${cid}` : "";
|
|
|
113948
114159
|
linkId: local.linkId,
|
|
113949
114160
|
version: local.version,
|
|
113950
114161
|
sendOptions,
|
|
113951
|
-
nextAttachment: prepared.nextAttachment
|
|
114162
|
+
nextAttachment: prepared.nextAttachment,
|
|
114163
|
+
committed: false
|
|
113952
114164
|
};
|
|
113953
114165
|
}));
|
|
113954
114166
|
return await new Promise((resolve, reject) => {
|
|
@@ -113957,7 +114169,9 @@ ${cid}` : "";
|
|
|
113957
114169
|
reject,
|
|
113958
114170
|
onError: () => {
|
|
113959
114171
|
for (const item of locals) {
|
|
113960
|
-
|
|
114172
|
+
if (!item.committed) {
|
|
114173
|
+
markLocalStatus(item.chatId, item.cid, LOCAL_FAILED);
|
|
114174
|
+
}
|
|
113961
114175
|
}
|
|
113962
114176
|
},
|
|
113963
114177
|
run: async () => {
|
|
@@ -113972,6 +114186,7 @@ ${cid}` : "";
|
|
|
113972
114186
|
results.push({ peerChatPK: item.peerChatPK, ok: false, error: uploadError });
|
|
113973
114187
|
continue;
|
|
113974
114188
|
}
|
|
114189
|
+
let sentMessage;
|
|
113975
114190
|
try {
|
|
113976
114191
|
let uploaded = uploads.get(uploadKey);
|
|
113977
114192
|
if (!uploaded) {
|
|
@@ -113984,17 +114199,32 @@ ${cid}` : "";
|
|
|
113984
114199
|
cid: item.cid,
|
|
113985
114200
|
s: chatPK
|
|
113986
114201
|
};
|
|
113987
|
-
|
|
114202
|
+
sentMessage = withMessageRetention(sent, item.sendOptions.retention);
|
|
113988
114203
|
rememberCachedLocalMedia(item.chatId, item.cid, sentMessage);
|
|
113989
|
-
await sendMsg(cloud, chatPK, chatPrivateKey, item.peerChatPK, sentMessage, {
|
|
113990
|
-
|
|
114204
|
+
await sendMsg(cloud, chatPK, chatPrivateKey, item.peerChatPK, sentMessage, {
|
|
114205
|
+
...item.sendOptions,
|
|
114206
|
+
chatId: item.chatId,
|
|
114207
|
+
linkId: item.linkId,
|
|
114208
|
+
senderUid: uid,
|
|
114209
|
+
onCommitted: () => {
|
|
114210
|
+
if (item.committed)
|
|
114211
|
+
return;
|
|
114212
|
+
item.committed = true;
|
|
114213
|
+
sentChatIdsRef.current.add(item.chatId);
|
|
114214
|
+
markLocalStatus(item.chatId, item.cid, LOCAL_SENT);
|
|
114215
|
+
}
|
|
114216
|
+
});
|
|
113991
114217
|
results.push({ peerChatPK: item.peerChatPK, ok: true, message: sentMessage });
|
|
113992
114218
|
} catch (error) {
|
|
113993
114219
|
if (!uploads.has(uploadKey)) {
|
|
113994
114220
|
uploadErrors.set(uploadKey, error);
|
|
113995
114221
|
}
|
|
113996
|
-
|
|
113997
|
-
|
|
114222
|
+
if (item.committed) {
|
|
114223
|
+
results.push({ peerChatPK: item.peerChatPK, ok: true, message: sentMessage });
|
|
114224
|
+
} else {
|
|
114225
|
+
markLocalStatus(item.chatId, item.cid, LOCAL_FAILED);
|
|
114226
|
+
results.push({ peerChatPK: item.peerChatPK, ok: false, error });
|
|
114227
|
+
}
|
|
113998
114228
|
}
|
|
113999
114229
|
}
|
|
114000
114230
|
return results;
|
|
@@ -114801,7 +115031,6 @@ async function decryptRecordEntries(records, userChatPK, userPrivKey, peerChatPK
|
|
|
114801
115031
|
return [];
|
|
114802
115032
|
}
|
|
114803
115033
|
const signingKeysVersion = signingKeysFingerprint(options?.signingKeysByChatKey);
|
|
114804
|
-
const pair = await getCachedPair(userChatPK, userPrivKey, peerChatPK, { chatId: options?.chatId });
|
|
114805
115034
|
const entryOptions = { ...options, signingKeysVersion };
|
|
114806
115035
|
const shouldYield = positiveInt(options?.yieldEvery, 0) > 0;
|
|
114807
115036
|
const entries = new Array(source.length).fill(null);
|
|
@@ -114818,38 +115047,40 @@ async function decryptRecordEntries(records, userChatPK, userPrivKey, peerChatPK
|
|
|
114818
115047
|
}
|
|
114819
115048
|
pending.push({ record, index });
|
|
114820
115049
|
};
|
|
114821
|
-
|
|
114822
|
-
|
|
114823
|
-
|
|
114824
|
-
|
|
114825
|
-
|
|
114826
|
-
|
|
114827
|
-
|
|
114828
|
-
|
|
114829
|
-
|
|
115050
|
+
return withCachedPair(userChatPK, userPrivKey, peerChatPK, { chatId: options?.chatId }, async (pair) => {
|
|
115051
|
+
const openPending = async (pending) => {
|
|
115052
|
+
if (!pending.length) {
|
|
115053
|
+
return;
|
|
115054
|
+
}
|
|
115055
|
+
const opened = await decryptRecordBatchWithPair(pending.map((item) => item.record), pair, cache, entryOptions);
|
|
115056
|
+
for (let index = 0;index < opened.length; index += 1) {
|
|
115057
|
+
const entry = opened[index];
|
|
115058
|
+
if (entry) {
|
|
115059
|
+
entries[pending[index].index] = entry;
|
|
115060
|
+
}
|
|
115061
|
+
}
|
|
115062
|
+
};
|
|
115063
|
+
if (!options?.signal && !shouldYield) {
|
|
115064
|
+
const pending = [];
|
|
115065
|
+
for (let index = 0;index < source.length; index += 1) {
|
|
115066
|
+
collectRecord(source[index], index, pending);
|
|
114830
115067
|
}
|
|
115068
|
+
await openPending(pending);
|
|
115069
|
+
return entries.filter(Boolean);
|
|
114831
115070
|
}
|
|
114832
|
-
|
|
114833
|
-
|
|
114834
|
-
|
|
114835
|
-
|
|
114836
|
-
|
|
115071
|
+
const chunkSize = positiveInt(options?.yieldEvery, source.length || 1);
|
|
115072
|
+
for (let index = 0;index < source.length; index += chunkSize) {
|
|
115073
|
+
throwIfAborted(options?.signal);
|
|
115074
|
+
const chunk = source.slice(index, index + chunkSize);
|
|
115075
|
+
const pending = [];
|
|
115076
|
+
for (let offset = 0;offset < chunk.length; offset += 1) {
|
|
115077
|
+
collectRecord(chunk[offset], index + offset, pending);
|
|
115078
|
+
}
|
|
115079
|
+
await openPending(pending);
|
|
115080
|
+
await maybeYield(index + chunk.length, options);
|
|
114837
115081
|
}
|
|
114838
|
-
await openPending(pending);
|
|
114839
115082
|
return entries.filter(Boolean);
|
|
114840
|
-
}
|
|
114841
|
-
const chunkSize = positiveInt(options?.yieldEvery, source.length || 1);
|
|
114842
|
-
for (let index = 0;index < source.length; index += chunkSize) {
|
|
114843
|
-
throwIfAborted(options?.signal);
|
|
114844
|
-
const chunk = source.slice(index, index + chunkSize);
|
|
114845
|
-
const pending = [];
|
|
114846
|
-
for (let offset = 0;offset < chunk.length; offset += 1) {
|
|
114847
|
-
collectRecord(chunk[offset], index + offset, pending);
|
|
114848
|
-
}
|
|
114849
|
-
await openPending(pending);
|
|
114850
|
-
await maybeYield(index + chunk.length, options);
|
|
114851
|
-
}
|
|
114852
|
-
return entries.filter(Boolean);
|
|
115083
|
+
});
|
|
114853
115084
|
}
|
|
114854
115085
|
function messageQueryLimit(pageSize) {
|
|
114855
115086
|
return positiveInt(pageSize, MSG_BATCH_SIZE);
|
|
@@ -115195,9 +115426,10 @@ async function decryptMsg(msgData, userChatPK, userPrivKey, peerChatPK, options
|
|
|
115195
115426
|
return null;
|
|
115196
115427
|
}
|
|
115197
115428
|
try {
|
|
115198
|
-
|
|
115199
|
-
|
|
115200
|
-
|
|
115429
|
+
return await withCachedPair(userChatPK, userPrivKey, peerChatPK, { chatId: options?.chatId }, async (pair) => {
|
|
115430
|
+
const message = await openMsg(pair, msgData, { signingKeysByChatKey: options?.signingKeysByChatKey, crypto: options?.crypto });
|
|
115431
|
+
return normalizeDecryptedMsg(msgData, message);
|
|
115432
|
+
});
|
|
115201
115433
|
} catch {
|
|
115202
115434
|
return null;
|
|
115203
115435
|
}
|
|
@@ -116267,12 +116499,12 @@ function warmKeyStore(ref) {
|
|
|
116267
116499
|
}
|
|
116268
116500
|
return ref.current;
|
|
116269
116501
|
}
|
|
116270
|
-
function readMessageMedia2(cloud, media,
|
|
116502
|
+
function readMessageMedia2(cloud, media, message) {
|
|
116271
116503
|
const readChatMedia = cloud?.chat?.media?.read;
|
|
116272
116504
|
if (typeof media?.readMessageFile === "function") {
|
|
116273
|
-
return media.readMessageFile(readChatMedia,
|
|
116505
|
+
return media.readMessageFile(readChatMedia, message);
|
|
116274
116506
|
}
|
|
116275
|
-
return readMsgMedia(readChatMedia,
|
|
116507
|
+
return readMsgMedia(readChatMedia, message);
|
|
116276
116508
|
}
|
|
116277
116509
|
function isDenied3(error) {
|
|
116278
116510
|
return error?.code === "permission-denied";
|
|
@@ -116479,12 +116711,12 @@ function createChatMessageBatches({ cloud, media = {}, chatPK, chatPrivateKey, c
|
|
|
116479
116711
|
return;
|
|
116480
116712
|
}
|
|
116481
116713
|
const tasks = buildMediaTasks();
|
|
116482
|
-
const readFile = async (
|
|
116714
|
+
const readFile = async (_peerChatPK, message) => {
|
|
116483
116715
|
const cached = await readCachedMedia(localCache, message);
|
|
116484
116716
|
if (cached?.byteLength) {
|
|
116485
116717
|
return cached;
|
|
116486
116718
|
}
|
|
116487
|
-
const bytes = await readMessageMedia2(cloud, media,
|
|
116719
|
+
const bytes = await readMessageMedia2(cloud, media, message);
|
|
116488
116720
|
if (bytes?.byteLength) {
|
|
116489
116721
|
saveMedia(localCache, message, bytes, message);
|
|
116490
116722
|
}
|
|
@@ -117231,6 +117463,16 @@ function pingSigningKeys(ping, existing) {
|
|
|
117231
117463
|
[ping.payload.senderChatPK]: ping.payload.signingPublicKey
|
|
117232
117464
|
};
|
|
117233
117465
|
}
|
|
117466
|
+
function chatSettingsFromPreview(settings, preview2) {
|
|
117467
|
+
const current = normalizeChatSettings(settings);
|
|
117468
|
+
if (!isSystemMsg(preview2)) {
|
|
117469
|
+
return current;
|
|
117470
|
+
}
|
|
117471
|
+
return {
|
|
117472
|
+
...current,
|
|
117473
|
+
retention: cleanChatRetention(preview2.retention)
|
|
117474
|
+
};
|
|
117475
|
+
}
|
|
117234
117476
|
function chatFromPing(ping, entryId, existing, preview2, userChatPK, ms, options = {}) {
|
|
117235
117477
|
const ts = timestampMs(ms, null) ?? timestampMs(existing?.ts, null) ?? timestampMs(preview2?.ts, null) ?? 0;
|
|
117236
117478
|
if (!ts) {
|
|
@@ -117247,7 +117489,7 @@ function chatFromPing(ping, entryId, existing, preview2, userChatPK, ms, options
|
|
|
117247
117489
|
peerChatPK: ping.payload.senderChatPK,
|
|
117248
117490
|
peerUid: existing?.peerUid || cleanText(ping.payload.senderUid) || null,
|
|
117249
117491
|
signingKeysByChatKey: pingSigningKeys(ping, existing),
|
|
117250
|
-
settings: existing?.settings,
|
|
117492
|
+
settings: chatSettingsFromPreview(existing?.settings, preview2),
|
|
117251
117493
|
saved: existing?.saved || null,
|
|
117252
117494
|
readMs,
|
|
117253
117495
|
startMs,
|
|
@@ -117306,7 +117548,7 @@ async function savePing(cloud, uid, userChatPK, userPrivKey, ping, options = {})
|
|
|
117306
117548
|
peerUid: peerUid2 || existing?.peerUid,
|
|
117307
117549
|
peerSigningPublicKey: ping.payload.signingPublicKey || existing?.signingKeysByChatKey?.[ping.payload.senderChatPK],
|
|
117308
117550
|
signingKeysByChatKey,
|
|
117309
|
-
settings: existing?.settings,
|
|
117551
|
+
settings: chatSettingsFromPreview(existing?.settings, preview2),
|
|
117310
117552
|
preview: preview2 || existing?.preview,
|
|
117311
117553
|
readMs: existing?.readMs,
|
|
117312
117554
|
startMs: existing ? existing.startMs : timestampMs(options.startPreview?.ts ?? preview2?.ts, null, { positive: true })
|
|
@@ -117495,6 +117737,7 @@ var init_inbox = __esm(() => {
|
|
|
117495
117737
|
init_ping();
|
|
117496
117738
|
init_query();
|
|
117497
117739
|
init_chats();
|
|
117740
|
+
init_ttl();
|
|
117498
117741
|
init_time();
|
|
117499
117742
|
init_protocol();
|
|
117500
117743
|
});
|
|
@@ -117990,6 +118233,7 @@ function createChatList({
|
|
|
117990
118233
|
let chats = [];
|
|
117991
118234
|
let peers = [];
|
|
117992
118235
|
let isChatDataReady = false;
|
|
118236
|
+
let isChatListLive = false;
|
|
117993
118237
|
let chatSourceReady = false;
|
|
117994
118238
|
let lastChat = null;
|
|
117995
118239
|
let serverChatIds = [];
|
|
@@ -118026,6 +118270,7 @@ function createChatList({
|
|
|
118026
118270
|
chats,
|
|
118027
118271
|
peers,
|
|
118028
118272
|
isChatDataReady,
|
|
118273
|
+
isChatListLive,
|
|
118029
118274
|
hasChats: chats.length > 0,
|
|
118030
118275
|
previewNow,
|
|
118031
118276
|
lastChat,
|
|
@@ -118059,6 +118304,13 @@ function createChatList({
|
|
|
118059
118304
|
isChatDataReady = value;
|
|
118060
118305
|
publish();
|
|
118061
118306
|
};
|
|
118307
|
+
const setIsChatListLive = (next) => {
|
|
118308
|
+
const value = nextValue(isChatListLive, next);
|
|
118309
|
+
if (Object.is(isChatListLive, value))
|
|
118310
|
+
return;
|
|
118311
|
+
isChatListLive = value;
|
|
118312
|
+
publish();
|
|
118313
|
+
};
|
|
118062
118314
|
const setLastChat = (next) => {
|
|
118063
118315
|
const value = nextValue(lastChat, next);
|
|
118064
118316
|
if (Object.is(lastChat, value))
|
|
@@ -118268,6 +118520,7 @@ function createChatList({
|
|
|
118268
118520
|
const resetChatList = (ready = false) => {
|
|
118269
118521
|
chatSourceReady = ready;
|
|
118270
118522
|
syncChatDataReady();
|
|
118523
|
+
setIsChatListLive(false);
|
|
118271
118524
|
setChats((prev) => prev.length ? [] : prev);
|
|
118272
118525
|
setPeers((prev) => prev.length ? [] : prev);
|
|
118273
118526
|
setLastChat((prev) => prev ? null : prev);
|
|
@@ -118357,6 +118610,7 @@ function createChatList({
|
|
|
118357
118610
|
resetAllChatState();
|
|
118358
118611
|
return;
|
|
118359
118612
|
}
|
|
118613
|
+
setIsChatListLive(false);
|
|
118360
118614
|
let cancelled = false;
|
|
118361
118615
|
const hydrateKey = localCache?.id ? `${localCache.id}:${chatPK}` : "";
|
|
118362
118616
|
if (hydrateKey && lastHydratedCacheKeyRef.current !== hydrateKey) {
|
|
@@ -118456,6 +118710,7 @@ function createChatList({
|
|
|
118456
118710
|
writeCache: true,
|
|
118457
118711
|
serverEndReached: cachedHistoryEndRef.current
|
|
118458
118712
|
});
|
|
118713
|
+
setIsChatListLive(true);
|
|
118459
118714
|
listenUpdateSeqRef.current += 1;
|
|
118460
118715
|
markDiag(diag, "chat.provider.listen.update", {
|
|
118461
118716
|
seq: listenUpdateSeqRef.current,
|
|
@@ -118498,6 +118753,7 @@ function createChatList({
|
|
|
118498
118753
|
markChatSourceReady();
|
|
118499
118754
|
fillVisibleChatPage();
|
|
118500
118755
|
}, (error) => {
|
|
118756
|
+
setIsChatListLive(false);
|
|
118501
118757
|
markError(diag, "chat.provider.listen", listenStartedAt, error);
|
|
118502
118758
|
if (shouldResetChatListAfterListenError(error)) {
|
|
118503
118759
|
resetAllChatState();
|
|
@@ -122187,11 +122443,6 @@ function createWalletPrivacy({ wallet, ghostWallet, diag }) {
|
|
|
122187
122443
|
const startedAt = Date.now();
|
|
122188
122444
|
const desired = desiredPrivacy;
|
|
122189
122445
|
markDiag(diag, "wallet.privacy.start", { ghostWallet: desired });
|
|
122190
|
-
const current = typeof wallet.getWalletSettings === "function" ? await wallet.getWalletSettings() : null;
|
|
122191
|
-
if (closed || requestRevision !== revision || current?.privateEnabled === true === desired) {
|
|
122192
|
-
markDone(diag, "wallet.privacy", startedAt, { changed: false, cancelled: closed || requestRevision !== revision });
|
|
122193
|
-
return;
|
|
122194
|
-
}
|
|
122195
122446
|
await wallet.setPrivacyEnabled(desired);
|
|
122196
122447
|
markDone(diag, "wallet.privacy", startedAt, { changed: true });
|
|
122197
122448
|
}).catch((error) => {
|
|
@@ -123041,7 +123292,7 @@ function adaptiveClaimBatchSize(maxBatchSize, queueDepth) {
|
|
|
123041
123292
|
}
|
|
123042
123293
|
return 1;
|
|
123043
123294
|
}
|
|
123044
|
-
function createWalletTransferSession({ wallet, walletPK, localCache, claimIncomingTransfers, pendingClaimBatchSize = null, eagerOutgoingStatusRefresh = false, transferStore, appState = null, deferBackgroundWork = null, backgroundSignal = null, diag }) {
|
|
123295
|
+
function createWalletTransferSession({ wallet, walletPK, localCache, claimIncomingTransfers, pendingClaimBatchSize = null, eagerOutgoingStatusRefresh = false, eagerCacheHistory = true, transferStore, appState = null, deferBackgroundWork = null, backgroundSignal = null, diag }) {
|
|
123045
123296
|
if (!transferStore || typeof transferStore.subscribe !== "function" || typeof transferStore.getSnapshot !== "function" || typeof transferStore.getCacheState !== "function" || typeof transferStore.setHistory !== "function") {
|
|
123046
123297
|
throw new Error("createWalletTransferSession requires transferStore");
|
|
123047
123298
|
}
|
|
@@ -123055,6 +123306,7 @@ function createWalletTransferSession({ wallet, walletPK, localCache, claimIncomi
|
|
|
123055
123306
|
const initialTransfers = canUseInitialStore ? transferStore.getTransfers() : [];
|
|
123056
123307
|
const initialHistoryTransfers = canUseInitialStore ? transferStore.getHistoryTransfers() : [];
|
|
123057
123308
|
const initialTxReady = canUseInitialStore && (initialStoreSnapshot.ready || initialTransfers.length > 0 || initialHistoryTransfers.length > 0);
|
|
123309
|
+
const initialCacheReady = initialTxReady && (eagerCacheHistory === false || initialStoreSnapshot.serverEndReached === true && initialHistoryTransfers.length >= initialStoreSnapshot.historyCount);
|
|
123058
123310
|
const listeners = new Set;
|
|
123059
123311
|
let isTxLoading = false;
|
|
123060
123312
|
let publishedSnapshot = null;
|
|
@@ -124771,6 +125023,9 @@ function createWalletTransferSession({ wallet, walletPK, localCache, claimIncomi
|
|
|
124771
125023
|
if (!wallet || !localCache || !walletPKRef.current) {
|
|
124772
125024
|
return;
|
|
124773
125025
|
}
|
|
125026
|
+
if (initialCacheReady) {
|
|
125027
|
+
return;
|
|
125028
|
+
}
|
|
124774
125029
|
const hydrateKey = `${localCache.id || "cache"}:${walletPKRef.current}`;
|
|
124775
125030
|
if (cacheHydrateKeyRef.current === hydrateKey) {
|
|
124776
125031
|
return;
|
|
@@ -124795,7 +125050,7 @@ function createWalletTransferSession({ wallet, walletPK, localCache, claimIncomi
|
|
|
124795
125050
|
return;
|
|
124796
125051
|
}
|
|
124797
125052
|
const hydratedHead = applyCachedTransferState(cachedHead, { label: "wallet.provider.cache.hydrate", publish: true, startedAt: hydrateStartedAt });
|
|
124798
|
-
if (cancelled)
|
|
125053
|
+
if (cancelled || !eagerCacheHistory)
|
|
124799
125054
|
return;
|
|
124800
125055
|
await loadFullTransferCache({ label: "wallet.provider.cache.fullHydrate", publish: !hydratedHead });
|
|
124801
125056
|
}).catch((error) => {
|
|
@@ -125204,6 +125459,7 @@ function createWalletSession({
|
|
|
125204
125459
|
pendingClaimBatchSize = null,
|
|
125205
125460
|
activeTransferRefreshMs = null,
|
|
125206
125461
|
eagerOutgoingStatusRefresh = false,
|
|
125462
|
+
eagerCacheHistory = true,
|
|
125207
125463
|
sentTransferRefreshDelayMs = null,
|
|
125208
125464
|
deferBackgroundWork = null,
|
|
125209
125465
|
appState = null,
|
|
@@ -125232,6 +125488,7 @@ function createWalletSession({
|
|
|
125232
125488
|
claimIncomingTransfers,
|
|
125233
125489
|
pendingClaimBatchSize,
|
|
125234
125490
|
eagerOutgoingStatusRefresh,
|
|
125491
|
+
eagerCacheHistory,
|
|
125235
125492
|
transferStore,
|
|
125236
125493
|
appState,
|
|
125237
125494
|
deferBackgroundWork,
|
|
@@ -125342,7 +125599,7 @@ function createWalletSession({
|
|
|
125342
125599
|
balanceReady: balanceState.balanceReady,
|
|
125343
125600
|
isBalanceLoading: balanceState.isBalanceLoading,
|
|
125344
125601
|
isWalletDataReady: true,
|
|
125345
|
-
isWalletDataLoaded: balanceState.balanceReady
|
|
125602
|
+
isWalletDataLoaded: balanceState.balanceReady || currentTransferState.txReady,
|
|
125346
125603
|
refresh: claims.refresh,
|
|
125347
125604
|
requestTransferDiscoveryHotWindow: polling.requestTransferDiscoveryHotWindow,
|
|
125348
125605
|
claimDeposits: claims.claimDeposits,
|
|
@@ -169284,7 +169541,12 @@ function createFirebaseCloud({ db, auth: auth2, getAuth: getAuth2, functions: fu
|
|
|
169284
169541
|
"Content-Type": upload?.metadata?.contentType || "application/octet-stream"
|
|
169285
169542
|
};
|
|
169286
169543
|
if (typeof uploadSignedStorageBytes === "function") {
|
|
169287
|
-
await uploadSignedStorageBytes(url, upload?.body, { ...signed, method, headers, metadata: upload?.metadata || {}, path: upload?.path || "" })
|
|
169544
|
+
await uploadSignedStorageBytes(url, upload?.body, { ...signed, method, headers, metadata: upload?.metadata || {}, path: upload?.path || "" }).catch((error) => {
|
|
169545
|
+
if (error?.status === 412 && (headers["X-Goog-If-Generation-Match"] === "0" || headers["x-goog-if-generation-match"] === "0")) {
|
|
169546
|
+
return true;
|
|
169547
|
+
}
|
|
169548
|
+
throw error;
|
|
169549
|
+
});
|
|
169288
169550
|
return true;
|
|
169289
169551
|
}
|
|
169290
169552
|
const payload = typeof Blob !== "undefined" && upload?.body instanceof Blob ? upload.body : toBytes(upload?.body, "upload bytes");
|
|
@@ -169293,6 +169555,9 @@ function createFirebaseCloud({ db, auth: auth2, getAuth: getAuth2, functions: fu
|
|
|
169293
169555
|
headers,
|
|
169294
169556
|
body: payload
|
|
169295
169557
|
});
|
|
169558
|
+
if (response.status === 412 && (headers["X-Goog-If-Generation-Match"] === "0" || headers["x-goog-if-generation-match"] === "0")) {
|
|
169559
|
+
return true;
|
|
169560
|
+
}
|
|
169296
169561
|
if (!response.ok) {
|
|
169297
169562
|
const error = new Error(`signed upload failed (${response.status || 0})`);
|
|
169298
169563
|
error.status = response.status || 0;
|
|
@@ -169615,16 +169880,11 @@ function createFirebaseCloud({ db, auth: auth2, getAuth: getAuth2, functions: fu
|
|
|
169615
169880
|
await deleteObject(ref(targetStorage, avatarPath(uid)));
|
|
169616
169881
|
return true;
|
|
169617
169882
|
}
|
|
169618
|
-
async function
|
|
169619
|
-
if (!
|
|
169620
|
-
throw new Error("
|
|
169621
|
-
|
|
169622
|
-
|
|
169623
|
-
}
|
|
169624
|
-
async function writeProfileChatPK(chatPK) {
|
|
169625
|
-
if (!chatPK)
|
|
169626
|
-
throw new Error("chat public key required");
|
|
169627
|
-
await callVaultFunction("setChatPK", VAULT_SIGNATURE_PURPOSES.SET_CHAT_IDENTITY, { chatPK });
|
|
169883
|
+
async function writeProfileIdentity(identity) {
|
|
169884
|
+
if (!identity || typeof identity !== "object" || Array.isArray(identity)) {
|
|
169885
|
+
throw new Error("profile identity required");
|
|
169886
|
+
}
|
|
169887
|
+
await callVaultFunction("setIdentities", VAULT_SIGNATURE_PURPOSES.SET_IDENTITIES, identity);
|
|
169628
169888
|
return true;
|
|
169629
169889
|
}
|
|
169630
169890
|
async function getUsername(username) {
|
|
@@ -169674,9 +169934,7 @@ function createFirebaseCloud({ db, auth: auth2, getAuth: getAuth2, functions: fu
|
|
|
169674
169934
|
}
|
|
169675
169935
|
return openSettings(key, uid, readCloudBytes(saved, "settings body"));
|
|
169676
169936
|
}
|
|
169677
|
-
|
|
169678
|
-
await callVaultFunction("setSettings", VAULT_SIGNATURE_PURPOSES.SET_SETTINGS, { settings: bytesBase64(await sealSettings(key, uid, settings)) });
|
|
169679
|
-
return settings;
|
|
169937
|
+
return normalizeSettings(defaultSettings);
|
|
169680
169938
|
}
|
|
169681
169939
|
async function writeSettings(uid, settings, { currentSettings, key } = {}) {
|
|
169682
169940
|
requireUid(uid);
|
|
@@ -169814,20 +170072,12 @@ function createFirebaseCloud({ db, auth: auth2, getAuth: getAuth2, functions: fu
|
|
|
169814
170072
|
const snapshot = await getDocs(roleQuery);
|
|
169815
170073
|
return peerRecordsFromSnapshot(snapshot);
|
|
169816
170074
|
}
|
|
169817
|
-
async function
|
|
170075
|
+
async function uploadMedia(upload) {
|
|
169818
170076
|
const path = upload?.path;
|
|
169819
170077
|
if (!path)
|
|
169820
170078
|
throw new Error("media path required");
|
|
169821
|
-
|
|
169822
|
-
await
|
|
169823
|
-
return true;
|
|
169824
|
-
}
|
|
169825
|
-
async function uploadSharedMedia(upload) {
|
|
169826
|
-
const path = upload?.path;
|
|
169827
|
-
if (!path)
|
|
169828
|
-
throw new Error("shared media path required");
|
|
169829
|
-
const signed = await callFunction("reserveSharedMediaUpload", {
|
|
169830
|
-
sharedId: upload?.sharedId,
|
|
170079
|
+
getMediaFileRef(path);
|
|
170080
|
+
const signed = await callFunction("reserveMediaUpload", {
|
|
169831
170081
|
path,
|
|
169832
170082
|
size: uploadByteSize(upload?.body),
|
|
169833
170083
|
contentType: upload?.metadata?.contentType || "application/octet-stream"
|
|
@@ -169835,6 +170085,14 @@ function createFirebaseCloud({ db, auth: auth2, getAuth: getAuth2, functions: fu
|
|
|
169835
170085
|
await uploadSignedStorageFile(upload, signed?.upload);
|
|
169836
170086
|
return true;
|
|
169837
170087
|
}
|
|
170088
|
+
async function uploadChatMedia(upload) {
|
|
170089
|
+
getChatMediaFileRef(upload?.path);
|
|
170090
|
+
return uploadMedia(upload);
|
|
170091
|
+
}
|
|
170092
|
+
async function uploadSharedMedia(upload) {
|
|
170093
|
+
getSharedMediaFileRef(upload?.path);
|
|
170094
|
+
return uploadMedia(upload);
|
|
170095
|
+
}
|
|
169838
170096
|
async function readChatMedia(path) {
|
|
169839
170097
|
if (!path)
|
|
169840
170098
|
throw new Error("media path required");
|
|
@@ -170564,16 +170822,13 @@ function createFirebaseCloud({ db, auth: auth2, getAuth: getAuth2, functions: fu
|
|
|
170564
170822
|
},
|
|
170565
170823
|
profile: {
|
|
170566
170824
|
watch: watchProfile,
|
|
170825
|
+
identity: {
|
|
170826
|
+
write: writeProfileIdentity
|
|
170827
|
+
},
|
|
170567
170828
|
avatar: {
|
|
170568
170829
|
write: writeProfileAvatar,
|
|
170569
170830
|
upload: uploadProfileAvatar,
|
|
170570
170831
|
delete: deleteProfileAvatar
|
|
170571
|
-
},
|
|
170572
|
-
walletpk: {
|
|
170573
|
-
write: writeProfileWalletPK
|
|
170574
|
-
},
|
|
170575
|
-
chatpk: {
|
|
170576
|
-
write: writeProfileChatPK
|
|
170577
170832
|
}
|
|
170578
170833
|
},
|
|
170579
170834
|
private: {
|
|
@@ -173325,7 +173580,7 @@ function createRuntimeProductActions({
|
|
|
173325
173580
|
if (Object.prototype.hasOwnProperty.call(patch, "walletNetwork") && nextNetwork !== previousNetwork) {
|
|
173326
173581
|
await lockVault();
|
|
173327
173582
|
if (nextNetwork)
|
|
173328
|
-
setNetwork(nextNetwork);
|
|
173583
|
+
await setNetwork(nextNetwork);
|
|
173329
173584
|
}
|
|
173330
173585
|
return { ...next, autolock: { ...next.autolock }, locked: nextNetwork !== previousNetwork };
|
|
173331
173586
|
}
|
|
@@ -173954,7 +174209,8 @@ function createRuntimeChatActions({ getRuntime, getSession, resolvePeer }) {
|
|
|
173954
174209
|
const updated = await target.runtime.chat.getSnapshot().updateMessage(target.chat.id, target.message.id, message, target.profile.chatPK);
|
|
173955
174210
|
return {
|
|
173956
174211
|
chat: simplifyAccountChat(target.chat, target.profile),
|
|
173957
|
-
message: simplifyAccountMessage(
|
|
174212
|
+
message: simplifyAccountMessage(message, target.chat, target.session.chatPK, options2),
|
|
174213
|
+
actionId: cleanText(updated?.msgId || updated?.cid) || null
|
|
173958
174214
|
};
|
|
173959
174215
|
}
|
|
173960
174216
|
async function deleteChat(peer, options2 = {}) {
|
|
@@ -174865,7 +175121,7 @@ var package_default;
|
|
|
174865
175121
|
var init_package = __esm(() => {
|
|
174866
175122
|
package_default = {
|
|
174867
175123
|
name: "veyl",
|
|
174868
|
-
version: "0.
|
|
175124
|
+
version: "0.35.0",
|
|
174869
175125
|
private: true,
|
|
174870
175126
|
license: "Apache-2.0",
|
|
174871
175127
|
workspaces: {
|
|
@@ -174881,16 +175137,16 @@ var init_package = __esm(() => {
|
|
|
174881
175137
|
"@noble/curves": "^2.2.0",
|
|
174882
175138
|
"@noble/hashes": "^2.2.0",
|
|
174883
175139
|
"@scure/bip39": "^2.2.0",
|
|
174884
|
-
"@tailwindcss/postcss": "^4.3.
|
|
175140
|
+
"@tailwindcss/postcss": "^4.3.3",
|
|
174885
175141
|
bech32: "^2.0.0",
|
|
174886
175142
|
firebase: "^12.16.0",
|
|
174887
175143
|
"lucide-react": "^1.24.0",
|
|
174888
175144
|
next: "16.3.0-preview.6",
|
|
174889
175145
|
"next-themes": "^0.4.6",
|
|
174890
|
-
postcss: "^8.5.
|
|
174891
|
-
react: "19.2.
|
|
174892
|
-
"react-dom": "19.2.
|
|
174893
|
-
tailwindcss: "^4.3.
|
|
175146
|
+
postcss: "^8.5.22",
|
|
175147
|
+
react: "19.2.8",
|
|
175148
|
+
"react-dom": "19.2.8",
|
|
175149
|
+
tailwindcss: "^4.3.3",
|
|
174894
175150
|
"tw-animate-css": "^1.4.0"
|
|
174895
175151
|
}
|
|
174896
175152
|
},
|
|
@@ -175165,9 +175421,17 @@ class VeylHeadlessClient {
|
|
|
175165
175421
|
resolvePeer: (peer, resolveOptions) => this.resolvePeer(peer, resolveOptions),
|
|
175166
175422
|
chat: this.runtimeChat,
|
|
175167
175423
|
lockVault: () => this.lockVault(),
|
|
175168
|
-
setNetwork: (network) => {
|
|
175169
|
-
|
|
175170
|
-
this.
|
|
175424
|
+
setNetwork: async (network) => {
|
|
175425
|
+
const nextNetwork = String(network || "").toUpperCase();
|
|
175426
|
+
this.network = nextNetwork;
|
|
175427
|
+
this.userOwner.setNetwork(nextNetwork);
|
|
175428
|
+
if (this.profileData) {
|
|
175429
|
+
await this.saveProfile({
|
|
175430
|
+
...this.profileData,
|
|
175431
|
+
network: nextNetwork,
|
|
175432
|
+
walletPK: null
|
|
175433
|
+
});
|
|
175434
|
+
}
|
|
175171
175435
|
},
|
|
175172
175436
|
runPasskeyBrowserFlow,
|
|
175173
175437
|
webUrl: options2.webUrl,
|
|
@@ -175280,7 +175544,7 @@ class VeylHeadlessClient {
|
|
|
175280
175544
|
username: profile.username,
|
|
175281
175545
|
profile: profile.profile,
|
|
175282
175546
|
credentialId: profile.credentialId,
|
|
175283
|
-
network: profile.network || this.network,
|
|
175547
|
+
network: this.session?.network || profile.network || this.network,
|
|
175284
175548
|
hasVault: profile.hasVault === true,
|
|
175285
175549
|
hasVaultSecret: !!profile.vaultSecret,
|
|
175286
175550
|
walletPK: profile.walletPK || null,
|
|
@@ -175641,10 +175905,9 @@ class VeylHeadlessClient {
|
|
|
175641
175905
|
vaultCrypto: headlessVaultCrypto,
|
|
175642
175906
|
bootWallet: (walletMnemonic, currentUser, { network }) => bootWallet(walletMnemonic, currentUser, {
|
|
175643
175907
|
SparkWallet: SparkWalletNodeJS,
|
|
175644
|
-
cloud: this.cloud,
|
|
175645
175908
|
network
|
|
175646
175909
|
}),
|
|
175647
|
-
bootChat: (chatSeed, currentUser) => bootChat(chatSeed, currentUser
|
|
175910
|
+
bootChat: (chatSeed, currentUser) => bootChat(chatSeed, currentUser),
|
|
175648
175911
|
openLocalCache: (cacheSeed, { uid, network }) => openHeadlessLocalDataCache(cacheSeed, {
|
|
175649
175912
|
homeDir: this.store.dir,
|
|
175650
175913
|
uid,
|
|
@@ -175655,6 +175918,7 @@ class VeylHeadlessClient {
|
|
|
175655
175918
|
this.userOwner.setNetwork(network);
|
|
175656
175919
|
}
|
|
175657
175920
|
});
|
|
175921
|
+
await opened.walletReady;
|
|
175658
175922
|
this.userSnapshot = this.userOwner.getSnapshot();
|
|
175659
175923
|
} catch (error) {
|
|
175660
175924
|
if (opened)
|
|
@@ -175689,6 +175953,7 @@ class VeylHeadlessClient {
|
|
|
175689
175953
|
...profile,
|
|
175690
175954
|
hasVault: true,
|
|
175691
175955
|
vaultSecret: options2.saveSecret === false ? null : vaultSecret,
|
|
175956
|
+
network: session.network,
|
|
175692
175957
|
walletPK: session.walletPK,
|
|
175693
175958
|
chatPK: session.chatPK,
|
|
175694
175959
|
vaultCreatedAt: Date.now()
|
|
@@ -175733,6 +175998,7 @@ class VeylHeadlessClient {
|
|
|
175733
175998
|
...profile,
|
|
175734
175999
|
hasVault: true,
|
|
175735
176000
|
vaultSecret: options2.saveSecret === false ? profile.vaultSecret || null : profile.vaultSecret || vaultSecret,
|
|
176001
|
+
network: session.network,
|
|
175736
176002
|
walletPK: session.walletPK,
|
|
175737
176003
|
chatPK: session.chatPK,
|
|
175738
176004
|
lastUnlockedAt: Date.now()
|