@renown/sdk 6.2.3-dev.23 → 6.2.3-dev.25

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.
Files changed (85) hide show
  1. package/dist/{browser-key-storage-e3RQsnLS.js → browser-key-storage-wjSwTnhs.js} +3 -2
  2. package/dist/browser-key-storage-wjSwTnhs.js.map +1 -0
  3. package/dist/{constants-BexAR53F.js → constants-DVOF17NB.js} +1 -1
  4. package/dist/{constants-BexAR53F.js.map → constants-DVOF17NB.js.map} +1 -1
  5. package/dist/crypto.d.ts +4 -3
  6. package/dist/crypto.js +2 -2
  7. package/dist/{index-BLIpkdF7.d.ts → index-CGTiUojp.d.ts} +11 -20
  8. package/dist/index-CGTiUojp.d.ts.map +1 -0
  9. package/dist/index.d.ts +12 -11
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +11 -7
  12. package/dist/index.js.map +1 -1
  13. package/dist/local-credential-verifier-BC4HS01T.js +429 -0
  14. package/dist/local-credential-verifier-BC4HS01T.js.map +1 -0
  15. package/dist/{meta-D-5kvwx8.js → meta-4NmijIbE.js} +2 -2
  16. package/dist/{meta-D-5kvwx8.js.map → meta-4NmijIbE.js.map} +1 -1
  17. package/dist/{meta-CHgd9Qd0.js → meta-B2fHYlPD.js} +2 -2
  18. package/dist/{meta-CHgd9Qd0.js.map → meta-B2fHYlPD.js.map} +1 -1
  19. package/dist/{meta-bV7L-1yb.d.ts → meta-CpBbgZnu.d.ts} +3 -3
  20. package/dist/meta-CpBbgZnu.d.ts.map +1 -0
  21. package/dist/{meta-BesJP74N.d.ts → meta-DlON7DmF.d.ts} +3 -3
  22. package/dist/meta-DlON7DmF.d.ts.map +1 -0
  23. package/dist/node.d.ts +42 -25
  24. package/dist/node.d.ts.map +1 -1
  25. package/dist/node.js +23 -7
  26. package/dist/node.js.map +1 -1
  27. package/dist/{signer-DrjINLqt.js → signer-GzTlZLjR.js} +38 -106
  28. package/dist/signer-GzTlZLjR.js.map +1 -0
  29. package/dist/{local-credential-verifier-CU8hmFlR.js → signer-trust-C6UJAsNJ.js} +120 -421
  30. package/dist/signer-trust-C6UJAsNJ.js.map +1 -0
  31. package/dist/signer-trust-DstQutcf.d.ts +53 -0
  32. package/dist/signer-trust-DstQutcf.d.ts.map +1 -0
  33. package/dist/trust.d.ts +3 -0
  34. package/dist/trust.js +2 -0
  35. package/dist/{types-DInveFLz.d.ts → types-Bsve10Ny.d.ts} +3 -3
  36. package/dist/types-Bsve10Ny.d.ts.map +1 -0
  37. package/dist/{types-C-hJrsQg.d.ts → types-CHIgkzKb.d.ts} +3 -3
  38. package/dist/types-CHIgkzKb.d.ts.map +1 -0
  39. package/dist/{types-BGQKPoUr.d.ts → types-DOTk0z2D.d.ts} +16 -6
  40. package/dist/types-DOTk0z2D.d.ts.map +1 -0
  41. package/dist/{types-C_qc_62W.js → types-Dwy6khXb.js} +1 -1
  42. package/dist/{types-C_qc_62W.js.map → types-Dwy6khXb.js.map} +1 -1
  43. package/dist/{utils-DtWREYeO.d.ts → utils-C_2VV8CS.d.ts} +5 -12
  44. package/dist/utils-C_2VV8CS.d.ts.map +1 -0
  45. package/dist/utils-DLQ5VVqT.js +75 -0
  46. package/dist/utils-DLQ5VVqT.js.map +1 -0
  47. package/dist/wallet/index.d.ts +5 -5
  48. package/dist/wallet/index.d.ts.map +1 -1
  49. package/dist/wallet/index.js +1 -1
  50. package/dist/wallet/index.js.map +1 -1
  51. package/dist/wallet/mock/factory.d.ts +4 -5
  52. package/dist/wallet/mock/factory.d.ts.map +1 -1
  53. package/dist/wallet/mock/factory.js +1 -1
  54. package/dist/wallet/mock/factory.js.map +1 -1
  55. package/dist/wallet/mock/index.d.ts +5 -5
  56. package/dist/wallet/mock/index.d.ts.map +1 -1
  57. package/dist/wallet/mock/index.js +1 -1
  58. package/dist/wallet/mock/index.js.map +1 -1
  59. package/dist/wallet/privy/factory.d.ts +9 -11
  60. package/dist/wallet/privy/factory.d.ts.map +1 -1
  61. package/dist/wallet/privy/factory.js +2 -2
  62. package/dist/wallet/privy/factory.js.map +1 -1
  63. package/dist/wallet/privy/index.d.ts +5 -5
  64. package/dist/wallet/privy/index.d.ts.map +1 -1
  65. package/dist/wallet/privy/index.js +1 -1
  66. package/dist/wallet/privy/index.js.map +1 -1
  67. package/dist/wallet/rainbow/factory.d.ts +5 -4
  68. package/dist/wallet/rainbow/factory.d.ts.map +1 -1
  69. package/dist/wallet/rainbow/factory.js +2 -2
  70. package/dist/wallet/rainbow/factory.js.map +1 -1
  71. package/dist/wallet/rainbow/index.d.ts +5 -5
  72. package/dist/wallet/rainbow/index.d.ts.map +1 -1
  73. package/dist/wallet/rainbow/index.js +1 -1
  74. package/dist/wallet/rainbow/index.js.map +1 -1
  75. package/package.json +11 -4
  76. package/dist/browser-key-storage-e3RQsnLS.js.map +0 -1
  77. package/dist/index-BLIpkdF7.d.ts.map +0 -1
  78. package/dist/local-credential-verifier-CU8hmFlR.js.map +0 -1
  79. package/dist/meta-BesJP74N.d.ts.map +0 -1
  80. package/dist/meta-bV7L-1yb.d.ts.map +0 -1
  81. package/dist/signer-DrjINLqt.js.map +0 -1
  82. package/dist/types-BGQKPoUr.d.ts.map +0 -1
  83. package/dist/types-C-hJrsQg.d.ts.map +0 -1
  84. package/dist/types-DInveFLz.d.ts.map +0 -1
  85. package/dist/utils-DtWREYeO.d.ts.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signer-GzTlZLjR.js","names":[],"sources":["../src/crypto/utils.ts","../src/crypto/renown-crypto.ts","../src/crypto/renown-crypto-builder.ts","../src/crypto/memory-key-storage.ts","../src/crypto/signer.ts"],"sourcesContent":["import { encodeDIDFromPub, getPublicKey } from \"@didtools/key-webcrypto\";\nimport type { DID, JwkKeyPair } from \"./types.js\";\n\nexport const ECDSA_ALGORITHM: EcKeyAlgorithm = {\n name: \"ECDSA\",\n namedCurve: \"P-256\",\n};\n\nexport const ECDSA_SIGN_ALGORITHM = {\n name: \"ECDSA\",\n namedCurve: \"P-256\",\n hash: \"SHA-256\",\n};\n\nexport async function parseDid(keyPair: CryptoKeyPair): Promise<DID> {\n return encodeDIDFromPub(await getPublicKey(keyPair)) as DID;\n}\n\nexport async function exportKeyPair(\n keyPair: CryptoKeyPair,\n subtleCrypto: SubtleCrypto,\n): Promise<JwkKeyPair> {\n return {\n publicKey: await subtleCrypto.exportKey(\"jwk\", keyPair.publicKey),\n privateKey: await subtleCrypto.exportKey(\"jwk\", keyPair.privateKey),\n };\n}\n\nexport async function importKeyPair(\n jwkKeyPair: JwkKeyPair,\n subtleCrypto: SubtleCrypto,\n algorithm: EcKeyAlgorithm = ECDSA_ALGORITHM,\n): Promise<CryptoKeyPair> {\n return {\n publicKey: await subtleCrypto.importKey(\n \"jwk\",\n jwkKeyPair.publicKey,\n algorithm,\n true,\n [\"verify\"],\n ),\n privateKey: await subtleCrypto.importKey(\n \"jwk\",\n jwkKeyPair.privateKey,\n algorithm,\n true,\n [\"sign\"],\n ),\n };\n}\n\nexport async function generateKeyPair(\n subtleCrypto: SubtleCrypto,\n algorithm: EcKeyAlgorithm = ECDSA_ALGORITHM,\n): Promise<CryptoKeyPair> {\n return subtleCrypto.generateKey(algorithm, true, [\"sign\", \"verify\"]);\n}\n","import { fromString, toString } from \"uint8arrays\";\nimport {\n DEFAULT_RENOWN_CHAIN_ID,\n DEFAULT_RENOWN_NETWORK_ID,\n} from \"../constants.js\";\nimport type { CreateBearerTokenOptions, Issuer } from \"../types.js\";\nimport { createAuthBearerToken } from \"../utils.js\";\nimport type { DID, IRenownCrypto, JsonWebKeyPairStorage } from \"./types.js\";\nimport { ECDSA_ALGORITHM, ECDSA_SIGN_ALGORITHM } from \"./utils.js\";\n\nexport class RenownCrypto implements IRenownCrypto {\n #subtleCrypto: SubtleCrypto;\n #keyPair: CryptoKeyPair;\n #keyPairStorage: JsonWebKeyPairStorage;\n\n readonly did: DID;\n /** Chain id the bearer token is scoped to; keep it equal to the issuing Renown instance's. */\n readonly chainId: number;\n\n static algorithm = ECDSA_ALGORITHM;\n static signAlgorithm = ECDSA_SIGN_ALGORITHM;\n\n constructor(\n keyPairStorage: JsonWebKeyPairStorage,\n crypto: SubtleCrypto,\n keyPair: CryptoKeyPair,\n did: DID,\n chainId = Number(DEFAULT_RENOWN_CHAIN_ID),\n ) {\n this.#keyPairStorage = keyPairStorage;\n this.#subtleCrypto = crypto;\n this.#keyPair = keyPair;\n this.did = did;\n this.chainId = chainId;\n }\n\n get publicKey() {\n return this.#keyPair.publicKey;\n }\n\n async getBearerToken(\n address: string | undefined,\n options?: CreateBearerTokenOptions,\n ): Promise<string> {\n return await createAuthBearerToken(\n this.chainId,\n DEFAULT_RENOWN_NETWORK_ID,\n address || this.did,\n this.issuer,\n options,\n );\n }\n\n async removeDid(): Promise<void> {\n await this.#keyPairStorage.removeKeyPair();\n }\n\n #stringToBytes(s: string): Uint8Array {\n return fromString(s, \"utf-8\");\n }\n\n async sign(data: Uint8Array | string): Promise<Uint8Array> {\n const dataBytes: Uint8Array =\n typeof data === \"string\" ? this.#stringToBytes(data) : data;\n\n const arrayBuffer = await this.#subtleCrypto.sign(\n RenownCrypto.signAlgorithm,\n this.#keyPair.privateKey,\n dataBytes.buffer as ArrayBuffer,\n );\n\n return new Uint8Array(arrayBuffer);\n }\n\n async verify(data: Uint8Array, signature: Uint8Array): Promise<boolean> {\n return this.#subtleCrypto.verify(\n { name: \"ECDSA\", hash: \"SHA-256\" },\n this.#keyPair.publicKey,\n signature.buffer as ArrayBuffer,\n data.buffer as ArrayBuffer,\n );\n }\n\n get issuer(): Issuer {\n return {\n did: this.did,\n signer: async (data: string | Uint8Array) => {\n const signature = await this.sign(\n typeof data === \"string\" ? new TextEncoder().encode(data) : data,\n );\n return toString(signature, \"base64url\");\n },\n alg: \"ES256\",\n };\n }\n}\n\n/**\n * @deprecated Use RenownCrypto instead\n */\nexport class ConnectCrypto extends RenownCrypto {}\n","import { RenownCrypto } from \"./renown-crypto.js\";\nimport type { JsonWebKeyPairStorage } from \"./types.js\";\nimport {\n exportKeyPair,\n generateKeyPair,\n importKeyPair,\n parseDid,\n} from \"./utils.js\";\n\nexport class RenownCryptoBuilder {\n private keyPairStorage?: JsonWebKeyPairStorage;\n private subtleCrypto?: SubtleCrypto;\n private chainId?: number;\n\n withKeyPairStorage(storage: JsonWebKeyPairStorage): this {\n this.keyPairStorage = storage;\n return this;\n }\n\n withSubtleCrypto(crypto: SubtleCrypto): this {\n this.subtleCrypto = crypto;\n return this;\n }\n\n // Scopes the bearer token to a chain (default 1). Match the Renown instance\n // issuing credentials, or the token and the credential disagree.\n withChainId(chainId: number): this {\n this.chainId = chainId;\n return this;\n }\n\n async build(): Promise<RenownCrypto> {\n if (!this.keyPairStorage) {\n throw new Error(\n \"KeyPairStorage is required. Use withKeyPairStorage() to set it.\",\n );\n }\n\n const subtleCrypto = this.subtleCrypto ?? globalThis.crypto.subtle;\n const keyPair = await this.#initializeKeyPair(\n subtleCrypto,\n this.keyPairStorage,\n );\n const did = await parseDid(keyPair);\n\n return new RenownCrypto(\n this.keyPairStorage,\n subtleCrypto,\n keyPair,\n did,\n this.chainId,\n );\n }\n\n async #initializeKeyPair(\n subtleCrypto: SubtleCrypto,\n keyPairStorage: JsonWebKeyPairStorage,\n ): Promise<CryptoKeyPair> {\n const loadedKeyPair = await keyPairStorage.loadKeyPair();\n if (loadedKeyPair) {\n return importKeyPair(loadedKeyPair, subtleCrypto);\n }\n\n const keyPair = await generateKeyPair(subtleCrypto);\n const exported = await exportKeyPair(keyPair, subtleCrypto);\n await keyPairStorage.saveKeyPair(exported);\n return keyPair;\n }\n}\n","import type { JsonWebKeyPairStorage, JwkKeyPair } from \"./types.js\";\n\nexport class MemoryKeyStorage implements JsonWebKeyPairStorage {\n private keyPair: JwkKeyPair | undefined;\n\n constructor(keyPair?: JwkKeyPair) {\n this.keyPair = keyPair;\n }\n\n loadKeyPair() {\n return Promise.resolve(this.keyPair);\n }\n\n saveKeyPair(keyPair: JwkKeyPair) {\n this.keyPair = keyPair;\n return Promise.resolve();\n }\n\n removeKeyPair() {\n this.keyPair = undefined;\n return Promise.resolve();\n }\n}\n","import type {\n Action,\n ActionSigningTarget,\n AppActionSigner,\n ISigner,\n Operation,\n Signature,\n SignatureVerificationHandler,\n UserActionSigner,\n} from \"@powerhousedao/shared/document-model\";\nimport {\n actionSignerIdentity,\n signActionV2,\n} from \"@powerhousedao/shared/document-model\";\nimport type { IRenownCrypto } from \"./index.js\";\n\nexport class InvalidSignatureError extends Error {\n constructor() {\n super(\"Invalid signature\");\n }\n}\n\nexport class RenownCryptoSigner implements ISigner {\n readonly app: AppActionSigner;\n\n constructor(\n private readonly crypto: IRenownCrypto,\n private readonly appName: string,\n public user?: UserActionSigner,\n ) {\n this.app = {\n key: this.crypto.did,\n name: this.appName,\n };\n }\n\n get publicKey() {\n return this.crypto.publicKey;\n }\n\n async sign(data: Uint8Array): Promise<Uint8Array> {\n return this.crypto.sign(data);\n }\n\n async verify(data: Uint8Array, signature: Uint8Array): Promise<void> {\n const isValid = await this.crypto.verify(data, signature);\n if (!isValid) {\n throw new InvalidSignatureError();\n }\n }\n\n async signAction(\n action: Action,\n target: ActionSigningTarget,\n abortSignal?: AbortSignal,\n ): Promise<Signature> {\n const hashField = action.context?.prevOpHash ?? \"\";\n return this._signAction(action, target, hashField, abortSignal);\n }\n\n /**\n * Signs an action including a predicted resulting state hash, packed into\n * element [3] as `${prevStateHash}:${resultingStateHash}`.\n */\n async signActionWithResultingState(\n action: Action,\n target: ActionSigningTarget,\n resultingStateHash: string,\n abortSignal?: AbortSignal,\n ): Promise<Signature> {\n const prevStateHash = action.context?.prevOpHash ?? \"\";\n const hashField = `${prevStateHash}:${resultingStateHash}`;\n return this._signAction(action, target, hashField, abortSignal);\n }\n\n /**\n * The pre-v2 tuple, over scope, type and input only. For peers and tests\n * that still need one; it binds neither the document nor the signer.\n */\n async signActionLegacy(\n action: Action,\n abortSignal?: AbortSignal,\n ): Promise<Signature> {\n if (abortSignal?.aborted) {\n throw new Error(\"Signing aborted\");\n }\n\n const params: [string, string, string, string] = [\n (new Date().getTime() / 1000).toFixed(0),\n this.crypto.did,\n await this.hashAction(action),\n action.context?.prevOpHash ?? \"\",\n ];\n const signatureBytes = await this.crypto.sign(\n this.buildSignatureMessage(params),\n );\n\n if (abortSignal?.aborted) {\n throw new Error(\"Signing aborted\");\n }\n return [...params, `0x${this.arrayBufferToHex(signatureBytes)}`];\n }\n\n private async _signAction(\n action: Action,\n target: ActionSigningTarget,\n hashField: string,\n abortSignal?: AbortSignal,\n ): Promise<Signature> {\n if (abortSignal?.aborted) {\n throw new Error(\"Signing aborted\");\n }\n\n const signature = await signActionV2({\n action,\n target,\n signer: actionSignerIdentity(this),\n sign: (message) => this.crypto.sign(message),\n previousStateHash: hashField,\n });\n\n if (abortSignal?.aborted) {\n throw new Error(\"Signing aborted\");\n }\n\n return signature;\n }\n\n private async hashAction(action: Action): Promise<string> {\n const payload = [\n action.scope,\n action.type,\n JSON.stringify(action.input),\n ].join(\"\");\n const encoder = new TextEncoder();\n const data = encoder.encode(payload);\n const hashBuffer = await crypto.subtle.digest(\"SHA-256\", data);\n return this.arrayBufferToBase64(hashBuffer);\n }\n\n private buildSignatureMessage(\n params: [string, string, string, string],\n ): Uint8Array {\n const message = params.join(\"\");\n const prefix = \"\\x19Signed Operation:\\n\" + message.length.toString();\n const encoder = new TextEncoder();\n return encoder.encode(prefix + message);\n }\n\n private arrayBufferToHex(buffer: Uint8Array | ArrayBuffer): string {\n const bytes =\n buffer instanceof Uint8Array ? buffer : new Uint8Array(buffer);\n return Array.from(bytes)\n .map((byte) => byte.toString(16).padStart(2, \"0\"))\n .join(\"\");\n }\n\n private arrayBufferToBase64(buffer: ArrayBuffer): string {\n const bytes = new Uint8Array(buffer);\n let binary = \"\";\n for (let i = 0; i < bytes.length; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return btoa(binary);\n }\n}\n\n/**\n * Creates a signature verification handler that verifies signatures using the Web Crypto API.\n * The verification uses ECDSA with P-256 curve and SHA-256 hash, matching the RenownCrypto signing algorithm.\n */\nexport function createSignatureVerifier(\n requireSignature = false,\n): SignatureVerificationHandler {\n return async (operation: Operation, publicKey: string): Promise<boolean> => {\n const signer = operation.action.context?.signer;\n if (!signer || !publicKey) {\n return !requireSignature;\n }\n\n const signatures = signer.signatures;\n if (signatures.length === 0) {\n return false;\n }\n\n const signature = signatures[signatures.length - 1];\n const [timestamp, signerKey, hash, prevStateHash, signatureHex] = signature;\n\n if (signerKey !== publicKey) {\n return false;\n }\n\n const params: [string, string, string, string] = [\n timestamp,\n signerKey,\n hash,\n prevStateHash,\n ];\n const message = buildSignatureMessage(params);\n const signatureBytes = hexToUint8Array(signatureHex);\n\n const cryptoKey = await importPublicKey(publicKey);\n\n const isValid = await crypto.subtle.verify(\n { name: \"ECDSA\", hash: \"SHA-256\" },\n cryptoKey,\n signatureBytes.buffer as ArrayBuffer,\n message.buffer as ArrayBuffer,\n );\n\n return isValid;\n };\n}\n\nfunction buildSignatureMessage(\n params: [string, string, string, string],\n): Uint8Array {\n const message = params.join(\"\");\n const prefix = \"\\x19Signed Operation:\\n\" + message.length.toString();\n const encoder = new TextEncoder();\n return encoder.encode(prefix + message);\n}\n\nfunction hexToUint8Array(hex: string): Uint8Array {\n const cleanHex = hex.startsWith(\"0x\") ? hex.slice(2) : hex;\n const bytes = new Uint8Array(cleanHex.length / 2);\n for (let i = 0; i < cleanHex.length; i += 2) {\n bytes[i / 2] = parseInt(cleanHex.substring(i, i + 2), 16);\n }\n return bytes;\n}\n\nasync function importPublicKey(did: string): Promise<CryptoKey> {\n const keyData = extractKeyFromDid(did);\n return crypto.subtle.importKey(\n \"raw\",\n keyData.buffer as ArrayBuffer,\n { name: \"ECDSA\", namedCurve: \"P-256\" },\n true,\n [\"verify\"],\n );\n}\n\nfunction extractKeyFromDid(did: string): Uint8Array {\n const parts = did.split(\":\");\n if (parts.length < 3 || parts[0] !== \"did\" || parts[1] !== \"key\") {\n throw new Error(`Invalid DID format: ${did}`);\n }\n\n const multibaseKey = parts[2];\n if (!multibaseKey.startsWith(\"z\")) {\n throw new Error(`Unsupported multibase encoding: ${multibaseKey[0]}`);\n }\n\n const decoded = base58Decode(multibaseKey.slice(1));\n\n if (decoded[0] !== 0x80 || decoded[1] !== 0x24) {\n throw new Error(\"Not a P-256 public key multicodec\");\n }\n\n const compressedKey = decoded.slice(2);\n return decompressP256PublicKey(compressedKey);\n}\n\nfunction base58Decode(input: string): Uint8Array {\n const ALPHABET = \"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz\";\n const ALPHABET_MAP = new Map<string, number>();\n for (let i = 0; i < ALPHABET.length; i++) {\n ALPHABET_MAP.set(ALPHABET[i], i);\n }\n\n if (input.length === 0) {\n return new Uint8Array(0);\n }\n\n const bytes: number[] = [0];\n for (const char of input) {\n const value = ALPHABET_MAP.get(char);\n if (value === undefined) {\n throw new Error(`Invalid base58 character: ${char}`);\n }\n\n let carry = value;\n for (let j = 0; j < bytes.length; j++) {\n carry += bytes[j] * 58;\n bytes[j] = carry & 0xff;\n carry >>= 8;\n }\n\n while (carry > 0) {\n bytes.push(carry & 0xff);\n carry >>= 8;\n }\n }\n\n for (const char of input) {\n if (char !== \"1\") break;\n bytes.push(0);\n }\n\n return new Uint8Array(bytes.reverse());\n}\n\nfunction decompressP256PublicKey(compressed: Uint8Array): Uint8Array {\n if (compressed.length !== 33) {\n throw new Error(`Invalid compressed key length: ${compressed.length}`);\n }\n\n const prefix = compressed[0];\n if (prefix !== 0x02 && prefix !== 0x03) {\n throw new Error(`Invalid compression prefix: ${prefix}`);\n }\n\n const p = BigInt(\n \"0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff\",\n );\n const a = BigInt(\n \"0xffffffff00000001000000000000000000000000fffffffffffffffffffffffc\",\n );\n const b = BigInt(\n \"0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b\",\n );\n\n let x = BigInt(0);\n for (let i = 1; i < compressed.length; i++) {\n x = (x << BigInt(8)) | BigInt(compressed[i]);\n }\n\n const ySquared = (modPow(x, BigInt(3), p) + a * x + b) % p;\n let y = modPow(ySquared, (p + BigInt(1)) / BigInt(4), p);\n\n const isYEven = y % BigInt(2) === BigInt(0);\n const shouldBeEven = prefix === 0x02;\n if (isYEven !== shouldBeEven) {\n y = p - y;\n }\n\n const uncompressed = new Uint8Array(65);\n uncompressed[0] = 0x04;\n\n const xBytes = bigIntToBytes(x, 32);\n const yBytes = bigIntToBytes(y, 32);\n\n uncompressed.set(xBytes, 1);\n uncompressed.set(yBytes, 33);\n\n return uncompressed;\n}\n\nfunction modPow(base: bigint, exp: bigint, mod: bigint): bigint {\n let result = BigInt(1);\n base = base % mod;\n while (exp > BigInt(0)) {\n if (exp % BigInt(2) === BigInt(1)) {\n result = (result * base) % mod;\n }\n exp = exp >> BigInt(1);\n base = (base * base) % mod;\n }\n return result;\n}\n\nfunction bigIntToBytes(n: bigint, length: number): Uint8Array {\n const bytes = new Uint8Array(length);\n for (let i = length - 1; i >= 0; i--) {\n bytes[i] = Number(n & BigInt(0xff));\n n = n >> BigInt(8);\n }\n return bytes;\n}\n\n/**\n * Parses the hash field (element [3]) from a signature tuple.\n *\n * Supports two formats:\n * - Old format: just `prevStateHash` (no colon)\n * - New format: `prevStateHash:resultingStateHash` (colon-separated)\n *\n * @param hashField - The 4th element of a Signature tuple\n * @returns Object with prevStateHash and optional resultingStateHash\n */\nexport function parseSignatureHashField(hashField: string): {\n prevStateHash: string;\n resultingStateHash: string | undefined;\n} {\n const colonIndex = hashField.indexOf(\":\");\n\n if (colonIndex === -1) {\n return {\n prevStateHash: hashField,\n resultingStateHash: undefined,\n };\n }\n\n return {\n prevStateHash: hashField.substring(0, colonIndex),\n resultingStateHash: hashField.substring(colonIndex + 1),\n };\n}\n\n/**\n * Extracts the resulting state hash from a signature, if present.\n *\n * @param signature - A Signature tuple\n * @returns The resulting state hash, or undefined if not present\n */\nexport function extractResultingHashFromSignature(\n signature: Signature,\n): string | undefined {\n const hashField = signature[3];\n const { resultingStateHash } = parseSignatureHashField(hashField);\n return resultingStateHash;\n}\n\n/**\n * Checks if a signature includes a resulting state hash.\n *\n * @param signature - A Signature tuple\n * @returns true if the signature includes a resulting state hash\n */\nexport function signatureHasResultingHash(signature: Signature): boolean {\n return extractResultingHashFromSignature(signature) !== undefined;\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- import { a as DEFAULT_RENOWN_NETWORK_ID, o as DEFAULT_RENOWN_URL, r as CREDENTIAL_TYPES } from "./constants-BexAR53F.js";
