rename nftbapp

This commit is contained in:
elegant651
2020-03-25 13:49:36 +09:00
parent 5ad3b5d2de
commit 8072a65374
51 changed files with 0 additions and 0 deletions

21
nftbapp/frontend-nftbapp/.gitignore vendored Normal file
View File

@@ -0,0 +1,21 @@
.DS_Store
node_modules
/dist
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw*

View File

@@ -0,0 +1,29 @@
# frontend-nftdapp
## Project setup
```
npm install
```
### Compiles and hot-reloads for development
```
npm run serve
```
### Compiles and minifies for production
```
npm run build
```
### Run your tests
```
npm run test
```
### Lints and fixes files
```
npm run lint
```
### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).

View File

@@ -0,0 +1,5 @@
module.exports = {
presets: [
'@vue/app'
]
}

11694
nftbapp/frontend-nftbapp/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,37 @@
{
"name": "frontend-nftdapp",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build"
},
"dependencies": {
"caver-js": "^1.3.2",
"vue": "^2.6.10",
"vue-router": "^3.0.2",
"vuetify": "^2.2.18",
"vuex": "^3.1.3",
"axios": "^0.18.0",
"vue-axios": "^2.1.4"
},
"devDependencies": {
"@vue/cli-plugin-babel": "^3.1.1",
"@vue/cli-service": "^3.1.1",
"sass": "^1.19.0",
"sass-loader": "^8.0.0",
"vue-cli-plugin-vuetify": "^2.0.5",
"vue-template-compiler": "^2.5.21",
"vuetify-loader": "^1.3.0"
},
"postcss": {
"plugins": {
"autoprefixer": {}
}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 8"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,21 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<link href='https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons' rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet">
<title>frontend-nftdapp</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@mdi/font@latest/css/materialdesignicons.min.css">
</head>
<body>
<noscript>
<strong>We're sorry but frontend-nftdapp doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>

View File

@@ -0,0 +1,77 @@
<template>
<v-app>
<v-app-bar app clipped-left dense>
<v-toolbar-title>NFT APP</v-toolbar-title>
<v-spacer></v-spacer>
<div class="nav">
<a href="/">Home</a>
<a href="/wallet">Wallet</a>
<a href="/upload">Upload</a>
</div>
</v-app-bar>
<v-content class="contentWrapper">
<v-container fluid>
<router-view></router-view>
</v-container>
</v-content>
</v-app>
</template>
<script>
import { mapMutations } from 'vuex'
import KlaytnService from './klaytn/klaytnService'
export default {
name: 'app',
async mounted () {
await this.connect()
},
methods: {
...mapMutations('wallet', [
'setKlaytn',
'setIsConnectWallet',
'setMyAddress'
]),
async connect () {
const klaytn = new KlaytnService()
this.setKlaytn(klaytn)
const address = await klaytn.init()
if (address) {
this.setMyAddress(address)
this.setIsConnectWallet(true)
} else {
this.setIsConnectWallet(false)
}
},
}
}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
.nav a {
font-weight: bold;
color: #2c3e50;
margin: 10px;
}
.nav a.router-link-exact-active {
color: #42b983;
}
.contentWrapper {
padding-top: 20px;
}
</style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

View File

@@ -0,0 +1 @@
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 87.5 100"><defs><style>.cls-1{fill:#1697f6;}.cls-2{fill:#7bc6ff;}.cls-3{fill:#1867c0;}.cls-4{fill:#aeddff;}</style></defs><title>Artboard 46</title><polyline class="cls-1" points="43.75 0 23.31 0 43.75 48.32"/><polygon class="cls-2" points="43.75 62.5 43.75 100 0 14.58 22.92 14.58 43.75 62.5"/><polyline class="cls-3" points="43.75 0 64.19 0 43.75 48.32"/><polygon class="cls-4" points="64.58 14.58 87.5 14.58 43.75 100 43.75 62.5 64.58 14.58"/></svg>

After

Width:  |  Height:  |  Size: 539 B

View File

@@ -0,0 +1,69 @@
<template>
<v-container grid-list-md text-xs-center>
<v-layout row wrap>
<v-flex v-for="(auction, index) in auctions" :key="index" xs4>
<v-card>
<v-img :src="auction.image" height="200px"></v-img>
<div>Title: {{auction.title}}</div>
<div>Price: {{auction.price}} Ether</div>
<div>TokenId: {{auction.tokenId}}</div>
<div>Owner: {{auction.owner}}</div>
<div>Active: {{auction.active}}</div>
<div>Finalized: {{auction.finalized}}</div>
</v-card>
</v-flex>
</v-layout>
</v-container>
</template>
<script>
import KlaytnService from '@/klaytn/klaytnService'
export default {
data() {
return {
auctions: []
}
},
mounted() {
this.getAuctions()
},
methods: {
getAuctions() {
const klaytn = new KlaytnService()
klaytn.getAuctions((auctions) => {
auctions.forEach(auction => {
console.log(auction)
})
})
// this.ciAuctions.getCount({}, (error, result) => {
// const count = result
// for(let i=0; i<count; i++) {
// this.ciAuctions.getAuctionById(i, {}, (err, result) => {
// this.ciMyNFT.ownerOf(result[3], {}, (error, owner) => {
// this.auctions.push({
// title: result[0],
// price: this.$web3.fromWei(result[1], 'ether'),
// image: 'https://gateway.ipfs.io/ipfs/'+result[2],
// tokenId: result[3],
// owner: owner,
// active: result[6],
// finalized: result[7]
// })
// })
// })
// }
// })
}
}
}
</script>

View File

@@ -0,0 +1,112 @@
<template>
<div>
<v-form class="form" ref="form">
<v-text-field
v-model="tokenId"
label="Unique ID">
</v-text-field>
<input
type="file"
@change="captureFile" />
<v-btn @click="uploadImg" outline color="teal">UploadImg</v-btn>
<img :src="uploadedImg()" width="300" />
<v-text-field
v-model="dataURI"
label="Data URI"
required
></v-text-field>
<v-btn @click="submit" outline color="teal">Submit</v-btn>
<div v-show="isRegistered">
<v-btn @click="transferToCA" outline color="teal">TransferToCA</v-btn>
</div>
</v-form>
<PostAuction v-bind:tokenid="tokenId" v-bind:metadata="dataURI" />
</div>
</template>
<script>
import { mapGetters } from 'vuex'
import PostAuction from '@/components/PostAuction.vue'
export default {
data() {
return {
file: null,
tokenId: null,
isRegistered: false,
dataURI: null
}
},
components: {
PostAuction
},
computed: {
...mapGetters('wallet', [
'klaytn',
])
},
async mounted() {
this.tokenId = this._getRandomInt(123456789,999999999)
},
methods: {
_getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min
},
captureFile(event) {
event.stopPropagation()
this.file = event.target.files[0]
},
async uploadImg() {
if(!this.file){
alert("Please put the file on input.")
return
}
const formData = new FormData()
formData.append('file', this.file)
this.axios({
method: 'post',
baseURL: 'https://ipfs.infura.io:5001',
url: '/api/v0/add',
data: formData,
headers: {'Content-Type': 'multipart/form-data'}
}).then((response)=> {
this.dataURI = response.data.Hash
})
},
uploadedImg(){
return 'https://gateway.ipfs.io/ipfs/'+this.dataURI
},
submit() {
if(!this.dataURI){
alert("Fill in dataURI on the input")
return
}
this.klaytn.registerUniqueToken(this.tokenId, this.dataURI, (receipt) => {
alert(`Token registered...! (#${receipt.blockNumber} ,${receipt.transactionHash})`)
this.isRegistered = true
})
},
transferToCA() {
this.klaytn.transferFrom(this.tokenId, (receipt) => {
alert(`Token transfered to CA...! (#${receipt.blockNumber} ,${receipt.transactionHash})`)
})
}
}
}
</script>

