Skip to main content

3. User Message Configuration

Introduction to User Message Configuration

The User Message Configuration is a critical component of integrating the SurferMonkey SDK, as it defines the parameters for blockchain transactions. This configuration ensures that each transaction is conducted in a secure, compliant, and privacy-preserving manner, while also providing flexibility for different types of interactions (e.g., single input/output, multi-call transactions, etc.).

The purpose of this section is to guide developers in configuring the user message properly to ensure successful transaction execution through the SurferMonkey protocol.

Key Parameters in User Message

The User Message includes several key parameters that must be defined to configure the intended transaction:

  • userEOA (Externally Owned Address) [String Hex EVM Address]: The address of the signer who initiates the transaction. This address must be a valid EVM address, and it must be registered with your institution.

  • inputTx (Input Transaction Object) [Object]: The input transaction object defines what assets are being locked and transferred within the SurferMonkey Universal Plugin. It contains fields such as:
    • AMOUNT_TOTAL [String uint256]: Total amount of the asset being locked
    • ASSET_ID [String Hex EVM address]: The address of the asset, the ERC20 address.
info

For Native Asset the field ASSET_ID is address(0) = 0x0000000000000000000000000000000000000000000000000000000000000000


  • outputTxArr (Output Transactions Array) [Array of Objects]: This array specifies how the locked assets will be distributed in the output. Each item in the array can contain:
    • amountOutput [String uint256]: The amount of the asset to be transferred in that particular output transaction.
    • smartContractCalls [Array of Objects]: Each output can define multiple smart contract calls (multi-call) that will be executed.
      • payloadAmountNative [String uint256]: The amount of native asset used in the call.
      • targetSC [String Hex EVM address]: The target smart contract address for the transaction to be called.
      • payloadObject [Object]:
        • functionHeader [String]: The function header for the smart contract call.
        • functionName [String]: The name of the function being called.
        • payloadParmsArr [Array of Strings]: An array of parameters to pass to the function.
info

For ERC20 transactions, payloadAmountNative is an array of [0, 0, 0, ...]. It is ignored but must be included, so do not remove it.


  • numberTxOut (Number of Output Transactions) [Number]: Indicates how many outputs are expected in the transaction. This should match the length of the outputTxArr.

  • pubKey (Institution Public Key) [Array of Strings]: The institution’s elliptic encryption public key, which is required for correct privacy-preserving in the SurferMonkey protocol.

  • chainID (Blockchain Identifier) [Number]: The identifier of the blockchain network on which the transaction will occur. This helps ensure compatibility with the correct network settings.

  • userMerkleProof (User Institution Membership Proof) [Object]:

    • The userMerkleProof is a cryptographic proof that demonstrates the user's membership in the institution's whitelist. The institution backend generates this proof using the getInstitutionMembershipProof function.
    • Only the resulting userMerkleProof object needs to be included in the userMessage—not the entire list of addresses (institutionLeaves).
info

Key Aspect: Only the userMerkleProof object is included in the userMessage, ensuring privacy by avoiding the inclusion of the entire institutionLeaves list. The institution backend shall call getInstitutionMembershipProof and provide the result to the client's device.

const userMerkleProof = await SurferMonkey.getInstitutionMembershipProof({
BACKEND_RPC,
userEOA: EOA_Address,
institutionLeaves
});

Example User Message Object

warning
  • userEOA must be included in the updated Merkle Root to verify the user as authorized.
  • The outputTxArr length must match numberTxOut to ensure consistency between defined outputs and expected outputs.
  • AMOUNT_TOTAL must equal the sum of all amountOutput values in outputTxArr.
  • Each amountOutput must match the total value used in the smartContractCalls payload array.
  • For Native Assets, each amountOutput must match the sum of payloadAmountNative values for all smart contract calls in the respective smartContractCalls array.

Here’s an example of how to structure a user message for SurferMonkey integration. In this example, we have a Native Asset input transaction that creates one output transaction, and the output transaction makes one single smart contract call:

info

For Native Transfers, specify the targetSC as the SurferMonkey Proxy Smart Contract address. And use the following function details:

  • Function Header: "function transferEth(address targetAddress, uint256 amount)"
  • Function Name: "transferEth"
const userMerkleProof = await SurferMonkey.getInstitutionMembershipProof({
BACKEND_RPC,
userEOA: "0xYourEvmAddressHere",
institutionLeaves: ["0xValidUserAddress1", "0xValidUserAddress2", "0xYourEvmAddressHere"]
});

const userMessage = {
userEOA: "0xYourEvmAddressHere",
inputTx: {
AMOUNT_TOTAL: "10000000000000",
ASSET_ID: "0x0000000000000000000000000000000000000000"
},
outputTxArr: [
{
amountOutput: "10000000000000",
smartContractCalls: [
{
payloadAmountNative: "10000000000000",
targetSC: "0xSurferMonkeyProxy", // For Native asset transfers
payloadObject: { // Proxy transfer function header
functionHeader: "function transferEth(address targetAddress, uint256 amount)",
functionName: "transferEth",
payloadParmsArr: ["0xRecipientAddress", "10000000000000"]
}
}
]
}
],
numberTxOut: 1,
pubKey: ["PubKeyString[0]", "PubKeyString[1]"],
chainID: "ChainIdentifier",
userMerkleProof: userMerkleProof
};