starknet 2.7.0 → 2.9.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 +29 -0
- package/CONTRIBUTING.md +1 -1
- package/README.md +3 -3
- package/__mocks__/typedDataExample.json +35 -0
- package/__tests__/provider.test.ts +5 -3
- package/__tests__/signer.test.ts +6 -0
- package/__tests__/utils/address.test.ts +16 -0
- package/__tests__/utils/typedData.test.ts +1 -36
- package/constants.d.ts +2 -0
- package/constants.js +4 -0
- package/dist/constants.d.ts +2 -0
- package/dist/constants.js +3 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/provider/default.d.ts +6 -5
- package/dist/provider/default.js +12 -12
- package/dist/provider/interface.d.ts +11 -14
- package/dist/provider/utils.d.ts +17 -1
- package/dist/provider/utils.js +39 -6
- package/dist/signer/default.d.ts +20 -0
- package/dist/signer/default.js +57 -0
- package/dist/signer/interface.d.ts +20 -0
- package/dist/types.d.ts +1 -1
- package/dist/utils/address.d.ts +2 -0
- package/dist/utils/address.js +22 -0
- package/index.d.ts +1 -0
- package/index.js +1 -0
- package/package.json +1 -1
- package/provider/default.d.ts +5 -11
- package/provider/default.js +16 -28
- package/provider/interface.d.ts +10 -17
- package/provider/utils.d.ts +19 -4
- package/provider/utils.js +44 -7
- package/signer/default.d.ts +20 -0
- package/signer/default.js +64 -0
- package/signer/interface.d.ts +20 -0
- package/src/constants.ts +2 -0
- package/src/index.ts +1 -0
- package/src/provider/default.ts +9 -16
- package/src/provider/interface.ts +10 -20
- package/src/provider/utils.ts +46 -9
- package/src/signer/default.ts +40 -1
- package/src/signer/interface.ts +22 -0
- package/src/types.ts +1 -1
- package/src/utils/address.ts +23 -0
- package/types.d.ts +1 -1
- package/utils/address.d.ts +2 -0
- package/utils/address.js +22 -0
package/src/provider/default.ts
CHANGED
|
@@ -3,7 +3,6 @@ import urljoin from 'url-join';
|
|
|
3
3
|
|
|
4
4
|
import {
|
|
5
5
|
AddTransactionResponse,
|
|
6
|
-
BlockNumber,
|
|
7
6
|
CallContractResponse,
|
|
8
7
|
CallContractTransaction,
|
|
9
8
|
CompiledContract,
|
|
@@ -19,7 +18,7 @@ import { parse, stringify } from '../utils/json';
|
|
|
19
18
|
import { BigNumberish, toBN, toHex } from '../utils/number';
|
|
20
19
|
import { compressProgram, formatSignature, randomAddress } from '../utils/stark';
|
|
21
20
|
import { ProviderInterface } from './interface';
|
|
22
|
-
import { getFormattedBlockIdentifier } from './utils';
|
|
21
|
+
import { BlockIdentifier, getFormattedBlockIdentifier } from './utils';
|
|
23
22
|
|
|
24
23
|
type NetworkName = 'mainnet-alpha' | 'goerli-alpha';
|
|
25
24
|
|
|
@@ -93,10 +92,9 @@ export class Provider implements ProviderInterface {
|
|
|
93
92
|
*/
|
|
94
93
|
public async callContract(
|
|
95
94
|
invokeTransaction: CallContractTransaction,
|
|
96
|
-
|
|
97
|
-
blockNumber: BlockNumber = null
|
|
95
|
+
blockIdentifier: BlockIdentifier = null
|
|
98
96
|
): Promise<CallContractResponse> {
|
|
99
|
-
const formattedBlockIdentifier = getFormattedBlockIdentifier(
|
|
97
|
+
const formattedBlockIdentifier = getFormattedBlockIdentifier(blockIdentifier);
|
|
100
98
|
|
|
101
99
|
const { data } = await axios.post<CallContractResponse>(
|
|
102
100
|
urljoin(this.feederGatewayUrl, 'call_contract', formattedBlockIdentifier),
|
|
@@ -118,11 +116,8 @@ export class Provider implements ProviderInterface {
|
|
|
118
116
|
* @param blockNumber
|
|
119
117
|
* @returns the block object { block_number, previous_block_number, state_root, status, timestamp, transaction_receipts, transactions }
|
|
120
118
|
*/
|
|
121
|
-
public async getBlock(
|
|
122
|
-
|
|
123
|
-
blockNumber: BlockNumber = null
|
|
124
|
-
): Promise<GetBlockResponse> {
|
|
125
|
-
const formattedBlockIdentifier = getFormattedBlockIdentifier(blockHash, blockNumber);
|
|
119
|
+
public async getBlock(blockIdentifier: BlockIdentifier = null): Promise<GetBlockResponse> {
|
|
120
|
+
const formattedBlockIdentifier = getFormattedBlockIdentifier(blockIdentifier);
|
|
126
121
|
|
|
127
122
|
const { data } = await axios.get<GetBlockResponse>(
|
|
128
123
|
urljoin(this.feederGatewayUrl, 'get_block', formattedBlockIdentifier)
|
|
@@ -142,10 +137,9 @@ export class Provider implements ProviderInterface {
|
|
|
142
137
|
*/
|
|
143
138
|
public async getCode(
|
|
144
139
|
contractAddress: string,
|
|
145
|
-
|
|
146
|
-
blockNumber: BlockNumber = null
|
|
140
|
+
blockIdentifier: BlockIdentifier = null
|
|
147
141
|
): Promise<GetCodeResponse> {
|
|
148
|
-
const formattedBlockIdentifier = getFormattedBlockIdentifier(
|
|
142
|
+
const formattedBlockIdentifier = getFormattedBlockIdentifier(blockIdentifier);
|
|
149
143
|
|
|
150
144
|
const { data } = await axios.get<GetCodeResponse>(
|
|
151
145
|
urljoin(
|
|
@@ -172,10 +166,9 @@ export class Provider implements ProviderInterface {
|
|
|
172
166
|
public async getStorageAt(
|
|
173
167
|
contractAddress: string,
|
|
174
168
|
key: number,
|
|
175
|
-
|
|
176
|
-
blockNumber: BlockNumber = null
|
|
169
|
+
blockIdentifier: BlockIdentifier = null
|
|
177
170
|
): Promise<object> {
|
|
178
|
-
const formattedBlockIdentifier = getFormattedBlockIdentifier(
|
|
171
|
+
const formattedBlockIdentifier = getFormattedBlockIdentifier(blockIdentifier);
|
|
179
172
|
|
|
180
173
|
const { data } = await axios.get<object>(
|
|
181
174
|
urljoin(
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
AddTransactionResponse,
|
|
3
|
-
BlockNumber,
|
|
4
3
|
CallContractResponse,
|
|
5
4
|
CallContractTransaction,
|
|
6
5
|
CompiledContract,
|
|
@@ -13,6 +12,7 @@ import type {
|
|
|
13
12
|
Transaction,
|
|
14
13
|
} from '../types';
|
|
15
14
|
import type { BigNumberish } from '../utils/number';
|
|
15
|
+
import { BlockIdentifier } from './utils';
|
|
16
16
|
|
|
17
17
|
export abstract class ProviderInterface {
|
|
18
18
|
public abstract baseUrl: string;
|
|
@@ -35,14 +35,12 @@ export abstract class ProviderInterface {
|
|
|
35
35
|
* [Reference](https://github.com/starkware-libs/cairo-lang/blob/fc97bdd8322a7df043c87c371634b26c15ed6cee/src/starkware/starknet/services/api/feeder_gateway/feeder_gateway_client.py#L25-L39)
|
|
36
36
|
*
|
|
37
37
|
* @param invokeTransaction - transaction to be invoked
|
|
38
|
-
* @param
|
|
39
|
-
* @param blockNumber
|
|
38
|
+
* @param blockIdentifier - block identifier
|
|
40
39
|
* @returns the result of the function on the smart contract.
|
|
41
40
|
*/
|
|
42
41
|
public abstract callContract(
|
|
43
42
|
invokeTransaction: CallContractTransaction,
|
|
44
|
-
|
|
45
|
-
blockNumber?: BlockNumber
|
|
43
|
+
blockIdentifier?: BlockIdentifier
|
|
46
44
|
): Promise<CallContractResponse>;
|
|
47
45
|
|
|
48
46
|
/**
|
|
@@ -50,29 +48,23 @@ export abstract class ProviderInterface {
|
|
|
50
48
|
*
|
|
51
49
|
* [Reference](https://github.com/starkware-libs/cairo-lang/blob/fc97bdd8322a7df043c87c371634b26c15ed6cee/src/starkware/starknet/services/api/feeder_gateway/feeder_gateway_client.py#L41-L53)
|
|
52
50
|
*
|
|
53
|
-
* @param
|
|
54
|
-
* @param blockNumber
|
|
51
|
+
* @param blockIdentifier - block identifier
|
|
55
52
|
* @returns the block object { block_number, previous_block_number, state_root, status, timestamp, transaction_receipts, transactions }
|
|
56
53
|
*/
|
|
57
|
-
public abstract getBlock(
|
|
58
|
-
blockHash?: BigNumberish,
|
|
59
|
-
blockNumber?: BlockNumber
|
|
60
|
-
): Promise<GetBlockResponse>;
|
|
54
|
+
public abstract getBlock(blockIdentifier?: BlockIdentifier): Promise<GetBlockResponse>;
|
|
61
55
|
|
|
62
56
|
/**
|
|
63
57
|
* Gets the code of the deployed contract.
|
|
64
58
|
*
|
|
65
59
|
* [Reference](https://github.com/starkware-libs/cairo-lang/blob/fc97bdd8322a7df043c87c371634b26c15ed6cee/src/starkware/starknet/services/api/feeder_gateway/feeder_gateway_client.py#L55-L68)
|
|
66
60
|
*
|
|
67
|
-
* @param contractAddress
|
|
68
|
-
* @param
|
|
69
|
-
* @param blockNumber
|
|
61
|
+
* @param contractAddress - contract address
|
|
62
|
+
* @param blockIdentifier - block identifier
|
|
70
63
|
* @returns Bytecode and ABI of compiled contract
|
|
71
64
|
*/
|
|
72
65
|
public abstract getCode(
|
|
73
66
|
contractAddress: string,
|
|
74
|
-
|
|
75
|
-
blockNumber?: BlockNumber
|
|
67
|
+
blockIdentifier?: BlockIdentifier
|
|
76
68
|
): Promise<GetCodeResponse>;
|
|
77
69
|
|
|
78
70
|
// TODO: add proper type
|
|
@@ -83,15 +75,13 @@ export abstract class ProviderInterface {
|
|
|
83
75
|
*
|
|
84
76
|
* @param contractAddress
|
|
85
77
|
* @param key - from getStorageVarAddress('<STORAGE_VARIABLE_NAME>') (WIP)
|
|
86
|
-
* @param
|
|
87
|
-
* @param blockNumber
|
|
78
|
+
* @param blockIdentifier - block identifier
|
|
88
79
|
* @returns the value of the storage variable
|
|
89
80
|
*/
|
|
90
81
|
public abstract getStorageAt(
|
|
91
82
|
contractAddress: string,
|
|
92
83
|
key: number,
|
|
93
|
-
|
|
94
|
-
blockNumber?: BlockNumber
|
|
84
|
+
blockIdentifier?: BlockIdentifier
|
|
95
85
|
): Promise<object>;
|
|
96
86
|
|
|
97
87
|
/**
|
package/src/provider/utils.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { BlockNumber } from '../types';
|
|
2
|
-
import { BigNumberish } from '../utils/number';
|
|
2
|
+
import { BigNumberish, toBN, toHex } from '../utils/number';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* TODO
|
|
@@ -18,6 +18,42 @@ export function formatHash() {}
|
|
|
18
18
|
*/
|
|
19
19
|
export function txIdentifier() {}
|
|
20
20
|
|
|
21
|
+
// hex string and BN are detected as block hashes
|
|
22
|
+
// decimal string and number are detected as block numbers
|
|
23
|
+
// null appends nothing to the request url
|
|
24
|
+
export type BlockIdentifier = BlockNumber | BigNumberish;
|
|
25
|
+
type BlockIdentifierObject =
|
|
26
|
+
| { type: 'BLOCK_NUMBER'; data: BlockNumber }
|
|
27
|
+
| { type: 'BLOCK_HASH'; data: BigNumberish };
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Identifies the block to be queried.
|
|
31
|
+
*
|
|
32
|
+
* @param blockIdentifier - block identifier
|
|
33
|
+
* @returns block identifier object
|
|
34
|
+
*/
|
|
35
|
+
export function getBlockIdentifier(blockIdentifier: BlockIdentifier): BlockIdentifierObject {
|
|
36
|
+
if (typeof blockIdentifier === 'number') {
|
|
37
|
+
return { type: 'BLOCK_NUMBER', data: blockIdentifier };
|
|
38
|
+
}
|
|
39
|
+
if (typeof blockIdentifier === 'string' && blockIdentifier.startsWith('0x')) {
|
|
40
|
+
return { type: 'BLOCK_HASH', data: blockIdentifier };
|
|
41
|
+
}
|
|
42
|
+
if (typeof blockIdentifier === 'string' && !Number.isNaN(parseInt(blockIdentifier, 10))) {
|
|
43
|
+
return { type: 'BLOCK_NUMBER', data: parseInt(blockIdentifier, 10) };
|
|
44
|
+
}
|
|
45
|
+
if (blockIdentifier === null) {
|
|
46
|
+
return { type: 'BLOCK_NUMBER', data: null };
|
|
47
|
+
}
|
|
48
|
+
if (blockIdentifier === 'pending') {
|
|
49
|
+
return { type: 'BLOCK_NUMBER', data: 'pending' };
|
|
50
|
+
}
|
|
51
|
+
if (typeof blockIdentifier === 'string') {
|
|
52
|
+
throw new Error(`Invalid block identifier: ${blockIdentifier}`);
|
|
53
|
+
}
|
|
54
|
+
return { type: 'BLOCK_HASH', data: blockIdentifier };
|
|
55
|
+
}
|
|
56
|
+
|
|
21
57
|
/**
|
|
22
58
|
* Gets the block identifier for API request
|
|
23
59
|
*
|
|
@@ -27,12 +63,13 @@ export function txIdentifier() {}
|
|
|
27
63
|
* @param blockHash
|
|
28
64
|
* @returns block identifier for API request
|
|
29
65
|
*/
|
|
30
|
-
export function getFormattedBlockIdentifier(
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
66
|
+
export function getFormattedBlockIdentifier(blockIdentifier: BlockIdentifier = null): string {
|
|
67
|
+
const blockIdentifierObject = getBlockIdentifier(blockIdentifier);
|
|
68
|
+
if (blockIdentifierObject.type === 'BLOCK_NUMBER' && blockIdentifierObject.data === null) {
|
|
69
|
+
return '';
|
|
70
|
+
}
|
|
71
|
+
if (blockIdentifierObject.type === 'BLOCK_NUMBER') {
|
|
72
|
+
return `?blockNumber=${blockIdentifierObject.data}`;
|
|
73
|
+
}
|
|
74
|
+
return `?blockHash=${toHex(toBN(blockIdentifierObject.data))}`;
|
|
38
75
|
}
|
package/src/signer/default.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import assert from 'minimalistic-assert';
|
|
2
2
|
|
|
3
|
+
import { compileCalldata } from '../contract';
|
|
3
4
|
import { Provider } from '../provider';
|
|
4
5
|
import { AddTransactionResponse, KeyPair, Signature, Transaction } from '../types';
|
|
5
6
|
import { sign } from '../utils/ellipticCurve';
|
|
6
7
|
import { addHexPrefix } from '../utils/encode';
|
|
7
8
|
import { hashMessage } from '../utils/hash';
|
|
8
|
-
import { toBN } from '../utils/number';
|
|
9
|
+
import { BigNumberish, toBN } from '../utils/number';
|
|
9
10
|
import { getSelectorFromName } from '../utils/stark';
|
|
10
11
|
import { TypedData, getMessageHash } from '../utils/typedData';
|
|
11
12
|
import { SignerInterface } from './interface';
|
|
@@ -98,4 +99,42 @@ export class Signer extends Provider implements SignerInterface {
|
|
|
98
99
|
public async hashMessage(typedData: TypedData): Promise<string> {
|
|
99
100
|
return getMessageHash(typedData, this.address);
|
|
100
101
|
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Verify a signature of a JSON object
|
|
105
|
+
*
|
|
106
|
+
* @param json - JSON object to be verified
|
|
107
|
+
* @param signature - signature of the JSON object
|
|
108
|
+
* @returns true if the signature is valid, false otherwise
|
|
109
|
+
* @throws {Error} if the JSON object is not a valid JSON or the signature is not a valid signature
|
|
110
|
+
*/
|
|
111
|
+
public async verifyMessageHash(hash: BigNumberish, signature: Signature): Promise<boolean> {
|
|
112
|
+
try {
|
|
113
|
+
await this.callContract({
|
|
114
|
+
contract_address: this.address,
|
|
115
|
+
entry_point_selector: getSelectorFromName('is_valid_signature'),
|
|
116
|
+
calldata: compileCalldata({
|
|
117
|
+
hash: toBN(hash).toString(),
|
|
118
|
+
signature: signature.map((x) => toBN(x).toString()),
|
|
119
|
+
}),
|
|
120
|
+
});
|
|
121
|
+
return true;
|
|
122
|
+
} catch {
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Verify a signature of a given hash
|
|
129
|
+
* @warning This method is not recommended, use verifyMessage instead
|
|
130
|
+
*
|
|
131
|
+
* @param hash - hash to be verified
|
|
132
|
+
* @param signature - signature of the hash
|
|
133
|
+
* @returns true if the signature is valid, false otherwise
|
|
134
|
+
* @throws {Error} if the signature is not a valid signature
|
|
135
|
+
*/
|
|
136
|
+
public async verifyMessage(typedData: TypedData, signature: Signature): Promise<boolean> {
|
|
137
|
+
const hash = await this.hashMessage(typedData);
|
|
138
|
+
return this.verifyMessageHash(hash, signature);
|
|
139
|
+
}
|
|
101
140
|
}
|
package/src/signer/interface.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Provider } from '../provider';
|
|
2
2
|
import { AddTransactionResponse, Signature, Transaction } from '../types';
|
|
3
|
+
import { BigNumberish } from '../utils/number';
|
|
3
4
|
import { TypedData } from '../utils/typedData/types';
|
|
4
5
|
|
|
5
6
|
export abstract class SignerInterface extends Provider {
|
|
@@ -35,4 +36,25 @@ export abstract class SignerInterface extends Provider {
|
|
|
35
36
|
* @throws {Error} if the JSON object is not a valid JSON
|
|
36
37
|
*/
|
|
37
38
|
public abstract hashMessage(typedData: TypedData): Promise<string>;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Verify a signature of a JSON object
|
|
42
|
+
*
|
|
43
|
+
* @param json - JSON object to be verified
|
|
44
|
+
* @param signature - signature of the JSON object
|
|
45
|
+
* @returns true if the signature is valid, false otherwise
|
|
46
|
+
* @throws {Error} if the JSON object is not a valid JSON or the signature is not a valid signature
|
|
47
|
+
*/
|
|
48
|
+
public abstract verifyMessage(typedData: TypedData, signature: Signature): Promise<boolean>;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Verify a signature of a given hash
|
|
52
|
+
* @warning This method is not recommended, use verifyMessage instead
|
|
53
|
+
*
|
|
54
|
+
* @param hash - hash to be verified
|
|
55
|
+
* @param signature - signature of the hash
|
|
56
|
+
* @returns true if the signature is valid, false otherwise
|
|
57
|
+
* @throws {Error} if the signature is not a valid signature
|
|
58
|
+
*/
|
|
59
|
+
public abstract verifyMessageHash(hash: BigNumberish, signature: Signature): Promise<boolean>;
|
|
38
60
|
}
|
package/src/types.ts
CHANGED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { MASK_251, ZERO } from '../constants';
|
|
2
|
+
import { addHexPrefix, removeHexPrefix } from './encode';
|
|
3
|
+
import { assertInRange } from './number';
|
|
4
|
+
|
|
5
|
+
export function addAddressPadding(address: string): string {
|
|
6
|
+
return addHexPrefix(removeHexPrefix(address).padStart(64, '0'));
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function validateAndParseAddress(address: string): string {
|
|
10
|
+
if (typeof address !== 'string') {
|
|
11
|
+
throw new Error('Invalid Address Type');
|
|
12
|
+
}
|
|
13
|
+
|
|
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
|
+
}
|
package/types.d.ts
CHANGED
package/utils/address.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
3
|
+
exports.validateAndParseAddress = exports.addAddressPadding = void 0;
|
|
4
|
+
var constants_1 = require('../constants');
|
|
5
|
+
var encode_1 = require('./encode');
|
|
6
|
+
var number_1 = require('./number');
|
|
7
|
+
function addAddressPadding(address) {
|
|
8
|
+
return (0, encode_1.addHexPrefix)((0, encode_1.removeHexPrefix)(address).padStart(64, '0'));
|
|
9
|
+
}
|
|
10
|
+
exports.addAddressPadding = addAddressPadding;
|
|
11
|
+
function validateAndParseAddress(address) {
|
|
12
|
+
if (typeof address !== 'string') {
|
|
13
|
+
throw new Error('Invalid Address Type');
|
|
14
|
+
}
|
|
15
|
+
(0, number_1.assertInRange)(address, constants_1.ZERO, constants_1.MASK_251, 'Starknet Address');
|
|
16
|
+
var result = addAddressPadding(address);
|
|
17
|
+
if (!result.match(/^(0x)?[0-9a-fA-F]{64}$/)) {
|
|
18
|
+
throw new Error('Invalid Address Format');
|
|
19
|
+
}
|
|
20
|
+
return result;
|
|
21
|
+
}
|
|
22
|
+
exports.validateAndParseAddress = validateAndParseAddress;
|