2
- import { m as verifyAuthBearerToken, p as parsePkhDid, s as RenownCryptoBuilder, t as RenownCryptoSigner } from "./signer-DrjINLqt.js";
1
+ import { a as DEFAULT_RENOWN_NETWORK_ID, r as CREDENTIAL_TYPES } from "./constants-DVOF17NB.js";
2
+ import { a as verifyAuthBearerToken } from "./utils-DLQ5VVqT.js";
3
3
  import { recoverTypedDataAddress } from "viem";
4
4
  import { createAction } from "@powerhousedao/shared/document-model";
5
5
  //#region src/discovery.ts
@@ -168,9 +168,12 @@ function issuerChainId(issuerId) {
168
168
  function issuerDidAddress(issuerId) {
169
169
  return issuerId.split(":")[4];
170
170
  }
171
- function bindsTo(row, address, chainId, appDid) {
171
+ function bindsTo$1(row, address, chainId, appDid) {
172
+ return !row.revoked && issuedTo(row, address, chainId, appDid);
173
+ }
174
+ function issuedTo(row, address, chainId, appDid) {
172
175
  const expected = address.toLowerCase();
173
- return !row.revoked && row.credentialSubjectId === appDid && issuerChainId(row.issuerId) === String(chainId) && issuerDidAddress(row.issuerId)?.toLowerCase() === expected && row.issuerEthereumAddress.toLowerCase() === expected;
176
+ return row.credentialSubjectId === appDid && issuerChainId(row.issuerId) === String(chainId) && issuerDidAddress(row.issuerId)?.toLowerCase() === expected && row.issuerEthereumAddress.toLowerCase() === expected;
174
177
  }
175
178
  var SwitchboardClient = class {
176
179
  #endpoint;
@@ -214,13 +217,30 @@ var SwitchboardClient = class {
214
217
  includeRevoked: false
215
218
  } });
216
219
  const now = Date.now();
217
- const mostRecent = renownCredentials.filter((row) => bindsTo(row, address, chainId, appDid)).filter((row) => {
220
+ const mostRecent = renownCredentials.filter((row) => bindsTo$1(row, address, chainId, appDid)).filter((row) => {
218
221
  if (!row.expirationDate) return true;
219
222
  const expiresAt = Date.parse(row.expirationDate);
220
223
  return !Number.isNaN(expiresAt) && expiresAt > now;
221
224
  }).sort((a, b) => Date.parse(b.issuanceDate) - Date.parse(a.issuanceDate)).at(0);
222
225
  return mostRecent ? reshapeCredential(mostRecent) : void 0;
223
226
  }
227
+ async getIssuedCredentials(params) {
228
+ const { address, chainId, appDid } = params;
229
+ const { renownCredentials } = await this.#request(CREDENTIALS_QUERY, { input: {
230
+ driveId: userDriveId(address),
231
+ ethAddress: address.toLowerCase(),
232
+ did: appDid,
233
+ includeRevoked: true
234
+ } });
235
+ const credentials = [];
236
+ for (const row of renownCredentials) {
237
+ if (!issuedTo(row, address, chainId, appDid)) continue;
238
+ try {
239
+ credentials.push(reshapeCredential(row));
240
+ } catch {}
241
+ }
242
+ return credentials;
243
+ }
224
244
  async getProfileByAddress(address) {
225
245
  const { renownUsers } = await this.#request(USERS_QUERY, { input: {
226
246
  driveId: userDriveId(address),
@@ -427,11 +447,16 @@ async function fetchDelegationCredentialRest(params) {
427
447
  }
428
448
  return credential;
429
449
  }
