Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 1bbbfdc

Browse files
author
keno dressel
committedSep 13, 2019
initial commit
0 parents  commit 1bbbfdc

20 files changed

+13333
-0
lines changed
 

‎.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
node_modules
2+
.idea
3+
tailwind.css

‎LICENSE.md

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
ISC License
2+
3+
Copyright (c) 2019, aeternity developers
4+
5+
Permission to use, copy, modify, and/or distribute this software for any
6+
purpose with or without fee is hereby granted, provided that the above
7+
copyright notice and this permission notice appear in all copies.
8+
9+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
10+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
12+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14+
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15+
PERFORMANCE OF THIS SOFTWARE.

‎README.md

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Boilerplate Aepp Vue.JS Frontend
2+
3+
## Setup
4+
5+
6+
Install the dependencies
7+
```
8+
npm install
9+
```
10+
11+
Once the setup is completed you can simply run
12+
```
13+
npm run dev
14+
```
15+
16+
### Known issues:
17+
- SCSS not working right now

‎babel.config.js

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
module.exports = {
2+
presets: [[
3+
'@babel/preset-env',
4+
{
5+
debug: false,
6+
useBuiltIns: 'usage',
7+
corejs: '2.0.0',
8+
}
9+
]],
10+
plugins: [
11+
'@babel/plugin-proposal-object-rest-spread',
12+
'@babel/plugin-transform-modules-commonjs',
13+
'@babel/plugin-transform-runtime',
14+
'@babel/plugin-transform-block-scoping'
15+
]
16+
}

‎package-lock.json

+12,774
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎package.json

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
{
2+
"name": "aepp-boilerplate",
3+
"version": "0.1.0",
4+
"scripts": {
5+
"test": "echo \"Error: no test specified\" && exit 1",
6+
"build": "webpack -p --env.NODE_ENV=prod",
7+
"dev": "webpack-dev-server --env.NODE_ENV=dev --config ./webpack.config.js",
8+
"build:stats": "webpack --env.NODE_ENV=prod --profile --json > stats.json"
9+
},
10+
"license": "ISC",
11+
"dependencies": {
12+
"@aeternity/aepp-components": "git+https://github.com/kenodressel/aepp-components.git#develop",
13+
"@aeternity/aepp-sdk": "~4.7.0",
14+
"axios": "^0.19.0",
15+
"bignumber.js": "^9.0.0",
16+
"core-js": "^2.6.9",
17+
"vue": "^2.6.10",
18+
"vue-router": "^3.1.3"
19+
},
20+
"devDependencies": {
21+
"@babel/cli": "^7.6.0",
22+
"@babel/core": "^7.6.0",
23+
"@babel/node": "^7.6.1",
24+
"@babel/plugin-proposal-object-rest-spread": "^7.5.1",
25+
"@babel/plugin-transform-block-scoping": "^7.6.0",
26+
"@babel/plugin-transform-modules-commonjs": "^7.6.0",
27+
"@babel/plugin-transform-runtime": "^7.6.0",
28+
"@babel/polyfill": "^7.6.0",
29+
"@babel/preset-env": "^7.6.0",
30+
"@babel/register": "^7.6.0",
31+
"@babel/runtime": "^7.6.0",
32+
"autoprefixer": "^9.6.1",
33+
"babel-loader": "^8.0.6",
34+
"babel-plugin-add-module-exports": "^1.0.2",
35+
"browserslist": "^4.7.0",
36+
"clean-webpack-plugin": "^3.0.0",
37+
"css-loader": "^3.0.0",
38+
"cssnano": "^4.1.10",
39+
"file-loader": "^4.0.0",
40+
"glob-all": "^3.1.0",
41+
"html-webpack-harddisk-plugin": "^1.0.1",
42+
"html-webpack-plugin": "^3.2.0",
43+
"node-sass": "^4.12.0",
44+
"postcss-import": "^12.0.1",
45+
"postcss-loader": "^3.0.0",
46+
"precss": "^4.0.0",
47+
"purgecss-webpack-plugin": "^1.5.0",
48+
"raw-loader": "^3.0.0",
49+
"sass-loader": "^8.0.0",
50+
"tailwindcss": "^1.1.2",
51+
"vue-loader": "^15.7.0",
52+
"vue-style-loader": "^4.1.2",
53+
"vue-template-compiler": "^2.6.10",
54+
"webpack": "^4.40.1",
55+
"webpack-bundle-analyzer": "^3.5.0",
56+
"webpack-cli": "^3.3.8",
57+
"webpack-dev-server": "^3.7.2",
58+
"webpack-pwa-manifest": "^4.0.0",
59+
"webpack-serve": "^3.1.0"
60+
},
61+
"browserslist": [
62+
"> 1%",
63+
"last 2 versions",
64+
"not ie <= 8",
65+
"maintained node versions",
66+
"not dead"
67+
]
68+
}

