Transaction comment encryption. #232
-
I`m looking for the code implementation of the description below. Thanks. |
Beta Was this translation helpful? Give feedback.
Replies: 0 comments 11 replies
-
Thanks for posting this here @GrandLegend. @aaronmgdr Do you happen to know who might have a link to an implementation of the "Encrypted Payment Comments" above? |
Beta Was this translation helpful? Give feedback.
-
/**
* Registers the accounts public key as the data encryption key.
* @param name the name to be saved in the accounts smart contract.
* @param publicKey the data encryption key.
* @param publicAddress the public address to paired with the public encryption key.
* @returns the saved data encryption key.
*/
export async function registerAccountEncryptionKey(name: string, publicKey: string, publicAddress: string) {
const wakalaContractKit = WakalaContractKit.getInstance();
const contractKit = wakalaContractKit?.kit;
const publicDataKey = compressedPubKey(hexToBuffer(publicKey))
const accounts: AccountsWrapper = await contractKit?.contracts.getAccounts();
const tsxObject = accounts.setAccount(name, publicDataKey, publicAddress, null);
let gasFees = new BigNumber(0);
const estimate = await wakalaContractKit?.fetchGasPrice(ERC20_ADDRESS);
if (estimate) {
gasFees = estimate
}
const txParams = {
from: contractKit?.defaultAccount,
feeCurrency: ERC20_ADDRESS,
gasPrice: gasFees.toString()
}
// receipt for logging if necessary when debugging
const r = await tsxObject.sendAndWaitForReceipt(txParams);
// console.log(r);
const dataEncryptionKey = await accounts?.getDataEncryptionKey(publicAddress);
console.log("==========>", dataEncryptionKey, await accounts?.getName(publicAddress))
console.log("===========comment encryption================>");
const encryptedPhone = await encryptComment("Enter the address of your Alfajores Testnet account to receive additional funds. Each request adds 1 CELO", publicAddress, "0x2f254ceA58719E3AE7DF82E1117Ea7C1cE2Ce30d");
console.log("Encrypted comment", encryptedPhone);
const decryptedComment = await decryptComment(encryptedPhone.comment, publicAddress, true);
console.log("Decrypted comment", decryptedComment);
return dataEncryptionKey;
}
/**
* Gets the data encryption key of a public address.
* @param publicAddress the public address with the data encryption key.
* @returns the public key/data encryption key.
*/
export async function getDataEncryptionKey(publicAddress: string) {
const wakalaContractKit = WakalaContractKit.getInstance();
const contractKit = wakalaContractKit?.kit;
const accounts = await contractKit?.contracts.getAccounts();
return await accounts?.getDataEncryptionKey(publicAddress);
}
/**
* Encrypts a comment given the right params.
* @param comment the comment to be encrypted.
* @param from the source address.
* @param to the recipient address
* @returns the encrypted comment.
*/
export async function encryptComment(comment: string, from: string, to: string) {
const fromKey = await getDataEncryptionKey(from);
const toKey = await getDataEncryptionKey(to);
if (fromKey == "" || toKey == "") {
throw "Invalid from or to address"
}
return encryptCommentRaw(comment, hexToBuffer(toKey), hexToBuffer(fromKey))
}
/**
* Decrypts encrypted comments.
* @param encryptedComment the comment to be decrypted.
* @param dataEncryptionKey the data encryption key used to encrypt the data.
* @param isSender true if the data encryption key belongs to the sender of the message.
*/
export async function decryptComment(encryptedComment: string, publicAddress: string, isSender: boolean) {
const decryptionKey = await getDataEncryptionKey(publicAddress);
return decryptCommentRaw(encryptedComment, decryptionKey, isSender);
} Arrived at the above solution however, ran into this |
Beta Was this translation helpful? Give feedback.
-
Hi @Allen-Muhani sorry for the delay in responding. I wanted to provide as much context as possible to help you. You can find an account's data encryption key ("DEK") by querying the Accounts.sol smart contract with the following illustrative code, which uses ContractKit: const accounts = await useKit((kit) => kit.contracts.getAccounts())
const [walletAddress, dekAddress] = await Promise.all([
accounts.getWalletAddress(getRequest.account),
accounts.getDataEncryptionKey(getRequest.account).then((x) => x && publicKeyToAddress(x)),
]) Thanks for the pointer @alecps 🙌 More on ContractKitThe illustrative code above calls a function in ContractKit, more specifically, it calls a function in the Accounts.sol contract wrapper (Accounts.ts). For more context:
Source: docs > ContractKit ContractKit includes wrapper functions such as Accounts.ts to access Celo Core Contracts such as Accounts.sol. For example, here are the two functions /**
* Returns the set data encryption key for the account
* @param account Account
*/
getDataEncryptionKey = proxyCall(this.contract.methods.getDataEncryptionKey, undefined, (res) =>
solidityBytesToString(res)
)
/**
* Returns the set wallet address for the account
* @param account Account
*/
getWalletAddress = proxyCall(this.contract.methods.getWalletAddress) You can follow the instructions here to setup and use ContractKit. More on Accounts.solIn a nutshell, the Accounts.sol contract lets users enrich their accounts with "other useful things". Here is the struct Account {
bool exists;
// [Deprecated] Each account may authorize signing keys to use for voting,
// validating or attestation. These keys may not be keys of other accounts,
// and may not be authorized by any other account for any purpose.
Signers signers;
// The address at which the account expects to receive transfers. If it's empty/0x0, the
// account indicates that an address exchange should be initiated with the dataEncryptionKey
address walletAddress;
// An optional human readable identifier for the account
string name;
// The ECDSA public key used to encrypt and decrypt data for this account
bytes dataEncryptionKey; // 👈 HERE
// The URL under which an account adds metadata and claims
string metadataURL;
} If you're interested, the Accounts.sol contract also lets you set special signing keys for various use cases. Here is the struct Signers {
// The address that is authorized to vote in governance and validator elections on behalf of the
// account. The account can vote as well, whether or not a vote signing key has been specified.
address vote;
// The address that is authorized to manage a validator or validator group and sign consensus
// messages on behalf of the account. The account can manage the validator, whether or not a
// validator signing key has been specified. However, if a validator signing key has been
// specified, only that key may actually participate in consensus.
address validator;
// The address of the key with which this account wants to sign attestations on the Attestations
// contract
address attestation;
} More on Data Encryption Keys
Source: docs > developer resources > contractkit > data encryption key Hope this helps! |
Beta Was this translation helpful? Give feedback.
Thanks for posting this here @GrandLegend.
@aaronmgdr Do you happen to know who might have a link to an implementation of the "Encrypted Payment Comments" above?