450
+ /** True when the credential's EIP-712 proof, on `chainId`, was signed by its
451
+ * issuer address. Binding and expiry are the caller's to check. */
452
+ async function verifyDelegationProof(credential, chainId) {
453
+ const withDomain = withEip712Domain(credential, chainId);
454
+ return withDomain.proof.eip712.domain.chainId === chainId && await verifyCredentialSignature(withDomain);
455
+ }
430
456
  async function finalizeCredential(credential, chainId, verifySignature) {
431
457
  if (!verifySignature) return credential;
432
- const withDomain = withEip712Domain(credential, chainId);
433
- if (withDomain.proof.eip712.domain.chainId !== chainId || !await verifyCredentialSignature(withDomain)) return;
434
- return withDomain;
458
+ if (!await verifyDelegationProof(credential, chainId)) return;
459
+ return withEip712Domain(credential, chainId);
435
460
  }
436
461
  async function fetchDelegationCredential(options) {
437
462
  const { address, chainId, appDid, switchboardUrl, switchboardRequest, discover = true, verifySignature = true } = options;
@@ -480,428 +505,102 @@ async function verifyAuthCredential(jwt, options = {}) {
480
505
  };
481
506
  }
482
507
  //#endregion
483
- //#region src/storage/common.ts
484
- var BaseStorage = class {};
485
- var MemoryStorage = class extends BaseStorage {
486
- data = /* @__PURE__ */ new Map();
487
- get(key) {
488
- return this.data.get(key);
489
- }
490
- set(key, value) {
491
- if (value === void 0) this.data.delete(key);
492
- else this.data.set(key, value);
493
- }
494
- delete(key) {
495
- this.data.delete(key);
496
- }
497
- };
498
- //#endregion
499
- //#region src/common.ts
500
- var RenownMemoryStorage = class extends MemoryStorage {};
508
+ //#region src/signer-trust.ts
509
+ const DEFAULT_MAX_ACCEPTED = 1e4;
510
+ const DEFAULT_REFUSAL_TTL_MS = 6e4;
501
511
  /**
502
- * The acting identity an action's signature carries.
503
- *
504
- * `User` here is the whole session record — it also holds the DID, the
505
- * credential, the fetched profile and ENS info — while `UserActionSigner` is
506
- * what travels on a signed action, and it is deliberately just an address on a
507
- * chain. The reactor's `ReactorSignerUserInput` declares exactly these three
508
- * fields, and a GraphQL input object refuses a field it does not declare by
509
- * rejecting the WHOLE request, so handing the session record to the signer
510
- * makes every signed push fail before it reaches the reactor.
511
- *
512
- * Narrowed here rather than at the transport, because the session record has no
513
- * business being on an operation in the first place: it is stored on every
514
- * operation a local reactor writes, not only on the ones that go over a wire.
515
- *
516
- * The compiler cannot catch the difference — excess-property checks apply to
517
- * fresh object literals, never to a variable of a wider type — which is why
518
- * this is a function rather than a type annotation.
512
+ * Accepts a key the user's EIP-712 Renown credential delegates to, ignoring
513
+ * expiry and revocation. Verdicts are cached per (address, key); this node's
514
+ * own key is checked before the cache and never cached.
519
515
  */
