Repository: ecadlabs/taquito
Pull request #1861 (2022-08-29 18:00:06)

1750 rpc add support for run script view endpoint
Thank you for your contribution to Taquito.

Before submitting this PR, please make sure:

- [ ] Your code builds cleanly without any errors or warnings
- [ ] You have added unit tests
- [ ] You have added integration tests (if relevant/appropriate)
- [ ] All public methods or types have TypeDoc coverage with a complete description, and ideally an @example
- [ ] You have added or updated corresponding documentation
- [ ] If relevant, you have written a first draft summary describing the change for inclusion in Release Notes. 

## Release Note Draft Snippet

__If relevant, please write a summary of your change that will be suitable for
inclusion in the Release Notes for the next Taquito release.__


github-actions[bot]: New packages have been deployed to the preview repository at https://npm.preview.tezostaquito.io/.

### Published packages:
```
npm i @taquito/local-forging@13.0.1-5339cec3--1861 --registry https://npm.preview.tezostaquito.io/
npm i @taquito/rpc@13.0.1-5339cec3--1861 --registry https://npm.preview.tezostaquito.io/
npm i @taquito/signer@13.0.1-5339cec3--1861 --registry https://npm.preview.tezostaquito.io/
npm i @taquito/taquito@13.0.1-5339cec3--1861 --registry https://npm.preview.tezostaquito.io/
npm i @taquito/remote-signer@13.0.1-5339cec3--1861 --registry https://npm.preview.tezostaquito.io/
npm i @taquito/tezbridge-wallet@13.0.1-5339cec3--1861 --registry https://npm.preview.tezostaquito.io/
npm i @taquito/michelson-encoder@13.0.1-5339cec3--1861 --registry https://npm.preview.tezostaquito.io/
npm i @taquito/contracts-library@13.0.1-5339cec3--1861 --registry https://npm.preview.tezostaquito.io/
npm i @taquito/ledger-signer@13.0.1-5339cec3--1861 --registry https://npm.preview.tezostaquito.io/
npm i @taquito/beacon-wallet@13.0.1-5339cec3--1861 --registry https://npm.preview.tezostaquito.io/
npm i @taquito/http-utils@13.0.1-5339cec3--1861 --registry https://npm.preview.tezostaquito.io/
npm i @taquito/tezbridge-signer@13.0.1-5339cec3--1861 --registry https://npm.preview.tezostaquito.io/
npm i @taquito/michel-codec@13.0.1-5339cec3--1861 --registry https://npm.preview.tezostaquito.io/
npm i @taquito/utils@13.0.1-5339cec3--1861 --registry https://npm.preview.tezostaquito.io/
npm i @taquito/tzip12@13.0.1-5339cec3--1861 --registry https://npm.preview.tezostaquito.io/
npm i @taquito/tzip16@13.0.1-5339cec3--1861 --registry https://npm.preview.tezostaquito.io/
```
<!-- Sticky Pull Request Commentdeploy-packages -->

