Skip to content

Commit

Permalink
Merge pull request #72 from xmtp/jazzz/preflight-address-check
Browse files Browse the repository at this point in the history
Add ability to check addresses prior to sending a message
  • Loading branch information
jazzz authored Feb 24, 2022
2 parents bfc4093 + 47d1d78 commit ca53240
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 11 deletions.
53 changes: 44 additions & 9 deletions src/Client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,14 @@ export default class Client {
waku: Waku
address: string
keys: PrivateKeyBundle
private contacts: Map<string, PublicKeyBundle> // addresses and key bundles that we already have connection with
private contacts: Set<string> // address which we have connected to
private knownPublicKeyBundles: Map<string, PublicKeyBundle> // addresses and key bundles that we have witnessed
private _conversations: Conversations

constructor(waku: Waku, keys: PrivateKeyBundle) {
this.waku = waku
this.contacts = new Map<string, PublicKeyBundle>()
this.contacts = new Set<string>()
this.knownPublicKeyBundles = new Map<string, PublicKeyBundle>()
this.keys = keys
this.address = keys.identityKey.publicKey.walletSignatureAddress()
this._conversations = new Conversations(this)
Expand Down Expand Up @@ -102,7 +104,7 @@ export default class Client {
}

// retrieve a key bundle from given user's contact topic
async getUserContact(
async getUserContactFromNetwork(
peerAddress: string
): Promise<PublicKeyBundle | undefined> {
const recipientKeys = (
Expand All @@ -118,25 +120,58 @@ export default class Client {
return recipientKeys.length > 0 ? recipientKeys[0] : undefined
}

/**
* Returns the cached PublicKeyBundle if one is known for the given address or fetches
* one from the network
*/

async getUserContact(
peerAddress: string
): Promise<PublicKeyBundle | undefined> {
const existingBundle = this.knownPublicKeyBundles.get(peerAddress)

if (existingBundle) {
return existingBundle
}

const newBundle = await this.getUserContactFromNetwork(peerAddress)

if (newBundle) {
this.knownPublicKeyBundles.set(peerAddress, newBundle)
}

return newBundle
}

/**
* Check if @peerAddress can be messaged, specifically it checks that a PublicKeyBundle can be
* found for the given address
*/
public async canMessage(peerAddress: string): Promise<boolean> {
const keyBundle = await this.getUserContact(peerAddress)
return keyBundle !== undefined
}

/**
* Send a message to the wallet identified by @peerAddress
*/
async sendMessage(peerAddress: string, msgString: string): Promise<void> {
let topics: string[]
let recipient = this.contacts.get(peerAddress)
const recipient = await this.getUserContact(peerAddress)

if (!recipient) {
recipient = await this.getUserContact(peerAddress)
if (!recipient) {
throw new Error(`recipient ${peerAddress} is not registered`)
}
this.contacts.set(peerAddress, recipient)
throw new Error(`recipient ${peerAddress} is not registered`)
}

if (!this.contacts.has(peerAddress)) {
topics = [
buildUserIntroTopic(peerAddress),
buildDirectMessageTopic(this.address, peerAddress),
]
if (peerAddress !== this.address) {
topics.push(buildUserIntroTopic(this.address))
}
this.contacts.add(peerAddress)
} else {
topics = [buildDirectMessageTopic(this.address, peerAddress)]
}
Expand Down
12 changes: 10 additions & 2 deletions test/Client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ describe('Client', () => {

it('user contacts published', async () => {
await sleep(10)
const alicePublic = await alice.getUserContact(alice.address)
const alicePublic = await alice.getUserContactFromNetwork(alice.address)
assert.deepEqual(alice.keys.getPublicKeyBundle(), alicePublic)
const bobPublic = await bob.getUserContact(bob.address)
const bobPublic = await bob.getUserContactFromNetwork(bob.address)
assert.deepEqual(bob.keys.getPublicKeyBundle(), bobPublic)
})

Expand Down Expand Up @@ -176,6 +176,14 @@ describe('Client', () => {
alice.sendMessage('unregistered address', 'hello as well')
).rejects.toThrow('recipient unregistered address is not registered')
})

it('Check address can be sent to', async () => {
const can_mesg_a = await alice.canMessage('NOT AN ADDRESS')
assert.equal(can_mesg_a, false)

const can_mesg_b = await alice.canMessage(bob.address)
assert.equal(can_mesg_b, true)
})
})
})
})

0 comments on commit ca53240

Please sign in to comment.