Transaction Signature Schemes

Introduction

This document provides an overview of the signature schemes used in FinP2P. Currently, two signature formats are supported:

  1. Hashlist
  2. EIP712

Financial Transactions orchestrated by FinP2P carries a corresponding signature, representing the business terms and signed by the investors, the signature format used for the different operations, is detailed below.

Generating a Signature

  1. Constructing the Values:
    Gather the necessary values based on the given signature template. These values typically include essential transaction or message details that need to be signed.

  2. Hashing:
    Given the signature format, structure and generate a hash using a cryptographic hashing algorithm, such as SHA-256 or Keccak-256. This hash represents a fixed-size, unique fingerprint of the original data.

  3. Signing the Hash:
    Use the investor FinP2P FinID, private secp256k1 key ,to sign the hash. This cryptographic signature ensures that the hash (and thus the original data) has not been tampered with and verifies the identity of the signer.


Signature Formats

Shared Fields

Nonce is a field that appears in each of the signature templates. The nonce value assigned by the operation requester.
The value of the nonce is a 32 bytes buffer, where first 24 bytes are assigned with a randomly generated value by the client and the last 8 bytes are assigned with the current epoch timestamp (in seconds).

Code Sample:

const nonce = Buffer.alloc(32);
nonce.fill(crypto.randomBytes(24), 0, 24);
const nowEpochSeconds = Math.floor(new Date().getTime() / 1000);
const t = BigInt(nowEpochSeconds);
nonce.writeBigInt64BE(t, 24);

1. Hashlist

Overview

The Hashlist signature format involves creating an array of hashes, where each hash represents a group of values. This structure is commonly used for operations involving multiple data points that need to be signed together. The benefit of this format is that during validation, one can construct only the necessary hash group from the original values while taking the other groups as is. This is somewhat analogous to a simplified Merkle tree, allowing for more efficient validation processes.

Operations and Templates

Operation 1: Deposit
  • Description:

The signature template for the deposit request contains the deposit details.

  • Template:
OrderValueTypeComment
1noncestringExplanation provided above.
2operationstring"deposit"
3assetTypestring"fiat", "cryptocurrency", "finp2p", "custom"
4assetIdstringUnique identifier of the asset (blank for "custom")
5dstAccountTypestring"finId"
6dstAccountstringAccount to deposit the asset to
7amountstringAmount to deposit
DHG = hash('SHA3-256', [fields by order]);
hashList = hash('SHA3-256', [DHG]);
Signature = sign(sender private secp256k1 key, hashList)
Operation 2: Primary Sale
  • Description:

The signature format for an issuance in a primary sale with Delivery vs Payment involves two main components: the Asset Hash Group (AHG) and the Settlement Hash Group (SHG). Each group is hashed individually, and the resulting hashes are then combined and hashed together.

  • Template:
Asset Hash Group (AHG) Structure

Represents the asset instructions.

OrderValueTypeComment
1nonce[]byteExplanation provided above.
2operationstring"issue"
3assetTypestring"finp2p"
4assetIdstringUnique identifier of the asset
5dstAccountTypestring"finId"
6dstAccountstringInvestor account finId address that will receive the tokens
7amountstringAsset amount
Settlement Hash Group (SHG) Structure

Represents the payment/settlement instructions.

OrderValueTypeComment
1assetTypestring"finp2p", "fiat", "cryptocurrency"
2assetIdstringUnique identifier of the asset
3srcAccountTypestring"finId"
4srcAccountstringInvestor account finId address for the payment asset
5dstAccountTypestring"finId"
6dstAccountstringIssuer account finId address for the payment asset
7amountstringSettlement amount
//Asset Hash Group (AHG) structure:
AHG = hash('SHA3-256', [fields by order]);

//Settlement Hash Group (SHG) structure:
SHG = hash('SHA3-256', [fields by order]);

hashList = hash('SHA3-256', [AHG, SHG]);
Signature = sign(sender private secp256k1 key, hashList)
Operation 3: Secondary Sale
  • Description:

The signature format for the Delivery vs Payment involved in the secondary sale (executing a buying or selling intent) with settlement operation involves two main components: the Asset Hash Group (AHG) and the Settlement Hash Group (SHG). Each group should be hashed individually, and then both should be hashed together.

  • Template:
Asset Hash Group (AHG) Structure

Represents the asset instructions.