‎postcss.config.js

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
module.exports = {
2+
parser: 'postcss',
3+
plugins: [
4+
require('postcss-import'),
5+
require('tailwindcss'),
6+
require('autoprefixer'),
7+
require('cssnano')({
8+
'preset': [
9+
'default',
10+
{ 'discardComments': { 'removeAll': true } }
11+
]
12+
})
13+
]
14+
}

‎src/App.vue

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<template>
2+
<div id="app" class="min-h-screen">
3+
<div class="content min-h-screen max-w-desktop">
4+
<div class="min-h-screen wrapper" ref="wrapper">
5+
<router-view></router-view>
6+
</div>
7+
</div>
8+
</div>
9+
</template>
10+
11+
<script>
12+
13+
import aeternity from './utils/aeternity.js'
14+
15+
export default {
16+
name: 'app',
17+
methods: {
18+
async checkAndReloadProvider() {
19+
if (!aeternity.address) return;
20+
const changesDetected = await aeternity.verifyAddress();
21+
if (changesDetected) this.$router.go();
22+
}
23+
},
24+
async created() {
25+
try {
26+
// Bypass check if there is already an active wallet
27+
if (aeternity.hasActiveWallet())
28+
return
29+
30+
// Otherwise init the aeternity sdk
31+
if (!(await aeternity.initClient()))
32+
throw new Error('Wallet init failed');
33+
34+
// Constantly check if wallet is changed
35+
setInterval(this.checkAndReloadProvider, 1000)
36+
} catch (e) {
37+
console.error('Initializing Wallet Error', e);
38+
}
39+
}
40+
}
41+
</script>
42+
43+
<style scoped>
44+
.min-h-screen {
45+
min-height: 100vh;
46+
max-height: 100vh;
47+
padding-bottom: 0;
48+
overflow-y: auto;
49+
background-color: #f8f8f8;
50+
}
51+
52+
@media (min-width: 700px) {
53+
#app {
54+
position: relative;
55+
display: flex;
56+
justify-content: center;
57+
}
58+
.content {
59+
box-shadow: 0 1px 5px 0 rgba(0, 0, 0, 0.15);
60+
}
61+
}
62+
</style>

‎src/assets/.empty

Whitespace-only changes.

‎src/components/.empty

Whitespace-only changes.

‎src/contracts/Idenitity.aes

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
contract Identity =
2+
type state = ()
3+
entrypoint main(x : int) = x

‎src/index.html

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<!DOCTYPE html>
2+
<html class="font-sans" lang="en">
3+
<head>
4+
<meta charset="utf-8">
5+
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
7+
<title></title>
8+
<!-- CSS files will be injected here by WebPack -->
9+
</head>
10+
<body>
11+
<div id="app"></div>
12+
<!-- JS files will be injected here by WebPack -->
13+
</body>
14+
</html>

‎src/main.css

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
@import "tailwindcss/base";
2+
3+
@import "tailwindcss/components";
4+
5+
@import "tailwindcss/utilities";
6+
7+
/* Add custom classes here */

‎src/main.js

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import './main.css'
2+
import '@aeternity/aepp-components/dist/aepp.fonts.css'
3+
import '@aeternity/aepp-components/dist/aepp.components.css'
4+
5+
import Vue from 'vue'
6+
import VueRouter from 'vue-router'
7+
import App from './App.vue'
8+
import router from './router'
9+
10+
11+
Vue.use(VueRouter);
12+
13+
Vue.config.productionTip = false;
14+
15+
export default new Vue({
16+
router: router,
17+
render: h => h(App)
18+
}).$mount('#app')

‎src/router.js

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import Router from 'vue-router'
2+
import Home from './views/Home.vue'
3+
4+
const routes = [
5+
{
6+
path: '/',
7+
name: 'home',
8+
component: Home,
9+
meta: {title: 'Home'}
10+
}
11+
]
12+
13+
const router = new Router({mode: 'hash', routes: routes})
14+
15+
router.beforeEach((to, from, next) => {
16+
document.title = `${to.meta.title} - Example Aepp`
17+
next()
18+
})
19+
20+
export default router;

‎src/utils/aeternity.js

