starknet 4.9.0 → 4.10.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.
Files changed (65) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/README.md +1 -3
  3. package/__tests__/account.test.ts +1 -1
  4. package/__tests__/defaultProvider.test.ts +85 -210
  5. package/__tests__/fixtures.ts +1 -1
  6. package/__tests__/rpcProvider.test.ts +4 -3
  7. package/__tests__/udc.test.ts +41 -0
  8. package/account/default.d.ts +3 -1
  9. package/account/default.js +50 -0
  10. package/account/interface.d.ts +24 -7
  11. package/constants.d.ts +7 -1
  12. package/constants.js +7 -1
  13. package/contract/default.d.ts +11 -27
  14. package/contract/default.js +104 -120
  15. package/contract/interface.d.ts +5 -2
  16. package/dist/account/default.d.ts +3 -1
  17. package/dist/account/default.js +50 -0
  18. package/dist/account/interface.d.ts +24 -7
  19. package/dist/constants.d.ts +7 -1
  20. package/dist/constants.js +7 -1
  21. package/dist/contract/default.d.ts +11 -27
  22. package/dist/contract/default.js +104 -120
  23. package/dist/contract/interface.d.ts +5 -2
  24. package/dist/provider/rpc.d.ts +3 -1
  25. package/dist/provider/rpc.js +15 -2
  26. package/dist/provider/sequencer.d.ts +4 -2
  27. package/dist/provider/sequencer.js +18 -5
  28. package/dist/signer/default.d.ts +2 -2
  29. package/dist/signer/default.js +15 -15
  30. package/dist/signer/interface.d.ts +2 -0
  31. package/dist/types/api/index.d.ts +0 -6
  32. package/dist/types/index.d.ts +1 -1
  33. package/dist/types/lib.d.ts +13 -0
  34. package/dist/utils/number.d.ts +1 -0
  35. package/dist/utils/number.js +3 -1
  36. package/package.json +1 -1
  37. package/provider/rpc.d.ts +3 -1
  38. package/provider/rpc.js +15 -2
  39. package/provider/sequencer.d.ts +4 -2
  40. package/provider/sequencer.js +18 -5
  41. package/signer/default.d.ts +2 -2
  42. package/signer/default.js +15 -15
  43. package/signer/interface.d.ts +2 -0
  44. package/src/account/default.ts +43 -3
  45. package/src/account/interface.ts +34 -7
  46. package/src/constants.ts +7 -0
  47. package/src/contract/default.ts +123 -140
  48. package/src/contract/interface.ts +5 -2
  49. package/src/provider/rpc.ts +7 -3
  50. package/src/provider/sequencer.ts +13 -4
  51. package/src/signer/default.ts +18 -18
  52. package/src/signer/interface.ts +2 -0
  53. package/src/types/api/index.ts +0 -4
  54. package/src/types/index.ts +1 -1
  55. package/src/types/lib.ts +13 -0
  56. package/src/utils/number.ts +2 -0
  57. package/types/api/index.d.ts +0 -6
  58. package/types/index.d.ts +1 -1
  59. package/types/lib.d.ts +13 -0
  60. package/utils/number.d.ts +1 -0
  61. package/utils/number.js +3 -1
  62. package/www/docs/API/account.md +122 -22
  63. package/www/docs/API/contract.md +39 -3
  64. package/www/docs/API/provider.md +4 -0
  65. package/www/docs/API/signer.md +56 -2
package/provider/rpc.js CHANGED
@@ -1,4 +1,15 @@
1
1
  "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
