# Movement Provider

After setting up your wallet, you can have access to the Movement provider:

```javascript
// react
const { providers } = useTomo()
const { movementProvider } = providers;

// pure js
const tronProvider = window.tomo_movement
```

### Get Movement Address

&#x20;The Movement address is from the wallet state or provider. In React framework:

```tsx
import { useTomo} from '@tomo-inc/tomo-web-sdk';
const { walletState, providers } = useTomo()

// get from wallet state
const movementAddress = walletState.movementAddress

// or get from provider
const movementAddress = await providers.movementProvider.getAddress()


```

Or Pure JS:

<pre class="language-javascript"><code class="lang-javascript"><strong>/** pure js */
</strong>import { getWalletState } from '@tomo-inc/tomo-web-sdk';
/** pure js */
// get from wallet state
const movementAddress = getWalletState().movementAddress

// or get from provider
const movementAddress = await window.tomo_movement.getAddress()
</code></pre>

## Provider Functions

### **Signing a Message**

It uses the Movement provider to sign a plaintext message with a nonce. The output is a response message output defined as below:&#x20;

{% code overflow="wrap" %}

```tsx
// interface
signMessage(
  input: AptosSignMessageInput
): Promise<UserResponse<AptosSignMessageOutput>>;

type AptosSignMessageInput = {
  address?: boolean;
  application?: boolean;
  chainId?: boolean;
  message: string;
  nonce: string;
};

declare enum UserResponseStatus {
  APPROVED = "Approved",
  REJECTED = "Rejected",
}

interface UserApproval<TResponseArgs> {
  status: UserResponseStatus.APPROVED;
  args: TResponseArgs;
}

interface UserRejection {
  status: UserResponseStatus.REJECTED;
}

type UserResponse<TResponseArgs> =
  | UserApproval<TResponseArgs>
  | UserRejection;

type AptosSignMessageOutput = {
  address?: string;
  application?: string;
  chainId?: number;
  fullMessage: string;
  message: string;
  nonce: string;
  prefix: "APTOS";
  signature: Signature;
};

// example
const signedMessage = await movementProvider.signMessage({
  message: "hello movement",
  nonce: "123",
});
```

{% endcode %}

### **Sign Transaction**

To sign a transaction, you need to create a `AnyRawTransaction`  from `Aptos` SDK and send it to the movement Provider for signing.&#x20;

{% code overflow="wrap" %}

```tsx
// interface
import {
  AnyRawTransaction,
  AptosConfig,
  Aptos,
  AccountAddress,
} from "@aptos-labs/ts-sdk";

signTransaction(
  transaction: AnyRawTransaction,
  asFeePayer?: boolean
): Promise<SignedTransaction>;

// example
const config = new AptosConfig({
  fullnode: yourRpcUrl,
});

const client = new Aptos(config);

const transaction = await client.transaction.build.simple({
  sender: AccountAddress.fromString(fromAddress),
  data: {
    functionArguments: [
      AccountAddress.fromString(toAddress),
      +value,
    ],
    function: "0x1::aptos_account::transfer",
  },
});

const signedRes = await movementProvider.signTransaction(transaction);
```

{% endcode %}

### Send Transaction

Our movement provider also supports signing and submitting a transaction through one call, which require a `InputGenerateTransactionPayloadData`  as inputs.

```typescript
// interface
import { InputGenerateTransactionPayloadData } from "@aptos-labs/ts-sdk";

signAndSubmitTransaction(
  transaction: AptosSignAndSubmitTransactionInput
): Promise<SignedTransaction>;

interface AptosSignAndSubmitTransactionInput {
  gasUnitPrice?: number;
  maxGasAmount?: number;
  payload: InputGenerateTransactionPayloadData;
}

// example
const transaction: { payload: InputEntryFunctionData } = {
  payload: {
    functionArguments: ["0x34324...", 123],
    function: "0x1::aptos_account::transfer",
  },
};

const sendRes = await movementProvider.signAndSubmitTransaction(transaction);
```

## Example