Patch:
diff --git a/docs/batch-api.md b/docs/batch-api.md
index fa8dc0221..f465065b2 100644
--- a/docs/batch-api.md
+++ b/docs/batch-api.md
@@ -20,7 +20,12 @@ await op1.confirmation();
 await op2.confirmation();
 
 /*
- * Error Message returned by the node:
+ * Error Message returned by the node (since Kathmandu):
+ * Error while applying operation opHash: 
+ * Only one manager operation per manager per block allowed (found opHash2 with Xtez fee. 
+ * You may want to use --replace to provide adequate fee and replace it).
+ * 
+ * Error Message that was returned by the node (before Kathmandu):
  * "Error while applying operation opWH2nEcmmzUwK4T6agHg3bn9GDR7fW1ynqWL58AVRAb7aZFciD:
  * branch refused (Error:
  * Counter 1122148 already used for contract tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb (expected 1122149))"
diff --git a/docs/increase_paid_storage.md b/docs/increase_paid_storage.md
new file mode 100644
index 000000000..c6ce4a995
--- /dev/null
+++ b/docs/increase_paid_storage.md
@@ -0,0 +1,72 @@
+---
+title: Increase Paid Storage
+author: Davis Sawali
+---
+
+Increase Paid Storage is a new operation available for use starting from Protocol 14 (Kathmandu). It is a new operation that enables a payer to increase the paid storage of a smart contract by a certain byte amount.
+
+This helps resolve an issue where several operations on the same contract would fail when they are added at the same level due to the storage limit being lower than the `paid_storage_size_diff`.
+
+For more information on this change, refer to this [MR](https://gitlab.com/tezos/tezos/-/merge_requests/5605) in the Tezos codebase.
+## Examples
+Similar to other operations, the Increase Paid Storage operation will be available in the Contract API (and later, the wallet API).
+
+### Simple Usage
+```js
+const op = await Tezos.contract.increasePaidStorage({
+  amount: 2,
+  destination: 'SMART_CONTRACT_ADDRESS'
+});
+
+await op.confirmation();
+```
+- `amount` is the the number of `bytes` you want to increase the paid storage by
+- `destination` is the `KT1` address of the smart contract which storage you would like to increase
+
+After waiting for the operation confirmation, you will also have access to various getters of the operation such as `status`, `amount`, `destination`, `fee`, `gasLimit`, `errors`, `storageLimit`, `consumedMilligas`.
+
+### Usage in Batches
+```js
+const op = await Tezos.contract
+    .batch()
+    .withOrigination({
+      balance: "1",
+      code: `parameter string;
+      storage string;
+      code {CAR;
+            PUSH string "Hello ";
+            CONCAT;
+            NIL operation; PAIR};
+      `,
+      init: `"test"`
+    })
+    .withIncreasePaidStorage({
+      amount: 1,
+      destination: 'SMART_CONTRACT_ADDRESS'
+    })
+    .send();
+    
+    await op.confirmation();
+```
+
+or 
+```js
+const op = await Tezos.contract.batch([
+    {
+      kind: 'origination', 
+      balance: '1', 
+      code: SAMPLE_CODE, 
+      storage: 0 
+    },
+    { 
+      kind: 'increase_paid_storage',
+      amount: 1, 
+      destination: 'SMART_CONTRACT_ADDRESS' 
+    } 
+    ])
+    .send();
+
+await op.confirmation();
+```
+
+Both syntax will work fine for batching any operations, including `increase_paid_storage`.
\ No newline at end of file
diff --git a/packages/taquito-contracts-library/src/rpc-wrapper.ts b/packages/taquito-contracts-library/src/rpc-wrapper.ts
index e2d66976c..e002ae5b8 100644
--- a/packages/taquito-contracts-library/src/rpc-wrapper.ts
+++ b/packages/taquito-contracts-library/src/rpc-wrapper.ts
@@ -31,8 +31,10 @@ import {
   RPCOptions,
   RPCRunCodeParam,
   RPCRunOperationParam,
+  RPCRunScriptViewParam,
   RPCRunViewParam,
   RunCodeResult,
+  RunScriptViewResult,
   RunViewResult,
   SaplingDiffResponse,
   ScriptResponse,
@@ -217,6 +219,18 @@ export class RpcWrapperContractsLibrary implements RpcClientInterface {
   ): Promise<RunCodeResult> {
     return this.rpc.runCode(code, { block });
   }
+  async runScriptView(
+    { unparsing_mode = 'Readable', ...rest }: RPCRunScriptViewParam,
+    { block }: RPCOptions = defaultRPCOptions
+  ): Promise<RunScriptViewResult> {
+    return this.rpc.runScriptView(
+      {
+        unparsing_mode,
+        ...rest,
+      },
+      { block }
+    );
+  }
   async runView(
     { unparsing_mode = 'Readable', ...rest }: RPCRunViewParam,
     { block }: RPCOptions = defaultRPCOptions
diff --git a/packages/taquito-michel-codec/src/binary.ts b/packages/taquito-michel-codec/src/binary.ts
index db177d76c..4a8864090 100644
--- a/packages/taquito-michel-codec/src/binary.ts
+++ b/packages/taquito-michel-codec/src/binary.ts
@@ -185,6 +185,7 @@ const primitives: PrimID[] = [
   'view',
   'constant',
   'SUB_MUTEZ',
+  'EMIT',
 ];
 
 const primTags: { [key in PrimID]?: number } & { [key: string]: number | undefined } =
diff --git a/packages/taquito-michel-codec/src/michelson-contract.ts b/packages/taquito-michel-codec/src/michelson-contract.ts
index e8b064375..c3ea6e452 100644
--- a/packages/taquito-michel-codec/src/michelson-contract.ts
+++ b/packages/taquito-michel-codec/src/michelson-contract.ts
@@ -62,7 +62,9 @@ export class Contract {
     if (expr === null) {
       throw new InvalidTypeExpressionError('empty type expression');
     }
-    if (assertMichelsonType(expr) && assertTypeAnnotationsValid(expr)) {
+    // remove assertTypeAnnotationsValid from if block because: () => void || throw error
+    if (assertMichelsonType(expr)) {
+      assertTypeAnnotationsValid(expr)
       return expr;
     }
     throw undefined;
diff --git a/packages/taquito-michel-codec/src/michelson-typecheck.ts b/packages/taquito-michel-codec/src/michelson-typecheck.ts
index f32b3e93b..d6cdfc76d 100644
--- a/packages/taquito-michel-codec/src/michelson-typecheck.ts
+++ b/packages/taquito-michel-codec/src/michelson-typecheck.ts
@@ -661,7 +661,7 @@ function functionTypeInternal(
   function rethrow<T extends unknown[], U>(fn: (...args: T) => U) {
     return (...args: T): U => {
       try {
-        return fn(...args);
+         return fn(...args);
       } catch (err) {
         if (err instanceof MichelsonError) {
           throw new MichelsonInstructionError(instruction, stack, err.message);
@@ -2004,9 +2004,20 @@ function functionTypeInternal(
         ensurePushableType(s[0]);
         return [annotateVar({ prim: 'option', args: [instruction.args[1]] }), ...stack.slice(2)];
       }
+
       case 'MIN_BLOCK_TIME':
         return [annotateVar({ prim: 'nat' }), ...stack];
 
+      case 'EMIT': {
+        const ia = instructionAnn({ f: 1, t: 1});
+        if (instruction.args) {
+          const s = args(0, null);
+          ensureTypesEqual(s[0], instruction.args[0]);
+          return [annotate({ prim: 'operation' }, ia), ...stack.slice(1)];
+        }
+          return [annotate({ prim: 'operation'}, ia), ...stack.slice(1)];
+      }
+
       default:
         throw new MichelsonError(
           instruction as MichelsonCode,
diff --git a/packages/taquito-michel-codec/src/michelson-types.ts b/packages/taquito-michel-codec/src/michelson-types.ts
index 84be85122..c4d537f21 100644
--- a/packages/taquito-michel-codec/src/michelson-types.ts
+++ b/packages/taquito-michel-codec/src/michelson-types.ts
@@ -113,6 +113,7 @@ type MichelsonRegularInstructionID =
   | 'UPDATE'
   | 'CAST'
   | 'VIEW'
+  | 'EMIT'
   // legacy
   | 'CREATE_ACCOUNT'
   | 'STEPS_TO_QUOTA';
@@ -142,6 +143,7 @@ export type MichelsonInstruction =
   | InstrX<'LAMBDA', [MichelsonType, MichelsonType, InstructionList]>
   | InstrX<'DIP', [IntLiteral, InstructionList] | [InstructionList]>
   | InstrX<'VIEW', [StringLiteral, MichelsonType]>
+  | InstrX<'EMIT', [MichelsonType]>
   | InstrPrim<'DROP' | 'PAIR' | 'UNPAIR' | 'DUP' | 'GET' | 'UPDATE', [IntLiteral]>;
 
 // Types
diff --git a/packages/taquito-michel-codec/src/michelson-validator.ts b/packages/taquito-michel-codec/src/michelson-validator.ts
index 3e97e7dc0..4d44a2b90 100644
--- a/packages/taquito-michel-codec/src/michelson-validator.ts
+++ b/packages/taquito-michel-codec/src/michelson-validator.ts
@@ -99,6 +99,7 @@ export const instructionIDs: Record<MichelsonInstruction['prim'], true> = Object
     DROP: true,
     DUG: true,
     DUP: true,
+    EMIT: true,
     EMPTY_BIG_MAP: true,
     EMPTY_MAP: true,
     EMPTY_SET: true,
@@ -419,6 +420,15 @@ export function assertMichelsonInstruction(ex: Expr): ex is MichelsonCode {
         }
         break;
 
+      case 'EMIT':
+        if (ex.args && ex.args.length > 0) {
+          assertArgs(ex, 1);
+        } else {
+          assertArgs(ex, 0)
+        }
+        break;
+
+
       default:
         throw new MichelsonValidationError(ex, 'instruction expected');
     }
diff --git a/packages/taquito-rpc/src/opkind.ts b/packages/taquito-rpc/src/opkind.ts
index 0c3883d35..9fb1316e2 100644
--- a/packages/taquito-rpc/src/opkind.ts
+++ b/packages/taquito-rpc/src/opkind.ts
@@ -26,4 +26,6 @@ export enum OpKind {
   TX_ROLLUP_DISPATCH_TICKETS = 'tx_rollup_dispatch_tickets',
   TRANSFER_TICKET = 'transfer_ticket',
   INCREASE_PAID_STORAGE = 'increase_paid_storage',
+  VDF_REVELATION = 'vdf_revelation',
+  EVENT = 'event',
 }
diff --git a/packages/taquito-rpc/src/rpc-client-interface.ts b/packages/taquito-rpc/src/rpc-client-interface.ts
index 046c8e797..c8d806b1a 100644
--- a/packages/taquito-rpc/src/rpc-client-interface.ts
+++ b/packages/taquito-rpc/src/rpc-client-interface.ts
@@ -30,8 +30,10 @@ import {
   ProtocolsResponse,
   RPCRunCodeParam,
   RPCRunOperationParam,
+  RPCRunScriptViewParam,
   RPCRunViewParam,
   RunCodeResult,
+  RunScriptViewResult,
   RunViewResult,
   SaplingDiffResponse,
   ScriptResponse,
@@ -91,6 +93,10 @@ export interface RpcClientInterface {
   getEntrypoints(contract: string, options?: RPCOptions): Promise<EntrypointsResponse>;
   runOperation(op: RPCRunOperationParam, options?: RPCOptions): Promise<PreapplyResponse>;
   runCode(code: RPCRunCodeParam, options?: RPCOptions): Promise<RunCodeResult>;
+  runScriptView(
+    viewScriptParams: RPCRunScriptViewParam,
+    options?: RPCOptions
+  ): Promise<RunScriptViewResult>;
   runView(viewParams: RPCRunViewParam, options?: RPCOptions): Promise<RunViewResult>;
   getChainId(): Promise<string>;
   packData(
diff --git a/packages/taquito-rpc/src/rpc-client-modules/rpc-cache.ts b/packages/taquito-rpc/src/rpc-client-modules/rpc-cache.ts
index 14ff6575d..beaa7b1ec 100644
--- a/packages/taquito-rpc/src/rpc-client-modules/rpc-cache.ts
+++ b/packages/taquito-rpc/src/rpc-client-modules/rpc-cache.ts
@@ -32,8 +32,10 @@ import {
   ProtocolsResponse,
   RPCRunCodeParam,
   RPCRunOperationParam,
+  RPCRunScriptViewParam,
   RPCRunViewParam,
   RunCodeResult,
+  RunScriptViewResult,
   RunViewResult,
   SaplingDiffResponse,
   ScriptResponse,
@@ -839,6 +841,26 @@ export class RpcClientCache implements RpcClientInterface {
     return this.rpcClient.runCode(code, { block });
   }
 
+  /**
+   * @param viewScriptParams Parameters of the script view to run
+   * @param options contains generic configuration for rpc calls
+   *
+   * @description Simulate a call to a michelson view
+   *
+   */
+  async runScriptView(
+    { unparsing_mode = 'Readable', ...rest }: RPCRunScriptViewParam,
+    { block }: RPCOptions = defaultRPCOptions
+  ): Promise<RunScriptViewResult> {
+    return this.rpcClient.runScriptView(
+      {
+        unparsing_mode,
+        ...rest,
+      },
+      { block }
+    );
+  }
+
   /**
    * @param viewParams Parameters of the view to run
    * @param options contains generic configuration for rpc calls
diff --git a/packages/taquito-rpc/src/taquito-rpc.ts b/packages/taquito-rpc/src/taquito-rpc.ts
index c6c342b31..e295ddd0c 100644
--- a/packages/taquito-rpc/src/taquito-rpc.ts
+++ b/packages/taquito-rpc/src/taquito-rpc.ts
@@ -44,8 +44,10 @@ import {
   RPCRunCodeParam,
   RPCRunOperationParam,
   RPCRunViewParam,
+  RPCRunScriptViewParam,
   RunCodeResult,
   RunViewResult,
+  RunScriptViewResult,
   SaplingDiffResponse,
   ScriptResponse,
   StorageResponse,
@@ -825,6 +827,31 @@ export class RpcClient implements RpcClientInterface {
     return response;
   }
 
+  /**
+   * @param viewScriptParams Parameters of the script view to run
+   * @param options contains generic configuration for rpc calls
+   *
+   * @description Simulate a call to a michelson view
+   *
+   */
+  async runScriptView(
+    { unparsing_mode = 'Readable', ...rest }: RPCRunScriptViewParam,
+    { block }: RPCOptions = defaultRPCOptions
+  ): Promise<RunScriptViewResult> {
+    return this.httpBackend.createRequest<any>(
+      {
+        url: this.createURL(
+          `/chains/${this.chain}/blocks/${block}/helpers/scripts/run_script_view`
+        ),
+        method: 'POST',
+      },
+      {
+        unparsing_mode,
+        ...rest,
+      }
+    );
+  }
+
   /**
    * @param viewParams Parameters of the view to run
    * @param options contains generic configuration for rpc calls
diff --git a/packages/taquito-rpc/src/types.ts b/packages/taquito-rpc/src/types.ts
index eec9cbb9c..fccb44ea0 100644
--- a/packages/taquito-rpc/src/types.ts
+++ b/packages/taquito-rpc/src/types.ts
@@ -106,6 +106,9 @@ export interface DelegatesResponse {
   deactivated: boolean;
   grace_period: number;
   voting_power?: BigNumber;
+  current_ballot?: OperationContentsBallotEnum;
+  current_proposals?: string[];
+  remaining_proposals?: number;
 }
 
 interface Frozenbalancebycycle {
@@ -223,6 +226,11 @@ export interface OperationContentsRevelation {
   nonce: string;
 }
 
+export interface OperationContentsVdfRevelation {
+  kind: OpKind.VDF_REVELATION;
+  solution: string[];
+}
+
 export interface OperationContentsDoubleEndorsement {
   kind: OpKind.DOUBLE_ENDORSEMENT_EVIDENCE;
   op1: InlinedEndorsement;
@@ -439,6 +447,7 @@ export type OperationContents =
   | OperationContentsPreEndorsement
   | OperationContentsDoublePreEndorsement
   | OperationContentsRevelation
+  | OperationContentsVdfRevelation
   | OperationContentsDoubleEndorsement
   | OperationContentsDoubleBaking
   | OperationContentsActivateAccount
@@ -834,6 +843,12 @@ export interface OperationContentsAndResultIncreasePaidStorage {
   metadata: OperationContentsAndResultMetadataIncreasePaidStorage;
 }
 
+export interface OperationContentsAndResultVdfRevelation {
+  kind: OpKind.VDF_REVELATION;
+  solution: string[];
+  metadata: OperationContentsAndResultMetadata;
+}
+
 export type OperationContentsAndResult =
   | OperationContentsAndResultEndorsement
   | OperationContentsAndResultPreEndorsement
@@ -860,7 +875,8 @@ export type OperationContentsAndResult =
   | OperationContentsAndResultTxRollupRemoveCommitment
   | OperationContentsAndResultTxRollupRejection
   | OperationContentsAndResultTransferTicket
-  | OperationContentsAndResultIncreasePaidStorage;
+  | OperationContentsAndResultIncreasePaidStorage
+  | OperationContentsAndResultVdfRevelation;
 
 export enum OPERATION_METADATA {
   TOO_LARGE = 'too large',
@@ -1058,9 +1074,15 @@ export interface ScriptedContracts {
   storage: MichelsonV1Expression;
 }
 
-export interface BondId {
-  tx_rollup: string;
-}
+export type BondId =
+  | {
+      sc_rollup?: never;
+      tx_rollup: string;
+    }
+  | {
+      sc_rollup: string;
+      tx_rollup?: never;
+    };
 
 export interface OperationBalanceUpdatesItem {
   kind: BalanceUpdateKindEnum;
@@ -1089,7 +1111,8 @@ export type InternalOperationResultKindEnum =
   | OpKind.REVEAL
   | OpKind.TRANSACTION
   | OpKind.ORIGINATION
-  | OpKind.DELEGATION;
+  | OpKind.DELEGATION
+  | OpKind.EVENT;
 
 export type SuccessfulManagerOperationResultKindEnum =
   | OpKind.REVEAL
@@ -1101,7 +1124,8 @@ export type InternalOperationResultEnum =
   | OperationResultReveal
   | OperationResultTransaction
   | OperationResultDelegation
-  | OperationResultOrigination;
+  | OperationResultOrigination
+  | OperationResultEvent;
 
 export interface OperationResultTxRollupOrigination {
   status: OperationResultStatusEnum;
@@ -1273,6 +1297,9 @@ export interface InternalOperationResult {
   value?: MichelsonV1Expression;
   limit?: string;
   result: InternalOperationResultEnum;
+  type?: MichelsonV1Expression;
+  tag?: string;
+  payload?: MichelsonV1Expression;
 }
 
 export interface SuccessfulManagerOperationResult {
@@ -1412,6 +1439,12 @@ export interface OperationResultOrigination {
   lazy_storage_diff?: LazyStorageDiff[];
 }
 
+export interface OperationResultEvent {
+  status: OperationResultStatusEnum;
+  consumed_milligas?: string;
+  errors?: TezosGenericOperationError[];
+}
+
 export interface OperationContentsAndResultMetadataOrigination {
   balance_updates: OperationMetadataBalanceUpdates[];
   operation_result: OperationResultOrigination;
@@ -1689,6 +1722,24 @@ export type RunCodeResult = {
   lazy_storage_diff?: LazyStorageDiff;
 };
 
+export type RPCRunScriptViewParam = {
+  contract: string;
+  view: string;
+  input: MichelsonV1Expression;
+  unlimited_gas?: boolean;
+  chain_id: string;
+  source?: string;
+  payer?: string;
+  gas?: string;
+  unparsing_mode?: UnparsingModeEnum;
+  now?: string;
+  level?: string;
+};
+
+export type RunScriptViewResult = {
+  data: MichelsonV1Expression;
+};
+
 export type RPCRunViewParam = {
   contract: string;
   entrypoint: string;
diff --git a/packages/taquito/src/batch/rpc-batch-provider.ts b/packages/taquito/src/batch/rpc-batch-provider.ts
index a168ab651..eca848eb2 100644
--- a/packages/taquito/src/batch/rpc-batch-provider.ts
+++ b/packages/taquito/src/batch/rpc-batch-provider.ts
@@ -11,6 +11,7 @@ import {
   createTransferOperation,
   createTxRollupBatchOperation,
   createTransferTicketOperation,
+  createIncreasePaidStorageOperation,
 } from '../contract/prepare';
 import { BatchOperation } from '../operations/batch-operation';
 import { OperationEmitter } from '../operations/operation-emitter';
@@ -28,6 +29,7 @@ import {
   TxRollupOriginateParams,
   TxRollupBatchParams,
   TransferTicketParams,
+  IncreasePaidStorageParams,
 } from '../operations/types';
 import { OpKind } from '@taquito/rpc';
 import { ContractMethodObject } from '../contract/contract-methods/contract-method-object-param';
@@ -87,7 +89,7 @@ export class OperationBatch extends OperationEmitter {
       throw new InvalidContractAddressError(params.destination);
     }
     this.operations.push({ kind: OpKind.TRANSFER_TICKET, ...params });
-    return this
+    return this;
   }
 
   /**
@@ -157,6 +159,17 @@ export class OperationBatch extends OperationEmitter {
     return this;
   }
 
+  /**
+   *
+   * @description Add an operation to increase paid storage to the batch
+   *
+   * @param params IncreasePaidStorage operation parameter
+   */
+  withIncreasePaidStorage(params: IncreasePaidStorageParams) {
+    this.operations.push({ kind: OpKind.INCREASE_PAID_STORAGE, ...params });
+    return this;
+  }
+
   /**
    *
    * @description Add an operation to originate a rollup to the batch
@@ -203,6 +216,10 @@ export class OperationBatch extends OperationEmitter {
         return createRegisterGlobalConstantOperation({
           ...param,
         });
+      case OpKind.INCREASE_PAID_STORAGE:
+        return createIncreasePaidStorageOperation({
+          ...param,
+        });
       case OpKind.TX_ROLLUP_ORIGINATION:
         return createTxRollupOriginationOperation({
           ...param,
@@ -213,8 +230,8 @@ export class OperationBatch extends OperationEmitter {
         });
       case OpKind.TRANSFER_TICKET:
         return createTransferTicketOperation({
-          ...param
-        })
+          ...param,
+        });
       default:
         throw new InvalidOperationKindError((param as any).kind);
     }
@@ -244,6 +261,9 @@ export class OperationBatch extends OperationEmitter {
         case OpKind.REGISTER_GLOBAL_CONSTANT:
           this.withRegisterGlobalConstant(param);
           break;
+        case OpKind.INCREASE_PAID_STORAGE:
+          this.withIncreasePaidStorage(param);
+          break;
         case OpKind.TX_ROLLUP_ORIGINATION:
           this.withTxRollupOrigination(param);
           break;
diff --git a/packages/taquito/src/contract/contract-methods/contract-on-chain-view.ts b/packages/taquito/src/contract/contract-methods/contract-on-chain-view.ts
index dd034add7..7f055cb8f 100644
--- a/packages/taquito/src/contract/contract-methods/contract-on-chain-view.ts
+++ b/packages/taquito/src/contract/contract-methods/contract-on-chain-view.ts
@@ -4,6 +4,7 @@ import {
   MichelsonV1ExpressionExtended,
   RpcClientInterface,
   RPCRunCodeParam,
+  RPCRunScriptViewParam,
 } from '@taquito/rpc';
 import { validateAddress, ValidationResult } from '@taquito/utils';
 import { TzReadProvider } from '../../read-provider/interface';
@@ -13,6 +14,7 @@ import {
   ViewSimulationError,
   validateAndExtractFailwith,
 } from '../errors';
+import { Protocols } from '../../constants';
 
 const runCodeHelper = (
   viewArgsType: MichelsonV1ExpressionExtended,
@@ -83,27 +85,48 @@ export class OnChainView {
    * @param executionContext.viewCaller the contract address which is the caller of view.
    */
   async executeView(executionContext: ExecutionContextParams) {
-    this.verifyContextExecution(executionContext);
-    const balance = (await this._readProvider.getBalance(this._contractAddress, 'head')).toString();
-    const chainId = await this._readProvider.getChainId();
-    const storage = await this._readProvider.getStorage(this._contractAddress, 'head');
-    return this.executeViewAndDecodeResult(
-      runCodeHelper(
-        this._smartContractViewSchema.viewArgsType,
-        this._smartContractViewSchema.viewReturnType,
-        this._contractStorageType,
-        this.adaptViewCodeToContext(
-          this._smartContractViewSchema.instructions,
-          executionContext.viewCaller,
-          balance
+    const protocol = (await this._rpc.getProtocols()).protocol;
+    if (protocol === Protocols.PtKathman) {
+      this.verifyContextExecution(executionContext);
+      const chainId = await this._readProvider.getChainId();
+      const viewArgs = this.transformArgsToMichelson();
+      const scriptView: RPCRunScriptViewParam = {
+        contract: this._contractAddress,
+        view: this._smartContractViewSchema.viewName,
+        input: viewArgs,
+        chain_id: chainId,
+        source: executionContext.viewCaller,
+      };
+      if (executionContext.source) {
+        scriptView.payer = executionContext.source;
+      }
+      return this.executeViewAndDecodeResult(scriptView, protocol);
+    } else {
+      this.verifyContextExecution(executionContext);
+      const balance = (
+        await this._readProvider.getBalance(this._contractAddress, 'head')
+      ).toString();
+      const chainId = await this._readProvider.getChainId();
+      const storage = await this._readProvider.getStorage(this._contractAddress, 'head');
+      return this.executeViewAndDecodeResult(
+        runCodeHelper(
+          this._smartContractViewSchema.viewArgsType,
+          this._smartContractViewSchema.viewReturnType,
+          this._contractStorageType,
+          this.adaptViewCodeToContext(
+            this._smartContractViewSchema.instructions,
+            executionContext.viewCaller,
+            balance
+          ),
+          this.transformArgsToMichelson(),
+          storage,
+          balance,
+          chainId,
+          executionContext.source
         ),
-        this.transformArgsToMichelson(),
-        storage,
-        balance,
-        chainId,
-        executionContext.source
-      )
-    );
+        protocol
+      );
+    }
   }
 
   private verifyContextExecution(executionContext: ExecutionContextParams) {
@@ -174,29 +197,54 @@ export class OnChainView {
     return instructions;
   }
 
-  private async executeViewAndDecodeResult(viewScript: RPCRunCodeParam) {
-    let storage: MichelsonV1ExpressionExtended;
-    try {
-      storage = (await this._rpc.runCode(viewScript)).storage as MichelsonV1ExpressionExtended;
-    } catch (error: any) {
-      const failWith = validateAndExtractFailwith(error);
-      throw failWith
-        ? new ViewSimulationError(
-            `The simulation of the on-chain view named ${
-              this._smartContractViewSchema.viewName
-            } failed with: ${JSON.stringify(failWith)}`,
-            this._smartContractViewSchema.viewName,
-            failWith,
-            error
-          )
-        : error;
-    }
-    if (!storage.args) {
-      throw new ViewSimulationError(
-        `View simulation failed with an invalid result: ${storage}`,
-        this._smartContractViewSchema.viewName
-      );
+  private async executeViewAndDecodeResult(
+    viewScript: RPCRunScriptViewParam | RPCRunCodeParam,
+    protocol: string
+  ) {
+    if (protocol === Protocols.PtKathman) {
+      let storage: MichelsonV1ExpressionExtended;
+      try {
+        storage = (await this._rpc.runScriptView(viewScript as RPCRunScriptViewParam))
+          .data as MichelsonV1ExpressionExtended;
+      } catch (error: any) {
+        const failWith = validateAndExtractFailwith(error);
+        throw failWith
+          ? new ViewSimulationError(
+              `The simulation of the on-chain view named ${
+                this._smartContractViewSchema.viewName
+              } failed with: ${JSON.stringify(failWith)}`,
+              this._smartContractViewSchema.viewName,
+              failWith,
+              error
+            )
+          : error;
+      }
+      return this._smartContractViewSchema.decodeViewResult(storage);
+    } else {
+      let storage: MichelsonV1ExpressionExtended;
+      try {
+        storage = (await this._rpc.runCode(viewScript as RPCRunCodeParam))
+          .storage as MichelsonV1ExpressionExtended;
+      } catch (error: any) {
+        const failWith = validateAndExtractFailwith(error);
+        throw failWith
+          ? new ViewSimulationError(
+              `The simulation of the on-chain view named ${
+                this._smartContractViewSchema.viewName
+              } failed with: ${JSON.stringify(failWith)}`,
+              this._smartContractViewSchema.viewName,
+              failWith,
+              error
+            )
+          : error;
+      }
+      if (!storage.args) {
+        throw new ViewSimulationError(
+          `View simulation failed with an invalid result: ${storage}`,
+          this._smartContractViewSchema.viewName
+        );
+      }
+      return this._smartContractViewSchema.decodeViewResult(storage.args[0]);
     }
-    return this._smartContractViewSchema.decodeViewResult(storage.args[0]);
   }
 }
diff --git a/packages/taquito/src/contract/interface.ts b/packages/taquito/src/contract/interface.ts
index f15150c16..799456ef4 100644
--- a/packages/taquito/src/contract/interface.ts
+++ b/packages/taquito/src/contract/interface.ts
@@ -18,9 +18,11 @@ import {
   RegisterGlobalConstantParams,
   TxRollupOriginateParams,
   TxRollupBatchParams,
+  IncreasePaidStorageParams,
 } from '../operations/types';
 import { ContractAbstraction, ContractStorageType, DefaultContractType } from './contract';
 import { TxRollupBatchOperation } from '../operations/tx-rollup-batch-operation';
+import { IncreasePaidStorageOperation } from '../operations/increase-paid-storage-operation';
 
 export type ContractSchema = Schema | unknown;
 
@@ -180,6 +182,16 @@ export interface ContractProvider extends StorageProvider {
     params: RegisterGlobalConstantParams
   ): Promise<RegisterGlobalConstantOperation>;
 
+  /**
+   *
+   * @description Increase the amount of bytes in a smart contract storage by paying a fee
+   *
+   * @returns An operation handle with the result from the rpc node
+   *
+   * @param params IncreasePaidStorage operation parameter
+   */
+  increasePaidStorage(params: IncreasePaidStorageParams): Promise<IncreasePaidStorageOperation>;
+
   /**
    *
    * @description Originate a new tx rollup. Will sign and inject an operation using the current context
diff --git a/packages/taquito/src/contract/prepare.ts b/packages/taquito/src/contract/prepare.ts
index 87fd74ac7..17366de72 100644
--- a/packages/taquito/src/contract/prepare.ts
+++ b/packages/taquito/src/contract/prepare.ts
@@ -19,6 +19,8 @@ import {
   RPCTxRollupBatchOperation,
   TransferTicketParams,
   RPCTransferTicketOperation,
+  IncreasePaidStorageParams,
+  RPCIncreasePaidStorageOperation,
 } from '../operations/types';
 import { DEFAULT_FEE, DEFAULT_GAS_LIMIT, DEFAULT_STORAGE_LIMIT } from '../constants';
 import { format } from '../format';
@@ -218,7 +220,7 @@ export const createTransferTicketOperation = async ({
   source,
   fee,
   gasLimit,
-  storageLimit
+  storageLimit,
 }: TransferTicketParams) => {
   return {
     kind: OpKind.TRANSFER_TICKET,
@@ -231,6 +233,25 @@ export const createTransferTicketOperation = async ({
     ticket_ticketer: ticketTicketer,
     ticket_amount: ticketAmount,
     destination,
-    entrypoint
-  } as RPCTransferTicketOperation
-}
+    entrypoint,
+  } as RPCTransferTicketOperation;
+};
+
+export const createIncreasePaidStorageOperation = async ({
+  source,
+  fee,
+  gasLimit,
+  storageLimit,
+  amount,
+  destination,
+}: IncreasePaidStorageParams) => {
+  return {
+    kind: OpKind.INCREASE_PAID_STORAGE,
+    source,
+    fee,
+    gas_limit: gasLimit,
+    storage_limit: storageLimit,
+    amount,
+    destination,
+  } as RPCIncreasePaidStorageOperation;
+};
diff --git a/packages/taquito/src/contract/rpc-contract-provider.ts b/packages/taquito/src/contract/rpc-contract-provider.ts
index 6f1ca7558..835b35247 100644
--- a/packages/taquito/src/contract/rpc-contract-provider.ts
+++ b/packages/taquito/src/contract/rpc-contract-provider.ts
@@ -24,6 +24,7 @@ import {
   withKind,
   TxRollupBatchParams,
   TransferTicketParams,
+  IncreasePaidStorageParams,
 } from '../operations/types';
 import { DefaultContractType, ContractStorageType, ContractAbstraction } from './contract';
 import { InvalidDelegationSource, RevealOperationError } from './errors';
@@ -38,6 +39,7 @@ import {
   createTransferOperation,
   createTxRollupBatchOperation,
   createTransferTicketOperation,
+  createIncreasePaidStorageOperation,
 } from './prepare';
 import { smartContractAbstractionSemantic } from './semantic';
 import {
@@ -51,6 +53,8 @@ import { EstimationProvider } from '../estimate/estimate-provider-interface';
 import { TxRollupOriginationOperation } from '../operations/tx-rollup-origination-operation';
 import { TxRollupBatchOperation } from '../operations/tx-rollup-batch-operation';
 import { TransferTicketOperation } from '../operations/transfer-ticket-operation';
+import { IncreasePaidStorageOperation } from '../operations/increase-paid-storage-operation';
+
 export class RpcContractProvider
   extends OperationEmitter
   implements ContractProvider, StorageProvider
@@ -110,7 +114,7 @@ export class RpcContractProvider
 
     let contractSchema: Schema;
     if (Schema.isSchema(schema as Schema)) {
-      contractSchema = schema as Schema
+      contractSchema = schema as Schema;
     } else {
       contractSchema = Schema.fromRPCResponse({ script: schema as ScriptResponse });
     }
@@ -406,17 +410,20 @@ export class RpcContractProvider
     }
 
     const publicKeyHash = await this.signer.publicKeyHash();
-    const estimate = await this.estimate(params, this.estimator.transferTicket.bind(this.estimator));
+    const estimate = await this.estimate(
+      params,
+      this.estimator.transferTicket.bind(this.estimator)
+    );
     const operation = await createTransferTicketOperation({
       ...params,
       ...estimate,
     });
-    const source = params.source ?? publicKeyHash
+    const source = params.source ?? publicKeyHash;
     const ops = await this.addRevealOperationIfNeeded(operation, publicKeyHash);
-    const prepared = await this.prepareOperation({ operation: ops, source: params.source});
+    const prepared = await this.prepareOperation({ operation: ops, source: params.source });
     const opBytes = await this.forge(prepared);
     const { hash, context, forgedBytes, opResponse } = await this.signAndInject(opBytes);
-    return new TransferTicketOperation(hash, operation, source, forgedBytes, opResponse, context)
+    return new TransferTicketOperation(hash, operation, source, forgedBytes, opResponse, context);
   }
 
   /**
@@ -482,6 +489,38 @@ export class RpcContractProvider
     );
   }
 
+  /**
+   *
+   * @description Increase the paid storage of a smart contract
+   *
+   * @returns An operation handle with the result from the rpc node
+   *
+   * @param params increasePaidStorage operation parameter
+   */
+  async increasePaidStorage(params: IncreasePaidStorageParams) {
+    const publicKeyHash = await this.signer.publicKeyHash();
+    const estimate = await this.estimate(
+      params,
+      this.estimator.increasePaidStorage.bind(this.estimator)
+    );
+    const operation = await createIncreasePaidStorageOperation({
+      ...params,
+      ...estimate,
+    });
+    const ops = await this.addRevealOperationIfNeeded(operation, publicKeyHash);
+    const prepared = await this.prepareOperation({ operation: ops, source: publicKeyHash });
+    const opBytes = await this.forge(prepared);
+    const { hash, context, forgedBytes, opResponse } = await this.signAndInject(opBytes);
+    return new IncreasePaidStorageOperation(
+      hash,
+      operation,
+      publicKeyHash,
+      forgedBytes,
+      opResponse,
+      context
+    );
+  }
+
   /**
    *
    * @description Originate a new tx rollup. Will sign and inject an operation using the current context
diff --git a/packages/taquito/src/estimate/estimate-provider-interface.ts b/packages/taquito/src/estimate/estimate-provider-interface.ts
index 6f21e9e63..a5c64b7cd 100644
--- a/packages/taquito/src/estimate/estimate-provider-interface.ts
+++ b/packages/taquito/src/estimate/estimate-provider-interface.ts
@@ -11,6 +11,7 @@ import {
   TxRollupOriginateParams,
   TxRollupBatchParams,
   TransferTicketParams,
+  IncreasePaidStorageParams,
 } from '../operations/types';
 import { Estimate } from './estimate';
 
@@ -81,12 +82,22 @@ export interface EstimationProvider {
    *
    * @description Estimate gasLimit, storageLimit and fees for registering an expression (registerGlobalConstant operation)
    *
-   * @returns An estimation of gasLimit, storageLimit and fees for the operation or undefined if the account is already revealed
+   * @returns An estimation of gasLimit, storageLimit and fees for the operation
    *
    * @param params registerGlobalConstant operation parameter
    */
   registerGlobalConstant(params: RegisterGlobalConstantParams): Promise<Estimate>;
 
+  /**
+   *
+   * @description Estimate gasLimit, storageLimit and fees for an increase paid storage operation
+   *
+   * @returns An estimation of gasLimit, storageLimit, and fees for the operation
+   *
+   * @param Estimate
+   */
+  increasePaidStorage(params: IncreasePaidStorageParams): Promise<Estimate>;
+
   /**
    *
    * @description Estimate gasLimit, storageLimit and fees for a tx rollup origination operation
diff --git a/packages/taquito/src/estimate/rpc-estimate-provider.ts b/packages/taquito/src/estimate/rpc-estimate-provider.ts
index e31f8614a..660255b88 100644
--- a/packages/taquito/src/estimate/rpc-estimate-provider.ts
+++ b/packages/taquito/src/estimate/rpc-estimate-provider.ts
@@ -21,6 +21,7 @@ import {
   TxRollupOriginateParams,
   TxRollupBatchParams,
   TransferTicketParams,
+  IncreasePaidStorageParams,
 } from '../operations/types';
 import { Estimate, EstimateProperties } from './estimate';
 import { EstimationProvider } from '../estimate/estimate-provider-interface';
@@ -34,6 +35,7 @@ import {
   createTxRollupOriginationOperation,
   createTxRollupBatchOperation,
   createTransferTicketOperation,
+  createIncreasePaidStorageOperation,
 } from '../contract/prepare';
 import {
   validateAddress,
@@ -442,6 +444,14 @@ export class RPCEstimateProvider extends OperationEmitter implements EstimationP
             })
           );
           break;
+        case OpKind.INCREASE_PAID_STORAGE:
+          operations.push(
+            await createIncreasePaidStorageOperation({
+              ...param,
+              ...mergeLimits(param, DEFAULT_PARAMS),
+            })
+          );
+          break;
         default:
           throw new InvalidOperationKindError((params as any).kind);
       }
@@ -550,6 +560,37 @@ export class RPCEstimateProvider extends OperationEmitter implements EstimationP
     return Estimate.createEstimateInstanceFromProperties(estimateProperties);
   }
 
+  /**
+   *
+   * @description Estimate gasLimit, storageLimit, and fees for an increasePaidStorage operation
+   *
+   * @returns An estimation of gasLimit, storageLimit, and fees for the operation
+   *
+   * @param params increasePaidStorage operation parameters
+   */
+  async increasePaidStorage(params: IncreasePaidStorageParams) {
+    const { fee, storageLimit, gasLimit, ...rest } = params;
+    const pkh = (await this.getKeys()).publicKeyHash;
+
+    const protocolConstants = await this.context.readProvider.getProtocolConstants('head');
+    const DEFAULT_PARAMS = await this.getAccountLimits(pkh, protocolConstants);
+    const op = await createIncreasePaidStorageOperation({
+      ...rest,
+      ...mergeLimits({ fee, storageLimit, gasLimit }, DEFAULT_PARAMS),
+    });
+    const isRevealNeeded = await this.isRevealOpNeeded([op], pkh);
+    const ops = isRevealNeeded ? await this.addRevealOp([op], pkh) : op;
+    const estimateProperties = await this.prepareEstimate(
+      { operation: ops, source: pkh },
+      protocolConstants,
+      pkh
+    );
+    if (isRevealNeeded) {
+      estimateProperties.shift();
+    }
+    return Estimate.createEstimateInstanceFromProperties(estimateProperties);
+  }
+
   /**
    *
    * @description Estimate gasLimit, storageLimit and fees for a rollup origination operation
diff --git a/packages/taquito/src/operations/increase-paid-storage-operation.ts b/packages/taquito/src/operations/increase-paid-storage-operation.ts
new file mode 100644
index 000000000..eb255d21b
--- /dev/null
+++ b/packages/taquito/src/operations/increase-paid-storage-operation.ts
@@ -0,0 +1,80 @@
+import {
+  OperationContentsAndResult,
+  OperationContentsAndResultIncreasePaidStorage,
+} from '@taquito/rpc';
+import { Context } from '../context';
+import { Operation } from './operations';
+import {
+  FeeConsumingOperation,
+  ForgedBytes,
+  GasConsumingOperation,
+  RPCIncreasePaidStorageOperation,
+  StorageConsumingOperation,
+} from './types';
+
+/**
+ *
+ * @description IncreasePaidStorageOperation provides utility functions to fetch a new operation of kind increase_paid_storage
+ *
+ */
+
+export class IncreasePaidStorageOperation
+  extends Operation
+  implements GasConsumingOperation, StorageConsumingOperation, FeeConsumingOperation
+{
+  constructor(
+    hash: string,
+    private readonly params: RPCIncreasePaidStorageOperation,
+    public readonly source: string,
+    raw: ForgedBytes,
+    results: OperationContentsAndResult[],
+    context: Context
+  ) {
+    super(hash, raw, results, context);
+  }
+
+  get operationResults() {
+    const increasePaidStorageOp =
+      Array.isArray(this.results) &&
+      (this.results.find(
+        (op) => op.kind === 'increase_paid_storage'
+      ) as OperationContentsAndResultIncreasePaidStorage);
+    const result =
+      increasePaidStorageOp &&
+      increasePaidStorageOp.metadata &&
+      increasePaidStorageOp.metadata.operation_result;
+    return result ? result : undefined;
+  }
+
+  get status() {
+    return this.operationResults?.status ?? 'unknown';
+  }
+
+  get fee() {
+    return this.params.fee;
+  }
+
+  get gasLimit() {
+    return this.params.gas_limit;
+  }
+
+  get storageLimit() {
+    return this.params.storage_limit;
+  }
+
+  get errors() {
+    return this.operationResults?.errors;
+  }
+
+  get consumedMilliGas() {
+    return this.operationResults?.consumed_milligas;
+  }
+
+  get amount() {
+    return this.params.amount;
+  }
+
+  get destination() {
+    return this.params.destination;
+  }
+}
diff --git a/packages/taquito/src/operations/operation-emitter.ts b/packages/taquito/src/operations/operation-emitter.ts
index 5dce93daa..9f7459d97 100644
--- a/packages/taquito/src/operations/operation-emitter.ts
+++ b/packages/taquito/src/operations/operation-emitter.ts
@@ -159,8 +159,15 @@ export abstract class OperationEmitter {
               ticket_amount: `${op.ticket_amount}`,
               ...getSource(op),
               ...getFee(op),
+            };
+          case OpKind.INCREASE_PAID_STORAGE:
+            return {
+              ...op,
+              amount: `${op.amount}`,
+              ...getSource(op),
+              ...getFee(op),
+            };
 
-            }
           default:
             throw new InvalidOperationKindError((op as any).kind);
         }
diff --git a/packages/taquito/src/operations/types.ts b/packages/taquito/src/operations/types.ts
index 0f521986a..9f7de84b7 100644
--- a/packages/taquito/src/operations/types.ts
+++ b/packages/taquito/src/operations/types.ts
@@ -16,6 +16,7 @@ export type ParamsWithKind =
   | withKind<TransferParams, OpKind.TRANSACTION>
   | withKind<ActivationParams, OpKind.ACTIVATION>
   | withKind<RegisterGlobalConstantParams, OpKind.REGISTER_GLOBAL_CONSTANT>
+  | withKind<IncreasePaidStorageParams, OpKind.INCREASE_PAID_STORAGE>
   | withKind<TxRollupOriginateParams, OpKind.TX_ROLLUP_ORIGINATION>
   | withKind<TxRollupBatchParams, OpKind.TX_ROLLUP_SUBMIT_BATCH>
   | withKind<TransferTicketParams, OpKind.TRANSFER_TICKET>;
@@ -52,6 +53,7 @@ export type RPCOpWithFee =
   | RPCDelegateOperation
   | RPCRevealOperation
   | RPCRegisterGlobalConstantOperation
+  | RPCIncreasePaidStorageOperation
   | RPCTxRollupOriginationOperation
   | RPCTxRollupBatchOperation
   | RPCTransferTicketOperation;
@@ -61,6 +63,7 @@ export type RPCOpWithSource =
   | RPCDelegateOperation
   | RPCRevealOperation
   | RPCRegisterGlobalConstantOperation
+  | RPCIncreasePaidStorageOperation
   | RPCTxRollupOriginationOperation
   | RPCTxRollupBatchOperation
   | RPCTransferTicketOperation;
@@ -75,6 +78,7 @@ export const isOpWithFee = <T extends { kind: OpKind }>(
       'origination',
       'reveal',
       'register_global_constant',
+      'increase_paid_storage',
       'tx_rollup_origination',
       'tx_rollup_submit_batch',
       'transfer_ticket',
@@ -91,6 +95,7 @@ export const isOpRequireReveal = <T extends { kind: OpKind }>(
       'delegation',
       'origination',
       'register_global_constant',
+      'increase_paid_storage',
       'tx_rollup_origination',
       'tx_rollup_submit_batch',
       'transfer_ticket',
@@ -337,6 +342,18 @@ export interface TxRollupOriginateParams {
   storageLimit?: number;
 }
 
+/**
+ * @description Parameters for the `txRollupSubmitBatch` method
+ */
+export interface TxRollupBatchParams {
+  source?: string;
+  fee?: number;
+  gasLimit?: number;
+  storageLimit?: number;
+  rollup: string;
+  content: string;
+}
+
 /**
  * @description RPC tx rollup batch operation
  */
@@ -384,15 +401,28 @@ export interface RPCTransferTicketOperation {
 }
 
 /**
- * @description Parameters for the `txRollupSubmitBatch` method
+ * @description Parameters for the increasePaidStorage method
  */
-export interface TxRollupBatchParams {
+export interface IncreasePaidStorageParams {
   source?: string;
   fee?: number;
   gasLimit?: number;
   storageLimit?: number;
-  rollup: string;
-  content: string;
+  amount: number;
+  destination: string;
+}
+
+/**
+ * @description RPC IncreasePaidStorage operation
+ */
+export interface RPCIncreasePaidStorageOperation {
+  kind: OpKind.INCREASE_PAID_STORAGE;
+  source: string;
+  fee: number;
+  gas_limit: number;
+  storage_limit: number;
+  amount: number;
+  destination: string;
 }
 
 export type RPCOperation =
@@ -404,7 +434,8 @@ export type RPCOperation =
   | RPCRegisterGlobalConstantOperation
   | RPCTxRollupOriginationOperation
   | RPCTxRollupBatchOperation
-  | RPCTransferTicketOperation;
+  | RPCTransferTicketOperation
+  | RPCIncreasePaidStorageOperation;
 
 export type PrepareOperationParams = {
   operation: RPCOperation | RPCOperation[];
diff --git a/website/sidebars.js b/website/sidebars.js
index 229516b28..0bc66af6d 100644
--- a/website/sidebars.js
+++ b/website/sidebars.js
@@ -37,6 +37,7 @@ const sidebars = {
         'maps_bigmaps',
         'michelsonmap',
         'originate',
+        'increase_paid_storage',
         'global_constant',
         'rpc_nodes',
         'rpc_package',


Test patch:
diff --git a/integration-tests/config.ts b/integration-tests/config.ts
index e15258b6f..9ef4f70c4 100644
--- a/integration-tests/config.ts
+++ b/integration-tests/config.ts
@@ -26,6 +26,7 @@ interface Config {
   knownBigMapContract: string;
   knownTzip1216Contract: string; 
   knownSaplingContract: string; 
+  knownViewContract?: string;
   protocol: Protocols;
   signerConfig: EphemeralConfig | FaucetConfig;
 }
@@ -67,6 +68,7 @@ const kathmandunetEphemeral = {
   knownBigMapContract: 'KT1AwUJp6ozYtzhpf5wVXZPQSFxb64JFcVvi',
   knownTzip1216Contract: 'KT1VjJDRHPWngmzvjdg9HNq4cbLq1R8A6nfe',
   knownSaplingContract: 'KT1W8U1Svr9ZK68SJT871DRuwDk8VjTuXkgd',
+  knownViewContract: 'KT1JzyH4mfJhGjKpU7E2YEiPQqBPbdDgrfeM',
   protocol: Protocols.PtKathman,
   signerConfig: {
     type: SignerType.EPHEMERAL_KEY as SignerType.EPHEMERAL_KEY,
@@ -112,6 +114,7 @@ const kathmandunetFaucet = {
   knownBigMapContract: 'KT1AwUJp6ozYtzhpf5wVXZPQSFxb64JFcVvi',
   knownTzip1216Contract: 'KT1VjJDRHPWngmzvjdg9HNq4cbLq1R8A6nfe',
   knownSaplingContract: 'KT1W8U1Svr9ZK68SJT871DRuwDk8VjTuXkgd',
+  knownViewContract: 'KT1JzyH4mfJhGjKpU7E2YEiPQqBPbdDgrfeM',
   protocol: Protocols.PtKathman,
   signerConfig: {
     type: SignerType.FAUCET as SignerType.FAUCET,
@@ -273,6 +276,7 @@ export const CONFIGS = () => {
         knownBigMapContract,
         knownTzip1216Contract,
         knownSaplingContract,
+        knownViewContract,
         signerConfig,
       }) => {
         const Tezos = new TezosToolkit(new RpcClientCache(new RpcClient(rpc)));
@@ -289,6 +293,7 @@ export const CONFIGS = () => {
           knownBigMapContract,
           knownTzip1216Contract,
           knownSaplingContract,
+          knownViewContract,
           signerConfig,
           setup: async (preferFreshKey: boolean = false) => {
             if (signerConfig.type === SignerType.FAUCET) {
diff --git a/integration-tests/contract-execute-on-chain-view.spec.ts b/integration-tests/contract-execute-on-chain-view.spec.ts
index b86c9f0f5..300882862 100644
--- a/integration-tests/contract-execute-on-chain-view.spec.ts
+++ b/integration-tests/contract-execute-on-chain-view.spec.ts
@@ -1,19 +1,19 @@
 import { codeViewsTopLevel } from "../packages/taquito-local-forging/test/data/contract_views_top_level";
 import { CONFIGS } from "./config";
 import BigNumber from 'bignumber.js';
-import { Protocols } from "@taquito/taquito";
+import { Protocols, ViewSimulationError } from "@taquito/taquito";
 import { HttpResponseError } from "@taquito/http-utils";
 
 CONFIGS().forEach(({ lib, rpc, setup }) => {
   const Tezos = lib;
- 
+
   describe(`On chain views using the contract API: ${rpc}`, () => {
 
     beforeEach(async (done) => {
       await setup(true)
       done()
     })
-    test(`As a user I want to originate a smart contract having top level views and simulate the views execution`, async (done) => {
+    it(`as a user I want to originate a smart contract having top level views and simulate the views execution`, async (done) => {
       // Contract origination
       const op = await Tezos.contract.originate({
         code: codeViewsTopLevel,
@@ -74,7 +74,12 @@ CONFIGS().forEach(({ lib, rpc, setup }) => {
         // view that always fails
         await contract.contractViews.test_failwith(3).executeView({ viewCaller: contract.address });
       } catch (error: any) {
-        expect(error).toBeInstanceOf(HttpResponseError)
+        const protocol = (await Tezos.rpc.getProtocols()).protocol
+        if(protocol === Protocols.PtKathman) {
+          expect(error).toBeInstanceOf(ViewSimulationError)
+        } else {
+          expect(error).toBeInstanceOf(HttpResponseError)
+        }
       }
 
       const viewSuccResult = await contract.contractViews.succ({ 0: 16, 1: contract.address }).executeView({ source, viewCaller: contract.address });
diff --git a/integration-tests/contract-increase-paid-storage-operation.spec.ts b/integration-tests/contract-increase-paid-storage-operation.spec.ts
new file mode 100644
index 000000000..e947cc594
--- /dev/null
+++ b/integration-tests/contract-increase-paid-storage-operation.spec.ts
@@ -0,0 +1,82 @@
+import { CONFIGS } from './config';
+import { OpKind, Protocols } from '@taquito/taquito';
+import { ligoSample } from './data/ligo-simple-contract';
+
+CONFIGS().forEach(({ lib, rpc, setup, protocol, knownContract }) => {
+  const kathmandunet = (protocol === Protocols.PtKathman) ? it : it.skip;
+  const Tezos = lib;
+
+  describe(`Test Increase Paid Storage using: ${rpc}`, () => {
+    beforeEach(async (done) => {
+      await setup(true);
+      done();
+    });
+
+    kathmandunet('should be able to increase the paid storage of a contract successfully', async (done) => {
+      const op = await Tezos.contract.increasePaidStorage({
+        amount: 1,
+        destination: knownContract
+      });
+
+      await op.confirmation();
+      expect(op.hash).toBeDefined();
+      expect(op.status).toEqual('applied');
+      done();
+    });
+
+    kathmandunet('should be able to include increasePaidStorage operation in a batch', async (done) => {
+      const op = await Tezos.contract
+        .batch()
+        .withOrigination({
+          balance: "1",
+          code: `parameter string;
+          storage string;
+          code {CAR;
+                PUSH string "Hello ";
+                CONCAT;
+                NIL operation; PAIR};
+          `,
+          init: `"test"`
+        })
+        .withIncreasePaidStorage({
+          amount: 1,
+          destination: knownContract
+        })
+        .send();
+      await op.confirmation();
+      expect(op.status).toEqual('applied');
+      done();
+    });
+
+    kathmandunet('should be able to include increasePaidStorage operation in a batch (different batch syntax)', async (done) => {
+      const op = await Tezos.contract.batch([
+        {
+          kind: OpKind.ORIGINATION, 
+          balance: '1', 
+          code: ligoSample, 
+          storage: 0 
+        },
+        { 
+          kind: OpKind.INCREASE_PAID_STORAGE,
+          amount: 1, 
+          destination: knownContract 
+        } 
+      ])
+      .send();
+
+      await op.confirmation();
+      expect(op.status).toEqual('applied');
+      done();
+    });
+
+    kathmandunet('should return error when destination contract address is invalid', async (done) => {
+      expect(async () => {
+        const op = await Tezos.contract.increasePaidStorage({
+          amount: 1,
+          destination: 'invalid_address'
+        });
+      }).rejects.toThrow();
+      done();
+    });
+  });
+});
\ No newline at end of file
diff --git a/integration-tests/injecting-multiple-manager-operations-in-a-block.spec.ts b/integration-tests/injecting-multiple-manager-operations-in-a-block.spec.ts
new file mode 100644
index 000000000..81dfd17f9
--- /dev/null
+++ b/integration-tests/injecting-multiple-manager-operations-in-a-block.spec.ts
@@ -0,0 +1,25 @@
+import { CONFIGS } from "./config";
+
+CONFIGS().forEach(({ lib, rpc, setup }) => {
+    const Tezos = lib;
+    describe(`Test injecting more than one manager operation in a block: ${rpc}`, () => {
+
+        beforeEach(async (done) => {
+            await setup()
+            done()
+        })
+        test('Verify that doing transfers without awaiting the confirmation after each will fail', async (done) => {
+            try {
+                const op1 = await Tezos.contract.transfer({ to: 'tz1ZfrERcALBwmAqwonRXYVQBDT9BjNjBHJu', amount: 1 });
+                const op2 = await Tezos.contract.transfer({ to: 'tz1ZfrERcALBwmAqwonRXYVQBDT9BjNjBHJu', amount: 2 });
+
+                await op1.confirmation();
+                await op2.confirmation();
+
+            } catch (error) {
+                expect(error.message).toContain('Only one manager operation per manager per block allowed');
+            }
+            done();
+        })
+    });
+})
diff --git a/integration-tests/rpc-nodes.spec.ts b/integration-tests/rpc-nodes.spec.ts
index 585bc3b36..9e7802d62 100644
--- a/integration-tests/rpc-nodes.spec.ts
+++ b/integration-tests/rpc-nodes.spec.ts
@@ -1,6 +1,6 @@
 import { CONFIGS } from './config';
 import { Protocols, ChainIds } from "@taquito/taquito";
-import { RpcClientCache, RpcClient, RPCRunViewParam } from '@taquito/rpc';
+import { RpcClientCache, RpcClient, RPCRunViewParam, RPCRunScriptViewParam } from '@taquito/rpc';
 import { encodeExpr } from '@taquito/utils';
 import { Schema } from '@taquito/michelson-encoder';
 import { tokenBigmapCode, tokenBigmapStorage } from './data/token_bigmap';
@@ -15,6 +15,7 @@ CONFIGS().forEach(
     knownContract,
     knownBigMapContract,
     knownSaplingContract,
+    knownViewContract,
   }) => {
     const Tezos = lib;
     const jakartanet = protocol === Protocols.PtJakart2 ? test: test.skip;
@@ -112,6 +113,22 @@ CONFIGS().forEach(
           done();
         });
 
+        kathmandunet('Executes michelson view by calling runScriptView ', async (done) => {
+          const params: RPCRunScriptViewParam = {
+            contract: knownViewContract!,
+            view: 'add',
+            chain_id: ChainIds.KATHMANDUNET,
+            input: {
+              int: '0'
+            }
+          }
+
+          const views = await Tezos.rpc.runScriptView(params)
+          expect(views).toBeDefined();
+          expect(views).toEqual({ "data": { "int": "2" } });
+          done();
+        });
+
         it(`Access the value associated with a key in a big map`, async (done) => {
           const schema = new Schema({
             prim: 'big_map',
diff --git a/packages/taquito-michel-codec/test/contracts_014.spec.ts b/packages/taquito-michel-codec/test/contracts_014.spec.ts
new file mode 100644
index 000000000..3e5804042
--- /dev/null
+++ b/packages/taquito-michel-codec/test/contracts_014.spec.ts
@@ -0,0 +1,57 @@
+import fs from 'fs';
+import path from 'path';
+import { inspect } from 'util';
+import { Contract, ContractOptions } from '../src/michelson-contract';
+import { Protocol } from '../src/michelson-types';
+import { MichelsonError } from '../src/utils';
+
+const contracts: {
+  [group: string]: string[];
+} = {
+  entrypoints: [
+
+  ],
+  ill_typed: [
+    'emit_instruction_error_contract.tz',
+  ],
+  lib_protocol: [
+  ],
+  macros: [
+  ],
+  mini_scenarios: [
+  ],
+  opcodes: [
+    'emit_instruction.tz',
+    'emit_instruction_event.tz',
+  ]
+};
+
+describe('PtKathmandu', () => {
+  for (const [group, list] of Object.entries(contracts)) {
+    describe(group, () => {
+      for (const contract of list) {
+        it(contract, () => {
+          const options: ContractOptions = {
+            protocol: Protocol.PtKathman,
+          };
+
+          const filename = path.resolve(__dirname, 'contracts_014', group, contract);
+          const src = fs.readFileSync(filename).toString();
+          if (group === 'ill_typed') {
+            expect(() => Contract.parse(src, options)).toThrow();
+            return;
+          }
+
+          try {
+            Contract.parse(src, options);
+          } catch (err) {
+            if (err instanceof MichelsonError) {
+              console.log(inspect(err, false, null));
+            }
+            throw err;
+          }
+        });
+      }
+    });
+  }
+});
diff --git a/packages/taquito-michel-codec/test/contracts_014/ill_typed/emit_instruction_error_contract.tz b/packages/taquito-michel-codec/test/contracts_014/ill_typed/emit_instruction_error_contract.tz
new file mode 100644
index 000000000..91bb320a0
--- /dev/null
+++ b/packages/taquito-michel-codec/test/contracts_014/ill_typed/emit_instruction_error_contract.tz
@@ -0,0 +1,16 @@
+{ parameter unit ;
+  storage unit ;
+  code { DROP ;
+         UNIT ;
+         PUSH nat 10 ;
+         LEFT string ;
+         EMIT %event ;
+         PUSH string "lorem ipsum" ;
+         RIGHT nat ;
+         EMIT %event (or (string %words) (string %words)) ;
+         NIL operation ;
+         SWAP ;
+         CONS ;
+         SWAP ;
+         CONS ;
+         PAIR } }
diff --git a/packages/taquito-michel-codec/test/contracts_014/opcodes/emit_instruction.tz b/packages/taquito-michel-codec/test/contracts_014/opcodes/emit_instruction.tz
new file mode 100644
index 000000000..c8c2da088
--- /dev/null
+++ b/packages/taquito-michel-codec/test/contracts_014/opcodes/emit_instruction.tz
@@ -0,0 +1,16 @@
+parameter unit;
+storage unit;
+code { DROP ;
+       UNIT ;
+       PUSH string "right" ;
+       RIGHT nat ;
+       EMIT %tag1 ;
+       PUSH nat 2 ;
+       LEFT string ;
+       EMIT %tag2 (or (nat %int) (string %str)) ;
+       NIL operation ;
+       SWAP ;
+       CONS ;
+       SWAP ;
+       CONS ;
+       PAIR }
diff --git a/packages/taquito-michel-codec/test/contracts_014/opcodes/emit_instruction_event.tz b/packages/taquito-michel-codec/test/contracts_014/opcodes/emit_instruction_event.tz
new file mode 100644
index 000000000..1d4c5a75f
--- /dev/null
+++ b/packages/taquito-michel-codec/test/contracts_014/opcodes/emit_instruction_event.tz
@@ -0,0 +1,16 @@
+{ parameter unit ;
+  storage unit ;
+  code { DROP ;
+         UNIT ;
+         PUSH nat 10 ;
+         LEFT string ;
+         EMIT %event ;
+         PUSH string "lorem ipsum" ;
+         RIGHT nat ;
+         EMIT %event (or (nat %number) (string %words)) ;
+         NIL operation ;
+         SWAP ;
+         CONS ;
+         SWAP ;
+         CONS ;
+         PAIR } }
diff --git a/packages/taquito-rpc/test/data/rpc-responses.ts b/packages/taquito-rpc/test/data/rpc-responses.ts
index 3f43ad4f9..674fd1e6b 100644
--- a/packages/taquito-rpc/test/data/rpc-responses.ts
+++ b/packages/taquito-rpc/test/data/rpc-responses.ts
@@ -2497,6 +2497,19 @@ export const delegatesIthacanetSample = {
   voting_power: 199,
 };
 
+export const delegatesKathmandunetSample = {
+  full_balance: '965532868030',
+  current_frozen_deposits: '96350095609',
+  frozen_deposits: '96350095609',
+  staking_balance: '970221941952',
+  delegated_contracts: ['tz1cjyja1TU6fiyiFav3mFAdnDsCReJ12hPD'],
+  delegated_balance: '4689073922',
+  deactivated: false,
+  grace_period: 42,
+  voting_power: '968128693450',
+  remaining_proposals: 20,
+};
+
 export const blockIthacanetSample = {
   protocol: 'Psithaca2MLRFYargivpo7YvUr7wUDqyxrdhC5CQq78mRvimz6A',
   chain_id: 'NetXnHfVqm9iesp',
@@ -4654,6 +4667,112 @@ export const blockKathmandunetSample = {
         signature:
           'sigdUXgzV3FcbhV7qUAYGCbV86xZEpcBq1S3Acng974GvG8rULLnoNkXn1dvKvfbfvz3zChYCpjcDmR8f1shjAg1uSksceRp',
       },
+      {
+        protocol: 'PtKathmankSpLLDALzWw7CGD2j2MtyveTwboEYokqUCP4a1LxMg',
+        chain_id: 'NetXi2ZagzEsXbZ',
+        hash: 'oorMQ4cCHReHtUdyEqpWBjyAgu59AWYMzSP5bSwi2gSGGHBSLF5',
+        branch: 'BKuq9qvyUfiZH64z7J7nxKAt7HGA1m2rgiR24XrCsAEgBh2JJd1',
+        contents: [
+          {
+            kind: 'transaction',
+            source: 'tz1ejWMc4oNPuYJcs2UBFALuzQy3jKcZxEwL',
+            fee: '673',
+            counter: '84777',
+            gas_limit: '4224',
+            storage_limit: '0',
+            amount: '0',
+            destination: 'KT1D7mKRckD2ZoWGcGtUvBpDxb48WxpnLu1Q',
+            metadata: {
+              balance_updates: [
+                {
+                  kind: 'contract',
+                  contract: 'tz1ejWMc4oNPuYJcs2UBFALuzQy3jKcZxEwL',
+                  change: '-673',
+                  origin: 'block',
+                },
+                {
+                  kind: 'accumulator',
+                  category: 'block fees',
+                  change: '673',
+                  origin: 'block',
+                },
+              ],
+              operation_result: {
+                status: 'applied',
+                storage: {
+                  prim: 'Unit',
+                },
+                consumed_milligas: '2123011',
+                storage_size: '133',
+              },
+              internal_operation_results: [
+                {
+                  kind: 'event',
+                  source: 'KT1D7mKRckD2ZoWGcGtUvBpDxb48WxpnLu1Q',
+                  nonce: 0,
+                  type: {
+                    prim: 'or',
+                    args: [
+                      {
+                        prim: 'nat',
+                      },
+                      {
+                        prim: 'string',
+                      },
+                    ],
+                  },
+                  tag: 'event',
+                  payload: {
+                    prim: 'Left',
+                    args: [
+                      {
+                        int: '10',
+                      },
+                    ],
+                  },
+                  result: {
+                    status: 'applied',
+                    consumed_milligas: '1000000',
+                  },
+                },
+                {
+                  kind: 'event',
+                  source: 'KT1D7mKRckD2ZoWGcGtUvBpDxb48WxpnLu1Q',
+                  nonce: 1,
+                  type: {
+                    prim: 'or',
+                    args: [
+                      {
+                        prim: 'nat',
+                        annots: ['%number'],
+                      },
+                      {
+                        prim: 'string',
+                        annots: ['%words'],
+                      },
+                    ],
+                  },
+                  tag: 'event',
+                  payload: {
+                    prim: 'Right',
+                    args: [
+                      {
+                        string: 'lorem ipsum',
+                      },
+                    ],
+                  },
+                  result: {
+                    status: 'applied',
+                    consumed_milligas: '1000000',
+                  },
+                },
+              ],
+            },
+          },
+        ],
+        signature:
+          'sigfSTrupvjTWBW4NNXJHLyNEd6gUuD3Jzm9YZzSrH82X3somYZPpgCayRTkzmk1NwxGQCKJHLGsv7xxhVNKsgtxTqF8FEqe',
+      },
     ],
   ],
 };
diff --git a/packages/taquito-rpc/test/taquito-rpc.spec.ts b/packages/taquito-rpc/test/taquito-rpc.spec.ts
index cd7283bae..4a20d5785 100644
--- a/packages/taquito-rpc/test/taquito-rpc.spec.ts
+++ b/packages/taquito-rpc/test/taquito-rpc.spec.ts
@@ -1,3 +1,4 @@
+/* eslint-disable @typescript-eslint/no-explicit-any */
 /* eslint-disable @typescript-eslint/no-non-null-assertion */
 import { OpKind, RpcClient } from '../src/taquito-rpc';
 import BigNumber from 'bignumber.js';
@@ -11,6 +12,7 @@ import {
   LazyStorageDiffSaplingState,
   OperationContentsAndResultRegisterGlobalConstant,
   RPCRunViewParam,
+  RPCRunScriptViewParam,
   OperationContentsAndResultSetDepositsLimit,
   METADATA_BALANCE_UPDATES_CATEGORY,
   OperationContentsAndResultTxRollupOrigination,
@@ -25,12 +27,14 @@ import {
   Inode,
   OtherElts,
   OperationContentsAndResultIncreasePaidStorage,
+  OperationResultEvent,
 } from '../src/types';
 import {
   blockIthacanetSample,
   blockJakartanetSample,
   blockKathmandunetSample,
   delegatesIthacanetSample,
+  delegatesKathmandunetSample,
 } from './data/rpc-responses';
 
 /**
@@ -92,7 +96,7 @@ describe('RpcClient test', () => {
   });
 
   describe('getBalance', () => {
-    it('query the right url and return a string', async (done) => {
+    it('should query the right url and return a string', async (done) => {
       httpBackend.createRequest.mockReturnValue(Promise.resolve('10000'));
       const balance = await client.getBalance(contractAddress);
 
@@ -108,7 +112,7 @@ describe('RpcClient test', () => {
   });
 
   describe('getStorage', () => {
-    it('query the right url', async (done) => {
+    it('should query the right url', async (done) => {
       await client.getStorage(contractAddress);
 
       expect(httpBackend.createRequest.mock.calls[0][0]).toEqual({
@@ -121,7 +125,7 @@ describe('RpcClient test', () => {
   });
 
   describe('getScript', () => {
-    it('query the right url', async (done) => {
+    it('should query the right url', async (done) => {
       await client.getScript(contractAddress);
 
       expect(httpBackend.createRequest.mock.calls[0][0]).toEqual({
@@ -134,7 +138,7 @@ describe('RpcClient test', () => {
   });
 
   describe('getNormalizedScript', () => {
-    it('query the right url', async (done) => {
+    it('should query the right url', async (done) => {
       await client.getNormalizedScript(contractAddress);
 
       expect(httpBackend.createRequest.mock.calls[0][0]).toEqual({
@@ -148,7 +152,7 @@ describe('RpcClient test', () => {
   });
 
   describe('getContract', () => {
-    it('query the right url', async (done) => {
+    it('should query the right url', async (done) => {
       httpBackend.createRequest.mockResolvedValue({ balance: '10000' });
       const response = await client.getContract(contractAddress);
 
@@ -165,7 +169,7 @@ describe('RpcClient test', () => {
   });
 
   describe('getManagerKey', () => {
-    it('query the right url', async (done) => {
+    it('should query the right url', async (done) => {
       await client.getManagerKey(contractAddress);
 
       expect(httpBackend.createRequest.mock.calls[0][0]).toEqual({
@@ -178,7 +182,7 @@ describe('RpcClient test', () => {
   });
 
   describe('getDelegate', () => {
-    it('query the right url', async (done) => {
+    it('should query the right url', async (done) => {
       await client.getDelegate(contractAddress);
 
       expect(httpBackend.createRequest.mock.calls[0][0]).toEqual({
@@ -191,7 +195,7 @@ describe('RpcClient test', () => {
   });
 
   describe('getBlockHash', () => {
-    it('query the right url', async (done) => {
+    it('should query the right url', async (done) => {
       await client.getBlockHash();
 
       expect(httpBackend.createRequest.mock.calls[0][0]).toEqual({
@@ -221,7 +225,7 @@ describe('RpcClient test', () => {
       grace_period: 146,
     };
 
-    it('query the right url', async (done) => {
+    it('should query the right url', async (done) => {
       httpBackend.createRequest.mockResolvedValue(sampleResponse);
       await client.getDelegates(contractAddress);
 
@@ -233,7 +237,7 @@ describe('RpcClient test', () => {
       done();
     });
 
-    it('parse the response properly', async (done) => {
+    it('should parse the response properly', async (done) => {
       httpBackend.createRequest.mockResolvedValue(sampleResponse);
       const response = await client.getDelegates(contractAddress);
 
@@ -267,7 +271,7 @@ describe('RpcClient test', () => {
       done();
     });
 
-    it('parse the response properly, proto10', async (done) => {
+    it('should parse the response properly, proto10', async (done) => {
       // deposit replaced by deposits
       httpBackend.createRequest.mockResolvedValue({
         balance: '5976016544884',
@@ -313,7 +317,7 @@ describe('RpcClient test', () => {
       done();
     });
 
-    it('parse the response properly, proto12', async (done) => {
+    it('should parse the response properly, proto12', async (done) => {
       httpBackend.createRequest.mockResolvedValue(delegatesIthacanetSample);
       const response = await client.getDelegates(contractAddress);
 
@@ -331,10 +335,30 @@ describe('RpcClient test', () => {
 
       done();
     });
+
+    it('should parse the response properly, proto14', async (done) => {
+      httpBackend.createRequest.mockResolvedValue(delegatesKathmandunetSample);
+      const response = await client.getDelegates(contractAddress);
+
+      expect(response).toEqual({
+        full_balance: new BigNumber('965532868030'),
+        current_frozen_deposits: new BigNumber('96350095609'),
+        frozen_deposits: new BigNumber('96350095609'),
+        staking_balance: new BigNumber('970221941952'),
+        delegated_contracts: ['tz1cjyja1TU6fiyiFav3mFAdnDsCReJ12hPD'],
+        delegated_balance: new BigNumber('4689073922'),
+        deactivated: false,
+        grace_period: 42,
+        voting_power: new BigNumber(968128693450),
+        remaining_proposals: 20,
+      });
+
+      done();
+    });
   });
 
   describe('getBigMapKey', () => {
-    it('query the right url', async (done) => {
+    it('should query the right url', async (done) => {
       await client.getBigMapKey(contractAddress, { key: 'test', type: 'string' } as any);
       expect(httpBackend.createRequest.mock.calls[0][0]).toEqual({
         method: 'POST',
@@ -348,7 +372,7 @@ describe('RpcClient test', () => {
   });
 
   describe('forgeOperation', () => {
-    it('query the right url', async (done) => {
+    it('should query the right url', async (done) => {
       await client.forgeOperations({} as any);
       expect(httpBackend.createRequest.mock.calls[0][0]).toEqual({
         method: 'POST',
@@ -362,7 +386,7 @@ describe('RpcClient test', () => {
   });
 
   describe('injectOperations', () => {
-    it('query the right url', async (done) => {
+    it('should query the right url', async (done) => {
       await client.injectOperation({} as any);
       expect(httpBackend.createRequest.mock.calls[0][0]).toEqual({
         method: 'POST',
@@ -376,7 +400,7 @@ describe('RpcClient test', () => {
   });
 
   describe('preapplyOperations', () => {
-    it('query the right url', async (done) => {
+    it('should query the right url', async (done) => {
       httpBackend.createRequest.mockResolvedValue({});
       await client.preapplyOperations({} as any);
       expect(httpBackend.createRequest.mock.calls[0][0]).toEqual({
@@ -391,7 +415,7 @@ describe('RpcClient test', () => {
   });
 
   describe('getBlockHeader', () => {
-    it('query the right url', async (done) => {
+    it('should query the right url', async (done) => {
       const sampleResponse = {
         protocol: 'Pt24m4xiPbLDhVgVfABUjirbmda3yohdN82Sp9FeuAXJ4eV9otd',
         chain_id: 'NetXdQprcVkpaWU',
@@ -440,7 +464,7 @@ describe('RpcClient test', () => {
   });
 
   describe('getBlockMetadata', () => {
-    it('query the right url', async (done) => {
+    it('should query the right url', async (done) => {
       const sampleResponse = {
         protocol: 'Pt24m4xiPbLDhVgVfABUjirbmda3yohdN82Sp9FeuAXJ4eV9otd',
         next_protocol: 'Pt24m4xiPbLDhVgVfABUjirbmda3yohdN82Sp9FeuAXJ4eV9otd',
@@ -565,7 +589,7 @@ describe('RpcClient test', () => {
   });
 
   describe('getConstants Proto014', () => {
-    it('query the right url and casts relevant properties to BigNumber', async (done) => {
+    it('should query the right url and casts relevant properties to BigNumber', async (done) => {
       httpBackend.createRequest.mockResolvedValue({
         proof_of_work_nonce_size: 8,
         nonce_length: 32,
@@ -752,7 +776,7 @@ describe('RpcClient test', () => {
   });
 
   describe('getConstants Proto012', () => {
-    it('query the right url and casts property to BigNumber', async (done) => {
+    it('should query the right url and casts property to BigNumber', async (done) => {
       httpBackend.createRequest.mockReturnValue(
         Promise.resolve({
           proof_of_work_nonce_size: 8,
@@ -860,7 +884,7 @@ describe('RpcClient test', () => {
   });
 
   describe('getConstants Proto007', () => {
-    it('query the right url and casts property to BigNumber', async (done) => {
+    it('should query the right url and casts property to BigNumber', async (done) => {
       httpBackend.createRequest.mockReturnValue(
         Promise.resolve({
           proof_of_work_nonce_size: 8,
@@ -935,7 +959,7 @@ describe('RpcClient test', () => {
   });
 
   describe('getConstants Proto006', () => {
-    it('properties return by the RPC are accessible and the ones that do not belong to proto6 are undefined', async (done) => {
+    it('should properties return by the RPC are accessible and the ones that do not belong to proto6 are undefined', async (done) => {
       httpBackend.createRequest.mockReturnValue(
         Promise.resolve({
           proof_of_work_nonce_size: 8,
@@ -991,7 +1015,7 @@ describe('RpcClient test', () => {
   });
 
   describe('getConstants Proto005', () => {
-    it('properties return by the RPC are accessible and the ones that do not belong to proto5 are undefined', async (done) => {
+    it('should properties return by the RPC are accessible and the ones that do not belong to proto5 are undefined', async (done) => {
       httpBackend.createRequest.mockReturnValue(
         Promise.resolve({
           proof_of_work_nonce_size: 8,
@@ -1057,7 +1081,7 @@ describe('RpcClient test', () => {
   });
 
   describe('getBlock', () => {
-    it('query the right url and property for endorsement', async (done) => {
+    it('should query the right url and property for endorsement', async (done) => {
       httpBackend.createRequest.mockReturnValue(
         Promise.resolve({
           protocol: 'Pt24m4xiPbLDhVgVfABUjirbmda3yohdN82Sp9FeuAXJ4eV9otd',
@@ -1198,7 +1222,7 @@ describe('RpcClient test', () => {
   });
 
   describe('getBlock', () => {
-    it('query the right url and property for operation', async (done) => {
+    it('should query the right url and property for operation', async (done) => {
       httpBackend.createRequest.mockReturnValue(
         Promise.resolve({
           protocol: 'PtEdo2ZkT9oKpimTah6x2embF25oss54njMuPzkJTEi5RqfdZFA',
@@ -1441,7 +1465,7 @@ describe('RpcClient test', () => {
       done();
     });
 
-    it('query the right url and property for operation, proto 9, endorsement_with_slot', async (done) => {
+    it('should query the right url and property for operation, proto 9, endorsement_with_slot', async (done) => {
       httpBackend.createRequest.mockReturnValue(
         Promise.resolve({
           protocol: 'PsFLorenaUUuikDWvMDr6fGBRG8kt3e3D3fHoXK1j1BFRxeSH4i',
@@ -1529,7 +1553,7 @@ describe('RpcClient test', () => {
       done();
     });
 
-    it('query the right url and properties (big_map_diff and lazy_storage_diff) in transaction operation result, proto 9', async (done) => {
+    it('should query the right url and properties (big_map_diff and lazy_storage_diff) in transaction operation result, proto 9', async (done) => {
       httpBackend.createRequest.mockReturnValue(
         Promise.resolve({
           protocol: 'PsFLorenaUUuikDWvMDr6fGBRG8kt3e3D3fHoXK1j1BFRxeSH4i',
@@ -2131,7 +2155,7 @@ describe('RpcClient test', () => {
       done();
     });
 
-    it('query the right url and properties (lazy_storage_diff of kind sapling_state) in transaction operation result, proto 8', async (done) => {
+    it('should query the right url and properties (lazy_storage_diff of kind sapling_state) in transaction operation result, proto 8', async (done) => {
       httpBackend.createRequest.mockReturnValue(
         Promise.resolve({
           protocol: 'PtEdo2ZkT9oKpimTah6x2embF25oss54njMuPzkJTEi5RqfdZFA',
@@ -2243,7 +2267,7 @@ describe('RpcClient test', () => {
       done();
     });
 
-    it('Access new properties "liquidity_baking_escape_ema", "implicit_operations_results" and "subsidy" in block metadata, proto 10', async (done) => {
+    it('should access new properties "liquidity_baking_escape_ema", "implicit_operations_results" and "subsidy" in block metadata, proto 10', async (done) => {
       httpBackend.createRequest.mockReturnValue(
         Promise.resolve({
           protocol: 'PtGRANADsDU8R9daYKAgWnQYAJ64omN1o3KMGVCykShA97vQbvV',
@@ -2368,7 +2392,7 @@ describe('RpcClient test', () => {
       done();
     });
 
-    it('fetches a block having a RegisterGlobalConstant operation and it validates its properties, proto 11', async (done) => {
+    it('should fetch a block having a RegisterGlobalConstant operation and it validates its properties, proto 11', async (done) => {
       httpBackend.createRequest.mockReturnValue(
         Promise.resolve({
           protocol: 'PtHangzHogokSuiMHemCuowEavgYTP8J5qQ9fQS793MHYFpCY3r',
@@ -3026,6 +3050,54 @@ describe('RpcClient test', () => {
       expect(content.metadata.operation_result.consumed_milligas).toEqual('1000000');
       done();
     });
+
+    it('should be able to access the properties of internal operation type event, proto14', async (done) => {
+      httpBackend.createRequest.mockReturnValue(Promise.resolve(blockKathmandunetSample));
+
+      const response = await client.getBlock();
+      const content = response.operations[3][1]
+        .contents[0] as OperationContentsAndResultTransaction;
+
+      expect(content.metadata.internal_operation_results).toBeDefined();
+      expect(content.metadata.internal_operation_results![0].kind).toEqual(OpKind.EVENT);
+      expect(content.metadata.internal_operation_results![0].source).toEqual(
+        'KT1D7mKRckD2ZoWGcGtUvBpDxb48WxpnLu1Q'
+      );
+      expect(content.metadata.internal_operation_results![0].nonce).toEqual(0);
+
+      expect(content.metadata.internal_operation_results![0].amount).toBeUndefined();
+      expect(content.metadata.internal_operation_results![0].destination).toBeUndefined();
+      expect(content.metadata.internal_operation_results![0].parameters).toBeUndefined();
+      expect(content.metadata.internal_operation_results![0].public_key).toBeUndefined();
+      expect(content.metadata.internal_operation_results![0].balance).toBeUndefined();
+      expect(content.metadata.internal_operation_results![0].delegate).toBeUndefined();
+      expect(content.metadata.internal_operation_results![0].value).toBeUndefined();
+      expect(content.metadata.internal_operation_results![0].limit).toBeUndefined();
+      expect(content.metadata.internal_operation_results![0].script).toBeUndefined();
+
+      expect(content.metadata.internal_operation_results![0].type).toBeDefined();
+      expect(content.metadata.internal_operation_results![0].type).toEqual({
+        prim: 'or',
+        args: [{ prim: 'nat' }, { prim: 'string' }],
+      });
+      expect(content.metadata.internal_operation_results![0].tag).toBeDefined();
+      expect(content.metadata.internal_operation_results![0].tag).toEqual('event');
+      expect(content.metadata.internal_operation_results![0].payload).toBeDefined();
+      expect(content.metadata.internal_operation_results![0].payload).toEqual({
+        prim: 'Left',
+        args: [{ int: '10' }],
+      });
+      expect(content.metadata.internal_operation_results![0].result).toBeDefined();
+
+      const internalResult = content.metadata.internal_operation_results![0]
+        .result as OperationResultEvent;
+      expect(internalResult.status).toEqual('applied');
+      expect(internalResult.consumed_milligas).toBeDefined();
+      expect(internalResult.consumed_milligas).toEqual('1000000');
+      expect(internalResult.errors).toBeUndefined();
+
+      done();
+    });
   });
 
   describe('getBakingRights', () => {
@@ -3109,7 +3181,7 @@ describe('RpcClient test', () => {
   });
 
   describe('getBallotList', () => {
-    it('query the right url and data', async (done) => {
+    it('should query the right url and data', async (done) => {
       httpBackend.createRequest.mockReturnValue(
         Promise.resolve([
           {
@@ -3151,7 +3223,7 @@ describe('RpcClient test', () => {
   });
 
   describe('getBallots', () => {
-    it('query the right url and data', async (done) => {
+    it('should query the right url and data', async (done) => {
       httpBackend.createRequest.mockReturnValue(Promise.resolve({ yay: 5943, nay: 0, pass: 0 }));
       const response = await client.getBallots();
 
@@ -3166,7 +3238,7 @@ describe('RpcClient test', () => {
   });
 
   describe('getCurrentProposal', () => {
-    it('query the right url and data', async (done) => {
+    it('should query the right url and data', async (done) => {
       httpBackend.createRequest.mockReturnValue(
         Promise.resolve('PsBABY5HQTSkA4297zNHfsZNKtxULfL18y95qb3m53QJiXGmrbU')
       );
@@ -3183,7 +3255,7 @@ describe('RpcClient test', () => {
   });
 
   describe('getCurrentQuorum', () => {
-    it('query the right url and data', async (done) => {
+    it('should query the right url and data', async (done) => {
       httpBackend.createRequest.mockReturnValue(Promise.resolve(7291));
       const response = await client.getCurrentQuorum();
 
@@ -3198,7 +3270,7 @@ describe('RpcClient test', () => {
   });
 
   describe('getVotesListings', () => {
-    it('query the right url and data', async (done) => {
+    it('should query the right url and data', async (done) => {
       httpBackend.createRequest.mockReturnValue(
         Promise.resolve([
           {
@@ -3259,7 +3331,7 @@ describe('RpcClient test', () => {
   });
 
   describe('getProposals', () => {
-    it('query the right url and data', async (done) => {
+    it('should query the right url and data', async (done) => {
       httpBackend.createRequest.mockReturnValue(
         Promise.resolve([
           ['PsBABY5HQTSkA4297zNHfsZNKtxULfL18y95qb3m53QJiXGmrbU', 2832],
@@ -3279,7 +3351,7 @@ describe('RpcClient test', () => {
   });
 
   describe('getEntrypoints', () => {
-    it('query the right url and data', async (done) => {
+    it('should query the right url and data', async (done) => {
       httpBackend.createRequest.mockReturnValue({ entrypoints: {} });
       const response = await client.getEntrypoints(contractAddress);
 
@@ -3293,7 +3365,7 @@ describe('RpcClient test', () => {
   });
 
   describe('runOperation', () => {
-    it('query the right url and data', async (done) => {
+    it('should query the right url and data', async (done) => {
       const testData = {};
 
       httpBackend.createRequest.mockResolvedValue({ content: {} });
@@ -3352,8 +3424,54 @@ describe('RpcClient test', () => {
     });
   });
 
-  describe('runView', () => {
+  describe('runScriptView', () => {
     it('query the right url and data', async (done) => {
+      const testData: RPCRunScriptViewParam = {
+        contract: 'test',
+        view: 'test',
+        chain_id: 'test',
+        input: {
+          int: '0',
+        },
+      };
+
+      await client.runScriptView(testData);
+
+      expect(httpBackend.createRequest.mock.calls[0][0]).toEqual({
+        method: 'POST',
+        url: 'root/chains/test/blocks/head/helpers/scripts/run_script_view',
+      });
+      expect(httpBackend.createRequest.mock.calls[0][1]).toEqual({
+        ...testData,
+        unparsing_mode: 'Readable',
+      });
+      done();
+    });
+
+    it('query the right url and data with unparsing_mode overriden', async (done) => {
+      const testData: RPCRunScriptViewParam = {
+        contract: 'test',
+        view: 'test',
+        chain_id: 'test',
+        input: {
+          int: '0',
+        },
+        unparsing_mode: 'Optimized',
+      };
+
+      await client.runScriptView(testData);
+
+      expect(httpBackend.createRequest.mock.calls[0][0]).toEqual({
+        method: 'POST',
+        url: 'root/chains/test/blocks/head/helpers/scripts/run_script_view',
+      });
+      expect(httpBackend.createRequest.mock.calls[0][1]).toEqual(testData);
+      done();
+    });
+  });
+
+  describe('runView', () => {
+    it('should query the right url and data', async (done) => {
       const testData: RPCRunViewParam = {
         contract: 'test',
         entrypoint: 'test',
@@ -3381,7 +3499,7 @@ describe('RpcClient test', () => {
       done();
     });
 
-    it('query the right url and data with unparsing_mode overriden', async (done) => {
+    it('should query the right url and data with unparsing_mode overriden', async (done) => {
       const testData: RPCRunViewParam = {
         contract: 'test',
         entrypoint: 'test',
@@ -3404,7 +3522,7 @@ describe('RpcClient test', () => {
   });
 
   describe('packData', () => {
-    it('query the right url and data', async (done) => {
+    it('should query the right url and data', async (done) => {
       httpBackend.createRequest.mockResolvedValue({ packed: 'cafe', gas: 'unaccounted' });
       const response = await client.packData({
         data: { string: 'test' },
@@ -3420,7 +3538,7 @@ describe('RpcClient test', () => {
       done();
     });
 
-    it('return a big number for gas when it is a big number', async (done) => {
+    it('should return a big number for gas when it is a big number', async (done) => {
       httpBackend.createRequest.mockResolvedValue({ packed: 'cafe', gas: '2' });
       const response = await client.packData({
         data: { string: 'test' },
@@ -3432,7 +3550,7 @@ describe('RpcClient test', () => {
       done();
     });
 
-    it('return undefined for gas when it is missing', async (done) => {
+    it('should return undefined for gas when it is missing', async (done) => {
       httpBackend.createRequest.mockResolvedValue({ packed: 'cafe' });
       const response = await client.packData({
         data: { string: 'test' },
@@ -3445,7 +3563,7 @@ describe('RpcClient test', () => {
   });
 
   describe('getBigMapExpr', () => {
-    it('query the right url and data', async (done) => {
+    it('should query the right url and data', async (done) => {
       await client.getBigMapExpr('1', '2');
 
       expect(httpBackend.createRequest.mock.calls[0][0]).toEqual({
@@ -3457,7 +3575,7 @@ describe('RpcClient test', () => {
   });
 
   describe('getRpcUrl', () => {
-    it('return the RPC Url', () => {
+    it('should return the RPC Url', () => {
       const url = 'https://mainnet.api.tez.ie/';
       const rpcUrlMainnet = new RpcClient(url).getRpcUrl();
       expect(rpcUrlMainnet).toEqual('https://mainnet.api.tez.ie/');
@@ -3467,7 +3585,7 @@ describe('RpcClient test', () => {
   });
 
   describe('getCurrentPeriod', () => {
-    it('query the right url and data', async (done) => {
+    it('should query the right url and data', async (done) => {
       const mockedResponse = {
         voting_period: {
           index: 87,
@@ -3491,7 +3609,7 @@ describe('RpcClient test', () => {
   });
 
   describe('getSuccessorPeriod', () => {
-    it('query the right url and data', async (done) => {
+    it('should query the right url and data', async (done) => {
       const mockedResponse = {
         voting_period: {
           index: 87,
@@ -3515,7 +3633,7 @@ describe('RpcClient test', () => {
   });
 
   describe('getSaplingDiffById', () => {
-    it('query the right url', async (done) => {
+    it('should query the right url', async (done) => {
       httpBackend.createRequest.mockResolvedValue({
         root: 'fbc2f4300c01f0b7820d00e3347c8da4ee614674376cbc45359daa54f9b5493e',
         commitments_and_ciphertexts: [],
@@ -3539,7 +3657,7 @@ describe('RpcClient test', () => {
   });
 
   describe('getSaplingDiffByContract', () => {
-    it('query the right url', async (done) => {
+    it('should query the right url', async (done) => {
       httpBackend.createRequest.mockResolvedValue({
         root: 'fbc2f4300c01f0b7820d00e3347c8da4ee614674376cbc45359daa54f9b5493e',
         commitments_and_ciphertexts: [],
@@ -3565,7 +3683,7 @@ describe('RpcClient test', () => {
   });
 
   describe('getProtocols', () => {
-    it('query the right url and return a ProtocolsResponse', async (done) => {
+    it('should query the right url and return a ProtocolsResponse', async (done) => {
       httpBackend.createRequest.mockReturnValue(
         Promise.resolve({
           protocol: 'PtHangz2aRngywmSRGGvrcTyMbbdpWdpFKuS4uMWxg2RaH9i1qx',
diff --git a/packages/taquito/test/batch/rpc-batch-provider.spec.ts b/packages/taquito/test/batch/rpc-batch-provider.spec.ts
index 0833b72f0..2a26a8664 100644
--- a/packages/taquito/test/batch/rpc-batch-provider.spec.ts
+++ b/packages/taquito/test/batch/rpc-batch-provider.spec.ts
@@ -566,6 +566,134 @@ describe('OperationBatch test', () => {
     });
   });
 
+  describe('withIncreasePaidStorage batch operation', () => {
+    it('should produce an operation batch which contains an increasePaidStorage operation', async (done) => {
+      const estimate = new Estimate(1230000, 93, 142, 250);
+      mockEstimate.batch.mockResolvedValue([estimate]);
+
+      const opToBatch: ParamsWithKind[] = [
+        {
+          kind: OpKind.INCREASE_PAID_STORAGE,
+          amount: 1,
+          destination: 'KT1UiLW7MQCrgaG8pubSJsnpFZzxB2PMs92W',
+        },
+      ];
+
+      const batchOp = await operationBatch.with(opToBatch).send();
+      expect(batchOp.raw).toEqual({
+        counter: 123456,
+        opOb: {
+          branch: 'test',
+          contents: [
+            {
+              kind: 'increase_paid_storage',
+              source: 'test_pub_key_hash',
+              fee: '475',
+              gas_limit: '1330',
+              storage_limit: '93',
+              amount: '1',
+              destination: 'KT1UiLW7MQCrgaG8pubSJsnpFZzxB2PMs92W',
+              counter: '123457',
+            },
+          ],
+          protocol: 'test_proto',
+          signature: 'test_sig',
+        },
+        opbytes: 'test',
+      });
+      done();
+    });
+
+    it('should produce an operation batch which contains a reveal and an increasePaidStorage operation', async (done) => {
+      mockRpcClient.getManagerKey.mockResolvedValue(null);
+      const estimateReveal = new Estimate(1000000, 0, 64, 250);
+      const estimate = new Estimate(1230000, 93, 142, 250);
+      mockEstimate.batch.mockResolvedValue([estimateReveal, estimate]);
+
+      const opToBatch: ParamsWithKind[] = [
+        {
+          kind: OpKind.INCREASE_PAID_STORAGE,
+          amount: 1,
+          destination: 'KT1UiLW7MQCrgaG8pubSJsnpFZzxB2PMs92W',
+        },
+      ];
+
+      const batchOp = await operationBatch.with(opToBatch).send();
+
+      expect(batchOp.raw).toEqual({
+        counter: 123456,
+        opOb: {
+          branch: 'test',
+          contents: [
+            {
+              counter: '123457',
+              fee: '374',
+              gas_limit: '1100',
+              kind: 'reveal',
+              public_key: 'test_pub_key',
+              source: 'test_pub_key_hash',
+              storage_limit: '0',
+            },
+            {
+              kind: 'increase_paid_storage',
+              source: 'test_pub_key_hash',
+              fee: '475',
+              gas_limit: '1330',
+              storage_limit: '93',
+              amount: '1',
+              destination: 'KT1UiLW7MQCrgaG8pubSJsnpFZzxB2PMs92W',
+              counter: '123458',
+            },
+          ],
+          protocol: 'test_proto',
+          signature: 'test_sig',
+        },
+        opbytes: 'test',
+      });
+      done();
+    });
+
+    it('should produce a batch operation which contants an increasePaidStorage operation where fee, gas limit, and storage limit are specified by the user', async (done) => {
+      const estimate = new Estimate(1230000, 93, 142, 250);
+      mockEstimate.batch.mockResolvedValue([estimate]);
+
+      const opToBatch: ParamsWithKind[] = [
+        {
+          kind: OpKind.INCREASE_PAID_STORAGE,
+          fee: 500,
+          gasLimit: 1400,
+          storageLimit: 100,
+          amount: 1,
+          destination: 'KT1UiLW7MQCrgaG8pubSJsnpFZzxB2PMs92W',
+        },
+      ];
+
+      const batchOp = await operationBatch.with(opToBatch).send();
+      expect(batchOp.raw).toEqual({
+        counter: 123456,
+        opOb: {
+          branch: 'test',
+          contents: [
+            {
+              kind: 'increase_paid_storage',
+              source: 'test_pub_key_hash',
+              fee: '500',
+              gas_limit: '1400',
+              storage_limit: '100',
+              amount: '1',
+              destination: 'KT1UiLW7MQCrgaG8pubSJsnpFZzxB2PMs92W',
+              counter: '123457',
+            },
+          ],
+          protocol: 'test_proto',
+          signature: 'test_sig',
+        },
+        opbytes: 'test',
+      });
+      done();
+    });
+  });
+
   describe('with txRollupOriginate operation', () => {
     it('should produce a batch operation which contains an txRollupOriginate operation', async (done) => {
       const estimate = new Estimate(1230000, 93, 142, 250);
@@ -757,7 +885,7 @@ describe('OperationBatch test', () => {
       done();
     });
 
-    it('should produce a batch operation which contains a reveal and a txRollupSubmitBatchp operation', async (done) => {
+    it('should produce a batch operation which contains a reveal and a txRollupSubmitBatch operation', async (done) => {
       mockRpcClient.getManagerKey.mockResolvedValue(null);
       const estimateReveal = new Estimate(1000000, 0, 64, 250);
       const estimate = new Estimate(1230000, 93, 142, 250);
diff --git a/packages/taquito/test/contract/contract-on-chain-view.spec.ts b/packages/taquito/test/contract/contract-on-chain-view.spec.ts
index 430f09069..2b4624b5f 100644
--- a/packages/taquito/test/contract/contract-on-chain-view.spec.ts
+++ b/packages/taquito/test/contract/contract-on-chain-view.spec.ts
@@ -9,10 +9,181 @@ import {
 import { HttpResponseError, STATUS_CODE } from '@taquito/http-utils';
 import { Context } from '../../src/context';
 import { RpcReadAdapter } from '../../src/read-provider/rpc-read-adapter';
+import { Protocols } from '../../src/constants';
 
-describe('OnChainView test', () => {
+describe('OnChainView test on K protocol', () => {
   let view: OnChainView;
   let mockRpcClient: {
+    getProtocols: jest.Mock<any, any>;
+    getChainId: jest.Mock<any, any>;
+    runScriptView: jest.Mock<any, any>;
+    getStorage: jest.Mock<any, any>;
+  };
+  let mockReadProvider: any;
+  beforeEach(() => {
+    mockRpcClient = {
+      getProtocols: jest.fn(),
+      getChainId: jest.fn(),
+      runScriptView: jest.fn(),
+      getStorage: jest.fn(),
+    };
+
+    mockRpcClient.getProtocols.mockResolvedValue({ protocol: Protocols.PtKathman });
+
+    mockRpcClient.getChainId.mockResolvedValue('test_chain_id');
+
+    mockRpcClient.runScriptView.mockResolvedValue({
+      data: { int: '23' },
+    });
+    mockRpcClient.getStorage.mockResolvedValue({ int: '3' });
+
+    const context = new Context(mockRpcClient as any);
+    mockReadProvider = new RpcReadAdapter(context);
+
+    view = new OnChainView(
+      mockRpcClient as any,
+      mockReadProvider,
+      'contractAddress',
+      new ViewSchema([
+        { string: 'add' },
+        { prim: 'nat' },
+        { prim: 'nat' },
+        [{ prim: 'UNPAIR' }, { prim: 'ADD' }],
+      ]),
+      { prim: 'nat' },
+      20
+    );
+  });
+
+  it('OnChainView is instantiable', () => {
+    expect(view).toBeInstanceOf(OnChainView);
+  });
+
+  it('should extract the signature of the view', () => {
+    expect(view.getSignature()).toEqual({
+      parameter: 'nat',
+      result: 'nat',
+    });
+  });
+
+  it('should execute of the view', async (done) => {
+    expect(
+      await view.executeView({
+        viewCaller: 'KT1TRHzT3HdLe3whe35q6rNxavGx8WVFHSpH',
+      })
+    ).toEqual(new BigNumber(23));
+
+    expect(mockRpcClient.runScriptView).toHaveBeenCalledWith({
+      contract: 'contractAddress',
+      view: 'add',
+      input: { int: '20' },
+      chain_id: 'test_chain_id',
+      source: 'KT1TRHzT3HdLe3whe35q6rNxavGx8WVFHSpH',
+    });
+
+    done();
+  });
+
+  it('should throw an error if the caller of the view is an invalid contract address', async (done) => {
+    try {
+      await view.executeView({
+        viewCaller: 'notAnAddress',
+      });
+    } catch (error) {
+      expect(error).toBeInstanceOf(InvalidViewSimulationContext);
+    }
+    done();
+  });
+
+  it('should throw an error if an invalid address is set as the source of the view', async (done) => {
+    try {
+      await view.executeView({
+        source: 'notAnAddress',
+        viewCaller: 'KT1TRHzT3HdLe3whe35q6rNxavGx8WVFHSpH',
+      });
+    } catch (error) {
+      expect(error).toBeInstanceOf(InvalidViewSimulationContext);
+    }
+    done();
+  });
+
+  it('should throw the original error when it does not contain a "with" property', async (done) => {
+    const httpError = new HttpResponseError(
+      'fail',
+      STATUS_CODE.FORBIDDEN,
+      'err',
+      'test',
+      'https://test.com'
+    );
+    mockRpcClient.runScriptView.mockRejectedValue(httpError);
+
+    try {
+      await view.executeView({
+        viewCaller: 'KT1TRHzT3HdLe3whe35q6rNxavGx8WVFHSpH',
+      });
+    } catch (error: any) {
+      expect(error).toBeInstanceOf(HttpResponseError);
+    }
+
+    done();
+  });
+
+  it('should throw a ViewSimulationError error with a detailed message if the view simulation reaches a failwith instruction', async (done) => {
+    const httpError = new HttpResponseError(
+      'fail',
+      STATUS_CODE.FORBIDDEN,
+      'err',
+      '[{},{"kind":"temporary","with":{"prim":"Unit"}}]',
+      'https://test.com'
+    );
+    mockRpcClient.runScriptView.mockRejectedValue(httpError);
+
+    try {
+      await view.executeView({
+        viewCaller: 'KT1TRHzT3HdLe3whe35q6rNxavGx8WVFHSpH',
+      });
+    } catch (error: any) {
+      expect(error).toBeInstanceOf(ViewSimulationError);
+      expect(error.message).toEqual(
+        'The simulation of the on-chain view named add failed with: {"prim":"Unit"}'
+      );
+      expect(error.viewName).toEqual('add');
+      expect(error.failWith).toEqual({ prim: 'Unit' });
+      expect(error.originalError).toEqual(httpError);
+    }
+
+    done();
+  });
+
+  it('should throw a InvalidViewParameterError error if the parameter of the view is invalid', async (done) => {
+    view = new OnChainView(
+      mockRpcClient as any,
+      mockReadProvider,
+      'contractAddress',
+      new ViewSchema([
+        { string: 'add' },
+        { prim: 'nat' },
+        { prim: 'nat' },
+        [{ prim: 'UNPAIR' }, { prim: 'ADD' }],
+      ]),
+      { prim: 'nat' },
+      'test'
+    );
+    try {
+      await view.executeView({
+        viewCaller: 'KT1TRHzT3HdLe3whe35q6rNxavGx8WVFHSpH',
+      });
+    } catch (error) {
+      expect(error).toBeInstanceOf(InvalidViewParameterError);
+    }
+    done();
+  });
+});
+
+describe('OnChainView test on J protocol', () => {
+  let view: OnChainView;
+  let mockRpcClient: {
+    getProtocols: jest.Mock<any, any>;
     getChainId: jest.Mock<any, any>;
     getBalance: jest.Mock<any, any>;
     runCode: jest.Mock<any, any>;
@@ -21,11 +192,13 @@ describe('OnChainView test', () => {
   let mockReadProvider: any;
   beforeEach(() => {
     mockRpcClient = {
+      getProtocols: jest.fn(),
       getChainId: jest.fn(),
       getBalance: jest.fn(),
       runCode: jest.fn(),
       getStorage: jest.fn(),
     };
+    mockRpcClient.getProtocols.mockResolvedValue({ protocol: Protocols.PtJakart2 });
     mockRpcClient.getChainId.mockResolvedValue('test_chain_id');
     mockRpcClient.getBalance.mockResolvedValue(new BigNumber(5000000));
     mockRpcClient.runCode.mockResolvedValue({
diff --git a/packages/taquito/test/contract/rpc-contract-provider.spec.ts b/packages/taquito/test/contract/rpc-contract-provider.spec.ts
index ace5a59f0..3320788ed 100644
--- a/packages/taquito/test/contract/rpc-contract-provider.spec.ts
+++ b/packages/taquito/test/contract/rpc-contract-provider.spec.ts
@@ -80,7 +80,8 @@ describe('RpcContractProvider test', () => {
     registerGlobalConstant: jest.Mock<any, any>;
     txRollupOriginate: jest.Mock<any, any>;
     txRollupSubmitBatch: jest.Mock<any, any>;
-    transferTicket: jest.Mock<any,any>;
+    transferTicket: jest.Mock<any, any>;
+    increasePaidStorage: jest.Mock<any, any>;
   };
 
   const revealOp = (source: string) => ({
@@ -134,6 +135,7 @@ describe('RpcContractProvider test', () => {
       txRollupOriginate: jest.fn(),
       txRollupSubmitBatch: jest.fn(),
       transferTicket: jest.fn(),
+      increasePaidStorage: jest.fn(),
     };
 
     // Required for operations confirmation polling
@@ -1237,8 +1239,8 @@ describe('RpcContractProvider test', () => {
     });
   });
 
-  describe("transferTicket", () => {
-    it("validate that a reveal operation will be added when needed", async (done) => {
+  describe('transferTicket', () => {
+    it('validate that a reveal operation will be added when needed', async (done) => {
       mockRpcClient.getManagerKey.mockReturnValue(null);
 
       const params: TransferTicketParams = {
@@ -1246,174 +1248,177 @@ describe('RpcContractProvider test', () => {
         fee: 804,
         gasLimit: 5009,
         storageLimit: 130,
-        ticketContents: { "string": "foobar" },
-        ticketTy: { "prim": "string" },
+        ticketContents: { string: 'foobar' },
+        ticketTy: { prim: 'string' },
         ticketTicketer: 'KT1AL8we1Bfajn2M7i3gQM5PJEuyD36sXaYb',
         ticketAmount: 2,
         destination: 'KT1SUT2TBFPCknkBxLqM5eJZKoYVY6mB26Fg',
         entrypoint: 'default',
-        };
-      const result = await rpcContractProvider.transferTicket(params)
-
-      const expectedReveal = revealOp('test_pub_key_hash')
-
-      const expecteReturn = {
-        counter: "2",
-        destination: "KT1SUT2TBFPCknkBxLqM5eJZKoYVY6mB26Fg",
-        entrypoint: "default",
-        fee: "804",
-        gas_limit: "5009",
-        kind: "transfer_ticket",
-        source: "tz1iedjFYksExq8snZK9MNo4AvXHBdXfTsGX",
-        storage_limit: "130",
-        ticket_amount: "2",
+      };
+      const result = await rpcContractProvider.transferTicket(params);
+
+      const expectedReveal = revealOp('test_pub_key_hash');
+
+      const expectedReturn = {
+        counter: '2',
+        destination: 'KT1SUT2TBFPCknkBxLqM5eJZKoYVY6mB26Fg',
+        entrypoint: 'default',
+        fee: '804',
+        gas_limit: '5009',
+        kind: 'transfer_ticket',
+        source: 'tz1iedjFYksExq8snZK9MNo4AvXHBdXfTsGX',
+        storage_limit: '130',
+        ticket_amount: '2',
         ticket_contents: {
-          string: "foobar",
+          string: 'foobar',
         },
-        ticket_ticketer: "KT1AL8we1Bfajn2M7i3gQM5PJEuyD36sXaYb",
+        ticket_ticketer: 'KT1AL8we1Bfajn2M7i3gQM5PJEuyD36sXaYb',
         ticket_ty: {
-          prim: "string",
-        }
-      }
-      const actual = result.raw.opOb.contents ?? []
-      expect(actual[0]).toEqual(expectedReveal)
-      expect(actual[1]).toEqual(expecteReturn)
-      done()
-    })
-    it("validate that a reveal option wont be added when not needed", async (done) => {
+          prim: 'string',
+        },
+      };
+      const actual = result.raw.opOb.contents ?? [];
+      expect(actual[0]).toEqual(expectedReveal);
+      expect(actual[1]).toEqual(expectedReturn);
+      done();
+    });
+
+    it('validate that a reveal option wont be added when not needed', async (done) => {
       mockRpcClient.getManagerKey.mockReturnValue('test_pub_key');
-      mockEstimate.reveal.mockResolvedValue(undefined)
+      mockEstimate.reveal.mockResolvedValue(undefined);
       const params: TransferTicketParams = {
         source: 'tz1iedjFYksExq8snZK9MNo4AvXHBdXfTsGX',
         fee: 804,
         gasLimit: 5009,
         storageLimit: 130,
-        ticketContents: { "string": "foobar" },
-        ticketTy: { "prim": "string" },
+        ticketContents: { string: 'foobar' },
+        ticketTy: { prim: 'string' },
         ticketTicketer: 'KT1AL8we1Bfajn2M7i3gQM5PJEuyD36sXaYb',
         ticketAmount: 2,
         destination: 'KT1SUT2TBFPCknkBxLqM5eJZKoYVY6mB26Fg',
         entrypoint: 'default',
-        };
+      };
       const result = await rpcContractProvider.transferTicket(params);
-      const expecteReturn = {
-        counter: "1",
-        destination: "KT1SUT2TBFPCknkBxLqM5eJZKoYVY6mB26Fg",
-        entrypoint: "default",
-        fee: "804",
-        gas_limit: "5009",
-        kind: "transfer_ticket",
-        source: "tz1iedjFYksExq8snZK9MNo4AvXHBdXfTsGX",
-        storage_limit: "130",
-        ticket_amount: "2",
+      const expectedReturn = {
+        counter: '1',
+        destination: 'KT1SUT2TBFPCknkBxLqM5eJZKoYVY6mB26Fg',
+        entrypoint: 'default',
+        fee: '804',
+        gas_limit: '5009',
+        kind: 'transfer_ticket',
+        source: 'tz1iedjFYksExq8snZK9MNo4AvXHBdXfTsGX',
+        storage_limit: '130',
+        ticket_amount: '2',
         ticket_contents: {
-          string: "foobar",
+          string: 'foobar',
         },
-        ticket_ticketer: "KT1AL8we1Bfajn2M7i3gQM5PJEuyD36sXaYb",
+        ticket_ticketer: 'KT1AL8we1Bfajn2M7i3gQM5PJEuyD36sXaYb',
         ticket_ty: {
-          prim: "string",
-        }
-      }
-      const actual = result.raw.opOb.contents ?? []
+          prim: 'string',
+        },
+      };
+      const actual = result.raw.opOb.contents ?? [];
+
+      expect(actual[0]).toEqual(expectedReturn);
+      done();
+    });
 
-      expect(actual[0]).toEqual(expecteReturn)
-      done()
-    })
-    it("validate that the user-specified fees will be taken into account when specified", async (done) => {
+    it('validate that the user-specified fees will be taken into account when specified', async (done) => {
       const params: TransferTicketParams = {
         source: 'tz1iedjFYksExq8snZK9MNo4AvXHBdXfTsGX',
         fee: 804,
         gasLimit: 5009,
         storageLimit: 130,
-        ticketContents: { "string": "foobar" },
-        ticketTy: { "prim": "string" },
+        ticketContents: { string: 'foobar' },
+        ticketTy: { prim: 'string' },
         ticketTicketer: 'KT1AL8we1Bfajn2M7i3gQM5PJEuyD36sXaYb',
         ticketAmount: 2,
         destination: 'KT1SUT2TBFPCknkBxLqM5eJZKoYVY6mB26Fg',
         entrypoint: 'default',
-        };
-      const result = await rpcContractProvider.transferTicket(params)
+      };
+      const result = await rpcContractProvider.transferTicket(params);
       const expectedReveal = {
         counter: 0,
         opOb: {
-          branch: "test",
-          contents:  [
+          branch: 'test',
+          contents: [
             revealOp('test_pub_key_hash'),
             {
-              counter: "2",
-              destination: "KT1SUT2TBFPCknkBxLqM5eJZKoYVY6mB26Fg",
-              entrypoint: "default",
-              fee: "804",
-              gas_limit: "5009",
-              kind: "transfer_ticket",
-              source: "tz1iedjFYksExq8snZK9MNo4AvXHBdXfTsGX",
-              storage_limit: "130",
-              ticket_amount: "2",
+              counter: '2',
+              destination: 'KT1SUT2TBFPCknkBxLqM5eJZKoYVY6mB26Fg',
+              entrypoint: 'default',
+              fee: '804',
+              gas_limit: '5009',
+              kind: 'transfer_ticket',
+              source: 'tz1iedjFYksExq8snZK9MNo4AvXHBdXfTsGX',
+              storage_limit: '130',
+              ticket_amount: '2',
               ticket_contents: {
-                string: "foobar",
+                string: 'foobar',
               },
-              ticket_ticketer: "KT1AL8we1Bfajn2M7i3gQM5PJEuyD36sXaYb",
+              ticket_ticketer: 'KT1AL8we1Bfajn2M7i3gQM5PJEuyD36sXaYb',
               ticket_ty: {
-                prim: "string",
+                prim: 'string',
               },
             },
           ],
-          protocol: "test_proto",
-          signature: "test_sig",
+          protocol: 'test_proto',
+          signature: 'test_sig',
         },
-        opbytes: "test",
-      }
-      expect(result.raw).toEqual(expectedReveal)
-      done()
-    })
-    it("validate that the fees taken from the estimate will be taken when there is no user-specified fees", async (done) => {
+        opbytes: 'test',
+      };
+      expect(result.raw).toEqual(expectedReveal);
+      done();
+    });
+
+    it('validate that the fees taken from the estimate will be taken when there is no user-specified fees', async (done) => {
       const estimate = new Estimate(10000, 1000, 180, 1000);
       mockEstimate.transferTicket.mockResolvedValue(estimate);
 
       const params: TransferTicketParams = {
         source: 'tz1iedjFYksExq8snZK9MNo4AvXHBdXfTsGX',
-        ticketContents: { "string": "foobar" },
-        ticketTy: { "prim": "string" },
+        ticketContents: { string: 'foobar' },
+        ticketTy: { prim: 'string' },
         ticketTicketer: 'KT1AL8we1Bfajn2M7i3gQM5PJEuyD36sXaYb',
         ticketAmount: 2,
         destination: 'KT1SUT2TBFPCknkBxLqM5eJZKoYVY6mB26Fg',
         entrypoint: 'default',
-        };
-      const result = await rpcContractProvider.transferTicket(params)
+      };
+      const result = await rpcContractProvider.transferTicket(params);
       const expected = {
         counter: 0,
         opOb: {
-          branch: "test",
-          contents:  [
+          branch: 'test',
+          contents: [
             revealOp('test_pub_key_hash'),
             {
-              counter: "2",
-              destination: "KT1SUT2TBFPCknkBxLqM5eJZKoYVY6mB26Fg",
-              entrypoint: "default",
+              counter: '2',
+              destination: 'KT1SUT2TBFPCknkBxLqM5eJZKoYVY6mB26Fg',
+              entrypoint: 'default',
               fee: estimate.suggestedFeeMutez.toString(),
               gas_limit: estimate.gasLimit.toString(),
-              kind: "transfer_ticket",
-              source: "tz1iedjFYksExq8snZK9MNo4AvXHBdXfTsGX",
+              kind: 'transfer_ticket',
+              source: 'tz1iedjFYksExq8snZK9MNo4AvXHBdXfTsGX',
               storage_limit: estimate.storageLimit.toString(),
-              ticket_amount: "2",
+              ticket_amount: '2',
               ticket_contents: {
-                string: "foobar",
+                string: 'foobar',
               },
-              ticket_ticketer: "KT1AL8we1Bfajn2M7i3gQM5PJEuyD36sXaYb",
+              ticket_ticketer: 'KT1AL8we1Bfajn2M7i3gQM5PJEuyD36sXaYb',
               ticket_ty: {
-                prim: "string",
+                prim: 'string',
               },
             },
           ],
-          protocol: "test_proto",
-          signature: "test_sig",
+          protocol: 'test_proto',
+          signature: 'test_sig',
         },
-        opbytes: "test",
-      }
-      expect(result.raw).toEqual(expected)
-      done()
-    })
-  })
+        opbytes: 'test',
+      };
+      expect(result.raw).toEqual(expected);
+      done();
+    });
+  });
 
   describe('setDelegate', () => {
     it('should produce a reveal and delegation operation', async (done) => {
@@ -1558,6 +1563,106 @@ describe('RpcContractProvider test', () => {
     });
   });
 
+  describe('increasePaidStorage', () => {
+    it('should produce an increasePaidStorage operation', async (done) => {
+      mockRpcClient.getManagerKey.mockReturnValue('test_pub_key_hash');
+      mockEstimate.reveal.mockResolvedValue(undefined);
+      const estimate = new Estimate(1230000, 93, 142, 250);
+      mockEstimate.increasePaidStorage.mockResolvedValue(estimate);
+      const result = await rpcContractProvider.increasePaidStorage({
+        amount: 1,
+        destination: 'KT1UiLW7MQCrgaG8pubSJsnpFZzxB2PMs92W',
+      });
+      expect(result.raw).toEqual({
+        opbytes: 'test',
+        opOb: {
+          branch: 'test',
+          contents: [
+            {
+              kind: 'increase_paid_storage',
+              source: 'test_pub_key_hash',
+              fee: '475',
+              gas_limit: '1330',
+              storage_limit: '93',
+              amount: '1',
+              destination: 'KT1UiLW7MQCrgaG8pubSJsnpFZzxB2PMs92W',
+              counter: '1',
+            },
+          ],
+          protocol: 'test_proto',
+          signature: 'test_sig',
+        },
+        counter: 0,
+      });
+      done();
+    });
+
+    it('should produce a reveal and an increasePaidStorage operation', async (done) => {
+      const estimate = new Estimate(1230000, 93, 142, 250);
+      mockEstimate.increasePaidStorage.mockResolvedValue(estimate);
+      const result = await rpcContractProvider.increasePaidStorage({
+        amount: 1,
+        destination: 'KT1UiLW7MQCrgaG8pubSJsnpFZzxB2PMs92W',
+      });
+      expect(result.raw).toEqual({
+        opbytes: 'test',
+        opOb: {
+          branch: 'test',
+          contents: [
+            revealOp('test_pub_key_hash'),
+            {
+              kind: 'increase_paid_storage',
+              source: 'test_pub_key_hash',
+              fee: '475',
+              gas_limit: '1330',
+              storage_limit: '93',
+              amount: '1',
+              destination: 'KT1UiLW7MQCrgaG8pubSJsnpFZzxB2PMs92W',
+              counter: '2',
+            },
+          ],
+          protocol: 'test_proto',
+          signature: 'test_sig',
+        },
+        counter: 0,
+      });
+      done();
+    });
+
+    it('should produce a reveal and increasePaidStorageOperation with fees specified', async (done) => {
+      const estimate = new Estimate(1230000, 93, 142, 250);
+      mockEstimate.increasePaidStorage.mockResolvedValue(estimate);
+      const result = await rpcContractProvider.increasePaidStorage({
+        amount: 1,
+        destination: 'KT1UiLW7MQCrgaG8pubSJsnpFZzxB2PMs92W',
+        fee: 500,
+      });
+      expect(result.raw).toEqual({
+        opbytes: 'test',
+        opOb: {
+          branch: 'test',
+          contents: [
+            revealOp('test_pub_key_hash'),
+            {
+              kind: 'increase_paid_storage',
+              source: 'test_pub_key_hash',
+              fee: '500',
+              gas_limit: '1330',
+              storage_limit: '93',
+              amount: '1',
+              destination: 'KT1UiLW7MQCrgaG8pubSJsnpFZzxB2PMs92W',
+              counter: '2',
+            },
+          ],
+          protocol: 'test_proto',
+          signature: 'test_sig',
+        },
+        counter: 0,
+      });
+      done();
+    });
+  });
+
   describe('txRollupOriginate', () => {
     it('should produce a reveal and txRollupOriginate operation', async (done) => {
       const result = await rpcContractProvider.txRollupOriginate({
diff --git a/packages/taquito/test/helpers.ts b/packages/taquito/test/helpers.ts
index efdb16e85..46d66c1a2 100644
--- a/packages/taquito/test/helpers.ts
+++ b/packages/taquito/test/helpers.ts
@@ -9,6 +9,7 @@ import {
   OperationContentsAndResultTxRollupOrigination,
   OperationContentsAndResultTxRollupSubmitBatch,
   OperationContentsAndResultTransferTicket,
+  OperationContentsAndResultIncreasePaidStorage,
 } from '@taquito/rpc';
 
 const defaultTransferData = {
@@ -102,6 +103,17 @@ const defaultTransferTicketData = {
   entrypoint: 'default',
 };
 
+const defaultIncreasePaidStorageData = {
+  kind: OpKind.INCREASE_PAID_STORAGE as OpKind.INCREASE_PAID_STORAGE,
+  source: 'tz2RVendfy3AQGEBwrhXF4kwyRiJUpa7qLnG',
+  fee: '349',
+  counter: '108123',
+  gas_limit: '1000',
+  storage_limit: '0',
+  amount: '2',
+  destination: 'KT1Vjr5PFC2Qm5XbSQZ8MdFZLgYMzwG5WZNh',
+};
+
 const defaultResult = {
   status: 'applied' as OperationResultStatusEnum,
   consumed_milligas: '15952999',
@@ -251,6 +263,35 @@ export class RegisterGlobalConstantOperationBuilder {
   }
 }
 
+export class IncreasePaidStorageOperationBuilder {
+  private result: OperationContentsAndResultIncreasePaidStorage['metadata']['operation_result'] =
+    defaultResult;
+  private data: Omit<OperationContentsAndResultIncreasePaidStorage, 'metadata'>;
+
+  constructor(
+    private _data: Partial<Omit<OperationContentsAndResultIncreasePaidStorage, 'metadata'>> = {}
+  ) {
+    this.data = { ...defaultIncreasePaidStorageData, ...this._data };
+  }
+
+  withResult(
+    result: Partial<OperationContentsAndResultIncreasePaidStorage['metadata']['operation_result']>
+  ) {
+    this.result = { ...defaultResult, ...result };
+    return this;
+  }
+
+  build(): OperationContentsAndResultIncreasePaidStorage {
+    return {
+      ...this.data,
+      metadata: {
+        balance_updates: [],
+        operation_result: this.result,
+      },
+    };
+  }
+}
+
 export class TxRollupOriginationOperationBuilder {
   private result: OperationContentsAndResultTxRollupOrigination['metadata']['operation_result'] =
     defaultResult;
diff --git a/packages/taquito/test/operations/increase-paid-storage-operation.spec.ts b/packages/taquito/test/operations/increase-paid-storage-operation.spec.ts
new file mode 100644
index 000000000..0d349099e
--- /dev/null
+++ b/packages/taquito/test/operations/increase-paid-storage-operation.spec.ts
@@ -0,0 +1,202 @@
+import { ForgedBytes } from '../../src/operations/types';
+import { OperationContentsAndResult } from '@taquito/rpc';
+import { IncreasePaidStorageOperation } from '../../src/operations/increase-paid-storage-operation';
+import { defaultConfigConfirmation } from '../../src/context';
+import { IncreasePaidStorageOperationBuilder } from '../helpers';
+
+describe('IncreasePaidStorage operation', () => {
+  let fakeContext: any;
+  const fakeForgedBytes = {} as ForgedBytes;
+
+  const successfulResult = [
+    {
+      kind: 'increase_paid_storage',
+      source: 'tz2RVendfy3AQGEBwrhXF4kwyRiJUpa7qLnG',
+      fee: '349',
+      counter: '108123',
+      gas_limit: '1000',
+      storage_limit: '0',
+      amount: '2',
+      destination: 'KT1Vjr5PFC2Qm5XbSQZ8MdFZLgYMzwG5WZNh',
+      metadata: {
+        balance_updates: [
+          {
+            kind: 'contract',
+            contract: 'tz2RVendfy3AQGEBwrhXF4kwyRiJUpa7qLnG',
+            change: '-349',
+            origin: 'block',
+          },
+          {
+            kind: 'accumulator',
+            category: 'block fees',
+            change: '349',
+            origin: 'block',
+          },
+        ],
+        operation_result: {
+          status: 'applied',
+          balance_updates: [
+            {
+              kind: 'contract',
+              contract: 'tz2RVendfy3AQGEBwrhXF4kwyRiJUpa7qLnG',
+              change: '-500',
+              origin: 'block',
+            },
+            {
+              kind: 'burned',
+              category: 'storage fees',
+              change: '500',
+              origin: 'block',
+            },
+          ],
+          consumed_milligas: '1000000',
+        },
+      },
+    },
+  ] as OperationContentsAndResult[];
+
+  beforeEach(() => {
+    fakeContext = {
+      rpc: {
+        getBlock: jest.fn(),
+      },
+      config: { ...defaultConfigConfirmation },
+    };
+
+    fakeContext.rpc.getBlock.mockResolvedValue({
+      operations: [[{ hash: 'ooBghN2ok5EpgEuMqYWqvfwNLBiK9eNFoPai91iwqk2nRCyUKgE' }], [], [], []],
+      header: {
+        level: 1,
+      },
+    });
+  });
+
+  it('should return status of IncreasePaidStorage operation', () => {
+    const op = new IncreasePaidStorageOperation(
+      'ooBghN2ok5EpgEuMqYWqvfwNLBiK9eNFoPai91iwqk2nRCyUKgE',
+      {} as any,
+      '',
+      fakeForgedBytes,
+      successfulResult,
+      fakeContext
+    );
+
+    expect(op.status).toEqual('applied');
+  });
+
+  it('should return the consumedMilligas', () => {
+    const op = new IncreasePaidStorageOperation(
+      'ooBghN2ok5EpgEuMqYWqvfwNLBiK9eNFoPai91iwqk2nRCyUKgE',
+      {} as any,
+      '',
+      fakeForgedBytes,
+      successfulResult,
+      fakeContext
+    );
+
+    expect(op.consumedMilliGas).toEqual('1000000');
+  });
+
+  it('should return the fee', () => {
+    const op = new IncreasePaidStorageOperation(
+      'ooBghN2ok5EpgEuMqYWqvfwNLBiK9eNFoPai91iwqk2nRCyUKgE',
+      { fee: 400 } as any,
+      '',
+      fakeForgedBytes,
+      successfulResult,
+      fakeContext
+    );
+
+    expect(op.fee).toEqual(400);
+  });
+
+  it('should return the error if there is one', () => {
+    const tx = new IncreasePaidStorageOperationBuilder();
+    const op = new IncreasePaidStorageOperation(
+      'ooBghN2ok5EpgEuMqYWqvfwNLBiK9eNFoPai91iwqk2nRCyUKgE',
+      {} as any,
+      '',
+      fakeForgedBytes,
+      [
+        tx
+          .withResult({
+            status: 'backtracked',
+            errors: [{ kind: 'temporary', id: 'proto.014-PtKathma.tez.subtraction_underflow' }],
+          })
+          .build(),
+      ],
+      fakeContext
+    );
+
+    expect(op.errors).toBeDefined();
+    expect(op.errors?.[0]).toEqual({
+      kind: 'temporary',
+      id: 'proto.014-PtKathma.tez.subtraction_underflow',
+    });
+  });
+
+  it('should return the gasLimit', () => {
+    const op = new IncreasePaidStorageOperation(
+      'ooBghN2ok5EpgEuMqYWqvfwNLBiK9eNFoPai91iwqk2nRCyUKgE',
+      { gas_limit: 450 } as any,
+      '',
+      fakeForgedBytes,
+      successfulResult,
+      fakeContext
+    );
+
+    expect(op.gasLimit).toEqual(450);
+  });
+
+  it('should return the storageLimit', () => {
+    const op = new IncreasePaidStorageOperation(
+      'ooBghN2ok5EpgEuMqYWqvfwNLBiK9eNFoPai91iwqk2nRCyUKgE',
+      { storage_limit: 450 } as any,
+      '',
+      fakeForgedBytes,
+      successfulResult,
+      fakeContext
+    );
+
+    expect(op.storageLimit).toEqual(450);
+  });
+
+  it('error property should be undefined when no error occurs', () => {
+    const op = new IncreasePaidStorageOperation(
+      'ooBghN2ok5EpgEuMqYWqvfwNLBiK9eNFoPai91iwqk2nRCyUKgE',
+      {} as any,
+      '',
+      fakeForgedBytes,
+      successfulResult,
+      fakeContext
+    );
+
+    expect(op.errors).toBeUndefined();
+  });
+
+  it('should return amount of increased bytes', () => {
+    const op = new IncreasePaidStorageOperation(
+      'ooBghN2ok5EpgEuMqYWqvfwNLBiK9eNFoPai91iwqk2nRCyUKgE',
+      { amount: 1 } as any,
+      '',
+      fakeForgedBytes,
+      successfulResult,
+      fakeContext
+    );
+
+    expect(op.amount).toEqual(1);
+  });
+
+  it('should return destination', () => {
+    const op = new IncreasePaidStorageOperation(
+      'ooBghN2ok5EpgEuMqYWqvfwNLBiK9eNFoPai91iwqk2nRCyUKgE',
+      { destination: 'testDestination' } as any,
+      '',
+      fakeForgedBytes,
+      successfulResult,
+      fakeContext
+    );
+
+    expect(op.destination).toEqual('testDestination');
+  });
+});