Skip to content

Commit

Permalink
feat: add utils functions to handle ERC-721 URNs (#172)
Browse files Browse the repository at this point in the history
  • Loading branch information
aleortega authored Aug 17, 2023
1 parent 2a38e9d commit 3cd4c6b
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 8 deletions.
9 changes: 9 additions & 0 deletions etc/urn-resolver.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,15 @@ export type EntityV3Asset = {
baseUrl?: string;
};

// @public
export function getTokenIdAndAssetUrn(completeUrn: string): {
assetUrn: string;
tokenId: string;
};

// @public
export function isExtendedUrn(asset: DecentralandAssetIdentifier): boolean;

// @public (undocumented)
export namespace LandUtils {
// (undocumented)
Expand Down
20 changes: 20 additions & 0 deletions src/collection-items-utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { DecentralandAssetIdentifier } from './types'

/**
* Checks if the URN follows the standard ERC-721 by having the tokenId identifier at the end
* @public
*/
export function isExtendedUrn(asset: DecentralandAssetIdentifier): boolean {
return ['blockchain-collection-v1-item', 'blockchain-collection-v2-item'].includes(asset.type)
}

/**
* Takes an URN adhering to the ERC-721 standard and resolves both its asset URN and token identity
* WARNING: it assumes the URN received follows the ERC-721 standard and that its last part refers to the token id
* @public
*/
export function getTokenIdAndAssetUrn(completeUrn: string): { assetUrn: string; tokenId: string } {
const lastColonIndex = completeUrn.lastIndexOf(':')
const urnValue = completeUrn.slice(0, lastColonIndex)
return { assetUrn: urnValue, tokenId: completeUrn.slice(lastColonIndex + 1) }
}
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ export * from './types'
export { LandUtils } from './land-utils'
import { resolveContentUrl, ResolversOptions } from './content-url-resolver'
export { resolveContentUrl, ResolversOptions }
export { isExtendedUrn, getTokenIdAndAssetUrn } from './collection-items-utils'

/**
* Function that parses an URN and returns a DecentralandAssetIdentifier record or null.
* @public
Expand Down
15 changes: 7 additions & 8 deletions src/resolvers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,23 +29,22 @@ export const resolvers: RouteMap<DecentralandAssetIdentifier> = {
// collections v1 asset (by contract)
'decentraland:{network}:collections-v1:{contract(0x[a-fA-F0-9]+)}:{name}': resolveCollectionV1Asset,
// collections v1 item (by asset name and token id)
'decentraland:{network}:collections-v1:{contract(0x[a-fA-F0-9]+)}:{name}:{tokenId([0-9]+)}':
resolveCollectionV1AssetTokenId,
'decentraland:{network}:collections-v1:{contract(0x[a-fA-F0-9]+)}:{name}:{tokenId([0-9]+)}': resolveCollectionV1Item,
// collections v1 asset (by name)
'decentraland:{network}:collections-v1:{collectionName}:{name}': resolveCollectionV1AssetByCollectionName,
// collections v1 item (by asset name and token id)
'decentraland:{network}:collections-v1:{collectionName}:{name}:{tokenId([0-9]+)}':
resolveCollectionV1AssetByCollectionNameTokenId,
resolveCollectionV1ItemByCollectionName,
// collections v2 asset (hex)
'decentraland:{network}:collections-v2:{contract(0x[a-fA-F0-9]+)}:{id(0x[a-fA-F0-9]+)}': resolveCollectionV2Asset,
// collections v2 item (by collection hex and token id)
'decentraland:{network}:collections-v2:{contract(0x[a-fA-F0-9]+)}:{id(0x[a-fA-F0-9]+)}:{tokenId([0-9]+)}':
resolveCollectionV2AssetTokenId,
resolveCollectionV2Item,
// collections v2 asset (id)
'decentraland:{network}:collections-v2:{contract(0x[a-fA-F0-9]+)}:{id([0-9]+)}': resolveCollectionV2Asset,
// collections v2 item (by collection asset and token id)
'decentraland:{network}:collections-v2:{contract(0x[a-fA-F0-9]+)}:{id([0-9]+)}:{tokenId([0-9]+)}':
resolveCollectionV2AssetTokenId,
resolveCollectionV2Item,
// collections v1 (by contract)
'decentraland:{network}:collections-v1:{contract(0x[a-fA-F0-9]+)}': resolveCollectionV1,
// collections v1 (by name)
Expand Down Expand Up @@ -234,7 +233,7 @@ export async function resolveCollectionV1AssetByCollectionName(
}
}

export async function resolveCollectionV1AssetByCollectionNameTokenId(
export async function resolveCollectionV1ItemByCollectionName(
uri: URL,
groups: Record<'network' | 'collectionName' | 'name' | 'tokenId', string>
): Promise<BlockchainCollectionV1Item | undefined> {
Expand Down Expand Up @@ -283,7 +282,7 @@ export async function resolveCollectionV1Asset(
return result
}

export async function resolveCollectionV1AssetTokenId(
export async function resolveCollectionV1Item(
uri: URL,
groups: Record<'network' | 'contract' | 'name' | 'tokenId', string>
): Promise<BlockchainCollectionV1Item | undefined> {
Expand Down Expand Up @@ -335,7 +334,7 @@ export async function resolveCollectionV2Asset(
return result
}

export async function resolveCollectionV2AssetTokenId(
export async function resolveCollectionV2Item(
uri: URL,
groups: Record<'network' | 'contract' | 'id' | 'tokenId', string>
): Promise<BlockchainCollectionV2Item | undefined> {
Expand Down
6 changes: 6 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ export type BlockchainCollectionV1Asset = {
*/
export type BlockchainCollectionV1Item = Omit<BlockchainCollectionV1Asset, 'type'> & {
type: 'blockchain-collection-v1-item'
/**
* Asset identifier for ERC721 contracts
*/
tokenId: string
}

Expand Down Expand Up @@ -113,6 +116,9 @@ export type BlockchainCollectionV2Asset = BaseBlockchainAsset & {
*/
export type BlockchainCollectionV2Item = Omit<BlockchainCollectionV2Asset, 'type'> & {
type: 'blockchain-collection-v2-item'
/**
* Asset identifier for ERC721 contracts
*/
tokenId: string
}

Expand Down

0 comments on commit 3cd4c6b

Please sign in to comment.