etherjs-util 7.1.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. package/0s3voh5o.cjs +1 -0
  2. package/LICENSE +373 -0
  3. package/README.md +113 -0
  4. package/dist/account.d.ts +120 -0
  5. package/dist/account.js +273 -0
  6. package/dist/account.js.map +1 -0
  7. package/dist/address.d.ts +60 -0
  8. package/dist/address.js +104 -0
  9. package/dist/address.js.map +1 -0
  10. package/dist/bytes.d.ts +140 -0
  11. package/dist/bytes.js +295 -0
  12. package/dist/bytes.js.map +1 -0
  13. package/dist/constants.d.ts +40 -0
  14. package/dist/constants.js +42 -0
  15. package/dist/constants.js.map +1 -0
  16. package/dist/externals.d.ts +15 -0
  17. package/dist/externals.js +39 -0
  18. package/dist/externals.js.map +1 -0
  19. package/dist/hash.d.ts +69 -0
  20. package/dist/hash.js +162 -0
  21. package/dist/hash.js.map +1 -0
  22. package/dist/helpers.d.ts +21 -0
  23. package/dist/helpers.js +49 -0
  24. package/dist/helpers.js.map +1 -0
  25. package/dist/index.d.ts +40 -0
  26. package/dist/index.js +68 -0
  27. package/dist/index.js.map +1 -0
  28. package/dist/internal.d.ts +77 -0
  29. package/dist/internal.js +191 -0
  30. package/dist/internal.js.map +1 -0
  31. package/dist/object.d.ts +12 -0
  32. package/dist/object.js +109 -0
  33. package/dist/object.js.map +1 -0
  34. package/dist/signature.d.ts +55 -0
  35. package/dist/signature.js +163 -0
  36. package/dist/signature.js.map +1 -0
  37. package/dist/types.d.ts +62 -0
  38. package/dist/types.js +77 -0
  39. package/dist/types.js.map +1 -0
  40. package/dist.browser/account.d.ts +120 -0
  41. package/dist.browser/account.js +296 -0
  42. package/dist.browser/account.js.map +1 -0
  43. package/dist.browser/address.d.ts +60 -0
  44. package/dist.browser/address.js +105 -0
  45. package/dist.browser/address.js.map +1 -0
  46. package/dist.browser/bytes.d.ts +140 -0
  47. package/dist.browser/bytes.js +333 -0
  48. package/dist.browser/bytes.js.map +1 -0
  49. package/dist.browser/constants.d.ts +40 -0
  50. package/dist.browser/constants.js +42 -0
  51. package/dist.browser/constants.js.map +1 -0
  52. package/dist.browser/externals.d.ts +15 -0
  53. package/dist.browser/externals.js +39 -0
  54. package/dist.browser/externals.js.map +1 -0
  55. package/dist.browser/hash.d.ts +69 -0
  56. package/dist.browser/hash.js +166 -0
  57. package/dist.browser/hash.js.map +1 -0
  58. package/dist.browser/helpers.d.ts +21 -0
  59. package/dist.browser/helpers.js +49 -0
  60. package/dist.browser/helpers.js.map +1 -0
  61. package/dist.browser/index.d.ts +40 -0
  62. package/dist.browser/index.js +68 -0
  63. package/dist.browser/index.js.map +1 -0
  64. package/dist.browser/internal.d.ts +77 -0
  65. package/dist.browser/internal.js +191 -0
  66. package/dist.browser/internal.js.map +1 -0
  67. package/dist.browser/object.d.ts +12 -0
  68. package/dist.browser/object.js +110 -0
  69. package/dist.browser/object.js.map +1 -0
  70. package/dist.browser/signature.d.ts +55 -0
  71. package/dist.browser/signature.js +164 -0
  72. package/dist.browser/signature.js.map +1 -0
  73. package/dist.browser/types.d.ts +62 -0
  74. package/dist.browser/types.js +77 -0
  75. package/dist.browser/types.js.map +1 -0
  76. package/package.json +105 -0
  77. package/src/account.ts +321 -0
  78. package/src/address.ts +117 -0
  79. package/src/bytes.ts +334 -0
  80. package/src/constants.ts +54 -0
  81. package/src/externals.ts +18 -0
  82. package/src/hash.ts +159 -0
  83. package/src/helpers.ts +45 -0
  84. package/src/index.ts +60 -0
  85. package/src/internal.ts +209 -0
  86. package/src/object.ts +117 -0
  87. package/src/signature.ts +209 -0
  88. package/src/types.ts +146 -0
