starknet 4.1.0 → 4.2.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 CHANGED
@@ -1,3 +1,9 @@
1
+ # [4.2.0](https://github.com/0xs34n/starknet.js/compare/v4.1.0...v4.2.0) (2022-08-09)
2
+
3
+ ### Features
4
+
5
+ - change checksum address hashing algorithm ([0f32adf](https://github.com/0xs34n/starknet.js/commit/0f32adf217b3d2e55046bbb21980648f0c8cf631))
6
+
1
7
  # [4.1.0](https://github.com/0xs34n/starknet.js/compare/v4.0.1...v4.1.0) (2022-08-03)
2
8
 
3
9
  ### Features
@@ -26,12 +26,12 @@ describe('address checksums', () => {
26
26
  '0x2fd23d9182193775423497fc0c472e156c57c69e4089a1967fb288a2d84e914'
27
27
  );
28
28
  expect(checksumAddress).toEqual(
29
- '0x02FD23D9182193775423497Fc0c472E156C57C69E4089a1967fb288a2D84e914'
29
+ '0x02Fd23d9182193775423497fc0c472E156C57C69E4089A1967fb288A2d84e914'
30
30
  );
31
31
  });
32
32
  test('should be able to verify checksum address', () => {
33
33
  const isValid = validateChecksumAddress(
34
- '0x02FD23D9182193775423497Fc0c472E156C57C69E4089a1967fb288a2D84e914'
34
+ '0x02Fd23d9182193775423497fc0c472E156C57C69E4089A1967fb288A2d84e914'
35
35
  );
36
36
  expect(isValid).toEqual(true);
37
37
  });
@@ -23,7 +23,7 @@ exports.validateAndParseAddress = validateAndParseAddress;
23
23
  // from https://github.com/ethers-io/ethers.js/blob/fc1e006575d59792fa97b4efb9ea2f8cca1944cf/packages/address/src.ts/index.ts#L12
24
24
  function getChecksumAddress(address) {
25
25
  var chars = (0, encode_1.removeHexPrefix)(validateAndParseAddress(address)).toLowerCase().split('');
26
- var hashed = (0, bytes_1.arrayify)((0, hash_1.pedersen)([0, address]), { hexPad: 'left' }); // as the hash will be 251 bits (63 chars) we need to pad it to 64 chars without changing the number value ("left")
26
+ var hashed = (0, bytes_1.arrayify)((0, hash_1.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")
27
27
  for (var i = 0; i < chars.length; i += 2) {
28
28
  if (hashed[i >> 1] >> 4 >= 8) {
29
29
  chars[i] = chars[i].toUpperCase();
@@ -4,6 +4,7 @@ import { RawCalldata } from '../types/lib';
4
4
  import { BigNumberish } from './number';
5
5
  export declare const transactionVersion = 0;
6
6
  export declare const feeTransactionVersion: BN;
7
+ export declare function keccakBn(value: BigNumberish): string;
7
8
  /**
8
9
  * Function to get the starknet keccak hash from a string
9
10
  *
@@ -28,8 +28,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
28
28
  return (mod && mod.__esModule) ? mod : { "default": mod };
29
29
  };
30
30
  Object.defineProperty(exports, "__esModule", { value: true });
31
- exports.calculateContractAddressFromHash = exports.calculcateTransactionHash = exports.calculateDeployTransactionHash = exports.calculateTransactionHashCommon = exports.computeHashOnElements = exports.pedersen = exports.getSelectorFromName = exports.starknetKeccak = exports.feeTransactionVersion = exports.transactionVersion = void 0;
31
+ exports.calculateContractAddressFromHash = exports.calculcateTransactionHash = exports.calculateDeployTransactionHash = exports.calculateTransactionHashCommon = exports.computeHashOnElements = exports.pedersen = exports.getSelectorFromName = exports.starknetKeccak = exports.keccakBn = exports.feeTransactionVersion = exports.transactionVersion = void 0;
32
32
  var keccak_1 = require("ethereum-cryptography/keccak");
33
+ var utils_1 = require("ethereum-cryptography/utils");
33
34
  var minimalistic_assert_1 = __importDefault(require("minimalistic-assert"));
34
35
  var constants_1 = require("../constants");
35
36
  var ellipticCurve_1 = require("./ellipticCurve");
@@ -37,6 +38,12 @@ var encode_1 = require("./encode");
37
38
  var number_1 = require("./number");
38
39
  exports.transactionVersion = 0;
39
40
  exports.feeTransactionVersion = (0, number_1.toBN)(2).pow((0, number_1.toBN)(128)).add((0, number_1.toBN)(exports.transactionVersion));
41
+ function keccakBn(value) {
42
+ var hexWithoutPrefix = (0, encode_1.removeHexPrefix)((0, number_1.toHex)((0, number_1.toBN)(value)));
43
+ var evenHex = hexWithoutPrefix.length % 2 === 0 ? hexWithoutPrefix : "0".concat(hexWithoutPrefix);
44
+ return (0, encode_1.addHexPrefix)((0, encode_1.buf2hex)((0, keccak_1.keccak256)((0, utils_1.hexToBytes)(evenHex))));
45
+ }
46
+ exports.keccakBn = keccakBn;
40
47
  function keccakHex(value) {
41
48
  return (0, encode_1.addHexPrefix)((0, encode_1.buf2hex)((0, keccak_1.keccak256)((0, encode_1.utf8ToArray)(value))));
42
49
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "starknet",
3
- "version": "4.1.0",
3
+ "version": "4.2.0",
4
4
  "description": "JavaScript library for StarkNet",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -3,7 +3,7 @@ import { arrayify } from '@ethersproject/bytes';
3
3
 
4
4
  import { MASK_251, ZERO } from '../constants';
5
5
  import { addHexPrefix, removeHexPrefix } from './encode';
6
- import { pedersen } from './hash';
6
+ import { keccakBn } from './hash';
7
7
  import { BigNumberish, assertInRange, toBN, toHex } from './number';
8
8
 
9
9
  export function addAddressPadding(address: BigNumberish): string {
@@ -25,7 +25,7 @@ export function validateAndParseAddress(address: BigNumberish): string {
25
25
  // from https://github.com/ethers-io/ethers.js/blob/fc1e006575d59792fa97b4efb9ea2f8cca1944cf/packages/address/src.ts/index.ts#L12
26
26
  export function getChecksumAddress(address: BigNumberish): string {
27
27
  const chars = removeHexPrefix(validateAndParseAddress(address)).toLowerCase().split('');
28
- const hashed = arrayify(pedersen([0, address]), { hexPad: 'left' }); // as the hash will be 251 bits (63 chars) we need to pad it to 64 chars without changing the number value ("left")
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
29
 
30
30
  for (let i = 0; i < chars.length; i += 2) {
31
31
  if (hashed[i >> 1] >> 4 >= 8) {
package/src/utils/hash.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import BN from 'bn.js';
2
2
  import { keccak256 } from 'ethereum-cryptography/keccak';
3
+ import { hexToBytes } from 'ethereum-cryptography/utils';
3
4
  import assert from 'minimalistic-assert';
4
5
 
5
6
  import {
@@ -13,12 +14,18 @@ import {
13
14
  } from '../constants';
14
15
  import { RawCalldata } from '../types/lib';
15
16
  import { ec } from './ellipticCurve';
16
- import { addHexPrefix, buf2hex, utf8ToArray } from './encode';
17
+ import { addHexPrefix, buf2hex, removeHexPrefix, utf8ToArray } from './encode';
17
18
  import { BigNumberish, toBN, toFelt, toHex } from './number';
18
19
 
19
20
  export const transactionVersion = 0;
20
21
  export const feeTransactionVersion = toBN(2).pow(toBN(128)).add(toBN(transactionVersion));
21
22
 
23
+ export function keccakBn(value: BigNumberish): string {
24
+ const hexWithoutPrefix = removeHexPrefix(toHex(toBN(value)));
25
+ const evenHex = hexWithoutPrefix.length % 2 === 0 ? hexWithoutPrefix : `0${hexWithoutPrefix}`;
26
+ return addHexPrefix(buf2hex(keccak256(hexToBytes(evenHex))));
27
+ }
28
+
22
29
  function keccakHex(value: string): string {
23
30
  return addHexPrefix(buf2hex(keccak256(utf8ToArray(value))));
24
31
  }
package/utils/address.js CHANGED
@@ -23,7 +23,7 @@ exports.validateAndParseAddress = validateAndParseAddress;
23
23
  // from https://github.com/ethers-io/ethers.js/blob/fc1e006575d59792fa97b4efb9ea2f8cca1944cf/packages/address/src.ts/index.ts#L12
24
24
  function getChecksumAddress(address) {
25
25
  var chars = (0, encode_1.removeHexPrefix)(validateAndParseAddress(address)).toLowerCase().split('');
26
- var hashed = (0, bytes_1.arrayify)((0, hash_1.pedersen)([0, address]), { hexPad: 'left' }); // as the hash will be 251 bits (63 chars) we need to pad it to 64 chars without changing the number value ("left")
26
+ var hashed = (0, bytes_1.arrayify)((0, hash_1.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")
27
27
  for (var i = 0; i < chars.length; i += 2) {
28
28
  if (hashed[i >> 1] >> 4 >= 8) {
29
29
  chars[i] = chars[i].toUpperCase();
package/utils/hash.d.ts CHANGED
@@ -4,6 +4,7 @@ import { RawCalldata } from '../types/lib';
4
4
  import { BigNumberish } from './number';
5
5
  export declare const transactionVersion = 0;
6
6
  export declare const feeTransactionVersion: BN;
7
+ export declare function keccakBn(value: BigNumberish): string;
7
8
  /**
8
9
  * Function to get the starknet keccak hash from a string
9
10
  *
package/utils/hash.js CHANGED
@@ -28,8 +28,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
28
28
  return (mod && mod.__esModule) ? mod : { "default": mod };
29
29
  };
30
30
  Object.defineProperty(exports, "__esModule", { value: true });
31
- exports.calculateContractAddressFromHash = exports.calculcateTransactionHash = exports.calculateDeployTransactionHash = exports.calculateTransactionHashCommon = exports.computeHashOnElements = exports.pedersen = exports.getSelectorFromName = exports.starknetKeccak = exports.feeTransactionVersion = exports.transactionVersion = void 0;
31
+ exports.calculateContractAddressFromHash = exports.calculcateTransactionHash = exports.calculateDeployTransactionHash = exports.calculateTransactionHashCommon = exports.computeHashOnElements = exports.pedersen = exports.getSelectorFromName = exports.starknetKeccak = exports.keccakBn = exports.feeTransactionVersion = exports.transactionVersion = void 0;
32
32
  var keccak_1 = require("ethereum-cryptography/keccak");
33
+ var utils_1 = require("ethereum-cryptography/utils");
33
34
  var minimalistic_assert_1 = __importDefault(require("minimalistic-assert"));
34
35
  var constants_1 = require("../constants");
35
36
  var ellipticCurve_1 = require("./ellipticCurve");
@@ -37,6 +38,12 @@ var encode_1 = require("./encode");
37
38
  var number_1 = require("./number");
38
39
  exports.transactionVersion = 0;
39
40
  exports.feeTransactionVersion = (0, number_1.toBN)(2).pow((0, number_1.toBN)(128)).add((0, number_1.toBN)(exports.transactionVersion));
41
+ function keccakBn(value) {
42
+ var hexWithoutPrefix = (0, encode_1.removeHexPrefix)((0, number_1.toHex)((0, number_1.toBN)(value)));
43
+ var evenHex = hexWithoutPrefix.length % 2 === 0 ? hexWithoutPrefix : "0".concat(hexWithoutPrefix);
44
+ return (0, encode_1.addHexPrefix)((0, encode_1.buf2hex)((0, keccak_1.keccak256)((0, utils_1.hexToBytes)(evenHex))));
45
+ }
46
+ exports.keccakBn = keccakBn;
40
47
  function keccakHex(value) {
41
48
  return (0, encode_1.addHexPrefix)((0, encode_1.buf2hex)((0, keccak_1.keccak256)((0, encode_1.utf8ToArray)(value))));
42
49
  }
@@ -14,7 +14,6 @@ Install the latest version of starknet with `npm install starknet@next`
14
14
 
15
15
  ```javascript
16
16
  import fs from "fs";
17
- import fs from "fs";
18
17
  import {
19
18
  Account,
20
19
  Contract,
@@ -42,12 +41,31 @@ Deploy the Account contract and wait for it to be verified on StarkNet.
42
41
  const compiledAccount = json.parse(
43
42
  fs.readFileSync("./Account.json").toString("ascii")
44
43
  );
44
+ ```
45
+
46
+ > **Note**
47
+ >
48
+ > below example uses [Argent's](https://github.com/argentlabs/argent-contracts-starknet/blob/develop/contracts/ArgentAccount.cairo) account contract
49
+
50
+ ```javascript
45
51
  const accountResponse = await defaultProvider.deployContract({
46
52
  contract: compiledAccount,
47
53
  addressSalt: starkKeyPub,
48
54
  });
49
55
  ```
50
56
 
57
+ > **Note**
58
+ >
59
+ > below example uses [OpenZeppelin's](https://github.com/OpenZeppelin/cairo-contracts/blob/main/src/openzeppelin/account/presets/Account.cairo) account contract
60
+
61
+ ```javascript
62
+ const accountResponse = await defaultProvider.deployContract({
63
+ contract: compiledAccount,
64
+ constructorCalldata: [starkKeyPub],
65
+ addressSalt: starkKeyPub,
66
+ });
67
+ ```
68
+
51
69
  ## Use your new account
52
70
 
53
71
  Wait for the deployment transaction to be accepted and assign the address of the deployed account to the Account object.
@@ -56,7 +74,11 @@ Wait for the deployment transaction to be accepted and assign the address of the
56
74
  await defaultProvider.waitForTransaction(accountResponse.transaction_hash);
57
75
  ```
58
76
 
59
- Once account contract is deployed [Account](../docs/API/account.md) instance can be created. Use your new account instance to sign transactions, messages or verify signatures! Make sure your Account has enough funds to execute invocations.
77
+ Once account contract is deployed [Account](../docs/API/account.md) instance can be created. Use your new account instance to sign transactions, messages or verify signatures!
78
+
79
+ > **Note**
80
+ >
81
+ > Make sure your Account has enough funds to execute invocations. Use this [faucet](https://faucet.goerli.starknet.io/) for funding on testnet.
60
82
 
61
83
  ```js
62
84
  const account = new Account(