@tinycloud/sdk-core 3.0.0-beta.5 → 3.0.0-beta.7

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
@@ -64,6 +64,7 @@ __export(index_exports, {
64
64
  CREDENTIAL_CONTRACT_VERSION: () => CREDENTIAL_CONTRACT_VERSION,
65
65
  CREDENTIAL_ERROR_CODES: () => CREDENTIAL_ERROR_CODES,
66
66
  CREDENTIAL_FORMAT: () => CREDENTIAL_FORMAT,
67
+ CREDENTIAL_INVITATION_REQUEST_DOMAIN: () => CREDENTIAL_INVITATION_REQUEST_DOMAIN,
67
68
  CREDENTIAL_PROTOCOL: () => CREDENTIAL_ACQUISITION_PROTOCOL,
68
69
  CREDENTIAL_STEP_REGISTRY_VERSION: () => CREDENTIAL_STEP_REGISTRY_VERSION,
69
70
  CapabilityKeyRegistry: () => CapabilityKeyRegistry,
@@ -87,6 +88,7 @@ __export(index_exports, {
87
88
  DEFAULT_SIGNED_READ_URL_EXPIRY_MS: () => DEFAULT_SIGNED_READ_URL_EXPIRY_MS,
88
89
  DEFAULT_TINYCLOUD_FALLBACK_HOST: () => DEFAULT_TINYCLOUD_FALLBACK_HOST,
89
90
  DEFAULT_TINYCLOUD_LOCATION_REGISTRY_URL: () => DEFAULT_TINYCLOUD_LOCATION_REGISTRY_URL,
91
+ DELIVERY_ADMISSION_DOMAIN: () => DELIVERY_ADMISSION_DOMAIN,
90
92
  DUCKDB: () => import_bootstrap4.DUCKDB,
91
93
  DataVaultService: () => import_sdk_services8.DataVaultService,
92
94
  DatabaseHandle: () => import_sdk_services8.DatabaseHandle,
@@ -392,6 +394,7 @@ __export(index_exports, {
392
394
  projectUnifiedPolicyCapabilities: () => projectUnifiedPolicyCapabilities,
393
395
  projectUnifiedPolicyCapability: () => projectUnifiedPolicyCapability,
394
396
  recapCaveatsEqual: () => recapCaveatsEqual,
397
+ registerPolicyV3: () => registerPolicyV3,
395
398
  renewPolicyRootStatusV3: () => renewPolicyRootStatusV3,
396
399
  requestTinyCloudManageKeyScope: () => requestTinyCloudManageKeyScope,
397
400
  resolveCloudLocation: () => resolveCloudLocation,
@@ -447,6 +450,7 @@ __export(index_exports, {
447
450
  validatePolicyStatusUnsigned: () => validatePolicyStatusUnsigned,
448
451
  validatePolicyUnsigned: () => validatePolicyUnsigned,
449
452
  validateShareDeliveryAuthorizationBytes: () => validateShareDeliveryAuthorizationBytes,
453
+ validateShareDeliveryAuthorizationV3Bytes: () => validateShareDeliveryAuthorizationV3Bytes,
450
454
  validateUnifiedPolicyV2: () => validateUnifiedPolicyV2,
451
455
  verifyDecryptResponse: () => import_sdk_services8.verifyDecryptResponse,
452
456
  verifyDidKeyEd25519Signature: () => verifyDidKeyEd25519Signature,
@@ -2242,16 +2246,16 @@ function policyCapabilityContains(authority, request) {
2242
2246
  return caveatsContain(auth.caveats, req.caveats);
2243
2247
  }
2244
2248
  function normalizePolicyCapabilityWithOptions(input, options2) {
2245
- const object3 = expectObject(input, "$");
2246
- assertExactKeys(object3, ["service", "space", "path", "actions", "caveats"], "$");
2247
- const service = requiredString(object3, "service", "$", "policy-capability-malformed-service");
2249
+ const object4 = expectObject(input, "$");
2250
+ assertExactKeys(object4, ["service", "space", "path", "actions", "caveats"], "$");
2251
+ const service = requiredString(object4, "service", "$", "policy-capability-malformed-service");
2248
2252
  if (!CEILING_SERVICES.has(service)) {
2249
2253
  throw new PolicyCapabilityError(
2250
2254
  "policy-capability-malformed-service",
2251
2255
  "$.service is outside the frozen permissionsCeiling vocabulary"
2252
2256
  );
2253
2257
  }
2254
- const space = requiredString(object3, "space", "$", "policy-capability-malformed-space");
2258
+ const space = requiredString(object4, "space", "$", "policy-capability-malformed-space");
2255
2259
  validateConcreteSpace(space);
2256
2260
  const canonicalSpace = space.normalize("NFC");
2257
2261
  if (options2.requireCanonical && canonicalSpace !== space) {
@@ -2260,7 +2264,7 @@ function normalizePolicyCapabilityWithOptions(input, options2) {
2260
2264
  "$.space must already be canonical NFC"
2261
2265
  );
2262
2266
  }
2263
- const rawPath = requiredString(object3, "path", "$", "policy-capability-malformed-path");
2267
+ const rawPath = requiredString(object4, "path", "$", "policy-capability-malformed-path");
2264
2268
  validateRawPath(rawPath, options2);
2265
2269
  const path = normalizePath(rawPath);
2266
2270
  if (options2.requireCanonical && path !== rawPath) {
@@ -2271,7 +2275,7 @@ function normalizePolicyCapabilityWithOptions(input, options2) {
2271
2275
  }
2272
2276
  validateRawPath(path, options2);
2273
2277
  const actions = normalizeActions(
2274
- requiredArray(object3, "actions", "$", "policy-capability-malformed-action"),
2278
+ requiredArray(object4, "actions", "$", "policy-capability-malformed-action"),
2275
2279
  service,
2276
2280
  options2
2277
2281
  );
@@ -2280,9 +2284,9 @@ function normalizePolicyCapabilityWithOptions(input, options2) {
2280
2284
  output.space = canonicalSpace;
2281
2285
  output.path = path;
2282
2286
  output.actions = actions;
2283
- if (hasOwn(object3, "caveats")) {
2287
+ if (hasOwn(object4, "caveats")) {
2284
2288
  output.caveats = validateCaveats(
2285
- requiredValue(object3, "caveats", "$", "policy-capability-malformed-caveats"),
2289
+ requiredValue(object4, "caveats", "$", "policy-capability-malformed-caveats"),
2286
2290
  output.service
2287
2291
  );
2288
2292
  }
@@ -2305,9 +2309,9 @@ function expectObject(input, path) {
2305
2309
  );
2306
2310
  }
2307
2311
  }
2308
- function assertExactKeys(object3, allowed, path) {
2312
+ function assertExactKeys(object4, allowed, path) {
2309
2313
  const allowedSet = new Set(allowed);
2310
- for (const key of Object.keys(object3)) {
2314
+ for (const key of Object.keys(object4)) {
2311
2315
  if (!allowedSet.has(key)) {
2312
2316
  throw new PolicyCapabilityError(
2313
2317
  key === "id" || key === "scope" ? "policy-capability-malformed" : "policy-capability-unknown-key",
@@ -2316,21 +2320,21 @@ function assertExactKeys(object3, allowed, path) {
2316
2320
  }
2317
2321
  }
2318
2322
  }
2319
- function requiredValue(object3, key, path, code3) {
2320
- if (!hasOwn(object3, key)) {
2323
+ function requiredValue(object4, key, path, code3) {
2324
+ if (!hasOwn(object4, key)) {
2321
2325
  throw new PolicyCapabilityError(code3, `${path}.${key} is required`);
2322
2326
  }
2323
- return object3[key];
2327
+ return object4[key];
2324
2328
  }
2325
- function requiredString(object3, key, path, code3) {
2326
- const value = requiredValue(object3, key, path, code3);
2329
+ function requiredString(object4, key, path, code3) {
2330
+ const value = requiredValue(object4, key, path, code3);
2327
2331
  if (typeof value !== "string" || value.length === 0) {
2328
2332
  throw new PolicyCapabilityError(code3, `${path}.${key} must be a non-empty string`);
2329
2333
  }
2330
2334
  return value;
2331
2335
  }
2332
- function requiredArray(object3, key, path, code3) {
2333
- const value = requiredValue(object3, key, path, code3);
2336
+ function requiredArray(object4, key, path, code3) {
2337
+ const value = requiredValue(object4, key, path, code3);
2334
2338
  if (!Array.isArray(value)) {
2335
2339
  throw new PolicyCapabilityError(code3, `${path}.${key} must be an array`);
2336
2340
  }
@@ -2475,11 +2479,11 @@ function validateSqlStatement(input, path) {
2475
2479
  if (input === null || typeof input !== "object" || Array.isArray(input)) {
2476
2480
  throw new PolicyCapabilityError("policy-capability-malformed-caveats", `${path} must be an object`);
2477
2481
  }
2478
- const object3 = input;
2479
- assertCaveatKeys(object3, ["name", "sql", "fixedParams"], path);
2480
- caveatString(object3, "name", path);
2481
- caveatString(object3, "sql", path);
2482
- const fixedParams = requiredCaveat(object3, "fixedParams", path);
2482
+ const object4 = input;
2483
+ assertCaveatKeys(object4, ["name", "sql", "fixedParams"], path);
2484
+ caveatString(object4, "name", path);
2485
+ caveatString(object4, "sql", path);
2486
+ const fixedParams = requiredCaveat(object4, "fixedParams", path);
2483
2487
  if (!Array.isArray(fixedParams)) {
2484
2488
  throw new PolicyCapabilityError(
2485
2489
  "policy-capability-malformed-caveats",
@@ -2494,20 +2498,20 @@ function validateFixedParam(input, path) {
2494
2498
  if (input === null || typeof input !== "object" || Array.isArray(input)) {
2495
2499
  throw new PolicyCapabilityError("policy-capability-malformed-caveats", `${path} must be an object`);
2496
2500
  }
2497
- const object3 = input;
2498
- assertCaveatKeys(object3, ["index", "value"], path);
2499
- const index = requiredCaveat(object3, "index", path);
2501
+ const object4 = input;
2502
+ assertCaveatKeys(object4, ["index", "value"], path);
2503
+ const index = requiredCaveat(object4, "index", path);
2500
2504
  if (typeof index !== "number" || !Number.isSafeInteger(index) || index < 0) {
2501
2505
  throw new PolicyCapabilityError(
2502
2506
  "policy-capability-malformed-caveats",
2503
2507
  `${path}.index must be a non-negative integer`
2504
2508
  );
2505
2509
  }
2506
- requiredCaveat(object3, "value", path);
2510
+ requiredCaveat(object4, "value", path);
2507
2511
  }
2508
- function assertCaveatKeys(object3, allowed, path) {
2512
+ function assertCaveatKeys(object4, allowed, path) {
2509
2513
  const allowedSet = new Set(allowed);
2510
- for (const key of Object.keys(object3)) {
2514
+ for (const key of Object.keys(object4)) {
2511
2515
  if (!allowedSet.has(key)) {
2512
2516
  throw new PolicyCapabilityError(
2513
2517
  "policy-capability-malformed-caveats",
@@ -2516,17 +2520,17 @@ function assertCaveatKeys(object3, allowed, path) {
2516
2520
  }
2517
2521
  }
2518
2522
  }
2519
- function requiredCaveat(object3, key, path) {
2520
- if (!hasOwn(object3, key)) {
2523
+ function requiredCaveat(object4, key, path) {
2524
+ if (!hasOwn(object4, key)) {
2521
2525
  throw new PolicyCapabilityError(
2522
2526
  "policy-capability-malformed-caveats",
2523
2527
  `${path}.${key} is required`
2524
2528
  );
2525
2529
  }
2526
- return object3[key];
2530
+ return object4[key];
2527
2531
  }
2528
- function caveatString(object3, key, path) {
2529
- const value = requiredCaveat(object3, key, path);
2532
+ function caveatString(object4, key, path) {
2533
+ const value = requiredCaveat(object4, key, path);
2530
2534
  if (typeof value !== "string" || value.length === 0) {
2531
2535
  throw new PolicyCapabilityError(
2532
2536
  "policy-capability-malformed-caveats",
@@ -2557,8 +2561,8 @@ function caveatsContain(authority, request) {
2557
2561
  (statement) => authorityStatements.some((candidate) => jcsCanonicalize(candidate) === jcsCanonicalize(statement))
2558
2562
  );
2559
2563
  }
2560
- function hasOwn(object3, key) {
2561
- return objectHasOwn2(object3, key);
2564
+ function hasOwn(object4, key) {
2565
+ return objectHasOwn2(object4, key);
2562
2566
  }
2563
2567
 
2564
2568
  // src/policy/signed-object.ts
@@ -2886,17 +2890,17 @@ async function createAndSignSignedObject(input, signer) {
2886
2890
  }
2887
2891
  function createAndSignPolicy(input, signer) {
2888
2892
  return createAndSignSignedObject(input, signer).then(
2889
- (object3) => validatePolicySignedShape(object3)
2893
+ (object4) => validatePolicySignedShape(object4)
2890
2894
  );
2891
2895
  }
2892
2896
  function createAndSignPolicyStatus(input, signer) {
2893
2897
  return createAndSignSignedObject(input, signer).then(
2894
- (object3) => validatePolicyStatusSignedShape(object3)
2898
+ (object4) => validatePolicyStatusSignedShape(object4)
2895
2899
  );
2896
2900
  }
2897
2901
  function createAndSignPolicyEngineRecord(input, signer) {
2898
2902
  return createAndSignSignedObject(input, signer).then(
2899
- (object3) => validatePolicyEngineRecordSignedShape(object3)
2903
+ (object4) => validatePolicyEngineRecordSignedShape(object4)
2900
2904
  );
2901
2905
  }
2902
2906
  async function verifySignedObject(input) {
@@ -3000,9 +3004,9 @@ function validateUnsignedForDescriptor(input, descriptor) {
3000
3004
  }
3001
3005
  }
3002
3006
  function validatePolicyShape(input, signed) {
3003
- const object3 = expectJsonObject(normalizeJson(input), "$");
3007
+ const object4 = expectJsonObject(normalizeJson(input), "$");
3004
3008
  assertExactKeys2(
3005
- object3,
3009
+ object4,
3006
3010
  signed ? [
3007
3011
  "schema",
3008
3012
  "policyId",
@@ -3030,30 +3034,30 @@ function validatePolicyShape(input, signed) {
3030
3034
  ],
3031
3035
  "$"
3032
3036
  );
3033
- expectConst(requiredString2(object3, "schema", "$"), POLICY_SCHEMA, "$.schema");
3037
+ expectConst(requiredString2(object4, "schema", "$"), POLICY_SCHEMA, "$.schema");
3034
3038
  if (signed) {
3035
- requiredString2(object3, "policyId", "$");
3036
- validateSignature(requiredValue2(object3, "signature", "$"));
3039
+ requiredString2(object4, "policyId", "$");
3040
+ validateSignature(requiredValue2(object4, "signature", "$"));
3037
3041
  }
3038
- requiredString2(object3, "ownerDid", "$");
3039
- requiredString2(object3, "signingKeyDid", "$");
3040
- requiredDateString(object3, "createdAt", "$");
3041
- optionalDateString(object3, "expiresAt", "$");
3042
- validatePolicyResource(requiredValue2(object3, "resource", "$"), "$.resource");
3043
- validateExpression(requiredValue2(object3, "when", "$"), "$.when");
3044
- validateGrant(requiredValue2(object3, "grant", "$"), "$.grant");
3045
- if (hasOwn2(object3, "disclosure")) {
3046
- validateDisclosure(requiredValue2(object3, "disclosure", "$"), "$.disclosure");
3042
+ requiredString2(object4, "ownerDid", "$");
3043
+ requiredString2(object4, "signingKeyDid", "$");
3044
+ requiredDateString(object4, "createdAt", "$");
3045
+ optionalDateString(object4, "expiresAt", "$");
3046
+ validatePolicyResource(requiredValue2(object4, "resource", "$"), "$.resource");
3047
+ validateExpression(requiredValue2(object4, "when", "$"), "$.when");
3048
+ validateGrant(requiredValue2(object4, "grant", "$"), "$.grant");
3049
+ if (hasOwn2(object4, "disclosure")) {
3050
+ validateDisclosure(requiredValue2(object4, "disclosure", "$"), "$.disclosure");
3047
3051
  }
3048
- if (hasOwn2(object3, "audit")) {
3049
- validateAudit(requiredValue2(object3, "audit", "$"), "$.audit");
3052
+ if (hasOwn2(object4, "audit")) {
3053
+ validateAudit(requiredValue2(object4, "audit", "$"), "$.audit");
3050
3054
  }
3051
- return object3;
3055
+ return object4;
3052
3056
  }
3053
3057
  function validatePolicyStatusShape(input, signed) {
3054
- const object3 = expectJsonObject(normalizeJson(input), "$");
3058
+ const object4 = expectJsonObject(normalizeJson(input), "$");
3055
3059
  assertExactKeys2(
3056
- object3,
3060
+ object4,
3057
3061
  signed ? [
3058
3062
  "schema",
3059
3063
  "statusId",
@@ -3077,28 +3081,28 @@ function validatePolicyStatusShape(input, signed) {
3077
3081
  ],
3078
3082
  "$"
3079
3083
  );
3080
- expectConst(requiredString2(object3, "schema", "$"), POLICY_STATUS_SCHEMA, "$.schema");
3084
+ expectConst(requiredString2(object4, "schema", "$"), POLICY_STATUS_SCHEMA, "$.schema");
3081
3085
  if (signed) {
3082
- requiredString2(object3, "statusId", "$");
3083
- validateSignature(requiredValue2(object3, "signature", "$"));
3086
+ requiredString2(object4, "statusId", "$");
3087
+ validateSignature(requiredValue2(object4, "signature", "$"));
3084
3088
  }
3085
- requiredString2(object3, "policyId", "$");
3086
- requiredString2(object3, "ownerDid", "$");
3087
- requiredInteger(object3, "sequence", "$", 0);
3088
- expectOneOf(requiredString2(object3, "disposition", "$"), [
3089
+ requiredString2(object4, "policyId", "$");
3090
+ requiredString2(object4, "ownerDid", "$");
3091
+ requiredInteger(object4, "sequence", "$", 0);
3092
+ expectOneOf(requiredString2(object4, "disposition", "$"), [
3089
3093
  "active",
3090
3094
  "suspended",
3091
3095
  "revoked"
3092
3096
  ], "$.disposition");
3093
- requiredDateString(object3, "effectiveAt", "$");
3094
- optionalString(object3, "reasonCode", "$");
3095
- requiredString2(object3, "signingKeyDid", "$");
3096
- return object3;
3097
+ requiredDateString(object4, "effectiveAt", "$");
3098
+ optionalString(object4, "reasonCode", "$");
3099
+ requiredString2(object4, "signingKeyDid", "$");
3100
+ return object4;
3097
3101
  }
3098
3102
  function validatePolicyEngineRecordShape(input, signed) {
3099
- const object3 = expectJsonObject(normalizeJson(input), "$");
3103
+ const object4 = expectJsonObject(normalizeJson(input), "$");
3100
3104
  assertExactKeys2(
3101
- object3,
3105
+ object4,
3102
3106
  signed ? [
3103
3107
  "schema",
3104
3108
  "engineRecordId",
@@ -3123,44 +3127,44 @@ function validatePolicyEngineRecordShape(input, signed) {
3123
3127
  "$"
3124
3128
  );
3125
3129
  expectConst(
3126
- requiredString2(object3, "schema", "$"),
3130
+ requiredString2(object4, "schema", "$"),
3127
3131
  POLICY_ENGINE_RECORD_SCHEMA,
3128
3132
  "$.schema"
3129
3133
  );
3130
3134
  if (signed) {
3131
- requiredString2(object3, "engineRecordId", "$");
3132
- validateSignature(requiredValue2(object3, "signature", "$"));
3135
+ requiredString2(object4, "engineRecordId", "$");
3136
+ validateSignature(requiredValue2(object4, "signature", "$"));
3133
3137
  }
3134
- requiredString2(object3, "ownerDid", "$");
3135
- requiredString2(object3, "endpoint", "$");
3136
- requiredString2(object3, "audience", "$");
3138
+ requiredString2(object4, "ownerDid", "$");
3139
+ requiredString2(object4, "endpoint", "$");
3140
+ requiredString2(object4, "audience", "$");
3137
3141
  requiredStringArray(
3138
- object3,
3142
+ object4,
3139
3143
  "supportedPolicyVersions",
3140
3144
  "$",
3141
3145
  (value, path) => expectConst(value, "v0", path)
3142
3146
  );
3143
- requiredStringArray(object3, "supportedEvidenceVerifiers", "$");
3144
- requiredString2(object3, "grantIssuerDid", "$");
3145
- requiredDateString(object3, "expiresAt", "$");
3146
- return object3;
3147
+ requiredStringArray(object4, "supportedEvidenceVerifiers", "$");
3148
+ requiredString2(object4, "grantIssuerDid", "$");
3149
+ requiredDateString(object4, "expiresAt", "$");
3150
+ return object4;
3147
3151
  }
3148
3152
  function validateSignature(input) {
3149
- const object3 = expectJsonObject(input, "$.signature");
3150
- assertExactKeys2(object3, ["suite", "signerDid", "value"], "$.signature");
3151
- const suite = requiredString2(object3, "suite", "$.signature");
3153
+ const object4 = expectJsonObject(input, "$.signature");
3154
+ assertExactKeys2(object4, ["suite", "signerDid", "value"], "$.signature");
3155
+ const suite = requiredString2(object4, "suite", "$.signature");
3152
3156
  assertSupportedSignatureSuite(suite);
3153
- const signerDid = requiredString2(object3, "signerDid", "$.signature");
3154
- const value = requiredString2(object3, "value", "$.signature");
3157
+ const signerDid = requiredString2(object4, "signerDid", "$.signature");
3158
+ const value = requiredString2(object4, "value", "$.signature");
3155
3159
  decodeSignatureValue(value, suite);
3156
3160
  return { suite, signerDid, value };
3157
3161
  }
3158
3162
  function validatePolicyResource(input, path) {
3159
- const object3 = expectJsonObject(input, path);
3160
- assertExactKeys2(object3, ["resourceType", "resourceId", "permissionsCeiling"], path);
3161
- requiredString2(object3, "resourceType", path);
3162
- requiredString2(object3, "resourceId", path);
3163
- const ceiling = requiredArray2(object3, "permissionsCeiling", path, 1);
3163
+ const object4 = expectJsonObject(input, path);
3164
+ assertExactKeys2(object4, ["resourceType", "resourceId", "permissionsCeiling"], path);
3165
+ requiredString2(object4, "resourceType", path);
3166
+ requiredString2(object4, "resourceId", path);
3167
+ const ceiling = requiredArray2(object4, "permissionsCeiling", path, 1);
3164
3168
  for (let index = 0; index < ceiling.length; index++) {
3165
3169
  validatePolicyCapability(ceiling[index], `${path}.permissionsCeiling[${index}]`);
3166
3170
  }
@@ -3176,10 +3180,10 @@ function validatePolicyPermissionsCeilingForSigning(input) {
3176
3180
  }
3177
3181
  }
3178
3182
  function validatePolicyCapability(input, path) {
3179
- const object3 = expectJsonObject(input, path);
3183
+ const object4 = expectJsonObject(input, path);
3180
3184
  try {
3181
- const canonical = canonicalizePolicyCapability(object3);
3182
- if (jcsCanonicalize(object3) !== jcsCanonicalize(canonical)) {
3185
+ const canonical = canonicalizePolicyCapability(object4);
3186
+ if (jcsCanonicalize(object4) !== jcsCanonicalize(canonical)) {
3183
3187
  throw new SignedObjectSchemaError(`${path} must be canonical PolicyCapability JSON`);
3184
3188
  }
3185
3189
  } catch (error) {
@@ -3192,10 +3196,10 @@ function validatePolicyCapability(input, path) {
3192
3196
  }
3193
3197
  }
3194
3198
  function validatePolicyCapabilityForSigning(input, path) {
3195
- const object3 = expectJsonObject(input, path);
3199
+ const object4 = expectJsonObject(input, path);
3196
3200
  try {
3197
- const canonical = normalizePolicyCapability(object3);
3198
- if (jcsCanonicalize(object3) !== jcsCanonicalize(canonical)) {
3201
+ const canonical = normalizePolicyCapability(object4);
3202
+ if (jcsCanonicalize(object4) !== jcsCanonicalize(canonical)) {
3199
3203
  throw new SignedObjectSchemaError(`${path} must be strict canonical PolicyCapability JSON`);
3200
3204
  }
3201
3205
  } catch (error) {
@@ -3208,43 +3212,43 @@ function validatePolicyCapabilityForSigning(input, path) {
3208
3212
  }
3209
3213
  }
3210
3214
  function validateExpression(input, path) {
3211
- const object3 = expectJsonObject(input, path);
3212
- const keys = Object.keys(object3);
3215
+ const object4 = expectJsonObject(input, path);
3216
+ const keys = Object.keys(object4);
3213
3217
  if (keys.length !== 1) {
3214
3218
  throw new SignedObjectSchemaError(`${path} must have exactly one expression key`);
3215
3219
  }
3216
3220
  const key = keys[0];
3217
3221
  if (key === "allOf" || key === "anyOf") {
3218
- const values = requiredArray2(object3, key, path, 1);
3222
+ const values = requiredArray2(object4, key, path, 1);
3219
3223
  for (let index = 0; index < values.length; index++) {
3220
3224
  validateExpression(values[index], `${path}.${key}[${index}]`);
3221
3225
  }
3222
3226
  return;
3223
3227
  }
3224
3228
  if (key === "subject") {
3225
- const subject = expectJsonObject(requiredValue2(object3, "subject", path), `${path}.subject`);
3229
+ const subject = expectJsonObject(requiredValue2(object4, "subject", path), `${path}.subject`);
3226
3230
  assertExactKeys2(subject, ["did"], `${path}.subject`);
3227
3231
  requiredString2(subject, "did", `${path}.subject`);
3228
3232
  return;
3229
3233
  }
3230
3234
  if (key === "evidence") {
3231
- validateEvidenceRequirement(requiredValue2(object3, "evidence", path), `${path}.evidence`);
3235
+ validateEvidenceRequirement(requiredValue2(object4, "evidence", path), `${path}.evidence`);
3232
3236
  return;
3233
3237
  }
3234
3238
  throw new SignedObjectSchemaError(`${path} has unknown expression key ${key}`);
3235
3239
  }
3236
3240
  function validateEvidenceRequirement(input, path) {
3237
- const object3 = expectJsonObject(input, path);
3241
+ const object4 = expectJsonObject(input, path);
3238
3242
  assertExactKeys2(
3239
- object3,
3243
+ object4,
3240
3244
  ["requirementId", "verifier", "requirements", "authority", "freshness"],
3241
3245
  path
3242
3246
  );
3243
- requiredString2(object3, "requirementId", path);
3244
- requiredString2(object3, "verifier", path);
3245
- requiredValue2(object3, "requirements", path);
3246
- if (hasOwn2(object3, "authority")) {
3247
- const authority = expectJsonObject(requiredValue2(object3, "authority", path), `${path}.authority`);
3247
+ requiredString2(object4, "requirementId", path);
3248
+ requiredString2(object4, "verifier", path);
3249
+ requiredValue2(object4, "requirements", path);
3250
+ if (hasOwn2(object4, "authority")) {
3251
+ const authority = expectJsonObject(requiredValue2(object4, "authority", path), `${path}.authority`);
3248
3252
  assertExactKeys2(
3249
3253
  authority,
3250
3254
  ["profile", "acceptedIssuers", "allowOwnerAuthorizedIssuer"],
@@ -3256,35 +3260,35 @@ function validateEvidenceRequirement(input, path) {
3256
3260
  }
3257
3261
  optionalBoolean(authority, "allowOwnerAuthorizedIssuer", `${path}.authority`);
3258
3262
  }
3259
- if (hasOwn2(object3, "freshness")) {
3260
- const freshness = expectJsonObject(requiredValue2(object3, "freshness", path), `${path}.freshness`);
3263
+ if (hasOwn2(object4, "freshness")) {
3264
+ const freshness = expectJsonObject(requiredValue2(object4, "freshness", path), `${path}.freshness`);
3261
3265
  assertExactKeys2(freshness, ["maxStatusAgeSeconds"], `${path}.freshness`);
3262
3266
  requiredInteger(freshness, "maxStatusAgeSeconds", `${path}.freshness`, 0);
3263
3267
  }
3264
3268
  }
3265
3269
  function validateGrant(input, path) {
3266
- const object3 = expectJsonObject(input, path);
3267
- assertExactKeys2(object3, ["output", "maxTtlSeconds", "delegationMode", "revocation"], path);
3268
- expectConst(requiredString2(object3, "output", path), "portable-delegation", `${path}.output`);
3269
- requiredInteger(object3, "maxTtlSeconds", path, 1);
3270
- expectOneOf(requiredString2(object3, "delegationMode", path), [
3270
+ const object4 = expectJsonObject(input, path);
3271
+ assertExactKeys2(object4, ["output", "maxTtlSeconds", "delegationMode", "revocation"], path);
3272
+ expectConst(requiredString2(object4, "output", path), "portable-delegation", `${path}.output`);
3273
+ requiredInteger(object4, "maxTtlSeconds", path, 1);
3274
+ expectOneOf(requiredString2(object4, "delegationMode", path), [
3271
3275
  "terminal",
3272
3276
  "attenuable"
3273
3277
  ], `${path}.delegationMode`);
3274
- expectOneOf(requiredString2(object3, "revocation", path), [
3278
+ expectOneOf(requiredString2(object4, "revocation", path), [
3275
3279
  "refresh_only",
3276
3280
  "active_cutoff"
3277
3281
  ], `${path}.revocation`);
3278
3282
  }
3279
3283
  function validateDisclosure(input, path) {
3280
- const object3 = expectJsonObject(input, path);
3281
- assertExactKeys2(object3, ["denial"], path);
3282
- expectOneOf(requiredString2(object3, "denial", path), ["none", "code", "debug"], `${path}.denial`);
3284
+ const object4 = expectJsonObject(input, path);
3285
+ assertExactKeys2(object4, ["denial"], path);
3286
+ expectOneOf(requiredString2(object4, "denial", path), ["none", "code", "debug"], `${path}.denial`);
3283
3287
  }
3284
3288
  function validateAudit(input, path) {
3285
- const object3 = expectJsonObject(input, path);
3286
- assertExactKeys2(object3, ["issuance"], path);
3287
- expectOneOf(requiredString2(object3, "issuance", path), ["off", "security", "full"], `${path}.issuance`);
3289
+ const object4 = expectJsonObject(input, path);
3290
+ assertExactKeys2(object4, ["issuance"], path);
3291
+ expectOneOf(requiredString2(object4, "issuance", path), ["off", "security", "full"], `${path}.issuance`);
3288
3292
  }
3289
3293
  function materialForUnsigned(unsigned, descriptor) {
3290
3294
  const jcs = jcsCanonicalize(unsigned);
@@ -3433,9 +3437,9 @@ function encodeSignatureValue(value, suite) {
3433
3437
  decodeSignatureValue(encoded, suite);
3434
3438
  return encoded;
3435
3439
  }
3436
- function stripOwnIdAndSignature(object3, descriptor) {
3440
+ function stripOwnIdAndSignature(object4, descriptor) {
3437
3441
  const output = /* @__PURE__ */ Object.create(null);
3438
- for (const [key, value] of Object.entries(object3)) {
3442
+ for (const [key, value] of Object.entries(object4)) {
3439
3443
  if (key === descriptor.idField || key === "signature") {
3440
3444
  continue;
3441
3445
  }
@@ -3444,8 +3448,8 @@ function stripOwnIdAndSignature(object3, descriptor) {
3444
3448
  return output;
3445
3449
  }
3446
3450
  function descriptorForUnsigned(input) {
3447
- const object3 = expectJsonObject(normalizeJson(input), "$");
3448
- return descriptorForSchema(requiredString2(object3, "schema", "$"));
3451
+ const object4 = expectJsonObject(normalizeJson(input), "$");
3452
+ return descriptorForSchema(requiredString2(object4, "schema", "$"));
3449
3453
  }
3450
3454
  function descriptorForSchema(schema) {
3451
3455
  if (schema === POLICY_SCHEMA) return DESCRIPTORS.Policy;
@@ -3459,28 +3463,28 @@ function expectJsonObject(input, path) {
3459
3463
  }
3460
3464
  return input;
3461
3465
  }
3462
- function assertExactKeys2(object3, allowed, path) {
3466
+ function assertExactKeys2(object4, allowed, path) {
3463
3467
  const allowedSet = new Set(allowed);
3464
- for (const key of Object.keys(object3)) {
3468
+ for (const key of Object.keys(object4)) {
3465
3469
  if (!allowedSet.has(key)) {
3466
3470
  throw new SignedObjectSchemaError(`${path} has unknown field ${key}`);
3467
3471
  }
3468
3472
  }
3469
3473
  }
3470
- function requiredValue2(object3, key, path) {
3471
- if (!hasOwn2(object3, key)) {
3474
+ function requiredValue2(object4, key, path) {
3475
+ if (!hasOwn2(object4, key)) {
3472
3476
  throw new SignedObjectSchemaError(`${path}.${key} is required`);
3473
3477
  }
3474
- return object3[key];
3478
+ return object4[key];
3475
3479
  }
3476
- function requiredString2(object3, key, path) {
3477
- return requireStringType(requiredValue2(object3, key, path), `${path}.${key}`);
3480
+ function requiredString2(object4, key, path) {
3481
+ return requireStringType(requiredValue2(object4, key, path), `${path}.${key}`);
3478
3482
  }
3479
- function optionalString(object3, key, path) {
3480
- if (!hasOwn2(object3, key)) {
3483
+ function optionalString(object4, key, path) {
3484
+ if (!hasOwn2(object4, key)) {
3481
3485
  return;
3482
3486
  }
3483
- requireStringType(requiredValue2(object3, key, path), `${path}.${key}`);
3487
+ requireStringType(requiredValue2(object4, key, path), `${path}.${key}`);
3484
3488
  }
3485
3489
  function requireStringType(value, path) {
3486
3490
  if (typeof value !== "string" || value.length === 0) {
@@ -3488,16 +3492,16 @@ function requireStringType(value, path) {
3488
3492
  }
3489
3493
  return value;
3490
3494
  }
3491
- function optionalBoolean(object3, key, path) {
3492
- if (!hasOwn2(object3, key)) {
3495
+ function optionalBoolean(object4, key, path) {
3496
+ if (!hasOwn2(object4, key)) {
3493
3497
  return;
3494
3498
  }
3495
- if (typeof requiredValue2(object3, key, path) !== "boolean") {
3499
+ if (typeof requiredValue2(object4, key, path) !== "boolean") {
3496
3500
  throw new SignedObjectSchemaError(`${path}.${key} must be a boolean`);
3497
3501
  }
3498
3502
  }
3499
- function requiredInteger(object3, key, path, minimum) {
3500
- const value = requiredValue2(object3, key, path);
3503
+ function requiredInteger(object4, key, path, minimum) {
3504
+ const value = requiredValue2(object4, key, path);
3501
3505
  if (typeof value !== "number" || !Number.isSafeInteger(value) || value < minimum) {
3502
3506
  throw new SignedObjectSchemaError(
3503
3507
  `${path}.${key} must be an integer >= ${minimum}`
@@ -3505,8 +3509,8 @@ function requiredInteger(object3, key, path, minimum) {
3505
3509
  }
3506
3510
  return value;
3507
3511
  }
3508
- function requiredArray2(object3, key, path, minimum) {
3509
- const value = requiredValue2(object3, key, path);
3512
+ function requiredArray2(object4, key, path, minimum) {
3513
+ const value = requiredValue2(object4, key, path);
3510
3514
  if (!Array.isArray(value) || value.length < minimum) {
3511
3515
  throw new SignedObjectSchemaError(
3512
3516
  `${path}.${key} must be an array with at least ${minimum} item(s)`
@@ -3514,22 +3518,22 @@ function requiredArray2(object3, key, path, minimum) {
3514
3518
  }
3515
3519
  return value;
3516
3520
  }
3517
- function requiredStringArray(object3, key, path, check) {
3518
- const values = requiredArray2(object3, key, path, 0);
3521
+ function requiredStringArray(object4, key, path, check) {
3522
+ const values = requiredArray2(object4, key, path, 0);
3519
3523
  for (let index = 0; index < values.length; index++) {
3520
3524
  const itemPath = `${path}.${key}[${index}]`;
3521
3525
  const value = requireStringType(values[index], itemPath);
3522
3526
  check?.(value, itemPath);
3523
3527
  }
3524
3528
  }
3525
- function requiredDateString(object3, key, path) {
3526
- assertRfc3339(requiredString2(object3, key, path), `${path}.${key}`);
3529
+ function requiredDateString(object4, key, path) {
3530
+ assertRfc3339(requiredString2(object4, key, path), `${path}.${key}`);
3527
3531
  }
3528
- function optionalDateString(object3, key, path) {
3529
- if (!hasOwn2(object3, key)) {
3532
+ function optionalDateString(object4, key, path) {
3533
+ if (!hasOwn2(object4, key)) {
3530
3534
  return;
3531
3535
  }
3532
- assertRfc3339(requiredString2(object3, key, path), `${path}.${key}`);
3536
+ assertRfc3339(requiredString2(object4, key, path), `${path}.${key}`);
3533
3537
  }
3534
3538
  function assertRfc3339(value, path) {
3535
3539
  const match = value.match(
@@ -3561,8 +3565,8 @@ function expectOneOf(actual, allowed, path) {
3561
3565
  }
3562
3566
  throw new SignedObjectSchemaError(`${path} has unsupported value ${actual}`);
3563
3567
  }
3564
- function hasOwn2(object3, key) {
3565
- return objectHasOwn3(object3, key);
3568
+ function hasOwn2(object4, key) {
3569
+ return objectHasOwn3(object4, key);
3566
3570
  }
3567
3571
  function assertSupportedSignatureSuite(suite) {
3568
3572
  if (suite !== ED25519_JCS_SIGNATURE_SUITE && suite !== EIP191_JCS_SIGNATURE_SUITE) {
@@ -3789,9 +3793,9 @@ function expectObject2(input, path, code3) {
3789
3793
  );
3790
3794
  }
3791
3795
  }
3792
- function assertExactKeys3(object3, allowed, path) {
3796
+ function assertExactKeys3(object4, allowed, path) {
3793
3797
  const allowedSet = new Set(allowed);
3794
- for (const key of Object.keys(object3)) {
3798
+ for (const key of Object.keys(object4)) {
3795
3799
  if (!allowedSet.has(key)) {
3796
3800
  throw new PolicyAuthoringError(
3797
3801
  "policy-authoring-unknown-key",
@@ -3800,17 +3804,17 @@ function assertExactKeys3(object3, allowed, path) {
3800
3804
  }
3801
3805
  }
3802
3806
  }
3803
- function requiredValue3(object3, key, path) {
3804
- if (!hasOwn3(object3, key)) {
3807
+ function requiredValue3(object4, key, path) {
3808
+ if (!hasOwn3(object4, key)) {
3805
3809
  throw new PolicyAuthoringError(
3806
3810
  "policy-authoring-malformed",
3807
3811
  `${path}.${key} is required`
3808
3812
  );
3809
3813
  }
3810
- return object3[key];
3814
+ return object4[key];
3811
3815
  }
3812
- function requiredString3(object3, key, path) {
3813
- const value = requiredValue3(object3, key, path);
3816
+ function requiredString3(object4, key, path) {
3817
+ const value = requiredValue3(object4, key, path);
3814
3818
  if (typeof value !== "string" || value.length === 0) {
3815
3819
  throw new PolicyAuthoringError(
3816
3820
  "policy-authoring-malformed",
@@ -3819,11 +3823,11 @@ function requiredString3(object3, key, path) {
3819
3823
  }
3820
3824
  return value;
3821
3825
  }
3822
- function fieldString(object3, key, path, code3) {
3823
- if (!hasOwn3(object3, key)) {
3826
+ function fieldString(object4, key, path, code3) {
3827
+ if (!hasOwn3(object4, key)) {
3824
3828
  throw new PolicyAuthoringError(code3, `${path}.${key} is required`);
3825
3829
  }
3826
- const value = object3[key];
3830
+ const value = object4[key];
3827
3831
  if (typeof value !== "string" || value.length === 0) {
3828
3832
  throw new PolicyAuthoringError(
3829
3833
  code3,
@@ -3861,8 +3865,8 @@ function parseStrictRfc3339(value, path) {
3861
3865
  var objectHasOwn4 = Object.hasOwn ?? Object.prototype.hasOwnProperty.call.bind(
3862
3866
  Object.prototype.hasOwnProperty
3863
3867
  );
3864
- function hasOwn3(object3, key) {
3865
- return objectHasOwn4(object3, key);
3868
+ function hasOwn3(object4, key) {
3869
+ return objectHasOwn4(object4, key);
3866
3870
  }
3867
3871
 
3868
3872
  // src/policy/unified.ts
@@ -3889,7 +3893,8 @@ var MAX_LEGACY_ENVELOPE_EXPIRES_AT = "2026-12-29T00:00:00Z";
3889
3893
  var LAST_V2_READ_AT = "2027-01-05T00:00:00Z";
3890
3894
  async function requestPolicyChallengeV3(input) {
3891
3895
  const fetchFn = input.fetch ?? globalThis.fetch.bind(globalThis);
3892
- const response = await fetchFn(new URL("/share/v3/policy/challenges", input.nodeOrigin), {
3896
+ const policyRuntimePath = policyRuntimeBasePath(input.policyRuntimePath);
3897
+ const response = await fetchFn(new URL(`${policyRuntimePath}/challenges`, input.nodeOrigin), {
3893
3898
  method: "POST",
3894
3899
  redirect: "error",
3895
3900
  signal: input.signal,
@@ -3902,6 +3907,13 @@ async function requestPolicyChallengeV3(input) {
3902
3907
  throw new Error("policy challenge binding is invalid");
3903
3908
  return value;
3904
3909
  }
3910
+ function policyRuntimeBasePath(value) {
3911
+ const path = value ?? "/policy/v3";
3912
+ if (!/^\/policy(?:\/[a-z0-9-]+)*$/.test(path)) {
3913
+ throw new Error("policy runtime path is invalid");
3914
+ }
3915
+ return path;
3916
+ }
3905
3917
  function compactAttenuationForPolicyCapabilities(input) {
3906
3918
  const attenuation = {};
3907
3919
  for (const raw of input) {
@@ -3947,7 +3959,7 @@ function verifyPolicyRootStatusCheckpointV3(input) {
3947
3959
  }
3948
3960
  async function getPolicyRootStatusV3(input) {
3949
3961
  const fetchFn = input.fetch ?? globalThis.fetch.bind(globalThis);
3950
- const response = await fetchFn(new URL(`/share/v3/policy/status/${encodeURIComponent(input.rootCid)}`, input.nodeOrigin), {
3962
+ const response = await fetchFn(new URL(`/policy/v3/status/${encodeURIComponent(input.rootCid)}`, input.nodeOrigin), {
3951
3963
  method: "GET",
3952
3964
  redirect: "error",
3953
3965
  headers: { accept: "application/json" }
@@ -4006,7 +4018,7 @@ async function renewPolicyRootStatusV3(input) {
4006
4018
  };
4007
4019
  const signature = await input.sign((0, import_sha256.sha256)(new TextEncoder().encode(ROOT_STATUS_RENEWAL_V1_DOMAIN + jcsCanonicalize(unsigned))));
4008
4020
  if (signature.length !== 64) throw new Error("policy root renewal signature must be Ed25519");
4009
- const response = await fetchFn(new URL("/share/v3/policy/status", input.nodeOrigin), {
4021
+ const response = await fetchFn(new URL("/policy/v3/status", input.nodeOrigin), {
4010
4022
  method: "POST",
4011
4023
  redirect: "error",
4012
4024
  headers: { accept: "application/json", "content-type": "application/json" },
@@ -4261,6 +4273,133 @@ function contentSourceDigestHex(input) {
4261
4273
  )
4262
4274
  );
4263
4275
  }
4276
+ function exactObject(value, keys, label) {
4277
+ if (value === null || typeof value !== "object" || Array.isArray(value)) {
4278
+ throw new Error(`${label} is invalid`);
4279
+ }
4280
+ const record2 = value;
4281
+ if (Object.keys(record2).length !== keys.length || keys.some((key) => !Object.prototype.hasOwnProperty.call(record2, key))) {
4282
+ throw new Error(`${label} is invalid`);
4283
+ }
4284
+ return record2;
4285
+ }
4286
+ function didKeyEd25519PublicKey(value) {
4287
+ const principal = value.split("#", 1)[0];
4288
+ if (!principal.startsWith("did:key:")) {
4289
+ throw new Error("policy enforcer binding signer is invalid");
4290
+ }
4291
+ const material = base58btc.decode(principal.slice("did:key:".length));
4292
+ if (material.length !== 34 || material[0] !== 237 || material[1] !== 1) {
4293
+ throw new Error("policy enforcer binding signer is invalid");
4294
+ }
4295
+ return material.slice(2);
4296
+ }
4297
+ async function registerPolicyV3(input) {
4298
+ const fetchFn = input.fetch ?? globalThis.fetch.bind(globalThis);
4299
+ const rootExpiresAt = new Date(input.rootExpiresAt);
4300
+ const canonicalRootExpiresAt = new Date(
4301
+ Math.floor(rootExpiresAt.getTime() / 1e3) * 1e3
4302
+ ).toISOString().replace(/\.000Z$/, "Z");
4303
+ if (!Number.isFinite(rootExpiresAt.getTime()) || canonicalRootExpiresAt !== input.rootExpiresAt || rootExpiresAt.getTime() <= Date.now()) {
4304
+ throw new Error("policy root expiry is invalid");
4305
+ }
4306
+ const bindingResponse = await fetchFn(
4307
+ new URL("/policy/v3/enforcer-bindings", input.nodeOrigin),
4308
+ {
4309
+ method: "POST",
4310
+ redirect: "error",
4311
+ signal: input.signal,
4312
+ headers: { accept: "application/json", "content-type": "application/json" },
4313
+ body: JSON.stringify({
4314
+ rootExpiresAt: input.rootExpiresAt,
4315
+ enforcerDid: input.enforcerDid
4316
+ })
4317
+ }
4318
+ );
4319
+ if (!bindingResponse.ok) {
4320
+ throw new Error(`policy enforcer binding rejected (${bindingResponse.status})`);
4321
+ }
4322
+ const binding = exactObject(
4323
+ await bindingResponse.json(),
4324
+ [
4325
+ "schema",
4326
+ "enforcerDid",
4327
+ "nodeAudience",
4328
+ "attestationBindingDigestHex",
4329
+ "issuedAt",
4330
+ "expiresAt",
4331
+ "signature"
4332
+ ],
4333
+ "policy enforcer binding"
4334
+ );
4335
+ const signature = exactObject(
4336
+ binding.signature,
4337
+ ["suite", "signerDid", "value"],
4338
+ "policy enforcer binding signature"
4339
+ );
4340
+ const expectedBindingDigestHex = hex(
4341
+ (0, import_sha256.sha256)(
4342
+ new TextEncoder().encode(
4343
+ jcsCanonicalize({
4344
+ enforcerDid: input.enforcerDid,
4345
+ nodeAudience: input.expectedNodeAudience
4346
+ })
4347
+ )
4348
+ )
4349
+ );
4350
+ if (binding.schema !== ATTESTED_ENFORCER_BINDING_V2_SCHEMA || binding.enforcerDid !== input.enforcerDid || binding.nodeAudience !== input.expectedNodeAudience || binding.attestationBindingDigestHex !== expectedBindingDigestHex || binding.expiresAt !== input.rootExpiresAt || typeof binding.issuedAt !== "string" || Date.parse(binding.issuedAt) > Date.now() || signature.suite !== "Ed25519" || signature.signerDid !== input.expectedNodeAudience || typeof signature.value !== "string") {
4351
+ throw new Error("policy enforcer binding is invalid");
4352
+ }
4353
+ const { signature: _signature, ...unsignedBinding } = binding;
4354
+ const signedBinding = (0, import_sha256.sha256)(
4355
+ new TextEncoder().encode(
4356
+ `xyz.tinycloud.policy/AttestedEnforcerBinding/v2\0${jcsCanonicalize(unsignedBinding)}`
4357
+ )
4358
+ );
4359
+ if (!import_ed255193.ed25519.verify(
4360
+ decodeBase64Url2(signature.value),
4361
+ signedBinding,
4362
+ didKeyEd25519PublicKey(input.expectedNodeAudience),
4363
+ { zip215: false }
4364
+ )) {
4365
+ throw new Error("policy enforcer binding signature is invalid");
4366
+ }
4367
+ const response = await fetchFn(
4368
+ new URL("/policy/v3/policies", input.nodeOrigin),
4369
+ {
4370
+ method: "POST",
4371
+ redirect: "error",
4372
+ signal: input.signal,
4373
+ headers: { accept: "application/json", "content-type": "application/json" },
4374
+ body: JSON.stringify({
4375
+ policyCid: input.policyCid,
4376
+ policy: input.policy,
4377
+ policyRoot: input.policyRoot.authorization.replace(/^Bearer\s+/i, ""),
4378
+ enforcementRoot: input.enforcementRoot.authorization.replace(/^Bearer\s+/i, ""),
4379
+ contentSourceDigestHex: input.contentSourceDigestHex,
4380
+ nativeProjectionHashHex: input.nativeProjectionHashHex,
4381
+ attestedEnforcerBinding: binding
4382
+ })
4383
+ }
4384
+ );
4385
+ if (!response.ok) {
4386
+ throw new Error(`policy registration rejected (${response.status})`);
4387
+ }
4388
+ const receipt = exactObject(
4389
+ await response.json(),
4390
+ ["policyCid", "policyRootCid", "enforcementRootCid"],
4391
+ "policy registration response"
4392
+ );
4393
+ if (receipt.policyCid !== input.policyCid || receipt.policyRootCid !== input.policyRoot.cid || receipt.enforcementRootCid !== input.enforcementRoot.cid) {
4394
+ throw new Error("policy registration response binding is invalid");
4395
+ }
4396
+ return {
4397
+ policyCid: input.policyCid,
4398
+ policyRootCid: input.policyRoot.cid,
4399
+ enforcementRootCid: input.enforcementRoot.cid,
4400
+ attestedEnforcerBinding: binding
4401
+ };
4402
+ }
4264
4403
  function policyDigestHex(policy) {
4265
4404
  const canonicalPolicy = {
4266
4405
  ...policy,
@@ -4877,6 +5016,7 @@ async function admitPolicyCredentialV3(input) {
4877
5016
  const fetchFn = input.fetch ?? globalThis.fetch.bind(globalThis);
4878
5017
  const challenge = await requestPolicyChallengeV3({
4879
5018
  nodeOrigin,
5019
+ policyRuntimePath: input.policyRuntimePath,
4880
5020
  policyCid: input.policyCid,
4881
5021
  recipientDid: input.credential.holderDid,
4882
5022
  requestedCapabilities: input.requestedCapabilities,
@@ -4889,7 +5029,7 @@ async function admitPolicyCredentialV3(input) {
4889
5029
  challenge
4890
5030
  });
4891
5031
  const response = await fetchFn(
4892
- new URL("/share/v3/policy/delegations", nodeOrigin),
5032
+ new URL(`${policyRuntimeBasePath2(input.policyRuntimePath)}/delegations`, nodeOrigin),
4893
5033
  {
4894
5034
  method: "POST",
4895
5035
  redirect: "error",
@@ -4934,6 +5074,7 @@ async function admitPolicyCredentialV4(input) {
4934
5074
  const fetchFn = input.fetch ?? globalThis.fetch.bind(globalThis);
4935
5075
  const challenge = await requestPolicyChallengeV3({
4936
5076
  nodeOrigin,
5077
+ policyRuntimePath: input.policyRuntimePath,
4937
5078
  policyCid: input.policyCid,
4938
5079
  recipientDid: input.credential.holderDid,
4939
5080
  requestedCapabilities: input.requestedCapabilities,
@@ -4945,7 +5086,7 @@ async function admitPolicyCredentialV4(input) {
4945
5086
  policy,
4946
5087
  challenge
4947
5088
  });
4948
- const response = await fetchFn(new URL("/share/v3/policy/delegations", nodeOrigin), {
5089
+ const response = await fetchFn(new URL(`${policyRuntimeBasePath2(input.policyRuntimePath)}/delegations`, nodeOrigin), {
4949
5090
  method: "POST",
4950
5091
  redirect: "error",
4951
5092
  signal: input.signal,
@@ -4972,8 +5113,22 @@ async function admitPolicyCredentialV4(input) {
4972
5113
  enforcerDid: input.expectedEnforcerDid
4973
5114
  });
4974
5115
  if (session.cid !== value.sessionCid || session.aud !== input.credential.holderDid || session.fact.policyCid !== input.policyCid || session.fact.recipientDid !== input.credential.holderDid || session.fact.policyDelegationCid !== input.policyRootCid || session.fact.enforcementDelegationCid !== input.enforcementRootCid || jcsCanonicalize(session.att) !== jcsCanonicalize(expectedAttenuation)) throw new Error("policy delegation signed binding is invalid");
5116
+ const importResponse = await fetchFn(new URL("/delegate", nodeOrigin), {
5117
+ method: "POST",
5118
+ redirect: "error",
5119
+ signal: input.signal,
5120
+ headers: { Authorization: session.authorization }
5121
+ });
5122
+ if (!importResponse.ok) throw new Error(`delegation import rejected (${importResponse.status})`);
4975
5123
  input.signal?.throwIfAborted();
4976
- return Object.freeze({ challenge, presentation, session });
5124
+ return Object.freeze({ challenge, presentation, session, delegationImported: true });
5125
+ }
5126
+ function policyRuntimeBasePath2(value) {
5127
+ const path = value ?? "/policy/v3";
5128
+ if (!/^\/policy(?:\/[a-z0-9-]+)*$/.test(path)) {
5129
+ throw new Error("policy runtime path is invalid");
5130
+ }
5131
+ return path;
4977
5132
  }
4978
5133
 
4979
5134
  // src/requester/index.ts
@@ -8381,13 +8536,13 @@ function canonicalizeRecapCaveats(caveats) {
8381
8536
  }
8382
8537
  if (Array.isArray(value)) return `[${value.map(canonicalize).join(",")}]`;
8383
8538
  if (typeof value === "object") {
8384
- const object3 = value;
8385
- const prototype = Object.getPrototypeOf(object3);
8539
+ const object4 = value;
8540
+ const prototype = Object.getPrototypeOf(object4);
8386
8541
  if (prototype !== Object.prototype && prototype !== null) {
8387
8542
  throw new Error("ReCap caveats must contain only JSON values.");
8388
8543
  }
8389
- return `{${Object.keys(object3).sort().map(
8390
- (key) => `${JSON.stringify(key)}:${canonicalize(object3[key])}`
8544
+ return `{${Object.keys(object4).sort().map(
8545
+ (key) => `${JSON.stringify(key)}:${canonicalize(object4[key])}`
8391
8546
  ).join(",")}}`;
8392
8547
  }
8393
8548
  throw new Error("ReCap caveats must contain only JSON values.");
@@ -8518,8 +8673,8 @@ function canonicalJson(value) {
8518
8673
  }
8519
8674
  if (Array.isArray(value)) return `[${value.map(canonicalJson).join(",")}]`;
8520
8675
  if (typeof value === "object") {
8521
- const object3 = value;
8522
- return `{${Object.keys(object3).sort().map((key) => `${JSON.stringify(key)}:${canonicalJson(object3[key])}`).join(",")}}`;
8676
+ const object4 = value;
8677
+ return `{${Object.keys(object4).sort().map((key) => `${JSON.stringify(key)}:${canonicalJson(object4[key])}`).join(",")}}`;
8523
8678
  }
8524
8679
  throw new ShareEnvelopeError("invalid-envelope", "unsupported JSON value");
8525
8680
  }
@@ -9701,8 +9856,8 @@ function canonicalJsonForProof(value) {
9701
9856
  }
9702
9857
  if (Array.isArray(value)) return `[${value.map(canonicalJsonForProof).join(",")}]`;
9703
9858
  if (typeof value === "object") {
9704
- const object3 = value;
9705
- return `{${Object.keys(object3).sort().map((key) => `${JSON.stringify(key)}:${canonicalJsonForProof(object3[key])}`).join(",")}}`;
9859
+ const object4 = value;
9860
+ return `{${Object.keys(object4).sort().map((key) => `${JSON.stringify(key)}:${canonicalJsonForProof(object4[key])}`).join(",")}}`;
9706
9861
  }
9707
9862
  throw new ShareAccessError("SHARE_SESSION_INVALID");
9708
9863
  }
@@ -10411,12 +10566,12 @@ var ShareRecipientClient = class {
10411
10566
  this.assertDetachedProof(request.proof);
10412
10567
  }
10413
10568
  parseSessionCapability(value) {
10414
- const object3 = this.requireObject(value, "session capability");
10415
- if (typeof object3.spaceId !== "string") throw new ShareAccessError("SHARE_SESSION_INVALID", "session capability space is invalid");
10416
- if (!Array.isArray(object3.actions) || object3.actions.some((action) => !["read", "list", "edit"].includes(action))) throw new ShareAccessError("SHARE_SESSION_INVALID", "session capability actions are invalid");
10417
- const resource = this.requireObject(object3.resource, "session capability resource");
10569
+ const object4 = this.requireObject(value, "session capability");
10570
+ if (typeof object4.spaceId !== "string") throw new ShareAccessError("SHARE_SESSION_INVALID", "session capability space is invalid");
10571
+ if (!Array.isArray(object4.actions) || object4.actions.some((action) => !["read", "list", "edit"].includes(action))) throw new ShareAccessError("SHARE_SESSION_INVALID", "session capability actions are invalid");
10572
+ const resource = this.requireObject(object4.resource, "session capability resource");
10418
10573
  if (resource.kind !== "exact" && resource.kind !== "prefix" || typeof resource.path !== "string") throw new ShareAccessError("SHARE_SESSION_INVALID", "session capability resource is invalid");
10419
- return { spaceId: object3.spaceId, actions: [...new Set(object3.actions)], resource: { kind: resource.kind, path: resource.path } };
10574
+ return { spaceId: object4.spaceId, actions: [...new Set(object4.actions)], resource: { kind: resource.kind, path: resource.path } };
10420
10575
  }
10421
10576
  assertProvidedPolicySession(session, envelope) {
10422
10577
  const sessionExpiry = dateValue(session.expiresAt);
@@ -12157,6 +12312,68 @@ function shareDeliveryTrustedKid(publicKey) {
12157
12312
  return `${did}#${did.slice("did:key:".length)}`;
12158
12313
  }
12159
12314
 
12315
+ // src/delegations/share-delivery-v3.ts
12316
+ var import_ed2551910 = require("@noble/curves/ed25519");
12317
+ var import_sha2567 = require("@noble/hashes/sha256");
12318
+ var CREDENTIAL_INVITATION_REQUEST_DOMAIN = "xyz.tinycloud.credentials/invitation-request/v1\0";
12319
+ var DELIVERY_ADMISSION_DOMAIN = "xyz.tinycloud.policy/delivery-admission/v0\0";
12320
+ var REQUEST_KEYS = ["schema", "policyId", "recipient", "resource", "credentialType", "returnLink", "envelopeRef", "audience", "issuedAt", "expiresAt", "nonce"];
12321
+ var ADMISSION_KEYS = ["schema", "policyId", "ownerDid", "recipient", "resource", "actions", "credentialType", "returnLink", "envelopeRef", "senderKeyDid", "audience", "issuedAt", "expiresAt", "nonce", "signature"];
12322
+ function exactObject2(value, keys, label) {
12323
+ if (typeof value !== "object" || value === null || Array.isArray(value)) throw new Error(`${label} is invalid`);
12324
+ const record2 = value;
12325
+ if (Object.keys(record2).length !== keys.length || keys.some((key) => !Object.prototype.hasOwnProperty.call(record2, key))) throw new Error(`${label} has unknown or missing fields`);
12326
+ return record2;
12327
+ }
12328
+ function decodeBase64Url3(value) {
12329
+ if (typeof value !== "string" || !/^[A-Za-z0-9_-]+$/.test(value)) throw new Error("share delivery value is not canonical base64url");
12330
+ if (typeof atob === "function") {
12331
+ const padded = value.replace(/-/g, "+").replace(/_/g, "/") + "=".repeat((4 - value.length % 4) % 4);
12332
+ return Uint8Array.from(atob(padded), (character) => character.charCodeAt(0));
12333
+ }
12334
+ if (typeof Buffer !== "undefined") return new Uint8Array(Buffer.from(value, "base64url"));
12335
+ throw new Error("base64url decoding is unavailable");
12336
+ }
12337
+ function object3(value, label) {
12338
+ if (typeof value !== "object" || value === null || Array.isArray(value)) throw new Error(`${label} is invalid`);
12339
+ return value;
12340
+ }
12341
+ function didKeyBytes2(did) {
12342
+ if (!did.startsWith("did:key:z") || /[#/?]/.test(did.slice("did:key:".length))) throw new Error("v3 delivery admission signer is invalid");
12343
+ const decoded = base58btc.decode(did.slice("did:key:".length));
12344
+ if (decoded.length !== 34 || decoded[0] !== 237 || decoded[1] !== 1) throw new Error("v3 delivery admission signer is invalid");
12345
+ return decoded.slice(2);
12346
+ }
12347
+ function validateShareDeliveryAuthorizationV3Bytes(bytes2, expected) {
12348
+ let parsed;
12349
+ try {
12350
+ parsed = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes2));
12351
+ } catch {
12352
+ throw new Error("v3 share delivery response is not valid UTF-8 JSON");
12353
+ }
12354
+ const root = exactObject2(parsed, ["request", "admission"], "v3 share delivery response");
12355
+ const request = exactObject2(root.request, REQUEST_KEYS, "credential invitation request");
12356
+ const admission = exactObject2(root.admission, ADMISSION_KEYS, "delivery admission");
12357
+ const signature = exactObject2(admission.signature, ["suite", "signerDid", "value"], "delivery admission signature");
12358
+ const envelope = object3(expected.request.envelope, "v3 share envelope");
12359
+ const policy = object3(envelope.policy, "v3 share policy");
12360
+ const requirement = object3(policy.credentialRequirement, "v3 credential requirement");
12361
+ const credentialType = object3(requirement.credentialType, "v3 credential type");
12362
+ const contentSource = object3(envelope.contentSource, "v3 content source");
12363
+ const envelopeSignature = object3(envelope.signature, "v3 envelope signature");
12364
+ const target = object3(envelope.target, "v3 target");
12365
+ const fields = ["policyId", "recipient", "resource", "credentialType", "returnLink", "envelopeRef", "audience", "issuedAt", "expiresAt", "nonce"];
12366
+ if (request.schema !== "xyz.tinycloud.credentials/invitation-request/v1" || admission.schema !== "xyz.tinycloud.policy/delivery-admission/v0" || fields.some((field) => request[field] !== admission[field]) || request.policyId !== envelope.policyCid || request.recipient !== expected.request.recipientEmail || request.resource !== contentSource.kvResource || request.credentialType !== credentialType.id || request.credentialType !== "opencredentials.email/v1" || request.returnLink !== expected.request.shareUrl || request.envelopeRef !== expected.request.shareCid || request.audience !== expected.credentialsAudience || request.expiresAt !== expected.request.expiresAt || request.nonce !== expected.request.jti || admission.ownerDid !== envelopeSignature.signerDid || admission.senderKeyDid !== expected.senderKeyDid || canonicalizeSignedObjectUnsigned(admission.actions) !== canonicalizeSignedObjectUnsigned(["tinycloud.kv/get"]) || signature.suite !== "eddsa-ed25519-sha256-jcs-v1" || signature.signerDid !== target.nodeAudience) throw new Error("v3 share delivery authorization is not bound to the submitted request");
12367
+ const issuedAt = Date.parse(String(request.issuedAt));
12368
+ const expiresAt = Date.parse(String(request.expiresAt));
12369
+ if (!Number.isFinite(issuedAt) || !Number.isFinite(expiresAt) || expiresAt <= issuedAt || expiresAt - issuedAt > 15 * 6e4) throw new Error("v3 share delivery authorization time is invalid");
12370
+ const admissionSignature = decodeBase64Url3(signature.value);
12371
+ const { signature: _signature, ...unsignedAdmission } = admission;
12372
+ const digest4 = (0, import_sha2567.sha256)(new TextEncoder().encode(`${DELIVERY_ADMISSION_DOMAIN}${canonicalizeSignedObjectUnsigned(unsignedAdmission)}`));
12373
+ if (admissionSignature.length !== 64 || !import_ed2551910.ed25519.verify(admissionSignature, digest4, didKeyBytes2(String(signature.signerDid)))) throw new Error("v3 share delivery admission signature is invalid");
12374
+ return { request, admission };
12375
+ }
12376
+
12160
12377
  // src/delegations/sender-share-store.ts
12161
12378
  var MemorySenderShareRecordStorage = class {
12162
12379
  constructor() {
@@ -14877,8 +15094,8 @@ function stableJson(value) {
14877
15094
  if (Array.isArray(value)) {
14878
15095
  return `[${value.map(stableJson).join(",")}]`;
14879
15096
  }
14880
- const object3 = value;
14881
- return `{${Object.keys(object3).sort().map((key) => `${JSON.stringify(key)}:${stableJson(object3[key])}`).join(",")}}`;
15097
+ const object4 = value;
15098
+ return `{${Object.keys(object4).sort().map((key) => `${JSON.stringify(key)}:${stableJson(object4[key])}`).join(",")}}`;
14882
15099
  }
14883
15100
  function indexedDelegationFromRow(row) {
14884
15101
  const [
@@ -17778,7 +17995,7 @@ function portForProtocol(protocol) {
17778
17995
  }
17779
17996
 
17780
17997
  // src/location.ts
17781
- var import_ed2551910 = require("@noble/curves/ed25519");
17998
+ var import_ed2551911 = require("@noble/curves/ed25519");
17782
17999
  var import_viem5 = require("viem");
17783
18000
  var DEFAULT_TINYCLOUD_LOCATION_REGISTRY_URL = "https://registry.tinycloud.xyz";
17784
18001
  var DEFAULT_TINYCLOUD_FALLBACK_HOST = "https://node.tinycloud.xyz";
@@ -18344,13 +18561,13 @@ async function verifyPkhSignature(did, payload, signature) {
18344
18561
  }
18345
18562
  function verifyDidKeySignature(did, payload, signature) {
18346
18563
  const publicKey = ed25519PublicKeyFromDidKey2(did);
18347
- const signatureBytes = decodeBase64Url3(signature);
18564
+ const signatureBytes = decodeBase64Url4(signature);
18348
18565
  if (signatureBytes.length !== 64) {
18349
18566
  throw new LocationRecordValidationError(
18350
18567
  "did:key signature must be a base64url Ed25519 signature"
18351
18568
  );
18352
18569
  }
18353
- return import_ed2551910.ed25519.verify(
18570
+ return import_ed2551911.ed25519.verify(
18354
18571
  signatureBytes,
18355
18572
  new TextEncoder().encode(payload),
18356
18573
  publicKey
@@ -18358,7 +18575,7 @@ function verifyDidKeySignature(did, payload, signature) {
18358
18575
  }
18359
18576
  function verifyDidKeyEd25519Signature(did, payload, signature) {
18360
18577
  const publicKey = ed25519PublicKeyFromDidKey2(did);
18361
- return import_ed2551910.ed25519.verify(signature, payload, publicKey);
18578
+ return import_ed2551911.ed25519.verify(signature, payload, publicKey);
18362
18579
  }
18363
18580
  function ed25519PublicKeyFromDidKey2(did) {
18364
18581
  const identifier = did.slice("did:key:".length);
@@ -18397,7 +18614,7 @@ function base64UrlEncode3(bytes2) {
18397
18614
  }
18398
18615
  return output;
18399
18616
  }
18400
- function decodeBase64Url3(value) {
18617
+ function decodeBase64Url4(value) {
18401
18618
  const alphabet2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
18402
18619
  const bytes2 = [];
18403
18620
  let buffer = 0;