Repository: solana-labs/solana-program-library
Pull request #7420 (2024-10-31 07:33:07)

chore: update instruction.rs
Unitialized -> Uninitialized


Patch:
diff --git a/account-compression/sdk/package.json b/account-compression/sdk/package.json
index c37be638b..1ee201e40 100644
--- a/account-compression/sdk/package.json
+++ b/account-compression/sdk/package.json
@@ -67,7 +67,7 @@
     "@solana/eslint-config-solana": "^3.0.3",
     "@types/bn.js": "^5.1.6",
     "@types/jest": "^29.5.14",
-    "@types/node": "^22.8.4",
+    "@types/node": "^22.8.5",
     "@types/node-fetch": "^2.6.11",
     "@typescript-eslint/eslint-plugin": "^8.4.0",
     "@typescript-eslint/parser": "^8.4.0",
diff --git a/libraries/type-length-value/js/package.json b/libraries/type-length-value/js/package.json
index 3390c414b..2f7c36191 100644
--- a/libraries/type-length-value/js/package.json
+++ b/libraries/type-length-value/js/package.json
@@ -49,14 +49,14 @@
     "devDependencies": {
         "@types/chai": "^5.0.1",
         "@types/mocha": "^10.0.9",
-        "@types/node": "^22.8.4",
+        "@types/node": "^22.8.5",
         "@typescript-eslint/eslint-plugin": "^8.4.0",
         "@typescript-eslint/parser": "^8.4.0",
         "chai": "^5.1.2",
         "eslint": "^8.57.0",
         "eslint-plugin-require-extensions": "^0.1.1",
         "gh-pages": "^6.2.0",
-        "mocha": "^10.8.1",
+        "mocha": "^10.8.2",
         "shx": "^0.3.4",
         "ts-node": "^10.9.2",
         "typedoc": "^0.26.10",
diff --git a/memo/js/package.json b/memo/js/package.json
index 717af855c..655dacf94 100644
--- a/memo/js/package.json
+++ b/memo/js/package.json
@@ -54,7 +54,7 @@
         "@solana/web3.js": "^1.95.4",
         "@types/chai": "^5.0.1",
         "@types/jest": "^29.5.14",
-        "@types/node": "^22.8.4",
+        "@types/node": "^22.8.5",
         "@types/node-fetch": "^2.6.11",
         "@typescript-eslint/eslint-plugin": "^8.4.0",
         "@typescript-eslint/parser": "^8.4.0",
diff --git a/name-service/js/package.json b/name-service/js/package.json
index 82c76265b..0dcbc8547 100644
--- a/name-service/js/package.json
+++ b/name-service/js/package.json
@@ -45,7 +45,7 @@
     "@jest/globals": "^29.7.0",
     "@types/bn.js": "^5.1.6",
     "@types/jest": "^29.5.14",
-    "@types/node": "^22.8.4",
+    "@types/node": "^22.8.5",
     "@typescript-eslint/eslint-plugin": "^8.4.0",
     "@typescript-eslint/parser": "^8.4.0",
     "eslint": "^8.57.0",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index dc1f06e48..3cd705515 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -70,8 +70,8 @@ importers:
         specifier: ^29.5.14
         version: 29.5.14
       '@types/node':
-        specifier: ^22.8.4
-        version: 22.8.4
+        specifier: ^22.8.5
+        version: 22.8.5
       '@types/node-fetch':
         specifier: ^2.6.11
         version: 2.6.11
@@ -107,10 +107,10 @@ importers:
         version: 6.2.0
       jest:
         specifier: ^29.0.1
-        version: 29.7.0(@types/node@22.8.4)(ts-node@10.9.2)
+        version: 29.7.0(@types/node@22.8.5)(ts-node@10.9.2)
       jest-config:
         specifier: ^29.0.1
-        version: 29.7.0(@types/node@22.8.4)(ts-node@10.9.2)
+        version: 29.7.0(@types/node@22.8.5)(ts-node@10.9.2)
       start-server-and-test:
         specifier: ^2.0.8
         version: 2.0.8
@@ -122,7 +122,7 @@ importers:
         version: 2.0.1
       ts-node:
         specifier: ^10.9.2
-        version: 10.9.2(@types/node@22.8.4)(typescript@5.6.3)
+        version: 10.9.2(@types/node@22.8.5)(typescript@5.6.3)
       typedoc:
         specifier: ^0.26.10
         version: 0.26.10(typescript@5.6.3)
@@ -146,8 +146,8 @@ importers:
         specifier: ^10.0.9
         version: 10.0.9
       '@types/node':
-        specifier: ^22.8.4
-        version: 22.8.4
+        specifier: ^22.8.5
+        version: 22.8.5
       '@typescript-eslint/eslint-plugin':
         specifier: ^8.4.0
         version: 8.4.0(@typescript-eslint/parser@8.4.0)(eslint@8.57.0)(typescript@5.6.3)
@@ -167,14 +167,14 @@ importers:
         specifier: ^6.2.0
         version: 6.2.0
       mocha:
-        specifier: ^10.8.1
-        version: 10.8.1
+        specifier: ^10.8.2
+        version: 10.8.2
       shx:
         specifier: ^0.3.4
         version: 0.3.4
       ts-node:
         specifier: ^10.9.2
-        version: 10.9.2(@types/node@22.8.4)(typescript@5.6.3)
+        version: 10.9.2(@types/node@22.8.5)(typescript@5.6.3)
       typedoc:
         specifier: ^0.26.10
         version: 0.26.10(typescript@5.6.3)
@@ -198,8 +198,8 @@ importers:
         specifier: ^29.5.14
         version: 29.5.14
       '@types/node':
-        specifier: ^22.8.4
-        version: 22.8.4
+        specifier: ^22.8.5
+        version: 22.8.5
       '@types/node-fetch':
         specifier: ^2.6.11
         version: 2.6.11
@@ -223,7 +223,7 @@ importers:
         version: 6.2.0
       jest:
         specifier: ^29.0.0
-        version: 29.7.0(@types/node@22.8.4)(ts-node@10.9.2)
+        version: 29.7.0(@types/node@22.8.5)(ts-node@10.9.2)
       process:
         specifier: ^0.11.10
         version: 0.11.10
@@ -238,7 +238,7 @@ importers:
         version: 29.2.5(@babel/core@7.23.2)(jest@29.7.0)(typescript@5.6.3)
       ts-node:
         specifier: ^10.9.2
-        version: 10.9.2(@types/node@22.8.4)(typescript@5.6.3)
+        version: 10.9.2(@types/node@22.8.5)(typescript@5.6.3)
       typedoc:
         specifier: ^0.26.10
         version: 0.26.10(typescript@5.6.3)
@@ -268,8 +268,8 @@ importers:
         specifier: ^29.5.14
         version: 29.5.14
       '@types/node':
-        specifier: ^22.8.4
-        version: 22.8.4
+        specifier: ^22.8.5
+        version: 22.8.5
       '@typescript-eslint/eslint-plugin':
         specifier: ^8.4.0
         version: 8.4.0(@typescript-eslint/parser@8.4.0)(eslint@8.57.0)(typescript@5.6.3)
@@ -290,7 +290,7 @@ importers:
         version: 2.31.0(@typescript-eslint/parser@8.4.0)(eslint@8.57.0)
       jest:
         specifier: ^29.7.0
-        version: 29.7.0(@types/node@22.8.4)(ts-node@10.9.2)
+        version: 29.7.0(@types/node@22.8.5)(ts-node@10.9.2)
       start-server-and-test:
         specifier: ^2.0.8
         version: 2.0.8
@@ -299,7 +299,7 @@ importers:
         version: 29.2.5(@babel/core@7.23.2)(jest@29.7.0)(typescript@5.6.3)
       ts-node:
         specifier: ^10.9.2
-        version: 10.9.2(@types/node@22.8.4)(typescript@5.6.3)
+        version: 10.9.2(@types/node@22.8.5)(typescript@5.6.3)
       typedoc:
         specifier: ^0.26.10
         version: 0.26.10(typescript@5.6.3)
@@ -323,8 +323,8 @@ importers:
         specifier: ^5.0.0
         version: 5.0.0
       '@types/node':
-        specifier: ^22.8.4
-        version: 22.8.4
+        specifier: ^22.8.5
+        version: 22.8.5
       '@typescript-eslint/eslint-plugin':
         specifier: ^8.4.0
         version: 8.4.0(@typescript-eslint/parser@8.4.0)(eslint@8.57.0)(typescript@5.6.3)
@@ -357,8 +357,8 @@ importers:
         version: 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3)
     devDependencies:
       '@types/node':
-        specifier: ^22.8.4
-        version: 22.8.4
+        specifier: ^22.8.5
+        version: 22.8.5
       '@typescript-eslint/eslint-plugin':
         specifier: ^8.4.0
         version: 8.4.0(@typescript-eslint/parser@8.4.0)(eslint@8.57.0)(typescript@5.6.3)
@@ -421,8 +421,8 @@ importers:
         specifier: ^29.5.14
         version: 29.5.14
       '@types/node':
-        specifier: ^22.8.4
-        version: 22.8.4
+        specifier: ^22.8.5
+        version: 22.8.5
       '@types/node-fetch':
         specifier: ^2.6.11
         version: 2.6.11
@@ -440,7 +440,7 @@ importers:
         version: 8.57.0
       jest:
         specifier: ^29.0.0
-        version: 29.7.0(@types/node@22.8.4)(ts-node@10.9.2)
+        version: 29.7.0(@types/node@22.8.5)(ts-node@10.9.2)
       rimraf:
         specifier: ^6.0.1
         version: 6.0.1
@@ -476,8 +476,8 @@ importers:
         specifier: ^10.0.9
         version: 10.0.9
       '@types/node':
-        specifier: ^22.8.4
-        version: 22.8.4
+        specifier: ^22.8.5
+        version: 22.8.5
       '@typescript-eslint/eslint-plugin':
         specifier: ^8.4.0
         version: 8.4.0(@typescript-eslint/parser@8.4.0)(eslint@8.57.0)(typescript@5.6.3)
@@ -497,14 +497,14 @@ importers:
         specifier: ^6.2.0
         version: 6.2.0
       mocha:
-        specifier: ^10.8.1
-        version: 10.8.1
+        specifier: ^10.8.2
+        version: 10.8.2
       shx:
         specifier: ^0.3.4
         version: 0.3.4
       ts-node:
         specifier: ^10.9.2
-        version: 10.9.2(@types/node@22.8.4)(typescript@5.6.3)
+        version: 10.9.2(@types/node@22.8.5)(typescript@5.6.3)
       tslib:
         specifier: ^2.8.0
         version: 2.8.0
@@ -549,8 +549,8 @@ importers:
         specifier: ^8.56.7
         version: 8.56.7
       '@types/node':
-        specifier: ^22.8.4
-        version: 22.8.4
+        specifier: ^22.8.5
+        version: 22.8.5
       '@typescript-eslint/eslint-plugin':
         specifier: ^8.4.0
         version: 8.4.0(@typescript-eslint/parser@8.4.0)(eslint@8.57.0)(typescript@5.6.3)
@@ -568,7 +568,7 @@ importers:
         version: 4.24.3
       ts-node:
         specifier: ^10.9.2
-        version: 10.9.2(@types/node@22.8.4)(typescript@5.6.3)
+        version: 10.9.2(@types/node@22.8.5)(typescript@5.6.3)
       tslib:
         specifier: ^2.8.0
         version: 2.8.0
@@ -598,8 +598,8 @@ importers:
         specifier: ^10.0.9
         version: 10.0.9
       '@types/node':
-        specifier: ^22.8.4
-        version: 22.8.4
+        specifier: ^22.8.5
+        version: 22.8.5
       '@typescript-eslint/eslint-plugin':
         specifier: ^8.4.0
         version: 8.4.0(@typescript-eslint/parser@8.4.0)(eslint@8.57.0)(typescript@5.6.3)
@@ -619,14 +619,14 @@ importers:
         specifier: ^6.2.0
         version: 6.2.0
       mocha:
-        specifier: ^10.8.1
-        version: 10.8.1
+        specifier: ^10.8.2
+        version: 10.8.2
       shx:
         specifier: ^0.3.4
         version: 0.3.4
       ts-node:
         specifier: ^10.9.2
-        version: 10.9.2(@types/node@22.8.4)(typescript@5.6.3)
+        version: 10.9.2(@types/node@22.8.5)(typescript@5.6.3)
       tslib:
         specifier: ^2.8.0
         version: 2.8.0
@@ -680,14 +680,14 @@ importers:
         specifier: ^0.1.1
         version: 0.1.3(eslint@8.57.0)
       mocha:
-        specifier: ^10.8.1
-        version: 10.8.1
+        specifier: ^10.8.2
+        version: 10.8.2
       start-server-and-test:
         specifier: ^2.0.8
         version: 2.0.8
       ts-node:
         specifier: ^10.9.2
-        version: 10.9.2(@types/node@22.8.4)(typescript@5.6.3)
+        version: 10.9.2(@types/node@22.8.5)(typescript@5.6.3)
       typescript:
         specifier: ^5.6.3
         version: 5.6.3
@@ -729,8 +729,8 @@ importers:
         specifier: ^10.0.9
         version: 10.0.9
       '@types/node':
-        specifier: ^22.8.4
-        version: 22.8.4
+        specifier: ^22.8.5
+        version: 22.8.5
       '@types/node-fetch':
         specifier: ^2.6.11
         version: 2.6.11
@@ -756,8 +756,8 @@ importers:
         specifier: ^6.2.0
         version: 6.2.0
       mocha:
-        specifier: ^10.8.1
-        version: 10.8.1
+        specifier: ^10.8.2
+        version: 10.8.2
       process:
         specifier: ^0.11.10
         version: 0.11.10
@@ -769,7 +769,7 @@ importers:
         version: 2.0.8
       ts-node:
         specifier: ^10.9.2
