@exodus/ethereum-lib 4.4.0 → 4.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@exodus/ethereum-lib",
3
- "version": "4.4.0",
3
+ "version": "4.6.0",
4
4
  "description": "Ethereum Library",
5
5
  "main": "src/index.js",
6
6
  "files": [
@@ -46,6 +46,7 @@
46
46
  "@exodus/optimism-meta": "^1.2.10",
47
47
  "@exodus/rootstock-meta": "^1.0.5",
48
48
  "@exodus/solidity-contract": "^1.1.3",
49
+ "@metamask/eth-sig-util": "^4.0.1",
49
50
  "base-x": "^3.0.2",
50
51
  "ethjs-util": "0.1.6",
51
52
  "lodash": "^4.17.15",
@@ -59,5 +60,5 @@
59
60
  "@exodus/bnbmainnet-meta": "^1.0.0",
60
61
  "@exodus/elliptic": "^6.5.4-precomputed"
61
62
  },
62
- "gitHead": "952a85ff2ce573b294d53fb411b9858088d15229"
63
+ "gitHead": "a9f627045d3323b35362d3513dd0ec325ccbfd7c"
63
64
  }
@@ -1,5 +1,6 @@
1
1
  import { get } from 'lodash'
2
2
 
3
+ // @deprecated to be removed. Use balances!
3
4
  export const getEthereumBalances = ({ asset, liquidBalance, accountState }) => {
4
5
  // asset = ethereum or ethereumgoerli or ethereumholesky
5
6
  const delegatedBalance = get(
@@ -1,2 +1,3 @@
1
+ // @deprecated to be removed. Use balances!
1
2
  export * from './ethereum-balance'
2
3
  export * from './polygon-balance'
@@ -3,6 +3,7 @@ import assets from '@exodus/ethereum-meta'
3
3
 
4
4
  const polygon = assets.find(({ name: tokenName }) => tokenName === 'polygon')
5
5
 
6
+ // @deprecated to be removed. Use balances!
6
7
  export const getPolygonBalances = ({ liquidBalance, accountState }) => {
7
8
  const delegatedBalance = get(
8
9
  accountState,
@@ -3,7 +3,7 @@ import { asset } from '@exodus/basemainnet-meta'
3
3
 
4
4
  export default new FeeData({
5
5
  config: {
6
- gasPrice: '0.07 Gwei',
6
+ gasPrice: '0.2 Gwei',
7
7
  max: '1 Gwei',
8
8
  min: '0.001 Gwei',
9
9
  fuelThreshold: '750000 Gwei',
package/src/index.js CHANGED
@@ -5,6 +5,7 @@ export * from './utils'
5
5
  export * from './constants'
6
6
  export * from './fee-monitor'
7
7
  export * from './selectors'
8
+ export { signMessage } from './sign-message'
8
9
  export { default as createGetKeyIdentifier } from './key-identifier'
9
10
  export { default as createEthereumLikeAccountState } from './account-state'
10
11
 
@@ -0,0 +1,96 @@
1
+ import assert from 'minimalistic-assert'
2
+ import {
3
+ SignTypedDataVersion,
4
+ typedSignatureHash,
5
+ TypedDataUtils,
6
+ personalSign,
7
+ signTypedData,
8
+ concatSig,
9
+ } from '@metamask/eth-sig-util'
10
+ import { hashPersonalMessage, toBuffer } from '@exodus/ethereumjs-util'
11
+
12
+ function hex0xStringToBuffer(hex) {
13
+ // Remove the 0x
14
+ const hexWithout0x = hex.startsWith('0x') ? hex.slice(2) : hex
15
+ // Pad the value until even
16
+ const hexWithLeadingZeros = hexWithout0x.length % 2 === 0 ? hexWithout0x : '0' + hexWithout0x
17
+ // Finally return the buffer
18
+ return Buffer.from(hexWithLeadingZeros, 'hex')
19
+ }
20
+
21
+ /**
22
+ * Converts a buffer to the 0xhex encoded value
23
+ * @param {Buffer} buf the buffer to convert to 0xHEXSTRING
24
+ * @returns the hex-encoded value prepended with 0x
25
+ */
26
+ function bufferToHex0xString(buf) {
27
+ if (!Buffer.isBuffer(buf)) {
28
+ throw new TypeError('expected a buffer')
29
+ }
30
+
31
+ const hex = buf.toString('hex')
32
+
33
+ if (typeof hex !== 'string') {
34
+ throw new TypeError('expected hex string')
35
+ }
36
+
37
+ return '0x' + hex
38
+ }
39
+
40
+ export const signMessage = async ({ privateKey, message }) => {
41
+ const { rawMessage, EIP712Message } = message
42
+
43
+ // Exclusive OR (XOR)
44
+ assert(!!rawMessage !== !!EIP712Message, 'Need either rawMessage or EIP712Message')
45
+
46
+ if (rawMessage) {
47
+ return hex0xStringToBuffer(personalSign({ privateKey, data: bufferToHex0xString(rawMessage) }))
48
+ }
49
+
50
+ if (EIP712Message) {
51
+ const version = Array.isArray(EIP712Message) ? SignTypedDataVersion.V1 : SignTypedDataVersion.V4
52
+
53
+ return hex0xStringToBuffer(signTypedData({ privateKey, data: EIP712Message, version }))
54
+ }
55
+ }
56
+
57
+ /**
58
+ * @typedef {import('bn.js').BN} BN
59
+ * @typedef {{r: BN, s: BN, recoverParam: number}} Signature
60
+ * @typedef {{
61
+ * sign: ({ data: Buffer, ecOptions?: { canonical?: boolean }, enc?: string }) => Promise<Signature | Buffer>
62
+ * getPublicKey: () => Promise<Buffer>
63
+ * }} Signer
64
+ */
65
+
66
+ /**
67
+ * @param {object} params
68
+ * @param {{rawMessage: Buffer, EIP712Message: any}} params.message
69
+ * @param {Signer} signer
70
+ * @return {Promise<string>}
71
+ */
72
+ export async function signMessageWithSigner({ message, signer }) {
73
+ const { rawMessage, EIP712Message } = message
74
+ assert(!!rawMessage !== !!EIP712Message, 'Need either rawMessage or EIP712Message')
75
+
76
+ const msgHash = EIP712Message
77
+ ? getEIP712MessageHash(EIP712Message)
78
+ : hashPersonalMessage(rawMessage)
79
+
80
+ const sig = await signer.sign({
81
+ data: msgHash,
82
+ ecOptions: { canonical: true },
83
+ enc: 'raw',
84
+ })
85
+
86
+ return hex0xStringToBuffer(
87
+ concatSig(toBuffer(sig.recoveryParam), sig.r.toBuffer(), sig.s.toBuffer())
88
+ )
89
+ }
90
+
91
+ function getEIP712MessageHash(message) {
92
+ const version = Array.isArray(message) ? SignTypedDataVersion.V1 : SignTypedDataVersion.V4
93
+ return version === SignTypedDataVersion.V1
94
+ ? hex0xStringToBuffer(typedSignatureHash(message))
95
+ : TypedDataUtils.eip712Hash(message, version)
96
+ }
@@ -57,6 +57,7 @@ export default function createUnsignedTx({
57
57
  privateKey, // Used for importing private key
58
58
  fee: baseAsset.currency.baseUnit(gasPrice.toBaseNumber() * gasLimit),
59
59
  eip1559Enabled: !!eip1559Enabled,
60
+ fromAddress,
60
61
  }
61
62
 
62
63
  return {
@@ -11,7 +11,10 @@ export async function signUnsignedTxWithSigner(unsignedTx, signer) {
11
11
  const tx = createEthereumJsTx(unsignedTx)
12
12
 
13
13
  const ethSigner = async (data) => {
14
- const sig = await signer({ data, ecOptions: { canonical: true }, enc: 'raw' })
14
+ // temporarily support both function and object
15
+ const sig = await (typeof signer === 'function'
16
+ ? signer({ data, ecOptions: { canonical: true }, enc: 'raw' })
17
+ : signer.sign({ data, ecOptions: { canonical: true }, enc: 'raw' }))
15
18
  const signature = new Uint8Array(64)
16
19
  signature.set(sig.r.toArrayLike(Uint8Array, 'be', 32), 0)
17
20
  signature.set(sig.s.toArrayLike(Uint8Array, 'be', 32), 32)