@renown/sdk 6.2.3-dev.23 → 6.2.3-dev.24
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/{browser-key-storage-e3RQsnLS.js → browser-key-storage-CeyLjla8.js} +1 -1
- package/dist/{browser-key-storage-e3RQsnLS.js.map → browser-key-storage-CeyLjla8.js.map} +1 -1
- package/dist/crypto.d.ts +2 -2
- package/dist/crypto.js +2 -2
- package/dist/{index-BLIpkdF7.d.ts → index-Bcs-BY-C.d.ts} +10 -19
- package/dist/{index-BLIpkdF7.d.ts.map → index-Bcs-BY-C.d.ts.map} +1 -1
- package/dist/index.d.ts +5 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -4
- package/dist/index.js.map +1 -1
- package/dist/local-credential-verifier-2aC00ymX.js +429 -0
- package/dist/local-credential-verifier-2aC00ymX.js.map +1 -0
- package/dist/{meta-bV7L-1yb.d.ts → meta-B8HbJHy8.d.ts} +2 -2
- package/dist/{meta-bV7L-1yb.d.ts.map → meta-B8HbJHy8.d.ts.map} +1 -1
- package/dist/{meta-CHgd9Qd0.js → meta-BOjLjJ1Y.js} +2 -2
- package/dist/{meta-CHgd9Qd0.js.map → meta-BOjLjJ1Y.js.map} +1 -1
- package/dist/{meta-BesJP74N.d.ts → meta-CRXEMUUQ.d.ts} +2 -2
- package/dist/{meta-BesJP74N.d.ts.map → meta-CRXEMUUQ.d.ts.map} +1 -1
- package/dist/{meta-D-5kvwx8.js → meta-adhFGw0o.js} +2 -2
- package/dist/{meta-D-5kvwx8.js.map → meta-adhFGw0o.js.map} +1 -1
- package/dist/node.d.ts +19 -4
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +18 -3
- package/dist/node.js.map +1 -1
- package/dist/{signer-DrjINLqt.js → signer-DIbtSfsu.js} +30 -102
- package/dist/signer-DIbtSfsu.js.map +1 -0
- package/dist/{local-credential-verifier-CU8hmFlR.js → signer-trust-D7vg4xbS.js} +120 -421
- package/dist/signer-trust-D7vg4xbS.js.map +1 -0
- package/dist/signer-trust-Dg7Wggsc.d.ts +53 -0
- package/dist/signer-trust-Dg7Wggsc.d.ts.map +1 -0
- package/dist/trust.d.ts +2 -0
- package/dist/trust.js +2 -0
- package/dist/{types-DInveFLz.d.ts → types-CQDAkCVn.d.ts} +2 -2
- package/dist/{types-DInveFLz.d.ts.map → types-CQDAkCVn.d.ts.map} +1 -1
- package/dist/{types-BGQKPoUr.d.ts → types-CXBWG4JY.d.ts} +10 -2
- package/dist/types-CXBWG4JY.d.ts.map +1 -0
- package/dist/{types-C-hJrsQg.d.ts → types-ChjGDXVS.d.ts} +2 -2
- package/dist/{types-C-hJrsQg.d.ts.map → types-ChjGDXVS.d.ts.map} +1 -1
- package/dist/{types-C_qc_62W.js → types-ome2Ysme.js} +1 -1
- package/dist/{types-C_qc_62W.js.map → types-ome2Ysme.js.map} +1 -1
- package/dist/{utils-DtWREYeO.d.ts → utils-BuSw6Mud.d.ts} +3 -11
- package/dist/utils-BuSw6Mud.d.ts.map +1 -0
- package/dist/utils-Dtdm4vFs.js +74 -0
- package/dist/utils-Dtdm4vFs.js.map +1 -0
- package/dist/wallet/index.d.ts +1 -1
- package/dist/wallet/index.js +1 -1
- package/dist/wallet/mock/factory.d.ts +2 -2
- package/dist/wallet/mock/factory.js +1 -1
- package/dist/wallet/mock/index.d.ts +2 -2
- package/dist/wallet/mock/index.js +1 -1
- package/dist/wallet/privy/factory.d.ts +3 -3
- package/dist/wallet/privy/factory.js +2 -2
- package/dist/wallet/privy/index.d.ts +2 -2
- package/dist/wallet/privy/index.js +1 -1
- package/dist/wallet/rainbow/factory.d.ts +2 -2
- package/dist/wallet/rainbow/factory.js +1 -1
- package/dist/wallet/rainbow/index.d.ts +2 -2
- package/dist/wallet/rainbow/index.js +1 -1
- package/package.json +9 -3
- package/dist/local-credential-verifier-CU8hmFlR.js.map +0 -1
- package/dist/signer-DrjINLqt.js.map +0 -1
- package/dist/types-BGQKPoUr.d.ts.map +0 -1
- package/dist/utils-DtWREYeO.d.ts.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as DEFAULT_RENOWN_NETWORK_ID,
|
|
2
|
-
import {
|
|
1
|
+
import { a as DEFAULT_RENOWN_NETWORK_ID, r as CREDENTIAL_TYPES } from "./constants-BexAR53F.js";
|
|
2
|
+
import { a as verifyAuthBearerToken } from "./utils-Dtdm4vFs.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
|
|
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
|
-
|
|
433
|
-
|
|
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/
|
|
484
|
-
|
|
485
|
-
|
|
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
|
-
*
|
|
503
|
-
*
|
|
504
|
-
*
|
|
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
|
|
521
|
-
|
|
522
|
-
|
|
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
|
-
|
|
525
|
-
|
|
526
|
-
};
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
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
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
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
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
if (!
|
|
607
|
-
const
|
|
608
|
-
if (
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
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
|
-
|
|
758
|
-
return
|
|
759
|
-
}
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
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
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
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 {
|
|
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=
|
|
606
|
+
//# sourceMappingURL=signer-trust-D7vg4xbS.js.map
|