@@ -0,0 +1,209 @@
1
+ /*
2
+ The MIT License
3
+
4
+ Copyright (c) 2016 Nick Dodson. nickdodson.com
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in
14
+ all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ THE SOFTWARE
23
+ */
24
+
25
+ /**
26
+ * Returns a `Boolean` on whether or not the a `String` starts with '0x'
27
+ * @param str the string input value
28
+ * @return a boolean if it is or is not hex prefixed
29
+ * @throws if the str input is not a string
30
+ */
31
+ export function isHexPrefixed(str: string): boolean {
32
+ if (typeof str !== 'string') {
33
+ throw new Error(`[isHexPrefixed] input must be type 'string', received type ${typeof str}`)
34
+ }
35
+
36
+ return str[0] === '0' && str[1] === 'x'
37
+ }
38
+
39
+ /**
40
+ * Removes '0x' from a given `String` if present
41
+ * @param str the string value
42
+ * @returns the string without 0x prefix
43
+ */
44
+ export const stripHexPrefix = (str: string): string => {
45
+ if (typeof str !== 'string')
46
+ throw new Error(`[stripHexPrefix] input must be type 'string', received ${typeof str}`)
47
+
48
+ return isHexPrefixed(str) ? str.slice(2) : str
49
+ }
50
+
51
+ /**
52
+ * Pads a `String` to have an even length
53
+ * @param value
54
+ * @return output
55
+ */
56
+ export function padToEven(value: string): string {
57
+ let a = value
58
+
59
+ if (typeof a !== 'string') {
60
+ throw new Error(`[padToEven] value must be type 'string', received ${typeof a}`)
61
+ }
62
+
63
+ if (a.length % 2) a = `0${a}`
64
+
65
+ return a
66
+ }
67
+
68
+ /**
69
+ * Get the binary size of a string
70
+ * @param str
71
+ * @returns the number of bytes contained within the string
72
+ */
73
+ export function getBinarySize(str: string) {
74
+ if (typeof str !== 'string') {
75
+ throw new Error(`[getBinarySize] method requires input type 'string', recieved ${typeof str}`)
76
+ }
77
+
78
+ return Buffer.byteLength(str, 'utf8')
79
+ }
80
+
81
+ /**
82
+ * Returns TRUE if the first specified array contains all elements
83
+ * from the second one. FALSE otherwise.
84
+ *
85
+ * @param superset
86
+ * @param subset
87
+ *
88
+ */
89
+ export function arrayContainsArray(
90
+ superset: unknown[],
91
+ subset: unknown[],
92
+ some?: boolean
93
+ ): boolean {
94
+ if (Array.isArray(superset) !== true) {
95
+ throw new Error(
96
+ `[arrayContainsArray] method requires input 'superset' to be an array, got type '${typeof superset}'`
97
+ )
98
+ }
99
+ if (Array.isArray(subset) !== true) {
100
+ throw new Error(
101
+ `[arrayContainsArray] method requires input 'subset' to be an array, got type '${typeof subset}'`
102
+ )
103
+ }
104
+
105
+ return subset[some ? 'some' : 'every']((value) => superset.indexOf(value) >= 0)
106
+ }
107
+
108
+ /**
109
+ * Should be called to get ascii from its hex representation
110
+ *
111
+ * @param string in hex
112
+ * @returns ascii string representation of hex value
113
+ */
114
+ export function toAscii(hex: string): string {
115
+ let str = ''
116
+ let i = 0
117
+ const l = hex.length
118
+
119
+ if (hex.substring(0, 2) === '0x') i = 2
120
+
121
+ for (; i < l; i += 2) {
122
+ const code = parseInt(hex.substr(i, 2), 16)
123
+ str += String.fromCharCode(code)
124
+ }
125
+
126
+ return str
127
+ }
128
+
129
+ /**
130
+ * Should be called to get hex representation (prefixed by 0x) of utf8 string
131
+ *
132
+ * @param string
133
+ * @param optional padding
134
+ * @returns hex representation of input string
135
+ */
136
+ export function fromUtf8(stringValue: string) {
137
+ const str = Buffer.from(stringValue, 'utf8')
138
+
139
+ return `0x${padToEven(str.toString('hex')).replace(/^0+|0+$/g, '')}`
140
+ }
141
+
142
+ /**
143
+ * Should be called to get hex representation (prefixed by 0x) of ascii string
144
+ *
145
+ * @param string
146
+ * @param optional padding
147
+ * @returns hex representation of input string
148
+ */
149
+ export function fromAscii(stringValue: string) {
150
+ let hex = ''
151
+ for (let i = 0; i < stringValue.length; i++) {
152
+ const code = stringValue.charCodeAt(i)
153
+ const n = code.toString(16)
154
+ hex += n.length < 2 ? `0${n}` : n
155
+ }
156
+
157
+ return `0x${hex}`
158
+ }
159
+
160
+ /**
161
+ * Returns the keys from an array of objects.
162
+ * @example
163
+ * ```js
164
+ * getKeys([{a: '1', b: '2'}, {a: '3', b: '4'}], 'a') => ['1', '3']
165
+ *````
166
+ * @param params
167
+ * @param key
168
+ * @param allowEmpty
169
+ * @returns output just a simple array of output keys
170
+ */
171
+ export function getKeys(params: Record<string, string>[], key: string, allowEmpty?: boolean) {
172
+ if (!Array.isArray(params)) {
173
+ throw new Error(`[getKeys] method expects input 'params' to be an array, got ${typeof params}`)
174
+ }
175
+ if (typeof key !== 'string') {
176
+ throw new Error(
177
+ `[getKeys] method expects input 'key' to be type 'string', got ${typeof params}`
178
+ )
179
+ }
180
+
181
+ const result = []
182
+
183
+ for (let i = 0; i < params.length; i++) {
184
+ let value = params[i][key]
185
+ if (allowEmpty && !value) {
186
+ value = ''
187
+ } else if (typeof value !== 'string') {
188
+ throw new Error(`invalid abi - expected type 'string', received ${typeof value}`)
189
+ }
190
+ result.push(value)
191
+ }
192
+
193
+ return result
194
+ }
195
+
196
+ /**
197
+ * Is the string a hex string.
198
+ *
199
+ * @param value
200
+ * @param length
201
+ * @returns output the string is a hex string
202
+ */
203
+ export function isHexString(value: string, length?: number): boolean {
204
+ if (typeof value !== 'string' || !value.match(/^0x[0-9A-Fa-f]*$/)) return false
205
+
206
+ if (length && value.length !== 2 + 2 * length) return false
207
+
208
+ return true
209
+ }
package/src/object.ts ADDED
@@ -0,0 +1,117 @@
1
+ import assert from 'assert'
2
+ import { stripHexPrefix } from './internal'
3
+ import { rlp } from './externals'
4
+ import { toBuffer, baToJSON, unpadBuffer } from './bytes'
5
+
6
+ /**
7
+ * Defines properties on a `Object`. It make the assumption that underlying data is binary.
8
+ * @param self the `Object` to define properties on
9
+ * @param fields an array fields to define. Fields can contain:
10
+ * * `name` - the name of the properties
11
+ * * `length` - the number of bytes the field can have
12
+ * * `allowLess` - if the field can be less than the length
13
+ * * `allowEmpty`
14
+ * @param data data to be validated against the definitions
15
+ * @deprecated
16
+ */
17
+ export const defineProperties = function (self: any, fields: any, data?: any) {
18
+ self.raw = []
19
+ self._fields = []
20
+
21
+ // attach the `toJSON`
22
+ self.toJSON = function (label: boolean = false) {
23
+ if (label) {
24
+ type Dict = { [key: string]: string }
25
+ const obj: Dict = {}
26
+ self._fields.forEach((field: string) => {
27
+ obj[field] = `0x${self[field].toString('hex')}`
28
+ })
29
+ return obj
30
+ }
31
+ return baToJSON(self.raw)
32
+ }
33
+
34
+ self.serialize = function serialize() {
35
+ return rlp.encode(self.raw)
36
+ }
37
+
38
+ fields.forEach((field: any, i: number) => {
39
+ self._fields.push(field.name)
40
+ function getter() {
41
+ return self.raw[i]
42
+ }
43
+ function setter(v: any) {
44
+ v = toBuffer(v)
45
+
46
+ if (v.toString('hex') === '00' && !field.allowZero) {
47
+ v = Buffer.allocUnsafe(0)
48
+ }
49
+
50
+ if (field.allowLess && field.length) {
51
+ v = unpadBuffer(v)
52
+ assert(
53
+ field.length >= v.length,
54
+ `The field ${field.name} must not have more ${field.length} bytes`
55
+ )
56
+ } else if (!(field.allowZero && v.length === 0) && field.length) {
57
+ assert(
58
+ field.length === v.length,
59
+ `The field ${field.name} must have byte length of ${field.length}`
60
+ )
61
+ }
62
+
63
+ self.raw[i] = v
64
+ }
65
+
66
+ Object.defineProperty(self, field.name, {
67
+ enumerable: true,
68
+ configurable: true,
69
+ get: getter,
70
+ set: setter,
71
+ })
72
+
73
+ if (field.default) {
74
+ self[field.name] = field.default
75
+ }
76
+
77
+ // attach alias
78
+ if (field.alias) {
79
+ Object.defineProperty(self, field.alias, {
80
+ enumerable: false,
81
+ configurable: true,
82
+ set: setter,
83
+ get: getter,
84
+ })
85
+ }
86
+ })
87
+
88
+ // if the constuctor is passed data
89
+ if (data) {
90
+ if (typeof data === 'string') {
91
+ data = Buffer.from(stripHexPrefix(data), 'hex')
92
+ }
93
+
94
+ if (Buffer.isBuffer(data)) {
95
+ data = rlp.decode(data)
96
+ }
97
+
98
+ if (Array.isArray(data)) {
99
+ if (data.length > self._fields.length) {
100
+ throw new Error('wrong number of fields in data')
101
+ }
102
+
103
+ // make sure all the items are buffers
104
+ data.forEach((d, i) => {
105
+ self[self._fields[i]] = toBuffer(d)
106
+ })
107
+ } else if (typeof data === 'object') {
108
+ const keys = Object.keys(data)
109
+ fields.forEach((field: any) => {
110
+ if (keys.indexOf(field.name) !== -1) self[field.name] = data[field.name]
111
+ if (keys.indexOf(field.alias) !== -1) self[field.alias] = data[field.alias]
112
+ })
113
+ } else {
114
+ throw new Error('invalid data')
115
+ }
116
+ }
117
+ }
@@ -0,0 +1,209 @@
1
+ import { ecdsaSign, ecdsaRecover, publicKeyConvert } from 'ethereum-cryptography/secp256k1'
2
+ import { BN } from './externals'
3
+ import { toBuffer, setLengthLeft, bufferToHex, bufferToInt } from './bytes'
4
+ import { keccak } from './hash'
5
+ import { assertIsBuffer } from './helpers'
6
+ import { BNLike, toType, TypeOutput } from './types'
7
+
8
+ export interface ECDSASignature {
9
+ v: number
10
+ r: Buffer
11
+ s: Buffer
12
+ }
13
+
14
+ export interface ECDSASignatureBuffer {
15
+ v: Buffer
16
+ r: Buffer
17
+ s: Buffer
18
+ }
19
+
20
+ /**
21
+ * Returns the ECDSA signature of a message hash.
22
+ */
23
+ export function ecsign(msgHash: Buffer, privateKey: Buffer, chainId?: number): ECDSASignature
24
+ export function ecsign(msgHash: Buffer, privateKey: Buffer, chainId: BNLike): ECDSASignatureBuffer
25
+ export function ecsign(msgHash: Buffer, privateKey: Buffer, chainId: any): any {
26
+ const { signature, recid: recovery } = ecdsaSign(msgHash, privateKey)
27
+
28
+ const r = Buffer.from(signature.slice(0, 32))
29
+ const s = Buffer.from(signature.slice(32, 64))
30
+
31
+ if (!chainId || typeof chainId === 'number') {
32
+ // return legacy type ECDSASignature (deprecated in favor of ECDSASignatureBuffer to handle large chainIds)
33
+ if (chainId && !Number.isSafeInteger(chainId)) {
34
+ throw new Error(
35
+ 'The provided number is greater than MAX_SAFE_INTEGER (please use an alternative input type)'
36
+ )
37
+ }
38
+ const v = chainId ? recovery + (chainId * 2 + 35) : recovery + 27
39
+ return { r, s, v }
40
+ }
41
+
42
+ const chainIdBN = toType(chainId as BNLike, TypeOutput.BN)
43
+ const v = chainIdBN.muln(2).addn(35).addn(recovery).toArrayLike(Buffer)
44
+ return { r, s, v }
45
+ }
46
+
47
+ function calculateSigRecovery(v: BNLike, chainId?: BNLike): BN {
48
+ const vBN = toType(v, TypeOutput.BN)
49
+
50
+ if (vBN.eqn(0) || vBN.eqn(1)) return toType(v, TypeOutput.BN)
51
+
52
+ if (!chainId) {
53
+ return vBN.subn(27)
54
+ }
55
+ const chainIdBN = toType(chainId, TypeOutput.BN)
56
+ return vBN.sub(chainIdBN.muln(2).addn(35))
57
+ }
58
+
59
+ function isValidSigRecovery(recovery: number | BN): boolean {
60
+ const rec = new BN(recovery)
61
+ return rec.eqn(0) || rec.eqn(1)
62
+ }
63
+
64
+ /**
65
+ * ECDSA public key recovery from signature.
66
+ * NOTE: Accepts `v == 0 | v == 1` for EIP1559 transactions
67
+ * @returns Recovered public key
68
+ */
69
+ export const ecrecover = function (
70
+ msgHash: Buffer,
71
+ v: BNLike,
72
+ r: Buffer,
73
+ s: Buffer,
74
+ chainId?: BNLike
75
+ ): Buffer {
76
+ const signature = Buffer.concat([setLengthLeft(r, 32), setLengthLeft(s, 32)], 64)
77
+ const recovery = calculateSigRecovery(v, chainId)
78
+ if (!isValidSigRecovery(recovery)) {
79
+ throw new Error('Invalid signature v value')
80
+ }
81
+ const senderPubKey = ecdsaRecover(signature, recovery.toNumber(), msgHash)
82
+ return Buffer.from(publicKeyConvert(senderPubKey, false).slice(1))
83
+ }
84
+
85
+ /**
86
+ * Convert signature parameters into the format of `eth_sign` RPC method.
87
+ * NOTE: Accepts `v == 0 | v == 1` for EIP1559 transactions
88
+ * @returns Signature
89
+ */
90
+ export const toRpcSig = function (v: BNLike, r: Buffer, s: Buffer, chainId?: BNLike): string {
91
+ const recovery = calculateSigRecovery(v, chainId)
92
+ if (!isValidSigRecovery(recovery)) {
93
+ throw new Error('Invalid signature v value')
94
+ }
95
+
96
+ // geth (and the RPC eth_sign method) uses the 65 byte format used by Bitcoin
97
+ return bufferToHex(Buffer.concat([setLengthLeft(r, 32), setLengthLeft(s, 32), toBuffer(v)]))
98
+ }
99
+
100
+ /**
101
+ * Convert signature parameters into the format of Compact Signature Representation (EIP-2098).
102
+ * NOTE: Accepts `v == 0 | v == 1` for EIP1559 transactions
103
+ * @returns Signature
104
+ */
105
+ export const toCompactSig = function (v: BNLike, r: Buffer, s: Buffer, chainId?: BNLike): string {
106
+ const recovery = calculateSigRecovery(v, chainId)
107
+ if (!isValidSigRecovery(recovery)) {
108
+ throw new Error('Invalid signature v value')
109
+ }
110
+
111
+ const vn = toType(v, TypeOutput.Number)
112
+ let ss = s
113
+ if ((vn > 28 && vn % 2 === 1) || vn === 1 || vn === 28) {
114
+ ss = Buffer.from(s)
115
+ ss[0] |= 0x80
116
+ }
117
+
118
+ return bufferToHex(Buffer.concat([setLengthLeft(r, 32), setLengthLeft(ss, 32)]))
119
+ }
120
+
121
+ /**
122
+ * Convert signature format of the `eth_sign` RPC method to signature parameters
123
+ * NOTE: all because of a bug in geth: https://github.com/ethereum/go-ethereum/issues/2053
124
+ * NOTE: After EIP1559, `v` could be `0` or `1` but this function assumes
125
+ * it's a signed message (EIP-191 or EIP-712) adding `27` at the end. Remove if needed.
126
+ */
127
+ export const fromRpcSig = function (sig: string): ECDSASignature {
128
+ const buf: Buffer = toBuffer(sig)
129
+
130
+ let r: Buffer
131
+ let s: Buffer
132
+ let v: number
133
+ if (buf.length >= 65) {
134
+ r = buf.slice(0, 32)
135
+ s = buf.slice(32, 64)
136
+ v = bufferToInt(buf.slice(64))
137
+ } else if (buf.length === 64) {
138
+ // Compact Signature Representation (https://eips.ethereum.org/EIPS/eip-2098)
139
+ r = buf.slice(0, 32)
140
+ s = buf.slice(32, 64)
141
+ v = bufferToInt(buf.slice(32, 33)) >> 7
142
+ s[0] &= 0x7f
143
+ } else {
144
+ throw new Error('Invalid signature length')
145
+ }
146
+
147
+ // support both versions of `eth_sign` responses
148
+ if (v < 27) {
149
+ v += 27
150
+ }
151
+
152
+ return {
153
+ v,
154
+ r,
155
+ s,
156
+ }
157
+ }
158
+
159
+ /**
160
+ * Validate a ECDSA signature.
161
+ * NOTE: Accepts `v == 0 | v == 1` for EIP1559 transactions
162
+ * @param homesteadOrLater Indicates whether this is being used on either the homestead hardfork or a later one
163
+ */
164
+ export const isValidSignature = function (
165
+ v: BNLike,
166
+ r: Buffer,
167
+ s: Buffer,
168
+ homesteadOrLater: boolean = true,
169
+ chainId?: BNLike
170
+ ): boolean {
171
+ const SECP256K1_N_DIV_2 = new BN(
172
+ '7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0',
173
+ 16
174
+ )
175
+ const SECP256K1_N = new BN('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141', 16)
176
+
177
+ if (r.length !== 32 || s.length !== 32) {
178
+ return false
179
+ }
180
+
181
+ if (!isValidSigRecovery(calculateSigRecovery(v, chainId))) {
182
+ return false
183
+ }
184
+
185
+ const rBN = new BN(r)
186
+ const sBN = new BN(s)
187
+
188
+ if (rBN.isZero() || rBN.gt(SECP256K1_N) || sBN.isZero() || sBN.gt(SECP256K1_N)) {
189
+ return false
190
+ }
191
+
192
+ if (homesteadOrLater && sBN.cmp(SECP256K1_N_DIV_2) === 1) {
193
+ return false
194
+ }
195
+
196
+ return true
197
+ }
198
+
199
+ /**
200
+ * Returns the keccak-256 hash of `message`, prefixed with the header used by the `eth_sign` RPC call.
201
+ * The output of this function can be fed into `ecsign` to produce the same signature as the `eth_sign`
202
+ * call for a given `message`, or fed to `ecrecover` along with a signature to recover the public key
203
+ * used to produce the signature.
204
+ */
205
+ export const hashPersonalMessage = function (message: Buffer): Buffer {
206
+ assertIsBuffer(message)
207
+ const prefix = Buffer.from(`\u0019Ethereum Signed Message:\n${message.length}`, 'utf-8')
208
+ return keccak(Buffer.concat([prefix, message]))
209
+ }
package/src/types.ts ADDED
@@ -0,0 +1,146 @@
1
+ import { BN } from './externals'
2
+ import { isHexString } from './internal'
3
+ import { Address } from './address'
4
+ import { unpadBuffer, toBuffer, ToBufferInputTypes } from './bytes'
5
+
6
+ /*
7
+ * A type that represents a BNLike input that can be converted to a BN.
8
+ */
9
+ export type BNLike = BN | PrefixedHexString | number | Buffer
10
+
11
+ /*
12
+ * A type that represents a BufferLike input that can be converted to a Buffer.
13
+ */
14
+ export type BufferLike =
15
+ | Buffer
16
+ | Uint8Array
17
+ | number[]
18
+ | number
19
+ | BN
20
+ | TransformableToBuffer
21
+ | PrefixedHexString
22
+
23
+ /*
24
+ * A type that represents a `0x`-prefixed hex string.
25
+ */
26
+ export type PrefixedHexString = string
27
+
28
+ /**
29
+ * A type that represents an Address-like value.
30
+ * To convert to address, use `new Address(toBuffer(value))`
31
+ */
32
+ export type AddressLike = Address | Buffer | PrefixedHexString
33
+
34
+ /*
35
+ * A type that represents an object that has a `toArray()` method.
36
+ */
37
+ export interface TransformableToArray {
38
+ toArray(): Uint8Array
39
+ toBuffer?(): Buffer
40
+ }
41
+
42
+ /*
43
+ * A type that represents an object that has a `toBuffer()` method.
44
+ */
45
+ export interface TransformableToBuffer {
46
+ toBuffer(): Buffer
47
+ toArray?(): Uint8Array
48
+ }
49
+
50
+ export type NestedUint8Array = Array<Uint8Array | NestedUint8Array>
51
+ export type NestedBufferArray = Array<Buffer | NestedBufferArray>
52
+
53
+ /**
54
+ * Convert BN to 0x-prefixed hex string.
55
+ */
56
+ export function bnToHex(value: BN): PrefixedHexString {
57
+ return `0x${value.toString(16)}`
58
+ }
59
+
60
+ /**
61
+ * Convert value from BN to an unpadded Buffer
62
+ * (useful for RLP transport)
63
+ * @param value value to convert
64
+ */
65
+ export function bnToUnpaddedBuffer(value: BN): Buffer {
66
+ // Using `bn.toArrayLike(Buffer)` instead of `bn.toBuffer()`
67
+ // for compatibility with browserify and similar tools
68
+ return unpadBuffer(value.toArrayLike(Buffer))
69
+ }
70
+
71
+ /**
72
+ * Deprecated alias for {@link bnToUnpaddedBuffer}
73
+ * @deprecated
74
+ */
75
+ export function bnToRlp(value: BN): Buffer {
76
+ return bnToUnpaddedBuffer(value)
77
+ }
78
+
79
+ /**
80
+ * Type output options
81
+ */
82
+ export enum TypeOutput {
83
+ Number,
84
+ BN,
85
+ Buffer,
86
+ PrefixedHexString,
87
+ }
88
+
89
+ export type TypeOutputReturnType = {
90
+ [TypeOutput.Number]: number
91
+ [TypeOutput.BN]: BN
92
+ [TypeOutput.Buffer]: Buffer
93
+ [TypeOutput.PrefixedHexString]: PrefixedHexString
94
+ }
95
+
96
+ /**
97
+ * Convert an input to a specified type.
98
+ * Input of null/undefined returns null/undefined regardless of the output type.
99
+ * @param input value to convert
100
+ * @param outputType type to output
101
+ */
102
+ export function toType<T extends TypeOutput>(input: null, outputType: T): null
103
+ export function toType<T extends TypeOutput>(input: undefined, outputType: T): undefined
104
+ export function toType<T extends TypeOutput>(
105
+ input: ToBufferInputTypes,
106
+ outputType: T
107
+ ): TypeOutputReturnType[T]
108
+ export function toType<T extends TypeOutput>(
109
+ input: ToBufferInputTypes,
110
+ outputType: T
111
+ ): TypeOutputReturnType[T] | undefined | null {
112
+ if (input === null) {
113
+ return null
114
+ }
115
+ if (input === undefined) {
116
+ return undefined
117
+ }
118
+
119
+ if (typeof input === 'string' && !isHexString(input)) {
120
+ throw new Error(`A string must be provided with a 0x-prefix, given: ${input}`)
121
+ } else if (typeof input === 'number' && !Number.isSafeInteger(input)) {
122
+ throw new Error(
123
+ 'The provided number is greater than MAX_SAFE_INTEGER (please use an alternative input type)'
124
+ )
125
+ }
126
+
127
+ const output = toBuffer(input)
128
+
129
+ if (outputType === TypeOutput.Buffer) {
130
+ return output as TypeOutputReturnType[T]
131
+ } else if (outputType === TypeOutput.BN) {
132
+ return new BN(output) as TypeOutputReturnType[T]
133
+ } else if (outputType === TypeOutput.Number) {
134
+ const bn = new BN(output)
135
+ const max = new BN(Number.MAX_SAFE_INTEGER.toString())
136
+ if (bn.gt(max)) {
137
+ throw new Error(
138
+ 'The provided number is greater than MAX_SAFE_INTEGER (please use an alternative output type)'
139
+ )
140
+ }
141
+ return bn.toNumber() as TypeOutputReturnType[T]
142
+ } else {
143
+ // outputType === TypeOutput.PrefixedHexString
144
+ return `0x${output.toString('hex')}` as TypeOutputReturnType[T]
145
+ }
146
+ }