@tinycloud/cli 1.2.0-beta.4 → 1.2.0-beta.6
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 +32 -7
- package/dist/courier-entry.d.ts +3 -0
- package/dist/courier-entry.js +2096 -0
- package/dist/courier-entry.js.map +1 -0
- package/dist/index.js +2211 -2011
- package/dist/index.js.map +1 -1
- package/dist/legacy-entry.js +3796 -3594
- package/dist/legacy-entry.js.map +1 -1
- package/package.json +8 -6
- package/skills/courier/SKILL.md +164 -0
- package/skills/courier/release.json +16 -0
- package/skills/tc-cli/INSTALL.md +8 -6
- package/skills/tc-cli/REFERENCE.md +4 -0
- package/skills/tc-cli/SKILL.md +1 -1
package/dist/index.js
CHANGED
|
@@ -5806,1095 +5806,568 @@ var init_replication_log = __esm({
|
|
|
5806
5806
|
}
|
|
5807
5807
|
});
|
|
5808
5808
|
|
|
5809
|
-
//
|
|
5810
|
-
|
|
5811
|
-
|
|
5812
|
-
|
|
5813
|
-
|
|
5814
|
-
|
|
5815
|
-
|
|
5816
|
-
return {
|
|
5817
|
-
enabled: true,
|
|
5818
|
-
prefixes: settings.prefixes,
|
|
5819
|
-
allowSecrets: settings.allowSecrets === true,
|
|
5820
|
-
mode: "foreground",
|
|
5821
|
-
verify: process.env.TC_REPLICATION_VERIFY === "1",
|
|
5822
|
-
maxStalenessMs: Number(process.env.TC_REPLICATION_MAX_STALENESS_MS ?? 6e4),
|
|
5823
|
-
staleSyncTimeoutMs: Number(process.env.TC_REPLICATION_SYNC_TIMEOUT_MS ?? 1e4),
|
|
5824
|
-
storage: sqliteReplicaStorage({
|
|
5825
|
-
dir: join5(root, "replication"),
|
|
5826
|
-
guard: (section) => withProfileLock2(profile, section, { requireProfile: true, timeoutMs: 35e3 })
|
|
5827
|
-
}),
|
|
5828
|
-
onEvent: createReplicationEventSink(root, output)
|
|
5829
|
-
};
|
|
5809
|
+
// ../../node_modules/@noble/hashes/esm/_blake.js
|
|
5810
|
+
function G1s(a, b, c, d, x) {
|
|
5811
|
+
a = a + b + x | 0;
|
|
5812
|
+
d = rotr(d ^ a, 16);
|
|
5813
|
+
c = c + d | 0;
|
|
5814
|
+
b = rotr(b ^ c, 12);
|
|
5815
|
+
return { a, b, c, d };
|
|
5830
5816
|
}
|
|
5831
|
-
|
|
5832
|
-
|
|
5817
|
+
function G2s(a, b, c, d, x) {
|
|
5818
|
+
a = a + b + x | 0;
|
|
5819
|
+
d = rotr(d ^ a, 8);
|
|
5820
|
+
c = c + d | 0;
|
|
5821
|
+
b = rotr(b ^ c, 7);
|
|
5822
|
+
return { a, b, c, d };
|
|
5823
|
+
}
|
|
5824
|
+
var init_blake = __esm({
|
|
5825
|
+
"../../node_modules/@noble/hashes/esm/_blake.js"() {
|
|
5833
5826
|
"use strict";
|
|
5834
|
-
|
|
5827
|
+
init_utils();
|
|
5835
5828
|
}
|
|
5836
5829
|
});
|
|
5837
5830
|
|
|
5838
|
-
//
|
|
5839
|
-
|
|
5840
|
-
|
|
5841
|
-
|
|
5842
|
-
|
|
5843
|
-
|
|
5844
|
-
|
|
5845
|
-
|
|
5846
|
-
|
|
5847
|
-
|
|
5848
|
-
|
|
5849
|
-
|
|
5850
|
-
|
|
5851
|
-
|
|
5852
|
-
});
|
|
5853
|
-
|
|
5854
|
-
|
|
5855
|
-
|
|
5856
|
-
|
|
5857
|
-
|
|
5831
|
+
// ../../node_modules/@noble/hashes/esm/blake2.js
|
|
5832
|
+
function compress(s, offset, msg, rounds, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) {
|
|
5833
|
+
let j = 0;
|
|
5834
|
+
for (let i = 0; i < rounds; i++) {
|
|
5835
|
+
({ a: v0, b: v4, c: v8, d: v12 } = G1s(v0, v4, v8, v12, msg[offset + s[j++]]));
|
|
5836
|
+
({ a: v0, b: v4, c: v8, d: v12 } = G2s(v0, v4, v8, v12, msg[offset + s[j++]]));
|
|
5837
|
+
({ a: v1, b: v5, c: v9, d: v13 } = G1s(v1, v5, v9, v13, msg[offset + s[j++]]));
|
|
5838
|
+
({ a: v1, b: v5, c: v9, d: v13 } = G2s(v1, v5, v9, v13, msg[offset + s[j++]]));
|
|
5839
|
+
({ a: v2, b: v6, c: v10, d: v14 } = G1s(v2, v6, v10, v14, msg[offset + s[j++]]));
|
|
5840
|
+
({ a: v2, b: v6, c: v10, d: v14 } = G2s(v2, v6, v10, v14, msg[offset + s[j++]]));
|
|
5841
|
+
({ a: v3, b: v7, c: v11, d: v15 } = G1s(v3, v7, v11, v15, msg[offset + s[j++]]));
|
|
5842
|
+
({ a: v3, b: v7, c: v11, d: v15 } = G2s(v3, v7, v11, v15, msg[offset + s[j++]]));
|
|
5843
|
+
({ a: v0, b: v5, c: v10, d: v15 } = G1s(v0, v5, v10, v15, msg[offset + s[j++]]));
|
|
5844
|
+
({ a: v0, b: v5, c: v10, d: v15 } = G2s(v0, v5, v10, v15, msg[offset + s[j++]]));
|
|
5845
|
+
({ a: v1, b: v6, c: v11, d: v12 } = G1s(v1, v6, v11, v12, msg[offset + s[j++]]));
|
|
5846
|
+
({ a: v1, b: v6, c: v11, d: v12 } = G2s(v1, v6, v11, v12, msg[offset + s[j++]]));
|
|
5847
|
+
({ a: v2, b: v7, c: v8, d: v13 } = G1s(v2, v7, v8, v13, msg[offset + s[j++]]));
|
|
5848
|
+
({ a: v2, b: v7, c: v8, d: v13 } = G2s(v2, v7, v8, v13, msg[offset + s[j++]]));
|
|
5849
|
+
({ a: v3, b: v4, c: v9, d: v14 } = G1s(v3, v4, v9, v14, msg[offset + s[j++]]));
|
|
5850
|
+
({ a: v3, b: v4, c: v9, d: v14 } = G2s(v3, v4, v9, v14, msg[offset + s[j++]]));
|
|
5851
|
+
}
|
|
5852
|
+
return { v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15 };
|
|
5858
5853
|
}
|
|
5859
|
-
|
|
5860
|
-
|
|
5861
|
-
|
|
5854
|
+
var BLAKE2;
|
|
5855
|
+
var init_blake2 = __esm({
|
|
5856
|
+
"../../node_modules/@noble/hashes/esm/blake2.js"() {
|
|
5857
|
+
"use strict";
|
|
5858
|
+
init_blake();
|
|
5859
|
+
init_utils();
|
|
5860
|
+
BLAKE2 = class extends Hash {
|
|
5861
|
+
constructor(blockLen, outputLen) {
|
|
5862
|
+
super();
|
|
5863
|
+
this.finished = false;
|
|
5864
|
+
this.destroyed = false;
|
|
5865
|
+
this.length = 0;
|
|
5866
|
+
this.pos = 0;
|
|
5867
|
+
anumber(blockLen);
|
|
5868
|
+
anumber(outputLen);
|
|
5869
|
+
this.blockLen = blockLen;
|
|
5870
|
+
this.outputLen = outputLen;
|
|
5871
|
+
this.buffer = new Uint8Array(blockLen);
|
|
5872
|
+
this.buffer32 = u32(this.buffer);
|
|
5873
|
+
}
|
|
5874
|
+
update(data) {
|
|
5875
|
+
aexists(this);
|
|
5876
|
+
data = toBytes(data);
|
|
5877
|
+
abytes(data);
|
|
5878
|
+
const { blockLen, buffer, buffer32 } = this;
|
|
5879
|
+
const len = data.length;
|
|
5880
|
+
const offset = data.byteOffset;
|
|
5881
|
+
const buf = data.buffer;
|
|
5882
|
+
for (let pos = 0; pos < len; ) {
|
|
5883
|
+
if (this.pos === blockLen) {
|
|
5884
|
+
swap32IfBE(buffer32);
|
|
5885
|
+
this.compress(buffer32, 0, false);
|
|
5886
|
+
swap32IfBE(buffer32);
|
|
5887
|
+
this.pos = 0;
|
|
5888
|
+
}
|
|
5889
|
+
const take = Math.min(blockLen - this.pos, len - pos);
|
|
5890
|
+
const dataOffset = offset + pos;
|
|
5891
|
+
if (take === blockLen && !(dataOffset % 4) && pos + take < len) {
|
|
5892
|
+
const data32 = new Uint32Array(buf, dataOffset, Math.floor((len - pos) / 4));
|
|
5893
|
+
swap32IfBE(data32);
|
|
5894
|
+
for (let pos32 = 0; pos + blockLen < len; pos32 += buffer32.length, pos += blockLen) {
|
|
5895
|
+
this.length += blockLen;
|
|
5896
|
+
this.compress(data32, pos32, false);
|
|
5897
|
+
}
|
|
5898
|
+
swap32IfBE(data32);
|
|
5899
|
+
continue;
|
|
5900
|
+
}
|
|
5901
|
+
buffer.set(data.subarray(pos, pos + take), this.pos);
|
|
5902
|
+
this.pos += take;
|
|
5903
|
+
this.length += take;
|
|
5904
|
+
pos += take;
|
|
5905
|
+
}
|
|
5906
|
+
return this;
|
|
5907
|
+
}
|
|
5908
|
+
digestInto(out) {
|
|
5909
|
+
aexists(this);
|
|
5910
|
+
aoutput(out, this);
|
|
5911
|
+
const { pos, buffer32 } = this;
|
|
5912
|
+
this.finished = true;
|
|
5913
|
+
clean(this.buffer.subarray(pos));
|
|
5914
|
+
swap32IfBE(buffer32);
|
|
5915
|
+
this.compress(buffer32, 0, true);
|
|
5916
|
+
swap32IfBE(buffer32);
|
|
5917
|
+
const out32 = u32(out);
|
|
5918
|
+
this.get().forEach((v, i) => out32[i] = swap8IfBE(v));
|
|
5919
|
+
}
|
|
5920
|
+
digest() {
|
|
5921
|
+
const { buffer, outputLen } = this;
|
|
5922
|
+
this.digestInto(buffer);
|
|
5923
|
+
const res = buffer.slice(0, outputLen);
|
|
5924
|
+
this.destroy();
|
|
5925
|
+
return res;
|
|
5926
|
+
}
|
|
5927
|
+
_cloneInto(to) {
|
|
5928
|
+
const { buffer, length: length4, finished, destroyed, outputLen, pos } = this;
|
|
5929
|
+
to || (to = new this.constructor({ dkLen: outputLen }));
|
|
5930
|
+
to.set(...this.get());
|
|
5931
|
+
to.buffer.set(buffer);
|
|
5932
|
+
to.destroyed = destroyed;
|
|
5933
|
+
to.finished = finished;
|
|
5934
|
+
to.length = length4;
|
|
5935
|
+
to.pos = pos;
|
|
5936
|
+
to.outputLen = outputLen;
|
|
5937
|
+
return to;
|
|
5938
|
+
}
|
|
5939
|
+
clone() {
|
|
5940
|
+
return this._cloneInto();
|
|
5941
|
+
}
|
|
5942
|
+
};
|
|
5862
5943
|
}
|
|
5863
|
-
|
|
5944
|
+
});
|
|
5945
|
+
|
|
5946
|
+
// ../../node_modules/@noble/hashes/esm/blake3.js
|
|
5947
|
+
var B3_Flags, B3_IV, B3_SIGMA, BLAKE3, blake3;
|
|
5948
|
+
var init_blake3 = __esm({
|
|
5949
|
+
"../../node_modules/@noble/hashes/esm/blake3.js"() {
|
|
5950
|
+
"use strict";
|
|
5951
|
+
init_md();
|
|
5952
|
+
init_u64();
|
|
5953
|
+
init_blake2();
|
|
5954
|
+
init_utils();
|
|
5955
|
+
B3_Flags = {
|
|
5956
|
+
CHUNK_START: 1,
|
|
5957
|
+
CHUNK_END: 2,
|
|
5958
|
+
PARENT: 4,
|
|
5959
|
+
ROOT: 8,
|
|
5960
|
+
KEYED_HASH: 16,
|
|
5961
|
+
DERIVE_KEY_CONTEXT: 32,
|
|
5962
|
+
DERIVE_KEY_MATERIAL: 64
|
|
5963
|
+
};
|
|
5964
|
+
B3_IV = SHA256_IV.slice();
|
|
5965
|
+
B3_SIGMA = /* @__PURE__ */ (() => {
|
|
5966
|
+
const Id = Array.from({ length: 16 }, (_, i) => i);
|
|
5967
|
+
const permute = (arr) => [2, 6, 3, 10, 7, 0, 4, 13, 1, 11, 12, 5, 9, 14, 15, 8].map((i) => arr[i]);
|
|
5968
|
+
const res = [];
|
|
5969
|
+
for (let i = 0, v = Id; i < 7; i++, v = permute(v))
|
|
5970
|
+
res.push(...v);
|
|
5971
|
+
return Uint8Array.from(res);
|
|
5972
|
+
})();
|
|
5973
|
+
BLAKE3 = class _BLAKE3 extends BLAKE2 {
|
|
5974
|
+
constructor(opts = {}, flags = 0) {
|
|
5975
|
+
super(64, opts.dkLen === void 0 ? 32 : opts.dkLen);
|
|
5976
|
+
this.chunkPos = 0;
|
|
5977
|
+
this.chunksDone = 0;
|
|
5978
|
+
this.flags = 0 | 0;
|
|
5979
|
+
this.stack = [];
|
|
5980
|
+
this.posOut = 0;
|
|
5981
|
+
this.bufferOut32 = new Uint32Array(16);
|
|
5982
|
+
this.chunkOut = 0;
|
|
5983
|
+
this.enableXOF = true;
|
|
5984
|
+
const { key, context } = opts;
|
|
5985
|
+
const hasContext = context !== void 0;
|
|
5986
|
+
if (key !== void 0) {
|
|
5987
|
+
if (hasContext)
|
|
5988
|
+
throw new Error('Only "key" or "context" can be specified at same time');
|
|
5989
|
+
const k = toBytes(key).slice();
|
|
5990
|
+
abytes(k, 32);
|
|
5991
|
+
this.IV = u32(k);
|
|
5992
|
+
swap32IfBE(this.IV);
|
|
5993
|
+
this.flags = flags | B3_Flags.KEYED_HASH;
|
|
5994
|
+
} else if (hasContext) {
|
|
5995
|
+
const ctx = toBytes(context);
|
|
5996
|
+
const contextKey = new _BLAKE3({ dkLen: 32 }, B3_Flags.DERIVE_KEY_CONTEXT).update(ctx).digest();
|
|
5997
|
+
this.IV = u32(contextKey);
|
|
5998
|
+
swap32IfBE(this.IV);
|
|
5999
|
+
this.flags = flags | B3_Flags.DERIVE_KEY_MATERIAL;
|
|
6000
|
+
} else {
|
|
6001
|
+
this.IV = B3_IV.slice();
|
|
6002
|
+
this.flags = flags;
|
|
6003
|
+
}
|
|
6004
|
+
this.state = this.IV.slice();
|
|
6005
|
+
this.bufferOut = u8(this.bufferOut32);
|
|
6006
|
+
}
|
|
6007
|
+
// Unused
|
|
6008
|
+
get() {
|
|
6009
|
+
return [];
|
|
6010
|
+
}
|
|
6011
|
+
set() {
|
|
6012
|
+
}
|
|
6013
|
+
b2Compress(counter, flags, buf, bufPos = 0) {
|
|
6014
|
+
const { state: s, pos } = this;
|
|
6015
|
+
const { h, l } = fromBig(BigInt(counter), true);
|
|
6016
|
+
const { v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15 } = compress(B3_SIGMA, bufPos, buf, 7, s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7], B3_IV[0], B3_IV[1], B3_IV[2], B3_IV[3], h, l, pos, flags);
|
|
6017
|
+
s[0] = v0 ^ v8;
|
|
6018
|
+
s[1] = v1 ^ v9;
|
|
6019
|
+
s[2] = v2 ^ v10;
|
|
6020
|
+
s[3] = v3 ^ v11;
|
|
6021
|
+
s[4] = v4 ^ v12;
|
|
6022
|
+
s[5] = v5 ^ v13;
|
|
6023
|
+
s[6] = v6 ^ v14;
|
|
6024
|
+
s[7] = v7 ^ v15;
|
|
6025
|
+
}
|
|
6026
|
+
compress(buf, bufPos = 0, isLast = false) {
|
|
6027
|
+
let flags = this.flags;
|
|
6028
|
+
if (!this.chunkPos)
|
|
6029
|
+
flags |= B3_Flags.CHUNK_START;
|
|
6030
|
+
if (this.chunkPos === 15 || isLast)
|
|
6031
|
+
flags |= B3_Flags.CHUNK_END;
|
|
6032
|
+
if (!isLast)
|
|
6033
|
+
this.pos = this.blockLen;
|
|
6034
|
+
this.b2Compress(this.chunksDone, flags, buf, bufPos);
|
|
6035
|
+
this.chunkPos += 1;
|
|
6036
|
+
if (this.chunkPos === 16 || isLast) {
|
|
6037
|
+
let chunk = this.state;
|
|
6038
|
+
this.state = this.IV.slice();
|
|
6039
|
+
for (let last, chunks = this.chunksDone + 1; isLast || !(chunks & 1); chunks >>= 1) {
|
|
6040
|
+
if (!(last = this.stack.pop()))
|
|
6041
|
+
break;
|
|
6042
|
+
this.buffer32.set(last, 0);
|
|
6043
|
+
this.buffer32.set(chunk, 8);
|
|
6044
|
+
this.pos = this.blockLen;
|
|
6045
|
+
this.b2Compress(0, this.flags | B3_Flags.PARENT, this.buffer32, 0);
|
|
6046
|
+
chunk = this.state;
|
|
6047
|
+
this.state = this.IV.slice();
|
|
6048
|
+
}
|
|
6049
|
+
this.chunksDone++;
|
|
6050
|
+
this.chunkPos = 0;
|
|
6051
|
+
this.stack.push(chunk);
|
|
6052
|
+
}
|
|
6053
|
+
this.pos = 0;
|
|
6054
|
+
}
|
|
6055
|
+
_cloneInto(to) {
|
|
6056
|
+
to = super._cloneInto(to);
|
|
6057
|
+
const { IV, flags, state: state2, chunkPos, posOut, chunkOut, stack, chunksDone } = this;
|
|
6058
|
+
to.state.set(state2.slice());
|
|
6059
|
+
to.stack = stack.map((i) => Uint32Array.from(i));
|
|
6060
|
+
to.IV.set(IV);
|
|
6061
|
+
to.flags = flags;
|
|
6062
|
+
to.chunkPos = chunkPos;
|
|
6063
|
+
to.chunksDone = chunksDone;
|
|
6064
|
+
to.posOut = posOut;
|
|
6065
|
+
to.chunkOut = chunkOut;
|
|
6066
|
+
to.enableXOF = this.enableXOF;
|
|
6067
|
+
to.bufferOut32.set(this.bufferOut32);
|
|
6068
|
+
return to;
|
|
6069
|
+
}
|
|
6070
|
+
destroy() {
|
|
6071
|
+
this.destroyed = true;
|
|
6072
|
+
clean(this.state, this.buffer32, this.IV, this.bufferOut32);
|
|
6073
|
+
clean(...this.stack);
|
|
6074
|
+
}
|
|
6075
|
+
// Same as b2Compress, but doesn't modify state and returns 16 u32 array (instead of 8)
|
|
6076
|
+
b2CompressOut() {
|
|
6077
|
+
const { state: s, pos, flags, buffer32, bufferOut32: out32 } = this;
|
|
6078
|
+
const { h, l } = fromBig(BigInt(this.chunkOut++));
|
|
6079
|
+
swap32IfBE(buffer32);
|
|
6080
|
+
const { v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15 } = compress(B3_SIGMA, 0, buffer32, 7, s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7], B3_IV[0], B3_IV[1], B3_IV[2], B3_IV[3], l, h, pos, flags);
|
|
6081
|
+
out32[0] = v0 ^ v8;
|
|
6082
|
+
out32[1] = v1 ^ v9;
|
|
6083
|
+
out32[2] = v2 ^ v10;
|
|
6084
|
+
out32[3] = v3 ^ v11;
|
|
6085
|
+
out32[4] = v4 ^ v12;
|
|
6086
|
+
out32[5] = v5 ^ v13;
|
|
6087
|
+
out32[6] = v6 ^ v14;
|
|
6088
|
+
out32[7] = v7 ^ v15;
|
|
6089
|
+
out32[8] = s[0] ^ v8;
|
|
6090
|
+
out32[9] = s[1] ^ v9;
|
|
6091
|
+
out32[10] = s[2] ^ v10;
|
|
6092
|
+
out32[11] = s[3] ^ v11;
|
|
6093
|
+
out32[12] = s[4] ^ v12;
|
|
6094
|
+
out32[13] = s[5] ^ v13;
|
|
6095
|
+
out32[14] = s[6] ^ v14;
|
|
6096
|
+
out32[15] = s[7] ^ v15;
|
|
6097
|
+
swap32IfBE(buffer32);
|
|
6098
|
+
swap32IfBE(out32);
|
|
6099
|
+
this.posOut = 0;
|
|
6100
|
+
}
|
|
6101
|
+
finish() {
|
|
6102
|
+
if (this.finished)
|
|
6103
|
+
return;
|
|
6104
|
+
this.finished = true;
|
|
6105
|
+
clean(this.buffer.subarray(this.pos));
|
|
6106
|
+
let flags = this.flags | B3_Flags.ROOT;
|
|
6107
|
+
if (this.stack.length) {
|
|
6108
|
+
flags |= B3_Flags.PARENT;
|
|
6109
|
+
swap32IfBE(this.buffer32);
|
|
6110
|
+
this.compress(this.buffer32, 0, true);
|
|
6111
|
+
swap32IfBE(this.buffer32);
|
|
6112
|
+
this.chunksDone = 0;
|
|
6113
|
+
this.pos = this.blockLen;
|
|
6114
|
+
} else {
|
|
6115
|
+
flags |= (!this.chunkPos ? B3_Flags.CHUNK_START : 0) | B3_Flags.CHUNK_END;
|
|
6116
|
+
}
|
|
6117
|
+
this.flags = flags;
|
|
6118
|
+
this.b2CompressOut();
|
|
6119
|
+
}
|
|
6120
|
+
writeInto(out) {
|
|
6121
|
+
aexists(this, false);
|
|
6122
|
+
abytes(out);
|
|
6123
|
+
this.finish();
|
|
6124
|
+
const { blockLen, bufferOut } = this;
|
|
6125
|
+
for (let pos = 0, len = out.length; pos < len; ) {
|
|
6126
|
+
if (this.posOut >= blockLen)
|
|
6127
|
+
this.b2CompressOut();
|
|
6128
|
+
const take = Math.min(blockLen - this.posOut, len - pos);
|
|
6129
|
+
out.set(bufferOut.subarray(this.posOut, this.posOut + take), pos);
|
|
6130
|
+
this.posOut += take;
|
|
6131
|
+
pos += take;
|
|
6132
|
+
}
|
|
6133
|
+
return out;
|
|
6134
|
+
}
|
|
6135
|
+
xofInto(out) {
|
|
6136
|
+
if (!this.enableXOF)
|
|
6137
|
+
throw new Error("XOF is not possible after digest call");
|
|
6138
|
+
return this.writeInto(out);
|
|
6139
|
+
}
|
|
6140
|
+
xof(bytes) {
|
|
6141
|
+
anumber(bytes);
|
|
6142
|
+
return this.xofInto(new Uint8Array(bytes));
|
|
6143
|
+
}
|
|
6144
|
+
digestInto(out) {
|
|
6145
|
+
aoutput(out, this);
|
|
6146
|
+
if (this.finished)
|
|
6147
|
+
throw new Error("digest() was already called");
|
|
6148
|
+
this.enableXOF = false;
|
|
6149
|
+
this.writeInto(out);
|
|
6150
|
+
this.destroy();
|
|
6151
|
+
return out;
|
|
6152
|
+
}
|
|
6153
|
+
digest() {
|
|
6154
|
+
return this.digestInto(new Uint8Array(this.outputLen));
|
|
6155
|
+
}
|
|
6156
|
+
};
|
|
6157
|
+
blake3 = /* @__PURE__ */ createXOFer((opts) => new BLAKE3(opts));
|
|
6158
|
+
}
|
|
6159
|
+
});
|
|
6160
|
+
|
|
6161
|
+
// ../../node_modules/@noble/curves/esm/utils.js
|
|
6162
|
+
function _abool2(value, title = "") {
|
|
6163
|
+
if (typeof value !== "boolean") {
|
|
6164
|
+
const prefix = title && `"${title}"`;
|
|
6165
|
+
throw new Error(prefix + "expected boolean, got type=" + typeof value);
|
|
6166
|
+
}
|
|
6167
|
+
return value;
|
|
5864
6168
|
}
|
|
5865
|
-
function
|
|
5866
|
-
const
|
|
5867
|
-
|
|
5868
|
-
|
|
6169
|
+
function _abytes2(value, length4, title = "") {
|
|
6170
|
+
const bytes = isBytes(value);
|
|
6171
|
+
const len = value?.length;
|
|
6172
|
+
const needsLen = length4 !== void 0;
|
|
6173
|
+
if (!bytes || needsLen && len !== length4) {
|
|
6174
|
+
const prefix = title && `"${title}" `;
|
|
6175
|
+
const ofLen = needsLen ? ` of length ${length4}` : "";
|
|
6176
|
+
const got = bytes ? `length=${len}` : `type=${typeof value}`;
|
|
6177
|
+
throw new Error(prefix + "expected Uint8Array" + ofLen + ", got " + got);
|
|
5869
6178
|
}
|
|
5870
|
-
|
|
5871
|
-
"AUTH_REQUIRED",
|
|
5872
|
-
`Profile "${profileName}" cannot restore its session because its private key material is missing.`,
|
|
5873
|
-
ExitCode.AUTH_REQUIRED,
|
|
5874
|
-
{
|
|
5875
|
-
hint: `Sign in again with: tc --profile ${profileName} auth login --method openkey`
|
|
5876
|
-
}
|
|
5877
|
-
);
|
|
6179
|
+
return value;
|
|
5878
6180
|
}
|
|
5879
|
-
function
|
|
5880
|
-
|
|
5881
|
-
|
|
5882
|
-
return
|
|
6181
|
+
function hexToNumber(hex3) {
|
|
6182
|
+
if (typeof hex3 !== "string")
|
|
6183
|
+
throw new Error("hex string expected, got " + typeof hex3);
|
|
6184
|
+
return hex3 === "" ? _0n : BigInt("0x" + hex3);
|
|
5883
6185
|
}
|
|
5884
|
-
|
|
5885
|
-
|
|
5886
|
-
await node.restoreSession(sessionData);
|
|
5887
|
-
} catch (error) {
|
|
5888
|
-
if (typeof error === "object" && error !== null && "code" in error && error.code === "AUTH_EXPIRED") {
|
|
5889
|
-
throw sessionExpiredError(profileName, profile === null ? void 0 : resolveProfilePosture(profile));
|
|
5890
|
-
}
|
|
5891
|
-
throw error;
|
|
5892
|
-
}
|
|
6186
|
+
function bytesToNumberBE(bytes) {
|
|
6187
|
+
return hexToNumber(bytesToHex(bytes));
|
|
5893
6188
|
}
|
|
5894
|
-
function
|
|
5895
|
-
|
|
5896
|
-
|
|
5897
|
-
delegationCid: session.delegationCid,
|
|
5898
|
-
spaceId: session.spaceId,
|
|
5899
|
-
jwk: signerJwkForProfile(profileName, session.jwk, key),
|
|
5900
|
-
verificationMethod: session.verificationMethod ?? profile.sessionDid ?? profile.did,
|
|
5901
|
-
address: session.address,
|
|
5902
|
-
chainId: session.chainId,
|
|
5903
|
-
siwe: session.siwe,
|
|
5904
|
-
signature: session.signature
|
|
5905
|
-
};
|
|
6189
|
+
function bytesToNumberLE(bytes) {
|
|
6190
|
+
abytes(bytes);
|
|
6191
|
+
return hexToNumber(bytesToHex(Uint8Array.from(bytes).reverse()));
|
|
5906
6192
|
}
|
|
5907
|
-
|
|
5908
|
-
|
|
5909
|
-
const session = await ProfileManager.getSession(ctx.profile);
|
|
5910
|
-
if (!session) return { unavailable: "session_missing" };
|
|
5911
|
-
if (typeof session.delegationCid !== "string" || typeof session.spaceId !== "string" || session.delegationHeader === null || typeof session.delegationHeader !== "object" || !("Authorization" in session.delegationHeader) || typeof session.delegationHeader.Authorization !== "string") {
|
|
5912
|
-
return { unavailable: "session_invalid" };
|
|
5913
|
-
}
|
|
5914
|
-
if (typeof session.expiresAt === "string" && Date.parse(session.expiresAt) <= Date.now()) {
|
|
5915
|
-
return { unavailable: "session_expired" };
|
|
5916
|
-
}
|
|
5917
|
-
const key = await ProfileManager.getKey(ctx.profile);
|
|
5918
|
-
try {
|
|
5919
|
-
const node = new TinyCloudNode({
|
|
5920
|
-
host: ctx.host,
|
|
5921
|
-
...profile.authMethod === "local" && profile.privateKey ? { privateKey: profile.privateKey } : {}
|
|
5922
|
-
});
|
|
5923
|
-
await restoreProfileSession(node, ctx.profile, profile, persistedSessionData(ctx.profile, profile, session, key));
|
|
5924
|
-
return { node };
|
|
5925
|
-
} catch (error) {
|
|
5926
|
-
if (error instanceof CLIError && error.metadata?.reason === "session_expired") {
|
|
5927
|
-
return { unavailable: "session_expired" };
|
|
5928
|
-
}
|
|
5929
|
-
return { unavailable: "session_invalid" };
|
|
5930
|
-
}
|
|
5931
|
-
}
|
|
5932
|
-
async function storedSessionVerifiesLocally(profileName) {
|
|
5933
|
-
const profile = await ProfileManager.getProfile(profileName).catch(() => null);
|
|
5934
|
-
if (profile === null) return true;
|
|
5935
|
-
const local = profile.authMethod === "local" && typeof profile.privateKey === "string";
|
|
5936
|
-
try {
|
|
5937
|
-
const session = await ProfileManager.getSession(profileName);
|
|
5938
|
-
if (!session || typeof session.delegationCid !== "string" || typeof session.spaceId !== "string" || session.delegationHeader === null || typeof session.delegationHeader !== "object" || !("Authorization" in session.delegationHeader) || typeof session.delegationHeader.Authorization !== "string") return true;
|
|
5939
|
-
const key = await ProfileManager.getKey(profileName);
|
|
5940
|
-
const node = new TinyCloudNode({
|
|
5941
|
-
host: profile.host ?? DEFAULT_HOST,
|
|
5942
|
-
...local ? { privateKey: profile.privateKey } : {}
|
|
5943
|
-
});
|
|
5944
|
-
await restoreProfileSession(node, profileName, profile, persistedSessionData(profileName, profile, session, key));
|
|
5945
|
-
return true;
|
|
5946
|
-
} catch {
|
|
5947
|
-
return false;
|
|
5948
|
-
}
|
|
6193
|
+
function numberToBytesBE(n, len) {
|
|
6194
|
+
return hexToBytes(n.toString(16).padStart(len * 2, "0"));
|
|
5949
6195
|
}
|
|
5950
|
-
|
|
5951
|
-
|
|
5952
|
-
const session = await ProfileManager.getSession(ctx.profile);
|
|
5953
|
-
const key = await ProfileManager.getKey(ctx.profile);
|
|
5954
|
-
const effectivePrivateKey = options?.privateKey ?? profile?.privateKey;
|
|
5955
|
-
if (!key && !effectivePrivateKey && !(profile?.authMethod === "openkey" && session !== null)) {
|
|
5956
|
-
throw new CLIError(
|
|
5957
|
-
"AUTH_REQUIRED",
|
|
5958
|
-
`No key found for profile "${ctx.profile}". Run \`tc --profile ${ctx.profile} auth rotate\` to create a new key and sign in.`,
|
|
5959
|
-
ExitCode.AUTH_REQUIRED
|
|
5960
|
-
);
|
|
5961
|
-
}
|
|
5962
|
-
if (profile?.authMethod === "local" && effectivePrivateKey) {
|
|
5963
|
-
const replication2 = createCliReplicationConfig(
|
|
5964
|
-
ctx.profile,
|
|
5965
|
-
profile?.replication,
|
|
5966
|
-
{ debug: ctx.replicationDebug, quiet: ctx.quiet },
|
|
5967
|
-
ctx.replication
|
|
5968
|
-
);
|
|
5969
|
-
if (ctx.replication && !replication2) {
|
|
5970
|
-
process.stderr.write("[replication] Enabled, but this profile has no configured prefixes; reads use the network.\n");
|
|
5971
|
-
}
|
|
5972
|
-
const node2 = new TinyCloudNode({
|
|
5973
|
-
host: ctx.host,
|
|
5974
|
-
privateKey: effectivePrivateKey,
|
|
5975
|
-
...replication2 ? { replication: replication2 } : {}
|
|
5976
|
-
});
|
|
5977
|
-
if (node2.replication) registerReplication(ctx.profile, node2.replication);
|
|
5978
|
-
const restoredOwnSession = Boolean(session && session.delegationHeader && session.delegationCid && session.spaceId);
|
|
5979
|
-
if (restoredOwnSession) {
|
|
5980
|
-
await restoreProfileSession(node2, ctx.profile, profile, persistedSessionData(ctx.profile, profile, session, key));
|
|
5981
|
-
} else {
|
|
5982
|
-
await node2.signIn();
|
|
5983
|
-
}
|
|
5984
|
-
if (restoredOwnSession) {
|
|
5985
|
-
recordWarnings(await replayAdditionalDelegations(node2, ctx.profile, {
|
|
5986
|
-
host: ctx.host,
|
|
5987
|
-
ownerSpace: profile.spaceId,
|
|
5988
|
-
migrate: options?.privateKey === void 0
|
|
5989
|
-
}));
|
|
5990
|
-
}
|
|
5991
|
-
return node2;
|
|
5992
|
-
}
|
|
5993
|
-
const replication = createCliReplicationConfig(
|
|
5994
|
-
ctx.profile,
|
|
5995
|
-
profile?.replication,
|
|
5996
|
-
{ debug: ctx.replicationDebug, quiet: ctx.quiet },
|
|
5997
|
-
ctx.replication
|
|
5998
|
-
);
|
|
5999
|
-
if (ctx.replication && !replication) {
|
|
6000
|
-
process.stderr.write("[replication] Enabled, but this profile has no configured prefixes; reads use the network.\n");
|
|
6001
|
-
}
|
|
6002
|
-
const node = new TinyCloudNode({
|
|
6003
|
-
host: ctx.host,
|
|
6004
|
-
privateKey: options?.privateKey,
|
|
6005
|
-
...replication ? { replication } : {}
|
|
6006
|
-
});
|
|
6007
|
-
if (node.replication) registerReplication(ctx.profile, node.replication);
|
|
6008
|
-
if (options?.privateKey) {
|
|
6009
|
-
await node.signIn();
|
|
6010
|
-
} else if (session && session.delegationHeader && session.delegationCid && session.spaceId) {
|
|
6011
|
-
await restoreProfileSession(node, ctx.profile, profile, persistedSessionData(ctx.profile, profile, session, key));
|
|
6012
|
-
recordWarnings(await replayAdditionalDelegations(node, ctx.profile, {
|
|
6013
|
-
host: ctx.host,
|
|
6014
|
-
ownerSpace: profile?.spaceId,
|
|
6015
|
-
migrate: true
|
|
6016
|
-
}));
|
|
6017
|
-
}
|
|
6018
|
-
return node;
|
|
6196
|
+
function numberToBytesLE(n, len) {
|
|
6197
|
+
return numberToBytesBE(n, len).reverse();
|
|
6019
6198
|
}
|
|
6020
|
-
|
|
6021
|
-
|
|
6022
|
-
|
|
6023
|
-
if (resolveProfilePosture(previousProfile) !== "delegate-session") {
|
|
6024
|
-
throw new CLIError(
|
|
6025
|
-
"AUTH_REQUIRED",
|
|
6026
|
-
`Profile "${ctx.profile}" is not a delegate-session profile.`,
|
|
6027
|
-
ExitCode.AUTH_REQUIRED
|
|
6028
|
-
);
|
|
6029
|
-
}
|
|
6030
|
-
const sessionDid = previousProfile.sessionDid ?? previousProfile.did;
|
|
6031
|
-
if (delegation.delegateDID.split("#", 1)[0] !== sessionDid.split("#", 1)[0]) {
|
|
6032
|
-
throw new CLIError(
|
|
6033
|
-
"DELEGATION_AUDIENCE_MISMATCH",
|
|
6034
|
-
`Delegation targets ${delegation.delegateDID}, but profile "${ctx.profile}" uses ${sessionDid}.`,
|
|
6035
|
-
ExitCode.PERMISSION_DENIED
|
|
6036
|
-
);
|
|
6037
|
-
}
|
|
6038
|
-
if (await ProfileManager.getSession(ctx.profile) !== null) {
|
|
6039
|
-
throw new CLIError(
|
|
6040
|
-
"PROFILE_CHANGED_DURING_IMPORT",
|
|
6041
|
-
`Profile "${ctx.profile}" gained a session (another login or import) after this import checked it. Nothing was saved; run the import again.`,
|
|
6042
|
-
ExitCode.ERROR
|
|
6043
|
-
);
|
|
6044
|
-
}
|
|
6045
|
-
if (signedLifetimePassed(delegation)) throw delegationExpiredError();
|
|
6046
|
-
const jwk = signerJwkForProfile(ctx.profile, void 0, await ProfileManager.getKey(ctx.profile));
|
|
6047
|
-
const session = {
|
|
6048
|
-
delegationHeader: delegation.delegationHeader,
|
|
6049
|
-
delegationCid: delegation.cid,
|
|
6050
|
-
spaceId: delegation.spaceId,
|
|
6051
|
-
jwk,
|
|
6052
|
-
verificationMethod: sessionDid
|
|
6053
|
-
};
|
|
6054
|
-
const profile = { ...previousProfile, sessionDid, spaceId: delegation.spaceId };
|
|
6199
|
+
function ensureBytes(title, hex3, expectedLength) {
|
|
6200
|
+
let res;
|
|
6201
|
+
if (typeof hex3 === "string") {
|
|
6055
6202
|
try {
|
|
6056
|
-
|
|
6057
|
-
|
|
6058
|
-
|
|
6059
|
-
throw annotate(error, await restoreBeforeBootstrap(ctx.profile, previousProfile));
|
|
6203
|
+
res = hexToBytes(hex3);
|
|
6204
|
+
} catch (e) {
|
|
6205
|
+
throw new Error(title + " must be hex string or Uint8Array, cause: " + e);
|
|
6060
6206
|
}
|
|
6061
|
-
|
|
6062
|
-
|
|
6063
|
-
|
|
6064
|
-
|
|
6065
|
-
const note = await ProfileManager.withLock(ctx.profile, async () => {
|
|
6066
|
-
const profile = await ProfileManager.getProfile(ctx.profile).catch((error) => {
|
|
6067
|
-
if (error instanceof CLIError && error.code === "PROFILE_NOT_FOUND") return null;
|
|
6068
|
-
throw error;
|
|
6069
|
-
});
|
|
6070
|
-
const session = await ProfileManager.getSession(ctx.profile);
|
|
6071
|
-
if (profile === null || BOOTSTRAP_PROFILE_FIELDS.some((field) => profile[field] !== written.profile[field]) || JSON.stringify(session) !== JSON.stringify(written.session)) {
|
|
6072
|
-
return `Profile "${ctx.profile}" changed while the import was pending (another login, logout or profile update), so its newer state was kept and the provisional session was not rolled back.`;
|
|
6073
|
-
}
|
|
6074
|
-
return restoreBeforeBootstrap(ctx.profile, written.previousProfile);
|
|
6075
|
-
}, { timeoutMs: PROFILE_COMMIT_LOCK_TIMEOUT_MS }).catch((error) => (
|
|
6076
|
-
// The lock or a read failed: the import's error stays the one reported.
|
|
6077
|
-
`Rolling back the provisional session of profile "${ctx.profile}" could not run (${failureName(error)}); check \`tc --profile ${ctx.profile} context\`.`
|
|
6078
|
-
));
|
|
6079
|
-
throw annotate(reported, note);
|
|
6080
|
-
};
|
|
6081
|
-
let node;
|
|
6082
|
-
try {
|
|
6083
|
-
node = await createSDKInstance(ctx);
|
|
6084
|
-
} catch (error) {
|
|
6085
|
-
return abandon(error);
|
|
6207
|
+
} else if (isBytes(hex3)) {
|
|
6208
|
+
res = Uint8Array.from(hex3);
|
|
6209
|
+
} else {
|
|
6210
|
+
throw new Error(title + " must be hex string or Uint8Array");
|
|
6086
6211
|
}
|
|
6087
|
-
|
|
6212
|
+
const len = res.length;
|
|
6213
|
+
if (typeof expectedLength === "number" && len !== expectedLength)
|
|
6214
|
+
throw new Error(title + " of length " + expectedLength + " expected, got " + len);
|
|
6215
|
+
return res;
|
|
6088
6216
|
}
|
|
6089
|
-
|
|
6090
|
-
|
|
6091
|
-
|
|
6092
|
-
|
|
6093
|
-
|
|
6094
|
-
|
|
6095
|
-
|
|
6096
|
-
if (previousProfile[field] === void 0) delete restored[field];
|
|
6097
|
-
else restored[field] = previousProfile[field];
|
|
6098
|
-
}
|
|
6099
|
-
return restored;
|
|
6100
|
-
})
|
|
6101
|
-
]) {
|
|
6102
|
-
await write().catch((error) => {
|
|
6103
|
-
failures.push(failureName(error));
|
|
6104
|
-
});
|
|
6105
|
-
}
|
|
6106
|
-
if (failures.length === 0) return void 0;
|
|
6107
|
-
return `Rolling back the provisional session of profile "${profileName}" failed too (${failures.join("; ")}); check \`tc --profile ${profileName} context\`.`;
|
|
6217
|
+
function equalBytes(a, b) {
|
|
6218
|
+
if (a.length !== b.length)
|
|
6219
|
+
return false;
|
|
6220
|
+
let diff = 0;
|
|
6221
|
+
for (let i = 0; i < a.length; i++)
|
|
6222
|
+
diff |= a[i] ^ b[i];
|
|
6223
|
+
return diff === 0;
|
|
6108
6224
|
}
|
|
6109
|
-
function
|
|
6110
|
-
|
|
6111
|
-
if (typeof error === "object" && error !== null && "code" in error && typeof error.code === "string") return error.code;
|
|
6112
|
-
return error instanceof Error ? error.name : "unknown error";
|
|
6225
|
+
function copyBytes(bytes) {
|
|
6226
|
+
return Uint8Array.from(bytes);
|
|
6113
6227
|
}
|
|
6114
|
-
function
|
|
6115
|
-
|
|
6116
|
-
const cause = wrapError(error);
|
|
6117
|
-
return new CLIError(cause.code, `${cause.message} ${note}`, cause.exitCode, cause.metadata);
|
|
6228
|
+
function inRange(n, min, max) {
|
|
6229
|
+
return isPosBig(n) && isPosBig(min) && isPosBig(max) && min <= n && n < max;
|
|
6118
6230
|
}
|
|
6119
|
-
|
|
6120
|
-
if (
|
|
6121
|
-
|
|
6122
|
-
}
|
|
6123
|
-
const profile = await ProfileManager.getProfile(ctx.profile).catch(() => null);
|
|
6124
|
-
if (profile?.authMethod === "local" && profile.privateKey) {
|
|
6125
|
-
return createSDKInstance(ctx);
|
|
6126
|
-
}
|
|
6127
|
-
const session = await ProfileManager.getSession(ctx.profile);
|
|
6128
|
-
if (!session) {
|
|
6129
|
-
throw new CLIError(
|
|
6130
|
-
"AUTH_REQUIRED",
|
|
6131
|
-
`Not authenticated. Run \`tc auth login\` or \`tc init\` first.`,
|
|
6132
|
-
ExitCode.AUTH_REQUIRED
|
|
6133
|
-
);
|
|
6134
|
-
}
|
|
6135
|
-
return createSDKInstance(ctx, options);
|
|
6231
|
+
function aInRange(title, n, min, max) {
|
|
6232
|
+
if (!inRange(n, min, max))
|
|
6233
|
+
throw new Error("expected valid " + title + ": " + min + " <= n < " + max + ", got " + n);
|
|
6136
6234
|
}
|
|
6137
|
-
|
|
6138
|
-
|
|
6139
|
-
|
|
6140
|
-
|
|
6141
|
-
|
|
6142
|
-
init_types();
|
|
6143
|
-
init_errors();
|
|
6144
|
-
init_constants();
|
|
6145
|
-
init_permissions();
|
|
6146
|
-
init_session_expired();
|
|
6147
|
-
init_warnings();
|
|
6148
|
-
init_delegation_expiry();
|
|
6149
|
-
init_replication_config();
|
|
6150
|
-
init_replication_registry();
|
|
6151
|
-
init_replication_registry();
|
|
6152
|
-
BOOTSTRAP_PROFILE_FIELDS = ["sessionDid", "spaceId"];
|
|
6153
|
-
}
|
|
6154
|
-
});
|
|
6155
|
-
|
|
6156
|
-
// src/lib/host.ts
|
|
6157
|
-
var host_exports = {};
|
|
6158
|
-
__export(host_exports, {
|
|
6159
|
-
completeDeferredLocalDiscovery: () => completeDeferredLocalDiscovery,
|
|
6160
|
-
discoverLocalNodeHost: () => discoverLocalNodeHost,
|
|
6161
|
-
isRootAuthority: () => isRootAuthority,
|
|
6162
|
-
ownerDidFromSpaceUri: () => ownerDidFromSpaceUri,
|
|
6163
|
-
profileLocalNodeIdentityStore: () => profileLocalNodeIdentityStore,
|
|
6164
|
-
resolveHostSpace: () => resolveHostSpace,
|
|
6165
|
-
spaceNameFromUri: () => spaceNameFromUri,
|
|
6166
|
-
unhostedSpaceError: () => unhostedSpaceError
|
|
6167
|
-
});
|
|
6168
|
-
import {
|
|
6169
|
-
discoverLocalTinyCloudNode
|
|
6170
|
-
} from "@tinycloud/sdk-core";
|
|
6171
|
-
function profileLocalNodeIdentityStore(profileName) {
|
|
6172
|
-
return {
|
|
6173
|
-
get: async (url) => {
|
|
6174
|
-
const profile = await ProfileManager.getProfile(profileName).catch(
|
|
6175
|
-
() => null
|
|
6176
|
-
);
|
|
6177
|
-
return profile?.pinnedLocalNodeDids?.[url];
|
|
6178
|
-
},
|
|
6179
|
-
set: async (url, nodeDid) => {
|
|
6180
|
-
if (!await ProfileManager.profileExists(profileName)) return;
|
|
6181
|
-
await ProfileManager.updateProfile(profileName, (profile) => ({
|
|
6182
|
-
...profile,
|
|
6183
|
-
pinnedLocalNodeDids: {
|
|
6184
|
-
...profile.pinnedLocalNodeDids,
|
|
6185
|
-
[url]: nodeDid
|
|
6186
|
-
}
|
|
6187
|
-
}));
|
|
6188
|
-
}
|
|
6189
|
-
};
|
|
6235
|
+
function bitLen(n) {
|
|
6236
|
+
let len;
|
|
6237
|
+
for (len = 0; n > _0n; n >>= _1n, len += 1)
|
|
6238
|
+
;
|
|
6239
|
+
return len;
|
|
6190
6240
|
}
|
|
6191
|
-
|
|
6192
|
-
|
|
6193
|
-
|
|
6194
|
-
|
|
6195
|
-
|
|
6196
|
-
|
|
6197
|
-
|
|
6241
|
+
function _validateObject(object3, fields, optFields = {}) {
|
|
6242
|
+
if (!object3 || typeof object3 !== "object")
|
|
6243
|
+
throw new Error("expected valid options object");
|
|
6244
|
+
function checkField(fieldName, expectedType, isOpt) {
|
|
6245
|
+
const val = object3[fieldName];
|
|
6246
|
+
if (isOpt && val === void 0)
|
|
6247
|
+
return;
|
|
6248
|
+
const current = typeof val;
|
|
6249
|
+
if (current !== expectedType || val === null)
|
|
6250
|
+
throw new Error(`param "${fieldName}" is invalid: expected ${expectedType}, got ${current}`);
|
|
6198
6251
|
}
|
|
6199
|
-
|
|
6200
|
-
|
|
6201
|
-
localLinkName: profile?.localLinkName,
|
|
6202
|
-
expectedNodeDid: profile?.expectedNodeDid,
|
|
6203
|
-
identityStore: profileLocalNodeIdentityStore(profileName)
|
|
6204
|
-
});
|
|
6205
|
-
return { host: discovered?.url ?? null, deferred: false };
|
|
6206
|
-
}
|
|
6207
|
-
async function completeDeferredLocalDiscovery(ctx) {
|
|
6208
|
-
const deferred = ctx.localDiscovery;
|
|
6209
|
-
if (deferred === void 0) return;
|
|
6210
|
-
delete ctx.localDiscovery;
|
|
6211
|
-
if (ctx.host !== deferred.deferredFrom) return;
|
|
6212
|
-
const discovered = await discoverLocalNodeHost(ctx.profile, { awaitStoredSession: false });
|
|
6213
|
-
if (discovered.host !== null) ctx.host = discovered.host;
|
|
6252
|
+
Object.entries(fields).forEach(([k, v]) => checkField(k, v, false));
|
|
6253
|
+
Object.entries(optFields).forEach(([k, v]) => checkField(k, v, true));
|
|
6214
6254
|
}
|
|
6215
|
-
function
|
|
6216
|
-
const
|
|
6217
|
-
return
|
|
6255
|
+
function memoized(fn) {
|
|
6256
|
+
const map = /* @__PURE__ */ new WeakMap();
|
|
6257
|
+
return (arg, ...args) => {
|
|
6258
|
+
const val = map.get(arg);
|
|
6259
|
+
if (val !== void 0)
|
|
6260
|
+
return val;
|
|
6261
|
+
const computed = fn(arg, ...args);
|
|
6262
|
+
map.set(arg, computed);
|
|
6263
|
+
return computed;
|
|
6264
|
+
};
|
|
6218
6265
|
}
|
|
6219
|
-
|
|
6220
|
-
|
|
6221
|
-
|
|
6222
|
-
|
|
6223
|
-
|
|
6266
|
+
var _0n, _1n, isPosBig, bitMask, notImplemented;
|
|
6267
|
+
var init_utils2 = __esm({
|
|
6268
|
+
"../../node_modules/@noble/curves/esm/utils.js"() {
|
|
6269
|
+
"use strict";
|
|
6270
|
+
init_utils();
|
|
6271
|
+
init_utils();
|
|
6272
|
+
_0n = /* @__PURE__ */ BigInt(0);
|
|
6273
|
+
_1n = /* @__PURE__ */ BigInt(1);
|
|
6274
|
+
isPosBig = (n) => typeof n === "bigint" && _0n <= n;
|
|
6275
|
+
bitMask = (n) => (_1n << BigInt(n)) - _1n;
|
|
6276
|
+
notImplemented = () => {
|
|
6277
|
+
throw new Error("not implemented");
|
|
6278
|
+
};
|
|
6224
6279
|
}
|
|
6225
|
-
|
|
6226
|
-
|
|
6227
|
-
|
|
6228
|
-
|
|
6280
|
+
});
|
|
6281
|
+
|
|
6282
|
+
// ../../node_modules/@noble/curves/esm/abstract/modular.js
|
|
6283
|
+
function mod(a, b) {
|
|
6284
|
+
const result = a % b;
|
|
6285
|
+
return result >= _0n2 ? result : b + result;
|
|
6286
|
+
}
|
|
6287
|
+
function pow2(x, power, modulo) {
|
|
6288
|
+
let res = x;
|
|
6289
|
+
while (power-- > _0n2) {
|
|
6290
|
+
res *= res;
|
|
6291
|
+
res %= modulo;
|
|
6229
6292
|
}
|
|
6230
|
-
return
|
|
6293
|
+
return res;
|
|
6231
6294
|
}
|
|
6232
|
-
function
|
|
6233
|
-
|
|
6234
|
-
|
|
6295
|
+
function invert(number, modulo) {
|
|
6296
|
+
if (number === _0n2)
|
|
6297
|
+
throw new Error("invert: expected non-zero number");
|
|
6298
|
+
if (modulo <= _0n2)
|
|
6299
|
+
throw new Error("invert: expected positive modulus, got " + modulo);
|
|
6300
|
+
let a = mod(number, modulo);
|
|
6301
|
+
let b = modulo;
|
|
6302
|
+
let x = _0n2, y = _1n2, u = _1n2, v = _0n2;
|
|
6303
|
+
while (a !== _0n2) {
|
|
6304
|
+
const q = b / a;
|
|
6305
|
+
const r = b % a;
|
|
6306
|
+
const m = x - u * q;
|
|
6307
|
+
const n = y - v * q;
|
|
6308
|
+
b = a, a = r, x = u, y = v, u = m, v = n;
|
|
6309
|
+
}
|
|
6310
|
+
const gcd = b;
|
|
6311
|
+
if (gcd !== _1n2)
|
|
6312
|
+
throw new Error("invert: does not exist");
|
|
6313
|
+
return mod(x, modulo);
|
|
6235
6314
|
}
|
|
6236
|
-
function
|
|
6237
|
-
|
|
6238
|
-
|
|
6239
|
-
return `did:pkh:eip155:${match[1]}:${canonicalizeAddress2(match[2])}`;
|
|
6315
|
+
function assertIsSquare(Fp2, root, n) {
|
|
6316
|
+
if (!Fp2.eql(Fp2.sqr(root), n))
|
|
6317
|
+
throw new Error("Cannot find square root");
|
|
6240
6318
|
}
|
|
6241
|
-
|
|
6242
|
-
const
|
|
6243
|
-
|
|
6244
|
-
|
|
6245
|
-
|
|
6246
|
-
const selfAddr = await resolveLocalAddress(profile, profileName);
|
|
6247
|
-
return selfAddr !== null && selfAddr === ownerAddr;
|
|
6319
|
+
function sqrt3mod4(Fp2, n) {
|
|
6320
|
+
const p1div4 = (Fp2.ORDER + _1n2) / _4n;
|
|
6321
|
+
const root = Fp2.pow(n, p1div4);
|
|
6322
|
+
assertIsSquare(Fp2, root, n);
|
|
6323
|
+
return root;
|
|
6248
6324
|
}
|
|
6249
|
-
function
|
|
6250
|
-
|
|
6325
|
+
function sqrt5mod8(Fp2, n) {
|
|
6326
|
+
const p5div8 = (Fp2.ORDER - _5n) / _8n;
|
|
6327
|
+
const n2 = Fp2.mul(n, _2n);
|
|
6328
|
+
const v = Fp2.pow(n2, p5div8);
|
|
6329
|
+
const nv = Fp2.mul(n, v);
|
|
6330
|
+
const i = Fp2.mul(Fp2.mul(nv, _2n), v);
|
|
6331
|
+
const root = Fp2.mul(nv, Fp2.sub(i, Fp2.ONE));
|
|
6332
|
+
assertIsSquare(Fp2, root, n);
|
|
6333
|
+
return root;
|
|
6251
6334
|
}
|
|
6252
|
-
|
|
6253
|
-
|
|
6254
|
-
const
|
|
6255
|
-
const
|
|
6256
|
-
|
|
6257
|
-
const
|
|
6258
|
-
const
|
|
6259
|
-
|
|
6260
|
-
|
|
6261
|
-
|
|
6262
|
-
|
|
6263
|
-
|
|
6264
|
-
|
|
6265
|
-
|
|
6266
|
-
|
|
6267
|
-
|
|
6268
|
-
|
|
6269
|
-
|
|
6270
|
-
|
|
6335
|
+
function sqrt9mod16(P) {
|
|
6336
|
+
const Fp_ = Field(P);
|
|
6337
|
+
const tn = tonelliShanks(P);
|
|
6338
|
+
const c1 = tn(Fp_, Fp_.neg(Fp_.ONE));
|
|
6339
|
+
const c2 = tn(Fp_, c1);
|
|
6340
|
+
const c3 = tn(Fp_, Fp_.neg(c1));
|
|
6341
|
+
const c4 = (P + _7n) / _16n;
|
|
6342
|
+
return (Fp2, n) => {
|
|
6343
|
+
let tv1 = Fp2.pow(n, c4);
|
|
6344
|
+
let tv2 = Fp2.mul(tv1, c1);
|
|
6345
|
+
const tv3 = Fp2.mul(tv1, c2);
|
|
6346
|
+
const tv4 = Fp2.mul(tv1, c3);
|
|
6347
|
+
const e1 = Fp2.eql(Fp2.sqr(tv2), n);
|
|
6348
|
+
const e2 = Fp2.eql(Fp2.sqr(tv3), n);
|
|
6349
|
+
tv1 = Fp2.cmov(tv1, tv2, e1);
|
|
6350
|
+
tv2 = Fp2.cmov(tv4, tv3, e2);
|
|
6351
|
+
const e3 = Fp2.eql(Fp2.sqr(tv2), n);
|
|
6352
|
+
const root = Fp2.cmov(tv1, tv2, e3);
|
|
6353
|
+
assertIsSquare(Fp2, root, n);
|
|
6354
|
+
return root;
|
|
6355
|
+
};
|
|
6271
6356
|
}
|
|
6272
|
-
|
|
6273
|
-
|
|
6274
|
-
|
|
6275
|
-
|
|
6357
|
+
function tonelliShanks(P) {
|
|
6358
|
+
if (P < _3n)
|
|
6359
|
+
throw new Error("sqrt is not defined for small field");
|
|
6360
|
+
let Q = P - _1n2;
|
|
6361
|
+
let S = 0;
|
|
6362
|
+
while (Q % _2n === _0n2) {
|
|
6363
|
+
Q /= _2n;
|
|
6364
|
+
S++;
|
|
6276
6365
|
}
|
|
6277
|
-
|
|
6278
|
-
|
|
6279
|
-
|
|
6280
|
-
|
|
6281
|
-
|
|
6282
|
-
init_profiles();
|
|
6283
|
-
init_constants();
|
|
6284
|
-
init_types();
|
|
6285
|
-
init_errors();
|
|
6286
|
-
init_space();
|
|
6287
|
-
}
|
|
6288
|
-
});
|
|
6289
|
-
|
|
6290
|
-
// src/config/profiles.ts
|
|
6291
|
-
import { chmod as chmod2, lstat, readdir as readdir2, rm as rm2, rmdir } from "fs/promises";
|
|
6292
|
-
import { join as join6 } from "path";
|
|
6293
|
-
import {
|
|
6294
|
-
profilePath as profilePath2,
|
|
6295
|
-
readSession,
|
|
6296
|
-
recordProfileDeletion,
|
|
6297
|
-
refuseWriteToDeletedProfile as refuseWriteToDeletedProfile2,
|
|
6298
|
-
removeSession,
|
|
6299
|
-
withProfileLock as withProfileLock3,
|
|
6300
|
-
writeSession
|
|
6301
|
-
} from "@tinycloud/operations/state";
|
|
6302
|
-
var ProfileManager;
|
|
6303
|
-
var init_profiles = __esm({
|
|
6304
|
-
"src/config/profiles.ts"() {
|
|
6305
|
-
"use strict";
|
|
6306
|
-
init_constants();
|
|
6307
|
-
init_storage2();
|
|
6308
|
-
init_errors();
|
|
6309
|
-
ProfileManager = class _ProfileManager {
|
|
6310
|
-
// ── Initialization ──────────────────────────────────────────────────
|
|
6311
|
-
/**
|
|
6312
|
-
* Runs `action` holding the profile's store lock (shared with operations
|
|
6313
|
-
* and MCP). Reentrant, so the writers below can be called inside it; hold
|
|
6314
|
-
* it around a whole read-modify-write, not just each write.
|
|
6315
|
-
*/
|
|
6316
|
-
static async withLock(name, action, options) {
|
|
6317
|
-
return withProfileLock3(name, action, options);
|
|
6318
|
-
}
|
|
6319
|
-
/**
|
|
6320
|
-
* Read-modify-write of profile.json under the profile lock, so concurrent
|
|
6321
|
-
* updates (another command, a login commit) are never erased.
|
|
6322
|
-
*/
|
|
6323
|
-
static async updateProfile(name, update) {
|
|
6324
|
-
return _ProfileManager.withLock(name, async () => {
|
|
6325
|
-
const next = update(await _ProfileManager.getProfile(name));
|
|
6326
|
-
await _ProfileManager.setProfile(name, next);
|
|
6327
|
-
return next;
|
|
6328
|
-
});
|
|
6329
|
-
}
|
|
6330
|
-
/**
|
|
6331
|
-
* Creates ~/.tinycloud/ and ~/.tinycloud/profiles/ if they don't exist and
|
|
6332
|
-
* (re)sets both to 0700: older releases created them 0775.
|
|
6333
|
-
*/
|
|
6334
|
-
static async ensureConfigDir() {
|
|
6335
|
-
for (const directory of [CONFIG_DIR, PROFILES_DIR]) {
|
|
6336
|
-
await ensureDir(directory);
|
|
6337
|
-
await chmod2(directory, PRIVATE_DIR_MODE);
|
|
6338
|
-
}
|
|
6339
|
-
}
|
|
6340
|
-
/** Owner-only profile directory (0700), created or tightened before any write into it. */
|
|
6341
|
-
static async ensureProfileDir(name) {
|
|
6342
|
-
await _ProfileManager.ensureConfigDir();
|
|
6343
|
-
const profileDir = join6(PROFILES_DIR, name);
|
|
6344
|
-
await ensureDir(profileDir);
|
|
6345
|
-
await chmod2(profileDir, PRIVATE_DIR_MODE);
|
|
6346
|
-
return profileDir;
|
|
6347
|
-
}
|
|
6348
|
-
// ── Global config ───────────────────────────────────────────────────
|
|
6349
|
-
/**
|
|
6350
|
-
* Reads config.json. Returns a default config if the file is missing.
|
|
6351
|
-
*/
|
|
6352
|
-
static async getConfig() {
|
|
6353
|
-
const config = await readJson(CONFIG_FILE);
|
|
6354
|
-
if (!config) {
|
|
6355
|
-
return { defaultProfile: DEFAULT_PROFILE, version: 1 };
|
|
6356
|
-
}
|
|
6357
|
-
return config;
|
|
6358
|
-
}
|
|
6359
|
-
/**
|
|
6360
|
-
* Writes the global config to config.json.
|
|
6361
|
-
*/
|
|
6362
|
-
static async setConfig(config) {
|
|
6363
|
-
await _ProfileManager.ensureConfigDir();
|
|
6364
|
-
await writeJson(CONFIG_FILE, config);
|
|
6365
|
-
}
|
|
6366
|
-
// ── Profile CRUD ────────────────────────────────────────────────────
|
|
6367
|
-
/**
|
|
6368
|
-
* Returns the profile config for the given name.
|
|
6369
|
-
* Throws CLIError if the profile doesn't exist.
|
|
6370
|
-
*/
|
|
6371
|
-
static async getProfile(name) {
|
|
6372
|
-
const profilePath3 = join6(PROFILES_DIR, name, "profile.json");
|
|
6373
|
-
const profile = await readJson(profilePath3);
|
|
6374
|
-
if (!profile) {
|
|
6375
|
-
throw new CLIError(
|
|
6376
|
-
"PROFILE_NOT_FOUND",
|
|
6377
|
-
`Profile "${name}" does not exist. Create it with \`tc init --name ${name}\`.`
|
|
6378
|
-
);
|
|
6379
|
-
}
|
|
6380
|
-
return profile;
|
|
6381
|
-
}
|
|
6382
|
-
/**
|
|
6383
|
-
* Saves a profile config under the profile lock, creating the profile
|
|
6384
|
-
* directory if needed. Use `updateProfile` to change an existing profile.
|
|
6385
|
-
*/
|
|
6386
|
-
static async setProfile(name, data) {
|
|
6387
|
-
await _ProfileManager.withLock(name, async () => {
|
|
6388
|
-
await writeJson(join6(await _ProfileManager.ensureProfileDir(name), "profile.json"), data);
|
|
6389
|
-
});
|
|
6390
|
-
}
|
|
6391
|
-
/** Removes profile.json under the profile lock (rollback of a profile a failed login created). */
|
|
6392
|
-
static async removeProfileConfig(name) {
|
|
6393
|
-
await _ProfileManager.withLock(name, () => rm2(join6(PROFILES_DIR, name, "profile.json"), { force: true }));
|
|
6394
|
-
}
|
|
6395
|
-
/**
|
|
6396
|
-
* Returns true if a profile directory exists.
|
|
6397
|
-
*/
|
|
6398
|
-
static async profileExists(name) {
|
|
6399
|
-
return fileExists(join6(PROFILES_DIR, name, "profile.json"));
|
|
6400
|
-
}
|
|
6401
|
-
/**
|
|
6402
|
-
* Returns an array of profile directory names.
|
|
6403
|
-
*/
|
|
6404
|
-
static async listProfiles() {
|
|
6405
|
-
return listDirs(PROFILES_DIR);
|
|
6406
|
-
}
|
|
6407
|
-
/**
|
|
6408
|
-
* Deletes a profile. Its key, session, settings, stores and cache are
|
|
6409
|
-
* removed while holding the profile lock, so another writer's critical
|
|
6410
|
-
* section never sees them vanish midway: session and key first, settings
|
|
6411
|
-
* last, so a crash midway never leaves a session or key without its
|
|
6412
|
-
* profile. The deletion is then recorded, so a store write that waited for
|
|
6413
|
-
* the lock meanwhile refuses rather than recreating a profile with only a
|
|
6414
|
-
* session in it. `.lock` itself is left to the lock's release; the
|
|
6415
|
-
* then-empty directory is removed afterwards unless another writer took
|
|
6416
|
-
* the lock (or wrote) meanwhile. A profile directory that is a symlink is
|
|
6417
|
-
* unlinked, its target left alone.
|
|
6418
|
-
* Throws if the name is not one path segment or names the default profile.
|
|
6419
|
-
*/
|
|
6420
|
-
static async deleteProfile(name) {
|
|
6421
|
-
let profileDir;
|
|
6422
|
-
try {
|
|
6423
|
-
profileDir = profilePath2(name);
|
|
6424
|
-
} catch {
|
|
6425
|
-
throw new CLIError(
|
|
6426
|
-
"INVALID_PROFILE_NAME",
|
|
6427
|
-
`Invalid profile name "${name}": a profile name is one path segment (no "/", "\\", "." or "..").`,
|
|
6428
|
-
ExitCode.USAGE_ERROR
|
|
6429
|
-
);
|
|
6430
|
-
}
|
|
6431
|
-
const config = await _ProfileManager.getConfig();
|
|
6432
|
-
if (config.defaultProfile === name) {
|
|
6433
|
-
throw new CLIError(
|
|
6434
|
-
"PROFILE_DELETE_DEFAULT",
|
|
6435
|
-
`Cannot delete the default profile "${name}". Change the default first with \`tc profile default <other>\`.`
|
|
6436
|
-
);
|
|
6437
|
-
}
|
|
6438
|
-
const kind = await lstat(profileDir).then((stats) => stats.isSymbolicLink() ? "link" : "present", (error) => {
|
|
6439
|
-
if (error.code === "ENOENT") return "missing";
|
|
6440
|
-
throw error;
|
|
6441
|
-
});
|
|
6442
|
-
if (kind === "missing") return;
|
|
6443
|
-
if (kind === "link") {
|
|
6444
|
-
await rm2(profileDir, { force: true });
|
|
6445
|
-
return;
|
|
6446
|
-
}
|
|
6447
|
-
await _ProfileManager.withLock(name, async () => {
|
|
6448
|
-
for (const file of ["session.json", "key.json"]) await rm2(join6(profileDir, file), { force: true });
|
|
6449
|
-
for (const entry of await readdir2(profileDir)) {
|
|
6450
|
-
if (entry !== ".lock" && entry !== "profile.json") await rm2(join6(profileDir, entry), { recursive: true, force: true });
|
|
6451
|
-
}
|
|
6452
|
-
await rm2(join6(profileDir, "profile.json"), { force: true });
|
|
6453
|
-
await recordProfileDeletion(name);
|
|
6454
|
-
});
|
|
6455
|
-
await rmdir(profileDir).catch((error) => {
|
|
6456
|
-
if (error.code !== "ENOENT" && error.code !== "ENOTEMPTY" && error.code !== "EEXIST") throw error;
|
|
6457
|
-
});
|
|
6458
|
-
}
|
|
6459
|
-
// ── Key management ──────────────────────────────────────────────────
|
|
6460
|
-
/**
|
|
6461
|
-
* Returns the parsed JWK for a profile, or null if no key exists.
|
|
6462
|
-
*/
|
|
6463
|
-
static async getKey(name) {
|
|
6464
|
-
return readJson(join6(PROFILES_DIR, name, "key.json"));
|
|
6465
|
-
}
|
|
6466
|
-
/**
|
|
6467
|
-
* Saves a JWK key under the profile lock (0600, in an owner-only profile
|
|
6468
|
-
* directory). Refused (PROFILE_NOT_FOUND) if the profile was deleted while
|
|
6469
|
-
* this waited for the lock, rather than leaving a key-only profile.
|
|
6470
|
-
*/
|
|
6471
|
-
static async setKey(name, jwk) {
|
|
6472
|
-
await _ProfileManager.withLock(name, async () => {
|
|
6473
|
-
await refuseWriteToDeletedProfile2(name);
|
|
6474
|
-
await writeJson(join6(await _ProfileManager.ensureProfileDir(name), "key.json"), jwk);
|
|
6475
|
-
});
|
|
6476
|
-
}
|
|
6477
|
-
/** Removes key.json under the profile lock (rollback of a key a failed login created). */
|
|
6478
|
-
static async removeKey(name) {
|
|
6479
|
-
await _ProfileManager.withLock(name, () => rm2(join6(PROFILES_DIR, name, "key.json"), { force: true }));
|
|
6480
|
-
}
|
|
6481
|
-
// ── Session management ──────────────────────────────────────────────
|
|
6482
|
-
/**
|
|
6483
|
-
* Returns the parsed session for a profile, or null if none exists.
|
|
6484
|
-
*/
|
|
6485
|
-
static async getSession(name) {
|
|
6486
|
-
return readSession(name);
|
|
6487
|
-
}
|
|
6488
|
-
/**
|
|
6489
|
-
* Saves session data for a profile.
|
|
6490
|
-
*/
|
|
6491
|
-
static async setSession(name, session) {
|
|
6492
|
-
await writeSession(name, session);
|
|
6493
|
-
}
|
|
6494
|
-
/**
|
|
6495
|
-
* Removes the session file for a profile.
|
|
6496
|
-
*/
|
|
6497
|
-
static async clearSession(name) {
|
|
6498
|
-
await removeSession(name);
|
|
6499
|
-
}
|
|
6500
|
-
// ── Cache management ────────────────────────────────────────────────
|
|
6501
|
-
/**
|
|
6502
|
-
* Returns the profile's cache directory (share history lives here),
|
|
6503
|
-
* created or tightened to 0700.
|
|
6504
|
-
*/
|
|
6505
|
-
static async getCacheDir(name) {
|
|
6506
|
-
const cacheDir = join6(await _ProfileManager.ensureProfileDir(name), "cache");
|
|
6507
|
-
await ensureDir(cacheDir);
|
|
6508
|
-
await chmod2(cacheDir, PRIVATE_DIR_MODE);
|
|
6509
|
-
return cacheDir;
|
|
6510
|
-
}
|
|
6511
|
-
// ── Resolution helpers ──────────────────────────────────────────────
|
|
6512
|
-
/**
|
|
6513
|
-
* Resolves the full CLI context from flags, env vars, and config.
|
|
6514
|
-
*
|
|
6515
|
-
* Profile resolution: options.profile > TC_PROFILE env > config.defaultProfile > "default"
|
|
6516
|
-
* Host resolution: options.host > TC_HOST env > discovered local node > profile.host > DEFAULT_HOST
|
|
6517
|
-
*
|
|
6518
|
-
* Local-node discovery (TC-106) only runs when no explicit host was given
|
|
6519
|
-
* (`--host` / `TC_HOST`); it probes configured or registered local nodes and,
|
|
6520
|
-
* after DID verification against the profile's pinned identity, prefers one
|
|
6521
|
-
* over the stored/default host. For session-using commands, it verifies the
|
|
6522
|
-
* stored session locally before probing. Loopback requires an explicit
|
|
6523
|
-
* `localNodeUrl`; disable discovery with `autoDiscoverLocalNode: false`.
|
|
6524
|
-
*/
|
|
6525
|
-
static async resolveContext(options, settings = {}) {
|
|
6526
|
-
const config = await _ProfileManager.getConfig();
|
|
6527
|
-
const profile = options.profile ?? process.env.TC_PROFILE ?? config.defaultProfile ?? DEFAULT_PROFILE;
|
|
6528
|
-
let profileHost;
|
|
6529
|
-
let profileConfig;
|
|
6530
|
-
try {
|
|
6531
|
-
profileConfig = await _ProfileManager.getProfile(profile);
|
|
6532
|
-
profileHost = profileConfig.host;
|
|
6533
|
-
} catch {
|
|
6534
|
-
}
|
|
6535
|
-
const envReplication = process.env.TC_REPLICATION?.toLowerCase();
|
|
6536
|
-
const envEnabled = envReplication === "1" || envReplication === "true" || envReplication === "on";
|
|
6537
|
-
const explicitEnvOff = envReplication === "0" || envReplication === "false" || envReplication === "off";
|
|
6538
|
-
if (envReplication !== void 0 && !envEnabled && !explicitEnvOff) {
|
|
6539
|
-
throw new CLIError("INVALID_ARGUMENT", "TC_REPLICATION must be one of 1, true, on, 0, false or off.", ExitCode.USAGE_ERROR);
|
|
6540
|
-
}
|
|
6541
|
-
const explicitOff = options.noReplication === true || options.replication === false;
|
|
6542
|
-
const replication = options.replication === true ? true : explicitOff ? false : envEnabled;
|
|
6543
|
-
const explicitHost = options.host ?? process.env.TC_HOST;
|
|
6544
|
-
let host = explicitHost ?? profileHost ?? DEFAULT_HOST;
|
|
6545
|
-
let localDiscovery;
|
|
6546
|
-
if (explicitHost === void 0) {
|
|
6547
|
-
const { discoverLocalNodeHost: discoverLocalNodeHost2 } = await Promise.resolve().then(() => (init_host(), host_exports));
|
|
6548
|
-
const explicitKey = Boolean(options.privateKey || process.env.TC_PRIVATE_KEY);
|
|
6549
|
-
const discovered = await discoverLocalNodeHost2(profile, {
|
|
6550
|
-
awaitStoredSession: settings.storedSession !== "unused" && !explicitKey
|
|
6551
|
-
});
|
|
6552
|
-
if (discovered.host !== null) host = discovered.host;
|
|
6553
|
-
if (discovered.deferred) localDiscovery = { deferredFrom: host };
|
|
6554
|
-
}
|
|
6555
|
-
setActiveProfileName(profile);
|
|
6556
|
-
return {
|
|
6557
|
-
profile,
|
|
6558
|
-
host,
|
|
6559
|
-
verbose: options.verbose ?? false,
|
|
6560
|
-
noCache: options.noCache ?? false,
|
|
6561
|
-
quiet: options.quiet ?? false,
|
|
6562
|
-
replication,
|
|
6563
|
-
replicationDebug: options.replicationDebug === true || process.env.TC_REPLICATION_DEBUG === "1",
|
|
6564
|
-
...localDiscovery === void 0 ? {} : { localDiscovery }
|
|
6565
|
-
};
|
|
6566
|
-
}
|
|
6567
|
-
};
|
|
6568
|
-
}
|
|
6569
|
-
});
|
|
6570
|
-
|
|
6571
|
-
// src/index.ts
|
|
6572
|
-
init_errors();
|
|
6573
|
-
import { readFileSync as readFileSync2 } from "fs";
|
|
6574
|
-
import { Command } from "commander";
|
|
6575
|
-
|
|
6576
|
-
// src/output/banner.ts
|
|
6577
|
-
init_formatter();
|
|
6578
|
-
|
|
6579
|
-
// src/output/taglines.ts
|
|
6580
|
-
var HOLIDAY_TAGLINES = [
|
|
6581
|
-
{ month: 1, day: 1, range: 1, tagline: "New year, new keys, same cloud." },
|
|
6582
|
-
{ month: 2, day: 14, tagline: "We love your data as much as you do." },
|
|
6583
|
-
{ month: 3, day: 14, tagline: "3.14159 reasons to encrypt everything." },
|
|
6584
|
-
{ month: 5, day: 4, tagline: "May the fourth be with your keys." },
|
|
6585
|
-
{ month: 10, day: 31, tagline: "Nothing scarier than plaintext secrets." },
|
|
6586
|
-
{ month: 12, day: 25, range: 2, tagline: "Unwrap your data, not your keys." },
|
|
6587
|
-
{ month: 12, day: 31, tagline: "Encrypt your resolutions." }
|
|
6588
|
-
];
|
|
6589
|
-
var TAGLINES = [
|
|
6590
|
-
// Professional
|
|
6591
|
-
"Your data, your keys, your cloud.",
|
|
6592
|
-
"Self-sovereign storage for the modern web.",
|
|
6593
|
-
"The cloud you actually own.",
|
|
6594
|
-
"Encrypted by default, decentralized by design.",
|
|
6595
|
-
"Where your data answers only to you.",
|
|
6596
|
-
"End-to-end encrypted. No exceptions.",
|
|
6597
|
-
"Like S3 but you hold the keys.",
|
|
6598
|
-
"Privacy isn't a feature. It's the architecture.",
|
|
6599
|
-
"Sovereign storage, zero knowledge.",
|
|
6600
|
-
"Your .env is safe here \u2014 we use real cryptography.",
|
|
6601
|
-
// Playful / nerdy
|
|
6602
|
-
"UCAN do anything.",
|
|
6603
|
-
"Keys generated, delegations granted, data liberated.",
|
|
6604
|
-
"Decentralized storage, centralized vibes.",
|
|
6605
|
-
"Trust nobody, delegate everything.",
|
|
6606
|
-
"sudo make me a sandwich, encrypted.",
|
|
6607
|
-
"Have you tried turning your keys off and on again?",
|
|
6608
|
-
"All your base are belong to you.",
|
|
6609
|
-
"In UCAN we trust.",
|
|
6610
|
-
"0 knowledge, 100% confidence.",
|
|
6611
|
-
"Keeping secrets since 2024."
|
|
6612
|
-
];
|
|
6613
|
-
function getHolidayTagline() {
|
|
6614
|
-
const now = /* @__PURE__ */ new Date();
|
|
6615
|
-
const month = now.getMonth() + 1;
|
|
6616
|
-
const day = now.getDate();
|
|
6617
|
-
for (const h of HOLIDAY_TAGLINES) {
|
|
6618
|
-
const range = h.range ?? 0;
|
|
6619
|
-
if (h.month === month && Math.abs(day - h.day) <= range) {
|
|
6620
|
-
return h.tagline;
|
|
6621
|
-
}
|
|
6622
|
-
}
|
|
6623
|
-
return null;
|
|
6624
|
-
}
|
|
6625
|
-
function pickTagline() {
|
|
6626
|
-
const holiday = getHolidayTagline();
|
|
6627
|
-
if (holiday) return holiday;
|
|
6628
|
-
return TAGLINES[Math.floor(Math.random() * TAGLINES.length)];
|
|
6629
|
-
}
|
|
6630
|
-
|
|
6631
|
-
// src/output/banner.ts
|
|
6632
|
-
init_theme();
|
|
6633
|
-
import { execSync } from "child_process";
|
|
6634
|
-
var bannerEmitted = false;
|
|
6635
|
-
function resolveCommitHash() {
|
|
6636
|
-
try {
|
|
6637
|
-
return execSync("git rev-parse --short HEAD", {
|
|
6638
|
-
encoding: "utf-8",
|
|
6639
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
6640
|
-
}).trim() || null;
|
|
6641
|
-
} catch {
|
|
6642
|
-
return null;
|
|
6643
|
-
}
|
|
6644
|
-
}
|
|
6645
|
-
function formatBannerLine(version2) {
|
|
6646
|
-
const commit = resolveCommitHash();
|
|
6647
|
-
const tagline = pickTagline();
|
|
6648
|
-
const versionPart = `tc v${version2}`;
|
|
6649
|
-
const commitPart = commit ? ` (${commit})` : "";
|
|
6650
|
-
const separator = " \u2014 ";
|
|
6651
|
-
if (!isInteractive()) {
|
|
6652
|
-
return `${versionPart}${commitPart}${separator}${tagline}`;
|
|
6653
|
-
}
|
|
6654
|
-
return [
|
|
6655
|
-
theme.brand("\u2601\uFE0F tc"),
|
|
6656
|
-
" ",
|
|
6657
|
-
theme.muted(`v${version2}`),
|
|
6658
|
-
commit ? theme.dim(` (${commit})`) : "",
|
|
6659
|
-
theme.dim(separator),
|
|
6660
|
-
theme.primary(tagline)
|
|
6661
|
-
].join("");
|
|
6662
|
-
}
|
|
6663
|
-
function emitBanner(version2) {
|
|
6664
|
-
if (bannerEmitted) return;
|
|
6665
|
-
if (shouldOutputJson()) return;
|
|
6666
|
-
if (process.env.TC_HIDE_BANNER === "1") return;
|
|
6667
|
-
bannerEmitted = true;
|
|
6668
|
-
process.stderr.write(formatBannerLine(version2) + "\n\n");
|
|
6669
|
-
}
|
|
6670
|
-
|
|
6671
|
-
// src/index.ts
|
|
6672
|
-
init_replication_registry();
|
|
6673
|
-
init_theme();
|
|
6674
|
-
init_formatter();
|
|
6675
|
-
init_profiles();
|
|
6676
|
-
|
|
6677
|
-
// ../share-sdk/dist/index.js
|
|
6678
|
-
init_sha2();
|
|
6679
|
-
|
|
6680
|
-
// ../../node_modules/@noble/curves/esm/ed25519.js
|
|
6681
|
-
init_sha2();
|
|
6682
|
-
init_utils();
|
|
6683
|
-
|
|
6684
|
-
// ../../node_modules/@noble/curves/esm/utils.js
|
|
6685
|
-
init_utils();
|
|
6686
|
-
init_utils();
|
|
6687
|
-
var _0n = /* @__PURE__ */ BigInt(0);
|
|
6688
|
-
var _1n = /* @__PURE__ */ BigInt(1);
|
|
6689
|
-
function _abool2(value, title = "") {
|
|
6690
|
-
if (typeof value !== "boolean") {
|
|
6691
|
-
const prefix = title && `"${title}"`;
|
|
6692
|
-
throw new Error(prefix + "expected boolean, got type=" + typeof value);
|
|
6693
|
-
}
|
|
6694
|
-
return value;
|
|
6695
|
-
}
|
|
6696
|
-
function _abytes2(value, length4, title = "") {
|
|
6697
|
-
const bytes = isBytes(value);
|
|
6698
|
-
const len = value?.length;
|
|
6699
|
-
const needsLen = length4 !== void 0;
|
|
6700
|
-
if (!bytes || needsLen && len !== length4) {
|
|
6701
|
-
const prefix = title && `"${title}" `;
|
|
6702
|
-
const ofLen = needsLen ? ` of length ${length4}` : "";
|
|
6703
|
-
const got = bytes ? `length=${len}` : `type=${typeof value}`;
|
|
6704
|
-
throw new Error(prefix + "expected Uint8Array" + ofLen + ", got " + got);
|
|
6705
|
-
}
|
|
6706
|
-
return value;
|
|
6707
|
-
}
|
|
6708
|
-
function hexToNumber(hex3) {
|
|
6709
|
-
if (typeof hex3 !== "string")
|
|
6710
|
-
throw new Error("hex string expected, got " + typeof hex3);
|
|
6711
|
-
return hex3 === "" ? _0n : BigInt("0x" + hex3);
|
|
6712
|
-
}
|
|
6713
|
-
function bytesToNumberBE(bytes) {
|
|
6714
|
-
return hexToNumber(bytesToHex(bytes));
|
|
6715
|
-
}
|
|
6716
|
-
function bytesToNumberLE(bytes) {
|
|
6717
|
-
abytes(bytes);
|
|
6718
|
-
return hexToNumber(bytesToHex(Uint8Array.from(bytes).reverse()));
|
|
6719
|
-
}
|
|
6720
|
-
function numberToBytesBE(n, len) {
|
|
6721
|
-
return hexToBytes(n.toString(16).padStart(len * 2, "0"));
|
|
6722
|
-
}
|
|
6723
|
-
function numberToBytesLE(n, len) {
|
|
6724
|
-
return numberToBytesBE(n, len).reverse();
|
|
6725
|
-
}
|
|
6726
|
-
function ensureBytes(title, hex3, expectedLength) {
|
|
6727
|
-
let res;
|
|
6728
|
-
if (typeof hex3 === "string") {
|
|
6729
|
-
try {
|
|
6730
|
-
res = hexToBytes(hex3);
|
|
6731
|
-
} catch (e) {
|
|
6732
|
-
throw new Error(title + " must be hex string or Uint8Array, cause: " + e);
|
|
6733
|
-
}
|
|
6734
|
-
} else if (isBytes(hex3)) {
|
|
6735
|
-
res = Uint8Array.from(hex3);
|
|
6736
|
-
} else {
|
|
6737
|
-
throw new Error(title + " must be hex string or Uint8Array");
|
|
6738
|
-
}
|
|
6739
|
-
const len = res.length;
|
|
6740
|
-
if (typeof expectedLength === "number" && len !== expectedLength)
|
|
6741
|
-
throw new Error(title + " of length " + expectedLength + " expected, got " + len);
|
|
6742
|
-
return res;
|
|
6743
|
-
}
|
|
6744
|
-
function equalBytes(a, b) {
|
|
6745
|
-
if (a.length !== b.length)
|
|
6746
|
-
return false;
|
|
6747
|
-
let diff = 0;
|
|
6748
|
-
for (let i = 0; i < a.length; i++)
|
|
6749
|
-
diff |= a[i] ^ b[i];
|
|
6750
|
-
return diff === 0;
|
|
6751
|
-
}
|
|
6752
|
-
function copyBytes(bytes) {
|
|
6753
|
-
return Uint8Array.from(bytes);
|
|
6754
|
-
}
|
|
6755
|
-
var isPosBig = (n) => typeof n === "bigint" && _0n <= n;
|
|
6756
|
-
function inRange(n, min, max) {
|
|
6757
|
-
return isPosBig(n) && isPosBig(min) && isPosBig(max) && min <= n && n < max;
|
|
6758
|
-
}
|
|
6759
|
-
function aInRange(title, n, min, max) {
|
|
6760
|
-
if (!inRange(n, min, max))
|
|
6761
|
-
throw new Error("expected valid " + title + ": " + min + " <= n < " + max + ", got " + n);
|
|
6762
|
-
}
|
|
6763
|
-
function bitLen(n) {
|
|
6764
|
-
let len;
|
|
6765
|
-
for (len = 0; n > _0n; n >>= _1n, len += 1)
|
|
6766
|
-
;
|
|
6767
|
-
return len;
|
|
6768
|
-
}
|
|
6769
|
-
var bitMask = (n) => (_1n << BigInt(n)) - _1n;
|
|
6770
|
-
function _validateObject(object3, fields, optFields = {}) {
|
|
6771
|
-
if (!object3 || typeof object3 !== "object")
|
|
6772
|
-
throw new Error("expected valid options object");
|
|
6773
|
-
function checkField(fieldName, expectedType, isOpt) {
|
|
6774
|
-
const val = object3[fieldName];
|
|
6775
|
-
if (isOpt && val === void 0)
|
|
6776
|
-
return;
|
|
6777
|
-
const current = typeof val;
|
|
6778
|
-
if (current !== expectedType || val === null)
|
|
6779
|
-
throw new Error(`param "${fieldName}" is invalid: expected ${expectedType}, got ${current}`);
|
|
6780
|
-
}
|
|
6781
|
-
Object.entries(fields).forEach(([k, v]) => checkField(k, v, false));
|
|
6782
|
-
Object.entries(optFields).forEach(([k, v]) => checkField(k, v, true));
|
|
6783
|
-
}
|
|
6784
|
-
var notImplemented = () => {
|
|
6785
|
-
throw new Error("not implemented");
|
|
6786
|
-
};
|
|
6787
|
-
function memoized(fn) {
|
|
6788
|
-
const map = /* @__PURE__ */ new WeakMap();
|
|
6789
|
-
return (arg, ...args) => {
|
|
6790
|
-
const val = map.get(arg);
|
|
6791
|
-
if (val !== void 0)
|
|
6792
|
-
return val;
|
|
6793
|
-
const computed = fn(arg, ...args);
|
|
6794
|
-
map.set(arg, computed);
|
|
6795
|
-
return computed;
|
|
6796
|
-
};
|
|
6797
|
-
}
|
|
6798
|
-
|
|
6799
|
-
// ../../node_modules/@noble/curves/esm/abstract/modular.js
|
|
6800
|
-
var _0n2 = BigInt(0);
|
|
6801
|
-
var _1n2 = BigInt(1);
|
|
6802
|
-
var _2n = /* @__PURE__ */ BigInt(2);
|
|
6803
|
-
var _3n = /* @__PURE__ */ BigInt(3);
|
|
6804
|
-
var _4n = /* @__PURE__ */ BigInt(4);
|
|
6805
|
-
var _5n = /* @__PURE__ */ BigInt(5);
|
|
6806
|
-
var _7n = /* @__PURE__ */ BigInt(7);
|
|
6807
|
-
var _8n = /* @__PURE__ */ BigInt(8);
|
|
6808
|
-
var _9n = /* @__PURE__ */ BigInt(9);
|
|
6809
|
-
var _16n = /* @__PURE__ */ BigInt(16);
|
|
6810
|
-
function mod(a, b) {
|
|
6811
|
-
const result = a % b;
|
|
6812
|
-
return result >= _0n2 ? result : b + result;
|
|
6813
|
-
}
|
|
6814
|
-
function pow2(x, power, modulo) {
|
|
6815
|
-
let res = x;
|
|
6816
|
-
while (power-- > _0n2) {
|
|
6817
|
-
res *= res;
|
|
6818
|
-
res %= modulo;
|
|
6819
|
-
}
|
|
6820
|
-
return res;
|
|
6821
|
-
}
|
|
6822
|
-
function invert(number, modulo) {
|
|
6823
|
-
if (number === _0n2)
|
|
6824
|
-
throw new Error("invert: expected non-zero number");
|
|
6825
|
-
if (modulo <= _0n2)
|
|
6826
|
-
throw new Error("invert: expected positive modulus, got " + modulo);
|
|
6827
|
-
let a = mod(number, modulo);
|
|
6828
|
-
let b = modulo;
|
|
6829
|
-
let x = _0n2, y = _1n2, u = _1n2, v = _0n2;
|
|
6830
|
-
while (a !== _0n2) {
|
|
6831
|
-
const q = b / a;
|
|
6832
|
-
const r = b % a;
|
|
6833
|
-
const m = x - u * q;
|
|
6834
|
-
const n = y - v * q;
|
|
6835
|
-
b = a, a = r, x = u, y = v, u = m, v = n;
|
|
6836
|
-
}
|
|
6837
|
-
const gcd = b;
|
|
6838
|
-
if (gcd !== _1n2)
|
|
6839
|
-
throw new Error("invert: does not exist");
|
|
6840
|
-
return mod(x, modulo);
|
|
6841
|
-
}
|
|
6842
|
-
function assertIsSquare(Fp2, root, n) {
|
|
6843
|
-
if (!Fp2.eql(Fp2.sqr(root), n))
|
|
6844
|
-
throw new Error("Cannot find square root");
|
|
6845
|
-
}
|
|
6846
|
-
function sqrt3mod4(Fp2, n) {
|
|
6847
|
-
const p1div4 = (Fp2.ORDER + _1n2) / _4n;
|
|
6848
|
-
const root = Fp2.pow(n, p1div4);
|
|
6849
|
-
assertIsSquare(Fp2, root, n);
|
|
6850
|
-
return root;
|
|
6851
|
-
}
|
|
6852
|
-
function sqrt5mod8(Fp2, n) {
|
|
6853
|
-
const p5div8 = (Fp2.ORDER - _5n) / _8n;
|
|
6854
|
-
const n2 = Fp2.mul(n, _2n);
|
|
6855
|
-
const v = Fp2.pow(n2, p5div8);
|
|
6856
|
-
const nv = Fp2.mul(n, v);
|
|
6857
|
-
const i = Fp2.mul(Fp2.mul(nv, _2n), v);
|
|
6858
|
-
const root = Fp2.mul(nv, Fp2.sub(i, Fp2.ONE));
|
|
6859
|
-
assertIsSquare(Fp2, root, n);
|
|
6860
|
-
return root;
|
|
6861
|
-
}
|
|
6862
|
-
function sqrt9mod16(P) {
|
|
6863
|
-
const Fp_ = Field(P);
|
|
6864
|
-
const tn = tonelliShanks(P);
|
|
6865
|
-
const c1 = tn(Fp_, Fp_.neg(Fp_.ONE));
|
|
6866
|
-
const c2 = tn(Fp_, c1);
|
|
6867
|
-
const c3 = tn(Fp_, Fp_.neg(c1));
|
|
6868
|
-
const c4 = (P + _7n) / _16n;
|
|
6869
|
-
return (Fp2, n) => {
|
|
6870
|
-
let tv1 = Fp2.pow(n, c4);
|
|
6871
|
-
let tv2 = Fp2.mul(tv1, c1);
|
|
6872
|
-
const tv3 = Fp2.mul(tv1, c2);
|
|
6873
|
-
const tv4 = Fp2.mul(tv1, c3);
|
|
6874
|
-
const e1 = Fp2.eql(Fp2.sqr(tv2), n);
|
|
6875
|
-
const e2 = Fp2.eql(Fp2.sqr(tv3), n);
|
|
6876
|
-
tv1 = Fp2.cmov(tv1, tv2, e1);
|
|
6877
|
-
tv2 = Fp2.cmov(tv4, tv3, e2);
|
|
6878
|
-
const e3 = Fp2.eql(Fp2.sqr(tv2), n);
|
|
6879
|
-
const root = Fp2.cmov(tv1, tv2, e3);
|
|
6880
|
-
assertIsSquare(Fp2, root, n);
|
|
6881
|
-
return root;
|
|
6882
|
-
};
|
|
6883
|
-
}
|
|
6884
|
-
function tonelliShanks(P) {
|
|
6885
|
-
if (P < _3n)
|
|
6886
|
-
throw new Error("sqrt is not defined for small field");
|
|
6887
|
-
let Q = P - _1n2;
|
|
6888
|
-
let S = 0;
|
|
6889
|
-
while (Q % _2n === _0n2) {
|
|
6890
|
-
Q /= _2n;
|
|
6891
|
-
S++;
|
|
6892
|
-
}
|
|
6893
|
-
let Z = _2n;
|
|
6894
|
-
const _Fp = Field(P);
|
|
6895
|
-
while (FpLegendre(_Fp, Z) === 1) {
|
|
6896
|
-
if (Z++ > 1e3)
|
|
6897
|
-
throw new Error("Cannot find square root: probably non-prime P");
|
|
6366
|
+
let Z = _2n;
|
|
6367
|
+
const _Fp = Field(P);
|
|
6368
|
+
while (FpLegendre(_Fp, Z) === 1) {
|
|
6369
|
+
if (Z++ > 1e3)
|
|
6370
|
+
throw new Error("Cannot find square root: probably non-prime P");
|
|
6898
6371
|
}
|
|
6899
6372
|
if (S === 1)
|
|
6900
6373
|
return sqrt3mod4;
|
|
@@ -6939,26 +6412,6 @@ function FpSqrt(P) {
|
|
|
6939
6412
|
return sqrt9mod16(P);
|
|
6940
6413
|
return tonelliShanks(P);
|
|
6941
6414
|
}
|
|
6942
|
-
var isNegativeLE = (num, modulo) => (mod(num, modulo) & _1n2) === _1n2;
|
|
6943
|
-
var FIELD_FIELDS = [
|
|
6944
|
-
"create",
|
|
6945
|
-
"isValid",
|
|
6946
|
-
"is0",
|
|
6947
|
-
"neg",
|
|
6948
|
-
"inv",
|
|
6949
|
-
"sqrt",
|
|
6950
|
-
"sqr",
|
|
6951
|
-
"eql",
|
|
6952
|
-
"add",
|
|
6953
|
-
"sub",
|
|
6954
|
-
"mul",
|
|
6955
|
-
"pow",
|
|
6956
|
-
"div",
|
|
6957
|
-
"addN",
|
|
6958
|
-
"subN",
|
|
6959
|
-
"mulN",
|
|
6960
|
-
"sqrN"
|
|
6961
|
-
];
|
|
6962
6415
|
function validateField(field) {
|
|
6963
6416
|
const initial = {
|
|
6964
6417
|
ORDER: "bigint",
|
|
@@ -7121,10 +6574,45 @@ function Field(ORDER, bitLenOrOpts, isLE2 = false, opts = {}) {
|
|
|
7121
6574
|
});
|
|
7122
6575
|
return Object.freeze(f);
|
|
7123
6576
|
}
|
|
6577
|
+
var _0n2, _1n2, _2n, _3n, _4n, _5n, _7n, _8n, _9n, _16n, isNegativeLE, FIELD_FIELDS;
|
|
6578
|
+
var init_modular = __esm({
|
|
6579
|
+
"../../node_modules/@noble/curves/esm/abstract/modular.js"() {
|
|
6580
|
+
"use strict";
|
|
6581
|
+
init_utils2();
|
|
6582
|
+
_0n2 = BigInt(0);
|
|
6583
|
+
_1n2 = BigInt(1);
|
|
6584
|
+
_2n = /* @__PURE__ */ BigInt(2);
|
|
6585
|
+
_3n = /* @__PURE__ */ BigInt(3);
|
|
6586
|
+
_4n = /* @__PURE__ */ BigInt(4);
|
|
6587
|
+
_5n = /* @__PURE__ */ BigInt(5);
|
|
6588
|
+
_7n = /* @__PURE__ */ BigInt(7);
|
|
6589
|
+
_8n = /* @__PURE__ */ BigInt(8);
|
|
6590
|
+
_9n = /* @__PURE__ */ BigInt(9);
|
|
6591
|
+
_16n = /* @__PURE__ */ BigInt(16);
|
|
6592
|
+
isNegativeLE = (num, modulo) => (mod(num, modulo) & _1n2) === _1n2;
|
|
6593
|
+
FIELD_FIELDS = [
|
|
6594
|
+
"create",
|
|
6595
|
+
"isValid",
|
|
6596
|
+
"is0",
|
|
6597
|
+
"neg",
|
|
6598
|
+
"inv",
|
|
6599
|
+
"sqrt",
|
|
6600
|
+
"sqr",
|
|
6601
|
+
"eql",
|
|
6602
|
+
"add",
|
|
6603
|
+
"sub",
|
|
6604
|
+
"mul",
|
|
6605
|
+
"pow",
|
|
6606
|
+
"div",
|
|
6607
|
+
"addN",
|
|
6608
|
+
"subN",
|
|
6609
|
+
"mulN",
|
|
6610
|
+
"sqrN"
|
|
6611
|
+
];
|
|
6612
|
+
}
|
|
6613
|
+
});
|
|
7124
6614
|
|
|
7125
6615
|
// ../../node_modules/@noble/curves/esm/abstract/curve.js
|
|
7126
|
-
var _0n3 = BigInt(0);
|
|
7127
|
-
var _1n3 = BigInt(1);
|
|
7128
6616
|
function negateCt(condition, item) {
|
|
7129
6617
|
const neg = item.negate();
|
|
7130
6618
|
return condition ? neg : item;
|
|
@@ -7171,149 +6659,20 @@ function validateMSMPoints(points, c) {
|
|
|
7171
6659
|
});
|
|
7172
6660
|
}
|
|
7173
6661
|
function validateMSMScalars(scalars, field) {
|
|
7174
|
-
if (!Array.isArray(scalars))
|
|
7175
|
-
throw new Error("array of scalars expected");
|
|
7176
|
-
scalars.forEach((s, i) => {
|
|
7177
|
-
if (!field.isValid(s))
|
|
7178
|
-
throw new Error("invalid scalar at index " + i);
|
|
7179
|
-
});
|
|
7180
|
-
}
|
|
7181
|
-
|
|
7182
|
-
|
|
7183
|
-
|
|
7184
|
-
|
|
7185
|
-
|
|
7186
|
-
|
|
7187
|
-
|
|
7188
|
-
throw new Error("invalid wNAF");
|
|
7189
|
-
}
|
|
7190
|
-
var wNAF = class {
|
|
7191
|
-
// Parametrized with a given Point class (not individual point)
|
|
7192
|
-
constructor(Point, bits) {
|
|
7193
|
-
this.BASE = Point.BASE;
|
|
7194
|
-
this.ZERO = Point.ZERO;
|
|
7195
|
-
this.Fn = Point.Fn;
|
|
7196
|
-
this.bits = bits;
|
|
7197
|
-
}
|
|
7198
|
-
// non-const time multiplication ladder
|
|
7199
|
-
_unsafeLadder(elm, n, p = this.ZERO) {
|
|
7200
|
-
let d = elm;
|
|
7201
|
-
while (n > _0n3) {
|
|
7202
|
-
if (n & _1n3)
|
|
7203
|
-
p = p.add(d);
|
|
7204
|
-
d = d.double();
|
|
7205
|
-
n >>= _1n3;
|
|
7206
|
-
}
|
|
7207
|
-
return p;
|
|
7208
|
-
}
|
|
7209
|
-
/**
|
|
7210
|
-
* Creates a wNAF precomputation window. Used for caching.
|
|
7211
|
-
* Default window size is set by `utils.precompute()` and is equal to 8.
|
|
7212
|
-
* Number of precomputed points depends on the curve size:
|
|
7213
|
-
* 2^(𝑊−1) * (Math.ceil(𝑛 / 𝑊) + 1), where:
|
|
7214
|
-
* - 𝑊 is the window size
|
|
7215
|
-
* - 𝑛 is the bitlength of the curve order.
|
|
7216
|
-
* For a 256-bit curve and window size 8, the number of precomputed points is 128 * 33 = 4224.
|
|
7217
|
-
* @param point Point instance
|
|
7218
|
-
* @param W window size
|
|
7219
|
-
* @returns precomputed point tables flattened to a single array
|
|
7220
|
-
*/
|
|
7221
|
-
precomputeWindow(point, W) {
|
|
7222
|
-
const { windows, windowSize } = calcWOpts(W, this.bits);
|
|
7223
|
-
const points = [];
|
|
7224
|
-
let p = point;
|
|
7225
|
-
let base4 = p;
|
|
7226
|
-
for (let window = 0; window < windows; window++) {
|
|
7227
|
-
base4 = p;
|
|
7228
|
-
points.push(base4);
|
|
7229
|
-
for (let i = 1; i < windowSize; i++) {
|
|
7230
|
-
base4 = base4.add(p);
|
|
7231
|
-
points.push(base4);
|
|
7232
|
-
}
|
|
7233
|
-
p = base4.double();
|
|
7234
|
-
}
|
|
7235
|
-
return points;
|
|
7236
|
-
}
|
|
7237
|
-
/**
|
|
7238
|
-
* Implements ec multiplication using precomputed tables and w-ary non-adjacent form.
|
|
7239
|
-
* More compact implementation:
|
|
7240
|
-
* https://github.com/paulmillr/noble-secp256k1/blob/47cb1669b6e506ad66b35fe7d76132ae97465da2/index.ts#L502-L541
|
|
7241
|
-
* @returns real and fake (for const-time) points
|
|
7242
|
-
*/
|
|
7243
|
-
wNAF(W, precomputes, n) {
|
|
7244
|
-
if (!this.Fn.isValid(n))
|
|
7245
|
-
throw new Error("invalid scalar");
|
|
7246
|
-
let p = this.ZERO;
|
|
7247
|
-
let f = this.BASE;
|
|
7248
|
-
const wo = calcWOpts(W, this.bits);
|
|
7249
|
-
for (let window = 0; window < wo.windows; window++) {
|
|
7250
|
-
const { nextN, offset, isZero, isNeg, isNegF, offsetF } = calcOffsets(n, window, wo);
|
|
7251
|
-
n = nextN;
|
|
7252
|
-
if (isZero) {
|
|
7253
|
-
f = f.add(negateCt(isNegF, precomputes[offsetF]));
|
|
7254
|
-
} else {
|
|
7255
|
-
p = p.add(negateCt(isNeg, precomputes[offset]));
|
|
7256
|
-
}
|
|
7257
|
-
}
|
|
7258
|
-
assert0(n);
|
|
7259
|
-
return { p, f };
|
|
7260
|
-
}
|
|
7261
|
-
/**
|
|
7262
|
-
* Implements ec unsafe (non const-time) multiplication using precomputed tables and w-ary non-adjacent form.
|
|
7263
|
-
* @param acc accumulator point to add result of multiplication
|
|
7264
|
-
* @returns point
|
|
7265
|
-
*/
|
|
7266
|
-
wNAFUnsafe(W, precomputes, n, acc = this.ZERO) {
|
|
7267
|
-
const wo = calcWOpts(W, this.bits);
|
|
7268
|
-
for (let window = 0; window < wo.windows; window++) {
|
|
7269
|
-
if (n === _0n3)
|
|
7270
|
-
break;
|
|
7271
|
-
const { nextN, offset, isZero, isNeg } = calcOffsets(n, window, wo);
|
|
7272
|
-
n = nextN;
|
|
7273
|
-
if (isZero) {
|
|
7274
|
-
continue;
|
|
7275
|
-
} else {
|
|
7276
|
-
const item = precomputes[offset];
|
|
7277
|
-
acc = acc.add(isNeg ? item.negate() : item);
|
|
7278
|
-
}
|
|
7279
|
-
}
|
|
7280
|
-
assert0(n);
|
|
7281
|
-
return acc;
|
|
7282
|
-
}
|
|
7283
|
-
getPrecomputes(W, point, transform) {
|
|
7284
|
-
let comp = pointPrecomputes.get(point);
|
|
7285
|
-
if (!comp) {
|
|
7286
|
-
comp = this.precomputeWindow(point, W);
|
|
7287
|
-
if (W !== 1) {
|
|
7288
|
-
if (typeof transform === "function")
|
|
7289
|
-
comp = transform(comp);
|
|
7290
|
-
pointPrecomputes.set(point, comp);
|
|
7291
|
-
}
|
|
7292
|
-
}
|
|
7293
|
-
return comp;
|
|
7294
|
-
}
|
|
7295
|
-
cached(point, scalar, transform) {
|
|
7296
|
-
const W = getW(point);
|
|
7297
|
-
return this.wNAF(W, this.getPrecomputes(W, point, transform), scalar);
|
|
7298
|
-
}
|
|
7299
|
-
unsafe(point, scalar, transform, prev) {
|
|
7300
|
-
const W = getW(point);
|
|
7301
|
-
if (W === 1)
|
|
7302
|
-
return this._unsafeLadder(point, scalar, prev);
|
|
7303
|
-
return this.wNAFUnsafe(W, this.getPrecomputes(W, point, transform), scalar, prev);
|
|
7304
|
-
}
|
|
7305
|
-
// We calculate precomputes for elliptic curve point multiplication
|
|
7306
|
-
// using windowed method. This specifies window size and
|
|
7307
|
-
// stores precomputed values. Usually only base point would be precomputed.
|
|
7308
|
-
createCache(P, W) {
|
|
7309
|
-
validateW(W, this.bits);
|
|
7310
|
-
pointWindowSizes.set(P, W);
|
|
7311
|
-
pointPrecomputes.delete(P);
|
|
7312
|
-
}
|
|
7313
|
-
hasCache(elm) {
|
|
7314
|
-
return getW(elm) !== 1;
|
|
7315
|
-
}
|
|
7316
|
-
};
|
|
6662
|
+
if (!Array.isArray(scalars))
|
|
6663
|
+
throw new Error("array of scalars expected");
|
|
6664
|
+
scalars.forEach((s, i) => {
|
|
6665
|
+
if (!field.isValid(s))
|
|
6666
|
+
throw new Error("invalid scalar at index " + i);
|
|
6667
|
+
});
|
|
6668
|
+
}
|
|
6669
|
+
function getW(P) {
|
|
6670
|
+
return pointWindowSizes.get(P) || 1;
|
|
6671
|
+
}
|
|
6672
|
+
function assert0(n) {
|
|
6673
|
+
if (n !== _0n3)
|
|
6674
|
+
throw new Error("invalid wNAF");
|
|
6675
|
+
}
|
|
7317
6676
|
function pippenger(c, fieldN, points, scalars) {
|
|
7318
6677
|
validateMSMPoints(points, c);
|
|
7319
6678
|
validateMSMScalars(scalars, fieldN);
|
|
@@ -7384,12 +6743,147 @@ function _createCurveFields(type, CURVE, curveOpts = {}, FpFnLE) {
|
|
|
7384
6743
|
CURVE = Object.freeze(Object.assign({}, CURVE));
|
|
7385
6744
|
return { CURVE, Fp: Fp2, Fn: Fn2 };
|
|
7386
6745
|
}
|
|
6746
|
+
var _0n3, _1n3, pointPrecomputes, pointWindowSizes, wNAF;
|
|
6747
|
+
var init_curve = __esm({
|
|
6748
|
+
"../../node_modules/@noble/curves/esm/abstract/curve.js"() {
|
|
6749
|
+
"use strict";
|
|
6750
|
+
init_utils2();
|
|
6751
|
+
init_modular();
|
|
6752
|
+
_0n3 = BigInt(0);
|
|
6753
|
+
_1n3 = BigInt(1);
|
|
6754
|
+
pointPrecomputes = /* @__PURE__ */ new WeakMap();
|
|
6755
|
+
pointWindowSizes = /* @__PURE__ */ new WeakMap();
|
|
6756
|
+
wNAF = class {
|
|
6757
|
+
// Parametrized with a given Point class (not individual point)
|
|
6758
|
+
constructor(Point, bits) {
|
|
6759
|
+
this.BASE = Point.BASE;
|
|
6760
|
+
this.ZERO = Point.ZERO;
|
|
6761
|
+
this.Fn = Point.Fn;
|
|
6762
|
+
this.bits = bits;
|
|
6763
|
+
}
|
|
6764
|
+
// non-const time multiplication ladder
|
|
6765
|
+
_unsafeLadder(elm, n, p = this.ZERO) {
|
|
6766
|
+
let d = elm;
|
|
6767
|
+
while (n > _0n3) {
|
|
6768
|
+
if (n & _1n3)
|
|
6769
|
+
p = p.add(d);
|
|
6770
|
+
d = d.double();
|
|
6771
|
+
n >>= _1n3;
|
|
6772
|
+
}
|
|
6773
|
+
return p;
|
|
6774
|
+
}
|
|
6775
|
+
/**
|
|
6776
|
+
* Creates a wNAF precomputation window. Used for caching.
|
|
6777
|
+
* Default window size is set by `utils.precompute()` and is equal to 8.
|
|
6778
|
+
* Number of precomputed points depends on the curve size:
|
|
6779
|
+
* 2^(𝑊−1) * (Math.ceil(𝑛 / 𝑊) + 1), where:
|
|
6780
|
+
* - 𝑊 is the window size
|
|
6781
|
+
* - 𝑛 is the bitlength of the curve order.
|
|
6782
|
+
* For a 256-bit curve and window size 8, the number of precomputed points is 128 * 33 = 4224.
|
|
6783
|
+
* @param point Point instance
|
|
6784
|
+
* @param W window size
|
|
6785
|
+
* @returns precomputed point tables flattened to a single array
|
|
6786
|
+
*/
|
|
6787
|
+
precomputeWindow(point, W) {
|
|
6788
|
+
const { windows, windowSize } = calcWOpts(W, this.bits);
|
|
6789
|
+
const points = [];
|
|
6790
|
+
let p = point;
|
|
6791
|
+
let base4 = p;
|
|
6792
|
+
for (let window = 0; window < windows; window++) {
|
|
6793
|
+
base4 = p;
|
|
6794
|
+
points.push(base4);
|
|
6795
|
+
for (let i = 1; i < windowSize; i++) {
|
|
6796
|
+
base4 = base4.add(p);
|
|
6797
|
+
points.push(base4);
|
|
6798
|
+
}
|
|
6799
|
+
p = base4.double();
|
|
6800
|
+
}
|
|
6801
|
+
return points;
|
|
6802
|
+
}
|
|
6803
|
+
/**
|
|
6804
|
+
* Implements ec multiplication using precomputed tables and w-ary non-adjacent form.
|
|
6805
|
+
* More compact implementation:
|
|
6806
|
+
* https://github.com/paulmillr/noble-secp256k1/blob/47cb1669b6e506ad66b35fe7d76132ae97465da2/index.ts#L502-L541
|
|
6807
|
+
* @returns real and fake (for const-time) points
|
|
6808
|
+
*/
|
|
6809
|
+
wNAF(W, precomputes, n) {
|
|
6810
|
+
if (!this.Fn.isValid(n))
|
|
6811
|
+
throw new Error("invalid scalar");
|
|
6812
|
+
let p = this.ZERO;
|
|
6813
|
+
let f = this.BASE;
|
|
6814
|
+
const wo = calcWOpts(W, this.bits);
|
|
6815
|
+
for (let window = 0; window < wo.windows; window++) {
|
|
6816
|
+
const { nextN, offset, isZero, isNeg, isNegF, offsetF } = calcOffsets(n, window, wo);
|
|
6817
|
+
n = nextN;
|
|
6818
|
+
if (isZero) {
|
|
6819
|
+
f = f.add(negateCt(isNegF, precomputes[offsetF]));
|
|
6820
|
+
} else {
|
|
6821
|
+
p = p.add(negateCt(isNeg, precomputes[offset]));
|
|
6822
|
+
}
|
|
6823
|
+
}
|
|
6824
|
+
assert0(n);
|
|
6825
|
+
return { p, f };
|
|
6826
|
+
}
|
|
6827
|
+
/**
|
|
6828
|
+
* Implements ec unsafe (non const-time) multiplication using precomputed tables and w-ary non-adjacent form.
|
|
6829
|
+
* @param acc accumulator point to add result of multiplication
|
|
6830
|
+
* @returns point
|
|
6831
|
+
*/
|
|
6832
|
+
wNAFUnsafe(W, precomputes, n, acc = this.ZERO) {
|
|
6833
|
+
const wo = calcWOpts(W, this.bits);
|
|
6834
|
+
for (let window = 0; window < wo.windows; window++) {
|
|
6835
|
+
if (n === _0n3)
|
|
6836
|
+
break;
|
|
6837
|
+
const { nextN, offset, isZero, isNeg } = calcOffsets(n, window, wo);
|
|
6838
|
+
n = nextN;
|
|
6839
|
+
if (isZero) {
|
|
6840
|
+
continue;
|
|
6841
|
+
} else {
|
|
6842
|
+
const item = precomputes[offset];
|
|
6843
|
+
acc = acc.add(isNeg ? item.negate() : item);
|
|
6844
|
+
}
|
|
6845
|
+
}
|
|
6846
|
+
assert0(n);
|
|
6847
|
+
return acc;
|
|
6848
|
+
}
|
|
6849
|
+
getPrecomputes(W, point, transform) {
|
|
6850
|
+
let comp = pointPrecomputes.get(point);
|
|
6851
|
+
if (!comp) {
|
|
6852
|
+
comp = this.precomputeWindow(point, W);
|
|
6853
|
+
if (W !== 1) {
|
|
6854
|
+
if (typeof transform === "function")
|
|
6855
|
+
comp = transform(comp);
|
|
6856
|
+
pointPrecomputes.set(point, comp);
|
|
6857
|
+
}
|
|
6858
|
+
}
|
|
6859
|
+
return comp;
|
|
6860
|
+
}
|
|
6861
|
+
cached(point, scalar, transform) {
|
|
6862
|
+
const W = getW(point);
|
|
6863
|
+
return this.wNAF(W, this.getPrecomputes(W, point, transform), scalar);
|
|
6864
|
+
}
|
|
6865
|
+
unsafe(point, scalar, transform, prev) {
|
|
6866
|
+
const W = getW(point);
|
|
6867
|
+
if (W === 1)
|
|
6868
|
+
return this._unsafeLadder(point, scalar, prev);
|
|
6869
|
+
return this.wNAFUnsafe(W, this.getPrecomputes(W, point, transform), scalar, prev);
|
|
6870
|
+
}
|
|
6871
|
+
// We calculate precomputes for elliptic curve point multiplication
|
|
6872
|
+
// using windowed method. This specifies window size and
|
|
6873
|
+
// stores precomputed values. Usually only base point would be precomputed.
|
|
6874
|
+
createCache(P, W) {
|
|
6875
|
+
validateW(W, this.bits);
|
|
6876
|
+
pointWindowSizes.set(P, W);
|
|
6877
|
+
pointPrecomputes.delete(P);
|
|
6878
|
+
}
|
|
6879
|
+
hasCache(elm) {
|
|
6880
|
+
return getW(elm) !== 1;
|
|
6881
|
+
}
|
|
6882
|
+
};
|
|
6883
|
+
}
|
|
6884
|
+
});
|
|
7387
6885
|
|
|
7388
6886
|
// ../../node_modules/@noble/curves/esm/abstract/edwards.js
|
|
7389
|
-
var _0n4 = BigInt(0);
|
|
7390
|
-
var _1n4 = BigInt(1);
|
|
7391
|
-
var _2n2 = BigInt(2);
|
|
7392
|
-
var _8n2 = BigInt(8);
|
|
7393
6887
|
function isEdValidXY(Fp2, CURVE, x, y) {
|
|
7394
6888
|
const x2 = Fp2.sqr(x);
|
|
7395
6889
|
const y2 = Fp2.sqr(y);
|
|
@@ -7673,828 +7167,1513 @@ function edwards(params, extraOpts = {}) {
|
|
|
7673
7167
|
Point.BASE.precompute(8);
|
|
7674
7168
|
return Point;
|
|
7675
7169
|
}
|
|
7676
|
-
|
|
7677
|
-
|
|
7678
|
-
|
|
7170
|
+
function eddsa(Point, cHash, eddsaOpts = {}) {
|
|
7171
|
+
if (typeof cHash !== "function")
|
|
7172
|
+
throw new Error('"hash" function param is required');
|
|
7173
|
+
_validateObject(eddsaOpts, {}, {
|
|
7174
|
+
adjustScalarBytes: "function",
|
|
7175
|
+
randomBytes: "function",
|
|
7176
|
+
domain: "function",
|
|
7177
|
+
prehash: "function",
|
|
7178
|
+
mapToCurve: "function"
|
|
7179
|
+
});
|
|
7180
|
+
const { prehash } = eddsaOpts;
|
|
7181
|
+
const { BASE, Fp: Fp2, Fn: Fn2 } = Point;
|
|
7182
|
+
const randomBytes3 = eddsaOpts.randomBytes || randomBytes;
|
|
7183
|
+
const adjustScalarBytes2 = eddsaOpts.adjustScalarBytes || ((bytes) => bytes);
|
|
7184
|
+
const domain = eddsaOpts.domain || ((data, ctx, phflag) => {
|
|
7185
|
+
_abool2(phflag, "phflag");
|
|
7186
|
+
if (ctx.length || phflag)
|
|
7187
|
+
throw new Error("Contexts/pre-hash are not supported");
|
|
7188
|
+
return data;
|
|
7189
|
+
});
|
|
7190
|
+
function modN_LE(hash) {
|
|
7191
|
+
return Fn2.create(bytesToNumberLE(hash));
|
|
7679
7192
|
}
|
|
7680
|
-
|
|
7681
|
-
|
|
7682
|
-
|
|
7193
|
+
function getPrivateScalar(key) {
|
|
7194
|
+
const len = lengths.secretKey;
|
|
7195
|
+
key = ensureBytes("private key", key, len);
|
|
7196
|
+
const hashed = ensureBytes("hashed private key", cHash(key), 2 * len);
|
|
7197
|
+
const head = adjustScalarBytes2(hashed.slice(0, len));
|
|
7198
|
+
const prefix = hashed.slice(len, 2 * len);
|
|
7199
|
+
const scalar = modN_LE(head);
|
|
7200
|
+
return { head, prefix, scalar };
|
|
7683
7201
|
}
|
|
7684
|
-
|
|
7685
|
-
|
|
7202
|
+
function getExtendedPublicKey(secretKey) {
|
|
7203
|
+
const { head, prefix, scalar } = getPrivateScalar(secretKey);
|
|
7204
|
+
const point = BASE.multiply(scalar);
|
|
7205
|
+
const pointBytes = point.toBytes();
|
|
7206
|
+
return { head, prefix, scalar, point, pointBytes };
|
|
7686
7207
|
}
|
|
7687
|
-
|
|
7688
|
-
return
|
|
7208
|
+
function getPublicKey(secretKey) {
|
|
7209
|
+
return getExtendedPublicKey(secretKey).pointBytes;
|
|
7689
7210
|
}
|
|
7690
|
-
|
|
7691
|
-
|
|
7211
|
+
function hashDomainToScalar(context = Uint8Array.of(), ...msgs) {
|
|
7212
|
+
const msg = concatBytes(...msgs);
|
|
7213
|
+
return modN_LE(cHash(domain(msg, ensureBytes("context", context), !!prehash)));
|
|
7692
7214
|
}
|
|
7693
|
-
|
|
7694
|
-
|
|
7695
|
-
|
|
7215
|
+
function sign(msg, secretKey, options = {}) {
|
|
7216
|
+
msg = ensureBytes("message", msg);
|
|
7217
|
+
if (prehash)
|
|
7218
|
+
msg = prehash(msg);
|
|
7219
|
+
const { prefix, scalar, pointBytes } = getExtendedPublicKey(secretKey);
|
|
7220
|
+
const r = hashDomainToScalar(options.context, prefix, msg);
|
|
7221
|
+
const R = BASE.multiply(r).toBytes();
|
|
7222
|
+
const k = hashDomainToScalar(options.context, R, pointBytes, msg);
|
|
7223
|
+
const s = Fn2.create(r + k * scalar);
|
|
7224
|
+
if (!Fn2.isValid(s))
|
|
7225
|
+
throw new Error("sign failed: invalid s");
|
|
7226
|
+
const rs = concatBytes(R, Fn2.toBytes(s));
|
|
7227
|
+
return _abytes2(rs, lengths.signature, "result");
|
|
7228
|
+
}
|
|
7229
|
+
const verifyOpts = { zip215: true };
|
|
7230
|
+
function verify(sig, msg, publicKey, options = verifyOpts) {
|
|
7231
|
+
const { context, zip215 } = options;
|
|
7232
|
+
const len = lengths.signature;
|
|
7233
|
+
sig = ensureBytes("signature", sig, len);
|
|
7234
|
+
msg = ensureBytes("message", msg);
|
|
7235
|
+
publicKey = ensureBytes("publicKey", publicKey, lengths.publicKey);
|
|
7236
|
+
if (zip215 !== void 0)
|
|
7237
|
+
_abool2(zip215, "zip215");
|
|
7238
|
+
if (prehash)
|
|
7239
|
+
msg = prehash(msg);
|
|
7240
|
+
const mid = len / 2;
|
|
7241
|
+
const r = sig.subarray(0, mid);
|
|
7242
|
+
const s = bytesToNumberLE(sig.subarray(mid, len));
|
|
7243
|
+
let A, R, SB;
|
|
7244
|
+
try {
|
|
7245
|
+
A = Point.fromBytes(publicKey, zip215);
|
|
7246
|
+
R = Point.fromBytes(r, zip215);
|
|
7247
|
+
SB = BASE.multiplyUnsafe(s);
|
|
7248
|
+
} catch (error) {
|
|
7249
|
+
return false;
|
|
7250
|
+
}
|
|
7251
|
+
if (!zip215 && A.isSmallOrder())
|
|
7252
|
+
return false;
|
|
7253
|
+
const k = hashDomainToScalar(context, R.toBytes(), A.toBytes(), msg);
|
|
7254
|
+
const RkA = R.add(A.multiplyUnsafe(k));
|
|
7255
|
+
return RkA.subtract(SB).clearCofactor().is0();
|
|
7256
|
+
}
|
|
7257
|
+
const _size = Fp2.BYTES;
|
|
7258
|
+
const lengths = {
|
|
7259
|
+
secretKey: _size,
|
|
7260
|
+
publicKey: _size,
|
|
7261
|
+
signature: 2 * _size,
|
|
7262
|
+
seed: _size
|
|
7263
|
+
};
|
|
7264
|
+
function randomSecretKey(seed = randomBytes3(lengths.seed)) {
|
|
7265
|
+
return _abytes2(seed, lengths.seed, "seed");
|
|
7266
|
+
}
|
|
7267
|
+
function keygen(seed) {
|
|
7268
|
+
const secretKey = utils.randomSecretKey(seed);
|
|
7269
|
+
return { secretKey, publicKey: getPublicKey(secretKey) };
|
|
7696
7270
|
}
|
|
7697
|
-
|
|
7698
|
-
|
|
7271
|
+
function isValidSecretKey(key) {
|
|
7272
|
+
return isBytes(key) && key.length === Fn2.BYTES;
|
|
7699
7273
|
}
|
|
7700
|
-
|
|
7701
|
-
|
|
7274
|
+
function isValidPublicKey(key, zip215) {
|
|
7275
|
+
try {
|
|
7276
|
+
return !!Point.fromBytes(key, zip215);
|
|
7277
|
+
} catch (error) {
|
|
7278
|
+
return false;
|
|
7279
|
+
}
|
|
7702
7280
|
}
|
|
7703
|
-
|
|
7704
|
-
|
|
7281
|
+
const utils = {
|
|
7282
|
+
getExtendedPublicKey,
|
|
7283
|
+
randomSecretKey,
|
|
7284
|
+
isValidSecretKey,
|
|
7285
|
+
isValidPublicKey,
|
|
7286
|
+
/**
|
|
7287
|
+
* Converts ed public key to x public key. Uses formula:
|
|
7288
|
+
* - ed25519:
|
|
7289
|
+
* - `(u, v) = ((1+y)/(1-y), sqrt(-486664)*u/x)`
|
|
7290
|
+
* - `(x, y) = (sqrt(-486664)*u/v, (u-1)/(u+1))`
|
|
7291
|
+
* - ed448:
|
|
7292
|
+
* - `(u, v) = ((y-1)/(y+1), sqrt(156324)*u/x)`
|
|
7293
|
+
* - `(x, y) = (sqrt(156324)*u/v, (1+u)/(1-u))`
|
|
7294
|
+
*/
|
|
7295
|
+
toMontgomery(publicKey) {
|
|
7296
|
+
const { y } = Point.fromBytes(publicKey);
|
|
7297
|
+
const size = lengths.publicKey;
|
|
7298
|
+
const is25519 = size === 32;
|
|
7299
|
+
if (!is25519 && size !== 57)
|
|
7300
|
+
throw new Error("only defined for 25519 and 448");
|
|
7301
|
+
const u = is25519 ? Fp2.div(_1n4 + y, _1n4 - y) : Fp2.div(y - _1n4, y + _1n4);
|
|
7302
|
+
return Fp2.toBytes(u);
|
|
7303
|
+
},
|
|
7304
|
+
toMontgomerySecret(secretKey) {
|
|
7305
|
+
const size = lengths.secretKey;
|
|
7306
|
+
_abytes2(secretKey, size);
|
|
7307
|
+
const hashed = cHash(secretKey.subarray(0, size));
|
|
7308
|
+
return adjustScalarBytes2(hashed).subarray(0, size);
|
|
7309
|
+
},
|
|
7310
|
+
/** @deprecated */
|
|
7311
|
+
randomPrivateKey: randomSecretKey,
|
|
7312
|
+
/** @deprecated */
|
|
7313
|
+
precompute(windowSize = 8, point = Point.BASE) {
|
|
7314
|
+
return point.precompute(windowSize, false);
|
|
7315
|
+
}
|
|
7316
|
+
};
|
|
7317
|
+
return Object.freeze({
|
|
7318
|
+
keygen,
|
|
7319
|
+
getPublicKey,
|
|
7320
|
+
sign,
|
|
7321
|
+
verify,
|
|
7322
|
+
utils,
|
|
7323
|
+
Point,
|
|
7324
|
+
lengths
|
|
7325
|
+
});
|
|
7326
|
+
}
|
|
7327
|
+
function _eddsa_legacy_opts_to_new(c) {
|
|
7328
|
+
const CURVE = {
|
|
7329
|
+
a: c.a,
|
|
7330
|
+
d: c.d,
|
|
7331
|
+
p: c.Fp.ORDER,
|
|
7332
|
+
n: c.n,
|
|
7333
|
+
h: c.h,
|
|
7334
|
+
Gx: c.Gx,
|
|
7335
|
+
Gy: c.Gy
|
|
7336
|
+
};
|
|
7337
|
+
const Fp2 = c.Fp;
|
|
7338
|
+
const Fn2 = Field(CURVE.n, c.nBitLength, true);
|
|
7339
|
+
const curveOpts = { Fp: Fp2, Fn: Fn2, uvRatio: c.uvRatio };
|
|
7340
|
+
const eddsaOpts = {
|
|
7341
|
+
randomBytes: c.randomBytes,
|
|
7342
|
+
adjustScalarBytes: c.adjustScalarBytes,
|
|
7343
|
+
domain: c.domain,
|
|
7344
|
+
prehash: c.prehash,
|
|
7345
|
+
mapToCurve: c.mapToCurve
|
|
7346
|
+
};
|
|
7347
|
+
return { CURVE, curveOpts, hash: c.hash, eddsaOpts };
|
|
7348
|
+
}
|
|
7349
|
+
function _eddsa_new_output_to_legacy(c, eddsa2) {
|
|
7350
|
+
const Point = eddsa2.Point;
|
|
7351
|
+
const legacy = Object.assign({}, eddsa2, {
|
|
7352
|
+
ExtendedPoint: Point,
|
|
7353
|
+
CURVE: c,
|
|
7354
|
+
nBitLength: Point.Fn.BITS,
|
|
7355
|
+
nByteLength: Point.Fn.BYTES
|
|
7356
|
+
});
|
|
7357
|
+
return legacy;
|
|
7358
|
+
}
|
|
7359
|
+
function twistedEdwards(c) {
|
|
7360
|
+
const { CURVE, curveOpts, hash, eddsaOpts } = _eddsa_legacy_opts_to_new(c);
|
|
7361
|
+
const Point = edwards(CURVE, curveOpts);
|
|
7362
|
+
const EDDSA = eddsa(Point, hash, eddsaOpts);
|
|
7363
|
+
return _eddsa_new_output_to_legacy(c, EDDSA);
|
|
7364
|
+
}
|
|
7365
|
+
var _0n4, _1n4, _2n2, _8n2, PrimeEdwardsPoint;
|
|
7366
|
+
var init_edwards = __esm({
|
|
7367
|
+
"../../node_modules/@noble/curves/esm/abstract/edwards.js"() {
|
|
7368
|
+
"use strict";
|
|
7369
|
+
init_utils2();
|
|
7370
|
+
init_curve();
|
|
7371
|
+
init_modular();
|
|
7372
|
+
_0n4 = BigInt(0);
|
|
7373
|
+
_1n4 = BigInt(1);
|
|
7374
|
+
_2n2 = BigInt(2);
|
|
7375
|
+
_8n2 = BigInt(8);
|
|
7376
|
+
PrimeEdwardsPoint = class {
|
|
7377
|
+
constructor(ep) {
|
|
7378
|
+
this.ep = ep;
|
|
7379
|
+
}
|
|
7380
|
+
// Static methods that must be implemented by subclasses
|
|
7381
|
+
static fromBytes(_bytes) {
|
|
7382
|
+
notImplemented();
|
|
7383
|
+
}
|
|
7384
|
+
static fromHex(_hex) {
|
|
7385
|
+
notImplemented();
|
|
7386
|
+
}
|
|
7387
|
+
get x() {
|
|
7388
|
+
return this.toAffine().x;
|
|
7389
|
+
}
|
|
7390
|
+
get y() {
|
|
7391
|
+
return this.toAffine().y;
|
|
7392
|
+
}
|
|
7393
|
+
// Common implementations
|
|
7394
|
+
clearCofactor() {
|
|
7395
|
+
return this;
|
|
7396
|
+
}
|
|
7397
|
+
assertValidity() {
|
|
7398
|
+
this.ep.assertValidity();
|
|
7399
|
+
}
|
|
7400
|
+
toAffine(invertedZ) {
|
|
7401
|
+
return this.ep.toAffine(invertedZ);
|
|
7402
|
+
}
|
|
7403
|
+
toHex() {
|
|
7404
|
+
return bytesToHex(this.toBytes());
|
|
7405
|
+
}
|
|
7406
|
+
toString() {
|
|
7407
|
+
return this.toHex();
|
|
7408
|
+
}
|
|
7409
|
+
isTorsionFree() {
|
|
7410
|
+
return true;
|
|
7411
|
+
}
|
|
7412
|
+
isSmallOrder() {
|
|
7413
|
+
return false;
|
|
7414
|
+
}
|
|
7415
|
+
add(other) {
|
|
7416
|
+
this.assertSame(other);
|
|
7417
|
+
return this.init(this.ep.add(other.ep));
|
|
7418
|
+
}
|
|
7419
|
+
subtract(other) {
|
|
7420
|
+
this.assertSame(other);
|
|
7421
|
+
return this.init(this.ep.subtract(other.ep));
|
|
7422
|
+
}
|
|
7423
|
+
multiply(scalar) {
|
|
7424
|
+
return this.init(this.ep.multiply(scalar));
|
|
7425
|
+
}
|
|
7426
|
+
multiplyUnsafe(scalar) {
|
|
7427
|
+
return this.init(this.ep.multiplyUnsafe(scalar));
|
|
7428
|
+
}
|
|
7429
|
+
double() {
|
|
7430
|
+
return this.init(this.ep.double());
|
|
7431
|
+
}
|
|
7432
|
+
negate() {
|
|
7433
|
+
return this.init(this.ep.negate());
|
|
7434
|
+
}
|
|
7435
|
+
precompute(windowSize, isLazy) {
|
|
7436
|
+
return this.init(this.ep.precompute(windowSize, isLazy));
|
|
7437
|
+
}
|
|
7438
|
+
/** @deprecated use `toBytes` */
|
|
7439
|
+
toRawBytes() {
|
|
7440
|
+
return this.toBytes();
|
|
7441
|
+
}
|
|
7442
|
+
};
|
|
7705
7443
|
}
|
|
7706
|
-
|
|
7707
|
-
|
|
7444
|
+
});
|
|
7445
|
+
|
|
7446
|
+
// ../../node_modules/@noble/curves/esm/ed25519.js
|
|
7447
|
+
function ed25519_pow_2_252_3(x) {
|
|
7448
|
+
const _10n = BigInt(10), _20n = BigInt(20), _40n = BigInt(40), _80n = BigInt(80);
|
|
7449
|
+
const P = ed25519_CURVE_p;
|
|
7450
|
+
const x2 = x * x % P;
|
|
7451
|
+
const b2 = x2 * x % P;
|
|
7452
|
+
const b4 = pow2(b2, _2n3, P) * b2 % P;
|
|
7453
|
+
const b5 = pow2(b4, _1n5, P) * x % P;
|
|
7454
|
+
const b10 = pow2(b5, _5n2, P) * b5 % P;
|
|
7455
|
+
const b20 = pow2(b10, _10n, P) * b10 % P;
|
|
7456
|
+
const b40 = pow2(b20, _20n, P) * b20 % P;
|
|
7457
|
+
const b80 = pow2(b40, _40n, P) * b40 % P;
|
|
7458
|
+
const b160 = pow2(b80, _80n, P) * b80 % P;
|
|
7459
|
+
const b240 = pow2(b160, _80n, P) * b80 % P;
|
|
7460
|
+
const b250 = pow2(b240, _10n, P) * b10 % P;
|
|
7461
|
+
const pow_p_5_8 = pow2(b250, _2n3, P) * x % P;
|
|
7462
|
+
return { pow_p_5_8, b2 };
|
|
7463
|
+
}
|
|
7464
|
+
function adjustScalarBytes(bytes) {
|
|
7465
|
+
bytes[0] &= 248;
|
|
7466
|
+
bytes[31] &= 127;
|
|
7467
|
+
bytes[31] |= 64;
|
|
7468
|
+
return bytes;
|
|
7469
|
+
}
|
|
7470
|
+
function uvRatio(u, v) {
|
|
7471
|
+
const P = ed25519_CURVE_p;
|
|
7472
|
+
const v3 = mod(v * v * v, P);
|
|
7473
|
+
const v7 = mod(v3 * v3 * v, P);
|
|
7474
|
+
const pow = ed25519_pow_2_252_3(u * v7).pow_p_5_8;
|
|
7475
|
+
let x = mod(u * v3 * pow, P);
|
|
7476
|
+
const vx2 = mod(v * x * x, P);
|
|
7477
|
+
const root1 = x;
|
|
7478
|
+
const root2 = mod(x * ED25519_SQRT_M1, P);
|
|
7479
|
+
const useRoot1 = vx2 === u;
|
|
7480
|
+
const useRoot2 = vx2 === mod(-u, P);
|
|
7481
|
+
const noRoot = vx2 === mod(-u * ED25519_SQRT_M1, P);
|
|
7482
|
+
if (useRoot1)
|
|
7483
|
+
x = root1;
|
|
7484
|
+
if (useRoot2 || noRoot)
|
|
7485
|
+
x = root2;
|
|
7486
|
+
if (isNegativeLE(x, P))
|
|
7487
|
+
x = mod(-x, P);
|
|
7488
|
+
return { isValid: useRoot1 || useRoot2, value: x };
|
|
7489
|
+
}
|
|
7490
|
+
function calcElligatorRistrettoMap(r0) {
|
|
7491
|
+
const { d } = ed25519_CURVE;
|
|
7492
|
+
const P = ed25519_CURVE_p;
|
|
7493
|
+
const mod2 = (n) => Fp.create(n);
|
|
7494
|
+
const r = mod2(SQRT_M1 * r0 * r0);
|
|
7495
|
+
const Ns = mod2((r + _1n5) * ONE_MINUS_D_SQ);
|
|
7496
|
+
let c = BigInt(-1);
|
|
7497
|
+
const D = mod2((c - d * r) * mod2(r + d));
|
|
7498
|
+
let { isValid: Ns_D_is_sq, value: s } = uvRatio(Ns, D);
|
|
7499
|
+
let s_ = mod2(s * r0);
|
|
7500
|
+
if (!isNegativeLE(s_, P))
|
|
7501
|
+
s_ = mod2(-s_);
|
|
7502
|
+
if (!Ns_D_is_sq)
|
|
7503
|
+
s = s_;
|
|
7504
|
+
if (!Ns_D_is_sq)
|
|
7505
|
+
c = r;
|
|
7506
|
+
const Nt = mod2(c * (r - _1n5) * D_MINUS_ONE_SQ - D);
|
|
7507
|
+
const s2 = s * s;
|
|
7508
|
+
const W0 = mod2((s + s) * D);
|
|
7509
|
+
const W1 = mod2(Nt * SQRT_AD_MINUS_ONE);
|
|
7510
|
+
const W2 = mod2(_1n5 - s2);
|
|
7511
|
+
const W3 = mod2(_1n5 + s2);
|
|
7512
|
+
return new ed25519.Point(mod2(W0 * W3), mod2(W2 * W1), mod2(W1 * W3), mod2(W0 * W2));
|
|
7513
|
+
}
|
|
7514
|
+
function ristretto255_map(bytes) {
|
|
7515
|
+
abytes(bytes, 64);
|
|
7516
|
+
const r1 = bytes255ToNumberLE(bytes.subarray(0, 32));
|
|
7517
|
+
const R1 = calcElligatorRistrettoMap(r1);
|
|
7518
|
+
const r2 = bytes255ToNumberLE(bytes.subarray(32, 64));
|
|
7519
|
+
const R2 = calcElligatorRistrettoMap(r2);
|
|
7520
|
+
return new _RistrettoPoint(R1.add(R2));
|
|
7521
|
+
}
|
|
7522
|
+
var _0n5, _1n5, _2n3, _3n2, _5n2, _8n3, ed25519_CURVE_p, ed25519_CURVE, ED25519_SQRT_M1, Fp, Fn, ed25519Defaults, ed25519, SQRT_M1, SQRT_AD_MINUS_ONE, INVSQRT_A_MINUS_D, ONE_MINUS_D_SQ, D_MINUS_ONE_SQ, invertSqrt, MAX_255B, bytes255ToNumberLE, _RistrettoPoint;
|
|
7523
|
+
var init_ed25519 = __esm({
|
|
7524
|
+
"../../node_modules/@noble/curves/esm/ed25519.js"() {
|
|
7525
|
+
"use strict";
|
|
7526
|
+
init_sha2();
|
|
7527
|
+
init_utils();
|
|
7528
|
+
init_curve();
|
|
7529
|
+
init_edwards();
|
|
7530
|
+
init_modular();
|
|
7531
|
+
init_utils2();
|
|
7532
|
+
_0n5 = /* @__PURE__ */ BigInt(0);
|
|
7533
|
+
_1n5 = BigInt(1);
|
|
7534
|
+
_2n3 = BigInt(2);
|
|
7535
|
+
_3n2 = BigInt(3);
|
|
7536
|
+
_5n2 = BigInt(5);
|
|
7537
|
+
_8n3 = BigInt(8);
|
|
7538
|
+
ed25519_CURVE_p = BigInt("0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed");
|
|
7539
|
+
ed25519_CURVE = /* @__PURE__ */ (() => ({
|
|
7540
|
+
p: ed25519_CURVE_p,
|
|
7541
|
+
n: BigInt("0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed"),
|
|
7542
|
+
h: _8n3,
|
|
7543
|
+
a: BigInt("0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec"),
|
|
7544
|
+
d: BigInt("0x52036cee2b6ffe738cc740797779e89800700a4d4141d8ab75eb4dca135978a3"),
|
|
7545
|
+
Gx: BigInt("0x216936d3cd6e53fec0a4e231fdd6dc5c692cc7609525a7b2c9562d608f25d51a"),
|
|
7546
|
+
Gy: BigInt("0x6666666666666666666666666666666666666666666666666666666666666658")
|
|
7547
|
+
}))();
|
|
7548
|
+
ED25519_SQRT_M1 = /* @__PURE__ */ BigInt("19681161376707505956807079304988542015446066515923890162744021073123829784752");
|
|
7549
|
+
Fp = /* @__PURE__ */ (() => Field(ed25519_CURVE.p, { isLE: true }))();
|
|
7550
|
+
Fn = /* @__PURE__ */ (() => Field(ed25519_CURVE.n, { isLE: true }))();
|
|
7551
|
+
ed25519Defaults = /* @__PURE__ */ (() => ({
|
|
7552
|
+
...ed25519_CURVE,
|
|
7553
|
+
Fp,
|
|
7554
|
+
hash: sha512,
|
|
7555
|
+
adjustScalarBytes,
|
|
7556
|
+
// dom2
|
|
7557
|
+
// Ratio of u to v. Allows us to combine inversion and square root. Uses algo from RFC8032 5.1.3.
|
|
7558
|
+
// Constant-time, u/√v
|
|
7559
|
+
uvRatio
|
|
7560
|
+
}))();
|
|
7561
|
+
ed25519 = /* @__PURE__ */ (() => twistedEdwards(ed25519Defaults))();
|
|
7562
|
+
SQRT_M1 = ED25519_SQRT_M1;
|
|
7563
|
+
SQRT_AD_MINUS_ONE = /* @__PURE__ */ BigInt("25063068953384623474111414158702152701244531502492656460079210482610430750235");
|
|
7564
|
+
INVSQRT_A_MINUS_D = /* @__PURE__ */ BigInt("54469307008909316920995813868745141605393597292927456921205312896311721017578");
|
|
7565
|
+
ONE_MINUS_D_SQ = /* @__PURE__ */ BigInt("1159843021668779879193775521855586647937357759715417654439879720876111806838");
|
|
7566
|
+
D_MINUS_ONE_SQ = /* @__PURE__ */ BigInt("40440834346308536858101042469323190826248399146238708352240133220865137265952");
|
|
7567
|
+
invertSqrt = (number) => uvRatio(_1n5, number);
|
|
7568
|
+
MAX_255B = /* @__PURE__ */ BigInt("0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
|
|
7569
|
+
bytes255ToNumberLE = (bytes) => ed25519.Point.Fp.create(bytesToNumberLE(bytes) & MAX_255B);
|
|
7570
|
+
_RistrettoPoint = class __RistrettoPoint extends PrimeEdwardsPoint {
|
|
7571
|
+
constructor(ep) {
|
|
7572
|
+
super(ep);
|
|
7573
|
+
}
|
|
7574
|
+
static fromAffine(ap) {
|
|
7575
|
+
return new __RistrettoPoint(ed25519.Point.fromAffine(ap));
|
|
7576
|
+
}
|
|
7577
|
+
assertSame(other) {
|
|
7578
|
+
if (!(other instanceof __RistrettoPoint))
|
|
7579
|
+
throw new Error("RistrettoPoint expected");
|
|
7580
|
+
}
|
|
7581
|
+
init(ep) {
|
|
7582
|
+
return new __RistrettoPoint(ep);
|
|
7583
|
+
}
|
|
7584
|
+
/** @deprecated use `import { ristretto255_hasher } from '@noble/curves/ed25519.js';` */
|
|
7585
|
+
static hashToCurve(hex3) {
|
|
7586
|
+
return ristretto255_map(ensureBytes("ristrettoHash", hex3, 64));
|
|
7587
|
+
}
|
|
7588
|
+
static fromBytes(bytes) {
|
|
7589
|
+
abytes(bytes, 32);
|
|
7590
|
+
const { a, d } = ed25519_CURVE;
|
|
7591
|
+
const P = ed25519_CURVE_p;
|
|
7592
|
+
const mod2 = (n) => Fp.create(n);
|
|
7593
|
+
const s = bytes255ToNumberLE(bytes);
|
|
7594
|
+
if (!equalBytes(Fp.toBytes(s), bytes) || isNegativeLE(s, P))
|
|
7595
|
+
throw new Error("invalid ristretto255 encoding 1");
|
|
7596
|
+
const s2 = mod2(s * s);
|
|
7597
|
+
const u1 = mod2(_1n5 + a * s2);
|
|
7598
|
+
const u2 = mod2(_1n5 - a * s2);
|
|
7599
|
+
const u1_2 = mod2(u1 * u1);
|
|
7600
|
+
const u2_2 = mod2(u2 * u2);
|
|
7601
|
+
const v = mod2(a * d * u1_2 - u2_2);
|
|
7602
|
+
const { isValid: isValid3, value: I } = invertSqrt(mod2(v * u2_2));
|
|
7603
|
+
const Dx = mod2(I * u2);
|
|
7604
|
+
const Dy = mod2(I * Dx * v);
|
|
7605
|
+
let x = mod2((s + s) * Dx);
|
|
7606
|
+
if (isNegativeLE(x, P))
|
|
7607
|
+
x = mod2(-x);
|
|
7608
|
+
const y = mod2(u1 * Dy);
|
|
7609
|
+
const t = mod2(x * y);
|
|
7610
|
+
if (!isValid3 || isNegativeLE(t, P) || y === _0n5)
|
|
7611
|
+
throw new Error("invalid ristretto255 encoding 2");
|
|
7612
|
+
return new __RistrettoPoint(new ed25519.Point(x, y, _1n5, t));
|
|
7613
|
+
}
|
|
7614
|
+
/**
|
|
7615
|
+
* Converts ristretto-encoded string to ristretto point.
|
|
7616
|
+
* Described in [RFC9496](https://www.rfc-editor.org/rfc/rfc9496#name-decode).
|
|
7617
|
+
* @param hex Ristretto-encoded 32 bytes. Not every 32-byte string is valid ristretto encoding
|
|
7618
|
+
*/
|
|
7619
|
+
static fromHex(hex3) {
|
|
7620
|
+
return __RistrettoPoint.fromBytes(ensureBytes("ristrettoHex", hex3, 32));
|
|
7621
|
+
}
|
|
7622
|
+
static msm(points, scalars) {
|
|
7623
|
+
return pippenger(__RistrettoPoint, ed25519.Point.Fn, points, scalars);
|
|
7624
|
+
}
|
|
7625
|
+
/**
|
|
7626
|
+
* Encodes ristretto point to Uint8Array.
|
|
7627
|
+
* Described in [RFC9496](https://www.rfc-editor.org/rfc/rfc9496#name-encode).
|
|
7628
|
+
*/
|
|
7629
|
+
toBytes() {
|
|
7630
|
+
let { X, Y, Z, T } = this.ep;
|
|
7631
|
+
const P = ed25519_CURVE_p;
|
|
7632
|
+
const mod2 = (n) => Fp.create(n);
|
|
7633
|
+
const u1 = mod2(mod2(Z + Y) * mod2(Z - Y));
|
|
7634
|
+
const u2 = mod2(X * Y);
|
|
7635
|
+
const u2sq = mod2(u2 * u2);
|
|
7636
|
+
const { value: invsqrt } = invertSqrt(mod2(u1 * u2sq));
|
|
7637
|
+
const D1 = mod2(invsqrt * u1);
|
|
7638
|
+
const D2 = mod2(invsqrt * u2);
|
|
7639
|
+
const zInv = mod2(D1 * D2 * T);
|
|
7640
|
+
let D;
|
|
7641
|
+
if (isNegativeLE(T * zInv, P)) {
|
|
7642
|
+
let _x = mod2(Y * SQRT_M1);
|
|
7643
|
+
let _y = mod2(X * SQRT_M1);
|
|
7644
|
+
X = _x;
|
|
7645
|
+
Y = _y;
|
|
7646
|
+
D = mod2(D1 * INVSQRT_A_MINUS_D);
|
|
7647
|
+
} else {
|
|
7648
|
+
D = D2;
|
|
7649
|
+
}
|
|
7650
|
+
if (isNegativeLE(X * zInv, P))
|
|
7651
|
+
Y = mod2(-Y);
|
|
7652
|
+
let s = mod2((Z - Y) * D);
|
|
7653
|
+
if (isNegativeLE(s, P))
|
|
7654
|
+
s = mod2(-s);
|
|
7655
|
+
return Fp.toBytes(s);
|
|
7656
|
+
}
|
|
7657
|
+
/**
|
|
7658
|
+
* Compares two Ristretto points.
|
|
7659
|
+
* Described in [RFC9496](https://www.rfc-editor.org/rfc/rfc9496#name-equals).
|
|
7660
|
+
*/
|
|
7661
|
+
equals(other) {
|
|
7662
|
+
this.assertSame(other);
|
|
7663
|
+
const { X: X1, Y: Y1 } = this.ep;
|
|
7664
|
+
const { X: X2, Y: Y2 } = other.ep;
|
|
7665
|
+
const mod2 = (n) => Fp.create(n);
|
|
7666
|
+
const one = mod2(X1 * Y2) === mod2(Y1 * X2);
|
|
7667
|
+
const two = mod2(Y1 * Y2) === mod2(X1 * X2);
|
|
7668
|
+
return one || two;
|
|
7669
|
+
}
|
|
7670
|
+
is0() {
|
|
7671
|
+
return this.equals(__RistrettoPoint.ZERO);
|
|
7672
|
+
}
|
|
7673
|
+
};
|
|
7674
|
+
_RistrettoPoint.BASE = /* @__PURE__ */ (() => new _RistrettoPoint(ed25519.Point.BASE))();
|
|
7675
|
+
_RistrettoPoint.ZERO = /* @__PURE__ */ (() => new _RistrettoPoint(ed25519.Point.ZERO))();
|
|
7676
|
+
_RistrettoPoint.Fp = /* @__PURE__ */ (() => Fp)();
|
|
7677
|
+
_RistrettoPoint.Fn = /* @__PURE__ */ (() => Fn)();
|
|
7708
7678
|
}
|
|
7709
|
-
|
|
7710
|
-
|
|
7679
|
+
});
|
|
7680
|
+
|
|
7681
|
+
// ../replica/dist/index.js
|
|
7682
|
+
function assertFolderPrefix(prefix) {
|
|
7683
|
+
const validFolder = typeof prefix === "string" && prefix.length > 0 && !prefix.startsWith("/") && !prefix.includes("//") && prefix.endsWith("/");
|
|
7684
|
+
if (prefix !== "/" && !validFolder) {
|
|
7685
|
+
const folderHint = typeof prefix === "string" ? prefix.replace(/^\/+/, "").replace(/\/+$/, "") : "";
|
|
7686
|
+
const suggestion = folderHint.length > 0 && !folderHint.includes("//") ? ` Use ${JSON.stringify(`${folderHint}/`)}.` : ' Use "/" or a slash-terminated folder path such as "notes/".';
|
|
7687
|
+
throw new TypeError(`Replication prefix must be "/" or a non-empty slash-terminated folder path without empty segments.${suggestion}`);
|
|
7711
7688
|
}
|
|
7712
|
-
|
|
7713
|
-
|
|
7689
|
+
}
|
|
7690
|
+
function assertFolderPrefix2(prefix) {
|
|
7691
|
+
try {
|
|
7692
|
+
assertFolderPrefix(prefix);
|
|
7693
|
+
} catch {
|
|
7694
|
+
const folderHint = typeof prefix === "string" ? prefix.replace(/^\/+/, "").replace(/\/+$/, "") : "";
|
|
7695
|
+
const suggestion = prefix === "" ? 'use "/" for the whole space' : folderHint.length > 0 && !folderHint.includes("//") ? `use ${JSON.stringify(`${folderHint}/`)}` : 'use "/" for the whole space or a folder path such as "notes/"';
|
|
7696
|
+
throw new ReplicaError(
|
|
7697
|
+
ReplicaErrorCode.INVALID_ARGUMENT,
|
|
7698
|
+
`Replication prefix ${JSON.stringify(prefix)} must be "/" or a non-empty folder path ending in / without empty segments; ${suggestion}. Run \`tc replica reset --replica <name> --purge\` and recreate it with the folder prefix.`
|
|
7699
|
+
);
|
|
7714
7700
|
}
|
|
7715
|
-
|
|
7716
|
-
|
|
7717
|
-
|
|
7701
|
+
}
|
|
7702
|
+
var ReplicaErrorCode, REPLICA_ERROR, ReplicaError, PENDING_REFUSALS, encoder;
|
|
7703
|
+
var init_dist = __esm({
|
|
7704
|
+
"../replica/dist/index.js"() {
|
|
7705
|
+
"use strict";
|
|
7706
|
+
ReplicaErrorCode = {
|
|
7707
|
+
/** Another process holds the sync lease. */
|
|
7708
|
+
BUSY: "REPLICA_BUSY",
|
|
7709
|
+
/** No replica with this name exists. */
|
|
7710
|
+
NOT_FOUND: "REPLICA_NOT_FOUND",
|
|
7711
|
+
/** The replica exists but its stored configuration differs from the request. */
|
|
7712
|
+
CONFIG_MISMATCH: "REPLICA_CONFIG_MISMATCH",
|
|
7713
|
+
/** The runtime has no supported durable store (e.g. Node < 22.13). */
|
|
7714
|
+
RUNTIME_UNSUPPORTED: "RUNTIME_UNSUPPORTED",
|
|
7715
|
+
/** A required open() argument is missing or malformed (e.g. `principal`). */
|
|
7716
|
+
INVALID_ARGUMENT: "REPLICA_INVALID_ARGUMENT",
|
|
7717
|
+
/** The local store failed (I/O, corruption, schema). */
|
|
7718
|
+
STORAGE_ERROR: "STORAGE_ERROR",
|
|
7719
|
+
/** The local disk is full. */
|
|
7720
|
+
STORAGE_FULL: "STORAGE_FULL",
|
|
7721
|
+
/** The key is outside the replica's prefix. */
|
|
7722
|
+
NOT_COVERED: "NOT_COVERED",
|
|
7723
|
+
/** Syncing the secrets space or the vault namespace needs an explicit opt-in. */
|
|
7724
|
+
SECRETS_OPT_IN_REQUIRED: "SECRETS_OPT_IN_REQUIRED",
|
|
7725
|
+
/** No grant is installed, or none covers the requested scope. */
|
|
7726
|
+
GRANT_MISSING: "GRANT_MISSING",
|
|
7727
|
+
/** The grant bytes are not a verifiable UCAN, or its signature is wrong. */
|
|
7728
|
+
GRANT_INVALID: "GRANT_INVALID",
|
|
7729
|
+
/** SIWE/CACAO and other non-UCAN grants cannot be used for a replica. */
|
|
7730
|
+
GRANT_FORMAT_UNSUPPORTED: "GRANT_FORMAT_UNSUPPORTED",
|
|
7731
|
+
/** The grant was issued to a different device. */
|
|
7732
|
+
GRANT_AUDIENCE_MISMATCH: "GRANT_AUDIENCE_MISMATCH",
|
|
7733
|
+
/** The grant lacks `tinycloud.kv/sync` or `tinycloud.kv/get` on the prefix. */
|
|
7734
|
+
GRANT_NOT_COVERING: "GRANT_NOT_COVERING",
|
|
7735
|
+
GRANT_NOT_YET_VALID: "GRANT_NOT_YET_VALID",
|
|
7736
|
+
GRANT_EXPIRED: "GRANT_EXPIRED",
|
|
7737
|
+
/** The configured node does not advertise whole-space KV sync support. */
|
|
7738
|
+
REPLICATION_ROOT_UNSUPPORTED: "REPLICATION_ROOT_UNSUPPORTED",
|
|
7739
|
+
GRANT_REVOKED: "GRANT_REVOKED",
|
|
7740
|
+
/** The node refused the invocation for a reason other than revocation. */
|
|
7741
|
+
GRANT_UNAUTHORIZED: "GRANT_UNAUTHORIZED",
|
|
7742
|
+
/** The node refused the retention grant. */
|
|
7743
|
+
RETENTION_GRANT_REFUSED: "RETENTION_GRANT_REFUSED",
|
|
7744
|
+
/** The node could not be reached. */
|
|
7745
|
+
NETWORK_ERROR: "NETWORK_ERROR",
|
|
7746
|
+
/** The node answered with an unexpected status. */
|
|
7747
|
+
NODE_ERROR: "NODE_ERROR",
|
|
7748
|
+
/** The node's answer violates the wire contract. */
|
|
7749
|
+
PROTOCOL_ERROR: "PROTOCOL_ERROR",
|
|
7750
|
+
/** The node asked for a fresh bootstrap (410). Handled inside sync. */
|
|
7751
|
+
RESET_REQUIRED: "RESET_REQUIRED",
|
|
7752
|
+
/** The feed now comes from a different node than the one pinned. */
|
|
7753
|
+
SOURCE_CHANGED: "SOURCE_CHANGED",
|
|
7754
|
+
/** The feed delivered a key outside the replica's prefix. */
|
|
7755
|
+
SCOPE_VIOLATION: "SCOPE_VIOLATION",
|
|
7756
|
+
/** Fetched bytes do not hash to the ETag the node attested for them. */
|
|
7757
|
+
CONTENT_MISMATCH: "CONTENT_MISMATCH",
|
|
7758
|
+
/** A stored blob no longer hashes to its name. */
|
|
7759
|
+
INTEGRITY_ERROR: "INTEGRITY_ERROR",
|
|
7760
|
+
/** The replica handle was closed; in-flight calls settle with this code. */
|
|
7761
|
+
CLOSED: "REPLICA_CLOSED"
|
|
7762
|
+
};
|
|
7763
|
+
REPLICA_ERROR = /* @__PURE__ */ Symbol.for("tinycloud.replica.error");
|
|
7764
|
+
ReplicaError = class extends Error {
|
|
7765
|
+
[REPLICA_ERROR] = true;
|
|
7766
|
+
code;
|
|
7767
|
+
detail;
|
|
7768
|
+
constructor(code3, message, detail, options) {
|
|
7769
|
+
super(message, options);
|
|
7770
|
+
this.name = "ReplicaError";
|
|
7771
|
+
this.code = code3;
|
|
7772
|
+
if (detail !== void 0) this.detail = detail;
|
|
7773
|
+
}
|
|
7774
|
+
};
|
|
7775
|
+
PENDING_REFUSALS = /* @__PURE__ */ new Set([
|
|
7776
|
+
ReplicaErrorCode.GRANT_UNAUTHORIZED,
|
|
7777
|
+
ReplicaErrorCode.GRANT_EXPIRED,
|
|
7778
|
+
ReplicaErrorCode.GRANT_NOT_YET_VALID
|
|
7779
|
+
]);
|
|
7780
|
+
encoder = new TextEncoder();
|
|
7718
7781
|
}
|
|
7719
|
-
|
|
7720
|
-
|
|
7721
|
-
|
|
7782
|
+
});
|
|
7783
|
+
|
|
7784
|
+
// src/lib/replication-config.ts
|
|
7785
|
+
import { join as join5 } from "path";
|
|
7786
|
+
import { profilePath, withProfileLock as withProfileLock2 } from "@tinycloud/operations/state";
|
|
7787
|
+
import { sqliteReplicaStorage } from "@tinycloud/node-sdk";
|
|
7788
|
+
function createCliReplicationConfig(profile, settings, output, enabled) {
|
|
7789
|
+
if (!enabled || !settings || settings.prefixes.length === 0) return void 0;
|
|
7790
|
+
for (const prefix of settings.prefixes) {
|
|
7791
|
+
try {
|
|
7792
|
+
assertFolderPrefix2(prefix);
|
|
7793
|
+
} catch (error) {
|
|
7794
|
+
const trimmed = prefix.replace(/^\/+/, "").replace(/\/+$/, "");
|
|
7795
|
+
const replacement = trimmed.length > 0 && !trimmed.includes("//") ? `${trimmed}/` : "/";
|
|
7796
|
+
throw new CLIError(
|
|
7797
|
+
"INVALID_REPLICATION_PREFIX",
|
|
7798
|
+
error instanceof Error ? error.message : String(error),
|
|
7799
|
+
ExitCode.USAGE_ERROR,
|
|
7800
|
+
{ hint: `Replace the saved replication prefix with \`tc auth login --replication-prefix ${replacement}\`; purging a replica alone does not change this profile setting.` }
|
|
7801
|
+
);
|
|
7802
|
+
}
|
|
7722
7803
|
}
|
|
7723
|
-
|
|
7724
|
-
|
|
7804
|
+
const root = profilePath(profile);
|
|
7805
|
+
return {
|
|
7806
|
+
enabled: true,
|
|
7807
|
+
prefixes: settings.prefixes,
|
|
7808
|
+
allowSecrets: settings.allowSecrets === true,
|
|
7809
|
+
mode: "foreground",
|
|
7810
|
+
verify: process.env.TC_REPLICATION_VERIFY === "1",
|
|
7811
|
+
maxStalenessMs: Number(process.env.TC_REPLICATION_MAX_STALENESS_MS ?? 6e4),
|
|
7812
|
+
staleSyncTimeoutMs: Number(process.env.TC_REPLICATION_SYNC_TIMEOUT_MS ?? 1e4),
|
|
7813
|
+
storage: sqliteReplicaStorage({
|
|
7814
|
+
dir: join5(root, "replication"),
|
|
7815
|
+
guard: (section) => withProfileLock2(profile, section, { requireProfile: true, timeoutMs: 35e3 })
|
|
7816
|
+
}),
|
|
7817
|
+
onEvent: createReplicationEventSink(root, output)
|
|
7818
|
+
};
|
|
7819
|
+
}
|
|
7820
|
+
var init_replication_config = __esm({
|
|
7821
|
+
"src/lib/replication-config.ts"() {
|
|
7822
|
+
"use strict";
|
|
7823
|
+
init_replication_log();
|
|
7824
|
+
init_dist();
|
|
7825
|
+
init_errors();
|
|
7826
|
+
init_constants();
|
|
7725
7827
|
}
|
|
7726
|
-
|
|
7727
|
-
|
|
7828
|
+
});
|
|
7829
|
+
|
|
7830
|
+
// src/lib/sdk.ts
|
|
7831
|
+
var sdk_exports = {};
|
|
7832
|
+
__export(sdk_exports, {
|
|
7833
|
+
bootstrapDelegatedSession: () => bootstrapDelegatedSession,
|
|
7834
|
+
closeReplication: () => closeReplication,
|
|
7835
|
+
createSDKInstance: () => createSDKInstance,
|
|
7836
|
+
ensureAuthenticated: () => ensureAuthenticated,
|
|
7837
|
+
jwkHasPrivateParameter: () => jwkHasPrivateParameter,
|
|
7838
|
+
registerReplication: () => registerReplication,
|
|
7839
|
+
registeredReplications: () => registeredReplications,
|
|
7840
|
+
replicationForProfile: () => replicationForProfile,
|
|
7841
|
+
restoreProfileSessionNode: () => restoreProfileSessionNode,
|
|
7842
|
+
selectSignerJwk: () => selectSignerJwk,
|
|
7843
|
+
storedSessionVerifiesLocally: () => storedSessionVerifiesLocally
|
|
7844
|
+
});
|
|
7845
|
+
import { TinyCloudNode, signedCompactUcanExpiry } from "@tinycloud/node-sdk";
|
|
7846
|
+
function jwkHasPrivateParameter(jwk) {
|
|
7847
|
+
if (!jwk || typeof jwk !== "object") return false;
|
|
7848
|
+
const d = jwk.d;
|
|
7849
|
+
return typeof d === "string" && d.length > 0;
|
|
7850
|
+
}
|
|
7851
|
+
function selectSignerJwk(sessionJwk, key) {
|
|
7852
|
+
if (jwkHasPrivateParameter(sessionJwk)) {
|
|
7853
|
+
return sessionJwk;
|
|
7728
7854
|
}
|
|
7729
|
-
|
|
7730
|
-
|
|
7855
|
+
return key ?? void 0;
|
|
7856
|
+
}
|
|
7857
|
+
function signerJwkForProfile(profileName, sessionJwk, key) {
|
|
7858
|
+
const jwk = selectSignerJwk(sessionJwk, key);
|
|
7859
|
+
if (jwkHasPrivateParameter(jwk)) {
|
|
7860
|
+
return jwk;
|
|
7731
7861
|
}
|
|
7732
|
-
|
|
7733
|
-
|
|
7862
|
+
throw new CLIError(
|
|
7863
|
+
"AUTH_REQUIRED",
|
|
7864
|
+
`Profile "${profileName}" cannot restore its session because its private key material is missing.`,
|
|
7865
|
+
ExitCode.AUTH_REQUIRED,
|
|
7866
|
+
{
|
|
7867
|
+
hint: `Sign in again with: tc --profile ${profileName} auth login --method openkey`
|
|
7868
|
+
}
|
|
7869
|
+
);
|
|
7870
|
+
}
|
|
7871
|
+
function signedLifetimePassed(delegation) {
|
|
7872
|
+
const authorization = delegation.delegationHeader?.Authorization;
|
|
7873
|
+
const expiry = typeof authorization === "string" ? signedCompactUcanExpiry(authorization) : void 0;
|
|
7874
|
+
return expiry !== void 0 && expiry.getTime() <= Date.now();
|
|
7875
|
+
}
|
|
7876
|
+
async function restoreProfileSession(node, profileName, profile, sessionData) {
|
|
7877
|
+
try {
|
|
7878
|
+
await node.restoreSession(sessionData);
|
|
7879
|
+
} catch (error) {
|
|
7880
|
+
if (typeof error === "object" && error !== null && "code" in error && error.code === "AUTH_EXPIRED") {
|
|
7881
|
+
throw sessionExpiredError(profileName, profile === null ? void 0 : resolveProfilePosture(profile));
|
|
7882
|
+
}
|
|
7883
|
+
throw error;
|
|
7734
7884
|
}
|
|
7735
|
-
|
|
7736
|
-
|
|
7885
|
+
}
|
|
7886
|
+
function persistedSessionData(profileName, profile, session, key) {
|
|
7887
|
+
return {
|
|
7888
|
+
delegationHeader: session.delegationHeader,
|
|
7889
|
+
delegationCid: session.delegationCid,
|
|
7890
|
+
spaceId: session.spaceId,
|
|
7891
|
+
jwk: signerJwkForProfile(profileName, session.jwk, key),
|
|
7892
|
+
verificationMethod: session.verificationMethod ?? profile.sessionDid ?? profile.did,
|
|
7893
|
+
address: session.address,
|
|
7894
|
+
chainId: session.chainId,
|
|
7895
|
+
siwe: session.siwe,
|
|
7896
|
+
signature: session.signature
|
|
7897
|
+
};
|
|
7898
|
+
}
|
|
7899
|
+
async function restoreProfileSessionNode(ctx) {
|
|
7900
|
+
const profile = await ProfileManager.getProfile(ctx.profile);
|
|
7901
|
+
const session = await ProfileManager.getSession(ctx.profile);
|
|
7902
|
+
if (!session) return { unavailable: "session_missing" };
|
|
7903
|
+
if (typeof session.delegationCid !== "string" || typeof session.spaceId !== "string" || session.delegationHeader === null || typeof session.delegationHeader !== "object" || !("Authorization" in session.delegationHeader) || typeof session.delegationHeader.Authorization !== "string") {
|
|
7904
|
+
return { unavailable: "session_invalid" };
|
|
7737
7905
|
}
|
|
7738
|
-
|
|
7739
|
-
|
|
7740
|
-
return this.toBytes();
|
|
7906
|
+
if (typeof session.expiresAt === "string" && Date.parse(session.expiresAt) <= Date.now()) {
|
|
7907
|
+
return { unavailable: "session_expired" };
|
|
7741
7908
|
}
|
|
7742
|
-
|
|
7743
|
-
|
|
7744
|
-
|
|
7745
|
-
|
|
7746
|
-
|
|
7747
|
-
|
|
7748
|
-
|
|
7749
|
-
|
|
7750
|
-
|
|
7751
|
-
|
|
7752
|
-
|
|
7753
|
-
|
|
7754
|
-
|
|
7755
|
-
const randomBytes3 = eddsaOpts.randomBytes || randomBytes;
|
|
7756
|
-
const adjustScalarBytes2 = eddsaOpts.adjustScalarBytes || ((bytes) => bytes);
|
|
7757
|
-
const domain = eddsaOpts.domain || ((data, ctx, phflag) => {
|
|
7758
|
-
_abool2(phflag, "phflag");
|
|
7759
|
-
if (ctx.length || phflag)
|
|
7760
|
-
throw new Error("Contexts/pre-hash are not supported");
|
|
7761
|
-
return data;
|
|
7762
|
-
});
|
|
7763
|
-
function modN_LE(hash) {
|
|
7764
|
-
return Fn2.create(bytesToNumberLE(hash));
|
|
7909
|
+
const key = await ProfileManager.getKey(ctx.profile);
|
|
7910
|
+
try {
|
|
7911
|
+
const node = new TinyCloudNode({
|
|
7912
|
+
host: ctx.host,
|
|
7913
|
+
...profile.authMethod === "local" && profile.privateKey ? { privateKey: profile.privateKey } : {}
|
|
7914
|
+
});
|
|
7915
|
+
await restoreProfileSession(node, ctx.profile, profile, persistedSessionData(ctx.profile, profile, session, key));
|
|
7916
|
+
return { node };
|
|
7917
|
+
} catch (error) {
|
|
7918
|
+
if (error instanceof CLIError && error.metadata?.reason === "session_expired") {
|
|
7919
|
+
return { unavailable: "session_expired" };
|
|
7920
|
+
}
|
|
7921
|
+
return { unavailable: "session_invalid" };
|
|
7765
7922
|
}
|
|
7766
|
-
|
|
7767
|
-
|
|
7768
|
-
|
|
7769
|
-
|
|
7770
|
-
|
|
7771
|
-
|
|
7772
|
-
const
|
|
7773
|
-
|
|
7923
|
+
}
|
|
7924
|
+
async function storedSessionVerifiesLocally(profileName) {
|
|
7925
|
+
const profile = await ProfileManager.getProfile(profileName).catch(() => null);
|
|
7926
|
+
if (profile === null) return true;
|
|
7927
|
+
const local = profile.authMethod === "local" && typeof profile.privateKey === "string";
|
|
7928
|
+
try {
|
|
7929
|
+
const session = await ProfileManager.getSession(profileName);
|
|
7930
|
+
if (!session || typeof session.delegationCid !== "string" || typeof session.spaceId !== "string" || session.delegationHeader === null || typeof session.delegationHeader !== "object" || !("Authorization" in session.delegationHeader) || typeof session.delegationHeader.Authorization !== "string") return true;
|
|
7931
|
+
const key = await ProfileManager.getKey(profileName);
|
|
7932
|
+
const node = new TinyCloudNode({
|
|
7933
|
+
host: profile.host ?? DEFAULT_HOST,
|
|
7934
|
+
...local ? { privateKey: profile.privateKey } : {}
|
|
7935
|
+
});
|
|
7936
|
+
await restoreProfileSession(node, profileName, profile, persistedSessionData(profileName, profile, session, key));
|
|
7937
|
+
return true;
|
|
7938
|
+
} catch {
|
|
7939
|
+
return false;
|
|
7774
7940
|
}
|
|
7775
|
-
|
|
7776
|
-
|
|
7777
|
-
|
|
7778
|
-
|
|
7779
|
-
|
|
7941
|
+
}
|
|
7942
|
+
async function createSDKInstance(ctx, options) {
|
|
7943
|
+
const profile = options?.privateKey ? await ProfileManager.getProfile(ctx.profile).catch(() => null) : await ProfileManager.getProfile(ctx.profile);
|
|
7944
|
+
const session = await ProfileManager.getSession(ctx.profile);
|
|
7945
|
+
const key = await ProfileManager.getKey(ctx.profile);
|
|
7946
|
+
const effectivePrivateKey = options?.privateKey ?? profile?.privateKey;
|
|
7947
|
+
if (!key && !effectivePrivateKey && !(profile?.authMethod === "openkey" && session !== null)) {
|
|
7948
|
+
throw new CLIError(
|
|
7949
|
+
"AUTH_REQUIRED",
|
|
7950
|
+
`No key found for profile "${ctx.profile}". Run \`tc --profile ${ctx.profile} auth rotate\` to create a new key and sign in.`,
|
|
7951
|
+
ExitCode.AUTH_REQUIRED
|
|
7952
|
+
);
|
|
7780
7953
|
}
|
|
7781
|
-
|
|
7782
|
-
|
|
7954
|
+
if (profile?.authMethod === "local" && effectivePrivateKey) {
|
|
7955
|
+
const replication2 = createCliReplicationConfig(
|
|
7956
|
+
ctx.profile,
|
|
7957
|
+
profile?.replication,
|
|
7958
|
+
{ debug: ctx.replicationDebug, quiet: ctx.quiet },
|
|
7959
|
+
ctx.replication
|
|
7960
|
+
);
|
|
7961
|
+
if (ctx.replication && !replication2) {
|
|
7962
|
+
process.stderr.write("[replication] Enabled, but this profile has no configured prefixes; reads use the network.\n");
|
|
7963
|
+
}
|
|
7964
|
+
const node2 = new TinyCloudNode({
|
|
7965
|
+
host: ctx.host,
|
|
7966
|
+
privateKey: effectivePrivateKey,
|
|
7967
|
+
...replication2 ? { replication: replication2 } : {}
|
|
7968
|
+
});
|
|
7969
|
+
if (node2.replication) registerReplication(ctx.profile, node2.replication);
|
|
7970
|
+
const restoredOwnSession = Boolean(session && session.delegationHeader && session.delegationCid && session.spaceId);
|
|
7971
|
+
if (restoredOwnSession) {
|
|
7972
|
+
await restoreProfileSession(node2, ctx.profile, profile, persistedSessionData(ctx.profile, profile, session, key));
|
|
7973
|
+
} else {
|
|
7974
|
+
await node2.signIn();
|
|
7975
|
+
}
|
|
7976
|
+
if (restoredOwnSession) {
|
|
7977
|
+
recordWarnings(await replayAdditionalDelegations(node2, ctx.profile, {
|
|
7978
|
+
host: ctx.host,
|
|
7979
|
+
ownerSpace: profile.spaceId,
|
|
7980
|
+
migrate: options?.privateKey === void 0
|
|
7981
|
+
}));
|
|
7982
|
+
}
|
|
7983
|
+
return node2;
|
|
7783
7984
|
}
|
|
7784
|
-
|
|
7785
|
-
|
|
7786
|
-
|
|
7985
|
+
const replication = createCliReplicationConfig(
|
|
7986
|
+
ctx.profile,
|
|
7987
|
+
profile?.replication,
|
|
7988
|
+
{ debug: ctx.replicationDebug, quiet: ctx.quiet },
|
|
7989
|
+
ctx.replication
|
|
7990
|
+
);
|
|
7991
|
+
if (ctx.replication && !replication) {
|
|
7992
|
+
process.stderr.write("[replication] Enabled, but this profile has no configured prefixes; reads use the network.\n");
|
|
7787
7993
|
}
|
|
7788
|
-
|
|
7789
|
-
|
|
7790
|
-
|
|
7791
|
-
|
|
7792
|
-
|
|
7793
|
-
|
|
7794
|
-
|
|
7795
|
-
|
|
7796
|
-
|
|
7797
|
-
|
|
7798
|
-
|
|
7799
|
-
|
|
7800
|
-
|
|
7994
|
+
const node = new TinyCloudNode({
|
|
7995
|
+
host: ctx.host,
|
|
7996
|
+
privateKey: options?.privateKey,
|
|
7997
|
+
...replication ? { replication } : {}
|
|
7998
|
+
});
|
|
7999
|
+
if (node.replication) registerReplication(ctx.profile, node.replication);
|
|
8000
|
+
if (options?.privateKey) {
|
|
8001
|
+
await node.signIn();
|
|
8002
|
+
} else if (session && session.delegationHeader && session.delegationCid && session.spaceId) {
|
|
8003
|
+
await restoreProfileSession(node, ctx.profile, profile, persistedSessionData(ctx.profile, profile, session, key));
|
|
8004
|
+
recordWarnings(await replayAdditionalDelegations(node, ctx.profile, {
|
|
8005
|
+
host: ctx.host,
|
|
8006
|
+
ownerSpace: profile?.spaceId,
|
|
8007
|
+
migrate: true
|
|
8008
|
+
}));
|
|
7801
8009
|
}
|
|
7802
|
-
|
|
7803
|
-
|
|
7804
|
-
|
|
7805
|
-
|
|
7806
|
-
|
|
7807
|
-
|
|
7808
|
-
|
|
7809
|
-
|
|
7810
|
-
|
|
7811
|
-
|
|
7812
|
-
|
|
7813
|
-
|
|
7814
|
-
const
|
|
7815
|
-
|
|
7816
|
-
|
|
8010
|
+
return node;
|
|
8011
|
+
}
|
|
8012
|
+
async function bootstrapDelegatedSession(ctx, delegation) {
|
|
8013
|
+
const written = await ProfileManager.withLock(ctx.profile, async () => {
|
|
8014
|
+
const previousProfile = await ProfileManager.getProfile(ctx.profile);
|
|
8015
|
+
if (resolveProfilePosture(previousProfile) !== "delegate-session") {
|
|
8016
|
+
throw new CLIError(
|
|
8017
|
+
"AUTH_REQUIRED",
|
|
8018
|
+
`Profile "${ctx.profile}" is not a delegate-session profile.`,
|
|
8019
|
+
ExitCode.AUTH_REQUIRED
|
|
8020
|
+
);
|
|
8021
|
+
}
|
|
8022
|
+
const sessionDid = previousProfile.sessionDid ?? previousProfile.did;
|
|
8023
|
+
if (delegation.delegateDID.split("#", 1)[0] !== sessionDid.split("#", 1)[0]) {
|
|
8024
|
+
throw new CLIError(
|
|
8025
|
+
"DELEGATION_AUDIENCE_MISMATCH",
|
|
8026
|
+
`Delegation targets ${delegation.delegateDID}, but profile "${ctx.profile}" uses ${sessionDid}.`,
|
|
8027
|
+
ExitCode.PERMISSION_DENIED
|
|
8028
|
+
);
|
|
8029
|
+
}
|
|
8030
|
+
if (await ProfileManager.getSession(ctx.profile) !== null) {
|
|
8031
|
+
throw new CLIError(
|
|
8032
|
+
"PROFILE_CHANGED_DURING_IMPORT",
|
|
8033
|
+
`Profile "${ctx.profile}" gained a session (another login or import) after this import checked it. Nothing was saved; run the import again.`,
|
|
8034
|
+
ExitCode.ERROR
|
|
8035
|
+
);
|
|
8036
|
+
}
|
|
8037
|
+
if (signedLifetimePassed(delegation)) throw delegationExpiredError();
|
|
8038
|
+
const jwk = signerJwkForProfile(ctx.profile, void 0, await ProfileManager.getKey(ctx.profile));
|
|
8039
|
+
const session = {
|
|
8040
|
+
delegationHeader: delegation.delegationHeader,
|
|
8041
|
+
delegationCid: delegation.cid,
|
|
8042
|
+
spaceId: delegation.spaceId,
|
|
8043
|
+
jwk,
|
|
8044
|
+
verificationMethod: sessionDid
|
|
8045
|
+
};
|
|
8046
|
+
const profile = { ...previousProfile, sessionDid, spaceId: delegation.spaceId };
|
|
7817
8047
|
try {
|
|
7818
|
-
|
|
7819
|
-
|
|
7820
|
-
SB = BASE.multiplyUnsafe(s);
|
|
8048
|
+
await ProfileManager.setSession(ctx.profile, session);
|
|
8049
|
+
await ProfileManager.setProfile(ctx.profile, profile);
|
|
7821
8050
|
} catch (error) {
|
|
7822
|
-
|
|
8051
|
+
throw annotate(error, await restoreBeforeBootstrap(ctx.profile, previousProfile));
|
|
7823
8052
|
}
|
|
7824
|
-
|
|
7825
|
-
|
|
7826
|
-
|
|
7827
|
-
const
|
|
7828
|
-
|
|
7829
|
-
|
|
7830
|
-
|
|
7831
|
-
|
|
7832
|
-
|
|
7833
|
-
|
|
7834
|
-
|
|
7835
|
-
|
|
8053
|
+
return { previousProfile, profile, session };
|
|
8054
|
+
});
|
|
8055
|
+
const abandon = async (cause) => {
|
|
8056
|
+
const reported = cause instanceof CLIError && cause.code === "AUTH_REQUIRED" && signedLifetimePassed(delegation) ? delegationExpiredError() : cause;
|
|
8057
|
+
const note = await ProfileManager.withLock(ctx.profile, async () => {
|
|
8058
|
+
const profile = await ProfileManager.getProfile(ctx.profile).catch((error) => {
|
|
8059
|
+
if (error instanceof CLIError && error.code === "PROFILE_NOT_FOUND") return null;
|
|
8060
|
+
throw error;
|
|
8061
|
+
});
|
|
8062
|
+
const session = await ProfileManager.getSession(ctx.profile);
|
|
8063
|
+
if (profile === null || BOOTSTRAP_PROFILE_FIELDS.some((field) => profile[field] !== written.profile[field]) || JSON.stringify(session) !== JSON.stringify(written.session)) {
|
|
8064
|
+
return `Profile "${ctx.profile}" changed while the import was pending (another login, logout or profile update), so its newer state was kept and the provisional session was not rolled back.`;
|
|
8065
|
+
}
|
|
8066
|
+
return restoreBeforeBootstrap(ctx.profile, written.previousProfile);
|
|
8067
|
+
}, { timeoutMs: PROFILE_COMMIT_LOCK_TIMEOUT_MS }).catch((error) => (
|
|
8068
|
+
// The lock or a read failed: the import's error stays the one reported.
|
|
8069
|
+
`Rolling back the provisional session of profile "${ctx.profile}" could not run (${failureName(error)}); check \`tc --profile ${ctx.profile} context\`.`
|
|
8070
|
+
));
|
|
8071
|
+
throw annotate(reported, note);
|
|
7836
8072
|
};
|
|
7837
|
-
|
|
7838
|
-
|
|
8073
|
+
let node;
|
|
8074
|
+
try {
|
|
8075
|
+
node = await createSDKInstance(ctx);
|
|
8076
|
+
} catch (error) {
|
|
8077
|
+
return abandon(error);
|
|
7839
8078
|
}
|
|
7840
|
-
|
|
7841
|
-
|
|
7842
|
-
|
|
8079
|
+
return { node, abandon };
|
|
8080
|
+
}
|
|
8081
|
+
async function restoreBeforeBootstrap(profileName, previousProfile) {
|
|
8082
|
+
const failures = [];
|
|
8083
|
+
for (const write of [
|
|
8084
|
+
() => ProfileManager.clearSession(profileName),
|
|
8085
|
+
() => ProfileManager.updateProfile(profileName, (current) => {
|
|
8086
|
+
const restored = { ...current };
|
|
8087
|
+
for (const field of BOOTSTRAP_PROFILE_FIELDS) {
|
|
8088
|
+
if (previousProfile[field] === void 0) delete restored[field];
|
|
8089
|
+
else restored[field] = previousProfile[field];
|
|
8090
|
+
}
|
|
8091
|
+
return restored;
|
|
8092
|
+
})
|
|
8093
|
+
]) {
|
|
8094
|
+
await write().catch((error) => {
|
|
8095
|
+
failures.push(failureName(error));
|
|
8096
|
+
});
|
|
7843
8097
|
}
|
|
7844
|
-
|
|
7845
|
-
|
|
8098
|
+
if (failures.length === 0) return void 0;
|
|
8099
|
+
return `Rolling back the provisional session of profile "${profileName}" failed too (${failures.join("; ")}); check \`tc --profile ${profileName} context\`.`;
|
|
8100
|
+
}
|
|
8101
|
+
function failureName(error) {
|
|
8102
|
+
if (error instanceof SyntaxError) return "a profile file is not valid JSON";
|
|
8103
|
+
if (typeof error === "object" && error !== null && "code" in error && typeof error.code === "string") return error.code;
|
|
8104
|
+
return error instanceof Error ? error.name : "unknown error";
|
|
8105
|
+
}
|
|
8106
|
+
function annotate(error, note) {
|
|
8107
|
+
if (note === void 0) return error;
|
|
8108
|
+
const cause = wrapError(error);
|
|
8109
|
+
return new CLIError(cause.code, `${cause.message} ${note}`, cause.exitCode, cause.metadata);
|
|
8110
|
+
}
|
|
8111
|
+
async function ensureAuthenticated(ctx, options) {
|
|
8112
|
+
if (options?.privateKey) {
|
|
8113
|
+
return createSDKInstance(ctx, options);
|
|
8114
|
+
}
|
|
8115
|
+
const profile = await ProfileManager.getProfile(ctx.profile).catch(() => null);
|
|
8116
|
+
if (profile?.authMethod === "local" && profile.privateKey) {
|
|
8117
|
+
return createSDKInstance(ctx);
|
|
8118
|
+
}
|
|
8119
|
+
const session = await ProfileManager.getSession(ctx.profile);
|
|
8120
|
+
if (!session) {
|
|
8121
|
+
throw new CLIError(
|
|
8122
|
+
"AUTH_REQUIRED",
|
|
8123
|
+
`Not authenticated. Run \`tc auth login\` or \`tc init\` first.`,
|
|
8124
|
+
ExitCode.AUTH_REQUIRED
|
|
8125
|
+
);
|
|
7846
8126
|
}
|
|
7847
|
-
|
|
7848
|
-
|
|
7849
|
-
|
|
7850
|
-
|
|
7851
|
-
|
|
7852
|
-
|
|
8127
|
+
return createSDKInstance(ctx, options);
|
|
8128
|
+
}
|
|
8129
|
+
var BOOTSTRAP_PROFILE_FIELDS;
|
|
8130
|
+
var init_sdk = __esm({
|
|
8131
|
+
"src/lib/sdk.ts"() {
|
|
8132
|
+
"use strict";
|
|
8133
|
+
init_profiles();
|
|
8134
|
+
init_types();
|
|
8135
|
+
init_errors();
|
|
8136
|
+
init_constants();
|
|
8137
|
+
init_permissions();
|
|
8138
|
+
init_session_expired();
|
|
8139
|
+
init_warnings();
|
|
8140
|
+
init_delegation_expiry();
|
|
8141
|
+
init_replication_config();
|
|
8142
|
+
init_replication_registry();
|
|
8143
|
+
init_replication_registry();
|
|
8144
|
+
BOOTSTRAP_PROFILE_FIELDS = ["sessionDid", "spaceId"];
|
|
7853
8145
|
}
|
|
7854
|
-
|
|
7855
|
-
|
|
7856
|
-
|
|
7857
|
-
|
|
7858
|
-
|
|
7859
|
-
|
|
7860
|
-
|
|
7861
|
-
|
|
7862
|
-
|
|
7863
|
-
|
|
7864
|
-
|
|
7865
|
-
|
|
7866
|
-
|
|
7867
|
-
|
|
7868
|
-
|
|
7869
|
-
|
|
7870
|
-
|
|
7871
|
-
|
|
7872
|
-
|
|
7873
|
-
|
|
7874
|
-
const
|
|
7875
|
-
|
|
7876
|
-
|
|
7877
|
-
|
|
7878
|
-
const size = lengths.secretKey;
|
|
7879
|
-
_abytes2(secretKey, size);
|
|
7880
|
-
const hashed = cHash(secretKey.subarray(0, size));
|
|
7881
|
-
return adjustScalarBytes2(hashed).subarray(0, size);
|
|
8146
|
+
});
|
|
8147
|
+
|
|
8148
|
+
// src/lib/host.ts
|
|
8149
|
+
var host_exports = {};
|
|
8150
|
+
__export(host_exports, {
|
|
8151
|
+
completeDeferredLocalDiscovery: () => completeDeferredLocalDiscovery,
|
|
8152
|
+
discoverLocalNodeHost: () => discoverLocalNodeHost,
|
|
8153
|
+
isRootAuthority: () => isRootAuthority,
|
|
8154
|
+
ownerDidFromSpaceUri: () => ownerDidFromSpaceUri,
|
|
8155
|
+
profileLocalNodeIdentityStore: () => profileLocalNodeIdentityStore,
|
|
8156
|
+
resolveHostSpace: () => resolveHostSpace,
|
|
8157
|
+
spaceNameFromUri: () => spaceNameFromUri,
|
|
8158
|
+
unhostedSpaceError: () => unhostedSpaceError
|
|
8159
|
+
});
|
|
8160
|
+
import {
|
|
8161
|
+
discoverLocalTinyCloudNode
|
|
8162
|
+
} from "@tinycloud/sdk-core";
|
|
8163
|
+
function profileLocalNodeIdentityStore(profileName) {
|
|
8164
|
+
return {
|
|
8165
|
+
get: async (url) => {
|
|
8166
|
+
const profile = await ProfileManager.getProfile(profileName).catch(
|
|
8167
|
+
() => null
|
|
8168
|
+
);
|
|
8169
|
+
return profile?.pinnedLocalNodeDids?.[url];
|
|
7882
8170
|
},
|
|
7883
|
-
|
|
7884
|
-
|
|
7885
|
-
|
|
7886
|
-
|
|
7887
|
-
|
|
8171
|
+
set: async (url, nodeDid) => {
|
|
8172
|
+
if (!await ProfileManager.profileExists(profileName)) return;
|
|
8173
|
+
await ProfileManager.updateProfile(profileName, (profile) => ({
|
|
8174
|
+
...profile,
|
|
8175
|
+
pinnedLocalNodeDids: {
|
|
8176
|
+
...profile.pinnedLocalNodeDids,
|
|
8177
|
+
[url]: nodeDid
|
|
8178
|
+
}
|
|
8179
|
+
}));
|
|
7888
8180
|
}
|
|
7889
8181
|
};
|
|
7890
|
-
|
|
7891
|
-
|
|
7892
|
-
|
|
7893
|
-
|
|
7894
|
-
|
|
7895
|
-
|
|
7896
|
-
|
|
7897
|
-
|
|
8182
|
+
}
|
|
8183
|
+
async function discoverLocalNodeHost(profileName, options) {
|
|
8184
|
+
const profile = await ProfileManager.getProfile(profileName).catch(() => null);
|
|
8185
|
+
if (profile?.autoDiscoverLocalNode === false) return { host: null, deferred: false };
|
|
8186
|
+
if (!profile?.localNodeUrl && !profile?.localLinkName) return { host: null, deferred: false };
|
|
8187
|
+
if (options.awaitStoredSession) {
|
|
8188
|
+
const { storedSessionVerifiesLocally: storedSessionVerifiesLocally2 } = await Promise.resolve().then(() => (init_sdk(), sdk_exports));
|
|
8189
|
+
if (!await storedSessionVerifiesLocally2(profileName)) return { host: null, deferred: true };
|
|
8190
|
+
}
|
|
8191
|
+
const discovered = await discoverLocalTinyCloudNode({
|
|
8192
|
+
localNodeUrl: profile?.localNodeUrl,
|
|
8193
|
+
localLinkName: profile?.localLinkName,
|
|
8194
|
+
expectedNodeDid: profile?.expectedNodeDid,
|
|
8195
|
+
identityStore: profileLocalNodeIdentityStore(profileName)
|
|
7898
8196
|
});
|
|
8197
|
+
return { host: discovered?.url ?? null, deferred: false };
|
|
7899
8198
|
}
|
|
7900
|
-
function
|
|
7901
|
-
const
|
|
7902
|
-
|
|
7903
|
-
|
|
7904
|
-
|
|
7905
|
-
|
|
7906
|
-
|
|
7907
|
-
Gx: c.Gx,
|
|
7908
|
-
Gy: c.Gy
|
|
7909
|
-
};
|
|
7910
|
-
const Fp2 = c.Fp;
|
|
7911
|
-
const Fn2 = Field(CURVE.n, c.nBitLength, true);
|
|
7912
|
-
const curveOpts = { Fp: Fp2, Fn: Fn2, uvRatio: c.uvRatio };
|
|
7913
|
-
const eddsaOpts = {
|
|
7914
|
-
randomBytes: c.randomBytes,
|
|
7915
|
-
adjustScalarBytes: c.adjustScalarBytes,
|
|
7916
|
-
domain: c.domain,
|
|
7917
|
-
prehash: c.prehash,
|
|
7918
|
-
mapToCurve: c.mapToCurve
|
|
7919
|
-
};
|
|
7920
|
-
return { CURVE, curveOpts, hash: c.hash, eddsaOpts };
|
|
8199
|
+
async function completeDeferredLocalDiscovery(ctx) {
|
|
8200
|
+
const deferred = ctx.localDiscovery;
|
|
8201
|
+
if (deferred === void 0) return;
|
|
8202
|
+
delete ctx.localDiscovery;
|
|
8203
|
+
if (ctx.host !== deferred.deferredFrom) return;
|
|
8204
|
+
const discovered = await discoverLocalNodeHost(ctx.profile, { awaitStoredSession: false });
|
|
8205
|
+
if (discovered.host !== null) ctx.host = discovered.host;
|
|
7921
8206
|
}
|
|
7922
|
-
function
|
|
7923
|
-
const
|
|
7924
|
-
|
|
7925
|
-
ExtendedPoint: Point,
|
|
7926
|
-
CURVE: c,
|
|
7927
|
-
nBitLength: Point.Fn.BITS,
|
|
7928
|
-
nByteLength: Point.Fn.BYTES
|
|
7929
|
-
});
|
|
7930
|
-
return legacy;
|
|
8207
|
+
function canonicalizeAddress2(address) {
|
|
8208
|
+
const trimmed = address.trim();
|
|
8209
|
+
return trimmed.startsWith("0x") ? `0x${trimmed.slice(2).toLowerCase()}` : trimmed.toLowerCase();
|
|
7931
8210
|
}
|
|
7932
|
-
function
|
|
7933
|
-
const
|
|
7934
|
-
const
|
|
7935
|
-
|
|
7936
|
-
|
|
8211
|
+
async function resolveLocalAddress(profile, profileName) {
|
|
8212
|
+
const session = await ProfileManager.getSession(profileName);
|
|
8213
|
+
const sessAddr = session?.address;
|
|
8214
|
+
if (typeof sessAddr === "string" && sessAddr.length > 0) {
|
|
8215
|
+
return canonicalizeAddress2(sessAddr);
|
|
8216
|
+
}
|
|
8217
|
+
if (profile.address) return canonicalizeAddress2(profile.address);
|
|
8218
|
+
if (profile.ownerDid) {
|
|
8219
|
+
const match = profile.ownerDid.match(/^did:pkh:eip155:\d+:(0x[a-fA-F0-9]{40})$/);
|
|
8220
|
+
if (match) return canonicalizeAddress2(match[1]);
|
|
8221
|
+
}
|
|
8222
|
+
return null;
|
|
7937
8223
|
}
|
|
7938
|
-
|
|
7939
|
-
|
|
7940
|
-
|
|
7941
|
-
var _1n5 = BigInt(1);
|
|
7942
|
-
var _2n3 = BigInt(2);
|
|
7943
|
-
var _3n2 = BigInt(3);
|
|
7944
|
-
var _5n2 = BigInt(5);
|
|
7945
|
-
var _8n3 = BigInt(8);
|
|
7946
|
-
var ed25519_CURVE_p = BigInt("0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed");
|
|
7947
|
-
var ed25519_CURVE = /* @__PURE__ */ (() => ({
|
|
7948
|
-
p: ed25519_CURVE_p,
|
|
7949
|
-
n: BigInt("0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed"),
|
|
7950
|
-
h: _8n3,
|
|
7951
|
-
a: BigInt("0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec"),
|
|
7952
|
-
d: BigInt("0x52036cee2b6ffe738cc740797779e89800700a4d4141d8ab75eb4dca135978a3"),
|
|
7953
|
-
Gx: BigInt("0x216936d3cd6e53fec0a4e231fdd6dc5c692cc7609525a7b2c9562d608f25d51a"),
|
|
7954
|
-
Gy: BigInt("0x6666666666666666666666666666666666666666666666666666666666666658")
|
|
7955
|
-
}))();
|
|
7956
|
-
function ed25519_pow_2_252_3(x) {
|
|
7957
|
-
const _10n = BigInt(10), _20n = BigInt(20), _40n = BigInt(40), _80n = BigInt(80);
|
|
7958
|
-
const P = ed25519_CURVE_p;
|
|
7959
|
-
const x2 = x * x % P;
|
|
7960
|
-
const b2 = x2 * x % P;
|
|
7961
|
-
const b4 = pow2(b2, _2n3, P) * b2 % P;
|
|
7962
|
-
const b5 = pow2(b4, _1n5, P) * x % P;
|
|
7963
|
-
const b10 = pow2(b5, _5n2, P) * b5 % P;
|
|
7964
|
-
const b20 = pow2(b10, _10n, P) * b10 % P;
|
|
7965
|
-
const b40 = pow2(b20, _20n, P) * b20 % P;
|
|
7966
|
-
const b80 = pow2(b40, _40n, P) * b40 % P;
|
|
7967
|
-
const b160 = pow2(b80, _80n, P) * b80 % P;
|
|
7968
|
-
const b240 = pow2(b160, _80n, P) * b80 % P;
|
|
7969
|
-
const b250 = pow2(b240, _10n, P) * b10 % P;
|
|
7970
|
-
const pow_p_5_8 = pow2(b250, _2n3, P) * x % P;
|
|
7971
|
-
return { pow_p_5_8, b2 };
|
|
8224
|
+
function ownerAddressFromSpaceUri(spaceUri) {
|
|
8225
|
+
const match = spaceUri.match(/^tinycloud:pkh:eip155:\d+:(0x[a-fA-F0-9]{40}):/);
|
|
8226
|
+
return match ? canonicalizeAddress2(match[1]) : null;
|
|
7972
8227
|
}
|
|
7973
|
-
function
|
|
7974
|
-
|
|
7975
|
-
|
|
7976
|
-
|
|
7977
|
-
return bytes;
|
|
8228
|
+
function ownerDidFromSpaceUri(spaceUri) {
|
|
8229
|
+
const match = spaceUri.match(/^tinycloud:pkh:eip155:(\d+):(0x[a-fA-F0-9]{40}):/);
|
|
8230
|
+
if (!match) return null;
|
|
8231
|
+
return `did:pkh:eip155:${match[1]}:${canonicalizeAddress2(match[2])}`;
|
|
7978
8232
|
}
|
|
7979
|
-
|
|
7980
|
-
|
|
7981
|
-
|
|
7982
|
-
const
|
|
7983
|
-
|
|
7984
|
-
const
|
|
7985
|
-
|
|
7986
|
-
const vx2 = mod(v * x * x, P);
|
|
7987
|
-
const root1 = x;
|
|
7988
|
-
const root2 = mod(x * ED25519_SQRT_M1, P);
|
|
7989
|
-
const useRoot1 = vx2 === u;
|
|
7990
|
-
const useRoot2 = vx2 === mod(-u, P);
|
|
7991
|
-
const noRoot = vx2 === mod(-u * ED25519_SQRT_M1, P);
|
|
7992
|
-
if (useRoot1)
|
|
7993
|
-
x = root1;
|
|
7994
|
-
if (useRoot2 || noRoot)
|
|
7995
|
-
x = root2;
|
|
7996
|
-
if (isNegativeLE(x, P))
|
|
7997
|
-
x = mod(-x, P);
|
|
7998
|
-
return { isValid: useRoot1 || useRoot2, value: x };
|
|
8233
|
+
async function isRootAuthority(spaceUri, profileName) {
|
|
8234
|
+
const profile = await ProfileManager.getProfile(profileName);
|
|
8235
|
+
if (resolveProfilePosture(profile) === "delegate-session") return false;
|
|
8236
|
+
const ownerAddr = ownerAddressFromSpaceUri(spaceUri);
|
|
8237
|
+
if (!ownerAddr) return false;
|
|
8238
|
+
const selfAddr = await resolveLocalAddress(profile, profileName);
|
|
8239
|
+
return selfAddr !== null && selfAddr === ownerAddr;
|
|
7999
8240
|
}
|
|
8000
|
-
|
|
8001
|
-
|
|
8002
|
-
var ed25519Defaults = /* @__PURE__ */ (() => ({
|
|
8003
|
-
...ed25519_CURVE,
|
|
8004
|
-
Fp,
|
|
8005
|
-
hash: sha512,
|
|
8006
|
-
adjustScalarBytes,
|
|
8007
|
-
// dom2
|
|
8008
|
-
// Ratio of u to v. Allows us to combine inversion and square root. Uses algo from RFC8032 5.1.3.
|
|
8009
|
-
// Constant-time, u/√v
|
|
8010
|
-
uvRatio
|
|
8011
|
-
}))();
|
|
8012
|
-
var ed25519 = /* @__PURE__ */ (() => twistedEdwards(ed25519Defaults))();
|
|
8013
|
-
var SQRT_M1 = ED25519_SQRT_M1;
|
|
8014
|
-
var SQRT_AD_MINUS_ONE = /* @__PURE__ */ BigInt("25063068953384623474111414158702152701244531502492656460079210482610430750235");
|
|
8015
|
-
var INVSQRT_A_MINUS_D = /* @__PURE__ */ BigInt("54469307008909316920995813868745141605393597292927456921205312896311721017578");
|
|
8016
|
-
var ONE_MINUS_D_SQ = /* @__PURE__ */ BigInt("1159843021668779879193775521855586647937357759715417654439879720876111806838");
|
|
8017
|
-
var D_MINUS_ONE_SQ = /* @__PURE__ */ BigInt("40440834346308536858101042469323190826248399146238708352240133220865137265952");
|
|
8018
|
-
var invertSqrt = (number) => uvRatio(_1n5, number);
|
|
8019
|
-
var MAX_255B = /* @__PURE__ */ BigInt("0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
|
|
8020
|
-
var bytes255ToNumberLE = (bytes) => ed25519.Point.Fp.create(bytesToNumberLE(bytes) & MAX_255B);
|
|
8021
|
-
function calcElligatorRistrettoMap(r0) {
|
|
8022
|
-
const { d } = ed25519_CURVE;
|
|
8023
|
-
const P = ed25519_CURVE_p;
|
|
8024
|
-
const mod2 = (n) => Fp.create(n);
|
|
8025
|
-
const r = mod2(SQRT_M1 * r0 * r0);
|
|
8026
|
-
const Ns = mod2((r + _1n5) * ONE_MINUS_D_SQ);
|
|
8027
|
-
let c = BigInt(-1);
|
|
8028
|
-
const D = mod2((c - d * r) * mod2(r + d));
|
|
8029
|
-
let { isValid: Ns_D_is_sq, value: s } = uvRatio(Ns, D);
|
|
8030
|
-
let s_ = mod2(s * r0);
|
|
8031
|
-
if (!isNegativeLE(s_, P))
|
|
8032
|
-
s_ = mod2(-s_);
|
|
8033
|
-
if (!Ns_D_is_sq)
|
|
8034
|
-
s = s_;
|
|
8035
|
-
if (!Ns_D_is_sq)
|
|
8036
|
-
c = r;
|
|
8037
|
-
const Nt = mod2(c * (r - _1n5) * D_MINUS_ONE_SQ - D);
|
|
8038
|
-
const s2 = s * s;
|
|
8039
|
-
const W0 = mod2((s + s) * D);
|
|
8040
|
-
const W1 = mod2(Nt * SQRT_AD_MINUS_ONE);
|
|
8041
|
-
const W2 = mod2(_1n5 - s2);
|
|
8042
|
-
const W3 = mod2(_1n5 + s2);
|
|
8043
|
-
return new ed25519.Point(mod2(W0 * W3), mod2(W2 * W1), mod2(W1 * W3), mod2(W0 * W2));
|
|
8241
|
+
function spaceNameFromUri(spaceUri) {
|
|
8242
|
+
return spaceUri.slice(spaceUri.lastIndexOf(":") + 1);
|
|
8044
8243
|
}
|
|
8045
|
-
function
|
|
8046
|
-
|
|
8047
|
-
const
|
|
8048
|
-
const
|
|
8049
|
-
|
|
8050
|
-
const
|
|
8051
|
-
|
|
8244
|
+
async function unhostedSpaceError(error, spaceUri, profileName) {
|
|
8245
|
+
if (!spaceUri) return null;
|
|
8246
|
+
const status = error.meta?.status;
|
|
8247
|
+
const isUnhosted = status === 404 && /space not found/i.test(error.message);
|
|
8248
|
+
if (!isUnhosted) return null;
|
|
8249
|
+
const spaceName = spaceNameFromUri(spaceUri);
|
|
8250
|
+
const owner = await isRootAuthority(spaceUri, profileName);
|
|
8251
|
+
const hint = owner ? [
|
|
8252
|
+
"You are the owner. Host it once:",
|
|
8253
|
+
` tc space host ${spaceName}`,
|
|
8254
|
+
"Then retry."
|
|
8255
|
+
].join("\n") : [
|
|
8256
|
+
"You are a delegate and CANNOT host this space \u2014 only its owner can.",
|
|
8257
|
+
"Emit a host request:",
|
|
8258
|
+
` tc space host-request ${spaceName} --emit ./host-request.json`,
|
|
8259
|
+
"Send it to the owner; they run `tc space host` and confirm. Then retry."
|
|
8260
|
+
].join("\n");
|
|
8261
|
+
const message = owner ? `Space '${spaceName}' (${spaceUri}) is not hosted.` : `Space '${spaceName}' (owner ${ownerDidFromSpaceUri(spaceUri) ?? spaceUri}) is not hosted.`;
|
|
8262
|
+
return new CLIError("SPACE_NOT_HOSTED", message, ExitCode.ERROR, { hint });
|
|
8052
8263
|
}
|
|
8053
|
-
|
|
8054
|
-
|
|
8055
|
-
|
|
8056
|
-
|
|
8057
|
-
static fromAffine(ap) {
|
|
8058
|
-
return new __RistrettoPoint(ed25519.Point.fromAffine(ap));
|
|
8059
|
-
}
|
|
8060
|
-
assertSame(other) {
|
|
8061
|
-
if (!(other instanceof __RistrettoPoint))
|
|
8062
|
-
throw new Error("RistrettoPoint expected");
|
|
8063
|
-
}
|
|
8064
|
-
init(ep) {
|
|
8065
|
-
return new __RistrettoPoint(ep);
|
|
8066
|
-
}
|
|
8067
|
-
/** @deprecated use `import { ristretto255_hasher } from '@noble/curves/ed25519.js';` */
|
|
8068
|
-
static hashToCurve(hex3) {
|
|
8069
|
-
return ristretto255_map(ensureBytes("ristrettoHash", hex3, 64));
|
|
8070
|
-
}
|
|
8071
|
-
static fromBytes(bytes) {
|
|
8072
|
-
abytes(bytes, 32);
|
|
8073
|
-
const { a, d } = ed25519_CURVE;
|
|
8074
|
-
const P = ed25519_CURVE_p;
|
|
8075
|
-
const mod2 = (n) => Fp.create(n);
|
|
8076
|
-
const s = bytes255ToNumberLE(bytes);
|
|
8077
|
-
if (!equalBytes(Fp.toBytes(s), bytes) || isNegativeLE(s, P))
|
|
8078
|
-
throw new Error("invalid ristretto255 encoding 1");
|
|
8079
|
-
const s2 = mod2(s * s);
|
|
8080
|
-
const u1 = mod2(_1n5 + a * s2);
|
|
8081
|
-
const u2 = mod2(_1n5 - a * s2);
|
|
8082
|
-
const u1_2 = mod2(u1 * u1);
|
|
8083
|
-
const u2_2 = mod2(u2 * u2);
|
|
8084
|
-
const v = mod2(a * d * u1_2 - u2_2);
|
|
8085
|
-
const { isValid: isValid3, value: I } = invertSqrt(mod2(v * u2_2));
|
|
8086
|
-
const Dx = mod2(I * u2);
|
|
8087
|
-
const Dy = mod2(I * Dx * v);
|
|
8088
|
-
let x = mod2((s + s) * Dx);
|
|
8089
|
-
if (isNegativeLE(x, P))
|
|
8090
|
-
x = mod2(-x);
|
|
8091
|
-
const y = mod2(u1 * Dy);
|
|
8092
|
-
const t = mod2(x * y);
|
|
8093
|
-
if (!isValid3 || isNegativeLE(t, P) || y === _0n5)
|
|
8094
|
-
throw new Error("invalid ristretto255 encoding 2");
|
|
8095
|
-
return new __RistrettoPoint(new ed25519.Point(x, y, _1n5, t));
|
|
8096
|
-
}
|
|
8097
|
-
/**
|
|
8098
|
-
* Converts ristretto-encoded string to ristretto point.
|
|
8099
|
-
* Described in [RFC9496](https://www.rfc-editor.org/rfc/rfc9496#name-decode).
|
|
8100
|
-
* @param hex Ristretto-encoded 32 bytes. Not every 32-byte string is valid ristretto encoding
|
|
8101
|
-
*/
|
|
8102
|
-
static fromHex(hex3) {
|
|
8103
|
-
return __RistrettoPoint.fromBytes(ensureBytes("ristrettoHex", hex3, 32));
|
|
8104
|
-
}
|
|
8105
|
-
static msm(points, scalars) {
|
|
8106
|
-
return pippenger(__RistrettoPoint, ed25519.Point.Fn, points, scalars);
|
|
8107
|
-
}
|
|
8108
|
-
/**
|
|
8109
|
-
* Encodes ristretto point to Uint8Array.
|
|
8110
|
-
* Described in [RFC9496](https://www.rfc-editor.org/rfc/rfc9496#name-encode).
|
|
8111
|
-
*/
|
|
8112
|
-
toBytes() {
|
|
8113
|
-
let { X, Y, Z, T } = this.ep;
|
|
8114
|
-
const P = ed25519_CURVE_p;
|
|
8115
|
-
const mod2 = (n) => Fp.create(n);
|
|
8116
|
-
const u1 = mod2(mod2(Z + Y) * mod2(Z - Y));
|
|
8117
|
-
const u2 = mod2(X * Y);
|
|
8118
|
-
const u2sq = mod2(u2 * u2);
|
|
8119
|
-
const { value: invsqrt } = invertSqrt(mod2(u1 * u2sq));
|
|
8120
|
-
const D1 = mod2(invsqrt * u1);
|
|
8121
|
-
const D2 = mod2(invsqrt * u2);
|
|
8122
|
-
const zInv = mod2(D1 * D2 * T);
|
|
8123
|
-
let D;
|
|
8124
|
-
if (isNegativeLE(T * zInv, P)) {
|
|
8125
|
-
let _x = mod2(Y * SQRT_M1);
|
|
8126
|
-
let _y = mod2(X * SQRT_M1);
|
|
8127
|
-
X = _x;
|
|
8128
|
-
Y = _y;
|
|
8129
|
-
D = mod2(D1 * INVSQRT_A_MINUS_D);
|
|
8130
|
-
} else {
|
|
8131
|
-
D = D2;
|
|
8132
|
-
}
|
|
8133
|
-
if (isNegativeLE(X * zInv, P))
|
|
8134
|
-
Y = mod2(-Y);
|
|
8135
|
-
let s = mod2((Z - Y) * D);
|
|
8136
|
-
if (isNegativeLE(s, P))
|
|
8137
|
-
s = mod2(-s);
|
|
8138
|
-
return Fp.toBytes(s);
|
|
8264
|
+
async function resolveHostSpace(name, profileName) {
|
|
8265
|
+
const resolved = await resolveSpaceUri(name, profileName);
|
|
8266
|
+
if (!resolved) {
|
|
8267
|
+
throw new Error(`Could not resolve a space for "${name}".`);
|
|
8139
8268
|
}
|
|
8140
|
-
|
|
8141
|
-
|
|
8142
|
-
|
|
8143
|
-
|
|
8144
|
-
|
|
8145
|
-
|
|
8146
|
-
|
|
8147
|
-
|
|
8148
|
-
|
|
8149
|
-
|
|
8150
|
-
const two = mod2(Y1 * Y2) === mod2(X1 * X2);
|
|
8151
|
-
return one || two;
|
|
8269
|
+
return resolved;
|
|
8270
|
+
}
|
|
8271
|
+
var init_host = __esm({
|
|
8272
|
+
"src/lib/host.ts"() {
|
|
8273
|
+
"use strict";
|
|
8274
|
+
init_profiles();
|
|
8275
|
+
init_constants();
|
|
8276
|
+
init_types();
|
|
8277
|
+
init_errors();
|
|
8278
|
+
init_space();
|
|
8152
8279
|
}
|
|
8153
|
-
|
|
8154
|
-
|
|
8280
|
+
});
|
|
8281
|
+
|
|
8282
|
+
// src/config/profiles.ts
|
|
8283
|
+
import { chmod as chmod2, lstat, readdir as readdir2, rm as rm2, rmdir } from "fs/promises";
|
|
8284
|
+
import { join as join6 } from "path";
|
|
8285
|
+
import {
|
|
8286
|
+
profilePath as profilePath2,
|
|
8287
|
+
readSession,
|
|
8288
|
+
recordProfileDeletion,
|
|
8289
|
+
refuseWriteToDeletedProfile as refuseWriteToDeletedProfile2,
|
|
8290
|
+
removeSession,
|
|
8291
|
+
withProfileLock as withProfileLock3,
|
|
8292
|
+
writeSession
|
|
8293
|
+
} from "@tinycloud/operations/state";
|
|
8294
|
+
var ProfileManager;
|
|
8295
|
+
var init_profiles = __esm({
|
|
8296
|
+
"src/config/profiles.ts"() {
|
|
8297
|
+
"use strict";
|
|
8298
|
+
init_constants();
|
|
8299
|
+
init_storage2();
|
|
8300
|
+
init_errors();
|
|
8301
|
+
ProfileManager = class _ProfileManager {
|
|
8302
|
+
// ── Initialization ──────────────────────────────────────────────────
|
|
8303
|
+
/**
|
|
8304
|
+
* Runs `action` holding the profile's store lock (shared with operations
|
|
8305
|
+
* and MCP). Reentrant, so the writers below can be called inside it; hold
|
|
8306
|
+
* it around a whole read-modify-write, not just each write.
|
|
8307
|
+
*/
|
|
8308
|
+
static async withLock(name, action, options) {
|
|
8309
|
+
return withProfileLock3(name, action, options);
|
|
8310
|
+
}
|
|
8311
|
+
/**
|
|
8312
|
+
* Read-modify-write of profile.json under the profile lock, so concurrent
|
|
8313
|
+
* updates (another command, a login commit) are never erased.
|
|
8314
|
+
*/
|
|
8315
|
+
static async updateProfile(name, update) {
|
|
8316
|
+
return _ProfileManager.withLock(name, async () => {
|
|
8317
|
+
const next = update(await _ProfileManager.getProfile(name));
|
|
8318
|
+
await _ProfileManager.setProfile(name, next);
|
|
8319
|
+
return next;
|
|
8320
|
+
});
|
|
8321
|
+
}
|
|
8322
|
+
/**
|
|
8323
|
+
* Creates ~/.tinycloud/ and ~/.tinycloud/profiles/ if they don't exist and
|
|
8324
|
+
* (re)sets both to 0700: older releases created them 0775.
|
|
8325
|
+
*/
|
|
8326
|
+
static async ensureConfigDir() {
|
|
8327
|
+
for (const directory of [CONFIG_DIR, PROFILES_DIR]) {
|
|
8328
|
+
await ensureDir(directory);
|
|
8329
|
+
await chmod2(directory, PRIVATE_DIR_MODE);
|
|
8330
|
+
}
|
|
8331
|
+
}
|
|
8332
|
+
/** Owner-only profile directory (0700), created or tightened before any write into it. */
|
|
8333
|
+
static async ensureProfileDir(name) {
|
|
8334
|
+
await _ProfileManager.ensureConfigDir();
|
|
8335
|
+
const profileDir = join6(PROFILES_DIR, name);
|
|
8336
|
+
await ensureDir(profileDir);
|
|
8337
|
+
await chmod2(profileDir, PRIVATE_DIR_MODE);
|
|
8338
|
+
return profileDir;
|
|
8339
|
+
}
|
|
8340
|
+
// ── Global config ───────────────────────────────────────────────────
|
|
8341
|
+
/**
|
|
8342
|
+
* Reads config.json. Returns a default config if the file is missing.
|
|
8343
|
+
*/
|
|
8344
|
+
static async getConfig() {
|
|
8345
|
+
const config = await readJson(CONFIG_FILE);
|
|
8346
|
+
if (!config) {
|
|
8347
|
+
return { defaultProfile: DEFAULT_PROFILE, version: 1 };
|
|
8348
|
+
}
|
|
8349
|
+
return config;
|
|
8350
|
+
}
|
|
8351
|
+
/**
|
|
8352
|
+
* Writes the global config to config.json.
|
|
8353
|
+
*/
|
|
8354
|
+
static async setConfig(config) {
|
|
8355
|
+
await _ProfileManager.ensureConfigDir();
|
|
8356
|
+
await writeJson(CONFIG_FILE, config);
|
|
8357
|
+
}
|
|
8358
|
+
// ── Profile CRUD ────────────────────────────────────────────────────
|
|
8359
|
+
/**
|
|
8360
|
+
* Returns the profile config for the given name.
|
|
8361
|
+
* Throws CLIError if the profile doesn't exist.
|
|
8362
|
+
*/
|
|
8363
|
+
static async getProfile(name) {
|
|
8364
|
+
const profilePath3 = join6(PROFILES_DIR, name, "profile.json");
|
|
8365
|
+
const profile = await readJson(profilePath3);
|
|
8366
|
+
if (!profile) {
|
|
8367
|
+
throw new CLIError(
|
|
8368
|
+
"PROFILE_NOT_FOUND",
|
|
8369
|
+
`Profile "${name}" does not exist. Create it with \`tc init --name ${name}\`.`
|
|
8370
|
+
);
|
|
8371
|
+
}
|
|
8372
|
+
return profile;
|
|
8373
|
+
}
|
|
8374
|
+
/**
|
|
8375
|
+
* Saves a profile config under the profile lock, creating the profile
|
|
8376
|
+
* directory if needed. Use `updateProfile` to change an existing profile.
|
|
8377
|
+
*/
|
|
8378
|
+
static async setProfile(name, data) {
|
|
8379
|
+
await _ProfileManager.withLock(name, async () => {
|
|
8380
|
+
await writeJson(join6(await _ProfileManager.ensureProfileDir(name), "profile.json"), data);
|
|
8381
|
+
});
|
|
8382
|
+
}
|
|
8383
|
+
/** Removes profile.json under the profile lock (rollback of a profile a failed login created). */
|
|
8384
|
+
static async removeProfileConfig(name) {
|
|
8385
|
+
await _ProfileManager.withLock(name, () => rm2(join6(PROFILES_DIR, name, "profile.json"), { force: true }));
|
|
8386
|
+
}
|
|
8387
|
+
/**
|
|
8388
|
+
* Returns true if a profile directory exists.
|
|
8389
|
+
*/
|
|
8390
|
+
static async profileExists(name) {
|
|
8391
|
+
return fileExists(join6(PROFILES_DIR, name, "profile.json"));
|
|
8392
|
+
}
|
|
8393
|
+
/**
|
|
8394
|
+
* Returns an array of profile directory names.
|
|
8395
|
+
*/
|
|
8396
|
+
static async listProfiles() {
|
|
8397
|
+
return listDirs(PROFILES_DIR);
|
|
8398
|
+
}
|
|
8399
|
+
/**
|
|
8400
|
+
* Deletes a profile. Its key, session, settings, stores and cache are
|
|
8401
|
+
* removed while holding the profile lock, so another writer's critical
|
|
8402
|
+
* section never sees them vanish midway: session and key first, settings
|
|
8403
|
+
* last, so a crash midway never leaves a session or key without its
|
|
8404
|
+
* profile. The deletion is then recorded, so a store write that waited for
|
|
8405
|
+
* the lock meanwhile refuses rather than recreating a profile with only a
|
|
8406
|
+
* session in it. `.lock` itself is left to the lock's release; the
|
|
8407
|
+
* then-empty directory is removed afterwards unless another writer took
|
|
8408
|
+
* the lock (or wrote) meanwhile. A profile directory that is a symlink is
|
|
8409
|
+
* unlinked, its target left alone.
|
|
8410
|
+
* Throws if the name is not one path segment or names the default profile.
|
|
8411
|
+
*/
|
|
8412
|
+
static async deleteProfile(name) {
|
|
8413
|
+
let profileDir;
|
|
8414
|
+
try {
|
|
8415
|
+
profileDir = profilePath2(name);
|
|
8416
|
+
} catch {
|
|
8417
|
+
throw new CLIError(
|
|
8418
|
+
"INVALID_PROFILE_NAME",
|
|
8419
|
+
`Invalid profile name "${name}": a profile name is one path segment (no "/", "\\", "." or "..").`,
|
|
8420
|
+
ExitCode.USAGE_ERROR
|
|
8421
|
+
);
|
|
8422
|
+
}
|
|
8423
|
+
const config = await _ProfileManager.getConfig();
|
|
8424
|
+
if (config.defaultProfile === name) {
|
|
8425
|
+
throw new CLIError(
|
|
8426
|
+
"PROFILE_DELETE_DEFAULT",
|
|
8427
|
+
`Cannot delete the default profile "${name}". Change the default first with \`tc profile default <other>\`.`
|
|
8428
|
+
);
|
|
8429
|
+
}
|
|
8430
|
+
const kind = await lstat(profileDir).then((stats) => stats.isSymbolicLink() ? "link" : "present", (error) => {
|
|
8431
|
+
if (error.code === "ENOENT") return "missing";
|
|
8432
|
+
throw error;
|
|
8433
|
+
});
|
|
8434
|
+
if (kind === "missing") return;
|
|
8435
|
+
if (kind === "link") {
|
|
8436
|
+
await rm2(profileDir, { force: true });
|
|
8437
|
+
return;
|
|
8438
|
+
}
|
|
8439
|
+
await _ProfileManager.withLock(name, async () => {
|
|
8440
|
+
for (const file of ["session.json", "key.json"]) await rm2(join6(profileDir, file), { force: true });
|
|
8441
|
+
for (const entry of await readdir2(profileDir)) {
|
|
8442
|
+
if (entry !== ".lock" && entry !== "profile.json") await rm2(join6(profileDir, entry), { recursive: true, force: true });
|
|
8443
|
+
}
|
|
8444
|
+
await rm2(join6(profileDir, "profile.json"), { force: true });
|
|
8445
|
+
await recordProfileDeletion(name);
|
|
8446
|
+
});
|
|
8447
|
+
await rmdir(profileDir).catch((error) => {
|
|
8448
|
+
if (error.code !== "ENOENT" && error.code !== "ENOTEMPTY" && error.code !== "EEXIST") throw error;
|
|
8449
|
+
});
|
|
8450
|
+
}
|
|
8451
|
+
// ── Key management ──────────────────────────────────────────────────
|
|
8452
|
+
/**
|
|
8453
|
+
* Returns the parsed JWK for a profile, or null if no key exists.
|
|
8454
|
+
*/
|
|
8455
|
+
static async getKey(name) {
|
|
8456
|
+
return readJson(join6(PROFILES_DIR, name, "key.json"));
|
|
8457
|
+
}
|
|
8458
|
+
/**
|
|
8459
|
+
* Saves a JWK key under the profile lock (0600, in an owner-only profile
|
|
8460
|
+
* directory). Refused (PROFILE_NOT_FOUND) if the profile was deleted while
|
|
8461
|
+
* this waited for the lock, rather than leaving a key-only profile.
|
|
8462
|
+
*/
|
|
8463
|
+
static async setKey(name, jwk) {
|
|
8464
|
+
await _ProfileManager.withLock(name, async () => {
|
|
8465
|
+
await refuseWriteToDeletedProfile2(name);
|
|
8466
|
+
await writeJson(join6(await _ProfileManager.ensureProfileDir(name), "key.json"), jwk);
|
|
8467
|
+
});
|
|
8468
|
+
}
|
|
8469
|
+
/** Removes key.json under the profile lock (rollback of a key a failed login created). */
|
|
8470
|
+
static async removeKey(name) {
|
|
8471
|
+
await _ProfileManager.withLock(name, () => rm2(join6(PROFILES_DIR, name, "key.json"), { force: true }));
|
|
8472
|
+
}
|
|
8473
|
+
// ── Session management ──────────────────────────────────────────────
|
|
8474
|
+
/**
|
|
8475
|
+
* Returns the parsed session for a profile, or null if none exists.
|
|
8476
|
+
*/
|
|
8477
|
+
static async getSession(name) {
|
|
8478
|
+
return readSession(name);
|
|
8479
|
+
}
|
|
8480
|
+
/**
|
|
8481
|
+
* Saves session data for a profile.
|
|
8482
|
+
*/
|
|
8483
|
+
static async setSession(name, session) {
|
|
8484
|
+
await writeSession(name, session);
|
|
8485
|
+
}
|
|
8486
|
+
/**
|
|
8487
|
+
* Removes the session file for a profile.
|
|
8488
|
+
*/
|
|
8489
|
+
static async clearSession(name) {
|
|
8490
|
+
await removeSession(name);
|
|
8491
|
+
}
|
|
8492
|
+
// ── Cache management ────────────────────────────────────────────────
|
|
8493
|
+
/**
|
|
8494
|
+
* Returns the profile's cache directory (share history lives here),
|
|
8495
|
+
* created or tightened to 0700.
|
|
8496
|
+
*/
|
|
8497
|
+
static async getCacheDir(name) {
|
|
8498
|
+
const cacheDir = join6(await _ProfileManager.ensureProfileDir(name), "cache");
|
|
8499
|
+
await ensureDir(cacheDir);
|
|
8500
|
+
await chmod2(cacheDir, PRIVATE_DIR_MODE);
|
|
8501
|
+
return cacheDir;
|
|
8502
|
+
}
|
|
8503
|
+
// ── Resolution helpers ──────────────────────────────────────────────
|
|
8504
|
+
/**
|
|
8505
|
+
* Resolves the full CLI context from flags, env vars, and config.
|
|
8506
|
+
*
|
|
8507
|
+
* Profile resolution: options.profile > TC_PROFILE env > config.defaultProfile > "default"
|
|
8508
|
+
* Host resolution: options.host > TC_HOST env > discovered local node > profile.host > DEFAULT_HOST
|
|
8509
|
+
*
|
|
8510
|
+
* Local-node discovery (TC-106) only runs when no explicit host was given
|
|
8511
|
+
* (`--host` / `TC_HOST`); it probes configured or registered local nodes and,
|
|
8512
|
+
* after DID verification against the profile's pinned identity, prefers one
|
|
8513
|
+
* over the stored/default host. For session-using commands, it verifies the
|
|
8514
|
+
* stored session locally before probing. Loopback requires an explicit
|
|
8515
|
+
* `localNodeUrl`; disable discovery with `autoDiscoverLocalNode: false`.
|
|
8516
|
+
*/
|
|
8517
|
+
static async resolveContext(options, settings = {}) {
|
|
8518
|
+
const config = await _ProfileManager.getConfig();
|
|
8519
|
+
const profile = options.profile ?? process.env.TC_PROFILE ?? config.defaultProfile ?? DEFAULT_PROFILE;
|
|
8520
|
+
let profileHost;
|
|
8521
|
+
let profileConfig;
|
|
8522
|
+
try {
|
|
8523
|
+
profileConfig = await _ProfileManager.getProfile(profile);
|
|
8524
|
+
profileHost = profileConfig.host;
|
|
8525
|
+
} catch {
|
|
8526
|
+
}
|
|
8527
|
+
const envReplication = process.env.TC_REPLICATION?.toLowerCase();
|
|
8528
|
+
const envEnabled = envReplication === "1" || envReplication === "true" || envReplication === "on";
|
|
8529
|
+
const explicitEnvOff = envReplication === "0" || envReplication === "false" || envReplication === "off";
|
|
8530
|
+
if (envReplication !== void 0 && !envEnabled && !explicitEnvOff) {
|
|
8531
|
+
throw new CLIError("INVALID_ARGUMENT", "TC_REPLICATION must be one of 1, true, on, 0, false or off.", ExitCode.USAGE_ERROR);
|
|
8532
|
+
}
|
|
8533
|
+
const explicitOff = options.noReplication === true || options.replication === false;
|
|
8534
|
+
const replication = options.replication === true ? true : explicitOff ? false : envEnabled;
|
|
8535
|
+
const explicitHost = options.host ?? process.env.TC_HOST;
|
|
8536
|
+
let host = explicitHost ?? profileHost ?? DEFAULT_HOST;
|
|
8537
|
+
let localDiscovery;
|
|
8538
|
+
if (explicitHost === void 0) {
|
|
8539
|
+
const { discoverLocalNodeHost: discoverLocalNodeHost2 } = await Promise.resolve().then(() => (init_host(), host_exports));
|
|
8540
|
+
const explicitKey = Boolean(options.privateKey || process.env.TC_PRIVATE_KEY);
|
|
8541
|
+
const discovered = await discoverLocalNodeHost2(profile, {
|
|
8542
|
+
awaitStoredSession: settings.storedSession !== "unused" && !explicitKey
|
|
8543
|
+
});
|
|
8544
|
+
if (discovered.host !== null) host = discovered.host;
|
|
8545
|
+
if (discovered.deferred) localDiscovery = { deferredFrom: host };
|
|
8546
|
+
}
|
|
8547
|
+
setActiveProfileName(profile);
|
|
8548
|
+
return {
|
|
8549
|
+
profile,
|
|
8550
|
+
host,
|
|
8551
|
+
verbose: options.verbose ?? false,
|
|
8552
|
+
noCache: options.noCache ?? false,
|
|
8553
|
+
quiet: options.quiet ?? false,
|
|
8554
|
+
replication,
|
|
8555
|
+
replicationDebug: options.replicationDebug === true || process.env.TC_REPLICATION_DEBUG === "1",
|
|
8556
|
+
...localDiscovery === void 0 ? {} : { localDiscovery }
|
|
8557
|
+
};
|
|
8558
|
+
}
|
|
8559
|
+
};
|
|
8155
8560
|
}
|
|
8156
|
-
};
|
|
8157
|
-
_RistrettoPoint.BASE = /* @__PURE__ */ (() => new _RistrettoPoint(ed25519.Point.BASE))();
|
|
8158
|
-
_RistrettoPoint.ZERO = /* @__PURE__ */ (() => new _RistrettoPoint(ed25519.Point.ZERO))();
|
|
8159
|
-
_RistrettoPoint.Fp = /* @__PURE__ */ (() => Fp)();
|
|
8160
|
-
_RistrettoPoint.Fn = /* @__PURE__ */ (() => Fn)();
|
|
8561
|
+
});
|
|
8161
8562
|
|
|
8162
|
-
//
|
|
8163
|
-
|
|
8164
|
-
init_u64();
|
|
8563
|
+
// src/commands/courier.ts
|
|
8564
|
+
var TC_OPTIONS_BEFORE_COURIER = 'tc courier takes no tc options and does not use tc profiles; Courier keeps its own profile in $COURIER_HOME (default ~/.courier). Put flags after "courier", e.g. tc courier init --host <url>.';
|
|
8165
8565
|
|
|
8166
|
-
//
|
|
8167
|
-
|
|
8168
|
-
|
|
8169
|
-
|
|
8170
|
-
d = rotr(d ^ a, 16);
|
|
8171
|
-
c = c + d | 0;
|
|
8172
|
-
b = rotr(b ^ c, 12);
|
|
8173
|
-
return { a, b, c, d };
|
|
8174
|
-
}
|
|
8175
|
-
function G2s(a, b, c, d, x) {
|
|
8176
|
-
a = a + b + x | 0;
|
|
8177
|
-
d = rotr(d ^ a, 8);
|
|
8178
|
-
c = c + d | 0;
|
|
8179
|
-
b = rotr(b ^ c, 7);
|
|
8180
|
-
return { a, b, c, d };
|
|
8181
|
-
}
|
|
8566
|
+
// src/index.ts
|
|
8567
|
+
init_errors();
|
|
8568
|
+
import { readFileSync as readFileSync2 } from "fs";
|
|
8569
|
+
import { Command } from "commander";
|
|
8182
8570
|
|
|
8183
|
-
//
|
|
8184
|
-
|
|
8185
|
-
|
|
8186
|
-
|
|
8187
|
-
|
|
8188
|
-
|
|
8189
|
-
|
|
8190
|
-
|
|
8191
|
-
|
|
8192
|
-
|
|
8193
|
-
|
|
8194
|
-
|
|
8195
|
-
|
|
8196
|
-
|
|
8197
|
-
|
|
8198
|
-
|
|
8199
|
-
|
|
8200
|
-
|
|
8201
|
-
|
|
8202
|
-
|
|
8203
|
-
|
|
8204
|
-
|
|
8205
|
-
|
|
8206
|
-
|
|
8207
|
-
|
|
8208
|
-
|
|
8209
|
-
|
|
8210
|
-
|
|
8211
|
-
|
|
8212
|
-
|
|
8213
|
-
|
|
8214
|
-
|
|
8215
|
-
|
|
8216
|
-
|
|
8217
|
-
|
|
8218
|
-
|
|
8219
|
-
|
|
8220
|
-
|
|
8221
|
-
|
|
8222
|
-
|
|
8223
|
-
|
|
8224
|
-
|
|
8225
|
-
|
|
8226
|
-
|
|
8227
|
-
|
|
8228
|
-
this.length += take;
|
|
8229
|
-
pos += take;
|
|
8571
|
+
// src/output/banner.ts
|
|
8572
|
+
init_formatter();
|
|
8573
|
+
|
|
8574
|
+
// src/output/taglines.ts
|
|
8575
|
+
var HOLIDAY_TAGLINES = [
|
|
8576
|
+
{ month: 1, day: 1, range: 1, tagline: "New year, new keys, same cloud." },
|
|
8577
|
+
{ month: 2, day: 14, tagline: "We love your data as much as you do." },
|
|
8578
|
+
{ month: 3, day: 14, tagline: "3.14159 reasons to encrypt everything." },
|
|
8579
|
+
{ month: 5, day: 4, tagline: "May the fourth be with your keys." },
|
|
8580
|
+
{ month: 10, day: 31, tagline: "Nothing scarier than plaintext secrets." },
|
|
8581
|
+
{ month: 12, day: 25, range: 2, tagline: "Unwrap your data, not your keys." },
|
|
8582
|
+
{ month: 12, day: 31, tagline: "Encrypt your resolutions." }
|
|
8583
|
+
];
|
|
8584
|
+
var TAGLINES = [
|
|
8585
|
+
// Professional
|
|
8586
|
+
"Your data, your keys, your cloud.",
|
|
8587
|
+
"Self-sovereign storage for the modern web.",
|
|
8588
|
+
"The cloud you actually own.",
|
|
8589
|
+
"Encrypted by default, decentralized by design.",
|
|
8590
|
+
"Where your data answers only to you.",
|
|
8591
|
+
"End-to-end encrypted. No exceptions.",
|
|
8592
|
+
"Like S3 but you hold the keys.",
|
|
8593
|
+
"Privacy isn't a feature. It's the architecture.",
|
|
8594
|
+
"Sovereign storage, zero knowledge.",
|
|
8595
|
+
"Your .env is safe here \u2014 we use real cryptography.",
|
|
8596
|
+
// Playful / nerdy
|
|
8597
|
+
"UCAN do anything.",
|
|
8598
|
+
"Keys generated, delegations granted, data liberated.",
|
|
8599
|
+
"Decentralized storage, centralized vibes.",
|
|
8600
|
+
"Trust nobody, delegate everything.",
|
|
8601
|
+
"sudo make me a sandwich, encrypted.",
|
|
8602
|
+
"Have you tried turning your keys off and on again?",
|
|
8603
|
+
"All your base are belong to you.",
|
|
8604
|
+
"In UCAN we trust.",
|
|
8605
|
+
"0 knowledge, 100% confidence.",
|
|
8606
|
+
"Keeping secrets since 2024."
|
|
8607
|
+
];
|
|
8608
|
+
function getHolidayTagline() {
|
|
8609
|
+
const now = /* @__PURE__ */ new Date();
|
|
8610
|
+
const month = now.getMonth() + 1;
|
|
8611
|
+
const day = now.getDate();
|
|
8612
|
+
for (const h of HOLIDAY_TAGLINES) {
|
|
8613
|
+
const range = h.range ?? 0;
|
|
8614
|
+
if (h.month === month && Math.abs(day - h.day) <= range) {
|
|
8615
|
+
return h.tagline;
|
|
8230
8616
|
}
|
|
8231
|
-
return this;
|
|
8232
|
-
}
|
|
8233
|
-
digestInto(out) {
|
|
8234
|
-
aexists(this);
|
|
8235
|
-
aoutput(out, this);
|
|
8236
|
-
const { pos, buffer32 } = this;
|
|
8237
|
-
this.finished = true;
|
|
8238
|
-
clean(this.buffer.subarray(pos));
|
|
8239
|
-
swap32IfBE(buffer32);
|
|
8240
|
-
this.compress(buffer32, 0, true);
|
|
8241
|
-
swap32IfBE(buffer32);
|
|
8242
|
-
const out32 = u32(out);
|
|
8243
|
-
this.get().forEach((v, i) => out32[i] = swap8IfBE(v));
|
|
8244
|
-
}
|
|
8245
|
-
digest() {
|
|
8246
|
-
const { buffer, outputLen } = this;
|
|
8247
|
-
this.digestInto(buffer);
|
|
8248
|
-
const res = buffer.slice(0, outputLen);
|
|
8249
|
-
this.destroy();
|
|
8250
|
-
return res;
|
|
8251
|
-
}
|
|
8252
|
-
_cloneInto(to) {
|
|
8253
|
-
const { buffer, length: length4, finished, destroyed, outputLen, pos } = this;
|
|
8254
|
-
to || (to = new this.constructor({ dkLen: outputLen }));
|
|
8255
|
-
to.set(...this.get());
|
|
8256
|
-
to.buffer.set(buffer);
|
|
8257
|
-
to.destroyed = destroyed;
|
|
8258
|
-
to.finished = finished;
|
|
8259
|
-
to.length = length4;
|
|
8260
|
-
to.pos = pos;
|
|
8261
|
-
to.outputLen = outputLen;
|
|
8262
|
-
return to;
|
|
8263
|
-
}
|
|
8264
|
-
clone() {
|
|
8265
|
-
return this._cloneInto();
|
|
8266
|
-
}
|
|
8267
|
-
};
|
|
8268
|
-
function compress(s, offset, msg, rounds, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) {
|
|
8269
|
-
let j = 0;
|
|
8270
|
-
for (let i = 0; i < rounds; i++) {
|
|
8271
|
-
({ a: v0, b: v4, c: v8, d: v12 } = G1s(v0, v4, v8, v12, msg[offset + s[j++]]));
|
|
8272
|
-
({ a: v0, b: v4, c: v8, d: v12 } = G2s(v0, v4, v8, v12, msg[offset + s[j++]]));
|
|
8273
|
-
({ a: v1, b: v5, c: v9, d: v13 } = G1s(v1, v5, v9, v13, msg[offset + s[j++]]));
|
|
8274
|
-
({ a: v1, b: v5, c: v9, d: v13 } = G2s(v1, v5, v9, v13, msg[offset + s[j++]]));
|
|
8275
|
-
({ a: v2, b: v6, c: v10, d: v14 } = G1s(v2, v6, v10, v14, msg[offset + s[j++]]));
|
|
8276
|
-
({ a: v2, b: v6, c: v10, d: v14 } = G2s(v2, v6, v10, v14, msg[offset + s[j++]]));
|
|
8277
|
-
({ a: v3, b: v7, c: v11, d: v15 } = G1s(v3, v7, v11, v15, msg[offset + s[j++]]));
|
|
8278
|
-
({ a: v3, b: v7, c: v11, d: v15 } = G2s(v3, v7, v11, v15, msg[offset + s[j++]]));
|
|
8279
|
-
({ a: v0, b: v5, c: v10, d: v15 } = G1s(v0, v5, v10, v15, msg[offset + s[j++]]));
|
|
8280
|
-
({ a: v0, b: v5, c: v10, d: v15 } = G2s(v0, v5, v10, v15, msg[offset + s[j++]]));
|
|
8281
|
-
({ a: v1, b: v6, c: v11, d: v12 } = G1s(v1, v6, v11, v12, msg[offset + s[j++]]));
|
|
8282
|
-
({ a: v1, b: v6, c: v11, d: v12 } = G2s(v1, v6, v11, v12, msg[offset + s[j++]]));
|
|
8283
|
-
({ a: v2, b: v7, c: v8, d: v13 } = G1s(v2, v7, v8, v13, msg[offset + s[j++]]));
|
|
8284
|
-
({ a: v2, b: v7, c: v8, d: v13 } = G2s(v2, v7, v8, v13, msg[offset + s[j++]]));
|
|
8285
|
-
({ a: v3, b: v4, c: v9, d: v14 } = G1s(v3, v4, v9, v14, msg[offset + s[j++]]));
|
|
8286
|
-
({ a: v3, b: v4, c: v9, d: v14 } = G2s(v3, v4, v9, v14, msg[offset + s[j++]]));
|
|
8287
8617
|
}
|
|
8288
|
-
return
|
|
8618
|
+
return null;
|
|
8619
|
+
}
|
|
8620
|
+
function pickTagline() {
|
|
8621
|
+
const holiday = getHolidayTagline();
|
|
8622
|
+
if (holiday) return holiday;
|
|
8623
|
+
return TAGLINES[Math.floor(Math.random() * TAGLINES.length)];
|
|
8289
8624
|
}
|
|
8290
8625
|
|
|
8291
|
-
//
|
|
8292
|
-
|
|
8293
|
-
|
|
8294
|
-
|
|
8295
|
-
|
|
8296
|
-
|
|
8297
|
-
|
|
8298
|
-
|
|
8299
|
-
|
|
8300
|
-
|
|
8301
|
-
}
|
|
8302
|
-
|
|
8303
|
-
var B3_SIGMA = /* @__PURE__ */ (() => {
|
|
8304
|
-
const Id = Array.from({ length: 16 }, (_, i) => i);
|
|
8305
|
-
const permute = (arr) => [2, 6, 3, 10, 7, 0, 4, 13, 1, 11, 12, 5, 9, 14, 15, 8].map((i) => arr[i]);
|
|
8306
|
-
const res = [];
|
|
8307
|
-
for (let i = 0, v = Id; i < 7; i++, v = permute(v))
|
|
8308
|
-
res.push(...v);
|
|
8309
|
-
return Uint8Array.from(res);
|
|
8310
|
-
})();
|
|
8311
|
-
var BLAKE3 = class _BLAKE3 extends BLAKE2 {
|
|
8312
|
-
constructor(opts = {}, flags = 0) {
|
|
8313
|
-
super(64, opts.dkLen === void 0 ? 32 : opts.dkLen);
|
|
8314
|
-
this.chunkPos = 0;
|
|
8315
|
-
this.chunksDone = 0;
|
|
8316
|
-
this.flags = 0 | 0;
|
|
8317
|
-
this.stack = [];
|
|
8318
|
-
this.posOut = 0;
|
|
8319
|
-
this.bufferOut32 = new Uint32Array(16);
|
|
8320
|
-
this.chunkOut = 0;
|
|
8321
|
-
this.enableXOF = true;
|
|
8322
|
-
const { key, context } = opts;
|
|
8323
|
-
const hasContext = context !== void 0;
|
|
8324
|
-
if (key !== void 0) {
|
|
8325
|
-
if (hasContext)
|
|
8326
|
-
throw new Error('Only "key" or "context" can be specified at same time');
|
|
8327
|
-
const k = toBytes(key).slice();
|
|
8328
|
-
abytes(k, 32);
|
|
8329
|
-
this.IV = u32(k);
|
|
8330
|
-
swap32IfBE(this.IV);
|
|
8331
|
-
this.flags = flags | B3_Flags.KEYED_HASH;
|
|
8332
|
-
} else if (hasContext) {
|
|
8333
|
-
const ctx = toBytes(context);
|
|
8334
|
-
const contextKey = new _BLAKE3({ dkLen: 32 }, B3_Flags.DERIVE_KEY_CONTEXT).update(ctx).digest();
|
|
8335
|
-
this.IV = u32(contextKey);
|
|
8336
|
-
swap32IfBE(this.IV);
|
|
8337
|
-
this.flags = flags | B3_Flags.DERIVE_KEY_MATERIAL;
|
|
8338
|
-
} else {
|
|
8339
|
-
this.IV = B3_IV.slice();
|
|
8340
|
-
this.flags = flags;
|
|
8341
|
-
}
|
|
8342
|
-
this.state = this.IV.slice();
|
|
8343
|
-
this.bufferOut = u8(this.bufferOut32);
|
|
8344
|
-
}
|
|
8345
|
-
// Unused
|
|
8346
|
-
get() {
|
|
8347
|
-
return [];
|
|
8626
|
+
// src/output/banner.ts
|
|
8627
|
+
init_theme();
|
|
8628
|
+
import { execSync } from "child_process";
|
|
8629
|
+
var bannerEmitted = false;
|
|
8630
|
+
function resolveCommitHash() {
|
|
8631
|
+
try {
|
|
8632
|
+
return execSync("git rev-parse --short HEAD", {
|
|
8633
|
+
encoding: "utf-8",
|
|
8634
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
8635
|
+
}).trim() || null;
|
|
8636
|
+
} catch {
|
|
8637
|
+
return null;
|
|
8348
8638
|
}
|
|
8349
|
-
|
|
8350
|
-
|
|
8351
|
-
|
|
8352
|
-
|
|
8353
|
-
|
|
8354
|
-
|
|
8355
|
-
|
|
8356
|
-
|
|
8357
|
-
|
|
8358
|
-
s[3] = v3 ^ v11;
|
|
8359
|
-
s[4] = v4 ^ v12;
|
|
8360
|
-
s[5] = v5 ^ v13;
|
|
8361
|
-
s[6] = v6 ^ v14;
|
|
8362
|
-
s[7] = v7 ^ v15;
|
|
8363
|
-
}
|
|
8364
|
-
compress(buf, bufPos = 0, isLast = false) {
|
|
8365
|
-
let flags = this.flags;
|
|
8366
|
-
if (!this.chunkPos)
|
|
8367
|
-
flags |= B3_Flags.CHUNK_START;
|
|
8368
|
-
if (this.chunkPos === 15 || isLast)
|
|
8369
|
-
flags |= B3_Flags.CHUNK_END;
|
|
8370
|
-
if (!isLast)
|
|
8371
|
-
this.pos = this.blockLen;
|
|
8372
|
-
this.b2Compress(this.chunksDone, flags, buf, bufPos);
|
|
8373
|
-
this.chunkPos += 1;
|
|
8374
|
-
if (this.chunkPos === 16 || isLast) {
|
|
8375
|
-
let chunk = this.state;
|
|
8376
|
-
this.state = this.IV.slice();
|
|
8377
|
-
for (let last, chunks = this.chunksDone + 1; isLast || !(chunks & 1); chunks >>= 1) {
|
|
8378
|
-
if (!(last = this.stack.pop()))
|
|
8379
|
-
break;
|
|
8380
|
-
this.buffer32.set(last, 0);
|
|
8381
|
-
this.buffer32.set(chunk, 8);
|
|
8382
|
-
this.pos = this.blockLen;
|
|
8383
|
-
this.b2Compress(0, this.flags | B3_Flags.PARENT, this.buffer32, 0);
|
|
8384
|
-
chunk = this.state;
|
|
8385
|
-
this.state = this.IV.slice();
|
|
8386
|
-
}
|
|
8387
|
-
this.chunksDone++;
|
|
8388
|
-
this.chunkPos = 0;
|
|
8389
|
-
this.stack.push(chunk);
|
|
8390
|
-
}
|
|
8391
|
-
this.pos = 0;
|
|
8392
|
-
}
|
|
8393
|
-
_cloneInto(to) {
|
|
8394
|
-
to = super._cloneInto(to);
|
|
8395
|
-
const { IV, flags, state: state2, chunkPos, posOut, chunkOut, stack, chunksDone } = this;
|
|
8396
|
-
to.state.set(state2.slice());
|
|
8397
|
-
to.stack = stack.map((i) => Uint32Array.from(i));
|
|
8398
|
-
to.IV.set(IV);
|
|
8399
|
-
to.flags = flags;
|
|
8400
|
-
to.chunkPos = chunkPos;
|
|
8401
|
-
to.chunksDone = chunksDone;
|
|
8402
|
-
to.posOut = posOut;
|
|
8403
|
-
to.chunkOut = chunkOut;
|
|
8404
|
-
to.enableXOF = this.enableXOF;
|
|
8405
|
-
to.bufferOut32.set(this.bufferOut32);
|
|
8406
|
-
return to;
|
|
8407
|
-
}
|
|
8408
|
-
destroy() {
|
|
8409
|
-
this.destroyed = true;
|
|
8410
|
-
clean(this.state, this.buffer32, this.IV, this.bufferOut32);
|
|
8411
|
-
clean(...this.stack);
|
|
8412
|
-
}
|
|
8413
|
-
// Same as b2Compress, but doesn't modify state and returns 16 u32 array (instead of 8)
|
|
8414
|
-
b2CompressOut() {
|
|
8415
|
-
const { state: s, pos, flags, buffer32, bufferOut32: out32 } = this;
|
|
8416
|
-
const { h, l } = fromBig(BigInt(this.chunkOut++));
|
|
8417
|
-
swap32IfBE(buffer32);
|
|
8418
|
-
const { v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15 } = compress(B3_SIGMA, 0, buffer32, 7, s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7], B3_IV[0], B3_IV[1], B3_IV[2], B3_IV[3], l, h, pos, flags);
|
|
8419
|
-
out32[0] = v0 ^ v8;
|
|
8420
|
-
out32[1] = v1 ^ v9;
|
|
8421
|
-
out32[2] = v2 ^ v10;
|
|
8422
|
-
out32[3] = v3 ^ v11;
|
|
8423
|
-
out32[4] = v4 ^ v12;
|
|
8424
|
-
out32[5] = v5 ^ v13;
|
|
8425
|
-
out32[6] = v6 ^ v14;
|
|
8426
|
-
out32[7] = v7 ^ v15;
|
|
8427
|
-
out32[8] = s[0] ^ v8;
|
|
8428
|
-
out32[9] = s[1] ^ v9;
|
|
8429
|
-
out32[10] = s[2] ^ v10;
|
|
8430
|
-
out32[11] = s[3] ^ v11;
|
|
8431
|
-
out32[12] = s[4] ^ v12;
|
|
8432
|
-
out32[13] = s[5] ^ v13;
|
|
8433
|
-
out32[14] = s[6] ^ v14;
|
|
8434
|
-
out32[15] = s[7] ^ v15;
|
|
8435
|
-
swap32IfBE(buffer32);
|
|
8436
|
-
swap32IfBE(out32);
|
|
8437
|
-
this.posOut = 0;
|
|
8438
|
-
}
|
|
8439
|
-
finish() {
|
|
8440
|
-
if (this.finished)
|
|
8441
|
-
return;
|
|
8442
|
-
this.finished = true;
|
|
8443
|
-
clean(this.buffer.subarray(this.pos));
|
|
8444
|
-
let flags = this.flags | B3_Flags.ROOT;
|
|
8445
|
-
if (this.stack.length) {
|
|
8446
|
-
flags |= B3_Flags.PARENT;
|
|
8447
|
-
swap32IfBE(this.buffer32);
|
|
8448
|
-
this.compress(this.buffer32, 0, true);
|
|
8449
|
-
swap32IfBE(this.buffer32);
|
|
8450
|
-
this.chunksDone = 0;
|
|
8451
|
-
this.pos = this.blockLen;
|
|
8452
|
-
} else {
|
|
8453
|
-
flags |= (!this.chunkPos ? B3_Flags.CHUNK_START : 0) | B3_Flags.CHUNK_END;
|
|
8454
|
-
}
|
|
8455
|
-
this.flags = flags;
|
|
8456
|
-
this.b2CompressOut();
|
|
8457
|
-
}
|
|
8458
|
-
writeInto(out) {
|
|
8459
|
-
aexists(this, false);
|
|
8460
|
-
abytes(out);
|
|
8461
|
-
this.finish();
|
|
8462
|
-
const { blockLen, bufferOut } = this;
|
|
8463
|
-
for (let pos = 0, len = out.length; pos < len; ) {
|
|
8464
|
-
if (this.posOut >= blockLen)
|
|
8465
|
-
this.b2CompressOut();
|
|
8466
|
-
const take = Math.min(blockLen - this.posOut, len - pos);
|
|
8467
|
-
out.set(bufferOut.subarray(this.posOut, this.posOut + take), pos);
|
|
8468
|
-
this.posOut += take;
|
|
8469
|
-
pos += take;
|
|
8470
|
-
}
|
|
8471
|
-
return out;
|
|
8472
|
-
}
|
|
8473
|
-
xofInto(out) {
|
|
8474
|
-
if (!this.enableXOF)
|
|
8475
|
-
throw new Error("XOF is not possible after digest call");
|
|
8476
|
-
return this.writeInto(out);
|
|
8477
|
-
}
|
|
8478
|
-
xof(bytes) {
|
|
8479
|
-
anumber(bytes);
|
|
8480
|
-
return this.xofInto(new Uint8Array(bytes));
|
|
8481
|
-
}
|
|
8482
|
-
digestInto(out) {
|
|
8483
|
-
aoutput(out, this);
|
|
8484
|
-
if (this.finished)
|
|
8485
|
-
throw new Error("digest() was already called");
|
|
8486
|
-
this.enableXOF = false;
|
|
8487
|
-
this.writeInto(out);
|
|
8488
|
-
this.destroy();
|
|
8489
|
-
return out;
|
|
8490
|
-
}
|
|
8491
|
-
digest() {
|
|
8492
|
-
return this.digestInto(new Uint8Array(this.outputLen));
|
|
8639
|
+
}
|
|
8640
|
+
function formatBannerLine(version2) {
|
|
8641
|
+
const commit = resolveCommitHash();
|
|
8642
|
+
const tagline = pickTagline();
|
|
8643
|
+
const versionPart = `tc v${version2}`;
|
|
8644
|
+
const commitPart = commit ? ` (${commit})` : "";
|
|
8645
|
+
const separator = " \u2014 ";
|
|
8646
|
+
if (!isInteractive()) {
|
|
8647
|
+
return `${versionPart}${commitPart}${separator}${tagline}`;
|
|
8493
8648
|
}
|
|
8494
|
-
|
|
8495
|
-
|
|
8649
|
+
return [
|
|
8650
|
+
theme.brand("\u2601\uFE0F tc"),
|
|
8651
|
+
" ",
|
|
8652
|
+
theme.muted(`v${version2}`),
|
|
8653
|
+
commit ? theme.dim(` (${commit})`) : "",
|
|
8654
|
+
theme.dim(separator),
|
|
8655
|
+
theme.primary(tagline)
|
|
8656
|
+
].join("");
|
|
8657
|
+
}
|
|
8658
|
+
function emitBanner(version2) {
|
|
8659
|
+
if (bannerEmitted) return;
|
|
8660
|
+
if (shouldOutputJson()) return;
|
|
8661
|
+
if (process.env.TC_HIDE_BANNER === "1") return;
|
|
8662
|
+
bannerEmitted = true;
|
|
8663
|
+
process.stderr.write(formatBannerLine(version2) + "\n\n");
|
|
8664
|
+
}
|
|
8665
|
+
|
|
8666
|
+
// src/index.ts
|
|
8667
|
+
init_replication_registry();
|
|
8668
|
+
init_theme();
|
|
8669
|
+
init_formatter();
|
|
8670
|
+
init_profiles();
|
|
8496
8671
|
|
|
8497
8672
|
// ../share-sdk/dist/index.js
|
|
8673
|
+
init_sha2();
|
|
8674
|
+
init_ed25519();
|
|
8675
|
+
init_blake3();
|
|
8676
|
+
init_ed25519();
|
|
8498
8677
|
init_sha256();
|
|
8499
8678
|
init_sha256();
|
|
8500
8679
|
var __defProp2 = Object.defineProperty;
|
|
@@ -18512,6 +18691,12 @@ async function selectedProfileName() {
|
|
|
18512
18691
|
return process.env.TC_PROFILE ?? config.defaultProfile;
|
|
18513
18692
|
}
|
|
18514
18693
|
|
|
18694
|
+
// src/lib/courier-loader.ts
|
|
18695
|
+
async function loadCourierEntry() {
|
|
18696
|
+
const load = new Function("specifier", "return import(specifier)");
|
|
18697
|
+
return load(new URL("./courier-entry.js", import.meta.url).href);
|
|
18698
|
+
}
|
|
18699
|
+
|
|
18515
18700
|
// src/index.ts
|
|
18516
18701
|
var { version } = JSON.parse(
|
|
18517
18702
|
readFileSync2(new URL("../package.json", import.meta.url), "utf-8")
|
|
@@ -18571,30 +18756,28 @@ configureShareCommandServices({
|
|
|
18571
18756
|
nativeReader: shareAuthority.nativeReader
|
|
18572
18757
|
});
|
|
18573
18758
|
var argv = process.argv.slice(2);
|
|
18574
|
-
var
|
|
18759
|
+
var globalLongOptionsWithValues = { "--profile": true, "--host": true };
|
|
18760
|
+
var globalShortOptionsWithValues = { p: true, H: true };
|
|
18575
18761
|
function firstCommandToken(values) {
|
|
18576
18762
|
for (let index = 0; index < values.length; index += 1) {
|
|
18577
18763
|
const value = values[index];
|
|
18578
18764
|
if (value === "--") return values[index + 1];
|
|
18579
|
-
if (
|
|
18580
|
-
index += 1;
|
|
18765
|
+
if (value.startsWith("--")) {
|
|
18766
|
+
if (globalLongOptionsWithValues[value]) index += 1;
|
|
18767
|
+
continue;
|
|
18768
|
+
}
|
|
18769
|
+
if (value.length > 1 && value.startsWith("-")) {
|
|
18770
|
+
for (let char = 1; char < value.length; char += 1) {
|
|
18771
|
+
if (!globalShortOptionsWithValues[value[char]]) continue;
|
|
18772
|
+
if (char === value.length - 1) index += 1;
|
|
18773
|
+
break;
|
|
18774
|
+
}
|
|
18581
18775
|
continue;
|
|
18582
18776
|
}
|
|
18583
|
-
if (value.startsWith("--profile=") || value.startsWith("--host=")) continue;
|
|
18584
|
-
if (value === "--verbose" || value === "--no-cache" || value === "-q" || value === "--quiet" || value === "--json" || value === "--replication" || value === "--no-replication" || value === "--replication-debug") continue;
|
|
18585
|
-
if (value.startsWith("-")) continue;
|
|
18586
18777
|
return value;
|
|
18587
18778
|
}
|
|
18588
18779
|
return void 0;
|
|
18589
18780
|
}
|
|
18590
|
-
var isShareInvocation = firstCommandToken(argv) === "share";
|
|
18591
|
-
if (isShareInvocation) {
|
|
18592
|
-
registerShareCommand(program);
|
|
18593
|
-
} else {
|
|
18594
|
-
const loadLegacy = new Function("specifier", "return import(specifier)");
|
|
18595
|
-
const { registerTinyCloudCommands } = await loadLegacy(new URL("./legacy-entry.js", import.meta.url).href);
|
|
18596
|
-
registerTinyCloudCommands(program);
|
|
18597
|
-
}
|
|
18598
18781
|
program.addHelpText("before", () => `${theme.label("Version:")} ${theme.value(version)}
|
|
18599
18782
|
`);
|
|
18600
18783
|
program.addHelpText("afterAll", () => {
|
|
@@ -18614,20 +18797,37 @@ ${theme.muted("Docs:")} ${theme.accent("https://docs.tinycloud.xyz/cli")}
|
|
|
18614
18797
|
${theme.muted("Repo:")} ${theme.accent("https://github.com/tinycloudlabs/web-sdk")}
|
|
18615
18798
|
`;
|
|
18616
18799
|
});
|
|
18617
|
-
|
|
18618
|
-
|
|
18619
|
-
|
|
18620
|
-
|
|
18621
|
-
|
|
18622
|
-
|
|
18623
|
-
|
|
18624
|
-
|
|
18625
|
-
|
|
18626
|
-
|
|
18627
|
-
|
|
18628
|
-
}
|
|
18629
|
-
|
|
18630
|
-
|
|
18800
|
+
var commandToken = firstCommandToken(argv);
|
|
18801
|
+
if (argv[0] === "courier") {
|
|
18802
|
+
const code3 = await (await loadCourierEntry()).runCourier(argv.slice(1));
|
|
18803
|
+
if (code3 !== 0) process.exit(code3);
|
|
18804
|
+
} else if (commandToken === "courier") {
|
|
18805
|
+
process.stderr.write(`${TC_OPTIONS_BEFORE_COURIER}
|
|
18806
|
+
`);
|
|
18807
|
+
process.exit(2);
|
|
18808
|
+
} else {
|
|
18809
|
+
if (commandToken === "share") {
|
|
18810
|
+
registerShareCommand(program);
|
|
18811
|
+
} else {
|
|
18812
|
+
const loadLegacy = new Function("specifier", "return import(specifier)");
|
|
18813
|
+
const { registerTinyCloudCommands } = await loadLegacy(new URL("./legacy-entry.js", import.meta.url).href);
|
|
18814
|
+
registerTinyCloudCommands(program);
|
|
18815
|
+
}
|
|
18816
|
+
try {
|
|
18817
|
+
await program.parseAsync(process.argv);
|
|
18818
|
+
if (await closeReplication()) {
|
|
18819
|
+
process.exitCode = 0;
|
|
18820
|
+
const stdoutFlushed = Promise.withResolvers();
|
|
18821
|
+
process.stdout.write("", () => stdoutFlushed.resolve());
|
|
18822
|
+
await stdoutFlushed.promise;
|
|
18823
|
+
const stderrFlushed = Promise.withResolvers();
|
|
18824
|
+
process.stderr.write("", () => stderrFlushed.resolve());
|
|
18825
|
+
await stderrFlushed.promise;
|
|
18826
|
+
process.exit();
|
|
18827
|
+
}
|
|
18828
|
+
} catch (error) {
|
|
18829
|
+
await handleError(error);
|
|
18830
|
+
}
|
|
18631
18831
|
}
|
|
18632
18832
|
/*! Bundled license information:
|
|
18633
18833
|
|