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/stark.ts
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import BN from 'bn.js';
|
|
2
|
-
import { gzip } from 'pako';
|
|
3
|
-
|
|
4
|
-
import { Calldata, CompressedProgram, Program, RawArgs, Signature } from '../types';
|
|
5
|
-
import { genKeyPair, getStarkKey } from './ellipticCurve';
|
|
6
|
-
import { addHexPrefix, btoaUniversal } from './encode';
|
|
7
|
-
import { stringify } from './json';
|
|
8
|
-
import { BigNumberish, toBN } from './number';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Function to compress compiled cairo program
|
|
12
|
-
*
|
|
13
|
-
* [Reference](https://github.com/starkware-libs/cairo-lang/blob/master/src/starkware/starknet/services/api/gateway/transaction.py#L54-L58)
|
|
14
|
-
* @param jsonProgram - json file representing the compiled cairo program
|
|
15
|
-
* @returns Compressed cairo program
|
|
16
|
-
*/
|
|
17
|
-
export function compressProgram(jsonProgram: Program | string): CompressedProgram {
|
|
18
|
-
const stringified = typeof jsonProgram === 'string' ? jsonProgram : stringify(jsonProgram);
|
|
19
|
-
const compressedProgram = gzip(stringified);
|
|
20
|
-
return btoaUniversal(compressedProgram);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export function randomAddress(): string {
|
|
24
|
-
const randomKeyPair = genKeyPair();
|
|
25
|
-
return getStarkKey(randomKeyPair);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export function makeAddress(input: string): string {
|
|
29
|
-
return addHexPrefix(input).toLowerCase();
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export function formatSignature(sig?: Signature): string[] {
|
|
33
|
-
if (!sig) return [];
|
|
34
|
-
try {
|
|
35
|
-
return sig.map((x) => toBN(x)).map((x) => x.toString());
|
|
36
|
-
} catch (e) {
|
|
37
|
-
return [];
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export function compileCalldata(args: RawArgs): Calldata {
|
|
42
|
-
return Object.values(args).flatMap((value) => {
|
|
43
|
-
if (Array.isArray(value))
|
|
44
|
-
return [toBN(value.length).toString(), ...value.map((x) => toBN(x).toString())];
|
|
45
|
-
if (typeof value === 'object' && 'type' in value)
|
|
46
|
-
return Object.entries(value)
|
|
47
|
-
.filter(([k]) => k !== 'type')
|
|
48
|
-
.map(([, v]) => toBN(v).toString());
|
|
49
|
-
return toBN(value).toString();
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
export function estimatedFeeToMaxFee(estimatedFee: BigNumberish, overhead: number = 0.5): BN {
|
|
54
|
-
// BN can only handle Integers, so we need to do all calulations with integers
|
|
55
|
-
const overHeadPercent = Math.round((1 + overhead) * 100);
|
|
56
|
-
return toBN(estimatedFee).mul(toBN(overHeadPercent)).div(toBN(100));
|
|
57
|
-
}
|
package/src/utils/starknetId.ts
DELETED
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
/* eslint-disable no-param-reassign */
|
|
2
|
-
import BN from 'bn.js';
|
|
3
|
-
|
|
4
|
-
import { StarknetChainId } from '../constants';
|
|
5
|
-
|
|
6
|
-
const basicAlphabet = 'abcdefghijklmnopqrstuvwxyz0123456789-';
|
|
7
|
-
const basicSizePlusOne = new BN(basicAlphabet.length + 1);
|
|
8
|
-
const bigAlphabet = '这来';
|
|
9
|
-
const basicAlphabetSize = new BN(basicAlphabet.length);
|
|
10
|
-
const bigAlphabetSize = new BN(bigAlphabet.length);
|
|
11
|
-
const bigAlphabetSizePlusOne = new BN(bigAlphabet.length + 1);
|
|
12
|
-
|
|
13
|
-
function extractStars(str: string): [string, number] {
|
|
14
|
-
let k = 0;
|
|
15
|
-
while (str.endsWith(bigAlphabet[bigAlphabet.length - 1])) {
|
|
16
|
-
str = str.substring(0, str.length - 1);
|
|
17
|
-
k += 1;
|
|
18
|
-
}
|
|
19
|
-
return [str, k];
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export function useDecoded(encoded: BN[]): string {
|
|
23
|
-
let decoded = '';
|
|
24
|
-
|
|
25
|
-
encoded.forEach((subdomain) => {
|
|
26
|
-
while (!subdomain.isZero()) {
|
|
27
|
-
const code = subdomain.mod(basicSizePlusOne).toNumber();
|
|
28
|
-
subdomain = subdomain.div(basicSizePlusOne);
|
|
29
|
-
if (code === basicAlphabet.length) {
|
|
30
|
-
const nextSubdomain = subdomain.div(bigAlphabetSizePlusOne);
|
|
31
|
-
if (nextSubdomain.isZero()) {
|
|
32
|
-
const code2 = subdomain.mod(bigAlphabetSizePlusOne).toNumber();
|
|
33
|
-
subdomain = nextSubdomain;
|
|
34
|
-
if (code2 === 0) decoded += basicAlphabet[0];
|
|
35
|
-
else decoded += bigAlphabet[code2 - 1];
|
|
36
|
-
} else {
|
|
37
|
-
const code2 = subdomain.mod(bigAlphabetSize).toNumber();
|
|
38
|
-
decoded += bigAlphabet[code2];
|
|
39
|
-
subdomain = subdomain.div(bigAlphabetSize);
|
|
40
|
-
}
|
|
41
|
-
} else decoded += basicAlphabet[code];
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const [str, k] = extractStars(decoded);
|
|
45
|
-
if (k)
|
|
46
|
-
decoded =
|
|
47
|
-
str +
|
|
48
|
-
(k % 2 === 0
|
|
49
|
-
? bigAlphabet[bigAlphabet.length - 1].repeat(k / 2 - 1) +
|
|
50
|
-
bigAlphabet[0] +
|
|
51
|
-
basicAlphabet[1]
|
|
52
|
-
: bigAlphabet[bigAlphabet.length - 1].repeat((k - 1) / 2 + 1));
|
|
53
|
-
decoded += '.';
|
|
54
|
-
});
|
|
55
|
-
return decoded.concat('stark');
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
export function useEncoded(decoded: string): BN {
|
|
59
|
-
let encoded = new BN(0);
|
|
60
|
-
let multiplier = new BN(1);
|
|
61
|
-
|
|
62
|
-
if (decoded.endsWith(bigAlphabet[0] + basicAlphabet[1])) {
|
|
63
|
-
const [str, k] = extractStars(decoded.substring(0, decoded.length - 2));
|
|
64
|
-
decoded = str + bigAlphabet[bigAlphabet.length - 1].repeat(2 * (k + 1));
|
|
65
|
-
} else {
|
|
66
|
-
const [str, k] = extractStars(decoded);
|
|
67
|
-
if (k) decoded = str + bigAlphabet[bigAlphabet.length - 1].repeat(1 + 2 * (k - 1));
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
for (let i = 0; i < decoded.length; i += 1) {
|
|
71
|
-
const char = decoded[i];
|
|
72
|
-
const index = basicAlphabet.indexOf(char);
|
|
73
|
-
const bnIndex = new BN(basicAlphabet.indexOf(char));
|
|
74
|
-
|
|
75
|
-
if (index !== -1) {
|
|
76
|
-
// add encoded + multiplier * index
|
|
77
|
-
if (i === decoded.length - 1 && decoded[i] === basicAlphabet[0]) {
|
|
78
|
-
encoded = encoded.add(multiplier.mul(basicAlphabetSize));
|
|
79
|
-
multiplier = multiplier.mul(basicSizePlusOne);
|
|
80
|
-
// add 0
|
|
81
|
-
multiplier = multiplier.mul(basicSizePlusOne);
|
|
82
|
-
} else {
|
|
83
|
-
encoded = encoded.add(multiplier.mul(bnIndex));
|
|
84
|
-
multiplier = multiplier.mul(basicSizePlusOne);
|
|
85
|
-
}
|
|
86
|
-
} else if (bigAlphabet.indexOf(char) !== -1) {
|
|
87
|
-
// add encoded + multiplier * (basicAlphabetSize)
|
|
88
|
-
encoded = encoded.add(multiplier.mul(basicAlphabetSize));
|
|
89
|
-
multiplier = multiplier.mul(basicSizePlusOne);
|
|
90
|
-
// add encoded + multiplier * index
|
|
91
|
-
const newid = (i === decoded.length - 1 ? 1 : 0) + bigAlphabet.indexOf(char);
|
|
92
|
-
encoded = encoded.add(multiplier.mul(new BN(newid)));
|
|
93
|
-
multiplier = multiplier.mul(bigAlphabetSize);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
return encoded;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
export function getStarknetIdContract(chainId: StarknetChainId): string {
|
|
101
|
-
const starknetIdMainnetContract =
|
|
102
|
-
'0x6ac597f8116f886fa1c97a23fa4e08299975ecaf6b598873ca6792b9bbfb678';
|
|
103
|
-
const starknetIdTestnetContract =
|
|
104
|
-
'0x05cf267a0af6101667013fc6bd3f6c11116a14cda9b8c4b1198520d59f900b17';
|
|
105
|
-
|
|
106
|
-
switch (chainId) {
|
|
107
|
-
case StarknetChainId.MAINNET:
|
|
108
|
-
return starknetIdMainnetContract;
|
|
109
|
-
|
|
110
|
-
case StarknetChainId.TESTNET:
|
|
111
|
-
return starknetIdTestnetContract;
|
|
112
|
-
|
|
113
|
-
default:
|
|
114
|
-
throw new Error('Starknet.id is not yet deployed on this network');
|
|
115
|
-
}
|
|
116
|
-
}
|
package/src/utils/transaction.ts
DELETED
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import { Call, ParsedStruct } from '../types';
|
|
2
|
-
import { getSelectorFromName } from './hash';
|
|
3
|
-
import { BigNumberish, bigNumberishArrayToDecimalStringArray, toBN } from './number';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Transforms a list of Calls, each with their own calldata, into
|
|
7
|
-
* two arrays: one with the entrypoints, and one with the concatenated calldata.
|
|
8
|
-
* @param calls
|
|
9
|
-
* @returns
|
|
10
|
-
*/
|
|
11
|
-
export const transformCallsToMulticallArrays = (calls: Call[]) => {
|
|
12
|
-
const callArray: ParsedStruct[] = [];
|
|
13
|
-
const calldata: BigNumberish[] = [];
|
|
14
|
-
calls.forEach((call) => {
|
|
15
|
-
const data = call.calldata || [];
|
|
16
|
-
callArray.push({
|
|
17
|
-
to: toBN(call.contractAddress).toString(10),
|
|
18
|
-
selector: toBN(getSelectorFromName(call.entrypoint)).toString(10),
|
|
19
|
-
data_offset: calldata.length.toString(),
|
|
20
|
-
data_len: data.length.toString(),
|
|
21
|
-
});
|
|
22
|
-
calldata.push(...data);
|
|
23
|
-
});
|
|
24
|
-
return {
|
|
25
|
-
callArray,
|
|
26
|
-
calldata: bigNumberishArrayToDecimalStringArray(calldata),
|
|
27
|
-
};
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Transforms a list of calls in the full flattened calldata expected
|
|
32
|
-
* by the __execute__ protocol.
|
|
33
|
-
* @param calls
|
|
34
|
-
* @returns
|
|
35
|
-
*/
|
|
36
|
-
export const fromCallsToExecuteCalldata = (calls: Call[]): string[] => {
|
|
37
|
-
const { callArray, calldata } = transformCallsToMulticallArrays(calls);
|
|
38
|
-
return [
|
|
39
|
-
callArray.length.toString(),
|
|
40
|
-
...callArray
|
|
41
|
-
.map(
|
|
42
|
-
({ to, selector, data_offset, data_len }) =>
|
|
43
|
-
[to, selector, data_offset, data_len] as string[]
|
|
44
|
-
)
|
|
45
|
-
.flat(),
|
|
46
|
-
calldata.length.toString(),
|
|
47
|
-
...calldata,
|
|
48
|
-
];
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
export const fromCallsToExecuteCalldataWithNonce = (
|
|
52
|
-
calls: Call[],
|
|
53
|
-
nonce: BigNumberish
|
|
54
|
-
): string[] => {
|
|
55
|
-
return [...fromCallsToExecuteCalldata(calls), toBN(nonce).toString()];
|
|
56
|
-
};
|
|
@@ -1,247 +0,0 @@
|
|
|
1
|
-
import { computeHashOnElements, getSelectorFromName } from '../hash';
|
|
2
|
-
import { MerkleTree } from '../merkle';
|
|
3
|
-
import { BigNumberish, isHex, toBN, toHex } from '../number';
|
|
4
|
-
import { encodeShortString } from '../shortString';
|
|
5
|
-
import { StarkNetMerkleType, StarkNetType, TypedData } from './types';
|
|
6
|
-
import { validateTypedData } from './utils';
|
|
7
|
-
|
|
8
|
-
export * from './types';
|
|
9
|
-
|
|
10
|
-
function getHex(value: BigNumberish): string {
|
|
11
|
-
try {
|
|
12
|
-
return toHex(toBN(value));
|
|
13
|
-
} catch (e) {
|
|
14
|
-
if (typeof value === 'string') {
|
|
15
|
-
return toHex(toBN(encodeShortString(value)));
|
|
16
|
-
}
|
|
17
|
-
throw new Error(`Invalid BigNumberish: ${value}`);
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export function prepareSelector(selector: string): string {
|
|
22
|
-
return isHex(selector) ? selector : getSelectorFromName(selector);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export function isMerkleTreeType(type: StarkNetType): type is StarkNetMerkleType {
|
|
26
|
-
return type.type === 'merkletree';
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
interface Context {
|
|
30
|
-
parent?: string;
|
|
31
|
-
key?: string;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Get the dependencies of a struct type. If a struct has the same dependency multiple times, it's only included once
|
|
36
|
-
* in the resulting array.
|
|
37
|
-
*
|
|
38
|
-
* @param {TypedData} typedData
|
|
39
|
-
* @param {string} type
|
|
40
|
-
* @param {string[]} [dependencies]
|
|
41
|
-
* @return {string[]}
|
|
42
|
-
*/
|
|
43
|
-
export const getDependencies = (
|
|
44
|
-
types: TypedData['types'],
|
|
45
|
-
type: string,
|
|
46
|
-
dependencies: string[] = []
|
|
47
|
-
): string[] => {
|
|
48
|
-
// Include pointers (struct arrays)
|
|
49
|
-
if (type[type.length - 1] === '*') {
|
|
50
|
-
// eslint-disable-next-line no-param-reassign
|
|
51
|
-
type = type.slice(0, -1);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
if (dependencies.includes(type)) {
|
|
55
|
-
return dependencies;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
if (!types[type]) {
|
|
59
|
-
return dependencies;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
return [
|
|
63
|
-
type,
|
|
64
|
-
...types[type].reduce<string[]>(
|
|
65
|
-
(previous, t) => [
|
|
66
|
-
...previous,
|
|
67
|
-
...getDependencies(types, t.type, previous).filter(
|
|
68
|
-
(dependency) => !previous.includes(dependency)
|
|
69
|
-
),
|
|
70
|
-
],
|
|
71
|
-
[]
|
|
72
|
-
),
|
|
73
|
-
];
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
function getMerkleTreeType(types: TypedData['types'], ctx: Context) {
|
|
77
|
-
if (ctx.parent && ctx.key) {
|
|
78
|
-
const parentType = types[ctx.parent];
|
|
79
|
-
const merkleType = parentType.find((t) => t.name === ctx.key)!;
|
|
80
|
-
const isMerkleTree = isMerkleTreeType(merkleType);
|
|
81
|
-
if (!isMerkleTree) {
|
|
82
|
-
throw new Error(`${ctx.key} is not a merkle tree`);
|
|
83
|
-
}
|
|
84
|
-
if (merkleType.contains.endsWith('*')) {
|
|
85
|
-
throw new Error(`Merkle tree contain property must not be an array but was given ${ctx.key}`);
|
|
86
|
-
}
|
|
87
|
-
return merkleType.contains;
|
|
88
|
-
}
|
|
89
|
-
return 'raw';
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Encode a type to a string. All dependant types are alphabetically sorted.
|
|
94
|
-
*
|
|
95
|
-
* @param {TypedData} typedData
|
|
96
|
-
* @param {string} type
|
|
97
|
-
* @return {string}
|
|
98
|
-
*/
|
|
99
|
-
export const encodeType = (types: TypedData['types'], type: string): string => {
|
|
100
|
-
const [primary, ...dependencies] = getDependencies(types, type);
|
|
101
|
-
const newTypes = !primary ? [] : [primary, ...dependencies.sort()];
|
|
102
|
-
|
|
103
|
-
return newTypes
|
|
104
|
-
.map((dependency) => {
|
|
105
|
-
return `${dependency}(${types[dependency].map((t) => `${t.name}:${t.type}`)})`;
|
|
106
|
-
})
|
|
107
|
-
.join('');
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Get a type string as hash.
|
|
112
|
-
*
|
|
113
|
-
* @param {TypedData} typedData
|
|
114
|
-
* @param {string} type
|
|
115
|
-
* @return {string}
|
|
116
|
-
*/
|
|
117
|
-
export const getTypeHash = (types: TypedData['types'], type: string): string => {
|
|
118
|
-
return getSelectorFromName(encodeType(types, type));
|
|
119
|
-
};
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Encodes a single value to an ABI serialisable string, number or Buffer. Returns the data as tuple, which consists of
|
|
123
|
-
* an array of ABI compatible types, and an array of corresponding values.
|
|
124
|
-
*
|
|
125
|
-
* @param {TypedData} typedData
|
|
126
|
-
* @param {string} type
|
|
127
|
-
* @param {any} data
|
|
128
|
-
* @returns {[string, string]}
|
|
129
|
-
*/
|
|
130
|
-
export const encodeValue = (
|
|
131
|
-
types: TypedData['types'],
|
|
132
|
-
type: string,
|
|
133
|
-
data: unknown,
|
|
134
|
-
ctx: Context = {}
|
|
135
|
-
): [string, string] => {
|
|
136
|
-
if (types[type]) {
|
|
137
|
-
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
138
|
-
return [type, getStructHash(types, type, data as Record<string, unknown>)];
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
if (
|
|
142
|
-
Object.keys(types)
|
|
143
|
-
.map((x) => `${x}*`)
|
|
144
|
-
.includes(type)
|
|
145
|
-
) {
|
|
146
|
-
const structHashes: string[] = (data as unknown[]).map((struct) => {
|
|
147
|
-
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
148
|
-
return getStructHash(types, type.slice(0, -1), struct as Record<string, unknown>);
|
|
149
|
-
});
|
|
150
|
-
return [type, computeHashOnElements(structHashes)];
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
if (type === 'merkletree') {
|
|
154
|
-
const merkleTreeType = getMerkleTreeType(types, ctx);
|
|
155
|
-
const structHashes: string[] = (data as unknown[]).map((struct) => {
|
|
156
|
-
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
157
|
-
return encodeValue(types, merkleTreeType, struct as Record<string, unknown>)[1];
|
|
158
|
-
});
|
|
159
|
-
const { root } = new MerkleTree(structHashes as string[]);
|
|
160
|
-
return ['felt', root];
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
if (type === 'felt*') {
|
|
164
|
-
return ['felt*', computeHashOnElements(data as string[])];
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
if (type === 'selector') {
|
|
168
|
-
return ['felt', prepareSelector(data as string)];
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
return [type, getHex(data as string)];
|
|
172
|
-
};
|
|
173
|
-
|
|
174
|
-
/**
|
|
175
|
-
* Encode the data to an ABI encoded Buffer. The data should be a key -> value object with all the required values. All
|
|
176
|
-
* dependant types are automatically encoded.
|
|
177
|
-
*
|
|
178
|
-
* @param {TypedData} typedData
|
|
179
|
-
* @param {string} type
|
|
180
|
-
* @param {Record<string, any>} data
|
|
181
|
-
*/
|
|
182
|
-
export const encodeData = <T extends TypedData>(
|
|
183
|
-
types: T['types'],
|
|
184
|
-
type: string,
|
|
185
|
-
data: T['message']
|
|
186
|
-
) => {
|
|
187
|
-
const [returnTypes, values] = types[type].reduce<[string[], string[]]>(
|
|
188
|
-
([ts, vs], field) => {
|
|
189
|
-
if (data[field.name] === undefined || data[field.name] === null) {
|
|
190
|
-
throw new Error(`Cannot encode data: missing data for '${field.name}'`);
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
const value = data[field.name];
|
|
194
|
-
const [t, encodedValue] = encodeValue(types, field.type, value, {
|
|
195
|
-
parent: type,
|
|
196
|
-
key: field.name,
|
|
197
|
-
});
|
|
198
|
-
|
|
199
|
-
return [
|
|
200
|
-
[...ts, t],
|
|
201
|
-
[...vs, encodedValue],
|
|
202
|
-
];
|
|
203
|
-
},
|
|
204
|
-
[['felt'], [getTypeHash(types, type)]]
|
|
205
|
-
);
|
|
206
|
-
|
|
207
|
-
return [returnTypes, values];
|
|
208
|
-
};
|
|
209
|
-
|
|
210
|
-
/**
|
|
211
|
-
* Get encoded data as a hash. The data should be a key -> value object with all the required values. All dependant
|
|
212
|
-
* types are automatically encoded.
|
|
213
|
-
*
|
|
214
|
-
* @param {TypedData} typedData
|
|
215
|
-
* @param {string} type
|
|
216
|
-
* @param {Record<string, any>} data
|
|
217
|
-
* @return {Buffer}
|
|
218
|
-
*/
|
|
219
|
-
export const getStructHash = <T extends TypedData>(
|
|
220
|
-
types: T['types'],
|
|
221
|
-
type: string,
|
|
222
|
-
data: T['message']
|
|
223
|
-
) => {
|
|
224
|
-
return computeHashOnElements(encodeData(types, type, data)[1]);
|
|
225
|
-
};
|
|
226
|
-
|
|
227
|
-
/**
|
|
228
|
-
* Get the EIP-191 encoded message to sign, from the typedData object.
|
|
229
|
-
*
|
|
230
|
-
* @param {TypedData} typedData
|
|
231
|
-
* @param {BigNumberish} account
|
|
232
|
-
* @return {string}
|
|
233
|
-
*/
|
|
234
|
-
export const getMessageHash = (typedData: TypedData, account: BigNumberish): string => {
|
|
235
|
-
if (!validateTypedData(typedData)) {
|
|
236
|
-
throw new Error('Typed data does not match JSON schema');
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
const message = [
|
|
240
|
-
encodeShortString('StarkNet Message'),
|
|
241
|
-
getStructHash(typedData.types, 'StarkNetDomain', typedData.domain),
|
|
242
|
-
account,
|
|
243
|
-
getStructHash(typedData.types, typedData.primaryType, typedData.message),
|
|
244
|
-
];
|
|
245
|
-
|
|
246
|
-
return computeHashOnElements(message);
|
|
247
|
-
};
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
export type StarkNetMerkleType = {
|
|
2
|
-
name: string;
|
|
3
|
-
type: 'merkletree';
|
|
4
|
-
contains: string;
|
|
5
|
-
};
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* A single type, as part of a struct. The `type` field can be any of the EIP-712 supported types.
|
|
9
|
-
*
|
|
10
|
-
* Note that the `uint` and `int` aliases like in Solidity, and fixed point numbers are not supported by the EIP-712
|
|
11
|
-
* standard.
|
|
12
|
-
*/
|
|
13
|
-
export type StarkNetType =
|
|
14
|
-
| {
|
|
15
|
-
name: string;
|
|
16
|
-
type: string;
|
|
17
|
-
}
|
|
18
|
-
| StarkNetMerkleType;
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* The EIP712 domain struct. Any of these fields are optional, but it must contain at least one field.
|
|
22
|
-
*/
|
|
23
|
-
export interface StarkNetDomain extends Record<string, unknown> {
|
|
24
|
-
name?: string;
|
|
25
|
-
version?: string;
|
|
26
|
-
chainId?: string | number;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* The complete typed data, with all the structs, domain data, primary type of the message, and the message itself.
|
|
31
|
-
*/
|
|
32
|
-
export interface TypedData {
|
|
33
|
-
types: Record<string, StarkNetType[]>;
|
|
34
|
-
primaryType: string;
|
|
35
|
-
domain: StarkNetDomain;
|
|
36
|
-
message: Record<string, unknown>;
|
|
37
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { TypedData } from './types';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Validates that `data` matches the EIP-712 JSON schema.
|
|
5
|
-
*
|
|
6
|
-
* @param {any} data
|
|
7
|
-
* @return {boolean}
|
|
8
|
-
*/
|
|
9
|
-
export const validateTypedData = (data: unknown): data is TypedData => {
|
|
10
|
-
const typedData = data as TypedData;
|
|
11
|
-
|
|
12
|
-
// Validate that the data matches the EIP-712 JSON schema
|
|
13
|
-
const valid = Boolean(typedData.types && typedData.primaryType && typedData.message);
|
|
14
|
-
|
|
15
|
-
return valid;
|
|
16
|
-
};
|
package/src/utils/uint256.ts
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { addHexPrefix } from './encode';
|
|
2
|
-
import { BigNumberish, toBN } from './number';
|
|
3
|
-
|
|
4
|
-
// Represents an integer in the range [0, 2^256).
|
|
5
|
-
export interface Uint256 {
|
|
6
|
-
// The low 128 bits of the value.
|
|
7
|
-
low: BigNumberish;
|
|
8
|
-
// The high 128 bits of the value.
|
|
9
|
-
high: BigNumberish;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
// function to convert Uint256 to BN
|
|
13
|
-
export function uint256ToBN(uint256: Uint256) {
|
|
14
|
-
return toBN(uint256.high).shln(128).add(toBN(uint256.low));
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export const UINT_128_MAX = toBN(1).shln(128).sub(toBN(1));
|
|
18
|
-
export const UINT_256_MAX = toBN(1).shln(256).sub(toBN(1));
|
|
19
|
-
// function to check if BN is smaller or equal 2**256-1
|
|
20
|
-
export function isUint256(bn: BigNumberish): boolean {
|
|
21
|
-
return toBN(bn).lte(UINT_256_MAX);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
// function to convert BN to Uint256
|
|
25
|
-
export function bnToUint256(bignumber: BigNumberish): Uint256 {
|
|
26
|
-
const bn = toBN(bignumber);
|
|
27
|
-
if (!isUint256(bn)) throw new Error('Number is too large');
|
|
28
|
-
return {
|
|
29
|
-
low: addHexPrefix(bn.maskn(128).toString(16)),
|
|
30
|
-
high: addHexPrefix(bn.shrn(128).toString(16)),
|
|
31
|
-
};
|
|
32
|
-
}
|
package/src/utils/url.ts
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import urljoin from 'url-join';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Inspired from https://github.com/segmentio/is-url
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* RegExps.
|
|
9
|
-
* A URL must match #1 and then at least one of #2/#3.
|
|
10
|
-
* Use two levels of REs to avoid REDOS.
|
|
11
|
-
*/
|
|
12
|
-
const protocolAndDomainRE = /^(?:\w+:)?\/\/(\S+)$/;
|
|
13
|
-
|
|
14
|
-
const localhostDomainRE = /^localhost[:?\d]*(?:[^:?\d]\S*)?$/;
|
|
15
|
-
const nonLocalhostDomainRE = /^[^\s.]+\.\S{2,}$/;
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Loosely validate a URL `string`.
|
|
19
|
-
* @param {String} s
|
|
20
|
-
* @return {Boolean}
|
|
21
|
-
*/
|
|
22
|
-
export function isUrl(s?: string): boolean {
|
|
23
|
-
if (!s) {
|
|
24
|
-
return false;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
if (typeof s !== 'string') {
|
|
28
|
-
return false;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const match = s.match(protocolAndDomainRE);
|
|
32
|
-
if (!match) {
|
|
33
|
-
return false;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const everythingAfterProtocol = match[1];
|
|
37
|
-
if (!everythingAfterProtocol) {
|
|
38
|
-
return false;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
if (
|
|
42
|
-
localhostDomainRE.test(everythingAfterProtocol) ||
|
|
43
|
-
nonLocalhostDomainRE.test(everythingAfterProtocol)
|
|
44
|
-
) {
|
|
45
|
-
return true;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return false;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export function buildUrl(baseUrl: string, defaultPath: string, urlOrPath?: string) {
|
|
52
|
-
return isUrl(urlOrPath) ? urlOrPath! : urljoin(baseUrl, urlOrPath ?? defaultPath);
|
|
53
|
-
}
|
package/tsconfig.eslint.json
DELETED
package/tsup.config.ts
DELETED
package/www/README.md
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
# Website
|
|
2
|
-
|
|
3
|
-
This website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator.
|
|
4
|
-
|
|
5
|
-
### Installation
|
|
6
|
-
|
|
7
|
-
```
|
|
8
|
-
$ yarn
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
### Local Development
|
|
12
|
-
|
|
13
|
-
```
|
|
14
|
-
$ yarn start
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.
|
|
18
|
-
|
|
19
|
-
### Build
|
|
20
|
-
|
|
21
|
-
```
|
|
22
|
-
$ yarn build
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
This command generates static content into the `build` directory and can be served using any static contents hosting service.
|
|
26
|
-
|
|
27
|
-
### Deployment
|
|
28
|
-
|
|
29
|
-
Using SSH:
|
|
30
|
-
|
|
31
|
-
```
|
|
32
|
-
$ USE_SSH=true yarn deploy
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
Not using SSH:
|
|
36
|
-
|
|
37
|
-
```
|
|
38
|
-
$ GIT_USER=<Your GitHub username> yarn deploy
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch.
|
package/www/babel.config.js
DELETED