create-near-app 2.0.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/{common/contracts → contracts}/assemblyscript/README.md +1 -2
- package/{common/contracts → contracts}/assemblyscript/as-pect.config.js +0 -0
- package/{common/contracts → contracts}/assemblyscript/asconfig.json +0 -0
- package/{common/contracts → contracts}/assemblyscript/assembly/__tests__/as-pect.d.ts +0 -0
- package/contracts/assemblyscript/assembly/__tests__/main.spec.ts +11 -0
- package/{common/contracts → contracts}/assemblyscript/assembly/as_types.d.ts +0 -0
- package/contracts/assemblyscript/assembly/index.ts +23 -0
- package/{common/contracts → contracts}/assemblyscript/assembly/tsconfig.json +0 -0
- package/{common/contracts → contracts}/assemblyscript/package.json +2 -6
- package/{common/contracts → contracts}/rust/.cargo/config +0 -0
- package/{common/contracts → contracts}/rust/Cargo.toml +4 -5
- package/{common/contracts → contracts}/rust/README.md +1 -2
- package/contracts/rust/src/lib.rs +72 -0
- package/index.js +51 -71
- package/integration-tests/rs/Cargo.toml +22 -0
- package/integration-tests/rs/src/tests.rs +66 -0
- package/integration-tests/ts/ava.config.cjs +9 -0
- package/integration-tests/ts/package.json +16 -0
- package/integration-tests/ts/src/main.ava.ts +44 -0
- package/package.json +23 -24
- package/templates/react/README.md +2 -2
- package/templates/react/ava.config.cjs +9 -0
- package/templates/react/{src → frontend}/App.js +34 -29
- package/templates/react/{src → frontend}/__mocks__/fileMock.js +0 -0
- package/{common/frontend → templates/react/frontend/assets/css}/global.css +4 -3
- package/{common/frontend/assets → templates/react/frontend/assets/img}/favicon.ico +0 -0
- package/{common/frontend/assets → templates/react/frontend/assets/img}/logo-black.svg +0 -0
- package/{common/frontend/assets → templates/react/frontend/assets/img}/logo-white.svg +0 -0
- package/templates/react/{src → frontend/assets/js/near}/config.js +1 -1
- package/templates/{vue/src → react/frontend/assets/js/near}/utils.js +14 -4
- package/templates/react/{src → frontend}/index.html +3 -3
- package/templates/react/frontend/index.js +14 -0
- package/templates/react/near.gitignore +1 -1
- package/templates/react/package.json +29 -43
- package/templates/vanilla/README.md +2 -2
- package/templates/vanilla/frontend/assets/css/global.css +189 -0
- package/templates/vanilla/frontend/assets/img/favicon.ico +0 -0
- package/templates/vanilla/frontend/assets/img/logo-black.svg +1 -0
- package/templates/vanilla/frontend/assets/img/logo-white.svg +1 -0
- package/templates/vanilla/frontend/assets/js/index.js +74 -0
- package/templates/vanilla/{src → frontend/assets/js/near}/config.js +1 -1
- package/templates/{angular/src → vanilla/frontend/assets/js/near}/utils.js +14 -4
- package/templates/vanilla/{src → frontend}/index.html +22 -27
- package/templates/vanilla/near.gitignore +1 -1
- package/templates/vanilla/package.json +25 -31
- package/utils/rust-setup.js +1 -20
- package/utils/tracking.js +1 -2
- package/common/contracts/assemblyscript/assembly/__tests__/main.spec.ts +0 -9
- package/common/contracts/assemblyscript/assembly/index.ts +0 -40
- package/common/contracts/assemblyscript/compile.js +0 -50
- package/common/contracts/rust/Cargo.lock +0 -638
- package/common/contracts/rust/compile.js +0 -53
- package/common/contracts/rust/res/.gitkeep +0 -0
- package/common/contracts/rust/src/lib.rs +0 -121
- package/templates/angular/.gitpod.yml +0 -6
- package/templates/angular/README.md +0 -102
- package/templates/angular/angular.json +0 -126
- package/templates/angular/extra-webpack.config.ts +0 -7
- package/templates/angular/karma.conf.js +0 -40
- package/templates/angular/near.gitignore +0 -46
- package/templates/angular/neardev/shared-test/test.near.json +0 -1
- package/templates/angular/neardev/shared-test-staging/test.near.json +0 -1
- package/templates/angular/package.json +0 -63
- package/templates/angular/set-contract-name.js +0 -16
- package/templates/angular/src/app/app.component.html +0 -87
- package/templates/angular/src/app/app.component.spec.ts +0 -107
- package/templates/angular/src/app/app.component.ts +0 -88
- package/templates/angular/src/app/app.module.ts +0 -21
- package/templates/angular/src/app/components/notification/notification.component.html +0 -12
- package/templates/angular/src/app/components/notification/notification.component.spec.ts +0 -25
- package/templates/angular/src/app/components/notification/notification.component.ts +0 -23
- package/templates/angular/src/app/services/window.service.ts +0 -43
- package/templates/angular/src/config.d.ts +0 -13
- package/templates/angular/src/config.js +0 -62
- package/templates/angular/src/contract-name.js +0 -1
- package/templates/angular/src/environments/environment.prod.ts +0 -3
- package/templates/angular/src/environments/environment.ts +0 -16
- package/templates/angular/src/index.html +0 -15
- package/templates/angular/src/main.ts +0 -15
- package/templates/angular/src/polyfills.ts +0 -64
- package/templates/angular/src/styles.scss +0 -1
- package/templates/angular/src/test.ts +0 -25
- package/templates/angular/src/utils.d.ts +0 -3
- package/templates/angular/src/window.d.ts +0 -15
- package/templates/angular/tsconfig.app.json +0 -15
- package/templates/angular/tsconfig.json +0 -21
- package/templates/angular/tsconfig.spec.json +0 -18
- package/templates/angular/tslint.json +0 -149
- package/templates/react/babel.config.js +0 -3
- package/templates/react/neardev/shared-test-staging/test.near.json +0 -1
- package/templates/react/src/index.js +0 -13
- package/templates/react/src/jest.init.js +0 -1
- package/templates/react/src/main.test.js +0 -28
- package/templates/react/src/utils.js +0 -39
- package/templates/react/src/wallet/login/index.html +0 -28
- package/templates/vanilla/neardev/shared-test-staging/test.near.json +0 -1
- package/templates/vanilla/src/index.js +0 -113
- package/templates/vanilla/src/main.test.js +0 -15
- package/templates/vanilla/src/utils.js +0 -39
- package/templates/vanilla/src/wallet/login/index.html +0 -28
- package/templates/vue/.gitpod.yml +0 -6
- package/templates/vue/README.md +0 -101
- package/templates/vue/babel.config.js +0 -5
- package/templates/vue/copy-dev-account.js +0 -7
- package/templates/vue/jest.config.js +0 -7
- package/templates/vue/near.gitignore +0 -46
- package/templates/vue/neardev/shared-test/test.near.json +0 -1
- package/templates/vue/neardev/shared-test-staging/test.near.json +0 -1
- package/templates/vue/package.json +0 -86
- package/templates/vue/src/App.vue +0 -37
- package/templates/vue/src/components/Notification.vue +0 -38
- package/templates/vue/src/components/SignedIn.vue +0 -179
- package/templates/vue/src/components/SignedOut.vue +0 -34
- package/templates/vue/src/config.js +0 -63
- package/templates/vue/src/main.js +0 -16
- package/templates/vue/tests/unit/Notification.spec.js +0 -26
- package/templates/vue/tests/unit/SignedIn.spec.js +0 -24
- package/templates/vue/tests/unit/SignedOut.spec.js +0 -17
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import 'regenerator-runtime/runtime'
|
|
2
2
|
import React from 'react'
|
|
3
|
-
import { login, logout } from './utils'
|
|
4
|
-
import './global.css'
|
|
5
3
|
|
|
6
|
-
import
|
|
7
|
-
|
|
4
|
+
import './assets/css/global.css'
|
|
5
|
+
|
|
6
|
+
import {login, logout, get_greeting, set_greeting} from './assets/js/near/utils'
|
|
7
|
+
import getConfig from './assets/js/near/config'
|
|
8
|
+
|
|
8
9
|
|
|
9
10
|
export default function App() {
|
|
10
11
|
// use React Hooks to store greeting in component state
|
|
@@ -20,15 +21,11 @@ export default function App() {
|
|
|
20
21
|
// Learn more: https://reactjs.org/docs/hooks-intro.html
|
|
21
22
|
React.useEffect(
|
|
22
23
|
() => {
|
|
23
|
-
//
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
.then(greetingFromContract => {
|
|
29
|
-
setGreeting(greetingFromContract)
|
|
30
|
-
})
|
|
31
|
-
}
|
|
24
|
+
// get_greeting is in near/utils.js
|
|
25
|
+
get_greeting()
|
|
26
|
+
.then(greetingFromContract => {
|
|
27
|
+
setGreeting(greetingFromContract)
|
|
28
|
+
})
|
|
32
29
|
},
|
|
33
30
|
|
|
34
31
|
// The second argument to useEffect tells React when to re-run the effect
|
|
@@ -41,19 +38,27 @@ export default function App() {
|
|
|
41
38
|
if (!window.walletConnection.isSignedIn()) {
|
|
42
39
|
return (
|
|
43
40
|
<main>
|
|
44
|
-
<h1>
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
41
|
+
<h1>
|
|
42
|
+
<label
|
|
43
|
+
htmlFor="greeting"
|
|
44
|
+
style={{
|
|
45
|
+
color: 'var(--secondary)',
|
|
46
|
+
borderBottom: '2px solid var(--secondary)'
|
|
47
|
+
}}
|
|
48
|
+
>
|
|
49
|
+
{greeting}
|
|
50
|
+
</label>!
|
|
51
|
+
Welcome to NEAR!
|
|
52
|
+
</h1>
|
|
49
53
|
<p>
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
convertible to other currencies – they're just for testing!
|
|
54
|
+
Your contract is storing a greeting message in the NEAR blockchain. To
|
|
55
|
+
change it you need to sign in using the NEAR Wallet. It is very simple,
|
|
56
|
+
just use the button below.
|
|
54
57
|
</p>
|
|
55
58
|
<p>
|
|
56
|
-
|
|
59
|
+
Do not worry, this app runs in the test network ("testnet"). It works
|
|
60
|
+
just like the main network ("mainnet"), but using NEAR Tokens that are
|
|
61
|
+
only for testing!
|
|
57
62
|
</p>
|
|
58
63
|
<p style={{ textAlign: 'center', marginTop: '2.5em' }}>
|
|
59
64
|
<button onClick={login}>Sign in</button>
|
|
@@ -96,10 +101,8 @@ export default function App() {
|
|
|
96
101
|
|
|
97
102
|
try {
|
|
98
103
|
// make an update call to the smart contract
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
message: newGreeting
|
|
102
|
-
})
|
|
104
|
+
// pass the value that the user entered in the greeting field
|
|
105
|
+
await set_greeting(newGreeting)
|
|
103
106
|
} catch (e) {
|
|
104
107
|
alert(
|
|
105
108
|
'Something went wrong! ' +
|
|
@@ -157,7 +160,7 @@ export default function App() {
|
|
|
157
160
|
</p>
|
|
158
161
|
<ol>
|
|
159
162
|
<li>
|
|
160
|
-
Look in <code>src/App.js</code> and <code>src/utils.js</code> – you'll see <code>
|
|
163
|
+
Look in <code>src/App.js</code> and <code>src/utils.js</code> – you'll see <code>get_greeting</code> and <code>set_greeting</code> being called on <code>contract</code>. What's this?
|
|
161
164
|
</li>
|
|
162
165
|
<li>
|
|
163
166
|
Ultimately, this <code>contract</code> code is defined in <code>assembly/main.ts</code> – this is the source code for your <a target="_blank" rel="noreferrer" href="https://docs.near.org/docs/develop/contracts/overview">smart contract</a>.</li>
|
|
@@ -176,14 +179,16 @@ export default function App() {
|
|
|
176
179
|
|
|
177
180
|
// this component gets rendered by App after the form is submitted
|
|
178
181
|
function Notification() {
|
|
182
|
+
const { networkId } = getConfig(process.env.NODE_ENV || 'development')
|
|
179
183
|
const urlPrefix = `https://explorer.${networkId}.near.org/accounts`
|
|
184
|
+
|
|
180
185
|
return (
|
|
181
186
|
<aside>
|
|
182
187
|
<a target="_blank" rel="noreferrer" href={`${urlPrefix}/${window.accountId}`}>
|
|
183
188
|
{window.accountId}
|
|
184
189
|
</a>
|
|
185
190
|
{' '/* React trims whitespace around tags; insert literal space character when needed */}
|
|
186
|
-
called method: '
|
|
191
|
+
called method: 'set_greeting' in contract:
|
|
187
192
|
{' '}
|
|
188
193
|
<a target="_blank" rel="noreferrer" href={`${urlPrefix}/${window.contract.contractId}`}>
|
|
189
194
|
{window.contract.contractId}
|
|
File without changes
|
|
@@ -26,11 +26,12 @@ body {
|
|
|
26
26
|
|
|
27
27
|
main {
|
|
28
28
|
margin: 0 auto;
|
|
29
|
-
max-width:
|
|
29
|
+
max-width: 26em;
|
|
30
|
+
text-align: justify;
|
|
30
31
|
}
|
|
31
32
|
|
|
32
33
|
h1 {
|
|
33
|
-
background-image: url(
|
|
34
|
+
background-image: url(../img/logo-black.svg);
|
|
34
35
|
background-position: center 1em;
|
|
35
36
|
background-repeat: no-repeat;
|
|
36
37
|
background-size: auto 1.5em;
|
|
@@ -180,7 +181,7 @@ aside footer *:last-child {
|
|
|
180
181
|
--light-gray: #444;
|
|
181
182
|
}
|
|
182
183
|
h1 {
|
|
183
|
-
background-image: url(
|
|
184
|
+
background-image: url(../img/logo-white.svg);
|
|
184
185
|
}
|
|
185
186
|
input:focus {
|
|
186
187
|
box-shadow: 0 0 10em rgba(255, 255, 255, 0.02) inset;
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -3,8 +3,6 @@ import getConfig from './config'
|
|
|
3
3
|
|
|
4
4
|
const nearConfig = getConfig(process.env.NODE_ENV || 'development')
|
|
5
5
|
|
|
6
|
-
console.log(nearConfig)
|
|
7
|
-
|
|
8
6
|
// Initialize contract & set global variables
|
|
9
7
|
export async function initContract() {
|
|
10
8
|
// Initialize connection to the NEAR testnet
|
|
@@ -20,9 +18,9 @@ export async function initContract() {
|
|
|
20
18
|
// Initializing our contract APIs by contract name and configuration
|
|
21
19
|
window.contract = await new Contract(window.walletConnection.account(), nearConfig.contractName, {
|
|
22
20
|
// View methods are read only. They don't modify the state, but usually return some value.
|
|
23
|
-
viewMethods: ['
|
|
21
|
+
viewMethods: ['get_greeting'],
|
|
24
22
|
// Change methods can modify the state. But you don't receive the returned value when called.
|
|
25
|
-
changeMethods: ['
|
|
23
|
+
changeMethods: ['set_greeting'],
|
|
26
24
|
})
|
|
27
25
|
}
|
|
28
26
|
|
|
@@ -39,3 +37,15 @@ export function login() {
|
|
|
39
37
|
// the private key in localStorage.
|
|
40
38
|
window.walletConnection.requestSignIn(nearConfig.contractName)
|
|
41
39
|
}
|
|
40
|
+
|
|
41
|
+
export async function set_greeting(message){
|
|
42
|
+
let response = await window.contract.set_greeting({
|
|
43
|
+
args:{message: message}
|
|
44
|
+
})
|
|
45
|
+
return response
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export async function get_greeting(){
|
|
49
|
+
let greeting = await window.contract.get_greeting()
|
|
50
|
+
return greeting
|
|
51
|
+
}
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
<html lang="en">
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="utf-8" />
|
|
5
|
-
<link rel="icon" href="./assets/favicon.ico" />
|
|
5
|
+
<link rel="icon" href="./assets/img/favicon.ico" />
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
7
|
-
<link rel="apple-touch-icon" href="./assets/favicon.ico" />
|
|
7
|
+
<link rel="apple-touch-icon" href="./assets/img/favicon.ico" />
|
|
8
8
|
<title>Welcome to NEAR with React</title>
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
|
@@ -20,6 +20,6 @@
|
|
|
20
20
|
To begin the development, run `npm start` or `yarn start`.
|
|
21
21
|
To create a production bundle, use `npm run build` or `yarn build`.
|
|
22
22
|
-->
|
|
23
|
-
<script src="./index.js"></script>
|
|
23
|
+
<script src="./index.js" type="module"></script>
|
|
24
24
|
</body>
|
|
25
25
|
</html>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { createRoot } from 'react-dom/client'
|
|
3
|
+
import App from './App'
|
|
4
|
+
import { initContract } from './assets/js/near/utils'
|
|
5
|
+
|
|
6
|
+
const container = document.querySelector('#root')
|
|
7
|
+
const root = createRoot(container) // createRoot(container!) if you use TypeScript
|
|
8
|
+
|
|
9
|
+
window.nearInitPromise = initContract()
|
|
10
|
+
.then(() => {
|
|
11
|
+
<App />
|
|
12
|
+
root.render(<App tab="home" />)
|
|
13
|
+
})
|
|
14
|
+
.catch(console.error)
|
|
@@ -1,59 +1,45 @@
|
|
|
1
1
|
{
|
|
2
|
-
"name": "
|
|
3
|
-
"version": "
|
|
4
|
-
"license": "
|
|
2
|
+
"name": "greeter",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"license": "(MIT AND Apache-2.0)",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"build": "npm run build:contract && npm run build:web",
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
-
"deploy:contract": "near deploy",
|
|
12
|
-
"deploy:pages": "gh-pages -d dist/",
|
|
13
|
-
"deploy": "npm run build && npm run deploy:contract && npm run deploy:pages",
|
|
14
|
-
"prestart": "npm run build:contract:debug && npm run dev:deploy:contract",
|
|
15
|
-
"start": "echo The app is starting! It will automatically open in your browser when ready && env-cmd -f ./neardev/dev-account.env parcel src/index.html --open",
|
|
7
|
+
"build:contract": "cd contract && npm run build && mkdir -p ../out && rm -f ./out/main.wasm && cp ./build/release/greeter.wasm ../out/main.wasm",
|
|
8
|
+
"build:web": "parcel build frontend/index.html --public-url ./",
|
|
9
|
+
"deploy": "npm run build:contract && near dev-deploy",
|
|
10
|
+
"start": "npm run deploy && echo The app is starting! It will automatically open in your browser when ready && env-cmd -f ./neardev/dev-account.env parcel frontend/index.html --open",
|
|
16
11
|
"dev": "nodemon --watch contract -e ts --exec \"npm run start\"",
|
|
17
|
-
"test": "npm run build:contract
|
|
12
|
+
"test": "npm run build:contract && npm run test:unit && npm run test:integration",
|
|
13
|
+
"test:unit": "cd contract && npm i && npm run test",
|
|
14
|
+
"test:integration": "npm run test:integration:ts && npm run test:integration:rs",
|
|
15
|
+
"test:integration:ts": "cd integration-tests/ts && npm run test",
|
|
16
|
+
"test:integration:rs": "cd integration-tests/rs && cargo run --example integration-tests"
|
|
18
17
|
},
|
|
19
18
|
"devDependencies": {
|
|
20
|
-
"@babel/core": "~7.
|
|
21
|
-
"@babel/preset-env": "~7.
|
|
22
|
-
"@babel/preset-react": "~7.
|
|
23
|
-
"
|
|
19
|
+
"@babel/core": "~7.18.2",
|
|
20
|
+
"@babel/preset-env": "~7.18.2",
|
|
21
|
+
"@babel/preset-react": "~7.17.12",
|
|
22
|
+
"ava": "^4.2.0",
|
|
24
23
|
"env-cmd": "~10.1.0",
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"
|
|
24
|
+
"near-cli": "~3.3.0",
|
|
25
|
+
"near-workspaces": "^2.0.0",
|
|
26
|
+
"nodemon": "~2.0.16",
|
|
27
|
+
"parcel": "^2.6.0",
|
|
28
|
+
"process": "^0.11.10",
|
|
29
|
+
"react-test-renderer": "~18.1.0",
|
|
30
|
+
"ts-node": "^10.8.0",
|
|
31
|
+
"typescript": "^4.7.2"
|
|
33
32
|
},
|
|
34
33
|
"dependencies": {
|
|
35
|
-
"near-api-js": "~0.
|
|
36
|
-
"
|
|
37
|
-
"react
|
|
38
|
-
"
|
|
34
|
+
"near-api-js": "~0.44.2",
|
|
35
|
+
"near-sdk-as": "^3.2.3",
|
|
36
|
+
"react": "~18.1.0",
|
|
37
|
+
"react-dom": "~18.1.0",
|
|
38
|
+
"regenerator-runtime": "~0.13.9"
|
|
39
39
|
},
|
|
40
40
|
"resolutions": {
|
|
41
41
|
"@babel/preset-env": "7.13.8"
|
|
42
42
|
},
|
|
43
|
-
"jest": {
|
|
44
|
-
"moduleNameMapper": {
|
|
45
|
-
"\\.(jpg|ico|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/src/__mocks__/fileMock.js",
|
|
46
|
-
"\\.(css|less)$": "<rootDir>/src/__mocks__/fileMock.js"
|
|
47
|
-
},
|
|
48
|
-
"setupFiles": [
|
|
49
|
-
"<rootDir>/src/jest.init.js"
|
|
50
|
-
],
|
|
51
|
-
"testEnvironment": "near-cli/test_environment",
|
|
52
|
-
"testPathIgnorePatterns": [
|
|
53
|
-
"<rootDir>/contract/",
|
|
54
|
-
"<rootDir>/node_modules/"
|
|
55
|
-
]
|
|
56
|
-
},
|
|
57
43
|
"browserslist": {
|
|
58
44
|
"production": [
|
|
59
45
|
">0.2%",
|
|
@@ -24,8 +24,8 @@ Exploring The Code
|
|
|
24
24
|
|
|
25
25
|
1. The "backend" code lives in the `/contract` folder. See the README there for
|
|
26
26
|
more info.
|
|
27
|
-
2. The frontend code lives in the `/
|
|
28
|
-
place to start exploring. Note that it loads in `/src/index.js`, where you
|
|
27
|
+
2. The frontend code lives in the `/frontend` folder. `/frontend/index.html` is a great
|
|
28
|
+
place to start exploring. Note that it loads in `/frontend/assets/src/js/index.js`, where you
|
|
29
29
|
can learn how the frontend connects to the NEAR blockchain.
|
|
30
30
|
3. Tests: there are different kinds of tests for the frontend and the smart
|
|
31
31
|
contract. See `contract/README` for info about how it's tested. The frontend
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
* {
|
|
2
|
+
box-sizing: border-box;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
html {
|
|
6
|
+
--bg: #efefef;
|
|
7
|
+
--fg: #1e1e1e;
|
|
8
|
+
--gray: #555;
|
|
9
|
+
--light-gray: #ccc;
|
|
10
|
+
--shadow: #e6e6e6;
|
|
11
|
+
--success: rgb(90, 206, 132);
|
|
12
|
+
--primary: #FF585D;
|
|
13
|
+
--secondary: #0072CE;
|
|
14
|
+
|
|
15
|
+
background-color: var(--bg);
|
|
16
|
+
color: var(--fg);
|
|
17
|
+
font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif;
|
|
18
|
+
font-size: calc(0.9em + 0.5vw);
|
|
19
|
+
line-height: 1.3;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
body {
|
|
23
|
+
margin: 0;
|
|
24
|
+
padding: 1em;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
main {
|
|
28
|
+
margin: 0 auto;
|
|
29
|
+
max-width: 26em;
|
|
30
|
+
text-align: justify;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
h1 {
|
|
34
|
+
background-image: url(../img/logo-black.svg);
|
|
35
|
+
background-position: center 1em;
|
|
36
|
+
background-repeat: no-repeat;
|
|
37
|
+
background-size: auto 1.5em;
|
|
38
|
+
margin-top: 0;
|
|
39
|
+
padding: 3.5em 0 0.5em;
|
|
40
|
+
text-align: center;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
a,
|
|
44
|
+
.link {
|
|
45
|
+
color: var(--primary);
|
|
46
|
+
text-decoration: none;
|
|
47
|
+
}
|
|
48
|
+
a:hover,
|
|
49
|
+
a:focus,
|
|
50
|
+
.link:hover,
|
|
51
|
+
.link:focus {
|
|
52
|
+
text-decoration: underline;
|
|
53
|
+
}
|
|
54
|
+
a:active,
|
|
55
|
+
.link:active {
|
|
56
|
+
color: var(--secondary);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
button, input {
|
|
60
|
+
font: inherit;
|
|
61
|
+
outline: none;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
button {
|
|
65
|
+
background-color: var(--secondary);
|
|
66
|
+
border-radius: 5px;
|
|
67
|
+
border: none;
|
|
68
|
+
color: #efefef;
|
|
69
|
+
cursor: pointer;
|
|
70
|
+
padding: 0.3em 0.75em;
|
|
71
|
+
transition: transform 30ms;
|
|
72
|
+
}
|
|
73
|
+
button:hover, button:focus {
|
|
74
|
+
box-shadow: 0 0 10em rgba(255, 255, 255, 0.2) inset;
|
|
75
|
+
}
|
|
76
|
+
button:active {
|
|
77
|
+
box-shadow: 0 0 10em rgba(0, 0, 0, 0.1) inset;
|
|
78
|
+
}
|
|
79
|
+
button.link {
|
|
80
|
+
background: none;
|
|
81
|
+
border: none;
|
|
82
|
+
box-shadow: none;
|
|
83
|
+
display: inline;
|
|
84
|
+
}
|
|
85
|
+
[disabled] button, button[disabled] {
|
|
86
|
+
box-shadow: none;
|
|
87
|
+
background-color: var(--light-gray);
|
|
88
|
+
color: gray;
|
|
89
|
+
cursor: not-allowed;
|
|
90
|
+
transform: none;
|
|
91
|
+
}
|
|
92
|
+
[disabled] button {
|
|
93
|
+
text-indent: -900em;
|
|
94
|
+
width: 2em;
|
|
95
|
+
position: relative;
|
|
96
|
+
}
|
|
97
|
+
[disabled] button:after {
|
|
98
|
+
content: " ";
|
|
99
|
+
display: block;
|
|
100
|
+
width: 0.8em;
|
|
101
|
+
height: 0.8em;
|
|
102
|
+
border-radius: 50%;
|
|
103
|
+
border: 2px solid #fff;
|
|
104
|
+
border-color: var(--fg) transparent var(--fg) transparent;
|
|
105
|
+
animation: loader 1.2s linear infinite;
|
|
106
|
+
position: absolute;
|
|
107
|
+
top: 0.45em;
|
|
108
|
+
right: 0.5em;
|
|
109
|
+
}
|
|
110
|
+
@keyframes loader {
|
|
111
|
+
0% { transform: rotate(0deg) }
|
|
112
|
+
100% { transform: rotate(360deg) }
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
fieldset {
|
|
116
|
+
border: none;
|
|
117
|
+
padding: 2em 0;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
input {
|
|
121
|
+
background-color: var(--shadow);
|
|
122
|
+
border: none;
|
|
123
|
+
border-radius: 5px 0 0 5px;
|
|
124
|
+
caret-color: var(--primary);
|
|
125
|
+
color: inherit;
|
|
126
|
+
padding: 0.25em 1em;
|
|
127
|
+
}
|
|
128
|
+
input::selection {
|
|
129
|
+
background-color: var(--secondary);
|
|
130
|
+
color: #efefef;
|
|
131
|
+
}
|
|
132
|
+
input:focus {
|
|
133
|
+
box-shadow: 0 0 10em rgba(0, 0, 0, 0.02) inset;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
code {
|
|
137
|
+
color: var(--gray);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
li {
|
|
141
|
+
padding-bottom: 1em;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
aside {
|
|
145
|
+
animation: notify ease-in-out 10s;
|
|
146
|
+
background-color: var(--shadow);
|
|
147
|
+
border-radius: 5px;
|
|
148
|
+
bottom: 0;
|
|
149
|
+
font-size: 0.8em;
|
|
150
|
+
margin: 1em;
|
|
151
|
+
padding: 1em;
|
|
152
|
+
position: fixed;
|
|
153
|
+
transform: translateY(10em);
|
|
154
|
+
right: 0;
|
|
155
|
+
}
|
|
156
|
+
aside footer {
|
|
157
|
+
display: flex;
|
|
158
|
+
font-size: 0.9em;
|
|
159
|
+
justify-content: space-between;
|
|
160
|
+
margin-top: 0.5em;
|
|
161
|
+
}
|
|
162
|
+
aside footer *:first-child {
|
|
163
|
+
color: var(--success);
|
|
164
|
+
}
|
|
165
|
+
aside footer *:last-child {
|
|
166
|
+
color: var(--gray);
|
|
167
|
+
}
|
|
168
|
+
@keyframes notify {
|
|
169
|
+
0% { transform: translateY(10em) }
|
|
170
|
+
5% { transform: translateY(0) }
|
|
171
|
+
95% { transform: translateY(0) }
|
|
172
|
+
100% { transform: translateY(10em) }
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
@media (prefers-color-scheme: dark) {
|
|
176
|
+
html {
|
|
177
|
+
--bg: #1e1e1e;
|
|
178
|
+
--fg: #efefef;
|
|
179
|
+
--gray: #aaa;
|
|
180
|
+
--shadow: #2a2a2a;
|
|
181
|
+
--light-gray: #444;
|
|
182
|
+
}
|
|
183
|
+
h1 {
|
|
184
|
+
background-image: url(../img/logo-white.svg);
|
|
185
|
+
}
|
|
186
|
+
input:focus {
|
|
187
|
+
box-shadow: 0 0 10em rgba(255, 255, 255, 0.02) inset;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg viewBox="0 0 288 288" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="76.81" x2="211.16" y1="211.17" y2="76.81"><stop offset=".21" stop-color="#24272a"/><stop offset=".42" stop-color="#24272a" stop-opacity="0"/><stop offset=".59" stop-color="#24272a" stop-opacity="0"/><stop offset=".81" stop-color="#24272a"/></linearGradient><path d="m88.46 216a16.45 16.45 0 0 0 12.46-5.71l112.56-130.57a16.42 16.42 0 0 0 -13.94-7.72 16.46 16.46 0 0 0 -12.41 5.65l-113.13 129.8a16.46 16.46 0 0 0 14.46 8.55z" fill="url(#a)"/><path d="m88.46 216a16.46 16.46 0 0 0 7.54-1.83v-109l87.45 104.94a16.44 16.44 0 0 0 12.64 5.89h3.45a16.46 16.46 0 0 0 16.46-16.46v-111.08a16.46 16.46 0 0 0 -16.46-16.46 16.36 16.36 0 0 0 -7.54 1.81v109.05l-87.45-104.94a16.44 16.44 0 0 0 -12.64-5.92h-3.45a16.46 16.46 0 0 0 -16.46 16.46v111.08a16.46 16.46 0 0 0 16.46 16.46z" fill="#24272a"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg viewBox="0 0 288 288" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="76.81" x2="211.16" y1="211.17" y2="76.81"><stop offset=".21" stop-color="#fff"/><stop offset=".42" stop-color="#fff" stop-opacity="0"/><stop offset=".59" stop-color="#fff" stop-opacity="0"/><stop offset=".81" stop-color="#fff"/></linearGradient><path d="m88.46 216a16.45 16.45 0 0 0 12.46-5.71l112.56-130.57a16.42 16.42 0 0 0 -13.94-7.72 16.46 16.46 0 0 0 -12.41 5.65l-113.13 129.8a16.46 16.46 0 0 0 14.46 8.55z" fill="url(#a)"/><path d="m88.46 216a16.46 16.46 0 0 0 7.54-1.83v-109l87.45 104.94a16.44 16.44 0 0 0 12.64 5.89h3.45a16.46 16.46 0 0 0 16.46-16.46v-111.08a16.46 16.46 0 0 0 -16.46-16.46 16.36 16.36 0 0 0 -7.54 1.81v109.05l-87.45-104.94a16.44 16.44 0 0 0 -12.64-5.92h-3.45a16.46 16.46 0 0 0 -16.46 16.46v111.08a16.46 16.46 0 0 0 16.46 16.46z" fill="#fff"/></svg>
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import 'regenerator-runtime/runtime'
|
|
2
|
+
import { initContract, login, logout, set_greeting, get_greeting } from './near/utils'
|
|
3
|
+
|
|
4
|
+
// On submit, get the greeting and send it to the contract
|
|
5
|
+
document.querySelector('form').onsubmit = async (event) => {
|
|
6
|
+
event.preventDefault()
|
|
7
|
+
|
|
8
|
+
// get elements from the form using their id attribute
|
|
9
|
+
const { fieldset, greeting } = event.target.elements
|
|
10
|
+
|
|
11
|
+
// disable the form while the value gets updated on-chain
|
|
12
|
+
fieldset.disabled = true
|
|
13
|
+
|
|
14
|
+
try {
|
|
15
|
+
await set_greeting(greeting.value)
|
|
16
|
+
} catch (e) {
|
|
17
|
+
alert(
|
|
18
|
+
'Something went wrong! ' +
|
|
19
|
+
'Maybe you need to sign out and back in? ' +
|
|
20
|
+
'Check your browser console for more info.'
|
|
21
|
+
)
|
|
22
|
+
throw e
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// re-enable the form, whether the call succeeded or failed
|
|
26
|
+
fieldset.disabled = false
|
|
27
|
+
|
|
28
|
+
// update the greeting in the UI
|
|
29
|
+
await fetchGreeting()
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
document.querySelector('#sign-in-button').onclick = login
|
|
33
|
+
document.querySelector('#sign-out-button').onclick = logout
|
|
34
|
+
|
|
35
|
+
async function fetchGreeting() {
|
|
36
|
+
// Get greeting from the contract
|
|
37
|
+
const currentGreeting = await get_greeting()
|
|
38
|
+
|
|
39
|
+
// Set all elements marked as greeting with the current greeting
|
|
40
|
+
document.querySelectorAll('[data-behavior=greeting]').forEach(el => {
|
|
41
|
+
el.innerText = currentGreeting
|
|
42
|
+
el.value = currentGreeting
|
|
43
|
+
})
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// `nearInitPromise` gets called on page load
|
|
47
|
+
window.nearInitPromise = initContract()
|
|
48
|
+
.then(flow)
|
|
49
|
+
.catch(console.error)
|
|
50
|
+
|
|
51
|
+
function flow(){
|
|
52
|
+
if (window.walletConnection.isSignedIn()){
|
|
53
|
+
signedInFlow()
|
|
54
|
+
}else{
|
|
55
|
+
signedOutFlow()
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Display the signed-out-flow container
|
|
60
|
+
function signedOutFlow() {
|
|
61
|
+
document.querySelector('#signed-out-flow').style.display = 'block'
|
|
62
|
+
fetchGreeting()
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Displaying the signed in flow container and fill in account-specific data
|
|
66
|
+
function signedInFlow() {
|
|
67
|
+
document.querySelector('#signed-in-flow').style.display = 'block'
|
|
68
|
+
|
|
69
|
+
document.querySelectorAll('[data-behavior=account-id]').forEach(el => {
|
|
70
|
+
el.innerText = window.accountId
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
fetchGreeting()
|
|
74
|
+
}
|
|
@@ -3,8 +3,6 @@ import getConfig from './config'
|
|
|
3
3
|
|
|
4
4
|
const nearConfig = getConfig(process.env.NODE_ENV || 'development')
|
|
5
5
|
|
|
6
|
-
console.log(nearConfig)
|
|
7
|
-
|
|
8
6
|
// Initialize contract & set global variables
|
|
9
7
|
export async function initContract() {
|
|
10
8
|
// Initialize connection to the NEAR testnet
|
|
@@ -20,9 +18,9 @@ export async function initContract() {
|
|
|
20
18
|
// Initializing our contract APIs by contract name and configuration
|
|
21
19
|
window.contract = await new Contract(window.walletConnection.account(), nearConfig.contractName, {
|
|
22
20
|
// View methods are read only. They don't modify the state, but usually return some value.
|
|
23
|
-
viewMethods: ['
|
|
21
|
+
viewMethods: ['get_greeting'],
|
|
24
22
|
// Change methods can modify the state. But you don't receive the returned value when called.
|
|
25
|
-
changeMethods: ['
|
|
23
|
+
changeMethods: ['set_greeting'],
|
|
26
24
|
})
|
|
27
25
|
}
|
|
28
26
|
|
|
@@ -39,3 +37,15 @@ export function login() {
|
|
|
39
37
|
// the private key in localStorage.
|
|
40
38
|
window.walletConnection.requestSignIn(nearConfig.contractName)
|
|
41
39
|
}
|
|
40
|
+
|
|
41
|
+
export async function set_greeting(message){
|
|
42
|
+
let response = await window.contract.set_greeting({
|
|
43
|
+
args:{message: message}
|
|
44
|
+
})
|
|
45
|
+
return response
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export async function get_greeting(){
|
|
49
|
+
let greeting = await window.contract.get_greeting()
|
|
50
|
+
return greeting
|
|
51
|
+
}
|