create-near-app 6.0.0-beta.5 → 6.0.1-beta.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/dist/app.js +0 -1
- package/dist/make.js +9 -11
- package/dist/messages.js +3 -2
- package/dist/tracking.js +4 -3
- package/dist/user-input.js +47 -36
- package/package.json +1 -1
- package/templates/contracts/ts/package.json +3 -0
- package/templates/frontend/next/package.json +3 -0
- package/templates/frontend/next/src/app/hello-components/page.js +25 -25
- package/templates/frontend/next/src/app/hello-near/page.js +17 -17
- package/templates/frontend/next/src/app/layout.js +7 -8
- package/templates/frontend/next/src/app/page.js +5 -5
- package/templates/frontend/next/src/components/cards.js +4 -4
- package/templates/frontend/next/src/components/navigation.js +8 -8
- package/templates/frontend/next/src/wallets/wallet-selector.js +18 -26
- package/templates/frontend/vanilla/src/components.js +3 -7
- package/templates/frontend/vanilla/src/hello.js +8 -8
- package/templates/frontend/vanilla/src/near-wallet.js +2 -2
- package/templates/sandbox-tests/sandbox-ts/ava.config.cjs +5 -5
- package/templates/frontend/next/.eslintrc.json +0 -3
package/dist/app.js
CHANGED
package/dist/make.js
CHANGED
|
@@ -32,22 +32,21 @@ const cross_spawn_1 = __importDefault(require("cross-spawn"));
|
|
|
32
32
|
const fs_1 = __importDefault(require("fs"));
|
|
33
33
|
const ncp_1 = require("ncp");
|
|
34
34
|
const path_1 = __importDefault(require("path"));
|
|
35
|
-
async function createProject({ contract, frontend, tests, projectPath,
|
|
35
|
+
async function createProject({ contract, frontend, tests, projectPath, templatesDir }) {
|
|
36
36
|
if (contract !== 'none') {
|
|
37
|
-
await createContract({ contract, tests, projectPath,
|
|
37
|
+
await createContract({ contract, tests, projectPath, templatesDir });
|
|
38
38
|
}
|
|
39
39
|
else {
|
|
40
|
-
await createGateway({ frontend, projectPath,
|
|
40
|
+
await createGateway({ frontend, projectPath, templatesDir });
|
|
41
41
|
}
|
|
42
42
|
return true;
|
|
43
43
|
}
|
|
44
44
|
exports.createProject = createProject;
|
|
45
|
-
async function createContract({ contract, tests, projectPath,
|
|
45
|
+
async function createContract({ contract, tests, projectPath, templatesDir }) {
|
|
46
46
|
// contract folder
|
|
47
47
|
const sourceContractDir = path_1.default.resolve(templatesDir, 'contracts', contract);
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
await copyDir(sourceContractDir, targetContractDir);
|
|
48
|
+
fs_1.default.mkdirSync(projectPath, { recursive: true });
|
|
49
|
+
await copyDir(sourceContractDir, projectPath);
|
|
51
50
|
// copy sandbox-test dir
|
|
52
51
|
const targetTestDir = path_1.default.resolve(projectPath, `sandbox-${tests}`);
|
|
53
52
|
const sourceTestDir = path_1.default.resolve(`${templatesDir}/sandbox-tests/sandbox-${tests}`);
|
|
@@ -71,11 +70,10 @@ async function createContract({ contract, tests, projectPath, projectName, templ
|
|
|
71
70
|
}
|
|
72
71
|
}
|
|
73
72
|
}
|
|
74
|
-
async function createGateway({ frontend, projectPath,
|
|
73
|
+
async function createGateway({ frontend, projectPath, templatesDir }) {
|
|
75
74
|
const sourceFrontendDir = path_1.default.resolve(`${templatesDir}/frontend/${frontend}`);
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
await copyDir(sourceFrontendDir, targetFrontendDir);
|
|
75
|
+
fs_1.default.mkdirSync(projectPath, { recursive: true });
|
|
76
|
+
await copyDir(sourceFrontendDir, projectPath);
|
|
79
77
|
}
|
|
80
78
|
// Wrap `ncp` tool to wait for the copy to finish when using `await`
|
|
81
79
|
function copyDir(source, dest) {
|
package/dist/messages.js
CHANGED
|
@@ -56,9 +56,10 @@ ${!install ? (0, chalk_1.default) ` - {inverse Install all dependencies}
|
|
|
56
56
|
- {inverse Start your app}:
|
|
57
57
|
{blue pnpm {bold run dev}}`;
|
|
58
58
|
exports.gatewayInstructions = gatewayInstructions;
|
|
59
|
-
const argsError = () => (0, exports.show)((0, chalk_1.default) `{red Arguments error}
|
|
59
|
+
const argsError = (msg) => (0, exports.show)((0, chalk_1.default) `{red Arguments error: {white ${msg}}}
|
|
60
|
+
|
|
60
61
|
Run {blue npx create-near-app} without arguments, or use:
|
|
61
|
-
npx create-near-app <projectName> --frontend next|vanilla|none --contract rs|ts|none --tests rs|ts|none`);
|
|
62
|
+
npx create-near-app <projectName> [--frontend next|vanilla|none] [--contract rs|ts|none --tests rs|ts|none]`);
|
|
62
63
|
exports.argsError = argsError;
|
|
63
64
|
const unsupportedNodeVersion = (supported) => (0, exports.show)((0, chalk_1.default) `{red We support node.js version ${supported} or later}`);
|
|
64
65
|
exports.unsupportedNodeVersion = unsupportedNodeVersion;
|
package/dist/tracking.js
CHANGED
|
@@ -6,11 +6,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.trackUsage = exports.trackingMessage = void 0;
|
|
7
7
|
const chalk_1 = __importDefault(require("chalk"));
|
|
8
8
|
const mixpanel_1 = __importDefault(require("mixpanel"));
|
|
9
|
-
const MIXPANEL_TOKEN = '
|
|
9
|
+
const MIXPANEL_TOKEN = '24177ef1ec09ffea5cb6f68909c66a61';
|
|
10
10
|
const tracker = mixpanel_1.default.init(MIXPANEL_TOKEN);
|
|
11
11
|
exports.trackingMessage = (0, chalk_1.default) `Near collects anonymous information on the commands used. No personal information that could identify you is shared`;
|
|
12
12
|
// TODO: track different failures & install usage
|
|
13
|
-
const trackUsage = async (frontend, contract) => {
|
|
13
|
+
const trackUsage = async (frontend, contract, testing) => {
|
|
14
14
|
// prevents logging from CI
|
|
15
15
|
if (process.env.NEAR_ENV === 'ci' || process.env.NODE_ENV === 'ci') {
|
|
16
16
|
console.log('Mixpanel logging is skipped in CI env');
|
|
@@ -20,11 +20,12 @@ const trackUsage = async (frontend, contract) => {
|
|
|
20
20
|
const mixPanelProperties = {
|
|
21
21
|
frontend,
|
|
22
22
|
contract,
|
|
23
|
+
testing,
|
|
23
24
|
os: process.platform,
|
|
24
25
|
nodeVersion: process.versions.node,
|
|
25
26
|
timestamp: new Date().toString()
|
|
26
27
|
};
|
|
27
|
-
tracker.track('
|
|
28
|
+
tracker.track('CNA', mixPanelProperties);
|
|
28
29
|
}
|
|
29
30
|
catch (e) {
|
|
30
31
|
console.error('Warning: problem while sending tracking data. Error: ', e);
|
package/dist/user-input.js
CHANGED
|
@@ -26,7 +26,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
26
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
27
|
};
|
|
28
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
exports.projectPath = exports.promptAndGetConfig = exports.getUserAnswers = exports.
|
|
29
|
+
exports.projectPath = exports.promptAndGetConfig = exports.getUserAnswers = exports.getUserArgs = void 0;
|
|
30
30
|
const types_1 = require("./types");
|
|
31
31
|
const chalk_1 = __importDefault(require("chalk"));
|
|
32
32
|
const prompts_1 = __importDefault(require("prompts"));
|
|
@@ -38,8 +38,8 @@ const fs_1 = __importDefault(require("fs"));
|
|
|
38
38
|
async function getUserArgs() {
|
|
39
39
|
commander_1.program
|
|
40
40
|
.argument('[projectName]')
|
|
41
|
-
.option('--contract [ts|rs|none]')
|
|
42
41
|
.option('--frontend [next|vanilla|none]')
|
|
42
|
+
.option('--contract [ts|rs|none]')
|
|
43
43
|
.option('--tests [rs|ts|none]')
|
|
44
44
|
.option('--install')
|
|
45
45
|
.addHelpText('after', 'You can create a frontend or a contract with tests');
|
|
@@ -50,31 +50,6 @@ async function getUserArgs() {
|
|
|
50
50
|
return { contract, frontend, projectName, tests, install };
|
|
51
51
|
}
|
|
52
52
|
exports.getUserArgs = getUserArgs;
|
|
53
|
-
function validateUserArgs(args) {
|
|
54
|
-
if (args === null) {
|
|
55
|
-
return 'error';
|
|
56
|
-
}
|
|
57
|
-
const { projectName, contract, frontend, tests } = args;
|
|
58
|
-
const hasAllOptions = contract !== undefined && frontend !== undefined;
|
|
59
|
-
const hasPartialOptions = contract !== undefined || frontend !== undefined;
|
|
60
|
-
const hasProjectName = projectName !== undefined;
|
|
61
|
-
const hasAllArgs = hasAllOptions && hasProjectName;
|
|
62
|
-
const hasNoArgs = !hasPartialOptions && !hasProjectName;
|
|
63
|
-
const optionsAreValid = hasAllOptions
|
|
64
|
-
&& types_1.FRONTENDS.includes(frontend)
|
|
65
|
-
&& types_1.CONTRACTS.includes(contract)
|
|
66
|
-
&& types_1.TESTING_FRAMEWORKS.includes(tests);
|
|
67
|
-
if (hasNoArgs) {
|
|
68
|
-
return 'none';
|
|
69
|
-
}
|
|
70
|
-
else if (hasAllArgs && optionsAreValid) {
|
|
71
|
-
return 'ok';
|
|
72
|
-
}
|
|
73
|
-
else {
|
|
74
|
-
return 'error';
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
exports.validateUserArgs = validateUserArgs;
|
|
78
53
|
const appChoices = [
|
|
79
54
|
{ title: 'A Near Gateway (Web App)', description: 'A multi-chain App that talks with Near contracts and Near components', value: 'gateway' },
|
|
80
55
|
{ title: 'A Near Smart Contract', description: 'A smart contract to be deployed in the Near Blockchain', value: 'contract' },
|
|
@@ -161,20 +136,20 @@ async function promptAndGetConfig() {
|
|
|
161
136
|
}
|
|
162
137
|
// process cli args
|
|
163
138
|
let args = await getUserArgs();
|
|
164
|
-
if (args.contract && (!args.tests || args.frontend)) {
|
|
165
|
-
return show.argsError();
|
|
166
|
-
}
|
|
167
|
-
if (args.frontend && (args.tests || args.contract)) {
|
|
168
|
-
return show.argsError();
|
|
169
|
-
}
|
|
170
139
|
// If no args, prompt user
|
|
171
|
-
if (!args.
|
|
140
|
+
if (!args.projectName) {
|
|
172
141
|
show.welcome();
|
|
173
142
|
args = await getUserAnswers();
|
|
174
143
|
}
|
|
144
|
+
// Homogenizing terminal args with prompt args
|
|
145
|
+
args.contract = args.contract || 'none';
|
|
146
|
+
args.frontend = args.frontend || 'none';
|
|
147
|
+
args.tests = args.tests || 'none';
|
|
148
|
+
if (!validateUserArgs(args))
|
|
149
|
+
return;
|
|
175
150
|
// track user input
|
|
176
|
-
const { frontend, contract } = args;
|
|
177
|
-
(0, tracking_1.trackUsage)(frontend, contract);
|
|
151
|
+
const { frontend, contract, tests } = args;
|
|
152
|
+
(0, tracking_1.trackUsage)(frontend, contract, tests);
|
|
178
153
|
let path = (0, exports.projectPath)(args.projectName);
|
|
179
154
|
if (fs_1.default.existsSync(path)) {
|
|
180
155
|
return show.directoryExists(path);
|
|
@@ -184,4 +159,40 @@ async function promptAndGetConfig() {
|
|
|
184
159
|
exports.promptAndGetConfig = promptAndGetConfig;
|
|
185
160
|
const projectPath = (projectName) => `${process.cwd()}/${projectName}`;
|
|
186
161
|
exports.projectPath = projectPath;
|
|
162
|
+
const validateUserArgs = (args) => {
|
|
163
|
+
if (!types_1.FRONTENDS.includes(args.frontend)) {
|
|
164
|
+
show.argsError(`Invalid frontend type: ${args.frontend}`);
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
167
|
+
if (!types_1.CONTRACTS.includes(args.contract)) {
|
|
168
|
+
show.argsError(`Invalid contract type: ${args.contract}`);
|
|
169
|
+
return false;
|
|
170
|
+
}
|
|
171
|
+
if (!types_1.TESTING_FRAMEWORKS.includes(args.tests)) {
|
|
172
|
+
show.argsError(`Invalid testing framework: ${args.tests}`);
|
|
173
|
+
return false;
|
|
174
|
+
}
|
|
175
|
+
if (!args.projectName) {
|
|
176
|
+
show.argsError('Please provide a project name');
|
|
177
|
+
return false;
|
|
178
|
+
}
|
|
179
|
+
if ((args.contract === 'none') === (args.frontend === 'none')) {
|
|
180
|
+
console.log(args.contract, args.frontend);
|
|
181
|
+
show.argsError('Please create a contract OR a frontend');
|
|
182
|
+
return false;
|
|
183
|
+
}
|
|
184
|
+
if (args.contract !== 'none' && args.tests === 'none') {
|
|
185
|
+
show.argsError('Please select a testing framework for your contract');
|
|
186
|
+
return false;
|
|
187
|
+
}
|
|
188
|
+
if (args.frontend !== 'none' && args.tests !== 'none') {
|
|
189
|
+
show.argsError('Remove the --tests flag when creating a frontend');
|
|
190
|
+
return false;
|
|
191
|
+
}
|
|
192
|
+
if (args.contract === 'ts' && args.tests === 'rs') {
|
|
193
|
+
show.argsError('We currently do not support creating a contract in TS with Rust tests, please create it manually');
|
|
194
|
+
return false;
|
|
195
|
+
}
|
|
196
|
+
return true;
|
|
197
|
+
};
|
|
187
198
|
//# sourceMappingURL=user-input.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import dynamic from 'next/dynamic';
|
|
2
2
|
|
|
3
|
-
import styles from '@/app/app.module.css'
|
|
3
|
+
import styles from '@/app/app.module.css';
|
|
4
4
|
import { DocsCard, HelloNearCard } from '@/components/cards';
|
|
5
5
|
import { NetworkId, ComponentMap } from '@/config';
|
|
6
6
|
|
|
@@ -12,33 +12,33 @@ export default function HelloComponents() {
|
|
|
12
12
|
|
|
13
13
|
return (
|
|
14
14
|
<>
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
</div>
|
|
22
|
-
<div className={styles.center}>
|
|
23
|
-
<h1> <code>Multi-chain</code> Components Made Simple </h1>
|
|
24
|
-
</div>
|
|
25
|
-
<div className='row'>
|
|
26
|
-
<div class="col-6">
|
|
27
|
-
<Component src={socialComponents.HelloNear} />
|
|
28
|
-
<p class="my-4"> </p>
|
|
29
|
-
<Component src={socialComponents.LoveNear} />
|
|
15
|
+
<main className={styles.main}>
|
|
16
|
+
<div className={styles.description}>
|
|
17
|
+
<p>
|
|
18
|
+
Loading components from:
|
|
19
|
+
<code className={styles.code}>{socialComponents.socialDB}</code>
|
|
20
|
+
</p>
|
|
30
21
|
</div>
|
|
31
|
-
<div
|
|
32
|
-
<
|
|
22
|
+
<div className={styles.center}>
|
|
23
|
+
<h1> <code>Multi-chain</code> Components Made Simple </h1>
|
|
33
24
|
</div>
|
|
34
|
-
|
|
35
|
-
|
|
25
|
+
<div className='row'>
|
|
26
|
+
<div class="col-6">
|
|
27
|
+
<Component src={socialComponents.HelloNear} />
|
|
28
|
+
<p class="my-4"> </p>
|
|
29
|
+
<Component src={socialComponents.LoveNear} />
|
|
30
|
+
</div>
|
|
31
|
+
<div class="col-6">
|
|
32
|
+
<Component src={socialComponents.Lido} />
|
|
33
|
+
</div>
|
|
34
|
+
</div>
|
|
35
|
+
<hr />
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
37
|
+
<div className={styles.grid}>
|
|
38
|
+
<DocsCard />
|
|
39
|
+
<HelloNearCard />
|
|
40
|
+
</div>
|
|
41
|
+
</main>
|
|
42
42
|
</>
|
|
43
43
|
);
|
|
44
44
|
}
|
|
@@ -1,35 +1,35 @@
|
|
|
1
|
-
'use client'
|
|
1
|
+
'use client';
|
|
2
2
|
import { DocsCard, HelloComponentsCard } from '@/components/cards';
|
|
3
3
|
import { useWallet } from '@/wallets/wallet-selector';
|
|
4
|
-
import { useState, useEffect } from 'react'
|
|
4
|
+
import { useState, useEffect } from 'react';
|
|
5
5
|
import { HelloNearContract, NetworkId } from '../../config';
|
|
6
|
-
import styles from '../app.module.css'
|
|
6
|
+
import styles from '../app.module.css';
|
|
7
7
|
|
|
8
8
|
// Contract that the app will interact with
|
|
9
9
|
const CONTRACT = HelloNearContract[NetworkId];
|
|
10
10
|
|
|
11
|
-
export default function HelloNear(
|
|
12
|
-
const { signedAccountId, viewMethod, callMethod } = useWallet()
|
|
11
|
+
export default function HelloNear() {
|
|
12
|
+
const { signedAccountId, viewMethod, callMethod } = useWallet();
|
|
13
13
|
|
|
14
|
-
const [greeting, setGreeting] = useState('loading...')
|
|
15
|
-
const [loggedIn, setLoggedIn] = useState(false)
|
|
16
|
-
const [showSpinner, setShowSpinner] = useState(false)
|
|
14
|
+
const [greeting, setGreeting] = useState('loading...');
|
|
15
|
+
const [loggedIn, setLoggedIn] = useState(false);
|
|
16
|
+
const [showSpinner, setShowSpinner] = useState(false);
|
|
17
17
|
|
|
18
18
|
useEffect(() => {
|
|
19
19
|
viewMethod && viewMethod(CONTRACT, 'get_greeting', {}).then(
|
|
20
20
|
greeting => setGreeting(greeting)
|
|
21
|
-
)
|
|
22
|
-
}, [viewMethod])
|
|
21
|
+
);
|
|
22
|
+
}, [viewMethod]);
|
|
23
23
|
|
|
24
24
|
useEffect(() => {
|
|
25
|
-
setLoggedIn(!!signedAccountId)
|
|
26
|
-
}, [signedAccountId])
|
|
25
|
+
setLoggedIn(!!signedAccountId);
|
|
26
|
+
}, [signedAccountId]);
|
|
27
27
|
|
|
28
28
|
const saveGreeting = async () => {
|
|
29
|
-
setShowSpinner(true)
|
|
29
|
+
setShowSpinner(true);
|
|
30
30
|
await callMethod(CONTRACT, 'set_greeting', { greeting });
|
|
31
|
-
setShowSpinner(false)
|
|
32
|
-
}
|
|
31
|
+
setShowSpinner(false);
|
|
32
|
+
};
|
|
33
33
|
|
|
34
34
|
return (
|
|
35
35
|
<main className={styles.main}>
|
|
@@ -43,7 +43,7 @@ export default function HelloNear({ }) {
|
|
|
43
43
|
<div className={styles.center}>
|
|
44
44
|
<h1 className="w-100"> The contract says: <code>{greeting}</code> </h1>
|
|
45
45
|
<div className="input-group" hidden={!loggedIn}>
|
|
46
|
-
<input type="text" className="form-control w-20" placeholder="Store a new greeting" onChange={t => { setGreeting(t.target.value) }} />
|
|
46
|
+
<input type="text" className="form-control w-20" placeholder="Store a new greeting" onChange={t => { setGreeting(t.target.value); } } />
|
|
47
47
|
<div className="input-group-append">
|
|
48
48
|
<button className="btn btn-secondary" onClick={saveGreeting}>
|
|
49
49
|
<span hidden={showSpinner}> Save </span>
|
|
@@ -60,5 +60,5 @@ export default function HelloNear({ }) {
|
|
|
60
60
|
<HelloComponentsCard />
|
|
61
61
|
</div>
|
|
62
62
|
</main>
|
|
63
|
-
)
|
|
63
|
+
);
|
|
64
64
|
}
|
|
@@ -1,16 +1,15 @@
|
|
|
1
|
-
'use client'
|
|
2
|
-
import './globals.css'
|
|
1
|
+
'use client';
|
|
2
|
+
import './globals.css';
|
|
3
3
|
import '@near-wallet-selector/modal-ui/styles.css';
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { NetworkId } from '@/config';
|
|
6
6
|
import { Navigation } from '@/components/navigation';
|
|
7
|
-
import {
|
|
7
|
+
import { useInitWallet } from '@/wallets/wallet-selector';
|
|
8
8
|
|
|
9
9
|
export default function RootLayout({ children }) {
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
useInitWallet({ createAccessKeyFor: '', networkId: NetworkId });
|
|
12
|
+
|
|
14
13
|
return (
|
|
15
14
|
<html lang="en">
|
|
16
15
|
<body>
|
|
@@ -18,5 +17,5 @@ export default function RootLayout({ children }) {
|
|
|
18
17
|
{children}
|
|
19
18
|
</body>
|
|
20
19
|
</html>
|
|
21
|
-
)
|
|
20
|
+
);
|
|
22
21
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import Image from 'next/image'
|
|
2
|
-
import styles from './app.module.css'
|
|
3
|
-
import { DocsCard, HelloComponentsCard, HelloNearCard } from '@/components/cards'
|
|
1
|
+
import Image from 'next/image';
|
|
2
|
+
import styles from './app.module.css';
|
|
3
|
+
import { DocsCard, HelloComponentsCard, HelloNearCard } from '@/components/cards';
|
|
4
4
|
|
|
5
|
-
export default function Home(
|
|
5
|
+
export default function Home() {
|
|
6
6
|
return (
|
|
7
7
|
<main className={styles.main}>
|
|
8
8
|
<div className={styles.description}> </div>
|
|
@@ -33,5 +33,5 @@ export default function Home({ }) {
|
|
|
33
33
|
<DocsCard />
|
|
34
34
|
</div>
|
|
35
35
|
</main>
|
|
36
|
-
)
|
|
36
|
+
);
|
|
37
37
|
}
|
|
@@ -13,7 +13,7 @@ export const DocsCard = () => {
|
|
|
13
13
|
</h2>
|
|
14
14
|
<p>Learn how this application works, and what you can build on Near.</p>
|
|
15
15
|
</a>);
|
|
16
|
-
}
|
|
16
|
+
};
|
|
17
17
|
|
|
18
18
|
export const HelloNearCard = () => {
|
|
19
19
|
return (
|
|
@@ -28,7 +28,7 @@ export const HelloNearCard = () => {
|
|
|
28
28
|
<p>Discover how simple it is to interact with a Near smart contract.</p>
|
|
29
29
|
</a>
|
|
30
30
|
);
|
|
31
|
-
}
|
|
31
|
+
};
|
|
32
32
|
|
|
33
33
|
export const HelloComponentsCard = () => {
|
|
34
34
|
return (
|
|
@@ -42,5 +42,5 @@ export const HelloComponentsCard = () => {
|
|
|
42
42
|
</h2>
|
|
43
43
|
<p>See how Web3 components can help you to create multi-chain apps.</p>
|
|
44
44
|
</a>
|
|
45
|
-
)
|
|
46
|
-
}
|
|
45
|
+
);
|
|
46
|
+
};
|
|
@@ -7,17 +7,17 @@ import { useWallet } from '@/wallets/wallet-selector';
|
|
|
7
7
|
|
|
8
8
|
export const Navigation = () => {
|
|
9
9
|
|
|
10
|
-
const { signedAccountId, logOut, logIn } = useWallet()
|
|
11
|
-
const [action, setAction] = useState(() => { })
|
|
12
|
-
const [label, setLabel] = useState('Loading...')
|
|
10
|
+
const { signedAccountId, logOut, logIn } = useWallet();
|
|
11
|
+
const [action, setAction] = useState(() => { });
|
|
12
|
+
const [label, setLabel] = useState('Loading...');
|
|
13
13
|
|
|
14
14
|
useEffect(() => {
|
|
15
15
|
if (signedAccountId) {
|
|
16
|
-
setAction(() => logOut)
|
|
17
|
-
setLabel(`Logout ${signedAccountId}`)
|
|
16
|
+
setAction(() => logOut);
|
|
17
|
+
setLabel(`Logout ${signedAccountId}`);
|
|
18
18
|
} else {
|
|
19
|
-
setAction(() => logIn)
|
|
20
|
-
setLabel('Login')
|
|
19
|
+
setAction(() => logIn);
|
|
20
|
+
setLabel('Login');
|
|
21
21
|
}
|
|
22
22
|
}, [signedAccountId, logOut, logIn, setAction, setLabel]);
|
|
23
23
|
|
|
@@ -33,4 +33,4 @@ export const Navigation = () => {
|
|
|
33
33
|
</div>
|
|
34
34
|
</nav>
|
|
35
35
|
);
|
|
36
|
-
}
|
|
36
|
+
};
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { create as createStore } from 'zustand';
|
|
2
|
-
import { distinctUntilChanged, map } from
|
|
2
|
+
import { distinctUntilChanged, map } from 'rxjs';
|
|
3
3
|
import { providers } from 'near-api-js';
|
|
4
4
|
import { setupWalletSelector } from '@near-wallet-selector/core';
|
|
5
5
|
import { setupModal } from '@near-wallet-selector/modal-ui';
|
|
6
6
|
import { setupMyNearWallet } from '@near-wallet-selector/my-near-wallet';
|
|
7
7
|
import { setupHereWallet } from '@near-wallet-selector/here-wallet';
|
|
8
8
|
|
|
9
|
-
import { NetworkId } from '@/config';
|
|
10
9
|
import { useEffect, useState } from 'react';
|
|
11
10
|
|
|
12
11
|
export const useWallet = createStore(set => ({
|
|
@@ -22,7 +21,7 @@ export const useWallet = createStore(set => ({
|
|
|
22
21
|
setStoreSelector: ({ selector }) => set({ selector }),
|
|
23
22
|
}));
|
|
24
23
|
|
|
25
|
-
export function
|
|
24
|
+
export function useInitWallet({ createAccessKeyFor, networkId }) {
|
|
26
25
|
const setAuth = useWallet(store => store.setAuth);
|
|
27
26
|
const setLogActions = useWallet(store => store.setLogActions);
|
|
28
27
|
const setMethods = useWallet(store => store.setMethods);
|
|
@@ -30,22 +29,20 @@ export function initWallet({ createAccessKeyFor }) {
|
|
|
30
29
|
const [selector, setSelector] = useState(undefined);
|
|
31
30
|
|
|
32
31
|
useEffect(() => {
|
|
33
|
-
console.log('initWallet')
|
|
34
32
|
const selector = setupWalletSelector({
|
|
35
|
-
network:
|
|
33
|
+
network: networkId,
|
|
36
34
|
modules: [setupMyNearWallet(), setupHereWallet()]
|
|
37
|
-
})
|
|
35
|
+
});
|
|
38
36
|
|
|
39
37
|
setSelector(selector);
|
|
40
38
|
setStoreSelector({ selector });
|
|
41
|
-
}, []);
|
|
39
|
+
}, [networkId, setStoreSelector]);
|
|
42
40
|
|
|
43
41
|
useEffect(() => {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
42
|
+
if (!selector) return;
|
|
43
|
+
|
|
47
44
|
selector.then(walletSelector => {
|
|
48
|
-
const accounts = walletSelector.store.getState().accounts
|
|
45
|
+
const accounts = walletSelector.store.getState().accounts;
|
|
49
46
|
const signedAccountId = accounts.find((account) => account.active)?.accountId || '';
|
|
50
47
|
setAuth({ signedAccountId });
|
|
51
48
|
|
|
@@ -55,37 +52,32 @@ export function initWallet({ createAccessKeyFor }) {
|
|
|
55
52
|
distinctUntilChanged()
|
|
56
53
|
)
|
|
57
54
|
.subscribe((accounts) => {
|
|
58
|
-
console.log("accounts", accounts)
|
|
59
55
|
const signedAccountId = accounts.find((account) => account.active)?.accountId || '';
|
|
60
56
|
setAuth({ signedAccountId });
|
|
61
57
|
});
|
|
62
|
-
})
|
|
58
|
+
});
|
|
63
59
|
}, [selector, setAuth]);
|
|
64
60
|
|
|
65
61
|
useEffect(() => {
|
|
66
|
-
|
|
62
|
+
if (!selector) return;
|
|
67
63
|
|
|
68
|
-
if(!selector) return;
|
|
69
|
-
|
|
70
64
|
// defined logOut and logIn actions
|
|
71
65
|
const logOut = async () => {
|
|
72
66
|
const wallet = await (await selector).wallet();
|
|
73
67
|
await wallet.signOut();
|
|
74
68
|
setAuth({ signedAccountId: '' });
|
|
75
|
-
}
|
|
69
|
+
};
|
|
76
70
|
|
|
77
71
|
const logIn = async () => {
|
|
78
72
|
const modal = setupModal(await selector, { contractId: createAccessKeyFor });
|
|
79
73
|
modal.show();
|
|
80
|
-
}
|
|
74
|
+
};
|
|
81
75
|
|
|
82
76
|
setLogActions({ logOut, logIn });
|
|
83
|
-
}, [selector, setAuth]);
|
|
77
|
+
}, [createAccessKeyFor, selector, setAuth, setLogActions]);
|
|
84
78
|
|
|
85
79
|
useEffect(() => {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
if(!selector) return;
|
|
80
|
+
if (!selector) return;
|
|
89
81
|
|
|
90
82
|
const viewMethod = async (contractId, method, args = {}) => {
|
|
91
83
|
const { network } = (await selector).options;
|
|
@@ -99,7 +91,7 @@ export function initWallet({ createAccessKeyFor }) {
|
|
|
99
91
|
finality: 'optimistic',
|
|
100
92
|
});
|
|
101
93
|
return JSON.parse(Buffer.from(res.result).toString());
|
|
102
|
-
}
|
|
94
|
+
};
|
|
103
95
|
|
|
104
96
|
const callMethod = async (contractId, method, args = {}, gas = '30000000000000', deposit = 0) => {
|
|
105
97
|
const wallet = await (await selector).wallet();
|
|
@@ -119,10 +111,10 @@ export function initWallet({ createAccessKeyFor }) {
|
|
|
119
111
|
],
|
|
120
112
|
});
|
|
121
113
|
|
|
122
|
-
return providers.getTransactionLastResult(outcome)
|
|
123
|
-
}
|
|
114
|
+
return providers.getTransactionLastResult(outcome);
|
|
115
|
+
};
|
|
124
116
|
|
|
125
117
|
setMethods({ viewMethod, callMethod });
|
|
126
118
|
|
|
127
|
-
}, [selector]);
|
|
119
|
+
}, [selector, setMethods]);
|
|
128
120
|
}
|
|
@@ -3,11 +3,7 @@ import { Wallet } from './near-wallet';
|
|
|
3
3
|
import { useInitNear, Widget } from 'near-social-vm';
|
|
4
4
|
import { useEffect } from 'react';
|
|
5
5
|
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
// When creating the wallet you can optionally ask to create an access key
|
|
9
|
-
// Having the key enables to call non-payable methods without interrupting the user to sign
|
|
10
|
-
const wallet = new Wallet({createAccessKeyFor: CONTRACT_ADDRESS, network: 'testnet'});
|
|
6
|
+
const wallet = new Wallet({network: 'testnet'});
|
|
11
7
|
|
|
12
8
|
export default function Component({ src }) {
|
|
13
9
|
|
|
@@ -46,8 +42,8 @@ window.onload = async () => {
|
|
|
46
42
|
};
|
|
47
43
|
|
|
48
44
|
// Button clicks
|
|
49
|
-
document.querySelector('#sign-in-button').onclick = () => { wallet.signIn() };
|
|
50
|
-
document.querySelector('#sign-out-button').onclick = () => { wallet.signOut() };
|
|
45
|
+
document.querySelector('#sign-in-button').onclick = () => { wallet.signIn(); };
|
|
46
|
+
document.querySelector('#sign-out-button').onclick = () => { wallet.signOut(); };
|
|
51
47
|
|
|
52
48
|
// UI: Display the signed-out container
|
|
53
49
|
function signedOutUI() {
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
import { Wallet } from './near-wallet';
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const HELLO_NEAR = 'hello.near-examples.testnet';
|
|
4
4
|
|
|
5
5
|
// When creating the wallet you can optionally ask to create an access key
|
|
6
6
|
// Having the key enables to call non-payable methods without interrupting the user to sign
|
|
7
|
-
const wallet = new Wallet({
|
|
7
|
+
const wallet = new Wallet({ network: 'testnet' });
|
|
8
8
|
|
|
9
9
|
// Setup on page load
|
|
10
10
|
window.onload = async () => {
|
|
11
11
|
let isSignedIn = await wallet.startUp();
|
|
12
|
-
isSignedIn? signedInUI(): signedOutUI();
|
|
12
|
+
isSignedIn ? signedInUI() : signedOutUI();
|
|
13
13
|
getGreeting();
|
|
14
14
|
};
|
|
15
15
|
|
|
16
16
|
// Button clicks
|
|
17
17
|
document.querySelector('form').onsubmit = setGreeting;
|
|
18
|
-
document.querySelector('#sign-in-button').onclick = () => { wallet.signIn() };
|
|
19
|
-
document.querySelector('#sign-out-button').onclick = () => { wallet.signOut() };
|
|
18
|
+
document.querySelector('#sign-in-button').onclick = () => { wallet.signIn(); };
|
|
19
|
+
document.querySelector('#sign-out-button').onclick = () => { wallet.signOut(); };
|
|
20
20
|
|
|
21
21
|
async function setGreeting(event) {
|
|
22
22
|
event.preventDefault();
|
|
@@ -26,7 +26,7 @@ async function setGreeting(event) {
|
|
|
26
26
|
|
|
27
27
|
// use the wallet to send the greeting to the Smart Contract
|
|
28
28
|
const { greeting } = event.target.elements;
|
|
29
|
-
await wallet.callMethod({ method: 'set_greeting', args: { greeting: greeting.value }, contractId:
|
|
29
|
+
await wallet.callMethod({ method: 'set_greeting', args: { greeting: greeting.value }, contractId: HELLO_NEAR });
|
|
30
30
|
|
|
31
31
|
// query the new greeting
|
|
32
32
|
await getGreeting();
|
|
@@ -37,7 +37,7 @@ async function setGreeting(event) {
|
|
|
37
37
|
|
|
38
38
|
async function getGreeting() {
|
|
39
39
|
// use the wallet to query the Smart Contract
|
|
40
|
-
const currentGreeting = await wallet.viewMethod({ method: 'get_greeting', contractId:
|
|
40
|
+
const currentGreeting = await wallet.viewMethod({ method: 'get_greeting', contractId: HELLO_NEAR });
|
|
41
41
|
|
|
42
42
|
// Display it
|
|
43
43
|
document.querySelector('#displayGreeting').innerText = currentGreeting;
|
|
@@ -56,6 +56,6 @@ function signedInUI() {
|
|
|
56
56
|
});
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
function hide(id){
|
|
59
|
+
function hide(id) {
|
|
60
60
|
document.querySelectorAll(id).forEach(el => el.style.display = 'none');
|
|
61
61
|
}
|
|
@@ -24,8 +24,8 @@ export class Wallet {
|
|
|
24
24
|
// key, so the user skips signing non-payable transactions.
|
|
25
25
|
// Omitting the accountId will result in the user being
|
|
26
26
|
// asked to sign all transactions.
|
|
27
|
-
this.createAccessKeyFor = createAccessKeyFor
|
|
28
|
-
this.network = network
|
|
27
|
+
this.createAccessKeyFor = createAccessKeyFor;
|
|
28
|
+
this.network = network;
|
|
29
29
|
this.selector = setupWalletSelector({
|
|
30
30
|
network: this.network,
|
|
31
31
|
modules: [setupMyNearWallet()],
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
require(
|
|
1
|
+
require('util').inspect.defaultOptions.depth = 5; // Increase AVA's printing depth
|
|
2
2
|
|
|
3
3
|
module.exports = {
|
|
4
|
-
timeout:
|
|
5
|
-
files: [
|
|
4
|
+
timeout: '300000',
|
|
5
|
+
files: ['src/*.ava.ts'],
|
|
6
6
|
failWithoutAssertions: false,
|
|
7
|
-
extensions: [
|
|
8
|
-
require: [
|
|
7
|
+
extensions: ['ts'],
|
|
8
|
+
require: ['ts-node/register'],
|
|
9
9
|
};
|