# Verifying signatures and cosigners

A good example can be found in this repo: [off-chain signatures](https://github.com/argentlabs/starknet-off-chain-signature)

## Signing

All the different Starknet libs give you the ability to sign messages from an account. Let's take [starknet.js](https://starknetjs.com/docs/guides/signature) or [starknet-react](https://www.starknet-react.com/docs/hooks/use-sign-typed-data) for example.&#x20;

Most of the time, you will try to make your users sign a [SNIP-12](https://github.com/starknet-io/SNIPs/blob/main/SNIPS/snip-12.md) typed data message.&#x20;

With starknet.js, you would do something like this:

```typescript
const account = new Account(provider, address, pk);
const typedData: TypedData = {
    // your typed data
}
const sig = await account.signMessage(typedData);
```

With starknet-react's hook, it will look like that:

```tsx
// declare hook
const { signTypedDataAsync } = useSignTypedData({
    // your typedData
})
// use hook
const doSomething = async () => {
    // rest of the code
    const signature = await signTypedDataAsync({
        // your typedData
    })
    // do something with sig
}
```

You'll notice that a signature is an array of several numbers. If the account is a standard account, then the sig length will be 5 and if it's a smart-account, it will be 9 (because you have both the account and the guardian signatures). The members of the sig array are explained [below](#verifying-multi-signatures).&#x20;

## Verifying signatures&#x20;

There are several ways of verifying a signature, on-chain or off-chain. Most of the time, you will use one of the on-chain methods. The starknet.js doc has an example of [off-chain verification](https://starknetjs.com/docs/guides/signature#verify-outside-of-starknet).&#x20;

#### On-chain verification method 1 - Calling the contract

Ready account signatures can be verified by calling the `isValidSignature` or `is_valid_signature` method of the account contract:

```javascript
const contractAccount = new Contract(abi, accountAddress, provider);
const msgHash = typedData.getMessageHash(data, accountAddress);
await contractAccount.isValidSignature(msgHash, [signature.r, signature.s])
```

<mark style="color:red;">**Be aware that most of Ready accounts will return more that one signature that should all be verified. See below.**</mark>

Signature r and s are the the 4th and 5th member of the sig array so `signature[3]` and `signature[4]` .&#x20;

#### On-chain verification method 2 - with Typed data

Most of the time, you will get your users to sign a typed data message following the SNIP-12 standard. There is an easy way to verify such a signature.&#x20;

```typescript
const provider = new RpcProvider({
  nodeUrl: rpcUrl
});
const isValidSig = await provider.verifyMessageInStarknet(
      typedData, // typed data json your user signed
      signature, // raw user sig, no need to filter r and s
      account // user address
    );
```

This method also accepts message hash instead of the full json.&#x20;

## Guardians and co-signers

A guardian is a trusted party, added by the user, that acts as a cosigner/co-validator for the user's account when carrying out typical wallet operations or for recovery purposes.

For most of Ready's products e.g Ready, Web Wallet, Smart Accounts in Ready Wallet etc, the guardian is usually Ready's backend.&#x20;

In the next section, let's take a look at how you can verify multi-signatures for accounts with an active guardian.

## Verifying multi-signatures

From a dApp's end, explicit support has to be provided for verifying multi-signatures, or account owners with guardians will be unable to sign transactions.

The signature is verified by calling the `isValidSignature` or  `is_valid_signature()` method. If the user has a guardian, the signature returned by the wallet will be longer and include more data. &#x20;

<figure><img src="/files/d9JAZgslKQY2LlgRpnmm" alt=""><figcaption></figcaption></figure>

`0:` number of signers (i.e. 2 in this example)

`1:` type of signer 1

`2:` pubkey 1

`3:` r1

`4:` s1

`5:` type of signer 2 (guardian)

`6:` pubkey 2 (guardian)

`7:` r2 (guardian)

`8:` s2 (guardian)

```javascript
const contractAccount = new Contract(abi, accountAddress, provider);
const msgHash = typedData.getMessageHash(data, accountAddress);
await contractAccount.isValidSignature(msgHash, [signature1.r, signature1.s, signature2.r, signature2.s])
```

{% hint style="info" %}
Different Starknet accounts or wallets might return different signatures. Only the signature verification with `isValidSignature` should be sent as a payload
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.ready.co/aa-use-cases/verifying-signatures-and-cosigners.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