-        version: 10.9.2(@types/node@22.8.4)(typescript@5.6.3)
+        version: 10.9.2(@types/node@22.8.5)(typescript@5.6.3)
       typedoc:
         specifier: ^0.26.10
         version: 0.26.10(typescript@5.6.3)
@@ -1494,7 +1494,7 @@ packages:
     engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
     dependencies:
       '@jest/types': 29.6.3
-      '@types/node': 22.8.4
+      '@types/node': 22.8.5
       chalk: 4.1.2
       jest-message-util: 29.7.0
       jest-util: 29.7.0
@@ -1515,14 +1515,14 @@ packages:
       '@jest/test-result': 29.7.0
       '@jest/transform': 29.7.0
       '@jest/types': 29.6.3
-      '@types/node': 22.8.4
+      '@types/node': 22.8.5
       ansi-escapes: 4.3.2
       chalk: 4.1.2
       ci-info: 3.9.0
       exit: 0.1.2
       graceful-fs: 4.2.11
       jest-changed-files: 29.7.0
-      jest-config: 29.7.0(@types/node@22.8.4)(ts-node@10.9.2)
+      jest-config: 29.7.0(@types/node@22.8.5)(ts-node@10.9.2)
       jest-haste-map: 29.7.0
       jest-message-util: 29.7.0
       jest-regex-util: 29.6.3
@@ -1550,7 +1550,7 @@ packages:
     dependencies:
       '@jest/fake-timers': 29.7.0
       '@jest/types': 29.6.3
-      '@types/node': 22.8.4
+      '@types/node': 22.8.5
       jest-mock: 29.7.0
     dev: true
 
@@ -1577,7 +1577,7 @@ packages:
     dependencies:
       '@jest/types': 29.6.3
       '@sinonjs/fake-timers': 10.3.0
-      '@types/node': 22.8.4
+      '@types/node': 22.8.5
       jest-message-util: 29.7.0
       jest-mock: 29.7.0
       jest-util: 29.7.0
@@ -1610,7 +1610,7 @@ packages:
       '@jest/transform': 29.7.0
       '@jest/types': 29.6.3
       '@jridgewell/trace-mapping': 0.3.20
-      '@types/node': 22.8.4
+      '@types/node': 22.8.5
       chalk: 4.1.2
       collect-v8-coverage: 1.0.2
       exit: 0.1.2
@@ -1698,7 +1698,7 @@ packages:
       '@jest/schemas': 29.6.3
       '@types/istanbul-lib-coverage': 2.0.6
       '@types/istanbul-reports': 3.0.4
-      '@types/node': 22.8.4
+      '@types/node': 22.8.5
       '@types/yargs': 17.0.31
       chalk: 4.1.2
     dev: true
@@ -2522,7 +2522,7 @@ packages:
   /@types/bn.js@5.1.6:
     resolution: {integrity: sha512-Xh8vSwUeMKeYYrj3cX4lGQgFSF/N03r+tv4AiLl1SucqV+uTQpxRcnM8AkXKHwYP9ZPXOYXRr2KPXpVlIvqh9w==}
     dependencies:
-      '@types/node': 22.8.4
+      '@types/node': 22.8.5
     dev: true
 
   /@types/chai-as-promised@8.0.1:
@@ -2540,7 +2540,7 @@ packages:
   /@types/connect@3.4.38:
     resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==}
     dependencies:
-      '@types/node': 22.8.4
+      '@types/node': 22.8.5
 
   /@types/deep-eql@4.0.2:
     resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==}
@@ -2564,7 +2564,7 @@ packages:
   /@types/graceful-fs@4.1.9:
     resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==}
     dependencies:
-      '@types/node': 22.8.4
+      '@types/node': 22.8.5
     dev: true
 
   /@types/hast@3.0.4:
@@ -2611,15 +2611,15 @@ packages:
   /@types/node-fetch@2.6.11:
     resolution: {integrity: sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==}
     dependencies:
-      '@types/node': 22.8.4
+      '@types/node': 22.8.5
       form-data: 4.0.0
     dev: true
 
   /@types/node@12.20.55:
     resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==}
 
-  /@types/node@22.8.4:
-    resolution: {integrity: sha512-SpNNxkftTJOPk0oN+y2bIqurEXHTA2AOZ3EJDDKeJ5VzkvvORSvmQXGQarcOzWV1ac7DCaPBEdMDxBsM+d8jWw==}
+  /@types/node@22.8.5:
+    resolution: {integrity: sha512-5iYk6AMPtsMbkZqCO1UGF9W5L38twq11S2pYWkybGHH2ogPUvXWNlQqJBzuEZWKj/WRH+QTeiv6ySWqJtvIEgA==}
     dependencies:
       undici-types: 6.19.8
 
@@ -2645,12 +2645,12 @@ packages:
   /@types/ws@7.4.7:
     resolution: {integrity: sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==}
     dependencies:
-      '@types/node': 22.8.4
+      '@types/node': 22.8.5
 
   /@types/ws@8.5.10:
     resolution: {integrity: sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==}
     dependencies:
-      '@types/node': 22.8.4
+      '@types/node': 22.8.5
 
   /@types/yargs-parser@21.0.3:
     resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==}
@@ -3933,7 +3933,7 @@ packages:
     engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
     dev: true
 
-  /create-jest@29.7.0(@types/node@22.8.4)(ts-node@10.9.2):
+  /create-jest@29.7.0(@types/node@22.8.5)(ts-node@10.9.2):
     resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==}
     engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
     hasBin: true
@@ -3942,7 +3942,7 @@ packages:
       chalk: 4.1.2
       exit: 0.1.2
       graceful-fs: 4.2.11
-      jest-config: 29.7.0(@types/node@22.8.4)(ts-node@10.9.2)
+      jest-config: 29.7.0(@types/node@22.8.5)(ts-node@10.9.2)
       jest-util: 29.7.0
       prompts: 2.4.2
     transitivePeerDependencies:
@@ -4573,7 +4573,7 @@ packages:
       '@typescript-eslint/eslint-plugin': 8.4.0(@typescript-eslint/parser@8.4.0)(eslint@8.57.0)(typescript@5.6.3)
       '@typescript-eslint/utils': 8.4.0(eslint@8.57.0)(typescript@5.6.3)
       eslint: 8.57.0
-      jest: 29.7.0(@types/node@22.8.4)(ts-node@10.9.2)
+      jest: 29.7.0(@types/node@22.8.5)(ts-node@10.9.2)
     transitivePeerDependencies:
       - supports-color
       - typescript
@@ -5871,7 +5871,7 @@ packages:
       '@jest/expect': 29.7.0
       '@jest/test-result': 29.7.0
       '@jest/types': 29.6.3
-      '@types/node': 22.8.4
+      '@types/node': 22.8.5
       chalk: 4.1.2
       co: 4.6.0
       dedent: 1.5.1
@@ -5892,7 +5892,7 @@ packages:
       - supports-color
     dev: true
 
-  /jest-cli@29.7.0(@types/node@22.8.4)(ts-node@10.9.2):
+  /jest-cli@29.7.0(@types/node@22.8.5)(ts-node@10.9.2):
     resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==}
     engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
     hasBin: true
@@ -5906,10 +5906,10 @@ packages:
       '@jest/test-result': 29.7.0
       '@jest/types': 29.6.3
       chalk: 4.1.2
-      create-jest: 29.7.0(@types/node@22.8.4)(ts-node@10.9.2)
+      create-jest: 29.7.0(@types/node@22.8.5)(ts-node@10.9.2)
       exit: 0.1.2
       import-local: 3.1.0
-      jest-config: 29.7.0(@types/node@22.8.4)(ts-node@10.9.2)
+      jest-config: 29.7.0(@types/node@22.8.5)(ts-node@10.9.2)
       jest-util: 29.7.0
       jest-validate: 29.7.0
       yargs: 17.7.2
@@ -5920,7 +5920,7 @@ packages:
       - ts-node
     dev: true
 
-  /jest-config@29.7.0(@types/node@22.8.4)(ts-node@10.9.2):
+  /jest-config@29.7.0(@types/node@22.8.5)(ts-node@10.9.2):
     resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==}
     engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
     peerDependencies:
@@ -5935,7 +5935,7 @@ packages:
       '@babel/core': 7.23.2
       '@jest/test-sequencer': 29.7.0
       '@jest/types': 29.6.3
-      '@types/node': 22.8.4
+      '@types/node': 22.8.5
       babel-jest: 29.7.0(@babel/core@7.23.2)
       chalk: 4.1.2
       ci-info: 3.9.0
@@ -5955,7 +5955,7 @@ packages:
       pretty-format: 29.7.0
       slash: 3.0.0
       strip-json-comments: 3.1.1
-      ts-node: 10.9.2(@types/node@22.8.4)(typescript@5.6.3)
+      ts-node: 10.9.2(@types/node@22.8.5)(typescript@5.6.3)
     transitivePeerDependencies:
       - babel-plugin-macros
       - supports-color
@@ -5996,7 +5996,7 @@ packages:
       '@jest/environment': 29.7.0
       '@jest/fake-timers': 29.7.0
       '@jest/types': 29.6.3
-      '@types/node': 22.8.4
+      '@types/node': 22.8.5
       jest-mock: 29.7.0
       jest-util: 29.7.0
     dev: true
@@ -6012,7 +6012,7 @@ packages:
     dependencies:
       '@jest/types': 29.6.3
       '@types/graceful-fs': 4.1.9
-      '@types/node': 22.8.4
+      '@types/node': 22.8.5
       anymatch: 3.1.3
       fb-watchman: 2.0.2
       graceful-fs: 4.2.11
@@ -6063,7 +6063,7 @@ packages:
     engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
     dependencies:
       '@jest/types': 29.6.3
-      '@types/node': 22.8.4
+      '@types/node': 22.8.5
       jest-util: 29.7.0
     dev: true
 
@@ -6118,7 +6118,7 @@ packages:
       '@jest/test-result': 29.7.0
       '@jest/transform': 29.7.0
       '@jest/types': 29.6.3
-      '@types/node': 22.8.4
+      '@types/node': 22.8.5
       chalk: 4.1.2
       emittery: 0.13.1
       graceful-fs: 4.2.11
@@ -6149,7 +6149,7 @@ packages:
       '@jest/test-result': 29.7.0
       '@jest/transform': 29.7.0
       '@jest/types': 29.6.3
-      '@types/node': 22.8.4
+      '@types/node': 22.8.5
       chalk: 4.1.2
       cjs-module-lexer: 1.2.3
       collect-v8-coverage: 1.0.2
@@ -6201,7 +6201,7 @@ packages:
     engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
     dependencies:
       '@jest/types': 29.6.3
-      '@types/node': 22.8.4
+      '@types/node': 22.8.5
       chalk: 4.1.2
       ci-info: 3.9.0
       graceful-fs: 4.2.11
@@ -6226,7 +6226,7 @@ packages:
     dependencies:
       '@jest/test-result': 29.7.0
       '@jest/types': 29.6.3
-      '@types/node': 22.8.4
+      '@types/node': 22.8.5
       ansi-escapes: 4.3.2
       chalk: 4.1.2
       emittery: 0.13.1
@@ -6238,13 +6238,13 @@ packages:
     resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==}
     engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
     dependencies:
-      '@types/node': 22.8.4
+      '@types/node': 22.8.5
       jest-util: 29.7.0
       merge-stream: 2.0.0
       supports-color: 8.1.1
     dev: true
 
-  /jest@29.7.0(@types/node@22.8.4)(ts-node@10.9.2):
+  /jest@29.7.0(@types/node@22.8.5)(ts-node@10.9.2):
     resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==}
     engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
     hasBin: true
@@ -6257,7 +6257,7 @@ packages:
       '@jest/core': 29.7.0(ts-node@10.9.2)
       '@jest/types': 29.6.3
       import-local: 3.1.0
-      jest-cli: 29.7.0(@types/node@22.8.4)(ts-node@10.9.2)
+      jest-cli: 29.7.0(@types/node@22.8.5)(ts-node@10.9.2)
     transitivePeerDependencies:
       - '@types/node'
       - babel-plugin-macros
@@ -6673,8 +6673,8 @@ packages:
     hasBin: true
     dev: true
 
-  /mocha@10.8.1:
-    resolution: {integrity: sha512-WxSpEWgF03HfgNKBuysfK40DUaOSVX5zxgLDoieMGO+zyE69iq2eQ1vBypvIJ5mOPKpuVAqWiTbt4Orj7L6wVw==}
+  /mocha@10.8.2:
+    resolution: {integrity: sha512-VZlYo/WE8t1tstuRmqgeyBgCbJc/lEdopaa+axcKzTBJ+UIdlAB9XnmvTCAH4pwR4ElNInaedhEBmZD8iCSVEg==}
     engines: {node: '>= 14.0.0'}
     hasBin: true
     dependencies:
@@ -7923,7 +7923,7 @@ packages:
       bs-logger: 0.2.6
       ejs: 3.1.10
       fast-json-stable-stringify: 2.1.0
-      jest: 29.7.0(@types/node@22.8.4)(ts-node@10.9.2)
+      jest: 29.7.0(@types/node@22.8.5)(ts-node@10.9.2)
       jest-util: 29.7.0
       json5: 2.2.3
       lodash.memoize: 4.1.2
@@ -7933,7 +7933,7 @@ packages:
       yargs-parser: 21.1.1
     dev: true
 
-  /ts-node@10.9.2(@types/node@22.8.4)(typescript@5.6.3):
+  /ts-node@10.9.2(@types/node@22.8.5)(typescript@5.6.3):
     resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==}
     hasBin: true
     peerDependencies:
@@ -7952,7 +7952,7 @@ packages:
       '@tsconfig/node12': 1.0.11
       '@tsconfig/node14': 1.0.3
       '@tsconfig/node16': 1.0.4