OrderValueTypeComment
1nonce[]byteExplanation provided abo
2operationstring"transfer"
3assetTypestring"finp2p"
4assetIdstringUnique identifier of the asset
5srcAccountTypestring"finId"
6srcAccountstringSeller account finId address that will has the tokens
7dstAccountTypestring"finId"
8dstAccountstringBuyer account finId address that will receive the tokens
9amountstringAsset amount
Settlement Hash Group (SHG) Structure

Represents the payment/settlement instructions.

OrderValueTypeComment
1assetTypestring"finp2p", "fiat", "cryptocurrency"
2assetIdstringUnique identifier of the asset
3srcAccountTypestring"finId"
4srcAccountstringBuyer account findId address for the payment asset
5dstAccountTypestring"finId"
6dstAccountstringSeller account findId address for the payment asset
7amountstringSettlement amount
//Asset Hash Group (AHG) structure:
AHG = hash('SHA3-256', [fields by order]);

//Settlement Hash Group (SHG) structure:
SHG = hash('SHA3-256', [fields by order]);

hashList = hash('SHA3-256', [AHG, SHG]);
Signature = sign(sender private secp256k1 key, hashList)
Operation 4: Loan
  • Description:

The signature format for the loan involved in the execution of a loan with includes both the pledged asset and money side of the transaction.

  • Template:
OrderValueTypeComment
1nonce[]byteExplanation provided above.
2operationstring"loan"
3pledgeAssetTypestring"finp2p"
4pledgeAssetIdstringUnique identifier of the asset
5pledgeBorrowerAccountTypestring"finId"
6pledgeBorrowerAccountIdstringBorrower account
7pledgeLenderAccountTypestring"finId"
8pledgeLenderAccountIdstringLender account
9pledgeAmountstringPledged asset amount
10moneyAssetTypestring"fiat"
11moneyAssetIdstringUnique identified of the asset
12moneyLenderAccountTypestring"finId"
13moneyLenderAccountIdstringLender account
14moneyBorrowerAccountTypestring"finId"
15moneyBorrowerAccountIdstringBorrower account
16borrowedMoneyAmountstringLender settlement amount
17returnedMoneyAmountstringReturned money at maturity, which includes applicable interest
18openTimestringSettlement time for Loan, EPOCH in seconds
19closeTimestringMaturity time for Loan, EPOCH in seconds
HG = hash('SHA3-256', [fields by order]);
hashList = hash('SHA3-256', [HG]);
Signature = sign(sender private secp256k1 key, hashList)
Operation 5: Redeem
  • Description:

The signature format for a redeem operation with settlement involves two main components: the Asset Hash Group (AHG) and the Settlement Hash Group (SHG). Each group should be hashed individually, and then both should be hashed together.

  • Template:
Asset Hash Group (AHG) Structure

Represents the asset instructions.

OrderValueTypeComment
1nonce[]byteExplanation provided above.
2operationstring"redeem"
3assetTypestring"finp2p"
4assetIdstringUnique identifier of the asset
5srcAccountTypestring"finId"
6srcAccountstringInvestor account finId address
7amountstringAsset amount
Settlement Hash Group (SHG) Structure

Represents the payment/settlement instructions.

OrderValueTypeComment
1assetTypestring"finp2p", "fiat", "cryptocurrency"
2assetIdstringUnique identifier of the asset
3srcAccountTypestring"finId"
4srcAccountstringIssuer account findId address for the payment
5dstAccountTypestring"finId"
6dstAccountstringInvestor account finId address that will receive the funds
7amountstringSettlement amount
//Asset Hash Group (AHG) structure:
AHG = hash('SHA3-256', [fields by order]);

//Settlement Hash Group (SHG) structure:
SHG = hash('SHA3-256', [fields by order]);

hashList = hash('SHA3-256', [AHG, SHG]);
Signature = sign(sender private secp256k1 key, hashList)
Operation 1: Withdraw
  • Description:

The signature template for the Withdraw request contains the Withdraw details.

OrderValueTypeComment
1noncestringExplanation provided above.
2operationstring"withdraw"
3assetTypestring"fiat", "cryptocurrency", "finp2p", "custom"
4assetIdstringUnique identifier of the asset (blank for "custom")
5srcAccountTypestring"finId"
6srcAccountstringSource account to withdraw funds from
5dstAccountTypestring"finId"
6dstAccountstringAccount to deposit the asset to
7amountstringstring representation of the amount
HG = hash('SHA3-256', [fields by order]);
hashList = hash('SHA3-256', [HG]);
Signature = sign(sender private secp256k1 key, hashList)

2. EIP712

