create-near-app 3.0.0 → 4.0.0-beta.2.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/README.md +37 -31
- package/dist/app.js +76 -0
- package/dist/checks.js +34 -0
- package/dist/make.js +135 -0
- package/dist/messages.js +56 -0
- package/dist/package-json.js +164 -0
- package/dist/tracking.js +34 -0
- package/dist/types.js +3 -0
- package/dist/user-input.js +211 -0
- package/index.js +1 -184
- package/package.json +49 -40
- package/{contracts → templates/contracts}/assemblyscript/README.md +6 -5
- package/templates/contracts/assemblyscript/as-pect.config.js +1 -0
- package/{contracts → templates/contracts}/assemblyscript/asconfig.json +0 -0
- package/{contracts → templates/contracts}/assemblyscript/assembly/__tests__/as-pect.d.ts +0 -0
- package/templates/contracts/assemblyscript/assembly/__tests__/main.spec.ts +11 -0
- package/{contracts → templates/contracts}/assemblyscript/assembly/as_types.d.ts +0 -0
- package/{contracts → templates/contracts}/assemblyscript/assembly/index.ts +5 -5
- package/{contracts → templates/contracts}/assemblyscript/assembly/tsconfig.json +0 -0
- package/templates/contracts/assemblyscript/package.json +14 -0
- package/templates/contracts/js/README.md +23 -0
- package/templates/contracts/js/babel.config.json +7 -0
- package/templates/contracts/js/package.json +18 -0
- package/templates/contracts/js/src/contract.ts +31 -0
- package/templates/contracts/js/tsconfig.json +10 -0
- package/{contracts → templates/contracts}/rust/.cargo/config +0 -0
- package/{contracts → templates/contracts}/rust/Cargo.toml +1 -1
- package/{contracts → templates/contracts}/rust/README.md +6 -8
- package/{contracts → templates/contracts}/rust/src/lib.rs +0 -0
- package/templates/frontend/react/frontend/App.js +66 -0
- package/templates/{react/frontend/assets/img → frontend/react/frontend/assets}/favicon.ico +0 -0
- package/templates/{vanilla/frontend/assets/css → frontend/react/frontend/assets}/global.css +64 -80
- package/templates/{react/frontend/assets/img → frontend/react/frontend/assets}/logo-black.svg +0 -0
- package/templates/{react/frontend/assets/img → frontend/react/frontend/assets}/logo-white.svg +0 -0
- package/templates/frontend/react/frontend/index.html +15 -0
- package/templates/frontend/react/frontend/index.js +15 -0
- package/templates/{react/frontend/assets/js/near/utils.js → frontend/react/frontend/near-api.js} +19 -19
- package/templates/frontend/react/frontend/near-config.js +61 -0
- package/templates/frontend/react/frontend/package.json +44 -0
- package/templates/frontend/react/frontend/ui-components.js +60 -0
- package/templates/{vanilla/frontend/assets/img → frontend/vanilla/frontend/assets}/favicon.ico +0 -0
- package/templates/{react/frontend/assets/css → frontend/vanilla/frontend/assets}/global.css +64 -80
- package/templates/{vanilla/frontend/assets/img → frontend/vanilla/frontend/assets}/logo-black.svg +0 -0
- package/templates/{vanilla/frontend/assets/img → frontend/vanilla/frontend/assets}/logo-white.svg +0 -0
- package/templates/frontend/vanilla/frontend/index.html +86 -0
- package/templates/frontend/vanilla/frontend/index.js +78 -0
- package/templates/{vanilla/frontend/assets/js/near/utils.js → frontend/vanilla/frontend/near-api.js} +18 -18
- package/templates/frontend/vanilla/frontend/near-config.js +62 -0
- package/templates/frontend/vanilla/frontend/package.json +18 -0
- package/{integration-tests/ts → templates/integration-tests/classic-tests}/ava.config.cjs +9 -9
- package/{integration-tests/ts → templates/integration-tests/classic-tests}/package.json +5 -4
- package/templates/integration-tests/classic-tests/src/config.ts +34 -0
- package/templates/integration-tests/classic-tests/src/main.ava.ts +32 -0
- package/{integration-tests → templates/integration-tests/workspaces-tests}/rs/Cargo.toml +0 -0
- package/{integration-tests → templates/integration-tests/workspaces-tests}/rs/src/tests.rs +5 -3
- package/templates/{react → integration-tests/workspaces-tests/ts}/ava.config.cjs +9 -9
- package/templates/integration-tests/workspaces-tests/ts/package.json +17 -0
- package/templates/integration-tests/workspaces-tests/ts/src/main.ava.ts +50 -0
- package/templates/{react → shared}/.gitpod.yml +2 -2
- package/templates/{vanilla → shared}/README.md +29 -30
- package/templates/{react → shared}/near.gitignore +1 -1
- package/contracts/assemblyscript/as-pect.config.js +0 -1
- package/contracts/assemblyscript/assembly/__tests__/main.spec.ts +0 -11
- package/contracts/assemblyscript/package.json +0 -13
- package/integration-tests/ts/src/main.ava.ts +0 -44
- package/templates/react/README.md +0 -102
- package/templates/react/frontend/App.js +0 -202
- package/templates/react/frontend/__mocks__/fileMock.js +0 -3
- package/templates/react/frontend/assets/js/near/config.js +0 -63
- package/templates/react/frontend/index.html +0 -25
- package/templates/react/frontend/index.js +0 -14
- package/templates/react/neardev/shared-test/test.near.json +0 -1
- package/templates/react/package.json +0 -55
- package/templates/vanilla/.gitattributes +0 -2
- package/templates/vanilla/.gitpod.yml +0 -6
- package/templates/vanilla/frontend/assets/js/index.js +0 -74
- package/templates/vanilla/frontend/assets/js/near/config.js +0 -63
- package/templates/vanilla/frontend/index.html +0 -103
- package/templates/vanilla/near.gitignore +0 -27
- package/templates/vanilla/neardev/shared-test/test.near.json +0 -1
- package/templates/vanilla/package.json +0 -34
- package/utils/rust-setup.js +0 -102
- package/utils/tracking.js +0 -29
|
@@ -27,17 +27,75 @@ body {
|
|
|
27
27
|
main {
|
|
28
28
|
margin: 0 auto;
|
|
29
29
|
max-width: 26em;
|
|
30
|
-
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
main.please-wait {
|
|
33
|
+
opacity: 0.5;
|
|
34
|
+
cursor: wait;
|
|
31
35
|
}
|
|
32
36
|
|
|
33
37
|
h1 {
|
|
34
|
-
background-image: url(
|
|
38
|
+
background-image: url(./logo-black.svg);
|
|
35
39
|
background-position: center 1em;
|
|
36
40
|
background-repeat: no-repeat;
|
|
37
41
|
background-size: auto 1.5em;
|
|
38
42
|
margin-top: 0;
|
|
39
|
-
padding: 3.5em 0 0
|
|
43
|
+
padding: 3.5em 0 0;
|
|
40
44
|
text-align: center;
|
|
45
|
+
font-size: 1.5em;
|
|
46
|
+
}
|
|
47
|
+
.greeting {
|
|
48
|
+
color: var(--secondary);
|
|
49
|
+
text-decoration: underline;
|
|
50
|
+
}
|
|
51
|
+
h2 {
|
|
52
|
+
text-align: center;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.please-wait .change {
|
|
56
|
+
pointer-events: none;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
ul.information {
|
|
60
|
+
margin: 2em 0 2em 0;
|
|
61
|
+
padding: 0;
|
|
62
|
+
text-align: left;
|
|
63
|
+
font-size: 0.8em;
|
|
64
|
+
|
|
65
|
+
}
|
|
66
|
+
.information li:first-child {
|
|
67
|
+
border-top: 1px solid var(--light-gray);
|
|
68
|
+
}
|
|
69
|
+
.information li {
|
|
70
|
+
padding: 0.5em 0;
|
|
71
|
+
border-bottom: 1px solid var(--light-gray);
|
|
72
|
+
list-style: none;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.change {
|
|
76
|
+
display: flex;
|
|
77
|
+
flex-direction: column;
|
|
78
|
+
align-content: stretch;
|
|
79
|
+
justify-content: space-evenly;
|
|
80
|
+
align-items: stretch;
|
|
81
|
+
font-size: 1em;
|
|
82
|
+
border: 2px solid var(--light-gray);
|
|
83
|
+
padding: 0.5em;
|
|
84
|
+
}
|
|
85
|
+
.change > div {
|
|
86
|
+
display: flex;
|
|
87
|
+
align-content: stretch;
|
|
88
|
+
justify-content: space-evenly;
|
|
89
|
+
align-items: stretch;
|
|
90
|
+
}
|
|
91
|
+
.change input {
|
|
92
|
+
flex: 1;
|
|
93
|
+
}
|
|
94
|
+
.change label {
|
|
95
|
+
display: block;
|
|
96
|
+
text-align: left;
|
|
97
|
+
margin-right: 10px;
|
|
98
|
+
padding-bottom: 0.5em;
|
|
41
99
|
}
|
|
42
100
|
|
|
43
101
|
a,
|
|
@@ -73,57 +131,14 @@ button {
|
|
|
73
131
|
button:hover, button:focus {
|
|
74
132
|
box-shadow: 0 0 10em rgba(255, 255, 255, 0.2) inset;
|
|
75
133
|
}
|
|
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
134
|
|
|
120
135
|
input {
|
|
121
|
-
background-color: var(--
|
|
136
|
+
background-color: var(--light-gray);
|
|
122
137
|
border: none;
|
|
123
138
|
border-radius: 5px 0 0 5px;
|
|
124
139
|
caret-color: var(--primary);
|
|
125
140
|
color: inherit;
|
|
126
|
-
padding: 0.25em
|
|
141
|
+
padding: 0.25em 0.5em;
|
|
127
142
|
}
|
|
128
143
|
input::selection {
|
|
129
144
|
background-color: var(--secondary);
|
|
@@ -141,37 +156,6 @@ li {
|
|
|
141
156
|
padding-bottom: 1em;
|
|
142
157
|
}
|
|
143
158
|
|
|
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
159
|
@media (prefers-color-scheme: dark) {
|
|
176
160
|
html {
|
|
177
161
|
--bg: #1e1e1e;
|
|
@@ -181,7 +165,7 @@ aside footer *:last-child {
|
|
|
181
165
|
--light-gray: #444;
|
|
182
166
|
}
|
|
183
167
|
h1 {
|
|
184
|
-
background-image: url(
|
|
168
|
+
background-image: url(./logo-white.svg);
|
|
185
169
|
}
|
|
186
170
|
input:focus {
|
|
187
171
|
box-shadow: 0 0 10em rgba(255, 255, 255, 0.02) inset;
|
package/templates/{vanilla/frontend/assets/img → frontend/vanilla/frontend/assets}/logo-black.svg
RENAMED
|
File without changes
|
package/templates/{vanilla/frontend/assets/img → frontend/vanilla/frontend/assets}/logo-white.svg
RENAMED
|
File without changes
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<link rel="icon" href="assets/favicon.ico"/>
|
|
7
|
+
<link rel="apple-touch-icon" href="assets/favicon.ico"/>
|
|
8
|
+
<title>Welcome to NEAR</title>
|
|
9
|
+
<link rel="stylesheet" href="assets/global.css">
|
|
10
|
+
</head>
|
|
11
|
+
<body>
|
|
12
|
+
<main id="signed-out-flow" style="display: none">
|
|
13
|
+
<h1>
|
|
14
|
+
The contract says: <span class="greeting" data-behavior="greeting"></span>
|
|
15
|
+
</h1>
|
|
16
|
+
<h3>
|
|
17
|
+
Welcome to NEAR!
|
|
18
|
+
</h3>
|
|
19
|
+
<p>
|
|
20
|
+
Your contract is storing a greeting message in the NEAR blockchain. To
|
|
21
|
+
change it you need to sign in using the NEAR Wallet. It is very simple,
|
|
22
|
+
just use the button below.
|
|
23
|
+
</p>
|
|
24
|
+
<p>
|
|
25
|
+
Do not worry, this app runs in the test network ("testnet"). It works
|
|
26
|
+
just like the main network ("mainnet"), but using NEAR Tokens that are
|
|
27
|
+
only for testing!
|
|
28
|
+
</p>
|
|
29
|
+
<p style="text-align: center; margin-top: 2.5em">
|
|
30
|
+
<button id="sign-in-button">Sign in with NEAR Wallet</button>
|
|
31
|
+
</p>
|
|
32
|
+
</main>
|
|
33
|
+
|
|
34
|
+
<div id="signed-in-flow" style="display: none">
|
|
35
|
+
<button style="float: right" id="sign-out-button">
|
|
36
|
+
Sign out <span data-behavior="account-id"></span>
|
|
37
|
+
</button>
|
|
38
|
+
<main>
|
|
39
|
+
<h1>
|
|
40
|
+
The contract says: <span class="greeting" data-behavior="greeting"></span>
|
|
41
|
+
</h1>
|
|
42
|
+
<form class="change">
|
|
43
|
+
<label for="greeting">Change greeting:</label>
|
|
44
|
+
<div>
|
|
45
|
+
<input
|
|
46
|
+
autocomplete="off"
|
|
47
|
+
id="greeting"
|
|
48
|
+
data-behavior="greeting"
|
|
49
|
+
/>
|
|
50
|
+
<button>Save</button>
|
|
51
|
+
</div>
|
|
52
|
+
</form>
|
|
53
|
+
<p>
|
|
54
|
+
Look at that! A Hello World app! This greeting is stored on the NEAR blockchain. Check it out:
|
|
55
|
+
</p>
|
|
56
|
+
<ol>
|
|
57
|
+
<li>
|
|
58
|
+
Look in <code>index.js</code> and <code>near-api.js</code> – you'll see <code>get_greeting</code>
|
|
59
|
+
and <code>set_greeting</code> being called on <code>contract</code>.
|
|
60
|
+
What's this?
|
|
61
|
+
</li>
|
|
62
|
+
<li>
|
|
63
|
+
Ultimately, this <code>contract</code> code is defined in
|
|
64
|
+
<code>assembly/index.ts</code> – this is the source code for your
|
|
65
|
+
<a target="_blank" href="https://docs.near.org/docs/develop/contracts/overview">smart contract</a>.
|
|
66
|
+
</li>
|
|
67
|
+
<li>
|
|
68
|
+
When you run <code>npm run dev</code>, the code in
|
|
69
|
+
<code>assembly/index.ts</code> gets deployed to the NEAR testnet. You
|
|
70
|
+
can see how this happens by looking in <code>package.json</code> at the
|
|
71
|
+
<code>scripts</code> section to find the <code>dev</code> command.
|
|
72
|
+
</li>
|
|
73
|
+
</ol>
|
|
74
|
+
<hr>
|
|
75
|
+
<p>
|
|
76
|
+
To keep learning, check out
|
|
77
|
+
<a target="_blank" href="https://docs.near.org">the NEAR docs</a>
|
|
78
|
+
or look through some
|
|
79
|
+
<a target="_blank" href="https://examples.near.org">example apps</a>.
|
|
80
|
+
</p>
|
|
81
|
+
</main>
|
|
82
|
+
</div>
|
|
83
|
+
|
|
84
|
+
<script src="index.js" type="module"></script>
|
|
85
|
+
</body>
|
|
86
|
+
</html>
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import 'regenerator-runtime/runtime';
|
|
2
|
+
import {
|
|
3
|
+
initContract,
|
|
4
|
+
signInWithNearWallet,
|
|
5
|
+
signOutNearWallet,
|
|
6
|
+
setGreetingOnContract,
|
|
7
|
+
getGreetingFromContract,
|
|
8
|
+
} from './near-api';
|
|
9
|
+
|
|
10
|
+
document.querySelector('form').onsubmit = doUserAction;
|
|
11
|
+
document.querySelector('#sign-in-button').onclick = signInWithNearWallet;
|
|
12
|
+
document.querySelector('#sign-out-button').onclick = signOutNearWallet;
|
|
13
|
+
|
|
14
|
+
// ====== Initialize the API for NEAR ======
|
|
15
|
+
window.nearInitPromise = initContract()
|
|
16
|
+
.then(() => {
|
|
17
|
+
if (window.walletConnection.isSignedIn()) {
|
|
18
|
+
signedInFlow();
|
|
19
|
+
} else {
|
|
20
|
+
signedOutFlow();
|
|
21
|
+
}
|
|
22
|
+
})
|
|
23
|
+
.catch(alert);
|
|
24
|
+
|
|
25
|
+
// Take the new greeting and send it to the contract
|
|
26
|
+
async function doUserAction(event) {
|
|
27
|
+
event.preventDefault();
|
|
28
|
+
const { greeting } = event.target.elements;
|
|
29
|
+
document
|
|
30
|
+
.querySelector('#signed-in-flow main')
|
|
31
|
+
.classList.add('please-wait');
|
|
32
|
+
try {
|
|
33
|
+
// ===== Call smart-contract to save the value on then blockchain =====
|
|
34
|
+
await setGreetingOnContract(greeting.value);
|
|
35
|
+
} catch (e) {
|
|
36
|
+
alert(
|
|
37
|
+
'Something went wrong! ' +
|
|
38
|
+
'Maybe you need to sign out and back in? ' +
|
|
39
|
+
'Check your browser console for more info.'
|
|
40
|
+
);
|
|
41
|
+
throw e;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// ===== Fetch the data from the blockchain =====
|
|
45
|
+
await fetchGreeting();
|
|
46
|
+
document
|
|
47
|
+
.querySelector('#signed-in-flow main')
|
|
48
|
+
.classList.remove('please-wait');
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Get greeting from the contract on chain
|
|
52
|
+
async function fetchGreeting() {
|
|
53
|
+
const currentGreeting = await getGreetingFromContract();
|
|
54
|
+
|
|
55
|
+
document.querySelectorAll('[data-behavior=greeting]').forEach(el => {
|
|
56
|
+
el.innerText = currentGreeting;
|
|
57
|
+
el.value = currentGreeting;
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Display the signed-out-flow container
|
|
62
|
+
function signedOutFlow() {
|
|
63
|
+
document.querySelector('#signed-in-flow').style.display = 'none';
|
|
64
|
+
document.querySelector('#signed-out-flow').style.display = 'block';
|
|
65
|
+
|
|
66
|
+
fetchGreeting();
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Displaying the signed in flow container and fill in account-specific data
|
|
70
|
+
function signedInFlow() {
|
|
71
|
+
document.querySelector('#signed-out-flow').style.display = 'none';
|
|
72
|
+
document.querySelector('#signed-in-flow').style.display = 'block';
|
|
73
|
+
document.querySelectorAll('[data-behavior=account-id]').forEach(el => {
|
|
74
|
+
el.innerText = window.accountId;
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
fetchGreeting();
|
|
78
|
+
}
|
package/templates/{vanilla/frontend/assets/js/near/utils.js → frontend/vanilla/frontend/near-api.js}
RENAMED
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import { connect, Contract, keyStores, WalletConnection } from 'near-api-js'
|
|
2
|
-
import getConfig from './config'
|
|
1
|
+
import { connect, Contract, keyStores, WalletConnection } from 'near-api-js';
|
|
2
|
+
import getConfig from './near-config';
|
|
3
3
|
|
|
4
|
-
const nearConfig = getConfig(process.env.NODE_ENV || 'development')
|
|
4
|
+
const nearConfig = getConfig(process.env.NODE_ENV || 'development');
|
|
5
5
|
|
|
6
6
|
// Initialize contract & set global variables
|
|
7
7
|
export async function initContract() {
|
|
8
8
|
// Initialize connection to the NEAR testnet
|
|
9
|
-
const near = await connect(Object.assign({ deps: { keyStore: new keyStores.BrowserLocalStorageKeyStore() } }, nearConfig))
|
|
9
|
+
const near = await connect(Object.assign({ deps: { keyStore: new keyStores.BrowserLocalStorageKeyStore() } }, nearConfig));
|
|
10
10
|
|
|
11
11
|
// Initializing Wallet based Account. It can work with NEAR testnet wallet that
|
|
12
12
|
// is hosted at https://wallet.testnet.near.org
|
|
13
|
-
window.walletConnection = new WalletConnection(near)
|
|
13
|
+
window.walletConnection = new WalletConnection(near);
|
|
14
14
|
|
|
15
15
|
// Getting the Account ID. If still unauthorized, it's just empty string
|
|
16
|
-
window.accountId = window.walletConnection.getAccountId()
|
|
16
|
+
window.accountId = window.walletConnection.getAccountId();
|
|
17
17
|
|
|
18
18
|
// Initializing our contract APIs by contract name and configuration
|
|
19
19
|
window.contract = await new Contract(window.walletConnection.account(), nearConfig.contractName, {
|
|
@@ -21,31 +21,31 @@ export async function initContract() {
|
|
|
21
21
|
viewMethods: ['get_greeting'],
|
|
22
22
|
// Change methods can modify the state. But you don't receive the returned value when called.
|
|
23
23
|
changeMethods: ['set_greeting'],
|
|
24
|
-
})
|
|
24
|
+
});
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
export function
|
|
28
|
-
window.walletConnection.signOut()
|
|
27
|
+
export function signOutNearWallet() {
|
|
28
|
+
window.walletConnection.signOut();
|
|
29
29
|
// reload page
|
|
30
|
-
window.location.replace(window.location.origin + window.location.pathname)
|
|
30
|
+
window.location.replace(window.location.origin + window.location.pathname);
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
export function
|
|
33
|
+
export function signInWithNearWallet() {
|
|
34
34
|
// Allow the current app to make calls to the specified contract on the
|
|
35
35
|
// user's behalf.
|
|
36
36
|
// This works by creating a new access key for the user's account and storing
|
|
37
37
|
// the private key in localStorage.
|
|
38
|
-
window.walletConnection.requestSignIn(nearConfig.contractName)
|
|
38
|
+
window.walletConnection.requestSignIn(nearConfig.contractName);
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
export async function
|
|
41
|
+
export async function setGreetingOnContract(message){
|
|
42
42
|
let response = await window.contract.set_greeting({
|
|
43
43
|
args:{message: message}
|
|
44
|
-
})
|
|
45
|
-
return response
|
|
44
|
+
});
|
|
45
|
+
return response;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
export async function
|
|
49
|
-
let greeting = await window.contract.get_greeting()
|
|
50
|
-
return greeting
|
|
48
|
+
export async function getGreetingFromContract(){
|
|
49
|
+
let greeting = await window.contract.get_greeting();
|
|
50
|
+
return greeting;
|
|
51
51
|
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
const CONTRACT_NAME = process.env.CONTRACT_NAME;
|
|
2
|
+
|
|
3
|
+
function getConfig(env) {
|
|
4
|
+
switch (env) {
|
|
5
|
+
case 'production':
|
|
6
|
+
case 'mainnet':
|
|
7
|
+
return {
|
|
8
|
+
networkId: 'mainnet',
|
|
9
|
+
nodeUrl: 'https://rpc.mainnet.near.org',
|
|
10
|
+
contractName: CONTRACT_NAME,
|
|
11
|
+
walletUrl: 'https://wallet.near.org',
|
|
12
|
+
helperUrl: 'https://helper.mainnet.near.org',
|
|
13
|
+
explorerUrl: 'https://explorer.mainnet.near.org',
|
|
14
|
+
};
|
|
15
|
+
case 'development':
|
|
16
|
+
case 'testnet':
|
|
17
|
+
return {
|
|
18
|
+
networkId: 'testnet',
|
|
19
|
+
nodeUrl: 'https://rpc.testnet.near.org',
|
|
20
|
+
contractName: CONTRACT_NAME,
|
|
21
|
+
walletUrl: 'https://wallet.testnet.near.org',
|
|
22
|
+
helperUrl: 'https://helper.testnet.near.org',
|
|
23
|
+
explorerUrl: 'https://explorer.testnet.near.org',
|
|
24
|
+
};
|
|
25
|
+
case 'betanet':
|
|
26
|
+
return {
|
|
27
|
+
networkId: 'betanet',
|
|
28
|
+
nodeUrl: 'https://rpc.betanet.near.org',
|
|
29
|
+
contractName: CONTRACT_NAME,
|
|
30
|
+
walletUrl: 'https://wallet.betanet.near.org',
|
|
31
|
+
helperUrl: 'https://helper.betanet.near.org',
|
|
32
|
+
explorerUrl: 'https://explorer.betanet.near.org',
|
|
33
|
+
};
|
|
34
|
+
case 'local':
|
|
35
|
+
return {
|
|
36
|
+
networkId: 'local',
|
|
37
|
+
nodeUrl: 'http://localhost:3030',
|
|
38
|
+
keyPath: `${process.env.HOME}/.near/validator_key.json`,
|
|
39
|
+
walletUrl: 'http://localhost:4000/wallet',
|
|
40
|
+
contractName: CONTRACT_NAME,
|
|
41
|
+
};
|
|
42
|
+
case 'test':
|
|
43
|
+
case 'ci':
|
|
44
|
+
return {
|
|
45
|
+
networkId: 'shared-test',
|
|
46
|
+
nodeUrl: 'https://rpc.ci-testnet.near.org',
|
|
47
|
+
contractName: CONTRACT_NAME,
|
|
48
|
+
masterAccount: 'test.near',
|
|
49
|
+
};
|
|
50
|
+
case 'ci-betanet':
|
|
51
|
+
return {
|
|
52
|
+
networkId: 'shared-test-staging',
|
|
53
|
+
nodeUrl: 'https://rpc.ci-betanet.near.org',
|
|
54
|
+
contractName: CONTRACT_NAME,
|
|
55
|
+
masterAccount: 'test.near',
|
|
56
|
+
};
|
|
57
|
+
default:
|
|
58
|
+
throw Error(`Unconfigured environment '${env}'. Can be configured in src/config.js.`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
module.exports = getConfig;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "my-near-app",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"license": "(MIT AND Apache-2.0)",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"start": "echo The app is starting! && env-cmd -f ../contract/neardev/dev-account.env parcel index.html --open",
|
|
7
|
+
"build": "parcel build index.html --public-url ./"
|
|
8
|
+
},
|
|
9
|
+
"devDependencies": {
|
|
10
|
+
"nodemon": "^2.0.16",
|
|
11
|
+
"parcel": "^2.6.0",
|
|
12
|
+
"process": "^0.11.10",
|
|
13
|
+
"env-cmd": "^10.1.0"
|
|
14
|
+
},
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"near-api-js": "^0.44.2"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
require("util").inspect.defaultOptions.depth = 5; // Increase AVA's printing depth
|
|
2
|
-
|
|
3
|
-
module.exports = {
|
|
4
|
-
timeout: "300000",
|
|
5
|
-
files: ["src/*.ava.ts"],
|
|
6
|
-
failWithoutAssertions: false,
|
|
7
|
-
extensions: ["ts"],
|
|
8
|
-
require: ["ts-node/register"],
|
|
9
|
-
};
|
|
1
|
+
require("util").inspect.defaultOptions.depth = 5; // Increase AVA's printing depth
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
timeout: "300000",
|
|
5
|
+
files: ["src/*.ava.ts"],
|
|
6
|
+
failWithoutAssertions: false,
|
|
7
|
+
extensions: ["ts"],
|
|
8
|
+
require: ["ts-node/register"],
|
|
9
|
+
};
|
|
@@ -3,14 +3,15 @@
|
|
|
3
3
|
"version": "1.0.0",
|
|
4
4
|
"license": "(MIT AND Apache-2.0)",
|
|
5
5
|
"scripts": {
|
|
6
|
-
"test": "ava
|
|
6
|
+
"test": "ava"
|
|
7
7
|
},
|
|
8
8
|
"devDependencies": {
|
|
9
|
+
"@types/bn.js": "^5.1.0",
|
|
10
|
+
"@types/node": "^18.6.2",
|
|
9
11
|
"ava": "^4.2.0",
|
|
10
|
-
"near-
|
|
11
|
-
"typescript": "^4.7.2",
|
|
12
|
+
"near-api-js": "^0.44.2",
|
|
12
13
|
"ts-node": "^10.8.0",
|
|
13
|
-
"
|
|
14
|
+
"typescript": "^4.7.2"
|
|
14
15
|
},
|
|
15
16
|
"dependencies": {}
|
|
16
17
|
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import {KeyPair, keyStores} from 'near-api-js';
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
|
|
6
|
+
// first make sure you deployed your contract with dev-deploy, see ../package.json deploy script
|
|
7
|
+
// here we take the contract from the auto-generated neardev folder
|
|
8
|
+
const CONTRACT_NAME = fs.readFileSync(path.resolve(__dirname, '../../contract/neardev/dev-account'), 'utf-8');
|
|
9
|
+
const NETWORK_ID = 'testnet';
|
|
10
|
+
|
|
11
|
+
// Create an InMemoryKeyStore
|
|
12
|
+
const keyStore = new keyStores.InMemoryKeyStore();
|
|
13
|
+
|
|
14
|
+
// Load credentials
|
|
15
|
+
const credPath = `${process.env.HOME}/.near-credentials/${NETWORK_ID}/${CONTRACT_NAME}.json`;
|
|
16
|
+
let credentials = JSON.parse(fs.readFileSync(credPath));
|
|
17
|
+
|
|
18
|
+
// Save key in the key store
|
|
19
|
+
keyStore.setKey(
|
|
20
|
+
NETWORK_ID,
|
|
21
|
+
CONTRACT_NAME,
|
|
22
|
+
KeyPair.fromString(credentials.private_key)
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
export const nearConfig = {
|
|
26
|
+
networkId: NETWORK_ID,
|
|
27
|
+
nodeUrl: 'https://rpc.testnet.near.org',
|
|
28
|
+
contractName: CONTRACT_NAME,
|
|
29
|
+
walletUrl: 'https://wallet.testnet.near.org',
|
|
30
|
+
helperUrl: 'https://helper.testnet.near.org',
|
|
31
|
+
explorerUrl: 'https://explorer.testnet.near.org',
|
|
32
|
+
headers: {},
|
|
33
|
+
deps: {keyStore}
|
|
34
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import anyTest, { TestFn } from 'ava';
|
|
2
|
+
|
|
3
|
+
import { Near, Account, Contract } from 'near-api-js';
|
|
4
|
+
import { nearConfig } from './config';
|
|
5
|
+
|
|
6
|
+
const test = anyTest as TestFn<{
|
|
7
|
+
accounts: Record<string, any>;
|
|
8
|
+
}>;
|
|
9
|
+
|
|
10
|
+
test.beforeEach(async (t) => {
|
|
11
|
+
const near = await new Near(nearConfig);
|
|
12
|
+
const user = await new Account(near.connection, nearConfig.contractName);
|
|
13
|
+
const contract = await new Contract(
|
|
14
|
+
user,
|
|
15
|
+
nearConfig.contractName,
|
|
16
|
+
{ viewMethods: ['get_greeting'], changeMethods: ['set_greeting'] }
|
|
17
|
+
);
|
|
18
|
+
t.context.accounts = { contract };
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test('returns the default greeting', async (t) => {
|
|
22
|
+
const { contract } = t.context.accounts;
|
|
23
|
+
const message: string = await contract.get_greeting({});
|
|
24
|
+
t.is(message, 'Hello');
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
test('changes the message', async (t) => {
|
|
28
|
+
const { contract } = t.context.accounts;
|
|
29
|
+
await contract.set_greeting({args:{ message: 'Howdy' }});
|
|
30
|
+
const message: string = await contract.get_greeting({});
|
|
31
|
+
t.is(message, 'Howdy');
|
|
32
|
+
});
|
|
File without changes
|
|
@@ -1,14 +1,16 @@
|
|
|
1
|
+
use std::{env, fs};
|
|
1
2
|
use near_units::parse_near;
|
|
2
3
|
use serde_json::json;
|
|
3
4
|
use workspaces::prelude::*;
|
|
4
5
|
use workspaces::{network::Sandbox, Account, Contract, Worker};
|
|
5
6
|
|
|
6
|
-
const WASM_FILEPATH: &str = "../../out/main.wasm";
|
|
7
|
-
|
|
8
7
|
#[tokio::main]
|
|
9
8
|
async fn main() -> anyhow::Result<()> {
|
|
9
|
+
let wasm_arg: &str = &(env::args().nth(1).unwrap());
|
|
10
|
+
let wasm_filepath = fs::canonicalize(env::current_dir()?.join(wasm_arg))?;
|
|
11
|
+
|
|
10
12
|
let worker = workspaces::sandbox().await?;
|
|
11
|
-
let wasm = std::fs::read(
|
|
13
|
+
let wasm = std::fs::read(wasm_filepath)?;
|
|
12
14
|
let contract = worker.dev_deploy(&wasm).await?;
|
|
13
15
|
|
|
14
16
|
// create accounts
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
require("util").inspect.defaultOptions.depth = 5; // Increase AVA's printing depth
|
|
2
|
-
|
|
3
|
-
module.exports = {
|
|
4
|
-
timeout: "300000",
|
|
5
|
-
files: ["
|
|
6
|
-
failWithoutAssertions: false,
|
|
7
|
-
extensions: ["ts"],
|
|
8
|
-
require: ["ts-node/register"],
|
|
9
|
-
};
|
|
1
|
+
require("util").inspect.defaultOptions.depth = 5; // Increase AVA's printing depth
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
timeout: "300000",
|
|
5
|
+
files: ["src/*.ava.ts"],
|
|
6
|
+
failWithoutAssertions: false,
|
|
7
|
+
extensions: ["ts"],
|
|
8
|
+
require: ["ts-node/register"],
|
|
9
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ava-testing",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"license": "(MIT AND Apache-2.0)",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"test": "ava"
|
|
7
|
+
},
|
|
8
|
+
"devDependencies": {
|
|
9
|
+
"@types/bn.js": "^5.1.0",
|
|
10
|
+
"@types/node": "^18.6.2",
|
|
11
|
+
"ava": "^4.2.0",
|
|
12
|
+
"near-workspaces": "^3.1.0",
|
|
13
|
+
"ts-node": "^10.8.0",
|
|
14
|
+
"typescript": "^4.7.2"
|
|
15
|
+
},
|
|
16
|
+
"dependencies": {}
|
|
17
|
+
}
|