@tinycloud/sdk-core 3.2.1 → 3.2.3-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -408,6 +408,7 @@ __export(index_exports, {
408
408
  parseShareArtifact: () => parseShareArtifact,
409
409
  parseShareUrl: () => parseShareUrl,
410
410
  parseSignedCompactUcanAttenuation: () => parseSignedCompactUcanAttenuation,
411
+ parseSignedSiweCacao: () => parseSignedSiweCacao,
411
412
  parseSpaceUri: () => parseSpaceUri,
412
413
  parseStorageRejection: () => import_sdk_services9.parseStorageRejection,
413
414
  parseStorageStatus: () => import_sdk_services9.parseStorageStatus,
@@ -1545,12 +1546,12 @@ var Decoder = class {
1545
1546
  this.prefixCodePoint = prefixCodePoint;
1546
1547
  this.baseDecode = baseDecode;
1547
1548
  }
1548
- decode(text2) {
1549
- if (typeof text2 === "string") {
1550
- if (text2.codePointAt(0) !== this.prefixCodePoint) {
1551
- throw Error(`Unable to decode multibase string ${JSON.stringify(text2)}, ${this.name} decoder only supports inputs prefixed with ${this.prefix}`);
1549
+ decode(text3) {
1550
+ if (typeof text3 === "string") {
1551
+ if (text3.codePointAt(0) !== this.prefixCodePoint) {
1552
+ throw Error(`Unable to decode multibase string ${JSON.stringify(text3)}, ${this.name} decoder only supports inputs prefixed with ${this.prefix}`);
1552
1553
  }
1553
- return this.baseDecode(text2.slice(this.prefix.length));
1554
+ return this.baseDecode(text3.slice(this.prefix.length));
1554
1555
  } else {
1555
1556
  throw Error("Can only multibase decode strings");
1556
1557
  }
@@ -1614,7 +1615,7 @@ function baseX({ name: name2, prefix, alphabet: alphabet2 }) {
1614
1615
  prefix,
1615
1616
  name: name2,
1616
1617
  encode: encode5,
1617
- decode: (text2) => coerce(decode7(text2))
1618
+ decode: (text3) => coerce(decode7(text3))
1618
1619
  });
1619
1620
  }
1620
1621
  function decode(string2, alphabetIdx, bitsPerChar, name2) {
@@ -4719,7 +4720,7 @@ function parseSignedCompactUcanAttenuation(input, expectedCid) {
4719
4720
  throw new Error("compact UCAN signed audience is missing");
4720
4721
  const cid2 = CID.createV1(85, create(30, (0, import_blake3.blake3)(new TextEncoder().encode(input)))).toString();
4721
4722
  if (expectedCid !== void 0 && cid2 !== expectedCid) throw new Error("compact UCAN CID does not match exact Authorization bytes");
4722
- return { cid: cid2, payload: { att, aud: payloadValue.aud } };
4723
+ return { cid: cid2, payload: { att, aud: payloadValue.aud, iss: payloadValue.iss } };
4723
4724
  }
4724
4725
  function parsePolicySessionUcan(authorization, expectedProofs) {
4725
4726
  const parsed = parseCompactUcanAuthorization(authorization);
@@ -4888,9 +4889,9 @@ function policyV2DigestHex(input) {
4888
4889
  );
4889
4890
  }
4890
4891
  function date(value, label) {
4891
- const text2 = nonEmpty(value, label);
4892
- if (!Number.isFinite(Date.parse(text2))) throw new Error(`${label} is invalid`);
4893
- return text2;
4892
+ const text3 = nonEmpty(value, label);
4893
+ if (!Number.isFinite(Date.parse(text3))) throw new Error(`${label} is invalid`);
4894
+ return text3;
4894
4895
  }
4895
4896
  function rfc3339Seconds2(value) {
4896
4897
  return new Date(Math.floor(value.getTime() / 1e3) * 1e3).toISOString().replace(/\.000Z$/, "Z");
@@ -8843,64 +8844,64 @@ function canonicalJson(value) {
8843
8844
  }
8844
8845
  throw new ShareEnvelopeError("invalid-envelope", "unsupported JSON value");
8845
8846
  }
8846
- function skipWhitespace(text2, start) {
8847
+ function skipWhitespace(text3, start) {
8847
8848
  let index = start;
8848
- while (/\s/.test(text2[index] ?? "")) index += 1;
8849
+ while (/\s/.test(text3[index] ?? "")) index += 1;
8849
8850
  return index;
8850
8851
  }
8851
- function scanJsonValue(text2, start) {
8852
- let index = skipWhitespace(text2, start);
8853
- const first = text2[index];
8852
+ function scanJsonValue(text3, start) {
8853
+ let index = skipWhitespace(text3, start);
8854
+ const first = text3[index];
8854
8855
  if (first === '"') {
8855
8856
  index += 1;
8856
- while (index < text2.length) {
8857
- if (text2[index] === "\\") index += 2;
8858
- else if (text2[index++] === '"') return index;
8857
+ while (index < text3.length) {
8858
+ if (text3[index] === "\\") index += 2;
8859
+ else if (text3[index++] === '"') return index;
8859
8860
  }
8860
8861
  throw new ShareEnvelopeError("invalid-envelope", "unterminated JSON string");
8861
8862
  }
8862
8863
  if (first === "{") {
8863
8864
  const keys = /* @__PURE__ */ new Set();
8864
- index = skipWhitespace(text2, index + 1);
8865
- if (text2[index] === "}") return index + 1;
8866
- while (index < text2.length) {
8867
- index = skipWhitespace(text2, index);
8868
- if (text2[index] !== '"') throw new ShareEnvelopeError("invalid-envelope", "object key must be a string");
8865
+ index = skipWhitespace(text3, index + 1);
8866
+ if (text3[index] === "}") return index + 1;
8867
+ while (index < text3.length) {
8868
+ index = skipWhitespace(text3, index);
8869
+ if (text3[index] !== '"') throw new ShareEnvelopeError("invalid-envelope", "object key must be a string");
8869
8870
  const keyStart = index;
8870
- index = scanJsonValue(text2, index);
8871
- const key = JSON.parse(text2.slice(keyStart, index));
8871
+ index = scanJsonValue(text3, index);
8872
+ const key = JSON.parse(text3.slice(keyStart, index));
8872
8873
  if (keys.has(key)) throw new ShareEnvelopeError("invalid-envelope", `duplicate JSON key ${key}`);
8873
8874
  keys.add(key);
8874
- index = skipWhitespace(text2, index);
8875
- if (text2[index++] !== ":") throw new ShareEnvelopeError("invalid-envelope", "missing object colon");
8876
- index = scanJsonValue(text2, index);
8877
- index = skipWhitespace(text2, index);
8878
- if (text2[index] === "}") return index + 1;
8879
- if (text2[index++] !== ",") throw new ShareEnvelopeError("invalid-envelope", "invalid object separator");
8875
+ index = skipWhitespace(text3, index);
8876
+ if (text3[index++] !== ":") throw new ShareEnvelopeError("invalid-envelope", "missing object colon");
8877
+ index = scanJsonValue(text3, index);
8878
+ index = skipWhitespace(text3, index);
8879
+ if (text3[index] === "}") return index + 1;
8880
+ if (text3[index++] !== ",") throw new ShareEnvelopeError("invalid-envelope", "invalid object separator");
8880
8881
  }
8881
8882
  throw new ShareEnvelopeError("invalid-envelope", "unterminated JSON object");
8882
8883
  }
8883
8884
  if (first === "[") {
8884
- index = skipWhitespace(text2, index + 1);
8885
- if (text2[index] === "]") return index + 1;
8886
- while (index < text2.length) {
8887
- index = scanJsonValue(text2, index);
8888
- index = skipWhitespace(text2, index);
8889
- if (text2[index] === "]") return index + 1;
8890
- if (text2[index++] !== ",") throw new ShareEnvelopeError("invalid-envelope", "invalid array separator");
8885
+ index = skipWhitespace(text3, index + 1);
8886
+ if (text3[index] === "]") return index + 1;
8887
+ while (index < text3.length) {
8888
+ index = scanJsonValue(text3, index);
8889
+ index = skipWhitespace(text3, index);
8890
+ if (text3[index] === "]") return index + 1;
8891
+ if (text3[index++] !== ",") throw new ShareEnvelopeError("invalid-envelope", "invalid array separator");
8891
8892
  }
8892
8893
  throw new ShareEnvelopeError("invalid-envelope", "unterminated JSON array");
8893
8894
  }
8894
- const match = text2.slice(index).match(/^(?:true|false|null|-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?)/);
8895
+ const match = text3.slice(index).match(/^(?:true|false|null|-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?)/);
8895
8896
  if (!match) throw new ShareEnvelopeError("invalid-envelope", "invalid JSON value");
8896
8897
  return index + match[0].length;
8897
8898
  }
8898
- function parseCanonicalJson(text2) {
8899
+ function parseCanonicalJson(text3) {
8899
8900
  try {
8900
- const end = scanJsonValue(text2, 0);
8901
- if (skipWhitespace(text2, end) !== text2.length) throw new Error("trailing JSON");
8902
- const parsed = JSON.parse(text2);
8903
- if (canonicalJson(parsed) !== text2) throw new Error("non-canonical JSON");
8901
+ const end = scanJsonValue(text3, 0);
8902
+ if (skipWhitespace(text3, end) !== text3.length) throw new Error("trailing JSON");
8903
+ const parsed = JSON.parse(text3);
8904
+ if (canonicalJson(parsed) !== text3) throw new Error("non-canonical JSON");
8904
8905
  return parsed;
8905
8906
  } catch (error) {
8906
8907
  if (error instanceof ShareEnvelopeError) throw error;
@@ -12329,8 +12330,8 @@ async function createPolicyEnforcementDelegation(input) {
12329
12330
  return { cid: cid(dagCborBytes), dagCbor: b64(dagCborBytes), issuerDid: input.shareKey.did, audienceDid: input.enforcerDid, facts, signature };
12330
12331
  }
12331
12332
  async function canonicalOwnerSharePolicy(policy) {
12332
- const text2 = canonicalizeSignedObjectUnsigned({ domain: POLICY_DOMAIN, policy });
12333
- const policyBytes = new TextEncoder().encode(text2);
12333
+ const text3 = canonicalizeSignedObjectUnsigned({ domain: POLICY_DOMAIN, policy });
12334
+ const policyBytes = new TextEncoder().encode(text3);
12334
12335
  return { bytes: policyBytes, cid: cid(policyBytes), digest: digest3(policyBytes) };
12335
12336
  }
12336
12337
  function computeOwnerShareRegistrationCid(registration) {
@@ -12562,6 +12563,222 @@ var SenderShareStore = class {
12562
12563
  var import_share_sdk = require("@tinycloud/share-sdk");
12563
12564
  var import_share_sdk2 = require("@tinycloud/share-sdk");
12564
12565
 
12566
+ // src/delegations/cacao.ts
12567
+ var import_blake34 = require("@noble/hashes/blake3");
12568
+ var import_siwe2 = require("siwe");
12569
+ var import_viem5 = require("viem");
12570
+ var MAX_CACAO_BYTES = 64 * 1024;
12571
+ var MAX_CBOR_DEPTH = 64;
12572
+ var RECAP_PREFIX = "urn:recap:";
12573
+ var RECAP_STATEMENT = "I further authorize the stated URI to perform the following actions on my behalf:";
12574
+ function compareKeys(left, right) {
12575
+ if (left.length !== right.length) return left.length - right.length;
12576
+ for (let index = 0; index < left.length; index++) {
12577
+ if (left[index] !== right[index]) return left[index] - right[index];
12578
+ }
12579
+ return 0;
12580
+ }
12581
+ function decodeDagCbor(bytes2) {
12582
+ let offset = 0;
12583
+ const view = new DataView(bytes2.buffer, bytes2.byteOffset, bytes2.byteLength);
12584
+ const take = (length2) => {
12585
+ if (length2 > bytes2.length - offset) throw new Error("CBOR input ended early");
12586
+ return bytes2.subarray(offset, offset += length2);
12587
+ };
12588
+ const read2 = (depth) => {
12589
+ if (depth > MAX_CBOR_DEPTH) throw new Error(`CBOR nesting exceeds ${MAX_CBOR_DEPTH} levels`);
12590
+ const [initial] = take(1);
12591
+ const major = initial >> 5;
12592
+ const info = initial & 31;
12593
+ if (major === 7) {
12594
+ if (info === 20) return false;
12595
+ if (info === 21) return true;
12596
+ if (info === 22) return null;
12597
+ throw new Error("CBOR floats and other simple values are not part of a CACAO");
12598
+ }
12599
+ if (major === 6) throw new Error("CBOR tags are not part of a CACAO");
12600
+ let argument;
12601
+ if (info < 24) argument = info;
12602
+ else if (info === 24) argument = take(1)[0];
12603
+ else if (info === 25) argument = view.getUint16(take(2).byteOffset - bytes2.byteOffset);
12604
+ else if (info === 26) argument = view.getUint32(take(4).byteOffset - bytes2.byteOffset);
12605
+ else if (info === 27) {
12606
+ const value2 = view.getBigUint64(take(8).byteOffset - bytes2.byteOffset);
12607
+ if (value2 > BigInt(Number.MAX_SAFE_INTEGER)) throw new Error("CBOR integer is too large");
12608
+ argument = Number(value2);
12609
+ } else throw new Error("CBOR indefinite lengths are not DAG-CBOR");
12610
+ switch (major) {
12611
+ case 0:
12612
+ return argument;
12613
+ case 1:
12614
+ return -1 - argument;
12615
+ case 2:
12616
+ return take(argument).slice();
12617
+ case 3:
12618
+ return new TextDecoder("utf-8", { fatal: true }).decode(take(argument));
12619
+ case 4: {
12620
+ if (argument > bytes2.length - offset) throw new Error("CBOR input ended early");
12621
+ const items = [];
12622
+ for (let index = 0; index < argument; index++) items.push(read2(depth + 1));
12623
+ return items;
12624
+ }
12625
+ default: {
12626
+ if (argument > bytes2.length - offset) throw new Error("CBOR input ended early");
12627
+ const map2 = /* @__PURE__ */ Object.create(null);
12628
+ for (let index = 0; index < argument; index++) {
12629
+ const key = read2(depth + 1);
12630
+ if (typeof key !== "string") throw new Error("CBOR map keys must be strings");
12631
+ if (key === "__proto__") throw new Error("CBOR map key __proto__ is not allowed");
12632
+ if (Object.prototype.hasOwnProperty.call(map2, key)) throw new Error(`CBOR map has a duplicate key ${JSON.stringify(key)}`);
12633
+ map2[key] = read2(depth + 1);
12634
+ }
12635
+ return map2;
12636
+ }
12637
+ }
12638
+ };
12639
+ const value = read2(0);
12640
+ if (offset !== bytes2.length) throw new Error("CBOR input has trailing bytes");
12641
+ return value;
12642
+ }
12643
+ function encodeDagCbor(value) {
12644
+ const output = [];
12645
+ const head = (major, argument) => {
12646
+ if (argument < 24) output.push(major << 5 | argument);
12647
+ else if (argument < 256) output.push(major << 5 | 24, argument);
12648
+ else if (argument < 65536) output.push(major << 5 | 25, argument >> 8, argument & 255);
12649
+ else if (argument < 4294967296) output.push(major << 5 | 26, ...[24, 16, 8, 0].map((shift) => argument >>> shift & 255));
12650
+ else output.push(major << 5 | 27, ...[56n, 48n, 40n, 32n, 24n, 16n, 8n, 0n].map((shift) => Number(BigInt(argument) >> shift & 0xffn)));
12651
+ };
12652
+ const write = (item) => {
12653
+ if (item === null) output.push(246);
12654
+ else if (item === false) output.push(244);
12655
+ else if (item === true) output.push(245);
12656
+ else if (typeof item === "number" && Number.isSafeInteger(item)) {
12657
+ if (item >= 0) head(0, item);
12658
+ else head(1, -1 - item);
12659
+ } else if (typeof item === "string") {
12660
+ const encoded = new TextEncoder().encode(item);
12661
+ head(3, encoded.length);
12662
+ output.push(...encoded);
12663
+ } else if (item instanceof Uint8Array) {
12664
+ head(2, item.length);
12665
+ output.push(...item);
12666
+ } else if (Array.isArray(item)) {
12667
+ head(4, item.length);
12668
+ item.forEach(write);
12669
+ } else if (typeof item === "object") {
12670
+ const entries = Object.keys(item).map((key) => [new TextEncoder().encode(key), item[key]]);
12671
+ entries.sort(([left], [right]) => compareKeys(left, right));
12672
+ head(5, entries.length);
12673
+ for (const [key, entry] of entries) {
12674
+ head(3, key.length);
12675
+ output.push(...key);
12676
+ write(entry);
12677
+ }
12678
+ } else throw new Error("value is not DAG-CBOR encodable");
12679
+ };
12680
+ write(value);
12681
+ return Uint8Array.from(output);
12682
+ }
12683
+ function map(value, label, keys, optional = []) {
12684
+ if (typeof value !== "object" || value === null || Array.isArray(value) || value instanceof Uint8Array) throw new Error(`CACAO ${label} must be a map`);
12685
+ const entries = value;
12686
+ for (const key of Object.keys(entries)) {
12687
+ if (!keys.includes(key) && !optional.includes(key)) throw new Error(`CACAO ${label} has unknown field ${JSON.stringify(key)}`);
12688
+ }
12689
+ for (const key of keys) if (!(key in entries)) throw new Error(`CACAO ${label} is missing ${key}`);
12690
+ return entries;
12691
+ }
12692
+ function text2(value, label) {
12693
+ if (typeof value !== "string" || value.length === 0) throw new Error(`CACAO ${label} must be a non-empty string`);
12694
+ return value;
12695
+ }
12696
+ function reCapStatement(attenuation) {
12697
+ var _a3;
12698
+ let index = 0;
12699
+ let lines = "";
12700
+ for (const resource of Object.keys(attenuation).sort()) {
12701
+ const namespaces = /* @__PURE__ */ Object.create(null);
12702
+ for (const ability of Object.keys(attenuation[resource]).sort()) {
12703
+ const slash = ability.indexOf("/");
12704
+ if (slash <= 0) throw new Error("ReCap ability must be namespace/name");
12705
+ (namespaces[_a3 = ability.slice(0, slash)] ?? (namespaces[_a3] = [])).push(ability.slice(slash + 1));
12706
+ }
12707
+ for (const namespace of Object.keys(namespaces).sort()) {
12708
+ lines += ` (${++index}) '${namespace}': ${namespaces[namespace].map((name2) => `'${name2}'`).join(", ")} for '${resource}'.`;
12709
+ }
12710
+ }
12711
+ return `${RECAP_STATEMENT}${lines}`;
12712
+ }
12713
+ function reCapAttenuation(resource) {
12714
+ const isObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
12715
+ const parsed = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(decodeBase64Url(resource.slice(RECAP_PREFIX.length))));
12716
+ if (!isObject(parsed) || !("att" in parsed) || !isObject(parsed.att)) throw new Error("ReCap attenuation must be an object");
12717
+ const attenuation = /* @__PURE__ */ Object.create(null);
12718
+ for (const [target, abilities] of Object.entries(parsed.att)) {
12719
+ if (target === "__proto__" || !isObject(abilities) || Object.keys(abilities).length === 0) throw new Error("ReCap resource must map to abilities");
12720
+ const copy = /* @__PURE__ */ Object.create(null);
12721
+ for (const [ability, caveats] of Object.entries(abilities)) {
12722
+ if (ability === "__proto__" || !/^[^/]+\/[^/]/.test(ability)) throw new Error("ReCap ability must be namespace/name");
12723
+ if (!Array.isArray(caveats) || caveats.length === 0 || !caveats.every(isObject)) throw new Error("ReCap caveats must be a non-empty array of objects");
12724
+ copy[ability] = caveats;
12725
+ }
12726
+ attenuation[target] = copy;
12727
+ }
12728
+ return attenuation;
12729
+ }
12730
+ async function parseSignedSiweCacao(authorization, expectedCid) {
12731
+ if (authorization.length > Math.ceil(MAX_CACAO_BYTES / 3) * 4 + 2) throw new Error(`CACAO exceeds ${MAX_CACAO_BYTES} bytes`);
12732
+ if (!/^[A-Za-z0-9_-]+={0,2}$/.test(authorization)) throw new Error("CACAO must be base64url DAG-CBOR");
12733
+ const bytes2 = decodeBase64Url(authorization.replace(/=+$/, ""));
12734
+ if (bytes2.length > MAX_CACAO_BYTES) throw new Error(`CACAO exceeds ${MAX_CACAO_BYTES} bytes`);
12735
+ const cid2 = CID.createV1(85, create(30, (0, import_blake34.blake3)(bytes2))).toString();
12736
+ if (expectedCid !== void 0 && cid2 !== expectedCid) throw new Error("CACAO CID does not match exact Authorization bytes");
12737
+ const decoded = decodeDagCbor(bytes2);
12738
+ const canonical = encodeDagCbor(decoded);
12739
+ if (canonical.length !== bytes2.length || canonical.some((byte, index) => byte !== bytes2[index])) throw new Error("CACAO is not canonical DAG-CBOR");
12740
+ const cacao = map(decoded, "envelope", ["h", "p", "s"]);
12741
+ if (map(cacao.h, "header", ["t"]).t !== "eip4361") throw new Error("CACAO header must be eip4361");
12742
+ const signature = map(cacao.s, "signature", ["t", "s"]);
12743
+ if (signature.t !== "eip191" || !(signature.s instanceof Uint8Array) || signature.s.length !== 65) throw new Error("CACAO signature must be a 65-byte eip191 signature");
12744
+ const payload = map(cacao.p, "payload", ["domain", "iss", "aud", "version", "nonce", "iat"], ["exp", "nbf", "statement", "requestId", "resources"]);
12745
+ if (payload.version !== 1) throw new Error("CACAO SIWE version must be the integer 1");
12746
+ const issuer = text2(payload.iss, "iss");
12747
+ const pkh = /^did:pkh:eip155:([1-9]\d*):(0x[0-9a-fA-F]{40})$/.exec(issuer);
12748
+ const chainId = Number(pkh?.[1]);
12749
+ if (pkh === null || !Number.isSafeInteger(chainId) || String(chainId) !== pkh[1]) throw new Error("CACAO issuer must be did:pkh:eip155 with a safe-integer chain ID");
12750
+ const audience = text2(payload.aud, "aud");
12751
+ const optional = (key) => payload[key] === void 0 ? void 0 : text2(payload[key], key);
12752
+ const statement = optional("statement");
12753
+ const expiresAt = optional("exp");
12754
+ const notBefore = optional("nbf");
12755
+ const requestId = optional("requestId");
12756
+ let resources = [];
12757
+ if ("resources" in payload) {
12758
+ if (!Array.isArray(payload.resources) || payload.resources.length === 0) throw new Error("CACAO resources must be a non-empty array when present");
12759
+ resources = payload.resources.map((resource, index) => text2(resource, `resources[${index}]`));
12760
+ }
12761
+ const last = resources.at(-1);
12762
+ const attenuation = last?.startsWith(RECAP_PREFIX) ? reCapAttenuation(last) : /* @__PURE__ */ Object.create(null);
12763
+ if (last?.startsWith(RECAP_PREFIX) && !statement?.endsWith(reCapStatement(attenuation))) throw new Error("CACAO statement does not match its ReCap");
12764
+ const message = new import_siwe2.SiweMessage({
12765
+ domain: text2(payload.domain, "domain"),
12766
+ address: pkh[2],
12767
+ uri: audience,
12768
+ version: "1",
12769
+ chainId,
12770
+ nonce: text2(payload.nonce, "nonce"),
12771
+ issuedAt: text2(payload.iat, "iat"),
12772
+ ...statement === void 0 ? {} : { statement },
12773
+ ...expiresAt === void 0 ? {} : { expirationTime: expiresAt },
12774
+ ...notBefore === void 0 ? {} : { notBefore },
12775
+ ...requestId === void 0 ? {} : { requestId },
12776
+ ...resources.length === 0 ? {} : { resources }
12777
+ }).prepareMessage();
12778
+ if (!await verifyEip191MessageSignature(message, (0, import_viem5.bytesToHex)(signature.s), pkh[2])) throw new Error("CACAO signature is invalid");
12779
+ return { cid: cid2, issuer, audience, attenuation, ...expiresAt === void 0 ? {} : { expiresAt } };
12780
+ }
12781
+
12565
12782
  // src/networkId.ts
12566
12783
  var import_sdk_services4 = require("@tinycloud/sdk-services");
12567
12784
  function canonicalizeNetworkId(networkId) {
@@ -14221,11 +14438,11 @@ var TinyCloud = class _TinyCloud {
14221
14438
  if (contentType?.includes("application/json")) {
14222
14439
  data = await response.json();
14223
14440
  } else {
14224
- const text2 = await response.text();
14441
+ const text3 = await response.text();
14225
14442
  try {
14226
- data = JSON.parse(text2);
14443
+ data = JSON.parse(text3);
14227
14444
  } catch {
14228
- data = text2;
14445
+ data = text3;
14229
14446
  }
14230
14447
  }
14231
14448
  return (0, import_sdk_services6.ok)(data);
@@ -18141,7 +18358,7 @@ function portForProtocol(protocol) {
18141
18358
 
18142
18359
  // src/location.ts
18143
18360
  var import_ed2551910 = require("@noble/curves/ed25519");
18144
- var import_viem5 = require("viem");
18361
+ var import_viem6 = require("viem");
18145
18362
  var DEFAULT_TINYCLOUD_LOCATION_REGISTRY_URL = "https://registry.tinycloud.xyz";
18146
18363
  var DEFAULT_TINYCLOUD_FALLBACK_HOST = "https://node.tinycloud.xyz";
18147
18364
  var DEFAULT_LOCAL_NODE_URL = "http://127.0.0.1:8000";
@@ -18311,10 +18528,10 @@ async function fetchLocationRecord(registryUrl, subject, fetchFn = globalThis.fe
18311
18528
  if (!response.ok) {
18312
18529
  throw new LocationRegistryHttpError(`location registry returned HTTP ${response.status}`, response.status);
18313
18530
  }
18314
- const text2 = await boundedResponseText(response, "location registry", 64 * 1024);
18531
+ const text3 = await boundedResponseText(response, "location registry", 64 * 1024);
18315
18532
  let body;
18316
18533
  try {
18317
- body = JSON.parse(text2);
18534
+ body = JSON.parse(text3);
18318
18535
  } catch {
18319
18536
  throw new LocationRecordValidationError("registry response is not JSON");
18320
18537
  }
@@ -18356,10 +18573,10 @@ async function publishLocationRecord(options2) {
18356
18573
  if (!response.ok) {
18357
18574
  throw new LocationRegistryHttpError(`location registry publish returned HTTP ${response.status}`, response.status);
18358
18575
  }
18359
- const text2 = await boundedResponseText(response, "location registry", 64 * 1024);
18576
+ const text3 = await boundedResponseText(response, "location registry", 64 * 1024);
18360
18577
  let body;
18361
18578
  try {
18362
- body = JSON.parse(text2);
18579
+ body = JSON.parse(text3);
18363
18580
  } catch {
18364
18581
  throw new LocationRecordValidationError("registry publish response is not JSON");
18365
18582
  }
@@ -18726,10 +18943,10 @@ async function verifyOwnerNodeBinding(options2) {
18726
18943
  Object.assign(failure, { status: response.status });
18727
18944
  throw failure;
18728
18945
  }
18729
- const text2 = await boundedResponseText(response, "target node /info", 16 * 1024);
18946
+ const text3 = await boundedResponseText(response, "target node /info", 16 * 1024);
18730
18947
  let body;
18731
18948
  try {
18732
- body = JSON.parse(text2);
18949
+ body = JSON.parse(text3);
18733
18950
  } catch {
18734
18951
  throw new LocationRecordValidationError("target node /info response is not JSON");
18735
18952
  }
@@ -18894,7 +19111,7 @@ async function verifyPkhSignature(did, payload, signature) {
18894
19111
  if (!/^0x[0-9a-fA-F]+$/.test(signature)) {
18895
19112
  throw new LocationRecordValidationError("did:pkh signature must be hex");
18896
19113
  }
18897
- return (0, import_viem5.verifyMessage)({
19114
+ return (0, import_viem6.verifyMessage)({
18898
19115
  address,
18899
19116
  message: payload,
18900
19117
  signature