-
+
-
-
+
+
);
-};
\ No newline at end of file
+};
diff --git a/frontend/src/components/SignIn.jsx b/frontend/src/components/SignIn.jsx
index ef15766..fd01de5 100644
--- a/frontend/src/components/SignIn.jsx
+++ b/frontend/src/components/SignIn.jsx
@@ -1,18 +1,18 @@
export default function SignIn() {
- return (
- <>
-
- This app demonstrates a key element of NEAR’s UX: once an app has
- permission to make calls on behalf of a user (that is, once a user signs
- in), the app can make calls to the blockchain for them without prompting
- extra confirmation. So you’ll see that if you don’t include a donation,
- your message gets posted right to the guest book.
-
-
- But, if you do add a donation, then NEAR will double-check that you’re
- ok with sending money to this app.
-
-
Go ahead and sign in to try it out!
- >
- );
+ return (
+ <>
+
+ This app demonstrates a key element of NEAR’s UX: once an app has
+ permission to make calls on behalf of a user (that is, once a user signs
+ in), the app can make calls to the blockchain for them without prompting
+ extra confirmation. So you’ll see that if you don’t include a donation,
+ your message gets posted right to the guest book.
+
+
+ But, if you do add a donation, then NEAR will double-check that you’re
+ ok with sending money to this app.
+
+
Go ahead and sign in to try it out!
+ >
+ );
}
diff --git a/frontend/src/config.js b/frontend/src/config.js
index b7cd6c2..d52d598 100644
--- a/frontend/src/config.js
+++ b/frontend/src/config.js
@@ -1,5 +1,5 @@
const contractPerNetwork = {
- testnet: "guestbook.near-examples.testnet",
+ testnet: "guestbook.near-examples.testnet",
};
export const NetworkId = "testnet";
diff --git a/frontend/src/context.js b/frontend/src/context.js
index 7422309..6678cfd 100644
--- a/frontend/src/context.js
+++ b/frontend/src/context.js
@@ -1,4 +1,4 @@
-import { createContext } from 'react';
+import { createContext } from "react";
/**
* @typedef NearContext
@@ -9,5 +9,5 @@ import { createContext } from 'react';
/** @type {import ('react').Context
} */
export const NearContext = createContext({
wallet: undefined,
- signedAccountId: ''
-});
\ No newline at end of file
+ signedAccountId: "",
+});
diff --git a/frontend/src/pages/_app.js b/frontend/src/pages/_app.js
index 41f0911..8cde3db 100644
--- a/frontend/src/pages/_app.js
+++ b/frontend/src/pages/_app.js
@@ -1,18 +1,23 @@
-import { useEffect, useState } from 'react';
+import { useEffect, useState } from "react";
-import '@/styles/globals.css';
-import { NearContext } from '@/context';
-import { Navigation } from '@/components/Navigation';
+import "@/styles/globals.css";
+import { NearContext } from "@/context";
+import { Navigation } from "@/components/Navigation";
-import { Wallet } from '@/wallets/near';
-import { NetworkId, GuestbookNearContract } from '@/config';
+import { Wallet } from "@/wallets/near";
+import { NetworkId, GuestbookNearContract } from "@/config";
-const wallet = new Wallet({ createAccessKeyFor: GuestbookNearContract, networkId: NetworkId });
+const wallet = new Wallet({
+ createAccessKeyFor: GuestbookNearContract,
+ networkId: NetworkId,
+});
export default function MyApp({ Component, pageProps }) {
- const [signedAccountId, setSignedAccountId] = useState('');
+ const [signedAccountId, setSignedAccountId] = useState("");
- useEffect(() => { wallet.startUp(setSignedAccountId) }, []);
+ useEffect(() => {
+ wallet.startUp(setSignedAccountId);
+ }, []);
return (
@@ -20,4 +25,4 @@ export default function MyApp({ Component, pageProps }) {
);
-}
\ No newline at end of file
+}
diff --git a/frontend/src/pages/index.js b/frontend/src/pages/index.js
index 70bd3f4..3406487 100644
--- a/frontend/src/pages/index.js
+++ b/frontend/src/pages/index.js
@@ -10,65 +10,64 @@ import { NearContext } from "@/context";
import { GuestbookNearContract } from "@/config";
export default function Home() {
- const { signedAccountId, wallet } = useContext(NearContext);
- const [messages, setMessages] = useState([]);
+ const { signedAccountId, wallet } = useContext(NearContext);
+ const [messages, setMessages] = useState([]);
- useEffect(() => {
- getLast10Messages()
- .then(messages => setMessages(messages.reverse()));
- }, []);
+ useEffect(() => {
+ getLast10Messages().then((messages) => setMessages(messages.reverse()));
+ }, []);
- const getLast10Messages = async () => {
- const total_messages = await wallet.viewMethod({
- contractId: GuestbookNearContract,
- method: "total_messages",
- });
- const from_index = total_messages >= 10 ? total_messages - 10 : 0;
- return wallet.viewMethod({
- contractId: GuestbookNearContract,
- method: "get_messages",
- args: { from_index: String(from_index), limit: "10" },
- });
- };
+ const getLast10Messages = async () => {
+ const total_messages = await wallet.viewMethod({
+ contractId: GuestbookNearContract,
+ method: "total_messages",
+ });
+ const from_index = total_messages >= 10 ? total_messages - 10 : 0;
+ return wallet.viewMethod({
+ contractId: GuestbookNearContract,
+ method: "get_messages",
+ args: { from_index: String(from_index), limit: "10" },
+ });
+ };
- const onSubmit = async (e) => {
- e.preventDefault();
+ const onSubmit = async (e) => {
+ e.preventDefault();
- const { fieldset, message, donation } = e.target.elements;
+ const { fieldset, message, donation } = e.target.elements;
- fieldset.disabled = true;
+ fieldset.disabled = true;
- // Add message to the guest book
- const deposit = utils.format.parseNearAmount(donation.value);
- await wallet.callMethod({
- contractId: GuestbookNearContract,
- method: "add_message",
- args: { text: message.value },
- deposit,
- });
+ // Add message to the guest book
+ const deposit = utils.format.parseNearAmount(donation.value);
+ await wallet.callMethod({
+ contractId: GuestbookNearContract,
+ method: "add_message",
+ args: { text: message.value },
+ deposit,
+ });
- // Get updated messages
- const messages = await getLast10Messages();
- setMessages(messages.reverse());
+ // Get updated messages
+ const messages = await getLast10Messages();
+ setMessages(messages.reverse());
- message.value = "";
- donation.value = "0";
- fieldset.disabled = false;
- message.focus();
- };
+ message.value = "";
+ donation.value = "0";
+ fieldset.disabled = false;
+ message.focus();
+ };
- return (
-
-
-
📖 NEAR Guest Book
- {signedAccountId ? (
-
- ) : (
-
- )}
-
+ return (
+
+
+
📖 NEAR Guest Book
+ {signedAccountId ? (
+
+ ) : (
+
+ )}
+
- {!!messages.length && }
-
- );
+ {!!messages.length && }
+
+ );
}
diff --git a/frontend/src/styles/app.module.css b/frontend/src/styles/app.module.css
index 67b1c24..8c1e4a5 100644
--- a/frontend/src/styles/app.module.css
+++ b/frontend/src/styles/app.module.css
@@ -3,6 +3,6 @@
flex-direction: column;
align-items: flex-start;
min-height: 100vh;
- max-width: 600px;
- margin: 0 auto;
-}
\ No newline at end of file
+ max-width: 600px;
+ margin: 0 auto;
+}
diff --git a/frontend/src/styles/globals.css b/frontend/src/styles/globals.css
index f34437c..a2d80cd 100644
--- a/frontend/src/styles/globals.css
+++ b/frontend/src/styles/globals.css
@@ -1,5 +1,5 @@
-@import 'bootstrap';
-@import 'bootstrap-icons';
+@import "bootstrap";
+@import "bootstrap-icons";
:root {
--max-width: 1100px;
@@ -9,24 +9,30 @@
--background-start-rgb: 214, 219, 220;
--background-end-rgb: 255, 255, 255;
- --primary-glow: conic-gradient(from 180deg at 50% 50%,
- #16abff33 0deg,
- #0885ff33 55deg,
- #54d6ff33 120deg,
- #0071ff33 160deg,
- transparent 360deg);
- --secondary-glow: radial-gradient(rgba(255, 255, 255, 1),
- rgba(255, 255, 255, 0));
+ --primary-glow: conic-gradient(
+ from 180deg at 50% 50%,
+ #16abff33 0deg,
+ #0885ff33 55deg,
+ #54d6ff33 120deg,
+ #0071ff33 160deg,
+ transparent 360deg
+ );
+ --secondary-glow: radial-gradient(
+ rgba(255, 255, 255, 1),
+ rgba(255, 255, 255, 0)
+ );
--tile-start-rgb: 239, 245, 249;
--tile-end-rgb: 228, 232, 233;
- --tile-border: conic-gradient(#00000080,
- #00000040,
- #00000030,
- #00000020,
- #00000010,
- #00000010,
- #00000080);
+ --tile-border: conic-gradient(
+ #00000080,
+ #00000040,
+ #00000030,
+ #00000020,
+ #00000010,
+ #00000010,
+ #00000080
+ );
--callout-rgb: 238, 240, 241;
--callout-border-rgb: 172, 175, 176;
@@ -41,20 +47,24 @@
--background-end-rgb: 0, 0, 0;
--primary-glow: radial-gradient(rgba(1, 65, 255, 0.4), rgba(1, 65, 255, 0));
- --secondary-glow: linear-gradient(to bottom right,
- rgba(1, 65, 255, 0),
- rgba(1, 65, 255, 0),
- rgba(1, 65, 255, 0.3));
+ --secondary-glow: linear-gradient(
+ to bottom right,
+ rgba(1, 65, 255, 0),
+ rgba(1, 65, 255, 0),
+ rgba(1, 65, 255, 0.3)
+ );
--tile-start-rgb: 2, 13, 46;
--tile-end-rgb: 2, 5, 19;
- --tile-border: conic-gradient(#ffffff80,
- #ffffff40,
- #ffffff30,
- #ffffff20,
- #ffffff10,
- #ffffff10,
- #ffffff80);
+ --tile-border: conic-gradient(
+ #ffffff80,
+ #ffffff40,
+ #ffffff30,
+ #ffffff20,
+ #ffffff10,
+ #ffffff10,
+ #ffffff80
+ );
--callout-rgb: 20, 20, 20;
--callout-border-rgb: 108, 108, 108;
@@ -77,10 +87,22 @@ body {
body {
color: rgb(var(--foreground-rgb));
- background: linear-gradient(to bottom,
+ background: linear-gradient(
+ to bottom,
transparent,
- rgb(var(--background-end-rgb))) rgb(var(--background-start-rgb));
- font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Noto Sans, Ubuntu, Droid Sans, Helvetica Neue, sans-serif;
+ rgb(var(--background-end-rgb))
+ )
+ rgb(var(--background-start-rgb));
+ font-family:
+ -apple-system,
+ BlinkMacSystemFont,
+ Segoe UI,
+ Roboto,
+ Noto Sans,
+ Ubuntu,
+ Droid Sans,
+ Helvetica Neue,
+ sans-serif;
}
a {
diff --git a/frontend/src/wallets/near.js b/frontend/src/wallets/near.js
index c7f038d..28b589d 100644
--- a/frontend/src/wallets/near.js
+++ b/frontend/src/wallets/near.js
@@ -1,16 +1,16 @@
// near api js
-import { providers } from 'near-api-js';
+import { providers } from "near-api-js";
// wallet selector
-import { distinctUntilChanged, map } from 'rxjs';
-import '@near-wallet-selector/modal-ui/styles.css';
-import { setupModal } from '@near-wallet-selector/modal-ui';
-import { setupWalletSelector } from '@near-wallet-selector/core';
-import { setupHereWallet } from '@near-wallet-selector/here-wallet';
-import { setupMyNearWallet } from '@near-wallet-selector/my-near-wallet';
+import { distinctUntilChanged, map } from "rxjs";
+import "@near-wallet-selector/modal-ui/styles.css";
+import { setupModal } from "@near-wallet-selector/modal-ui";
+import { setupWalletSelector } from "@near-wallet-selector/core";
+import { setupHereWallet } from "@near-wallet-selector/here-wallet";
+import { setupMyNearWallet } from "@near-wallet-selector/my-near-wallet";
-const THIRTY_TGAS = '30000000000000';
-const NO_DEPOSIT = '0';
+const THIRTY_TGAS = "30000000000000";
+const NO_DEPOSIT = "0";
export class Wallet {
/**
@@ -22,7 +22,7 @@ export class Wallet {
* const wallet = new Wallet({ networkId: 'testnet', createAccessKeyFor: 'contractId' });
* wallet.startUp((signedAccountId) => console.log(signedAccountId));
*/
- constructor({ networkId = 'testnet', createAccessKeyFor = undefined }) {
+ constructor({ networkId = "testnet", createAccessKeyFor = undefined }) {
this.createAccessKeyFor = createAccessKeyFor;
this.networkId = networkId;
}
@@ -30,25 +30,29 @@ export class Wallet {
/**
* To be called when the website loads
* @param {Function} accountChangeHook - a function that is called when the user signs in or out#
- * @returns {Promise} - the accountId of the signed-in user
+ * @returns {Promise} - the accountId of the signed-in user
*/
startUp = async (accountChangeHook) => {
this.selector = setupWalletSelector({
network: this.networkId,
- modules: [setupMyNearWallet(), setupHereWallet()]
+ modules: [setupMyNearWallet(), setupHereWallet()],
});
const walletSelector = await this.selector;
const isSignedIn = walletSelector.isSignedIn();
- const accountId = isSignedIn ? walletSelector.store.getState().accounts[0].accountId : '';
+ const accountId = isSignedIn
+ ? walletSelector.store.getState().accounts[0].accountId
+ : "";
walletSelector.store.observable
.pipe(
- map(state => state.accounts),
- distinctUntilChanged()
+ map((state) => state.accounts),
+ distinctUntilChanged(),
)
- .subscribe(accounts => {
- const signedAccount = accounts.find((account) => account.active)?.accountId;
+ .subscribe((accounts) => {
+ const signedAccount = accounts.find(
+ (account) => account.active,
+ )?.accountId;
accountChangeHook(signedAccount);
});
@@ -59,7 +63,9 @@ export class Wallet {
* Displays a modal to login the user
*/
signIn = async () => {
- const modal = setupModal(await this.selector, { contractId: this.createAccessKeyFor });
+ const modal = setupModal(await this.selector, {
+ contractId: this.createAccessKeyFor,
+ });
modal.show();
};
@@ -84,16 +90,15 @@ export class Wallet {
const provider = new providers.JsonRpcProvider({ url });
let res = await provider.query({
- request_type: 'call_function',
+ request_type: "call_function",
account_id: contractId,
method_name: method,
- args_base64: Buffer.from(JSON.stringify(args)).toString('base64'),
- finality: 'optimistic',
+ args_base64: Buffer.from(JSON.stringify(args)).toString("base64"),
+ finality: "optimistic",
});
return JSON.parse(Buffer.from(res.result).toString());
};
-
/**
* Makes a call to a contract
* @param {Object} options - the options for the call
@@ -104,14 +109,20 @@ export class Wallet {
* @param {string} options.deposit - the amount of yoctoNEAR to deposit
* @returns {Promise} - the resulting transaction
*/
- callMethod = async ({ contractId, method, args = {}, gas = THIRTY_TGAS, deposit = NO_DEPOSIT }) => {
+ callMethod = async ({
+ contractId,
+ method,
+ args = {},
+ gas = THIRTY_TGAS,
+ deposit = NO_DEPOSIT,
+ }) => {
// Sign a transaction with the "FunctionCall" action
const selectedWallet = await (await this.selector).wallet();
const outcome = await selectedWallet.signAndSendTransaction({
receiverId: contractId,
actions: [
{
- type: 'FunctionCall',
+ type: "FunctionCall",
params: {
methodName: method,
args,
@@ -136,7 +147,7 @@ export class Wallet {
const provider = new providers.JsonRpcProvider({ url: network.nodeUrl });
// Retrieve transaction result from the network
- const transaction = await provider.txStatus(txhash, 'unnused');
+ const transaction = await provider.txStatus(txhash, "unnused");
return providers.getTransactionLastResult(transaction);
};
-}
\ No newline at end of file
+}