mirror of
https://github.com/Permissionless-Software-Foundation/psf-memo-client.git
synced 2026-09-22 17:22:02 -07:00
feat(footer): Retrieving IPFS CID from BCH blockchain
This commit is contained in:
+1
-1
@@ -3,6 +3,7 @@
|
||||
"version": "2.0.1",
|
||||
"dependencies": {
|
||||
"axios": "0.27.2",
|
||||
"bch-message-lib": "2.2.1",
|
||||
"bootstrap": "5.2.0",
|
||||
"query-string": "7.1.1",
|
||||
"react": "18.2.0",
|
||||
@@ -35,7 +36,6 @@
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"bch-message-lib": "2.2.1",
|
||||
"minimal-slp-wallet": "5.0.3",
|
||||
"standard": "17.0.0",
|
||||
"web3.storage": "4.3.0"
|
||||
|
||||
+3
-2
@@ -103,7 +103,8 @@ class App extends React.Component {
|
||||
// This is a macro object that is passed to all child components. It gathers
|
||||
// all the data and handlers used throughout the app.
|
||||
const appData = {
|
||||
servers: this.state.servers // Alternative back end servers
|
||||
servers: this.state.servers, // Alternative back end servers
|
||||
wallet: this.state.wallet
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -119,7 +120,7 @@ class App extends React.Component {
|
||||
}
|
||||
|
||||
<SelectServerButton menuHandler={this.onMenuClick} />
|
||||
<Footer />
|
||||
<Footer appData={appData} />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
A footer section for the SPA
|
||||
*/
|
||||
|
||||
// Global npm libraries
|
||||
import React from 'react'
|
||||
import { Container, Row, Col } from 'react-bootstrap'
|
||||
|
||||
const IPFS_CID = 'bafybeibkck6ylwqmpkqglvsvb7wc5xecb65uypg7fbcembuj7u4xuh2evq'
|
||||
|
||||
class Footer extends React.Component {
|
||||
render () {
|
||||
return (
|
||||
<Container style={{ backgroundColor: '#ddd' }}>
|
||||
<Row style={{ padding: '25px' }}>
|
||||
<Col>
|
||||
<h6>Site Mirrors</h6>
|
||||
<ul>
|
||||
<li><a href={`https://${IPFS_CID}.ipfs.dweb.link/`} target='_blank' rel='noreferrer'>Filecoin</a></li>
|
||||
</ul>
|
||||
</Col>
|
||||
|
||||
<Col>
|
||||
<h6>Source Code</h6>
|
||||
<ul>
|
||||
<li><a href='https://github.com/Permissionless-Software-Foundation/react-bootstrap-web3-spa' target='_blank' rel='noreferrer'>GitHub</a></li>
|
||||
</ul>
|
||||
</Col>
|
||||
</Row>
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default Footer
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
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
|
||||
*/
|
||||
|
||||
// Global npm libraries
|
||||
import BchMessage from 'bch-message-lib'
|
||||
|
||||
// Local libraries
|
||||
import AppUtil from '../../util'
|
||||
|
||||
class Memo {
|
||||
constructor (config) {
|
||||
this.config = config
|
||||
|
||||
// Encapsulate dependencies
|
||||
this.util = new AppUtil()
|
||||
}
|
||||
|
||||
// Instantiate the bch-message-lib library.
|
||||
async initialize (wallet) {
|
||||
try {
|
||||
// Throw an error if this class is instantiated without passing a BCH address.
|
||||
if (!this.config || !this.config.bchAddr) {
|
||||
throw new Error('Must pass a BCH address to Memo constructor.')
|
||||
} else {
|
||||
this.bchAddr = this.config.bchAddr
|
||||
}
|
||||
|
||||
this.wallet = wallet
|
||||
|
||||
this.bchMessage = new BchMessage({ wallet })
|
||||
} catch (err) {
|
||||
console.error('Error in get-cid.js/initialize(): ', err.message)
|
||||
// console.log('Waiting 5 seconds before trying again.')
|
||||
// await this.util.sleep(5000)
|
||||
// this.initialize()
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
A footer section for the SPA
|
||||
*/
|
||||
|
||||
// Global npm libraries
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import { Container, Row, Col } from 'react-bootstrap'
|
||||
|
||||
// Local libraries
|
||||
import config from '../../config'
|
||||
import Memo from './get-cid'
|
||||
|
||||
function Footer (props) {
|
||||
const [ipfsCid, setIpfsCid] = useState(config.ipfsCid)
|
||||
const wallet = props.appData.wallet
|
||||
|
||||
// Retrieve the most up-to-date CID for the app on Filecoin from the BCH blockchain.
|
||||
useEffect(() => {
|
||||
async function fetchData () {
|
||||
try {
|
||||
const hash = await getUpdatedUrl(wallet)
|
||||
setIpfsCid(hash)
|
||||
} catch (err) {
|
||||
console.error('Error trying to retrieve Filecoin CID for the app from the BCH blockchain.')
|
||||
}
|
||||
}
|
||||
fetchData()
|
||||
}, [wallet])
|
||||
|
||||
return (
|
||||
<Container style={{ backgroundColor: '#ddd' }}>
|
||||
<Row style={{ padding: '25px' }}>
|
||||
<Col>
|
||||
<h6>Site Mirrors</h6>
|
||||
<ul>
|
||||
<li><a href={`https://${ipfsCid}.ipfs.dweb.link/`} target='_blank' rel='noreferrer'>Filecoin</a></li>
|
||||
</ul>
|
||||
</Col>
|
||||
|
||||
<Col>
|
||||
<h6>Source Code</h6>
|
||||
<ul>
|
||||
<li><a href='https://github.com/Permissionless-Software-Foundation/react-bootstrap-web3-spa' target='_blank' rel='noreferrer'>GitHub</a></li>
|
||||
</ul>
|
||||
</Col>
|
||||
</Row>
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
|
||||
async function getUpdatedUrl (wallet) {
|
||||
try {
|
||||
// Exit if the wallet is not initialized.
|
||||
if (!wallet) return
|
||||
|
||||
// Initialize the memo library for retrieving data from the BCH blockchain.
|
||||
const memo = new Memo({ bchAddr: config.appBchAddr })
|
||||
await memo.initialize(wallet)
|
||||
const hash = await memo.findHash()
|
||||
|
||||
if (!hash) {
|
||||
console.error(
|
||||
`Could not find IPFS hash in transactions for address ${config.appBchAddr}`
|
||||
)
|
||||
return false
|
||||
}
|
||||
// console.log(`latest IPFS hash: ${hash}`)
|
||||
|
||||
return hash
|
||||
} catch (err) {
|
||||
console.log('Error in getUpdatedUrl(): ', err)
|
||||
}
|
||||
}
|
||||
|
||||
export default Footer
|
||||
@@ -0,0 +1,13 @@
|
||||
/*
|
||||
Global configuration settings for this app.
|
||||
*/
|
||||
|
||||
const config = {
|
||||
// Default IPFS CID for the app. This will be overwritten by dynamic lookup.
|
||||
ipfsCid: 'bafybeibya4cwro6rgqfaazqxckcchy6qo5sz2aqc4dx7ptcvpns5peqcz4',
|
||||
|
||||
// BCH address used to point to the latest version of the IPFS CID.
|
||||
appBchAddr: 'bitcoincash:qztv87ppjh82v527jq2drp4u8rzzn63r5cmhth2zzm'
|
||||
}
|
||||
|
||||
export default config
|
||||
@@ -0,0 +1,13 @@
|
||||
/*
|
||||
A utility library for holding functions that are commonly used by many different
|
||||
areas of the app.
|
||||
*/
|
||||
|
||||
class AppUtil {
|
||||
// Returns a promise that resolves 'ms' milliseconds.
|
||||
sleep (ms) {
|
||||
return new Promise(resolve => setTimeout(resolve, ms))
|
||||
}
|
||||
}
|
||||
|
||||
export default AppUtil
|
||||
Reference in New Issue
Block a user