520
- function toActionSigner(user) {
521
- if (!user) return void 0;
522
- return {
516
+ function createRenownTrustPolicy(options = {}) {
517
+ const maxAccepted = options.maxAccepted ?? DEFAULT_MAX_ACCEPTED;
518
+ const refusalTtlMs = options.refusalTtlMs ?? DEFAULT_REFUSAL_TTL_MS;
519
+ const client = options.switchboard ? new SwitchboardClient(options.switchboard) : void 0;
520
+ const renownUrl = options.renownUrl ?? "https://www.renown.id";
521
+ const accepted = /* @__PURE__ */ new Set();
522
+ const refusedUntil = /* @__PURE__ */ new Map();
523
+ const pending = /* @__PURE__ */ new Map();
524
+ const issued = (user, key) => client ? client.getIssuedCredentials({
523
525
  address: user.address,
524
- networkId: user.networkId,
525
- chainId: user.chainId
526
- };
527
- }
528
- var Renown = class {
529
- #baseUrl;
530
- #store;
531
- #eventEmitter;
532
- #appName;
533
- #crypto;
534
- #signer;
535
- #profileFetcher;
536
- #switchboard;
537
- #chainId;
538
- #status = "initial";
539
- constructor(store, eventEmitter, crypto, appName, baseUrl = DEFAULT_RENOWN_URL, profileFetcher, switchboard, chainId = 1) {
540
- this.#store = store;
541
- this.#eventEmitter = eventEmitter;
542
- this.#baseUrl = baseUrl;
543
- this.#crypto = crypto;
544
- this.#appName = appName;
545
- this.#profileFetcher = profileFetcher;
546
- this.#switchboard = switchboard;
547
- this.#chainId = chainId;
548
- const restoredUser = this.user;
549
- this.#signer = new RenownCryptoSigner(crypto, this.#appName, toActionSigner(restoredUser));
550
- if (restoredUser) this.#status = "authorized";
551
- this.on("user", (user) => {
552
- this.#signer.user = toActionSigner(user);
553
- });
554
- }
555
- get baseUrl() {
556
- return this.#baseUrl;
557
- }
558
- /** Chain id this app issues credentials on; a session from another chain is rejected by {@link signIn}. */
559
- get chainId() {
560
- return this.#chainId;
561
- }
562
- get user() {
563
- return this.#store.get("user");
564
- }
565
- get status() {
566
- return this.#status;
567
- }
568
- get signer() {
569
- return this.#signer;
570
- }
571
- get crypto() {
572
- return this.#crypto;
573
- }
574
- get did() {
575
- return this.#crypto.did;
576
- }
577
- get profileFetcher() {
578
- return this.#profileFetcher;
579
- }
580
- #updateStatus(status) {
581
- this.#status = status;
582
- this.#eventEmitter.emit("status", status);
583
- }
584
- #updateUser(user) {
585
- if (user) this.#store.set("user", user);
586
- else this.#store.delete("user");
587
- this.#eventEmitter.emit("user", user);
526
+ chainId: user.chainId,
527
+ appDid: key
528
+ }) : fetchIssuedCredentialRest(user, key, renownUrl);
529
+ async function lookup(user, key) {
530
+ for (const credential of await issued(user, key)) if (bindsTo(credential, user, key) && await verifyDelegationProof(credential, user.chainId)) return true;
531
+ return false;
588
532
  }
589
- async login(userDid) {
590
- this.#updateStatus("checking");
591
- try {
592
- const result = parsePkhDid(userDid);
593
- const credential = await this.#getCredential(result.address, result.chainId, this.#crypto.did);
594
- if (!credential) {
595
- this.#updateUser(void 0);
596
- throw new Error("Credential not found");
533
+ function remember(entry, verdict) {
534
+ if (verdict) {
535
+ if (accepted.size >= maxAccepted) {
536
+ const oldest = accepted.values().next().value;
537
+ if (oldest !== void 0) accepted.delete(oldest);
597
538
  }
598
- return await this.#completeLogin(userDid, result, credential);
599
- } catch (error) {
600
- this.#updateUser(void 0);
601
- this.#updateStatus("not-authorized");
602
- throw error;
603
- }
604
- }
605
- async signIn(params) {
606
- if (!this.#switchboard) throw new MissingSwitchboardError();
607
- const { address, chainId, signTypedData, username, userImage, expiresInDays } = params;
608
- if (chainId !== this.#chainId) throw new Error(`Renown signIn: wallet is on chain ${chainId}, but this app issues credentials on chain ${this.#chainId}. Switch networks and retry — signing here would create a separate identity for the same address.`);
609
- this.#updateStatus("checking");
610
- try {
611
- const credential = await buildAndSignCredential({
612
- signTypedData,
613
- address,
614
- chainId,
615
- app: this.#appName,
616
- appId: this.did,
617
- expiresInDays
618
- });
619
- await this.#switchboard.issueCredential(credential);
620
- await this.#switchboard.findOrCreateUser(address, {
621
- username,
622
- userImage
623
- });
624
- const userDid = `did:pkh:${DEFAULT_RENOWN_NETWORK_ID}:${chainId}:${address.toLowerCase()}`;
625
- return await this.#completeLogin(userDid, parsePkhDid(userDid), credential);
626
- } catch (error) {
627
- this.#updateUser(void 0);
628
- this.#updateStatus("not-authorized");
539
+ accepted.add(entry);
540
+ refusedUntil.delete(entry);
541
+ } else refusedUntil.set(entry, Date.now() + refusalTtlMs);
542
+ }
543
+ return { authorizeSigner(signer, key) {
544
+ const user = signer.user;
545
+ const self = ownIdentity(options);
546
+ if (self && isSelf(self, user, key)) return Promise.resolve(true);
547
+ if (!user || !isLookupable(user, key)) return Promise.resolve(false);
548
+ const entry = `${user.networkId}|${user.chainId}|${user.address.toLowerCase()}|${key}`;
549
+ if (accepted.has(entry)) return Promise.resolve(true);
550
+ const until = refusedUntil.get(entry);
551
+ if (until !== void 0 && until > Date.now()) return Promise.resolve(false);
552
+ const inFlight = pending.get(entry);
553
+ if (inFlight) return inFlight;
554
+ const verdict = lookup(user, key).then((result) => {
555
+ pending.delete(entry);
556
+ remember(entry, result);
557
+ return result;
558
+ }, (error) => {
559
+ pending.delete(entry);
629
560
  throw error;
630
- }
631
- }
632
- async #completeLogin(userDid, result, credential) {
633
- if (!(credential.issuer.id === userDid && credential.credentialSubject.id === this.did)) throw new Error("Invalid credential");
634
- const verifiableCredential = credential.proof.eip712?.domain ? credential : {
635
- ...credential,
636
- proof: {
637
- ...credential.proof,
638
- eip712: {
639
- domain: {
640
- version: "1",
641
- chainId: result.chainId
642
- },
643
- types: CREDENTIAL_TYPES,
644
- primaryType: "VerifiableCredential"
645
- }
646
- }
647
- };
648
- if (credential.issuer.ethereumAddress.toLowerCase() !== result.address.toLowerCase() || verifiableCredential.proof.eip712.domain.chainId !== result.chainId || !await verifyCredentialSignature(verifiableCredential)) throw new Error("Invalid credential signature");
649
- const user = {
650
- ...result,
651
- address: credential.issuer.ethereumAddress,
652
- did: userDid,
653
- credential: verifiableCredential
654
- };
655
- this.#updateUser(user);
656
- this.#updateStatus("authorized");
657
- if (this.#profileFetcher) this.#profileFetcher(user, this.#baseUrl).then((profile) => {
658
- if (profile && this.user?.address === user.address && this.user.chainId === user.chainId) this.#updateUser({
659
- ...this.user,
660
- profile,
661
- ens: {
662
- name: profile.username ?? void 0,
663
- avatarUrl: profile.userImage ?? void 0
664
- }
665
- });
666
- }).catch(console.error);
667
- return user;
668
- }
669
- logout() {
670
- this.#updateUser(void 0);
671
- this.#updateStatus("initial");
672
- return Promise.resolve();
673
- }
674
- async revalidate() {
675
- const user = this.user;
676
- if (!user) return false;
677
- try {
678
- if (!await this.#getCredential(user.address, user.chainId, this.#crypto.did)) {
679
- await this.logout();
680
- return false;
681
- }
682
- await this.refreshProfile();
683
- return true;
684
- } catch {
685
- return true;
686
- }
687
- }
688
- async refreshProfile() {
689
- const user = this.user;
690
- if (!user || !this.#profileFetcher) return false;
691
- try {
692
- const profile = await this.#profileFetcher(user, this.#baseUrl);
693
- if (!profile) return false;
694
- const current = this.user;
695
- if (!current || current.address !== user.address || current.chainId !== user.chainId) return false;
696
- if (current.profile !== void 0 && current.profile.documentId === profile.documentId && current.profile.username === profile.username && current.profile.userImage === profile.userImage) return false;
697
- this.#updateUser({
698
- ...current,
699
- profile,
700
- ens: {
701
- name: profile.username ?? void 0,
702
- avatarUrl: profile.userImage ?? void 0
703
- }
704
- });
705
- return true;
706
- } catch {
707
- return false;
708
- }
709
- }
710
- on(event, listener) {
711
- return this.#eventEmitter.on(event, listener);
712
- }
713
- async #getCredential(address, chainId, appDid) {
714
- if (this.#switchboard) return this.#switchboard.getCredential({
715
- address,
716
- chainId,
717
- appDid
718
- });
719
- if (!this.#baseUrl) throw new Error("RENOWN_URL is not set");
720
- const url = new URL(`/api/auth/credential?address=${encodeURIComponent(address)}&chainId=${encodeURIComponent(chainId)}&connectId=${encodeURIComponent(appDid)}&appId=${encodeURIComponent(appDid)}`, this.#baseUrl);
721
- const response = await fetch(url, { method: "GET" });
722
- if (response.ok) return (await response.json()).credential;
723
- else throw new Error(`Failed to get credential: ${response.status}`);
724
- }
725
- async verifyBearerToken(token) {
726
- return verifyAuthBearerToken(token);
727
- }
728
- async getBearerToken(options) {
729
- if (!this.user) throw new Error("User not found");
730
- return this.#crypto.getBearerToken(this.user.address, options);
731
- }
732
- };
733
- //#endregion
734
- //#region src/event/memory.ts
735
- var MemoryEventEmitter = class {
736
- #listeners = /* @__PURE__ */ new Map();
737
- on(event, listener) {
738
- if (!this.#listeners.has(event)) this.#listeners.set(event, /* @__PURE__ */ new Set());
739
- this.#listeners.get(event).add(listener);
740
- return () => {
741
- this.#listeners.get(event)?.delete(listener);
742
- };
743
- }
744
- emit(event, data) {
745
- this.#listeners.get(event)?.forEach((listener) => listener(data));
746
- }
747
- };
748
- //#endregion
749
- //#region src/profile.ts
750
- const fetchRenownProfile = async (user, baseUrl) => {
751
- try {
752
- const response = await fetch(`${baseUrl.replace(/\/+$/, "")}/api/profile`, {
753
- method: "POST",
754
- headers: { "Content-Type": "application/json" },
755
- body: JSON.stringify({ ethAddress: user.address })
756
561
  });
757
- if (!response.ok) return;
758
- return (await response.json()).profile ?? void 0;
759
- } catch {
760
- return;
761
- }
762
- };
763
- //#endregion
764
- //#region src/renown-builder.ts
765
- /**
766
- * Base builder for creating Renown instances.
767
- * Use platform-specific builders (RenownBuilder from init.browser.js or init.node.js)
768
- * for pre-configured defaults.
769
- */
770
- var BaseRenownBuilder = class BaseRenownBuilder {
771
- #appName;
772
- #storage;
773
- #eventEmitter;
774
- #crypto;
775
- #keyPairStorage;
776
- #baseUrl;
777
- #switchboardUrl;
778
- #profileFetcher;
779
- #chainId;
780
- /**
781
- * @param appName - Application name used for signing context
782
- */
783
- constructor(appName) {
784
- this.#appName = appName;
785
- }
786
- /**
787
- * Set custom storage for user data persistence.
788
- * Defaults to in-memory storage if not set.
789
- */
790
- withStorage(storage) {
791
- this.#storage = storage;
792
- return this;
793
- }
794
- /**
795
- * Set custom event emitter for user state changes.
796
- * Defaults to in-memory event emitter if not set.
797
- */
798
- withEventEmitter(eventEmitter) {
799
- this.#eventEmitter = eventEmitter;
800
- return this;
801
- }
802
- /**
803
- * Set a pre-built crypto instance.
804
- * Either crypto or keyPairStorage must be provided.
805
- */
806
- withCrypto(crypto) {
807
- this.#crypto = crypto;
808
- return this;
809
- }
810
- /**
811
- * Set key pair storage for cryptographic keys.
812
- * A crypto instance will be built from this storage.
813
- * Either crypto or keyPairStorage must be provided.
814
- */
815
- withKeyPairStorage(keyPairStorage) {
816
- this.#keyPairStorage = keyPairStorage;
817
- return this;
818
- }
819
- /**
820
- * Set the Renown server URL for credential verification.
821
- * Defaults to https://www.renown.id
822
- */
823
- withBaseUrl(baseUrl) {
824
- this.#baseUrl = baseUrl;
825
- return this;
826
- }
827
- withSwitchboardUrl(switchboardUrl) {
828
- this.#switchboardUrl = switchboardUrl;
829
- return this;
830
- }
831
- withChainId(chainId) {
832
- this.#chainId = chainId;
833
- return this;
834
- }
835
- /**
836
- * Set a profile fetcher strategy for enriching user data after login.
837
- * The fetcher receives the authenticated user and the base URL,
838
- * and returns a RenownProfile. Called in the background after each login.
839
- * Defaults to fetchRenownProfile which calls the Renown API.
840
- */
841
- withProfileFetcher(profileFetcher) {
842
- this.#profileFetcher = profileFetcher;
843
- return this;
844
- }
845
- /**
846
- * Build and initialize the Renown instance.
847
- * If a user is stored, attempts to re-authenticate them.
848
- * @throws Error if neither crypto nor keyPairStorage is provided
849
- */
850
- async build() {
851
- if (!this.#crypto && !this.#keyPairStorage) throw new Error("Either crypto or keyPairStorage is required. Use withCrypto() or withKeyPairStorage() to set one.");
852
- const chainId = this.#chainId ?? 1;
853
- const crypto = this.#crypto ?? await new RenownCryptoBuilder().withKeyPairStorage(this.#keyPairStorage).withChainId(chainId).build();
854
- if (crypto.chainId !== void 0 && crypto.chainId !== chainId) console.warn(`Renown: the supplied crypto signs bearer tokens for chain ${crypto.chainId}, but credentials are issued on chain ${chainId}.`);
855
- const storage = this.#storage ?? new RenownMemoryStorage();
856
- const eventEmitter = this.#eventEmitter ?? new MemoryEventEmitter();
857
- const baseUrl = this.#baseUrl ?? "https://www.renown.id";
858
- const switchboardEndpoint = await resolveSwitchboardEndpoint({
859
- switchboardUrl: this.#switchboardUrl,
860
- baseUrl
861
- });
862
- const switchboard = switchboardEndpoint ? new SwitchboardClient(switchboardEndpoint) : void 0;
863
- const profileFetcher = this.#profileFetcher ?? (switchboard ? switchboard.profileFetcher : fetchRenownProfile);
864
- return new Renown(storage, eventEmitter, crypto, this.#appName, baseUrl, profileFetcher, switchboard, chainId);
865
- }
866
- /**
867
- * Create a BaseRenownBuilder from options object for a more concise API
868
- */
869
- static from(options) {
870
- const builder = new BaseRenownBuilder(options.appName);
871
- if (options.storage) builder.withStorage(options.storage);
872
- if (options.eventEmitter) builder.withEventEmitter(options.eventEmitter);
873
- if (options.crypto) builder.withCrypto(options.crypto);
874
- if (options.keyPairStorage) builder.withKeyPairStorage(options.keyPairStorage);
875
- if (options.baseUrl) builder.withBaseUrl(options.baseUrl);
876
- if (options.switchboardUrl) builder.withSwitchboardUrl(options.switchboardUrl);
877
- if (options.profileFetcher) builder.withProfileFetcher(options.profileFetcher);
878
- if (options.chainId !== void 0) builder.withChainId(options.chainId);
879
- return builder;
880
- }
881
- };
882
- //#endregion
883
- //#region src/local-credential-verifier.ts
884
- /** A credential check that reads a Switchboard's own renown read model through
885
- * `execute`, rather than any Renown or Switchboard over HTTP. */
886
- function createLocalCredentialVerifier(execute, options = {}) {
887
- const request = async (query, variables) => {
888
- try {
889
- return await execute(query, variables);
890
- } catch (error) {
891
- options.onError?.(error);
892
- throw error;
562
+ pending.set(entry, verdict);
563
+ return verdict;
564
+ } };
565
+ }
566
+ function ownIdentity(options) {
567
+ if (!options.ownSigner) return options.self;
568
+ const { app, user } = options.ownSigner;
569
+ return {
570
+ key: app?.key ?? "",
571
+ user: {
572
+ address: user?.address ?? "",
573
+ networkId: user?.networkId ?? "",
574
+ chainId: user?.chainId ?? 0
893
575
  }
894
576
  };
895
- return async ({ address, chainId, appId }) => {
896
- return await fetchDelegationCredential({
897
- address,
898
- chainId,
899
- appDid: appId,
900
- switchboardRequest: request
901
- }) !== void 0;
902
- };
577
+ }
578
+ function isSelf(self, user, key) {
579
+ return self.key !== "" && key === self.key && (user?.address ?? "").toLowerCase() === self.user.address.toLowerCase() && (user?.networkId ?? "") === self.user.networkId && (user?.chainId ?? 0) === self.user.chainId;
580
+ }
581
+ function isLookupable(user, key) {
582
+ return key.startsWith("did:key:") && /^0x[0-9a-fA-F]{40}$/.test(user.address) && user.networkId !== "" && Number.isInteger(user.chainId) && user.chainId > 0;
583
+ }
584
+ function bindsTo(credential, user, key) {
585
+ const address = user.address.toLowerCase();
586
+ const issuer = credential.issuer.id.split(":");
587
+ if (issuer.length !== 5) return false;
588
+ const [scheme, method, networkId, chainId, issuerAddress] = issuer;
589
+ return credential.credentialSubject.id === key && scheme === "did" && method === "pkh" && networkId === user.networkId && chainId === String(user.chainId) && issuerAddress.toLowerCase() === address && credential.issuer.ethereumAddress.toLowerCase() === address;
590
+ }
591
+ async function fetchIssuedCredentialRest(user, key, renownUrl) {
592
+ const url = new URL("/api/auth/credential", renownUrl);
593
+ url.searchParams.set("address", user.address);
594
+ url.searchParams.set("chainId", String(user.chainId));
595
+ url.searchParams.set("connectId", key);
596
+ url.searchParams.set("appId", key);
597
+ const response = await fetch(url, { method: "GET" });
598
+ if (response.status === 404) return [];
599
+ if (!response.ok) throw new Error(`Renown credential lookup failed: ${response.status}`);
600
+ const { credential } = await response.json();
601
+ return credential ? [credential] : [];
903
602
  }
904
603
  //#endregion
905
- export { RenownMemoryStorage as a, fetchDelegationCredential as c, verifyCredentialSignature as d, MissingSwitchboardError as f, Renown as i, recoverCredentialSigner as l, resolveSwitchboardEndpoint as m, BaseRenownBuilder as n, BaseStorage as o, SwitchboardClient as p, fetchRenownProfile as r, buildAndSignCredential as s, createLocalCredentialVerifier as t, verifyAuthCredential as u };
604
+ export { verifyAuthCredential as a, MissingSwitchboardError as c, recoverCredentialSigner as i, SwitchboardClient as l, buildAndSignCredential as n, verifyCredentialSignature as o, fetchDelegationCredential as r, verifyDelegationProof as s, createRenownTrustPolicy as t, resolveSwitchboardEndpoint as u };
906
605
 
907
- //# sourceMappingURL=local-credential-verifier-CU8hmFlR.js.map
606
+ //# sourceMappingURL=signer-trust-C6UJAsNJ.js.map