-
Notifications
You must be signed in to change notification settings - Fork 8
/
echo-direct.js
117 lines (104 loc) · 5.36 KB
/
echo-direct.js
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
110
111
112
113
114
115
116
117
const { ethers } = require("ethers");
const { arrayify } = require("ethers/utils");
const { AnyDotSenderCoreClient } = require("@any-sender/client");
const config = require("./configuration");
function wait(milliseconds) {
return new Promise((resolve) => setTimeout(resolve, milliseconds));
}
async function waitForConfirmation(provider, anySenderClient, id, sentAtBlock) {
let mined = false;
// Loop until it is mined
while (!mined) {
// Contact the status API
const status = await anySenderClient.getStatus(id);
for (let i = 0; i < status.length; i++) {
const txReceipt = await provider.getTransactionReceipt(
status[i].ethTxHash
);
// Did we find a receipt?
if (
txReceipt != undefined &&
txReceipt != undefined &&
txReceipt.blockNumber != undefined
) {
// Is it confirmed?
const confirmedBy = txReceipt.blockNumber;
const confirmationEstimate = confirmedBy - sentAtBlock + 1;
if (confirmationEstimate >= 1) {
const blocksUntilMined = confirmedBy - sentAtBlock;
console.log(`Direct tx mined with id: ${id} at block ${confirmedBy}`);
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/${txReceipt.transactionHash}#eventlog`
);
mined = true;
}
}
}
await wait(5000);
}
}
const run = async (
userWallet,
provider,
message,
echoContractAddress,
echoAbi,
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.01")))
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()})`,
]);
const relayTx = {
chainId: 1,
from: userWallet.address,
to: echoContractAddress,
data: data,
gasLimit: 100000, // should be plenty,
type: "direct",
};
// sign the relay transaction
const id = AnyDotSenderCoreClient.relayTxId(relayTx);
const signature = await userWallet.signMessage(arrayify(id));
const signedTx = { ...relayTx, signature };
// send it!
console.log(
`Sending relay tx: ${id} at block ${await provider.getBlockNumber()}`
);
console.log();
await anySenderClient.relay(signedTx);
const sentAtBlock = await provider.getBlockNumber();
await waitForConfirmation(provider, anySenderClient, id, sentAtBlock);
};
run(
config.userWallet,
new ethers.providers.JsonRpcProvider(config.jsonRpcUrl),
config.message,
config.echoContractAddress,
config.echoAbi,
config.apiUrl,
config.receiptSignerAddress
).catch((err) => console.error(err.message));