Skip to content

Commit c62389c

Browse files
feat: examples
Signed-off-by: Ivaylo Nikolov <[email protected]>
1 parent 762ad8f commit c62389c

11 files changed

+1114
-0
lines changed

examples/account-hooks-example.js

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
import { decode } from "../src/encoding/hex.js";
2+
import fs from "fs";
3+
import {
4+
AccountCreateTransaction,
5+
AccountUpdateTransaction,
6+
ContractCreateTransaction,
7+
PrivateKey,
8+
Hbar,
9+
Client,
10+
AccountId,
11+
HookCreationDetails,
12+
LambdaEvmHook,
13+
HookExtensionPoint,
14+
Long,
15+
} from "@hashgraph/sdk";
16+
17+
import dotenv from "dotenv";
18+
19+
dotenv.config();
20+
21+
async function main() {
22+
if (
23+
process.env.OPERATOR_ID == null ||
24+
process.env.OPERATOR_KEY == null ||
25+
process.env.HEDERA_NETWORK == null
26+
) {
27+
throw new Error(
28+
"Environment variables OPERATOR_ID, HEDERA_NETWORK, and OPERATOR_KEY are required.",
29+
);
30+
}
31+
32+
const operatorId = AccountId.fromString(process.env.OPERATOR_ID);
33+
const operatorKey = PrivateKey.fromStringECDSA(process.env.OPERATOR_KEY);
34+
const network = process.env.HEDERA_NETWORK;
35+
const client = Client.forName(network).setOperator(operatorId, operatorKey);
36+
37+
try {
38+
console.log("Account Hooks Example Start!");
39+
40+
/*
41+
* Step 1: Create the hook contract.
42+
*/
43+
console.log("Creating hook contract...");
44+
45+
// Create bytecode file for the hook contract
46+
console.log("Creating bytecode for hook contract...");
47+
const contractBytecodeHex = fs.readFileSync(
48+
"./contracts/HieroHookContract.bytecode.txt",
49+
"utf8",
50+
);
51+
52+
// Create the hook contract
53+
console.log("Creating hook contract...");
54+
let { contractId } = await (
55+
await (
56+
await new ContractCreateTransaction()
57+
.setAdminKey(operatorKey.publicKey)
58+
.setGas(500_000)
59+
.setBytecode(decode(contractBytecodeHex))
60+
.freezeWith(client)
61+
.sign(operatorKey)
62+
).execute(client)
63+
).getReceipt(client);
64+
65+
console.log("Hook contract created with ID:", contractId.toString());
66+
67+
/*
68+
* Step 2: Demonstrate creating an account with hooks.
69+
*/
70+
console.log("\n=== Creating Account with Hooks ===");
71+
console.log("Creating account with lambda EVM hook...");
72+
73+
const accountKey = PrivateKey.generate();
74+
const accountPublicKey = accountKey.publicKey;
75+
76+
// Create a lambda EVM hook
77+
const lambdaHook = new LambdaEvmHook({ contractId });
78+
79+
// Create hook creation details
80+
const adminKey = client.operatorPublicKey;
81+
const hookWithId1002 = new HookCreationDetails({
82+
extensionPoint: HookExtensionPoint.ACCOUNT_ALLOWANCE_HOOK,
83+
hookId: Long.fromInt(1002),
84+
hook: lambdaHook,
85+
key: adminKey,
86+
});
87+
88+
let { accountId } = await (
89+
await (
90+
await new AccountCreateTransaction()
91+
.setKeyWithoutAlias(accountPublicKey)
92+
.setInitialBalance(new Hbar(1))
93+
.addHook(hookWithId1002)
94+
.freezeWith(client)
95+
.sign(operatorKey)
96+
).execute(client)
97+
).getReceipt(client);
98+
99+
console.log(`account id = ${accountId.toString()}`);
100+
console.log("Successfully created account with lambda hook!");
101+
102+
/*
103+
* Step 3: Demonstrate adding hooks to an existing account.
104+
*/
105+
console.log("\n=== Adding Hooks to Existing Account ===");
106+
console.log("Adding hooks to existing account...");
107+
108+
// Create basic lambda hooks with no storage updates
109+
const basicHook = new LambdaEvmHook({ contractId });
110+
const hookWithId1 = new HookCreationDetails({
111+
extensionPoint: HookExtensionPoint.ACCOUNT_ALLOWANCE_HOOK,
112+
hookId: Long.fromInt(1),
113+
hook: basicHook,
114+
key: adminKey,
115+
});
116+
117+
const basicHook2 = new LambdaEvmHook({ contractId });
118+
const hookWithId2 = new HookCreationDetails({
119+
extensionPoint: HookExtensionPoint.ACCOUNT_ALLOWANCE_HOOK,
120+
hookId: Long.fromInt(2),
121+
hook: basicHook2,
122+
key: adminKey,
123+
});
124+
125+
try {
126+
await (
127+
await (
128+
await new AccountUpdateTransaction()
129+
.setAccountId(accountId)
130+
.addHookToCreate(hookWithId1)
131+
.addHookToCreate(hookWithId2)
132+
.freezeWith(client)
133+
.sign(accountKey)
134+
).execute(client)
135+
).getReceipt(client);
136+
137+
console.log("Successfully added hooks to account!");
138+
} catch (error) {
139+
console.error("Failed to execute hook transaction:", error);
140+
}
141+
142+
/*
143+
* Step 4: Demonstrate hook deletion.
144+
*/
145+
console.log("\n=== Deleting Hooks from Account ===");
146+
console.log("Deleting hooks from account...");
147+
148+
try {
149+
await (
150+
await (
151+
await new AccountUpdateTransaction()
152+
.setAccountId(accountId)
153+
.addHookToDelete(Long.fromNumber(1))
154+
.addHookToDelete(Long.fromNumber(2))
155+
.freezeWith(client)
156+
.sign(accountKey)
157+
).execute(client)
158+
).getReceipt(client);
159+
160+
console.log("Successfully deleted hooks (IDs: 1, 2)");
161+
} catch (error) {
162+
console.error("Failed to execute hook deletion:", error);
163+
}
164+
165+
console.log("Account Hooks Example Complete!");
166+
} catch (error) {
167+
console.error("Error occurred:", error);
168+
}
169+
170+
client.close();
171+
}
172+
173+
void main();

