diff --git a/.gitignore b/.gitignore index 97b0ddc..284481d 100644 --- a/.gitignore +++ b/.gitignore @@ -73,4 +73,5 @@ typings/ # intellij .idea -/tests/.bin \ No newline at end of file +/tests/.bin +/tests/.latest.json diff --git a/src/resolver.ts b/src/resolver.ts index 9981b6b..7b1af97 100644 --- a/src/resolver.ts +++ b/src/resolver.ts @@ -57,7 +57,7 @@ export function handleAddrChanged(event: AddrChangedEvent): void { } export function handleMulticoinAddrChanged(event: AddressChangedEvent): void { - let resolver = getOrCreateResolver(event.params.node, event.address); + let resolver = getOrCreateResolver(event.params.node, event.address, false); let coinType = event.params.coinType; if (resolver.coinTypes == null) { @@ -84,8 +84,10 @@ export function handleMulticoinAddrChanged(event: AddressChangedEvent): void { export function handleNameChanged(event: NameChangedEvent): void { if (event.params.name.indexOf("\u0000") != -1) return; + const resolver = getOrCreateResolver(event.params.node, event.address, true); + let resolverEvent = new NameChanged(createEventID(event)); - resolverEvent.resolver = createResolverID(event.params.node, event.address); + resolverEvent.resolver = resolver.id; resolverEvent.blockNumber = event.block.number.toI32(); resolverEvent.transactionID = event.transaction.hash; resolverEvent.name = event.params.name; @@ -93,8 +95,10 @@ export function handleNameChanged(event: NameChangedEvent): void { } export function handleABIChanged(event: ABIChangedEvent): void { + const resolver = getOrCreateResolver(event.params.node, event.address, true); + let resolverEvent = new AbiChanged(createEventID(event)); - resolverEvent.resolver = createResolverID(event.params.node, event.address); + resolverEvent.resolver = resolver.id; resolverEvent.blockNumber = event.block.number.toI32(); resolverEvent.transactionID = event.transaction.hash; resolverEvent.contentType = event.params.contentType; @@ -102,8 +106,10 @@ export function handleABIChanged(event: ABIChangedEvent): void { } export function handlePubkeyChanged(event: PubkeyChangedEvent): void { + const resolver = getOrCreateResolver(event.params.node, event.address, true); + let resolverEvent = new PubkeyChanged(createEventID(event)); - resolverEvent.resolver = createResolverID(event.params.node, event.address); + resolverEvent.resolver = resolver.id; resolverEvent.blockNumber = event.block.number.toI32(); resolverEvent.transactionID = event.transaction.hash; resolverEvent.x = event.params.x; @@ -112,7 +118,7 @@ export function handlePubkeyChanged(event: PubkeyChangedEvent): void { } export function handleTextChanged(event: TextChangedEvent): void { - let resolver = getOrCreateResolver(event.params.node, event.address); + let resolver = getOrCreateResolver(event.params.node, event.address, false); let key = event.params.key; if (resolver.texts == null) { @@ -128,7 +134,7 @@ export function handleTextChanged(event: TextChangedEvent): void { } let resolverEvent = new TextChanged(createEventID(event)); - resolverEvent.resolver = createResolverID(event.params.node, event.address); + resolverEvent.resolver = resolver.id; resolverEvent.blockNumber = event.block.number.toI32(); resolverEvent.transactionID = event.transaction.hash; resolverEvent.key = event.params.key; @@ -138,7 +144,7 @@ export function handleTextChanged(event: TextChangedEvent): void { export function handleTextChangedWithValue( event: TextChangedWithValueEvent ): void { - let resolver = getOrCreateResolver(event.params.node, event.address); + let resolver = getOrCreateResolver(event.params.node, event.address, false); let key = event.params.key; if (resolver.texts == null) { @@ -154,7 +160,7 @@ export function handleTextChangedWithValue( } let resolverEvent = new TextChanged(createEventID(event)); - resolverEvent.resolver = createResolverID(event.params.node, event.address); + resolverEvent.resolver = resolver.id; resolverEvent.blockNumber = event.block.number.toI32(); resolverEvent.transactionID = event.transaction.hash; resolverEvent.key = event.params.key; @@ -163,12 +169,12 @@ export function handleTextChangedWithValue( } export function handleContentHashChanged(event: ContenthashChangedEvent): void { - let resolver = getOrCreateResolver(event.params.node, event.address); + let resolver = getOrCreateResolver(event.params.node, event.address, false); resolver.contentHash = event.params.hash; resolver.save(); let resolverEvent = new ContenthashChanged(createEventID(event)); - resolverEvent.resolver = createResolverID(event.params.node, event.address); + resolverEvent.resolver = resolver.id; resolverEvent.blockNumber = event.block.number.toI32(); resolverEvent.transactionID = event.transaction.hash; resolverEvent.hash = event.params.hash; @@ -176,8 +182,10 @@ export function handleContentHashChanged(event: ContenthashChangedEvent): void { } export function handleInterfaceChanged(event: InterfaceChangedEvent): void { + const resolver = getOrCreateResolver(event.params.node, event.address, true); + let resolverEvent = new InterfaceChanged(createEventID(event)); - resolverEvent.resolver = createResolverID(event.params.node, event.address); + resolverEvent.resolver = resolver.id; resolverEvent.blockNumber = event.block.number.toI32(); resolverEvent.transactionID = event.transaction.hash; resolverEvent.interfaceID = event.params.interfaceID; @@ -188,10 +196,12 @@ export function handleInterfaceChanged(event: InterfaceChangedEvent): void { export function handleAuthorisationChanged( event: AuthorisationChangedEvent ): void { + const resolver = getOrCreateResolver(event.params.node, event.address, true); + let resolverEvent = new AuthorisationChanged(createEventID(event)); resolverEvent.blockNumber = event.block.number.toI32(); resolverEvent.transactionID = event.transaction.hash; - resolverEvent.resolver = createResolverID(event.params.node, event.address); + resolverEvent.resolver = resolver.id; resolverEvent.owner = event.params.owner; resolverEvent.target = event.params.target; resolverEvent.isAuthorized = event.params.isAuthorised; @@ -212,7 +222,7 @@ export function handleVersionChanged(event: VersionChangedEvent): void { domain.save(); } - let resolver = getOrCreateResolver(event.params.node, event.address); + let resolver = getOrCreateResolver(event.params.node, event.address, false); resolver.addr = null; resolver.contentHash = null; resolver.texts = null; @@ -220,13 +230,20 @@ export function handleVersionChanged(event: VersionChangedEvent): void { resolver.save(); } -function getOrCreateResolver(node: Bytes, address: Address): Resolver { +function getOrCreateResolver( + node: Bytes, + address: Address, + saveOnNew: boolean +): Resolver { let id = createResolverID(node, address); let resolver = Resolver.load(id); if (resolver == null) { resolver = new Resolver(id); resolver.domain = node.toHexString(); resolver.address = address; + if (saveOnNew) { + resolver.save(); + } } return resolver as Resolver; } @@ -238,7 +255,7 @@ function createEventID(event: ethereum.Event): string { .concat(event.logIndex.toString()); } -function createResolverID(node: Bytes, resolver: Address): string { +export function createResolverID(node: Bytes, resolver: Address): string { return resolver .toHexString() .concat("-") diff --git a/tests/.latest.json b/tests/.latest.json index fdc5f57..5779e76 100644 --- a/tests/.latest.json +++ b/tests/.latest.json @@ -1,4 +1,4 @@ { "version": "0.6.0", - "timestamp": 1702245606450 + "timestamp": 1702332546798 } \ No newline at end of file diff --git a/tests/resolver.test.ts b/tests/resolver.test.ts new file mode 100644 index 0000000..7eaae05 --- /dev/null +++ b/tests/resolver.test.ts @@ -0,0 +1,475 @@ +import { Address, BigInt, Bytes, ethereum } from "@graphprotocol/graph-ts"; +import { + assert, + beforeEach, + clearStore, + describe, + newMockEvent, + test, +} from "matchstick-as/assembly/index"; +import { + createResolverID, + handleABIChanged, + handleAddrChanged, + handleAuthorisationChanged, + handleContentHashChanged, + handleInterfaceChanged, + handleMulticoinAddrChanged, + handleNameChanged, + handlePubkeyChanged, + handleTextChanged, + handleTextChangedWithValue, + handleVersionChanged, +} from "../src/resolver"; +import { + ABIChanged, + AddrChanged, + AddressChanged, + AuthorisationChanged, + ContenthashChanged, + InterfaceChanged, + NameChanged, + PubkeyChanged, + TextChanged, + TextChanged1 as TextChangedWithValue, + VersionChanged, +} from "../src/types/Resolver/Resolver"; +import { Resolver } from "../src/types/schema"; + +const namehash = Bytes.fromHexString( + "0x7857c9824139b8a8c3cb04712b41558b4878c55fa9c1e5390e910ee3220c3cce" +); + +const addressValue = ethereum.Value.fromAddress( + Address.fromString("0x8e8db5ccef88cca9d624701db544989c996e3216") +); + +const getResolver = (address: Address): Resolver | null => + Resolver.load(createResolverID(namehash, address)); + +describe("creates new resolver when resolver entity doesn't exist", () => { + beforeEach(() => { + clearStore(); + }); + test("handleAddrChanged", () => { + const mockEvent = newMockEvent(); + const resolverEvent = new AddrChanged( + mockEvent.address, + mockEvent.logIndex, + mockEvent.transactionLogIndex, + mockEvent.logType, + mockEvent.block, + mockEvent.transaction, + mockEvent.parameters, + mockEvent.receipt + ); + resolverEvent.parameters = new Array(); + + let nodeParam = new ethereum.EventParam( + "node", + ethereum.Value.fromFixedBytes(namehash) + ); + let aParam = new ethereum.EventParam("a", addressValue); + resolverEvent.parameters.push(nodeParam); + resolverEvent.parameters.push(aParam); + + let resolver = getResolver(mockEvent.address); + + assert.assertNull(resolver); + + handleAddrChanged(resolverEvent); + + resolver = getResolver(mockEvent.address); + + assert.assertNotNull(resolver); + }); + test("handleMulticoinAddrChanged", () => { + const mockEvent = newMockEvent(); + const resolverEvent = new AddressChanged( + mockEvent.address, + mockEvent.logIndex, + mockEvent.transactionLogIndex, + mockEvent.logType, + mockEvent.block, + mockEvent.transaction, + mockEvent.parameters, + mockEvent.receipt + ); + resolverEvent.parameters = new Array(); + + let nodeParam = new ethereum.EventParam( + "node", + ethereum.Value.fromFixedBytes(namehash) + ); + let coinTypeParam = new ethereum.EventParam( + "coinType", + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(60)) + ); + let newAddressParam = new ethereum.EventParam( + "newAddress", + ethereum.Value.fromBytes( + Address.fromString("0x8e8db5ccef88cca9d624701db544989c996e3216") + ) + ); + resolverEvent.parameters.push(nodeParam); + resolverEvent.parameters.push(coinTypeParam); + resolverEvent.parameters.push(newAddressParam); + + let resolver = getResolver(mockEvent.address); + + assert.assertNull(resolver); + + handleMulticoinAddrChanged(resolverEvent); + + resolver = getResolver(mockEvent.address); + + assert.assertNotNull(resolver); + }); + test("handleNameChanged", () => { + const mockEvent = newMockEvent(); + const resolverEvent = new NameChanged( + mockEvent.address, + mockEvent.logIndex, + mockEvent.transactionLogIndex, + mockEvent.logType, + mockEvent.block, + mockEvent.transaction, + mockEvent.parameters, + mockEvent.receipt + ); + resolverEvent.parameters = new Array(); + + let nodeParam = new ethereum.EventParam( + "node", + ethereum.Value.fromFixedBytes(namehash) + ); + let nameParam = new ethereum.EventParam( + "name", + ethereum.Value.fromString("test.eth") + ); + resolverEvent.parameters.push(nodeParam); + resolverEvent.parameters.push(nameParam); + + let resolver = getResolver(mockEvent.address); + + assert.assertNull(resolver); + + handleNameChanged(resolverEvent); + + resolver = getResolver(mockEvent.address); + + assert.assertNotNull(resolver); + }); + test("handleABIChanged", () => { + const mockEvent = newMockEvent(); + const resolverEvent = new ABIChanged( + mockEvent.address, + mockEvent.logIndex, + mockEvent.transactionLogIndex, + mockEvent.logType, + mockEvent.block, + mockEvent.transaction, + mockEvent.parameters, + mockEvent.receipt + ); + resolverEvent.parameters = new Array(); + + let nodeParam = new ethereum.EventParam( + "node", + ethereum.Value.fromFixedBytes(namehash) + ); + let contentTypeParam = new ethereum.EventParam( + "contentType", + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(1)) + ); + resolverEvent.parameters.push(nodeParam); + resolverEvent.parameters.push(contentTypeParam); + + let resolver = getResolver(mockEvent.address); + + assert.assertNull(resolver); + + handleABIChanged(resolverEvent); + + resolver = getResolver(mockEvent.address); + + assert.assertNotNull(resolver); + }); + test("handlePubkeyChanged", () => { + const mockEvent = newMockEvent(); + const resolverEvent = new PubkeyChanged( + mockEvent.address, + mockEvent.logIndex, + mockEvent.transactionLogIndex, + mockEvent.logType, + mockEvent.block, + mockEvent.transaction, + mockEvent.parameters, + mockEvent.receipt + ); + resolverEvent.parameters = new Array(); + + let nodeParam = new ethereum.EventParam( + "node", + ethereum.Value.fromFixedBytes(namehash) + ); + let xParam = new ethereum.EventParam( + "x", + ethereum.Value.fromBytes(Bytes.fromI32(1)) + ); + let yParam = new ethereum.EventParam( + "y", + ethereum.Value.fromBytes(Bytes.fromI32(1)) + ); + resolverEvent.parameters.push(nodeParam); + resolverEvent.parameters.push(xParam); + resolverEvent.parameters.push(yParam); + + let resolver = getResolver(mockEvent.address); + + assert.assertNull(resolver); + + handlePubkeyChanged(resolverEvent); + + resolver = getResolver(mockEvent.address); + + assert.assertNotNull(resolver); + }); + test("handleTextChanged", () => { + const mockEvent = newMockEvent(); + const resolverEvent = new TextChanged( + mockEvent.address, + mockEvent.logIndex, + mockEvent.transactionLogIndex, + mockEvent.logType, + mockEvent.block, + mockEvent.transaction, + mockEvent.parameters, + mockEvent.receipt + ); + resolverEvent.parameters = new Array(); + + let nodeParam = new ethereum.EventParam( + "node", + ethereum.Value.fromFixedBytes(namehash) + ); + let indexedKeyParam = new ethereum.EventParam( + "indexedKey", + ethereum.Value.fromString("foo") + ); + let keyParam = new ethereum.EventParam( + "key", + ethereum.Value.fromString("foo") + ); + resolverEvent.parameters.push(nodeParam); + resolverEvent.parameters.push(indexedKeyParam); + resolverEvent.parameters.push(keyParam); + + let resolver = getResolver(mockEvent.address); + + assert.assertNull(resolver); + + handleTextChanged(resolverEvent); + + resolver = getResolver(mockEvent.address); + + assert.assertNotNull(resolver); + }); + test("handleTextChangedWithValue", () => { + const mockEvent = newMockEvent(); + const resolverEvent = new TextChangedWithValue( + mockEvent.address, + mockEvent.logIndex, + mockEvent.transactionLogIndex, + mockEvent.logType, + mockEvent.block, + mockEvent.transaction, + mockEvent.parameters, + mockEvent.receipt + ); + resolverEvent.parameters = new Array(); + + let nodeParam = new ethereum.EventParam( + "node", + ethereum.Value.fromFixedBytes(namehash) + ); + let indexedKeyParam = new ethereum.EventParam( + "indexedKey", + ethereum.Value.fromString("foo") + ); + let keyParam = new ethereum.EventParam( + "key", + ethereum.Value.fromString("foo") + ); + let valueParam = new ethereum.EventParam( + "value", + ethereum.Value.fromString("bar") + ); + resolverEvent.parameters.push(nodeParam); + resolverEvent.parameters.push(indexedKeyParam); + resolverEvent.parameters.push(keyParam); + resolverEvent.parameters.push(valueParam); + + let resolver = getResolver(mockEvent.address); + + assert.assertNull(resolver); + + handleTextChangedWithValue(resolverEvent); + + resolver = getResolver(mockEvent.address); + + assert.assertNotNull(resolver); + }); + test("handleContentHashChanged", () => { + const mockEvent = newMockEvent(); + const resolverEvent = new ContenthashChanged( + mockEvent.address, + mockEvent.logIndex, + mockEvent.transactionLogIndex, + mockEvent.logType, + mockEvent.block, + mockEvent.transaction, + mockEvent.parameters, + mockEvent.receipt + ); + resolverEvent.parameters = new Array(); + + let nodeParam = new ethereum.EventParam( + "node", + ethereum.Value.fromFixedBytes(namehash) + ); + let hashParam = new ethereum.EventParam( + "hash", + ethereum.Value.fromBytes(Bytes.fromI32(0)) + ); + resolverEvent.parameters.push(nodeParam); + resolverEvent.parameters.push(hashParam); + + let resolver = getResolver(mockEvent.address); + + assert.assertNull(resolver); + + handleContentHashChanged(resolverEvent); + + resolver = getResolver(mockEvent.address); + + assert.assertNotNull(resolver); + }); + test("handleInterfaceChanged", () => { + const mockEvent = newMockEvent(); + const resolverEvent = new InterfaceChanged( + mockEvent.address, + mockEvent.logIndex, + mockEvent.transactionLogIndex, + mockEvent.logType, + mockEvent.block, + mockEvent.transaction, + mockEvent.parameters, + mockEvent.receipt + ); + resolverEvent.parameters = new Array(); + + let nodeParam = new ethereum.EventParam( + "node", + ethereum.Value.fromFixedBytes(namehash) + ); + let interfaceIdParam = new ethereum.EventParam( + "interfaceID", + ethereum.Value.fromFixedBytes(Bytes.fromI32(0)) + ); + let implementerParam = new ethereum.EventParam("implementer", addressValue); + resolverEvent.parameters.push(nodeParam); + resolverEvent.parameters.push(interfaceIdParam); + resolverEvent.parameters.push(implementerParam); + + let resolver = getResolver(mockEvent.address); + + assert.assertNull(resolver); + + handleInterfaceChanged(resolverEvent); + + resolver = getResolver(mockEvent.address); + + assert.assertNotNull(resolver); + }); + test("handleAuthorisationChanged", () => { + const mockEvent = newMockEvent(); + const resolverEvent = new AuthorisationChanged( + mockEvent.address, + mockEvent.logIndex, + mockEvent.transactionLogIndex, + mockEvent.logType, + mockEvent.block, + mockEvent.transaction, + mockEvent.parameters, + mockEvent.receipt + ); + resolverEvent.parameters = new Array(); + + let nodeParam = new ethereum.EventParam( + "node", + ethereum.Value.fromFixedBytes(namehash) + ); + let ownerParam = new ethereum.EventParam("owner", addressValue); + let targetParam = new ethereum.EventParam( + "target", + ethereum.Value.fromAddress( + Address.fromString("0x8e8db5ccef88cca9d624701db544989c996e3216") + ) + ); + let isAuthorised = new ethereum.EventParam( + "isAuthorised", + ethereum.Value.fromBoolean(true) + ); + resolverEvent.parameters.push(nodeParam); + resolverEvent.parameters.push(ownerParam); + resolverEvent.parameters.push(targetParam); + resolverEvent.parameters.push(isAuthorised); + + let resolver = getResolver(mockEvent.address); + + assert.assertNull(resolver); + + handleAuthorisationChanged(resolverEvent); + + resolver = getResolver(mockEvent.address); + + assert.assertNotNull(resolver); + }); + test("handleVersionChanged", () => { + const mockEvent = newMockEvent(); + const resolverEvent = new VersionChanged( + mockEvent.address, + mockEvent.logIndex, + mockEvent.transactionLogIndex, + mockEvent.logType, + mockEvent.block, + mockEvent.transaction, + mockEvent.parameters, + mockEvent.receipt + ); + resolverEvent.parameters = new Array(); + + let nodeParam = new ethereum.EventParam( + "node", + ethereum.Value.fromFixedBytes(namehash) + ); + let newVersionParam = new ethereum.EventParam( + "newVersion", + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(1)) + ); + + resolverEvent.parameters.push(nodeParam); + resolverEvent.parameters.push(newVersionParam); + + let resolver = getResolver(mockEvent.address); + + assert.assertNull(resolver); + + handleVersionChanged(resolverEvent); + + resolver = getResolver(mockEvent.address); + + assert.assertNotNull(resolver); + }); +});