+95
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import Aepp from '@aeternity/aepp-sdk/es/ae/aepp'
2+
import Util from './util'
3+
import identity from '../contracts/Idenitity.aes'
4+
import {Universal} from "@aeternity/aepp-sdk/es/ae/universal";
5+
6+
const aeternity = {
7+
client: null,
8+
address: null,
9+
height: null,
10+
networkId: null,
11+
passive: false,
12+
contractAddress: ''
13+
};
14+
15+
const timeout = async (promise) => {
16+
return Promise.race([
17+
promise,
18+
new Promise(resolve =>
19+
setTimeout(() => {
20+
resolve('TIMEOUT');
21+
}, 30000))
22+
]);
23+
};
24+
25+
aeternity.initProvider = async () => {
26+
try {
27+
28+
aeternity.address = await aeternity.client.address();
29+
aeternity.balance = await aeternity.client.balance(aeternity.address)
30+
.then(balance => `${Util.atomsToAe(balance)}`.replace(',', ''))
31+
.catch(() => '0');
32+
aeternity.height = await aeternity.client.height();
33+
aeternity.networkId = (await aeternity.client.getNodeInfo()).nodeNetworkId;
34+
if(aeternity.contractAddress)
35+
aeternity.contract = await aeternity.client.getContractInstance(registryContractSource, {contractAddress: aeternity.contractAddress});
36+
return true;
37+
} catch (e) {
38+
console.error(e);
39+
return false
40+
}
41+
};
42+
43+
aeternity.initMobileBaseAepp = async () => {
44+
try {
45+
if (window.parent === window) return false;
46+
return await timeout(Aepp());
47+
} catch (e) {
48+
console.warn('Base Aepp init failed');
49+
return false;
50+
}
51+
};
52+
53+
aeternity.initStaticClient = async () => {
54+
return Universal({
55+
url: 'http://localhost:3001',
56+
internalUrl: 'http://localhost:3001',
57+
compilerUrl: 'http://localhost:3080'
58+
});
59+
};
60+
61+
aeternity.hasActiveWallet = () => {
62+
return !!aeternity.client;
63+
};
64+
65+
aeternity.isTestnet = () => {
66+
return aeternity.networkId !== 'ae_mainnet';
67+
};
68+
69+
/**
70+
* Initializes the aeternity sdk to be imported in other occasions
71+
* @returns {Promise<boolean>}
72+
*/
73+
aeternity.initClient = async () => {
74+
let result = true;
75+
if (!aeternity.client) {
76+
try {
77+
aeternity.client = await aeternity.initMobileBaseAepp();
78+
result = await aeternity.initProvider();
79+
} catch (e) {
80+
console.error(e);
81+
result = false;
82+
}
83+
} else {
84+
result = await aeternity.initProvider();
85+
}
86+
return result;
87+
};
88+
89+
aeternity.verifyAddress = async () => {
90+
const currAddress = await aeternity.client.address();
91+
return currAddress !== aeternity.address
92+
};
93+
94+
95+
export default aeternity

‎src/utils/util.js

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import BigNumber from 'bignumber.js'
2+
3+
const atomsToAe = (atoms) => (new BigNumber(atoms)).dividedBy(new BigNumber(1000000000000000000));
4+
const aeToAtoms = (ae) => (new BigNumber(ae)).times(new BigNumber(1000000000000000000));
5+
6+
export default {
7+
atomsToAe, aeToAtoms
8+
}

‎src/views/Home.vue

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<template>
2+
<div>
3+
<h1>Account</h1>
4+
{{address}}
5+
<h1>Balance</h1>
6+
{{balance}} AE
7+
</div>
8+
</template>
9+
10+
<script>
11+
import aeternity from "../utils/aeternity";
12+
13+
export default {
14+
name: 'Home',
15+
components: {},
16+
data() {
17+
return {
18+
address: null,
19+
balance: null
20+
};
21+
},
22+
23+
24+
async mounted() {
25+
await aeternity.initClient();
26+
27+
if (aeternity.isTestnet() && aeternity.balance <= 5) {
28+
await axios.post(`https://testnet.faucet.aepps.com/account/${aeternity.address}`, {}, {headers: {'content-type': 'application/x-www-form-urlencoded'}}).catch(console.error);
29+
}
30+
this.address = aeternity.address;
31+
this.balance = aeternity.balance;
32+
},
33+
};
34+
</script>
35+
36+
<style scoped>
37+
38+
</style>

‎tailwind.config.js

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
module.exports = {
2+
theme: {
3+
extend: {}
4+
},
5+
variants: {},
6+
plugins: []
7+
}

‎webpack.config.js

