diff --git a/package.json b/package.json index 4e58cb1..a670dc8 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,8 @@ "test": "echo \"Error: no test specified\" && exit 1", "build": "rm -rf ./dist && webpack && tsc --declaration -p ./ -t es2015 --emitDeclarationOnly --outDir dist ", "dts": "tsc --declaration -p ./ -t es2015 --emitDeclarationOnly --outDir dist ", - "postinstall": "patch-package" + "postinstall": "patch-package", + "dist": "webpack" }, "author": "zhl", "license": "ISC", diff --git a/src/config/chain_config.ts b/src/config/chain_config.ts index 2749642..9bdf104 100644 --- a/src/config/chain_config.ts +++ b/src/config/chain_config.ts @@ -1,3 +1,5 @@ +export const BASE_TOKEN_URI = 'https://market.cebg.games/api/nft/info/' + export const DEFALUT_TOKENS = { 321: [ { @@ -54,18 +56,44 @@ export const DEFALUT_TOKENS = { symbol: 'BNB', decimal: 18 } + ], + 137: [ + { + type: 'eth', + address: 'eth', + symbol: 'MATIC', + decimal: 18 + } + ], + 80001: [ + { + type: 'eth', + address: 'eth', + symbol: 'MATIC', + decimal: 18 + } ] } export const DEFAULT_NFT_TYPES = { 321: { - hero: '0x0EB362BD40F2288fF25A6Ee1b487cB0cb4638e0D', - weapon: '0x29F67A372AC1c6AcF478A564992D421FE20F2cc8', - chip: '0x54B6ED7EDe9355b471985439421Aa1DC7Da6Dc20' + hero: {address: '0x0EB362BD40F2288fF25A6Ee1b487cB0cb4638e0D', type: 'erc721'}, + weapon: {address: '0x29F67A372AC1c6AcF478A564992D421FE20F2cc8', type: 'erc721'}, + chip: {address: '0x54B6ED7EDe9355b471985439421Aa1DC7Da6Dc20', type: 'erc1155'} }, 322: { - hero: '0x52917087cd4E48bDb5f336012E677f471f9E1C2D', - weapon: '0x500AD8A4D50d71Af5cA8eA3b12B914f7aE5466f7', - chip: '0x0640958BDb4D7956e1452FacEBD550C6Cf42aC94' + hero: {address: '0x52917087cd4E48bDb5f336012E677f471f9E1C2D', type: 'erc721'}, + weapon: {address: '0x500AD8A4D50d71Af5cA8eA3b12B914f7aE5466f7', type: 'erc721'}, + chip: {address: '0x0640958BDb4D7956e1452FacEBD550C6Cf42aC94', type: 'erc1155'} + }, + 137: { + hero: {address: '0x0EB362BD40F2288fF25A6Ee1b487cB0cb4638e0D', type: 'erc721'}, + weapon: {address: '0x29F67A372AC1c6AcF478A564992D421FE20F2cc8', type: 'erc721'}, + chip: {address: '0x54B6ED7EDe9355b471985439421Aa1DC7Da6Dc20', type: 'erc1155'} + }, + 80001: { + hero: {address: '0x0EB362BD40F2288fF25A6Ee1b487cB0cb4638e0D', type: 'erc721'}, + weapon: {address: '0x29F67A372AC1c6AcF478A564992D421FE20F2cc8', type: 'erc721'}, + chip: {address: '0x54B6ED7EDe9355b471985439421Aa1DC7Da6Dc20', type: 'erc1155'} } } \ No newline at end of file diff --git a/src/data/DataModel.ts b/src/data/DataModel.ts index 0cbde81..1f50b95 100644 --- a/src/data/DataModel.ts +++ b/src/data/DataModel.ts @@ -13,6 +13,7 @@ export interface IToken { export interface INFT { address: string; + type: "erc721" | "erc1155"; index: number; tokenId?: string; image?: string; @@ -21,10 +22,11 @@ export interface INFT { last?: number; } -export function initNFT(address: string, index: number) { +export function initNFT(address: string, index: number, type: 'erc721'|'erc1155') { return { address, index, + type }; } diff --git a/src/index.ts b/src/index.ts index 9992a57..819e693 100644 --- a/src/index.ts +++ b/src/index.ts @@ -15,7 +15,7 @@ import { } from './common/WalletEvent' import { ERC20Standard } from './standards/ERC20Standard' import { ERC721Standard } from './standards/ERC721Standard' -import { IAccount, initAccount } from './data/DataModel' +import { IAccount, INFT, initAccount, initNFT } from './data/DataModel' import { checkPassword, loadData, @@ -33,13 +33,17 @@ import { buildLoginSignMsg, signLogin } from './util/sign.util' import { JazzIcon } from './comp/JazzIcon' import { ERC1155Standard } from './standards/ERC1155Standard' import { ZWalletConnect } from './comp/ZWalletConnect' -import { rejects } from 'assert' +import { getJCErc721Info, getTypeByAddress, UNKNOW } from './util/chain.util' + var global = (typeof globalThis !== 'undefined' && globalThis) || (typeof self !== 'undefined' && self) || (typeof global !== 'undefined' && global) || {} + + + declare global { interface Window { jc: { @@ -131,7 +135,10 @@ export default class JCWallet { console.log(`init wallet ext data cost: ${(Date.now() - start) / 1000}`) } - + /** + * init wallet connect + * @returns + */ public async initThirdPartyWallet() { return new Promise((resolve, reject) => { for (const d of AllChains) { @@ -152,7 +159,11 @@ export default class JCWallet { }) } - + /** + * init chain data + * create local wallet data if there is no local wallet data + * @returns + */ private init({ chains, password }: { chains: number[]; password: string }) { for (let chain of chains) { this.chainSet.add(chain) @@ -211,8 +222,10 @@ export default class JCWallet { .catch(err=>{ reject && reject(err); }) - // @ts-ignore - jumpToWallet() + setTimeout(()=>{ + // @ts-ignore + jumpToWallet() + }, 500) } }) @@ -398,8 +411,11 @@ export default class JCWallet { .catch(err=> { reject && reject(err); }) - // @ts-ignore - jumpToWallet() + setTimeout(()=>{ + // @ts-ignore + jumpToWallet() + }, 500) + } }) } @@ -441,6 +457,84 @@ export default class JCWallet { }) return result } + + private async updateTokenInfo(data: INFT, address: string, index: number, account: string) { + const tokenId = await this.wallet.erc721Standard.getCollectibleTokenId( + address, + account, + index + ) + const info = await getJCErc721Info(tokenId); + data.tokenId = tokenId; + data.name = info.name; + data.desc = info.description; + data.image = info.image; + data.last = Date.now(); + } + + public async nftInfo(address: string, index: number, account: string, refresh: boolean) { + account = account || this.currentAccount().address + const chain = this.wallet.currentChain.id + const { categor, type } = getTypeByAddress(chain, address); + let nfts = []; + if (categor !== UNKNOW) { + nfts = this.currentAccountData.tokenData[chain][`${categor}s`] + } + let needRefresh = !(nfts.length > index && nfts[index].tokenId && !refresh); + if (needRefresh) { + this.updateTokenInfo(nfts[index], address, index, account); + saveData(this.data); + } + return nfts[index]; + } + + public async nftList(address: string, account?: string) { + account = account || this.currentAccount().address + const chain = this.wallet.currentChain.id + const amount = await this.erc721Standard.getBalance(address, account) + const { categor, type }= getTypeByAddress(chain, address); + let nfts = []; + if (categor !== UNKNOW) { + nfts = this.currentAccountData.tokenData[chain][`${categor}s`] + } + let refresh = false; + if (nfts.length !== amount) { + refresh = true; + } + if (refresh) { + nfts.length = 0; + for (let i = 0; i < amount; i++) { + const nftData = initNFT(address, i, type) + nfts.push(nftData) + } + } + return nfts; + } + + public async sendNFT(address: string, to: string, tokenId: string) { + let from = this.currentAccount().address + let result = await this.erc721Standard.transfer({ + address, + from, + to, + tokenId, + }) + return result + } + + public async erc1155Info(address: string) { + + } + + public async erc1155List(address: string, account?: string) { + if (!account) { + account = this.currentAccount().address + } + } + + public async sendErc1155() { + + } } // window.jc = window.jc || {wallet: new JCWallet()}; diff --git a/src/standards/ERC721Standard.ts b/src/standards/ERC721Standard.ts index 4a6ca40..6329ccf 100644 --- a/src/standards/ERC721Standard.ts +++ b/src/standards/ERC721Standard.ts @@ -285,4 +285,25 @@ export class ERC721Standard { image, }; }; + + + async transfer({ + address, + from, + to, + tokenId, + gas, + }: { + address: string; + from: string; + to: string; + tokenId: string; + gas?: number; + }) { + const contract = new this.web3.eth.Contract(abiERC721, address); + return contract.methods.safeTransferFrom(from, to, tokenId).send({ + from, + gas: gas || 1000000, + }); + } } \ No newline at end of file diff --git a/src/util/chain.util.ts b/src/util/chain.util.ts index 706466e..fafef26 100644 --- a/src/util/chain.util.ts +++ b/src/util/chain.util.ts @@ -1,3 +1,6 @@ +import { BASE_TOKEN_URI, DEFAULT_NFT_TYPES } from "../config/chain_config"; + +export const UNKNOW = 'unknow'; /** * change price with customer decimals to bigNum with 18 decimals @@ -43,3 +46,24 @@ export function formatPrice(price: number|string, decimals?: number, fixed = 2) export function toHexChainId(chainId: number) { return '0x' + chainId.toString(16) } + + +export function getTypeByAddress(chain: number, address: string) { + const cfgs = DEFAULT_NFT_TYPES[chain]; + let categor = UNKNOW; + let type: 'erc721' | 'erc1155' = 'erc721'; + if (cfgs) { + for (let key in cfgs) { + if (cfgs[key] && cfgs[key].address === address) { + categor = key + type = cfgs[key].type + } + } + } + return { categor, type }; +} + +export async function getJCErc721Info(tokenId: string) { + const url = `${BASE_TOKEN_URI}${tokenId}` + return fetch(url).then(response => {return response.json()}) +} \ No newline at end of file