starknet 4.17.0 → 4.18.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/CHANGELOG.md +20 -0
- package/README.md +2 -10
- package/dist/index.d.ts +27 -9
- package/dist/index.global.js +30 -13
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +30 -13
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +30 -13
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -1
- package/.babelrc +0 -6
- package/.commitlintrc +0 -22
- package/.eslintignore +0 -2
- package/.eslintrc +0 -28
- package/.prettierrc +0 -6
- package/.releaserc +0 -28
- package/CODE_OF_CONDUCT.md +0 -128
- package/CONTRIBUTING.md +0 -52
- package/__mocks__/Account.json +0 -25486
- package/__mocks__/ERC20.json +0 -40027
- package/__mocks__/TestDapp.json +0 -12962
- package/__mocks__/contract.json +0 -33191
- package/__mocks__/l1l2_compiled.json +0 -10107
- package/__mocks__/multicall.json +0 -8139
- package/__mocks__/naming_compiled.json +0 -53283
- package/__mocks__/starknetId_compiled.json +0 -44703
- package/__mocks__/typedDataExample.json +0 -35
- package/__mocks__/typedDataSessionExample.json +0 -42
- package/__mocks__/typedDataStructArrayExample.json +0 -44
- package/__tests__/account.test.ts +0 -345
- package/__tests__/contract.test.ts +0 -249
- package/__tests__/defaultProvider.test.ts +0 -177
- package/__tests__/fixtures.ts +0 -84
- package/__tests__/jest.setup.ts +0 -30
- package/__tests__/rpcProvider.test.ts +0 -132
- package/__tests__/sequencerProvider.test.ts +0 -123
- package/__tests__/utils/__snapshots__/ellipticalCurve.test.ts.snap +0 -5
- package/__tests__/utils/__snapshots__/utils.browser.test.ts.snap +0 -5
- package/__tests__/utils/__snapshots__/utils.test.ts.snap +0 -5
- package/__tests__/utils/address.test.ts +0 -45
- package/__tests__/utils/ellipticalCurve.test.ts +0 -91
- package/__tests__/utils/merkle.test.ts +0 -256
- package/__tests__/utils/shortString.test.ts +0 -22
- package/__tests__/utils/starknetId.test.ts +0 -53
- package/__tests__/utils/transactionHash.test.ts +0 -17
- package/__tests__/utils/typedData.test.ts +0 -223
- package/__tests__/utils/uint256.test.ts +0 -32
- package/__tests__/utils/utils.browser.test.ts +0 -29
- package/__tests__/utils/utils.test.ts +0 -141
- package/img/logo.svg +0 -17
- package/index.d.ts +0 -2683
- package/index.global.js +0 -23192
- package/index.global.js.map +0 -1
- package/index.js +0 -4910
- package/index.js.map +0 -1
- package/index.mjs +0 -4852
- package/index.mjs.map +0 -1
- package/src/account/default.ts +0 -501
- package/src/account/index.ts +0 -2
- package/src/account/interface.ts +0 -309
- package/src/constants.ts +0 -2065
- package/src/contract/contractFactory.ts +0 -88
- package/src/contract/default.ts +0 -425
- package/src/contract/index.ts +0 -3
- package/src/contract/interface.ts +0 -106
- package/src/index.ts +0 -26
- package/src/provider/default.ts +0 -187
- package/src/provider/errors.ts +0 -14
- package/src/provider/index.ts +0 -9
- package/src/provider/interface.ts +0 -281
- package/src/provider/rpc.ts +0 -482
- package/src/provider/sequencer.ts +0 -523
- package/src/provider/utils.ts +0 -100
- package/src/signer/default.ts +0 -99
- package/src/signer/index.ts +0 -2
- package/src/signer/interface.ts +0 -77
- package/src/types/account.ts +0 -43
- package/src/types/api/index.ts +0 -10
- package/src/types/api/openrpc.ts +0 -607
- package/src/types/api/rpc.ts +0 -45
- package/src/types/api/sequencer.ts +0 -369
- package/src/types/contract.ts +0 -5
- package/src/types/index.ts +0 -8
- package/src/types/lib.ts +0 -143
- package/src/types/provider.ts +0 -134
- package/src/types/signer.ts +0 -24
- package/src/utils/address.ts +0 -44
- package/src/utils/calldata.ts +0 -250
- package/src/utils/ellipticCurve.ts +0 -120
- package/src/utils/encode.ts +0 -66
- package/src/utils/events.ts +0 -32
- package/src/utils/fetchPonyfill.ts +0 -5
- package/src/utils/hash.ts +0 -235
- package/src/utils/json.ts +0 -15
- package/src/utils/merkle.ts +0 -69
- package/src/utils/number.ts +0 -98
- package/src/utils/provider.ts +0 -28
- package/src/utils/responseParser/index.ts +0 -28
- package/src/utils/responseParser/rpc.ts +0 -70
- package/src/utils/responseParser/sequencer.ts +0 -135
- package/src/utils/shortString.ts +0 -21
- package/src/utils/stark.ts +0 -57
- package/src/utils/starknetId.ts +0 -116
- package/src/utils/transaction.ts +0 -56
- package/src/utils/typedData/index.ts +0 -247
- package/src/utils/typedData/types.ts +0 -37
- package/src/utils/typedData/utils.ts +0 -16
- package/src/utils/uint256.ts +0 -32
- package/src/utils/url.ts +0 -53
- package/tsconfig.eslint.json +0 -4
- package/tsup.config.ts +0 -9
- package/www/README.md +0 -41
- package/www/babel.config.js +0 -3
- package/www/code-examples/account.js +0 -65
- package/www/code-examples/amm.js +0 -44
- package/www/code-examples/erc20.js +0 -13
- package/www/code-examples/package-lock.json +0 -336
- package/www/code-examples/package.json +0 -15
- package/www/docs/API/_category_.json +0 -5
- package/www/docs/API/account.md +0 -463
- package/www/docs/API/changelog.md +0 -15
- package/www/docs/API/contract.md +0 -135
- package/www/docs/API/contractFactory.md +0 -45
- package/www/docs/API/index.md +0 -3
- package/www/docs/API/provider.md +0 -725
- package/www/docs/API/signer.md +0 -105
- package/www/docs/API/utils.md +0 -374
- package/www/docusaurus.config.js +0 -130
- package/www/guides/account.md +0 -140
- package/www/guides/cra.md +0 -3
- package/www/guides/erc20.md +0 -163
- package/www/guides/intro.md +0 -63
- package/www/package-lock.json +0 -20405
- package/www/package.json +0 -43
- package/www/sidebars.js +0 -31
- package/www/src/components/HomepageFeatures/index.tsx +0 -67
- package/www/src/components/HomepageFeatures/styles.module.css +0 -10
- package/www/src/css/custom.css +0 -39
- package/www/src/pages/index.module.css +0 -23
- package/www/src/pages/index.tsx +0 -40
- package/www/src/pages/markdown-page.md +0 -7
- package/www/static/.nojekyll +0 -0
- package/www/static/img/docusaurus.png +0 -0
- package/www/static/img/favicon.ico +0 -0
- package/www/static/img/logo.svg +0 -17
- package/www/static/img/starknet-1.png +0 -0
- package/www/static/img/starknet-2.png +0 -0
- package/www/static/img/starknet-3.png +0 -0
- package/www/static/img/tutorial/docsVersionDropdown.png +0 -0
- package/www/static/img/tutorial/localeDropdown.png +0 -0
package/src/utils/address.ts
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
/* eslint-disable no-bitwise */
|
|
2
|
-
import { arrayify } from '@ethersproject/bytes';
|
|
3
|
-
|
|
4
|
-
import { MASK_251, ZERO } from '../constants';
|
|
5
|
-
import { addHexPrefix, removeHexPrefix } from './encode';
|
|
6
|
-
import { keccakBn } from './hash';
|
|
7
|
-
import { BigNumberish, assertInRange, toBN, toHex } from './number';
|
|
8
|
-
|
|
9
|
-
export function addAddressPadding(address: BigNumberish): string {
|
|
10
|
-
return addHexPrefix(removeHexPrefix(toHex(toBN(address))).padStart(64, '0'));
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export function validateAndParseAddress(address: BigNumberish): string {
|
|
14
|
-
assertInRange(address, ZERO, MASK_251, 'Starknet Address');
|
|
15
|
-
|
|
16
|
-
const result = addAddressPadding(address);
|
|
17
|
-
|
|
18
|
-
if (!result.match(/^(0x)?[0-9a-fA-F]{64}$/)) {
|
|
19
|
-
throw new Error('Invalid Address Format');
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
return result;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
// from https://github.com/ethers-io/ethers.js/blob/fc1e006575d59792fa97b4efb9ea2f8cca1944cf/packages/address/src.ts/index.ts#L12
|
|
26
|
-
export function getChecksumAddress(address: BigNumberish): string {
|
|
27
|
-
const chars = removeHexPrefix(validateAndParseAddress(address)).toLowerCase().split('');
|
|
28
|
-
const hashed = arrayify(keccakBn(address), { hexPad: 'left' }); // in case the hash is 251 bits (63 chars) we need to pad it to 64 chars without changing the number value ("left")
|
|
29
|
-
|
|
30
|
-
for (let i = 0; i < chars.length; i += 2) {
|
|
31
|
-
if (hashed[i >> 1] >> 4 >= 8) {
|
|
32
|
-
chars[i] = chars[i].toUpperCase();
|
|
33
|
-
}
|
|
34
|
-
if ((hashed[i >> 1] & 0x0f) >= 8) {
|
|
35
|
-
chars[i + 1] = chars[i + 1].toUpperCase();
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
return addHexPrefix(chars.join(''));
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export function validateChecksumAddress(address: string): boolean {
|
|
43
|
-
return getChecksumAddress(address) === address;
|
|
44
|
-
}
|
package/src/utils/calldata.ts
DELETED
|
@@ -1,250 +0,0 @@
|
|
|
1
|
-
import BN from 'bn.js';
|
|
2
|
-
import assert from 'minimalistic-assert';
|
|
3
|
-
|
|
4
|
-
import { Abi, AbiEntry, Calldata, FunctionAbi, ParsedStruct, StructAbi } from '../types';
|
|
5
|
-
import { BigNumberish, toFelt } from './number';
|
|
6
|
-
|
|
7
|
-
export class CheckCallData {
|
|
8
|
-
abi: Abi;
|
|
9
|
-
|
|
10
|
-
protected readonly structs: { [name: string]: StructAbi };
|
|
11
|
-
|
|
12
|
-
constructor(abi: Abi) {
|
|
13
|
-
this.abi = abi;
|
|
14
|
-
this.structs = abi
|
|
15
|
-
.filter((abiEntry) => abiEntry.type === 'struct')
|
|
16
|
-
.reduce(
|
|
17
|
-
(acc, abiEntry) => ({
|
|
18
|
-
...acc,
|
|
19
|
-
[abiEntry.name]: abiEntry,
|
|
20
|
-
}),
|
|
21
|
-
{}
|
|
22
|
-
);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Parse the calldata by using input fields from the abi for that method
|
|
27
|
-
*
|
|
28
|
-
* @param args - arguments passed the the method
|
|
29
|
-
* @param inputs - list of inputs(fields) that are in the abi
|
|
30
|
-
* @return {Calldata} - parsed arguments in format that contract is expecting
|
|
31
|
-
*/
|
|
32
|
-
public compileCalldata(args: Array<any>, inputs: AbiEntry[]): Calldata {
|
|
33
|
-
const argsIterator = args[Symbol.iterator]();
|
|
34
|
-
return inputs.reduce((acc, input) => {
|
|
35
|
-
if (/_len$/.test(input.name)) {
|
|
36
|
-
return acc;
|
|
37
|
-
}
|
|
38
|
-
const parsedData = this.parseCalldataField(argsIterator, input);
|
|
39
|
-
if (Array.isArray(parsedData)) {
|
|
40
|
-
acc.push(...parsedData);
|
|
41
|
-
} else {
|
|
42
|
-
acc.push(parsedData);
|
|
43
|
-
}
|
|
44
|
-
return acc;
|
|
45
|
-
}, [] as Calldata);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Validates if all arguments that are passed to the method are corresponding to the ones in the abi
|
|
50
|
-
*
|
|
51
|
-
* @param type - type of the method
|
|
52
|
-
* @param method - name of the method
|
|
53
|
-
* @param args - arguments that are passed to the method
|
|
54
|
-
*/
|
|
55
|
-
public validateMethodAndArgs(
|
|
56
|
-
type: 'INVOKE' | 'CALL' | 'DEPLOY',
|
|
57
|
-
method: string,
|
|
58
|
-
args: Array<any> = []
|
|
59
|
-
) {
|
|
60
|
-
// ensure provided method exists
|
|
61
|
-
if (type !== 'DEPLOY') {
|
|
62
|
-
const invocableFunctionNames = this.abi
|
|
63
|
-
.filter((abi) => {
|
|
64
|
-
if (abi.type !== 'function') return false;
|
|
65
|
-
const isView = abi.stateMutability === 'view';
|
|
66
|
-
return type === 'INVOKE' ? !isView : isView;
|
|
67
|
-
})
|
|
68
|
-
.map((abi) => abi.name);
|
|
69
|
-
assert(
|
|
70
|
-
invocableFunctionNames.includes(method),
|
|
71
|
-
`${type === 'INVOKE' ? 'invocable' : 'viewable'} method not found in abi`
|
|
72
|
-
);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// ensure args match abi type
|
|
76
|
-
const methodAbi = this.abi.find((abi) =>
|
|
77
|
-
type === 'DEPLOY'
|
|
78
|
-
? abi.name === method && abi.type === method
|
|
79
|
-
: abi.name === method && abi.type === 'function'
|
|
80
|
-
) as FunctionAbi;
|
|
81
|
-
let argPosition = 0;
|
|
82
|
-
methodAbi.inputs.forEach((input) => {
|
|
83
|
-
if (/_len$/.test(input.name)) {
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
if (input.type === 'felt') {
|
|
87
|
-
assert(
|
|
88
|
-
typeof args[argPosition] === 'string' ||
|
|
89
|
-
typeof args[argPosition] === 'number' ||
|
|
90
|
-
args[argPosition] instanceof BN,
|
|
91
|
-
`arg ${input.name} should be a felt (string, number, BigNumber)`
|
|
92
|
-
);
|
|
93
|
-
argPosition += 1;
|
|
94
|
-
} else if (input.type in this.structs && typeof args[argPosition] === 'object') {
|
|
95
|
-
if (Array.isArray(args[argPosition])) {
|
|
96
|
-
const structMembersLength = this.calculateStructMembers(input.type);
|
|
97
|
-
assert(
|
|
98
|
-
args[argPosition].length === structMembersLength,
|
|
99
|
-
`arg should be of length ${structMembersLength}`
|
|
100
|
-
);
|
|
101
|
-
} else {
|
|
102
|
-
this.structs[input.type].members.forEach(({ name }) => {
|
|
103
|
-
assert(
|
|
104
|
-
Object.keys(args[argPosition]).includes(name),
|
|
105
|
-
`arg should have a property ${name}`
|
|
106
|
-
);
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
argPosition += 1;
|
|
110
|
-
} else {
|
|
111
|
-
assert(Array.isArray(args[argPosition]), `arg ${input.name} should be an Array`);
|
|
112
|
-
if (input.type === 'felt*') {
|
|
113
|
-
args[argPosition].forEach((felt: BigNumberish) => {
|
|
114
|
-
assert(
|
|
115
|
-
typeof felt === 'string' || typeof felt === 'number' || felt instanceof BN,
|
|
116
|
-
`arg ${input.name} should be an array of string, number or BigNumber`
|
|
117
|
-
);
|
|
118
|
-
});
|
|
119
|
-
argPosition += 1;
|
|
120
|
-
} else if (/\(felt/.test(input.type)) {
|
|
121
|
-
const tupleLength = input.type.split(',').length;
|
|
122
|
-
assert(
|
|
123
|
-
args[argPosition].length === tupleLength,
|
|
124
|
-
`arg ${input.name} should have ${tupleLength} elements in tuple`
|
|
125
|
-
);
|
|
126
|
-
args[argPosition].forEach((felt: BigNumberish) => {
|
|
127
|
-
assert(
|
|
128
|
-
typeof felt === 'string' || typeof felt === 'number' || felt instanceof BN,
|
|
129
|
-
`arg ${input.name} should be an array of string, number or BigNumber`
|
|
130
|
-
);
|
|
131
|
-
});
|
|
132
|
-
argPosition += 1;
|
|
133
|
-
} else {
|
|
134
|
-
const arrayType = input.type.replace('*', '');
|
|
135
|
-
args[argPosition].forEach((struct: any) => {
|
|
136
|
-
this.structs[arrayType].members.forEach(({ name }) => {
|
|
137
|
-
if (Array.isArray(struct)) {
|
|
138
|
-
const structMembersLength = this.calculateStructMembers(arrayType);
|
|
139
|
-
assert(
|
|
140
|
-
struct.length === structMembersLength,
|
|
141
|
-
`arg should be of length ${structMembersLength}`
|
|
142
|
-
);
|
|
143
|
-
} else {
|
|
144
|
-
assert(
|
|
145
|
-
Object.keys(struct).includes(name),
|
|
146
|
-
`arg ${input.name} should be an array of ${arrayType}`
|
|
147
|
-
);
|
|
148
|
-
}
|
|
149
|
-
});
|
|
150
|
-
});
|
|
151
|
-
argPosition += 1;
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
});
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
/**
|
|
158
|
-
* Parse one field of the calldata by using input field from the abi for that method
|
|
159
|
-
*
|
|
160
|
-
* @param args - value of the field
|
|
161
|
-
* @param input - input(field) information from the abi that will be used to parse the data
|
|
162
|
-
* @return {string | string[]} - parsed arguments in format that contract is expecting
|
|
163
|
-
*/
|
|
164
|
-
protected parseCalldataField(argsIterator: Iterator<any>, input: AbiEntry): string | string[] {
|
|
165
|
-
const { name, type } = input;
|
|
166
|
-
const { value } = argsIterator.next();
|
|
167
|
-
|
|
168
|
-
const parsedCalldata: string[] = [];
|
|
169
|
-
switch (true) {
|
|
170
|
-
case /\*/.test(type):
|
|
171
|
-
if (Array.isArray(value)) {
|
|
172
|
-
parsedCalldata.push(toFelt(value.length));
|
|
173
|
-
return (value as (BigNumberish | ParsedStruct)[]).reduce((acc, el) => {
|
|
174
|
-
if (/felt/.test(type)) {
|
|
175
|
-
acc.push(toFelt(el as BigNumberish));
|
|
176
|
-
} else {
|
|
177
|
-
acc.push(...this.parseCalldataValue(el, type.replace('*', '')));
|
|
178
|
-
}
|
|
179
|
-
return acc;
|
|
180
|
-
}, parsedCalldata);
|
|
181
|
-
}
|
|
182
|
-
throw Error(`Expected ${name} to be array`);
|
|
183
|
-
case type in this.structs:
|
|
184
|
-
return this.parseCalldataValue(value as ParsedStruct | BigNumberish[], type);
|
|
185
|
-
case /\(felt/.test(type):
|
|
186
|
-
if (Array.isArray(value)) {
|
|
187
|
-
return value.map((el) => toFelt(el as BigNumberish));
|
|
188
|
-
}
|
|
189
|
-
throw Error(`Expected ${name} to be array`);
|
|
190
|
-
default:
|
|
191
|
-
return toFelt(value as BigNumberish);
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
/**
|
|
196
|
-
* Deep parse of the object that has been passed to the method
|
|
197
|
-
*
|
|
198
|
-
* @param element - element that needs to be parsed
|
|
199
|
-
* @param type - name of the method
|
|
200
|
-
* @return {string | string[]} - parsed arguments in format that contract is expecting
|
|
201
|
-
*/
|
|
202
|
-
|
|
203
|
-
protected parseCalldataValue(
|
|
204
|
-
element: ParsedStruct | BigNumberish | BigNumberish[],
|
|
205
|
-
type: string
|
|
206
|
-
): string | string[] {
|
|
207
|
-
if (element === undefined) {
|
|
208
|
-
throw Error('Missing element in calldata');
|
|
209
|
-
}
|
|
210
|
-
if (Array.isArray(element)) {
|
|
211
|
-
const structMemberNum = this.calculateStructMembers(type);
|
|
212
|
-
if (element.length !== structMemberNum) {
|
|
213
|
-
throw Error('Missing element in calldata');
|
|
214
|
-
}
|
|
215
|
-
return element.map((el) => toFelt(el));
|
|
216
|
-
}
|
|
217
|
-
// checking if the passed element is struct or element in struct
|
|
218
|
-
if (this.structs[type] && this.structs[type].members.length) {
|
|
219
|
-
// going through all the members of the struct and parsing the value
|
|
220
|
-
return this.structs[type].members.reduce((acc, member: AbiEntry) => {
|
|
221
|
-
// if the member of the struct is another struct this will return array of the felts if not it will be single felt
|
|
222
|
-
// TODO: refactor types so member name can be used as keyof ParsedStruct
|
|
223
|
-
/* @ts-ignore */
|
|
224
|
-
const parsedData = this.parseCalldataValue(element[member.name], member.type);
|
|
225
|
-
if (typeof parsedData === 'string') {
|
|
226
|
-
acc.push(parsedData);
|
|
227
|
-
} else {
|
|
228
|
-
acc.push(...parsedData);
|
|
229
|
-
}
|
|
230
|
-
return acc;
|
|
231
|
-
}, [] as string[]);
|
|
232
|
-
}
|
|
233
|
-
return toFelt(element as BigNumberish);
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
/**
|
|
237
|
-
* Deep parse of the object that has been passed to the method
|
|
238
|
-
*
|
|
239
|
-
* @param struct - struct that needs to be calculated
|
|
240
|
-
* @return {number} - number of members for the given struct
|
|
241
|
-
*/
|
|
242
|
-
private calculateStructMembers(struct: string): number {
|
|
243
|
-
return this.structs[struct].members.reduce((acc, member) => {
|
|
244
|
-
if (member.type === 'felt') {
|
|
245
|
-
return acc + 1;
|
|
246
|
-
}
|
|
247
|
-
return acc + this.calculateStructMembers(member.type);
|
|
248
|
-
}, 0);
|
|
249
|
-
}
|
|
250
|
-
}
|
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
import elliptic from 'elliptic';
|
|
2
|
-
import hashJS from 'hash.js';
|
|
3
|
-
import assert from 'minimalistic-assert';
|
|
4
|
-
|
|
5
|
-
import { CONSTANT_POINTS, EC_ORDER, FIELD_PRIME, MAX_ECDSA_VAL, ONE, ZERO } from '../constants';
|
|
6
|
-
import { KeyPair, Signature } from '../types';
|
|
7
|
-
import { addHexPrefix, removeHexPrefix, sanitizeBytes } from './encode';
|
|
8
|
-
import { BigNumberish, assertInRange, toBN, toHex } from './number';
|
|
9
|
-
|
|
10
|
-
const { ec: EC, curves } = elliptic;
|
|
11
|
-
|
|
12
|
-
export const ec = new EC(
|
|
13
|
-
new curves.PresetCurve({
|
|
14
|
-
type: 'short',
|
|
15
|
-
prime: null,
|
|
16
|
-
p: FIELD_PRIME,
|
|
17
|
-
a: '00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001',
|
|
18
|
-
b: '06f21413 efbe40de 150e596d 72f7a8c5 609ad26c 15c915c1 f4cdfcb9 9cee9e89',
|
|
19
|
-
n: EC_ORDER,
|
|
20
|
-
hash: hashJS.sha256,
|
|
21
|
-
gRed: false,
|
|
22
|
-
g: CONSTANT_POINTS[1],
|
|
23
|
-
})
|
|
24
|
-
);
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* The function _truncateToN in lib/elliptic/ec/index.js does a shift-right of 4 bits
|
|
28
|
-
* in some cases. This function does the opposite operation so that
|
|
29
|
-
* _truncateToN(fixMessage(msg)) == msg.
|
|
30
|
-
*
|
|
31
|
-
* @param msg
|
|
32
|
-
*/
|
|
33
|
-
function fixMessage(msg: string) {
|
|
34
|
-
const pureHex = msg.replace(/^0x0*/, '');
|
|
35
|
-
|
|
36
|
-
if (pureHex.length <= 62) {
|
|
37
|
-
// In this case, pureHex should not be transformed, as the byteLength() is at most 31,
|
|
38
|
-
// so delta < 0 (see _truncateToN).
|
|
39
|
-
return pureHex;
|
|
40
|
-
}
|
|
41
|
-
assert(pureHex.length === 63);
|
|
42
|
-
// In this case delta will be 4 so we perform a shift-left of 4 bits by adding a ZERO_BN.
|
|
43
|
-
return `${pureHex}0`;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export const genKeyPair = ec.genKeyPair.bind(ec);
|
|
47
|
-
|
|
48
|
-
export function getKeyPair(pk: BigNumberish): KeyPair {
|
|
49
|
-
const pkBn = toBN(pk);
|
|
50
|
-
return ec.keyFromPrivate(removeHexPrefix(toHex(pkBn)), 'hex');
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
export function getStarkKey(keyPair: KeyPair): string {
|
|
54
|
-
// this method needs to be run to generate the .pub property used below
|
|
55
|
-
// the result can be dumped
|
|
56
|
-
keyPair.getPublic(true, 'hex');
|
|
57
|
-
return addHexPrefix(sanitizeBytes((keyPair as any).pub.getX().toString(16), 2));
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Takes a public key and casts it into `elliptic` KeyPair format.
|
|
62
|
-
*
|
|
63
|
-
* @param publicKey - public key which should get casted to a KeyPair
|
|
64
|
-
* @returns keyPair with public key only, which can be used to verify signatures, but cant sign anything
|
|
65
|
-
*/
|
|
66
|
-
export function getKeyPairFromPublicKey(publicKey: BigNumberish): KeyPair {
|
|
67
|
-
const publicKeyBn = toBN(publicKey);
|
|
68
|
-
return ec.keyFromPublic(removeHexPrefix(toHex(publicKeyBn)), 'hex');
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Signs a message using the provided key.
|
|
73
|
-
*
|
|
74
|
-
* @param keyPair should be an KeyPair with a valid private key.
|
|
75
|
-
* @returns an Signature.
|
|
76
|
-
*/
|
|
77
|
-
export function sign(keyPair: KeyPair, msgHash: string): Signature {
|
|
78
|
-
const msgHashBN = toBN(addHexPrefix(msgHash));
|
|
79
|
-
// Verify message hash has valid length.
|
|
80
|
-
assertInRange(msgHashBN, ZERO, toBN(addHexPrefix(MAX_ECDSA_VAL)), 'msgHash');
|
|
81
|
-
const msgSignature = keyPair.sign(fixMessage(msgHash));
|
|
82
|
-
const { r, s } = msgSignature;
|
|
83
|
-
const w = s.invm((ec as any).n);
|
|
84
|
-
// Verify signature has valid length.
|
|
85
|
-
assertInRange(r, ONE, toBN(addHexPrefix(MAX_ECDSA_VAL)), 'r');
|
|
86
|
-
assertInRange(s, ONE, toBN(addHexPrefix(EC_ORDER)), 's');
|
|
87
|
-
assertInRange(w, ONE, toBN(addHexPrefix(MAX_ECDSA_VAL)), 'w');
|
|
88
|
-
return [r.toString(), s.toString()];
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
function chunkArray(arr: any[], n: number): any[][] {
|
|
92
|
-
return Array(Math.ceil(arr.length / n))
|
|
93
|
-
.fill('')
|
|
94
|
-
.map((_, i) => arr.slice(i * n, i * n + n));
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Verifies a message using the provided key.
|
|
99
|
-
*
|
|
100
|
-
* @param keyPair should be an KeyPair with a valid public key.
|
|
101
|
-
* @param sig should be an Signature.
|
|
102
|
-
* @returns true if the verification succeeds.
|
|
103
|
-
*/
|
|
104
|
-
export function verify(keyPair: KeyPair | KeyPair[], msgHash: string, sig: Signature): boolean {
|
|
105
|
-
const keyPairArray = Array.isArray(keyPair) ? keyPair : [keyPair];
|
|
106
|
-
const msgHashBN = toBN(addHexPrefix(msgHash));
|
|
107
|
-
assert(sig.length % 2 === 0, 'Signature must be an array of length dividable by 2');
|
|
108
|
-
assertInRange(msgHashBN, ZERO, toBN(addHexPrefix(MAX_ECDSA_VAL)), 'msgHash');
|
|
109
|
-
assert(keyPairArray.length === sig.length / 2, 'Signature and keyPair length must be equal');
|
|
110
|
-
|
|
111
|
-
return chunkArray(sig, 2).every(([r, s], i) => {
|
|
112
|
-
const rBN = toBN(r);
|
|
113
|
-
const sBN = toBN(s);
|
|
114
|
-
const w = sBN.invm((ec as any).n);
|
|
115
|
-
assertInRange(rBN, ONE, toBN(addHexPrefix(MAX_ECDSA_VAL)), 'r');
|
|
116
|
-
assertInRange(sBN, ONE, toBN(addHexPrefix(EC_ORDER)), 's');
|
|
117
|
-
assertInRange(w, ONE, toBN(addHexPrefix(MAX_ECDSA_VAL)), 'w');
|
|
118
|
-
return ec.verify(fixMessage(msgHash), { r: rBN, s: sBN }, keyPairArray[i]) ?? false;
|
|
119
|
-
});
|
|
120
|
-
}
|
package/src/utils/encode.ts
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
/* eslint-disable no-param-reassign */
|
|
2
|
-
export const IS_BROWSER = typeof window !== 'undefined';
|
|
3
|
-
|
|
4
|
-
const STRING_ZERO = '0';
|
|
5
|
-
|
|
6
|
-
export function arrayBufferToString(array: ArrayBuffer): string {
|
|
7
|
-
return new Uint8Array(array).reduce((data, byte) => data + String.fromCharCode(byte), '');
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export function btoaUniversal(b: ArrayBuffer): string {
|
|
11
|
-
return IS_BROWSER ? btoa(arrayBufferToString(b)) : Buffer.from(b).toString('base64');
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export function buf2hex(buffer: Uint8Array) {
|
|
15
|
-
return [...buffer].map((x) => x.toString(16).padStart(2, '0')).join('');
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Some function imported from https://github.com/pedrouid/enc-utils/blob/master/src/index.ts
|
|
20
|
-
* enc-utils is no dependency to avoid using `Buffer` which just works in node and no browsers
|
|
21
|
-
*/
|
|
22
|
-
|
|
23
|
-
export function removeHexPrefix(hex: string): string {
|
|
24
|
-
return hex.replace(/^0x/, '');
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export function addHexPrefix(hex: string): string {
|
|
28
|
-
return `0x${removeHexPrefix(hex)}`;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
function padString(str: string, length: number, left: boolean, padding = STRING_ZERO): string {
|
|
32
|
-
const diff = length - str.length;
|
|
33
|
-
let result = str;
|
|
34
|
-
if (diff > 0) {
|
|
35
|
-
const pad = padding.repeat(diff);
|
|
36
|
-
result = left ? pad + str : str + pad;
|
|
37
|
-
}
|
|
38
|
-
return result;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export function padLeft(str: string, length: number, padding = STRING_ZERO): string {
|
|
42
|
-
return padString(str, length, true, padding);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export function calcByteLength(length: number, byteSize = 8): number {
|
|
46
|
-
const remainder = length % byteSize;
|
|
47
|
-
return remainder ? ((length - remainder) / byteSize) * byteSize + byteSize : length;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export function sanitizeBytes(str: string, byteSize = 8, padding = STRING_ZERO): string {
|
|
51
|
-
return padLeft(str, calcByteLength(str.length, byteSize), padding);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export function sanitizeHex(hex: string): string {
|
|
55
|
-
hex = removeHexPrefix(hex);
|
|
56
|
-
hex = sanitizeBytes(hex, 2);
|
|
57
|
-
if (hex) {
|
|
58
|
-
hex = addHexPrefix(hex);
|
|
59
|
-
}
|
|
60
|
-
return hex;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// implemented using TextEncoder to make it isomorphic
|
|
64
|
-
export function utf8ToArray(str: string): Uint8Array {
|
|
65
|
-
return new TextEncoder().encode(str);
|
|
66
|
-
}
|
package/src/utils/events.ts
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { UDC } from '../constants';
|
|
2
|
-
import { InvokeTransactionReceiptResponse } from '../types/provider';
|
|
3
|
-
import { cleanHex } from './number';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Parse Transaction Receipt Event from UDC invoke transaction and
|
|
7
|
-
* create DeployContractResponse compatibile response with adition of UDC Event data
|
|
8
|
-
*
|
|
9
|
-
* @param txReceipt
|
|
10
|
-
* @returns DeployContractResponse | UDC Event Response data
|
|
11
|
-
*/
|
|
12
|
-
export function parseUDCEvent(txReceipt: InvokeTransactionReceiptResponse) {
|
|
13
|
-
if (!txReceipt.events) {
|
|
14
|
-
throw new Error('UDC emited event is empty');
|
|
15
|
-
}
|
|
16
|
-
const event = txReceipt.events.find(
|
|
17
|
-
(it) => cleanHex(it.from_address) === cleanHex(UDC.ADDRESS)
|
|
18
|
-
) || {
|
|
19
|
-
data: [],
|
|
20
|
-
};
|
|
21
|
-
return {
|
|
22
|
-
transaction_hash: txReceipt.transaction_hash,
|
|
23
|
-
contract_address: event.data[0],
|
|
24
|
-
address: event.data[0],
|
|
25
|
-
deployer: event.data[1],
|
|
26
|
-
unique: event.data[2],
|
|
27
|
-
classHash: event.data[3],
|
|
28
|
-
calldata_len: event.data[4],
|
|
29
|
-
calldata: event.data.slice(5, 5 + parseInt(event.data[4], 16)),
|
|
30
|
-
salt: event.data[event.data.length - 1],
|
|
31
|
-
};
|
|
32
|
-
}
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import isomorphicFetch from 'isomorphic-fetch';
|
|
2
|
-
|
|
3
|
-
export default (typeof window !== 'undefined' && window.fetch) || // use buildin fetch in browser if available
|
|
4
|
-
(typeof global !== 'undefined' && global.fetch) || // use buildin fetch in node, react-native and service worker if available
|
|
5
|
-
isomorphicFetch; // ponyfill fetch in node and browsers that don't have it
|