+154
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
const path = require('path')
2+
const HtmlWebpackPlugin = require('html-webpack-plugin')
3+
4+
const HtmlWebpackHarddiskPlugin = require('html-webpack-harddisk-plugin')
5+
// Cleans dist folder before building for fresh build
6+
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
7+
const { VueLoaderPlugin } = require('vue-loader')
8+
// const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
9+
const PurgecssPlugin = require('purgecss-webpack-plugin')
10+
const WebpackPwaManifest = require('webpack-pwa-manifest');
11+
const glob = require('glob-all')
12+
13+
// Custom PurgeCSS extractor for Tailwind that allows special characters in
14+
// class names.
15+
//
16+
// https://github.com/FullHuman/purgecss#extractor
17+
class TailwindExtractor {
18+
static extract (content) {
19+
return content.match(/[A-z0-9-:\/]+/g) || []
20+
}
21+
}
22+
23+
module.exports = env => {
24+
return {
25+
mode: env.NODE_ENV === 'prod' ? 'production' : 'development',
26+
resolve: {
27+
extensions: ['.vue', '.css', '.js']
28+
},
29+
node: {
30+
fs: 'empty'
31+
},
32+
entry: {
33+
'main': './src/main.js'
34+
},
35+
output: {
36+
filename: 'bundle.js?[hash]',
37+
publicPath: env.NODE_ENV === 'prod' ? './' : '/'
38+
},
39+
devServer: {
40+
contentBase: path.join(__dirname, 'dist'),
41+
port: 8081,
42+
historyApiFallback: true,
43+
// Enable to allow other (than localhost) machines to access the aepp on your computer
44+
disableHostCheck: false,
45+
host: '0.0.0.0'
46+
},
47+
devtool: env.NODE_ENV === 'prod' ? '' : 'eval-source-map',
48+
plugins: [
49+
new HtmlWebpackPlugin({
50+
inject: true,
51+
// chunks: ['main'],
52+
title: 'Governance Aepp',
53+
template: './src/index.html',
54+
filename: path.join(__dirname, 'dist', 'index.html'),
55+
// Avoids building twice for dev
56+
alwaysWriteToDisk: true
57+
}),
58+
new PurgecssPlugin({
59+
// Specify the locations of any files you want to scan for class names.
60+
paths: glob.sync([
61+
path.join(__dirname, './src/**/*.vue'),
62+
path.join(__dirname, './src/index.html')
63+
]),
64+
extractors: [
65+
{
66+
extractor: TailwindExtractor,
67+
// Specify the file extensions to include when scanning for
68+
// class names.
69+
extensions: ['html', 'js', 'vue']
70+
}
71+
]
72+
}),
73+
new HtmlWebpackHarddiskPlugin(),
74+
new CleanWebpackPlugin(),
75+
new VueLoaderPlugin(),
76+
new WebpackPwaManifest({
77+
name: 'Example Aepp',
78+
short_name: 'Example',
79+
description: 'Your average aepp.',
80+
background_color: '#ff0d6a'
81+
})
82+
],
83+
module: {
84+
rules: [
85+
// this will apply to both plain `.js` files
86+
// AND `<script>` blocks in `.vue` files
87+
{
88+
test: /\.js$/,
89+
include: [
90+
path.resolve(__dirname, 'src'),
91+
path.resolve(__dirname, 'node_modules/@aeternity'),
92+
path.resolve(__dirname, 'node_modules/rlp'),
93+
// Contains 'const' or 'let'
94+
path.resolve(__dirname, 'node_modules/base-x')
95+
],
96+
loader: 'babel-loader'
97+
},
98+
{
99+
type: 'javascript/auto',
100+
test: /\.mjs$/,
101+
include: [
102+
path.resolve(__dirname, 'node_modules/@download/blockies')
103+
],
104+
loader: 'babel-loader'
105+
},
106+
// this will apply to both plain `.css` files
107+
// AND `<style>` blocks in `.vue` files
108+
{
109+
test: /\.css$/,
110+
use: [
111+
'vue-style-loader',
112+
'css-loader',
113+
{
114+
loader: 'postcss-loader',
115+
options: {
116+
config: {
117+
path: 'postcss.config.js'
118+
}
119+
}
120+
}
121+
]
122+
},
123+
// allows vue compoents in '<template><html><script><style>' syntax
124+
{
125+
test: /\.vue$/,
126+
loader: 'vue-loader',
127+
options: {
128+
loaders: {
129+
js: 'babel-loader'
130+
}
131+
// extractCSS: true
132+
// other vue-loader options go here
133+
}
134+
},
135+
{
136+
test: /\.aes$/,
137+
use: [
138+
'raw-loader'
139+
]
140+
},
141+
{
142+
test: /\.(woff(2)?|ttf|eot|svg|png)(\?v=\d+\.\d+\.\d+)?$/,
143+
use: [{
144+
loader: 'file-loader',
145+
options: {
146+
name: '[name].[ext]',
147+
outputPath: 'assets/'
148+
}
149+
}]
150+
}
151+
]
152+
}
153+
}
154+
}

0 commit comments

Comments
 (0)
Please sign in to comment.