@unique-nft/utils
Version:
A tiny library to work with Substrate and Ethereum addresses and do some more
1 lines • 21.3 kB
Source Map (JSON)
{"version":3,"sources":["../src/ChainLens/ChainLens.ts","../src/ChainLens/index.ts"],"sourcesContent":["import {Address, CrossAccountIdUncapitalized, EnhancedCrossAccountId} from '../index'\n\nimport {Utf8, Utf16, HexString} from 'utf-helpers'\n\ntype MakeFieldsNullable<Ob> = { [K in keyof Ob]: Ob[K] | null }\n\nexport enum UNIQUE_CHAINS {\n unique = 'unique',\n quartz = 'quartz',\n opal = 'opal',\n sapphire = 'sapphire',\n rc = 'rc',\n}\n\nconst UNIQUE_RPCs: { [K in UNIQUE_CHAINS]: string } = {\n quartz: 'https://rpc-quartz.unique.network/',\n opal: 'https://rpc-opal.unique.network/',\n unique: 'https://rpc.unique.network/',\n sapphire: 'https://rpc-sapphire.unique.network/',\n rc: 'https://rpc-rc.unique.network/',\n}\n\ntype RequestRPC = <T = any>(method: string, params: unknown[]) => Promise<T>\n\nconst requestRPCFactory = (rpcUrl: string): RequestRPC => async (method, params) => {\n const fetch = globalThis.fetch\n const response = await fetch(rpcUrl, {\n method: 'POST',\n headers: {'Content-Type': 'application/json'},\n body: JSON.stringify({jsonrpc: \"2.0\", id: 1, method, params}),\n })\n const result = await response.json()\n return result.result\n}\n\nexport type TokenPropertyPermissionValue = {\n mutable: boolean\n collection_admin: boolean\n token_owner: boolean\n}\nexport type TokenPropertyPermission = {\n key: string\n keyHex: string\n permission: TokenPropertyPermissionValue\n}\n\nconst decodeTPPArray = (arr: Array<{ key: number[], permission: any }>): TokenPropertyPermission[] => {\n return arr.map(({key, permission}) => {\n return {\n key: Utf8.numberArrayToString(key),\n keyHex: HexString.fromArray(key),\n permission: permission as TokenPropertyPermissionValue,\n }\n })\n}\n\nexport interface DecodedProperty {\n key: string\n value: string\n keyHex: string\n valueHex: string\n}\n\nexport interface DecodedPropertyWithTokenPropertyPermission extends DecodedProperty {\n tokenPropertyPermission: TokenPropertyPermissionValue\n}\n\nexport type DecodedPropertiesMap = Record<string, DecodedProperty>\nexport type DecodedPropertiesWithTokenPropertyPermissionsMap = Record<string, DecodedPropertyWithTokenPropertyPermission>\n\nconst decodeCollectionProperties = (arr: Array<{ key: number[], value: number[] }>): { properties: DecodedProperty[], propertiesMap: DecodedPropertiesMap } => {\n const properties: DecodedProperty[] = []\n const propertiesMap: Record<string, DecodedProperty> = {}\n\n for (const elem of arr) {\n const {key, value} = elem\n const decoded: DecodedProperty = {\n key: Utf8.numberArrayToString(key),\n keyHex: HexString.fromArray(key),\n value: Utf8.numberArrayToString(value),\n valueHex: HexString.fromArray(value),\n }\n properties.push(decoded)\n propertiesMap[decoded.key] = decoded\n }\n return {\n properties,\n propertiesMap,\n }\n}\n\nconst decodeTokenProperties = (arr: Array<{ key: number[], value: number[] }>, tpps: TokenPropertyPermission[]): { properties: DecodedPropertyWithTokenPropertyPermission[], propertiesMap: DecodedPropertiesWithTokenPropertyPermissionsMap } => {\n const {properties, propertiesMap} = decodeCollectionProperties(arr) as {\n properties: DecodedPropertyWithTokenPropertyPermission[]\n propertiesMap: DecodedPropertiesWithTokenPropertyPermissionsMap\n }\n\n for (const property of properties) {\n const tppValue = tpps.find(tpp => tpp.keyHex === property.keyHex)!.permission\n property.tokenPropertyPermission = tppValue\n propertiesMap[property.key].tokenPropertyPermission = tppValue\n }\n\n return {\n properties,\n propertiesMap,\n }\n}\n\nexport interface CollectionEffectiveLimits { // default value\n account_token_ownership_limit: number // 100000\n owner_can_destroy: boolean // true\n owner_can_transfer: boolean // false\n sponsor_approve_timeout: number // 5\n sponsor_transfer_timeout: number // 5\n sponsored_data_rate_limit: 'SponsoringDisabled' | { Blocks: number } // \"SponsoringDisabled\"\n sponsored_data_size: number // 2048\n token_limit: number // 4294967295\n transfers_enabled: boolean // true\n}\n\nexport type CollectionLimits = MakeFieldsNullable<CollectionEffectiveLimits>\n\nexport type DecodedCollectionLimits = {\n [K in keyof CollectionEffectiveLimits]: {\n key: K\n value: CollectionEffectiveLimits[K]\n isDefaultValue: boolean\n }\n}\n\nexport interface CollectionPermissions { // default value\n access: 'Normal' | 'AllowList' // 'Normal'\n mint_mode: boolean // false\n nesting: {\n token_owner: boolean // false\n collection_admin: boolean // false\n restricted: null | number[] // null\n }\n}\n\nexport type CollectionType = 'NFT' | 'RFT' | 'FT'\n\nexport interface ICollection {\n collectionId: number\n collectionAddress: string\n owner: EnhancedCrossAccountId\n adminList: EnhancedCrossAccountId[]\n mode: 'NFT' | 'ReFungible' | { Fungible: number }\n name: string\n description: string\n tokenPrefix: string\n sponsorship: 'Disabled' | { Confirmed: string } | { Unconfirmed: string }\n decodedSponsorship: {\n enabled: boolean\n confirmed: boolean\n sponsor: EnhancedCrossAccountId | null\n }\n lastTokenId: number\n limits: CollectionLimits\n decodedLimits: DecodedCollectionLimits\n permissions: CollectionPermissions\n tokenPropertyPermissions: TokenPropertyPermission[]\n properties: DecodedProperty[]\n propertiesMap: DecodedPropertiesMap\n readOnly: boolean\n additionalInfo: {\n isNFT: boolean\n isRFT: boolean\n isFT: boolean\n type: CollectionType\n }\n flags?: {foreign: boolean, erc721metadata: boolean}\n}\n\nexport interface INftToken {\n collectionId: number\n tokenId: number\n collectionAddress: string\n tokenAddress: string\n owner: EnhancedCrossAccountId\n\n properties: DecodedPropertyWithTokenPropertyPermission[]\n propertiesMap: DecodedPropertiesWithTokenPropertyPermissionsMap\n}\n\nexport interface IRftToken {\n collectionId: number\n tokenId: number\n collectionAddress: string\n tokenAddress: string\n\n pieces: number\n\n owners: EnhancedCrossAccountId[]\n allOwnersAreKnown: boolean\n isOnlyOneOwner: boolean\n\n properties: DecodedPropertyWithTokenPropertyPermission[]\n propertiesMap: DecodedPropertiesWithTokenPropertyPermissionsMap\n}\n\n\nexport const requestCollection = async (requestRPC: RequestRPC, collectionId: number, ss58Prefix: number): Promise<ICollection | null> => {\n const rawCollection = await requestRPC(\"unique_collectionById\", [collectionId])\n if (!rawCollection) return null\n\n const {properties, propertiesMap} = decodeCollectionProperties(rawCollection.properties)\n\n const [\n adminListResult,\n effectiveLimits,\n lastTokenId,\n ] = await Promise.all([\n requestRPC('unique_adminlist', [collectionId]) as Promise<CrossAccountIdUncapitalized[]>,\n requestRPC('unique_effectiveCollectionLimits', [collectionId]) as Promise<CollectionEffectiveLimits>,\n requestRPC('unique_lastTokenId', [collectionId]) as Promise<number>,\n ])\n\n const adminList = adminListResult.map(crossAccountId => Address.extract.enhancedCrossAccountId(crossAccountId, ss58Prefix))\n\n const decodedLimits = Object.entries(effectiveLimits).reduce((acc, elem) => {\n const [key, value] = elem as [keyof CollectionEffectiveLimits, CollectionEffectiveLimits[keyof CollectionEffectiveLimits]]\n\n acc[key] = {\n key,\n value,\n isDefaultValue: rawCollection.limits[key] === null\n } as any\n\n return acc\n }, {} as DecodedCollectionLimits)\n\n const isNFT = rawCollection.mode === 'NFT'\n const isRFT = rawCollection.mode === 'ReFungible'\n const isFT = typeof rawCollection.mode === 'object' && typeof rawCollection.mode?.Fungible === 'number'\n\n const decodedSponsorship: ICollection['decodedSponsorship'] = {\n enabled: typeof rawCollection.sponsorship !== 'string',\n confirmed: !!rawCollection.sponsorship?.Confirmed,\n sponsor: typeof rawCollection.sponsorship === 'object' && !!rawCollection.sponsorship\n ? rawCollection.sponsorship.Confirmed\n ? Address.extract.enhancedCrossAccountId(rawCollection.sponsorship.Confirmed, ss58Prefix)\n : Address.extract.enhancedCrossAccountId(rawCollection.sponsorship.Unconfirmed, ss58Prefix)\n : null\n }\n\n const collection: ICollection = {\n ...rawCollection,\n collectionId,\n collectionAddress: Address.collection.idToAddress(collectionId),\n owner: Address.extract.enhancedCrossAccountId(rawCollection.owner, ss58Prefix),\n adminList,\n mode: rawCollection.mode,\n name: Utf16.numberArrayToString(rawCollection.name),\n description: Utf16.numberArrayToString(rawCollection.description),\n tokenPrefix: Utf8.numberArrayToString(rawCollection.token_prefix),\n sponsorship: rawCollection.sponsorship,\n decodedSponsorship,\n lastTokenId,\n limits: rawCollection.limits,\n decodedLimits,\n permissions: rawCollection.permissions,\n tokenPropertyPermissions: decodeTPPArray(rawCollection.token_property_permissions),\n properties,\n propertiesMap,\n readOnly: rawCollection.read_only as boolean,\n additionalInfo: {\n isNFT, isRFT, isFT,\n type: isRFT ? 'RFT' : isFT ? 'FT' : 'NFT'\n },\n flags: rawCollection.flags || undefined\n }\n return collection\n}\n\nexport const requestNftToken = async (requestRPC: RequestRPC, collectionId: number, tokenId: number, ss58Prefix: number): Promise<INftToken | null> => {\n const [rawCollection, rawToken] = await Promise.all([\n requestRPC(\"unique_collectionById\", [collectionId]),\n requestRPC(\"unique_tokenData\", [collectionId, tokenId]),\n ])\n\n if (!rawCollection || rawCollection.mode !== 'NFT' || !rawToken || !rawToken.owner) {\n return null\n }\n\n const {properties, propertiesMap} = decodeTokenProperties(\n rawToken.properties,\n decodeTPPArray(rawCollection.token_property_permissions)\n )\n\n const nftToken: INftToken = {\n collectionId,\n tokenId,\n collectionAddress: Address.collection.idToAddress(collectionId),\n tokenAddress: Address.nesting.idsToAddress(collectionId, tokenId),\n\n owner: Address.extract.enhancedCrossAccountId(rawToken.owner, ss58Prefix),\n\n properties,\n propertiesMap,\n }\n return nftToken\n}\n\n\nexport const requestRftToken = async (requestRPC: RequestRPC, collectionId: number, tokenId: number, ss58Prefix: number): Promise<IRftToken | null> => {\n const [rawCollection, rawToken] = await Promise.all([\n requestRPC(\"unique_collectionById\", [collectionId]),\n requestRPC(\"unique_tokenData\", [collectionId, tokenId]),\n ])\n\n if (!rawCollection || rawCollection.mode !== 'ReFungible' || !rawToken || typeof rawToken.pieces !== 'number') { // protects from NFT/FT collections and from chains below 929030\n return null\n }\n\n let owners: EnhancedCrossAccountId[] = []\n let allOwnersAreKnown = true\n\n if (rawToken.owner) {\n owners = [Address.extract.enhancedCrossAccountId(rawToken.owner, ss58Prefix)]\n } else {\n owners = (await requestRPC<CrossAccountIdUncapitalized[]>('unique_tokenOwners', [collectionId, tokenId]))\n .map(crossAccountId => Address.extract.enhancedCrossAccountId(crossAccountId, ss58Prefix))\n allOwnersAreKnown = owners.length < 10\n }\n\n const {properties, propertiesMap} = decodeTokenProperties(\n rawToken.properties,\n decodeTPPArray(rawCollection.token_property_permissions)\n )\n\n const rftToken: IRftToken = {\n collectionId,\n tokenId,\n collectionAddress: Address.collection.idToAddress(collectionId),\n tokenAddress: Address.nesting.idsToAddress(collectionId, tokenId),\n\n owners,\n allOwnersAreKnown,\n isOnlyOneOwner: !!rawToken.owner,\n\n pieces: rawToken.pieces,\n\n properties,\n propertiesMap,\n }\n return rftToken\n}\n\nconst collectionIdOrAddressToCollectionId = (collectionIdOrAddress: number | string): number => {\n return typeof collectionIdOrAddress === 'string'\n ? Address.collection.addressToId(collectionIdOrAddress)\n : collectionIdOrAddress\n}\n\nexport interface ChainLensOptions {\n ss58Prefix: number\n}\n\nexport const generateChainLens = (rpcBaseUrlOrRequestRPC: string | RequestRPC, options: ChainLensOptions = {ss58Prefix: 42}) => {\n const requestRPC = typeof rpcBaseUrlOrRequestRPC === 'string' ? requestRPCFactory(rpcBaseUrlOrRequestRPC) : rpcBaseUrlOrRequestRPC\n\n const ss58Prefix = options.ss58Prefix\n\n return {\n get ss58Prefix() {\n return ss58Prefix\n },\n requestRPC: async <T = any>(method: string, params: unknown[]): Promise<T> => {\n return requestRPC(method, params)\n },\n requestCollection: async (collectionIdOrAddress: number | string) => {\n const collectionId = collectionIdOrAddressToCollectionId(collectionIdOrAddress)\n\n return requestCollection(requestRPC, collectionId, ss58Prefix)\n },\n requestNftToken: async (collectionIdOrAddress: number | string, tokenId: number) => {\n const collectionId = collectionIdOrAddressToCollectionId(collectionIdOrAddress)\n\n return requestNftToken(requestRPC, collectionId, tokenId, ss58Prefix)\n },\n requestNftTokenByAddress: async (tokenAddress: string) => {\n const {collectionId, tokenId} = Address.nesting.addressToIds(tokenAddress)\n\n return requestNftToken(requestRPC, collectionId, tokenId, ss58Prefix)\n },\n requestRftToken: async (collectionIdOrAddress: number | string, tokenId: number) => {\n const collectionId = collectionIdOrAddressToCollectionId(collectionIdOrAddress)\n\n return requestRftToken(requestRPC, collectionId, tokenId, ss58Prefix)\n },\n requestRftTokenByAddress: async (tokenAddress: string) => {\n const {collectionId, tokenId} = Address.nesting.addressToIds(tokenAddress)\n\n return requestRftToken(requestRPC, collectionId, tokenId, ss58Prefix)\n },\n }\n}\n\nexport type IChainLens = ReturnType<typeof generateChainLens>\n\nexport const ChainLenses: { [K in UNIQUE_CHAINS]: IChainLens } = {\n unique: generateChainLens(UNIQUE_RPCs.unique, {ss58Prefix: 7391}),\n quartz: generateChainLens(UNIQUE_RPCs.quartz, {ss58Prefix: 255}),\n opal: generateChainLens(UNIQUE_RPCs.opal, {ss58Prefix: 42}),\n sapphire: generateChainLens(UNIQUE_RPCs.sapphire, {ss58Prefix: 8883}),\n rc: generateChainLens(UNIQUE_RPCs.rc, {ss58Prefix: 42}),\n}\n","import {ChainLenses, generateChainLens} from './ChainLens'\n\nconst constants = {\n maxRefungiblePieces: 1000000000000000000000n,\n collectionCreationPrice: 2,\n}\n\nexport {ChainLenses, constants, generateChainLens}\nexport default ChainLenses\n\nexport type {\n DecodedProperty,\n UNIQUE_CHAINS,\n IChainLens,\n INftToken,\n IRftToken,\n ICollection,\n CollectionType,\n DecodedPropertiesMap,\n DecodedCollectionLimits,\n CollectionLimits,\n CollectionEffectiveLimits,\n CollectionPermissions,\n TokenPropertyPermission,\n TokenPropertyPermissionValue,\n} from './ChainLens'\n\n"],"mappings":"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","names":[]}