🚀 Big News: Socket Acquires Coana to Bring Reachability Analysis to Every Appsec Team.Learn more
Socket
Sign inDemoInstall
Socket

embeddable-nfts

Package Overview
Dependencies
Maintainers
1
Versions
11
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

embeddable-nfts - npm Package Compare versions

Comparing version

to
0.3.0

src/types.ts

31

package.json
{
"name": "embeddable-nfts",
"version": "0.2.0",
"version": "0.3.0",
"description": "Resuable, embeddable webcomponent for OpenSea assets.",

@@ -21,8 +21,7 @@ "scripts": {

},
"homepage": "https://github.com/ProjectOpenSea/embeddable_nfts#readme",
"homepage": "https://github.com/ProjectOpenSea/embeddable-nfts#readme",
"dependencies": {
"lit-element": "^2.2.1",
"lit-html": "^1.1.2",
"my-package": "0.0.0",
"opensea-js": "^0.7.1",
"opensea-js": "^1.1.0",
"web3": "0.20.6"

@@ -36,12 +35,12 @@ },

"devDependencies": {
"@babel/cli": "^7.8.3",
"@babel/core": "^7.8.3",
"@babel/cli": "^7.8.4",
"@babel/core": "^7.8.7",
"@babel/plugin-proposal-class-properties": "^7.8.3",
"@babel/plugin-proposal-decorators": "^7.8.3",
"@babel/preset-env": "^7.8.3",
"@babel/preset-env": "^7.8.7",
"@babel/preset-typescript": "^7.8.3",
"@types/node": "^13.1.8",
"@typescript-eslint/eslint-plugin": "^2.16.0",
"@typescript-eslint/parser": "^2.16.0",
"@webcomponents/webcomponentsjs": "^2.4.1",
"@types/node": "^13.9.1",
"@typescript-eslint/eslint-plugin": "^2.23.0",
"@typescript-eslint/parser": "^2.23.0",
"@webcomponents/webcomponentsjs": "^2.4.2",
"html-webpack-plugin": "^3.2.0",

@@ -52,10 +51,10 @@ "husky": "^4.2.3",

"ts-loader": "^6.2.1",
"tslint": "^5.20.1",
"tslint": "^6.1.0",
"tslint-eslint-rules": "^5.4.0",
"typescript": "^3.7.5",
"typescript": "^3.8.3",
"web3-typescript-typings": "^0.10.2",
"webpack": "^4.41.5",
"webpack-cli": "^3.3.10",
"webpack-dev-server": "^3.10.1"
"webpack": "^4.42.0",
"webpack-cli": "^3.3.11",
"webpack-dev-server": "^3.10.3"
}
}

@@ -15,3 +15,3 @@ # Embeddable NFTs

`contractAddress`\*- The token's contract address.
`tokenAddress`\*- The token's contract address.

@@ -34,3 +34,3 @@ `tokenId`\* - The token Id of the asset.

<nft-card
contractAddress="0x5caebd3b32e210e85ce3e9d51638b9c445481567"
tokenAddress="0x5caebd3b32e210e85ce3e9d51638b9c445481567"
tokenId="2242579050293992223"

@@ -37,0 +37,0 @@ network="mainnet"

@@ -1,1 +0,13 @@

export const NO_WEB3_ERROR: string = 'You need an Ethereum wallet to interact with this marketplace. Unlock your wallet, get MetaMask.io or Portis on desktop, or get Trust Wallet or Coinbase Wallet on mobile.'
import { ButtonType } from './types'
export const NO_WEB3_ERROR: string = 'You need an Ethereum wallet to interact ' +
'with this marketplace. Unlock your wallet, get MetaMask.io or ' +
'Portis on desktop, or get Trust Wallet or Coinbase Wallet on mobile.'
export const BTN_TEXT: { [index: string]: string } = {
[ButtonType.Manage]: 'manage this item ❯',
[ButtonType.Buy]: 'buy this item ❯',
[ButtonType.View]: 'view on openSea ❯',
[ButtonType.SwitchNetwork]: 'switch to ',
[ButtonType.Unlock]: 'buy this item ❯'
}
import { LitElement, html, customElement, property, css } from 'lit-element'
import { styleMap } from 'lit-html/directives/style-map'
import { classMap } from 'lit-html/directives/class-map'
import { OpenSeaTraitStats } from 'opensea-js/lib/types'
import './info-button'
import { Trait, TraitData, Traits, TraitType } from './types'
enum TraitType {
Property = 'prop',
Stat = 'stat',
Ranking = 'ranking',
Boost = 'boost',
}
import {
formatTraitType,
getTraitType
} from './utils'
interface Traits {
[index: string]: Trait[]
props: Trait[]
stats: Trait[]
rankings: Trait[]
boosts: Trait[]
}
interface Trait {
value: string | number
max?: string | number
display_type?: string
trait_type: string
}
interface TraitData {
traits: Trait[]
collectionTraits: CollectionTraits
}
interface CollectionTraits {
[index: string]: OpenSeaTraitStats
}
const TRAIT_HEADER_HEIGHT = 42

