-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #41 from keypom/ben/trial-accounts
Ben/trial accounts
- Loading branch information
Showing
38 changed files
with
774 additions
and
906 deletions.
There are no files selected for viewing
77 changes: 77 additions & 0 deletions
77
docs-advanced-tutorials/trial-accounts/create-trial-drop.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
require('dotenv').config() | ||
const path = require("path"); | ||
const homedir = require("os").homedir(); | ||
const { readFileSync } = require('fs'); | ||
const { keyStores, connect, Account } = require('near-api-js'); | ||
|
||
const keypom = require("../../lib"); | ||
const { | ||
initKeypom, | ||
createTrialAccountDrop | ||
} = keypom | ||
|
||
const funderAccountId = 'benjiman.testnet'; | ||
const NETWORK_ID = 'testnet'; | ||
async function createTrialAccount() { | ||
// Initiate connection to the NEAR blockchain. | ||
const CREDENTIALS_DIR = ".near-credentials"; | ||
const credentialsPath = path.join(homedir, CREDENTIALS_DIR); | ||
|
||
let keyStore = new keyStores.UnencryptedFileSystemKeyStore(credentialsPath); | ||
|
||
let nearConfig = { | ||
networkId: NETWORK_ID, | ||
keyStore: keyStore, | ||
nodeUrl: `https://rpc.${NETWORK_ID}.near.org`, | ||
walletUrl: `https://wallet.${NETWORK_ID}.near.org`, | ||
helperUrl: `https://helper.${NETWORK_ID}.near.org`, | ||
explorerUrl: `https://explorer.${NETWORK_ID}.near.org`, | ||
}; | ||
|
||
let near = await connect(nearConfig); | ||
const fundingAccount = new Account(near.connection, funderAccountId) | ||
|
||
// Initialize the SDK and point it to the custom NEAR object that was created. | ||
await initKeypom({ | ||
near, | ||
network: NETWORK_ID | ||
}); | ||
|
||
// What contracts can the trial account call? | ||
const callableContracts = [ | ||
'guest-book.examples.keypom.testnet' | ||
] | ||
// What is the maximum amount of $NEAR that can be attached to a call for each callable contract? | ||
const maxAttachableNEARPerContract = [ | ||
'1', | ||
] | ||
// What methods can the trial account call? | ||
const callableMethods = [ | ||
['*'], | ||
] | ||
|
||
const wasmDirectory = `${require('path').resolve(__dirname, '..')}/trial-accounts/ext-wasm/trial-accounts.wasm` | ||
const {keys} = await createTrialAccountDrop({ | ||
account: fundingAccount, | ||
numKeys: 1, | ||
contractBytes: [...readFileSync(wasmDirectory)], | ||
// How much $NEAR should be made available to the trial account when it's created? | ||
startingBalanceNEAR: 2.5, | ||
callableContracts, | ||
callableMethods, | ||
maxAttachableNEARPerContract, | ||
// Once the trial account has spent this much $NEAR, the trial will be over. | ||
trialEndFloorNEAR: 1.25 | ||
}) | ||
|
||
const guestBookInstance = "http://localhost:1234" | ||
console.log(` | ||
Guest-Book App: | ||
${guestBookInstance}/keypom-url#v2.keypom.testnet/${keys.secretKeys[0]} | ||
Good Luck! | ||
`) | ||
} | ||
|
||
createTrialAccount(); |
File renamed without changes.
31 changes: 31 additions & 0 deletions
31
docs-advanced-tutorials/trial-accounts/guest-book/.gitignore
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. | ||
# Developer note: near.gitignore will be renamed to .gitignore upon project creation | ||
# dependencies | ||
node_modules | ||
/.pnp | ||
.pnp.js | ||
|
||
# build | ||
/out | ||
/dist | ||
|
||
# keys | ||
/neardev | ||
|
||
# testing | ||
/coverage | ||
|
||
# production | ||
/build | ||
|
||
# misc | ||
.DS_Store | ||
.env.local | ||
.env.development.local | ||
.env.test.local | ||
.env.production.local | ||
/.cache | ||
|
||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
import 'regenerator-runtime/runtime'; | ||
import React, { useState, useEffect } from 'react'; | ||
import Form from './components/Form'; | ||
import SignIn from './components/SignIn'; | ||
import Messages from './components/Messages'; | ||
|
||
const App = ({ isSignedIn, guestBook, wallet }) => { | ||
const [messages, setMessages] = useState([]); | ||
|
||
useEffect(() => { | ||
guestBook.getMessages().then(setMessages); | ||
}, []); | ||
|
||
onSubmit = async (e) => { | ||
e.preventDefault(); | ||
|
||
const { fieldset, message, donation } = e.target.elements; | ||
|
||
fieldset.disabled = true; | ||
|
||
await guestBook.addMessage(message.value, donation.value) | ||
const messages = await guestBook.getMessages() | ||
|
||
setMessages(messages); | ||
message.value = ''; | ||
donation.value = '0'; | ||
fieldset.disabled = false; | ||
message.focus(); | ||
}; | ||
|
||
const signIn = () => { wallet.signIn() } | ||
|
||
const signOut = () => { wallet.signOut() } | ||
|
||
return ( | ||
<main> | ||
<table> | ||
<tr> | ||
<td><h1>📖 NEAR Guest Book</h1></td> | ||
<td>{ isSignedIn | ||
? <button onClick={signOut}>Log out</button> | ||
: <button onClick={signIn}>Log in</button> | ||
}</td> | ||
</tr> | ||
</table> | ||
|
||
<hr /> | ||
{ isSignedIn | ||
? <Form onSubmit={onSubmit} currentAccountId={wallet.accountId} /> | ||
: <SignIn/> | ||
} | ||
|
||
<hr /> | ||
|
||
{ !!messages.length && <Messages messages={messages}/> } | ||
|
||
</main> | ||
); | ||
}; | ||
|
||
export default App; |
44 changes: 44 additions & 0 deletions
44
docs-advanced-tutorials/trial-accounts/guest-book/components/Form.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import React from 'react'; | ||
import PropTypes from 'prop-types'; | ||
|
||
export default function Form({ onSubmit, currentAccountId }) { | ||
return ( | ||
<form onSubmit={onSubmit}> | ||
<fieldset id="fieldset"> | ||
<p>Sign the guest book, { currentAccountId }!</p> | ||
<p className="highlight"> | ||
<label htmlFor="message">Message:</label> | ||
<input | ||
autoComplete="off" | ||
autoFocus | ||
id="message" | ||
required | ||
/> | ||
</p> | ||
<p> | ||
<label htmlFor="donation">Donation (optional):</label> | ||
<input | ||
autoComplete="off" | ||
defaultValue={'0'} | ||
id="donation" | ||
min="0" | ||
step="0.01" | ||
type="number" | ||
/> | ||
<span title="NEAR Tokens">Ⓝ</span> | ||
</p> | ||
<button type="submit"> | ||
Sign | ||
</button> | ||
</fieldset> | ||
</form> | ||
); | ||
} | ||
|
||
Form.propTypes = { | ||
onSubmit: PropTypes.func.isRequired, | ||
currentUser: PropTypes.shape({ | ||
accountId: PropTypes.string.isRequired, | ||
balance: PropTypes.string.isRequired | ||
}) | ||
}; |
21 changes: 21 additions & 0 deletions
21
docs-advanced-tutorials/trial-accounts/guest-book/components/Messages.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import React from 'react'; | ||
import PropTypes from 'prop-types'; | ||
|
||
export default function Messages({ messages }) { | ||
return ( | ||
<> | ||
<h2>Messages</h2> | ||
{messages.map((message, i) => | ||
// TODO: format as cards, add timestamp | ||
<p key={i} className={message.premium ? 'is-premium' : ''}> | ||
<strong>{message.sender}</strong>:<br/> | ||
{message.text} | ||
</p> | ||
)} | ||
</> | ||
); | ||
} | ||
|
||
Messages.propTypes = { | ||
messages: PropTypes.array | ||
}; |
22 changes: 22 additions & 0 deletions
22
docs-advanced-tutorials/trial-accounts/guest-book/components/SignIn.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import React from 'react'; | ||
|
||
export default function SignIn() { | ||
return ( | ||
<> | ||
<p> | ||
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. | ||
</p> | ||
<p> | ||
But, if you do add a donation, then NEAR will double-check that | ||
you’re ok with sending money to this app. | ||
</p> | ||
<p> | ||
Go ahead and sign in to try it out! | ||
</p> | ||
</> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
CONTRACT_NAME=guest-book.examples.keypom.testnet |
Binary file not shown.
128 changes: 128 additions & 0 deletions
128
docs-advanced-tutorials/trial-accounts/guest-book/global.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
* { | ||
box-sizing: border-box; | ||
} | ||
|
||
html { | ||
--bg: #f4f4f4; | ||
--fg: #25282A; | ||
--gray: #888; | ||
--royal: #0072CE; | ||
--blue: #6AD1E3; | ||
--primary: #93b0df; | ||
--secondary: var(--royal); | ||
--tertiary: #FF585D; | ||
|
||
background-color: var(--bg); | ||
color: var(--fg); | ||
font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif; | ||
font-size: calc(.65em + 0.7vw); | ||
line-height: 1.3; | ||
|
||
::selection { | ||
background: var(--secondary); | ||
color: var(--bg); | ||
} | ||
|
||
@media (prefers-color-scheme: light) { | ||
--bg: #25282A; | ||
--fg: #fff; | ||
--secondary: var(--blue); | ||
|
||
::selection { | ||
background: var(--secondary); | ||
color: var(--fg); | ||
} | ||
} | ||
} | ||
|
||
body { | ||
margin: 0 auto; | ||
padding: 0 1em; | ||
max-width: 40em; | ||
} | ||
|
||
fieldset { | ||
border: none; | ||
margin: 0; | ||
padding: 0; | ||
} | ||
|
||
.highlight { | ||
align-items: center; | ||
display: flex; | ||
margin-bottom: 0.5em; | ||
width: 100%; | ||
label { | ||
margin-right: 0.5em; | ||
} | ||
input { | ||
caret-color: var(--secondary); | ||
} | ||
} | ||
|
||
label { | ||
color: var(--gray); | ||
} | ||
|
||
button, .highlight { | ||
border-radius: 5px; | ||
border-color: var(--primary); | ||
border: 0.1em solid var(--primary); | ||
padding: 0.5em 1em; | ||
|
||
&:hover, &:focus, &:focus-within { | ||
border-color: var(--secondary); | ||
} | ||
} | ||
|
||
input { | ||
border: none; | ||
flex: 1; | ||
&:read-only { | ||
color: var(--primary) | ||
} | ||
} | ||
|
||
input[type="number"] { | ||
text-align: center; | ||
border-bottom: 0.1em solid var(--primary); | ||
margin: 0 1em; | ||
width: 4em; | ||
padding-left: 0.5em; | ||
&:hover, &:focus { | ||
border-color: var(--secondary); | ||
} | ||
} | ||
|
||
button, input { | ||
background: transparent; | ||
color: inherit; | ||
cursor: pointer; | ||
font: inherit; | ||
outline: none; | ||
} | ||
|
||
button { | ||
position: relative; | ||
transition: top 50ms; | ||
&:hover, &:focus { | ||
top: -1px; | ||
} | ||
background: var(--primary); | ||
|
||
&:active { | ||
background: var(--secondary); | ||
border-color: var(--secondary); | ||
top: 1px; | ||
} | ||
} | ||
|
||
.is-premium { | ||
border-left: 0.25em solid var(--secondary); | ||
padding-left: 0.25em; | ||
margin-left: -0.5em; | ||
} | ||
|
||
table button{ | ||
margin-left: 1rem; | ||
} |
Oops, something went wrong.