@oma3/omatrust 0.1.0-alpha.4 → 0.1.0-alpha.6
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/README.md +21 -7
- package/dist/{eip712-C4a-JGko.d.cts → eip712-CevLiOcD.d.cts} +32 -1
- package/dist/{eip712-C4a-JGko.d.ts → eip712-CevLiOcD.d.ts} +32 -1
- package/dist/index-BsUwj4r5.d.cts +103 -0
- package/dist/index-pYFRyitI.d.ts +103 -0
- package/dist/index.cjs +188 -54
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +189 -55
- package/dist/index.js.map +1 -1
- package/dist/reputation/index.browser.cjs +188 -54
- package/dist/reputation/index.browser.cjs.map +1 -1
- package/dist/reputation/index.browser.d.cts +2 -2
- package/dist/reputation/index.browser.d.ts +2 -2
- package/dist/reputation/index.browser.js +187 -56
- package/dist/reputation/index.browser.js.map +1 -1
- package/dist/reputation/index.cjs +188 -54
- package/dist/reputation/index.cjs.map +1 -1
- package/dist/reputation/index.d.cts +2 -2
- package/dist/reputation/index.d.ts +2 -2
- package/dist/reputation/index.js +187 -56
- package/dist/reputation/index.js.map +1 -1
- package/package.json +2 -1
- package/dist/index-BDeQNCi_.d.ts +0 -96
- package/dist/index-DP6IIpIh.d.cts +0 -96
package/dist/index.d.cts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { i as identity } from './index-QZDExA4I.cjs';
|
|
2
|
-
export { i as reputation } from './index-
|
|
2
|
+
export { i as reputation } from './index-BsUwj4r5.cjs';
|
|
3
3
|
export { i as appRegistry } from './index-_Bkhoj8k.cjs';
|
|
4
|
-
import './eip712-
|
|
4
|
+
import './eip712-CevLiOcD.cjs';
|
|
5
5
|
|
|
6
6
|
declare class OmaTrustError extends Error {
|
|
7
7
|
code: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { i as identity } from './index-QZDExA4I.js';
|
|
2
|
-
export { i as reputation } from './index-
|
|
2
|
+
export { i as reputation } from './index-pYFRyitI.js';
|
|
3
3
|
export { i as appRegistry } from './index-_Bkhoj8k.js';
|
|
4
|
-
import './eip712-
|
|
4
|
+
import './eip712-CevLiOcD.js';
|
|
5
5
|
|
|
6
6
|
declare class OmaTrustError extends Error {
|
|
7
7
|
code: string;
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { keccak256, toUtf8Bytes, isAddress, getAddress, sha256, ZeroAddress, Signature,
|
|
1
|
+
import { keccak256, toUtf8Bytes, isAddress, getAddress, sha256, ZeroAddress, Signature, formatUnits, verifyTypedData, hexlify, randomBytes, id, Contract } from 'ethers';
|
|
2
2
|
import canonicalize from 'canonicalize';
|
|
3
3
|
import { SchemaEncoder, EAS } from '@ethereum-attestation-service/eas-sdk';
|
|
4
4
|
import { resolveTxt } from 'dns/promises';
|
|
@@ -379,6 +379,7 @@ __export(reputation_exports, {
|
|
|
379
379
|
formatSchemaUid: () => formatSchemaUid,
|
|
380
380
|
formatTransferAmount: () => formatTransferAmount,
|
|
381
381
|
getAttestation: () => getAttestation,
|
|
382
|
+
getAttestationsByAttester: () => getAttestationsByAttester,
|
|
382
383
|
getAttestationsForDid: () => getAttestationsForDid,
|
|
383
384
|
getChainConstants: () => getChainConstants,
|
|
384
385
|
getExplorerAddressUrl: () => getExplorerAddressUrl,
|
|
@@ -394,10 +395,12 @@ __export(reputation_exports, {
|
|
|
394
395
|
normalizeSchema: () => normalizeSchema,
|
|
395
396
|
parseDnsTxtRecord: () => parseDnsTxtRecord,
|
|
396
397
|
prepareDelegatedAttestation: () => prepareDelegatedAttestation,
|
|
398
|
+
revokeAttestation: () => revokeAttestation,
|
|
397
399
|
schemaToString: () => schemaToString,
|
|
398
400
|
splitSignature: () => splitSignature,
|
|
399
401
|
submitAttestation: () => submitAttestation,
|
|
400
402
|
submitDelegatedAttestation: () => submitDelegatedAttestation,
|
|
403
|
+
validateAttestationData: () => validateAttestationData,
|
|
401
404
|
verifyAttestation: () => verifyAttestation,
|
|
402
405
|
verifyDidDocumentControllerDid: () => verifyDidDocumentControllerDid,
|
|
403
406
|
verifyDnsTxtControllerDid: () => verifyDnsTxtControllerDid,
|
|
@@ -439,6 +442,13 @@ function encodeAttestationData(schema, data) {
|
|
|
439
442
|
if (!data || typeof data !== "object") {
|
|
440
443
|
throw new OmaTrustError("INVALID_INPUT", "data must be an object");
|
|
441
444
|
}
|
|
445
|
+
const validationErrors = validateAttestationData(schema, data);
|
|
446
|
+
if (validationErrors.length > 0) {
|
|
447
|
+
const summary = validationErrors.map((error) => `Field "${error.schemaFieldName}" (${error.expectedType}) got ${error.providedType}`).join("; ");
|
|
448
|
+
throw new OmaTrustError("INVALID_INPUT", `Attestation data validation failed: ${summary}`, {
|
|
449
|
+
errors: validationErrors
|
|
450
|
+
});
|
|
451
|
+
}
|
|
442
452
|
const fields = normalizeSchema(schema);
|
|
443
453
|
const schemaString = schemaToString(fields);
|
|
444
454
|
const encoder = new SchemaEncoder(schemaString);
|
|
@@ -451,6 +461,99 @@ function encodeAttestationData(schema, data) {
|
|
|
451
461
|
);
|
|
452
462
|
return encoded;
|
|
453
463
|
}
|
|
464
|
+
function getActualType(value) {
|
|
465
|
+
if (value === null) {
|
|
466
|
+
return "null";
|
|
467
|
+
}
|
|
468
|
+
if (value === void 0) {
|
|
469
|
+
return "undefined";
|
|
470
|
+
}
|
|
471
|
+
if (Array.isArray(value)) {
|
|
472
|
+
return "array";
|
|
473
|
+
}
|
|
474
|
+
if (typeof value === "number") {
|
|
475
|
+
return Number.isFinite(value) ? "number" : "non-finite-number";
|
|
476
|
+
}
|
|
477
|
+
return typeof value;
|
|
478
|
+
}
|
|
479
|
+
function isNumericValue(value, allowNegative) {
|
|
480
|
+
if (typeof value === "bigint") {
|
|
481
|
+
return allowNegative || value >= 0n;
|
|
482
|
+
}
|
|
483
|
+
if (typeof value === "number") {
|
|
484
|
+
if (!Number.isFinite(value) || !Number.isInteger(value)) {
|
|
485
|
+
return false;
|
|
486
|
+
}
|
|
487
|
+
return allowNegative || value >= 0;
|
|
488
|
+
}
|
|
489
|
+
if (typeof value === "string") {
|
|
490
|
+
if (value.length === 0) {
|
|
491
|
+
return false;
|
|
492
|
+
}
|
|
493
|
+
const pattern = allowNegative ? /^-?\d+$/ : /^\d+$/;
|
|
494
|
+
return pattern.test(value);
|
|
495
|
+
}
|
|
496
|
+
return false;
|
|
497
|
+
}
|
|
498
|
+
function isHex(value) {
|
|
499
|
+
return typeof value === "string" && /^0x[0-9a-fA-F]*$/.test(value);
|
|
500
|
+
}
|
|
501
|
+
function validateFieldValue(type, value) {
|
|
502
|
+
const normalizedType = type.trim().toLowerCase();
|
|
503
|
+
const bytesNMatch = normalizedType.match(/^bytes([1-9]|[12]\d|3[0-2])$/);
|
|
504
|
+
if (/^uint\d*$/.test(normalizedType)) {
|
|
505
|
+
return isNumericValue(value, false);
|
|
506
|
+
}
|
|
507
|
+
if (/^int\d*$/.test(normalizedType)) {
|
|
508
|
+
return isNumericValue(value, true);
|
|
509
|
+
}
|
|
510
|
+
if (normalizedType === "string") {
|
|
511
|
+
return typeof value === "string";
|
|
512
|
+
}
|
|
513
|
+
if (normalizedType === "string[]") {
|
|
514
|
+
return Array.isArray(value) && value.every((entry) => typeof entry === "string");
|
|
515
|
+
}
|
|
516
|
+
if (normalizedType === "bool") {
|
|
517
|
+
return typeof value === "boolean";
|
|
518
|
+
}
|
|
519
|
+
if (normalizedType === "address") {
|
|
520
|
+
return typeof value === "string" && isAddress(value);
|
|
521
|
+
}
|
|
522
|
+
if (normalizedType === "bytes") {
|
|
523
|
+
return isHex(value) && (value.length - 2) % 2 === 0;
|
|
524
|
+
}
|
|
525
|
+
if (bytesNMatch) {
|
|
526
|
+
const expectedBytes = Number(bytesNMatch[1]);
|
|
527
|
+
return isHex(value) && value.length === 2 + expectedBytes * 2;
|
|
528
|
+
}
|
|
529
|
+
return true;
|
|
530
|
+
}
|
|
531
|
+
function validateAttestationData(schema, data) {
|
|
532
|
+
if (!data || typeof data !== "object") {
|
|
533
|
+
return [{
|
|
534
|
+
schemaFieldName: "data",
|
|
535
|
+
expectedType: "object",
|
|
536
|
+
providedType: getActualType(data),
|
|
537
|
+
providedValue: data
|
|
538
|
+
}];
|
|
539
|
+
}
|
|
540
|
+
const fields = normalizeSchema(schema);
|
|
541
|
+
const errors = [];
|
|
542
|
+
for (const field of fields) {
|
|
543
|
+
const value = data[field.name];
|
|
544
|
+
const isValid = validateFieldValue(field.type, value);
|
|
545
|
+
if (isValid) {
|
|
546
|
+
continue;
|
|
547
|
+
}
|
|
548
|
+
errors.push({
|
|
549
|
+
schemaFieldName: field.name,
|
|
550
|
+
expectedType: field.type,
|
|
551
|
+
providedType: getActualType(value),
|
|
552
|
+
providedValue: value
|
|
553
|
+
});
|
|
554
|
+
}
|
|
555
|
+
return errors;
|
|
556
|
+
}
|
|
454
557
|
function decodeAttestationData(schema, encodedData) {
|
|
455
558
|
if (typeof encodedData !== "string" || !encodedData.startsWith("0x")) {
|
|
456
559
|
throw new OmaTrustError("INVALID_INPUT", "encodedData must be a hex string");
|
|
@@ -471,22 +574,11 @@ function decodeAttestationData(schema, encodedData) {
|
|
|
471
574
|
return result;
|
|
472
575
|
}
|
|
473
576
|
function extractExpirationTime(data) {
|
|
474
|
-
const
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
}
|
|
480
|
-
if (typeof value === "bigint") {
|
|
481
|
-
return value;
|
|
482
|
-
}
|
|
483
|
-
if (typeof value === "number") {
|
|
484
|
-
return value;
|
|
485
|
-
}
|
|
486
|
-
if (typeof value === "string" && /^\d+$/.test(value)) {
|
|
487
|
-
return BigInt(value);
|
|
488
|
-
}
|
|
489
|
-
}
|
|
577
|
+
const value = data["expiresAt"];
|
|
578
|
+
if (value === void 0 || value === null) return void 0;
|
|
579
|
+
if (typeof value === "bigint") return value;
|
|
580
|
+
if (typeof value === "number") return value;
|
|
581
|
+
if (typeof value === "string" && /^\d+$/.test(value)) return BigInt(value);
|
|
490
582
|
return void 0;
|
|
491
583
|
}
|
|
492
584
|
var ZERO_UID = "0x0000000000000000000000000000000000000000000000000000000000000000";
|
|
@@ -615,6 +707,34 @@ async function submitAttestation(params) {
|
|
|
615
707
|
throw new OmaTrustError("NETWORK_ERROR", "Failed to submit attestation", { err });
|
|
616
708
|
}
|
|
617
709
|
}
|
|
710
|
+
async function revokeAttestation(params) {
|
|
711
|
+
if (!params || typeof params !== "object") {
|
|
712
|
+
throw new OmaTrustError("INVALID_INPUT", "params must be provided");
|
|
713
|
+
}
|
|
714
|
+
if (!params.signer) {
|
|
715
|
+
throw new OmaTrustError("INVALID_INPUT", "signer is required");
|
|
716
|
+
}
|
|
717
|
+
const eas = new EAS(params.easContractAddress);
|
|
718
|
+
eas.connect(params.signer);
|
|
719
|
+
try {
|
|
720
|
+
const tx = await eas.revoke({
|
|
721
|
+
schema: params.schemaUid,
|
|
722
|
+
data: {
|
|
723
|
+
uid: params.uid,
|
|
724
|
+
value: toBigIntOrDefault(params.value, 0n)
|
|
725
|
+
}
|
|
726
|
+
});
|
|
727
|
+
await tx.wait();
|
|
728
|
+
const txHash = getEasTransactionHash(tx) ?? ZERO_UID;
|
|
729
|
+
const receipt = getEasTransactionReceipt(tx);
|
|
730
|
+
return {
|
|
731
|
+
txHash,
|
|
732
|
+
receipt
|
|
733
|
+
};
|
|
734
|
+
} catch (err) {
|
|
735
|
+
throw new OmaTrustError("NETWORK_ERROR", "Failed to revoke attestation", { err });
|
|
736
|
+
}
|
|
737
|
+
}
|
|
618
738
|
function buildDelegatedTypedData(params) {
|
|
619
739
|
return {
|
|
620
740
|
domain: {
|
|
@@ -762,7 +882,14 @@ async function submitDelegatedAttestation(params) {
|
|
|
762
882
|
var EAS_EVENT_ABI = [
|
|
763
883
|
"event Attested(address indexed recipient, address indexed attester, bytes32 uid, bytes32 indexed schemaUID)"
|
|
764
884
|
];
|
|
765
|
-
function
|
|
885
|
+
function parseEventTxHash(event) {
|
|
886
|
+
const txHash = event.transactionHash;
|
|
887
|
+
if (typeof txHash !== "string") {
|
|
888
|
+
return void 0;
|
|
889
|
+
}
|
|
890
|
+
return /^0x[0-9a-fA-F]{64}$/.test(txHash) ? txHash : void 0;
|
|
891
|
+
}
|
|
892
|
+
function parseAttestation(attestation, schema, txHash) {
|
|
766
893
|
const rawData = attestation.data ?? "0x";
|
|
767
894
|
const decoded = schema ? decodeAttestationData(schema, rawData) : {};
|
|
768
895
|
const toBigIntSafe = (value) => {
|
|
@@ -782,6 +909,7 @@ function parseAttestation(attestation, schema) {
|
|
|
782
909
|
schema: attestation.schema,
|
|
783
910
|
attester: attestation.attester,
|
|
784
911
|
recipient: attestation.recipient,
|
|
912
|
+
txHash,
|
|
785
913
|
revocable: Boolean(attestation.revocable),
|
|
786
914
|
revocationTime: toBigIntSafe(attestation.revocationTime),
|
|
787
915
|
expirationTime: toBigIntSafe(attestation.expirationTime),
|
|
@@ -807,21 +935,18 @@ async function getAttestation(params) {
|
|
|
807
935
|
throw new OmaTrustError("NETWORK_ERROR", "Failed to read attestation", { err });
|
|
808
936
|
}
|
|
809
937
|
}
|
|
810
|
-
async function
|
|
811
|
-
const
|
|
812
|
-
const
|
|
813
|
-
const toBlock = params.toBlock ?? await provider.getBlockNumber();
|
|
814
|
-
const fromBlock = params.fromBlock ?? Math.max(0, toBlock - 5e4);
|
|
815
|
-
const filter = contract.filters.Attested(didToAddress(params.did));
|
|
938
|
+
async function queryAttestationEvents(easContractAddress, provider, fromBlock, toBlock, options) {
|
|
939
|
+
const contract = new Contract(easContractAddress, EAS_EVENT_ABI, provider);
|
|
940
|
+
const filter = contract.filters.Attested(options?.recipient ?? null, options?.attester ?? null);
|
|
816
941
|
let events;
|
|
817
942
|
try {
|
|
818
943
|
events = await contract.queryFilter(filter, fromBlock, toBlock);
|
|
819
944
|
} catch (err) {
|
|
820
945
|
throw new OmaTrustError("NETWORK_ERROR", "Failed to query attestation events", { err });
|
|
821
946
|
}
|
|
822
|
-
const eas = new EAS(
|
|
947
|
+
const eas = new EAS(easContractAddress);
|
|
823
948
|
eas.connect(provider);
|
|
824
|
-
const schemaFilter =
|
|
949
|
+
const schemaFilter = options?.schemas?.map((s) => s.toLowerCase());
|
|
825
950
|
const results = [];
|
|
826
951
|
for (const event of events) {
|
|
827
952
|
if (!("args" in event && Array.isArray(event.args))) {
|
|
@@ -840,11 +965,39 @@ async function getAttestationsForDid(params) {
|
|
|
840
965
|
if (!attestation || !attestation.uid) {
|
|
841
966
|
continue;
|
|
842
967
|
}
|
|
843
|
-
results.push(parseAttestation(attestation));
|
|
968
|
+
results.push(parseAttestation(attestation, void 0, parseEventTxHash(event)));
|
|
844
969
|
}
|
|
845
970
|
results.sort((a, b) => Number(b.time - a.time));
|
|
846
971
|
return results;
|
|
847
972
|
}
|
|
973
|
+
async function getAttestationsForDid(params) {
|
|
974
|
+
const provider = params.provider;
|
|
975
|
+
const toBlock = params.toBlock ?? await provider.getBlockNumber();
|
|
976
|
+
const fromBlock = params.fromBlock ?? Math.max(0, toBlock - 5e4);
|
|
977
|
+
return queryAttestationEvents(
|
|
978
|
+
params.easContractAddress,
|
|
979
|
+
provider,
|
|
980
|
+
fromBlock,
|
|
981
|
+
toBlock,
|
|
982
|
+
{ recipient: didToAddress(params.did), schemas: params.schemas }
|
|
983
|
+
);
|
|
984
|
+
}
|
|
985
|
+
async function getAttestationsByAttester(params) {
|
|
986
|
+
const provider = params.provider;
|
|
987
|
+
const toBlock = params.toBlock ?? await provider.getBlockNumber();
|
|
988
|
+
const fromBlock = params.fromBlock ?? Math.max(0, toBlock - 5e4);
|
|
989
|
+
if (params.limit !== void 0 && params.limit <= 0) {
|
|
990
|
+
return [];
|
|
991
|
+
}
|
|
992
|
+
const results = await queryAttestationEvents(
|
|
993
|
+
params.easContractAddress,
|
|
994
|
+
provider,
|
|
995
|
+
fromBlock,
|
|
996
|
+
toBlock,
|
|
997
|
+
{ attester: params.attester, schemas: params.schemas }
|
|
998
|
+
);
|
|
999
|
+
return params.limit !== void 0 ? results.slice(0, params.limit) : results;
|
|
1000
|
+
}
|
|
848
1001
|
async function listAttestations(params) {
|
|
849
1002
|
const limit = params.limit ?? 20;
|
|
850
1003
|
if (limit <= 0) {
|
|
@@ -855,34 +1008,15 @@ async function listAttestations(params) {
|
|
|
855
1008
|
}
|
|
856
1009
|
async function getLatestAttestations(params) {
|
|
857
1010
|
const provider = params.provider;
|
|
858
|
-
const
|
|
859
|
-
const
|
|
860
|
-
const
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
if (!("args" in event && Array.isArray(event.args))) {
|
|
868
|
-
continue;
|
|
869
|
-
}
|
|
870
|
-
const args = event.args;
|
|
871
|
-
const uid = args?.[2];
|
|
872
|
-
const schemaUid = args?.[3];
|
|
873
|
-
if (!uid || !schemaUid) {
|
|
874
|
-
continue;
|
|
875
|
-
}
|
|
876
|
-
if (schemaFilter && !schemaFilter.includes(schemaUid.toLowerCase())) {
|
|
877
|
-
continue;
|
|
878
|
-
}
|
|
879
|
-
const attestation = await eas.getAttestation(uid);
|
|
880
|
-
if (!attestation || !attestation.uid) {
|
|
881
|
-
continue;
|
|
882
|
-
}
|
|
883
|
-
results.push(parseAttestation(attestation));
|
|
884
|
-
}
|
|
885
|
-
results.sort((a, b) => Number(b.time - a.time));
|
|
1011
|
+
const toBlock = await provider.getBlockNumber();
|
|
1012
|
+
const fromBlock = params.fromBlock ?? Math.max(0, toBlock - 5e4);
|
|
1013
|
+
const results = await queryAttestationEvents(
|
|
1014
|
+
params.easContractAddress,
|
|
1015
|
+
provider,
|
|
1016
|
+
fromBlock,
|
|
1017
|
+
toBlock,
|
|
1018
|
+
{ schemas: params.schemas }
|
|
1019
|
+
);
|
|
886
1020
|
return results.slice(0, params.limit ?? 20);
|
|
887
1021
|
}
|
|
888
1022
|
function deduplicateReviews(attestations) {
|