Merge pull request #116 from Permissionless-Software-Foundation/ct-new-footer

Adding improved IPFS hash lookup to the footer
This commit is contained in:
Chris Troutner
2020-12-18 14:45:55 -08:00
committed by GitHub
9 changed files with 156 additions and 2493 deletions
-2
View File
@@ -25,5 +25,3 @@ Standard workflow for setting up a development environment for working on this r
[MIT](./LICENSE.md)
t
+26 -2416
View File
File diff suppressed because it is too large Load Diff
-1
View File
@@ -31,7 +31,6 @@
"gatsby-plugin-sharp": "^2.9.0",
"gatsby-source-filesystem": "^2.3.8",
"gatsby-transformer-sharp": "2.7.0",
"memo-get-gatsby": "^1.0.4",
"prop-types": "^15.7.2",
"qrcode.react": "^1.0.0",
"react": "^16.12.0",
+1 -1
View File
@@ -101,7 +101,7 @@ class AdminLTEPage extends React.Component {
<Navbar.Core>
<VersionStatus />
</Navbar.Core>
<Layout path='/'>
<Layout path='/' {..._this.props}>
<div className='components-container'>
{_this.renderNewViewItems(_this.props)}
</div>
+35 -69
View File
@@ -3,10 +3,11 @@ import './footer.css'
import { Row, Col } from 'adminlte-2-react'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faGithub } from '@fortawesome/free-brands-svg-icons'
import { getWalletInfo } from '../localWallet'
import PropTypes from 'prop-types'
// Get the IPFS hash from the BCH Blockchain.
import MemoGet from 'memo-get-gatsby'
import Memo from '../../services/memo-hash'
const siteConfig = require('../site-config')
let _this
@@ -19,53 +20,39 @@ class Footer extends React.Component {
ipfsHash: 'No Result',
ipfsHashLink: ''
}
// memo-get-gatsby Instance
this.memoGet = _this.instantiateMemoLib()
this.memo = new Memo({
bchWallet: props.bchWallet,
bchAddr: siteConfig.memoAddr
})
}
async componentDidMount () {
try {
const addr = 'bitcoincash:qqwdv3hkmvd5vk0uhwqrqnef54542e5ctvy3ppt0nq'
const hash = await _this.memoGet.read(addr)
console.log(`hash: ${hash}`)
this.setState({
ipfsHash: hash,
ipfsHashLink: `https://ipfs-gateway.fullstack.cash/ipfs/${hash}`
})
} catch (err) {
console.error('Error trying to retrieve IPFS hash for the site: ', err)
// Manually set an old hash.
const hash = 'QmVm1y1MX4YPzmgQiAafY96Pq7j6GTNMFNuvHki1jAwxYg'
this.setState({
ipfsHash: hash,
ipfsHashLink: `https://ipfs-gateway.fullstack.cash/ipfs/${hash}`
})
}
// const bchjs = new BCHJS()
// const balance = await bchjs.Blockbook.balance(addr)
// console.log(`balance: ${JSON.stringify(balance, null, 2)}`)
// Get hash using memo service
await this.handleMemoService()
}
// Instantiate the library with the
// bchjs options established in the configuration section
instantiateMemoLib () {
// Get wallet info
const localStorageInfo = getWalletInfo()
async handleMemoService () {
// This is a hard-coded hash or 'checkpoint' to use in times when the
// connection fails.
const hash = 'QmXT85Xoi7xMRD9m7Ta4Cx8Yrsd2WSzLrq2VRo26KW4xLu'
// Get bchjs options
const jwtToken = localStorageInfo.JWT
const restURL = localStorageInfo.selectedServer
const bchjsOptions = {}
// Try to retrieve the hash from the BCH blockchain.
try {
const hash = await this.memo.findHash()
console.log(`IPFS hash found: ${hash}`)
if (jwtToken) {
bchjsOptions.apiToken = jwtToken
if (!hash) {
throw new Error('Hash not found! Falling back to hard coded IPFS hash.')
}
} catch (err) {
console.error('Error trying to retrieve IPFS hash for the site: ', err)
}
if (restURL) {
bchjsOptions.restURL = restURL
}
return new MemoGet(bchjsOptions)
this.setState({
ipfsHash: hash,
ipfsHashLink: `https://ipfs-gateway.fullstack.cash/ipfs/${hash}`
})
}
render () {
@@ -119,8 +106,8 @@ class Footer extends React.Component {
<b>Tor</b>
</span>
<b>|</b>
<a href='http://puh2fyj2ly5b4p5m.onion/'>
puh2fyj2ly5b4p5m.onion
<a href='http://2egutot63q765ciwsenlcy5zdyxwxt7olzbldr5dx5i3ixsef2nvrzid.onion/'>
2egutot63q765ciwsenlcy5zdyxwxt7olzbldr5dx5i3ixsef2nvrzid.onion
</a>
</li>
@@ -135,35 +122,14 @@ class Footer extends React.Component {
</div>
</Col>
</Row>
{/* <center>
<a href="https://psfoundation.cash/" target="_blank" rel="noreferrer">
Produced by the Permissionless Software Foundation
</a>
<br /><br />
<p>Ways to access this web-app:</p>
<ul>
<li>
Web: <a href="https://wallet.fullstack.cash">wallet.fullstack.cash</a>
</li>
<li>
Tor: <a href="http://puh2fyj2ly5b4p5m.onion/">puh2fyj2ly5b4p5m.onion</a>
</li>
<li>
IPFS: <a href="https://ipfs.io/ipfs/QmTMpYt66SGSjckXTHF6bPip6h1V5fXT23tEUJgy7pyTkf/">QmTMpYt66SGSjckXTHF6bPip6h1V5fXT23tEUJgy7pyTkf</a>
</li>
</ul>
<br />
<a href="https://github.com/Permissionless-Software-Foundation/gatsby-ipfs-web-wallet" target="_blank" rel="noreferrer">
Source Code
</a>
</center> */}
</section>
)
}
}
// Props prvided by redux
Footer.propTypes = {
bchWallet: PropTypes.object // get minimal-slp-wallet instance
}
export default Footer
+5 -3
View File
@@ -16,7 +16,7 @@ import './layout.css'
const Footer = typeof window !== 'undefined' ? require('./footer').default : null
// import Footer from "./footer"
const Layout = ({ children }) => {
const Layout = ({ children, bchWallet }) => {
/* const data = useStaticQuery(graphql`
query SiteTitleQuery {
site {
@@ -30,12 +30,14 @@ const Layout = ({ children }) => {
return (
<>
<main>{children}</main>
{Footer && <Footer />}{' '}
{Footer && <Footer bchWallet={bchWallet} />}{' '}
</>
)
}
Layout.propTypes = {
children: PropTypes.node.isRequired
children: PropTypes.node.isRequired,
bchWallet: PropTypes.object // get minimal-slp-wallet instance
}
export default Layout
+5 -1
View File
@@ -7,7 +7,11 @@ const config = {
title: 'FullStack.cash',
titleShort: 'PSF',
balanceText: 'BCH Balance',
balanceIcon: 'fab-bitcoin'
balanceIcon: 'fab-bitcoin',
// The BCH address used in a memo.cash account. Used for tracking the IPFS
// hash of the mirror of this site.
memoAddr: 'bitcoincash:qqwdv3hkmvd5vk0uhwqrqnef54542e5ctvy3ppt0nq'
}
module.exports = config
+3
View File
@@ -41,6 +41,9 @@ export default function HTML (props) {
{/* minimal-slp-wallet */}
<script src='https://unpkg.com/minimal-slp-wallet' />
{/* bch-message-lib */}
<script src='https://unpkg.com/bch-message-lib' />
{props.headComponents}
</head>
<body {...props.bodyAttributes}>
+81
View File
@@ -0,0 +1,81 @@
/*
This service file contains functions for retrieving an IPFS hash from the
BCH blockchain, in a fasion similar to PS001:
https://github.com/Permissionless-Software-Foundation/specifications/blob/master/ps001-media-sharing.md
*/
// These libraries are retrieved in /src/html.js
// minimal-slp-wallet-web
const BchWallet = typeof window !== 'undefined' ? window.SlpWallet : null
// bch-message-lib
const BchMessage = typeof window !== 'undefined' ? window.BchMessage : null
class Memo {
constructor (config) {
console.log('Memo config', config)
// Throw an error if this class is instantiated without passing a BCH address.
if (!config || !config.bchAddr) {
throw new Error('Must pass a BCH address to Memo constructor.')
} else this.bchAddr = config.bchAddr
// Use the bchWallet instance if already exists otherwise
// creates a new one with default values
if (config && config.bchWallet) {
this.wallet = config.bchWallet
this.bchjs = this.wallet.bchjs
// The way bchjs is used on the previous line
// contains the configuration stablished by
// the user ( apiToken, restURL )
// for a new instance we could use the folowing code
// const BCHJS = props.bchWallet.BCHJS
// this.bchjs = new BCHJS()
// debugger
} else if (BchWallet) {
this.wallet = new BchWallet()
// bchjs instance with default values
this.bchjs = this.wallet.bchjs
// debugger
} else {
console.error('Could not access minimal-slp-wallet library.')
}
if (BchMessage) {
this.bchMessage = new BchMessage({ bchjs: this.bchjs })
} else {
console.error('Could not access bch-message-lib library.')
}
}
// Walk the transactions associated with an address until a proper IPFS hash is
// found. If one is not found, will return false.
async findHash () {
try {
console.log(`finding latest IPFS hash for address: ${this.bchAddr}...`)
const txs = await this.bchMessage.memo.memoRead(
this.bchAddr,
'IPFS UPDATE'
)
// console.log(`txs: ${JSON.stringify(txs, null, 2)}`)
// If the array is empty, then return false.
if (txs.length === 0) return false
const hash = txs[0].subject
console.log(`...found this IPFS hash: ${hash}`)
// The transactions should automatically be sorted by the bchMessage
// library. So Just return the subject.
return hash
} catch (err) {
console.warn('Could not find IPFS hash in transaction history.')
return false
}
}
}
export default Memo