-
Notifications
You must be signed in to change notification settings - Fork 0
/
cheques.js
161 lines (138 loc) · 4.91 KB
/
cheques.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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
const DOMAIN_NAME = "CaminoMessenger";
const DOMAIN_VERSION = "1";
function calculateMessengerChequeTypeHash() {
const typeHash = ethers.keccak256(
ethers.toUtf8Bytes(
"MessengerCheque(address fromCMAccount,address toCMAccount,address toBot,uint256 counter,uint256 amount,uint256 createdAt,uint256 expiresAt)",
),
);
return typeHash;
}
function calculateDomainTypeHash() {
const domainTypeHash = ethers.keccak256(
ethers.toUtf8Bytes("EIP712Domain(string name,string version,uint256 chainId)"),
);
return domainTypeHash;
}
function calculateDomainSeparator(domainName, domainVersion, chainId) {
const coder = ethers.AbiCoder.defaultAbiCoder();
const domainSeparator = ethers.keccak256(
coder.encode(
["bytes32", "bytes32", "bytes32", "uint256"],
[
calculateDomainTypeHash(),
ethers.keccak256(ethers.toUtf8Bytes(domainName)),
ethers.keccak256(ethers.toUtf8Bytes(domainVersion)),
ethers.toBigInt(chainId),
],
),
);
return domainSeparator;
}
function calculateDomainSeparatorForChain(_chainId) {
const domainName = "CaminoMessenger";
const domainVersion = "1";
const chainId = _chainId;
return calculateDomainSeparator(domainName, domainVersion, chainId);
}
function calculateDomainSeparatorCamino() {
return calculateDomainSeparatorForChain(500);
}
function calculateDomainSeparatorColumbus() {
return calculateDomainSeparatorForChain(501);
}
function calculateDomainSeparatorKopernikus() {
return calculateDomainSeparatorForChain(502);
}
function calculateTypedDataHash(cheque, domainSeparator) {
const chequeHash = calculateMessengerChequeHash(cheque);
return ethers.keccak256(ethers.concat([ethers.toUtf8Bytes("\x19\x01"), domainSeparator, chequeHash]));
}
function calculateMessengerChequeHash(cheque) {
const chequeTypeHash = calculateMessengerChequeTypeHash();
const coder = ethers.AbiCoder.defaultAbiCoder();
const encodedCheque = coder.encode(
["bytes32", "address", "address", "address", "uint256", "uint256", "uint256", "uint256"],
[
chequeTypeHash,
cheque.fromCMAccount,
cheque.toCMAccount,
cheque.toBot,
cheque.counter,
cheque.amount,
cheque.createdAt,
cheque.expiresAt,
],
);
return ethers.keccak256(encodedCheque);
}
async function _signMessengerCheque(fromCMAccount, toCMAccount, toBot, counter, amount, createdAt, expiresAt, signer) {
const chainId = await signer.provider.getNetwork().then((n) => n.chainId);
const cheque = {
fromCMAccount: fromCMAccount,
toCMAccount: toCMAccount,
toBot: toBot,
counter: counter,
amount: amount,
createdAt: createdAt,
expiresAt: expiresAt,
};
const signature = await signMessengerCheque(cheque, signer);
return signature;
}
async function signMessengerCheque(cheque, signer) {
const chainId = await signer.provider.getNetwork().then((n) => n.chainId);
const types = {
MessengerCheque: [
{ name: "fromCMAccount", type: "address" },
{ name: "toCMAccount", type: "address" },
{ name: "toBot", type: "address" },
{ name: "counter", type: "uint256" },
{ name: "amount", type: "uint256" },
{ name: "createdAt", type: "uint256" },
{ name: "expiresAt", type: "uint256" },
],
};
const domain = {
name: DOMAIN_NAME,
version: DOMAIN_VERSION,
chainId: chainId,
};
const signature = await signer.signTypedData(domain, types, cheque);
return signature;
}
async function signInvalidMessengerCheque(cheque, signer) {
const chainId = await signer.provider.getNetwork().then((n) => n.chainId);
const types = {
MessengerCheque: [
{ name: "fromCMAccount", type: "address" },
{ name: "toCMAccount", type: "address" },
{ name: "toBot", type: "address" },
{ name: "counter", type: "uint256" },
{ name: "amount", type: "uint256" },
{ name: "createdAt", type: "uint256" },
{ name: "expiresAt", type: "uint256" },
],
};
const domain = {
name: DOMAIN_NAME,
version: DOMAIN_VERSION,
chainId: chainId + 42n, // Invalid chainId
};
const signature = await signer.signTypedData(domain, types, cheque);
return signature;
}
module.exports = {
calculateMessengerChequeTypeHash,
calculateTypedDataHash,
calculateMessengerChequeHash,
calculateDomainTypeHash,
calculateDomainSeparator,
calculateDomainSeparatorCamino,
calculateDomainSeparatorColumbus,
calculateDomainSeparatorKopernikus,
calculateDomainSeparatorForChain,
signMessengerCheque,
signInvalidMessengerCheque,
_signMessengerCheque,
};