Documentation Index Fetch the complete documentation index at: https://turnkey-0e7c1f5b-ethan-captcha-protection.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
Address derivation
Turnkey fully supports IOTA addresss derived from the Ed25519 curve.
Transaction construction and signing
Turnkey supports IOTA transaction signing through the core signing capabilities. We provide an example repository that demonstrates how to construct and sign IOTA transactions:
Example
Here’s a practical example showing how to integrate Turnkey with the IOTA SDK :
import * as dotenv from 'dotenv' ;
import * as path from 'path' ;
import { IotaClient , getFullnodeUrl } from '@iota/iota-sdk/client' ;
import { Transaction } from '@iota/iota-sdk/transactions' ;
import { Ed25519PublicKey } from '@iota/iota-sdk/keypairs/ed25519' ;
import { messageWithIntent } from '@iota/iota-sdk/cryptography' ;
import { Turnkey } from '@turnkey/sdk-server' ;
import { blake2b } from '@noble/hashes/blake2b' ;
import { bytesToHex } from '@noble/hashes/utils' ;
dotenv . config ({ path: path . resolve ( process . cwd (), '.env.local' ) });
function toSerializedSignature ({
signature ,
pubKey ,
} : {
signature : Uint8Array ;
pubKey : Ed25519PublicKey ;
}) : string {
const scheme = new Uint8Array ([ 0x00 ]); // ED25519 flag
const pubKeyBytes = pubKey . toRawBytes ();
const serialized = new Uint8Array (
scheme . length + signature . length + pubKeyBytes . length
);
serialized . set ( scheme , 0 );
serialized . set ( signature , scheme . length );
serialized . set ( pubKeyBytes , scheme . length + signature . length );
return Buffer . from ( serialized ). toString ( 'base64' );
}
async function main () {
// load the variables from .env
// IOTA_ADDRESS and IOTA_PUBLIC_KEY of the Turnkey signer
const {
ORGANIZATION_ID ,
API_PRIVATE_KEY ,
API_PUBLIC_KEY ,
IOTA_ADDRESS ,
IOTA_PUBLIC_KEY ,
} = process . env ;
if ( IOTA_ADDRESS === undefined || IOTA_PUBLIC_KEY === undefined ) {
throw new Error ( 'IOTA_ADDRESS or IOTA_PUBLIC_KEY not set in .env.local' );
}
// sending to the same address
const recipient = IOTA_ADDRESS ;
const amount = 1_000_000 n ; // 0.001 IOTA
const turnkeyClient = new Turnkey ({
apiBaseUrl: 'https://api.turnkey.com' ,
apiPrivateKey: API_PRIVATE_KEY ! ,
apiPublicKey: API_PUBLIC_KEY ! ,
defaultOrganizationId: ORGANIZATION_ID ! ,
});
const provider = new IotaClient ({ url: getFullnodeUrl ( 'testnet' ) });
const publicKey = new Ed25519PublicKey ( Buffer . from ( IOTA_PUBLIC_KEY ! , 'hex' ));
// if (publicKey.toIotaAddress() !== IOTA_ADDRESS) {
// throw new Error('IOTA_PUBLIC_KEY does not match IOTA_ADDRESS');
// }
// fetch the user's IOTA coin objects
const coins = await provider . getCoins ({
owner: IOTA_ADDRESS ! ,
coinType: '0x2::iota::IOTA' ,
});
if ( ! coins . data . length ) throw new Error ( 'No IOTA coins' );
const tx = new Transaction ();
tx . setSender ( IOTA_ADDRESS ! );
tx . setGasPrice ( await provider . getReferenceGasPrice ());
tx . setGasBudget ( 5_000_000 n );
tx . setGasPayment ([
{
objectId: coins . data [ 0 ] ! . coinObjectId ,
version: coins . data [ 0 ] ! . version ,
digest: coins . data [ 0 ] ! . digest ,
},
]);
const coin = tx . splitCoins ( tx . gas , [ tx . pure ( 'u64' , amount )]);
tx . transferObjects ([ coin ], tx . pure . address ( recipient ));
const txBytes = await tx . build ();
const intentMsg = messageWithIntent ( 'TransactionData' , txBytes );
const digest = blake2b ( intentMsg , { dkLen: 32 });
const { r , s } = await turnkeyClient . apiClient (). signRawPayload ({
signWith: IOTA_ADDRESS ! ,
payload: bytesToHex ( digest ),
encoding: 'PAYLOAD_ENCODING_HEXADECIMAL' ,
hashFunction: 'HASH_FUNCTION_NOT_APPLICABLE' ,
});
const signature = Buffer . from ( r + s , 'hex' );
const serialized = toSerializedSignature ({ signature , pubKey: publicKey });
const result = await provider . executeTransactionBlock ({
transactionBlock: Buffer . from ( txBytes ). toString ( 'base64' ),
signature: serialized ,
requestType: 'WaitForEffectsCert' ,
options: { showEffects: true },
});
console . log ( 'Transaction digest:' , result . digest );
}
main (). catch (( err ) => {
console . error ( 'Error:' , err );
process . exit ( 1 );
});
See all 112 lines
IOTA Network Support
Turnkey supports:
IOTA Mainnet
IOTA Testnet
IOTA Devnet
Key Features for IOTA
Ed25519 Signing : Turnkey fully supports the Ed25519 curve used by IOTA
Raw Transaction Signing : Sign any IOTA transaction format with Turnkey’s flexible signing API
Integration Example : Our example repository provides a reference implementation
Benefits of using Turnkey with IOTA
Secure Key Management : Private keys never leave Turnkey’s secure infrastructure
Developer Friendly : Integrate with existing IOTA development workflows
Signing Policies : Apply custom policies to control transaction approvals
Multi-user Support : Manage multiple IOTA addresses under a single organization
If you’re building on IOTA and need assistance with Turnkey integration, feel free to contact us at hello@turnkey.com , on X , or on Slack .