@tinycloud/share-sdk 1.0.0-beta.8 → 1.0.0-beta.9

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.d.cts CHANGED
@@ -976,12 +976,21 @@ interface ShareRecipientClientOptions {
976
976
  readonly sign?: (bytes: Uint8Array) => Promise<Uint8Array>;
977
977
  readonly signal?: AbortSignal;
978
978
  readonly onStage?: (stage: "policy-admission" | "delegation-import" | "invocation" | "decryption") => void;
979
- /** Previously admitted and imported ordinary policy delegation (account v3 fast path). */
979
+ /**
980
+ * A previously admitted and imported policy session (S0), optionally with
981
+ * the descendants that re-delegate it, in order, down to this holder.
982
+ */
980
983
  readonly policyAuthorization?: {
981
984
  readonly authorization: string;
982
985
  readonly cid: string;
986
+ readonly descendants?: readonly SharePolicyDelegationLink[];
983
987
  };
984
988
  }
989
+ /** One signed link of a policy delegation chain, as imported into the Node. */
990
+ interface SharePolicyDelegationLink {
991
+ readonly authorization: string;
992
+ readonly cid: string;
993
+ }
985
994
  interface SharePolicySession {
986
995
  readonly sessionId: string;
987
996
  readonly expiresAt: string;
@@ -1124,4 +1133,4 @@ declare function parseNativeShareUrl(value: string): string;
1124
1133
  /** Receive through the public SDK without creating another transport protocol. */
1125
1134
  declare function openNativeShare(sharing: NativeSharingService, link: string): Promise<unknown>;
1126
1135
 
1127
- export { type AddressedOwnerRootInput, type AddressedOwnerRootReceipt, type AddressedPolicyRegistrationInput, type AddressedPolicyRegistrationReceipt, type AddressedPublishAuthority, type AddressedSharePublishOptions, type AddressedShareRequest, type CreateOwnerDelegationParams, CredentialInvitationError, type CredentialInvitationErrorCode, type CredentialInvitationReceipt, type CredentialInvitationResult, DEFAULT_MAX_CONTENT_BLOB_BYTES, DEFAULT_MAX_SEALED_BLOB_BYTES, DEFAULT_SHARE_LIFETIME_MS, type DelegatedShareKey, EncryptedSenderShareHistory, type EncryptedShareHistoryStorage, MAX_CONTENT_BYTES, MemoryEncryptedShareHistoryStorage, MemorySenderShareKeyStorage, MemorySenderShareRecordStorage, MemoryShareCache, NATIVE_SHARE_FRAGMENT_PARAMETER, type NativeShareResult, type NativeSharingService, OWNER_SHARE_REGISTRATION_DOMAIN, type OwnerDelegationPermission, type OwnerDelegationReceipt, type OwnerShareAction, type OwnerShareDecryption, type OwnerShareMatcher, type OwnerSharePolicyRegistration, type OwnerSharePolicyRegistrationReceipt, type OwnerSharePolicyV2, type ParsedAddressedEnvelope, type PreparedAddressedShare, type PublishedShare, type PublishedShareDeliveryMaterial, type PublishedShareMetadata, type RegisterOwnerSharePolicyParams, SHARE_CONTENT_LIMIT, SHARE_PUBLISH_RESULT_VERSION, SHARE_RESULT_VERSION, SHARE_V2_PROTOCOL, type SenderShareKeyStorage, type SenderShareRecord, type SenderShareRecordStorage, type SenderShareRevocationScope, SenderShareStore, type ShareAuthorizationAdapter, type ShareAuthorizationDenied, type ShareAuthorizationMethod, type ShareAuthorizationReady, type ShareAuthorizationRequired, type ShareAuthorizationResult, type ShareAuthorizedContent, type ShareCache, type ShareCacheEntry, type ShareCacheKey, type ShareCacheMetadata, type ShareDeliveryAdapter, type ShareErrorCode, type ShareErrorInfo, type ShareFetchOptions, type ShareHistoryView, type ShareInspection, type ShareMetadata, type ShareNodeTrust, ShareNotifyError, type ShareNotifyInput, type ShareNotifyResult, type ShareNotifyState, type SharePolicyChallenge, type SharePolicyPublishAdapter, type SharePolicyRootRevocation, type SharePolicySession, type SharePresentationMaterial, SharePublishError, type SharePublishErrorCode, type SharePublishOptions, type SharePublishTarget, type ShareReceiveAuthorizationRequired, ShareReceiveError, type ShareReceiveOutcome, type ShareReceiveResult, ShareRecipientClient, type ShareRecipientClientOptions, type ShareRevocationAdapter, type ShareRevocationResult, type ShareTarget, type SignedDelegation, type TargetPublishAdapter, type TargetPublishInput, type TargetPublishOutcome, addressedCredentialRequirement, authorizationMethodForTarget, authorizeShare, canonicalOwnerSharePolicy, canonicalShareFilename, claimShare, computeOwnerShareRegistrationCid, createAddressedAuthorization, createDelegatedShareKey, createNativeShare, createPolicyEnforcementDelegation, createShareV2HolderBindingArtifact, deliverCredentialInvitation, hasUnsafeFilenameCodePoint, historyRecordForPublishedShare, inspectShare, listShares, normalizeShareTarget, notifyShare, openNativeShare, parseAddressedEnvelope, parseNativeShareUrl, prepareAddressedShare, publishAddressedShare, publishPolicyShare, publishTargetShare, receiveShare, recipientMatchesShareRecord, redactPublishedShare, restoreDelegatedShareKey, resumeShareAuthorization, revokeShare, showShare, targetAuthorizationMethod, toShareErrorInfo, validateOwnerSharePolicyRegistration, validateOwnerSharePolicyRegistrationBytes };
1136
+ export { type AddressedOwnerRootInput, type AddressedOwnerRootReceipt, type AddressedPolicyRegistrationInput, type AddressedPolicyRegistrationReceipt, type AddressedPublishAuthority, type AddressedSharePublishOptions, type AddressedShareRequest, type CreateOwnerDelegationParams, CredentialInvitationError, type CredentialInvitationErrorCode, type CredentialInvitationReceipt, type CredentialInvitationResult, DEFAULT_MAX_CONTENT_BLOB_BYTES, DEFAULT_MAX_SEALED_BLOB_BYTES, DEFAULT_SHARE_LIFETIME_MS, type DelegatedShareKey, EncryptedSenderShareHistory, type EncryptedShareHistoryStorage, MAX_CONTENT_BYTES, MemoryEncryptedShareHistoryStorage, MemorySenderShareKeyStorage, MemorySenderShareRecordStorage, MemoryShareCache, NATIVE_SHARE_FRAGMENT_PARAMETER, type NativeShareResult, type NativeSharingService, OWNER_SHARE_REGISTRATION_DOMAIN, type OwnerDelegationPermission, type OwnerDelegationReceipt, type OwnerShareAction, type OwnerShareDecryption, type OwnerShareMatcher, type OwnerSharePolicyRegistration, type OwnerSharePolicyRegistrationReceipt, type OwnerSharePolicyV2, type ParsedAddressedEnvelope, type PreparedAddressedShare, type PublishedShare, type PublishedShareDeliveryMaterial, type PublishedShareMetadata, type RegisterOwnerSharePolicyParams, SHARE_CONTENT_LIMIT, SHARE_PUBLISH_RESULT_VERSION, SHARE_RESULT_VERSION, SHARE_V2_PROTOCOL, type SenderShareKeyStorage, type SenderShareRecord, type SenderShareRecordStorage, type SenderShareRevocationScope, SenderShareStore, type ShareAuthorizationAdapter, type ShareAuthorizationDenied, type ShareAuthorizationMethod, type ShareAuthorizationReady, type ShareAuthorizationRequired, type ShareAuthorizationResult, type ShareAuthorizedContent, type ShareCache, type ShareCacheEntry, type ShareCacheKey, type ShareCacheMetadata, type ShareDeliveryAdapter, type ShareErrorCode, type ShareErrorInfo, type ShareFetchOptions, type ShareHistoryView, type ShareInspection, type ShareMetadata, type ShareNodeTrust, ShareNotifyError, type ShareNotifyInput, type ShareNotifyResult, type ShareNotifyState, type SharePolicyChallenge, type SharePolicyDelegationLink, type SharePolicyPublishAdapter, type SharePolicyRootRevocation, type SharePolicySession, type SharePresentationMaterial, SharePublishError, type SharePublishErrorCode, type SharePublishOptions, type SharePublishTarget, type ShareReceiveAuthorizationRequired, ShareReceiveError, type ShareReceiveOutcome, type ShareReceiveResult, ShareRecipientClient, type ShareRecipientClientOptions, type ShareRevocationAdapter, type ShareRevocationResult, type ShareTarget, type SignedDelegation, type TargetPublishAdapter, type TargetPublishInput, type TargetPublishOutcome, addressedCredentialRequirement, authorizationMethodForTarget, authorizeShare, canonicalOwnerSharePolicy, canonicalShareFilename, claimShare, computeOwnerShareRegistrationCid, createAddressedAuthorization, createDelegatedShareKey, createNativeShare, createPolicyEnforcementDelegation, createShareV2HolderBindingArtifact, deliverCredentialInvitation, hasUnsafeFilenameCodePoint, historyRecordForPublishedShare, inspectShare, listShares, normalizeShareTarget, notifyShare, openNativeShare, parseAddressedEnvelope, parseNativeShareUrl, prepareAddressedShare, publishAddressedShare, publishPolicyShare, publishTargetShare, receiveShare, recipientMatchesShareRecord, redactPublishedShare, restoreDelegatedShareKey, resumeShareAuthorization, revokeShare, showShare, targetAuthorizationMethod, toShareErrorInfo, validateOwnerSharePolicyRegistration, validateOwnerSharePolicyRegistrationBytes };
package/dist/index.d.ts CHANGED
@@ -976,12 +976,21 @@ interface ShareRecipientClientOptions {
976
976
  readonly sign?: (bytes: Uint8Array) => Promise<Uint8Array>;
977
977
  readonly signal?: AbortSignal;
978
978
  readonly onStage?: (stage: "policy-admission" | "delegation-import" | "invocation" | "decryption") => void;
979
- /** Previously admitted and imported ordinary policy delegation (account v3 fast path). */
979
+ /**
980
+ * A previously admitted and imported policy session (S0), optionally with
981
+ * the descendants that re-delegate it, in order, down to this holder.
982
+ */
980
983
  readonly policyAuthorization?: {
981
984
  readonly authorization: string;
982
985
  readonly cid: string;
986
+ readonly descendants?: readonly SharePolicyDelegationLink[];
983
987
  };
984
988
  }
989
+ /** One signed link of a policy delegation chain, as imported into the Node. */
990
+ interface SharePolicyDelegationLink {
991
+ readonly authorization: string;
992
+ readonly cid: string;
993
+ }
985
994
  interface SharePolicySession {
986
995
  readonly sessionId: string;
987
996
  readonly expiresAt: string;
@@ -1124,4 +1133,4 @@ declare function parseNativeShareUrl(value: string): string;
1124
1133
  /** Receive through the public SDK without creating another transport protocol. */
1125
1134
  declare function openNativeShare(sharing: NativeSharingService, link: string): Promise<unknown>;
1126
1135
 
1127
- export { type AddressedOwnerRootInput, type AddressedOwnerRootReceipt, type AddressedPolicyRegistrationInput, type AddressedPolicyRegistrationReceipt, type AddressedPublishAuthority, type AddressedSharePublishOptions, type AddressedShareRequest, type CreateOwnerDelegationParams, CredentialInvitationError, type CredentialInvitationErrorCode, type CredentialInvitationReceipt, type CredentialInvitationResult, DEFAULT_MAX_CONTENT_BLOB_BYTES, DEFAULT_MAX_SEALED_BLOB_BYTES, DEFAULT_SHARE_LIFETIME_MS, type DelegatedShareKey, EncryptedSenderShareHistory, type EncryptedShareHistoryStorage, MAX_CONTENT_BYTES, MemoryEncryptedShareHistoryStorage, MemorySenderShareKeyStorage, MemorySenderShareRecordStorage, MemoryShareCache, NATIVE_SHARE_FRAGMENT_PARAMETER, type NativeShareResult, type NativeSharingService, OWNER_SHARE_REGISTRATION_DOMAIN, type OwnerDelegationPermission, type OwnerDelegationReceipt, type OwnerShareAction, type OwnerShareDecryption, type OwnerShareMatcher, type OwnerSharePolicyRegistration, type OwnerSharePolicyRegistrationReceipt, type OwnerSharePolicyV2, type ParsedAddressedEnvelope, type PreparedAddressedShare, type PublishedShare, type PublishedShareDeliveryMaterial, type PublishedShareMetadata, type RegisterOwnerSharePolicyParams, SHARE_CONTENT_LIMIT, SHARE_PUBLISH_RESULT_VERSION, SHARE_RESULT_VERSION, SHARE_V2_PROTOCOL, type SenderShareKeyStorage, type SenderShareRecord, type SenderShareRecordStorage, type SenderShareRevocationScope, SenderShareStore, type ShareAuthorizationAdapter, type ShareAuthorizationDenied, type ShareAuthorizationMethod, type ShareAuthorizationReady, type ShareAuthorizationRequired, type ShareAuthorizationResult, type ShareAuthorizedContent, type ShareCache, type ShareCacheEntry, type ShareCacheKey, type ShareCacheMetadata, type ShareDeliveryAdapter, type ShareErrorCode, type ShareErrorInfo, type ShareFetchOptions, type ShareHistoryView, type ShareInspection, type ShareMetadata, type ShareNodeTrust, ShareNotifyError, type ShareNotifyInput, type ShareNotifyResult, type ShareNotifyState, type SharePolicyChallenge, type SharePolicyPublishAdapter, type SharePolicyRootRevocation, type SharePolicySession, type SharePresentationMaterial, SharePublishError, type SharePublishErrorCode, type SharePublishOptions, type SharePublishTarget, type ShareReceiveAuthorizationRequired, ShareReceiveError, type ShareReceiveOutcome, type ShareReceiveResult, ShareRecipientClient, type ShareRecipientClientOptions, type ShareRevocationAdapter, type ShareRevocationResult, type ShareTarget, type SignedDelegation, type TargetPublishAdapter, type TargetPublishInput, type TargetPublishOutcome, addressedCredentialRequirement, authorizationMethodForTarget, authorizeShare, canonicalOwnerSharePolicy, canonicalShareFilename, claimShare, computeOwnerShareRegistrationCid, createAddressedAuthorization, createDelegatedShareKey, createNativeShare, createPolicyEnforcementDelegation, createShareV2HolderBindingArtifact, deliverCredentialInvitation, hasUnsafeFilenameCodePoint, historyRecordForPublishedShare, inspectShare, listShares, normalizeShareTarget, notifyShare, openNativeShare, parseAddressedEnvelope, parseNativeShareUrl, prepareAddressedShare, publishAddressedShare, publishPolicyShare, publishTargetShare, receiveShare, recipientMatchesShareRecord, redactPublishedShare, restoreDelegatedShareKey, resumeShareAuthorization, revokeShare, showShare, targetAuthorizationMethod, toShareErrorInfo, validateOwnerSharePolicyRegistration, validateOwnerSharePolicyRegistrationBytes };
1136
+ export { type AddressedOwnerRootInput, type AddressedOwnerRootReceipt, type AddressedPolicyRegistrationInput, type AddressedPolicyRegistrationReceipt, type AddressedPublishAuthority, type AddressedSharePublishOptions, type AddressedShareRequest, type CreateOwnerDelegationParams, CredentialInvitationError, type CredentialInvitationErrorCode, type CredentialInvitationReceipt, type CredentialInvitationResult, DEFAULT_MAX_CONTENT_BLOB_BYTES, DEFAULT_MAX_SEALED_BLOB_BYTES, DEFAULT_SHARE_LIFETIME_MS, type DelegatedShareKey, EncryptedSenderShareHistory, type EncryptedShareHistoryStorage, MAX_CONTENT_BYTES, MemoryEncryptedShareHistoryStorage, MemorySenderShareKeyStorage, MemorySenderShareRecordStorage, MemoryShareCache, NATIVE_SHARE_FRAGMENT_PARAMETER, type NativeShareResult, type NativeSharingService, OWNER_SHARE_REGISTRATION_DOMAIN, type OwnerDelegationPermission, type OwnerDelegationReceipt, type OwnerShareAction, type OwnerShareDecryption, type OwnerShareMatcher, type OwnerSharePolicyRegistration, type OwnerSharePolicyRegistrationReceipt, type OwnerSharePolicyV2, type ParsedAddressedEnvelope, type PreparedAddressedShare, type PublishedShare, type PublishedShareDeliveryMaterial, type PublishedShareMetadata, type RegisterOwnerSharePolicyParams, SHARE_CONTENT_LIMIT, SHARE_PUBLISH_RESULT_VERSION, SHARE_RESULT_VERSION, SHARE_V2_PROTOCOL, type SenderShareKeyStorage, type SenderShareRecord, type SenderShareRecordStorage, type SenderShareRevocationScope, SenderShareStore, type ShareAuthorizationAdapter, type ShareAuthorizationDenied, type ShareAuthorizationMethod, type ShareAuthorizationReady, type ShareAuthorizationRequired, type ShareAuthorizationResult, type ShareAuthorizedContent, type ShareCache, type ShareCacheEntry, type ShareCacheKey, type ShareCacheMetadata, type ShareDeliveryAdapter, type ShareErrorCode, type ShareErrorInfo, type ShareFetchOptions, type ShareHistoryView, type ShareInspection, type ShareMetadata, type ShareNodeTrust, ShareNotifyError, type ShareNotifyInput, type ShareNotifyResult, type ShareNotifyState, type SharePolicyChallenge, type SharePolicyDelegationLink, type SharePolicyPublishAdapter, type SharePolicyRootRevocation, type SharePolicySession, type SharePresentationMaterial, SharePublishError, type SharePublishErrorCode, type SharePublishOptions, type SharePublishTarget, type ShareReceiveAuthorizationRequired, ShareReceiveError, type ShareReceiveOutcome, type ShareReceiveResult, ShareRecipientClient, type ShareRecipientClientOptions, type ShareRevocationAdapter, type ShareRevocationResult, type ShareTarget, type SignedDelegation, type TargetPublishAdapter, type TargetPublishInput, type TargetPublishOutcome, addressedCredentialRequirement, authorizationMethodForTarget, authorizeShare, canonicalOwnerSharePolicy, canonicalShareFilename, claimShare, computeOwnerShareRegistrationCid, createAddressedAuthorization, createDelegatedShareKey, createNativeShare, createPolicyEnforcementDelegation, createShareV2HolderBindingArtifact, deliverCredentialInvitation, hasUnsafeFilenameCodePoint, historyRecordForPublishedShare, inspectShare, listShares, normalizeShareTarget, notifyShare, openNativeShare, parseAddressedEnvelope, parseNativeShareUrl, prepareAddressedShare, publishAddressedShare, publishPolicyShare, publishTargetShare, receiveShare, recipientMatchesShareRecord, redactPublishedShare, restoreDelegatedShareKey, resumeShareAuthorization, revokeShare, showShare, targetAuthorizationMethod, toShareErrorInfo, validateOwnerSharePolicyRegistration, validateOwnerSharePolicyRegistrationBytes };
package/dist/index.js CHANGED
@@ -6584,6 +6584,7 @@ function targetMatcher(target) {
6584
6584
  function targetKind(target) {
6585
6585
  return target.kind;
6586
6586
  }
6587
+ var OWNER_SHARE_ACTIONS = /* @__PURE__ */ new Set(["tinycloud.kv/get", "tinycloud.kv/list", "tinycloud.kv/metadata", "tinycloud.kv/put"]);
6587
6588
  function assertSafeInput(input) {
6588
6589
  if (!/^[A-Za-z0-9_-]{16,128}$/.test(input.shareId)) throw new TypeError("addressed share id is invalid");
6589
6590
  if (!Number.isSafeInteger(input.byteLength) || input.byteLength < 0 || input.byteLength > SHARE_CONTENT_LIMIT) throw new TypeError("addressed content length is invalid");
@@ -6712,12 +6713,12 @@ function prepareAddressedShare(request) {
6712
6713
  throw new TypeError("addressed filename is invalid");
6713
6714
  }
6714
6715
  if (request.actions.length === 0 || request.policyActions.length === 0) throw new TypeError("addressed share actions are empty");
6716
+ if (request.policyActions.some((action) => !OWNER_SHARE_ACTIONS.has(action))) throw new TypeError("addressed share action is not supported");
6715
6717
  const target = normalizeShareTarget(request.target);
6716
6718
  if (target.kind === "bearer") throw new TypeError("addressed target is required");
6717
6719
  if (target.kind === "recipientDid") return { target };
6718
- if (target.kind === "emailDomain") {
6719
- if (!request.actions.every((action) => action === "read" || action === "list") || !request.policyActions.every((action) => action === "tinycloud.kv/get" || action === "tinycloud.kv/list" || action === "tinycloud.kv/metadata")) throw new TypeError("email-domain shares are view-only");
6720
- if (request.deliveryEmail !== void 0) throw new TypeError("email-domain shares are not emailed");
6720
+ if (target.kind === "emailDomain" && request.deliveryEmail !== void 0 && (request.deliveryEmail !== request.deliveryEmail.toLowerCase() || !request.deliveryEmail.endsWith(`@${target.domain}`))) {
6721
+ throw new TypeError("email-domain delivery address must be a lowercase mailbox at the domain");
6721
6722
  }
6722
6723
  return { target, credentialRequirement: mailboxCredentialCommitment(target) };
6723
6724
  }
@@ -8226,9 +8227,28 @@ function verifyV3PolicyAuthorization(input) {
8226
8227
  const binding = object3(input.envelope.attestedEnforcerBinding, "v3 attested enforcer binding");
8227
8228
  const policy = object3(input.envelope.policy, "v3 policy");
8228
8229
  const now = Math.floor(Date.now() / 1e3);
8229
- if (!legacyShape && !v4Shape || POLICY_SESSION_DIGEST_FACT_KEYS.some((key) => !LOWER_SHA256_HEX.test(fact[key])) || v4Shape && (!LOWER_SHA256_HEX.test(fact.credentialIdAuditDigestHex) || !LOWER_SHA256_HEX.test(fact.presentationJtiAuditDigestHex)) || compact.payload.aud !== input.holderDid || compact.payload.iss.split("#", 1)[0] !== fact.nodeAudience || fact.profile !== "policy-session-ucan/v1" || fact.ownerDid !== policy.ownerDid || fact.policyId !== policy.policyId || fact.policyCid !== input.envelope.policyCid || fact.contentSourceDigestHex !== input.envelope.contentSourceDigestHex || fact.enforcerDid !== binding.enforcerDid || fact.nodeAudience !== binding.nodeAudience || fact.recipientDid !== input.holderDid || fact.policyDelegationCid !== input.envelope.policyRoot.cid || fact.enforcementDelegationCid !== input.envelope.enforcementRoot.cid || typeof fact.remainingRedelegationDepth !== "number" || !Number.isInteger(fact.remainingRedelegationDepth) || fact.remainingRedelegationDepth < 0 || fact.remainingRedelegationDepth > 8 || compact.payload.prf.length !== 2 || compact.payload.prf[0] !== input.envelope.policyRoot.cid || compact.payload.prf[1] !== input.envelope.enforcementRoot.cid || compact.payload.nbf > now || compact.payload.exp <= now || compact.payload.exp - compact.payload.nbf > 60 || canonicalize(compact.payload.att) !== canonicalize(policyAttenuationForV3(input.envelope))) throw new Error("v3 policy delegation signed binding mismatch");
8230
+ if (!legacyShape && !v4Shape || POLICY_SESSION_DIGEST_FACT_KEYS.some((key) => !LOWER_SHA256_HEX.test(fact[key])) || v4Shape && (!LOWER_SHA256_HEX.test(fact.credentialIdAuditDigestHex) || !LOWER_SHA256_HEX.test(fact.presentationJtiAuditDigestHex)) || compact.payload.aud !== input.holderDid || compact.payload.iss.split("#", 1)[0] !== fact.nodeAudience || fact.profile !== "policy-session-ucan/v1" || fact.ownerDid !== policy.ownerDid || fact.policyId !== policy.policyId || fact.policyCid !== input.envelope.policyCid || fact.contentSourceDigestHex !== input.envelope.contentSourceDigestHex || fact.enforcerDid !== binding.enforcerDid || fact.nodeAudience !== binding.nodeAudience || fact.recipientDid !== input.holderDid || fact.policyDelegationCid !== input.envelope.policyRoot.cid || fact.enforcementDelegationCid !== input.envelope.enforcementRoot.cid || typeof fact.remainingRedelegationDepth !== "number" || !Number.isInteger(fact.remainingRedelegationDepth) || fact.remainingRedelegationDepth < 0 || fact.remainingRedelegationDepth > 8 || compact.payload.prf.length !== 2 || compact.payload.prf[0] !== input.envelope.policyRoot.cid || compact.payload.prf[1] !== input.envelope.enforcementRoot.cid || compact.payload.nbf > now || compact.payload.exp <= now || !(compact.payload.exp * 1e3 <= Date.parse(input.envelope.expiry)) || canonicalize(compact.payload.att) !== canonicalize(policyAttenuationForV3(input.envelope))) throw new Error("v3 policy delegation signed binding mismatch");
8230
8231
  return compact;
8231
8232
  }
8233
+ function verifyV3PolicyDescendants(session, descendants, holderDid) {
8234
+ let parent = session;
8235
+ for (const link of descendants) {
8236
+ const child = verifyCompactUcanAuthorization(link.authorization, link.cid);
8237
+ const { remainingRedelegationDepth: parentDepth, ...parentFacts } = parent.payload.fct[0];
8238
+ const { remainingRedelegationDepth: depth, ...facts } = child.payload.fct[0];
8239
+ if (child.payload.iss.split("#", 1)[0] !== parent.payload.aud || child.payload.prf.length !== 1 || child.payload.prf[0] !== parent.cid || child.payload.nbf <= parent.payload.nbf || child.payload.exp >= parent.payload.exp || typeof parentDepth !== "number" || parentDepth <= 0 || depth !== parentDepth - 1 || canonicalize(facts) !== canonicalize(parentFacts) || canonicalize(child.payload.att) !== canonicalize(parent.payload.att)) throw new Error("v3 policy descendant does not extend its parent");
8240
+ parent = child;
8241
+ }
8242
+ const now = Math.floor(Date.now() / 1e3);
8243
+ if (parent.payload.aud !== holderDid) throw new Error("v3 policy delegation chain does not end at this holder");
8244
+ if (parent.payload.nbf > now || parent.payload.exp <= now) throw new Error("v3 policy delegation chain is not currently valid");
8245
+ return parent;
8246
+ }
8247
+ function requestedSessionExpiry(expiry) {
8248
+ const seconds = Math.floor(Date.parse(expiry) / 1e3);
8249
+ if (!Number.isFinite(seconds) || seconds <= Math.floor(Date.now() / 1e3) + 60) return void 0;
8250
+ return new Date(seconds * 1e3).toISOString().replace(/\.\d{3}Z$/, "Z");
8251
+ }
8232
8252
  function hex3(value) {
8233
8253
  return [...value].map((byte) => byte.toString(16).padStart(2, "0")).join("");
8234
8254
  }
@@ -8281,14 +8301,17 @@ var ShareRecipientClient = class {
8281
8301
  this.signer = options.sign;
8282
8302
  if (options.policyAuthorization !== void 0) {
8283
8303
  if (options.envelope.version !== 3) throw new Error("policy delegation fast path requires a v3 envelope");
8284
- const compact = verifyV3PolicyAuthorization({ ...options.policyAuthorization, envelope: options.envelope, holderDid: options.holderDid });
8304
+ const { authorization, cid: cid2, descendants = [] } = options.policyAuthorization;
8305
+ const sessionHolder = descendants.length === 0 ? options.holderDid : verifyCompactUcanAuthorization(authorization, cid2).payload.aud;
8306
+ const compact = verifyV3PolicyAuthorization({ authorization, cid: cid2, envelope: options.envelope, holderDid: sessionHolder });
8307
+ const leaf = verifyV3PolicyDescendants(compact, descendants, options.holderDid);
8285
8308
  const nodeAudience = compact.payload.fct[0].nodeAudience;
8286
- this.v3Authorization = options.policyAuthorization.authorization;
8309
+ this.v3Authorization = leaf.authorization;
8287
8310
  this.v3NodeAudience = nodeAudience;
8288
8311
  this.nativeSigner = options.sign;
8289
8312
  this.session = {
8290
- sessionId: options.policyAuthorization.cid,
8291
- expiresAt: new Date(compact.payload.exp * 1e3).toISOString(),
8313
+ sessionId: leaf.cid,
8314
+ expiresAt: new Date(leaf.payload.exp * 1e3).toISOString(),
8292
8315
  actions: options.envelope.actions,
8293
8316
  resource: options.envelope.resource
8294
8317
  };
@@ -8358,13 +8381,17 @@ var ShareRecipientClient = class {
8358
8381
  throw new Error(accountless ? "v4 ceremony requires a verified credential and requirement" : "v3 ceremony requires a claim");
8359
8382
  }
8360
8383
  this.options.onStage?.("policy-admission");
8361
- const delegationResponse = await this.fetchFn(new URL("/policy/v3/delegations", this.options.nodeOrigin), {
8384
+ const mintBody = accountless ? { policyCid: envelope.policyCid, challengeId: challenge.challengeId, nonce: challenge.nonce, requirement: material.requirement, credential: material.credentialEnvelope, presentation: material.presentation } : { policyCid: envelope.policyCid, challengeId: challenge.challengeId, nonce: challenge.nonce, claim: material.claim, presentation: material.presentation };
8385
+ const mint = (body) => this.fetchFn(new URL("/policy/v3/delegations", this.options.nodeOrigin), {
8362
8386
  method: "POST",
8363
8387
  redirect: "error",
8364
8388
  headers: { accept: "application/json", "content-type": "application/json" },
8365
- body: JSON.stringify(accountless ? { policyCid: envelope.policyCid, challengeId: challenge.challengeId, nonce: challenge.nonce, requirement: material.requirement, credential: material.credentialEnvelope, presentation: material.presentation } : { policyCid: envelope.policyCid, challengeId: challenge.challengeId, nonce: challenge.nonce, claim: material.claim, presentation: material.presentation }),
8389
+ body: JSON.stringify(body),
8366
8390
  ...this.options.signal === void 0 ? {} : { signal: this.options.signal }
8367
8391
  });
8392
+ const requestedExpiresAt = requestedSessionExpiry(envelope.expiry);
8393
+ let delegationResponse = await mint(requestedExpiresAt === void 0 ? mintBody : { ...mintBody, requestedExpiresAt });
8394
+ if (requestedExpiresAt !== void 0 && delegationResponse.status === 422) delegationResponse = await mint(mintBody);
8368
8395
  if (!delegationResponse.ok) throw new Error(`v3 policy delegation rejected (${delegationResponse.status})`);
8369
8396
  const delegation = object3(await delegationResponse.json(), "v3 policy delegation");
8370
8397
  if (delegation.admitted !== true || typeof delegation.sessionCid !== "string" || typeof delegation.authorization !== "string") throw new Error("v3 policy delegation response is not admitted");