-
+
-
-
{{ $formatMessage('asset_filter_owned_assets') }}
-
{{ $formatMessage('asset_filter_created_assets') }}
+
+
+ {{ $formatMessage('asset_filter_owned_assets') }}
+ {{ $formatMessage('asset_filter_created_assets') }}
+
+
+
+
+
-
-
diff --git a/public/images/lyx-token.jpg b/public/images/lyx-token.jpg
new file mode 100644
index 00000000..9a09e42a
Binary files /dev/null and b/public/images/lyx-token.jpg differ
diff --git a/public/images/token-default.svg b/public/images/token-default.svg
new file mode 100644
index 00000000..9e2e1940
--- /dev/null
+++ b/public/images/token-default.svg
@@ -0,0 +1,30 @@
+
diff --git a/shared/config.ts b/shared/config.ts
index 5087dba1..1e726e6e 100644
--- a/shared/config.ts
+++ b/shared/config.ts
@@ -8,7 +8,6 @@ export const NETWORKS: NetworkInfo[] = [
name: 'LUKSO Testnet',
chainId: '0x1069',
rpcHttp: 'https://rpc.testnet.lukso.gateway.fm',
- ipfsUrl: 'https://2eff.lukso.dev/ipfs/',
storeUrls: {
chrome:
'https://chrome.google.com/webstore/detail/universal-profiles-testin/abpickdkkbnbcoepogfhkhennhfhehfn',
@@ -26,7 +25,6 @@ export const NETWORKS: NetworkInfo[] = [
name: 'LUKSO Mainnet',
chainId: '0x2a',
rpcHttp: 'https://rpc.lukso.gateway.fm',
- ipfsUrl: 'https://2eff.lukso.dev/ipfs/',
storeUrls: {
chrome: '',
brave: '',
@@ -49,3 +47,9 @@ export const CONNECTION_EXPIRY_TIME_MS = 1000 * 60 * 30 // 30 minutes
// interval to check if the user is still connected
export const CONNECTION_EXPIRY_CHECK_INTERVAL_MS = 1000 * 10 // 10 seconds
+
+// placeholder icon if asset icon is not available
+export const ASSET_ICON_PLACEHOLDER_URL = '/images/token-default.svg'
+
+// url of the ipfs gateway
+export const IPFS_URL = 'https://2eff.lukso.dev/ipfs/'
diff --git a/shared/errors.ts b/shared/errors.ts
index 91410947..e3249fd4 100644
--- a/shared/errors.ts
+++ b/shared/errors.ts
@@ -3,3 +3,9 @@ export class EoAError extends Error {
super('The profile is an EoA')
}
}
+
+export class InterfaceError extends Error {
+ constructor(interfaceId: string) {
+ super(`This profile contract doesn't support ${interfaceId} interface`)
+ }
+}
diff --git a/shared/schemas/LSP8IdentifiableDigitalAsset.json b/shared/schemas/LSP8IdentifiableDigitalAsset.json
new file mode 100644
index 00000000..7d0af41f
--- /dev/null
+++ b/shared/schemas/LSP8IdentifiableDigitalAsset.json
@@ -0,0 +1,51 @@
+[
+ {
+ "name": "LSP8MetadataAddress:
",
+ "key": "0x73dcc7c3c4096cdc7f8a0000",
+ "keyType": "Mapping",
+ "valueType": "Mixed",
+ "valueContent": "Mixed"
+ },
+ {
+ "name": "LSP8MetadataAddress:",
+ "key": "0x73dcc7c3c4096cdc7f8a0000",
+ "keyType": "Mapping",
+ "valueType": "Mixed",
+ "valueContent": "Mixed"
+ },
+ {
+ "name": "LSP8MetadataAddress:",
+ "key": "0x73dcc7c3c4096cdc7f8a0000",
+ "keyType": "Mapping",
+ "valueType": "Mixed",
+ "valueContent": "Mixed"
+ },
+ {
+ "name": "LSP8MetadataJSON:",
+ "key": "0x9a26b4060ae7f7d5e3cd0000",
+ "keyType": "Mapping",
+ "valueType": "bytes",
+ "valueContent": "JSONURL"
+ },
+ {
+ "name": "LSP8MetadataJSON:",
+ "key": "0x9a26b4060ae7f7d5e3cd0000",
+ "keyType": "Mapping",
+ "valueType": "bytes",
+ "valueContent": "JSONURL"
+ },
+ {
+ "name": "LSP8MetadataJSON:",
+ "key": "0x9a26b4060ae7f7d5e3cd0000",
+ "keyType": "Mapping",
+ "valueType": "bytes",
+ "valueContent": "JSONURL"
+ },
+ {
+ "name": "LSP8TokenIdType",
+ "key": "0x715f248956de7ce65e94d9d836bfead479f7e70d69b718d47bfe7b00e05b4fe4",
+ "keyType": "Singleton",
+ "valueType": "uint256",
+ "valueContent": "Number"
+ }
+]
diff --git a/stores/connection.ts b/stores/connection.ts
index 1fa942b6..1028fce3 100644
--- a/stores/connection.ts
+++ b/stores/connection.ts
@@ -5,11 +5,7 @@
*/
export const useConnectionStore = defineStore('connection', () => {
const profile = reactive({} as Profile)
- const status = reactive({ isLoading: true, isConnected: false })
- const assets = reactive<{
- lsp7Assets: Lsp7AssetType[]
- lsp8Assets: Lsp8AssetType[]
- }>({ lsp7Assets: [], lsp8Assets: [] })
+ const status = reactive({ isConnected: false })
// --- actions
@@ -21,10 +17,6 @@ export const useConnectionStore = defineStore('connection', () => {
Object.assign(profile, newProfile)
}
- const setLoading = (newLoading: boolean) => {
- status.isLoading = newLoading
- }
-
const clearConnectedProfile = () => {
Object.assign(profile, {})
}
@@ -39,25 +31,13 @@ export const useConnectionStore = defineStore('connection', () => {
setConnectedProfile(profile)
}
- const setLsp7Assets = (newAssets: Lsp7AssetType[]) => {
- assets.lsp7Assets = newAssets
- }
-
- const setLsp8Assets = (newAssets: Lsp8AssetType[]) => {
- assets.lsp8Assets = newAssets
- }
-
return {
setConnectedAddress,
profile,
setConnectedProfile,
status,
- setLoading,
clearConnectedProfile,
setIsConnected,
reloadConnectedProfile,
- assets,
- setLsp7Assets,
- setLsp8Assets,
}
})
diff --git a/stores/profile.ts b/stores/profile.ts
index 9cfe2595..2bb22052 100644
--- a/stores/profile.ts
+++ b/stores/profile.ts
@@ -1,3 +1,13 @@
+import {
+ AssetFilter,
+ InterfaceId,
+ Nft,
+ SupportedAssets,
+ Token,
+ nftStandards,
+ tokenStandards,
+} from '@/types/assets'
+
/**
* Profile store
* Keeps the information about viewed profile
@@ -5,14 +15,69 @@
*/
export const useProfileStore = defineStore('profile', () => {
const profile = reactive({} as Profile)
- const status = reactive({ isLoading: true })
- const assets = reactive<{
- lsp7Assets: Lsp7AssetType[]
- lsp8Assets: Lsp8AssetType[]
- }>({ lsp7Assets: [], lsp8Assets: [] })
+ const status = reactive({ isProfileLoading: true, isAssetLoading: true })
+ const assetFilter = ref(AssetFilter.owned)
+ const ownedAssets = ref()
+ const createdAssets = ref()
+
+ // --- getters
+
+ const tokens = computed(() => {
+ return (assetFilter: AssetFilter) => {
+ let assets: SupportedAssets[] = []
+
+ switch (assetFilter) {
+ case AssetFilter.owned:
+ assets = ownedAssets.value || []
+ break
+ case AssetFilter.created:
+ assets = createdAssets.value || []
+ break
+ default:
+ return []
+ }
+
+ return (
+ (assets?.filter(asset =>
+ tokenStandards.includes(asset.standard as InterfaceId)
+ ) as Token[]) || []
+ )
+ }
+ })
+
+ const nfts = computed(() => {
+ return (assetFilter: AssetFilter) => {
+ let assets: SupportedAssets[] = []
+
+ switch (assetFilter) {
+ case AssetFilter.owned:
+ assets = ownedAssets.value || []
+ break
+ case AssetFilter.created:
+ assets = createdAssets.value || []
+ break
+ default:
+ return []
+ }
+
+ return (
+ (assets?.filter(nft =>
+ nftStandards.includes(nft.standard as InterfaceId)
+ ) as Nft[]) || []
+ )
+ }
+ })
// --- actions
+ const setOwnedAssets = (assets: SupportedAssets[]) => {
+ ownedAssets.value = assets
+ }
+
+ const setCreatedAssets = (assets: SupportedAssets[]) => {
+ createdAssets.value = assets
+ }
+
const setAddress = (newAddress: Address) => {
profile.address = newAddress
}
@@ -21,8 +86,8 @@ export const useProfileStore = defineStore('profile', () => {
Object.assign(profile, newProfile)
}
- const setLoading = (newLoading: boolean) => {
- status.isLoading = newLoading
+ const setStatus = (statusName: keyof typeof status, newStatus: boolean) => {
+ status[statusName] = newStatus
}
const clearProfile = () => {
@@ -35,24 +100,20 @@ export const useProfileStore = defineStore('profile', () => {
setProfile(profile)
}
- const setLsp7Assets = (newAssets: Lsp7AssetType[]) => {
- assets.lsp7Assets = newAssets
- }
-
- const setLsp8Assets = (newAssets: Lsp8AssetType[]) => {
- assets.lsp8Assets = newAssets
- }
-
return {
setAddress,
profile,
setProfile,
status,
- setLoading,
clearProfile,
reloadProfile,
- assets,
- setLsp7Assets,
- setLsp8Assets,
+ ownedAssets,
+ setOwnedAssets,
+ tokens,
+ assetFilter,
+ createdAssets,
+ nfts,
+ setStatus,
+ setCreatedAssets,
}
})
diff --git a/translations/en_US.json b/translations/en_US.json
index e6d6b01f..ec2c0429 100644
--- a/translations/en_US.json
+++ b/translations/en_US.json
@@ -1,26 +1,38 @@
{
"web3_eoa_error_message": "Please use Universal Profile Extension. ",
+ "button_send": "Send",
+ "asset_standard_info_LSP8_title": "LSP8 Token Standard",
+ "header_title": "Wallet",
+ "token_details_contract_address": "Contract Address",
"web3_connect_no_extension": "You don't have the Universal Profile browser extension installed.",
+ "asset_standard_info_legacy_details": "Info about the standard goes here....",
+ "asset_standard_info_LSP7_details": "Info about the standard goes here....",
"web3_connect_error_title": "Can't connect",
- "web3_connect_error_rejected_request": "User rejected the request.",
"web3_connect_error_pending_request": "You have pending request. Check your browser extension.",
- "web3_connect_error": "There was error while connecting to the browser extension.",
- "tokens_title": "Tokens",
+ "token_details_send": "Send {token}",
+ "asset_filter_owned_assets": "Owned assets",
+ "asset_standard_info_LSP8_details": "Info about the standard goes here....",
+ "web3_connect_error_rejected_request": "You rejected the request",
"modal_default_title": "Something went wrong...",
- "modal_default_confirm": "Ok",
- "header_title": "Wallet",
+ "footer_need_help_text": "NEED HELP?",
+ "asset_standard_info_LSP7_title": "LSP7 Token Standard",
+ "asset_filter_created_assets": "Created assets",
"header_send": "Send",
+ "asset_standard_info_legacy_title": "Legacy Token Standard",
+ "token_details_description": "Token Description",
"header_my_profile": "My profile",
- "header_disconnect": "Disconnect",
- "header_connect": "Connect",
"footer_terms_text": "Terms & Conditions",
- "footer_privacy_policy_text": "Privacy Policy",
- "footer_need_help_url": "mailto:support@lukso.network",
- "footer_need_help_text": "NEED HELP?",
+ "header_disconnect": "Disconnect",
+ "tokens_title": "Tokens",
"footer_faq_text": "FAQs",
+ "asset_created_by": "Created by",
"collectibles_title": "Collectibles",
- "button_send": "Send",
- "asset_filter_owned_assets": "Owned assets",
- "asset_filter_created_assets": "Created assets",
- "asset_created_by": "Created by"
+ "modal_default_confirm": "Ok",
+ "token_details_own": "You own this token",
+ "footer_need_help_url": "mailto:support@lukso.network",
+ "web3_interface_error_message": "You try to connect to legacy profile that is no longer supported.",
+ "header_connect": "Connect",
+ "web3_connect_error": "There was an error while connecting to the browser extension.",
+ "footer_privacy_policy_text": "Privacy Policy",
+ "token_details_images": "Token Images"
}
\ No newline at end of file
diff --git a/types/assets.ts b/types/assets.ts
new file mode 100644
index 00000000..3a78e975
--- /dev/null
+++ b/types/assets.ts
@@ -0,0 +1,78 @@
+import { INTERFACE_IDS } from '@lukso/lsp-smart-contracts'
+
+export type InterfaceId = keyof typeof INTERFACE_IDS
+export type SupportedStandards = keyof AssetApi
+export type SupportedAssets = Asset
+
+export const tokenStandards: InterfaceId[] = ['LSP7DigitalAsset', 'ERC20']
+export const nftStandards: InterfaceId[] = ['LSP8IdentifiableDigitalAsset']
+
+export const StandardsAbbreviations: { [K in InterfaceId]?: string } = {
+ LSP7DigitalAsset: 'LSP7',
+ ERC20: 'ERC20',
+ LSP8IdentifiableDigitalAsset: 'LSP8',
+}
+
+export interface Asset {
+ address: Address
+ standard?: InterfaceId
+ data: AssetApi[T]
+}
+
+export interface TokenApi {
+ LSP7DigitalAsset: LSP7Asset
+ ERC20: ERC20Asset
+}
+
+export type SupportedTokens = keyof TokenApi
+export type SupportedNfts = keyof NftApi
+export type Token = Asset>
+export type Nft = Asset>
+
+export interface NftApi {
+ LSP8IdentifiableDigitalAsset: LSP8Asset
+}
+
+export type AssetApi = TokenApi & NftApi
+
+export interface LSP7Asset {
+ name: string
+ symbol: string
+ amount: string
+ icon: string
+ address: string
+}
+
+export interface ERC20Asset {
+ name: string
+ symbol: string
+ amount: string
+ address: string
+}
+
+export interface LSP8Asset {
+ image: string
+ icon: string
+ tokenId: string
+ description: string
+ collectionName: string
+ collectionDescription: string
+ collectionImage: string
+ collectionIcon: string
+ collectionAddress: string
+ collectionSymbol: string
+ creatorName?: string
+ creatorAddress?: Address
+ creatorProfileImage?: string
+}
+
+export enum AssetFilter {
+ owned = 'owned',
+ created = 'created',
+}
+
+export enum TokenIdType {
+ address = '1',
+ number = '2',
+ bytes32 = '3',
+}
diff --git a/types/global.d.ts b/types/global.d.ts
index c4c098d2..208236e6 100644
--- a/types/global.d.ts
+++ b/types/global.d.ts
@@ -3,32 +3,15 @@ import { LSP3Profile } from '@lukso/lsp-factory.js'
declare global {
type Address = `0x${string}`
- interface Lsp7AssetType {
- name: string
- symbol: string
- amount: string
- icon: string
- address: string
- }
-
- interface Lsp8AssetType {
- image: string
- icon: string
- tokenId: string
- description: string
- collectionName: string
- collectionDescription: string
- collectionImage: string
- collectionIcon: string
- collectionAddress: string
- }
-
type Profile = LSP3Profile & {
backgroundImageUrl?: string
profileImageUrl?: string
address?: Address
+ balance: string
}
+ type Creator = Partial>
+
type NetworkId = string
type ChainIdHex = `0x${string}`
@@ -37,7 +20,6 @@ declare global {
name: string
rpcHttp: string
chainId: ChainIdHex
- ipfsUrl: string
storeUrls?: { [key in BrowserName]: string }
}
diff --git a/utils/detect-standard.ts b/utils/detect-standard.ts
new file mode 100644
index 00000000..03088cdf
--- /dev/null
+++ b/utils/detect-standard.ts
@@ -0,0 +1,38 @@
+import { INTERFACE_IDS } from '@lukso/lsp-smart-contracts'
+
+import { InterfaceId } from '@/types/assets'
+
+export const detectStandard = async (
+ contractAddress: Address
+): Promise => {
+ const { supportInterface } = useErc725()
+
+ // LSP0
+ if (
+ await supportInterface(contractAddress, INTERFACE_IDS.LSP0ERC725Account)
+ ) {
+ return 'LSP0ERC725Account'
+ }
+
+ // LSP7
+ if (await supportInterface(contractAddress, INTERFACE_IDS.LSP7DigitalAsset)) {
+ return 'LSP7DigitalAsset'
+ }
+
+ // LSP8
+ if (
+ await supportInterface(
+ contractAddress,
+ INTERFACE_IDS.LSP8IdentifiableDigitalAsset
+ )
+ ) {
+ return 'LSP8IdentifiableDigitalAsset'
+ }
+
+ // LSP9
+ if (await supportInterface(contractAddress, INTERFACE_IDS.LSP9Vault)) {
+ return 'LSP9Vault'
+ }
+
+ // TODO: add legacy standard detection (ERC20, ERC721, ERC1155...)
+}
diff --git a/utils/fetchLSP7Assets.ts b/utils/fetchLSP7Assets.ts
index fb68e0fb..474f8530 100644
--- a/utils/fetchLSP7Assets.ts
+++ b/utils/fetchLSP7Assets.ts
@@ -1,21 +1,51 @@
-export const fetchLSP7Assets = (/*profileAddress: Address*/) => {
- // TODO replace this with real asset fetching logic
- const lsp7Assets = [
- {
- name: 'LUKSO',
- symbol: 'LYX',
- amount: '10.000',
- icon: '',
- address: '0x463306b7D641FDff5D3E30947aC96074b705d4E8',
- },
- {
- name: 'LUKSO',
- symbol: 'LYX',
- amount: '10.000',
- icon: '',
- address: '0x463306b7D641FDff5D3E30947aC96074b705d4E8',
- },
- ] as Lsp7AssetType[]
-
- return lsp7Assets
+import LSP7DigitalAsset from '@lukso/lsp-smart-contracts/artifacts/LSP7DigitalAsset.json'
+import { LSP4DigitalAssetJSON } from '@lukso/lsp-factory.js/build/main/src/lib/interfaces/lsp4-digital-asset'
+
+import { PROVIDERS } from '@/types/enums'
+import { LSP7Asset } from '@/types/assets'
+import { ASSET_ICON_PLACEHOLDER_URL } from '@/shared/config'
+
+const fetchLSP7Assets = async (
+ assetAddress: Address,
+ profileAddress: Address
+): Promise => {
+ const { fetchLSP4Metadata } = useErc725()
+ const lsp4Metadata = await fetchLSP4Metadata(assetAddress)
+
+ // fetch amount of tokens received
+ const tokenBalance = await fetchLSP7Balance(assetAddress, profileAddress)
+
+ const lsp7Object = createLSP7Object(lsp4Metadata, tokenBalance, assetAddress)
+ return lsp7Object
+}
+
+const fetchLSP7Balance = async (
+ contractAddress: Address,
+ profileAddress: Address
+): Promise => {
+ const { contract } = useWeb3(PROVIDERS.RPC)
+ const lsp7Contract = contract(LSP7DigitalAsset.abi as any, contractAddress)
+ const balance = await lsp7Contract.methods.balanceOf(profileAddress).call()
+
+ return balance
}
+
+const createLSP7Object = (
+ lsp4DigitalAssetJSON: [string, string, LSP4DigitalAssetJSON],
+ tokenBalance: number,
+ assetAddress: Address
+): LSP7Asset => {
+ const [name, symbol, lsp4MetadataJSON] = lsp4DigitalAssetJSON
+ const lsp7AssetObject = {
+ name,
+ symbol,
+ amount: tokenBalance.toString(),
+ icon: lsp4MetadataJSON.LSP4Metadata.icon[0]?.url
+ ? lsp4MetadataJSON.LSP4Metadata.icon[0]?.url
+ : ASSET_ICON_PLACEHOLDER_URL,
+ address: assetAddress,
+ }
+ return lsp7AssetObject
+}
+
+export default fetchLSP7Assets
diff --git a/utils/fetchLSP8Assets.ts b/utils/fetchLSP8Assets.ts
index 8a0ab7e7..82236fc0 100644
--- a/utils/fetchLSP8Assets.ts
+++ b/utils/fetchLSP8Assets.ts
@@ -1,12 +1,103 @@
-export const fetchLSP8Assets = (/*profileAddress: Address*/) => {
- // TODO replace this with real asset fetching logic
- const lsp8Assets = [
- {
- collectionName: 'MetaShoe Axium',
- collectionIcon: 'MSA',
- collectionAddress: '0x463306b7D641FDff5D3E30947aC96074b705d4E8',
- },
- ] as Lsp8AssetType[]
-
- return lsp8Assets
+import { LSP4DigitalAssetJSON } from '@lukso/lsp-factory.js/build/main/src/lib/interfaces/lsp4-digital-asset'
+import LSP8IdentifiableDigitalAsset from '@lukso/lsp-smart-contracts/artifacts/LSP8IdentifiableDigitalAsset.json'
+
+import { LSP8Asset } from '@/types/assets'
+import { PROVIDERS } from '@/types/enums'
+
+export const fetchLSP8Assets = async (
+ assetAddress: Address,
+ profileAddress: Address
+) => {
+ // profile can have few ids of same LSP8 asset
+ const tokensIds = await fetchLSP8TokensIds(assetAddress, profileAddress)
+ console.log('tokensIds', tokensIds)
+
+ if (!tokensIds.length) {
+ return
+ }
+
+ const { fetchLSP4Metadata, fetchLSP8Metadata, fetchLSP4Creator } = useErc725()
+ const [collectionName, collectionSymbol, collectionLSP4Metadata] =
+ await fetchLSP4Metadata(assetAddress)
+
+ const newLSP8Assets: LSP8Asset[] = []
+
+ await Promise.all(
+ tokensIds.map(async tokenId => {
+ const nftMetadata = await fetchLSP8Metadata(tokenId, assetAddress)
+ const creatorMetadata = await fetchLSP4Creator(assetAddress)
+
+ const lsp8AssetObject: LSP8Asset = createLSP8Object(
+ assetAddress,
+ tokenId,
+ collectionName,
+ collectionSymbol,
+ nftMetadata,
+ collectionLSP4Metadata,
+ creatorMetadata
+ )
+ newLSP8Assets.push(lsp8AssetObject)
+ })
+ )
+ return newLSP8Assets
+}
+
+const fetchLSP8TokensIds = async (
+ contractAddress: string,
+ profileAddress: string
+): Promise => {
+ const { contract } = useWeb3(PROVIDERS.RPC)
+
+ const lsp8Contract = contract(
+ LSP8IdentifiableDigitalAsset.abi as any,
+ contractAddress
+ )
+
+ const tokensIds = (await lsp8Contract.methods
+ .tokenIdsOf(profileAddress)
+ .call()) as string[]
+ return tokensIds
+}
+
+const createLSP8Object = (
+ assetAddress: Address,
+ tokenId: string,
+ collectionName: string,
+ collectionSymbol: string,
+ nftMetadata: LSP4DigitalAssetJSON,
+ collectionMetadata: LSP4DigitalAssetJSON,
+ creatorMetadata?: Creator
+): LSP8Asset => {
+ const { description, images, icon } = nftMetadata.LSP4Metadata
+ const {
+ description: collectionDescription,
+ images: collectionImage,
+ icon: collectionIcon,
+ } = collectionMetadata.LSP4Metadata
+ const {
+ name: creatorName,
+ address: creatorAddress,
+ profileImageUrl: creatorProfileImage,
+ } = creatorMetadata || {}
+
+ const lsp8AssetObject = {
+ tokenId,
+ description,
+ image: images[0][0]?.url ? formatUrl(images[0][0].url) : '',
+ icon: icon[0]?.url ? formatUrl(icon[0].url) : '',
+ collectionName,
+ collectionSymbol,
+ collectionAddress: assetAddress,
+ collectionDescription,
+ collectionImage: collectionImage[0][0]?.url
+ ? formatUrl(collectionImage[0][0]?.url)
+ : '',
+ collectionIcon: formatUrl(collectionIcon[0]?.url)
+ ? collectionIcon[0]?.url
+ : '',
+ creatorName,
+ creatorAddress,
+ creatorProfileImage,
+ }
+ return lsp8AssetObject as LSP8Asset
}
diff --git a/utils/fetchProfile.ts b/utils/fetchProfile.ts
index 4a13e383..4ade8bb9 100644
--- a/utils/fetchProfile.ts
+++ b/utils/fetchProfile.ts
@@ -1,23 +1,24 @@
import { INTERFACE_IDS, SupportedStandards } from '@lukso/lsp-smart-contracts'
-import { eip165ABI } from '@/shared/abis/eip165ABI'
import { PROVIDERS } from '@/types/enums'
import { getDataABI } from '@/shared/abis/getDataABI'
-import { EoAError } from '@/shared/errors'
+import { InterfaceError } from '@/shared/errors'
export const fetchProfile = async (profileAddress: Address) => {
const { contract, isEoA } = useWeb3(PROVIDERS.RPC)
+ const { supportInterface } = useErc725()
// EoA check
if (await isEoA(profileAddress)) {
- throw new EoAError()
+ throw new Error('The profile is an EoA')
}
// interface check
- const eip165Contract = contract(eip165ABI as any, profileAddress)
- await eip165Contract.methods
- .supportsInterface(INTERFACE_IDS.LSP0ERC725Account)
- .call()
+ if (
+ !(await supportInterface(profileAddress, INTERFACE_IDS.LSP0ERC725Account))
+ ) {
+ throw new InterfaceError('LSP0ERC725Account')
+ }
// standard check
const supportedStandard = await contract(getDataABI, profileAddress)
diff --git a/utils/formatUrl.ts b/utils/formatUrl.ts
index 439724f2..d7051bdf 100644
--- a/utils/formatUrl.ts
+++ b/utils/formatUrl.ts
@@ -1,3 +1,5 @@
+import { IPFS_URL } from '@/shared/config'
+
/**
* Replaces protocol in the given URL with their respective gateway URLs.
* If the URL does not contain either protocol, returns the original URL.
@@ -6,11 +8,9 @@
* @returns {string} The formatted URL.
*/
export function formatUrl(url: string): string {
- const network = useAppStore().getNetwork(useAppStore().selectedNetwork)
-
// IPFS
if (url && url.includes('ipfs://')) {
- return url.replace('ipfs://', network.ipfsUrl)
+ return url.replace('ipfs://', IPFS_URL)
}
return url
diff --git a/utils/validators.ts b/utils/validators.ts
index e913fbfe..9f1fb251 100644
--- a/utils/validators.ts
+++ b/utils/validators.ts
@@ -27,6 +27,7 @@ export function assertAddress(
* otherwise throws an error.
*
* @param value - the value to check
+ * @param name - the name of the value
* @returns - throws an error if the value is not an array of addresses
*/
export function assertAddresses(
@@ -56,3 +57,19 @@ export function assertString(value: any): asserts value is string {
throw Error(`${value} is not a string`)
}
}
+
+/**
+ * Ensures that the input parameter is not undefined.
+ *
+ * @param input - the input param
+ * @param message - optional message to include in the error
+ * @throws {Error} - throws if input is not a undefined
+ */
+export function assertNotUndefined(
+ input: unknown,
+ message?: string
+): asserts input {
+ if (input === undefined) {
+ throw new Error(message || 'Input is undefined')
+ }
+}
diff --git a/yarn.lock b/yarn.lock
index 01afdb76..8f70a92a 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -494,7 +494,7 @@ __metadata:
languageName: node
linkType: hard
-"@erc725/erc725.js@npm:^0.17.2":
+"@erc725/erc725.js@npm:^0.17.2, @erc725/erc725.js@npm:~0.17.1":
version: 0.17.2
resolution: "@erc725/erc725.js@npm:0.17.2"
dependencies:
@@ -506,18 +506,6 @@ __metadata:
languageName: node
linkType: hard
-"@erc725/erc725.js@npm:^0.18.0":
- version: 0.18.0
- resolution: "@erc725/erc725.js@npm:0.18.0"
- dependencies:
- ethereumjs-util: ^7.1.5
- web3-eth-abi: ^1.10.0
- web3-providers-http: ^1.10.0
- web3-utils: ^1.10.0
- checksum: 2a03510bfb6a6a134a4522ccf366c44016389d380c7ebff39bf26158a23c523e2c1be0010837814aea7877ac533b63d419af4f0494cd639809b000b1f1ab419c
- languageName: node
- linkType: hard
-
"@erc725/smart-contracts@npm:^4.1.1":
version: 4.2.0
resolution: "@erc725/smart-contracts@npm:4.2.0"
@@ -529,6 +517,17 @@ __metadata:
languageName: node
linkType: hard
+"@erc725/smart-contracts@npm:^5.1.0":
+ version: 5.1.0
+ resolution: "@erc725/smart-contracts@npm:5.1.0"
+ dependencies:
+ "@openzeppelin/contracts": ^4.9.2
+ "@openzeppelin/contracts-upgradeable": ^4.9.2
+ solidity-bytes-utils: 0.8.0
+ checksum: 63748c8b6af72de0e87a7e015a2dae6926876705c3798f72da4b57d37e05d7eb67cd8ff527e3f5f1e85425035d5ca811577b11a1ec4a8030968bac206738dcee
+ languageName: node
+ linkType: hard
+
"@esbuild-kit/cjs-loader@npm:^2.4.2":
version: 2.4.2
resolution: "@esbuild-kit/cjs-loader@npm:2.4.2"
@@ -1633,6 +1632,18 @@ __metadata:
languageName: node
linkType: hard
+"@lukso/lsp-smart-contracts@npm:^0.11.0-rc.1":
+ version: 0.11.0-rc.1
+ resolution: "@lukso/lsp-smart-contracts@npm:0.11.0-rc.1"
+ dependencies:
+ "@erc725/smart-contracts": ^5.1.0
+ "@openzeppelin/contracts": ^4.9.2
+ "@openzeppelin/contracts-upgradeable": ^4.9.2
+ solidity-bytes-utils: 0.8.0
+ checksum: 3acf90d2d356d992337e84b8a96765a0591b30855ac76f71f3d0ce838d3e99736d0b4b31882689e853652101deb080d27111b3a79abaa51394e567000059b893
+ languageName: node
+ linkType: hard
+
"@lukso/lsp-smart-contracts@npm:^0.8.2":
version: 0.8.2
resolution: "@lukso/lsp-smart-contracts@npm:0.8.2"
@@ -2095,14 +2106,14 @@ __metadata:
languageName: node
linkType: hard
-"@openzeppelin/contracts-upgradeable@npm:^4.7.3, @openzeppelin/contracts-upgradeable@npm:^4.8.0":
+"@openzeppelin/contracts-upgradeable@npm:^4.7.3, @openzeppelin/contracts-upgradeable@npm:^4.8.0, @openzeppelin/contracts-upgradeable@npm:^4.9.2":
version: 4.9.3
resolution: "@openzeppelin/contracts-upgradeable@npm:4.9.3"
checksum: bda0240b1d44c913ec5a4e109c622f216c2bbd7b468d210822f75782a5f7fe0609d08bf03b78b253333625e99e507cf2f75212f1de3b274bd9fc64ae967aeec3
languageName: node
linkType: hard
-"@openzeppelin/contracts@npm:^4.7.3, @openzeppelin/contracts@npm:^4.8.0":
+"@openzeppelin/contracts@npm:^4.7.3, @openzeppelin/contracts@npm:^4.8.0, @openzeppelin/contracts@npm:^4.9.2":
version: 4.9.3
resolution: "@openzeppelin/contracts@npm:4.9.3"
checksum: 4932063e733b35fa7669b9fe2053f69b062366c5c208b0c6cfa1ac451712100c78acff98120c3a4b88d94154c802be05d160d71f37e7d74cadbe150964458838
@@ -15845,10 +15856,11 @@ __metadata:
version: 0.0.0-use.local
resolution: "wallet.universalprofile.cloud@workspace:."
dependencies:
- "@erc725/erc725.js": ^0.18.0
+ "@erc725/erc725.js": ~0.17.1
"@esbuild-plugins/node-globals-polyfill": 0.2.3
"@formatjs/intl": ^2.9.0
"@lukso/lsp-factory.js": ^2.5.1
+ "@lukso/lsp-smart-contracts": ^0.11.0-rc.1
"@lukso/web-components": ^1.30.0
"@nuxt/devtools": ^0.7.4
"@nuxtjs/device": ^3.1.0
@@ -15986,7 +15998,7 @@ __metadata:
languageName: node
linkType: hard
-"web3-eth-abi@npm:1.10.0, web3-eth-abi@npm:^1.10.0, web3-eth-abi@npm:^1.8.2":
+"web3-eth-abi@npm:1.10.0, web3-eth-abi@npm:^1.8.2":
version: 1.10.0
resolution: "web3-eth-abi@npm:1.10.0"
dependencies:
@@ -16131,7 +16143,7 @@ __metadata:
languageName: node
linkType: hard
-"web3-providers-http@npm:1.10.0, web3-providers-http@npm:^1.10.0, web3-providers-http@npm:^1.8.0":
+"web3-providers-http@npm:1.10.0, web3-providers-http@npm:^1.8.0":
version: 1.10.0
resolution: "web3-providers-http@npm:1.10.0"
dependencies:
@@ -16176,7 +16188,7 @@ __metadata:
languageName: node
linkType: hard
-"web3-utils@npm:1.10.0, web3-utils@npm:^1.10.0, web3-utils@npm:^1.8.2, web3-utils@npm:~1.10.0":
+"web3-utils@npm:1.10.0, web3-utils@npm:^1.8.2, web3-utils@npm:~1.10.0":
version: 1.10.0
resolution: "web3-utils@npm:1.10.0"
dependencies: