import { BzzFeed } from'@erebos/bzz-feed'import { BzzNode } from'@erebos/bzz-node'import { pubKeyToAddress } from'@erebos/keccak256'import { createKeyPair, sign } from'@erebos/secp256k1'import { TimelineReader, TimelineWriter } from'@erebos/timeline'const BZZ_URL = 'http://localhost:8500'const FEED_NAME = 'alice-bob'// This setup is meant for demonstration purpose only - keys and signatures security must be handled by the applicationconst keyPair = createKeyPair()
const signBytes = async bytes => sign(bytes, keyPair)
const bzz = new BzzNode({ url: BZZ_URL })
const bzzFeed = new BzzFeed({ bzz, signBytes })
// In this example we are Alice communicating with Bobconst aliceAddress = pubKeyToAddress(keyPair.getPublic('array'))
const aliceTimeline = new TimelineWriter({
bzz: bzzFeed,
feed: { user: aliceAddress, name: FEED_NAME },
})
// The provided metadata will be added to each messageconst aliceSend = aliceTimeline.createAddChapter({
author: aliceAddress,
type: 'text/plain',
})
// Alice will be able to add messages to her timeline calling this function, it simply abstracts away the underlying Chapter data structure that the updater usesconst sendMessage = async content => {
await aliceSend({ content })
}
// Alice's address must be known by Bobconst bobTimeline = new TimelineReader({
bzz: bzzFeed,
feed: { user: aliceAddress, name: FEED_NAME },
})
// This creates an AsyncIterator that can be used to retrieve previous messages in the timelineconst getPreviousMessage = bobTimeline.createIterator()
// Listen to new messages added to Bob's timeline readerconst bobsNewMessages = bobTimeline
.live({ interval: 10000 }) // 10 seconds
.subscribe(chapters => {
chapters.forEach(c => {
console.log(`New message from Alice: ${c.content}`)
})
})
const getMessageAndSayHello = async () => {
// Iteration is performed in reverse chronological orderconst latestMessage = await getPreviousMessage.next()
if (latestMessage != null) {
console.log(`Latest message from Alice: ${c.content}`)
}
await sendMessage('Hello!')
}