-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathecho-accountable.js
More file actions
109 lines (99 loc) · 3.38 KB
/
echo-accountable.js
File metadata and controls
109 lines (99 loc) · 3.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
const { ethers } = require("ethers");
const { arrayify } = require("ethers/utils");
const { AnyDotSenderCoreClient } = require("@any-sender/client");
const config = require("./configuration");
const run = async (
userWallet,
provider,
message,
echoContractAddress,
echoAbi,
relayContractAddress,
apiUrl,
receiptSignerAddress
) => {
// set up the any sender client
const anySenderClient = new AnyDotSenderCoreClient({
apiUrl,
receiptSignerAddress,
});
// check we have enough balance
const balance = await anySenderClient.balance(userWallet.address);
if (balance.lt(ethers.utils.parseEther("0.1")))
throw new Error(
`Not enough balance. Balance is: ${balance.toString()} wei.`
);
console.log("Current balance: " + balance.toString());
// form a relay to the echo contract
// first construct the data
const echoInterface = new ethers.utils.Interface(echoAbi);
const data = echoInterface.functions.echo.encode([
`-- ${message} -- (message sent by ${userWallet.address} at ${new Date(
Date.now()
).toString()})`,
]);
// set the deadline = 400 + small margin
const currentBlock = await provider.getBlockNumber();
const deadline = currentBlock + 400;
const relayTx = {
chainId: 3,
from: userWallet.address,
to: echoContractAddress,
data: data,
deadline: deadline,
gasLimit: 100000, // should be plenty
compensation: "500000000", // 0.5 gwei
relayContractAddress: relayContractAddress,
type: "accountable", // accountable transaction type
};
// sign the relay transaction
const id = AnyDotSenderCoreClient.relayTxId(relayTx);
const signature = await userWallet.signMessage(arrayify(id));
const signedTx = { ...relayTx, signature };
// subscribe to the relay event, so we know when the transaction has been relayed
console.log();
console.log("Subscribing to relay event.");
const topics = AnyDotSenderCoreClient.getRelayExecutedEventTopics(relayTx);
provider.once({ address: relayContractAddress, topics }, async (event) => {
const blocksUntilMined = event.blockNumber - currentBlock;
console.log();
console.log(
`Relay tx mined with id: ${event.topics[1]} at block ${event.blockNumber}`
);
console.log(
`Tx relayed after ${blocksUntilMined - 1} block${
blocksUntilMined > 2 ? "s" : ""
}. Pretty cool, I guess. (⌐■_■)`
);
console.log();
console.log(
`See your message at https://ropsten.etherscan.io/tx/${event.transactionHash}#eventlog`
);
// remove the block listener so we can exit
provider.removeAllListeners("block");
});
provider.on("block", (block) => {
if (block !== currentBlock) console.log("... block mined", block);
});
// send it!
console.log(`Sending relay tx: ${id} at block ${currentBlock}`);
console.log();
const receipt = await anySenderClient.relay(signedTx);
// received, we can save this receipt for later proof that any.sender was hired
console.log(
"Receipt received for tx: " +
AnyDotSenderCoreClient.relayTxId(receipt.relayTransaction)
);
console.log("Waiting for relay event...");
console.log();
};
run(
config.userWallet,
new ethers.providers.JsonRpcProvider(config.jsonRpcUrl),
config.message,
config.echoContractAddress,
config.echoAbi,
config.relayContractAddress,
config.apiUrl,
config.receiptSignerAddress
).catch((err) => console.error(err.message));