Skip to main content

Abar transfer

Below you can see an example of how to perform abar transfer operation (a.k.a. abar to abar).

// An instance of the Anonymous wallet, where the `abar` would be sent from
const anonKeysSender = {
axfrPublicKey: "-Gdf_hulMdWPeC2dG3RG-Hjo8yLTdWnPfB5csEGkbmg=",
axfrSecretKey:
"z4atlAssg_PcVa05__EXB5VbT23JF4mSdAuCUa2-fQn4Z2P-G6UzNY94LbcbdEb4eOhbItPZac8AHlywQaRbaA==",
decKey: "1Js-MFSVJipTNL-y09zkSBakd15WLK-SfAUTTfsUInE=",
encKey: "bim4EWU_PnClrNiVpKen4DZ0v-RwsVLSUtZy7PXCOCc=",
};

// An instance of the Anonymous wallet, where the `abar` would be sent to
const anonKeysReceiver = {
axfrPublicKey: "T_0kQOWEToeg53Q8dS8eej91sJKVBEV2f7rs7Btz5CY=",
axfrSecretKey:
"HVdrTiyyL6dFBqq7HvPjYgACG1eIF6-pgvc-OomswAhP_SRA5YROh6DndDx1Lx56P3WwkpUERXZ_uuzsG3PkJg==",
decKey: "GMzcWMbWz41hO5AEpXk1q1XYr8wpkq_zRscrxqg7TW0=",
encKey: "nGfox4UJTBHCjiUMUmyUolyOGMAmR25ktfEYOZXTJ0s=",
};

const abarToAbar = async () => {
// First we need to provide a commitment string for the abar which we would `transfer` to another anonymous wallet
const givenCommitmentToTransfer =
"FRghJ4uC3E4yJ4a9pFydogXRNLt2nvRZrrKd6woDMFQs";

// `abar to abar` fee is paid using an abar data, so to cover the fee for the operation
// we need to provide another commitment (there might be more than one).
// It would be used solely to pay the fee for the operation amd must be in FRA
const givenCommitmentsToPayFee = [
"CdhXbHX1Fb22LH4mNcw1es8rA2RnmA9Xjmb1hmPuQAmu",
];

// Just a helper varibale to keep all the commitments which belong to a sender in one place
// It would be updated with a new commitment later
const givenCommitmentsListSender = [
givenCommitmentToTransfer,
...givenCommitmentsToPayFee,
];

// Abars data, which would be used to pay the fee, is also stored in a container for convenience purposes
const additionalOwnedAbarItems = [];

// Transfer operation would require instances of abars, which will be created (restored)
// using given commitment strings
const ownedAbarsResponseOne = await TripleMasking.getOwnedAbars(
anonKeysSender.axfrPublicKey,
givenCommitmentToTransfer
);

const [ownedAbarToUseAsSource] = ownedAbarsResponseOne;

for (let givenCommitmentToPayFee of givenCommitmentsToPayFee) {
const ownedAbarsResponseTwo = await TripleMasking.getOwnedAbars(
anonKeysSender.axfrPublicKey,
givenCommitmentToPayFee
);

const [additionalOwnedAbarItem] = ownedAbarsResponseTwo;

additionalOwnedAbarItems.push(additionalOwnedAbarItem);
}

// Amount of funds to be sent. For custom asset it has to match with the amount of the ownedAbarToUseAsSource abar
const amount = "3";

// Next is a key method, which returns 2 things:
// - an instance of the anonTransferOperationBuilder, which would be used to submit the generated tx to the network
// - an object with the information about the mapping for the new commitments, which contains remanined funds after paying the fee, as well as the receiver commitment inforamtion
const { anonTransferOperationBuilder, abarToAbarData } =
await TripleMasking.abarToAbar(
anonKeysSender,
anonKeysReceiver,
amount,
ownedAbarToUseAsSource,
additionalOwnedAbarItems
);

// Then we retrieve transaction data (to be broadcasted)
const submitData = anonTransferOperationBuilder.transaction();

// Finally, we submut the transaction to the network to finalize the `abar to bar` operation
// and, as a result we receive a transaction hash
const result = await Network.submitTransaction(submitData);
const { response: resultHandle } = result;

// Here we simply wait for 17s until next block is produced by the network
await sleep(17000);

// Now we are processing the commitments mapping returned by the `abar to abar` operation
// to update a `givenCommitmentsListSender` list of commitments with the commitments which belong to the sender
// and vice versa for the receiver.
// It is very important to preserve this data and have it properly processed, otherwise both receiver and sender
// will lose their funds
const { commitmentsMap } = abarToAbarData;

const retrivedRandomizersListReceiver = [];

for (const commitmentsMapEntry of commitmentsMap) {
const { commitmentKey, commitmentAxfrPublicKey } = commitmentsMapEntry;

if (commitmentAxfrPublicKey === anonKeysSender.axfrPublicKey) {
givenCommitmentsListSender.push(commitmentKey);
}

if (commitmentAxfrPublicKey === anonKeysReceiver.axfrPublicKey) {
retrivedRandomizersListReceiver.push(commitmentKey);
}
}
};