ERC777 "Sender account not recognized"

Beginner here, trying to implement an ERC777 token, recipient and sender. The code at the bottom stands for the token and the sender/receiver, respectively. I wrote them out as per this tutorial, but there must be something wrong because the following truffle console commands result in an error:

var accs = await web3.eth.getAccounts()
>> undefined
const [personA, personB] = accs
>> undefined
var token = await MyToken.new(10000, { from: personA })
>> undefined
token.balanceOf(personA)
>> BN: 10000
token.balanceOf(personB)
>> BN: 0
var clientA = await Client.new(token.address, { from: personA })
>> undefined
var clientB = await Client.new(token.address, { from: personB })
>> undefined
token.balanceOf(clientA)
>> BN: 0
token.balanceOf(clientB)
>> BN: 0
token.send(clientA.address, new BN(2500), web3.utils.sha3('whatever'), { from: personA })
>> undefined
token.balanceOf(personA)
>> BN: 7500
token.balanceOf(clientA.address)
>> BN: 2500
token.send(clientB.address, new BN(1000), web3.utils.sha3('whatever'), { from: clientA.address })
>> TXRejectedError: sender account not recognized
// SPDX-License-Identifier: MIT
pragma solidity ^0.8;

import "@openzeppelin/contracts/token/ERC777/ERC777.sol";

contract MyToken is ERC777 {
  constructor(uint initialSupply) 
    ERC777("Token", "TKN", new address[](0)) {
      _mint(msg.sender, initialSupply, "", "");
  }
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8;

import "@openzeppelin/contracts/token/ERC777/IERC777.sol";
import "@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol";
import "@openzeppelin/contracts/utils/introspection/IERC1820Registry.sol";
import "@openzeppelin/contracts/utils/introspection/ERC1820Implementer.sol";
import "@openzeppelin/contracts/token/ERC777/IERC777Sender.sol";

contract Client is IERC777Recipient, IERC777Sender, ERC1820Implementer {
  IERC777 private _token;
  IERC1820Registry private _erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);
  bytes32 constant private TOKENS_RECIPIENT_INTERFACE_HASH = keccak256("ERC777TokensRecipient");
  bytes32 constant private TOKENS_SENDER_INTERFACE_HASH = keccak256("ERC777TokensSender");

  event TokensSent(
    address operator,
    address from,
    address to,
    uint256 amount,
    bytes userData,
    bytes operatorData
  );
  event TokensReceived(
    address operator,
    address from,
    address to,
    uint amount,
    bytes userData,
    bytes operatorData
  );

  constructor(address token_) {
    _token = IERC777(token_);
    _erc1820.setInterfaceImplementer(address(this), TOKENS_RECIPIENT_INTERFACE_HASH, address(this));
  }

  function senderFor(address account_) public {
    _registerInterfaceForAddress(TOKENS_SENDER_INTERFACE_HASH, account_);
  }

  function tokensToSend(
    address operator_,
    address from_,
    address to_,
    uint amount_,
    bytes calldata userData_,
    bytes calldata operatorData_
  ) external {
    emit TokensSent(
      operator_,
      from_, 
      to_, 
      amount_, 
      userData_, 
      operatorData_
    );
  }

  function tokensReceived(
    address operator_,
    address from_,
    address to_,
    uint amount_,
    bytes calldata userData_,
    bytes calldata operatorData_
  ) external {
    require(msg.sender == address(_token), "Client: invalid token");

    emit TokensReceived(
      operator_,
      from_,
      to_,
      amount_,
      userData_,
      operatorData_
    );
  }
}