View File

@@ -0,0 +1,111 @@
<template>
<div class="containWrap">
<v-card class="cardG">
<div>
<p class="text-center address">
{{myaddress}} <span class="reftxt">(Address)</span>
</p>
<p class="text-center balance">
{{balance}} Klay <span class="reftxt">(Balance)</span>
</p>
</div>
</v-card>
<h2>Transfer</h2>
<v-select v-model="selectedAuction" :items="auctionIds" label="Asset" @change="getAuctionById"></v-select>
<div v-show="selectedAuction">
<h3>Auction Info</h3>
<div>Title: {{auctionInfo.title}}</div>
<div>Price: {{auctionInfo.price}} Ether</div>
<div>TokenId: {{auctionInfo.tokenId}}</div>
<div>Owner: {{auctionInfo.owner}}</div>
</div>
<v-text-field
v-model="toAddress"
label="To Address"
required
></v-text-field>
<v-btn @click="finalizeAuction" outline color="teal">Finalize</v-btn>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
data() {
return {
auctionIds:[],
toAddress: null,
selectedAuction: null,
auctionInfo: {
title: '',
price: 0,
tokenId: '',
owner: ''
}
}
},
computed: {
...mapGetters('wallet', [
'klaytn',
'isConnectWallet',
'myaddress',
'balance'
])
},
async mounted() {
this.getBalance()
},
methods: {
async getBalance () {
if (this.myaddress) {
const balance = await this.klaytn.getBalance(this.myaddress)
this.setBalance(balance)
}
},
async getMyAuctions() {
this.auctionIds = await this.klaytn.getAuctionsOf(this.myaddress)
},
async getAuctionById() {
this.auctionInfo = await this.klaytn.getAuctionById(this.selectedAuction)
},
finalizeAuction() {
if(!this.toAddress) {
alert("please fill in to Address")
return
}
this.klaytn.finalizeAuction(this.selectedAuction, this.toAddress, (receipt) => {
alert(`Auction finalized...! (#${receipt.blockNumber} ,${receipt.transactionHash})`)
}, (error) => {
console.error(error)
})
}
}
}
</script>
<style scoped>
.containWrap {
max-width: 600px;
margin: 0 auto;
}
.cardG {
margin: 10px;
padding: 10px;
}
.cardG .reftxt {
color: #b7afaf;
}
</style>

