-
-
Notifications
You must be signed in to change notification settings - Fork 183
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix ipfs address generation #655
Changes from all commits
99e41e3
803fa01
6837f4a
7a06e51
f240901
57dc963
a32fe61
d4c8ade
3432359
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,6 +12,7 @@ import { ethErrors } from 'eth-rpc-errors'; | |
import ensNamehash from 'eth-ens-namehash'; | ||
import { TYPED_MESSAGE_SCHEMA, typedSignatureHash } from 'eth-sig-util'; | ||
import { validate } from 'jsonschema'; | ||
import { CID } from 'multiformats/cid'; | ||
import { | ||
Transaction, | ||
FetchAllOptions, | ||
|
@@ -769,19 +770,79 @@ export function validateMinimumIncrease(proposed: string, min: string) { | |
} | ||
|
||
/** | ||
* Extracts content identifier from ipfs url. | ||
* Removes IPFS protocol prefix from input string. | ||
* | ||
* @param url - Ipfs url. | ||
* @returns Ipfs content identifier as string. | ||
* @param ipfsUrl - An IPFS url (e.g. ipfs://{content id}) | ||
* @returns IPFS content identifier and (possibly) path in a string | ||
* @throws Will throw if the url passed is not IPFS. | ||
*/ | ||
export function getIpfsUrlContentIdentifier(url: string): string { | ||
if (url.startsWith('ipfs://ipfs/')) { | ||
return url.replace('ipfs://ipfs/', ''); | ||
} | ||
export function removeIpfsProtocolPrefix(ipfsUrl: string) { | ||
if (ipfsUrl.startsWith('ipfs://ipfs/')) { | ||
return ipfsUrl.replace('ipfs://ipfs/', ''); | ||
} else if (ipfsUrl.startsWith('ipfs://')) { | ||
return ipfsUrl.replace('ipfs://', ''); | ||
} | ||
// this method should not be used with non-ipfs urls (i.e. startsWith('ipfs://') === true) | ||
throw new Error('this method should not be used with non ipfs urls'); | ||
} | ||
|
||
if (url.startsWith('ipfs://')) { | ||
return url.replace('ipfs://', ''); | ||
/** | ||
* Extracts content identifier and path from an input string. | ||
* | ||
* @param ipfsUrl - An IPFS URL minus the IPFS protocol prefix | ||
* @returns IFPS content identifier (cid) and sub path as string. | ||
* @throws Will throw if the url passed is not ipfs. | ||
*/ | ||
export function getIpfsCIDv1AndPath( | ||
ipfsUrl: string, | ||
): { cid: string; path?: string } { | ||
const url = removeIpfsProtocolPrefix(ipfsUrl); | ||
|
||
// check if there is a path | ||
// (CID is everything preceding first forward slash, path is everything after) | ||
const index = url.indexOf('/'); | ||
const cid = index !== -1 ? url.substring(0, index) : url; | ||
const path = index !== -1 ? url.substring(index) : undefined; | ||
|
||
// We want to ensure that the CID is v1 (https://docs.ipfs.io/concepts/content-addressing/#identifier-formats) | ||
// because most cid v0s appear to be incompatible with IPFS subdomains | ||
return { | ||
cid: CID.parse(cid).toV1().toString(), | ||
path, | ||
}; | ||
} | ||
|
||
/** | ||
* Adds URL protocol prefix to input URL string if missing. | ||
* | ||
* @param urlString - An IPFS URL. | ||
* @returns A URL with a https:// prepended. | ||
*/ | ||
export function addUrlProtocolPrefix(urlString: string): string { | ||
Gudahtt marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if (!urlString.match(/(^http:\/\/)|(^https:\/\/)/u)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. NIt: This still only allows This might be an extreme edge case though. I don't know of any IPFS gateways run on non-HTTP/HTTPS protocols 🤔 I don't know much about this space though. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will research and handle in follow up PR! |
||
return `https://${urlString}`; | ||
} | ||
return urlString; | ||
} | ||
|
||
return url; | ||
/** | ||
* Formats URL correctly for use retrieving assets hosted on IPFS. | ||
* | ||
* @param ipfsGateway - The users preferred IPFS gateway (full URL or just host). | ||
* @param ipfsUrl - The IFPS URL pointed at the asset. | ||
* @param subdomainSupported - Boolean indicating whether the URL should be formatted with subdomains or not. | ||
* @returns A formatted URL, with the user's preferred IPFS gateway and format (subdomain or not), pointing to an asset hosted on IPFS. | ||
*/ | ||
export function getFormattedIpfsUrl( | ||
ipfsGateway: string, | ||
ipfsUrl: string, | ||
subdomainSupported: boolean, | ||
): string { | ||
const { host, protocol, origin } = new URL(addUrlProtocolPrefix(ipfsGateway)); | ||
if (subdomainSupported) { | ||
const { cid, path } = getIpfsCIDv1AndPath(ipfsUrl); | ||
return `${protocol}//${cid}.ipfs.${host}${path ?? ''}`; | ||
} | ||
const cidAndPath = removeIpfsProtocolPrefix(ipfsUrl); | ||
return `${origin}/ipfs/${cidAndPath}`; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: It's probably also worth ensuring that
http
URLs are handled correctly as wellThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will handle in follow up PR!