examples/contract-hooks-example.js

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
import fs from "fs";
2+
import { decode } from "../src/encoding/hex.js";
3+
import {
4+
ContractCreateTransaction,
5+
ContractUpdateTransaction,
6+
PrivateKey,
7+
Client,
8+
AccountId,
9+
HookCreationDetails,
10+
LambdaEvmHook,
11+
HookExtensionPoint,
12+
Long,
13+
} from "@hashgraph/sdk";
14+
15+
import dotenv from "dotenv";
16+
17+
dotenv.config();
18+
19+
async function main() {
20+
if (
21+
process.env.OPERATOR_ID == null ||
22+
process.env.OPERATOR_KEY == null ||
23+
process.env.HEDERA_NETWORK == null
24+
) {
25+
throw new Error(
26+
"Environment variables OPERATOR_ID, HEDERA_NETWORK, and OPERATOR_KEY are required.",
27+
);
28+
}
29+
30+
const operatorId = AccountId.fromString(process.env.OPERATOR_ID);
31+
const operatorKey = PrivateKey.fromStringECDSA(process.env.OPERATOR_KEY);
32+
const network = process.env.HEDERA_NETWORK;
33+
const client = Client.forName(network).setOperator(operatorId, operatorKey);
34+
35+
try {
36+
console.log("Contract Hooks Example Start!");
37+
38+
/*
39+
* Step 1: Create the hook contract.
40+
*/
41+
console.log("Creating hook contract...");
42+
43+
// Create bytecode file for the hook contract
44+
console.log("Creating bytecode for hook contract...");
45+
const hookContractBytecodeHex = fs.readFileSync(
46+
"./contracts/HieroHookContract.bytecode.txt",
47+
"utf8",
48+
);
49+
50+
// Create the hook contract
51+
console.log("Creating hook contract...");
52+
let { contractId: hookContractId } = await (
53+
await (
54+
await new ContractCreateTransaction()
55+
.setAdminKey(operatorKey.publicKey)
56+
.setGas(500_000)
57+
.setBytecode(decode(hookContractBytecodeHex))
58+
.freezeWith(client)
59+
.sign(operatorKey)
60+
).execute(client)
61+
).getReceipt(client);
62+
63+
console.log(
64+
"Hook contract created with ID:",
65+
hookContractId.toString(),
66+
);
67+
68+
/*
69+
* Step 2: Demonstrate creating a contract with hooks.
70+
*/
71+
console.log("\n=== Creating Contract with Hooks ===");
72+
console.log("Creating contract with lambda EVM hook...");
73+
74+
const simpleContractBytecodeHex = fs.readFileSync(
75+
"./contracts/HelloWorld.bytecode.txt",
76+
"utf8",
77+
);
78+
79+
// Build a basic lambda EVM hook (no admin key, no storage updates)
80+
const lambdaHook = new LambdaEvmHook({ contractId: hookContractId });
81+
const hookWithId1 = new HookCreationDetails({
82+
extensionPoint: HookExtensionPoint.ACCOUNT_ALLOWANCE_HOOK,
83+
hookId: Long.fromInt(1),
84+
hook: lambdaHook,
85+
});
86+
87+
let { contractId: contractWithHooksId } = await (
88+
await (
89+
await new ContractCreateTransaction()
90+
.setAdminKey(operatorKey.publicKey)
91+
.setGas(400_000)
92+
.setBytecode(decode(simpleContractBytecodeHex))
93+
.addHook(hookWithId1)
94+
.freezeWith(client)
95+
.sign(operatorKey)
96+
).execute(client)
97+
).getReceipt(client);
98+
99+
console.log(
100+
"Created contract with ID:",
101+
contractWithHooksId.toString(),
102+
);
103+
console.log("Successfully created contract with basic lambda hook!");
104+
105+
/*
106+
* Step 3: Demonstrate adding hooks to an existing contract.
107+
*/
108+
console.log("\n=== Adding Hooks to Existing Contract ===");
109+
console.log("Adding hooks to existing contract...");
110+
111+
const adminKey = client.operatorPublicKey;
112+
113+
// Hook 3: Basic lambda hook with no storage updates (using ID 3 to avoid conflict with existing hook 1)
114+
const basicHook = new LambdaEvmHook({ contractId: hookContractId });
115+
const hookWithId3 = new HookCreationDetails({
116+
extensionPoint: HookExtensionPoint.ACCOUNT_ALLOWANCE_HOOK,
117+
hookId: Long.fromInt(3),
118+
hook: basicHook,
119+
key: adminKey,
120+
});
121+
122+
try {
123+
await (
124+
await (
125+
await new ContractUpdateTransaction()
126+
.setContractId(contractWithHooksId)
127+
.addHookToCreate(hookWithId3)
128+
.freezeWith(client)
129+
.sign(operatorKey)
130+
).execute(client)
131+
).getReceipt(client);
132+
133+
console.log("Successfully added hooks to contract!");
134+
} catch (error) {
135+
console.error("Failed to execute hook transaction:", error);
136+
}
137+
138+
/*
139+
* Step 4: Demonstrate hook deletion.
140+
*/
141+
console.log("\n=== Deleting Hooks from Contract ===");
142+
console.log("Deleting hooks from contract...");
143+
144+
try {
145+
await (
146+
await (
147+
await new ContractUpdateTransaction()
148+
.setContractId(contractWithHooksId)
149+
.addHookToDelete(Long.fromNumber(1)) // Delete hook created during contract creation
150+
.addHookToDelete(Long.fromNumber(3)) // Delete hook added via contract update
151+
.freezeWith(client)
152+
.sign(operatorKey)
153+
).execute(client)
154+
).getReceipt(client);
155+
156+
console.log("Successfully deleted hooks with IDs: 1 and 3");
157+
} catch (error) {
158+
console.error("Failed to execute hook deletion:", error);
159+
}
160+
161+
console.log("Contract Hooks Example Complete!");
162+
} catch (error) {
163+
console.error("Error occurred:", error);
164+
}
165+
166+
client.close();
167+
}
168+
169+
void main();
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
608060405234801561001057600080fd5b50610167806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80632f570a2314610030575b600080fd5b61004a600480360381019061004591906100b6565b610060565b604051610057919061010a565b60405180910390f35b60006001905092915050565b60008083601f84011261007e57600080fd5b8235905067ffffffffffffffff81111561009757600080fd5b6020830191508360018202830111156100af57600080fd5b9250929050565b600080602083850312156100c957600080fd5b600083013567ffffffffffffffff8111156100e357600080fd5b6100ef8582860161006c565b92509250509250929050565b61010481610125565b82525050565b600060208201905061011f60008301846100fb565b92915050565b6000811515905091905056fea264697066735822122097fc0c3ac3155b53596be3af3b4d2c05eb5e273c020ee447f01b72abc3416e1264736f6c63430008000033