View File

@@ -0,0 +1,65 @@
<template>
<div>
<v-form class="form" ref="form">
<v-text-field
v-model="tokenid"
></v-text-field>
<v-text-field
v-model="auction.auctionTitle"
placeholder="e.g. My NFT"
label="Auction title"
persistent-hint
></v-text-field>
<v-text-field
v-model="auction.price"
placeholder="e.g. 1"
label="Price"
persistent-hint
></v-text-field>
<v-btn @click="createAuction()" outline color="teal">Create Auction</v-btn>
</v-form>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
props: ['tokenid', 'metadata'],
data() {
return {
auction: {
auctionTitle: '',
price: null
},
}
},
computed: {
...mapGetters('wallet', [
'klaytn',
])
},
async mounted() {
},
methods: {
async createAuction() {
if(!this.tokenid) {
alert("Check for tokenId")
return
}
this.klaytn.createAuction(this.tokenid, this.auction.auctionTitle, this.metadata, auction.price, (receipt) => {
alert(`Creation completed...! (#${receipt.blockNumber} ,${receipt.transactionHash})`)
}, error => {
alert(error)
})
}
}
}
</script>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,36 @@
/**
* caver-js library helps making connection with klaytn node.
* You can connect to specific klaytn node by setting 'rpcURL' value.
* default rpcURL is 'https://api.baobab.klaytn.net:8651'.
*/
import Caver from 'caver-js'
const AuctionsABI = require('@/contracts/Auctions.json').abi
const MyNFTABI = require('@/contracts/MyNFT.json').abi
const TEST_NET = 'https://api.baobab.klaytn.net:8651'
export const config = {
rpcURL: TEST_NET
}
const MYNFT_CA = '0xfd0d9aeaae3c10b1acd9db5a17f2ee2775493f64'
const AUCTIONS_CA = '0x3a235ca1b8d08f2f5d6607f8b9f4fa33f540fed6'
const cav = new Caver(config.rpcURL)
const getMyNFTInstance = () => {
const contractInstance = MyNFTABI
&& MYNFT_CA
&& new cav.klay.Contract(MyNFTABI, MYNFT_CA)
return contractInstance
}
const getAuctionsInstance = () => {
const contractInstance = AuctionsABI
&& AUCTIONS_CA
&& new cav.klay.Contract(AuctionsABI, AUCTIONS_CA)
return contractInstance
}
export {cav, MYNFT_CA, AUCTIONS_CA, getMyNFTInstance, getAuctionsInstance}

View File