Overview

The EIP712 signature format leverages the widely adopted EIP712 standard for creating structured, off-chain signatures. This format is designed to securely sign typed data, ensuring that the data structure is clear and unambiguous. It is commonly used in operations requiring multiple data points to be signed in a standardized and interoperable manner. Furthermore, the EIP712 format is understood and supported by various key management systems, making it a versatile choice for secure digital signatures.

Operations and Templates

Template Domain Header

Field NameField TypeValueDescription
namestringFinP2PThe name of the domain.
versionstring1The version of the domain.
chainIduint2561The ID of the blockchain network (e.g., 1 for Ethereum mainnet).
verifyingContractaddress0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccCThe address of the verifying contract. (Not used for FinP2P, as contracts on multiple ledgers may be involved.)
Operation 1: Deposit

The signature template for the deposit request contains the deposit details.

Type Definitions

primaryType: Deposit

Type NameField NameField TypeDescription
FinIdidkeystringThe unique identifier key for the FinP2P account.
TermassetIdstringThe unique identifier of the asset.
TermassetTypestringThe type of the asset (e.g., "fiat", "cryptocurrency").
TermamountstringThe amount of the asset involved in the transaction.
DepositnoncestringA unique identifier for the deposit request.
DepositdstAccountFinIdThe destination account, represented by the FinId type.
DepositdstAccountTypestringThe type of the destination account, typically specified as a string (e.g., "finId").
DepositassetTermThe asset details, represented by the Term type.
Message
OrderValueTypeComment
1noncestringA unique identifier for the deposit request.
2dstAccountFinIdThe destination account, represented by the FinId type.
3dstAccountTypestringThe type of the destination account (e.g., "finId").
4AssetAsset details, represented by the Term type.
4a---> assetIdstringUnique identifier of the asset.
4b---> assetTypestringType of the asset (e.g., "fiat").
4c---> amountstringAmount of the asset involved in the transaction.

JSON Sample:

{
  "primaryType": "Deposit",
  "domain": {
    "name": "FinP2P",
    "version": "1",
    "chainId": 1,
    "verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC"
  },
  "types": {
    "EIP712Domain": [
      {"name": "name", "type": "string"},
      {"name": "version", "type": "string"},
      {"name": "chainId", "type": "uint256"},
      {"name": "verifyingContract", "type": "address"}
    ],
    "FinId": [
      {"name": "idkey", "type": "string"}
    ],
    "Term": [
      {"name": "assetId", "type": "string"},
      {"name": "assetType", "type": "string"},
      {"name": "amount", "type": "string"}
    ],
    "Deposit": [
      {"name": "nonce", "type": "string"},
      {"name": "dstAccount", "type": "FinId"},
      {"name": "dstAccountType", "type": "string"},
      {"name": "asset", "type": "Term"}
    ]
  },
  "message": {
    "nonce": "0x1234567890abcdef",
    "dstAccount": {"idkey": "finId123"},
    "dstAccountType": "finId",
    "asset": {
      "assetId": "asset123",
      "assetType": "fiat",
      "amount": "1000"
    }
  }
}
Operation 2: Primary Sale

The signature format for the issuance involved in the primary sale, including both the asset and settlement instructions.

Type Definitions

primaryType: PrimarySale

