Soda Labs
Soda Labs Docs

Onboard user

Onboard an address to Bubble and obtain the AES user key needed for encrypted operations.

Once an account is created and linked to an address, it must be onboarded to the Bubble system to perform secure operations. Onboarding involves obtaining an AES key, which can be used for encryption and decryption within the system.

Onboarding a user into the bubble network is done via a gRPC function:

rpc OnboardUser(OnboardUserRequest) returns (OnboardUserResponse);

message OnboardUserRequest {
    bytes rsa_public_key = 1;
    bytes address = 2;
    bytes user_signature = 3;
}

message OnboardUserResponse{
    bytes rsa_ciphertexts = 1;
    repeated bytes mpc_signatures = 2;
    int32 result_code = 3;
}

The following Python code demonstrates how to perform an OnboardeUser RPC request using the Bubble SDK:

  • client: A gRPC client.
  • signing_private_key: ECDSA private key for request signing
def onboard_user(client, signing_private_key):

	signers = get_signers_addresses()

	# Create RSA key pair
	rsa_private_key, rsa_public_key = generate_rsa_keypair()

	# Get the Ethereum address from private key
	account = Account.from_key(signing_private_key)
	user_address = to_bytes(hexstr=account.address)

	print(f"User address: {user_address.hex()}")

	message = rsa_public_key + user_address

	# Sign the rsa public key
	signature = sign_eip191(message, bytes.fromhex(signing_private_key[2:]))

	print(f"Onboarding user with address: {account.address}")

	# Call the gRPC service
	request = pb.OnboardUserRequest(
		rsa_public_key=rsa_public_key,
		address=user_address,
		user_signature=signature
	)
	response = client.OnboardUser(request)

	logging.info(f"OnboardUser returned {len(response.rsa_ciphertexts)} bytes")

	if len(response.rsa_ciphertexts) != 2 * RSA_CIPHERTEXT_SIZE:
		raise ValueError(f"Invalid response size: {len(response.rsa_ciphertexts)}")

	if len(response.mpc_signatures) != NUM_EVALUATORS:
		raise ValueError(f"Invalid number of signatures: {len(response.mpc_signatures)}")

    	# Verify the signatures
	if not verify_signatures(response.rsa_ciphertexts, response.mpc_signatures, signers): # returns true if the signatures are valid, false otherwise
		raise ValueError(f"Signatures verification failed")

	# Split the response into two ciphers
	cipher0 = response.rsa_ciphertexts[:RSA_CIPHERTEXT_SIZE]
	cipher1 = response.rsa_ciphertexts[RSA_CIPHERTEXT_SIZE:]

	# Decrypt the ciphers
	share0 = decrypt_rsa(rsa_private_key, cipher0)
	share1 = decrypt_rsa(rsa_private_key, cipher1)

	# XOR the key shares to get the user AES key
	user_aes_key = bytes(a ^ b for a, b in zip(share0, share1))

	return user_aes_key

Bubble supplies scripts that perform user onboarding.

  • Script: The script named onboard_user, available in both Python and JavaScript, is provided to facilitate the the onboarding process.
  • Execution: Navigate to the main bubble directory and run the appropriate command depending on the language choice:
python3 -m lib.offchain.onboardUser.python.onboard_user
  • Output: After running the script, an AES key is added to the .env file.

  • Environment Loading: The user should load the AES key into their environment using the command:

    source .env

After completing these steps, the user has a functional account with the necessary credentials and tokens, allowing them to start interacting with the system, including running smart contracts or performing other actions as needed.