Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add removeSignature/clearAllSignatures methods #2491

Merged
merged 16 commits into from
Sep 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
05f3b85
feat: Added removeSignature/clearAllSignatures methods to Transaction…
ivaylogarnev-limechain Aug 26, 2024
9febd0e
feat: Added more unit tests for removeSignature/clearAllSignatures an…
ivaylogarnev-limechain Aug 27, 2024
350b988
refactor: Turned signAndAddSignatures function into arrow
ivaylogarnev-limechain Aug 27, 2024
af34748
refactor: Cleared some unnecessary comments and changed variable assi…
ivaylogarnev-limechain Aug 27, 2024
ff24587
feat: Enhancement removeSignature/clearAllSignatures to return the re…
ivaylogarnev-limechain Aug 29, 2024
e81ef5a
refactor: Removed the signature param from removeSignature method and…
ivaylogarnev-limechain Aug 30, 2024
81245d0
Merge branch 'main' into feat/2461-remove-clear-signatures
ivaylogarnev-limechain Aug 30, 2024
e24e2de
refactor: Remove redundant code
ivaylogarnev-limechain Sep 2, 2024
ef868b1
Merge branch 'main' into feat/2461-remove-clear-signatures
ivaylonikolov7 Sep 15, 2024
0b264e3
refactor: Cleared some uneccessary comments & changed a bit the flow …
ivaylogarnev-limechain Sep 17, 2024
f8a3152
Merge branch main into feat/2461-remove-clear-signatures
ivaylogarnev-limechain Sep 18, 2024
e3cc17a
refactor: Refactored signTransaction method a bit, added integration …
ivaylogarnev-limechain Sep 18, 2024
52487c6
refactor: Removed duplicate integration tests and added description t…
ivaylogarnev-limechain Sep 18, 2024
d5b548c
Merge branch 'main' into feat/2461-remove-clear-signatures
ivaylogarnev-limechain Sep 19, 2024
01d9e0a
refactor: Examples pre-release warnings fixes
ivaylogarnev-limechain Sep 20, 2024
c5e7d1e
Merge branch 'feat/2461-remove-clear-signatures' of github.com:hashgr…
ivaylogarnev-limechain Sep 20, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
209 changes: 209 additions & 0 deletions examples/multi-node-multi-signature-remove.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
import {
Client,
PrivateKey,
AccountCreateTransaction,
Hbar,
AccountId,
KeyList,
TransferTransaction,
Transaction,
} from "@hashgraph/sdk";

import dotenv from "dotenv";

dotenv.config();

let aliceKey;
let bobKey;

/**
* @description Create a transaction with multiple nodes and multiple signatures
* and remove one of the signatures from the transaction then add it back
*/
async function main() {
/**
*
* Step 1: Create Client
*
*/
if (
process.env.OPERATOR_ID == null ||
process.env.OPERATOR_KEY == null ||
process.env.HEDERA_NETWORK == null
) {
throw new Error(
"Environment variables OPERATOR_ID, HEDERA_NETWORK, and OPERATOR_KEY are required.",
);
}

const client = Client.forName(process.env.HEDERA_NETWORK).setOperator(
AccountId.fromString(process.env.OPERATOR_ID),
PrivateKey.fromStringED25519(process.env.OPERATOR_KEY),
);

/**
*
* Step 2: Create keys for two users
*
*/
aliceKey = PrivateKey.generate();
bobKey = PrivateKey.generate();

const keyList = new KeyList([aliceKey.publicKey, bobKey.publicKey]);

/**
*
* Step 3: Create an account with the keyList
*
*/
const createAccountTransaction = new AccountCreateTransaction()
.setInitialBalance(new Hbar(2))
.setKey(keyList);

const createResponse = await createAccountTransaction.execute(client);
const createReceipt = await createResponse.getReceipt(client);

/**
*
* Step 4: Create a transfer transaction with multiple nodes
*
*/
const transferTransaction = new TransferTransaction()
.addHbarTransfer(createReceipt.accountId, new Hbar(-1))
.addHbarTransfer("0.0.3", new Hbar(1))
// Set multiple nodes
.setNodeAccountIds([
new AccountId(3),
new AccountId(4),
new AccountId(5),
])
.freezeWith(client);

/**
*
* Step 5: Serialize the transaction
* & Collect multiple signatures (Uint8Array[]) from one key
*
*/

const transferTransactionBytes = transferTransaction.toBytes();

const aliceSignatures = aliceKey.signTransaction(transferTransaction);
const bobSignatures = bobKey.signTransaction(transferTransaction);

/**
*
* Step 6: Deserialize the transaction
* & Add the previously collected signatures
*
*/
const signedTransaction = Transaction.fromBytes(transferTransactionBytes);

signedTransaction.addSignature(aliceKey.publicKey, aliceSignatures);
signedTransaction.addSignature(bobKey.publicKey, bobSignatures);

console.log("ADDED users signatures below: \n");

if (Array.isArray(aliceSignatures) && Array.isArray(bobSignatures)) {
console.log(
"Alice Signatures =>",
aliceSignatures.map((aliceSig) =>
PrivateKey.fromBytes(aliceSig).toStringDer(),
),
);

console.log(
"Bob Signatures =>",
bobSignatures.map((bobSig) =>
PrivateKey.fromBytes(bobSig).toStringDer(),
),
);
}

const signaturesInTheTransactionBefore =
getAllSignaturesFromTransaction(signedTransaction);

console.log("\n\nSignatures in the transaction: ");
console.log(signaturesInTheTransactionBefore);

/**
*
* Step 7: Remove the signatures for Alice from the transaction
*
*/

const removedAliceSignatures = signedTransaction.removeSignature(
aliceKey.publicKey,
);

console.log("\nREMOVED Alice signatures below: \n");

if (Array.isArray(aliceSignatures) && Array.isArray(bobSignatures)) {
console.log(
"Alice removed signatures =>",
removedAliceSignatures.map((aliceSig) =>
PrivateKey.fromBytes(aliceSig).toStringDer(),
),
);
}

const signaturesInTheTransactionAfter =
getAllSignaturesFromTransaction(signedTransaction);

console.log("\n\nSignatures left in the transaction: ");
console.log(signaturesInTheTransactionAfter);

/**
*
* Step 8: Add the removed signature back to the transaction
*
*/
signedTransaction.addSignature(aliceKey.publicKey, removedAliceSignatures);

/**
*
* Step 9: Execute and take the receipt
*
*/
const result = await signedTransaction.execute(client);

const receipt = await result.getReceipt(client);

console.log(`\n \nTransaction status: ${receipt.status.toString()}`);

client.close();
}

void main();

/**
* Extracts all signatures from a signed transaction.
* @param {Transaction} signedTransaction - The signed transaction object containing the list of signed transactions.
* @returns {string[]} An array of signatures in DER format.
*/
const getAllSignaturesFromTransaction = (signedTransaction) => {
/** @type {string[]} */
const signatures = [];

signedTransaction._signedTransactions.list.forEach((transaction) => {
if (transaction.sigMap?.sigPair) {
transaction.sigMap.sigPair.forEach((sigPair) => {
if (sigPair.ed25519) {
signatures.push(
PrivateKey.fromBytesED25519(
sigPair.ed25519,
).toStringDer(),
);
} else if (sigPair.ECDSASecp256k1) {
signatures.push(
PrivateKey.fromBytesECDSA(
sigPair.ECDSASecp256k1,
).toStringDer(),
);
}
});
}
});

return signatures;
};
Loading