Type NameField NameField TypeDescription
FinIdidkeystringUnique identifier key for the FinP2P account.
TermassetIdstringUnique identifier of the asset.
TermassetTypestringType of the asset (e.g., "fiat", "cryptocurrency").
TermamountstringAmount of the asset involved in the transaction.
PrimarySalenoncestringUnique identifier for the primary sale request.
PrimarySalebuyerFinIdBuyer information represented by the FinId type.
PrimarySaleissuerFinIdIssuer information represented by the FinId type.
PrimarySaleassetTermAsset details represented by the Term type.
PrimarySalesettlementTermSettlement details represented by the Term type.
Message:
OrderValueTypeComment
1noncestringA unique identifier for the primary sale request.
2BuyerFinIdThe finId of the investor (buyer) participating in the issuance.
3IssuerFinIdThe finId of the issuer of the asset sold in primary sale.
4AssetAsset details, represented by the Term type.
4a---> assetIdstringUnique identifier of the asset.
4b---> assetTypestringType of the asset (e.g., "finp2p").
4c---> amountstringAmount of tokens being issued.
5SettlementSettlement details, represented by the Term type.
5a---> assetIdstringUnique identifier of the settlement asset.
5b---> assetTypestringType of the settlement asset (e.g., "fiat").
5c---> amountstringUnit value for each token.
{
  "primaryType": "PrimarySale",
  "domain": {
    "name": "FinP2P",
    "version": "1",
    "chainId": 1,
    "verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC"
  },
  "types": {
    "EIP712Domain": [
      {"name": "name", "type": "string"},
      {"name": "version", "type": "string"},
      {"name": "chainId", "type": "uint256"},
      {"name": "verifyingContract", "type": "address"}
    ],
    "FinId": [
      {"name": "idkey", "type": "string"}
    ],
    "Term": [
      {"name": "assetId", "type": "string"},
      {"name": "assetType", "type": "string"},
      {"name": "amount", "type": "string"}
    ],
    "PrimarySale": [
      {"name": "nonce", "type": "string"},
      {"name": "buyer", "type": "FinId"},
      {"name": "issuer", "type": "FinId"},
      {"name": "asset", "type": "Term"},
      {"name": "settlement", "type": "Term"}
    ]
  },
  "message": {
    "nonce": "0xabcdef1234567890",
    "buyer": {"idkey": "buyerFinId"},
    "issuer": {"idkey": "issuerFinId"},
    "asset": {
      "assetId": "asset456",
      "assetType": "finp2p",
      "amount": "2000"
    },
    "settlement": {
      "assetId": "settleAsset456",
      "assetType": "fiat",
      "amount": "2000"
    }
  }
}

Operation 3: Secondary

The signature format for the trade involved in a secondary sale, including both the asset and settlement instructions.

Type Definitions
  • Primary Type: Buying
Type NameField NameField TypeDescription
FinIdidkeystringUnique identifier key for the FinP2P account.
TermassetIdstringUnique identifier of the asset.
TermassetTypestringType of the asset (e.g., "fiat", "cryptocurrency").
TermamountstringAmount of the asset involved in the transaction.
BuyingnoncestringUnique identifier for the buying request.
BuyingbuyerFinIdBuyer information represented by the FinId type.
BuyingsellerFinIdSeller information represented by the FinId type.
BuyingassetTermAsset details represented by the Term type.
BuyingsettlementTermSettlement details represented by the Term type.

Message:

OrderValueTypeComment
1noncestringA unique identifier for the buying request.
2BuyerFinIdThe finId of the buyer of the asset.
3SellerFinIdThe finId of the seller of the asset.
4AssetAsset details, represented by the Term type.
4a---> assetIdstringUnique identifier of the asset.
4b---> assetTypestringType of the asset (e.g., "finp2p").
4c---> amountstringAmount of tokens being issued.
5SettlementSettlement details, represented by the Term type.
5a---> assetIdstringUnique identifier of the settlement asset.
5b---> assetTypestringType of the settlement asset (e.g., "fiat").
5c---> amountstringUnit value for each token.

Sample JSON:

{
  "primaryType": "Buying",
  "domain": {
    "name": "FinP2P",
    "version": "1",
    "chainId": 1,
    "verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC"
  },
  "types": {
    "EIP712Domain": [
      {"name": "name", "type": "string"},
      {"name": "version", "type": "string"},
      {"name": "chainId", "type": "uint256"},
      {"name": "verifyingContract", "type": "address"}
    ],
    "FinId": [
      {"name": "idkey", "type": "string"}
    ],
    "Term": [
      {"name": "assetId", "type": "string"},
      {"name": "assetType", "type": "string"},
      {"name": "amount", "type": "string"}
    ],
    "Buying": [
      {"name": "nonce", "type": "string"},
      {"name": "buyer", "type": "FinId"},
      {"name": "seller", "type": "FinId"},
      {"name": "asset", "type": "Term"},
      {"name": "settlement", "type": "Term"}
    ]
  },
  "message": {
    "nonce": "0x123abc456def7890",
    "buyer": {"idkey": "buyerFinId456"},
    "seller": {"idkey": "sellerFinId456"},
    "asset": {
      "assetId": "asset789",
      "assetType": "finp2p",
      "amount": "3000"
    },
    "settlement": {
      "assetId": "settleAsset789",
      "assetType": "fiat",
      "amount": "3000"
    }
  }
}
  • Primary Type: Selling
