docs: async function registerDevice(options) {
      options = options || {};
      const atlasClient = options.atlasClient || await AtlasClient.factory();
      const accountInfo = await atlasClient.fetch('/v1/provision/account');
      if (!accountInfo.devices.length) {
          console.error("Must use `registerAccount` for first device");
          throw new TypeError("No Account");
      }
      const signalClient = new SignalClient(null, null, accountInfo.serverUrl);
      const autoProvision = options.autoProvision !== false;
      const name = options.name || defaultName;
      if (!options.onProvisionReady && !autoProvision) {
          throw new TypeError("Missing: onProvisionReady callback");
      }
      const returnInterface = {waiting: true};
      const provisioningCipher = new ProvisioningCipher();
      const pubKey = provisioningCipher.getPublicKey().toString('base64');
      let wsr;
      const webSocketWaiter = new Promise((resolve, reject) => {
          wsr = new WebSocketResource(signalClient.getProvisioningWebSocketURL(), {
              keepalive: {path: '/v1/keepalive/provisioning'},
              handleRequest: request => {
                  if (request.path === "/v1/address" && request.verb === "PUT") {
                      const proto = protobufs.ProvisioningUuid.decode(request.body);
                      request.respond(200, 'OK');
                      if (autoProvision) {
                          atlasClient.fetch('/v1/provision/request', {
                              method: 'POST',
                              json: {
                                  uuid: proto.uuid,
                                  key: pubKey
                              }
                          }).catch(reject);
                      }
                      if (options.onProvisionReady) {
                          const r = options.onProvisionReady(proto.uuid, pubKey);
                          if (r instanceof Promise) {
                              r.catch(reject);
                          }
                      }
                  } else if (request.path === "/v1/message" && request.verb === "PUT") {
                      const msgEnvelope = protobufs.ProvisionEnvelope.decode(request.body);
                      request.respond(200, 'OK');
                      wsr.close();
                      resolve(msgEnvelope);
                  } else {
                      reject(new Error('Unknown websocket message ' + request.path));
                  }
              }
          });
      });
      await wsr.connect();
  
      returnInterface.done = (async () => {
          const provisionMessage = await provisioningCipher.decrypt(await webSocketWaiter);
          returnInterface.waiting = false;
          const addr = provisionMessage.addr;
          const identity = provisionMessage.identityKeyPair;
          if (provisionMessage.addr != accountInfo.userId) {
              throw new Error('Security Violation: Foreign account sent us an identity key!');
          }
          const registrationId = libsignal.keyhelper.generateRegistrationId();
          const password = generatePassword();
          const signalingKey = generateSignalingKey();
          const response = await signalClient.request({
              httpType: 'PUT',
              call: 'devices',
              urlParameters: '/' + provisionMessage.provisioningCode,
              json: {
                  signalingKey: signalingKey.toString('base64'),
                  supportsSms: false,
                  fetchesMessages: true,
                  registrationId,
                  name
              },
              username: addr,
              password,
              validateResponse: {deviceId: 'number'}
          });
          const username = `${addr}.${response.deviceId}`;
          await storage.clearSessionStore();
          await storage.removeOurIdentity();
          await storage.removeIdentity(addr);
          await storage.saveIdentity(addr, identity.pubKey);
          await storage.saveOurIdentity(identity);
          await storage.putState('addr', addr);
          await storage.putState('serverUrl', signalClient.url);
          await storage.putState('deviceId', response.deviceId);
          await storage.putState('name', name);
          await storage.putState('username', username);
          await storage.putState('password', password);
          await storage.putState('registrationId', registrationId);
          await storage.putState('signalingKey', signalingKey);
          const authedClient = new SignalClient(username, password, signalClient.url);
          await authedClient.registerKeys(await authedClient.generateKeys());
      })();
  
      returnInterface.cancel = async () => {
          wsr.close();
          try {
              await webSocketWaiter;
          } catch(e) {
              console.warn("Ignoring web socket error:", e);
          }
      };
      return returnInterface;
  }