Skip to content

Commit

Permalink
[Attestation Service] MessageBird provider check for KYCed US-based n…
Browse files Browse the repository at this point in the history
…umber (#5929)

### Description

Error on startup if MessageBird provider if:
* API key is incorrect
* No US numbers found that are enabled for SMS, and have passed KYC.

### Tested

Locally

### Backwards compatibility

Yes
  • Loading branch information
timmoreton authored Nov 25, 2020
1 parent 1e45cd6 commit 42c6f12
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 7 deletions.
33 changes: 30 additions & 3 deletions packages/attestation-service/src/sms/messagebird.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import Logger from 'bunyan'
import { randomBytes } from 'crypto'
import express from 'express'
import initMB, { MessageBird } from 'messagebird'
import fetch from 'node-fetch'
import util from 'util'
import { fetchEnv } from '../env'
import { AttestationModel, AttestationStatus } from '../models/attestation'
Expand All @@ -20,9 +21,11 @@ export class MessageBirdSmsProvider extends SmsProvider {
messagebird: MessageBird
type = SmsProviderType.MESSAGEBIRD
deliveryStatusURL: string | undefined
apiKey: string

constructor(apiKey: string, unsupportedRegionCodes: string[]) {
super()
this.apiKey = apiKey
this.messagebird = initMB(apiKey)
this.unsupportedRegionCodes = unsupportedRegionCodes
}
Expand Down Expand Up @@ -61,12 +64,36 @@ export class MessageBirdSmsProvider extends SmsProvider {
return [bodyParser.urlencoded({ extended: false })]
}

async getUSNumbers(): Promise<string[]> {
const response = await fetch('https://numbers.messagebird.com/v1/phone-numbers?features=sms', {
method: 'GET',
headers: {
Accept: 'application/json',
Authorization: `AccessKey ${this.apiKey}`,
},
})
if (!response.ok) {
throw new Error('Could not list numbers! ' + response.status)
}
const body = JSON.parse(await response.text())
return body.items
? body.items
.filter((n: any) => n.country === 'US' && n.kycStatus === 'ok')
.map((n: any) => n.number)
: []
}

async initialize(deliveryStatusURL: string) {
// Ensure the messaging service exists
this.deliveryStatusURL = deliveryStatusURL
let numbers
try {
this.deliveryStatusURL = deliveryStatusURL
// Ensure at least one KYC-ed US based sms number is available for SMS.
numbers = await this.getUSNumbers()
} catch (error) {
throw new Error(`Twilio Messaging Service could not be fetched: ${error}`)
throw new Error(`MessageBird: could not access numbers: ${error}`)
}
if (numbers.length === 0) {
throw new Error('MessageBird: complete KYC and purchase a US-based number enabled for SMS')
}
}

Expand Down
8 changes: 4 additions & 4 deletions packages/docs/validator-guide/attestation-service.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ Note that Attestation Service from version 1.2.0 no longer requires callback URL

MessageBird support is introduced in version 1.2.0 and later. After signing up for [MessageBird](https://messagebird.com/en/), locate the `Your API Keys` section on the [Dashboard](https://dashboard.messagebird.com/en/user/index), click `Show` next to the `Live` key, and copy its value into the `MESSAGEBIRD_API_KEY` configuration variable. Click `Top Up` to add credit. MessageBird requires a dedicated number and approval to send SMS to certain countries that validators must support including the USA, Canada and others. Click `Numbers` then [Buy Number](https://dashboard.messagebird.com/en/numbers/buy/search) to purchase a number. Then visit [SMS Settings](https://dashboard.messagebird.com/en/settings/sms) and request approval to send to these countries.

Unlike Twilio and Nexmo, you will need to enter the callback URL for [delivery receipts](#delivery-receipts) in the MessageBird dashboard.
Unlike Twilio and Nexmo, you will need to enter the callback URL for [delivery receipts](#delivery-receipts) in the MessageBird dashboard. As such, it is not currently possible to share MessageBird accounts between validators while receiving delivery receipts.

## Installation

Expand Down Expand Up @@ -234,9 +234,9 @@ docker run --name celo-attestation-service -it --restart always --entrypoint /bi

### Registering Metadata

Celo uses [Metadata](../celo-codebase/protocol/identity/metadata.md) to allow accounts to make certain claims without having to do so on-chain. Users can use any authorized signer address to make claims on behalf of the registered Account. For convenience this guide uses the `CELO_ATTESTATION_SIGNER_ADDRESS`, but any authorized signer will work. To complete the metadata process, we have to claim which URL users can request attestations from.
Celo uses [Metadata](../celo-codebase/protocol/identity/metadata.md) to allow accounts to make certain claims without having to do so on-chain. Users can use any authorized signer address to make claims on behalf of the registered Account. For convenience this guide uses the `CELO_ATTESTATION_SIGNER_ADDRESS`, but any authorized signer will work. Note that metadata needs recreating if the key signing it is changed; it is recommended not to use the validator signer address since that key is typically rotated more regularly.

Run the following commands on your local machine. This section uses several environment variables defined during the validator setup.
To complete the metadata process, we have to claim which URL users can request attestations from. Run the following commands on your local machine. This section uses several environment variables defined during the validator setup.

```bash
# On your local machine
Expand Down Expand Up @@ -290,7 +290,7 @@ celocli identity:test-attestation-service --from $CELO_ATTESTATION_SIGNER_ADDRES

You need the attestation signer key available and unlocked on your local machine.

You may wish to do this once for each provider you have configured (`--provider=twilio` and `--provider=nexmo`). (If this option is not recognized, try upgrading `celocli`).
You may wish to do this once for each provider you have configured (`--provider=twilio`, `--provider=nexmo` etc). (If this option is not recognized, try upgrading `celocli`).

Note that this does not use an identical code path to real attestations (since those require specific on-chain state) so this endpoint should not be used in place of monitoring logs and metrics.

Expand Down

0 comments on commit 42c6f12

Please sign in to comment.