Type NameField NameField TypeDescription
FinIdidkeystringUnique identifier key for the FinP2P account.
TermassetIdstringUnique identifier of the asset.
TermassetTypestringType of the asset (e.g., "fiat", "cryptocurrency").
TermamountstringAmount of the asset involved in the transaction.
SellingnoncestringUnique identifier for the selling request.
SellingbuyerFinIdBuyer information represented by the FinId type.
SellingsellerFinIdSeller information represented by the FinId type.
SellingassetTermAsset details represented by the Term type.
SellingsettlementTermSettlement details represented by the Term type.

Message:

OrderValueTypeComment
1noncestringA unique identifier for the selling request.
2BuyerFinIdThe finId of the buyer of the asset.
3SellerFinIdThe finId of the seller of the asset.
4AssetAsset details, represented by the Term type.
4a---> assetIdstringUnique identifier of the asset.
4b---> assetTypestringType of the asset (e.g., "finp2p").
4c---> amountstringAmount of tokens being issued.
5SettlementSettlement details, represented by the Term type.
5a---> assetIdstringUnique identifier of the settlement asset.
5b---> assetTypestringType of the settlement asset (e.g., "fiat").
5c---> amountstringUnit value for each token.

Sample JSON:

{
  "primaryType": "Selling",
  "domain": {
    "name": "FinP2P",
    "version": "1",
    "chainId": 1,
    "verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC"
  },
  "types": {
    "EIP712Domain": [
      {"name": "name", "type": "string"},
      {"name": "version", "type": "string"},
      {"name": "chainId", "type": "uint256"},
      {"name": "verifyingContract", "type": "address"}
    ],
    "FinId": [
      {"name": "idkey", "type": "string"}
    ],
    "Term": [
      {"name": "assetId", "type": "string"},
      {"name": "assetType", "type": "string"},
      {"name": "amount", "type": "string"}
    ],
    "Selling": [
      {"name": "nonce", "type": "string"},
      {"name": "buyer", "type": "FinId"},
      {"name": "seller", "type": "FinId"},
      {"name": "asset", "type": "Term"},
      {"name": "settlement", "type": "Term"}
    ]
  },
  "message": {
    "nonce": "0xabcdef9876543210",
    "buyer": {"idkey": "buyerFinId987"},
    "seller": {"idkey": "sellerFinId987"},
    "asset": {
      "assetId": "asset321",
      "assetType": "finp2p",
      "amount": "1500"
    },
    "settlement": {
      "assetId": "settleAsset321",
      "assetType": "fiat",
      "amount": "1500"
    }
  }
}

Operation 4: Redemption

The signature format for a redemption operation, including both the asset and settlement instructions.

Type Definitions
  • Primary Type: Redemption
Type NameField NameField TypeDescription
FinIdidkeystringUnique identifier key for the FinP2P account.
TermassetIdstringUnique identifier of the asset.
TermassetTypestringType of the asset (e.g., "fiat", "cryptocurrency").
RedemptionnoncestringUnique identifier for the redemption request.
RedemptionsellerFinIdSeller information represented by the FinId type.
RedemptionissuerFinIdIssuer information represented by the FinId type.
RedemptionassetTermAsset details represented by the Term type.
RedemptionsettlementTermSettlement details represented by the Term type.
Message
OrderValueTypeComment
1noncestringA unique identifier for the redemption request.
2SellerFinIdSeller information represented by the FinId type.
3IssuerFinIdIssuer information represented by the FinId type.
4AssetAsset details, represented by the Term type.
4a---> assetIdstringUnique identifier of the asset.
4b---> assetTypestringType of the asset (e.g., "finp2p").
4c---> amountstringAmount of tokens being redeemed.
5SettlementSettlement details, represented by the Term type.
5a---> assetIdstringUnique identifier of the settlement asset.
5b---> assetTypestringType of the settlement asset (e.g., "fiat").
5c---> amountstringUnit value for each token.

Sample JSON:

{
  "primaryType": "Redemption",
  "domain": {
    "name": "FinP2P",
    "version": "1",
    "chainId": 1,
    "verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC"
  },
  "types": {
    "EIP712Domain": [
      {"name": "name", "type": "string"},
      {"name": "version", "type": "string"},
      {"name": "chainId", "type": "uint256"},
      {"name": "verifyingContract", "type": "address"}
    ],
    "FinId": [
      {"name": "idkey", "type": "string"}
    ],
    "Term": [
      {"name": "assetId", "type": "string"},
      {"name": "assetType", "type": "string"},
      {"name": "amount", "type": "string"}
    ],
    "Redemption": [
      {"name": "nonce", "type": "string"},
      {"name": "seller", "type": "FinId"},
      {"name": "issuer", "type": "FinId"},
      {"name": "asset", "type": "Term"},
      {"name": "settlement", "type": "Term"}
    ]
  },
  "message": {
    "nonce": "0xabcdef1234567890",
    "seller": {"idkey": "sellerFinId123"},
    "issuer": {"idkey": "issuerFinId123"},
    "asset": {
      "assetId": "asset456",
      "assetType": "finp2p",
      "amount": "2000"
    },
    "settlement": {
      "assetId": "settleAsset456",
      "assetType": "fiat",
      "amount": "2000"
    }
  }
}
Operation 4: Loan

