import { Turnkey } from "@turnkey/sdk-server";
import {
Connection,
JsonRpcProvider,
Ed25519Keypair,
RawSigner,
TransactionBlock,
} from "@mysten/sui.js";
// Custom Turnkey signer for Sui
class TurnkeySuiSigner {
private turnkeyClient: Turnkey;
private organizationId: string;
private suiAddress: string;
constructor(
apiPrivateKey: string,
apiPublicKey: string,
organizationId: string,
suiAddress: string
) {
this.turnkeyClient = new Turnkey({
apiBaseUrl: "https://api.turnkey.com",
apiPrivateKey,
apiPublicKey,
defaultOrganizationId: organizationId,
});
this.organizationId = organizationId;
this.suiAddress = suiAddress;
}
// Sign bytes using Turnkey
async signData(data: Uint8Array): Promise<Uint8Array> {
const dataToSign = Buffer.from(data).toString("hex");
const signResult = await this.turnkeyClient.signRawPayload({
organizationId: this.organizationId,
signWith: this.suiAddress,
payload: dataToSign,
encoding: "hex",
});
// Return signature as bytes
return Buffer.from(signResult.signature, "hex");
}
// Get the Sui address associated with this signer
getAddress(): string {
return this.suiAddress;
}
}
// Usage example
async function sendSuiTransaction() {
// Initialize your Turnkey signer
const turnkeySigner = new TurnkeySuiSigner(
process.env.API_PRIVATE_KEY!,
process.env.API_PUBLIC_KEY!,
process.env.ORGANIZATION_ID!,
process.env.SUI_ADDRESS! // Your Sui address in Turnkey
);
// Connect to Sui network
const connection = new Connection({
fullnode: "https://fullnode.mainnet.sui.io", // Use testnet for development
});
const provider = new JsonRpcProvider(connection);
// Create a keypair that acts as an adapter between our signer and Sui SDK
// Note: We don't use the actual keypair for signing, only as an adapter
const dummyKeypair = new Ed25519Keypair();
// Create a Sui signer that will use our Turnkey signer for actual signing
const signer = new RawSigner(
// Override the signData method to use our Turnkey signer
{
getPublicKey: async () => {
return dummyKeypair.getPublicKey();
},
signData: async (data: Uint8Array) => {
return {
signature: await turnkeySigner.signData(data),
signatureScheme: dummyKeypair.getKeyScheme(),
};
},
},
provider
);
// Build a transaction
const tx = new TransactionBlock();
// Example: Transfer SUI tokens
tx.transferObjects(
[
tx.object("0x..."), // Object ID to transfer
],
tx.pure("0x...")
); // Recipient address
// Sign and execute transaction
const result = await signer.signAndExecuteTransactionBlock({
transactionBlock: tx,
});
console.log("Transaction executed:", result.digest);
return result;
}