diff --git a/packages/dashpay-contract/schema/v2/dashpay.schema.json b/packages/dashpay-contract/schema/v2/dashpay.schema.json
new file mode 100644
index 00000000000..db5ce9b4dcd
--- /dev/null
+++ b/packages/dashpay-contract/schema/v2/dashpay.schema.json
@@ -0,0 +1,271 @@
+{
+ "profile": {
+ "type": "object",
+ "indices": [
+ {
+ "name": "ownerId",
+ "properties": [
+ {
+ "$ownerId": "asc"
+ }
+ ],
+ "unique": true
+ },
+ {
+ "name": "ownerIdAndUpdatedAt",
+ "properties": [
+ {
+ "$ownerId": "asc"
+ },
+ {
+ "$updatedAt": "asc"
+ }
+ ]
+ }
+ ],
+ "properties": {
+ "avatarUrl": {
+ "type": "string",
+ "format": "uri",
+ "minLength": 1,
+ "maxLength": 2048,
+ "position": 0
+ },
+ "avatarHash": {
+ "type": "array",
+ "byteArray": true,
+ "minItems": 32,
+ "maxItems": 32,
+ "description": "SHA256 hash of the bytes of the image specified by avatarUrl",
+ "position": 1
+ },
+ "avatarFingerprint": {
+ "type": "array",
+ "byteArray": true,
+ "minItems": 8,
+ "maxItems": 8,
+ "description": "dHash the image specified by avatarUrl",
+ "position": 2
+ },
+ "publicMessage": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 140,
+ "position": 3
+ },
+ "displayName": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 25,
+ "position": 4
+ },
+ "corePaymentAddress": {
+ "type": "array",
+ "byteArray": true,
+ "minItems": 21,
+ "maxItems": 21,
+ "description": "Core chain address in storage form (type byte 0x00 P2PKH / 0x01 P2SH followed by the 20-byte HASH160, i.e. RIPEMD160 of SHA256, of the public key or redeem script) for public payments. The type byte is consensus-enforced by a data trigger; clients render the address as Base58Check for the network they are on. Payments to it are publicly linkable to this profile.",
+ "position": 5
+ },
+ "platformPaymentAddress": {
+ "type": "array",
+ "byteArray": true,
+ "minItems": 21,
+ "maxItems": 21,
+ "description": "Platform address in storage form (type byte 0x00 P2PKH / 0x01 P2SH followed by the 20-byte HASH160, i.e. RIPEMD160 of SHA256, of the public key or redeem script) for public payments. The type byte is consensus-enforced by a data trigger.",
+ "position": 6
+ }
+ },
+ "minProperties": 1,
+ "dependentRequired": {
+ "avatarUrl": ["avatarHash", "avatarFingerprint"],
+ "avatarHash": ["avatarUrl", "avatarFingerprint"],
+ "avatarFingerprint": ["avatarUrl", "avatarHash"]
+ },
+ "required": [
+ "$createdAt",
+ "$updatedAt"
+ ],
+ "additionalProperties": false
+ },
+ "contactInfo": {
+ "type": "object",
+ "indices": [
+ {
+ "name": "ownerIdAndKeys",
+ "properties": [
+ {
+ "$ownerId": "asc"
+ },
+ {
+ "rootEncryptionKeyIndex": "asc"
+ },
+ {
+ "derivationEncryptionKeyIndex": "asc"
+ }
+ ],
+ "unique": true
+ },
+ {
+ "name": "ownerIdAndUpdatedAt",
+ "properties": [
+ {
+ "$ownerId": "asc"
+ },
+ {
+ "$updatedAt": "asc"
+ }
+ ]
+ }
+ ],
+ "properties": {
+ "encToUserId": {
+ "type": "array",
+ "byteArray": true,
+ "minItems": 32,
+ "maxItems": 32,
+ "position": 0
+ },
+ "rootEncryptionKeyIndex": {
+ "type": "integer",
+ "minimum": 0,
+ "position": 1
+ },
+ "derivationEncryptionKeyIndex": {
+ "type": "integer",
+ "minimum": 0,
+ "position": 2
+ },
+ "privateData": {
+ "type": "array",
+ "byteArray": true,
+ "minItems": 48,
+ "maxItems": 2048,
+ "position": 3,
+ "description": "This is the encrypted values of aliasName + note + displayHidden encoded as an array in cbor"
+ }
+ },
+ "required": [
+ "$createdAt",
+ "$updatedAt",
+ "encToUserId",
+ "privateData",
+ "rootEncryptionKeyIndex",
+ "derivationEncryptionKeyIndex"
+ ],
+ "additionalProperties": false
+ },
+ "contactRequest": {
+ "documentsMutable": false,
+ "canBeDeleted": false,
+ "requiresIdentityEncryptionBoundedKey": 2,
+ "requiresIdentityDecryptionBoundedKey": 2,
+ "type": "object",
+ "indices": [
+ {
+ "name": "ownerIdUserIdAndAccountRef",
+ "properties": [
+ {
+ "$ownerId": "asc"
+ },
+ {
+ "toUserId": "asc"
+ },
+ {
+ "accountReference": "asc"
+ }
+ ],
+ "unique": true
+ },
+ {
+ "name": "ownerIdUserId",
+ "properties": [
+ {
+ "$ownerId": "asc"
+ },
+ {
+ "toUserId": "asc"
+ }
+ ]
+ },
+ {
+ "name": "userIdCreatedAt",
+ "properties": [
+ {
+ "toUserId": "asc"
+ },
+ {
+ "$createdAt": "asc"
+ }
+ ]
+ },
+ {
+ "name": "ownerIdCreatedAt",
+ "properties": [
+ {
+ "$ownerId": "asc"
+ },
+ {
+ "$createdAt": "asc"
+ }
+ ]
+ }
+ ],
+ "properties": {
+ "toUserId": {
+ "type": "array",
+ "byteArray": true,
+ "minItems": 32,
+ "maxItems": 32,
+ "position": 0,
+ "contentMediaType": "application/x.dash.dpp.identifier"
+ },
+ "encryptedPublicKey": {
+ "type": "array",
+ "byteArray": true,
+ "minItems": 96,
+ "maxItems": 96,
+ "position": 1
+ },
+ "senderKeyIndex": {
+ "type": "integer",
+ "minimum": 0,
+ "position": 2
+ },
+ "recipientKeyIndex": {
+ "type": "integer",
+ "minimum": 0,
+ "position": 3
+ },
+ "accountReference": {
+ "type": "integer",
+ "minimum": 0,
+ "position": 4
+ },
+ "encryptedAccountLabel": {
+ "type": "array",
+ "byteArray": true,
+ "minItems": 48,
+ "maxItems": 80,
+ "position": 5
+ },
+ "autoAcceptProof": {
+ "type": "array",
+ "byteArray": true,
+ "minItems": 38,
+ "maxItems": 102,
+ "position": 6
+ }
+ },
+ "required": [
+ "$createdAt",
+ "$createdAtCoreBlockHeight",
+ "toUserId",
+ "encryptedPublicKey",
+ "senderKeyIndex",
+ "recipientKeyIndex",
+ "accountReference"
+ ],
+ "additionalProperties": false
+ }
+}
diff --git a/packages/dashpay-contract/src/lib.rs b/packages/dashpay-contract/src/lib.rs
index f17916867c2..3132e0acd50 100644
--- a/packages/dashpay-contract/src/lib.rs
+++ b/packages/dashpay-contract/src/lib.rs
@@ -1,5 +1,6 @@
mod error;
pub mod v1;
+pub mod v2;
pub use crate::error::Error;
use platform_value::{Identifier, IdentifierBytes32};
@@ -18,10 +19,10 @@ pub const OWNER_ID: Identifier = Identifier(IdentifierBytes32(OWNER_ID_BYTES));
pub fn load_definitions(platform_version: &PlatformVersion) -> Result