starknet 7.2.0 → 7.4.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/dist/index.js CHANGED
@@ -70,6 +70,8 @@ __export(index_exports, {
70
70
  OutsideExecutionTypesV1: () => OutsideExecutionTypesV1,
71
71
  OutsideExecutionTypesV2: () => OutsideExecutionTypesV2,
72
72
  OutsideExecutionVersion: () => OutsideExecutionVersion,
73
+ PaymasterInterface: () => PaymasterInterface,
74
+ PaymasterRpc: () => PaymasterRpc,
73
75
  Provider: () => RpcProvider2,
74
76
  ProviderInterface: () => ProviderInterface,
75
77
  RPC: () => api_exports,
@@ -108,6 +110,7 @@ __export(index_exports, {
108
110
  config: () => config,
109
111
  constants: () => constants_exports,
110
112
  contractClassResponseToLegacyCompiledContract: () => contractClassResponseToLegacyCompiledContract,
113
+ defaultPaymaster: () => defaultPaymaster,
111
114
  defaultProvider: () => defaultProvider,
112
115
  ec: () => ec_exports,
113
116
  encode: () => encode_exports,
@@ -137,6 +140,7 @@ __export(index_exports, {
137
140
  num: () => num_exports,
138
141
  outsideExecution: () => outsideExecution_exports,
139
142
  parseCalldataField: () => parseCalldataField,
143
+ paymaster: () => paymaster_exports,
140
144
  provider: () => provider_exports,
141
145
  selector: () => selector_exports,
142
146
  shortString: () => shortString_exports,
@@ -172,6 +176,7 @@ __export(constants_exports, {
172
176
  MAX_STORAGE_ITEM_SIZE: () => MAX_STORAGE_ITEM_SIZE,
173
177
  NetworkName: () => _NetworkName,
174
178
  OutsideExecutionCallerAny: () => OutsideExecutionCallerAny,
179
+ PAYMASTER_RPC_NODES: () => PAYMASTER_RPC_NODES,
175
180
  PRIME: () => PRIME,
176
181
  RANGE_FELT: () => RANGE_FELT,
177
182
  RANGE_I128: () => RANGE_I128,
@@ -193,6 +198,7 @@ __export(constants_exports, {
193
198
  var api_exports = {};
194
199
  __export(api_exports, {
195
200
  JRPC: () => jsonrpc_exports,
201
+ PAYMASTER_API: () => import_starknet_types_08.PAYMASTER_API,
196
202
  RPCSPEC07: () => RPCSPEC07,
197
203
  RPCSPEC08: () => RPCSPEC08
198
204
  });
@@ -203,6 +209,7 @@ var jsonrpc_exports = {};
203
209
  // src/types/api/index.ts
204
210
  var RPCSPEC07 = __toESM(require("starknet-types-07"));
205
211
  var RPCSPEC08 = __toESM(require("starknet-types-08"));
212
+ var import_starknet_types_08 = require("starknet-types-08");
206
213
  __reExport(api_exports, require("starknet-types-08"));
207
214
 
208
215
  // src/utils/encode.ts
@@ -365,21 +372,20 @@ var DEFAULT_GLOBAL_CONFIG = {
365
372
  websocket: void 0
366
373
  };
367
374
  var RPC_DEFAULT_NODES = {
368
- SN_MAIN: [
369
- `https://starknet-mainnet.public.blastapi.io/rpc/`,
370
- `https://free-rpc.nethermind.io/mainnet-juno/`
371
- ],
372
- SN_SEPOLIA: [
373
- `https://starknet-sepolia.public.blastapi.io/rpc/`,
374
- `https://free-rpc.nethermind.io/sepolia-juno/`
375
- ]
375
+ SN_MAIN: [`https://starknet-mainnet.public.blastapi.io/rpc/`],
376
+ SN_SEPOLIA: [`https://starknet-sepolia.public.blastapi.io/rpc/`]
377
+ };
378
+ var PAYMASTER_RPC_NODES = {
379
+ SN_MAIN: [`https://starknet.paymaster.avnu.fi`],
380
+ SN_SEPOLIA: [`https://sepolia.paymaster.avnu.fi`]
376
381
  };
377
382
  var SYSTEM_MESSAGES = {
378
383
  legacyTxWarningMessage: "You are using a deprecated transaction version (V0,V1,V2)!\nUpdate to the latest V3 transactions!",
379
384
  legacyTxRPC08Message: "RPC 0.8 do not support legacy transactions",
380
385
  SWOldV3: "RPC 0.7 V3 tx (improper resource bounds) not supported in RPC 0.8",
381
386
  channelVersionMismatch: "Channel specification version is not compatible with the connected node Specification Version",
382
- unsupportedSpecVersion: "The connected node specification version is not supported by this library"
387
+ unsupportedSpecVersion: "The connected node specification version is not supported by this library",
388
+ maxFeeInV3: "maxFee is not supported in V3 transactions, use resourceBounds instead"
383
389
  };
384
390
 
385
391
  // src/global/config.ts
@@ -829,6 +835,15 @@ function assert(condition, message) {
829
835
  throw new Error(message || "Assertion failure");
830
836
  }
831
837
  }
838
+ function assertX(condition, method) {
839
+ if (!condition) {
840
+ if (method.length === 0) {
841
+ method();
842
+ } else {
843
+ throw new Error("AssertionX failure: message function should not require arguments");
844
+ }
845
+ }
846
+ }
832
847
 
833
848
  // src/utils/num.ts
834
849
  var num_exports = {};
@@ -973,6 +988,7 @@ function isBigNumberish(input) {
973
988
  // src/utils/hash/selector.ts
974
989
  var selector_exports = {};
975
990
  __export(selector_exports, {
991
+ getL1MessageHash: () => getL1MessageHash,
976
992
  getL2MessageHash: () => getL2MessageHash,
977
993
  getSelector: () => getSelector,
978
994
  getSelectorFromName: () => getSelectorFromName,
@@ -1023,6 +1039,9 @@ function getL2MessageHash(l1FromAddress, l2ToAddress, l2Selector, l2Calldata, l1
1023
1039
  ...l2Calldata
1024
1040
  ]);
1025
1041
  }
1042
+ function getL1MessageHash(fromL2Address, toL1Address, payload) {
1043
+ return solidityUint256PackedKeccak256([fromL2Address, toL1Address, payload.length, ...payload]);
1044
+ }
1026
1045
 
1027
1046
  // src/utils/shortString.ts
1028
1047
  var shortString_exports = {};
@@ -3176,6 +3195,7 @@ __export(hash_exports, {
3176
3195
  computePoseidonHashOnElements: () => computePoseidonHashOnElements,
3177
3196
  computeSierraContractClassHash: () => computeSierraContractClassHash,
3178
3197
  formatSpaces: () => formatSpaces,
3198
+ getL1MessageHash: () => getL1MessageHash,
3179
3199
  getL2MessageHash: () => getL2MessageHash,
3180
3200
  getSelector: () => getSelector,
3181
3201
  getSelectorFromName: () => getSelectorFromName,
@@ -3903,7 +3923,18 @@ var errorCodes = {
3903
3923
  INVALID_SUBSCRIPTION_ID: 66,
3904
3924
  TOO_MANY_ADDRESSES_IN_FILTER: 67,
3905
3925
  TOO_MANY_BLOCKS_BACK: 68,
3906
- COMPILATION_ERROR: 100
3926
+ COMPILATION_ERROR: 100,
3927
+ INVALID_ADDRESS: 150,
3928
+ TOKEN_NOT_SUPPORTED: 151,
3929
+ INVALID_SIGNATURE: 153,
3930
+ MAX_AMOUNT_TOO_LOW: 154,
3931
+ CLASS_HASH_NOT_SUPPORTED: 155,
3932
+ PAYMASTER_TRANSACTION_EXECUTION_ERROR: 156,
3933
+ INVALID_TIME_BOUNDS: 157,
3934
+ INVALID_DEPLOYMENT_DATA: 158,
3935
+ INVALID_CLASS_HASH: 159,
3936
+ INVALID_ID: 160,
3937
+ UNKNOWN_ERROR: 163
3907
3938
  };
3908
3939
  var rpc_default = errorCodes;
3909
3940
 
@@ -4617,6 +4648,11 @@ var RpcChannel = class {
4617
4648
  fee_data_availability_mode: details.feeDataAvailabilityMode
4618
4649
  }
4619
4650
  });
4651
+ assertX(!details.maxFee, () => {
4652
+ logger.warn(SYSTEM_MESSAGES.maxFeeInV3, {
4653
+ type: RPCSPEC07.ETransactionType.INVOKE
4654
+ });
4655
+ });
4620
4656
  }
4621
4657
  return this.waitMode ? this.waitForTransaction((await promise).transaction_hash) : promise;
4622
4658
  }
@@ -4687,6 +4723,11 @@ var RpcChannel = class {
4687
4723
  fee_data_availability_mode: details.feeDataAvailabilityMode
4688
4724
  }
4689
4725
  });
4726
+ assertX(!details.maxFee, () => {
4727
+ logger.warn(SYSTEM_MESSAGES.maxFeeInV3, {
4728
+ type: RPCSPEC07.ETransactionType.DECLARE
4729
+ });
4730
+ });
4690
4731
  } else {
4691
4732
  throw Error("declare unspotted parameters");
4692
4733
  }
@@ -4728,6 +4769,11 @@ var RpcChannel = class {
4728
4769
  fee_data_availability_mode: details.feeDataAvailabilityMode
4729
4770
  }
4730
4771
  });
4772
+ assertX(!details.maxFee, () => {
4773
+ logger.warn(SYSTEM_MESSAGES.maxFeeInV3, {
4774
+ type: RPCSPEC07.ETransactionType.DEPLOY_ACCOUNT
4775
+ });
4776
+ });
4731
4777
  }
4732
4778
  return this.waitMode ? this.waitForTransaction((await promise).transaction_hash) : promise;
4733
4779
  }
@@ -4798,6 +4844,12 @@ var RpcChannel = class {
4798
4844
  fee_data_availability_mode: invocation.feeDataAvailabilityMode,
4799
4845
  account_deployment_data: invocation.accountDeploymentData.map((it) => toHex(it))
4800
4846
  };
4847
+ assertX(!invocation.maxFee, () => {
4848
+ logger.warn(SYSTEM_MESSAGES.maxFeeInV3, {
4849
+ type: invocation.type,
4850
+ versionType
4851
+ });
4852
+ });
4801
4853
  }