2
13
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
14
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
15
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -52,9 +63,10 @@ var RpcProvider = /** @class */ (function () {
52
63
  function RpcProvider(optionsOrProvider) {
53
64
  var _this = this;
54
65
  this.responseParser = new rpc_1.RPCResponseParser();
55
- var nodeUrl = optionsOrProvider.nodeUrl, retries = optionsOrProvider.retries;
66
+ var nodeUrl = optionsOrProvider.nodeUrl, retries = optionsOrProvider.retries, headers = optionsOrProvider.headers;
56
67
  this.nodeUrl = nodeUrl;
57
68
  this.retries = retries || 200;
69
+ this.headers = __assign({ 'Content-Type': 'application/json' }, headers);
58
70
  this.getChainId().then(function (chainId) {
59
71
  _this.chainId = chainId;
60
72
  });
@@ -63,7 +75,7 @@ var RpcProvider = /** @class */ (function () {
63
75
  return (0, fetchPonyfill_1.default)(this.nodeUrl, {
64
76
  method: 'POST',
65
77
  body: (0, json_1.stringify)({ method: method, jsonrpc: '2.0', params: params, id: 0 }),
66
- headers: { 'Content-Type': 'application/json' },
78
+ headers: this.headers,
67
79
  });
68
80
  };
69
81
  RpcProvider.prototype.errorHandler = function (error) {
@@ -243,6 +255,7 @@ var RpcProvider = /** @class */ (function () {
243
255
  });
244
256
  };
245
257
  RpcProvider.prototype.getClassAt = function (contractAddress, blockIdentifier) {
258
+ if (blockIdentifier === void 0) { blockIdentifier = 'pending'; }
246
259
  return __awaiter(this, void 0, void 0, function () {
247
260
  var block_id;
248
261
  return __generator(this, function (_a) {
@@ -5,7 +5,7 @@ import { DeclareContractTransaction, DeployAccountContractTransaction } from '..
5
5
  import { BigNumberish } from '../utils/number';
6
6
  import { ProviderInterface } from './interface';
7
7
  import { BlockIdentifier } from './utils';
8
- declare type NetworkName = 'mainnet-alpha' | 'goerli-alpha';
8
+ declare type NetworkName = 'mainnet-alpha' | 'goerli-alpha' | 'goerli-alpha-2';
9
9
  export declare type SequencerProviderOptions = {
10
10
  network: NetworkName;
11
11
  } | {
@@ -13,15 +13,17 @@ export declare type SequencerProviderOptions = {
13
13
  feederGatewayUrl?: string;
14
14
  gatewayUrl?: string;
15
15
  chainId?: StarknetChainId;
16
+ headers?: object;
16
17
  };
17
18
  export declare class SequencerProvider implements ProviderInterface {
18
19
  baseUrl: string;
19
20
  feederGatewayUrl: string;
20
21
  gatewayUrl: string;
21
22
  chainId: StarknetChainId;
23
+ headers: object | undefined;
22
24
  private responseParser;
23
25
  constructor(optionsOrProvider?: SequencerProviderOptions);
24
- protected static getNetworkFromName(name: NetworkName): "https://alpha-mainnet.starknet.io" | "https://alpha4.starknet.io";
26
+ protected static getNetworkFromName(name: NetworkName): "https://alpha-mainnet.starknet.io" | "https://alpha4.starknet.io" | "https://alpha4-2.starknet.io";
25
27
  protected static getChainIdFromBaseUrl(baseUrl: string): StarknetChainId;
26
28
  private getFetchUrl;
27
29
  private getFetchMethod;
@@ -1,4 +1,15 @@
1
1
  "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
2
13
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
14
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
15
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -79,7 +90,7 @@ function isEmptyQueryObject(obj) {
79
90
  }
80
91
  var SequencerProvider = /** @class */ (function () {
81
92
  function SequencerProvider(optionsOrProvider) {
82
- if (optionsOrProvider === void 0) { optionsOrProvider = { network: 'goerli-alpha' }; }
93
+ if (optionsOrProvider === void 0) { optionsOrProvider = { network: 'goerli-alpha-2' }; }
83
94
  var _a;
84
95
  this.responseParser = new sequencer_1.SequencerAPIResponseParser();
85
96
  if ('network' in optionsOrProvider) {
@@ -94,6 +105,7 @@ var SequencerProvider = /** @class */ (function () {
94
105
  this.gatewayUrl = (0, url_1.buildUrl)(this.baseUrl, 'gateway', optionsOrProvider.gatewayUrl);
95
106
  this.chainId =
96
107
  (_a = optionsOrProvider.chainId) !== null && _a !== void 0 ? _a : SequencerProvider.getChainIdFromBaseUrl(optionsOrProvider.baseUrl);
108
+ this.headers = optionsOrProvider === null || optionsOrProvider === void 0 ? void 0 : optionsOrProvider.headers;
97
109
  }
98
110
  }
99
111
  SequencerProvider.getNetworkFromName = function (name) {
@@ -101,6 +113,9 @@ var SequencerProvider = /** @class */ (function () {
101
113
  case 'mainnet-alpha':
102
114
  return 'https://alpha-mainnet.starknet.io';
103
115
  case 'goerli-alpha':
116
+ return 'https://alpha4.starknet.io';
117
+ case 'goerli-alpha-2':
118
+ return 'https://alpha4-2.starknet.io';
104
119
  default:
105
120
  return 'https://alpha4.starknet.io';
106
121
  }
@@ -149,11 +164,9 @@ var SequencerProvider = /** @class */ (function () {
149
164
  };
150
165
  SequencerProvider.prototype.getHeaders = function (method) {
151
166
  if (method === 'POST') {
152
- return {
153
- 'Content-Type': 'application/json',
154
- };
167
+ return __assign({ 'Content-Type': 'application/json' }, this.headers);
155
168
  }
156
- return undefined;
169
+ return this.headers;
157
170
  };
158
171
  // typesafe fetch
159
172
  SequencerProvider.prototype.fetchEndpoint = function (endpoint) {
@@ -6,8 +6,8 @@ export declare class Signer implements SignerInterface {
6
6
  protected keyPair: KeyPair;
7
7
  constructor(keyPair?: KeyPair);
8
8
  getPubKey(): Promise<string>;
9
+ signMessage(typedData: TypedData, accountAddress: string): Promise<Signature>;
9
10
  signTransaction(transactions: Call[], transactionsDetail: InvocationsSignerDetails, abis?: Abi[]): Promise<Signature>;
10
- signDeclareTransaction({ classHash, senderAddress, chainId, maxFee, version, nonce }: DeclareSignerDetails): Promise<Signature>;
11
11
  signDeployAccountTransaction({ classHash, contractAddress, constructorCalldata, addressSalt, maxFee, version, chainId, nonce, }: DeployAccountSignerDetails): Promise<Signature>;
12
- signMessage(typedData: TypedData, accountAddress: string): Promise<Signature>;
12
+ signDeclareTransaction({ classHash, senderAddress, chainId, maxFee, version, nonce }: DeclareSignerDetails): Promise<Signature>;
13
13
  }
package/signer/default.js CHANGED
@@ -53,6 +53,15 @@ var Signer = /** @class */ (function () {
53
53
  });
54
54
  });
55
55
  };
56
+ Signer.prototype.signMessage = function (typedData, accountAddress) {
57
+ return __awaiter(this, void 0, void 0, function () {
58
+ var msgHash;
59
+ return __generator(this, function (_a) {
60
+ msgHash = (0, typedData_1.getMessageHash)(typedData, accountAddress);
61
+ return [2 /*return*/, (0, ellipticCurve_1.sign)(this.keyPair, msgHash)];
62
+ });
63
+ });
64
+ };
56
65
  Signer.prototype.signTransaction = function (transactions, transactionsDetail, abis) {
57
66
  return __awaiter(this, void 0, void 0, function () {
58
67
  var calldata, msgHash;
@@ -66,18 +75,6 @@ var Signer = /** @class */ (function () {
66
75
  });
67
76
  });
68
77
  };
69
- Signer.prototype.signDeclareTransaction = function (
70
- // contractClass: ContractClass, // Should be used once class hash is present in ContractClass
71
- _a) {
72
- var classHash = _a.classHash, senderAddress = _a.senderAddress, chainId = _a.chainId, maxFee = _a.maxFee, version = _a.version, nonce = _a.nonce;
73
- return __awaiter(this, void 0, void 0, function () {
74
- var msgHash;
75
- return __generator(this, function (_b) {
76
- msgHash = (0, hash_1.calculateDeclareTransactionHash)(classHash, senderAddress, version, maxFee, chainId, nonce);
77
- return [2 /*return*/, (0, ellipticCurve_1.sign)(this.keyPair, msgHash)];
78
- });
79
- });
80
- };
81
78
  Signer.prototype.signDeployAccountTransaction = function (_a) {
82
79
  var classHash = _a.classHash, contractAddress = _a.contractAddress, constructorCalldata = _a.constructorCalldata, addressSalt = _a.addressSalt, maxFee = _a.maxFee, version = _a.version, chainId = _a.chainId, nonce = _a.nonce;
83
80
  return __awaiter(this, void 0, void 0, function () {
@@ -88,11 +85,14 @@ var Signer = /** @class */ (function () {
88
85
  });
89
86
  });
90
87
  };
91
- Signer.prototype.signMessage = function (typedData, accountAddress) {
88
+ Signer.prototype.signDeclareTransaction = function (
89
+ // contractClass: ContractClass, // Should be used once class hash is present in ContractClass
90
+ _a) {
91
+ var classHash = _a.classHash, senderAddress = _a.senderAddress, chainId = _a.chainId, maxFee = _a.maxFee, version = _a.version, nonce = _a.nonce;
92
92
  return __awaiter(this, void 0, void 0, function () {
93
93
  var msgHash;
94
- return __generator(this, function (_a) {
95
- msgHash = (0, typedData_1.getMessageHash)(typedData, accountAddress);
94
+ return __generator(this, function (_b) {
95
+ msgHash = (0, hash_1.calculateDeclareTransactionHash)(classHash, senderAddress, version, maxFee, chainId, nonce);
96
96
  return [2 /*return*/, (0, ellipticCurve_1.sign)(this.keyPair, msgHash)];
97
97
  });
98
98
  });
@@ -32,6 +32,7 @@ export declare abstract class SignerInterface {
32
32
  abstract signTransaction(transactions: Call[], transactionsDetail: InvocationsSignerDetails, abis?: Abi[]): Promise<Signature>;
33
33
  /**
34
34
  * Signs a DEPLOY_ACCOUNT transaction with the starknet private key and returns the signature
35
+ *
35
36
  * @param transaction
36
37
  * - contractAddress - the computed address of the contract
37
38
  * - constructorCalldata - calldata to be passed in deploy constructor
@@ -45,6 +46,7 @@ export declare abstract class SignerInterface {
45
46
  abstract signDeployAccountTransaction(transaction: DeployAccountSignerDetails): Promise<Signature>;
46
47
  /**
47
48
  * Signs a DECLARE transaction with the starknet private key and returns the signature
49
+ *
48
50
  * @param transaction
49
51
  * - classHash - computed class hash. Will be replaced by ContractClass in future once class hash is present in CompiledContract
50
52
  * - senderAddress - the address of the sender
@@ -1,4 +1,4 @@
1
- import { ZERO } from '../constants';
1
+ import { UDC, ZERO } from '../constants';
2
2
  import { ProviderInterface, ProviderOptions } from '../provider';
3
3
  import { Provider } from '../provider/default';
4
4
  import { BlockIdentifier } from '../provider/utils';
@@ -16,9 +16,14 @@ import {
16
16
  Signature,
17
17
  } from '../types';
18
18
  import { EstimateFee, EstimateFeeDetails } from '../types/account';
19
- import { AllowArray, DeclareContractPayload, DeployAccountContractPayload } from '../types/lib';
19
+ import {
20
+ AllowArray,
21
+ DeclareContractPayload,
22
+ DeployAccountContractPayload,
23
+ UniversalDeployerContractPayload,
24
+ } from '../types/lib';
20
25
  import { calculateContractAddressFromHash, transactionVersion } from '../utils/hash';
21
- import { BigNumberish, toBN } from '../utils/number';
26
+ import { BigNumberish, toBN, toCairoBool } from '../utils/number';
22
27
  import { parseContract } from '../utils/provider';
23
28
  import { compileCalldata, estimatedFeeToMaxFee } from '../utils/stark';
24
29
  import { fromCallsToExecuteCalldata } from '../utils/transaction';
@@ -228,6 +233,41 @@ export class Account extends Provider implements AccountInterface {
228
233
  );
229
234
  }
230
235
 
236
+ public async deploy(
237
+ {
238
+ classHash,
239
+ salt,
240
+ unique = true,
241
+ constructorCalldata = [],
242
+ isDevnet = false,
243
+ }: UniversalDeployerContractPayload,
244
+ additionalCalls: AllowArray<Call> = [], // support multicall
245
+ transactionsDetail: InvocationsDetails = {}
246
+ ): Promise<InvokeFunctionResponse> {
247
+ const compiledConstructorCallData = compileCalldata(constructorCalldata);
248
+
249
+ const callsArray = Array.isArray(additionalCalls) ? additionalCalls : [additionalCalls];
250
+
251
+ return this.execute(
252
+ [
253
+ {
254
+ contractAddress: isDevnet ? UDC.ADDRESS_DEVNET : UDC.ADDRESS,
255
+ entrypoint: UDC.ENTRYPOINT,
256
+ calldata: [
257
+ classHash,
258
+ salt,
259
+ toCairoBool(unique),
260
+ compiledConstructorCallData.length,
261
+ ...compiledConstructorCallData,
262
+ ],
263
+ },
264
+ ...callsArray,
265
+ ],
266
+ undefined,
267
+ transactionsDetail
268
+ );
269
+ }
270
+
231
271
  public async deployAccount(
232
272
  {
233
273
  classHash,
@@ -13,7 +13,12 @@ import {
13
13
  InvokeFunctionResponse,
14
14
  Signature,
15
15
  } from '../types';
16
- import { AllowArray, DeclareContractPayload, DeployAccountContractPayload } from '../types/lib';
16
+ import {
17
+ AllowArray,
18
+ DeclareContractPayload,
19
+ DeployAccountContractPayload,
20
+ UniversalDeployerContractPayload,
21
+ } from '../types/lib';
17
22
  import { BigNumberish } from '../utils/number';
18
23
  import { TypedData } from '../utils/typedData/types';
19
24
 
@@ -71,7 +76,7 @@ export abstract class AccountInterface extends ProviderInterface {
71
76
  * Estimate Fee for executing a DEPLOY_ACCOUNT transaction on starknet
72
77
  *
73
78
  * @param contractPayload the payload object containing:
74
- * - contract - the compiled contract to be declared
79
+ * - contract - the compiled contract to be deployed
75
80
  * - classHash - the class hash of the compiled contract. This can be obtained by using starknet-cli.
76
81
  *
77
82
  * @returns response from estimate_fee
@@ -101,6 +106,7 @@ export abstract class AccountInterface extends ProviderInterface {
101
106
 
102
107
  /**
103
108
  * Declares a given compiled contract (json) to starknet
109
+ *
104
110
  * @param contractPayload transaction payload to be deployed containing:
105
111
  - contract: compiled contract code
106
112
  - classHash: computed class hash of compiled contract
@@ -116,13 +122,32 @@ export abstract class AccountInterface extends ProviderInterface {
116
122
  transactionsDetail?: InvocationsDetails
117
123
  ): Promise<DeclareContractResponse>;
118
124
 
125
+ /**
126
+ * @param deployContractPayload containing
127
+ * - classHash: computed class hash of compiled contract
128
+ * - salt: address salt
129
+ * - unique: bool if true ensure unique salt
130
+ * - calldata: constructor calldata
131
+ * @param additionalCalls - optional additional calls array to support multicall
132
+ * @param transactionsDetail Invocation Details containing:
133
+ * - optional nonce
134
+ * - optional version
135
+ * - optional maxFee
136
+ */
137
+ public abstract deploy(
138
+ deployContractPayload: UniversalDeployerContractPayload,
139
+ additionalCalls?: AllowArray<Call>,
140
+ transactionsDetail?: InvocationsDetails
141
+ ): Promise<InvokeFunctionResponse>;
142
+
119
143
  /**
120
144
  * Deploy the account on Starknet
145
+ *
121
146
  * @param contractPayload transaction payload to be deployed containing:
122
- * - classHash: computed class hash of compiled contract
123
- * - constructor calldata
124
- * - address salt
125
- - signature
147
+ - classHash: computed class hash of compiled contract
148
+ - optional constructor calldata
149
+ - optional address salt
150
+ - optional contractAddress
126
151
  * @param transactionsDetail Invocation Details containing:
127
152
  - optional nonce
128
153
  - optional version
@@ -157,7 +182,7 @@ export abstract class AccountInterface extends ProviderInterface {
157
182
  /**
158
183
  * Verify a signature of a JSON object
159
184
  *
160
- * @param json - JSON object to be verified
185
+ * @param typedData - JSON object to be verified
161
186
  * @param signature - signature of the JSON object
162
187
  * @returns true if the signature is valid, false otherwise
163
188
  * @throws {Error} if the JSON object is not a valid JSON or the signature is not a valid signature
@@ -177,6 +202,7 @@ export abstract class AccountInterface extends ProviderInterface {
177
202
 
178
203
  /**
179
204
  * Gets the nonce of the account with respect to a specific block
205
+ *
180
206
  * @param {BlockIdentifier} blockIdentifier - optional blockIdentifier. Defaults to 'pending'
181
207
  * @returns nonce of the account
182
208
  */
@@ -184,6 +210,7 @@ export abstract class AccountInterface extends ProviderInterface {
184
210
 
185
211
  /**
186
212
  * Gets Suggested Max Fee based on the transaction type
213
+ *
187
214
  * @param {EstimateFeeAction} estimateFeeAction
188
215
  * @param {EstimateFeeDetails} details
189
216
  * @returns suggestedMaxFee
package/src/constants.ts CHANGED
@@ -11,6 +11,7 @@ export const MASK_251 = TWO.pow(toBN(251));
11
11
  export enum StarknetChainId {
12
12
  MAINNET = '0x534e5f4d41494e', // encodeShortString('SN_MAIN'),
13
13
  TESTNET = '0x534e5f474f45524c49', // encodeShortString('SN_GOERLI'),
14
+ TESTNET2 = '0x534e5f474f45524c4932',
14
15
  }
15
16
  export enum TransactionHashPrefix {
16
17
  DECLARE = '0x6465636c617265', // encodeShortString('declare'),
@@ -20,6 +21,12 @@ export enum TransactionHashPrefix {
20
21
  L1_HANDLER = '0x6c315f68616e646c6572', // encodeShortString('l1_handler'),
21
22
  }
22
23
 
24
+ export const UDC = {
25
+ ADDRESS: '0x041a78e741e5af2fec34b695679bc6891742439f7afb8484ecd7766661ad02bf',
26
+ ENTRYPOINT: 'deployContract',
27
+ ADDRESS_DEVNET: '0x25fcb74260022bd8ed7e8d542408941826b53345e478b8303d6f31744838a36',
28
+ };
29
+
23
30
  /**
24
31
  * The following is taken from https://github.com/starkware-libs/starkex-resources/blob/master/crypto/starkware/crypto/signature/pedersen_params.json but converted to hex, because JS is very bad handling big integers by default
25
32
  * Please do not edit until the JSON changes.
@@ -204,30 +204,14 @@ export class Contract implements ContractInterface {
204
204
  });
205
205
  }
206
206
 
207
- /**
208
- * Saves the address of the contract deployed on network that will be used for interaction
209
- *
210
- * @param address - address of the contract
211
- */
212
207
  public attach(address: string): void {
213
208
  this.address = address;
214
209
  }
215
210
 
216
- /**
217
- * Attaches to new Provider or Account
218
- *
219
- * @param providerOrAccount - new Provider or Account to attach to
220
- */
221
211
  public connect(providerOrAccount: ProviderInterface | AccountInterface) {
222
212
  this.providerOrAccount = providerOrAccount;
223
213
  }
224
214
 
225
- /**
226
- * Resolves when contract is deployed on the network or when no deployment transaction is found
227
- *
228
- * @returns Promise that resolves when contract is deployed on the network or when no deployment transaction is found
229
- * @throws When deployment fails
230
- */
231
215
  public async deployed(): Promise<Contract> {
232
216
  if (this.deployTransactionHash) {
233
217
  await this.providerOrAccount.waitForTransaction(this.deployTransactionHash);
@@ -236,6 +220,129 @@ export class Contract implements ContractInterface {
236
220
  return this;
237
221
  }
238
222
 
223
+ public async call(
224
+ method: string,
225
+ args: Array<any> = [],
226
+ {
227
+ blockIdentifier = 'pending',
228
+ }: {
229
+ blockIdentifier?: BlockIdentifier;
230
+ } = {}
231
+ ): Promise<Result> {
232
+ // ensure contract is connected
233
+ assert(this.address !== null, 'contract is not connected to an address');
234
+
235
+ // validate method and args
236
+ this.validateMethodAndArgs('CALL', method, args);
237
+ const { inputs } = this.abi.find((abi) => abi.name === method) as FunctionAbi;
238
+
239
+ // compile calldata
240
+ const calldata = this.compileCalldata(args, inputs);
241
+ return this.providerOrAccount
242
+ .callContract(
243
+ {
244
+ contractAddress: this.address,
245
+ calldata,
246
+ entrypoint: method,
247
+ },
248
+ blockIdentifier
249
+ )
250
+ .then((x) => this.parseResponse(method, x.result));
251
+ }
252
+
253
+ public invoke(
254
+ method: string,
255
+ args: Array<any> = [],
256
+ options: Overrides = {}
257
+ ): Promise<InvokeFunctionResponse> {
258
+ // ensure contract is connected
259
+ assert(this.address !== null, 'contract is not connected to an address');
260
+ // validate method and args
261
+ this.validateMethodAndArgs('INVOKE', method, args);
262
+
263
+ const { inputs } = this.abi.find((abi) => abi.name === method) as FunctionAbi;
264
+ const inputsLength = inputs.reduce((acc, input) => {
265
+ if (!/_len$/.test(input.name)) {
266
+ return acc + 1;
267
+ }
268
+ return acc;
269
+ }, 0);
270
+
271
+ if (args.length !== inputsLength) {
272
+ throw Error(
273
+ `Invalid number of arguments, expected ${inputsLength} arguments, but got ${args.length}`
274
+ );
275
+ }
276
+ // compile calldata
277
+ const calldata = this.compileCalldata(args, inputs);
278
+
279
+ const invocation = {
280
+ contractAddress: this.address,
281
+ calldata,
282
+ entrypoint: method,
283
+ };
284
+ if ('execute' in this.providerOrAccount) {
285
+ return this.providerOrAccount.execute(invocation, undefined, {
286
+ maxFee: options.maxFee,
287
+ nonce: options.nonce,
288
+ });
289
+ }
290
+
291
+ if (!options.nonce) {
292
+ throw new Error(`Nonce is required when invoking a function without an account`);
293
+ }
294
+
295
+ // eslint-disable-next-line no-console
296
+ console.warn(`Invoking ${method} without an account. This will not work on a public node.`);
297
+
298
+ return this.providerOrAccount.invokeFunction(
299
+ {
300
+ ...invocation,
301
+ signature: options.signature || [],
302
+ },
303
+ {
304
+ nonce: options.nonce,
305
+ }
306
+ );
307
+ }
308
+
309
+ public async estimate(method: string, args: Array<any> = []) {
310
+ // ensure contract is connected
311
+ assert(this.address !== null, 'contract is not connected to an address');
312
+
313
+ // validate method and args
314
+ this.validateMethodAndArgs('INVOKE', method, args);
315
+ const invocation = this.populateTransaction[method](...args);
316
+ if ('estimateInvokeFee' in this.providerOrAccount) {
317
+ return this.providerOrAccount.estimateInvokeFee(invocation);
318
+ }
319
+ throw Error('Contract must be connected to the account contract to estimate');
320
+ }
321
+
322
+ public populate(method: string, args: Array<any> = []): Call {
323
+ const { inputs } = this.abi.find((abi) => abi.name === method) as FunctionAbi;
324
+ return {
325
+ contractAddress: this.address,
326
+ entrypoint: method,
327
+ calldata: this.compileCalldata(args, inputs),
328
+ };
329
+ }
330
+
331
+ /**
332
+ * Deep parse of the object that has been passed to the method
333
+ *
334
+ * @param struct - struct that needs to be calculated
335
+ * @return {number} - number of members for the given struct
336
+ */
337
+ private calculateStructMembers(struct: string): number {
338
+ return this.structs[struct].members.reduce((acc, member) => {
339
+ if (member.type === 'felt') {
340
+ return acc + 1;
341
+ }
342
+ return acc + this.calculateStructMembers(member.type);
343
+ }, 0);
344
+ }
345
+
239
346
  /**
240
347
  * Validates if all arguments that are passed to the method are corresponding to the ones in the abi
241
348
  *
@@ -337,22 +444,6 @@ export class Contract implements ContractInterface {
337
444
  });
338
445
  }
339
446
 
340
- /**
341
- * Deep parse of the object that has been passed to the method
342
- *
343
- * @param struct - struct that needs to be calculated
344
- * @return {number} - number of members for the given struct
345
- */
346
-
347
- private calculateStructMembers(struct: string): number {
348
- return this.structs[struct].members.reduce((acc, member) => {
349
- if (member.type === 'felt') {
350
- return acc + 1;
351
- }
352
- return acc + this.calculateStructMembers(member.type);
353
- }, 0);
354
- }
355
-
356
447
  /**
357
448
  * Deep parse of the object that has been passed to the method
358
449
  *
@@ -539,112 +630,4 @@ export class Contract implements ContractInterface {
539
630
  return acc;
540
631
  }, [] as Result);
541
632
  }
542
-
543
- public invoke(
544
- method: string,
545
- args: Array<any> = [],
546
- options: Overrides = {}
547
- ): Promise<InvokeFunctionResponse> {
548
- // ensure contract is connected
549
- assert(this.address !== null, 'contract is not connected to an address');
550
- // validate method and args
551
- this.validateMethodAndArgs('INVOKE', method, args);
552
-
553
- const { inputs } = this.abi.find((abi) => abi.name === method) as FunctionAbi;
554
- const inputsLength = inputs.reduce((acc, input) => {
555
- if (!/_len$/.test(input.name)) {
556
- return acc + 1;
557
- }
558
- return acc;
559
- }, 0);
560
-
561
- if (args.length !== inputsLength) {
562
- throw Error(
563
- `Invalid number of arguments, expected ${inputsLength} arguments, but got ${args.length}`
564
- );
565
- }
566
- // compile calldata
567
- const calldata = this.compileCalldata(args, inputs);
568
-
569
- const invocation = {
570
- contractAddress: this.address,
571
- calldata,
572
- entrypoint: method,
573
- };
574
- if ('execute' in this.providerOrAccount) {
575
- return this.providerOrAccount.execute(invocation, undefined, {
576
- maxFee: options.maxFee,
577
- nonce: options.nonce,
578
- });
579
- }
580
-
581
- if (!options.nonce) {
582
- throw new Error(`Nonce is required when invoking a function without an account`);
583
- }
584
-
585
- // eslint-disable-next-line no-console
586
- console.warn(`Invoking ${method} without an account. This will not work on a public node.`);
587
-
588
- return this.providerOrAccount.invokeFunction(
589
- {
590
- ...invocation,
591
- signature: options.signature || [],
592
- },
593
- {
594
- nonce: options.nonce,
595
- }
596
- );
597
- }
598
-
599
- public async call(
600
- method: string,
601
- args: Array<any> = [],
602
- {
603
- blockIdentifier = 'pending',
604
- }: {
605
- blockIdentifier?: BlockIdentifier;
606
- } = {}
607
- ): Promise<Result> {
608
- // ensure contract is connected
609
- assert(this.address !== null, 'contract is not connected to an address');
610
-
611
- // validate method and args
612
- this.validateMethodAndArgs('CALL', method, args);
613
- const { inputs } = this.abi.find((abi) => abi.name === method) as FunctionAbi;
614
-
615
- // compile calldata
616
- const calldata = this.compileCalldata(args, inputs);
617
- return this.providerOrAccount
618
- .callContract(
619
- {
620
- contractAddress: this.address,
621
- calldata,
622
- entrypoint: method,
623
- },
624
- blockIdentifier
625
- )
626
- .then((x) => this.parseResponse(method, x.result));
627
- }
628
-
629
- public async estimate(method: string, args: Array<any> = []) {
630
- // ensure contract is connected
631
- assert(this.address !== null, 'contract is not connected to an address');
632
-
633
- // validate method and args
634
- this.validateMethodAndArgs('INVOKE', method, args);
635
- const invocation = this.populateTransaction[method](...args);
636
- if ('estimateInvokeFee' in this.providerOrAccount) {
637
- return this.providerOrAccount.estimateInvokeFee(invocation);
638
- }
639
- throw Error('Contract must be connected to the account contract to estimate');
640
- }
641
-
642
- public populate(method: string, args: Array<any> = []): Call {
643
- const { inputs } = this.abi.find((abi) => abi.name === method) as FunctionAbi;
644
- return {
645
- contractAddress: this.address,
646
- entrypoint: method,
647
- calldata: this.compileCalldata(args, inputs),
648
- };
649
- }
650
633
  }