diff --git a/CHANGELOG.md b/CHANGELOG.md index 4946381..f856199 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## 2.5.0 + +- Add schema verification function +- Fix handling of schemas with "ipfsHash" variables + ## 2.4.1 - Export Private Data types diff --git a/dist/schema-encoder.d.ts b/dist/schema-encoder.d.ts index 1aab7a4..7d29550 100644 --- a/dist/schema-encoder.d.ts +++ b/dist/schema-encoder.d.ts @@ -18,6 +18,7 @@ export declare class SchemaEncoder { constructor(schema: string); encodeData(params: SchemaItem[]): string; decodeData(data: string): SchemaDecodedItem[]; + static isSchemaValid(schema: string): boolean; isEncodedDataValid(data: string): boolean; static isCID(cid: string): boolean; static encodeQmHash(hash: string): string; diff --git a/dist/schema-encoder.js b/dist/schema-encoder.js index 52bc5de..e9eb932 100644 --- a/dist/schema-encoder.js +++ b/dist/schema-encoder.js @@ -6,11 +6,17 @@ const multiformats_1 = require("multiformats"); const utils_1 = require("./utils"); const TUPLE_TYPE = 'tuple'; const TUPLE_ARRAY_TYPE = 'tuple[]'; +const BYTES32 = 'bytes32'; +const STRING = 'string'; +const ADDRESS = 'address'; +const BOOL = 'bool'; +const UINT = 'uint'; +const IPFS_HASH = 'ipfsHash'; class SchemaEncoder { schema; constructor(schema) { this.schema = []; - const fixedSchema = schema.replace(/ipfsHash/g, 'bytes32'); + const fixedSchema = schema.replace(new RegExp(`${IPFS_HASH} (\\S+)`, 'g'), `${BYTES32} $1`); const fragment = ethers_1.FunctionFragment.from(`func(${fixedSchema})`); // The following verification will throw in case of an incorrect schema ethers_1.AbiCoder.defaultAbiCoder().getDefaultValue(fragment.inputs); @@ -54,15 +60,15 @@ class SchemaEncoder { const sanitizedType = type.replace(/\s/g, ''); if (sanitizedType !== schemaItem.type && sanitizedType !== schemaItem.signature && - !(sanitizedType === 'ipfsHash' && schemaItem.type === 'bytes32')) { + !(sanitizedType === IPFS_HASH && schemaItem.type === BYTES32)) { throw new Error(`Incompatible param type: ${sanitizedType}`); } if (name !== schemaItem.name) { throw new Error(`Incompatible param name: ${name}`); } - data.push(schemaItem.type === 'bytes32' && schemaItem.name === 'ipfsHash' + data.push(schemaItem.type === BYTES32 && schemaItem.name === IPFS_HASH ? SchemaEncoder.decodeIpfsValue(value) - : schemaItem.type === 'bytes32' && typeof value === 'string' && !(0, ethers_1.isBytesLike)(value) + : schemaItem.type === BYTES32 && typeof value === 'string' && !(0, ethers_1.isBytesLike)(value) ? (0, ethers_1.encodeBytes32String)(value) : value); } @@ -78,7 +84,7 @@ class SchemaEncoder { let value = values[i]; const input = fragment.inputs[0]; const components = input.components ?? input.arrayChildren?.components ?? []; - if (value.length > 0 && typeof value !== 'string' && components?.length > 0) { + if (value.length > 0 && typeof value !== STRING && components?.length > 0) { if (Array.isArray(value[0])) { const namedValues = []; for (const val of value) { @@ -121,6 +127,15 @@ class SchemaEncoder { }; }); } + static isSchemaValid(schema) { + try { + new SchemaEncoder(schema); + return true; + } + catch (e) { + return false; + } + } isEncodedDataValid(data) { try { this.decodeData(data); @@ -141,7 +156,7 @@ class SchemaEncoder { } static encodeQmHash(hash) { const a = multiformats_1.CID.parse(hash); - return ethers_1.AbiCoder.defaultAbiCoder().encode(['bytes32'], [a.multihash.digest]); + return ethers_1.AbiCoder.defaultAbiCoder().encode([BYTES32], [a.multihash.digest]); } static decodeQmHash(bytes32) { const digest = Uint8Array.from(Buffer.from(bytes32.slice(2), 'hex')); @@ -155,7 +170,7 @@ class SchemaEncoder { return dCID.toString(); } static getDefaultValueForTypeName(typeName) { - return typeName === 'bool' ? false : typeName.includes('uint') ? '0' : typeName === 'address' ? utils_1.ZERO_ADDRESS : ''; + return typeName === BOOL ? false : typeName.includes(UINT) ? '0' : typeName === ADDRESS ? utils_1.ZERO_ADDRESS : ''; } static decodeIpfsValue(val) { if ((0, ethers_1.isBytesLike)(val)) { @@ -163,7 +178,7 @@ class SchemaEncoder { } try { const decodedHash = multiformats_1.CID.parse(val); - const encoded = ethers_1.AbiCoder.defaultAbiCoder().encode(['bytes32'], [decodedHash.multihash.digest]); + const encoded = ethers_1.AbiCoder.defaultAbiCoder().encode([BYTES32], [decodedHash.multihash.digest]); return encoded; } catch { @@ -172,7 +187,7 @@ class SchemaEncoder { } static encodeBytes32Value(value) { try { - ethers_1.AbiCoder.defaultAbiCoder().encode(['bytes32'], [value]); + ethers_1.AbiCoder.defaultAbiCoder().encode([BYTES32], [value]); return value; } catch (e) { diff --git a/dist/schema-encoder.js.map b/dist/schema-encoder.js.map index f560748..305bc70 100644 --- a/dist/schema-encoder.js.map +++ b/dist/schema-encoder.js.map @@ -1 +1 @@ -{"version":3,"file":"schema-encoder.js","sourceRoot":"","sources":["../src/schema-encoder.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"schema-encoder.js","sourceRoot":"","sources":["../src/schema-encoder.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/package.json b/package.json index 2f3b44d..afc94cf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@ethereum-attestation-service/eas-sdk", - "version": "2.4.1", + "version": "2.5.0", "description": "Ethereum Attestation Service - TypeScript/JavaScript SDK", "repository": "git@github.com:ethereum-attestation-service/eas-sdk.git", "author": "Leonid Beder ", diff --git a/src/schema-encoder.ts b/src/schema-encoder.ts index baaa010..9d75094 100644 --- a/src/schema-encoder.ts +++ b/src/schema-encoder.ts @@ -30,6 +30,12 @@ export interface SchemaDecodedItem { const TUPLE_TYPE = 'tuple'; const TUPLE_ARRAY_TYPE = 'tuple[]'; +const BYTES32 = 'bytes32'; +const STRING = 'string'; +const ADDRESS = 'address'; +const BOOL = 'bool'; +const UINT = 'uint'; +const IPFS_HASH = 'ipfsHash'; export class SchemaEncoder { public schema: SchemaItemWithSignature[]; @@ -37,7 +43,7 @@ export class SchemaEncoder { constructor(schema: string) { this.schema = []; - const fixedSchema = schema.replace(/ipfsHash/g, 'bytes32'); + const fixedSchema = schema.replace(new RegExp(`${IPFS_HASH} (\\S+)`, 'g'), `${BYTES32} $1`); const fragment = FunctionFragment.from(`func(${fixedSchema})`); // The following verification will throw in case of an incorrect schema @@ -93,7 +99,7 @@ export class SchemaEncoder { if ( sanitizedType !== schemaItem.type && sanitizedType !== schemaItem.signature && - !(sanitizedType === 'ipfsHash' && schemaItem.type === 'bytes32') + !(sanitizedType === IPFS_HASH && schemaItem.type === BYTES32) ) { throw new Error(`Incompatible param type: ${sanitizedType}`); } @@ -103,9 +109,9 @@ export class SchemaEncoder { } data.push( - schemaItem.type === 'bytes32' && schemaItem.name === 'ipfsHash' + schemaItem.type === BYTES32 && schemaItem.name === IPFS_HASH ? SchemaEncoder.decodeIpfsValue(value as string) - : schemaItem.type === 'bytes32' && typeof value === 'string' && !isBytesLike(value) + : schemaItem.type === BYTES32 && typeof value === 'string' && !isBytesLike(value) ? encodeBytes32String(value) : value ); @@ -128,7 +134,7 @@ export class SchemaEncoder { const input = fragment.inputs[0]; const components = input.components ?? input.arrayChildren?.components ?? []; - if (value.length > 0 && typeof value !== 'string' && components?.length > 0) { + if (value.length > 0 && typeof value !== STRING && components?.length > 0) { if (Array.isArray(value[0])) { const namedValues = []; @@ -179,6 +185,16 @@ export class SchemaEncoder { }); } + public static isSchemaValid(schema: string) { + try { + new SchemaEncoder(schema); + + return true; + } catch (e) { + return false; + } + } + public isEncodedDataValid(data: string) { try { this.decodeData(data); @@ -200,7 +216,7 @@ export class SchemaEncoder { public static encodeQmHash(hash: string): string { const a = CID.parse(hash); - return AbiCoder.defaultAbiCoder().encode(['bytes32'], [a.multihash.digest]); + return AbiCoder.defaultAbiCoder().encode([BYTES32], [a.multihash.digest]); } public static decodeQmHash(bytes32: string): string { @@ -217,7 +233,7 @@ export class SchemaEncoder { } private static getDefaultValueForTypeName(typeName: string) { - return typeName === 'bool' ? false : typeName.includes('uint') ? '0' : typeName === 'address' ? ZERO_ADDRESS : ''; + return typeName === BOOL ? false : typeName.includes(UINT) ? '0' : typeName === ADDRESS ? ZERO_ADDRESS : ''; } private static decodeIpfsValue(val: string) { @@ -227,7 +243,7 @@ export class SchemaEncoder { try { const decodedHash = CID.parse(val); - const encoded = AbiCoder.defaultAbiCoder().encode(['bytes32'], [decodedHash.multihash.digest]); + const encoded = AbiCoder.defaultAbiCoder().encode([BYTES32], [decodedHash.multihash.digest]); return encoded; } catch { @@ -237,7 +253,7 @@ export class SchemaEncoder { private static encodeBytes32Value(value: string) { try { - AbiCoder.defaultAbiCoder().encode(['bytes32'], [value]); + AbiCoder.defaultAbiCoder().encode([BYTES32], [value]); return value; } catch (e) { return encodeBytes32String(value); diff --git a/test/test/schema-encoder.ts b/test/test/schema-encoder.ts index 0ea5072..174c8fd 100644 --- a/test/test/schema-encoder.ts +++ b/test/test/schema-encoder.ts @@ -115,6 +115,54 @@ describe('SchemaEncoder', () => { value: [] } ] + }, + { + schema: + 'string contractGroupName,string ipfsHash,string readmeIpfsHash,address[] contractAddresses,string[] contractNames,string[] contractNetworks,string[] contractIpfsHashes', + decodedSchema: [ + { + name: 'contractGroupName', + type: 'string', + signature: 'string contractGroupName', + value: '' + }, + { + name: 'ipfsHash', + type: 'string', + signature: 'string ipfsHash', + value: '' + }, + { + name: 'readmeIpfsHash', + type: 'string', + signature: 'string readmeIpfsHash', + value: '' + }, + { + name: 'contractAddresses', + type: 'address[]', + signature: 'address[] contractAddresses', + value: [] + }, + { + name: 'contractNames', + type: 'string[]', + signature: 'string[] contractNames', + value: [] + }, + { + name: 'contractNetworks', + type: 'string[]', + signature: 'string[] contractNetworks', + value: [] + }, + { + name: 'contractIpfsHashes', + type: 'string[]', + signature: 'string[] contractIpfsHashes', + value: [] + } + ] } ]) { context(schema, () => { @@ -122,18 +170,9 @@ describe('SchemaEncoder', () => { const schemaEncoder = new SchemaEncoder(schema); expect(schemaEncoder.schema).to.deep.equal(decodedSchema); }); - }); - } - for (const schema of [ - 'boo like', - 'adss contractAddress,bool trusted', - 'bytes32 eventId,uint8 ticketType,uint10000 ticketNum', - 'bytes32 eventId,uint8 ticketType,ticketNum' - ]) { - context(schema, () => { - it('should throw', () => { - expect(() => new SchemaEncoder(schema)).to.throw(Error); + it('should verify', () => { + expect(SchemaEncoder.isSchemaValid(schema)).to.be.true; }); }); } @@ -678,6 +717,21 @@ describe('SchemaEncoder', () => { } }); + describe('verification', () => { + for (const schema of [ + 'boo like', + 'adss contractAddress,bool trusted', + 'bytes32 eventId,uint8 ticketType,uint10000 ticketNum', + 'bytes32 eventId,uint8 ticketType,ticketNum' + ]) { + context(schema, () => { + it('should unable to verify', () => { + expect(SchemaEncoder.isSchemaValid(schema)).to.be.false; + }); + }); + } + }); + describe('ipfs', () => { describe('CID verification', () => { for (const cid of [