@@ -0,0 +1,228 @@
import { cav, MYNFT_CA, AUCTIONS_CA, getMyNFTInstance, getAuctionsInstance } from './caver'
export default class KlaytnService {
constructor() {}
async init () {
const walletFromSession = sessionStorage.getItem('walletInstance')
if (walletFromSession) {
try {
const address = JSON.parse(walletFromSession).address
cav.klay.accounts.wallet.add(JSON.parse(walletFromSession))
return address
} catch (e) {
sessionStorage.removeItem('walletInstance')
return false
}
}
}
async getBlockNumber () {
const blockNumber = await cav.klay.getBlockNumber()
return blockNumber
}
async getBalance (address) {
const balance = await cav.klay.getBalance(address)
return cav.utils.fromPeb(balance, "KLAY")
}
async loginWithKeystore (keystore, password) {
const { privateKey: privateKeyFromKeystore } = cav.klay.accounts.decrypt(keystore, password)
await this.integrateWallet(privateKeyFromKeystore)
return true
}
integrateWallet (privateKey) {
const walletInstance = cav.klay.accounts.privateKeyToAccount(privateKey)
cav.klay.accounts.wallet.add(walletInstance)
sessionStorage.setItem('walletInstance', JSON.stringify(walletInstance))
return true
}
removeWallet () {
cav.klay.accounts.wallet.clear()
sessionStorage.removeItem('walletInstance')
return true
}
getWallet () {
if (cav.klay.accounts.wallet.length) {
return cav.klay.accounts.wallet[0]
}
return null
}
getAuctions (dispatch) {
getAuctionsInstance().methods.getCount().call()
.then(count => {
if (!count) return []
const auctions = []
for (let i = count; i > 0; i--) {
const auction = getAuctionsInstance().methods.getAuctionById(i).call()
auctions.push(auction)
}
return Promise.all(auctions)
})
.then(auctions => {
dispatch(auctions)
})
}
async getOwner (tokenId) {
const owner = await getMyNFTInstance().methods.ownerOf(tokenId).call()
return owner
}
async getAuctionsOf (address) {
const result = await getAuctionsInstance().methods.getAuctionsOf(address).call()
return result
}
async getAuctionById (auctionId) {
const auction = await getAuctionsInstance().methods.getAuctionById(auctionId).call()
const aucionInfo = {}
auctionInfo.title = result[0]
auctionInfo.price = cav.utils.fromPeb(result[1], "KLAY")
auctionInfo.tokenId = result[3]
auctionInfo.owner = await this.getOwner(result[3])
return auctionInfo
}
createAuction (tokenId, title, metadata, price, dispatch, errorCb) {
const walletInstance = cav.klay.accounts.wallet && cav.klay.accounts.wallet[0]
if (!walletInstance) {
console.log('no walletInstance')
return
}
price = cav.utils.fromPeb(price, "KLAY")
const address = walletInstance.address
getAuctionsInstance().methods.createAuction(MYNFT_CA, tokenId, title, metadata, price).send({
from: address,
gas: '100000000'
})
.once('transactionHash', (txHash) => {
console.log(`
Sending a transaction...
txHash: ${txHash}
`
)
})
.once('receipt', (receipt) => {
console.log(`
Received receipt! (#${receipt.blockNumber} ,${receipt.transactionHash})
`, receipt)
dispatch(receipt)
})
.once('error', (error) => {
errorCb(error.message)
})
}
finalizeAuction (auctionId, toAddress, dispatch, errorCb) {
const walletInstance = cav.klay.accounts.wallet && cav.klay.accounts.wallet[0]
if (!walletInstance) {
console.log('no walletInstance')
return
}
const address = walletInstance.address
getAuctionsInstance().methods.finalizeAuction(auctionId, toAddress).send({
from: address,
gas: '1000000'
})
.once('transactionHash', (txHash) => {
console.log(`
Sending a transaction...
txHash: ${txHash}
`
)
})
.once('receipt', (receipt) => {
console.log(`
Received receipt! (#${receipt.blockNumber} ,${receipt.transactionHash})
`, receipt)
dispatch(receipt)
})
.once('error', (error) => {
errorCb(error.message)
})
}
registerUniqueToken (tokenId, dataURI, dispatch) {
const walletInstance = cav.klay.accounts.wallet && cav.klay.accounts.wallet[0]
if (!walletInstance) {
console.log('no walletInstance')
return
}
const address = walletInstance.address
getMyNFTInstance().methods.registerUniqueToken(address, tokenId, dataURI).send({
from: address,
gas: '100000000',
})
.once('transactionHash', (txHash) => {
console.log(`
Sending a transaction...
txHash: ${txHash}
`
)
})
.once('receipt', (receipt) => {
console.log(`
Received receipt! (#${receipt.blockNumber} ,${receipt.transactionHash})
`, receipt)
dispatch(receipt)
})
.once('error', (error) => {
errorCb(error.message)
})
}
transferFrom (tokenId) {
const walletInstance = cav.klay.accounts.wallet && cav.klay.accounts.wallet[0]
if (!walletInstance) {
console.log('no walletInstance')
return
}
const address = walletInstance.address
getMyNFTInstance().methods.transferFrom(address, AUCTIONS_CA, tokenId).send({
from: address,
gas: '100000000',
})
.once('transactionHash', (txHash) => {
console.log(`
Sending a transaction...
txHash: ${txHash}
`
)
})
.once('receipt', (receipt) => {
console.log(`
Received receipt! (#${receipt.blockNumber} ,${receipt.transactionHash})
`, receipt)
dispatch(receipt)
})
.once('error', (error) => {
errorCb(error.message)
})
}
}