@@ -82,2 +56,12 @@ const TRAIT_HEADER_MARGIN_BOTTOM = 8

@property({type: Object}) public traitData!: TraitData
@property({type: Object}) public openseaLink?: string
@property({type: Boolean}) public loading = true
@property({type: Boolean}) public horizontal!: boolean
@property({type: Number}) public cardHeight!: number
@property({type: Number}) public cardInnerHeight?: number
@property({type: Number}) public cardWidth!: number
@property({type: Object}) private traits?: Traits
static get styles() {

@@ -254,52 +238,2 @@ return css`

@property({type: Object}) public traitData!: TraitData
@property({type: Object}) public openseaLink?: string
@property({type: Boolean}) public loading = true
@property({type: Boolean}) public horizontal!: boolean
@property({type: Number}) public cardHeight!: number
@property({type: Number}) public cardInnerHeight?: number
@property({type: Number}) public cardWidth!: number
@property({type: Object}) private traits?: Traits
private static formatTraitType(traitType: string) {
return traitType.replace(/_/g, ' ')
}
private static isBoost(trait: Trait) {
return trait.display_type && trait.display_type.includes('boost')
}
private static isRanking(trait: Trait, collectionTraits: CollectionTraits) {
return trait.display_type === null && trait.trait_type in collectionTraits && 'max' in collectionTraits[trait.trait_type]
}
/**
* IsStat - Checks to see if the given trait is a 'Stat'
* A 'Stat' is defined as any trait that has a `display_type` of 'number'
*
* @param trait - The object containing an asset's trait
* @return true if the trait is a 'Stat' and false otherwise
*/
private static isStat(trait: Trait) {
return trait.display_type === 'number'
}
/**
* IsProperty - Checks to see if the given trait is a 'Property'.
* A 'Property' is defined as any trait that has a `display_type` of null
* and does not have a min/max value
*
* @param trait - The object containing an asset's trait
* @return true if the trait is a 'Property' and false otherwise
*/
private static isProperty(trait: Trait, collectionTraits: CollectionTraits) {
return (
trait.display_type === null &&
trait.trait_type in collectionTraits &&
!('max' in collectionTraits[trait.trait_type]) ||
!(trait.trait_type in collectionTraits)
)
}
public updated(changedProperties: Map<string, string>) {

@@ -392,3 +326,3 @@ // Assumption: If the traitData gets updated we should rebuild the

<div class="trait_boost-name">
${NftCardBackTemplate.formatTraitType(trait_type)}
${formatTraitType(trait_type)}
</div>

@@ -431,3 +365,3 @@ </div>

<div class="stat-name">
${NftCardBackTemplate.formatTraitType(stat.trait_type)}
${formatTraitType(stat.trait_type)}
</div>

@@ -469,3 +403,3 @@ </div>

<div class="trait_ranking-header-name">
${NftCardBackTemplate.formatTraitType(trait_type)}
${formatTraitType(trait_type)}
</div>

@@ -499,3 +433,3 @@ <div class="trait_ranking-header-value">${value} of ${max}</div>

<div class="trait_property" style="${styleMap(propStyle)}">
<p class="trait_property-type">${NftCardBackTemplate.formatTraitType(trait_type)}</p>
<p class="trait_property-type">${formatTraitType(trait_type)}</p>
<p class="trait_property-value">${value}</p>

@@ -572,3 +506,3 @@ </div>

for (const trait of assetTraits) {
const type = this.getTraitType(trait, collectionTraits)
const type = getTraitType(trait, collectionTraits)

@@ -584,18 +518,2 @@ const name = trait.trait_type

}
private getTraitType(trait: Trait, collectionTraits: CollectionTraits) {
if (NftCardBackTemplate.isProperty(trait, collectionTraits)) {
return TraitType.Property
}
if (NftCardBackTemplate.isRanking(trait, collectionTraits)) {
return TraitType.Ranking
}
if (NftCardBackTemplate.isStat(trait)) {
return TraitType.Stat
}
if (NftCardBackTemplate.isBoost(trait)) {
return TraitType.Boost
}
return null // Default return statement
}
}

@@ -1,9 +0,2 @@

import {
LitElement,
html,
customElement,
property,
css,
TemplateResult
} from 'lit-element'
import { css, customElement, html, LitElement, property } from 'lit-element'

@@ -13,41 +6,16 @@ import { classMap } from 'lit-html/directives/class-map'

import { OpenSeaAsset, OpenSeaFungibleToken, Order, Network } from 'opensea-js/lib/types'
import { OpenSeaAsset, OpenSeaFungibleToken } from 'opensea-js/lib/types'
/* lit-element classes */
import './info-button'
import { toBaseDenomination } from './utils'
import { ButtonType, PriceType, State } from './types'
import { BTN_TEXT } from './constants'
enum ButtonType {
Manage = 'manage',
Buy = 'buy',
View = 'view',
SwitchNetwork = 'switchNetwork',
Unlock = 'unlock'
}
const BTN_TEXT: { [index: string]: string } = {
[ButtonType.Manage]: 'manage this item ❯',
[ButtonType.Buy]: 'buy this item ❯',
[ButtonType.View]: 'view on openSea ❯',
[ButtonType.SwitchNetwork]: 'switch to ',
[ButtonType.Unlock]: 'buy this item ❯'
}
interface LastSaleData {
paymentToken?: OpenSeaFungibleToken
currentPrice: number
expires: Date
}
interface State {
isOwnedByAccount: boolean
isMatchingNetwork: boolean
isUnlocked: boolean
hasWeb3: boolean
network: Network
}
const TOKEN_DECIMALS = 18
@customElement('nft-card-front')
export class NftCardFrontTemplate extends LitElement {
@property({type: Object}) public asset?: OpenSeaAsset
@property({type: Boolean}) public isOwnedByAccount!: boolean
@property({type: String}) public account!: string
@property({type: Boolean}) public horizontal!: boolean
@property({type: Object}) public state!: State

@@ -123,3 +91,3 @@ static get styles() {

}
.asset-detail-price-current {
.asset-detail-price {
font-size: 18px;

@@ -132,9 +100,10 @@ font-weight: 400;

}
.asset-detail-price-current img {
.asset-detail-price img {
margin-left: 5px;
width: 15px;
}
.asset-detail-price-current-value {
.asset-detail-price .value {
margin-left: 5px;
}
.asset-detail-price-previous {
.asset-detail-price .previous-value {
font-size: 14px;

@@ -170,59 +139,12 @@ color: #828282;

}
@property({type: Object}) public asset?: OpenSeaAsset
@property({type: Boolean}) public isOwnedByAccount!: boolean
@property({type: String}) public account!: string
@property({type: Boolean}) public horizontal!: boolean
@property({type: Object}) public state!: State
@property({type: Object}) private lastSaleData?: LastSaleData
public updated(changedProperties: Map<string, string>) {
// Assumption: If the traitData gets updated we should rebuild the
// traits object that populates UI
// Assumption: This will ONLY get called once per refresh
changedProperties.forEach(async (_oldValue: string, propName: string) => {
if (propName === 'asset') {
// Check for a sell order to populate the UI with the sell information
// TODO: We will be using lastSale here once added to SDK
if (this.asset?.sellOrders && this.asset.sellOrders.length > 0) {
const order: Order = this.asset.sellOrders[0]
const paymentToken = order.paymentTokenContract
const decimals = paymentToken ? paymentToken.decimals : TOKEN_DECIMALS // Default decimals to 18
const currentPrice = order.currentPrice ? +order.currentPrice.toFixed() / Math.pow(10, decimals) : 0
const expires = new Date(order.expirationTime.toFixed())
this.lastSaleData = {
paymentToken,
currentPrice,
expires
}
}
// Tell the component to update with new state
await this.requestUpdate()
}
})
}
public getAssetPriceTemplate() {
// TODO: Needs to account for tokens with images not symbols
// If payment_token.image_url then use token image instead of symbol
let prevPriceTemplate: TemplateResult = html``
let currentPriceTemplate: TemplateResult = html``
const sellOrder = this.asset?.sellOrders && this.asset?.sellOrders.length > 0 ? this.asset.sellOrders[0] : null
const currentPriceTemplate = sellOrder && sellOrder?.paymentTokenContract ?
this.getPriceTemplate(PriceType.Current, sellOrder?.paymentTokenContract, sellOrder?.currentPrice?.toNumber() || 0) : null
if (this.lastSaleData?.paymentToken) {
// const currentPriceSymbol = this.lastSaleData.paymentToken.symbol === 'ETH' ? 'Ξ ' : ''
currentPriceTemplate = this.getCurrentPriceTemplate(this.lastSaleData.paymentToken, this.lastSaleData.currentPrice)
const prevPriceTemplate = this.asset?.lastSale?.paymentToken ?
this.getPriceTemplate(PriceType.Previous, this.asset?.lastSale?.paymentToken,
+this.asset?.lastSale?.totalPrice) : null
}
if (this.asset?.lastSale) {
// @ts-ignore ignore until LastSale type gets added to SDK
const formattedPrevPrice = this.asset.lastSale.total_price / Math.pow(10, this.asset.lastSale.payment_token.decimals)
// @ts-ignore ignore until LastSale type gets added to SDK
const prevPriceSymbol = this.asset.lastSale.payment_token.symbol === 'ETH' ? 'Ξ ' : ''
prevPriceTemplate = html`<div class="asset-detail-price-previous">Prev. ${prevPriceSymbol} ${formattedPrevPrice}</div>`
}
return (html`

@@ -299,10 +221,13 @@ <div class="asset-detail-price">

private getCurrentPriceTemplate(paymentToken: OpenSeaFungibleToken, currentPrice: number) {
private getPriceTemplate(priceType: PriceType, paymentToken: OpenSeaFungibleToken, price: number) {
return html`
<div class="asset-detail-price-current">
<div class="asset-detail-price">
${priceType === PriceType.Previous ? html`<div class="previous-value">Prev.&nbsp;</div>` : null}
${ paymentToken.imageUrl ?
html`<img src="${paymentToken.imageUrl}" alt="" ></img>`
: paymentToken.symbol
: html`<div class="previous-value">${paymentToken.symbol === 'ETH' ? 'Ξ' : paymentToken.symbol}</div>`
}
<div class="asset-detail-price-current-value">${currentPrice}</div>
<div class="asset-detail-price value ${priceType}-value">
${toBaseDenomination(price, paymentToken.decimals)}
</div>
</div>

@@ -326,3 +251,14 @@ `

private getButtonTemplate() {
return html`
<button
@click="${(e: any) => this.eventHandler(e, 'view')}"
>
${BTN_TEXT[ButtonType.Buy]}
</button>
`
}
// @ts-ignore
private _getButtonTemplate() {
let btnType: ButtonType

@@ -329,0 +265,0 @@

import { css, customElement, html, LitElement, property } from 'lit-element'
import { styleMap } from 'lit-html/directives/style-map'
// @ts-ignore ts error TS7016

@@ -11,3 +10,2 @@ import Web3 from 'web3'

import { NO_WEB3_ERROR } from './constants'
/* lit-element classes */

@@ -18,17 +16,8 @@ import './pill.ts'

import './nft-card-back.ts'
import { ButtonEvent, CustomWindow } from './types'
import { getProvider, networkFromId } from './utils'
export interface CustomWindow extends Window {
ethereum: Web3.Provider
web3: Web3
}
declare const window: CustomWindow
export interface ButtonEvent {
detail: {
type: string
}
}
const HORIZONTAL_MIN_CARD_HEIGHT = '190px'
const HORIZONTAL_MIN_CARD_HEIGHT = '200px'
const VERT_MIN_CARD_HEIGHT = '670px'

@@ -41,3 +30,3 @@

const HORIZONTAL_CARD_HEIGHT = '250px'
const HORIZONTAL_CARD_HEIGHT = '200px'
const HORIZONTAL_CARD_WIDTH = '670px'

@@ -61,2 +50,28 @@

/* User configurable properties */
@property({type: Boolean}) public horizontal: boolean = true
@property({type: Boolean}) public orientationMode: OrientationMode = OrientationMode.Auto
@property({type: String}) public tokenAddress: string = ''
@property({type: String}) public contractAddress: string = ''
@property({type: String}) public tokenId: string = ''
@property({type: String}) public width: string = ''
@property({type: String}) public height: string = ''
@property({type: String}) public minHeight: string = ''
@property({type: String}) public network: Network = Network.Main
@property({type: Object}) private asset!: OpenSeaAsset
@property({type: Object}) private traitData: object = {}
@property({type: String}) private account: string = ''
@property({type: String}) private flippedCard: boolean = false
@property({type: Object}) private provider: Web3.Provider
@property({type: Object}) private seaport!: OpenSeaPort
// Card state variables
@property({type: Boolean}) private loading = true
@property({type: Boolean}) private error = false
@property({type: Boolean}) private isOwnedByAccount = false
@property({type: Boolean}) private isUnlocked: boolean = true
@property({type: Boolean}) private hasWeb3: boolean = false
@property({type: Boolean}) private isMatchingNetwork: boolean = false
static get styles() {

@@ -106,47 +121,2 @@ return css`

/* User configurable properties */
@property({type: Boolean}) public horizontal: boolean = false
@property({type: Boolean}) public orientationMode: OrientationMode = OrientationMode.Auto
@property({type: String}) public contractAddress: string = ''
@property({type: String}) public tokenId: string = ''
@property({type: String}) public width: string = ''
@property({type: String}) public height: string = ''
@property({type: String}) public minHeight: string = ''
@property({type: String}) public network: Network = Network.Main
@property({type: Object}) private asset!: OpenSeaAsset
@property({type: Object}) private traitData: object = {}
@property({type: String}) private account: string = ''
@property({type: String}) private flippedCard: boolean = false
@property({type: Object}) private provider: Web3.Provider
@property({type: Object}) private seaport!: OpenSeaPort
// Card state variables
@property({type: Boolean}) private loading = true
@property({type: Boolean}) private error = false
@property({type: Boolean}) private isOwnedByAccount = false
@property({type: Boolean}) private isUnlocked: boolean = true
@property({type: Boolean}) private hasWeb3: boolean = false
@property({type: Boolean}) private isMatchingNetwork: boolean = false
private static getProvider() {
if (window.ethereum) {
return window.ethereum
} else if (window.web3) {
return window.web3.currentProvider
} else {
return new Web3.providers.HttpProvider('https://mainnet.infura.io')
}
}
// Given the network version this method returns the network name
// Since only Main & Rinkeby are supported we ignore the other networks
private static networkFromId(id: string) {
switch (id) {
case '1': return Network.Main
case '4': return Network.Rinkeby
default: return null
}
}
/**

@@ -159,2 +129,3 @@ * ConnectedCallback - Invoked when a component is added to the document’s DOM.

super.connectedCallback()
this.tokenAddress = this.contractAddress ? this.contractAddress : this.tokenAddress

@@ -181,3 +152,3 @@ let vertCardWidth

// Get the web3 provider
this.provider = NftCard.getProvider()
this.provider = getProvider()

@@ -187,3 +158,4 @@ this.seaport = new OpenSeaPort(this.provider, {networkName: this.network})

try {
this.asset = await this.seaport.api.getAsset(this.contractAddress, this.tokenId)
this.asset = await this.seaport.api.getAsset({ tokenAddress: this.tokenAddress, tokenId: this.tokenId })
this.traitData = {

@@ -202,3 +174,3 @@ traits: this.asset.traits,

this.isMatchingNetwork = NftCard.networkFromId(this.provider.networkVersion) === this.network
this.isMatchingNetwork = networkFromId(this.provider.networkVersion) === this.network

@@ -214,3 +186,3 @@ // Tell the component to update with new state

this.provider.on('networkChanged', (networkId: string) => {
const network = NftCard.networkFromId(networkId)
const network = networkFromId(networkId)
this.isMatchingNetwork = network === this.network

@@ -288,2 +260,3 @@ })

const {detail} = event
switch (detail.type) {

@@ -290,0 +263,0 @@ case 'view':

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet