> ## Documentation Index
> Fetch the complete documentation index at: https://docs.getpara.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Sign Messages with Para

> Learn how to sign a "Hello, Para!" message using the Para SDK

export const LinkListCard = ({imgUrl, title, links = [], horizontal = false, newTab = false}) => {
  return <div className="not-prose relative my-2 p-[1px] rounded-xl bg-gray-200">
      <div className={`not-prose flex ${horizontal ? 'flex-row' : 'flex-col'} font-normal h-full bg-white overflow-hidden w-full rounded-[11px]`}>
        {imgUrl && <div className={`relative overflow-hidden flex-shrink-0 ${horizontal ? 'w-[30%] rounded-l-[11px]' : 'w-full'}`}>
            <img src={imgUrl} alt={title} className="w-full h-full object-cover pointer-events-none select-none" draggable="false" />
            <div className="absolute inset-0 pointer-events-none" />
          </div>}
        <div className={`flex-grow px-6 py-5 ${horizontal ? 'w-[70%]' : 'w-full'} flex flex-col ${horizontal && imgUrl ? 'justify-center' : 'justify-start'}`}>
          {title && <h2 className="font-semibold text-base text-gray-800 m-0 mb-3">{title}</h2>}
          {links.length > 0 && <div className="flex flex-col items-start space-y-3">
              {links.map((link, index) => <Link key={index} href={link.href} label={link.label} newTab={newTab} />)}
            </div>}
        </div>
      </div>
    </div>;
};

export const Link = ({href, label, newTab = false}) => {
  const [isHovered, setIsHovered] = useState(false);
  return <a href={href} target={newTab ? '_blank' : '_self'} rel={newTab ? 'noopener noreferrer' : undefined} className="not-prose inline-block relative text-black font-semibold cursor-pointer border-b-0 no-underline" onMouseEnter={() => setIsHovered(true)} onMouseLeave={() => setIsHovered(false)}>
      {label}
      <span className={`absolute left-0 bottom-0 w-full rounded-sm bg-gradient-to-r from-orange-600 to-purple-600 transition-all duration-300 ${isHovered ? 'h-0.5' : 'h-px'}`} />
    </a>;
};

export const MethodDocs = ({name, description, parameters = [], returns, deprecated = false, since = null, async = false, static: isStatic = false, tag = null, defaultExpanded = false, preventCollapse = false, id = 'method'}) => {
  const [isExpanded, setIsExpanded] = useState(defaultExpanded || preventCollapse);
  const [isHovered, setIsHovered] = useState(false);
  const [isCopied, setIsCopied] = useState(false);
  const [hoveredParam, setHoveredParam] = useState(null);
  const [hoveredReturn, setHoveredReturn] = useState(false);
  const parseMethodName = fullName => {
    const match = fullName.match(/^([^(]+)(\()([^)]*)(\))$/);
    if (match) {
      return {
        name: match[1],
        openParen: match[2],
        params: match[3],
        closeParen: match[4]
      };
    }
    return {
      name: fullName,
      openParen: '',
      params: '',
      closeParen: ''
    };
  };
  const methodParts = parseMethodName(name);
  const handleCopy = e => {
    e.stopPropagation();
    navigator.clipboard.writeText(name);
    setIsCopied(true);
    setTimeout(() => setIsCopied(false), 2000);
  };
  return <div className={`not-prose rounded-2xl border border-gray-200 overflow-hidden transition-colors duration-200 mb-6 ${isHovered && !preventCollapse ? 'bg-gray-50' : 'bg-white'}`} onMouseEnter={() => setIsHovered(true)} onMouseLeave={() => setIsHovered(false)}>
      <button onClick={() => !preventCollapse && setIsExpanded(!isExpanded)} className={`w-full bg-transparent p-6 border-none text-left ${preventCollapse ? 'cursor-default' : 'cursor-pointer'}`}>
        <div className="flex items-start justify-between gap-4">
          <div className="flex-1 flex flex-col gap-2">
            <div className="flex items-center gap-3 flex-wrap">
              <div className="flex items-center gap-2">
                {async && <span className="px-1.5 py-0.5 text-[0.625rem] font-medium bg-purple-200 text-purple-800 rounded-lg">
                    async
                  </span>}
                {isStatic && <span className="px-1.5 py-0.5 text-[0.625rem] font-medium bg-violet-200 text-violet-900 rounded-lg">
                    static
                  </span>}
                {tag && <span className="px-1.5 py-0.5 text-[0.625rem] font-medium bg-teal-200 text-teal-800 rounded-lg">
                    {tag}
                  </span>}
              </div>

              <code className="text-lg font-mono font-semibold text-gray-900">
                <span>{methodParts.name}</span>
                <span className="text-gray-500 font-normal">{methodParts.openParen}</span>
                <span className="text-blue-600 font-normal">{methodParts.params}</span>
                <span className="text-gray-500 font-normal">{methodParts.closeParen}</span>
              </code>

              {deprecated && <span className="px-1.5 py-0.5 text-[0.625rem] font-medium bg-red-100 text-red-800 rounded-lg flex items-center gap-0.5">
                  ⚠ Deprecated
                </span>}
              {since && <span className="px-1.5 py-0.5 text-[0.625rem] font-medium bg-blue-100 text-blue-800 rounded-lg">
                  Since v{since}
                </span>}
            </div>

            <p className="text-sm text-gray-600 leading-6 m-0">
              {description}
            </p>
          </div>

          <div className="flex items-center gap-2 flex-shrink-0">
            <button onClick={handleCopy} className="p-2 bg-transparent border-none rounded-md cursor-pointer transition-colors duration-200 text-gray-500 hover:bg-gray-100" title="Copy method signature">
              {isCopied ? <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#16a34a" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
                  <polyline points="20 6 9 17 4 12"></polyline>
                </svg> : <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
                  <rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect>
                  <path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path>
                </svg>}
            </button>

            {!preventCollapse && <span className="text-gray-400">
                {isExpanded ? <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
                    <polyline points="18 15 12 9 6 15"></polyline>
                  </svg> : <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
                    <polyline points="6 9 12 15 18 9"></polyline>
                  </svg>}
              </span>}
          </div>
        </div>
      </button>

      <div className={`overflow-hidden transition-all duration-300 ease-in-out px-6 border-t border-gray-200 ${isExpanded ? 'max-h-[2000px] opacity-100 pb-6' : 'max-h-0 opacity-0 pb-0'}`}>
        {parameters.length > 0 && <div className="pt-6">
            <div className="flex items-center gap-2 mb-3">
              <h3 className="text-sm font-semibold text-gray-700 uppercase tracking-wider m-0">
                Parameters
              </h3>
              <span className="text-xs text-gray-500">({parameters.length})</span>
            </div>
            <div>
              {parameters.map((param, index) => <div key={index} className={`pl-4 border-l-2 transition-colors duration-200 ${hoveredParam === index ? 'border-gray-300' : 'border-gray-200'} ${index < parameters.length - 1 ? 'mb-3' : ''}`} onMouseEnter={() => setHoveredParam(index)} onMouseLeave={() => setHoveredParam(null)}>
                  <div className="flex items-baseline gap-2 mb-1 flex-wrap">
                    <code className="font-mono text-sm font-medium text-gray-900">
                      {param.name}
                    </code>
                    <span className="text-sm text-gray-500">:</span>
                    {param.typeLink ? <a href={param.typeLink} className="no-underline">
                        <code className="font-mono text-sm text-blue-600 bg-transparent px-1 py-0.5 rounded-md cursor-pointer transition-all duration-200 hover:bg-gray-100 hover:text-blue-700">
                          {param.type}
                        </code>
                      </a> : <code className="font-mono text-sm text-blue-600 bg-transparent px-1 py-0.5 rounded-md">
                        {param.type}
                      </code>}
                    {param.required && <span className="px-1.5 py-0.5 text-[0.625rem] font-medium bg-yellow-100 text-yellow-800 rounded-lg">
                        Required
                      </span>}
                    {param.optional && <span className="px-1.5 py-0.5 text-[0.625rem] font-medium bg-gray-100 text-gray-600 rounded-lg">
                        Optional
                      </span>}
                  </div>
                  {param.description && <p className="text-sm text-gray-600 mt-1 mb-0">
                      {param.description}
                    </p>}
                  {param.defaultValue !== undefined && <p className="text-sm text-gray-500 mt-1">
                      Default: <code className="font-mono text-[0.625rem] bg-gray-100 px-1.5 py-0.5 rounded-lg">{param.defaultValue}</code>
                    </p>}
                </div>)}
            </div>
          </div>}

        {returns && <div className={`${parameters.length > 0 ? 'mt-6' : 'pt-6'}`}>
            <h3 className="text-sm font-semibold text-gray-700 uppercase tracking-wider m-0 mb-3">
              Returns
            </h3>
            <div className={`pl-4 border-l-2 transition-colors duration-200 ${hoveredReturn ? 'border-gray-300' : 'border-gray-200'}`} onMouseEnter={() => setHoveredReturn(true)} onMouseLeave={() => setHoveredReturn(false)}>
              <div className="flex items-baseline gap-2 mb-1">
                {returns.typeLink ? <a href={returns.typeLink} className="no-underline">
                    <code className="font-mono text-sm text-blue-600 bg-transparent px-1 py-0.5 rounded cursor-pointer transition-all duration-200 hover:bg-gray-100 hover:text-blue-700">
                      {returns.type}
                    </code>
                  </a> : <code className="font-mono text-sm text-blue-600 bg-transparent px-1 py-0.5 rounded">
                    {returns.type}
                  </code>}
              </div>
              {returns.description && <p className="text-sm text-gray-600 mt-1 mb-0">
                  {returns.description}
                </p>}
            </div>
          </div>}
      </div>
    </div>;
};

