Skip to content
This repository was archived by the owner on May 22, 2025. It is now read-only.

Feat: Add IPFS fallback logic to fetch metadata#89

Merged
0xGabi merged 14 commits intomasterfrom
ipfs-fallback
Jul 3, 2020
Merged

Feat: Add IPFS fallback logic to fetch metadata#89
0xGabi merged 14 commits intomasterfrom
ipfs-fallback

Conversation

@0xGabi
Copy link
Copy Markdown
Contributor

@0xGabi 0xGabi commented Jun 29, 2020

This PR includes a new async method create() for the entities that need metadata (App, Repo, and Role). This a requirement when creating the entity. We handle this during creation at the connector.

If we can't get the metadata from The Graph we use ethers to fetch with a GET request constructing the URL from the contentUri pointing to the default Aragon IPFS node.

@0xGabi 0xGabi requested review from bpierre and eternauta1337 June 29, 2020 23:01
Comment thread packages/connect-core/src/entities/Organization.ts Outdated
Copy link
Copy Markdown
Contributor

@Evalir Evalir left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❤️ Asking some questions!

Comment thread packages/connect-core/src/entities/Organization.ts Outdated
}

this.address = data.address
this.contentUri = data.contentUri ?? undefined
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ES2020 🤩 wouldn't it be better to return null?

Copy link
Copy Markdown
Contributor Author

@0xGabi 0xGabi Jun 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank for the suggestions. I think in this particular case the problem is that we are implementing the RepositoryData interface and the contentUri has those types. Regardless I agree there is something a bit odd here, and I believe it's a consequence of allowing data on The Graph to be undefined / null.

Anyways I like to know why you think null would be better than undefined?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's probably due to my mental model regarding null & undefined; for me, null is the proper thing to use when there's no value. It indicates the absence of it. undefined, for me, indicates problems with fetching some data, a function that returns nothing (void) or some other anomalous development in processing data.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed on the mental model, I see null as “empty”, while undefined is “nothing”. I also like to keep using the same type when it makes sense, e.g. here we could use "", or if it was a list we could use []: it removes the need to treat null / undefined as an exception for the consumer.

…I wish JS only had null 😆

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that you mention about using an empty object of the particular type. I was wondering if we should do that at the subgraph level and always asure that at least we have an empty object. At least for the most part of the attributes.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that you mention about using an empty object of the particular type. I was wondering if we should do that at the subgraph level and always asure that at least we have an empty object. At least for the most part of the attributes.

I think it could be nice yes. 👍

Comment thread packages/connect-core/src/entities/Role.ts Outdated
@codecov
Copy link
Copy Markdown

codecov Bot commented Jun 30, 2020

Codecov Report

Merging #89 into master will decrease coverage by 0.70%.
The diff coverage is 19.84%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master      #89      +/-   ##
==========================================
- Coverage   28.82%   28.12%   -0.71%     
==========================================
  Files          53       54       +1     
  Lines         836      889      +53     
  Branches      137      145       +8     
==========================================
+ Hits          241      250       +9     
- Misses        595      639      +44     
Flag Coverage Δ
#unittests 28.12% <19.84%> (-0.71%) ⬇️
Impacted Files Coverage Δ
packages/connect-core/src/entities/App.ts 0.00% <0.00%> (ø)
packages/connect-core/src/entities/Organization.ts 0.00% <0.00%> (ø)
packages/connect-core/src/entities/Permission.ts 0.00% <0.00%> (ø)
packages/connect-core/src/entities/Repo.ts 0.00% <0.00%> (ø)
packages/connect-core/src/entities/Role.ts 0.00% <0.00%> (ø)
packages/connect-core/src/params.ts 0.00% <0.00%> (ø)
packages/connect-core/src/utils/metadata.ts 0.00% <0.00%> (ø)
...ckages/connect-thegraph/src/core/GraphQLWrapper.ts 43.39% <25.00%> (ø)
packages/connect-thegraph/src/parsers/roles.ts 68.96% <80.00%> (-1.41%) ⬇️
packages/connect-thegraph/src/parsers/apps.ts 93.33% <100.00%> (+1.33%) ⬆️
... and 3 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update d12ca93...079ed25. Read the comment docs.

@0xGabi 0xGabi marked this pull request as ready for review June 30, 2020 14:00
Copy link
Copy Markdown
Contributor

@bpierre bpierre left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left some comments, let me know what you think!

Comment on lines +42 to +51
abi?: Abi
appName?: string
author?: string
contractPath?: string
deprecatedIntents?: { [version: string]: AppIntent[] }
description?: string
icons?: { src: string; sizes: string }[]
intents?: AppIntent[]
htmlUrl?: string
sourceUrl?: string
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I didn’t think about that… I’m wondering if it’s worth using readonly at all then?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we are going to use a method _init() / create() always required probably not worth it. I can't think other alternatives to try to have readonly otherwise.

Comment on lines +73 to +95
const {
appName,
path,
functions,
deprecatedFunctions,
abi,
}: AragonArtifact = await resolveMetadata(
'artifact.json',
this.contentUri!,
this.#artifact
)

const {
author,
description,
start_url: htmlUrl,
icons,
source_url: sourceUrl,
}: AragonManifest = await resolveMetadata(
'manifest.json',
this.contentUri!,
this.#manifest
)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably try / catch these two, and emit contextual errors.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I decide to handle it in the resolveMetadata function. What you think?

Comment thread packages/connect-core/src/entities/Role.ts Outdated
Comment thread packages/connect-core/src/entities/Role.ts Outdated
@0xGabi 0xGabi requested review from Evalir and bpierre July 2, 2020 03:58
@0xGabi
Copy link
Copy Markdown
Contributor Author

0xGabi commented Jul 2, 2020

As we discussed with Pierre I move the logic of _init() to create() instead. Then I move the method call to the connector so we have both the instantiation of a new object and the call to create() method together.

@0xGabi
Copy link
Copy Markdown
Contributor Author

0xGabi commented Jul 2, 2020

Note I split the PRs to keep the changes more clear.

@sohkai
Copy link
Copy Markdown
Contributor

sohkai commented Jul 3, 2020

We use ethers to fetch with a GET request constructing the URL from the contentUri pointing to the default Aragon IPFS node

I was thinking about this (moreso in the context of a CLI/frontend using connect to connect to generic apps that may or may not be hosted by our default IPFS node), and I think it's important to provide a way to override the default IPFS gateway used.

return this.#created
}

async create({ artifact, manifest, ...data }: AppData): Promise<void> {
Copy link
Copy Markdown
Contributor

@bpierre bpierre Jul 3, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For create(), I was more thinking of a static method, that would fetch everything needed and instantiate, so we can do this:

const app = await App.create(/* … */)

Rather than this:

const app = new App(/* … */)
await app.create()

That way, App would never be in a state where it is instantiated, but not initialized.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I didn't think about that. I'll include this change as a new PR.

Comment thread packages/connect-core/src/entities/App.ts
this.htmlUrl = htmlUrl
this.kernelAddress = data.kernelAddress
this.name = data.name
this.registry = data.registry || undefined
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
this.registry = data.registry || undefined
this.registry = data.registry

@0xGabi 0xGabi merged commit 12ec1da into master Jul 3, 2020
@0xGabi 0xGabi deleted the ipfs-fallback branch July 3, 2020 16:38
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants