diff --git a/src/index.test.ts b/src/index.test.ts index 6e444748..76b9c63b 100644 --- a/src/index.test.ts +++ b/src/index.test.ts @@ -561,8 +561,15 @@ describe('Running @erc725/erc725.js tests...', () => { const jsonString = `{"LSP3Profile":{"profileImage":"ipfs://QmYo8yg4zzmdu26NSvtsoKeU5oVR6h2ohmoa2Cx5i91mPf","backgroundImage":"ipfs://QmZF5pxDJcB8eVvCd74rsXBFXhWL3S1XR5tty2cy1a58Ew","description":"Beautiful clothing that doesn't cost the Earth. A sustainable designer based in London Patrick works with brand partners to refocus on systemic change centred around creative education. "}}`; const fetchStub = sinon.stub(global, 'fetch'); - fetchStub.onCall(0).returns(Promise.resolve(new Response(jsonString))); + fetchStub.onCall(0).returns( + Promise.resolve( + new Response(jsonString, { + headers: { 'content-type': 'application/json' }, + }), + ), + ); const result = await erc725.fetchData('TestJSONURL'); + console.log(fetchStub.getCalls(), result); fetchStub.restore(); assert.deepStrictEqual(result, { @@ -584,7 +591,7 @@ describe('Running @erc725/erc725.js tests...', () => { [contractVersion.interface], ); - const ipfsGateway = 'https://2eff.lukso.dev'; + const ipfsGateway = 'https://api.universalprofile.cloud'; const erc725 = new ERC725([testJSONURLSchema], address, provider, { ipfsGateway, @@ -593,7 +600,13 @@ describe('Running @erc725/erc725.js tests...', () => { const jsonString = `{"LSP3Profile":{"profileImage":"ipfs://QmYo8yg4zzmdu26NSvtsoKeU5oVR6h2ohmoa2Cx5i91mPf","backgroundImage":"ipfs://QmZF5pxDJcB8eVvCd74rsXBFXhWL3S1XR5tty2cy1a58Ew","description":"Beautiful clothing that doesn't cost the Earth. A sustainable designer based in London Patrick works with brand partners to refocus on systemic change centred around creative education. "}}`; const fetchStub = sinon.stub(global, 'fetch'); - fetchStub.onCall(0).returns(Promise.resolve(new Response(jsonString))); + fetchStub.onCall(0).returns( + Promise.resolve( + new Response(jsonString, { + headers: { 'content-type': 'application/json' }, + }), + ), + ); const result = await erc725.fetchData('TestJSONURL'); assert.deepStrictEqual(result, { key: testJSONURLSchema.key, diff --git a/src/lib/decodeData.test.ts b/src/lib/decodeData.test.ts index 22ea7ea2..65845c33 100644 --- a/src/lib/decodeData.test.ts +++ b/src/lib/decodeData.test.ts @@ -91,6 +91,11 @@ describe('decodeData', () => { value: '0x6f357c6a820464ddfac1bec070cc14a8daf04129871d458f2ca94368aae8391311af6361696670733a2f2f516d597231564a4c776572673670456f73636468564775676f3339706136727963455a4c6a7452504466573834554178', }, + { + keyName: 'JSONURLCase', + value: + '0x8019f9b1820464ddfac1bec070cc14a8daf04129871d458f2ca94368aae8391311af6361696670733a2f2f516d597231564a4c776572673670456f73636468564775676f3339706136727963455a4c6a7452504466573834554178', + }, { keyName: 'AssetURLCase', value: @@ -105,6 +110,13 @@ describe('decodeData', () => { valueType: 'bytes', valueContent: 'JSONURL', // Deprecated - We keep it for backward compatibility between v0.21.3 and v0.22.0 }, + { + name: 'JSONURLCase2', + key: '0x9136feeb09af67b63993b586ce46a43bd3456990d3fdb39d07beab9dee8d5910', + keyType: 'Singleton', + valueType: 'bytes', + valueContent: 'JSONURL', // Deprecated - We keep it for backward compatibility between v0.21.3 and v0.22.0 + }, { name: 'AssetURLCase', key: '0xbda5878fa57d8da097bf7cfd78c28e75f2c2c7b028e4e056d16d7e4b83f98081', @@ -123,6 +135,13 @@ describe('decodeData', () => { }, url: 'ifps://QmYr1VJLwerg6pEoscdhVGugo39pa6rycEZLjtRPDfW84UAx', }, + { + verification: { + method: 'keccak256(bytes)', // 0x8019f9b1 + data: '0x820464ddfac1bec070cc14a8daf04129871d458f2ca94368aae8391311af6361', + }, + url: 'ifps://QmYr1VJLwerg6pEoscdhVGugo39pa6rycEZLjtRPDfW84UAx', + }, { verification: { method: 'keccak256(bytes)', // 0x8019f9b1 @@ -206,6 +225,44 @@ describe('decodeData', () => { ]); }); + it('parses type Array correctly (even with uint256)', () => { + const decodedData = decodeData( + { + keyName: 'LSP12IssuedAssets[]', + value: [ + { + key: '0x7c8c3416d6cda87cd42c71ea1843df28ac4850354f988d55ee2eaa47b6dc05cd', + value: + '0x0000000000000000000000000000000000000000000000000000000000000002', + }, + { + key: '0x7c8c3416d6cda87cd42c71ea1843df2800000000000000000000000000000000', + value: '0xd94353d9b005b3c0a9da169b768a31c57844e490', + }, + { + key: '0x7c8c3416d6cda87cd42c71ea1843df2800000000000000000000000000000001', + value: '0xdaea594e385fc724449e3118b2db7e86dfba1826', + }, + ], + }, + [ + { + name: 'LSP12IssuedAssets[]', + key: '0x7c8c3416d6cda87cd42c71ea1843df28ac4850354f988d55ee2eaa47b6dc05cd', + keyType: 'Array', + valueContent: 'Address', + valueType: 'address', + }, + ], + ); + + expect(decodedData.name).to.eql('LSP12IssuedAssets[]'); + expect(decodedData.value).to.eql([ + '0xD94353D9B005B3c0A9Da169b768a31C57844e490', + '0xDaea594E385Fc724449E3118B2Db7E86dFBa1826', + ]); + }); + it('decodes dynamic keys', () => { const decodedData = decodeData( [ diff --git a/src/lib/encoder.test.ts b/src/lib/encoder.test.ts index 3d5a8826..3cc5d68a 100644 --- a/src/lib/encoder.test.ts +++ b/src/lib/encoder.test.ts @@ -38,7 +38,7 @@ import { } from '../constants/constants'; import { URLDataToEncode, URLDataWithHash } from '../types'; -describe('encoder', () => { +describe.only('encoder', () => { describe('valueType', () => { describe('`bool`/`boolean` type', () => { const validTestCases = [ @@ -667,13 +667,15 @@ describe('encoder', () => { ); }); - it('throws when trying to decode a bytes17 as `uint128`', () => { - expect(() => - decodeValueType('uint128', '0x000000000000000000000000000000ffff'), - ).to.throw( - "Can't convert hex value 0x000000000000000000000000000000ffff to uint128. Too many bytes. 17 > 16", - ); - }); + // We do not want this during decode. During encode we enforce the correct sizes. + // + // it('throws when trying to decode a bytes17 as `uint128`', () => { + // expect(() => + // decodeValueType('uint128', '0x000000000000000000000000000000ffff'), + // ).to.throw( + // "Can't convert hex value 0x000000000000000000000000000000ffff to uint128. Too many bytes. 17 > 16", + // ); + // }); }); describe('`type[CompactBytesArray]` (of static types)', () => { diff --git a/src/lib/encoder.ts b/src/lib/encoder.ts index 0c51d712..a87068a6 100644 --- a/src/lib/encoder.ts +++ b/src/lib/encoder.ts @@ -506,14 +506,25 @@ const valueTypeEncodingMap = ( ); } const abiEncodedValue = abiCoder.encodeParameter(type, value); - + console.log(value, abiEncodedValue); const bytesArray = hexToBytes(abiEncodedValue); const numberOfBytes = (uintLength as number) / 8; - // abi-encoding always pad to 32 bytes. We need to keep the `n` rightmost bytes. // where `n` = `numberOfBytes` const startIndex = 32 - numberOfBytes; + console.log( + bytesArray, + startIndex, + bytesArray.slice(0, startIndex), + bytesArray.slice(startIndex), + ); + if (bytesArray.slice(0, startIndex).some((byte) => byte !== 0)) { + throw Error( + `Number ${value} is too large to be represented as ${type}`, + ); + } + return bytesToHex(bytesArray.slice(startIndex)); }, decode: (value: string) => { diff --git a/src/lib/getDataFromExternalSources.ts b/src/lib/getDataFromExternalSources.ts index 927bf81a..d0cb9349 100644 --- a/src/lib/getDataFromExternalSources.ts +++ b/src/lib/getDataFromExternalSources.ts @@ -77,6 +77,7 @@ export const getDataFromExternalSources = ( const { url } = patchIPFSUrlsIfApplicable(urlDataWithHash, ipfsGateway); receivedData = await fetch(url).then(async (response) => { + console.log(receivedData, urlDataWithHash, response); if (!response.ok) { return undefined; } @@ -90,8 +91,14 @@ export const getDataFromExternalSources = ( } return response.json(); }); + console.log( + receivedData, + urlDataWithHash, + receivedData, + urlDataWithHash.verification, + ); if (isDataAuthentic(receivedData, urlDataWithHash.verification)) { - return dataEntry; + return { ...dataEntry, value: receivedData }; } console.error( `GET request to ${urlDataWithHash.url} did not correctly validate`,