examples/contracts/HelloWorld.sol

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// SPDX-License-Identifier: GPL-3.0
2+
pragma solidity 0.8.0;
3+
4+
/**
5+
* @title Test
6+
*/
7+
contract HelloWorld {
8+
constructor() {
9+
}
10+
11+
function test(bytes calldata calldata_test) external returns(bool) {
12+
return true;
13+
}
14+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
6080604052348015600e575f5ffd5b506107d18061001c5f395ff3fe608060405260043610610033575f3560e01c8063124d8b301461003757806394112e2f14610067578063bd0dd0b614610097575b5f5ffd5b610051600480360381019061004c91906106f2565b6100c7565b60405161005e9190610782565b60405180910390f35b610081600480360381019061007c91906106f2565b6100d2565b60405161008e9190610782565b60405180910390f35b6100b160048036038101906100ac91906106f2565b6100dd565b6040516100be9190610782565b60405180910390f35b5f6001905092915050565b5f6001905092915050565b5f6001905092915050565b5f604051905090565b5f5ffd5b5f5ffd5b5f5ffd5b5f60a08284031215610112576101116100f9565b5b81905092915050565b5f5ffd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6101658261011f565b810181811067ffffffffffffffff821117156101845761018361012f565b5b80604052505050565b5f6101966100e8565b90506101a2828261015c565b919050565b5f5ffd5b5f5ffd5b5f67ffffffffffffffff8211156101c9576101c861012f565b5b602082029050602081019050919050565b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f610207826101de565b9050919050565b610217816101fd565b8114610221575f5ffd5b50565b5f813590506102328161020e565b92915050565b5f8160070b9050919050565b61024d81610238565b8114610257575f5ffd5b50565b5f8135905061026881610244565b92915050565b5f604082840312156102835761028261011b565b5b61028d604061018d565b90505f61029c84828501610224565b5f8301525060206102af8482850161025a565b60208301525092915050565b5f6102cd6102c8846101af565b61018d565b905080838252602082019050604084028301858111156102f0576102ef6101da565b5b835b818110156103195780610305888261026e565b8452602084019350506040810190506102f2565b5050509392505050565b5f82601f830112610337576103366101ab565b5b81356103478482602086016102bb565b91505092915050565b5f67ffffffffffffffff82111561036a5761036961012f565b5b602082029050602081019050919050565b5f67ffffffffffffffff8211156103955761039461012f565b5b602082029050602081019050919050565b5f606082840312156103bb576103ba61011b565b5b6103c5606061018d565b90505f6103d484828501610224565b5f8301525060206103e784828501610224565b60208301525060406103fb8482850161025a565b60408301525092915050565b5f6104196104148461037b565b61018d565b9050808382526020820190506060840283018581111561043c5761043b6101da565b5b835b81811015610465578061045188826103a6565b84526020840193505060608101905061043e565b5050509392505050565b5f82601f830112610483576104826101ab565b5b8135610493848260208601610407565b91505092915050565b5f606082840312156104b1576104b061011b565b5b6104bb606061018d565b90505f6104ca84828501610224565b5f83015250602082013567ffffffffffffffff8111156104ed576104ec6101a7565b5b6104f984828501610323565b602083015250604082013567ffffffffffffffff81111561051d5761051c6101a7565b5b6105298482850161046f565b60408301525092915050565b5f61054761054284610350565b61018d565b9050808382526020820190506020840283018581111561056a576105696101da565b5b835b818110156105b157803567ffffffffffffffff81111561058f5761058e6101ab565b5b80860161059c898261049c565b8552602085019450505060208101905061056c565b5050509392505050565b5f82601f8301126105cf576105ce6101ab565b5b81356105df848260208601610535565b91505092915050565b5f604082840312156105fd576105fc61011b565b5b610607604061018d565b90505f82013567ffffffffffffffff811115610626576106256101a7565b5b61063284828501610323565b5f83015250602082013567ffffffffffffffff811115610655576106546101a7565b5b610661848285016105bb565b60208301525092915050565b5f604082840312156106825761068161011b565b5b61068c604061018d565b90505f82013567ffffffffffffffff8111156106ab576106aa6101a7565b5b6106b7848285016105e8565b5f83015250602082013567ffffffffffffffff8111156106da576106d96101a7565b5b6106e6848285016105e8565b60208301525092915050565b5f5f60408385031215610708576107076100f1565b5b5f83013567ffffffffffffffff811115610725576107246100f5565b5b610731858286016100fd565b925050602083013567ffffffffffffffff811115610752576107516100f5565b5b61075e8582860161066d565b9150509250929050565b5f8115159050919050565b61077c81610768565b82525050565b5f6020820190506107955f830184610773565b9291505056fea26469706673582212207dfe7723f6d6869419b1cb0619758b439da0cf4ffd9520997c40a3946299d4dc64736f6c634300081e0033

0 commit comments

Comments
 (0)