The `signMessage` method is a **low-level API** that signs raw bytes directly without any modifications. This is useful for verifying your Para integration with a simple "Hello, Para!" test after initial setup and authentication.

<Warning>
  **Important:** `signMessage` signs raw bytes without standard modifications like EIP-191 message prefixes that libraries like Ethers and Viem automatically add. For production use, always use proper Web3 libraries that handle message formatting, encoding standards, and chain-specific requirements.
</Warning>

<Note>
  **When to use signMessage:** This method is best suited for signing simple text messages and basic authentication flows. For complex operations like transactions, typed data (EIP-712), or chain-specific functionality, **you should use the appropriate Web3 library** (Viem, Ethers, Solana Web3.js, CosmJS). These libraries provide proper encoding, type safety, and chain-specific features that signMessage alone cannot offer.
</Note>

### Message Signing

This method signs the exact bytes you provide - perfect for initial "hello world" testing:

<MethodDocs
  defaultExpanded={true}
  preventCollapse={true}
  name="useSignMessage()"
  description="A mutation hook that signs a message using a specified wallet."
  parameters={[
{
  name: "walletId",
  type: "string",
  required: true,
  description: "The ID of the wallet to use for signing."
},
{
  name: "messageBase64",
  type: "string",
  required: true,
  description: "The message to sign as a base64-encoded string."
},
{
  name: "timeoutMs",
  type: "number",
  optional: true,
  description: "The duration in milliseconds to wait before the signing operation times out."
},
{
  name: "cosmosSignDocBase64",
  type: "string",
  optional: true,
  description: "For Cosmos transactions, the `SignDoc` as a base64-encoded string."
},
{
  name: "isCanceled",
  type: "() => boolean",
  optional: true,
  description: "A callback that returns a boolean, indicating whether the signing operation should be cancelled."
},
{
  name: "onPoll",
  type: "() => void",
  optional: true,
  description: "A callback function that will be invoked on each method poll."
},
{
  name: "onCancel",
  type: "() => void",
  optional: true,
  description: "A callback function that will be invoked if the method call is canceled."
}
]}
  returns={{ type: "{ signMessage: (params) => void, signMessageAsync: (params) => Promise<FullSignatureRes>, data: FullSignatureRes | undefined, isPending: boolean, error: Error | null, reset: () => void }", description: "A mutation result with `signMessage` / `signMessageAsync` functions, `data`, and standard React Query mutation fields." }}
  async={true}
/>

```tsx SignMessageExample.tsx theme={null}
import { useSignMessage, useWallet } from '@getpara/react-sdk';

export default function SignMessageExample() {
  const { mutateAsync: signMessageAsync } = useSignMessage();
  const { data: wallet } = useWallet();

  const handleSign = async () => {
    if (!wallet) return;

    const message = "Hello, Para!";
    // Encode message to base64
    const messageBase64 = btoa(message);

    const result = await signMessageAsync({
      walletId: wallet.id,
      messageBase64
    });

    console.log('Signature result:', result);
  };

  return (
    <button onClick={handleSign}>Sign Message</button>
  );
}
```

## Next Steps

Now that you've successfully verified your Para setup with a simple message signature, it's time to move on to more advanced operations. Depending on your target blockchain, you can explore the following libraries that integrate seamlessly with Para for signing transactions, typed data, and more:

<CardGroup cols={3}>
  <LinkListCard
    title="EVM Libraries"
    imgUrl="/images/v3/network-evm.png"
    links={[
  { label: "Viem", href: "/v3/react/guides/web3-operations/evm/setup-libraries#viem" },
  { label: "Ethers.js", href: "/v3/react/guides/web3-operations/evm/setup-libraries#ethers" },
  { label: "Wagmi", href: "/v3/react/guides/web3-operations/evm/setup-libraries#wagmi" }
]}
  />

  <LinkListCard
    title="Solana Libraries"
    imgUrl="/images/v3/network-solana.png"
    links={[
  { label: "Solana Web3.js", href: "/v3/react/guides/web3-operations/solana/setup-libraries#solana-web3" },
  { label: "Solana Kit", href: "/v3/react/guides/web3-operations/solana/setup-libraries#solana-kit" },
  { label: "Anchor Framework", href: "/v3/react/guides/web3-operations/solana/setup-libraries#anchor-framework" }
]}
  />

  <LinkListCard
    title="Cosmos Libraries"
    imgUrl="/images/v3/network-cosmos.png"
    links={[
  { label: "CosmJS", href: "/v3/react/guides/web3-operations/cosmos/setup-libraries#cosmjs" }
]}
  />

  <LinkListCard
    title="Stellar Libraries"
    links={[
  { label: "Stellar SDK", href: "/v3/react/guides/web3-operations/stellar/setup-libraries" }
]}
  />
</CardGroup>
