routstrd 0.4.10 → 0.4.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -14
- package/SECURITY.md +0 -1
- package/SKILL.md +242 -52
- package/dist/daemon/index.js +1855 -400
- package/dist/index.js +2441 -908
- package/package.json +3 -2
- package/src/daemon/http/index.ts +5 -11
- package/src/daemon/http/request-body.ts +67 -0
- package/src/daemon/wallet/coco-client.ts +20 -5
- package/src/daemon/wallet/trusted-mints.ts +87 -0
- package/src/integrations/pi.ts +137 -32
- package/src/integrations/registry.ts +14 -0
- package/src/tui/usage/render.ts +161 -22
- package/src/TUI refactor.md +0 -113
package/dist/daemon/index.js
CHANGED
|
@@ -34170,7 +34170,7 @@ var init_hpke_noble = __esm(() => {
|
|
|
34170
34170
|
priv2 = Symbol();
|
|
34171
34171
|
});
|
|
34172
34172
|
|
|
34173
|
-
// node_modules/ehbp/dist/esm/protocol.js
|
|
34173
|
+
// node_modules/tinfoil/node_modules/ehbp/dist/esm/protocol.js
|
|
34174
34174
|
var PROTOCOL, HPKE_CONFIG;
|
|
34175
34175
|
var init_protocol = __esm(() => {
|
|
34176
34176
|
PROTOCOL = {
|
|
@@ -34188,7 +34188,7 @@ var init_protocol = __esm(() => {
|
|
|
34188
34188
|
};
|
|
34189
34189
|
});
|
|
34190
34190
|
|
|
34191
|
-
// node_modules/ehbp/dist/esm/derive.js
|
|
34191
|
+
// node_modules/tinfoil/node_modules/ehbp/dist/esm/derive.js
|
|
34192
34192
|
async function deriveResponseKeys(exportedSecret, requestEnc, responseNonce) {
|
|
34193
34193
|
if (exportedSecret.length !== EXPORT_LENGTH) {
|
|
34194
34194
|
throw new Error(`exported secret must be ${EXPORT_LENGTH} bytes, got ${exportedSecret.length}`);
|
|
@@ -34224,11 +34224,6 @@ function computeNonce(nonceBase, seq) {
|
|
|
34224
34224
|
}
|
|
34225
34225
|
return nonce;
|
|
34226
34226
|
}
|
|
34227
|
-
async function encryptChunk(km, seq, plaintext) {
|
|
34228
|
-
const nonce = computeNonce(km.nonceBase, seq);
|
|
34229
|
-
const ciphertext = await aead.Seal(km.keyBytes, nonce, new Uint8Array(0), plaintext);
|
|
34230
|
-
return ciphertext;
|
|
34231
|
-
}
|
|
34232
34227
|
async function decryptChunk(km, seq, ciphertext) {
|
|
34233
34228
|
const nonce = computeNonce(km.nonceBase, seq);
|
|
34234
34229
|
const plaintext = await aead.Open(km.keyBytes, nonce, new Uint8Array(0), ciphertext);
|
|
@@ -34259,7 +34254,7 @@ var init_derive = __esm(() => {
|
|
|
34259
34254
|
RESPONSE_NONCE_LABEL = new TextEncoder().encode("nonce");
|
|
34260
34255
|
});
|
|
34261
34256
|
|
|
34262
|
-
// node_modules/ehbp/dist/esm/errors.js
|
|
34257
|
+
// node_modules/tinfoil/node_modules/ehbp/dist/esm/errors.js
|
|
34263
34258
|
var EhbpError, KeyConfigMismatchError, ProtocolError, DecryptionError;
|
|
34264
34259
|
var init_errors = __esm(() => {
|
|
34265
34260
|
EhbpError = class EhbpError extends Error {
|
|
@@ -34292,7 +34287,7 @@ var init_errors = __esm(() => {
|
|
|
34292
34287
|
};
|
|
34293
34288
|
});
|
|
34294
34289
|
|
|
34295
|
-
// node_modules/ehbp/dist/esm/request-options.js
|
|
34290
|
+
// node_modules/tinfoil/node_modules/ehbp/dist/esm/request-options.js
|
|
34296
34291
|
function forwardedRequestInit(source) {
|
|
34297
34292
|
const forwarded = {};
|
|
34298
34293
|
if (!source) {
|
|
@@ -34326,7 +34321,7 @@ var init_request_options = __esm(() => {
|
|
|
34326
34321
|
];
|
|
34327
34322
|
});
|
|
34328
34323
|
|
|
34329
|
-
// node_modules/ehbp/dist/esm/identity.js
|
|
34324
|
+
// node_modules/tinfoil/node_modules/ehbp/dist/esm/identity.js
|
|
34330
34325
|
function createSuite() {
|
|
34331
34326
|
return new CipherSuite(KEM_DHKEM_X25519_HKDF_SHA256, KDF_HKDF_SHA256, AEAD_AES_256_GCM);
|
|
34332
34327
|
}
|
|
@@ -34612,7 +34607,7 @@ var init_identity = __esm(() => {
|
|
|
34612
34607
|
MAX_RESPONSE_CHUNK_BYTES = 64 * 1024 * 1024;
|
|
34613
34608
|
});
|
|
34614
34609
|
|
|
34615
|
-
// node_modules/ehbp/dist/esm/client.js
|
|
34610
|
+
// node_modules/tinfoil/node_modules/ehbp/dist/esm/client.js
|
|
34616
34611
|
class Transport {
|
|
34617
34612
|
serverIdentity;
|
|
34618
34613
|
serverHost;
|
|
@@ -34763,9 +34758,6 @@ class Transport {
|
|
|
34763
34758
|
return this.request(url2, { ...init, method: "DELETE" });
|
|
34764
34759
|
}
|
|
34765
34760
|
}
|
|
34766
|
-
async function createTransport(serverURL, init) {
|
|
34767
|
-
return Transport.create(serverURL, init);
|
|
34768
|
-
}
|
|
34769
34761
|
var MAX_PROBLEM_DETAILS_BYTES;
|
|
34770
34762
|
var init_client3 = __esm(() => {
|
|
34771
34763
|
init_identity();
|
|
@@ -34776,35 +34768,7 @@ var init_client3 = __esm(() => {
|
|
|
34776
34768
|
MAX_PROBLEM_DETAILS_BYTES = 64 * 1024;
|
|
34777
34769
|
});
|
|
34778
34770
|
|
|
34779
|
-
// node_modules/ehbp/dist/esm/index.js
|
|
34780
|
-
var exports_esm = {};
|
|
34781
|
-
__export(exports_esm, {
|
|
34782
|
-
serializeSessionRecoveryToken: () => serializeSessionRecoveryToken,
|
|
34783
|
-
hexToBytes: () => hexToBytes8,
|
|
34784
|
-
extractSessionRecoveryToken: () => extractSessionRecoveryToken,
|
|
34785
|
-
encryptChunk: () => encryptChunk,
|
|
34786
|
-
deserializeSessionRecoveryToken: () => deserializeSessionRecoveryToken,
|
|
34787
|
-
deriveResponseKeys: () => deriveResponseKeys,
|
|
34788
|
-
decryptResponseWithToken: () => decryptResponseWithToken,
|
|
34789
|
-
decryptChunk: () => decryptChunk,
|
|
34790
|
-
createTransport: () => createTransport,
|
|
34791
|
-
computeNonce: () => computeNonce,
|
|
34792
|
-
bytesToHex: () => bytesToHex8,
|
|
34793
|
-
Transport: () => Transport,
|
|
34794
|
-
RESPONSE_NONCE_LENGTH: () => RESPONSE_NONCE_LENGTH,
|
|
34795
|
-
ProtocolError: () => ProtocolError,
|
|
34796
|
-
PROTOCOL: () => PROTOCOL,
|
|
34797
|
-
KeyConfigMismatchError: () => KeyConfigMismatchError,
|
|
34798
|
-
Identity: () => Identity,
|
|
34799
|
-
HPKE_REQUEST_INFO: () => HPKE_REQUEST_INFO,
|
|
34800
|
-
HPKE_CONFIG: () => HPKE_CONFIG,
|
|
34801
|
-
EhbpError: () => EhbpError,
|
|
34802
|
-
EXPORT_LENGTH: () => EXPORT_LENGTH,
|
|
34803
|
-
EXPORT_LABEL: () => EXPORT_LABEL,
|
|
34804
|
-
DecryptionError: () => DecryptionError,
|
|
34805
|
-
AES_GCM_NONCE_LENGTH: () => AES_GCM_NONCE_LENGTH,
|
|
34806
|
-
AES256_KEY_LENGTH: () => AES256_KEY_LENGTH
|
|
34807
|
-
});
|
|
34771
|
+
// node_modules/tinfoil/node_modules/ehbp/dist/esm/index.js
|
|
34808
34772
|
var init_esm3 = __esm(() => {
|
|
34809
34773
|
init_identity();
|
|
34810
34774
|
init_identity();
|
|
@@ -64619,6 +64583,650 @@ var init_dist10 = __esm(() => {
|
|
|
64619
64583
|
init_openai();
|
|
64620
64584
|
});
|
|
64621
64585
|
|
|
64586
|
+
// node_modules/ehbp/dist/esm/protocol.js
|
|
64587
|
+
var PROTOCOL2, HPKE_CONFIG2;
|
|
64588
|
+
var init_protocol2 = __esm(() => {
|
|
64589
|
+
PROTOCOL2 = {
|
|
64590
|
+
ENCAPSULATED_KEY_HEADER: "Ehbp-Encapsulated-Key",
|
|
64591
|
+
RESPONSE_NONCE_HEADER: "Ehbp-Response-Nonce",
|
|
64592
|
+
KEYS_MEDIA_TYPE: "application/ohttp-keys",
|
|
64593
|
+
KEYS_PATH: "/.well-known/hpke-keys",
|
|
64594
|
+
PROBLEM_JSON_MEDIA_TYPE: "application/problem+json",
|
|
64595
|
+
KEY_CONFIG_PROBLEM_TYPE: "urn:ietf:params:ehbp:error:key-config"
|
|
64596
|
+
};
|
|
64597
|
+
HPKE_CONFIG2 = {
|
|
64598
|
+
KEM: 32,
|
|
64599
|
+
KDF: 1,
|
|
64600
|
+
AEAD: 2
|
|
64601
|
+
};
|
|
64602
|
+
});
|
|
64603
|
+
|
|
64604
|
+
// node_modules/ehbp/dist/esm/derive.js
|
|
64605
|
+
async function deriveResponseKeys2(exportedSecret, requestEnc, responseNonce) {
|
|
64606
|
+
if (exportedSecret.length !== EXPORT_LENGTH2) {
|
|
64607
|
+
throw new Error(`exported secret must be ${EXPORT_LENGTH2} bytes, got ${exportedSecret.length}`);
|
|
64608
|
+
}
|
|
64609
|
+
if (requestEnc.length !== REQUEST_ENC_LENGTH2) {
|
|
64610
|
+
throw new Error(`request enc must be ${REQUEST_ENC_LENGTH2} bytes, got ${requestEnc.length}`);
|
|
64611
|
+
}
|
|
64612
|
+
if (responseNonce.length !== RESPONSE_NONCE_LENGTH2) {
|
|
64613
|
+
throw new Error(`response nonce must be ${RESPONSE_NONCE_LENGTH2} bytes, got ${responseNonce.length}`);
|
|
64614
|
+
}
|
|
64615
|
+
const salt = new Uint8Array(requestEnc.length + responseNonce.length);
|
|
64616
|
+
salt.set(requestEnc, 0);
|
|
64617
|
+
salt.set(responseNonce, requestEnc.length);
|
|
64618
|
+
const prk = await kdf2.Extract(salt, exportedSecret);
|
|
64619
|
+
const keyBytes = await kdf2.Expand(prk, RESPONSE_KEY_LABEL2, AES256_KEY_LENGTH2);
|
|
64620
|
+
const nonceBase = await kdf2.Expand(prk, RESPONSE_NONCE_LABEL2, AES_GCM_NONCE_LENGTH2);
|
|
64621
|
+
return { keyBytes, nonceBase };
|
|
64622
|
+
}
|
|
64623
|
+
function computeNonce2(nonceBase, seq) {
|
|
64624
|
+
if (nonceBase.length !== AES_GCM_NONCE_LENGTH2) {
|
|
64625
|
+
throw new Error(`nonce base must be ${AES_GCM_NONCE_LENGTH2} bytes`);
|
|
64626
|
+
}
|
|
64627
|
+
if (!Number.isInteger(seq) || seq < 0 || seq >= 4294967296) {
|
|
64628
|
+
throw new Error(`sequence number must be an integer in range [0, 2^32): got ${seq}`);
|
|
64629
|
+
}
|
|
64630
|
+
const nonce = new Uint8Array(AES_GCM_NONCE_LENGTH2);
|
|
64631
|
+
nonce.set(nonceBase);
|
|
64632
|
+
for (let i4 = 0;i4 < 8; i4++) {
|
|
64633
|
+
const shift = i4 * 8;
|
|
64634
|
+
if (shift < 32) {
|
|
64635
|
+
nonce[AES_GCM_NONCE_LENGTH2 - 1 - i4] ^= seq >>> shift & 255;
|
|
64636
|
+
}
|
|
64637
|
+
}
|
|
64638
|
+
return nonce;
|
|
64639
|
+
}
|
|
64640
|
+
async function encryptChunk2(km, seq, plaintext) {
|
|
64641
|
+
const nonce = computeNonce2(km.nonceBase, seq);
|
|
64642
|
+
const ciphertext = await aead2.Seal(km.keyBytes, nonce, new Uint8Array(0), plaintext);
|
|
64643
|
+
return ciphertext;
|
|
64644
|
+
}
|
|
64645
|
+
async function decryptChunk2(km, seq, ciphertext) {
|
|
64646
|
+
const nonce = computeNonce2(km.nonceBase, seq);
|
|
64647
|
+
const plaintext = await aead2.Open(km.keyBytes, nonce, new Uint8Array(0), ciphertext);
|
|
64648
|
+
return plaintext;
|
|
64649
|
+
}
|
|
64650
|
+
function hexToBytes10(hex6) {
|
|
64651
|
+
if (hex6.length % 2 !== 0) {
|
|
64652
|
+
throw new Error("Hex string must have even length");
|
|
64653
|
+
}
|
|
64654
|
+
if (!/^[0-9a-fA-F]*$/.test(hex6)) {
|
|
64655
|
+
throw new Error("Invalid hex character");
|
|
64656
|
+
}
|
|
64657
|
+
const bytes6 = new Uint8Array(hex6.length / 2);
|
|
64658
|
+
for (let i4 = 0;i4 < bytes6.length; i4++) {
|
|
64659
|
+
bytes6[i4] = parseInt(hex6.substring(i4 * 2, i4 * 2 + 2), 16);
|
|
64660
|
+
}
|
|
64661
|
+
return bytes6;
|
|
64662
|
+
}
|
|
64663
|
+
function bytesToHex12(bytes6) {
|
|
64664
|
+
return Array.from(bytes6).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
64665
|
+
}
|
|
64666
|
+
var kdf2, aead2, HPKE_REQUEST_INFO2 = "ehbp request", EXPORT_LABEL2 = "ehbp response", EXPORT_LENGTH2 = 32, RESPONSE_NONCE_LENGTH2 = 32, AES256_KEY_LENGTH2 = 32, AES_GCM_NONCE_LENGTH2 = 12, REQUEST_ENC_LENGTH2 = 32, RESPONSE_KEY_LABEL2, RESPONSE_NONCE_LABEL2;
|
|
64667
|
+
var init_derive2 = __esm(() => {
|
|
64668
|
+
init_hpke_noble();
|
|
64669
|
+
kdf2 = KDF_HKDF_SHA256();
|
|
64670
|
+
aead2 = AEAD_AES_256_GCM();
|
|
64671
|
+
RESPONSE_KEY_LABEL2 = new TextEncoder().encode("key");
|
|
64672
|
+
RESPONSE_NONCE_LABEL2 = new TextEncoder().encode("nonce");
|
|
64673
|
+
});
|
|
64674
|
+
|
|
64675
|
+
// node_modules/ehbp/dist/esm/errors.js
|
|
64676
|
+
var EhbpError2, KeyConfigMismatchError2, ProtocolError2, DecryptionError2;
|
|
64677
|
+
var init_errors6 = __esm(() => {
|
|
64678
|
+
EhbpError2 = class EhbpError2 extends Error {
|
|
64679
|
+
constructor(message, options) {
|
|
64680
|
+
super(message);
|
|
64681
|
+
this.name = "EhbpError";
|
|
64682
|
+
if (options?.cause)
|
|
64683
|
+
this.cause = options.cause;
|
|
64684
|
+
}
|
|
64685
|
+
};
|
|
64686
|
+
KeyConfigMismatchError2 = class KeyConfigMismatchError2 extends EhbpError2 {
|
|
64687
|
+
title;
|
|
64688
|
+
constructor(title) {
|
|
64689
|
+
super(title || "Server key configuration mismatch");
|
|
64690
|
+
this.name = "KeyConfigMismatchError";
|
|
64691
|
+
this.title = title || "";
|
|
64692
|
+
}
|
|
64693
|
+
};
|
|
64694
|
+
ProtocolError2 = class ProtocolError2 extends EhbpError2 {
|
|
64695
|
+
constructor(message, options) {
|
|
64696
|
+
super(message, options);
|
|
64697
|
+
this.name = "ProtocolError";
|
|
64698
|
+
}
|
|
64699
|
+
};
|
|
64700
|
+
DecryptionError2 = class DecryptionError2 extends EhbpError2 {
|
|
64701
|
+
constructor(message, options) {
|
|
64702
|
+
super(message, options);
|
|
64703
|
+
this.name = "DecryptionError";
|
|
64704
|
+
}
|
|
64705
|
+
};
|
|
64706
|
+
});
|
|
64707
|
+
|
|
64708
|
+
// node_modules/ehbp/dist/esm/request-options.js
|
|
64709
|
+
function forwardedRequestInit2(source) {
|
|
64710
|
+
const forwarded = {};
|
|
64711
|
+
if (!source) {
|
|
64712
|
+
return forwarded;
|
|
64713
|
+
}
|
|
64714
|
+
const record2 = source;
|
|
64715
|
+
const target = forwarded;
|
|
64716
|
+
for (const key of FORWARDED_INIT_KEYS2) {
|
|
64717
|
+
const value = record2[key];
|
|
64718
|
+
if (value !== undefined) {
|
|
64719
|
+
target[key] = value;
|
|
64720
|
+
}
|
|
64721
|
+
}
|
|
64722
|
+
if (forwarded.mode === "navigate") {
|
|
64723
|
+
delete forwarded.mode;
|
|
64724
|
+
}
|
|
64725
|
+
return forwarded;
|
|
64726
|
+
}
|
|
64727
|
+
var FORWARDED_INIT_KEYS2;
|
|
64728
|
+
var init_request_options2 = __esm(() => {
|
|
64729
|
+
FORWARDED_INIT_KEYS2 = [
|
|
64730
|
+
"cache",
|
|
64731
|
+
"credentials",
|
|
64732
|
+
"integrity",
|
|
64733
|
+
"keepalive",
|
|
64734
|
+
"mode",
|
|
64735
|
+
"redirect",
|
|
64736
|
+
"referrer",
|
|
64737
|
+
"referrerPolicy",
|
|
64738
|
+
"signal"
|
|
64739
|
+
];
|
|
64740
|
+
});
|
|
64741
|
+
|
|
64742
|
+
// node_modules/ehbp/dist/esm/identity.js
|
|
64743
|
+
function createSuite2() {
|
|
64744
|
+
return new CipherSuite(KEM_DHKEM_X25519_HKDF_SHA256, KDF_HKDF_SHA256, AEAD_AES_256_GCM);
|
|
64745
|
+
}
|
|
64746
|
+
|
|
64747
|
+
class Identity3 {
|
|
64748
|
+
suite;
|
|
64749
|
+
publicKey;
|
|
64750
|
+
privateKey;
|
|
64751
|
+
constructor(suite, publicKey, privateKey) {
|
|
64752
|
+
this.suite = suite;
|
|
64753
|
+
this.publicKey = publicKey;
|
|
64754
|
+
this.privateKey = privateKey;
|
|
64755
|
+
}
|
|
64756
|
+
static async generate() {
|
|
64757
|
+
const suite = createSuite2();
|
|
64758
|
+
const { publicKey, privateKey } = await suite.GenerateKeyPair(true);
|
|
64759
|
+
return new Identity3(suite, publicKey, privateKey);
|
|
64760
|
+
}
|
|
64761
|
+
static async fromJSON(json3) {
|
|
64762
|
+
const data = JSON.parse(json3);
|
|
64763
|
+
const suite = createSuite2();
|
|
64764
|
+
const publicKey = await suite.DeserializePublicKey(new Uint8Array(data.publicKey));
|
|
64765
|
+
const privateKey = await suite.DeserializePrivateKey(new Uint8Array(data.privateKey), true);
|
|
64766
|
+
return new Identity3(suite, publicKey, privateKey);
|
|
64767
|
+
}
|
|
64768
|
+
async toJSON() {
|
|
64769
|
+
const publicKeyBytes = await this.suite.SerializePublicKey(this.publicKey);
|
|
64770
|
+
const privateKeyBytes = await this.suite.SerializePrivateKey(this.privateKey);
|
|
64771
|
+
return JSON.stringify({
|
|
64772
|
+
publicKey: Array.from(publicKeyBytes),
|
|
64773
|
+
privateKey: Array.from(privateKeyBytes)
|
|
64774
|
+
});
|
|
64775
|
+
}
|
|
64776
|
+
getPublicKey() {
|
|
64777
|
+
return this.publicKey;
|
|
64778
|
+
}
|
|
64779
|
+
async getPublicKeyHex() {
|
|
64780
|
+
const exported = await this.suite.SerializePublicKey(this.publicKey);
|
|
64781
|
+
return bytesToHex12(exported);
|
|
64782
|
+
}
|
|
64783
|
+
getPrivateKey() {
|
|
64784
|
+
return this.privateKey;
|
|
64785
|
+
}
|
|
64786
|
+
async marshalConfig() {
|
|
64787
|
+
const kemId = HPKE_CONFIG2.KEM;
|
|
64788
|
+
const kdfId = HPKE_CONFIG2.KDF;
|
|
64789
|
+
const aeadId = HPKE_CONFIG2.AEAD;
|
|
64790
|
+
const publicKeyBytes = await this.suite.SerializePublicKey(this.publicKey);
|
|
64791
|
+
const keyId = 0;
|
|
64792
|
+
const publicKeySize = publicKeyBytes.length;
|
|
64793
|
+
const cipherSuitesSize = 2 + 2;
|
|
64794
|
+
const buffer = new Uint8Array(1 + 2 + publicKeySize + 2 + cipherSuitesSize);
|
|
64795
|
+
let offset = 0;
|
|
64796
|
+
buffer[offset++] = keyId;
|
|
64797
|
+
buffer[offset++] = kemId >> 8 & 255;
|
|
64798
|
+
buffer[offset++] = kemId & 255;
|
|
64799
|
+
buffer.set(publicKeyBytes, offset);
|
|
64800
|
+
offset += publicKeySize;
|
|
64801
|
+
buffer[offset++] = cipherSuitesSize >> 8 & 255;
|
|
64802
|
+
buffer[offset++] = cipherSuitesSize & 255;
|
|
64803
|
+
buffer[offset++] = kdfId >> 8 & 255;
|
|
64804
|
+
buffer[offset++] = kdfId & 255;
|
|
64805
|
+
buffer[offset++] = aeadId >> 8 & 255;
|
|
64806
|
+
buffer[offset++] = aeadId & 255;
|
|
64807
|
+
return buffer;
|
|
64808
|
+
}
|
|
64809
|
+
static async unmarshalPublicConfig(data) {
|
|
64810
|
+
let offset = 0;
|
|
64811
|
+
const keyId = data[offset++];
|
|
64812
|
+
const kemId = data[offset++] << 8 | data[offset++];
|
|
64813
|
+
const publicKeySize = 32;
|
|
64814
|
+
const publicKeyBytes = data.slice(offset, offset + publicKeySize);
|
|
64815
|
+
offset += publicKeySize;
|
|
64816
|
+
const cipherSuitesLength = data[offset++] << 8 | data[offset++];
|
|
64817
|
+
const suites = [];
|
|
64818
|
+
const cipherSuitesEnd = offset + cipherSuitesLength;
|
|
64819
|
+
while (offset < cipherSuitesEnd) {
|
|
64820
|
+
const kdfId = data[offset++] << 8 | data[offset++];
|
|
64821
|
+
const aeadId = data[offset++] << 8 | data[offset++];
|
|
64822
|
+
suites.push({ kdfId, aeadId });
|
|
64823
|
+
}
|
|
64824
|
+
if (suites.length === 0) {
|
|
64825
|
+
throw new ProtocolError2("No cipher suites found in config");
|
|
64826
|
+
}
|
|
64827
|
+
const firstSuite = suites[0];
|
|
64828
|
+
if (firstSuite.kdfId !== HPKE_CONFIG2.KDF || firstSuite.aeadId !== HPKE_CONFIG2.AEAD) {
|
|
64829
|
+
throw new ProtocolError2(`Unsupported cipher suite: KDF=0x${firstSuite.kdfId.toString(16)}, AEAD=0x${firstSuite.aeadId.toString(16)}`);
|
|
64830
|
+
}
|
|
64831
|
+
return Identity3.fromPublicKeyBytes(publicKeyBytes);
|
|
64832
|
+
}
|
|
64833
|
+
static async fromPublicKeyHex(publicKeyHex) {
|
|
64834
|
+
const publicKeyBytes = hexToBytes10(publicKeyHex);
|
|
64835
|
+
if (publicKeyBytes.length !== 32) {
|
|
64836
|
+
throw new ProtocolError2(`Invalid public key length: expected 32, got ${publicKeyBytes.length}`);
|
|
64837
|
+
}
|
|
64838
|
+
return Identity3.fromPublicKeyBytes(publicKeyBytes);
|
|
64839
|
+
}
|
|
64840
|
+
static async fromPublicKeyBytes(publicKeyBytes) {
|
|
64841
|
+
const suite = createSuite2();
|
|
64842
|
+
const publicKey = await suite.DeserializePublicKey(publicKeyBytes);
|
|
64843
|
+
const placeholderPrivateKey = await suite.DeserializePrivateKey(new Uint8Array(32), false);
|
|
64844
|
+
return new Identity3(suite, publicKey, placeholderPrivateKey);
|
|
64845
|
+
}
|
|
64846
|
+
async encryptRequestWithContext(request) {
|
|
64847
|
+
const body = await request.arrayBuffer();
|
|
64848
|
+
if (body.byteLength === 0) {
|
|
64849
|
+
return {
|
|
64850
|
+
request: new Request(request.url, {
|
|
64851
|
+
...forwardedRequestInit2(request),
|
|
64852
|
+
method: request.method,
|
|
64853
|
+
headers: request.headers,
|
|
64854
|
+
body: null
|
|
64855
|
+
}),
|
|
64856
|
+
context: null
|
|
64857
|
+
};
|
|
64858
|
+
}
|
|
64859
|
+
const infoBytes = new TextEncoder().encode(HPKE_REQUEST_INFO2);
|
|
64860
|
+
const { encapsulatedSecret, ctx } = await this.suite.SetupSender(this.publicKey, {
|
|
64861
|
+
info: infoBytes
|
|
64862
|
+
});
|
|
64863
|
+
const context = {
|
|
64864
|
+
senderContext: ctx,
|
|
64865
|
+
requestEnc: encapsulatedSecret
|
|
64866
|
+
};
|
|
64867
|
+
const headers = new Headers(request.headers);
|
|
64868
|
+
headers.set(PROTOCOL2.ENCAPSULATED_KEY_HEADER, bytesToHex12(context.requestEnc));
|
|
64869
|
+
const encrypted = await ctx.Seal(new Uint8Array(body));
|
|
64870
|
+
const chunkLength = new Uint8Array(4);
|
|
64871
|
+
new DataView(chunkLength.buffer).setUint32(0, encrypted.byteLength, false);
|
|
64872
|
+
const chunkedData = new Uint8Array(4 + encrypted.byteLength);
|
|
64873
|
+
chunkedData.set(chunkLength, 0);
|
|
64874
|
+
chunkedData.set(encrypted, 4);
|
|
64875
|
+
return {
|
|
64876
|
+
request: new Request(request.url, {
|
|
64877
|
+
...forwardedRequestInit2(request),
|
|
64878
|
+
method: request.method,
|
|
64879
|
+
headers,
|
|
64880
|
+
body: chunkedData,
|
|
64881
|
+
duplex: "half"
|
|
64882
|
+
}),
|
|
64883
|
+
context
|
|
64884
|
+
};
|
|
64885
|
+
}
|
|
64886
|
+
async decryptResponseWithContext(response, context) {
|
|
64887
|
+
const token = await extractSessionRecoveryToken2(context);
|
|
64888
|
+
return decryptResponseWithToken2(response, token);
|
|
64889
|
+
}
|
|
64890
|
+
}
|
|
64891
|
+
async function extractSessionRecoveryToken2(context) {
|
|
64892
|
+
const exportLabelBytes = new TextEncoder().encode(EXPORT_LABEL2);
|
|
64893
|
+
const exportedSecret = new Uint8Array(await context.senderContext.Export(exportLabelBytes, EXPORT_LENGTH2));
|
|
64894
|
+
return {
|
|
64895
|
+
exportedSecret,
|
|
64896
|
+
requestEnc: new Uint8Array(context.requestEnc)
|
|
64897
|
+
};
|
|
64898
|
+
}
|
|
64899
|
+
function serializeSessionRecoveryToken2(token) {
|
|
64900
|
+
return JSON.stringify({
|
|
64901
|
+
exportedSecret: bytesToHex12(token.exportedSecret),
|
|
64902
|
+
requestEnc: bytesToHex12(token.requestEnc)
|
|
64903
|
+
});
|
|
64904
|
+
}
|
|
64905
|
+
function deserializeSessionRecoveryToken2(json3) {
|
|
64906
|
+
const parsed = JSON.parse(json3);
|
|
64907
|
+
return {
|
|
64908
|
+
exportedSecret: hexToBytes10(parsed.exportedSecret),
|
|
64909
|
+
requestEnc: hexToBytes10(parsed.requestEnc)
|
|
64910
|
+
};
|
|
64911
|
+
}
|
|
64912
|
+
async function decryptResponseWithToken2(response, token, onStreamError, onStreamComplete) {
|
|
64913
|
+
const responseNonceHex = response.headers.get(PROTOCOL2.RESPONSE_NONCE_HEADER);
|
|
64914
|
+
if (!response.body && !responseNonceHex) {
|
|
64915
|
+
return response;
|
|
64916
|
+
}
|
|
64917
|
+
if (!responseNonceHex) {
|
|
64918
|
+
throw new ProtocolError2(`Missing ${PROTOCOL2.RESPONSE_NONCE_HEADER} header`);
|
|
64919
|
+
}
|
|
64920
|
+
const responseNonce = hexToBytes10(responseNonceHex);
|
|
64921
|
+
if (responseNonce.length !== RESPONSE_NONCE_LENGTH2) {
|
|
64922
|
+
throw new ProtocolError2(`Invalid response nonce length`);
|
|
64923
|
+
}
|
|
64924
|
+
if (!response.body) {
|
|
64925
|
+
onStreamComplete?.();
|
|
64926
|
+
return response;
|
|
64927
|
+
}
|
|
64928
|
+
const km = await deriveResponseKeys2(token.exportedSecret, token.requestEnc, responseNonce);
|
|
64929
|
+
const decryptedStream = createDecryptStream2(response.body, km, onStreamError, onStreamComplete);
|
|
64930
|
+
const headers = new Headers(response.headers);
|
|
64931
|
+
headers.delete("content-length");
|
|
64932
|
+
headers.delete("transfer-encoding");
|
|
64933
|
+
return new Response(decryptedStream, {
|
|
64934
|
+
status: response.status,
|
|
64935
|
+
statusText: response.statusText,
|
|
64936
|
+
headers
|
|
64937
|
+
});
|
|
64938
|
+
}
|
|
64939
|
+
function createDecryptStream2(body, km, onStreamError, onStreamComplete) {
|
|
64940
|
+
let buffer = new Uint8Array(0);
|
|
64941
|
+
let seq = 0;
|
|
64942
|
+
const reader = body.getReader();
|
|
64943
|
+
let consumerCancelled = false;
|
|
64944
|
+
return new ReadableStream({
|
|
64945
|
+
async pull(controller) {
|
|
64946
|
+
const fail = (error53) => {
|
|
64947
|
+
try {
|
|
64948
|
+
onStreamError?.();
|
|
64949
|
+
} catch {}
|
|
64950
|
+
try {
|
|
64951
|
+
controller.error(error53);
|
|
64952
|
+
} finally {
|
|
64953
|
+
reader.cancel(error53).catch(() => {});
|
|
64954
|
+
}
|
|
64955
|
+
};
|
|
64956
|
+
while (true) {
|
|
64957
|
+
if (buffer.length >= 4) {
|
|
64958
|
+
const chunkLength = (buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3]) >>> 0;
|
|
64959
|
+
if (chunkLength === 0) {
|
|
64960
|
+
buffer = buffer.slice(4);
|
|
64961
|
+
continue;
|
|
64962
|
+
}
|
|
64963
|
+
if (chunkLength > MAX_RESPONSE_CHUNK_BYTES2) {
|
|
64964
|
+
fail(new ProtocolError2("response chunk exceeds maximum allowed size"));
|
|
64965
|
+
return;
|
|
64966
|
+
}
|
|
64967
|
+
if (buffer.length >= 4 + chunkLength) {
|
|
64968
|
+
const ciphertext = buffer.slice(4, 4 + chunkLength);
|
|
64969
|
+
buffer = buffer.slice(4 + chunkLength);
|
|
64970
|
+
try {
|
|
64971
|
+
const plaintext = await decryptChunk2(km, seq++, ciphertext);
|
|
64972
|
+
controller.enqueue(plaintext);
|
|
64973
|
+
return;
|
|
64974
|
+
} catch (error53) {
|
|
64975
|
+
fail(new DecryptionError2(`Decryption failed at chunk ${seq - 1}`, { cause: error53 }));
|
|
64976
|
+
return;
|
|
64977
|
+
}
|
|
64978
|
+
}
|
|
64979
|
+
}
|
|
64980
|
+
let result;
|
|
64981
|
+
try {
|
|
64982
|
+
result = await reader.read();
|
|
64983
|
+
} catch (error53) {
|
|
64984
|
+
if (consumerCancelled) {
|
|
64985
|
+
return;
|
|
64986
|
+
}
|
|
64987
|
+
fail(error53 instanceof Error ? error53 : new Error("Encrypted response read failed", {
|
|
64988
|
+
cause: error53
|
|
64989
|
+
}));
|
|
64990
|
+
return;
|
|
64991
|
+
}
|
|
64992
|
+
const { done, value } = result;
|
|
64993
|
+
if (done) {
|
|
64994
|
+
if (consumerCancelled) {
|
|
64995
|
+
return;
|
|
64996
|
+
}
|
|
64997
|
+
if (buffer.length !== 0) {
|
|
64998
|
+
fail(new ProtocolError2("truncated encrypted response chunk"));
|
|
64999
|
+
} else {
|
|
65000
|
+
onStreamComplete?.();
|
|
65001
|
+
controller.close();
|
|
65002
|
+
}
|
|
65003
|
+
return;
|
|
65004
|
+
}
|
|
65005
|
+
const newBuffer = new Uint8Array(buffer.length + value.length);
|
|
65006
|
+
newBuffer.set(buffer);
|
|
65007
|
+
newBuffer.set(value, buffer.length);
|
|
65008
|
+
buffer = newBuffer;
|
|
65009
|
+
}
|
|
65010
|
+
},
|
|
65011
|
+
cancel(reason) {
|
|
65012
|
+
consumerCancelled = true;
|
|
65013
|
+
return reader.cancel(reason);
|
|
65014
|
+
}
|
|
65015
|
+
});
|
|
65016
|
+
}
|
|
65017
|
+
var MAX_RESPONSE_CHUNK_BYTES2;
|
|
65018
|
+
var init_identity2 = __esm(() => {
|
|
65019
|
+
init_hpke();
|
|
65020
|
+
init_hpke_noble();
|
|
65021
|
+
init_protocol2();
|
|
65022
|
+
init_derive2();
|
|
65023
|
+
init_errors6();
|
|
65024
|
+
init_request_options2();
|
|
65025
|
+
MAX_RESPONSE_CHUNK_BYTES2 = 64 * 1024 * 1024;
|
|
65026
|
+
});
|
|
65027
|
+
|
|
65028
|
+
// node_modules/ehbp/dist/esm/client.js
|
|
65029
|
+
class Transport2 {
|
|
65030
|
+
serverIdentity;
|
|
65031
|
+
serverHost;
|
|
65032
|
+
_lastSessionRecoveryToken;
|
|
65033
|
+
requestGeneration = 0;
|
|
65034
|
+
constructor(serverIdentity, serverHost) {
|
|
65035
|
+
this.serverIdentity = serverIdentity;
|
|
65036
|
+
this.serverHost = serverHost;
|
|
65037
|
+
}
|
|
65038
|
+
getSessionRecoveryToken() {
|
|
65039
|
+
if (!this._lastSessionRecoveryToken) {
|
|
65040
|
+
throw new Error("No session recovery token available \u2014 no request has been made yet");
|
|
65041
|
+
}
|
|
65042
|
+
return this._lastSessionRecoveryToken;
|
|
65043
|
+
}
|
|
65044
|
+
static async create(serverURL, init) {
|
|
65045
|
+
const url3 = new URL(serverURL);
|
|
65046
|
+
const serverHost = url3.host;
|
|
65047
|
+
const keysURL = new URL(PROTOCOL2.KEYS_PATH, serverURL);
|
|
65048
|
+
const response = await fetch(keysURL.toString(), init);
|
|
65049
|
+
if (!response.ok) {
|
|
65050
|
+
throw new Error(`Failed to get server public key: ${response.status}`);
|
|
65051
|
+
}
|
|
65052
|
+
const contentType = response.headers.get("content-type");
|
|
65053
|
+
if (contentType !== PROTOCOL2.KEYS_MEDIA_TYPE) {
|
|
65054
|
+
throw new Error(`Invalid content type: ${contentType}`);
|
|
65055
|
+
}
|
|
65056
|
+
const keysData = new Uint8Array(await response.arrayBuffer());
|
|
65057
|
+
const serverIdentity = await Identity3.unmarshalPublicConfig(keysData);
|
|
65058
|
+
return new Transport2(serverIdentity, serverHost);
|
|
65059
|
+
}
|
|
65060
|
+
static isProblemJSONContentType(contentType) {
|
|
65061
|
+
if (!contentType) {
|
|
65062
|
+
return false;
|
|
65063
|
+
}
|
|
65064
|
+
const mediaType = contentType.split(";", 1)[0]?.trim().toLowerCase() ?? "";
|
|
65065
|
+
return mediaType === PROTOCOL2.PROBLEM_JSON_MEDIA_TYPE;
|
|
65066
|
+
}
|
|
65067
|
+
static async checkKeyConfigMismatch(response) {
|
|
65068
|
+
if (response.status !== 422)
|
|
65069
|
+
return;
|
|
65070
|
+
if (!Transport2.isProblemJSONContentType(response.headers.get("content-type")))
|
|
65071
|
+
return;
|
|
65072
|
+
let problem;
|
|
65073
|
+
try {
|
|
65074
|
+
const clone2 = response.clone();
|
|
65075
|
+
if (!clone2.body)
|
|
65076
|
+
return;
|
|
65077
|
+
const reader = clone2.body.getReader();
|
|
65078
|
+
const chunks = [];
|
|
65079
|
+
let length2 = 0;
|
|
65080
|
+
while (true) {
|
|
65081
|
+
const { done, value } = await reader.read();
|
|
65082
|
+
if (done)
|
|
65083
|
+
break;
|
|
65084
|
+
length2 += value.byteLength;
|
|
65085
|
+
if (length2 > MAX_PROBLEM_DETAILS_BYTES2) {
|
|
65086
|
+
reader.cancel().catch(() => {});
|
|
65087
|
+
return;
|
|
65088
|
+
}
|
|
65089
|
+
chunks.push(value);
|
|
65090
|
+
}
|
|
65091
|
+
const body = new Uint8Array(length2);
|
|
65092
|
+
let offset = 0;
|
|
65093
|
+
for (const chunk of chunks) {
|
|
65094
|
+
body.set(chunk, offset);
|
|
65095
|
+
offset += chunk.byteLength;
|
|
65096
|
+
}
|
|
65097
|
+
problem = JSON.parse(new TextDecoder().decode(body));
|
|
65098
|
+
} catch {
|
|
65099
|
+
return;
|
|
65100
|
+
}
|
|
65101
|
+
if (problem?.type === PROTOCOL2.KEY_CONFIG_PROBLEM_TYPE) {
|
|
65102
|
+
throw new KeyConfigMismatchError2(typeof problem.title === "string" ? problem.title : undefined);
|
|
65103
|
+
}
|
|
65104
|
+
}
|
|
65105
|
+
static async shouldDecryptResponse(response) {
|
|
65106
|
+
if (response.headers.has(PROTOCOL2.RESPONSE_NONCE_HEADER)) {
|
|
65107
|
+
return true;
|
|
65108
|
+
}
|
|
65109
|
+
await Transport2.checkKeyConfigMismatch(response);
|
|
65110
|
+
if (!response.ok) {
|
|
65111
|
+
return false;
|
|
65112
|
+
}
|
|
65113
|
+
throw new ProtocolError2(`Missing ${PROTOCOL2.RESPONSE_NONCE_HEADER} header`);
|
|
65114
|
+
}
|
|
65115
|
+
getServerIdentity() {
|
|
65116
|
+
return this.serverIdentity;
|
|
65117
|
+
}
|
|
65118
|
+
getServerPublicKey() {
|
|
65119
|
+
return this.serverIdentity.getPublicKey();
|
|
65120
|
+
}
|
|
65121
|
+
async getServerPublicKeyHex() {
|
|
65122
|
+
return this.serverIdentity.getPublicKeyHex();
|
|
65123
|
+
}
|
|
65124
|
+
async request(input, init) {
|
|
65125
|
+
const generation = ++this.requestGeneration;
|
|
65126
|
+
this._lastSessionRecoveryToken = undefined;
|
|
65127
|
+
const inputUrl = input instanceof Request ? input.url : String(input);
|
|
65128
|
+
if (inputUrl.startsWith("data:") || inputUrl.startsWith("blob:")) {
|
|
65129
|
+
return fetch(input, init);
|
|
65130
|
+
}
|
|
65131
|
+
const normalizedRequest = new Request(input, init);
|
|
65132
|
+
const requestBodyBytes = await normalizedRequest.arrayBuffer();
|
|
65133
|
+
const requestBody = requestBodyBytes.byteLength > 0 ? requestBodyBytes : null;
|
|
65134
|
+
const url3 = new URL(normalizedRequest.url);
|
|
65135
|
+
url3.host = this.serverHost;
|
|
65136
|
+
const request = new Request(url3.toString(), {
|
|
65137
|
+
...forwardedRequestInit2(normalizedRequest),
|
|
65138
|
+
method: normalizedRequest.method,
|
|
65139
|
+
headers: normalizedRequest.headers,
|
|
65140
|
+
body: requestBody,
|
|
65141
|
+
duplex: "half"
|
|
65142
|
+
});
|
|
65143
|
+
const { request: encryptedRequest, context } = await this.serverIdentity.encryptRequestWithContext(request);
|
|
65144
|
+
const token = context ? await extractSessionRecoveryToken2(context) : undefined;
|
|
65145
|
+
const response = await fetch(encryptedRequest);
|
|
65146
|
+
if (!token) {
|
|
65147
|
+
return response;
|
|
65148
|
+
}
|
|
65149
|
+
const shouldDecrypt = await Transport2.shouldDecryptResponse(response);
|
|
65150
|
+
if (!shouldDecrypt) {
|
|
65151
|
+
return response;
|
|
65152
|
+
}
|
|
65153
|
+
let streamTerminated = false;
|
|
65154
|
+
const clearToken = () => {
|
|
65155
|
+
streamTerminated = true;
|
|
65156
|
+
if (this.requestGeneration === generation) {
|
|
65157
|
+
this._lastSessionRecoveryToken = undefined;
|
|
65158
|
+
}
|
|
65159
|
+
};
|
|
65160
|
+
const decryptedResponse = await decryptResponseWithToken2(response, token, clearToken, clearToken);
|
|
65161
|
+
if (this.requestGeneration === generation) {
|
|
65162
|
+
this._lastSessionRecoveryToken = streamTerminated ? undefined : token;
|
|
65163
|
+
}
|
|
65164
|
+
return decryptedResponse;
|
|
65165
|
+
}
|
|
65166
|
+
async get(url3, init) {
|
|
65167
|
+
return this.request(url3, { ...init, method: "GET" });
|
|
65168
|
+
}
|
|
65169
|
+
async post(url3, body, init) {
|
|
65170
|
+
return this.request(url3, { ...init, method: "POST", body });
|
|
65171
|
+
}
|
|
65172
|
+
async put(url3, body, init) {
|
|
65173
|
+
return this.request(url3, { ...init, method: "PUT", body });
|
|
65174
|
+
}
|
|
65175
|
+
async delete(url3, init) {
|
|
65176
|
+
return this.request(url3, { ...init, method: "DELETE" });
|
|
65177
|
+
}
|
|
65178
|
+
}
|
|
65179
|
+
async function createTransport2(serverURL, init) {
|
|
65180
|
+
return Transport2.create(serverURL, init);
|
|
65181
|
+
}
|
|
65182
|
+
var MAX_PROBLEM_DETAILS_BYTES2;
|
|
65183
|
+
var init_client5 = __esm(() => {
|
|
65184
|
+
init_identity2();
|
|
65185
|
+
init_identity2();
|
|
65186
|
+
init_protocol2();
|
|
65187
|
+
init_request_options2();
|
|
65188
|
+
init_errors6();
|
|
65189
|
+
MAX_PROBLEM_DETAILS_BYTES2 = 64 * 1024;
|
|
65190
|
+
});
|
|
65191
|
+
|
|
65192
|
+
// node_modules/ehbp/dist/esm/index.js
|
|
65193
|
+
var exports_esm = {};
|
|
65194
|
+
__export(exports_esm, {
|
|
65195
|
+
serializeSessionRecoveryToken: () => serializeSessionRecoveryToken2,
|
|
65196
|
+
hexToBytes: () => hexToBytes10,
|
|
65197
|
+
extractSessionRecoveryToken: () => extractSessionRecoveryToken2,
|
|
65198
|
+
encryptChunk: () => encryptChunk2,
|
|
65199
|
+
deserializeSessionRecoveryToken: () => deserializeSessionRecoveryToken2,
|
|
65200
|
+
deriveResponseKeys: () => deriveResponseKeys2,
|
|
65201
|
+
decryptResponseWithToken: () => decryptResponseWithToken2,
|
|
65202
|
+
decryptChunk: () => decryptChunk2,
|
|
65203
|
+
createTransport: () => createTransport2,
|
|
65204
|
+
computeNonce: () => computeNonce2,
|
|
65205
|
+
bytesToHex: () => bytesToHex12,
|
|
65206
|
+
Transport: () => Transport2,
|
|
65207
|
+
RESPONSE_NONCE_LENGTH: () => RESPONSE_NONCE_LENGTH2,
|
|
65208
|
+
ProtocolError: () => ProtocolError2,
|
|
65209
|
+
PROTOCOL: () => PROTOCOL2,
|
|
65210
|
+
KeyConfigMismatchError: () => KeyConfigMismatchError2,
|
|
65211
|
+
Identity: () => Identity3,
|
|
65212
|
+
HPKE_REQUEST_INFO: () => HPKE_REQUEST_INFO2,
|
|
65213
|
+
HPKE_CONFIG: () => HPKE_CONFIG2,
|
|
65214
|
+
EhbpError: () => EhbpError2,
|
|
65215
|
+
EXPORT_LENGTH: () => EXPORT_LENGTH2,
|
|
65216
|
+
EXPORT_LABEL: () => EXPORT_LABEL2,
|
|
65217
|
+
DecryptionError: () => DecryptionError2,
|
|
65218
|
+
AES_GCM_NONCE_LENGTH: () => AES_GCM_NONCE_LENGTH2,
|
|
65219
|
+
AES256_KEY_LENGTH: () => AES256_KEY_LENGTH2
|
|
65220
|
+
});
|
|
65221
|
+
var init_esm4 = __esm(() => {
|
|
65222
|
+
init_identity2();
|
|
65223
|
+
init_identity2();
|
|
65224
|
+
init_client5();
|
|
65225
|
+
init_protocol2();
|
|
65226
|
+
init_errors6();
|
|
65227
|
+
init_derive2();
|
|
65228
|
+
});
|
|
65229
|
+
|
|
64622
65230
|
// node_modules/applesauce-sqlite/node_modules/applesauce-core/dist/factories/types.js
|
|
64623
65231
|
var init_types4 = () => {};
|
|
64624
65232
|
|
|
@@ -64999,20 +65607,20 @@ __export(exports_utils3, {
|
|
|
64999
65607
|
numberToBytesLE: () => numberToBytesLE5,
|
|
65000
65608
|
numberToBytesBE: () => numberToBytesBE5,
|
|
65001
65609
|
hexToNumber: () => hexToNumber5,
|
|
65002
|
-
hexToBytes: () =>
|
|
65610
|
+
hexToBytes: () => hexToBytes11,
|
|
65003
65611
|
equalBytes: () => equalBytes7,
|
|
65004
65612
|
ensureBytes: () => ensureBytes4,
|
|
65005
65613
|
createHmacDrbg: () => createHmacDrbg5,
|
|
65006
65614
|
concatBytes: () => concatBytes12,
|
|
65007
65615
|
bytesToNumberLE: () => bytesToNumberLE5,
|
|
65008
65616
|
bytesToNumberBE: () => bytesToNumberBE5,
|
|
65009
|
-
bytesToHex: () =>
|
|
65617
|
+
bytesToHex: () => bytesToHex13,
|
|
65010
65618
|
bitSet: () => bitSet3,
|
|
65011
65619
|
bitMask: () => bitMask5,
|
|
65012
65620
|
bitLen: () => bitLen5,
|
|
65013
65621
|
bitGet: () => bitGet3
|
|
65014
65622
|
});
|
|
65015
|
-
function
|
|
65623
|
+
function bytesToHex13(bytes7) {
|
|
65016
65624
|
if (!u8a8(bytes7))
|
|
65017
65625
|
throw new Error("Uint8Array expected");
|
|
65018
65626
|
let hex6 = "";
|
|
@@ -65030,7 +65638,7 @@ function hexToNumber5(hex6) {
|
|
|
65030
65638
|
throw new Error("hex string expected, got " + typeof hex6);
|
|
65031
65639
|
return BigInt(hex6 === "" ? "0" : `0x${hex6}`);
|
|
65032
65640
|
}
|
|
65033
|
-
function
|
|
65641
|
+
function hexToBytes11(hex6) {
|
|
65034
65642
|
if (typeof hex6 !== "string")
|
|
65035
65643
|
throw new Error("hex string expected, got " + typeof hex6);
|
|
65036
65644
|
const len = hex6.length;
|
|
@@ -65048,27 +65656,27 @@ function hexToBytes10(hex6) {
|
|
|
65048
65656
|
return array2;
|
|
65049
65657
|
}
|
|
65050
65658
|
function bytesToNumberBE5(bytes7) {
|
|
65051
|
-
return hexToNumber5(
|
|
65659
|
+
return hexToNumber5(bytesToHex13(bytes7));
|
|
65052
65660
|
}
|
|
65053
65661
|
function bytesToNumberLE5(bytes7) {
|
|
65054
65662
|
if (!u8a8(bytes7))
|
|
65055
65663
|
throw new Error("Uint8Array expected");
|
|
65056
|
-
return hexToNumber5(
|
|
65664
|
+
return hexToNumber5(bytesToHex13(Uint8Array.from(bytes7).reverse()));
|
|
65057
65665
|
}
|
|
65058
65666
|
function numberToBytesBE5(n, len) {
|
|
65059
|
-
return
|
|
65667
|
+
return hexToBytes11(n.toString(16).padStart(len * 2, "0"));
|
|
65060
65668
|
}
|
|
65061
65669
|
function numberToBytesLE5(n, len) {
|
|
65062
65670
|
return numberToBytesBE5(n, len).reverse();
|
|
65063
65671
|
}
|
|
65064
65672
|
function numberToVarBytesBE3(n) {
|
|
65065
|
-
return
|
|
65673
|
+
return hexToBytes11(numberToHexUnpadded5(n));
|
|
65066
65674
|
}
|
|
65067
65675
|
function ensureBytes4(title, hex6, expectedLength) {
|
|
65068
65676
|
let res;
|
|
65069
65677
|
if (typeof hex6 === "string") {
|
|
65070
65678
|
try {
|
|
65071
|
-
res =
|
|
65679
|
+
res = hexToBytes11(hex6);
|
|
65072
65680
|
} catch (e13) {
|
|
65073
65681
|
throw new Error(`${title} must be valid hex string, got "${hex6}". Cause: ${e13}`);
|
|
65074
65682
|
}
|
|
@@ -65634,7 +66242,7 @@ function weierstrassPoints3(opts) {
|
|
|
65634
66242
|
const { allowedPrivateKeyLengths: lengths, nByteLength, wrapPrivateKey, n } = CURVE;
|
|
65635
66243
|
if (lengths && typeof key !== "bigint") {
|
|
65636
66244
|
if (key instanceof Uint8Array)
|
|
65637
|
-
key =
|
|
66245
|
+
key = bytesToHex13(key);
|
|
65638
66246
|
if (typeof key !== "string" || !lengths.includes(key.length))
|
|
65639
66247
|
throw new Error("Invalid key");
|
|
65640
66248
|
key = key.padStart(nByteLength * 2, "0");
|
|
@@ -65925,7 +66533,7 @@ function weierstrassPoints3(opts) {
|
|
|
65925
66533
|
return toBytes9(Point4, this, isCompressed);
|
|
65926
66534
|
}
|
|
65927
66535
|
toHex(isCompressed = true) {
|
|
65928
|
-
return
|
|
66536
|
+
return bytesToHex13(this.toRawBytes(isCompressed));
|
|
65929
66537
|
}
|
|
65930
66538
|
}
|
|
65931
66539
|
Point4.BASE = new Point4(CURVE.Gx, CURVE.Gy, Fp5.ONE);
|
|
@@ -66003,7 +66611,7 @@ function weierstrass5(curveDef) {
|
|
|
66003
66611
|
}
|
|
66004
66612
|
}
|
|
66005
66613
|
});
|
|
66006
|
-
const numToNByteStr = (num2) =>
|
|
66614
|
+
const numToNByteStr = (num2) => bytesToHex13(numberToBytesBE5(num2, CURVE.nByteLength));
|
|
66007
66615
|
function isBiggerThanHalfOrder(number10) {
|
|
66008
66616
|
const HALF = CURVE_ORDER >> _1n27;
|
|
66009
66617
|
return number10 > HALF;
|
|
@@ -66064,13 +66672,13 @@ function weierstrass5(curveDef) {
|
|
|
66064
66672
|
return this.hasHighS() ? new Signature(this.r, modN3(-this.s), this.recovery) : this;
|
|
66065
66673
|
}
|
|
66066
66674
|
toDERRawBytes() {
|
|
66067
|
-
return
|
|
66675
|
+
return hexToBytes11(this.toDERHex());
|
|
66068
66676
|
}
|
|
66069
66677
|
toDERHex() {
|
|
66070
66678
|
return DER5.hexFromSig({ r: this.r, s: this.s });
|
|
66071
66679
|
}
|
|
66072
66680
|
toCompactRawBytes() {
|
|
66073
|
-
return
|
|
66681
|
+
return hexToBytes11(this.toCompactHex());
|
|
66074
66682
|
}
|
|
66075
66683
|
toCompactHex() {
|
|
66076
66684
|
return numToNByteStr(this.r) + numToNByteStr(this.s);
|
|
@@ -66565,7 +67173,7 @@ var init_cryptoNode5 = __esm(() => {
|
|
|
66565
67173
|
});
|
|
66566
67174
|
|
|
66567
67175
|
// node_modules/applesauce-sqlite/node_modules/applesauce-core/node_modules/nostr-tools/node_modules/@noble/hashes/esm/utils.js
|
|
66568
|
-
function
|
|
67176
|
+
function bytesToHex14(bytes7) {
|
|
66569
67177
|
if (!u8a9(bytes7))
|
|
66570
67178
|
throw new Error("Uint8Array expected");
|
|
66571
67179
|
let hex6 = "";
|
|
@@ -66574,7 +67182,7 @@ function bytesToHex13(bytes7) {
|
|
|
66574
67182
|
}
|
|
66575
67183
|
return hex6;
|
|
66576
67184
|
}
|
|
66577
|
-
function
|
|
67185
|
+
function hexToBytes12(hex6) {
|
|
66578
67186
|
if (typeof hex6 !== "string")
|
|
66579
67187
|
throw new Error("hex string expected, got " + typeof hex6);
|
|
66580
67188
|
const len = hex6.length;
|
|
@@ -67256,7 +67864,7 @@ function genBech324(encoding2) {
|
|
|
67256
67864
|
return { encode: encode5, decode: decode4, decodeToBytes, decodeUnsafe, fromWords, fromWordsUnsafe, toWords };
|
|
67257
67865
|
}
|
|
67258
67866
|
var gcd4 = (a, b) => !b ? a : gcd4(b, a % b), radix2carry4 = (from7, to) => from7 + (to - gcd4(from7, to)), base164, base324, base32hex4, base32crockford4, base647, base64url6, genBase584 = (abc) => chain4(radix6(58), alphabet4(abc), join5("")), base584, base58flickr4, base58xrp4, XMR_BLOCK_LEN3, base58xmr3, BECH_ALPHABET4, POLYMOD_GENERATORS4, bech324, bech32m4, utf83, hex6, CODERS3, coderTypeError3;
|
|
67259
|
-
var
|
|
67867
|
+
var init_esm5 = __esm(() => {
|
|
67260
67868
|
/*! scure-base - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
67261
67869
|
base164 = chain4(radix24(4), alphabet4("0123456789ABCDEF"), join5(""));
|
|
67262
67870
|
base324 = chain4(radix24(5), alphabet4("ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"), padding4(5), join5(""));
|
|
@@ -67352,7 +67960,7 @@ function output8(out, instance) {
|
|
|
67352
67960
|
var init__assert6 = () => {};
|
|
67353
67961
|
|
|
67354
67962
|
// node_modules/applesauce-sqlite/node_modules/applesauce-core/node_modules/nostr-tools/node_modules/@noble/ciphers/esm/utils.js
|
|
67355
|
-
function
|
|
67963
|
+
function bytesToHex15(bytes9) {
|
|
67356
67964
|
bytes8(bytes9);
|
|
67357
67965
|
let hex7 = "";
|
|
67358
67966
|
for (let i4 = 0;i4 < bytes9.length; i4++) {
|
|
@@ -67369,7 +67977,7 @@ function asciiToBase164(char) {
|
|
|
67369
67977
|
return char - (asciis4._a - 10);
|
|
67370
67978
|
return;
|
|
67371
67979
|
}
|
|
67372
|
-
function
|
|
67980
|
+
function hexToBytes13(hex7) {
|
|
67373
67981
|
if (typeof hex7 !== "string")
|
|
67374
67982
|
throw new Error("hex string expected, got " + typeof hex7);
|
|
67375
67983
|
const hl = hex7.length;
|
|
@@ -68999,7 +69607,7 @@ function serializeEvent4(evt) {
|
|
|
68999
69607
|
}
|
|
69000
69608
|
function getEventHash4(event3) {
|
|
69001
69609
|
let eventHash = sha2569(utf8Encoder5.encode(serializeEvent4(event3)));
|
|
69002
|
-
return
|
|
69610
|
+
return bytesToHex14(eventHash);
|
|
69003
69611
|
}
|
|
69004
69612
|
function isRegularKind4(kind) {
|
|
69005
69613
|
return kind < 1e4 && kind !== 0 && kind !== 3;
|
|
@@ -69164,7 +69772,7 @@ function decode4(code) {
|
|
|
69164
69772
|
return {
|
|
69165
69773
|
type: "nprofile",
|
|
69166
69774
|
data: {
|
|
69167
|
-
pubkey:
|
|
69775
|
+
pubkey: bytesToHex14(tlv[0][0]),
|
|
69168
69776
|
relays: tlv[1] ? tlv[1].map((d) => utf8Decoder5.decode(d)) : []
|
|
69169
69777
|
}
|
|
69170
69778
|
};
|
|
@@ -69182,10 +69790,10 @@ function decode4(code) {
|
|
|
69182
69790
|
return {
|
|
69183
69791
|
type: "nevent",
|
|
69184
69792
|
data: {
|
|
69185
|
-
id:
|
|
69793
|
+
id: bytesToHex14(tlv[0][0]),
|
|
69186
69794
|
relays: tlv[1] ? tlv[1].map((d) => utf8Decoder5.decode(d)) : [],
|
|
69187
|
-
author: tlv[2]?.[0] ?
|
|
69188
|
-
kind: tlv[3]?.[0] ? parseInt(
|
|
69795
|
+
author: tlv[2]?.[0] ? bytesToHex14(tlv[2][0]) : undefined,
|
|
69796
|
+
kind: tlv[3]?.[0] ? parseInt(bytesToHex14(tlv[3][0]), 16) : undefined
|
|
69189
69797
|
}
|
|
69190
69798
|
};
|
|
69191
69799
|
}
|
|
@@ -69205,8 +69813,8 @@ function decode4(code) {
|
|
|
69205
69813
|
type: "naddr",
|
|
69206
69814
|
data: {
|
|
69207
69815
|
identifier: utf8Decoder5.decode(tlv[0][0]),
|
|
69208
|
-
pubkey:
|
|
69209
|
-
kind: parseInt(
|
|
69816
|
+
pubkey: bytesToHex14(tlv[2][0]),
|
|
69817
|
+
kind: parseInt(bytesToHex14(tlv[3][0]), 16),
|
|
69210
69818
|
relays: tlv[1] ? tlv[1].map((d) => utf8Decoder5.decode(d)) : []
|
|
69211
69819
|
}
|
|
69212
69820
|
};
|
|
@@ -69215,7 +69823,7 @@ function decode4(code) {
|
|
|
69215
69823
|
return { type: prefix, data };
|
|
69216
69824
|
case "npub":
|
|
69217
69825
|
case "note":
|
|
69218
|
-
return { type: prefix, data:
|
|
69826
|
+
return { type: prefix, data: bytesToHex14(data) };
|
|
69219
69827
|
default:
|
|
69220
69828
|
throw new Error(`unknown prefix ${prefix}`);
|
|
69221
69829
|
}
|
|
@@ -69239,10 +69847,10 @@ function nsecEncode2(key) {
|
|
|
69239
69847
|
return encodeBytes2("nsec", key);
|
|
69240
69848
|
}
|
|
69241
69849
|
function npubEncode3(hex7) {
|
|
69242
|
-
return encodeBytes2("npub",
|
|
69850
|
+
return encodeBytes2("npub", hexToBytes12(hex7));
|
|
69243
69851
|
}
|
|
69244
69852
|
function noteEncode2(hex7) {
|
|
69245
|
-
return encodeBytes2("note",
|
|
69853
|
+
return encodeBytes2("note", hexToBytes12(hex7));
|
|
69246
69854
|
}
|
|
69247
69855
|
function encodeBech322(prefix, data) {
|
|
69248
69856
|
let words = bech324.toWords(data);
|
|
@@ -69253,7 +69861,7 @@ function encodeBytes2(prefix, bytes9) {
|
|
|
69253
69861
|
}
|
|
69254
69862
|
function nprofileEncode2(profile3) {
|
|
69255
69863
|
let data = encodeTLV2({
|
|
69256
|
-
0: [
|
|
69864
|
+
0: [hexToBytes12(profile3.pubkey)],
|
|
69257
69865
|
1: (profile3.relays || []).map((url3) => utf8Encoder5.encode(url3))
|
|
69258
69866
|
});
|
|
69259
69867
|
return encodeBech322("nprofile", data);
|
|
@@ -69264,9 +69872,9 @@ function neventEncode2(event3) {
|
|
|
69264
69872
|
kindArray = integerToUint8Array2(event3.kind);
|
|
69265
69873
|
}
|
|
69266
69874
|
let data = encodeTLV2({
|
|
69267
|
-
0: [
|
|
69875
|
+
0: [hexToBytes12(event3.id)],
|
|
69268
69876
|
1: (event3.relays || []).map((url3) => utf8Encoder5.encode(url3)),
|
|
69269
|
-
2: event3.author ? [
|
|
69877
|
+
2: event3.author ? [hexToBytes12(event3.author)] : [],
|
|
69270
69878
|
3: kindArray ? [new Uint8Array(kindArray)] : []
|
|
69271
69879
|
});
|
|
69272
69880
|
return encodeBech322("nevent", data);
|
|
@@ -69277,7 +69885,7 @@ function naddrEncode2(addr) {
|
|
|
69277
69885
|
let data = encodeTLV2({
|
|
69278
69886
|
0: [utf8Encoder5.encode(addr.identifier)],
|
|
69279
69887
|
1: (addr.relays || []).map((url3) => utf8Encoder5.encode(url3)),
|
|
69280
|
-
2: [
|
|
69888
|
+
2: [hexToBytes12(addr.pubkey)],
|
|
69281
69889
|
3: [new Uint8Array(kind)]
|
|
69282
69890
|
});
|
|
69283
69891
|
return encodeBech322("naddr", data);
|
|
@@ -69296,7 +69904,7 @@ function encodeTLV2(tlv) {
|
|
|
69296
69904
|
return concatBytes13(...entries);
|
|
69297
69905
|
}
|
|
69298
69906
|
function encrypt5(secretKey, pubkey, text) {
|
|
69299
|
-
const privkey = secretKey instanceof Uint8Array ?
|
|
69907
|
+
const privkey = secretKey instanceof Uint8Array ? bytesToHex14(secretKey) : secretKey;
|
|
69300
69908
|
const key = secp256k14.getSharedSecret(privkey, "02" + pubkey);
|
|
69301
69909
|
const normalizedKey = getNormalizedX2(key);
|
|
69302
69910
|
let iv = Uint8Array.from(randomBytes8(16));
|
|
@@ -69307,7 +69915,7 @@ function encrypt5(secretKey, pubkey, text) {
|
|
|
69307
69915
|
return `${ctb64}?iv=${ivb64}`;
|
|
69308
69916
|
}
|
|
69309
69917
|
function decrypt4(secretKey, pubkey, data) {
|
|
69310
|
-
const privkey = secretKey instanceof Uint8Array ?
|
|
69918
|
+
const privkey = secretKey instanceof Uint8Array ? bytesToHex14(secretKey) : secretKey;
|
|
69311
69919
|
let [ctb64, ivb64] = data.split("?iv=");
|
|
69312
69920
|
let key = secp256k14.getSharedSecret(privkey, "02" + pubkey);
|
|
69313
69921
|
let normalizedKey = getNormalizedX2(key);
|
|
@@ -69496,7 +70104,7 @@ function minePow2(unsigned, difficulty) {
|
|
|
69496
70104
|
return event3;
|
|
69497
70105
|
}
|
|
69498
70106
|
function fastEventHash2(evt) {
|
|
69499
|
-
return
|
|
70107
|
+
return bytesToHex14(sha2569(utf8Encoder5.encode(JSON.stringify([0, evt.pubkey, evt.created_at, evt.kind, evt.tags, evt.content]))));
|
|
69500
70108
|
}
|
|
69501
70109
|
function getConversationKey2(privkeyA, pubkeyB) {
|
|
69502
70110
|
const sharedX = secp256k14.getSharedSecret(privkeyA, "02" + pubkeyB).subarray(1, 33);
|
|
@@ -70244,7 +70852,7 @@ function validateEventMethodTag2(event3, method) {
|
|
|
70244
70852
|
}
|
|
70245
70853
|
function hashPayload3(payload) {
|
|
70246
70854
|
const hash8 = sha2569(utf8Encoder5.encode(JSON.stringify(payload)));
|
|
70247
|
-
return
|
|
70855
|
+
return bytesToHex14(hash8);
|
|
70248
70856
|
}
|
|
70249
70857
|
function validateEventPayloadTag2(event3, payload) {
|
|
70250
70858
|
const payloadTag = event3.tags.find((t) => t[0] === "payload");
|
|
@@ -70331,13 +70939,13 @@ var __defProp3, __export3 = (target, all) => {
|
|
|
70331
70939
|
return schnorr4.utils.randomPrivateKey();
|
|
70332
70940
|
}
|
|
70333
70941
|
getPublicKey(secretKey) {
|
|
70334
|
-
return
|
|
70942
|
+
return bytesToHex14(schnorr4.getPublicKey(secretKey));
|
|
70335
70943
|
}
|
|
70336
70944
|
finalizeEvent(t, secretKey) {
|
|
70337
70945
|
const event3 = t;
|
|
70338
|
-
event3.pubkey =
|
|
70946
|
+
event3.pubkey = bytesToHex14(schnorr4.getPublicKey(secretKey));
|
|
70339
70947
|
event3.id = getEventHash4(event3);
|
|
70340
|
-
event3.sig =
|
|
70948
|
+
event3.sig = bytesToHex14(schnorr4.sign(getEventHash4(event3), secretKey));
|
|
70341
70949
|
event3[verifiedSymbol6] = true;
|
|
70342
70950
|
return event3;
|
|
70343
70951
|
}
|
|
@@ -70960,7 +71568,7 @@ var __defProp3, __export3 = (target, all) => {
|
|
|
70960
71568
|
insert(timestamp, id) {
|
|
70961
71569
|
if (this.sealed)
|
|
70962
71570
|
throw Error("already sealed");
|
|
70963
|
-
const idb =
|
|
71571
|
+
const idb = hexToBytes13(id);
|
|
70964
71572
|
if (idb.byteLength !== ID_SIZE3)
|
|
70965
71573
|
throw Error("bad id size for added item");
|
|
70966
71574
|
this.items.push({ timestamp, id: idb });
|
|
@@ -71053,10 +71661,10 @@ var __defProp3, __export3 = (target, all) => {
|
|
|
71053
71661
|
let output9 = new WrappedBuffer3;
|
|
71054
71662
|
output9.extend(new Uint8Array([PROTOCOL_VERSION3]));
|
|
71055
71663
|
this.splitRange(0, this.storage.size(), this._bound(Number.MAX_VALUE), output9);
|
|
71056
|
-
return
|
|
71664
|
+
return bytesToHex15(output9.unwrap());
|
|
71057
71665
|
}
|
|
71058
71666
|
reconcile(queryMsg, onhave, onneed) {
|
|
71059
|
-
const query2 = new WrappedBuffer3(
|
|
71667
|
+
const query2 = new WrappedBuffer3(hexToBytes13(queryMsg));
|
|
71060
71668
|
this.lastTimestampIn = this.lastTimestampOut = 0;
|
|
71061
71669
|
let fullOutput = new WrappedBuffer3;
|
|
71062
71670
|
fullOutput.extend(new Uint8Array([PROTOCOL_VERSION3]));
|
|
@@ -71099,22 +71707,22 @@ var __defProp3, __export3 = (target, all) => {
|
|
|
71099
71707
|
let theirElems = {};
|
|
71100
71708
|
for (let i22 = 0;i22 < numIds; i22++) {
|
|
71101
71709
|
let e13 = getBytes4(query2, ID_SIZE3);
|
|
71102
|
-
theirElems[
|
|
71710
|
+
theirElems[bytesToHex15(e13)] = e13;
|
|
71103
71711
|
}
|
|
71104
71712
|
skip2 = true;
|
|
71105
71713
|
this.storage.iterate(lower, upper, (item) => {
|
|
71106
71714
|
let k2 = item.id;
|
|
71107
|
-
const id =
|
|
71715
|
+
const id = bytesToHex15(k2);
|
|
71108
71716
|
if (!theirElems[id]) {
|
|
71109
71717
|
onhave?.(id);
|
|
71110
71718
|
} else {
|
|
71111
|
-
delete theirElems[
|
|
71719
|
+
delete theirElems[bytesToHex15(k2)];
|
|
71112
71720
|
}
|
|
71113
71721
|
return true;
|
|
71114
71722
|
});
|
|
71115
71723
|
if (onneed) {
|
|
71116
71724
|
for (let v3 of Object.values(theirElems)) {
|
|
71117
|
-
onneed(
|
|
71725
|
+
onneed(bytesToHex15(v3));
|
|
71118
71726
|
}
|
|
71119
71727
|
}
|
|
71120
71728
|
} else {
|
|
@@ -71132,7 +71740,7 @@ var __defProp3, __export3 = (target, all) => {
|
|
|
71132
71740
|
prevIndex = upper;
|
|
71133
71741
|
prevBound = currBound;
|
|
71134
71742
|
}
|
|
71135
|
-
return fullOutput.length === 1 ? null :
|
|
71743
|
+
return fullOutput.length === 1 ? null : bytesToHex15(fullOutput.unwrap());
|
|
71136
71744
|
}
|
|
71137
71745
|
splitRange(lower, upper, upperBound, o) {
|
|
71138
71746
|
let numElems = upper - lower;
|
|
@@ -71285,17 +71893,17 @@ var __defProp3, __export3 = (target, all) => {
|
|
|
71285
71893
|
this.subscription.close();
|
|
71286
71894
|
}
|
|
71287
71895
|
}, nip98_exports2, _authorizationScheme3 = "Nostr ";
|
|
71288
|
-
var
|
|
71896
|
+
var init_esm6 = __esm(() => {
|
|
71289
71897
|
init_secp256k12();
|
|
71290
71898
|
init_utils16();
|
|
71291
71899
|
init_sha2564();
|
|
71292
71900
|
init_utils16();
|
|
71293
71901
|
init_utils16();
|
|
71294
|
-
|
|
71902
|
+
init_esm5();
|
|
71295
71903
|
init_utils16();
|
|
71296
71904
|
init_secp256k12();
|
|
71297
71905
|
init_aes3();
|
|
71298
|
-
|
|
71906
|
+
init_esm5();
|
|
71299
71907
|
init_utils16();
|
|
71300
71908
|
init_sha2564();
|
|
71301
71909
|
init_chacha2();
|
|
@@ -71305,13 +71913,13 @@ var init_esm5 = __esm(() => {
|
|
|
71305
71913
|
init_hmac6();
|
|
71306
71914
|
init_sha2564();
|
|
71307
71915
|
init_utils16();
|
|
71308
|
-
|
|
71309
|
-
|
|
71916
|
+
init_esm5();
|
|
71917
|
+
init_esm5();
|
|
71310
71918
|
init_utils17();
|
|
71311
71919
|
init_sha2564();
|
|
71312
71920
|
init_sha2564();
|
|
71313
71921
|
init_utils16();
|
|
71314
|
-
|
|
71922
|
+
init_esm5();
|
|
71315
71923
|
__defProp3 = Object.defineProperty;
|
|
71316
71924
|
verifiedSymbol6 = Symbol("verified");
|
|
71317
71925
|
utils_exports2 = {};
|
|
@@ -71319,8 +71927,8 @@ var init_esm5 = __esm(() => {
|
|
|
71319
71927
|
Queue: () => Queue2,
|
|
71320
71928
|
QueueNode: () => QueueNode2,
|
|
71321
71929
|
binarySearch: () => binarySearch3,
|
|
71322
|
-
bytesToHex: () =>
|
|
71323
|
-
hexToBytes: () =>
|
|
71930
|
+
bytesToHex: () => bytesToHex14,
|
|
71931
|
+
hexToBytes: () => hexToBytes12,
|
|
71324
71932
|
insertEventIntoAscendingList: () => insertEventIntoAscendingList3,
|
|
71325
71933
|
insertEventIntoDescendingList: () => insertEventIntoDescendingList3,
|
|
71326
71934
|
normalizeURL: () => normalizeURL3,
|
|
@@ -71685,20 +72293,20 @@ function serializeEvent5(evt) {
|
|
|
71685
72293
|
}
|
|
71686
72294
|
function getEventHash5(event3) {
|
|
71687
72295
|
let eventHash = sha2569(utf8Encoder6.encode(serializeEvent5(event3)));
|
|
71688
|
-
return
|
|
72296
|
+
return bytesToHex14(eventHash);
|
|
71689
72297
|
}
|
|
71690
72298
|
var verifiedSymbol7, isRecord5 = (obj2) => obj2 instanceof Object, utf8Decoder6, utf8Encoder6, JS5 = class {
|
|
71691
72299
|
generateSecretKey() {
|
|
71692
72300
|
return schnorr4.utils.randomPrivateKey();
|
|
71693
72301
|
}
|
|
71694
72302
|
getPublicKey(secretKey) {
|
|
71695
|
-
return
|
|
72303
|
+
return bytesToHex14(schnorr4.getPublicKey(secretKey));
|
|
71696
72304
|
}
|
|
71697
72305
|
finalizeEvent(t, secretKey) {
|
|
71698
72306
|
const event3 = t;
|
|
71699
|
-
event3.pubkey =
|
|
72307
|
+
event3.pubkey = bytesToHex14(schnorr4.getPublicKey(secretKey));
|
|
71700
72308
|
event3.id = getEventHash5(event3);
|
|
71701
|
-
event3.sig =
|
|
72309
|
+
event3.sig = bytesToHex14(schnorr4.sign(getEventHash5(event3), secretKey));
|
|
71702
72310
|
event3[verifiedSymbol7] = true;
|
|
71703
72311
|
return event3;
|
|
71704
72312
|
}
|
|
@@ -71824,7 +72432,7 @@ function getReplaceableIdentifier2(event3) {
|
|
|
71824
72432
|
}
|
|
71825
72433
|
var EventStoreSymbol2, EventUIDSymbol2, ReplaceableAddressSymbol2, FromCacheSymbol2, ReplaceableIdentifierSymbol2;
|
|
71826
72434
|
var init_event3 = __esm(() => {
|
|
71827
|
-
|
|
72435
|
+
init_esm6();
|
|
71828
72436
|
init_kinds2();
|
|
71829
72437
|
init_utils18();
|
|
71830
72438
|
EventStoreSymbol2 = Symbol.for("event-store");
|
|
@@ -71906,7 +72514,7 @@ var processTags2 = (tags3, ...fns) => {
|
|
|
71906
72514
|
|
|
71907
72515
|
// node_modules/applesauce-sqlite/node_modules/applesauce-core/node_modules/nostr-tools/lib/esm/nip19.js
|
|
71908
72516
|
function npubEncode4(hex7) {
|
|
71909
|
-
return encodeBytes3("npub",
|
|
72517
|
+
return encodeBytes3("npub", hexToBytes12(hex7));
|
|
71910
72518
|
}
|
|
71911
72519
|
function encodeBech323(prefix, data) {
|
|
71912
72520
|
let words = bech324.toWords(data);
|
|
@@ -71917,7 +72525,7 @@ function encodeBytes3(prefix, bytes9) {
|
|
|
71917
72525
|
}
|
|
71918
72526
|
function nprofileEncode3(profile3) {
|
|
71919
72527
|
let data = encodeTLV3({
|
|
71920
|
-
0: [
|
|
72528
|
+
0: [hexToBytes12(profile3.pubkey)],
|
|
71921
72529
|
1: (profile3.relays || []).map((url3) => utf8Encoder8.encode(url3))
|
|
71922
72530
|
});
|
|
71923
72531
|
return encodeBech323("nprofile", data);
|
|
@@ -71938,7 +72546,7 @@ function encodeTLV3(tlv) {
|
|
|
71938
72546
|
var utf8Decoder8, utf8Encoder8, Bech32MaxSize3 = 5000;
|
|
71939
72547
|
var init_nip19 = __esm(() => {
|
|
71940
72548
|
init_utils16();
|
|
71941
|
-
|
|
72549
|
+
init_esm5();
|
|
71942
72550
|
init_utils16();
|
|
71943
72551
|
utf8Decoder8 = new TextDecoder("utf-8");
|
|
71944
72552
|
utf8Encoder8 = new TextEncoder;
|
|
@@ -74614,7 +75222,7 @@ var init_models3 = __esm(() => {
|
|
|
74614
75222
|
|
|
74615
75223
|
// node_modules/applesauce-sqlite/node_modules/applesauce-core/dist/operations/client.js
|
|
74616
75224
|
var NEVER_ATTACH_CLIENT_TAG2;
|
|
74617
|
-
var
|
|
75225
|
+
var init_client6 = __esm(() => {
|
|
74618
75226
|
init_event3();
|
|
74619
75227
|
init_pointers2();
|
|
74620
75228
|
init_tags2();
|
|
@@ -74628,7 +75236,7 @@ var init_hidden_content4 = __esm(() => {
|
|
|
74628
75236
|
|
|
74629
75237
|
// node_modules/applesauce-sqlite/node_modules/applesauce-core/dist/operations/index.js
|
|
74630
75238
|
var init_operations2 = __esm(() => {
|
|
74631
|
-
|
|
75239
|
+
init_client6();
|
|
74632
75240
|
init_content5();
|
|
74633
75241
|
init_encrypted_content5();
|
|
74634
75242
|
init_event4();
|
|
@@ -90915,49 +91523,6 @@ var ModelManager = class _ModelManager {
|
|
|
90915
91523
|
}
|
|
90916
91524
|
}
|
|
90917
91525
|
};
|
|
90918
|
-
var AuditLogger = class _AuditLogger {
|
|
90919
|
-
static instance = null;
|
|
90920
|
-
static getInstance() {
|
|
90921
|
-
if (!_AuditLogger.instance) {
|
|
90922
|
-
_AuditLogger.instance = new _AuditLogger;
|
|
90923
|
-
}
|
|
90924
|
-
return _AuditLogger.instance;
|
|
90925
|
-
}
|
|
90926
|
-
async log(entry) {
|
|
90927
|
-
const fullEntry = {
|
|
90928
|
-
...entry,
|
|
90929
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
90930
|
-
};
|
|
90931
|
-
const logLine = JSON.stringify(fullEntry) + `
|
|
90932
|
-
`;
|
|
90933
|
-
if (typeof window === "undefined") {
|
|
90934
|
-
try {
|
|
90935
|
-
const fs = await import("fs");
|
|
90936
|
-
const path2 = await import("path");
|
|
90937
|
-
const logPath = path2.join(process.cwd(), "audit.log");
|
|
90938
|
-
fs.appendFileSync(logPath, logLine);
|
|
90939
|
-
} catch (error53) {
|
|
90940
|
-
console.error("[AuditLogger] Failed to write to file:", error53);
|
|
90941
|
-
}
|
|
90942
|
-
} else {
|
|
90943
|
-
console.log("[AUDIT]", logLine.trim());
|
|
90944
|
-
}
|
|
90945
|
-
}
|
|
90946
|
-
async logBalanceSnapshot(action, amounts, options) {
|
|
90947
|
-
await this.log({
|
|
90948
|
-
action,
|
|
90949
|
-
totalBalance: amounts.totalBalance,
|
|
90950
|
-
providerBalances: amounts.providerBalances,
|
|
90951
|
-
mintBalances: amounts.mintBalances,
|
|
90952
|
-
amount: options?.amount,
|
|
90953
|
-
mintUrl: options?.mintUrl,
|
|
90954
|
-
baseUrl: options?.baseUrl,
|
|
90955
|
-
status: options?.status ?? "success",
|
|
90956
|
-
details: options?.details
|
|
90957
|
-
});
|
|
90958
|
-
}
|
|
90959
|
-
};
|
|
90960
|
-
var auditLogger = AuditLogger.getInstance();
|
|
90961
91526
|
function isNetworkErrorMessage(message) {
|
|
90962
91527
|
return message.includes("NetworkError when attempting to fetch resource") || message.includes("Failed to fetch") || message.includes("Load failed") || message.includes("Unable to connect") || message.includes("Was there a typo in the url or port") || message.includes("ERR_TLS_CERT_ALTNAME_INVALID") || message.includes("ERR_TLS_CERT_NOT_YET_VALID") || message.includes("ERR_TLS_CERT_EXPIRED") || message.includes("UNABLE_TO_VERIFY_LEAF_SIGNATURE") || message.includes("SELF_SIGNED_CERT_IN_CHAIN");
|
|
90963
91528
|
}
|
|
@@ -90992,7 +91557,7 @@ var CashuSpender = class _CashuSpender {
|
|
|
90992
91557
|
debugLevel = "WARN";
|
|
90993
91558
|
logger;
|
|
90994
91559
|
static MAX_REFUND_RETRIES = 3;
|
|
90995
|
-
static REFUND_RETRY_INTERVAL_MS =
|
|
91560
|
+
static REFUND_RETRY_INTERVAL_MS = 2 * 60 * 1000;
|
|
90996
91561
|
_refundRetryInterval = null;
|
|
90997
91562
|
async receiveToken(token) {
|
|
90998
91563
|
try {
|
|
@@ -91060,10 +91625,6 @@ var CashuSpender = class _CashuSpender {
|
|
|
91060
91625
|
mintBalances: normalizedMintBalances
|
|
91061
91626
|
};
|
|
91062
91627
|
}
|
|
91063
|
-
async _logTransaction(action, options) {
|
|
91064
|
-
const balanceState = await this._getBalanceState();
|
|
91065
|
-
await auditLogger.logBalanceSnapshot(action, balanceState, options);
|
|
91066
|
-
}
|
|
91067
91628
|
get isBusy() {
|
|
91068
91629
|
return this._isBusy;
|
|
91069
91630
|
}
|
|
@@ -91212,12 +91773,6 @@ var CashuSpender = class _CashuSpender {
|
|
|
91212
91773
|
if (token) {
|
|
91213
91774
|
this._log("DEBUG", `[CashuSpender] _spendInternal: Successfully spent ${spentAmount}, returning token with balance=${spentAmount}`);
|
|
91214
91775
|
}
|
|
91215
|
-
this._logTransaction("spend", {
|
|
91216
|
-
amount: spentAmount,
|
|
91217
|
-
mintUrl: selectedMintUrl || mintUrl,
|
|
91218
|
-
baseUrl,
|
|
91219
|
-
status: "success"
|
|
91220
|
-
});
|
|
91221
91776
|
this._log("DEBUG", `[CashuSpender] _spendInternal: Successfully spent ${spentAmount}, returning token with balance=${spentAmount}`);
|
|
91222
91777
|
const units = this.walletAdapter.getMintUnits();
|
|
91223
91778
|
return {
|
|
@@ -91258,12 +91813,6 @@ var CashuSpender = class _CashuSpender {
|
|
|
91258
91813
|
const newBalance = balanceForBaseUrl + topUpResult.toppedUpAmount;
|
|
91259
91814
|
const units = this.walletAdapter.getMintUnits();
|
|
91260
91815
|
const unit = units[mintUrl] || "sat";
|
|
91261
|
-
this._logTransaction("topup", {
|
|
91262
|
-
amount: topUpResult.toppedUpAmount,
|
|
91263
|
-
mintUrl,
|
|
91264
|
-
baseUrl,
|
|
91265
|
-
status: "success"
|
|
91266
|
-
});
|
|
91267
91816
|
return {
|
|
91268
91817
|
token: apiKeyEntry.key,
|
|
91269
91818
|
status: "success",
|
|
@@ -91620,7 +92169,7 @@ var BalanceManager = class _BalanceManager {
|
|
|
91620
92169
|
if (!forceRefund) {
|
|
91621
92170
|
const apiKeyEntry = this.storageAdapter.getApiKey(baseUrl);
|
|
91622
92171
|
if (apiKeyEntry?.lastUsed) {
|
|
91623
|
-
const fiveMinutesAgo = Date.now() -
|
|
92172
|
+
const fiveMinutesAgo = Date.now() - 5 * 60 * 1000;
|
|
91624
92173
|
if (apiKeyEntry.lastUsed > fiveMinutesAgo) {
|
|
91625
92174
|
this.logger.log(`refundApiKey: skipping ${baseUrl} - used ${Math.round((Date.now() - apiKeyEntry.lastUsed) / 1000)}s ago`);
|
|
91626
92175
|
return {
|
|
@@ -92274,13 +92823,18 @@ var isOnionUrl = (url3) => {
|
|
|
92274
92823
|
return trimmed.includes(TOR_ONION_SUFFIX);
|
|
92275
92824
|
}
|
|
92276
92825
|
};
|
|
92277
|
-
var
|
|
92278
|
-
var USER_CACHE_SECRET_ENV2 = "TINFOIL_USER_CACHE_SECRET";
|
|
92279
|
-
var USER_CACHE_SECRET_PATHS2 = [
|
|
92826
|
+
var OPENAI_JSON_BODY_PATHS = [
|
|
92280
92827
|
"/chat/completions",
|
|
92281
92828
|
"/completions",
|
|
92282
92829
|
"/responses"
|
|
92283
92830
|
];
|
|
92831
|
+
function isOpenAiJsonBodyPath(pathname) {
|
|
92832
|
+
const path2 = (pathname.split("?")[0] ?? "").replace(/\/+$/, "");
|
|
92833
|
+
return OPENAI_JSON_BODY_PATHS.some((suffix) => path2.endsWith(suffix));
|
|
92834
|
+
}
|
|
92835
|
+
var USER_CACHE_SECRET_FIELD2 = "user_cache_secret";
|
|
92836
|
+
var USER_CACHE_SECRET_ENV2 = "TINFOIL_USER_CACHE_SECRET";
|
|
92837
|
+
var USER_CACHE_SECRET_PATHS2 = OPENAI_JSON_BODY_PATHS;
|
|
92284
92838
|
var USER_CACHE_SECRET_DIR_NAME2 = ".tinfoil";
|
|
92285
92839
|
var USER_CACHE_SECRET_FILE_NAME2 = "user_cache_secret";
|
|
92286
92840
|
function newUserCacheSecret2() {
|
|
@@ -92657,7 +93211,7 @@ async function isEhbpKeyConfigMismatchResponse(response, protocol) {
|
|
|
92657
93211
|
}
|
|
92658
93212
|
}
|
|
92659
93213
|
async function fetchTinfoilEhbpOnce(context, options, normalized, ehbp, userCacheSecret) {
|
|
92660
|
-
const { Identity:
|
|
93214
|
+
const { Identity: Identity4, PROTOCOL: PROTOCOL3, decryptResponseWithToken: decryptResponseWithToken3, extractSessionRecoveryToken: extractSessionRecoveryToken3 } = ehbp;
|
|
92661
93215
|
const resolved = resolveOptions(options);
|
|
92662
93216
|
const baseURL = context.client.getBaseURL() ?? resolved.baseUrl;
|
|
92663
93217
|
const enclaveURL = context.client.getEnclaveURL();
|
|
@@ -92685,7 +93239,7 @@ async function fetchTinfoilEhbpOnce(context, options, normalized, ehbp, userCach
|
|
|
92685
93239
|
}
|
|
92686
93240
|
}
|
|
92687
93241
|
}
|
|
92688
|
-
const serverIdentity = await
|
|
93242
|
+
const serverIdentity = await Identity4.fromPublicKeyHex(context.verification.hpkePublicKey);
|
|
92689
93243
|
const request = new Request(targetUrl.toString(), {
|
|
92690
93244
|
method,
|
|
92691
93245
|
headers,
|
|
@@ -92700,18 +93254,18 @@ async function fetchTinfoilEhbpOnce(context, options, normalized, ehbp, userCach
|
|
|
92700
93254
|
if (!requestContext) {
|
|
92701
93255
|
return response;
|
|
92702
93256
|
}
|
|
92703
|
-
if (await isEhbpKeyConfigMismatchResponse(response,
|
|
93257
|
+
if (await isEhbpKeyConfigMismatchResponse(response, PROTOCOL3)) {
|
|
92704
93258
|
throw new ehbp.KeyConfigMismatchError("EHBP key configuration mismatch");
|
|
92705
93259
|
}
|
|
92706
|
-
if (!response.headers.get(
|
|
93260
|
+
if (!response.headers.get(PROTOCOL3.RESPONSE_NONCE_HEADER)) {
|
|
92707
93261
|
return response;
|
|
92708
93262
|
}
|
|
92709
|
-
const token = await
|
|
92710
|
-
return await
|
|
93263
|
+
const token = await extractSessionRecoveryToken3(requestContext);
|
|
93264
|
+
return await decryptResponseWithToken3(response, token);
|
|
92711
93265
|
}
|
|
92712
93266
|
async function fetchTinfoilPreservingPlaintextErrors(options, input, init) {
|
|
92713
93267
|
const context = await prepareTinfoilClient(options);
|
|
92714
|
-
const ehbp = await Promise.resolve().then(() => (
|
|
93268
|
+
const ehbp = await Promise.resolve().then(() => (init_esm4(), exports_esm));
|
|
92715
93269
|
const normalized = normalizeFetchArgs(input, init);
|
|
92716
93270
|
const userCacheSecret = await resolveUserCacheSecret2({
|
|
92717
93271
|
explicit: options.userCacheSecret,
|
|
@@ -92826,6 +93380,10 @@ function getImageResolutionFromDataUrl(dataUrl) {
|
|
|
92826
93380
|
function calculateImageTokens(width, height, detail = "auto") {
|
|
92827
93381
|
if (detail === "low")
|
|
92828
93382
|
return 85;
|
|
93383
|
+
if (detail === "original") {
|
|
93384
|
+
const patches = Math.ceil(width / IMAGE_PATCH_PX) * Math.ceil(height / IMAGE_PATCH_PX);
|
|
93385
|
+
return Math.ceil(Math.min(patches, MAX_IMAGE_PATCHES) * 1.2);
|
|
93386
|
+
}
|
|
92829
93387
|
let w2 = width;
|
|
92830
93388
|
let h2 = height;
|
|
92831
93389
|
if (w2 > 2048 || h2 > 2048) {
|
|
@@ -92853,6 +93411,238 @@ function calculateImageTokens(width, height, detail = "auto") {
|
|
|
92853
93411
|
const numTiles = tilesWidth * tilesHeight;
|
|
92854
93412
|
return 85 + 170 * numTiles;
|
|
92855
93413
|
}
|
|
93414
|
+
var IMAGE_PATCH_PX = 32;
|
|
93415
|
+
var MAX_IMAGE_PATCHES = 30000;
|
|
93416
|
+
var MAX_TILED_IMAGE_TOKENS = 765;
|
|
93417
|
+
var MAX_ORIGINAL_IMAGE_TOKENS = Math.ceil(MAX_IMAGE_PATCHES * 1.2);
|
|
93418
|
+
function worstCaseImageTokensForDetail(detail) {
|
|
93419
|
+
if (detail === "low")
|
|
93420
|
+
return 85;
|
|
93421
|
+
if (detail === "original")
|
|
93422
|
+
return MAX_ORIGINAL_IMAGE_TOKENS;
|
|
93423
|
+
return MAX_TILED_IMAGE_TOKENS;
|
|
93424
|
+
}
|
|
93425
|
+
function estimateImageTokensForUrl(url3, detail) {
|
|
93426
|
+
if (!url3 || typeof url3 !== "string")
|
|
93427
|
+
return 0;
|
|
93428
|
+
if (url3.startsWith("data:")) {
|
|
93429
|
+
const res = getImageResolutionFromDataUrl(url3);
|
|
93430
|
+
if (res) {
|
|
93431
|
+
return calculateImageTokens(res.width, res.height, detail);
|
|
93432
|
+
}
|
|
93433
|
+
return worstCaseImageTokensForDetail(detail);
|
|
93434
|
+
}
|
|
93435
|
+
return worstCaseImageTokensForDetail(detail);
|
|
93436
|
+
}
|
|
93437
|
+
function estimateInputImageTokens(item) {
|
|
93438
|
+
const detail = typeof item?.detail === "string" && item?.detail ? item.detail : "auto";
|
|
93439
|
+
const url3 = typeof item?.image_url === "string" ? item.image_url : item?.image_url?.url;
|
|
93440
|
+
const fromUrl = estimateImageTokensForUrl(url3, detail);
|
|
93441
|
+
if (fromUrl > 0 || !item?.file_id)
|
|
93442
|
+
return fromUrl;
|
|
93443
|
+
return worstCaseImageTokensForDetail(detail);
|
|
93444
|
+
}
|
|
93445
|
+
function countImageTokensInMessages(apiMessages) {
|
|
93446
|
+
let total = 0;
|
|
93447
|
+
for (const msg of apiMessages ?? []) {
|
|
93448
|
+
const content2 = msg?.content;
|
|
93449
|
+
if (!Array.isArray(content2))
|
|
93450
|
+
continue;
|
|
93451
|
+
for (const part of content2) {
|
|
93452
|
+
if (!part || typeof part !== "object")
|
|
93453
|
+
continue;
|
|
93454
|
+
if (part.type === "image_url") {
|
|
93455
|
+
const detail = typeof part.image_url?.detail === "string" && part.image_url?.detail ? part.image_url.detail : "auto";
|
|
93456
|
+
const url3 = typeof part.image_url === "string" ? part.image_url : part.image_url?.url;
|
|
93457
|
+
total += estimateImageTokensForUrl(url3, detail);
|
|
93458
|
+
} else if (part.type === "input_image") {
|
|
93459
|
+
total += estimateInputImageTokens(part);
|
|
93460
|
+
}
|
|
93461
|
+
}
|
|
93462
|
+
}
|
|
93463
|
+
return total;
|
|
93464
|
+
}
|
|
93465
|
+
function countImageTokensInResponsesInput(input) {
|
|
93466
|
+
if (!Array.isArray(input))
|
|
93467
|
+
return 0;
|
|
93468
|
+
let total = 0;
|
|
93469
|
+
for (const item of input) {
|
|
93470
|
+
if (!item || typeof item !== "object")
|
|
93471
|
+
continue;
|
|
93472
|
+
if (item.type === "input_image") {
|
|
93473
|
+
total += estimateInputImageTokens(item);
|
|
93474
|
+
continue;
|
|
93475
|
+
}
|
|
93476
|
+
if (Array.isArray(item.content)) {
|
|
93477
|
+
for (const part of item.content) {
|
|
93478
|
+
if (part && typeof part === "object" && part.type === "input_image") {
|
|
93479
|
+
total += estimateInputImageTokens(part);
|
|
93480
|
+
}
|
|
93481
|
+
}
|
|
93482
|
+
}
|
|
93483
|
+
}
|
|
93484
|
+
return total;
|
|
93485
|
+
}
|
|
93486
|
+
function safeStringifyCompact(value) {
|
|
93487
|
+
try {
|
|
93488
|
+
return JSON.stringify(value);
|
|
93489
|
+
} catch {
|
|
93490
|
+
return null;
|
|
93491
|
+
}
|
|
93492
|
+
}
|
|
93493
|
+
function textLength(value) {
|
|
93494
|
+
if (typeof value === "string")
|
|
93495
|
+
return value.length;
|
|
93496
|
+
if (value !== null && typeof value === "object") {
|
|
93497
|
+
return safeStringifyCompact(value)?.length ?? 0;
|
|
93498
|
+
}
|
|
93499
|
+
return 0;
|
|
93500
|
+
}
|
|
93501
|
+
function countMessageTextChars(apiMessages) {
|
|
93502
|
+
let total = 0;
|
|
93503
|
+
for (const msg of apiMessages ?? []) {
|
|
93504
|
+
if (!msg || typeof msg !== "object")
|
|
93505
|
+
continue;
|
|
93506
|
+
const content2 = msg.content;
|
|
93507
|
+
if (typeof content2 === "string") {
|
|
93508
|
+
total += content2.length;
|
|
93509
|
+
} else if (Array.isArray(content2)) {
|
|
93510
|
+
for (const part of content2) {
|
|
93511
|
+
if (part && typeof part === "object" && part.type === "text") {
|
|
93512
|
+
total += textLength(part.text);
|
|
93513
|
+
}
|
|
93514
|
+
}
|
|
93515
|
+
}
|
|
93516
|
+
const toolCalls = msg.tool_calls;
|
|
93517
|
+
if (Array.isArray(toolCalls)) {
|
|
93518
|
+
for (const call of toolCalls) {
|
|
93519
|
+
const fn = call?.function;
|
|
93520
|
+
if (!fn || typeof fn !== "object")
|
|
93521
|
+
continue;
|
|
93522
|
+
total += textLength(fn.name);
|
|
93523
|
+
total += textLength(fn.arguments);
|
|
93524
|
+
}
|
|
93525
|
+
}
|
|
93526
|
+
}
|
|
93527
|
+
return total;
|
|
93528
|
+
}
|
|
93529
|
+
function countResponsesInputTextChars(input) {
|
|
93530
|
+
if (!Array.isArray(input))
|
|
93531
|
+
return 0;
|
|
93532
|
+
let total = 0;
|
|
93533
|
+
for (const item of input) {
|
|
93534
|
+
if (!item || typeof item !== "object")
|
|
93535
|
+
continue;
|
|
93536
|
+
const itemType = item.type;
|
|
93537
|
+
if (itemType === "input_text") {
|
|
93538
|
+
total += textLength(item.text);
|
|
93539
|
+
continue;
|
|
93540
|
+
}
|
|
93541
|
+
if (itemType === "function_call") {
|
|
93542
|
+
total += textLength(item.arguments);
|
|
93543
|
+
continue;
|
|
93544
|
+
}
|
|
93545
|
+
if (itemType === "function_call_output") {
|
|
93546
|
+
total += textLength(item.output);
|
|
93547
|
+
continue;
|
|
93548
|
+
}
|
|
93549
|
+
if (itemType === "reasoning") {
|
|
93550
|
+
const summary = item.summary;
|
|
93551
|
+
if (Array.isArray(summary)) {
|
|
93552
|
+
for (const part of summary) {
|
|
93553
|
+
if (part && typeof part === "object") {
|
|
93554
|
+
total += textLength(part.text);
|
|
93555
|
+
}
|
|
93556
|
+
}
|
|
93557
|
+
}
|
|
93558
|
+
}
|
|
93559
|
+
const content2 = item.content;
|
|
93560
|
+
if (typeof content2 === "string") {
|
|
93561
|
+
total += content2.length;
|
|
93562
|
+
} else if (Array.isArray(content2)) {
|
|
93563
|
+
for (const part of content2) {
|
|
93564
|
+
if (!part || typeof part !== "object")
|
|
93565
|
+
continue;
|
|
93566
|
+
total += textLength(part.text);
|
|
93567
|
+
if (typeof part.refusal === "string") {
|
|
93568
|
+
total += part.refusal.length;
|
|
93569
|
+
}
|
|
93570
|
+
}
|
|
93571
|
+
}
|
|
93572
|
+
}
|
|
93573
|
+
return total;
|
|
93574
|
+
}
|
|
93575
|
+
var NODE_TOLERANCE_PERCENT = 1;
|
|
93576
|
+
function sumStringChars(node) {
|
|
93577
|
+
if (typeof node === "string")
|
|
93578
|
+
return node.length;
|
|
93579
|
+
if (Array.isArray(node)) {
|
|
93580
|
+
return node.reduce((total, item) => total + sumStringChars(item), 0);
|
|
93581
|
+
}
|
|
93582
|
+
if (node && typeof node === "object") {
|
|
93583
|
+
let total = 0;
|
|
93584
|
+
for (const [key, value] of Object.entries(node)) {
|
|
93585
|
+
total += key.length + sumStringChars(value);
|
|
93586
|
+
}
|
|
93587
|
+
return total;
|
|
93588
|
+
}
|
|
93589
|
+
return 0;
|
|
93590
|
+
}
|
|
93591
|
+
function countPromptTokenIds(node) {
|
|
93592
|
+
if (typeof node === "number" && Number.isInteger(node))
|
|
93593
|
+
return 1;
|
|
93594
|
+
if (Array.isArray(node)) {
|
|
93595
|
+
return node.reduce((total, item) => total + countPromptTokenIds(item), 0);
|
|
93596
|
+
}
|
|
93597
|
+
return 0;
|
|
93598
|
+
}
|
|
93599
|
+
function estimateNodePromptTokens(body) {
|
|
93600
|
+
return Math.floor(sumStringChars(body) / 3) + countPromptTokenIds(body?.prompt);
|
|
93601
|
+
}
|
|
93602
|
+
function nodeGateSats(model2, satsPricing, requestBody, imageTokens) {
|
|
93603
|
+
const maxCost = satsPricing?.max_cost;
|
|
93604
|
+
if (typeof maxCost !== "number" || !Number.isFinite(maxCost))
|
|
93605
|
+
return 0;
|
|
93606
|
+
const toleranceFactor = 1 - NODE_TOLERANCE_PERCENT / 100;
|
|
93607
|
+
const promptPrice = typeof satsPricing.prompt === "number" ? satsPricing.prompt : 0;
|
|
93608
|
+
const completionPrice = typeof satsPricing.completion === "number" ? satsPricing.completion : 0;
|
|
93609
|
+
let gateMsats = Math.max(1, Math.floor(maxCost * 1000 * toleranceFactor));
|
|
93610
|
+
let promptAllowanceSats = typeof satsPricing.max_prompt_cost === "number" ? satsPricing.max_prompt_cost * toleranceFactor : 0;
|
|
93611
|
+
const topProvider = model2?.top_provider;
|
|
93612
|
+
const providerContextLength = topProvider?.context_length;
|
|
93613
|
+
const providerMaxCompletion = topProvider?.max_completion_tokens;
|
|
93614
|
+
let promptTokenLimit;
|
|
93615
|
+
if (topProvider && (providerContextLength || providerMaxCompletion)) {
|
|
93616
|
+
if (providerContextLength && providerMaxCompletion) {
|
|
93617
|
+
promptTokenLimit = Math.max(0, providerContextLength - providerMaxCompletion);
|
|
93618
|
+
} else if (providerContextLength) {
|
|
93619
|
+
promptTokenLimit = providerContextLength;
|
|
93620
|
+
} else {
|
|
93621
|
+
promptTokenLimit = 0;
|
|
93622
|
+
}
|
|
93623
|
+
} else if (model2?.context_length) {
|
|
93624
|
+
promptTokenLimit = model2.context_length;
|
|
93625
|
+
}
|
|
93626
|
+
if (promptTokenLimit !== undefined) {
|
|
93627
|
+
promptAllowanceSats = promptTokenLimit * promptPrice * toleranceFactor;
|
|
93628
|
+
}
|
|
93629
|
+
const promptTokens = estimateNodePromptTokens(requestBody) + (Array.isArray(requestBody?.messages) ? imageTokens : 0);
|
|
93630
|
+
if (promptTokens > 0) {
|
|
93631
|
+
const unusedPromptBudget = promptAllowanceSats - promptTokens * promptPrice;
|
|
93632
|
+
if (unusedPromptBudget > 0) {
|
|
93633
|
+
gateMsats -= Math.floor(unusedPromptBudget * 1000);
|
|
93634
|
+
}
|
|
93635
|
+
}
|
|
93636
|
+
const rawMaxTokens = requestBody?.max_tokens;
|
|
93637
|
+
const parsedMaxTokens = typeof rawMaxTokens === "number" ? rawMaxTokens : typeof rawMaxTokens === "string" && rawMaxTokens.trim() !== "" ? Number(rawMaxTokens) : NaN;
|
|
93638
|
+
if (Number.isFinite(parsedMaxTokens) && parsedMaxTokens > 0 && typeof satsPricing?.max_completion_cost === "number" && completionPrice > 0 && !isTinfoilModel(model2.id)) {
|
|
93639
|
+
const unusedCompletionBudget = satsPricing.max_completion_cost * toleranceFactor - parsedMaxTokens * completionPrice;
|
|
93640
|
+
if (unusedCompletionBudget > 0) {
|
|
93641
|
+
gateMsats -= Math.floor(unusedCompletionBudget * 1000);
|
|
93642
|
+
}
|
|
93643
|
+
}
|
|
93644
|
+
return Math.max(gateMsats, 1) / 1000;
|
|
93645
|
+
}
|
|
92856
93646
|
var ProviderManager = class _ProviderManager {
|
|
92857
93647
|
constructor(discoveryAdapter, store, logger3) {
|
|
92858
93648
|
this.discoveryAdapter = discoveryAdapter;
|
|
@@ -93095,35 +93885,45 @@ ${ranking}`);
|
|
|
93095
93885
|
}
|
|
93096
93886
|
return providerMints.includes(mintUrl);
|
|
93097
93887
|
}
|
|
93098
|
-
getRequiredSatsForModel(model2, apiMessages, maxTokens) {
|
|
93888
|
+
getRequiredSatsForModel(model2, apiMessages, maxTokens, requestBody) {
|
|
93099
93889
|
try {
|
|
93890
|
+
const body = requestBody ?? {};
|
|
93100
93891
|
let imageTokens = 0;
|
|
93101
|
-
|
|
93102
|
-
|
|
93103
|
-
|
|
93104
|
-
|
|
93105
|
-
|
|
93106
|
-
|
|
93107
|
-
|
|
93108
|
-
|
|
93109
|
-
|
|
93110
|
-
|
|
93111
|
-
|
|
93112
|
-
|
|
93113
|
-
|
|
93114
|
-
|
|
93115
|
-
|
|
93116
|
-
|
|
93892
|
+
let textChars = 0;
|
|
93893
|
+
let sawPromptShape = false;
|
|
93894
|
+
let textEstimateUnknown = false;
|
|
93895
|
+
if (Array.isArray(apiMessages) && apiMessages.length > 0) {
|
|
93896
|
+
sawPromptShape = true;
|
|
93897
|
+
imageTokens += countImageTokensInMessages(apiMessages);
|
|
93898
|
+
textChars += countMessageTextChars(apiMessages);
|
|
93899
|
+
}
|
|
93900
|
+
const responsesInput = body.input;
|
|
93901
|
+
if (!sawPromptShape) {
|
|
93902
|
+
if (Array.isArray(responsesInput)) {
|
|
93903
|
+
sawPromptShape = true;
|
|
93904
|
+
imageTokens += countImageTokensInResponsesInput(responsesInput);
|
|
93905
|
+
textChars += countResponsesInputTextChars(responsesInput);
|
|
93906
|
+
} else if (typeof responsesInput === "string") {
|
|
93907
|
+
sawPromptShape = true;
|
|
93908
|
+
textChars += responsesInput.length;
|
|
93909
|
+
}
|
|
93910
|
+
}
|
|
93911
|
+
const instructions = body.instructions;
|
|
93912
|
+
if (typeof instructions === "string" && instructions) {
|
|
93913
|
+
sawPromptShape = true;
|
|
93914
|
+
textChars += instructions.length;
|
|
93915
|
+
}
|
|
93916
|
+
const tools = body.tools;
|
|
93917
|
+
if (Array.isArray(tools) && tools.length > 0) {
|
|
93918
|
+
sawPromptShape = true;
|
|
93919
|
+
const serialized = safeStringifyCompact(tools);
|
|
93920
|
+
if (serialized === null) {
|
|
93921
|
+
textEstimateUnknown = true;
|
|
93922
|
+
} else {
|
|
93923
|
+
textChars += serialized.length;
|
|
93117
93924
|
}
|
|
93118
93925
|
}
|
|
93119
|
-
const
|
|
93120
|
-
if (Array.isArray(m?.content)) {
|
|
93121
|
-
const filtered = m.content.filter((p) => !(p && typeof p === "object" && p.type === "image_url"));
|
|
93122
|
-
return { ...m, content: filtered };
|
|
93123
|
-
}
|
|
93124
|
-
return m;
|
|
93125
|
-
}) : undefined;
|
|
93126
|
-
const approximateTokens = apiMessagesNoImages ? Math.ceil(JSON.stringify(apiMessagesNoImages, null, 2).length / 2.84) : 1e4;
|
|
93926
|
+
const approximateTokens = textEstimateUnknown ? 1e4 : sawPromptShape ? Math.ceil(textChars / 2.84) : 1e4;
|
|
93127
93927
|
const totalInputTokens = approximateTokens + imageTokens;
|
|
93128
93928
|
const sp = model2?.sats_pricing;
|
|
93129
93929
|
if (!sp) {
|
|
@@ -93138,11 +93938,17 @@ ${ranking}`);
|
|
|
93138
93938
|
if (maxTokens !== undefined && sp.completion && !isTinfoilModel(model2.id)) {
|
|
93139
93939
|
completionCost = sp.completion * maxTokens;
|
|
93140
93940
|
}
|
|
93141
|
-
const
|
|
93941
|
+
const componentEstimate = (promptCosts + completionCost + requestFee) * 1.05;
|
|
93942
|
+
const gateEstimate = nodeGateSats(model2, sp, body, imageTokens) * 1.05;
|
|
93943
|
+
let totalEstimatedCosts = Math.max(componentEstimate, gateEstimate);
|
|
93944
|
+
if (typeof sp.max_cost === "number" && totalEstimatedCosts > sp.max_cost) {
|
|
93945
|
+
return sp.max_cost;
|
|
93946
|
+
}
|
|
93142
93947
|
return totalEstimatedCosts;
|
|
93143
93948
|
} catch (e13) {
|
|
93144
93949
|
this.logger.error("getRequiredSatsForModel error:", e13);
|
|
93145
|
-
|
|
93950
|
+
const sp = model2?.sats_pricing;
|
|
93951
|
+
return sp?.max_cost ?? 50;
|
|
93146
93952
|
}
|
|
93147
93953
|
}
|
|
93148
93954
|
};
|
|
@@ -94556,7 +95362,6 @@ var RoutstrClient = class {
|
|
|
94556
95362
|
const satsSpent = await this._handlePostResponseBalanceUpdate({
|
|
94557
95363
|
token: prepared.tokenUsed,
|
|
94558
95364
|
baseUrl: prepared.baseUrlUsed,
|
|
94559
|
-
mintUrl: params.mintUrl,
|
|
94560
95365
|
initialTokenBalance: prepared.tokenBalanceInSats,
|
|
94561
95366
|
initialTokenBalanceUnknown: prepared.tokenBalanceUnknown,
|
|
94562
95367
|
fallbackSatsSpent: usage?.satsCost,
|
|
@@ -94612,17 +95417,22 @@ var RoutstrClient = class {
|
|
|
94612
95417
|
messageCount: requestMessages.length,
|
|
94613
95418
|
maxTokens: requestMaxTokens
|
|
94614
95419
|
});
|
|
94615
|
-
requiredSats = this.providerManager.getRequiredSatsForModel(selectedModel, requestMessages, requestMaxTokens);
|
|
95420
|
+
requiredSats = this.providerManager.getRequiredSatsForModel(selectedModel, requestMessages, requestMaxTokens, requestBodyForPricing);
|
|
94616
95421
|
}
|
|
94617
95422
|
}
|
|
94618
95423
|
let requestBody = body;
|
|
94619
95424
|
if (body && typeof body === "object") {
|
|
94620
95425
|
const bodyObj = body;
|
|
94621
|
-
if (!bodyObj.stream) {
|
|
95426
|
+
if (isOpenAiJsonBodyPath(requestPath) && !bodyObj.stream) {
|
|
94622
95427
|
requestBody = { ...bodyObj, stream: false };
|
|
94623
95428
|
}
|
|
94624
95429
|
}
|
|
94625
95430
|
const baseHeaders = this._buildBaseHeaders();
|
|
95431
|
+
for (const [name16, value] of Object.entries(headers)) {
|
|
95432
|
+
if (name16.toLowerCase() === "x-routstr-model-path") {
|
|
95433
|
+
baseHeaders["x-routstr-model-path"] = value;
|
|
95434
|
+
}
|
|
95435
|
+
}
|
|
94626
95436
|
const tinfoilEnabled = Boolean(modelId && isTinfoilModel(modelId));
|
|
94627
95437
|
if (tinfoilEnabled) {
|
|
94628
95438
|
this._log("DEBUG", `[RoutstrClient] Attesting Tinfoil model ${modelId} before spend`);
|
|
@@ -95128,7 +95938,7 @@ var RoutstrClient = class {
|
|
|
95128
95938
|
this._log("DEBUG", `[RoutstrClient] _handleErrorResponse: Failing over to next provider: ${nextProvider}, model: ${selectedModel.id}`);
|
|
95129
95939
|
const newModel = await this.providerManager.getModelForProvider(nextProvider, selectedModel.id) ?? selectedModel;
|
|
95130
95940
|
const messagesForPricing = Array.isArray(body?.messages) ? body.messages : [];
|
|
95131
|
-
const newRequiredSats = this.providerManager.getRequiredSatsForModel(newModel, messagesForPricing, params.maxTokens);
|
|
95941
|
+
const newRequiredSats = this.providerManager.getRequiredSatsForModel(newModel, messagesForPricing, params.maxTokens, body && typeof body === "object" ? body : undefined);
|
|
95132
95942
|
if (params.tinfoilEnabled) {
|
|
95133
95943
|
this._log("DEBUG", `[RoutstrClient] _handleErrorResponse: Attesting Tinfoil failover provider ${nextProvider} before spend`);
|
|
95134
95944
|
await prepareTinfoilClient({ baseUrl: nextProvider });
|
|
@@ -95253,7 +96063,6 @@ var RoutstrClient = class {
|
|
|
95253
96063
|
const {
|
|
95254
96064
|
token,
|
|
95255
96065
|
baseUrl,
|
|
95256
|
-
mintUrl,
|
|
95257
96066
|
initialTokenBalance,
|
|
95258
96067
|
initialTokenBalanceUnknown,
|
|
95259
96068
|
fallbackSatsSpent,
|
|
@@ -95812,6 +96621,20 @@ function makeConsoleLogger2(prefix) {
|
|
|
95812
96621
|
};
|
|
95813
96622
|
}
|
|
95814
96623
|
var consoleLogger2 = makeConsoleLogger2();
|
|
96624
|
+
var InsufficientBalanceError2 = class extends Error {
|
|
96625
|
+
constructor(required2, available, maxMintBalance = 0, maxMintUrl = "", customMessage) {
|
|
96626
|
+
super(customMessage ?? `Insufficient balance: need ${required2} sats, have ${available} sats available. ` + (maxMintBalance > 0 ? `Largest mint balance: ${maxMintBalance} sats from ${maxMintUrl}` : ""));
|
|
96627
|
+
this.required = required2;
|
|
96628
|
+
this.available = available;
|
|
96629
|
+
this.maxMintBalance = maxMintBalance;
|
|
96630
|
+
this.maxMintUrl = maxMintUrl;
|
|
96631
|
+
this.name = "InsufficientBalanceError";
|
|
96632
|
+
}
|
|
96633
|
+
required;
|
|
96634
|
+
available;
|
|
96635
|
+
maxMintBalance;
|
|
96636
|
+
maxMintUrl;
|
|
96637
|
+
};
|
|
95815
96638
|
var ProviderBootstrapError2 = class extends Error {
|
|
95816
96639
|
constructor(failedProviders, message) {
|
|
95817
96640
|
super(message || `Failed to bootstrap providers. Tried: ${failedProviders.join(", ")}`);
|
|
@@ -95826,6 +96649,47 @@ var NoProvidersAvailableError2 = class extends Error {
|
|
|
95826
96649
|
this.name = "NoProvidersAvailableError";
|
|
95827
96650
|
}
|
|
95828
96651
|
};
|
|
96652
|
+
var CoreErrorType2 = {
|
|
96653
|
+
TOKEN_ALREADY_SPENT: "token_already_spent",
|
|
96654
|
+
INVALID_TOKEN: "invalid_token",
|
|
96655
|
+
MINT_ERROR: "mint_error",
|
|
96656
|
+
MINT_UNREACHABLE: "mint_unreachable",
|
|
96657
|
+
CASHU_ERROR: "cashu_error",
|
|
96658
|
+
INSUFFICIENT_QUOTA: "insufficient_quota",
|
|
96659
|
+
MINIMUM_BALANCE_REQUIRED: "minimum_balance_required",
|
|
96660
|
+
TOKEN_CONSUMED: "token_consumed",
|
|
96661
|
+
API_ERROR: "api_error",
|
|
96662
|
+
PAYMENT_ERROR: "payment_error"
|
|
96663
|
+
};
|
|
96664
|
+
var CoreErrorCode2 = {
|
|
96665
|
+
TOKEN_ALREADY_SPENT: "cashu_token_already_spent",
|
|
96666
|
+
INVALID_CASHU_TOKEN: "invalid_cashu_token",
|
|
96667
|
+
CASHU_TOKEN_SWAP_FEES_EXCEED_AMOUNT: "cashu_token_swap_fees_exceed_amount",
|
|
96668
|
+
CASHU_FOREIGN_MINT_SWAP_FAILED: "cashu_foreign_mint_swap_failed",
|
|
96669
|
+
CASHU_MINT_UNREACHABLE: "cashu_mint_unreachable",
|
|
96670
|
+
CASHU_TOKEN_REDEMPTION_FAILED: "cashu_token_redemption_failed",
|
|
96671
|
+
CASHU_TOKEN_ZERO_VALUE: "cashu_token_zero_value",
|
|
96672
|
+
CASHU_TOKEN_CONSUMED: "cashu_token_consumed",
|
|
96673
|
+
INTERNAL_ERROR: "internal_error",
|
|
96674
|
+
INVALID_API_KEY: "invalid_api_key",
|
|
96675
|
+
INSUFFICIENT_BALANCE: "insufficient_balance",
|
|
96676
|
+
BALANCE_LIMIT_EXCEEDED: "balance_limit_exceeded"
|
|
96677
|
+
};
|
|
96678
|
+
function isInvalidTokenError2(parsed) {
|
|
96679
|
+
return parsed.type === CoreErrorType2.INVALID_TOKEN && parsed.code === CoreErrorCode2.INVALID_CASHU_TOKEN;
|
|
96680
|
+
}
|
|
96681
|
+
function isCashuRedemptionError2(parsed) {
|
|
96682
|
+
return parsed.type === CoreErrorType2.CASHU_ERROR && (parsed.code === CoreErrorCode2.CASHU_TOKEN_REDEMPTION_FAILED || parsed.code === CoreErrorCode2.CASHU_TOKEN_ZERO_VALUE);
|
|
96683
|
+
}
|
|
96684
|
+
function isTokenConsumedError2(parsed) {
|
|
96685
|
+
return parsed.type === CoreErrorType2.TOKEN_CONSUMED && parsed.code === CoreErrorCode2.CASHU_TOKEN_CONSUMED;
|
|
96686
|
+
}
|
|
96687
|
+
function isCoreInternalError2(parsed) {
|
|
96688
|
+
return parsed.type === CoreErrorType2.API_ERROR && parsed.code === CoreErrorCode2.INTERNAL_ERROR;
|
|
96689
|
+
}
|
|
96690
|
+
function isHandledRedemptionError2(parsed) {
|
|
96691
|
+
return isInvalidTokenError2(parsed) || isCashuRedemptionError2(parsed) || isTokenConsumedError2(parsed) || isCoreInternalError2(parsed);
|
|
96692
|
+
}
|
|
95829
96693
|
var DEFAULT_NOSTR_RELAYS2 = [
|
|
95830
96694
|
"wss://relay.damus.io",
|
|
95831
96695
|
"wss://nos.lol",
|
|
@@ -96549,49 +97413,535 @@ var ModelManager2 = class _ModelManager2 {
|
|
|
96549
97413
|
}
|
|
96550
97414
|
}
|
|
96551
97415
|
};
|
|
96552
|
-
|
|
96553
|
-
|
|
96554
|
-
|
|
96555
|
-
|
|
96556
|
-
|
|
97416
|
+
function isNetworkErrorMessage2(message) {
|
|
97417
|
+
return message.includes("NetworkError when attempting to fetch resource") || message.includes("Failed to fetch") || message.includes("Load failed") || message.includes("Unable to connect") || message.includes("Was there a typo in the url or port") || message.includes("ERR_TLS_CERT_ALTNAME_INVALID") || message.includes("ERR_TLS_CERT_NOT_YET_VALID") || message.includes("ERR_TLS_CERT_EXPIRED") || message.includes("UNABLE_TO_VERIFY_LEAF_SIGNATURE") || message.includes("SELF_SIGNED_CERT_IN_CHAIN");
|
|
97418
|
+
}
|
|
97419
|
+
function getBalanceInSats2(balance, unit) {
|
|
97420
|
+
return unit === "msat" ? balance / 1000 : balance;
|
|
97421
|
+
}
|
|
97422
|
+
var CashuSpender2 = class _CashuSpender2 {
|
|
97423
|
+
constructor(walletAdapter, storageAdapter, _discoveryAdapter, balanceManager, logger5) {
|
|
97424
|
+
this.walletAdapter = walletAdapter;
|
|
97425
|
+
this.storageAdapter = storageAdapter;
|
|
97426
|
+
this._discoveryAdapter = _discoveryAdapter;
|
|
97427
|
+
this.balanceManager = balanceManager;
|
|
97428
|
+
this.logger = (logger5 ?? consoleLogger2).child("CashuSpender");
|
|
97429
|
+
}
|
|
97430
|
+
walletAdapter;
|
|
97431
|
+
storageAdapter;
|
|
97432
|
+
_discoveryAdapter;
|
|
97433
|
+
balanceManager;
|
|
97434
|
+
_isBusy = false;
|
|
97435
|
+
debugLevel = "WARN";
|
|
97436
|
+
logger;
|
|
97437
|
+
static MAX_REFUND_RETRIES = 3;
|
|
97438
|
+
static REFUND_RETRY_INTERVAL_MS = 2 * 60 * 1000;
|
|
97439
|
+
_refundRetryInterval = null;
|
|
97440
|
+
async receiveToken(token) {
|
|
97441
|
+
try {
|
|
97442
|
+
const result = await this.walletAdapter.receiveToken(token);
|
|
97443
|
+
return result;
|
|
97444
|
+
} catch (error53) {
|
|
97445
|
+
const errorMessage = error53 instanceof Error ? error53.message : String(error53);
|
|
97446
|
+
if (errorMessage.includes("Failed to fetch mint")) {
|
|
97447
|
+
const cachedTokens = this.storageAdapter.getCachedReceiveTokens();
|
|
97448
|
+
const existingIndex = cachedTokens.findIndex((t) => t.token === token);
|
|
97449
|
+
if (existingIndex === -1) {
|
|
97450
|
+
const { amount: amount2, unit: unit2 } = this._decodeTokenAmount(token);
|
|
97451
|
+
this.storageAdapter.setCachedReceiveTokens([
|
|
97452
|
+
...cachedTokens,
|
|
97453
|
+
{
|
|
97454
|
+
token,
|
|
97455
|
+
amount: amount2,
|
|
97456
|
+
unit: unit2,
|
|
97457
|
+
createdAt: Date.now()
|
|
97458
|
+
}
|
|
97459
|
+
]);
|
|
97460
|
+
}
|
|
97461
|
+
}
|
|
97462
|
+
const { amount, unit } = this._decodeTokenAmount(token);
|
|
97463
|
+
return { success: false, amount, unit, message: errorMessage };
|
|
96557
97464
|
}
|
|
96558
|
-
return _AuditLogger2.instance;
|
|
96559
97465
|
}
|
|
96560
|
-
|
|
96561
|
-
|
|
96562
|
-
|
|
96563
|
-
|
|
97466
|
+
_decodeTokenAmount(token) {
|
|
97467
|
+
try {
|
|
97468
|
+
const metadata = ur(token);
|
|
97469
|
+
const unit = metadata.unit || "sat";
|
|
97470
|
+
return { amount: metadata.amount, unit };
|
|
97471
|
+
} catch {
|
|
97472
|
+
return { amount: 0, unit: "sat" };
|
|
97473
|
+
}
|
|
97474
|
+
}
|
|
97475
|
+
async _getBalanceState() {
|
|
97476
|
+
if (this.balanceManager) {
|
|
97477
|
+
return this.balanceManager.getBalanceState();
|
|
97478
|
+
}
|
|
97479
|
+
const mintBalances = await this.walletAdapter.getBalances();
|
|
97480
|
+
const units = this.walletAdapter.getMintUnits();
|
|
97481
|
+
let totalMintBalance = 0;
|
|
97482
|
+
const normalizedMintBalances = {};
|
|
97483
|
+
for (const url4 in mintBalances) {
|
|
97484
|
+
const balance = mintBalances[url4];
|
|
97485
|
+
const unit = units[url4];
|
|
97486
|
+
const balanceInSats = getBalanceInSats2(balance, unit);
|
|
97487
|
+
normalizedMintBalances[url4] = balanceInSats;
|
|
97488
|
+
totalMintBalance += balanceInSats;
|
|
97489
|
+
}
|
|
97490
|
+
const providerBalances = {};
|
|
97491
|
+
let totalProviderBalance = 0;
|
|
97492
|
+
const apiKeys = this.storageAdapter.getAllApiKeys();
|
|
97493
|
+
for (const apiKey of apiKeys) {
|
|
97494
|
+
if (!providerBalances[apiKey.baseUrl]) {
|
|
97495
|
+
providerBalances[apiKey.baseUrl] = 0;
|
|
97496
|
+
}
|
|
97497
|
+
providerBalances[apiKey.baseUrl] += apiKey.balance;
|
|
97498
|
+
totalProviderBalance += apiKey.balance;
|
|
97499
|
+
}
|
|
97500
|
+
return {
|
|
97501
|
+
totalBalance: totalMintBalance + totalProviderBalance,
|
|
97502
|
+
providerBalances,
|
|
97503
|
+
mintBalances: normalizedMintBalances
|
|
96564
97504
|
};
|
|
96565
|
-
|
|
96566
|
-
|
|
96567
|
-
|
|
97505
|
+
}
|
|
97506
|
+
get isBusy() {
|
|
97507
|
+
return this._isBusy;
|
|
97508
|
+
}
|
|
97509
|
+
getDebugLevel() {
|
|
97510
|
+
return this.debugLevel;
|
|
97511
|
+
}
|
|
97512
|
+
setDebugLevel(level) {
|
|
97513
|
+
this.debugLevel = level;
|
|
97514
|
+
}
|
|
97515
|
+
_log(level, ...args) {
|
|
97516
|
+
const levelPriority = {
|
|
97517
|
+
DEBUG: 0,
|
|
97518
|
+
WARN: 1,
|
|
97519
|
+
ERROR: 2
|
|
97520
|
+
};
|
|
97521
|
+
if (levelPriority[level] >= levelPriority[this.debugLevel]) {
|
|
97522
|
+
switch (level) {
|
|
97523
|
+
case "DEBUG":
|
|
97524
|
+
this.logger.log(...args);
|
|
97525
|
+
break;
|
|
97526
|
+
case "WARN":
|
|
97527
|
+
this.logger.warn(...args);
|
|
97528
|
+
break;
|
|
97529
|
+
case "ERROR":
|
|
97530
|
+
this.logger.error(...args);
|
|
97531
|
+
break;
|
|
97532
|
+
}
|
|
97533
|
+
}
|
|
97534
|
+
}
|
|
97535
|
+
async spend(options) {
|
|
97536
|
+
const {
|
|
97537
|
+
mintUrl,
|
|
97538
|
+
amount,
|
|
97539
|
+
baseUrl,
|
|
97540
|
+
reuseToken = false,
|
|
97541
|
+
p2pkPubkey,
|
|
97542
|
+
excludeMints = [],
|
|
97543
|
+
retryCount = 0
|
|
97544
|
+
} = options;
|
|
97545
|
+
this._isBusy = true;
|
|
97546
|
+
try {
|
|
97547
|
+
const result = await this._spendInternal({
|
|
97548
|
+
mintUrl,
|
|
97549
|
+
amount,
|
|
97550
|
+
baseUrl,
|
|
97551
|
+
reuseToken,
|
|
97552
|
+
p2pkPubkey,
|
|
97553
|
+
excludeMints,
|
|
97554
|
+
retryCount
|
|
97555
|
+
});
|
|
97556
|
+
if (result.status === "failed" || !result.token) {
|
|
97557
|
+
const errorMsg = result.error || `Insufficient balance. Need ${amount} sats.`;
|
|
97558
|
+
if (this._isNetworkError(errorMsg)) {
|
|
97559
|
+
throw new Error(`Your mint ${mintUrl} is unreachable or is blocking your IP. Please try again later or switch mints.`);
|
|
97560
|
+
}
|
|
97561
|
+
if (result.errorDetails) {
|
|
97562
|
+
throw new InsufficientBalanceError2(result.errorDetails.required, result.errorDetails.available, result.errorDetails.maxMintBalance, result.errorDetails.maxMintUrl);
|
|
97563
|
+
}
|
|
97564
|
+
throw new Error(errorMsg);
|
|
97565
|
+
}
|
|
97566
|
+
return result;
|
|
97567
|
+
} finally {
|
|
97568
|
+
this._isBusy = false;
|
|
97569
|
+
}
|
|
97570
|
+
}
|
|
97571
|
+
_isNetworkError(message) {
|
|
97572
|
+
return isNetworkErrorMessage2(message) || message.includes("Your mint") && message.includes("unreachable");
|
|
97573
|
+
}
|
|
97574
|
+
async _spendInternal(options) {
|
|
97575
|
+
let {
|
|
97576
|
+
mintUrl,
|
|
97577
|
+
amount,
|
|
97578
|
+
baseUrl,
|
|
97579
|
+
reuseToken,
|
|
97580
|
+
p2pkPubkey,
|
|
97581
|
+
excludeMints,
|
|
97582
|
+
retryCount
|
|
97583
|
+
} = options;
|
|
97584
|
+
this._log("DEBUG", `[CashuSpender] _spendInternal: amount=${amount}, mintUrl=${mintUrl}, baseUrl=${baseUrl}, reuseToken=${reuseToken}`);
|
|
97585
|
+
let adjustedAmount = Math.ceil(amount);
|
|
97586
|
+
if (!adjustedAmount || isNaN(adjustedAmount)) {
|
|
97587
|
+
this._log("ERROR", `[CashuSpender] _spendInternal: Invalid amount: ${amount}`);
|
|
97588
|
+
return {
|
|
97589
|
+
token: null,
|
|
97590
|
+
status: "failed",
|
|
97591
|
+
balance: 0,
|
|
97592
|
+
error: "Please enter a valid amount"
|
|
97593
|
+
};
|
|
97594
|
+
}
|
|
97595
|
+
if (reuseToken && baseUrl) {
|
|
97596
|
+
this._log("DEBUG", `[CashuSpender] _spendInternal: Attempting to reuse token for ${baseUrl}`);
|
|
97597
|
+
const existingResult = await this._tryReuseToken(baseUrl, adjustedAmount, mintUrl);
|
|
97598
|
+
if (existingResult) {
|
|
97599
|
+
this._log("DEBUG", `[CashuSpender] _spendInternal: Successfully reused token, balance: ${existingResult.balance}`);
|
|
97600
|
+
return existingResult;
|
|
97601
|
+
}
|
|
97602
|
+
this._log("DEBUG", `[CashuSpender] _spendInternal: Could not reuse token, will create new token`);
|
|
97603
|
+
}
|
|
97604
|
+
const balanceState = await this._getBalanceState();
|
|
97605
|
+
const totalAvailableBalance = balanceState.totalBalance;
|
|
97606
|
+
this._log("DEBUG", `[CashuSpender] _spendInternal: totalAvailableBalance=${totalAvailableBalance}, adjustedAmount=${adjustedAmount}`);
|
|
97607
|
+
if (totalAvailableBalance < adjustedAmount) {
|
|
97608
|
+
this._log("ERROR", `[CashuSpender] _spendInternal: Insufficient balance, have=${totalAvailableBalance}, need=${adjustedAmount}`);
|
|
97609
|
+
return this._createInsufficientBalanceError(adjustedAmount, balanceState.mintBalances, totalAvailableBalance);
|
|
97610
|
+
}
|
|
97611
|
+
let token = null;
|
|
97612
|
+
let selectedMintUrl;
|
|
97613
|
+
let spentAmount = adjustedAmount;
|
|
97614
|
+
if (this.balanceManager) {
|
|
97615
|
+
const tokenResult = await this.balanceManager.createProviderToken({
|
|
97616
|
+
mintUrl,
|
|
97617
|
+
baseUrl,
|
|
97618
|
+
amount: adjustedAmount,
|
|
97619
|
+
p2pkPubkey,
|
|
97620
|
+
excludeMints,
|
|
97621
|
+
retryCount
|
|
97622
|
+
});
|
|
97623
|
+
if (!tokenResult.success || !tokenResult.token) {
|
|
97624
|
+
if ((tokenResult.error || "").includes("Insufficient balance")) {
|
|
97625
|
+
return this._createInsufficientBalanceError(adjustedAmount, balanceState.mintBalances, totalAvailableBalance);
|
|
97626
|
+
}
|
|
97627
|
+
return {
|
|
97628
|
+
token: null,
|
|
97629
|
+
status: "failed",
|
|
97630
|
+
balance: 0,
|
|
97631
|
+
error: tokenResult.error || "Failed to create token"
|
|
97632
|
+
};
|
|
97633
|
+
}
|
|
97634
|
+
token = tokenResult.token;
|
|
97635
|
+
selectedMintUrl = tokenResult.selectedMintUrl;
|
|
97636
|
+
spentAmount = tokenResult.amountSpent || adjustedAmount;
|
|
97637
|
+
} else {
|
|
96568
97638
|
try {
|
|
96569
|
-
|
|
96570
|
-
|
|
96571
|
-
const logPath = path2.join(process.cwd(), "audit.log");
|
|
96572
|
-
fs.appendFileSync(logPath, logLine);
|
|
97639
|
+
token = await this.walletAdapter.sendToken(mintUrl, adjustedAmount, p2pkPubkey);
|
|
97640
|
+
selectedMintUrl = mintUrl;
|
|
96573
97641
|
} catch (error53) {
|
|
96574
|
-
|
|
97642
|
+
const errorMsg = error53 instanceof Error ? error53.message : String(error53);
|
|
97643
|
+
return {
|
|
97644
|
+
token: null,
|
|
97645
|
+
status: "failed",
|
|
97646
|
+
balance: 0,
|
|
97647
|
+
error: `Error generating token: ${errorMsg}`
|
|
97648
|
+
};
|
|
96575
97649
|
}
|
|
96576
|
-
} else {
|
|
96577
|
-
console.log("[AUDIT]", logLine.trim());
|
|
96578
97650
|
}
|
|
97651
|
+
if (token) {
|
|
97652
|
+
this._log("DEBUG", `[CashuSpender] _spendInternal: Successfully spent ${spentAmount}, returning token with balance=${spentAmount}`);
|
|
97653
|
+
}
|
|
97654
|
+
this._log("DEBUG", `[CashuSpender] _spendInternal: Successfully spent ${spentAmount}, returning token with balance=${spentAmount}`);
|
|
97655
|
+
const units = this.walletAdapter.getMintUnits();
|
|
97656
|
+
return {
|
|
97657
|
+
token,
|
|
97658
|
+
status: "success",
|
|
97659
|
+
balance: spentAmount,
|
|
97660
|
+
unit: (selectedMintUrl ? units[selectedMintUrl] : units[mintUrl]) || "sat",
|
|
97661
|
+
selectedMintUrl: selectedMintUrl || mintUrl
|
|
97662
|
+
};
|
|
96579
97663
|
}
|
|
96580
|
-
async
|
|
96581
|
-
|
|
96582
|
-
|
|
96583
|
-
|
|
96584
|
-
|
|
96585
|
-
|
|
96586
|
-
|
|
96587
|
-
|
|
96588
|
-
|
|
96589
|
-
|
|
96590
|
-
|
|
96591
|
-
|
|
97664
|
+
async _tryReuseToken(baseUrl, amount, mintUrl) {
|
|
97665
|
+
const apiKeyEntry = this.storageAdapter.getApiKey(baseUrl);
|
|
97666
|
+
if (!apiKeyEntry)
|
|
97667
|
+
return null;
|
|
97668
|
+
const apiKeyDistribution = this.storageAdapter.getApiKeyDistribution();
|
|
97669
|
+
const balanceForBaseUrl = apiKeyDistribution.find((b) => b.baseUrl === baseUrl)?.amount || 0;
|
|
97670
|
+
this._log("DEBUG", "Reusing API key", balanceForBaseUrl, amount);
|
|
97671
|
+
if (balanceForBaseUrl > amount) {
|
|
97672
|
+
const units = this.walletAdapter.getMintUnits();
|
|
97673
|
+
const unit = units[mintUrl] || "sat";
|
|
97674
|
+
return {
|
|
97675
|
+
token: apiKeyEntry.key,
|
|
97676
|
+
status: "success",
|
|
97677
|
+
balance: balanceForBaseUrl,
|
|
97678
|
+
unit
|
|
97679
|
+
};
|
|
97680
|
+
}
|
|
97681
|
+
if (this.balanceManager) {
|
|
97682
|
+
const topUpAmount = Math.ceil(amount * 1.2 - balanceForBaseUrl);
|
|
97683
|
+
const topUpResult = await this.balanceManager.topUp({
|
|
97684
|
+
mintUrl,
|
|
97685
|
+
baseUrl,
|
|
97686
|
+
amount: topUpAmount,
|
|
97687
|
+
token: apiKeyEntry.key
|
|
97688
|
+
});
|
|
97689
|
+
this._log("DEBUG", "TOPUP ", topUpResult);
|
|
97690
|
+
if (topUpResult.success && topUpResult.toppedUpAmount) {
|
|
97691
|
+
const newBalance = balanceForBaseUrl + topUpResult.toppedUpAmount;
|
|
97692
|
+
const units = this.walletAdapter.getMintUnits();
|
|
97693
|
+
const unit = units[mintUrl] || "sat";
|
|
97694
|
+
return {
|
|
97695
|
+
token: apiKeyEntry.key,
|
|
97696
|
+
status: "success",
|
|
97697
|
+
balance: newBalance,
|
|
97698
|
+
unit
|
|
97699
|
+
};
|
|
97700
|
+
}
|
|
97701
|
+
const providerBalance = await this._getProviderTokenBalance(baseUrl, apiKeyEntry.key);
|
|
97702
|
+
this._log("DEBUG", providerBalance);
|
|
97703
|
+
if (providerBalance <= 0) {
|
|
97704
|
+
this.storageAdapter.removeApiKey(baseUrl);
|
|
97705
|
+
}
|
|
97706
|
+
}
|
|
97707
|
+
return null;
|
|
97708
|
+
}
|
|
97709
|
+
async refundXcashuTokens(mintUrl, excludeBaseUrls) {
|
|
97710
|
+
const results = [];
|
|
97711
|
+
const xcashuTokens = this.storageAdapter.getXcashuTokens();
|
|
97712
|
+
const excludedUrls = new Set(excludeBaseUrls || []);
|
|
97713
|
+
for (const [baseUrl, tokens] of Object.entries(xcashuTokens)) {
|
|
97714
|
+
if (excludedUrls.has(baseUrl))
|
|
97715
|
+
continue;
|
|
97716
|
+
for (const xcashuToken of tokens) {
|
|
97717
|
+
try {
|
|
97718
|
+
if (!this.balanceManager) {
|
|
97719
|
+
throw new Error("BalanceManager not available for xcashu refund");
|
|
97720
|
+
}
|
|
97721
|
+
const fetchResult = await this.balanceManager.fetchRefundToken(baseUrl, xcashuToken.token, true);
|
|
97722
|
+
if (!fetchResult.success && fetchResult.status === 425) {
|
|
97723
|
+
results.push({
|
|
97724
|
+
baseUrl,
|
|
97725
|
+
token: xcashuToken.token,
|
|
97726
|
+
success: false,
|
|
97727
|
+
error: fetchResult.error
|
|
97728
|
+
});
|
|
97729
|
+
this._log("WARN", `[CashuSpender] refundXcashuTokens: 425 "Refund is pending" for ${baseUrl}; leaving token in store, tryCount untouched`);
|
|
97730
|
+
continue;
|
|
97731
|
+
}
|
|
97732
|
+
if (!fetchResult.success && fetchResult.parsedError?.type === CoreErrorType2.TOKEN_ALREADY_SPENT) {
|
|
97733
|
+
this.storageAdapter.removeXcashuToken(baseUrl, xcashuToken.token);
|
|
97734
|
+
results.push({
|
|
97735
|
+
baseUrl,
|
|
97736
|
+
token: xcashuToken.token,
|
|
97737
|
+
success: false,
|
|
97738
|
+
error: fetchResult.error
|
|
97739
|
+
});
|
|
97740
|
+
this._log("WARN", `[CashuSpender] refundXcashuTokens: token_already_spent for ${baseUrl}; removing permanently-spent xcashu token from store`);
|
|
97741
|
+
continue;
|
|
97742
|
+
}
|
|
97743
|
+
if (!fetchResult.success && fetchResult.parsedError && isHandledRedemptionError2(fetchResult.parsedError)) {
|
|
97744
|
+
const directReceive = await this.receiveToken(xcashuToken.token);
|
|
97745
|
+
if (directReceive.success) {
|
|
97746
|
+
this.storageAdapter.removeXcashuToken(baseUrl, xcashuToken.token);
|
|
97747
|
+
results.push({
|
|
97748
|
+
baseUrl,
|
|
97749
|
+
token: xcashuToken.token,
|
|
97750
|
+
success: true
|
|
97751
|
+
});
|
|
97752
|
+
this._log("DEBUG", `[CashuSpender] refundXcashuTokens: provider returned ${fetchResult.parsedError.type}/${fetchResult.parsedError.code}; recovered original token directly, amount=${directReceive.amount}`);
|
|
97753
|
+
continue;
|
|
97754
|
+
}
|
|
97755
|
+
this._log("WARN", `[CashuSpender] refundXcashuTokens: provider returned ${fetchResult.parsedError.type}/${fetchResult.parsedError.code}; direct original-token recovery also failed: ${directReceive.message ?? "unknown error"}`);
|
|
97756
|
+
}
|
|
97757
|
+
if (!fetchResult.success && fetchResult.status === 404 && (fetchResult.error || "").includes("Refund not found")) {
|
|
97758
|
+
const currentTryCount = xcashuToken.tryCount ?? 0;
|
|
97759
|
+
const newTryCount = currentTryCount + 1;
|
|
97760
|
+
if (newTryCount >= _CashuSpender2.MAX_REFUND_RETRIES) {
|
|
97761
|
+
this.storageAdapter.removeXcashuToken(baseUrl, xcashuToken.token);
|
|
97762
|
+
this._log("WARN", `[CashuSpender] refundXcashuTokens: 404 "Refund not found" for ${baseUrl} after ${newTryCount} retries; removing unrefundable xcashu token from store`);
|
|
97763
|
+
} else {
|
|
97764
|
+
this.storageAdapter.updateXcashuTokenTryCount(xcashuToken.token, newTryCount);
|
|
97765
|
+
this._log("WARN", `[CashuSpender] refundXcashuTokens: 404 "Refund not found" for ${baseUrl}; tryCount=${newTryCount}/${_CashuSpender2.MAX_REFUND_RETRIES}, will retry in ${_CashuSpender2.REFUND_RETRY_INTERVAL_MS / 1000}s`);
|
|
97766
|
+
this._startRefundRetryInterval(mintUrl);
|
|
97767
|
+
}
|
|
97768
|
+
results.push({
|
|
97769
|
+
baseUrl,
|
|
97770
|
+
token: xcashuToken.token,
|
|
97771
|
+
success: false,
|
|
97772
|
+
error: fetchResult.error
|
|
97773
|
+
});
|
|
97774
|
+
continue;
|
|
97775
|
+
}
|
|
97776
|
+
if (!fetchResult.success || !fetchResult.token) {
|
|
97777
|
+
throw new Error(fetchResult.error || "Failed to fetch refund token from provider");
|
|
97778
|
+
}
|
|
97779
|
+
const receiveResult = await this.receiveToken(fetchResult.token);
|
|
97780
|
+
if (receiveResult.success) {
|
|
97781
|
+
this.storageAdapter.removeXcashuToken(baseUrl, xcashuToken.token);
|
|
97782
|
+
results.push({
|
|
97783
|
+
baseUrl,
|
|
97784
|
+
token: xcashuToken.token,
|
|
97785
|
+
success: true
|
|
97786
|
+
});
|
|
97787
|
+
this._log("DEBUG", `[CashuSpender] refundXcashuTokens: Successfully refunded xcashu token for ${baseUrl}, amount=${receiveResult.amount}`);
|
|
97788
|
+
} else {
|
|
97789
|
+
const currentTryCount = xcashuToken.tryCount ?? 0;
|
|
97790
|
+
const newTryCount = currentTryCount + 1;
|
|
97791
|
+
this.storageAdapter.updateXcashuTokenTryCount(xcashuToken.token, newTryCount);
|
|
97792
|
+
results.push({
|
|
97793
|
+
baseUrl,
|
|
97794
|
+
token: xcashuToken.token,
|
|
97795
|
+
success: false,
|
|
97796
|
+
error: receiveResult.message ?? "Refund failed"
|
|
97797
|
+
});
|
|
97798
|
+
this._log("DEBUG", `[CashuSpender] refundXcashuTokens: Failed to receive refund token for ${baseUrl}, incremented tryCount to ${newTryCount}: ${receiveResult.message}`);
|
|
97799
|
+
}
|
|
97800
|
+
} catch (error53) {
|
|
97801
|
+
const currentTryCount = xcashuToken.tryCount ?? 0;
|
|
97802
|
+
const newTryCount = currentTryCount + 1;
|
|
97803
|
+
this.storageAdapter.updateXcashuTokenTryCount(xcashuToken.token, newTryCount);
|
|
97804
|
+
const errorMessage = error53 instanceof Error ? error53.message : String(error53);
|
|
97805
|
+
results.push({
|
|
97806
|
+
baseUrl,
|
|
97807
|
+
token: xcashuToken.token,
|
|
97808
|
+
success: false,
|
|
97809
|
+
error: errorMessage
|
|
97810
|
+
});
|
|
97811
|
+
this._log("ERROR", `[CashuSpender] refundXcashuTokens: Exception during refund for ${baseUrl}: ${errorMessage}, incremented tryCount to ${newTryCount}`);
|
|
97812
|
+
}
|
|
97813
|
+
}
|
|
97814
|
+
}
|
|
97815
|
+
return results;
|
|
97816
|
+
}
|
|
97817
|
+
_startRefundRetryInterval(mintUrl) {
|
|
97818
|
+
if (this._refundRetryInterval)
|
|
97819
|
+
return;
|
|
97820
|
+
this._log("DEBUG", `[CashuSpender] Starting refund retry interval (every ${_CashuSpender2.REFUND_RETRY_INTERVAL_MS / 1000}s)`);
|
|
97821
|
+
this._refundRetryInterval = setInterval(async () => {
|
|
97822
|
+
const remainingTokens = this.storageAdapter.getXcashuTokens();
|
|
97823
|
+
const hasTokens = Object.values(remainingTokens).some((tokens) => tokens.length > 0);
|
|
97824
|
+
if (!hasTokens) {
|
|
97825
|
+
this._stopRefundRetryInterval();
|
|
97826
|
+
return;
|
|
97827
|
+
}
|
|
97828
|
+
try {
|
|
97829
|
+
await this.refundXcashuTokens(mintUrl);
|
|
97830
|
+
} catch (error53) {
|
|
97831
|
+
this._log("ERROR", `[CashuSpender] Refund retry interval error: ${error53 instanceof Error ? error53.message : String(error53)}`);
|
|
97832
|
+
}
|
|
97833
|
+
}, _CashuSpender2.REFUND_RETRY_INTERVAL_MS);
|
|
97834
|
+
}
|
|
97835
|
+
_stopRefundRetryInterval() {
|
|
97836
|
+
if (this._refundRetryInterval) {
|
|
97837
|
+
clearInterval(this._refundRetryInterval);
|
|
97838
|
+
this._refundRetryInterval = null;
|
|
97839
|
+
this._log("DEBUG", `[CashuSpender] Stopped refund retry interval`);
|
|
97840
|
+
}
|
|
97841
|
+
}
|
|
97842
|
+
async refundProviders(mintUrl, forceRefund) {
|
|
97843
|
+
const results = [];
|
|
97844
|
+
const apiKeyDistribution = this.storageAdapter.getApiKeyDistribution();
|
|
97845
|
+
for (const apiKeyEntry of apiKeyDistribution) {
|
|
97846
|
+
const apiKeyEntryFull = this.storageAdapter.getApiKey(apiKeyEntry.baseUrl);
|
|
97847
|
+
if (apiKeyEntryFull && this.balanceManager) {
|
|
97848
|
+
try {
|
|
97849
|
+
const balanceResult = await this.balanceManager.getTokenBalance(apiKeyEntryFull.key, apiKeyEntry.baseUrl);
|
|
97850
|
+
if (balanceResult.isInvalidApiKey) {
|
|
97851
|
+
this.logger.warn(`refundProviders: ${apiKeyEntry.baseUrl} returned invalid API key; removing local key and treating as success`);
|
|
97852
|
+
this.storageAdapter.removeApiKey(apiKeyEntry.baseUrl);
|
|
97853
|
+
results.push({
|
|
97854
|
+
baseUrl: apiKeyEntry.baseUrl,
|
|
97855
|
+
success: true
|
|
97856
|
+
});
|
|
97857
|
+
continue;
|
|
97858
|
+
}
|
|
97859
|
+
if (balanceResult.amount >= 0 && !balanceResult.balanceUnknown) {
|
|
97860
|
+
const balanceSat = balanceResult.unit === "msat" ? Math.floor(balanceResult.amount / 1000) : balanceResult.amount;
|
|
97861
|
+
const reservedSat = balanceResult.unit === "msat" ? Math.floor(balanceResult.reserved / 1000) : balanceResult.reserved;
|
|
97862
|
+
this.storageAdapter.updateApiKeyBalance(apiKeyEntry.baseUrl, balanceSat, reservedSat);
|
|
97863
|
+
} else {
|
|
97864
|
+
this.logger.warn(`refundProviders: balance refresh for ${apiKeyEntry.baseUrl} returned negative amount; keeping stale local balance=${apiKeyEntryFull.balance}`);
|
|
97865
|
+
}
|
|
97866
|
+
} catch (error53) {
|
|
97867
|
+
this.logger.warn(`refundProviders: balance refresh threw for ${apiKeyEntry.baseUrl}; proceeding with stale local balance`, error53);
|
|
97868
|
+
}
|
|
97869
|
+
const refreshedEntry = this.storageAdapter.getApiKey(apiKeyEntry.baseUrl);
|
|
97870
|
+
if (!refreshedEntry) {
|
|
97871
|
+
continue;
|
|
97872
|
+
}
|
|
97873
|
+
const refundResult = await this.balanceManager.refundApiKey({
|
|
97874
|
+
mintUrl,
|
|
97875
|
+
baseUrl: apiKeyEntry.baseUrl,
|
|
97876
|
+
apiKey: refreshedEntry.key,
|
|
97877
|
+
forceRefund
|
|
97878
|
+
});
|
|
97879
|
+
if (refundResult.success) {
|
|
97880
|
+
this.storageAdapter.removeApiKey(apiKeyEntry.baseUrl);
|
|
97881
|
+
} else {
|
|
97882
|
+
const currentEntry = this.storageAdapter.getApiKey(apiKeyEntry.baseUrl);
|
|
97883
|
+
this.logger.warn(`refundProviders: refund failed for ${apiKeyEntry.baseUrl}; currentEntry=${Boolean(currentEntry)} balance=${currentEntry?.balance ?? "none"}. Touching lastUsed to rate-limit retries.`);
|
|
97884
|
+
if (currentEntry) {
|
|
97885
|
+
this.storageAdapter.touchApiKeyLastUsed(apiKeyEntry.baseUrl);
|
|
97886
|
+
}
|
|
97887
|
+
}
|
|
97888
|
+
results.push({
|
|
97889
|
+
baseUrl: apiKeyEntry.baseUrl,
|
|
97890
|
+
success: refundResult.success
|
|
97891
|
+
});
|
|
97892
|
+
} else {
|
|
97893
|
+
this.logger.warn(`refundProviders: cannot refund ${apiKeyEntry.baseUrl}; apiKeyEntryFull=${Boolean(apiKeyEntryFull)} balanceManager=${Boolean(this.balanceManager)}`);
|
|
97894
|
+
results.push({
|
|
97895
|
+
baseUrl: apiKeyEntry.baseUrl,
|
|
97896
|
+
success: false
|
|
97897
|
+
});
|
|
97898
|
+
}
|
|
97899
|
+
}
|
|
97900
|
+
return results;
|
|
97901
|
+
}
|
|
97902
|
+
_createInsufficientBalanceError(required2, normalizedBalances, availableBalance) {
|
|
97903
|
+
let maxBalance = 0;
|
|
97904
|
+
let maxMintUrl = "";
|
|
97905
|
+
for (const mintUrl in normalizedBalances) {
|
|
97906
|
+
const balanceInSats = normalizedBalances[mintUrl];
|
|
97907
|
+
if (balanceInSats > maxBalance) {
|
|
97908
|
+
maxBalance = balanceInSats;
|
|
97909
|
+
maxMintUrl = mintUrl;
|
|
97910
|
+
}
|
|
97911
|
+
}
|
|
97912
|
+
const error53 = new InsufficientBalanceError2(required2, availableBalance ?? maxBalance, maxBalance, maxMintUrl);
|
|
97913
|
+
return {
|
|
97914
|
+
token: null,
|
|
97915
|
+
status: "failed",
|
|
97916
|
+
balance: 0,
|
|
97917
|
+
error: error53.message,
|
|
97918
|
+
errorDetails: {
|
|
97919
|
+
required: required2,
|
|
97920
|
+
available: availableBalance ?? maxBalance,
|
|
97921
|
+
maxMintBalance: maxBalance,
|
|
97922
|
+
maxMintUrl
|
|
97923
|
+
}
|
|
97924
|
+
};
|
|
97925
|
+
}
|
|
97926
|
+
async _getProviderTokenBalance(baseUrl, token) {
|
|
97927
|
+
try {
|
|
97928
|
+
const response = await fetch(`${baseUrl}v1/wallet/info`, {
|
|
97929
|
+
headers: {
|
|
97930
|
+
Authorization: `Bearer ${token}`
|
|
97931
|
+
}
|
|
97932
|
+
});
|
|
97933
|
+
if (response.ok) {
|
|
97934
|
+
const data = await response.json();
|
|
97935
|
+
return data.balance / 1000;
|
|
97936
|
+
}
|
|
97937
|
+
} catch {
|
|
97938
|
+
return 0;
|
|
97939
|
+
}
|
|
97940
|
+
return 0;
|
|
96592
97941
|
}
|
|
96593
97942
|
};
|
|
96594
|
-
var
|
|
97943
|
+
var MAX_IMAGE_PATCHES2 = 30000;
|
|
97944
|
+
var MAX_ORIGINAL_IMAGE_TOKENS2 = Math.ceil(MAX_IMAGE_PATCHES2 * 1.2);
|
|
96595
97945
|
var createBunPersistentEventDatabase = async (dbPath) => {
|
|
96596
97946
|
const { BunSqliteEventDatabase: BunSqliteEventDatabase2 } = await Promise.resolve().then(() => (init_bun(), exports_bun));
|
|
96597
97947
|
return new BunSqliteEventDatabase2(dbPath);
|
|
@@ -100997,14 +102347,14 @@ __export(exports_utils4, {
|
|
|
100997
102347
|
numberToBytesLE: () => numberToBytesLE6,
|
|
100998
102348
|
numberToBytesBE: () => numberToBytesBE6,
|
|
100999
102349
|
hexToNumber: () => hexToNumber6,
|
|
101000
|
-
hexToBytes: () =>
|
|
102350
|
+
hexToBytes: () => hexToBytes14,
|
|
101001
102351
|
equalBytes: () => equalBytes9,
|
|
101002
102352
|
ensureBytes: () => ensureBytes5,
|
|
101003
102353
|
createHmacDrbg: () => createHmacDrbg6,
|
|
101004
102354
|
concatBytes: () => concatBytes15,
|
|
101005
102355
|
bytesToNumberLE: () => bytesToNumberLE6,
|
|
101006
102356
|
bytesToNumberBE: () => bytesToNumberBE6,
|
|
101007
|
-
bytesToHex: () =>
|
|
102357
|
+
bytesToHex: () => bytesToHex16,
|
|
101008
102358
|
bitSet: () => bitSet4,
|
|
101009
102359
|
bitMask: () => bitMask6,
|
|
101010
102360
|
bitLen: () => bitLen6,
|
|
@@ -101016,7 +102366,7 @@ var _1n29 = BigInt(1);
|
|
|
101016
102366
|
var _2n23 = BigInt(2);
|
|
101017
102367
|
var u8a11 = (a) => a instanceof Uint8Array;
|
|
101018
102368
|
var hexes11 = /* @__PURE__ */ Array.from({ length: 256 }, (_3, i6) => i6.toString(16).padStart(2, "0"));
|
|
101019
|
-
function
|
|
102369
|
+
function bytesToHex16(bytes10) {
|
|
101020
102370
|
if (!u8a11(bytes10))
|
|
101021
102371
|
throw new Error("Uint8Array expected");
|
|
101022
102372
|
let hex7 = "";
|
|
@@ -101034,7 +102384,7 @@ function hexToNumber6(hex7) {
|
|
|
101034
102384
|
throw new Error("hex string expected, got " + typeof hex7);
|
|
101035
102385
|
return BigInt(hex7 === "" ? "0" : `0x${hex7}`);
|
|
101036
102386
|
}
|
|
101037
|
-
function
|
|
102387
|
+
function hexToBytes14(hex7) {
|
|
101038
102388
|
if (typeof hex7 !== "string")
|
|
101039
102389
|
throw new Error("hex string expected, got " + typeof hex7);
|
|
101040
102390
|
const len = hex7.length;
|
|
@@ -101052,27 +102402,27 @@ function hexToBytes13(hex7) {
|
|
|
101052
102402
|
return array2;
|
|
101053
102403
|
}
|
|
101054
102404
|
function bytesToNumberBE6(bytes10) {
|
|
101055
|
-
return hexToNumber6(
|
|
102405
|
+
return hexToNumber6(bytesToHex16(bytes10));
|
|
101056
102406
|
}
|
|
101057
102407
|
function bytesToNumberLE6(bytes10) {
|
|
101058
102408
|
if (!u8a11(bytes10))
|
|
101059
102409
|
throw new Error("Uint8Array expected");
|
|
101060
|
-
return hexToNumber6(
|
|
102410
|
+
return hexToNumber6(bytesToHex16(Uint8Array.from(bytes10).reverse()));
|
|
101061
102411
|
}
|
|
101062
102412
|
function numberToBytesBE6(n, len) {
|
|
101063
|
-
return
|
|
102413
|
+
return hexToBytes14(n.toString(16).padStart(len * 2, "0"));
|
|
101064
102414
|
}
|
|
101065
102415
|
function numberToBytesLE6(n, len) {
|
|
101066
102416
|
return numberToBytesBE6(n, len).reverse();
|
|
101067
102417
|
}
|
|
101068
102418
|
function numberToVarBytesBE4(n) {
|
|
101069
|
-
return
|
|
102419
|
+
return hexToBytes14(numberToHexUnpadded6(n));
|
|
101070
102420
|
}
|
|
101071
102421
|
function ensureBytes5(title, hex7, expectedLength) {
|
|
101072
102422
|
let res;
|
|
101073
102423
|
if (typeof hex7 === "string") {
|
|
101074
102424
|
try {
|
|
101075
|
-
res =
|
|
102425
|
+
res = hexToBytes14(hex7);
|
|
101076
102426
|
} catch (e29) {
|
|
101077
102427
|
throw new Error(`${title} must be valid hex string, got "${hex7}". Cause: ${e29}`);
|
|
101078
102428
|
}
|
|
@@ -101683,7 +103033,7 @@ function weierstrassPoints4(opts) {
|
|
|
101683
103033
|
const { allowedPrivateKeyLengths: lengths, nByteLength, wrapPrivateKey, n } = CURVE;
|
|
101684
103034
|
if (lengths && typeof key !== "bigint") {
|
|
101685
103035
|
if (key instanceof Uint8Array)
|
|
101686
|
-
key =
|
|
103036
|
+
key = bytesToHex16(key);
|
|
101687
103037
|
if (typeof key !== "string" || !lengths.includes(key.length))
|
|
101688
103038
|
throw new Error("Invalid key");
|
|
101689
103039
|
key = key.padStart(nByteLength * 2, "0");
|
|
@@ -101974,7 +103324,7 @@ function weierstrassPoints4(opts) {
|
|
|
101974
103324
|
return toBytes12(Point5, this, isCompressed);
|
|
101975
103325
|
}
|
|
101976
103326
|
toHex(isCompressed = true) {
|
|
101977
|
-
return
|
|
103327
|
+
return bytesToHex16(this.toRawBytes(isCompressed));
|
|
101978
103328
|
}
|
|
101979
103329
|
}
|
|
101980
103330
|
Point5.BASE = new Point5(CURVE.Gx, CURVE.Gy, Fp6.ONE);
|
|
@@ -102052,7 +103402,7 @@ function weierstrass6(curveDef) {
|
|
|
102052
103402
|
}
|
|
102053
103403
|
}
|
|
102054
103404
|
});
|
|
102055
|
-
const numToNByteStr = (num2) =>
|
|
103405
|
+
const numToNByteStr = (num2) => bytesToHex16(numberToBytesBE6(num2, CURVE.nByteLength));
|
|
102056
103406
|
function isBiggerThanHalfOrder(number13) {
|
|
102057
103407
|
const HALF = CURVE_ORDER >> _1n32;
|
|
102058
103408
|
return number13 > HALF;
|
|
@@ -102113,13 +103463,13 @@ function weierstrass6(curveDef) {
|
|
|
102113
103463
|
return this.hasHighS() ? new Signature(this.r, modN4(-this.s), this.recovery) : this;
|
|
102114
103464
|
}
|
|
102115
103465
|
toDERRawBytes() {
|
|
102116
|
-
return
|
|
103466
|
+
return hexToBytes14(this.toDERHex());
|
|
102117
103467
|
}
|
|
102118
103468
|
toDERHex() {
|
|
102119
103469
|
return DER6.hexFromSig({ r: this.r, s: this.s });
|
|
102120
103470
|
}
|
|
102121
103471
|
toCompactRawBytes() {
|
|
102122
|
-
return
|
|
103472
|
+
return hexToBytes14(this.toCompactHex());
|
|
102123
103473
|
}
|
|
102124
103474
|
toCompactHex() {
|
|
102125
103475
|
return numToNByteStr(this.r) + numToNByteStr(this.s);
|
|
@@ -102545,7 +103895,7 @@ var isLE11 = new Uint8Array(new Uint32Array([287454020]).buffer)[0] === 68;
|
|
|
102545
103895
|
if (!isLE11)
|
|
102546
103896
|
throw new Error("Non little-endian hardware is not supported");
|
|
102547
103897
|
var hexes12 = Array.from({ length: 256 }, (v4, i6) => i6.toString(16).padStart(2, "0"));
|
|
102548
|
-
function
|
|
103898
|
+
function bytesToHex17(bytes10) {
|
|
102549
103899
|
if (!u8a12(bytes10))
|
|
102550
103900
|
throw new Error("Uint8Array expected");
|
|
102551
103901
|
let hex7 = "";
|
|
@@ -102554,7 +103904,7 @@ function bytesToHex16(bytes10) {
|
|
|
102554
103904
|
}
|
|
102555
103905
|
return hex7;
|
|
102556
103906
|
}
|
|
102557
|
-
function
|
|
103907
|
+
function hexToBytes15(hex7) {
|
|
102558
103908
|
if (typeof hex7 !== "string")
|
|
102559
103909
|
throw new Error("hex string expected, got " + typeof hex7);
|
|
102560
103910
|
const len = hex7.length;
|
|
@@ -103322,7 +104672,7 @@ var isLE12 = new Uint8Array(new Uint32Array([287454020]).buffer)[0] === 68;
|
|
|
103322
104672
|
if (!isLE12)
|
|
103323
104673
|
throw new Error("Non little-endian hardware is not supported");
|
|
103324
104674
|
var hexes13 = /* @__PURE__ */ Array.from({ length: 256 }, (_3, i6) => i6.toString(16).padStart(2, "0"));
|
|
103325
|
-
function
|
|
104675
|
+
function bytesToHex18(bytes12) {
|
|
103326
104676
|
bytes11(bytes12);
|
|
103327
104677
|
let hex8 = "";
|
|
103328
104678
|
for (let i6 = 0;i6 < bytes12.length; i6++) {
|
|
@@ -103340,7 +104690,7 @@ function asciiToBase165(char) {
|
|
|
103340
104690
|
return char - (asciis5._a - 10);
|
|
103341
104691
|
return;
|
|
103342
104692
|
}
|
|
103343
|
-
function
|
|
104693
|
+
function hexToBytes16(hex8) {
|
|
103344
104694
|
if (typeof hex8 !== "string")
|
|
103345
104695
|
throw new Error("hex string expected, got " + typeof hex8);
|
|
103346
104696
|
const hl = hex8.length;
|
|
@@ -104883,8 +106233,8 @@ __export4(utils_exports3, {
|
|
|
104883
106233
|
Queue: () => Queue3,
|
|
104884
106234
|
QueueNode: () => QueueNode3,
|
|
104885
106235
|
binarySearch: () => binarySearch5,
|
|
104886
|
-
bytesToHex: () =>
|
|
104887
|
-
hexToBytes: () =>
|
|
106236
|
+
bytesToHex: () => bytesToHex17,
|
|
106237
|
+
hexToBytes: () => hexToBytes15,
|
|
104888
106238
|
insertEventIntoAscendingList: () => insertEventIntoAscendingList5,
|
|
104889
106239
|
insertEventIntoDescendingList: () => insertEventIntoDescendingList5,
|
|
104890
106240
|
normalizeURL: () => normalizeURL5,
|
|
@@ -105010,13 +106360,13 @@ var JS6 = class {
|
|
|
105010
106360
|
return schnorr5.utils.randomPrivateKey();
|
|
105011
106361
|
}
|
|
105012
106362
|
getPublicKey(secretKey) {
|
|
105013
|
-
return
|
|
106363
|
+
return bytesToHex17(schnorr5.getPublicKey(secretKey));
|
|
105014
106364
|
}
|
|
105015
106365
|
finalizeEvent(t, secretKey) {
|
|
105016
106366
|
const event7 = t;
|
|
105017
|
-
event7.pubkey =
|
|
106367
|
+
event7.pubkey = bytesToHex17(schnorr5.getPublicKey(secretKey));
|
|
105018
106368
|
event7.id = getEventHash6(event7);
|
|
105019
|
-
event7.sig =
|
|
106369
|
+
event7.sig = bytesToHex17(schnorr5.sign(getEventHash6(event7), secretKey));
|
|
105020
106370
|
event7[verifiedSymbol9] = true;
|
|
105021
106371
|
return event7;
|
|
105022
106372
|
}
|
|
@@ -105045,7 +106395,7 @@ function serializeEvent6(evt) {
|
|
|
105045
106395
|
}
|
|
105046
106396
|
function getEventHash6(event7) {
|
|
105047
106397
|
let eventHash = sha25611(utf8Encoder9.encode(serializeEvent6(event7)));
|
|
105048
|
-
return
|
|
106398
|
+
return bytesToHex17(eventHash);
|
|
105049
106399
|
}
|
|
105050
106400
|
var i6 = new JS6;
|
|
105051
106401
|
var generateSecretKey6 = i6.generateSecretKey;
|
|
@@ -105893,7 +107243,7 @@ function decode6(code) {
|
|
|
105893
107243
|
return {
|
|
105894
107244
|
type: "nprofile",
|
|
105895
107245
|
data: {
|
|
105896
|
-
pubkey:
|
|
107246
|
+
pubkey: bytesToHex17(tlv[0][0]),
|
|
105897
107247
|
relays: tlv[1] ? tlv[1].map((d) => utf8Decoder9.decode(d)) : []
|
|
105898
107248
|
}
|
|
105899
107249
|
};
|
|
@@ -105911,10 +107261,10 @@ function decode6(code) {
|
|
|
105911
107261
|
return {
|
|
105912
107262
|
type: "nevent",
|
|
105913
107263
|
data: {
|
|
105914
|
-
id:
|
|
107264
|
+
id: bytesToHex17(tlv[0][0]),
|
|
105915
107265
|
relays: tlv[1] ? tlv[1].map((d) => utf8Decoder9.decode(d)) : [],
|
|
105916
|
-
author: tlv[2]?.[0] ?
|
|
105917
|
-
kind: tlv[3]?.[0] ? parseInt(
|
|
107266
|
+
author: tlv[2]?.[0] ? bytesToHex17(tlv[2][0]) : undefined,
|
|
107267
|
+
kind: tlv[3]?.[0] ? parseInt(bytesToHex17(tlv[3][0]), 16) : undefined
|
|
105918
107268
|
}
|
|
105919
107269
|
};
|
|
105920
107270
|
}
|
|
@@ -105934,8 +107284,8 @@ function decode6(code) {
|
|
|
105934
107284
|
type: "naddr",
|
|
105935
107285
|
data: {
|
|
105936
107286
|
identifier: utf8Decoder9.decode(tlv[0][0]),
|
|
105937
|
-
pubkey:
|
|
105938
|
-
kind: parseInt(
|
|
107287
|
+
pubkey: bytesToHex17(tlv[2][0]),
|
|
107288
|
+
kind: parseInt(bytesToHex17(tlv[3][0]), 16),
|
|
105939
107289
|
relays: tlv[1] ? tlv[1].map((d) => utf8Decoder9.decode(d)) : []
|
|
105940
107290
|
}
|
|
105941
107291
|
};
|
|
@@ -105944,7 +107294,7 @@ function decode6(code) {
|
|
|
105944
107294
|
return { type: prefix, data };
|
|
105945
107295
|
case "npub":
|
|
105946
107296
|
case "note":
|
|
105947
|
-
return { type: prefix, data:
|
|
107297
|
+
return { type: prefix, data: bytesToHex17(data) };
|
|
105948
107298
|
default:
|
|
105949
107299
|
throw new Error(`unknown prefix ${prefix}`);
|
|
105950
107300
|
}
|
|
@@ -105968,10 +107318,10 @@ function nsecEncode4(key) {
|
|
|
105968
107318
|
return encodeBytes4("nsec", key);
|
|
105969
107319
|
}
|
|
105970
107320
|
function npubEncode5(hex8) {
|
|
105971
|
-
return encodeBytes4("npub",
|
|
107321
|
+
return encodeBytes4("npub", hexToBytes15(hex8));
|
|
105972
107322
|
}
|
|
105973
107323
|
function noteEncode4(hex8) {
|
|
105974
|
-
return encodeBytes4("note",
|
|
107324
|
+
return encodeBytes4("note", hexToBytes15(hex8));
|
|
105975
107325
|
}
|
|
105976
107326
|
function encodeBech324(prefix, data) {
|
|
105977
107327
|
let words = bech325.toWords(data);
|
|
@@ -105982,7 +107332,7 @@ function encodeBytes4(prefix, bytes12) {
|
|
|
105982
107332
|
}
|
|
105983
107333
|
function nprofileEncode4(profile6) {
|
|
105984
107334
|
let data = encodeTLV4({
|
|
105985
|
-
0: [
|
|
107335
|
+
0: [hexToBytes15(profile6.pubkey)],
|
|
105986
107336
|
1: (profile6.relays || []).map((url4) => utf8Encoder9.encode(url4))
|
|
105987
107337
|
});
|
|
105988
107338
|
return encodeBech324("nprofile", data);
|
|
@@ -105993,9 +107343,9 @@ function neventEncode4(event7) {
|
|
|
105993
107343
|
kindArray = integerToUint8Array3(event7.kind);
|
|
105994
107344
|
}
|
|
105995
107345
|
let data = encodeTLV4({
|
|
105996
|
-
0: [
|
|
107346
|
+
0: [hexToBytes15(event7.id)],
|
|
105997
107347
|
1: (event7.relays || []).map((url4) => utf8Encoder9.encode(url4)),
|
|
105998
|
-
2: event7.author ? [
|
|
107348
|
+
2: event7.author ? [hexToBytes15(event7.author)] : [],
|
|
105999
107349
|
3: kindArray ? [new Uint8Array(kindArray)] : []
|
|
106000
107350
|
});
|
|
106001
107351
|
return encodeBech324("nevent", data);
|
|
@@ -106006,7 +107356,7 @@ function naddrEncode4(addr) {
|
|
|
106006
107356
|
let data = encodeTLV4({
|
|
106007
107357
|
0: [utf8Encoder9.encode(addr.identifier)],
|
|
106008
107358
|
1: (addr.relays || []).map((url4) => utf8Encoder9.encode(url4)),
|
|
106009
|
-
2: [
|
|
107359
|
+
2: [hexToBytes15(addr.pubkey)],
|
|
106010
107360
|
3: [new Uint8Array(kind)]
|
|
106011
107361
|
});
|
|
106012
107362
|
return encodeBech324("naddr", data);
|
|
@@ -106030,7 +107380,7 @@ __export4(nip04_exports3, {
|
|
|
106030
107380
|
encrypt: () => encrypt7
|
|
106031
107381
|
});
|
|
106032
107382
|
function encrypt7(secretKey, pubkey2, text) {
|
|
106033
|
-
const privkey = secretKey instanceof Uint8Array ?
|
|
107383
|
+
const privkey = secretKey instanceof Uint8Array ? bytesToHex17(secretKey) : secretKey;
|
|
106034
107384
|
const key = secp256k15.getSharedSecret(privkey, "02" + pubkey2);
|
|
106035
107385
|
const normalizedKey = getNormalizedX3(key);
|
|
106036
107386
|
let iv = Uint8Array.from(randomBytes10(16));
|
|
@@ -106041,7 +107391,7 @@ function encrypt7(secretKey, pubkey2, text) {
|
|
|
106041
107391
|
return `${ctb64}?iv=${ivb64}`;
|
|
106042
107392
|
}
|
|
106043
107393
|
function decrypt6(secretKey, pubkey2, data) {
|
|
106044
|
-
const privkey = secretKey instanceof Uint8Array ?
|
|
107394
|
+
const privkey = secretKey instanceof Uint8Array ? bytesToHex17(secretKey) : secretKey;
|
|
106045
107395
|
let [ctb64, ivb64] = data.split("?iv=");
|
|
106046
107396
|
let key = secp256k15.getSharedSecret(privkey, "02" + pubkey2);
|
|
106047
107397
|
let normalizedKey = getNormalizedX3(key);
|
|
@@ -106264,7 +107614,7 @@ function minePow3(unsigned, difficulty) {
|
|
|
106264
107614
|
return event7;
|
|
106265
107615
|
}
|
|
106266
107616
|
function fastEventHash3(evt) {
|
|
106267
|
-
return
|
|
107617
|
+
return bytesToHex17(sha25611(utf8Encoder9.encode(JSON.stringify([0, evt.pubkey, evt.created_at, evt.kind, evt.tags, evt.content]))));
|
|
106268
107618
|
}
|
|
106269
107619
|
var nip17_exports3 = {};
|
|
106270
107620
|
__export4(nip17_exports3, {
|
|
@@ -107238,7 +108588,7 @@ var NegentropyStorageVector4 = class {
|
|
|
107238
108588
|
insert(timestamp, id) {
|
|
107239
108589
|
if (this.sealed)
|
|
107240
108590
|
throw Error("already sealed");
|
|
107241
|
-
const idb =
|
|
108591
|
+
const idb = hexToBytes16(id);
|
|
107242
108592
|
if (idb.byteLength !== ID_SIZE4)
|
|
107243
108593
|
throw Error("bad id size for added item");
|
|
107244
108594
|
this.items.push({ timestamp, id: idb });
|
|
@@ -107332,10 +108682,10 @@ var Negentropy4 = class {
|
|
|
107332
108682
|
let output12 = new WrappedBuffer4;
|
|
107333
108683
|
output12.extend(new Uint8Array([PROTOCOL_VERSION4]));
|
|
107334
108684
|
this.splitRange(0, this.storage.size(), this._bound(Number.MAX_VALUE), output12);
|
|
107335
|
-
return
|
|
108685
|
+
return bytesToHex18(output12.unwrap());
|
|
107336
108686
|
}
|
|
107337
108687
|
reconcile(queryMsg, onhave, onneed) {
|
|
107338
|
-
const query2 = new WrappedBuffer4(
|
|
108688
|
+
const query2 = new WrappedBuffer4(hexToBytes16(queryMsg));
|
|
107339
108689
|
this.lastTimestampIn = this.lastTimestampOut = 0;
|
|
107340
108690
|
let fullOutput = new WrappedBuffer4;
|
|
107341
108691
|
fullOutput.extend(new Uint8Array([PROTOCOL_VERSION4]));
|
|
@@ -107378,22 +108728,22 @@ var Negentropy4 = class {
|
|
|
107378
108728
|
let theirElems = {};
|
|
107379
108729
|
for (let i22 = 0;i22 < numIds; i22++) {
|
|
107380
108730
|
let e29 = getBytes5(query2, ID_SIZE4);
|
|
107381
|
-
theirElems[
|
|
108731
|
+
theirElems[bytesToHex18(e29)] = e29;
|
|
107382
108732
|
}
|
|
107383
108733
|
skip3 = true;
|
|
107384
108734
|
this.storage.iterate(lower, upper, (item) => {
|
|
107385
108735
|
let k3 = item.id;
|
|
107386
|
-
const id =
|
|
108736
|
+
const id = bytesToHex18(k3);
|
|
107387
108737
|
if (!theirElems[id]) {
|
|
107388
108738
|
onhave?.(id);
|
|
107389
108739
|
} else {
|
|
107390
|
-
delete theirElems[
|
|
108740
|
+
delete theirElems[bytesToHex18(k3)];
|
|
107391
108741
|
}
|
|
107392
108742
|
return true;
|
|
107393
108743
|
});
|
|
107394
108744
|
if (onneed) {
|
|
107395
108745
|
for (let v4 of Object.values(theirElems)) {
|
|
107396
|
-
onneed(
|
|
108746
|
+
onneed(bytesToHex18(v4));
|
|
107397
108747
|
}
|
|
107398
108748
|
}
|
|
107399
108749
|
} else {
|
|
@@ -107411,7 +108761,7 @@ var Negentropy4 = class {
|
|
|
107411
108761
|
prevIndex = upper;
|
|
107412
108762
|
prevBound = currBound;
|
|
107413
108763
|
}
|
|
107414
|
-
return fullOutput.length === 1 ? null :
|
|
108764
|
+
return fullOutput.length === 1 ? null : bytesToHex18(fullOutput.unwrap());
|
|
107415
108765
|
}
|
|
107416
108766
|
splitRange(lower, upper, upperBound, o) {
|
|
107417
108767
|
let numElems = upper - lower;
|
|
@@ -107661,7 +109011,7 @@ function validateEventMethodTag3(event7, method) {
|
|
|
107661
109011
|
}
|
|
107662
109012
|
function hashPayload4(payload) {
|
|
107663
109013
|
const hash10 = sha25611(utf8Encoder9.encode(JSON.stringify(payload)));
|
|
107664
|
-
return
|
|
109014
|
+
return bytesToHex17(hash10);
|
|
107665
109015
|
}
|
|
107666
109016
|
function validateEventPayloadTag3(event7, payload) {
|
|
107667
109017
|
const payloadTag = event7.tags.find((t) => t[0] === "payload");
|
|
@@ -107731,13 +109081,13 @@ var JS7 = class {
|
|
|
107731
109081
|
return schnorr5.utils.randomPrivateKey();
|
|
107732
109082
|
}
|
|
107733
109083
|
getPublicKey(secretKey) {
|
|
107734
|
-
return
|
|
109084
|
+
return bytesToHex17(schnorr5.getPublicKey(secretKey));
|
|
107735
109085
|
}
|
|
107736
109086
|
finalizeEvent(t, secretKey) {
|
|
107737
109087
|
const event7 = t;
|
|
107738
|
-
event7.pubkey =
|
|
109088
|
+
event7.pubkey = bytesToHex17(schnorr5.getPublicKey(secretKey));
|
|
107739
109089
|
event7.id = getEventHash7(event7);
|
|
107740
|
-
event7.sig =
|
|
109090
|
+
event7.sig = bytesToHex17(schnorr5.sign(getEventHash7(event7), secretKey));
|
|
107741
109091
|
event7[verifiedSymbol10] = true;
|
|
107742
109092
|
return event7;
|
|
107743
109093
|
}
|
|
@@ -107766,7 +109116,7 @@ function serializeEvent7(evt) {
|
|
|
107766
109116
|
}
|
|
107767
109117
|
function getEventHash7(event7) {
|
|
107768
109118
|
let eventHash = sha25611(utf8Encoder10.encode(serializeEvent7(event7)));
|
|
107769
|
-
return
|
|
109119
|
+
return bytesToHex17(eventHash);
|
|
107770
109120
|
}
|
|
107771
109121
|
var i7 = new JS7;
|
|
107772
109122
|
var generateSecretKey7 = i7.generateSecretKey;
|
|
@@ -108003,7 +109353,7 @@ var utf8Decoder12 = new TextDecoder("utf-8");
|
|
|
108003
109353
|
var utf8Encoder12 = new TextEncoder;
|
|
108004
109354
|
var Bech32MaxSize5 = 5000;
|
|
108005
109355
|
function npubEncode6(hex8) {
|
|
108006
|
-
return encodeBytes5("npub",
|
|
109356
|
+
return encodeBytes5("npub", hexToBytes15(hex8));
|
|
108007
109357
|
}
|
|
108008
109358
|
function encodeBech325(prefix, data) {
|
|
108009
109359
|
let words = bech325.toWords(data);
|
|
@@ -108014,7 +109364,7 @@ function encodeBytes5(prefix, bytes12) {
|
|
|
108014
109364
|
}
|
|
108015
109365
|
function nprofileEncode5(profile6) {
|
|
108016
109366
|
let data = encodeTLV5({
|
|
108017
|
-
0: [
|
|
109367
|
+
0: [hexToBytes15(profile6.pubkey)],
|
|
108018
109368
|
1: (profile6.relays || []).map((url4) => utf8Encoder12.encode(url4))
|
|
108019
109369
|
});
|
|
108020
109370
|
return encodeBech325("nprofile", data);
|
|
@@ -111009,7 +112359,7 @@ class NotImplementedError extends WalletBaseError {
|
|
|
111009
112359
|
code = "NOT_IMPLEMENTED";
|
|
111010
112360
|
}
|
|
111011
112361
|
|
|
111012
|
-
class
|
|
112362
|
+
class InsufficientBalanceError3 extends WalletBaseError {
|
|
111013
112363
|
code = "INSUFFICIENT_BALANCE";
|
|
111014
112364
|
}
|
|
111015
112365
|
|
|
@@ -111051,7 +112401,7 @@ function createWalletError(code, message) {
|
|
|
111051
112401
|
case "NOT_IMPLEMENTED":
|
|
111052
112402
|
return new NotImplementedError(message);
|
|
111053
112403
|
case "INSUFFICIENT_BALANCE":
|
|
111054
|
-
return new
|
|
112404
|
+
return new InsufficientBalanceError3(message);
|
|
111055
112405
|
case "QUOTA_EXCEEDED":
|
|
111056
112406
|
return new QuotaExceededError(message);
|
|
111057
112407
|
case "RESTRICTED":
|
|
@@ -126995,7 +128345,7 @@ function rotl5(word, shift) {
|
|
|
126995
128345
|
}
|
|
126996
128346
|
var hasHexBuiltin4 = /* @__PURE__ */ (() => typeof Uint8Array.from([]).toHex === "function" && typeof Uint8Array.fromHex === "function")();
|
|
126997
128347
|
var hexes14 = /* @__PURE__ */ Array.from({ length: 256 }, (_4, i8) => i8.toString(16).padStart(2, "0"));
|
|
126998
|
-
function
|
|
128348
|
+
function bytesToHex19(bytes12) {
|
|
126999
128349
|
abytes7(bytes12);
|
|
127000
128350
|
if (hasHexBuiltin4)
|
|
127001
128351
|
return bytes12.toHex();
|
|
@@ -127015,7 +128365,7 @@ function asciiToBase166(ch) {
|
|
|
127015
128365
|
return ch - (asciis6.a - 10);
|
|
127016
128366
|
return;
|
|
127017
128367
|
}
|
|
127018
|
-
function
|
|
128368
|
+
function hexToBytes17(hex8) {
|
|
127019
128369
|
if (typeof hex8 !== "string")
|
|
127020
128370
|
throw new Error("hex string expected, got " + typeof hex8);
|
|
127021
128371
|
if (hasHexBuiltin4)
|
|
@@ -127774,15 +129124,15 @@ function hexToNumber7(hex8) {
|
|
|
127774
129124
|
return hex8 === "" ? _0n35 : BigInt("0x" + hex8);
|
|
127775
129125
|
}
|
|
127776
129126
|
function bytesToNumberBE7(bytes12) {
|
|
127777
|
-
return hexToNumber7(
|
|
129127
|
+
return hexToNumber7(bytesToHex19(bytes12));
|
|
127778
129128
|
}
|
|
127779
129129
|
function bytesToNumberLE7(bytes12) {
|
|
127780
|
-
return hexToNumber7(
|
|
129130
|
+
return hexToNumber7(bytesToHex19(copyBytes4(abytes7(bytes12)).reverse()));
|
|
127781
129131
|
}
|
|
127782
129132
|
function numberToBytesBE7(n, len) {
|
|
127783
129133
|
anumber6(len);
|
|
127784
129134
|
n = abignumber2(n);
|
|
127785
|
-
const res =
|
|
129135
|
+
const res = hexToBytes17(n.toString(16).padStart(len * 2, "0"));
|
|
127786
129136
|
if (res.length !== len)
|
|
127787
129137
|
throw new Error("number too large");
|
|
127788
129138
|
return res;
|
|
@@ -128870,7 +130220,7 @@ function weierstrass7(params, extraOpts = {}) {
|
|
|
128870
130220
|
return P3;
|
|
128871
130221
|
}
|
|
128872
130222
|
static fromHex(hex8) {
|
|
128873
|
-
return Point6.fromBytes(
|
|
130223
|
+
return Point6.fromBytes(hexToBytes17(hex8));
|
|
128874
130224
|
}
|
|
128875
130225
|
get x() {
|
|
128876
130226
|
return this.toAffine().x;
|
|
@@ -129063,7 +130413,7 @@ function weierstrass7(params, extraOpts = {}) {
|
|
|
129063
130413
|
return encodePoint(Point6, this, isCompressed);
|
|
129064
130414
|
}
|
|
129065
130415
|
toHex(isCompressed = true) {
|
|
129066
|
-
return
|
|
130416
|
+
return bytesToHex19(this.toBytes(isCompressed));
|
|
129067
130417
|
}
|
|
129068
130418
|
toString() {
|
|
129069
130419
|
return `<Point ${this.is0() ? "ZERO" : this.toHex()}>`;
|
|
@@ -129218,7 +130568,7 @@ function ecdsa3(Point6, hash10, ecdsaOpts = {}) {
|
|
|
129218
130568
|
return new Signature(Fn5.fromBytes(r), Fn5.fromBytes(s), recid);
|
|
129219
130569
|
}
|
|
129220
130570
|
static fromHex(hex8, format) {
|
|
129221
|
-
return this.fromBytes(
|
|
130571
|
+
return this.fromBytes(hexToBytes17(hex8), format);
|
|
129222
130572
|
}
|
|
129223
130573
|
assertRecovery() {
|
|
129224
130574
|
const { recovery } = this;
|
|
@@ -129253,7 +130603,7 @@ function ecdsa3(Point6, hash10, ecdsaOpts = {}) {
|
|
|
129253
130603
|
toBytes(format = defaultSigOpts.format) {
|
|
129254
130604
|
validateSigFormat3(format);
|
|
129255
130605
|
if (format === "der")
|
|
129256
|
-
return
|
|
130606
|
+
return hexToBytes17(DER7.hexFromSig(this));
|
|
129257
130607
|
const { r, s } = this;
|
|
129258
130608
|
const rb = Fn5.toBytes(r);
|
|
129259
130609
|
const sb = Fn5.toBytes(s);
|
|
@@ -129264,7 +130614,7 @@ function ecdsa3(Point6, hash10, ecdsaOpts = {}) {
|
|
|
129264
130614
|
return concatBytes17(rb, sb);
|
|
129265
130615
|
}
|
|
129266
130616
|
toHex(format) {
|
|
129267
|
-
return
|
|
130617
|
+
return bytesToHex19(this.toBytes(format));
|
|
129268
130618
|
}
|
|
129269
130619
|
}
|
|
129270
130620
|
const bits2int = ecdsaOpts.bits2int || function bits2int_def(bytes12) {
|
|
@@ -131124,8 +132474,8 @@ function validateEvent9(event11) {
|
|
|
131124
132474
|
var utils_exports4 = {};
|
|
131125
132475
|
__export5(utils_exports4, {
|
|
131126
132476
|
binarySearch: () => binarySearch7,
|
|
131127
|
-
bytesToHex: () =>
|
|
131128
|
-
hexToBytes: () =>
|
|
132477
|
+
bytesToHex: () => bytesToHex19,
|
|
132478
|
+
hexToBytes: () => hexToBytes17,
|
|
131129
132479
|
insertEventIntoAscendingList: () => insertEventIntoAscendingList7,
|
|
131130
132480
|
insertEventIntoDescendingList: () => insertEventIntoDescendingList7,
|
|
131131
132481
|
mergeReverseSortedLists: () => mergeReverseSortedLists,
|
|
@@ -131254,13 +132604,13 @@ var JS8 = class {
|
|
|
131254
132604
|
return schnorr6.utils.randomSecretKey();
|
|
131255
132605
|
}
|
|
131256
132606
|
getPublicKey(secretKey) {
|
|
131257
|
-
return
|
|
132607
|
+
return bytesToHex19(schnorr6.getPublicKey(secretKey));
|
|
131258
132608
|
}
|
|
131259
132609
|
finalizeEvent(t, secretKey) {
|
|
131260
132610
|
const event11 = t;
|
|
131261
|
-
event11.pubkey =
|
|
132611
|
+
event11.pubkey = bytesToHex19(schnorr6.getPublicKey(secretKey));
|
|
131262
132612
|
event11.id = getEventHash8(event11);
|
|
131263
|
-
event11.sig =
|
|
132613
|
+
event11.sig = bytesToHex19(schnorr6.sign(hexToBytes17(getEventHash8(event11)), secretKey));
|
|
131264
132614
|
event11[verifiedSymbol11] = true;
|
|
131265
132615
|
return event11;
|
|
131266
132616
|
}
|
|
@@ -131273,7 +132623,7 @@ var JS8 = class {
|
|
|
131273
132623
|
event11[verifiedSymbol11] = false;
|
|
131274
132624
|
return false;
|
|
131275
132625
|
}
|
|
131276
|
-
const valid = schnorr6.verify(
|
|
132626
|
+
const valid = schnorr6.verify(hexToBytes17(event11.sig), hexToBytes17(hash10), hexToBytes17(event11.pubkey));
|
|
131277
132627
|
event11[verifiedSymbol11] = valid;
|
|
131278
132628
|
return valid;
|
|
131279
132629
|
} catch (err) {
|
|
@@ -131289,7 +132639,7 @@ function serializeEvent8(evt) {
|
|
|
131289
132639
|
}
|
|
131290
132640
|
function getEventHash8(event11) {
|
|
131291
132641
|
let eventHash = sha25612(utf8Encoder13.encode(serializeEvent8(event11)));
|
|
131292
|
-
return
|
|
132642
|
+
return bytesToHex19(eventHash);
|
|
131293
132643
|
}
|
|
131294
132644
|
var i8 = new JS8;
|
|
131295
132645
|
var generateSecretKey8 = i8.generateSecretKey;
|
|
@@ -132356,7 +133706,7 @@ function decode8(code) {
|
|
|
132356
133706
|
return {
|
|
132357
133707
|
type: "nprofile",
|
|
132358
133708
|
data: {
|
|
132359
|
-
pubkey:
|
|
133709
|
+
pubkey: bytesToHex19(tlv[0][0]),
|
|
132360
133710
|
relays: tlv[1] ? tlv[1].map((d) => utf8Decoder13.decode(d)) : []
|
|
132361
133711
|
}
|
|
132362
133712
|
};
|
|
@@ -132374,10 +133724,10 @@ function decode8(code) {
|
|
|
132374
133724
|
return {
|
|
132375
133725
|
type: "nevent",
|
|
132376
133726
|
data: {
|
|
132377
|
-
id:
|
|
133727
|
+
id: bytesToHex19(tlv[0][0]),
|
|
132378
133728
|
relays: tlv[1] ? tlv[1].map((d) => utf8Decoder13.decode(d)) : [],
|
|
132379
|
-
author: tlv[2]?.[0] ?
|
|
132380
|
-
kind: tlv[3]?.[0] ? parseInt(
|
|
133729
|
+
author: tlv[2]?.[0] ? bytesToHex19(tlv[2][0]) : undefined,
|
|
133730
|
+
kind: tlv[3]?.[0] ? parseInt(bytesToHex19(tlv[3][0]), 16) : undefined
|
|
132381
133731
|
}
|
|
132382
133732
|
};
|
|
132383
133733
|
}
|
|
@@ -132397,8 +133747,8 @@ function decode8(code) {
|
|
|
132397
133747
|
type: "naddr",
|
|
132398
133748
|
data: {
|
|
132399
133749
|
identifier: utf8Decoder13.decode(tlv[0][0]),
|
|
132400
|
-
pubkey:
|
|
132401
|
-
kind: parseInt(
|
|
133750
|
+
pubkey: bytesToHex19(tlv[2][0]),
|
|
133751
|
+
kind: parseInt(bytesToHex19(tlv[3][0]), 16),
|
|
132402
133752
|
relays: tlv[1] ? tlv[1].map((d) => utf8Decoder13.decode(d)) : []
|
|
132403
133753
|
}
|
|
132404
133754
|
};
|
|
@@ -132407,7 +133757,7 @@ function decode8(code) {
|
|
|
132407
133757
|
return { type: prefix, data };
|
|
132408
133758
|
case "npub":
|
|
132409
133759
|
case "note":
|
|
132410
|
-
return { type: prefix, data:
|
|
133760
|
+
return { type: prefix, data: bytesToHex19(data) };
|
|
132411
133761
|
default:
|
|
132412
133762
|
throw new Error(`unknown prefix ${prefix}`);
|
|
132413
133763
|
}
|
|
@@ -132433,10 +133783,10 @@ function nsecEncode6(key) {
|
|
|
132433
133783
|
return encodeBytes6("nsec", key);
|
|
132434
133784
|
}
|
|
132435
133785
|
function npubEncode7(hex9) {
|
|
132436
|
-
return encodeBytes6("npub",
|
|
133786
|
+
return encodeBytes6("npub", hexToBytes17(hex9));
|
|
132437
133787
|
}
|
|
132438
133788
|
function noteEncode6(hex9) {
|
|
132439
|
-
return encodeBytes6("note",
|
|
133789
|
+
return encodeBytes6("note", hexToBytes17(hex9));
|
|
132440
133790
|
}
|
|
132441
133791
|
function encodeBech326(prefix, data) {
|
|
132442
133792
|
let words = bech326.toWords(data);
|
|
@@ -132447,7 +133797,7 @@ function encodeBytes6(prefix, bytes12) {
|
|
|
132447
133797
|
}
|
|
132448
133798
|
function nprofileEncode6(profile9) {
|
|
132449
133799
|
let data = encodeTLV6({
|
|
132450
|
-
0: [
|
|
133800
|
+
0: [hexToBytes17(profile9.pubkey)],
|
|
132451
133801
|
1: (profile9.relays || []).map((url5) => utf8Encoder13.encode(url5))
|
|
132452
133802
|
});
|
|
132453
133803
|
return encodeBech326("nprofile", data);
|
|
@@ -132458,9 +133808,9 @@ function neventEncode6(event11) {
|
|
|
132458
133808
|
kindArray = integerToUint8Array4(event11.kind);
|
|
132459
133809
|
}
|
|
132460
133810
|
let data = encodeTLV6({
|
|
132461
|
-
0: [
|
|
133811
|
+
0: [hexToBytes17(event11.id)],
|
|
132462
133812
|
1: (event11.relays || []).map((url5) => utf8Encoder13.encode(url5)),
|
|
132463
|
-
2: event11.author ? [
|
|
133813
|
+
2: event11.author ? [hexToBytes17(event11.author)] : [],
|
|
132464
133814
|
3: kindArray ? [new Uint8Array(kindArray)] : []
|
|
132465
133815
|
});
|
|
132466
133816
|
return encodeBech326("nevent", data);
|
|
@@ -132471,7 +133821,7 @@ function naddrEncode6(addr) {
|
|
|
132471
133821
|
let data = encodeTLV6({
|
|
132472
133822
|
0: [utf8Encoder13.encode(addr.identifier)],
|
|
132473
133823
|
1: (addr.relays || []).map((url5) => utf8Encoder13.encode(url5)),
|
|
132474
|
-
2: [
|
|
133824
|
+
2: [hexToBytes17(addr.pubkey)],
|
|
132475
133825
|
3: [new Uint8Array(kind)]
|
|
132476
133826
|
});
|
|
132477
133827
|
return encodeBech326("naddr", data);
|
|
@@ -132495,8 +133845,8 @@ __export5(nip04_exports4, {
|
|
|
132495
133845
|
encrypt: () => encrypt9
|
|
132496
133846
|
});
|
|
132497
133847
|
function encrypt9(secretKey, pubkey3, text) {
|
|
132498
|
-
const privkey = secretKey instanceof Uint8Array ? secretKey :
|
|
132499
|
-
const key = secp256k16.getSharedSecret(privkey,
|
|
133848
|
+
const privkey = secretKey instanceof Uint8Array ? secretKey : hexToBytes17(secretKey);
|
|
133849
|
+
const key = secp256k16.getSharedSecret(privkey, hexToBytes17("02" + pubkey3));
|
|
132500
133850
|
const normalizedKey = getNormalizedX4(key);
|
|
132501
133851
|
let iv = Uint8Array.from(randomBytes11(16));
|
|
132502
133852
|
let plaintext = utf8Encoder13.encode(text);
|
|
@@ -132506,9 +133856,9 @@ function encrypt9(secretKey, pubkey3, text) {
|
|
|
132506
133856
|
return `${ctb64}?iv=${ivb64}`;
|
|
132507
133857
|
}
|
|
132508
133858
|
function decrypt8(secretKey, pubkey3, data) {
|
|
132509
|
-
const privkey = secretKey instanceof Uint8Array ? secretKey :
|
|
133859
|
+
const privkey = secretKey instanceof Uint8Array ? secretKey : hexToBytes17(secretKey);
|
|
132510
133860
|
let [ctb64, ivb64] = data.split("?iv=");
|
|
132511
|
-
let key = secp256k16.getSharedSecret(privkey,
|
|
133861
|
+
let key = secp256k16.getSharedSecret(privkey, hexToBytes17("02" + pubkey3));
|
|
132512
133862
|
let normalizedKey = getNormalizedX4(key);
|
|
132513
133863
|
let iv = base649.decode(ivb64);
|
|
132514
133864
|
let ciphertext = base649.decode(ctb64);
|
|
@@ -132736,7 +134086,7 @@ function minePow4(unsigned, difficulty) {
|
|
|
132736
134086
|
tag2[1] = (++count).toString();
|
|
132737
134087
|
const hash10 = sha25612(utf8Encoder13.encode(JSON.stringify([0, event11.pubkey, event11.created_at, event11.kind, event11.tags, event11.content])));
|
|
132738
134088
|
if (getPowFromBytes(hash10) >= difficulty) {
|
|
132739
|
-
event11.id =
|
|
134089
|
+
event11.id = bytesToHex19(hash10);
|
|
132740
134090
|
break;
|
|
132741
134091
|
}
|
|
132742
134092
|
}
|
|
@@ -132770,7 +134120,7 @@ var minPlaintextSize4 = 1;
|
|
|
132770
134120
|
var maxPlaintextSize4 = 4294967295;
|
|
132771
134121
|
var extendedPrefixThreshold = 65536;
|
|
132772
134122
|
function getConversationKey4(privkeyA, pubkeyB) {
|
|
132773
|
-
const sharedX = secp256k16.getSharedSecret(privkeyA,
|
|
134123
|
+
const sharedX = secp256k16.getSharedSecret(privkeyA, hexToBytes17("02" + pubkeyB)).subarray(1, 33);
|
|
132774
134124
|
return extract5(sha25612, sharedX, utf8Encoder13.encode("nip44-v2"));
|
|
132775
134125
|
}
|
|
132776
134126
|
function getMessageKeys4(conversationKey, nonce) {
|
|
@@ -133877,7 +135227,7 @@ var NegentropyStorageVector5 = class {
|
|
|
133877
135227
|
insert(timestamp, id) {
|
|
133878
135228
|
if (this.sealed)
|
|
133879
135229
|
throw Error("already sealed");
|
|
133880
|
-
const idb =
|
|
135230
|
+
const idb = hexToBytes17(id);
|
|
133881
135231
|
if (idb.byteLength !== ID_SIZE5)
|
|
133882
135232
|
throw Error("bad id size for added item");
|
|
133883
135233
|
this.items.push({ timestamp, id: idb });
|
|
@@ -133971,10 +135321,10 @@ var Negentropy5 = class {
|
|
|
133971
135321
|
let output12 = new WrappedBuffer5;
|
|
133972
135322
|
output12.extend(new Uint8Array([PROTOCOL_VERSION5]));
|
|
133973
135323
|
this.splitRange(0, this.storage.size(), this._bound(Number.MAX_VALUE), output12);
|
|
133974
|
-
return
|
|
135324
|
+
return bytesToHex19(output12.unwrap());
|
|
133975
135325
|
}
|
|
133976
135326
|
reconcile(queryMsg, onhave, onneed) {
|
|
133977
|
-
const query2 = new WrappedBuffer5(
|
|
135327
|
+
const query2 = new WrappedBuffer5(hexToBytes17(queryMsg));
|
|
133978
135328
|
this.lastTimestampIn = this.lastTimestampOut = 0;
|
|
133979
135329
|
let fullOutput = new WrappedBuffer5;
|
|
133980
135330
|
fullOutput.extend(new Uint8Array([PROTOCOL_VERSION5]));
|
|
@@ -134017,22 +135367,22 @@ var Negentropy5 = class {
|
|
|
134017
135367
|
let theirElems = {};
|
|
134018
135368
|
for (let i22 = 0;i22 < numIds; i22++) {
|
|
134019
135369
|
let e43 = getBytes6(query2, ID_SIZE5);
|
|
134020
|
-
theirElems[
|
|
135370
|
+
theirElems[bytesToHex19(e43)] = e43;
|
|
134021
135371
|
}
|
|
134022
135372
|
skip4 = true;
|
|
134023
135373
|
this.storage.iterate(lower, upper, (item) => {
|
|
134024
135374
|
let k4 = item.id;
|
|
134025
|
-
const id =
|
|
135375
|
+
const id = bytesToHex19(k4);
|
|
134026
135376
|
if (!theirElems[id]) {
|
|
134027
135377
|
onhave?.(id);
|
|
134028
135378
|
} else {
|
|
134029
|
-
delete theirElems[
|
|
135379
|
+
delete theirElems[bytesToHex19(k4)];
|
|
134030
135380
|
}
|
|
134031
135381
|
return true;
|
|
134032
135382
|
});
|
|
134033
135383
|
if (onneed) {
|
|
134034
135384
|
for (let v4 of Object.values(theirElems)) {
|
|
134035
|
-
onneed(
|
|
135385
|
+
onneed(bytesToHex19(v4));
|
|
134036
135386
|
}
|
|
134037
135387
|
}
|
|
134038
135388
|
} else {
|
|
@@ -134050,7 +135400,7 @@ var Negentropy5 = class {
|
|
|
134050
135400
|
prevIndex = upper;
|
|
134051
135401
|
prevBound = currBound;
|
|
134052
135402
|
}
|
|
134053
|
-
return fullOutput.length === 1 ? null :
|
|
135403
|
+
return fullOutput.length === 1 ? null : bytesToHex19(fullOutput.unwrap());
|
|
134054
135404
|
}
|
|
134055
135405
|
splitRange(lower, upper, upperBound, o) {
|
|
134056
135406
|
let numElems = upper - lower;
|
|
@@ -134300,7 +135650,7 @@ function validateEventMethodTag4(event11, method) {
|
|
|
134300
135650
|
}
|
|
134301
135651
|
function hashPayload5(payload) {
|
|
134302
135652
|
const hash10 = sha25612(utf8Encoder13.encode(JSON.stringify(payload)));
|
|
134303
|
-
return
|
|
135653
|
+
return bytesToHex19(hash10);
|
|
134304
135654
|
}
|
|
134305
135655
|
function validateEventPayloadTag4(event11, payload) {
|
|
134306
135656
|
const payloadTag = event11.tags.find((t) => t[0] === "payload");
|
|
@@ -134336,7 +135686,7 @@ async function validateEvent25(event11, url5, method, body) {
|
|
|
134336
135686
|
|
|
134337
135687
|
// src/utils/nip98.ts
|
|
134338
135688
|
var NIP98_KIND = 27235;
|
|
134339
|
-
function
|
|
135689
|
+
function hexToBytes18(hex9) {
|
|
134340
135690
|
const normalized = hex9.trim().toLowerCase();
|
|
134341
135691
|
if (!/^[a-f0-9]{64}$/.test(normalized)) {
|
|
134342
135692
|
throw new Error("Expected a 64-char hex private key or an nsec private key.");
|
|
@@ -134359,7 +135709,7 @@ function parseSecretKey(value) {
|
|
|
134359
135709
|
}
|
|
134360
135710
|
return decoded.data;
|
|
134361
135711
|
}
|
|
134362
|
-
return
|
|
135712
|
+
return hexToBytes18(trimmed);
|
|
134363
135713
|
}
|
|
134364
135714
|
async function sha256Hex(data) {
|
|
134365
135715
|
const digest = await crypto.subtle.digest("SHA-256", new Uint8Array(data));
|
|
@@ -134543,6 +135893,75 @@ Installing routstr models in opencode.json...`);
|
|
|
134543
135893
|
import { existsSync as existsSync5, mkdirSync as mkdirSync5 } from "fs";
|
|
134544
135894
|
import { readFile as readFile3, writeFile as writeFile3 } from "fs/promises";
|
|
134545
135895
|
import { dirname as dirname3 } from "path";
|
|
135896
|
+
var PI_THINKING_LEVELS = [
|
|
135897
|
+
"off",
|
|
135898
|
+
"minimal",
|
|
135899
|
+
"low",
|
|
135900
|
+
"medium",
|
|
135901
|
+
"high",
|
|
135902
|
+
"xhigh",
|
|
135903
|
+
"max"
|
|
135904
|
+
];
|
|
135905
|
+
var THINKING_LEVEL_VALUES = {
|
|
135906
|
+
off: "none",
|
|
135907
|
+
minimal: "minimal",
|
|
135908
|
+
low: "low",
|
|
135909
|
+
medium: "medium",
|
|
135910
|
+
high: "high",
|
|
135911
|
+
xhigh: "xhigh",
|
|
135912
|
+
max: "max"
|
|
135913
|
+
};
|
|
135914
|
+
function deriveThinkingFields(model4) {
|
|
135915
|
+
const reasoning = model4.reasoning;
|
|
135916
|
+
if (!reasoning)
|
|
135917
|
+
return null;
|
|
135918
|
+
const supported = (reasoning.supported_efforts ?? []).filter((effort) => typeof effort === "string").map((effort) => effort.trim().toLowerCase()).filter(Boolean);
|
|
135919
|
+
if (supported.length === 0)
|
|
135920
|
+
return null;
|
|
135921
|
+
const allowed = new Set(supported);
|
|
135922
|
+
if (reasoning.mandatory === true)
|
|
135923
|
+
allowed.delete("none");
|
|
135924
|
+
const thinkingLevelMap = {};
|
|
135925
|
+
for (const level of PI_THINKING_LEVELS) {
|
|
135926
|
+
const value = THINKING_LEVEL_VALUES[level];
|
|
135927
|
+
thinkingLevelMap[level] = allowed.has(value) ? value : null;
|
|
135928
|
+
}
|
|
135929
|
+
return { reasoning: true, thinkingLevelMap };
|
|
135930
|
+
}
|
|
135931
|
+
var isDeepSeekModel = (id) => id.startsWith("deepseek");
|
|
135932
|
+
function buildPiModelEntry(model4, previous) {
|
|
135933
|
+
const entry = { id: model4.id };
|
|
135934
|
+
if (model4.context_length !== undefined && model4.context_length > 0) {
|
|
135935
|
+
entry.contextWindow = model4.context_length;
|
|
135936
|
+
}
|
|
135937
|
+
if (model4.name) {
|
|
135938
|
+
entry.name = model4.name;
|
|
135939
|
+
}
|
|
135940
|
+
const mods = model4.architecture?.input_modalities ?? [];
|
|
135941
|
+
const input = [];
|
|
135942
|
+
if (mods.includes("text"))
|
|
135943
|
+
input.push("text");
|
|
135944
|
+
if (mods.includes("image"))
|
|
135945
|
+
input.push("image");
|
|
135946
|
+
entry.input = input;
|
|
135947
|
+
const derived = deriveThinkingFields(model4);
|
|
135948
|
+
if (derived) {
|
|
135949
|
+
entry.reasoning = derived.reasoning;
|
|
135950
|
+
entry.thinkingLevelMap = derived.thinkingLevelMap;
|
|
135951
|
+
} else {
|
|
135952
|
+
if (previous?.reasoning !== undefined)
|
|
135953
|
+
entry.reasoning = previous.reasoning;
|
|
135954
|
+
if (previous?.thinkingLevelMap !== undefined) {
|
|
135955
|
+
entry.thinkingLevelMap = previous.thinkingLevelMap;
|
|
135956
|
+
}
|
|
135957
|
+
}
|
|
135958
|
+
if (isDeepSeekModel(model4.id)) {
|
|
135959
|
+
entry.compat = { ...previous?.compat ?? {}, supportsDeveloperRole: false };
|
|
135960
|
+
} else if (previous?.compat !== undefined) {
|
|
135961
|
+
entry.compat = previous.compat;
|
|
135962
|
+
}
|
|
135963
|
+
return entry;
|
|
135964
|
+
}
|
|
134546
135965
|
async function installPiIntegration(config2, apiKey, integrationConfig) {
|
|
134547
135966
|
const { name: name16, configPath } = integrationConfig;
|
|
134548
135967
|
console.log(`
|
|
@@ -134571,30 +135990,7 @@ Installing routstr models in pi models.json...`);
|
|
|
134571
135990
|
return;
|
|
134572
135991
|
}
|
|
134573
135992
|
const existingModels = new Map((piConfig.providers["routstr"]?.models ?? []).map((m) => [m.id, m]));
|
|
134574
|
-
const providerModels = models.map((model4) =>
|
|
134575
|
-
const previous = existingModels.get(model4.id);
|
|
134576
|
-
const entry = { id: model4.id };
|
|
134577
|
-
if (model4.context_length !== undefined && model4.context_length > 0) {
|
|
134578
|
-
entry.contextWindow = model4.context_length;
|
|
134579
|
-
}
|
|
134580
|
-
if (model4.name) {
|
|
134581
|
-
entry.name = model4.name;
|
|
134582
|
-
}
|
|
134583
|
-
const mods = model4.architecture?.input_modalities ?? [];
|
|
134584
|
-
const input = [];
|
|
134585
|
-
if (mods.includes("text"))
|
|
134586
|
-
input.push("text");
|
|
134587
|
-
if (mods.includes("image"))
|
|
134588
|
-
input.push("image");
|
|
134589
|
-
entry.input = input;
|
|
134590
|
-
if (previous?.reasoning !== undefined)
|
|
134591
|
-
entry.reasoning = previous.reasoning;
|
|
134592
|
-
if (previous?.thinkingLevelMap !== undefined)
|
|
134593
|
-
entry.thinkingLevelMap = previous.thinkingLevelMap;
|
|
134594
|
-
if (previous?.compat !== undefined)
|
|
134595
|
-
entry.compat = previous.compat;
|
|
134596
|
-
return entry;
|
|
134597
|
-
});
|
|
135993
|
+
const providerModels = models.map((model4) => buildPiModelEntry(model4, existingModels.get(model4.id)));
|
|
134598
135994
|
piConfig.providers["routstr"] = {
|
|
134599
135995
|
baseUrl,
|
|
134600
135996
|
api: "openai-completions",
|
|
@@ -135188,6 +136584,32 @@ async function getUsageSummary(driver, clients, tzOffsetMinutes, clientFilter) {
|
|
|
135188
136584
|
return summary;
|
|
135189
136585
|
}
|
|
135190
136586
|
|
|
136587
|
+
// src/daemon/http/request-body.ts
|
|
136588
|
+
var OPENAI_JSON_BODY_PATH_SUFFIXES = [
|
|
136589
|
+
"/chat/completions",
|
|
136590
|
+
"/completions",
|
|
136591
|
+
"/responses"
|
|
136592
|
+
];
|
|
136593
|
+
function isOpenAiJsonBodyPath2(pathname) {
|
|
136594
|
+
const path2 = (pathname.split("?")[0] ?? "").replace(/\/+$/, "");
|
|
136595
|
+
return OPENAI_JSON_BODY_PATH_SUFFIXES.some((suffix) => path2.endsWith(suffix));
|
|
136596
|
+
}
|
|
136597
|
+
function applyDefaultOutputTokenLimit(pathname, body, maxTokens) {
|
|
136598
|
+
if (!(maxTokens > 0) || !isOpenAiJsonBodyPath2(pathname)) {
|
|
136599
|
+
return false;
|
|
136600
|
+
}
|
|
136601
|
+
if (pathname.split("?")[0].replace(/\/+$/, "").endsWith("/responses")) {
|
|
136602
|
+
if (typeof body.max_output_tokens === "number")
|
|
136603
|
+
return false;
|
|
136604
|
+
body.max_output_tokens = maxTokens;
|
|
136605
|
+
return true;
|
|
136606
|
+
}
|
|
136607
|
+
if (typeof body.max_tokens === "number")
|
|
136608
|
+
return false;
|
|
136609
|
+
body.max_tokens = maxTokens;
|
|
136610
|
+
return true;
|
|
136611
|
+
}
|
|
136612
|
+
|
|
135191
136613
|
// src/daemon/http/index.ts
|
|
135192
136614
|
var HOP_BY_HOP_HEADERS = new Set([
|
|
135193
136615
|
"connection",
|
|
@@ -136425,16 +137847,7 @@ function createDaemonRequestHandler(deps) {
|
|
|
136425
137847
|
sendJson(res, 400, { error: "Missing required 'model' field." });
|
|
136426
137848
|
return;
|
|
136427
137849
|
}
|
|
136428
|
-
|
|
136429
|
-
const isResponsesPath = url5.pathname.includes("/responses");
|
|
136430
|
-
if (isResponsesPath) {
|
|
136431
|
-
if (typeof bodyObj.max_output_tokens !== "number") {
|
|
136432
|
-
bodyObj.max_output_tokens = deps.maxTokens;
|
|
136433
|
-
}
|
|
136434
|
-
} else if (typeof bodyObj.max_tokens !== "number") {
|
|
136435
|
-
bodyObj.max_tokens = deps.maxTokens;
|
|
136436
|
-
}
|
|
136437
|
-
}
|
|
137850
|
+
applyDefaultOutputTokenLimit(url5.pathname, bodyObj, deps.maxTokens);
|
|
136438
137851
|
const forcedProvider = url5.searchParams.get("provider") || req.headers["x-routstr-provider"] || deps.provider || undefined;
|
|
136439
137852
|
const incomingHeaders = {};
|
|
136440
137853
|
for (const [key, value] of Object.entries(req.headers)) {
|
|
@@ -137649,7 +139062,7 @@ var SqliteKeysetRepository = class {
|
|
|
137649
139062
|
await this.db.run("DELETE FROM coco_cashu_keysets WHERE mintUrl = ? AND id = ?", [mintUrl, keysetId]);
|
|
137650
139063
|
}
|
|
137651
139064
|
};
|
|
137652
|
-
function
|
|
139065
|
+
function hexToBytes19(hexString) {
|
|
137653
139066
|
if (!/^[0-9a-fA-F]+$/.test(hexString))
|
|
137654
139067
|
throw new Error(`Invalid hex string: contains non-hex characters`);
|
|
137655
139068
|
if (hexString.length % 2 !== 0)
|
|
@@ -137659,7 +139072,7 @@ function hexToBytes18(hexString) {
|
|
|
137659
139072
|
throw new Error(`Failed to parse hex string`);
|
|
137660
139073
|
return new Uint8Array(matches.map((byte) => parseInt(byte, 16)));
|
|
137661
139074
|
}
|
|
137662
|
-
function
|
|
139075
|
+
function bytesToHex21(bytes12) {
|
|
137663
139076
|
return Array.from(bytes12).map((b2) => b2.toString(16).padStart(2, "0")).join("");
|
|
137664
139077
|
}
|
|
137665
139078
|
var SqliteKeyRingRepository = class {
|
|
@@ -137672,7 +139085,7 @@ var SqliteKeyRingRepository = class {
|
|
|
137672
139085
|
if (!row)
|
|
137673
139086
|
return null;
|
|
137674
139087
|
try {
|
|
137675
|
-
const secretKeyBytes =
|
|
139088
|
+
const secretKeyBytes = hexToBytes19(row.secretKey);
|
|
137676
139089
|
return {
|
|
137677
139090
|
publicKeyHex: row.publicKey,
|
|
137678
139091
|
secretKey: secretKeyBytes,
|
|
@@ -137683,7 +139096,7 @@ var SqliteKeyRingRepository = class {
|
|
|
137683
139096
|
}
|
|
137684
139097
|
}
|
|
137685
139098
|
async setPersistedKeyPair(keyPair) {
|
|
137686
|
-
const secretKeyHex =
|
|
139099
|
+
const secretKeyHex = bytesToHex21(keyPair.secretKey);
|
|
137687
139100
|
await this.db.run(`INSERT INTO coco_cashu_keypairs (publicKey, secretKey, createdAt, derivationIndex)
|
|
137688
139101
|
VALUES (?, ?, ?, ?)
|
|
137689
139102
|
ON CONFLICT(publicKey) DO UPDATE SET
|
|
@@ -137701,7 +139114,7 @@ var SqliteKeyRingRepository = class {
|
|
|
137701
139114
|
async getAllPersistedKeyPairs() {
|
|
137702
139115
|
return (await this.db.all("SELECT publicKey, secretKey, derivationIndex FROM coco_cashu_keypairs")).map((row) => {
|
|
137703
139116
|
try {
|
|
137704
|
-
const secretKeyBytes =
|
|
139117
|
+
const secretKeyBytes = hexToBytes19(row.secretKey);
|
|
137705
139118
|
return {
|
|
137706
139119
|
publicKeyHex: row.publicKey,
|
|
137707
139120
|
secretKey: secretKeyBytes,
|
|
@@ -137717,7 +139130,7 @@ var SqliteKeyRingRepository = class {
|
|
|
137717
139130
|
if (!row)
|
|
137718
139131
|
return null;
|
|
137719
139132
|
try {
|
|
137720
|
-
const secretKeyBytes =
|
|
139133
|
+
const secretKeyBytes = hexToBytes19(row.secretKey);
|
|
137721
139134
|
return {
|
|
137722
139135
|
publicKeyHex: row.publicKey,
|
|
137723
139136
|
secretKey: secretKeyBytes,
|
|
@@ -139146,13 +140559,13 @@ var JS9 = class {
|
|
|
139146
140559
|
return schnorr6.utils.randomSecretKey();
|
|
139147
140560
|
}
|
|
139148
140561
|
getPublicKey(secretKey) {
|
|
139149
|
-
return
|
|
140562
|
+
return bytesToHex19(schnorr6.getPublicKey(secretKey));
|
|
139150
140563
|
}
|
|
139151
140564
|
finalizeEvent(t, secretKey) {
|
|
139152
140565
|
const event11 = t;
|
|
139153
|
-
event11.pubkey =
|
|
140566
|
+
event11.pubkey = bytesToHex19(schnorr6.getPublicKey(secretKey));
|
|
139154
140567
|
event11.id = getEventHash9(event11);
|
|
139155
|
-
event11.sig =
|
|
140568
|
+
event11.sig = bytesToHex19(schnorr6.sign(hexToBytes17(getEventHash9(event11)), secretKey));
|
|
139156
140569
|
event11[verifiedSymbol12] = true;
|
|
139157
140570
|
return event11;
|
|
139158
140571
|
}
|
|
@@ -139165,7 +140578,7 @@ var JS9 = class {
|
|
|
139165
140578
|
event11[verifiedSymbol12] = false;
|
|
139166
140579
|
return false;
|
|
139167
140580
|
}
|
|
139168
|
-
const valid = schnorr6.verify(
|
|
140581
|
+
const valid = schnorr6.verify(hexToBytes17(event11.sig), hexToBytes17(hash10), hexToBytes17(event11.pubkey));
|
|
139169
140582
|
event11[verifiedSymbol12] = valid;
|
|
139170
140583
|
return valid;
|
|
139171
140584
|
} catch (err) {
|
|
@@ -139181,7 +140594,7 @@ function serializeEvent9(evt) {
|
|
|
139181
140594
|
}
|
|
139182
140595
|
function getEventHash9(event11) {
|
|
139183
140596
|
let eventHash = sha25612(utf8Encoder14.encode(serializeEvent9(event11)));
|
|
139184
|
-
return
|
|
140597
|
+
return bytesToHex19(eventHash);
|
|
139185
140598
|
}
|
|
139186
140599
|
var i9 = new JS9;
|
|
139187
140600
|
var generateSecretKey9 = i9.generateSecretKey;
|
|
@@ -139209,7 +140622,7 @@ async function getToken6(loginUrl, httpMethod, sign4, includeAuthorizationScheme
|
|
|
139209
140622
|
}
|
|
139210
140623
|
function hashPayload6(payload) {
|
|
139211
140624
|
const hash10 = sha25612(utf8Encoder14.encode(JSON.stringify(payload)));
|
|
139212
|
-
return
|
|
140625
|
+
return bytesToHex19(hash10);
|
|
139213
140626
|
}
|
|
139214
140627
|
|
|
139215
140628
|
// node_modules/npubcash-sdk/dist/npc-sdk.mjs
|
|
@@ -155929,6 +157342,44 @@ function legacyCocodPidPath() {
|
|
|
155929
157342
|
return process.env.COCOD_PID || join11(legacyCocodDir(), "cocod.pid");
|
|
155930
157343
|
}
|
|
155931
157344
|
|
|
157345
|
+
// src/daemon/wallet/trusted-mints.ts
|
|
157346
|
+
var DEFAULT_MINT_URL = "https://mint.cubabitcoin.org";
|
|
157347
|
+
var DEFAULT_TRUSTED_MINT_URLS = [
|
|
157348
|
+
DEFAULT_MINT_URL,
|
|
157349
|
+
"https://mint.minibits.cash/Bitcoin"
|
|
157350
|
+
];
|
|
157351
|
+
function safeNormalizeMintUrl(mintUrl) {
|
|
157352
|
+
try {
|
|
157353
|
+
return normalizeMintUrl(mintUrl);
|
|
157354
|
+
} catch {
|
|
157355
|
+
return mintUrl;
|
|
157356
|
+
}
|
|
157357
|
+
}
|
|
157358
|
+
async function seedTrustedMints(wallet, defaultMintUrl, options = {}) {
|
|
157359
|
+
const seeds = options.seeds ?? DEFAULT_TRUSTED_MINT_URLS;
|
|
157360
|
+
const target = safeNormalizeMintUrl(defaultMintUrl);
|
|
157361
|
+
const trusted = new Set(wallet.trustedMints.map(safeNormalizeMintUrl));
|
|
157362
|
+
const attempted = new Set;
|
|
157363
|
+
for (const seed of [defaultMintUrl, ...seeds]) {
|
|
157364
|
+
const mintUrl = safeNormalizeMintUrl(seed);
|
|
157365
|
+
if (attempted.has(mintUrl))
|
|
157366
|
+
continue;
|
|
157367
|
+
attempted.add(mintUrl);
|
|
157368
|
+
if (trusted.has(mintUrl))
|
|
157369
|
+
continue;
|
|
157370
|
+
const isDefault = mintUrl === target;
|
|
157371
|
+
try {
|
|
157372
|
+
options.onProgress?.(`Adding ${isDefault ? "default" : "trusted"} mint: ${mintUrl}`);
|
|
157373
|
+
await wallet.addMint(mintUrl);
|
|
157374
|
+
trusted.add(mintUrl);
|
|
157375
|
+
} catch (error53) {
|
|
157376
|
+
if (isDefault)
|
|
157377
|
+
throw error53;
|
|
157378
|
+
options.onError?.(`Could not add trusted mint ${mintUrl}`, error53);
|
|
157379
|
+
}
|
|
157380
|
+
}
|
|
157381
|
+
}
|
|
157382
|
+
|
|
155932
157383
|
// src/daemon/wallet/coco-client.ts
|
|
155933
157384
|
var NPC_DEFAULT_BASE_URL = "https://npubx.cash";
|
|
155934
157385
|
var STALE_SOCKET_ERROR_CODES = new Set([
|
|
@@ -155937,7 +157388,6 @@ var STALE_SOCKET_ERROR_CODES = new Set([
|
|
|
155937
157388
|
"FailedToOpenSocket"
|
|
155938
157389
|
]);
|
|
155939
157390
|
var STARTUP_LOG_PREFIX = "[routstrd:start]";
|
|
155940
|
-
var DEFAULT_MINT_URL = "https://mint.cubabitcoin.org";
|
|
155941
157391
|
function startupProgress(message) {
|
|
155942
157392
|
logger5.info(message);
|
|
155943
157393
|
console.log(`${STARTUP_LOG_PREFIX} ${message}`);
|
|
@@ -156596,10 +158046,15 @@ async function createCocoClient(options = {}) {
|
|
|
156596
158046
|
const trustedMints = await coco.mint.getAllTrustedMints();
|
|
156597
158047
|
const configuredDefault = walletConfig.defaultMintUrl;
|
|
156598
158048
|
const defaultMintUrl = normalizeMintUrl(configuredDefault || trustedMints[0]?.mintUrl || DEFAULT_MINT_URL);
|
|
156599
|
-
|
|
156600
|
-
|
|
156601
|
-
|
|
156602
|
-
}
|
|
158049
|
+
await seedTrustedMints({
|
|
158050
|
+
trustedMints: trustedMints.map((mint) => mint.mintUrl),
|
|
158051
|
+
addMint: (mintUrl) => coco.mint.addMint(mintUrl, { trusted: true })
|
|
158052
|
+
}, defaultMintUrl, {
|
|
158053
|
+
onProgress: startupProgress,
|
|
158054
|
+
onError: (message, error53) => logger5.warn(message, {
|
|
158055
|
+
error: error53 instanceof Error ? error53.message : String(error53)
|
|
158056
|
+
})
|
|
158057
|
+
});
|
|
156603
158058
|
walletConfig.defaultMintUrl = defaultMintUrl;
|
|
156604
158059
|
if (configuredDefault !== defaultMintUrl) {
|
|
156605
158060
|
saveConfig(walletConfig, configFile);
|