-
Notifications
You must be signed in to change notification settings - Fork 146
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' into feat/tck-update-accounts-transactions
Signed-off-by: ivaylogarnev-limechain <[email protected]>
- Loading branch information
Showing
38 changed files
with
39,917 additions
and
5,869 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
name: 'PR Formatting' | ||
on: | ||
workflow_dispatch: | ||
pull_request: | ||
types: | ||
- opened | ||
- reopened | ||
- edited | ||
- synchronize | ||
|
||
defaults: | ||
run: | ||
shell: bash | ||
|
||
permissions: | ||
contents: read | ||
|
||
concurrency: | ||
group: pr-checks-${{ github.workflow }}-${{ github.head_ref || github.run_id }} | ||
cancel-in-progress: true | ||
|
||
jobs: | ||
title-check: | ||
name: Title Check | ||
runs-on: client-sdk-linux-medium | ||
if: ${{ !github.event.pull_request.base.repo.fork }} | ||
permissions: | ||
statuses: write | ||
steps: | ||
- name: Harden Runner | ||
uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2 | ||
with: | ||
egress-policy: audit | ||
|
||
- name: Check PR Title | ||
uses: step-security/conventional-pr-title-action@19fb561b33015fd2184055a05ce5a3bcf2ba3f54 # v3.2.0 | ||
env: | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,209 @@ | ||
import { | ||
Client, | ||
AccountCreateTransaction, | ||
Hbar, | ||
PrivateKey, | ||
KeyList, | ||
TransferTransaction, | ||
ScheduleSignTransaction, | ||
ScheduleInfoQuery, | ||
AccountBalanceQuery, | ||
AccountUpdateTransaction, | ||
Timestamp, | ||
} from "@hashgraph/sdk"; | ||
|
||
import dotenv from "dotenv"; | ||
dotenv.config(); | ||
|
||
async function main() { | ||
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.", | ||
); | ||
} | ||
|
||
console.log("Long Term Scheduled Transaction Example Start!"); | ||
|
||
// Step 0: Create and configure the SDK Client. | ||
const operatorId = process.env.OPERATOR_ID; | ||
const operatorKey = PrivateKey.fromStringED25519(process.env.OPERATOR_KEY); | ||
const client = Client.forName(process.env.HEDERA_NETWORK || "testnet"); | ||
client.setOperator(operatorId, operatorKey); | ||
|
||
// Step 1: Create key pairs | ||
const privateKey1 = PrivateKey.generateED25519(); | ||
const privateKey2 = PrivateKey.generateED25519(); | ||
const thresholdKey = new KeyList([ | ||
privateKey1.publicKey, | ||
privateKey2.publicKey, | ||
]); | ||
console.log("Created a Key List: ", thresholdKey); | ||
|
||
// Step 2: Create the account | ||
console.log("Creating new account..."); | ||
const aliceId = ( | ||
await ( | ||
await new AccountCreateTransaction() | ||
.setKey(thresholdKey) | ||
.setInitialBalance(new Hbar(2)) | ||
.execute(client) | ||
).getReceipt(client) | ||
).accountId; | ||
console.log("Created new account with ID: ", aliceId.toString()); | ||
|
||
// Step 3: Schedule a transfer transaction | ||
console.log("Creating new scheduled transaction with 1 day expiry"); | ||
const transfer = new TransferTransaction() | ||
.addHbarTransfer(aliceId, new Hbar(-1)) | ||
.addHbarTransfer(client.operatorAccountId, new Hbar(1)); | ||
const hasJitter = false; | ||
|
||
const scheduleId = ( | ||
await ( | ||
await transfer | ||
.schedule() | ||
.setWaitForExpiry(false) | ||
.setExpirationTime( | ||
Timestamp.generate(hasJitter).plusNanos( | ||
86400 * 1_000_000_000, | ||
), | ||
) // 1 day in milliseconds | ||
.execute(client) | ||
).getReceipt(client) | ||
).scheduleId; | ||
|
||
// Step 4: Sign the transaction with one key | ||
console.log("Signing the new scheduled transaction with 1 key"); | ||
await ( | ||
await ( | ||
await new ScheduleSignTransaction() | ||
.setScheduleId(scheduleId) | ||
.freezeWith(client) | ||
.sign(privateKey1) | ||
).execute(client) | ||
).getReceipt(client); | ||
|
||
let info = await new ScheduleInfoQuery() | ||
.setScheduleId(scheduleId) | ||
.execute(client); | ||
let executedAt = info.executed ? info.executed : "none"; | ||
console.log( | ||
"Scheduled transaction is not yet executed. Executed at: ", | ||
executedAt, | ||
); | ||
|
||
// Step 5: Sign the transaction with the other key | ||
let accountBalance = await new AccountBalanceQuery() | ||
.setAccountId(aliceId) | ||
.execute(client); | ||
console.log( | ||
"Alice's account balance before schedule transfer: ", | ||
accountBalance.hbars.toString(), | ||
); | ||
|
||
console.log("Signing the new scheduled transaction with the 2nd key"); | ||
await ( | ||
await ( | ||
await new ScheduleSignTransaction() | ||
.setScheduleId(scheduleId) | ||
.freezeWith(client) | ||
.sign(privateKey2) | ||
).execute(client) | ||
).getReceipt(client); | ||
|
||
accountBalance = await new AccountBalanceQuery() | ||
.setAccountId(aliceId) | ||
.execute(client); | ||
console.log( | ||
"Alice's account balance after schedule transfer: ", | ||
accountBalance.hbars.toString(), | ||
); | ||
|
||
info = await new ScheduleInfoQuery() | ||
.setScheduleId(scheduleId) | ||
.execute(client); | ||
console.log( | ||
"Scheduled transaction is executed. Executed at: ", | ||
info.executed.toDate(), | ||
); | ||
|
||
// Step 6: Schedule another transfer transaction | ||
console.log("Creating new scheduled transaction with 10 seconds expiry"); | ||
const transfer2 = new TransferTransaction() | ||
.addHbarTransfer(aliceId, new Hbar(-1)) | ||
.addHbarTransfer(client.operatorAccountId, new Hbar(1)); | ||
|
||
const scheduleId2 = ( | ||
await ( | ||
await transfer2 | ||
.schedule() | ||
.setWaitForExpiry(true) | ||
.setExpirationTime( | ||
Timestamp.generate(hasJitter).plusNanos(10 * 1_000_000_000), | ||
) // 10 seconds in milliseconds | ||
.execute(client) | ||
).getReceipt(client) | ||
).scheduleId; | ||
|
||
// Step 7: Sign the transaction with one key | ||
console.log("Signing the new scheduled transaction with 1 key"); | ||
await ( | ||
await ( | ||
await new ScheduleSignTransaction() | ||
.setScheduleId(scheduleId2) | ||
.freezeWith(client) | ||
.sign(privateKey1) | ||
).execute(client) | ||
).getReceipt(client); | ||
|
||
info = await new ScheduleInfoQuery() | ||
.setScheduleId(scheduleId2) | ||
.execute(client); | ||
executedAt = info.executed ? info.executed : "none"; | ||
console.log( | ||
"Scheduled transaction is not yet executed. Executed at: ", | ||
executedAt, | ||
); | ||
|
||
// Step 8: Update the account’s key | ||
console.log("Updating Alice's key to be the 1st key"); | ||
await ( | ||
await ( | ||
await ( | ||
await new AccountUpdateTransaction() | ||
.setAccountId(aliceId) | ||
.setKey(privateKey1.publicKey) | ||
.freezeWith(client) | ||
.sign(privateKey1) | ||
).sign(privateKey2) | ||
).execute(client) | ||
).getReceipt(client); | ||
|
||
// Step 9: Verify that the transfer successfully executes | ||
accountBalance = await new AccountBalanceQuery() | ||
.setAccountId(aliceId) | ||
.execute(client); | ||
console.log( | ||
"Alice's account balance before schedule transfer: ", | ||
accountBalance.hbars.toString(), | ||
); | ||
|
||
// Wait for the scheduled transaction to execute | ||
await new Promise((resolve) => setTimeout(resolve, 10000)); // Wait for 10 seconds | ||
|
||
accountBalance = await new AccountBalanceQuery() | ||
.setAccountId(aliceId) | ||
.execute(client); | ||
console.log( | ||
"Alice's account balance after schedule transfer: ", | ||
accountBalance.hbars.toString(), | ||
); | ||
|
||
console.log("Long Term Scheduled Transaction Example Complete!"); | ||
} | ||
|
||
main().catch(console.error); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.