Address derivation

Turnkey supports Movement address derivation. Movement is built on the Move VM and uses Ed25519 cryptography, which Turnkey fully supports.

Transaction construction and signing

Turnkey supports Movement transaction signing through our core signing capabilities. We provide an example repository that demonstrates how to construct and sign Movement transactions:

Example

Here’s a comprehensive example showing how to integrate Turnkey with Movement for transaction signing:

import { Turnkey } from "@turnkey/sdk-server";
import {
  MovementClient,
  AptosAccount,
  TxnBuilderTypes,
  BCS,
  HexString
} from "movement-sdk";

// Custom Turnkey signer for Movement
class TurnkeyMovementSigner {
  private turnkeyClient: Turnkey;
  private movementClient: MovementClient;
  private address: string;
  private organizationId: string;

  constructor(
    apiPrivateKey: string,
    apiPublicKey: string,
    organizationId: string,
    address: string,
    nodeUrl: string = "https://seed-node1.movementlabs.xyz"
  ) {
    this.turnkeyClient = new Turnkey({
      apiBaseUrl: "https://api.turnkey.com",
      apiPrivateKey,
      apiPublicKey,
      defaultOrganizationId: organizationId
    });

    this.movementClient = new MovementClient(nodeUrl);
    this.address = address;
    this.organizationId = organizationId;
  }

  // Get the account address
  getAddress(): string {
    return this.address;
  }

  // Sign a raw payload using Turnkey
  async signRawPayload(payload: Uint8Array): Promise<Uint8Array> {
    const hexPayload = Buffer.from(payload).toString('hex');

    const signResult = await this.turnkeyClient.signRawPayload({
      organizationId: this.organizationId,
      signWith: this.address,
      payload: hexPayload,
      encoding: "hex"
    });

    return Buffer.from(signResult.signature, 'hex');
  }

  // Submit a transaction to Movement
  async submitTransaction(payload: any): Promise<string> {
    try {
      // Get account info for sequence number
      const accountInfo = await this.movementClient.getAccount(this.address);
      const sequenceNumber = BigInt(accountInfo.sequence_number);

      // Get chain ID for the transaction
      const chainId = await this.movementClient.getChainId();

      // Build raw transaction
      const rawTx = new TxnBuilderTypes.RawTransaction(
        // Account address
        TxnBuilderTypes.AccountAddress.fromHex(this.address),
        // Sequence number
        sequenceNumber,
        // Transaction payload
        payload,
        // Max gas
        BigInt(10000),
        // Gas unit price
        BigInt(100),
        // Expiration timestamp (30 seconds from now)
        BigInt(Math.floor(Date.now() / 1000) + 30),
        // Chain ID
        new TxnBuilderTypes.ChainId(chainId)
      );

      // Serialize the transaction
      const serializer = new BCS.Serializer();
      rawTx.serialize(serializer);
      const toSign = serializer.getBytes();

      // Sign the transaction
      const signature = await this.signRawPayload(toSign);

      // In a real implementation, you would need the actual public key from the address
      // Here we use a placeholder
      const dummyPublicKey = new TxnBuilderTypes.Ed25519PublicKey(new Uint8Array(32));

      // Create authenticator
      const authenticator = new TxnBuilderTypes.TransactionAuthenticatorEd25519(
        dummyPublicKey,
        new TxnBuilderTypes.Ed25519Signature(signature)
      );

      // Create signed transaction
      const signedTx = new TxnBuilderTypes.SignedTransaction(
        rawTx,
        authenticator
      );

      // Submit transaction
      const txnResponse = await this.movementClient.submitTransaction(
        BCS.bcsToBytes(signedTx)
      );

      return txnResponse.hash;
    } catch (error) {
      console.error("Error submitting transaction:", error);
      throw error;
    }
  }
}

// Example usage: Transfer MOV tokens
async function transferMovTokens() {
  const signer = new TurnkeyMovementSigner(
    process.env.API_PRIVATE_KEY!,
    process.env.API_PUBLIC_KEY!,
    process.env.ORGANIZATION_ID!,
    process.env.MOVEMENT_ADDRESS!, // Your Movement address in Turnkey
    "https://testnet.movementlabs.xyz" // Use testnet URL for development
  );

  const recipientAddress = "0x..."; // Recipient address
  const amount = 1000000; // Amount (adjust decimal places as needed)

  // Create a transfer transaction payload
  const payload = new TxnBuilderTypes.TransactionPayloadEntryFunction(
    TxnBuilderTypes.EntryFunction.natural(
      "0x1::coin",
      "transfer",
      [new TxnBuilderTypes.TypeTagStruct(
        TxnBuilderTypes.StructTag.fromString("0x1::mov_coin::MOV")
      )],
      [
        BCS.bcsToBytes(TxnBuilderTypes.AccountAddress.fromHex(recipientAddress)),
        BCS.bcsSerializeUint64(amount)
      ]
    )
  );

  try {
    const txnHash = await signer.submitTransaction(payload);
    console.log(`Transaction submitted successfully! Hash: ${txnHash}`);
    return txnHash;
  } catch (error) {
    console.error("Error transferring tokens:", error);
    throw error;
  }
}

## Movement Network Support

Turnkey supports:

* Movement Mainnet
* Movement Testnet

## Key Features for Movement

* **Ed25519 Signing**: Turnkey fully supports the Ed25519 curve used by Movement
* **BCS Format Support**: Sign transactions serialized in the Binary Canonical Serialization format
* **Integration Example**: Our example repository provides a reference implementation for integrating with the Movement ecosystem

## Benefits of Using Turnkey with Movement

* **Secure Private Keys**: Keys are securely stored in Turnkey's infrastructure
* **Customizable Policies**: Implement rules to control when and how transactions are signed
* **Developer-Friendly**: Seamless integration with existing Movement development workflows
* **Enterprise-Ready**: Built for production environments with high security requirements

## Move Smart Contract Development

Movement leverages the Move VM for smart contracts. When developing Move smart contracts on Movement, Turnkey can securely manage your private keys for:

* Deploying Move modules
* Publishing packages
* Executing Move functions
* Managing on-chain resources

If you're building on Movement and need assistance with your Turnkey integration, feel free to contact us at [hello@turnkey.com](mailto:hello@turnkey.com), on [X](https://x.com/turnkeyhq/), or [on Slack](https://join.slack.com/t/clubturnkey/shared_invite/zt-31v4yhgw6-PwBzyNsWCCBTk2xft3EoHQ).