Sequence Wallets admiten la verificación de firmas estándar de contratos ERC-1271 para permitir la firma de transacciones y mensajes.

ERC-191 Ethereum Signed Data

Los mensajes codificados como ERC-191 Ethereum Signed Data pueden ser creados y firmados de la siguiente manera.

import { Wallet } from '@0xsequence/wallet'

// Construct your Sequence Wallet (out of scope for this section)
const wallet: Wallet

const message = "Hello, World!"

const prefixedMessage = "\x19Ethereum Signed Message:\n" + len(message) + message
const signature = await wallet.signMessage(prefixedMessage)

Lo anterior iterará localmente, firmando el mensaje. Si se alcanza el umbral, se devuelve la firma. De lo contrario, la librería también iterará a través de los firmantes remotos. Las firmas resultantes se unen y codifican como una cadena hexadecimal.

Firmas de datos estructurados ERC-712

ERC-712 Structured Data también puede firmarse de manera similar.

import { Wallet } from '@0xsequence/wallet'
import { encodeTypedDataDigest } from '@0xsequence/utils'

// Construct your Sequence Wallet (out of scope for this section)
const wallet: Wallet

// Encode the typed data
const chainId = 1
const typedData = {
	types: {
		Person: [
			{ name: 'name', type: 'string' },
			{ name: 'wallet', type: 'address' },
			{ name: 'count', type: 'uint8' }
		]
	},
	primaryType: 'Person' as const,
	domain: {
		name: 'Ether Mail',
		version: '1',
		chainId: chainId,
		verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC'
	},
	message: {
		name: 'Bob',
		wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB',
		count: 4
	}
} 
const hashedData = encodeTypedDataDigest(typedData)

const signature = await wallet.signMessage(hashedData)

Lo anterior iterará localmente, firmando el mensaje. Si se alcanza el umbral, se devuelve la firma. De lo contrario, la librería también iterará a través de los firmantes remotos. Las firmas resultantes se unen y codifican como una cadena hexadecimal.

Verificación

La firma puede verificarse llamando al método isValidSignature en el wallet.

/**
   * @notice Verifies whether the provided signature is valid with respect to the provided hash
   * @dev MUST return the correct magic value if the signature provided is valid for the provided hash
   *   > The bytes4 magic value to return when signature is valid is 0x1626ba7e : bytes4(keccak256("isValidSignature(bytes32,bytes)"))
   * @param _hash       keccak256 hash that was signed
   * @param _signatures Signature byte array associated with _data.
   *                    Encoded as abi.encode(Signature[], Configs)
   * @return magicValue Magic value 0x1626ba7e if the signature is valid and 0x0 otherwise
   */
  function isValidSignature(
    bytes32 _hash,
    bytes calldata _signatures
  ) public override virtual view returns (bytes4) {
    // Validate signatures
    (bool isValid,) = _signatureValidation(_hash, _signatures);
    if (isValid) {
      return SELECTOR_ERC1271_BYTES32_BYTES;
    }

    return bytes4(0);
  }

Esto iterará a través de las firmas combinadas y validará que la firma resultante supere el umbral del wallet.