|
1 | | -import { encodeFunctionData, toHex } from "viem"; |
| 1 | +import { encodeFunctionData } from "viem"; |
2 | 2 | import { abi as checkpointAbi } from "./abis/Checkpoint"; |
3 | 3 | import { abi as piggyBankAbi } from "./abis/PiggyBank"; |
4 | 4 | import { abi as noticeBoardAbi } from "./abis/NoticeBoard"; |
5 | | -import { abi as iInstructionsFacetAbi } from "./abis/IInstructionsFacet"; |
6 | 5 | import { |
7 | | - getInstructionFee, |
8 | | - getOperatorXrplAddresses, |
| 6 | + encodeCustomInstruction, |
9 | 7 | getPersonalAccountAddress, |
10 | | - MASTER_ACCOUNT_CONTROLLER_ADDRESS, |
11 | 8 | registerCustomInstruction, |
| 9 | + sendCustomInstruction, |
| 10 | + waitForCustomInstructionExecutedEvent, |
12 | 11 | type CustomInstruction, |
13 | 12 | } from "./utils/smart-accounts"; |
14 | | -import { publicClient } from "./utils/client"; |
15 | | -import { sendXrplPayment } from "./utils/xrpl"; |
16 | 13 | import { Client, Wallet } from "xrpl"; |
17 | | -import type { CustomInstructionExecutedEventType } from "./utils/event-types"; |
18 | | -import { abi } from "./abis/CustomInstructionsFacet"; |
19 | | - |
20 | | -async function encodeCustomInstruction( |
21 | | - instructions: CustomInstruction[], |
22 | | - walletId: number, |
23 | | -) { |
24 | | - const encodedInstruction = (await publicClient.readContract({ |
25 | | - address: MASTER_ACCOUNT_CONTROLLER_ADDRESS, |
26 | | - abi: abi, |
27 | | - functionName: "encodeCustomInstruction", |
28 | | - args: [instructions], |
29 | | - })) as `0x${string}`; |
30 | | - // NOTE:(Nik) We cut off the `0x` prefix and the first 2 bytes to get the length down to 30 bytes |
31 | | - return ("0xff" + |
32 | | - toHex(walletId, { size: 1 }).slice(2) + |
33 | | - encodedInstruction.slice(6)) as `0x${string}`; |
34 | | -} |
35 | | - |
36 | | -async function sendCustomInstruction({ |
37 | | - encodedInstruction, |
38 | | - xrplClient, |
39 | | - xrplWallet, |
40 | | -}: { |
41 | | - encodedInstruction: `0x${string}`; |
42 | | - xrplClient: Client; |
43 | | - xrplWallet: Wallet; |
44 | | -}) { |
45 | | - const operatorXrplAddress = (await getOperatorXrplAddresses())[0] as string; |
46 | | - |
47 | | - const instructionFee = await getInstructionFee(encodedInstruction); |
48 | | - console.log("Instruction fee:", instructionFee, "\n"); |
49 | | - |
50 | | - const customInstructionTransaction = await sendXrplPayment({ |
51 | | - destination: operatorXrplAddress, |
52 | | - amount: instructionFee, |
53 | | - memos: [{ Memo: { MemoData: encodedInstruction.slice(2) } }], |
54 | | - wallet: xrplWallet, |
55 | | - client: xrplClient, |
56 | | - }); |
57 | | - |
58 | | - return customInstructionTransaction; |
59 | | -} |
60 | | - |
61 | | -async function waitForCustomInstructionExecutedEvent({ |
62 | | - encodedInstruction, |
63 | | - personalAccountAddress, |
64 | | -}: { |
65 | | - encodedInstruction: `0x${string}`; |
66 | | - personalAccountAddress: string; |
67 | | -}) { |
68 | | - let customInstructionExecutedEvent: |
69 | | - | CustomInstructionExecutedEventType |
70 | | - | undefined; |
71 | | - let customInstructionExecutedEventFound = false; |
72 | | - |
73 | | - const unwatchCustomInstructionExecuted = publicClient.watchContractEvent({ |
74 | | - address: MASTER_ACCOUNT_CONTROLLER_ADDRESS, |
75 | | - abi: iInstructionsFacetAbi, |
76 | | - eventName: "CustomInstructionExecuted", |
77 | | - onLogs: (logs) => { |
78 | | - for (const log of logs) { |
79 | | - customInstructionExecutedEvent = |
80 | | - log as CustomInstructionExecutedEventType; |
81 | | - if ( |
82 | | - customInstructionExecutedEvent.args.callHash.slice(6) !== |
83 | | - encodedInstruction.slice(6) || |
84 | | - customInstructionExecutedEvent.args.personalAccount.toLowerCase() !== |
85 | | - personalAccountAddress.toLowerCase() |
86 | | - ) { |
87 | | - continue; |
88 | | - } |
89 | | - customInstructionExecutedEventFound = true; |
90 | | - break; |
91 | | - } |
92 | | - }, |
93 | | - }); |
94 | | - |
95 | | - console.log("Waiting for CustomInstructionExecuted event..."); |
96 | | - while (!customInstructionExecutedEventFound) { |
97 | | - await new Promise((resolve) => setTimeout(resolve, 10000)); |
98 | | - } |
99 | | - unwatchCustomInstructionExecuted(); |
100 | | - |
101 | | - return customInstructionExecutedEvent; |
102 | | -} |
103 | 14 |
|
104 | 15 | // NOTE:(Nik) For this example to work, you first need to faucet C2FLR to your personal account address. |
105 | 16 | async function main() { |
|
0 commit comments