View File

@@ -0,0 +1,18 @@
import Vue from 'vue'
import App from './App.vue'
import store from './store'
import router from './router'
import vuetify from './plugins/vuetify';
import axios from 'axios'
import VueAxios from 'vue-axios'
Vue.use(VueAxios, axios)
Vue.config.productionTip = false
new Vue({
router,
store,
vuetify,
render: h => h(App)
}).$mount('#app')

View File

@@ -0,0 +1,7 @@
import Vue from 'vue';
import Vuetify from 'vuetify/lib';
Vue.use(Vuetify);
export default new Vuetify({
});

View File

@@ -0,0 +1,30 @@
import Vue from 'vue'
import Router from 'vue-router'
import Main from './views/Main.vue'
import Wallet from './views/Wallet.vue'
import Upload from './views/Upload.vue'
Vue.use(Router)
export default new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: [
{
path: '/',
name: 'main',
component: Main
},
{
path: '/wallet',
name: 'wallet',
component: Wallet
},
{
path: '/upload',
name: 'upload',
component: Upload
}
]
})

View File

@@ -0,0 +1,12 @@
import Vue from 'vue'
import Vuex from 'vuex'
import wallet from '@/store/modules/wallet'
Vue.use(Vuex)
export default new Vuex.Store({
modules: {
wallet
}
})

View File

@@ -0,0 +1,41 @@
const state = {
klaytn: null,
isConnectWallet: false,
myaddress: '',
balance: 0
}
const getters = {
klaytn: (state) => state.klaytn,
isConnectWallet: (state) => state.isConnectWallet,
myaddress: (state) => state.myaddress,
balance: (state) => state.balance
}
const mutations = {
setKlaytn(state, klaytn) {
state.klaytn = klaytn
},
setIsConnectWallet(state, isConnected) {
state.isConnectWallet = isConnected
},
setMyAddress(state, address) {
state.myaddress = address
},
setBalance(state, balance) {
state.balance = balance
}
}
const actions = {
}
export default {
namespaced: true,
state,
getters,
actions,
mutations
}

View File

@@ -0,0 +1,15 @@
<template>
<div>
<h2>Main Page</h2>
<Marketplace />
</div>
</template>
<script>
import Marketplace from '@/components/Marketplace.vue'
export default {
components: {
Marketplace
}
}
</script>

View File

@@ -0,0 +1,15 @@
<template>
<div>
<h2>Upload Page</h2>
<MyUpload />
</div>
</template>
<script>
import MyUpload from '@/components/MyUpload.vue'
export default {
components: {
MyUpload
}
}
</script>

View File

@@ -0,0 +1,16 @@
<template>
<div>
<h2>Wallet Page</h2>
<MyWallet />
</div>
</template>
<script>
import MyWallet from '@/components/MyWallet.vue'
export default {
components: {
MyWallet
}
}
</script>

View File

@@ -0,0 +1,5 @@
module.exports = {
"transpileDependencies": [
"vuetify"
]
}