The signature format for a loan operation, including both the asset and settlement instructions.

Type Definitions
  • Primary Type: Loan
Type NameField NameField TypeDescription
FinIdidkeystringUnique identifier key for the FinP2P account.
TermassetIdstringUnique identifier of the asset.
TermassetTypestringType of the asset (e.g., "fiat", "cryptocurrency").
TermamountstringAmount of the asset involved in the transaction.
LoannoncestringUnique identifier for the loan request.
LoanborrowerFinIdBorrower information represented by the FinId type.
LoanlenderFinIdLender information represented by the FinId type.
LoanassetTermAsset details represented by the Term type.
LoansettlementTermSettlement details represented by the Term type.
LoanloanTermsLoanTermsLoan terms represented by the LoanTerms type.
LoanTermsopenTimestringOpening time of the loan.
LoanTermscloseTimestringClosing time of the loan.
LoanTermsborrowedMoneyAmountstringAmount of money borrowed in the loan.
LoanTermsreturnedMoneyAmountstringAmount of money to be returned at the loan’s maturity.
Message
OrderValueTypeComment
1noncestringA unique identifier for the loan request.
2BorrowerFinIdBorrower information represented by the FinId type.
3LenderFinIdLender information represented by the FinId type.
4AssetAsset details represented by the Term type.
4a---> assetIdstringUnique identifier of the asset.
4b---> assetTypestringType of the asset (e.g., "finp2p").
4c---> amountstringAmount of tokens being issued.
5SettlementSettlement details represented by the Term type.
5a---> assetIdstringUnique identifier of the settlement asset.
5b---> assetTypestringType of the settlement asset (e.g., "fiat").
5c---> amountstringUnit value for each token.
6LoanTermsLoan terms represented by the LoanTerms type.
6a---> openTimestringOpening time of the loan.
6b---> closeTimestringClosing time of the loan.
6c---> borrowedMoneyAmountstringAmount of money borrowed in the loan.
6d---> returnedMoneyAmountstringAmount of money to be returned at the loan’s maturity.

Sample JSON:

{
  "primaryType": "Loan",
  "domain": {
    "name": "FinP2P",
    "version": "1",
    "chainId": 1,
    "verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC"
  },
  "types": {
    "EIP712Domain": [
      {"name": "name", "type": "string"},
      {"name": "version", "type": "string"},
      {"name": "chainId", "type": "uint256"},
      {"name": "verifyingContract", "type": "address"}
    ],
    "FinId": [
      {"name": "idkey", "type": "string"}
    ],
    "Term": [
      {"name": "assetId", "type": "string"},
      {"name": "assetType", "type": "string"},
      {"name": "amount", "type": "string"}
    ],
    "LoanTerms": [
      {"name": "openTime", "type": "string"},
      {"name": "closeTime", "type": "string"},
      {"name": "borrowedMoneyAmount", "type": "string"},
      {"name": "returnedMoneyAmount", "type": "string"}
    ],
    "Loan": [
      {"name": "nonce", "type": "string"},
      {"name": "borrower", "type": "FinId"},
      {"name": "lender", "type": "FinId"},
      {"name": "asset", "type": "Term"},
      {"name": "settlement", "type": "Term"},
      {"name": "loanTerms", "type": "LoanTerms"}
    ]
  },
  "message": {
    "nonce": "0x1234567890abcdef",
    "borrower": {"idkey": "borrowerFinId"},
    "lender": {"idkey": "lenderFinId"},
    "asset": {
      "assetId": "asset123",
      "assetType": "finp2p",
      "amount": "10000"
    },
    "settlement": {
      "assetId": "settleAsset123",
      "assetType": "fiat",
      "amount": "10000"
    },
    "loanTerms": {
      "openTime": "1609459200",
      "closeTime": "1640995200",
      "borrowedMoneyAmount": "10000",
      "returnedMoneyAmount": "11000"
    }
  }
}