-      '@types/node': 22.8.4
+      '@types/node': 22.8.5
       acorn: 8.11.2
       acorn-walk: 8.3.0
       arg: 4.1.3
diff --git a/single-pool/js/packages/classic/package.json b/single-pool/js/packages/classic/package.json
index 4757ab950..28f3b10de 100644
--- a/single-pool/js/packages/classic/package.json
+++ b/single-pool/js/packages/classic/package.json
@@ -18,7 +18,7 @@
     "test": "sed -i '1s/.*/{ \"type\": \"module\",/' package.json && NODE_OPTIONS='--loader=tsx' ava ; ret=$?; sed -i '1s/.*/{/' package.json && exit $ret"
   },
   "devDependencies": {
-    "@types/node": "^22.8.4",
+    "@types/node": "^22.8.5",
     "@ava/typescript": "^5.0.0",
     "@typescript-eslint/eslint-plugin": "^8.4.0",
     "ava": "^6.2.0",
diff --git a/single-pool/js/packages/modern/package.json b/single-pool/js/packages/modern/package.json
index ec915f0a1..c3ca919e4 100644
--- a/single-pool/js/packages/modern/package.json
+++ b/single-pool/js/packages/modern/package.json
@@ -16,7 +16,7 @@
     "lint:fix": "eslint . --fix"
   },
   "devDependencies": {
-    "@types/node": "^22.8.4",
+    "@types/node": "^22.8.5",
     "@typescript-eslint/eslint-plugin": "^8.4.0",
     "eslint": "^8.57.0",
     "typescript": "^5.6.3"
diff --git a/stake-pool/js/package.json b/stake-pool/js/package.json
index d84d214ce..d547108c1 100644
--- a/stake-pool/js/package.json
+++ b/stake-pool/js/package.json
@@ -61,7 +61,7 @@
     "@rollup/plugin-typescript": "^12.1.1",
     "@types/bn.js": "^5.1.6",
     "@types/jest": "^29.5.14",
-    "@types/node": "^22.8.4",
+    "@types/node": "^22.8.5",
     "@types/node-fetch": "^2.6.11",
     "@typescript-eslint/eslint-plugin": "^8.4.0",
     "@typescript-eslint/parser": "^8.4.0",
diff --git a/stake-pool/program/src/instruction.rs b/stake-pool/program/src/instruction.rs
index 9709bef0f..ef6a801e3 100644
--- a/stake-pool/program/src/instruction.rs
+++ b/stake-pool/program/src/instruction.rs
@@ -320,7 +320,7 @@ pub enum StakePoolInstruction {
     ///   1. `[w]` Validator stake list storage account
     ///   2. `[]` Stake pool withdraw authority
     ///   3. `[w]` Validator or reserve stake account to split
-    ///   4. `[w]` Unitialized stake account to receive withdrawal
+    ///   4. `[w]` Uninitialized stake account to receive withdrawal
     ///   5. `[]` User account to set as a new withdraw authority
     ///   6. `[s]` User transfer authority, for pool token account
     ///   7. `[w]` User account with pool tokens to burn from
@@ -665,7 +665,7 @@ pub enum StakePoolInstruction {
     ///   1. `[w]` Validator stake list storage account
     ///   2. `[]` Stake pool withdraw authority
     ///   3. `[w]` Validator or reserve stake account to split
-    ///   4. `[w]` Unitialized stake account to receive withdrawal
+    ///   4. `[w]` Uninitialized stake account to receive withdrawal
     ///   5. `[]` User account to set as a new withdraw authority
     ///   6. `[s]` User transfer authority, for pool token account
     ///   7. `[w]` User account with pool tokens to burn from
diff --git a/token-group/js/package.json b/token-group/js/package.json
index 3d40f219d..202466037 100644
--- a/token-group/js/package.json
+++ b/token-group/js/package.json
@@ -53,14 +53,14 @@
         "@solana/web3.js": "^1.95.4",
         "@types/chai": "^5.0.1",
         "@types/mocha": "^10.0.9",
-        "@types/node": "^22.8.4",
+        "@types/node": "^22.8.5",
         "@typescript-eslint/eslint-plugin": "^8.4.0",
         "@typescript-eslint/parser": "^8.4.0",
         "chai": "^5.1.2",
         "eslint": "^8.57.0",
         "eslint-plugin-require-extensions": "^0.1.1",
         "gh-pages": "^6.2.0",
-        "mocha": "^10.8.1",
+        "mocha": "^10.8.2",
         "shx": "^0.3.4",
         "ts-node": "^10.9.2",
         "tslib": "^2.8.0",
diff --git a/token-lending/js/package.json b/token-lending/js/package.json
index aed7db397..d15da460a 100644
--- a/token-lending/js/package.json
+++ b/token-lending/js/package.json
@@ -47,7 +47,7 @@
         "@solana/spl-token": "0.4.9",
         "@solana/web3.js": "^1.95.4",
         "@types/eslint": "^8.56.7",
-        "@types/node": "^22.8.4",
+        "@types/node": "^22.8.5",
         "@typescript-eslint/eslint-plugin": "^8.4.0",
         "@typescript-eslint/parser": "^8.4.0",
         "eslint": "^8.57.0",
diff --git a/token-metadata/js/package.json b/token-metadata/js/package.json
index 18ec7c03a..9c6f9796c 100644
--- a/token-metadata/js/package.json
+++ b/token-metadata/js/package.json
@@ -53,14 +53,14 @@
         "@solana/web3.js": "^1.95.4",
         "@types/chai": "^5.0.1",
         "@types/mocha": "^10.0.9",
-        "@types/node": "^22.8.4",
+        "@types/node": "^22.8.5",
         "@typescript-eslint/eslint-plugin": "^8.4.0",
         "@typescript-eslint/parser": "^8.4.0",
         "chai": "^5.1.2",
         "eslint": "^8.57.0",
         "eslint-plugin-require-extensions": "^0.1.1",
         "gh-pages": "^6.2.0",
-        "mocha": "^10.8.1",
+        "mocha": "^10.8.2",
         "shx": "^0.3.4",
         "ts-node": "^10.9.2",
         "tslib": "^2.8.0",
diff --git a/token-swap/js/package.json b/token-swap/js/package.json
index 714ac08ba..8e80b5a9c 100644
--- a/token-swap/js/package.json
+++ b/token-swap/js/package.json
@@ -60,7 +60,7 @@
     "eslint": "^8.57.0",
     "eslint-plugin-import": "^2.31.0",
     "eslint-plugin-require-extensions": "^0.1.1",
-    "mocha": "^10.8.1",
+    "mocha": "^10.8.2",
     "start-server-and-test": "^2.0.8",
     "ts-node": "^10.9.2",
     "typescript": "^5.6.3"
diff --git a/token/confidential-transfer/proof-extraction/src/encryption.rs b/token/confidential-transfer/proof-extraction/src/encryption.rs
index b0a991235..383108d41 100644
--- a/token/confidential-transfer/proof-extraction/src/encryption.rs
+++ b/token/confidential-transfer/proof-extraction/src/encryption.rs
@@ -5,7 +5,6 @@ use {
         grouped_elgamal::{
             PodGroupedElGamalCiphertext2Handles, PodGroupedElGamalCiphertext3Handles,
         },
-        pedersen::PodPedersenCommitment,
     },
 };
 
@@ -14,10 +13,6 @@ use {
 pub struct PodTransferAmountCiphertext(pub(crate) PodGroupedElGamalCiphertext3Handles);
 
 impl PodTransferAmountCiphertext {
-    pub fn extract_commitment(&self) -> PodPedersenCommitment {
-        self.0.extract_commitment()
-    }
-
     pub fn try_extract_ciphertext(
         &self,
         index: usize,
@@ -33,10 +28,6 @@ impl PodTransferAmountCiphertext {
 pub struct PodFeeCiphertext(pub(crate) PodGroupedElGamalCiphertext2Handles);
 
 impl PodFeeCiphertext {
-    pub fn extract_commitment(&self) -> PodPedersenCommitment {
-        self.0.extract_commitment()
-    }
-
     pub fn try_extract_ciphertext(
         &self,
         index: usize,
@@ -51,6 +42,28 @@ impl PodFeeCiphertext {
 #[repr(C)]
 pub struct PodBurnAmountCiphertext(pub(crate) PodGroupedElGamalCiphertext3Handles);
 
+impl PodBurnAmountCiphertext {
+    pub fn try_extract_ciphertext(
+        &self,
+        index: usize,
+    ) -> Result<PodElGamalCiphertext, TokenProofExtractionError> {
+        self.0
+            .try_extract_ciphertext(index)
+            .map_err(|_| TokenProofExtractionError::CiphertextExtraction)
+    }
+}
+
 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
 #[repr(C)]
 pub struct PodMintAmountCiphertext(pub(crate) PodGroupedElGamalCiphertext3Handles);
+
+impl PodMintAmountCiphertext {
+    pub fn try_extract_ciphertext(
+        &self,
+        index: usize,
+    ) -> Result<PodElGamalCiphertext, TokenProofExtractionError> {
+        self.0
+            .try_extract_ciphertext(index)
+            .map_err(|_| TokenProofExtractionError::CiphertextExtraction)
+    }
+}
diff --git a/token/confidential-transfer/proof-extraction/src/instruction.rs b/token/confidential-transfer/proof-extraction/src/instruction.rs
index 761a2b3fc..be41a4bb6 100644
--- a/token/confidential-transfer/proof-extraction/src/instruction.rs
+++ b/token/confidential-transfer/proof-extraction/src/instruction.rs
@@ -6,11 +6,11 @@ use {
     solana_program::{
         account_info::{next_account_info, AccountInfo},
         entrypoint::ProgramResult,
-        instruction::Instruction,
+        instruction::{AccountMeta, Instruction},
         msg,
         program_error::ProgramError,
         pubkey::Pubkey,
-        sysvar::instructions::get_instruction_relative,
+        sysvar::{self, instructions::get_instruction_relative},
     },
     solana_zk_sdk::zk_elgamal_proof_program::{
         self,
@@ -146,6 +146,56 @@ pub fn verify_and_extract_context<'a, T: Pod + ZkProofData<U>, U: Pod>(
     }
 }
 
+/// Processes a proof location for instruction creation. Adds relevant accounts
+/// to supplied account vector
+///
+/// If the proof location is an instruction offset the corresponding proof
+/// instruction is created and added to the `proof_instructions` vector.
+pub fn process_proof_location<T, U>(
+    accounts: &mut Vec<AccountMeta>,
+    expected_instruction_offset: &mut i8,
+    proof_instructions: &mut Vec<Instruction>,
+    proof_location: ProofLocation<T>,
+    push_sysvar_to_accounts: bool,
+    proof_instruction_type: ProofInstruction,
+) -> Result<i8, ProgramError>
+where
+    T: Pod + ZkProofData<U>,
+    U: Pod,
+{
+    match proof_location {
+        ProofLocation::InstructionOffset(proof_instruction_offset, proof_data) => {
+            let proof_instruction_offset: i8 = proof_instruction_offset.into();
+            if &proof_instruction_offset != expected_instruction_offset {
+                return Err(ProgramError::InvalidInstructionData);
+            }
+
+            if push_sysvar_to_accounts {
+                accounts.push(AccountMeta::new_readonly(sysvar::instructions::id(), false));
+            }
+            match proof_data {
+                ProofData::InstructionData(data) => proof_instructions
+                    .push(proof_instruction_type.encode_verify_proof::<T, U>(None, data)),
+                ProofData::RecordAccount(address, offset) => {
+                    accounts.push(AccountMeta::new_readonly(*address, false));
+                    proof_instructions.push(
+                        proof_instruction_type
+                            .encode_verify_proof_from_account(None, address, offset),
+                    )
+                }
+            };
+            *expected_instruction_offset = expected_instruction_offset
+                .checked_add(1)
+                .ok_or(ProgramError::InvalidInstructionData)?;
+            Ok(proof_instruction_offset)
+        }
+        ProofLocation::ContextStateAccount(context_state_account) => {
+            accounts.push(AccountMeta::new_readonly(*context_state_account, false));
+            Ok(0)
+        }
+    }
+}
+
 /// Converts a zk proof type to a corresponding ZK ElGamal proof program
 /// instruction that verifies the proof.
 pub fn zk_proof_type_to_instruction(
diff --git a/token/confidential-transfer/proof-generation/src/mint.rs b/token/confidential-transfer/proof-generation/src/mint.rs
index e25dc70a2..1ada01840 100644
--- a/token/confidential-transfer/proof-generation/src/mint.rs
+++ b/token/confidential-transfer/proof-generation/src/mint.rs
@@ -27,12 +27,13 @@ pub struct MintProofData {
     pub equality_proof_data: CiphertextCommitmentEqualityProofData,
     pub ciphertext_validity_proof_data: BatchedGroupedCiphertext3HandlesValidityProofData,
     pub range_proof_data: BatchedRangeProofU128Data,
+    pub new_decryptable_supply: AeCiphertext,
 }
 
 pub fn mint_split_proof_data(
     current_supply_ciphertext: &ElGamalCiphertext,
-    current_decryptable_supply: &AeCiphertext,
     mint_amount: u64,
+    current_supply: u64,
     supply_elgamal_keypair: &ElGamalKeypair,
     supply_aes_key: &AeKey,
     destination_elgamal_pubkey: &ElGamalPubkey,
@@ -77,11 +78,6 @@ pub fn mint_split_proof_data(
         )
         .ok_or(TokenProofGenerationError::IllegalAmountBitLength)?;
 
-    // decrypt the current supply
-    let current_supply = current_decryptable_supply
-        .decrypt(supply_aes_key)
-        .ok_or(TokenProofGenerationError::IllegalAmountBitLength)?;
-
     // compute the new supply
     let new_supply = current_supply
         .checked_add(mint_amount)
@@ -142,5 +138,6 @@ pub fn mint_split_proof_data(
         equality_proof_data,
         ciphertext_validity_proof_data,
         range_proof_data,
+        new_decryptable_supply: supply_aes_key.encrypt(new_supply),
     })
 }
diff --git a/token/js/package.json b/token/js/package.json
index 3ee93044a..2adfa8518 100644
--- a/token/js/package.json
+++ b/token/js/package.json
@@ -66,7 +66,7 @@
         "@types/chai-as-promised": "^8.0.1",
         "@types/chai": "^5.0.1",
         "@types/mocha": "^10.0.9",
-        "@types/node": "^22.8.4",
+        "@types/node": "^22.8.5",
         "@types/node-fetch": "^2.6.11",
         "@typescript-eslint/eslint-plugin": "^8.4.0",
         "@typescript-eslint/parser": "^8.4.0",
@@ -75,7 +75,7 @@
         "eslint": "^8.57.0",
         "eslint-plugin-require-extensions": "^0.1.1",
         "gh-pages": "^6.2.0",
-        "mocha": "^10.8.1",
+        "mocha": "^10.8.2",
         "process": "^0.11.10",
         "shx": "^0.3.4",
         "start-server-and-test": "^2.0.8",
diff --git a/token/program-2022/src/error.rs b/token/program-2022/src/error.rs
index a886eb29e..54e4e2501 100644
--- a/token/program-2022/src/error.rs
+++ b/token/program-2022/src/error.rs
@@ -258,6 +258,11 @@ pub enum TokenError {
     /// Fee calculation failed
     #[error("Fee calculation failed")]
     FeeCalculation,
+
+    //65
+    /// Withdraw / Deposit not allowed for confidential-mint-burn
+    #[error("Withdraw / Deposit not allowed for confidential-mint-burn")]
+    IllegalMintBurnConversion,
 }
 impl From<TokenError> for ProgramError {
     fn from(e: TokenError) -> Self {
@@ -445,6 +450,9 @@ impl PrintProgramError for TokenError {
             TokenError::FeeCalculation => {
                 msg!("Transfer fee calculation failed")
             }
+            TokenError::IllegalMintBurnConversion => {
+                msg!("Conversions from normal to confidential token balance and vice versa are illegal if the confidential-mint-burn extension is enabled")
+            }
         }
     }
 }
diff --git a/token/program-2022/src/extension/confidential_mint_burn/account_info.rs b/token/program-2022/src/extension/confidential_mint_burn/account_info.rs
new file mode 100644
index 000000000..01cae83ac
--- /dev/null
+++ b/token/program-2022/src/extension/confidential_mint_burn/account_info.rs
@@ -0,0 +1,105 @@
+use {
+    super::ConfidentialMintBurn,
+    crate::error::TokenError,
+    bytemuck::{Pod, Zeroable},
+    solana_zk_sdk::{
+        encryption::{
+            auth_encryption::{AeCiphertext, AeKey},
+            elgamal::{ElGamalCiphertext, ElGamalKeypair},
+            pedersen::PedersenOpening,
+            pod::{
+                auth_encryption::PodAeCiphertext,
+                elgamal::{PodElGamalCiphertext, PodElGamalPubkey},
+            },
+        },
+        zk_elgamal_proof_program::proof_data::CiphertextCiphertextEqualityProofData,
+    },
+};
+
+/// Confidential Mint Burn extension information needed to construct a
+/// `RotateSupplyElgamalPubkey` instruction.
+#[repr(C)]
+#[derive(Clone, Copy, Debug, Default, PartialEq, Pod, Zeroable)]
+pub struct SupplyAccountInfo {
+    /// The available balance (encrypted by `supply_elgamal_pubkey`)
+    pub current_supply: PodElGamalCiphertext,
+    /// The decryptable supply
+    pub decryptable_supply: PodAeCiphertext,
+    /// The supply's elgamal pubkey
+    pub supply_elgamal_pubkey: PodElGamalPubkey,
+}
+
+impl SupplyAccountInfo {
+    /// Creates a SupplyAccountInfo from ConfidentialMintBurn extension account
+    /// data
+    pub fn new(extension: &ConfidentialMintBurn) -> Self {
+        Self {
+            current_supply: extension.confidential_supply,
+            decryptable_supply: extension.decryptable_supply,
+            supply_elgamal_pubkey: extension.supply_elgamal_pubkey,
+        }
+    }
+
+    /// Computes the current supply from the decryptable supply and the
+    /// difference between the decryptable supply and the elgamal encrypted
+    /// supply ciphertext
+    pub fn decrypt_current_supply(
+        &self,
+        aes_key: &AeKey,
+        elgamal_keypair: &ElGamalKeypair,
+    ) -> Result<u64, TokenError> {
+        // decrypt the decryptable supply
+        let current_decyptable_supply = AeCiphertext::try_from(self.decryptable_supply)
+            .map_err(|_| TokenError::MalformedCiphertext)?
+            .decrypt(aes_key)
+            .ok_or(TokenError::MalformedCiphertext)?;
+
+        // get the difference between the supply ciphertext and the decryptable supply
+        // explanation see https://github.com/solana-labs/solana-program-library/pull/6881#issuecomment-2385579058
+        let decryptable_supply_ciphertext =
+            elgamal_keypair.pubkey().encrypt(current_decyptable_supply);
+        #[allow(clippy::arithmetic_side_effects)]
+        let supply_delta_ciphertext = decryptable_supply_ciphertext
+            - ElGamalCiphertext::try_from(self.current_supply)
+                .map_err(|_| TokenError::MalformedCiphertext)?;
+        let decryptable_to_current_diff = elgamal_keypair
+            .secret()
+            .decrypt_u32(&supply_delta_ciphertext)
+            .ok_or(TokenError::MalformedCiphertext)?;
+
+        // compute the current supply
+        current_decyptable_supply
+            .checked_sub(decryptable_to_current_diff)
+            .ok_or(TokenError::Overflow)
+    }
+
+    /// Generates the `CiphertextCiphertextEqualityProofData` needed for a
+    /// `RotateSupplyElgamalPubkey` instruction
+    pub fn generate_rotate_supply_elgamal_pubkey_proof(
+        &self,
+        aes_key: &AeKey,
+        current_supply_elgamal_keypair: &ElGamalKeypair,
+        new_supply_elgamal_keypair: &ElGamalKeypair,
+    ) -> Result<CiphertextCiphertextEqualityProofData, TokenError> {
+        let current_supply =
+            self.decrypt_current_supply(aes_key, current_supply_elgamal_keypair)?;
+
+        let new_supply_opening = PedersenOpening::new_rand();
+        let new_supply_ciphertext = new_supply_elgamal_keypair
+            .pubkey()
+            .encrypt_with(current_supply, &new_supply_opening);
+
+        CiphertextCiphertextEqualityProofData::new(
+            current_supply_elgamal_keypair,
+            new_supply_elgamal_keypair.pubkey(),
+            &self
+                .current_supply
+                .try_into()
+                .map_err(|_| TokenError::MalformedCiphertext)?,
+            &new_supply_ciphertext,
+            &new_supply_opening,
+            current_supply,
+        )
+        .map_err(|_| TokenError::ProofGeneration)
+    }
+}
diff --git a/token/program-2022/src/extension/confidential_mint_burn/instruction.rs b/token/program-2022/src/extension/confidential_mint_burn/instruction.rs
new file mode 100644
index 000000000..6e808d365
--- /dev/null
+++ b/token/program-2022/src/extension/confidential_mint_burn/instruction.rs
@@ -0,0 +1,549 @@
+#[cfg(feature = "serde-traits")]
+use {
+    crate::serialization::{aeciphertext_fromstr, elgamalpubkey_fromstr},
+    serde::{Deserialize, Serialize},
+};
+use {
+    crate::{
+        check_program_account,
+        extension::confidential_transfer::DecryptableBalance,
+        instruction::{encode_instruction, TokenInstruction},
+    },
+    bytemuck::{Pod, Zeroable},
+    num_enum::{IntoPrimitive, TryFromPrimitive},
+    solana_program::{
+        instruction::{AccountMeta, Instruction},
+        program_error::ProgramError,
+        pubkey::Pubkey,
+    },
+    solana_zk_sdk::encryption::pod::{auth_encryption::PodAeCiphertext, elgamal::PodElGamalPubkey},
+};
+#[cfg(not(target_os = "solana"))]
+use {
+    solana_zk_sdk::{
+        encryption::{auth_encryption::AeCiphertext, elgamal::ElGamalPubkey},
+        zk_elgamal_proof_program::{
+            instruction::ProofInstruction,
+            proof_data::{
+                BatchedGroupedCiphertext3HandlesValidityProofData, BatchedRangeProofU128Data,
+                CiphertextCiphertextEqualityProofData, CiphertextCommitmentEqualityProofData,
+            },
+        },
+    },
+    spl_token_confidential_transfer_proof_extraction::instruction::{
+        process_proof_location, ProofLocation,
+    },
+};
+
+/// Confidential Transfer extension instructions
+#[cfg_attr(feature = "serde-traits", derive(Serialize, Deserialize))]
+#[cfg_attr(feature = "serde-traits", serde(rename_all = "camelCase"))]
+#[derive(Clone, Copy, Debug, TryFromPrimitive, IntoPrimitive)]
+#[repr(u8)]
+pub enum ConfidentialMintBurnInstruction {
+    /// Initializes confidential mints and burns for a mint.
+    ///
+    /// The `ConfidentialMintBurnInstruction::InitializeMint` instruction
+    /// requires no signers and MUST be included within the same Transaction
+    /// as `TokenInstruction::InitializeMint`. Otherwise another party can
+    /// initialize the configuration.
+    ///
+    /// The instruction fails if the `TokenInstruction::InitializeMint`
+    /// instruction has already executed for the mint.
+    ///
+    /// Accounts expected by this instruction:
+    ///
+    ///   0. `[writable]` The SPL Token mint.
+    ///
+    /// Data expected by this instruction:
+    ///   `InitializeMintData`
+    InitializeMint,
+    /// Rotates the ElGamal pubkey used to encrypt confidential supply
+    ///
+    /// Accounts expected by this instruction:
+    ///
+    ///   * Single authority
+    ///   0. `[writable]` The SPL Token mint.
+    ///   1. `[]` Instructions sysvar if `CiphertextCiphertextEquality` is
+    ///      included in the same transaction or context state account if
+    ///      `CiphertextCiphertextEquality` is pre-verified into a context state
+    ///      account.
+    ///   2. `[signer]` Confidential mint authority.
+    ///
+    ///   * Multisignature authority
+    ///   0. `[writable]` The SPL Token mint.
+    ///   1. `[]` Instructions sysvar if `CiphertextCiphertextEquality` is
+    ///      included in the same transaction or context state account if
+    ///      `CiphertextCiphertextEquality` is pre-verified into a context state
+    ///      account.
+    ///   2. `[]` The multisig authority account owner.
+    ///   3.. `[signer]` Required M signer accounts for the SPL Token Multisig
+    ///
+    /// Data expected by this instruction:
+    ///   `RotateSupplyElGamalPubkeyData`
+    RotateSupplyElGamalPubkey,
+    /// Updates the decryptable supply of the mint
+    ///
+    /// Accounts expected by this instruction:
+    ///
+    ///   * Single authority
+    ///   0. `[writable]` The SPL Token mint.
+    ///   1. `[signer]` Confidential mint authority.
+    ///
+    ///   * Multisignature authority
+    ///   0. `[writable]` The SPL Token mint.
+    ///   1. `[]` The multisig authority account owner.
+    ///   2.. `[signer]` Required M signer accounts for the SPL Token Multisig
+    ///
+    /// Data expected by this instruction:
+    ///   `UpdateDecryptableSupplyData`
+    UpdateDecryptableSupply,
+    /// Mints tokens to confidential balance
+    ///
+    /// Fails if the destination account is frozen.
+    ///
+    /// Accounts expected by this instruction:
+    ///
+    ///   * Single authority
+    ///   0. `[writable]` The SPL Token account.
+    ///   1. `[]` The SPL Token mint. `[writable]` if the mint has a non-zero
+    ///      supply elgamal-pubkey
+    ///   2. `[]` (Optional) Instructions sysvar if at least one of the
+    ///      `zk_elgamal_proof` instructions are included in the same
+    ///      transaction.
+    ///   3. `[]` (Optional) The context state account containing the
+    ///      pre-verified `VerifyCiphertextCommitmentEquality` proof
+    ///   4. `[]` (Optional) The context state account containing the
+    ///      pre-verified `VerifyBatchedGroupedCiphertext3HandlesValidity` proof
+    ///   5. `[]` (Optional) The context state account containing the
+    ///      pre-verified `VerifyBatchedRangeProofU128`
+    ///   6. `[signer]` The single account owner.
+    ///
+    ///   * Multisignature authority
+    ///   0. `[writable]` The SPL Token mint.
+    ///   1. `[]` The SPL Token mint. `[writable]` if the mint has a non-zero
+    ///      supply elgamal-pubkey
+    ///   2. `[]` (Optional) Instructions sysvar if at least one of the
+    ///      `zk_elgamal_proof` instructions are included in the same
+    ///      transaction.
+    ///   3. `[]` (Optional) The context state account containing the
+    ///      pre-verified `VerifyCiphertextCommitmentEquality` proof
+    ///   4. `[]` (Optional) The context state account containing the
+    ///      pre-verified `VerifyBatchedGroupedCiphertext3HandlesValidity` proof
+    ///   5. `[]` (Optional) The context state account containing the
+    ///      pre-verified `VerifyBatchedRangeProofU128`
+    ///   6. `[]` The multisig account owner.
+    ///   7.. `[signer]` Required M signer accounts for the SPL Token Multisig
+    ///
+    /// Data expected by this instruction:
+    ///   `MintInstructionData`
+    Mint,
+    /// Burn tokens from confidential balance
+    ///
+    /// Fails if the destination account is frozen.
+    ///
+    /// Accounts expected by this instruction:
+    ///
+    ///   * Single authority
+    ///   0. `[writable]` The SPL Token account.
+    ///   1. `[]` The SPL Token mint. `[writable]` if the mint has a non-zero
+    ///      supply elgamal-pubkey
+    ///   2. `[]` (Optional) Instructions sysvar if at least one of the
+    ///      `zk_elgamal_proof` instructions are included in the same
+    ///      transaction.
+    ///   3. `[]` (Optional) The context state account containing the
+    ///      pre-verified `VerifyCiphertextCommitmentEquality` proof
+    ///   4. `[]` (Optional) The context state account containing the
+    ///      pre-verified `VerifyBatchedGroupedCiphertext3HandlesValidity` proof
+    ///   5. `[]` (Optional) The context state account containing the
+    ///      pre-verified `VerifyBatchedRangeProofU128`
+    ///   6. `[signer]` The single account owner.
+    ///
+    ///   * Multisignature authority
+    ///   0. `[writable]` The SPL Token mint.
+    ///   1. `[]` The SPL Token mint. `[writable]` if the mint has a non-zero
+    ///      supply elgamal-pubkey
+    ///   2. `[]` (Optional) Instructions sysvar if at least one of the
+    ///      `zk_elgamal_proof` instructions are included in the same
+    ///      transaction.
+    ///   3. `[]` (Optional) The context state account containing the
+    ///      pre-verified `VerifyCiphertextCommitmentEquality` proof
+    ///   4. `[]` (Optional) The context state account containing the
+    ///      pre-verified `VerifyBatchedGroupedCiphertext3HandlesValidity` proof
+    ///   5. `[]` (Optional) The context state account containing the
+    ///      pre-verified `VerifyBatchedRangeProofU128`
+    ///   6. `[]` The multisig account owner.
+    ///   7.. `[signer]` Required M signer accounts for the SPL Token Multisig
+    ///
+    /// Data expected by this instruction:
+    ///   `BurnInstructionData`
+    Burn,
+}
+
+/// Data expected by `ConfidentialMintBurnInstruction::InitializeMint`
+#[cfg_attr(feature = "serde-traits", derive(Serialize, Deserialize))]
+#[cfg_attr(feature = "serde-traits", serde(rename_all = "camelCase"))]
+#[derive(Clone, Copy, Debug, PartialEq, Pod, Zeroable)]
+#[repr(C)]
+pub struct InitializeMintData {
+    /// The ElGamal pubkey used to encrypt the confidential supply
+    #[cfg_attr(feature = "serde-traits", serde(with = "elgamalpubkey_fromstr"))]
+    pub supply_elgamal_pubkey: PodElGamalPubkey,
+    /// The initial 0 supply ecrypted with the supply aes key
+    #[cfg_attr(feature = "serde-traits", serde(with = "aeciphertext_fromstr"))]
+    pub decryptable_supply: PodAeCiphertext,
+}
+
+/// Data expected by `ConfidentialMintBurnInstruction::RotateSupplyElGamal`
+#[cfg_attr(feature = "serde-traits", derive(Serialize, Deserialize))]
+#[cfg_attr(feature = "serde-traits", serde(rename_all = "camelCase"))]
+#[derive(Clone, Copy, Debug, PartialEq, Pod, Zeroable)]
+#[repr(C)]
+pub struct RotateSupplyElGamalPubkeyData {
+    /// The new ElGamal pubkey for supply encryption
+    #[cfg_attr(feature = "serde-traits", serde(with = "elgamalpubkey_fromstr"))]
+    pub new_supply_elgamal_pubkey: PodElGamalPubkey,
+    /// The location of the
+    /// `ProofInstruction::VerifyCiphertextCiphertextEquality` instruction
+    /// relative to the `RotateSupplyElGamal` instruction in the transaction
+    pub proof_instruction_offset: i8,
+}
+
+/// Data expected by `ConfidentialMintBurnInstruction::UpdateDecryptableSupply`
+#[cfg_attr(feature = "serde-traits", derive(Serialize, Deserialize))]
+#[cfg_attr(feature = "serde-traits", serde(rename_all = "camelCase"))]
+#[derive(Clone, Copy, Debug, PartialEq, Pod, Zeroable)]
+#[repr(C)]
+pub struct UpdateDecryptableSupplyData {
+    /// The new decryptable supply
+    #[cfg_attr(feature = "serde-traits", serde(with = "aeciphertext_fromstr"))]
+    pub new_decryptable_supply: PodAeCiphertext,
+}
+
+/// Data expected by `ConfidentialMintBurnInstruction::ConfidentialMint`
+#[cfg_attr(feature = "serde-traits", derive(Serialize, Deserialize))]
+#[cfg_attr(feature = "serde-traits", serde(rename_all = "camelCase"))]
+#[derive(Clone, Copy, Debug, PartialEq, Pod, Zeroable)]
+#[repr(C)]
+pub struct MintInstructionData {
+    /// The new decryptable supply if the mint succeeds
+    #[cfg_attr(feature = "serde-traits", serde(with = "aeciphertext_fromstr"))]
+    pub new_decryptable_supply: PodAeCiphertext,
+    /// Relative location of the
+    /// `ProofInstruction::VerifyCiphertextCommitmentEquality` instruction
+    /// to the `ConfidentialMint` instruction in the transaction. 0 if the
+    /// proof is in a pre-verified context account
+    pub equality_proof_instruction_offset: i8,
+    /// Relative location of the
+    /// `ProofInstruction::VerifyBatchedGroupedCiphertext3HandlesValidity`
+    /// instruction to the `ConfidentialMint` instruction in the
+    /// transaction. 0 if the proof is in a pre-verified context account
+    pub ciphertext_validity_proof_instruction_offset: i8,
+    /// Relative location of the `ProofInstruction::VerifyBatchedRangeProofU128`
+    /// instruction to the `ConfidentialMint` instruction in the
+    /// transaction. 0 if the proof is in a pre-verified context account
+    pub range_proof_instruction_offset: i8,
+}
+
+/// Data expected by `ConfidentialMintBurnInstruction::ConfidentialBurn`
+#[cfg_attr(feature = "serde-traits", derive(Serialize, Deserialize))]
+#[cfg_attr(feature = "serde-traits", serde(rename_all = "camelCase"))]
+#[derive(Clone, Copy, Debug, PartialEq, Pod, Zeroable)]
+#[repr(C)]
+pub struct BurnInstructionData {
+    /// The new decryptable balance of the burner if the burn succeeds
+    #[cfg_attr(feature = "serde-traits", serde(with = "aeciphertext_fromstr"))]
+    pub new_decryptable_available_balance: DecryptableBalance,
+    /// Relative location of the
+    /// `ProofInstruction::VerifyCiphertextCommitmentEquality` instruction
+    /// to the `ConfidentialMint` instruction in the transaction. 0 if the
+    /// proof is in a pre-verified context account
+    pub equality_proof_instruction_offset: i8,
+    /// Relative location of the
+    /// `ProofInstruction::VerifyBatchedGroupedCiphertext3HandlesValidity`
+    /// instruction to the `ConfidentialMint` instruction in the
+    /// transaction. 0 if the proof is in a pre-verified context account
+    pub ciphertext_validity_proof_instruction_offset: i8,
+    /// Relative location of the `ProofInstruction::VerifyBatchedRangeProofU128`
+    /// instruction to the `ConfidentialMint` instruction in the
+    /// transaction. 0 if the proof is in a pre-verified context account
+    pub range_proof_instruction_offset: i8,
+}
+
+/// Create a `InitializeMint` instruction
+pub fn initialize_mint(
+    token_program_id: &Pubkey,
+    mint: &Pubkey,
+    supply_elgamal_pubkey: PodElGamalPubkey,
+    decryptable_supply: PodAeCiphertext,
+) -> Result<Instruction, ProgramError> {
+    check_program_account(token_program_id)?;
+    let accounts = vec![AccountMeta::new(*mint, false)];
+
+    Ok(encode_instruction(
+        token_program_id,
+        accounts,
+        TokenInstruction::ConfidentialMintBurnExtension,
+        ConfidentialMintBurnInstruction::InitializeMint,
+        &InitializeMintData {
+            supply_elgamal_pubkey,
+            decryptable_supply,
+        },
+    ))
+}
+
+/// Create a `RotateSupplyElGamal` instruction
+#[allow(clippy::too_many_arguments)]
+#[cfg(not(target_os = "solana"))]
+pub fn rotate_supply_elgamal_pubkey(
+    token_program_id: &Pubkey,
+    mint: &Pubkey,
+    authority: &Pubkey,
+    multisig_signers: &[&Pubkey],
+    new_supply_elgamal_pubkey: ElGamalPubkey,
+    ciphertext_equality_proof: ProofLocation<CiphertextCiphertextEqualityProofData>,
+) -> Result<Vec<Instruction>, ProgramError> {
+    check_program_account(token_program_id)?;
+    let mut accounts = vec![AccountMeta::new(*mint, false)];
+
+    let mut expected_instruction_offset = 1;
+    let mut proof_instructions = vec![];
+
+    let proof_instruction_offset = process_proof_location(
+        &mut accounts,
+        &mut expected_instruction_offset,
+        &mut proof_instructions,
+        ciphertext_equality_proof,
+        true,
+        ProofInstruction::VerifyCiphertextCiphertextEquality,
+    )?;
+
+    accounts.push(AccountMeta::new_readonly(
+        *authority,
+        multisig_signers.is_empty(),
+    ));
+    for multisig_signer in multisig_signers.iter() {
+        accounts.push(AccountMeta::new_readonly(**multisig_signer, true));
+    }
+
+    let mut instructions = vec![encode_instruction(
+        token_program_id,
+        accounts,
+        TokenInstruction::ConfidentialMintBurnExtension,
+        ConfidentialMintBurnInstruction::RotateSupplyElGamalPubkey,
+        &RotateSupplyElGamalPubkeyData {
+            new_supply_elgamal_pubkey: PodElGamalPubkey::from(new_supply_elgamal_pubkey),
+            proof_instruction_offset,
+        },
+    )];
+
+    instructions.extend_from_slice(&proof_instructions);
+
+    Ok(instructions)
+}
+
+/// Create a `UpdateMint` instruction
+#[cfg(not(target_os = "solana"))]
+pub fn update_decryptable_supply(
+    token_program_id: &Pubkey,
+    mint: &Pubkey,
+    authority: &Pubkey,
+    multisig_signers: &[&Pubkey],
+    new_decryptable_supply: AeCiphertext,
+) -> Result<Instruction, ProgramError> {
+    check_program_account(token_program_id)?;
+    let mut accounts = vec![
+        AccountMeta::new(*mint, false),
+        AccountMeta::new_readonly(*authority, multisig_signers.is_empty()),
+    ];
+    for multisig_signer in multisig_signers.iter() {
+        accounts.push(AccountMeta::new_readonly(**multisig_signer, true));
+    }
+    Ok(encode_instruction(
+        token_program_id,
+        accounts,
+        TokenInstruction::ConfidentialMintBurnExtension,
+        ConfidentialMintBurnInstruction::UpdateDecryptableSupply,
+        &UpdateDecryptableSupplyData {
+            new_decryptable_supply: new_decryptable_supply.into(),
+        },
+    ))
+}
+
+/// Context state accounts used in confidential mint
+#[derive(Clone, Copy)]
+pub struct MintSplitContextStateAccounts<'a> {
+    /// Location of equality proof
+    pub equality_proof: &'a Pubkey,
+    /// Location of ciphertext validity proof
+    pub ciphertext_validity_proof: &'a Pubkey,
+    /// Location of range proof
+    pub range_proof: &'a Pubkey,
+    /// Authority able to close proof accounts
+    pub authority: &'a Pubkey,
+}
+
+/// Create a `ConfidentialMint` instruction
+#[allow(clippy::too_many_arguments)]
+#[cfg(not(target_os = "solana"))]
+pub fn confidential_mint_with_split_proofs(
+    token_program_id: &Pubkey,
+    token_account: &Pubkey,
+    mint: &Pubkey,
+    supply_elgamal_pubkey: Option<ElGamalPubkey>,
+    authority: &Pubkey,
+    multisig_signers: &[&Pubkey],
+    equality_proof_location: ProofLocation<CiphertextCommitmentEqualityProofData>,
+    ciphertext_validity_proof_location: ProofLocation<
+        BatchedGroupedCiphertext3HandlesValidityProofData,
+    >,
+    range_proof_location: ProofLocation<BatchedRangeProofU128Data>,
+    new_decryptable_supply: AeCiphertext,
+) -> Result<Vec<Instruction>, ProgramError> {
+    check_program_account(token_program_id)?;
+    let mut accounts = vec![AccountMeta::new(*token_account, false)];
+    // we only need write lock to adjust confidential suppy on
+    // mint if a value for supply_elgamal_pubkey has been set
+    if supply_elgamal_pubkey.is_some() {
+        accounts.push(AccountMeta::new(*mint, false));
+    } else {
+        accounts.push(AccountMeta::new_readonly(*mint, false));
+    }
+
+    let mut expected_instruction_offset = 1;
+    let mut proof_instructions = vec![];
+
+    let equality_proof_instruction_offset = process_proof_location(
+        &mut accounts,
+        &mut expected_instruction_offset,
+        &mut proof_instructions,
+        equality_proof_location,
+        true,
+        ProofInstruction::VerifyCiphertextCommitmentEquality,
+    )?;
+
+    let ciphertext_validity_proof_instruction_offset = process_proof_location(
+        &mut accounts,
+        &mut expected_instruction_offset,
+        &mut proof_instructions,
+        ciphertext_validity_proof_location,
+        false,
+        ProofInstruction::VerifyBatchedGroupedCiphertext3HandlesValidity,
+    )?;
+
+    let range_proof_instruction_offset = process_proof_location(
+        &mut accounts,
+        &mut expected_instruction_offset,
+        &mut proof_instructions,
+        range_proof_location,
+        false,
+        ProofInstruction::VerifyBatchedRangeProofU128,
+    )?;
+
+    accounts.push(AccountMeta::new_readonly(
+        *authority,
+        multisig_signers.is_empty(),
+    ));
+    for multisig_signer in multisig_signers.iter() {
+        accounts.push(AccountMeta::new_readonly(**multisig_signer, true));
+    }
+
+    let mut instructions = vec![encode_instruction(
+        token_program_id,
+        accounts,
+        TokenInstruction::ConfidentialMintBurnExtension,
+        ConfidentialMintBurnInstruction::Mint,
+        &MintInstructionData {
+            new_decryptable_supply: new_decryptable_supply.into(),
+            equality_proof_instruction_offset,
+            ciphertext_validity_proof_instruction_offset,
+            range_proof_instruction_offset,
+        },
+    )];
+
+    instructions.extend_from_slice(&proof_instructions);
+
+    Ok(instructions)
+}
+
+/// Create a inner `ConfidentialBurn` instruction
+#[allow(clippy::too_many_arguments)]
+#[cfg(not(target_os = "solana"))]
+pub fn confidential_burn_with_split_proofs(
+    token_program_id: &Pubkey,
+    token_account: &Pubkey,
+    mint: &Pubkey,
+    supply_elgamal_pubkey: Option<ElGamalPubkey>,
+    new_decryptable_available_balance: DecryptableBalance,
+    authority: &Pubkey,
+    multisig_signers: &[&Pubkey],
+    equality_proof_location: ProofLocation<CiphertextCommitmentEqualityProofData>,
+    ciphertext_validity_proof_location: ProofLocation<
+        BatchedGroupedCiphertext3HandlesValidityProofData,
+    >,
+    range_proof_location: ProofLocation<BatchedRangeProofU128Data>,
+) -> Result<Vec<Instruction>, ProgramError> {
+    check_program_account(token_program_id)?;
+    let mut accounts = vec![AccountMeta::new(*token_account, false)];
+    if supply_elgamal_pubkey.is_some() {
+        accounts.push(AccountMeta::new(*mint, false));
+    } else {
+        accounts.push(AccountMeta::new_readonly(*mint, false));
+    }
+
+    let mut expected_instruction_offset = 1;
+    let mut proof_instructions = vec![];
+
+    let equality_proof_instruction_offset = process_proof_location(
+        &mut accounts,
+        &mut expected_instruction_offset,
+        &mut proof_instructions,
+        equality_proof_location,
+        true,
+        ProofInstruction::VerifyCiphertextCommitmentEquality,
+    )?;
+
+    let ciphertext_validity_proof_instruction_offset = process_proof_location(
+        &mut accounts,
+        &mut expected_instruction_offset,
+        &mut proof_instructions,
+        ciphertext_validity_proof_location,
+        false,
+        ProofInstruction::VerifyBatchedGroupedCiphertext3HandlesValidity,
+    )?;
+
+    let range_proof_instruction_offset = process_proof_location(
+        &mut accounts,
+        &mut expected_instruction_offset,
+        &mut proof_instructions,
+        range_proof_location,
+        false,
+        ProofInstruction::VerifyBatchedRangeProofU128,
+    )?;
+
+    accounts.push(AccountMeta::new_readonly(
+        *authority,
+        multisig_signers.is_empty(),
+    ));
+
+    for multisig_signer in multisig_signers.iter() {
+        accounts.push(AccountMeta::new_readonly(**multisig_signer, true));
+    }
+
+    let mut instructions = vec![encode_instruction(
+        token_program_id,
+        accounts,
+        TokenInstruction::ConfidentialMintBurnExtension,
+        ConfidentialMintBurnInstruction::Burn,
+        &BurnInstructionData {
+            new_decryptable_available_balance,
+            equality_proof_instruction_offset,
+            ciphertext_validity_proof_instruction_offset,
+            range_proof_instruction_offset,
+        },
+    )];
+
+    instructions.extend_from_slice(&proof_instructions);
+
+    Ok(instructions)
+}
diff --git a/token/program-2022/src/extension/confidential_mint_burn/mod.rs b/token/program-2022/src/extension/confidential_mint_burn/mod.rs
new file mode 100644
index 000000000..049ced268
--- /dev/null
+++ b/token/program-2022/src/extension/confidential_mint_burn/mod.rs
@@ -0,0 +1,45 @@
+use {
+    crate::extension::{Extension, ExtensionType},
+    bytemuck::{Pod, Zeroable},
+    solana_zk_sdk::encryption::pod::{
+        auth_encryption::PodAeCiphertext,
+        elgamal::{PodElGamalCiphertext, PodElGamalPubkey},
+    },
+};
+
+/// Maximum bit length of any mint or burn amount
+///
+/// Any mint or burn amount must be less than 2^48
+pub const MAXIMUM_DEPOSIT_TRANSFER_AMOUNT: u64 = (u16::MAX as u64) + (1 << 16) * (u32::MAX as u64);
+
+/// Bit length of the low bits of pending balance plaintext
+pub const PENDING_BALANCE_LO_BIT_LENGTH: u32 = 16;
+
+/// Confidential Mint-Burn Extension instructions
+pub mod instruction;
+
+/// Confidential Mint-Burn Extension processor
+pub mod processor;
+
+/// Confidential Mint-Burn proof verification
+pub mod verify_proof;
+
+/// Confidential Mint Burn Extension supply information needed for instructions
+#[cfg(not(target_os = "solana"))]
+pub mod account_info;
+
+/// Confidential mint-burn mint configuration
+#[derive(Clone, Copy, Debug, Default, PartialEq, Pod, Zeroable)]
+#[repr(C)]
+pub struct ConfidentialMintBurn {
+    /// The confidential supply of the mint (encrypted by `encryption_pubkey`)
+    pub confidential_supply: PodElGamalCiphertext,
+    /// The decryptable confidential supply of the mint
+    pub decryptable_supply: PodAeCiphertext,
+    /// The ElGamal pubkey used to encrypt the confidential supply
+    pub supply_elgamal_pubkey: PodElGamalPubkey,
+}
+
+impl Extension for ConfidentialMintBurn {
+    const TYPE: ExtensionType = ExtensionType::ConfidentialMintBurn;
+}
diff --git a/token/program-2022/src/extension/confidential_mint_burn/processor.rs b/token/program-2022/src/extension/confidential_mint_burn/processor.rs
new file mode 100644
index 000000000..f06973377
--- /dev/null
+++ b/token/program-2022/src/extension/confidential_mint_burn/processor.rs
@@ -0,0 +1,402 @@
+#[cfg(feature = "zk-ops")]
+use spl_token_confidential_transfer_ciphertext_arithmetic as ciphertext_arithmetic;
+use {
+    crate::{
+        check_program_account,
+        error::TokenError,
+        extension::{
+            confidential_mint_burn::{
+                instruction::{
+                    BurnInstructionData, ConfidentialMintBurnInstruction, InitializeMintData,
+                    MintInstructionData, RotateSupplyElGamalPubkeyData,
+                    UpdateDecryptableSupplyData,
+                },
+                verify_proof::{verify_burn_proof, verify_mint_proof},
+                ConfidentialMintBurn,
+            },
+            confidential_transfer::{ConfidentialTransferAccount, ConfidentialTransferMint},
+            BaseStateWithExtensions, BaseStateWithExtensionsMut, PodStateWithExtensionsMut,
+        },
+        instruction::{decode_instruction_data, decode_instruction_type},
+        pod::{PodAccount, PodMint},
+        processor::Processor,
+    },
+    solana_program::{
+        account_info::{next_account_info, AccountInfo},
+        entrypoint::ProgramResult,
+        msg,
+        program_error::ProgramError,
+        pubkey::Pubkey,
+    },
+    solana_zk_sdk::{
+        encryption::pod::{auth_encryption::PodAeCiphertext, elgamal::PodElGamalPubkey},
+        zk_elgamal_proof_program::proof_data::{
+            CiphertextCiphertextEqualityProofContext, CiphertextCiphertextEqualityProofData,
+        },
+    },
+    spl_token_confidential_transfer_proof_extraction::instruction::verify_and_extract_context,
+};
+
+/// Processes an [InitializeMint] instruction.
+fn process_initialize_mint(accounts: &[AccountInfo], data: &InitializeMintData) -> ProgramResult {
+    let account_info_iter = &mut accounts.iter();
+    let mint_info = next_account_info(account_info_iter)?;
+
+    check_program_account(mint_info.owner)?;
+
+    let mint_data = &mut mint_info.data.borrow_mut();
+    let mut mint = PodStateWithExtensionsMut::<PodMint>::unpack_uninitialized(mint_data)?;
+    let mint_burn_extension = mint.init_extension::<ConfidentialMintBurn>(true)?;
+
+    mint_burn_extension.supply_elgamal_pubkey = data.supply_elgamal_pubkey;
+    mint_burn_extension.decryptable_supply = data.decryptable_supply;
+
+    Ok(())
+}
+
+/// Processes an [RotateSupplyElGamal] instruction.
+#[cfg(feature = "zk-ops")]
+fn process_rotate_supply_elgamal_pubkey(
+    program_id: &Pubkey,
+    accounts: &[AccountInfo],
+    data: &RotateSupplyElGamalPubkeyData,
+) -> ProgramResult {
+    let account_info_iter = &mut accounts.iter();
+    let mint_info = next_account_info(account_info_iter)?;
+
+    check_program_account(mint_info.owner)?;
+    let mint_data = &mut mint_info.data.borrow_mut();
+    let mut mint = PodStateWithExtensionsMut::<PodMint>::unpack(mint_data)?;
+    let mint_authority = mint.base.mint_authority;
+    let mint_burn_extension = mint.get_extension_mut::<ConfidentialMintBurn>()?;
+
+    let proof_context = verify_and_extract_context::<
+        CiphertextCiphertextEqualityProofData,
+        CiphertextCiphertextEqualityProofContext,
+    >(
+        account_info_iter,
+        data.proof_instruction_offset as i64,
+        None,
+    )?;
+
+    let supply_elgamal_pubkey: Option<PodElGamalPubkey> =
+        mint_burn_extension.supply_elgamal_pubkey.into();
+    let Some(supply_elgamal_pubkey) = supply_elgamal_pubkey else {
+        return Err(TokenError::InvalidState.into());
+    };
+
+    if !supply_elgamal_pubkey.eq(&proof_context.first_pubkey) {
+        return Err(TokenError::ConfidentialTransferElGamalPubkeyMismatch.into());
+    }
+    if mint_burn_extension.confidential_supply != proof_context.first_ciphertext {
+        return Err(ProgramError::InvalidInstructionData);
+    }
+
+    let authority_info = next_account_info(account_info_iter)?;
+    let authority_info_data_len = authority_info.data_len();
+    let authority = mint_authority.ok_or(TokenError::NoAuthorityExists)?;
+
+    Processor::validate_owner(
+        program_id,
+        &authority,
+        authority_info,
+        authority_info_data_len,
+        account_info_iter.as_slice(),
+    )?;
+
+    mint_burn_extension.supply_elgamal_pubkey = proof_context.second_pubkey;
+    mint_burn_extension.confidential_supply = proof_context.second_ciphertext;
+
+    Ok(())
+}
+
+/// Processes an [UpdateAuthority] instruction.
+fn process_update_decryptable_supply(
+    program_id: &Pubkey,
+    accounts: &[AccountInfo],
+    new_decryptable_supply: PodAeCiphertext,
+) -> ProgramResult {
+    let account_info_iter = &mut accounts.iter();
+    let mint_info = next_account_info(account_info_iter)?;
+
+    check_program_account(mint_info.owner)?;
+    let mint_data = &mut mint_info.data.borrow_mut();
+    let mut mint = PodStateWithExtensionsMut::<PodMint>::unpack(mint_data)?;
+    let mint_authority = mint.base.mint_authority;
+    let mint_burn_extension = mint.get_extension_mut::<ConfidentialMintBurn>()?;
+
+    let authority_info = next_account_info(account_info_iter)?;
+    let authority_info_data_len = authority_info.data_len();
+    let authority = mint_authority.ok_or(TokenError::NoAuthorityExists)?;
+
+    Processor::validate_owner(
+        program_id,
+        &authority,
+        authority_info,
+        authority_info_data_len,
+        account_info_iter.as_slice(),
+    )?;
+
+    mint_burn_extension.decryptable_supply = new_decryptable_supply;
+
+    Ok(())
+}
+
+/// Processes a [ConfidentialMint] instruction.
+#[cfg(feature = "zk-ops")]
+fn process_confidential_mint(
+    program_id: &Pubkey,
+    accounts: &[AccountInfo],
+    data: &MintInstructionData,
+) -> ProgramResult {
+    let account_info_iter = &mut accounts.iter();
+    let token_account_info = next_account_info(account_info_iter)?;
+    let mint_info = next_account_info(account_info_iter)?;
+
+    check_program_account(mint_info.owner)?;
+    let mint_data = &mut mint_info.data.borrow_mut();
+    let mut mint = PodStateWithExtensionsMut::<PodMint>::unpack(mint_data)?;
+    let mint_authority = mint.base.mint_authority;
+
+    let auditor_elgamal_pubkey = mint
+        .get_extension::<ConfidentialTransferMint>()?
+        .auditor_elgamal_pubkey;
+    let mint_burn_extension = mint.get_extension_mut::<ConfidentialMintBurn>()?;
+
+    let proof_context = verify_mint_proof(
+        account_info_iter,
+        data.equality_proof_instruction_offset,
+        data.ciphertext_validity_proof_instruction_offset,
+        data.range_proof_instruction_offset,
+    )?;
+
+    check_program_account(token_account_info.owner)?;
+    let token_account_data = &mut token_account_info.data.borrow_mut();
+    let mut token_account = PodStateWithExtensionsMut::<PodAccount>::unpack(token_account_data)?;
+
+    let authority_info = next_account_info(account_info_iter)?;
+    let authority_info_data_len = authority_info.data_len();
+    let authority = mint_authority.ok_or(TokenError::NoAuthorityExists)?;
+
+    Processor::validate_owner(
+        program_id,
+        &authority,
+        authority_info,
+        authority_info_data_len,
+        account_info_iter.as_slice(),
+    )?;
+
+    if token_account.base.is_frozen() {
+        return Err(TokenError::AccountFrozen.into());
+    }
+
+    if token_account.base.mint != *mint_info.key {
+        return Err(TokenError::MintMismatch.into());
+    }
+
+    assert!(!token_account.base.is_native());
+
+    let confidential_transfer_account =
+        token_account.get_extension_mut::<ConfidentialTransferAccount>()?;
+    confidential_transfer_account.valid_as_destination()?;
+
+    if proof_context.mint_pubkeys.destination != confidential_transfer_account.elgamal_pubkey {
+        return Err(ProgramError::InvalidInstructionData);
+    }
+
+    if let Some(auditor_pubkey) = Option::<PodElGamalPubkey>::from(auditor_elgamal_pubkey) {
+        if auditor_pubkey != proof_context.mint_pubkeys.auditor {
+            return Err(ProgramError::InvalidInstructionData);
+        }
+    }
+
+    confidential_transfer_account.pending_balance_lo = ciphertext_arithmetic::add(
+        &confidential_transfer_account.pending_balance_lo,
+        &proof_context
+            .mint_amount_ciphertext_lo
+            .try_extract_ciphertext(0)
+            .map_err(|_| ProgramError::InvalidAccountData)?,
+    )
+    .ok_or(TokenError::CiphertextArithmeticFailed)?;
+    confidential_transfer_account.pending_balance_hi = ciphertext_arithmetic::add(
+        &confidential_transfer_account.pending_balance_hi,
+        &proof_context
+            .mint_amount_ciphertext_hi
+            .try_extract_ciphertext(0)
+            .map_err(|_| ProgramError::InvalidAccountData)?,
+    )
+    .ok_or(TokenError::CiphertextArithmeticFailed)?;
+
+    confidential_transfer_account.increment_pending_balance_credit_counter()?;
+
+    // update supply
+    if mint_burn_extension.supply_elgamal_pubkey != proof_context.mint_pubkeys.supply {
+        return Err(ProgramError::InvalidInstructionData);
+    }
+    let current_supply = mint_burn_extension.confidential_supply;
+    mint_burn_extension.confidential_supply = ciphertext_arithmetic::add_with_lo_hi(
+        &current_supply,
+        &proof_context
+            .mint_amount_ciphertext_lo
+            .try_extract_ciphertext(2)
+            .map_err(|_| ProgramError::InvalidAccountData)?,
+        &proof_context
+            .mint_amount_ciphertext_hi
+            .try_extract_ciphertext(2)
+            .map_err(|_| ProgramError::InvalidAccountData)?,
+    )
+    .ok_or(TokenError::CiphertextArithmeticFailed)?;
+    mint_burn_extension.decryptable_supply = data.new_decryptable_supply;
+
+    Ok(())
+}
+
+/// Processes a [ConfidentialBurn] instruction.
+#[cfg(feature = "zk-ops")]
+fn process_confidential_burn(
+    program_id: &Pubkey,
+    accounts: &[AccountInfo],
+    data: &BurnInstructionData,
+) -> ProgramResult {
+    let account_info_iter = &mut accounts.iter();
+    let token_account_info = next_account_info(account_info_iter)?;
+    let mint_info = next_account_info(account_info_iter)?;
+
+    check_program_account(mint_info.owner)?;
+    let mint_data = &mut mint_info.data.borrow_mut();
+    let mut mint = PodStateWithExtensionsMut::<PodMint>::unpack(mint_data)?;
+
+    let auditor_elgamal_pubkey = mint
+        .get_extension::<ConfidentialTransferMint>()?
+        .auditor_elgamal_pubkey;
+    let mint_burn_extension = mint.get_extension_mut::<ConfidentialMintBurn>()?;
+
+    let proof_context = verify_burn_proof(
+        account_info_iter,
+        data.equality_proof_instruction_offset,
+        data.ciphertext_validity_proof_instruction_offset,
+        data.range_proof_instruction_offset,
+    )?;
+
+    check_program_account(token_account_info.owner)?;
+    let token_account_data = &mut token_account_info.data.borrow_mut();
+    let mut token_account = PodStateWithExtensionsMut::<PodAccount>::unpack(token_account_data)?;
+
+    let authority_info = next_account_info(account_info_iter)?;
+    let authority_info_data_len = authority_info.data_len();
+
+    Processor::validate_owner(
+        program_id,
+        &token_account.base.owner,
+        authority_info,
+        authority_info_data_len,
+        account_info_iter.as_slice(),
+    )?;
+
+    if token_account.base.is_frozen() {
+        return Err(TokenError::AccountFrozen.into());
+    }
+
+    if token_account.base.mint != *mint_info.key {
+        return Err(TokenError::MintMismatch.into());
+    }
+
+    let confidential_transfer_account =
+        token_account.get_extension_mut::<ConfidentialTransferAccount>()?;
+    confidential_transfer_account.valid_as_source()?;
+
+    // Check that the source encryption public key is consistent with what was
+    // actually used to generate the zkp.
+    if proof_context.burn_pubkeys.source != confidential_transfer_account.elgamal_pubkey {
+        return Err(TokenError::ConfidentialTransferElGamalPubkeyMismatch.into());
+    }
+
+    let burn_amount_lo = &proof_context
+        .burn_amount_ciphertext_lo
+        .try_extract_ciphertext(0)
+        .map_err(|_| ProgramError::InvalidAccountData)?;
+    let burn_amount_hi = &proof_context
+        .burn_amount_ciphertext_hi
+        .try_extract_ciphertext(0)
+        .map_err(|_| ProgramError::InvalidAccountData)?;
+
+    let new_source_available_balance = ciphertext_arithmetic::subtract_with_lo_hi(
+        &confidential_transfer_account.available_balance,
+        burn_amount_lo,
+        burn_amount_hi,
+    )
+    .ok_or(TokenError::CiphertextArithmeticFailed)?;
+
+    // Check that the computed available balance is consistent with what was
+    // actually used to generate the zkp on the client side.
+    if new_source_available_balance != proof_context.remaining_balance_ciphertext {
+        return Err(TokenError::ConfidentialTransferBalanceMismatch.into());
+    }
+
+    confidential_transfer_account.available_balance = new_source_available_balance;
+    confidential_transfer_account.decryptable_available_balance =
+        data.new_decryptable_available_balance;
+
+    if let Some(auditor_pubkey) = Option::<PodElGamalPubkey>::from(auditor_elgamal_pubkey) {
+        if auditor_pubkey != proof_context.burn_pubkeys.auditor {
+            return Err(ProgramError::InvalidInstructionData);
+        }
+    }
+
+    // update supply
+    if mint_burn_extension.supply_elgamal_pubkey != proof_context.burn_pubkeys.supply {
+        return Err(ProgramError::InvalidInstructionData);
+    }
+    let current_supply = mint_burn_extension.confidential_supply;
+    mint_burn_extension.confidential_supply = ciphertext_arithmetic::subtract_with_lo_hi(
+        &current_supply,
+        &proof_context
+            .burn_amount_ciphertext_lo
+            .try_extract_ciphertext(2)
+            .map_err(|_| ProgramError::InvalidAccountData)?,
+        &proof_context
+            .burn_amount_ciphertext_hi
+            .try_extract_ciphertext(2)
+            .map_err(|_| ProgramError::InvalidAccountData)?,
+    )
+    .ok_or(TokenError::CiphertextArithmeticFailed)?;
+
+    Ok(())
+}
+
+#[allow(dead_code)]
+pub(crate) fn process_instruction(
+    program_id: &Pubkey,
+    accounts: &[AccountInfo],
+    input: &[u8],
+) -> ProgramResult {
+    check_program_account(program_id)?;
+
+    match decode_instruction_type(input)? {
+        ConfidentialMintBurnInstruction::InitializeMint => {
+            msg!("ConfidentialMintBurnInstruction::InitializeMint");
+            let data = decode_instruction_data::<InitializeMintData>(input)?;
+            process_initialize_mint(accounts, data)
+        }
+        ConfidentialMintBurnInstruction::RotateSupplyElGamalPubkey => {
+            msg!("ConfidentialMintBurnInstruction::RotateSupplyElGamal");
+            let data = decode_instruction_data::<RotateSupplyElGamalPubkeyData>(input)?;
+            process_rotate_supply_elgamal_pubkey(program_id, accounts, data)
+        }
+        ConfidentialMintBurnInstruction::UpdateDecryptableSupply => {
+            msg!("ConfidentialMintBurnInstruction::UpdateDecryptableSupply");
+            let data = decode_instruction_data::<UpdateDecryptableSupplyData>(input)?;
+            process_update_decryptable_supply(program_id, accounts, data.new_decryptable_supply)
+        }
+        ConfidentialMintBurnInstruction::Mint => {
+            msg!("ConfidentialMintBurnInstruction::ConfidentialMint");
+            let data = decode_instruction_data::<MintInstructionData>(input)?;
+            process_confidential_mint(program_id, accounts, data)
+        }
+        ConfidentialMintBurnInstruction::Burn => {
+            msg!("ConfidentialMintBurnInstruction::ConfidentialBurn");
+            let data = decode_instruction_data::<BurnInstructionData>(input)?;
+            process_confidential_burn(program_id, accounts, data)
+        }
+    }
+}
diff --git a/token/program-2022/src/extension/confidential_mint_burn/verify_proof.rs b/token/program-2022/src/extension/confidential_mint_burn/verify_proof.rs
new file mode 100644
index 000000000..cb1e3392d
--- /dev/null
+++ b/token/program-2022/src/extension/confidential_mint_burn/verify_proof.rs
@@ -0,0 +1,114 @@
+use crate::error::TokenError;
+#[cfg(feature = "zk-ops")]
+use {
+    solana_program::{
+        account_info::{next_account_info, AccountInfo},
+        program_error::ProgramError,
+    },
+    solana_zk_sdk::zk_elgamal_proof_program::proof_data::{
+        BatchedGroupedCiphertext3HandlesValidityProofContext,
+        BatchedGroupedCiphertext3HandlesValidityProofData, BatchedRangeProofContext,
+        BatchedRangeProofU128Data, CiphertextCommitmentEqualityProofContext,
+        CiphertextCommitmentEqualityProofData,
+    },
+    spl_token_confidential_transfer_proof_extraction::{
+        burn::BurnProofContext, instruction::verify_and_extract_context, mint::MintProofContext,
+    },
+    std::slice::Iter,
+};
+
+/// Verify zero-knowledge proofs needed for a [ConfidentialMint] instruction and
+/// return the corresponding proof context information.
+#[cfg(feature = "zk-ops")]
+pub fn verify_mint_proof(
+    account_info_iter: &mut Iter<'_, AccountInfo<'_>>,
+    equality_proof_instruction_offset: i8,
+    ciphertext_validity_proof_instruction_offset: i8,
+    range_proof_instruction_offset: i8,
+) -> Result<MintProofContext, ProgramError> {
+    let sysvar_account_info = if equality_proof_instruction_offset != 0 {
+        Some(next_account_info(account_info_iter)?)
+    } else {
+        None
+    };
+
+    let equality_proof_context = verify_and_extract_context::<
+        CiphertextCommitmentEqualityProofData,
+        CiphertextCommitmentEqualityProofContext,
+    >(
+        account_info_iter,
+        equality_proof_instruction_offset as i64,
+        sysvar_account_info,
+    )?;
+
+    let ciphertext_validity_proof_context = verify_and_extract_context::<
+        BatchedGroupedCiphertext3HandlesValidityProofData,
+        BatchedGroupedCiphertext3HandlesValidityProofContext,
+    >(
+        account_info_iter,
+        ciphertext_validity_proof_instruction_offset as i64,
+        sysvar_account_info,
+    )?;
+
+    let range_proof_context =
+        verify_and_extract_context::<BatchedRangeProofU128Data, BatchedRangeProofContext>(
+            account_info_iter,
+            range_proof_instruction_offset as i64,
+            sysvar_account_info,
+        )?;
+
+    Ok(MintProofContext::verify_and_extract(
+        &equality_proof_context,
+        &ciphertext_validity_proof_context,
+        &range_proof_context,
+    )
+    .map_err(|e| -> TokenError { e.into() })?)
+}
+
+/// Verify zero-knowledge proofs needed for a [ConfidentialBurn] instruction and
+/// return the corresponding proof context information.
+#[cfg(feature = "zk-ops")]
+pub fn verify_burn_proof(
+    account_info_iter: &mut Iter<'_, AccountInfo<'_>>,
+    equality_proof_instruction_offset: i8,
+    ciphertext_validity_proof_instruction_offset: i8,
+    range_proof_instruction_offset: i8,
+) -> Result<BurnProofContext, ProgramError> {
+    let sysvar_account_info = if equality_proof_instruction_offset != 0 {
+        Some(next_account_info(account_info_iter)?)
+    } else {
+        None
+    };
+
+    let equality_proof_context = verify_and_extract_context::<
+        CiphertextCommitmentEqualityProofData,
+        CiphertextCommitmentEqualityProofContext,
+    >(
+        account_info_iter,
+        equality_proof_instruction_offset as i64,
+        sysvar_account_info,
+    )?;
+
+    let ciphertext_validity_proof_context = verify_and_extract_context::<
+        BatchedGroupedCiphertext3HandlesValidityProofData,
+        BatchedGroupedCiphertext3HandlesValidityProofContext,
+    >(
+        account_info_iter,
+        ciphertext_validity_proof_instruction_offset as i64,
+        sysvar_account_info,
+    )?;
+
+    let range_proof_context =
+        verify_and_extract_context::<BatchedRangeProofU128Data, BatchedRangeProofContext>(
+            account_info_iter,
+            range_proof_instruction_offset as i64,
+            sysvar_account_info,
+        )?;
+
+    Ok(BurnProofContext::verify_and_extract(
+        &equality_proof_context,
+        &ciphertext_validity_proof_context,
+        &range_proof_context,
+    )
+    .map_err(|e| -> TokenError { e.into() })?)
+}
diff --git a/token/program-2022/src/extension/confidential_transfer/account_info.rs b/token/program-2022/src/extension/confidential_transfer/account_info.rs
index ed9a94e68..39b819b9a 100644
--- a/token/program-2022/src/extension/confidential_transfer/account_info.rs
+++ b/token/program-2022/src/extension/confidential_transfer/account_info.rs
@@ -324,7 +324,8 @@ impl TransferAccountInfo {
     }
 }
 
-fn combine_balances(balance_lo: u64, balance_hi: u64) -> Option<u64> {
+/// Combines pending balances low and high bits into singular pending balance
+pub fn combine_balances(balance_lo: u64, balance_hi: u64) -> Option<u64> {
     balance_hi
         .checked_shl(PENDING_BALANCE_LO_BIT_LENGTH)?
         .checked_add(balance_lo)
diff --git a/token/program-2022/src/extension/confidential_transfer/instruction.rs b/token/program-2022/src/extension/confidential_transfer/instruction.rs
index e82f4f521..335fdf4a2 100644
--- a/token/program-2022/src/extension/confidential_transfer/instruction.rs
+++ b/token/program-2022/src/extension/confidential_transfer/instruction.rs
@@ -182,6 +182,7 @@ pub enum ConfidentialTransferInstruction {
     ///
     /// Fails if the source or destination accounts are frozen.
     /// Fails if the associated mint is extended as `NonTransferable`.
+    /// Fails if the associated mint is extended as `ConfidentialMintBurn`.
     ///
     /// Accounts expected by this instruction:
     ///
@@ -215,6 +216,7 @@ pub enum ConfidentialTransferInstruction {
     ///
     /// Fails if the source or destination accounts are frozen.
     /// Fails if the associated mint is extended as `NonTransferable`.
+    /// Fails if the associated mint is extended as `ConfidentialMintBurn`.
     ///
     /// Accounts expected by this instruction:
     ///
diff --git a/token/program-2022/src/extension/confidential_transfer/processor.rs b/token/program-2022/src/extension/confidential_transfer/processor.rs
index a93b5e852..c387dedff 100644
--- a/token/program-2022/src/extension/confidential_transfer/processor.rs
+++ b/token/program-2022/src/extension/confidential_transfer/processor.rs
@@ -1,6 +1,7 @@
 // Remove feature once zk ops syscalls are enabled on all networks
 #[cfg(feature = "zk-ops")]
 use {
+    crate::extension::confidential_mint_burn::ConfidentialMintBurn,
     crate::extension::non_transferable::NonTransferableAccount,
     spl_token_confidential_transfer_ciphertext_arithmetic as ciphertext_arithmetic,
 };
@@ -262,6 +263,7 @@ fn process_configure_account(
     // `ConfidentialTransferAccount` extension
     let confidential_transfer_account =
         token_account.init_extension::<ConfidentialTransferAccount>(false)?;
+
     confidential_transfer_account.approved = confidential_transfer_mint.auto_approve_new_accounts;
     confidential_transfer_account.elgamal_pubkey = elgamal_pubkey;
     confidential_transfer_account.maximum_pending_balance_credit_counter =
@@ -399,6 +401,10 @@ fn process_deposit(
         return Err(TokenError::MintDecimalsMismatch.into());
     }
 
+    if mint.get_extension::<ConfidentialMintBurn>().is_ok() {
+        return Err(TokenError::IllegalMintBurnConversion.into());
+    }
+
     check_program_account(token_account_info.owner)?;
     let token_account_data = &mut token_account_info.data.borrow_mut();
     let mut token_account = PodStateWithExtensionsMut::<PodAccount>::unpack(token_account_data)?;
@@ -508,6 +514,10 @@ fn process_withdraw(
         return Err(TokenError::MintDecimalsMismatch.into());
     }
 
+    if mint.get_extension::<ConfidentialMintBurn>().is_ok() {
+        return Err(TokenError::IllegalMintBurnConversion.into());
+    }
+
     check_program_account(token_account_info.owner)?;
     let token_account_data = &mut token_account_info.data.borrow_mut();
     let mut token_account = PodStateWithExtensionsMut::<PodAccount>::unpack(token_account_data)?;
@@ -757,6 +767,7 @@ fn process_transfer(
     Ok(())
 }
 
+/// Processes the changes for the sending party of a confidential transfer
 #[cfg(feature = "zk-ops")]
 fn process_source_for_transfer(
     program_id: &Pubkey,
diff --git a/token/program-2022/src/extension/mod.rs b/token/program-2022/src/extension/mod.rs
index 0cfc0cbdc..f2e09ab2a 100644
--- a/token/program-2022/src/extension/mod.rs
+++ b/token/program-2022/src/extension/mod.rs
@@ -6,6 +6,7 @@ use {
     crate::{
         error::TokenError,
         extension::{
+            confidential_mint_burn::ConfidentialMintBurn,
             confidential_transfer::{ConfidentialTransferAccount, ConfidentialTransferMint},
             confidential_transfer_fee::{
                 ConfidentialTransferFeeAmount, ConfidentialTransferFeeConfig,
@@ -84,6 +85,9 @@ pub mod transfer_fee;
 /// Transfer Hook extension
 pub mod transfer_hook;
 
+/// Confidential mint-burn extension
+pub mod confidential_mint_burn;
+
 /// Length in TLV structure
 #[derive(Clone, Copy, Debug, Default, PartialEq, Pod, Zeroable)]
 #[repr(transparent)]
@@ -1101,6 +1105,9 @@ pub enum ExtensionType {
     GroupMemberPointer,
     /// Mint contains token group member configurations
     TokenGroupMember,
+    /// Mint allowing the minting and burning of confidential tokens
+    ConfidentialMintBurn,
+
     /// Test variable-length mint extension
     #[cfg(test)]
     VariableLenMintTest = u16::MAX - 2,
@@ -1181,6 +1188,7 @@ impl ExtensionType {
             ExtensionType::TokenGroup => pod_get_packed_len::<TokenGroup>(),
             ExtensionType::GroupMemberPointer => pod_get_packed_len::<GroupMemberPointer>(),
             ExtensionType::TokenGroupMember => pod_get_packed_len::<TokenGroupMember>(),
+            ExtensionType::ConfidentialMintBurn => pod_get_packed_len::<ConfidentialMintBurn>(),
             #[cfg(test)]
             ExtensionType::AccountPaddingTest => pod_get_packed_len::<AccountPaddingTest>(),
             #[cfg(test)]
@@ -1244,6 +1252,7 @@ impl ExtensionType {
             | ExtensionType::GroupPointer
             | ExtensionType::TokenGroup
             | ExtensionType::GroupMemberPointer
+            | ExtensionType::ConfidentialMintBurn
             | ExtensionType::TokenGroupMember => AccountType::Mint,
             ExtensionType::ImmutableOwner
             | ExtensionType::TransferFeeAmount
@@ -1295,6 +1304,7 @@ impl ExtensionType {
         let mut transfer_fee_config = false;
         let mut confidential_transfer_mint = false;
         let mut confidential_transfer_fee_config = false;
+        let mut confidential_mint_burn = false;
 
         for extension_type in mint_extension_types {
             match extension_type {
@@ -1303,6 +1313,7 @@ impl ExtensionType {
                 ExtensionType::ConfidentialTransferFeeConfig => {
                     confidential_transfer_fee_config = true
                 }
+                ExtensionType::ConfidentialMintBurn => confidential_mint_burn = true,
                 _ => (),
             }
         }
@@ -1316,6 +1327,10 @@ impl ExtensionType {
             return Err(TokenError::InvalidExtensionCombination);
         }
 
+        if confidential_mint_burn && !confidential_transfer_mint {
+            return Err(TokenError::InvalidExtensionCombination);
+        }
+
         Ok(())
     }
 }
diff --git a/token/program-2022/src/instruction.rs b/token/program-2022/src/instruction.rs
index 9b2cb5510..3d766aa02 100644
--- a/token/program-2022/src/instruction.rs
+++ b/token/program-2022/src/instruction.rs
@@ -708,6 +708,9 @@ pub enum TokenInstruction<'a> {
     /// for further details about the extended instructions that share this
     /// instruction prefix
     GroupMemberPointerExtension,
+    /// Instruction prefix for instructions to the confidential-mint-burn
+    /// extension
+    ConfidentialMintBurnExtension,
 }
 impl<'a> TokenInstruction<'a> {
     /// Unpacks a byte buffer into a
@@ -847,6 +850,7 @@ impl<'a> TokenInstruction<'a> {
             39 => Self::MetadataPointerExtension,
             40 => Self::GroupPointerExtension,
             41 => Self::GroupMemberPointerExtension,
+            42 => Self::ConfidentialMintBurnExtension,
             _ => return Err(TokenError::InvalidInstruction.into()),
         })
     }
@@ -1018,6 +1022,9 @@ impl<'a> TokenInstruction<'a> {
             &Self::GroupMemberPointerExtension => {
                 buf.push(41);
             }
+            &Self::ConfidentialMintBurnExtension => {
+                buf.push(42);
+            }
         };
         buf
     }
diff --git a/token/program-2022/src/pod_instruction.rs b/token/program-2022/src/pod_instruction.rs
index dcf487c96..a08f8b68a 100644
--- a/token/program-2022/src/pod_instruction.rs
+++ b/token/program-2022/src/pod_instruction.rs
@@ -114,6 +114,7 @@ pub(crate) enum PodTokenInstruction {
     // 40
     GroupPointerExtension,
     GroupMemberPointerExtension,
+    ConfidentialMintBurnExtension,
 }
 
 fn unpack_pubkey_option(input: &[u8]) -> Result<PodCOption<Pubkey>, ProgramError> {
diff --git a/token/program-2022/src/processor.rs b/token/program-2022/src/processor.rs
index 93e00c157..697cf042f 100644
--- a/token/program-2022/src/processor.rs
+++ b/token/program-2022/src/processor.rs
@@ -5,6 +5,7 @@ use {
         check_program_account,
         error::TokenError,
         extension::{
+            confidential_mint_burn::{self, ConfidentialMintBurn},
             confidential_transfer::{self, ConfidentialTransferAccount, ConfidentialTransferMint},
             confidential_transfer_fee::{
                 self, ConfidentialTransferFeeAmount, ConfidentialTransferFeeConfig,
@@ -322,6 +323,7 @@ impl Processor {
         {
             return Err(TokenError::NonTransferable.into());
         }
+
         let (fee, maybe_permanent_delegate, maybe_transfer_hook_program_id) =
             if let Some((mint_info, expected_decimals)) = expected_mint_info {
                 if &source_account.base.mint != mint_info.key {
@@ -369,9 +371,9 @@ impl Processor {
                     .is_ok()
                 {
                     return Err(TokenError::MintRequiredForTransfer.into());
-                } else {
-                    (0, None, None)
                 }
+
+                (0, None, None)
             };
         if let Some(expected_fee) = expected_fee {
             if expected_fee != fee {
@@ -954,6 +956,10 @@ impl Processor {
             return Err(TokenError::NonTransferableNeedsImmutableOwnership.into());
         }
 
+        if mint.get_extension::<ConfidentialMintBurn>().is_ok() {
+            return Err(TokenError::IllegalMintBurnConversion.into());
+        }
+
         if let Some(expected_decimals) = expected_decimals {
             if expected_decimals != mint.base.decimals {
                 return Err(TokenError::MintDecimalsMismatch.into());
@@ -1793,6 +1799,14 @@ impl Processor {
                         &input[1..],
                     )
                 }
+                PodTokenInstruction::ConfidentialMintBurnExtension => {
+                    msg!("Instruction: ConfidentialMintBurnExtension");
+                    confidential_mint_burn::processor::process_instruction(
+                        program_id,
+                        accounts,
+                        &input[1..],
+                    )
+                }
             }
         } else if let Ok(instruction) = TokenMetadataInstruction::unpack(input) {
             token_metadata::processor::process_instruction(program_id, accounts, instruction)


Test patch:
diff --git a/token/confidential-transfer/proof-tests/tests/proof_test.rs b/token/confidential-transfer/proof-tests/tests/proof_test.rs
index f4c3a7f3a..6e73e303e 100644
--- a/token/confidential-transfer/proof-tests/tests/proof_test.rs
+++ b/token/confidential-transfer/proof-tests/tests/proof_test.rs
@@ -217,16 +217,16 @@ fn test_mint_validity(mint_amount: u64, supply: u64) {
     let supply_aes_key = AeKey::new_rand();
 
     let supply_ciphertext = supply_keypair.pubkey().encrypt(supply);
-    let decryptable_supply = supply_aes_key.encrypt(supply);
 
     let MintProofData {
         equality_proof_data,
         ciphertext_validity_proof_data,
         range_proof_data,
+        new_decryptable_supply: _,
     } = mint_split_proof_data(
         &supply_ciphertext,
-        &decryptable_supply,
         mint_amount,
+        supply,
         &supply_keypair,
         &supply_aes_key,
         destination_pubkey,