From 761d40cfed1d686c13104eefe753fca423fb507d Mon Sep 17 00:00:00 2001 From: Omkar Shanbhag Date: Thu, 12 Dec 2024 10:52:17 -0800 Subject: [PATCH] working implementation --- .../src/allowTokenTransferPolicy.ts | 16 ++++--- examples/with-solana/src/keys.ts | 19 ++++----- .../with-solana/src/requests/createPolicy.ts | 5 +-- examples/with-solana/src/requests/index.ts | 2 +- examples/with-solana/src/requests/utils.ts | 17 ++++---- examples/with-solana/src/tokenTransfer.ts | 5 +-- .../src/utils/createTokenTransfer.ts | 42 +++++++++++++++---- examples/with-solana/src/utils/index.ts | 6 ++- 8 files changed, 67 insertions(+), 45 deletions(-) diff --git a/examples/with-solana/src/allowTokenTransferPolicy.ts b/examples/with-solana/src/allowTokenTransferPolicy.ts index 75b5a02ed..b09a04075 100644 --- a/examples/with-solana/src/allowTokenTransferPolicy.ts +++ b/examples/with-solana/src/allowTokenTransferPolicy.ts @@ -16,17 +16,14 @@ import { createNewSolanaWallet, createToken, createTokenAccount, - createTokenTransfer, + createTokenTransferSignTransaction, solanaNetwork, TURNKEY_WAR_CHEST, } from "./utils"; import keys from "./keys"; -import { - createUser, - createPolicy, -} from "./requests"; +import { createUser, createPolicy } from "./requests"; async function main() { const turnkeyWarchest = new PublicKey(TURNKEY_WAR_CHEST); @@ -132,8 +129,8 @@ async function main() { tokenAccount.address, mintAuthority.publicKey ); - - // Create non-root user + + // Create non-root user let nonRootUserID = await createUser( turnkeyClient.apiClient(), "Non Root User", @@ -163,8 +160,9 @@ async function main() { `solana.tx.spl_transfers.any(transfer, transfer.to == '${tokenAccountWarchest.address}')` ); - // Transfer token from primary to Warchest - await createTokenTransfer( + // Transfer token from primary to Warchest associated token account\ + // This call uses Turnkey's sign transaction endpoint which passes the transaction through the policy engine + await createTokenTransferSignTransaction( nonRootUserSigner, connection, solAddress, diff --git a/examples/with-solana/src/keys.ts b/examples/with-solana/src/keys.ts index 4fb15a9e2..ea7418a0d 100644 --- a/examples/with-solana/src/keys.ts +++ b/examples/with-solana/src/keys.ts @@ -2,13 +2,12 @@ // NOTE: Only used for demo purposes const keys: { [key: string]: { [key: string]: string } } = { - nonRootUser: { - publicKey: - "03178b1cb727bd1ab23c3c5725d633f9ad3c7c0502efda2371e4e4bd88aea8a94d", - privateKey: - "26e53957146d5d5b5612f09518b8bb40deddcf28d378270101227cb0a231969e", - }, - }; - - export default keys; - \ No newline at end of file + nonRootUser: { + publicKey: + "03178b1cb727bd1ab23c3c5725d633f9ad3c7c0502efda2371e4e4bd88aea8a94d", + privateKey: + "26e53957146d5d5b5612f09518b8bb40deddcf28d378270101227cb0a231969e", + }, +}; + +export default keys; diff --git a/examples/with-solana/src/requests/createPolicy.ts b/examples/with-solana/src/requests/createPolicy.ts index 198bf77ff..afd2f040b 100644 --- a/examples/with-solana/src/requests/createPolicy.ts +++ b/examples/with-solana/src/requests/createPolicy.ts @@ -1,6 +1,6 @@ import { - type TurnkeyServerClient, - TurnkeyActivityError, + type TurnkeyServerClient, + TurnkeyActivityError, } from "@turnkey/sdk-server"; import { refineNonNull } from "./utils"; @@ -49,4 +49,3 @@ export default async function createPolicy( }); } } - \ No newline at end of file diff --git a/examples/with-solana/src/requests/index.ts b/examples/with-solana/src/requests/index.ts index 6206670ba..adaab3fc9 100644 --- a/examples/with-solana/src/requests/index.ts +++ b/examples/with-solana/src/requests/index.ts @@ -1,2 +1,2 @@ export { default as createUser } from "./createUser"; -export { default as createPolicy } from "./createPolicy"; \ No newline at end of file +export { default as createPolicy } from "./createPolicy"; diff --git a/examples/with-solana/src/requests/utils.ts b/examples/with-solana/src/requests/utils.ts index 9ef8ba18d..d26b4fd42 100644 --- a/examples/with-solana/src/requests/utils.ts +++ b/examples/with-solana/src/requests/utils.ts @@ -1,11 +1,10 @@ export function refineNonNull( - input: T | null | undefined, - errorMessage?: string - ): T { - if (input == null) { - throw new Error(errorMessage ?? `Unexpected ${JSON.stringify(input)}`); - } - - return input; + input: T | null | undefined, + errorMessage?: string +): T { + if (input == null) { + throw new Error(errorMessage ?? `Unexpected ${JSON.stringify(input)}`); } - \ No newline at end of file + + return input; +} diff --git a/examples/with-solana/src/tokenTransfer.ts b/examples/with-solana/src/tokenTransfer.ts index 6071ea24a..ec5781dd8 100644 --- a/examples/with-solana/src/tokenTransfer.ts +++ b/examples/with-solana/src/tokenTransfer.ts @@ -11,10 +11,7 @@ import { getAccount, getAssociatedTokenAddress } from "@solana/spl-token"; import { Turnkey } from "@turnkey/sdk-server"; import { TurnkeySigner } from "@turnkey/solana"; -import { - createUser, - createPolicy, -} from "./requests"; +import { createUser, createPolicy } from "./requests"; import { createMint, diff --git a/examples/with-solana/src/utils/createTokenTransfer.ts b/examples/with-solana/src/utils/createTokenTransfer.ts index bfd690053..e3df88e6c 100644 --- a/examples/with-solana/src/utils/createTokenTransfer.ts +++ b/examples/with-solana/src/utils/createTokenTransfer.ts @@ -30,17 +30,43 @@ export async function createTokenTransfer( // Set the signer transferTx.feePayer = fromKey; - // const serializedTransaction = transferTx.serialize({ - // requireAllSignatures: false, - // verifySignatures: false - // }); - - // const hexString = serializedTransaction.toString('hex'); - // console.log("Transaction hex:", hexString); - await turnkeySigner.addSignature(transferTx, solAddress); console.log("Broadcasting token transfer transaction..."); await solanaNetwork.broadcast(connection, transferTx); } + +export async function createTokenTransferSignTransaction( + turnkeySigner: TurnkeySigner, + connection: Connection, + solAddress: string, + tokenAccountPubkey: PublicKey, + mintAuthority: PublicKey, + ataRecipient: PublicKey +): Promise { + const fromKey = new PublicKey(solAddress); + + let transferTx = new Transaction().add( + createTransferCheckedInstruction( + tokenAccountPubkey, // from (should be a token account) + mintAuthority, // mint + ataRecipient, // to (should be a token account) + fromKey, // from's owner + 1e4, // amount, if your deciamls is 8, send 10^8 for 1 token + 8 // decimals + ) + ); + + // Get a recent block hash + transferTx.recentBlockhash = await solanaNetwork.recentBlockhash(); + // Set the signer + transferTx.feePayer = fromKey; + + // Use Turnkey's sign transaction endpoint that passes the created transaction through the policy engine + let signedTx = await turnkeySigner.signTransaction(transferTx, solAddress); + + console.log("Broadcasting token transfer transaction..."); + + await solanaNetwork.broadcast(connection, signedTx); +} diff --git a/examples/with-solana/src/utils/index.ts b/examples/with-solana/src/utils/index.ts index ac88013b8..fe26a6759 100644 --- a/examples/with-solana/src/utils/index.ts +++ b/examples/with-solana/src/utils/index.ts @@ -6,7 +6,10 @@ import { print } from "./print"; import { createMint } from "./createMint"; import { createToken } from "./createToken"; import { createTokenAccount } from "./createTokenAccount"; -import { createTokenTransfer } from "./createTokenTransfer"; +import { + createTokenTransfer, + createTokenTransferSignTransaction, +} from "./createTokenTransfer"; import { transactionSenderAndConfirmationWaiter } from "./retrySender"; import { handleActivityError } from "./handleActivityError"; @@ -18,6 +21,7 @@ export { createToken, createTokenAccount, createTokenTransfer, + createTokenTransferSignTransaction, createTransfer, handleActivityError, print,