We provide an [example ](https://socialwallet-react-prod.tomo.inc/movement)as follows:

### React

```tsx
import {
  AnyRawTransaction,
  AptosConfig,
  Aptos,
  AccountAddress,
  InputEntryFunctionData,
} from "@aptos-labs/ts-sdk";
import { TomoContextProvider, useTomo } from "@tomo-inc/tomo-web-sdk";

const CLIENT_ID = "Your client id";

enum Theme {
  Light = "light",
  Dark = "dark",
}

export default function MovementDemo() {
  return (
    <TomoContextProvider
      theme={Theme.Light}
      chainTypes={["movement"]}
      clientId={CLIENT_ID}
    >
      <App />
    </TomoContextProvider>
  );
}

export function App() {
  const { providers, walletState, openConnectModal } = useTomo();
  const { movementProvider } = providers;

  return (
    <div style={{ display: "flex", gap: "10px" }}>
      <button onClick={openConnectModal}>openConnectModal</button>

      <button
        onClick={async () => {
          if (!movementProvider) throw new Error("movementProvider not found");

          try {
            const config = new AptosConfig({ fullnode: yourRpcUrl });
            const client = new Aptos(config);

            const transaction = await client.transaction.build.simple({
              sender: AccountAddress.fromString(fromAddress),
              data: {
                functionArguments: [AccountAddress.fromString(toAddress), value],
                function: "0x1::aptos_account::transfer",
              },
            });

            const signRes = await movementProvider.signTransaction(transaction);
            console.log("signRes>>>", signRes);

            if (signRes?.status === UserResponseStatus.REJECTED) {
              throw new Error("User rejected the request or failed to sign Move transaction");
            }

            console.log("The transaction was signed successfully:", signRes.args);
          } catch (error) {
            console.error("Error signing transaction:", error);
          }
        }}
      >
        sign transaction
      </button>

      <button
        onClick={async () => {
          if (!movementProvider) throw new Error("movementProvider not found");

          try {
            const transaction: { payload: InputEntryFunctionData } = {
              payload: {
                functionArguments: [address, 123],
                function: "0x1::aptos_account::transfer",
              },
            };

            const sendRes = await movementProvider.signAndSubmitTransaction(transaction);
            console.log("sendRes>>>", sendRes);

            if (sendRes?.status === UserResponseStatus.REJECTED) {
              throw new Error("User rejected the request or failed to send Move transaction");
            }

            console.log("The transaction was sent successfully:", sendRes.args.hash);
          } catch (error) {
            console.error("Error signing and submitting transaction:", error);
          }
        }}
      >
        sign and submit transaction
      </button>
    </div>
  );
}
```

### Pure JS

```javascript
import { initTomoModal } from "@tomo-inc/tomo-web-sdk";
import {
  AnyRawTransaction,
  AptosConfig,
  Aptos,
  AccountAddress,
  InputEntryFunctionData,
} from "@aptos-labs/ts-sdk";

const CLIENT_ID = "Your client id";

enum Theme {
  Light = "light",
  Dark = "dark",
}

initTomoModal({
  theme: Theme.Light,
  clientId: CLIENT_ID,
  chainTypes: ["movement"],
});

export default function MovementDemo() {
  return (
    <div style={{ display: "flex", gap: "10px" }}>
      <button onClick={() => window.openTomoConnectModal?.()}>
        openConnectModal
      </button>

      <button
        onClick={async () => {
          if (!window.movementProvider)
            throw new Error("movementProvider not found");

          try {
            const config = new AptosConfig({ fullnode: yourRpcUrl });
            const client = new Aptos(config);

            const transaction = await client.transaction.build.simple({
              sender: AccountAddress.fromString(fromAddress),
              data: {
                functionArguments: [
                  AccountAddress.fromString(toAddress),
                  value,
                ],
                function: "0x1::aptos_account::transfer",
              },
            });

            const signRes = await window.movementProvider.signTransaction(
              transaction
            );
            console.log("signRes>>>", signRes);

            if (signRes?.status === UserResponseStatus.REJECTED) {
              throw new Error(
                "User rejected the request or failed to sign Move transaction"
              );
            }

            console.log("The transaction was signed successfully:", signRes.args);
          } catch (error) {
            console.error("Error signing transaction:", error);
          }
        }}
      >
        sign transaction
      </button>

      <button
        onClick={async () => {
          if (!window.movementProvider)
            throw new Error("movementProvider not found");

          try {
            const transaction: { payload: InputEntryFunctionData } = {
              payload: {
                functionArguments: [address, 123],
                function: "0x1::aptos_account::transfer",
              },
            };

            const sendRes =
              await window.movementProvider.signAndSubmitTransaction(transaction);
            console.log("sendRes>>>", sendRes);

            if (sendRes?.status === UserResponseStatus.REJECTED) {
              throw new Error(
                "User rejected the request or failed to send Move transaction"
              );
            }

            console.log(
              "The transaction was sent successfully:",
              sendRes.args.hash
            );
          } catch (error) {
            console.error("Error signing and submitting transaction:", error);
          }
        }}
      >
        sign and submit transaction
      </button>
    </div>
  );
}
```


---

# 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.tomo.inc/tomo-sdk/tomo-web-sdk/movement-provider.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.