4802
4854
  if (invocation.type === TransactionType.INVOKE) {
4803
4855
  return {
@@ -8861,19 +8913,20 @@ function mergeAbiEvents(target, source) {
8861
8913
  }
8862
8914
  function parseEvents(providerReceivedEvents, abiEvents, abiStructs, abiEnums) {
8863
8915
  const ret = providerReceivedEvents.flat().reduce((acc, recEvent) => {
8864
- let abiEvent = abiEvents[recEvent.keys.shift() ?? 0];
8916
+ const currentEvent = JSON.parse(JSON.stringify(recEvent));
8917
+ let abiEvent = abiEvents[currentEvent.keys.shift() ?? 0];
8865
8918
  if (!abiEvent) {
8866
8919
  return acc;
8867
8920
  }
8868
8921
  while (!abiEvent.name) {
8869
- const hashName = recEvent.keys.shift();
8922
+ const hashName = currentEvent.keys.shift();
8870
8923
  assert(!!hashName, 'Not enough data in "keys" property of this event.');
8871
8924
  abiEvent = abiEvent[hashName];
8872
8925
  }
8873
8926
  const parsedEvent = {};
8874
8927
  parsedEvent[abiEvent.name] = {};
8875
- const keysIter = recEvent.keys[Symbol.iterator]();
8876
- const dataIter = recEvent.data[Symbol.iterator]();
8928
+ const keysIter = currentEvent.keys[Symbol.iterator]();
8929
+ const dataIter = currentEvent.data[Symbol.iterator]();
8877
8930
  const abiEventKeys = abiEvent.members?.filter((it) => it.kind === "key") || abiEvent.keys;
8878
8931
  const abiEventData = abiEvent.members?.filter((it) => it.kind === "data") || abiEvent.data;
8879
8932
  abiEventKeys.forEach((key) => {
@@ -8894,9 +8947,10 @@ function parseEvents(providerReceivedEvents, abiEvents, abiStructs, abiEnums) {
8894
8947
  parsedEvent[abiEvent.name]
8895
8948
  );
8896
8949
  });
8897
- if ("block_hash" in recEvent) parsedEvent.block_hash = recEvent.block_hash;
8898
- if ("block_number" in recEvent) parsedEvent.block_number = recEvent.block_number;
8899
- if ("transaction_hash" in recEvent) parsedEvent.transaction_hash = recEvent.transaction_hash;
8950
+ if ("block_hash" in currentEvent) parsedEvent.block_hash = currentEvent.block_hash;
8951
+ if ("block_number" in currentEvent) parsedEvent.block_number = currentEvent.block_number;
8952
+ if ("transaction_hash" in currentEvent)
8953
+ parsedEvent.transaction_hash = currentEvent.transaction_hash;
8900
8954
  acc.push(parsedEvent);
8901
8955
  return acc;
8902
8956
  }, []);
@@ -8930,8 +8984,19 @@ __export(outsideExecution_exports, {
8930
8984
  buildExecuteFromOutsideCall: () => buildExecuteFromOutsideCall,
8931
8985
  buildExecuteFromOutsideCallData: () => buildExecuteFromOutsideCallData,
8932
8986
  getOutsideCall: () => getOutsideCall,
8933
- getTypedData: () => getTypedData
8987
+ getTypedData: () => getTypedData,
8988
+ toOutsideCallV2: () => toOutsideCallV2
8934
8989
  });
8990
+ function toOutsideCallV2(call) {
8991
+ if ("calldata_len" in call) {
8992
+ return {
8993
+ To: call.to,
8994
+ Selector: call.selector,
8995
+ Calldata: call.calldata
8996
+ };
8997
+ }
8998
+ return call;
8999
+ }
8935
9000
  function getOutsideCall(call) {
8936
9001
  const callData = call.calldata ?? [];
8937
9002
  const callDataCompiled = Array.isArray(callData) ? callData : CallData.compile(callData);
@@ -9038,13 +9103,332 @@ async function supportsInterface(provider, contractAddress, interfaceId) {
9038
9103
  }
9039
9104
  }
9040
9105
 
9106
+ // src/utils/paymaster.ts
9107
+ var paymaster_exports = {};
9108
+ __export(paymaster_exports, {
9109
+ assertCallsAreStrictlyEqual: () => assertCallsAreStrictlyEqual,
9110
+ assertPaymasterTransactionSafety: () => assertPaymasterTransactionSafety,
9111
+ getDefaultPaymasterNodeUrl: () => getDefaultPaymasterNodeUrl
9112
+ });
9113
+ var getDefaultPaymasterNodeUrl = (networkName, mute = false) => {
9114
+ if (!mute) {
9115
+ logger.info("Using default public node url, please provide nodeUrl in provider options!");
9116
+ }
9117
+ const nodes = PAYMASTER_RPC_NODES[networkName ?? _NetworkName.SN_SEPOLIA];
9118
+ const randIdx = Math.floor(Math.random() * nodes.length);
9119
+ return nodes[randIdx];
9120
+ };
9121
+ var assertGasFeeFromUnsafeCalls = (unsafeCalls, fees) => {
9122
+ const unsafeCall = toOutsideCallV2(unsafeCalls[unsafeCalls.length - 1]);
9123
+ const unsafeGasTokenCalldata = CallData.toCalldata(unsafeCall.Calldata);
9124
+ const unsafeGasTokenValue = unsafeGasTokenCalldata[1];
9125
+ assert(
9126
+ BigInt(unsafeGasTokenValue) === BigInt(fees),
9127
+ "Gas token value is not equal to the provided gas fees"
9128
+ );
9129
+ };
9130
+ var assertGasTokenFromUnsafeCalls = (unsafeCalls, gasToken) => {
9131
+ const unsafeCall = toOutsideCallV2(unsafeCalls[unsafeCalls.length - 1]);
9132
+ assert(
9133
+ BigInt(unsafeCall.To) === BigInt(gasToken),
9134
+ "Gas token address is not equal to the provided gas token"
9135
+ );
9136
+ };
9137
+ function assertCallsAreStrictlyEqual(originalCalls, unsafeCalls) {
9138
+ const baseError = "Provided calls are not strictly equal to the returned calls";
9139
+ assert(
9140
+ unsafeCalls.length - 1 === originalCalls.length,
9141
+ `${baseError}: Expected ${originalCalls.length + 1} calls, got ${unsafeCalls.length}`
9142
+ );
9143
+ for (let callIndex = 0; callIndex < originalCalls.length; callIndex += 1) {
9144
+ const originalCall = originalCalls[callIndex];
9145
+ const unsafeCall = toOutsideCallV2(unsafeCalls[callIndex]);
9146
+ const normalizeAddress = (address) => {
9147
+ return toBigInt(address).toString(16).toLowerCase();
9148
+ };
9149
+ const originalAddress = normalizeAddress(originalCall.contractAddress);
9150
+ const unsafeAddress = normalizeAddress(unsafeCall.To);
9151
+ assert(
9152
+ originalAddress === unsafeAddress,
9153
+ `${baseError}: Contract address mismatch at call ${callIndex}. Expected: ${originalCall.contractAddress}, Got: ${unsafeCall.To}`
9154
+ );
9155
+ assert(
9156
+ getSelectorFromName(originalCall.entrypoint) === unsafeCall.Selector,
9157
+ `${baseError}: Entrypoint mismatch at call ${callIndex}. Expected: ${originalCall.entrypoint}, Got: ${unsafeCall.Selector}`
9158
+ );
9159
+ const originalCalldata = CallData.toCalldata(originalCall.calldata);
9160
+ const unsafeCalldata = CallData.toCalldata(unsafeCall.Calldata);
9161
+ assert(
9162
+ originalCalldata.length === unsafeCalldata.length,
9163
+ `${baseError}: Calldata length mismatch at call ${callIndex}. Expected length: ${originalCalldata.length}, Got length: ${unsafeCalldata.length}`
9164
+ );
9165
+ for (let dataIndex = 0; dataIndex < originalCalldata.length; dataIndex += 1) {
9166
+ const originalValue = BigInt(originalCalldata[dataIndex]);
9167
+ const unsafeValue = BigInt(unsafeCalldata[dataIndex]);
9168
+ assert(
9169
+ originalValue === unsafeValue,
9170
+ `${baseError}: Calldata value mismatch at call ${callIndex}, parameter ${dataIndex}. Expected: ${originalCalldata[dataIndex]}, Got: ${unsafeCalldata[dataIndex]}`
9171
+ );
9172
+ }
9173
+ }
9174
+ }
9175
+ var assertPaymasterTransactionSafety = (preparedTransaction, calls, paymasterDetails, maxFeeInGasToken) => {
9176
+ if (paymasterDetails.feeMode.mode !== "sponsored") {
9177
+ if (preparedTransaction.type === "invoke" || preparedTransaction.type === "deploy_and_invoke") {
9178
+ const unsafeCalls = "calls" in preparedTransaction.typed_data.message ? preparedTransaction.typed_data.message.calls : preparedTransaction.typed_data.message.Calls;
9179
+ assertCallsAreStrictlyEqual(calls, unsafeCalls);
9180
+ assertGasTokenFromUnsafeCalls(unsafeCalls, paymasterDetails.feeMode.gasToken);
9181
+ if (maxFeeInGasToken) {
9182
+ assert(
9183
+ preparedTransaction.fee.suggested_max_fee_in_gas_token <= maxFeeInGasToken,
9184
+ "Gas token price is too high"
9185
+ );
9186
+ assertGasFeeFromUnsafeCalls(
9187
+ unsafeCalls,
9188
+ preparedTransaction.fee.suggested_max_fee_in_gas_token
9189
+ );
9190
+ }
9191
+ }
9192
+ }
9193
+ };
9194
+
9195
+ // src/paymaster/rpc.ts
9196
+ var convertCalls = (calls) => calls.map((call) => ({
9197
+ to: call.contractAddress,
9198
+ selector: getSelectorFromName(call.entrypoint),
9199
+ calldata: CallData.toHex(call.calldata)
9200
+ }));
9201
+ var convertFeeMode = (feeMode) => {
9202
+ if (feeMode.mode === "sponsored") {
9203
+ return { mode: "sponsored" };
9204
+ }
9205
+ return { mode: "default", gas_token: feeMode.gasToken };
9206
+ };
9207
+ var convertFEE_MODE = (feeMode) => {
9208
+ if (feeMode.mode === "sponsored") {
9209
+ return { mode: "sponsored" };
9210
+ }
9211
+ return { mode: "default", gasToken: feeMode.gas_token };
9212
+ };
9213
+ var convertTimeBounds = (timeBounds) => timeBounds && timeBounds.executeAfter && timeBounds.executeBefore ? {
9214
+ execute_after: timeBounds.executeAfter.getTime().toString(),
9215
+ execute_before: timeBounds.executeBefore.getTime().toString()
9216
+ } : void 0;
9217
+ var convertTIME_BOUNDS = (timeBounds) => timeBounds && timeBounds.execute_after && timeBounds.execute_before ? {
9218
+ executeAfter: new Date(timeBounds.execute_after),
9219
+ executeBefore: new Date(timeBounds.execute_before)
9220
+ } : void 0;
9221
+ var convertEXECUTION_PARAMETERS = (parameters) => ({
9222
+ version: parameters.version,
9223
+ feeMode: convertFEE_MODE(parameters.fee_mode),
9224
+ timeBounds: convertTIME_BOUNDS(parameters.time_bounds)
9225
+ });
9226
+ var defaultOptions3 = {
9227
+ headers: { "Content-Type": "application/json" }
9228
+ };
9229
+ var PaymasterRpc = class _PaymasterRpc {
9230
+ nodeUrl;
9231
+ headers;
9232
+ baseFetch;
9233
+ requestId;
9234
+ constructor(options) {
9235
+ if (options instanceof _PaymasterRpc) {
9236
+ this.nodeUrl = options.nodeUrl;
9237
+ this.headers = { ...defaultOptions3.headers, ...options.headers };
9238
+ this.baseFetch = options.baseFetch;
9239
+ this.requestId = options.requestId;
9240
+ return;
9241
+ }
9242
+ if (options && "nodeUrl" in options && "headers" in options && "baseFetch" in options) {
9243
+ this.nodeUrl = options.nodeUrl ?? getDefaultPaymasterNodeUrl(void 0);
9244
+ this.headers = { ...defaultOptions3.headers, ...options.headers };
9245
+ this.baseFetch = options.baseFetch ?? fetch_default;
9246
+ this.requestId = 0;
9247
+ return;
9248
+ }
9249
+ const { nodeUrl, headers, baseFetch } = options || {};
9250
+ if (nodeUrl && Object.values(_NetworkName).includes(nodeUrl)) {
9251
+ this.nodeUrl = getDefaultPaymasterNodeUrl(nodeUrl, options?.default);
9252
+ } else if (nodeUrl) {
9253
+ this.nodeUrl = nodeUrl;
9254
+ } else {
9255
+ this.nodeUrl = getDefaultPaymasterNodeUrl(void 0, options?.default);
9256
+ }
9257
+ this.baseFetch = baseFetch ?? fetch_default;
9258
+ this.headers = { ...defaultOptions3.headers, ...headers };
9259
+ this.requestId = 0;
9260
+ }
9261
+ fetch(method, params, id = 0) {
9262
+ const rpcRequestBody = {
9263
+ id,
9264
+ jsonrpc: "2.0",
9265
+ method,
9266
+ ...params && { params }
9267
+ };
9268
+ return this.baseFetch(this.nodeUrl, {
9269
+ method: "POST",
9270
+ body: stringify2(rpcRequestBody),
9271
+ headers: this.headers
9272
+ });
9273
+ }
9274
+ errorHandler(method, params, rpcError, otherError) {
9275
+ if (rpcError) {
9276
+ throw new RpcError(rpcError, method, params);
9277
+ }
9278
+ if (otherError instanceof LibraryError) {
9279
+ throw otherError;
9280
+ }
9281
+ if (otherError) {
9282
+ throw Error(otherError.message);
9283
+ }
9284
+ }
9285
+ async fetchEndpoint(method, params) {
9286
+ try {
9287
+ this.requestId += 1;
9288
+ const rawResult = await this.fetch(method, params, this.requestId);
9289
+ const { error, result } = await rawResult.json();
9290
+ this.errorHandler(method, params, error);
9291
+ return result;
9292
+ } catch (error) {
9293
+ this.errorHandler(method, params, error?.response?.data, error);
9294
+ throw error;
9295
+ }
9296
+ }
9297
+ async isAvailable() {
9298
+ return this.fetchEndpoint("paymaster_isAvailable");
9299
+ }
9300
+ async buildTransaction(transaction, parameters) {
9301
+ let userTransaction;
9302
+ switch (transaction.type) {
9303
+ case "invoke":
9304
+ userTransaction = {
9305
+ ...transaction,
9306
+ invoke: {
9307
+ user_address: transaction.invoke.userAddress,
9308
+ calls: convertCalls(transaction.invoke.calls)
9309
+ }
9310
+ };
9311
+ break;
9312
+ case "deploy_and_invoke":
9313
+ userTransaction = {
9314
+ ...transaction,
9315
+ invoke: {
9316
+ user_address: transaction.invoke.userAddress,
9317
+ calls: convertCalls(transaction.invoke.calls)
9318
+ }
9319
+ };
9320
+ break;
9321
+ case "deploy":
9322
+ default:
9323
+ userTransaction = transaction;
9324
+ break;
9325
+ }
9326
+ const executionParameters = {
9327
+ version: parameters.version,
9328
+ fee_mode: convertFeeMode(parameters.feeMode),
9329
+ time_bounds: convertTimeBounds(parameters.timeBounds)
9330
+ };
9331
+ const response = await this.fetchEndpoint("paymaster_buildTransaction", {
9332
+ transaction: userTransaction,
9333
+ parameters: executionParameters
9334
+ });
9335
+ const fee = {
9336
+ gas_token_price_in_strk: BigInt(response.fee.gas_token_price_in_strk),
9337
+ estimated_fee_in_strk: BigInt(response.fee.estimated_fee_in_strk),
9338
+ estimated_fee_in_gas_token: BigInt(response.fee.estimated_fee_in_gas_token),
9339
+ suggested_max_fee_in_strk: BigInt(response.fee.suggested_max_fee_in_strk),
9340
+ suggested_max_fee_in_gas_token: BigInt(response.fee.suggested_max_fee_in_gas_token)
9341
+ };
9342
+ switch (response.type) {
9343
+ case "invoke":
9344
+ return {
9345
+ type: "invoke",
9346
+ typed_data: response.typed_data,
9347
+ parameters: convertEXECUTION_PARAMETERS(response.parameters),
9348
+ fee
9349
+ };
9350
+ case "deploy_and_invoke":
9351
+ return {
9352
+ type: "deploy_and_invoke",
9353
+ deployment: response.deployment,
9354
+ typed_data: response.typed_data,
9355
+ parameters: convertEXECUTION_PARAMETERS(response.parameters),
9356
+ fee
9357
+ };
9358
+ case "deploy":
9359
+ default:
9360
+ return {
9361
+ type: "deploy",
9362
+ deployment: response.deployment,
9363
+ parameters: convertEXECUTION_PARAMETERS(response.parameters),
9364
+ fee
9365
+ };
9366
+ }
9367
+ }
9368
+ async executeTransaction(transaction, parameters) {
9369
+ let user_transaction;
9370
+ switch (transaction.type) {
9371
+ case "invoke":
9372
+ user_transaction = {
9373
+ ...transaction,
9374
+ invoke: {
9375
+ user_address: transaction.invoke.userAddress,
9376
+ typed_data: transaction.invoke.typedData,
9377
+ signature: signatureToHexArray(transaction.invoke.signature)
9378
+ }
9379
+ };
9380
+ break;
9381
+ case "deploy_and_invoke":
9382
+ user_transaction = {
9383
+ ...transaction,
9384
+ invoke: {
9385
+ user_address: transaction.invoke.userAddress,
9386
+ typed_data: transaction.invoke.typedData,
9387
+ signature: signatureToHexArray(transaction.invoke.signature)
9388
+ }
9389
+ };
9390
+ break;
9391
+ case "deploy":
9392
+ default:
9393
+ user_transaction = transaction;
9394
+ break;
9395
+ }
9396
+ const executionParameters = {
9397
+ version: parameters.version,
9398
+ fee_mode: convertFeeMode(parameters.feeMode),
9399
+ time_bounds: convertTimeBounds(parameters.timeBounds)
9400
+ };
9401
+ return this.fetchEndpoint("paymaster_executeTransaction", {
9402
+ transaction: user_transaction,
9403
+ parameters: executionParameters
9404
+ });
9405
+ }
9406
+ async getSupportedTokens() {
9407
+ return this.fetchEndpoint("paymaster_getSupportedTokens").then(
9408
+ (tokens) => tokens.map((token) => ({
9409
+ token_address: token.token_address,
9410
+ decimals: token.decimals,
9411
+ priceInStrk: BigInt(token.price_in_strk)
9412
+ }))
9413
+ );
9414
+ }
9415
+ };
9416
+
9417
+ // src/paymaster/interface.ts
9418
+ var PaymasterInterface = class {
9419
+ };
9420
+
9421
+ // src/paymaster/index.ts
9422
+ var defaultPaymaster = new PaymasterRpc({ default: true });
9423
+
9041
9424
  // src/account/default.ts
9042
9425
  var Account = class extends RpcProvider2 {
9043
9426
  signer;
9044
9427
  address;
9045
9428
  cairoVersion;
9046
9429
  transactionVersion;
9047
- constructor(providerOrOptions, address, pkOrSigner, cairoVersion, transactionVersion = config.get("transactionVersion")) {
9430
+ paymaster;
9431
+ constructor(providerOrOptions, address, pkOrSigner, cairoVersion, transactionVersion = config.get("transactionVersion"), paymaster) {
9048
9432
  super(providerOrOptions);
9049
9433
  this.address = address.toLowerCase();
9050
9434
  this.signer = isString(pkOrSigner) || pkOrSigner instanceof Uint8Array ? new Signer(pkOrSigner) : pkOrSigner;
@@ -9052,6 +9436,7 @@ var Account = class extends RpcProvider2 {
9052
9436
  this.cairoVersion = cairoVersion.toString();
9053
9437
  }
9054
9438
  this.transactionVersion = transactionVersion;
9439
+ this.paymaster = paymaster ? new PaymasterRpc(paymaster) : defaultPaymaster;
9055
9440
  logger.debug("Account setup", {
9056
9441
  transactionVersion: this.transactionVersion,
9057
9442
  cairoVersion: this.cairoVersion,
@@ -9282,6 +9667,95 @@ var Account = class extends RpcProvider2 {
9282
9667
  }
9283
9668
  );
9284
9669
  }
9670
+ async buildPaymasterTransaction(calls, paymasterDetails) {
9671
+ if (!paymasterDetails.deploymentData) {
9672
+ const snip9Version = await this.getSnip9Version();
9673
+ if (snip9Version === OutsideExecutionVersion.UNSUPPORTED) {
9674
+ throw Error("Account is not compatible with SNIP-9");
9675
+ }
9676
+ }
9677
+ const parameters = {
9678
+ version: "0x1",
9679
+ feeMode: paymasterDetails.feeMode,
9680
+ timeBounds: paymasterDetails.timeBounds
9681
+ };
9682
+ let transaction;
9683
+ if (paymasterDetails.deploymentData) {
9684
+ if (calls.length > 0) {
9685
+ transaction = {
9686
+ type: "deploy_and_invoke",
9687
+ invoke: { userAddress: this.address, calls },
9688
+ deployment: paymasterDetails.deploymentData
9689
+ };
9690
+ } else {
9691
+ transaction = {
9692
+ type: "deploy",
9693
+ deployment: paymasterDetails.deploymentData
9694
+ };
9695
+ }
9696
+ } else {
9697
+ transaction = {
9698
+ type: "invoke",
9699
+ invoke: { userAddress: this.address, calls }
9700
+ };
9701
+ }
9702
+ return this.paymaster.buildTransaction(transaction, parameters);
9703
+ }
9704
+ async estimatePaymasterTransactionFee(calls, paymasterDetails) {
9705
+ const preparedTransaction = await this.buildPaymasterTransaction(calls, paymasterDetails);
9706
+ return preparedTransaction.fee;
9707
+ }
9708
+ async preparePaymasterTransaction(preparedTransaction) {
9709
+ let transaction;
9710
+ switch (preparedTransaction.type) {
9711
+ case "deploy_and_invoke": {
9712
+ const signature = await this.signMessage(preparedTransaction.typed_data);
9713
+ transaction = {
9714
+ type: "deploy_and_invoke",
9715
+ invoke: {
9716
+ userAddress: this.address,
9717
+ typedData: preparedTransaction.typed_data,
9718
+ signature: signatureToHexArray(signature)
9719
+ },
9720
+ deployment: preparedTransaction.deployment
9721
+ };
9722
+ break;
9723
+ }
9724
+ case "invoke": {
9725
+ const signature = await this.signMessage(preparedTransaction.typed_data);
9726
+ transaction = {
9727
+ type: "invoke",
9728
+ invoke: {
9729
+ userAddress: this.address,
9730
+ typedData: preparedTransaction.typed_data,
9731
+ signature: signatureToHexArray(signature)
9732
+ }
9733
+ };
9734
+ break;
9735
+ }
9736
+ case "deploy": {
9737
+ transaction = {
9738
+ type: "deploy",
9739
+ deployment: preparedTransaction.deployment
9740
+ };
9741
+ break;
9742
+ }
9743
+ default:
9744
+ throw Error("Invalid transaction type");
9745
+ }
9746
+ return transaction;
9747
+ }
9748
+ async executePaymasterTransaction(calls, paymasterDetails, maxFeeInGasToken) {
9749
+ const preparedTransaction = await this.buildPaymasterTransaction(calls, paymasterDetails);
9750
+ assertPaymasterTransactionSafety(
9751
+ preparedTransaction,
9752
+ calls,
9753
+ paymasterDetails,
9754
+ maxFeeInGasToken
9755
+ );
9756
+ const transaction = await this.preparePaymasterTransaction(preparedTransaction);
9757
+ return this.paymaster.executeTransaction(transaction, preparedTransaction.parameters).then((response) => ({ transaction_hash: response.transaction_hash }));
9758
+ }
9285
9759
  /**
9286
9760
  * First check if contract is already declared, if not declare it
9287
9761
  * If contract already declared returned transaction_hash is ''.
@@ -9828,8 +10302,8 @@ function onNetworkChanged(swo, callback) {
9828
10302
  // src/wallet/account.ts
9829
10303
  var WalletAccount = class _WalletAccount extends Account {
9830
10304
  walletProvider;
9831
- constructor(providerOrOptions, walletProvider, address, cairoVersion) {
9832
- super(providerOrOptions, address, "", cairoVersion);
10305
+ constructor(providerOrOptions, walletProvider, address, cairoVersion, paymaster) {
10306
+ super(providerOrOptions, address, "", cairoVersion, void 0, paymaster);
9833
10307
  this.walletProvider = walletProvider;
9834
10308
  this.walletProvider.on("accountsChanged", (res) => {
9835
10309
  if (!res) return;
@@ -9911,12 +10385,12 @@ var WalletAccount = class _WalletAccount extends Account {
9911
10385
  signMessage(typedData) {
9912
10386
  return signMessage(this.walletProvider, typedData);
9913
10387
  }
9914
- static async connect(provider, walletProvider, cairoVersion, silentMode = false) {
10388
+ static async connect(provider, walletProvider, cairoVersion, paymaster, silentMode = false) {
9915
10389
  const [accountAddress] = await requestAccounts(walletProvider, silentMode);
9916
- return new _WalletAccount(provider, walletProvider, accountAddress, cairoVersion);
10390
+ return new _WalletAccount(provider, walletProvider, accountAddress, cairoVersion, paymaster);
9917
10391
  }
9918
- static async connectSilent(provider, walletProvider, cairoVersion) {
9919
- return _WalletAccount.connect(provider, walletProvider, cairoVersion, true);
10392
+ static async connectSilent(provider, walletProvider, cairoVersion, paymaster) {
10393
+ return _WalletAccount.connect(provider, walletProvider, cairoVersion, paymaster, true);
9920
10394
  }
9921
10395
  // TODO: MISSING ESTIMATES
9922
10396
  };
@@ -10335,6 +10809,8 @@ function units(amount, simbol = "fri") {
10335
10809
  OutsideExecutionTypesV1,
10336
10810
  OutsideExecutionTypesV2,
10337
10811
  OutsideExecutionVersion,
10812
+ PaymasterInterface,
10813
+ PaymasterRpc,
10338
10814
  Provider,
10339
10815
  ProviderInterface,
10340
10816
  RPC,
@@ -10373,6 +10849,7 @@ function units(amount, simbol = "fri") {
10373
10849
  config,
10374
10850
  constants,
10375
10851
  contractClassResponseToLegacyCompiledContract,
10852
+ defaultPaymaster,
10376
10853
  defaultProvider,
10377
10854
  ec,
10378
10855
  encode,
@@ -10402,6 +10879,7 @@ function units(amount, simbol = "fri") {
10402
10879
  num,
10403
10880
  outsideExecution,
10404
10881
  parseCalldataField,
10882
+ paymaster,
10405
10883
  provider,
10406
10884
  selector,
10407
10885
  shortString,