Ethereum: Sign transaction
Asks device to sign given transaction using the private key derived by given BIP32 path. User is asked to confirm all transaction details on OneKey.
Copy const result = await HardwareSDK .evmSignTransaction (connectId , deviceId , params);
Copy HardwareSDK .evmSignTransaction (connectId , deviceId , {
path : "m/44'/60'/0'" ,
transaction : {
to : '0xd0d6d6c5fe4a677d343cc433536bb717bae167dd' ,
value : '0xf4240' ,
data : '0xa' ,
chainId : 1 ,
nonce : '0x0' ,
maxFeePerGas : '0x14' ,
maxPriorityFeePerGas : '0x0' ,
gasLimit : '0x14' ,
} ,
chainId : 1
});
Copy HardwareSDK .evmSignTransaction (connectId , deviceId , {
path : "m/44'/60'/0'" ,
transaction : {
to : "0x7314e0f1c0e28474bdb6be3e2c3e0453255188f8" ,
value : "0xf4240" ,
data : "0x01" ,
chainId : 1 ,
nonce : "0x0" ,
gasLimit : "0x5208" ,
gasPrice : "0xbebc200"
} ,
chainId : 1
});
Copy {
success : true ,
payload : {
v : string , // hexadecimal string with "0x" prefix
r : string , // hexadecimal string with "0x" prefix
s : string , // hexadecimal string with "0x" prefix
}
}
Copy {
success : false ,
payload : {
error : string , // error message
code : number // error code
}
}
Transaction Signing and Broadcasting example
Copy import type { UnsignedTransaction } from '@ethersproject/transactions' ;
import { TransactionTypes , serialize } from '@ethersproject/transactions' ;
import { keccak256 } from '@ethersproject/keccak256' ;
function buildSignedTxFromSignatureEvm ({
tx ,
signature ,
} : {
tx : UnsignedTransaction ;
signature : {
v : string | number ; // '0x11' , '17', 17
r : string ; // prefix 0x
s : string ; // prefix 0x
};
}) {
const { r , s , v } = signature;
/**
* sdk legacy return {v,r,s}; eip1559 return {recoveryParam,r,s}
* splitSignature auto convert v to recoveryParam
*/
const sig = splitSignature ({
v : Number (v) ,
r ,
s ,
});
const rawTx = serialize (tx , sig);
const txid = keccak256 (rawTx);
return {
rawTx ,
txid ,
};
}
// 1. Create transaction parameters
const txParams = {
to : '0x7314e0f1c0e28474bdb6be3e2c3e0453255188f8' ,
value : '0x0' , // Default to 0 if no value
data : '0x' , // Empty data
chainId : 1 ,
nonce : '0x0' ,
// For EIP-1559 transaction
maxFeePerGas : '0x14' , // 20
maxPriorityFeePerGas : '0x0' , // 0
gasLimit : '0x5208' , // 21000
// For legacy transaction
// gasPrice: '0x14', //
};
// 2. Sign the transaction
const result = await HardwareSDK .evmSignTransaction (connectId , deviceId , {
path : "m/44'/60'/0'" ,
transaction : txParams ,
... deviceCommonParams
});
// 3. Build signed transaction
const baseTx = {
to : txParams .to ,
nonce : parseInt ( txParams .nonce , 16 ) ,
gasLimit : txParams .gasLimit
data: txParams .data ,
value : txParams .value ,
chainId : txParams .chainId ,
};
// Add EIP-1559 specific fields
const isEIP1559 = txParams ?.maxFeePerGas || txParams ?.maxPriorityFeePerGas;
if (isEIP1559) {
Object .assign (baseTx , {
type : TransactionTypes .eip1559 ,
maxFeePerGas : txParams ?.maxFeePerGas
maxPriorityFeePerGas: txParams ?.maxPriorityFeePerGas
});
} else {
Object .assign (baseTx , {
gasPrice : txParams .gasPrice ,
});
}
// 4. Build final transaction with signature
const { rawTx , txid } = buildSignedTxFromSignatureEvm ({
tx : baseTx ,
signature : result .payload
});
// 5. Broadcast the transaction
// const provider = new ethers.providers.JsonRpcProvider();
// const broadcastedTx = await provider.sendTransaction(rawTx);
// 6. Wait for confirmation
// const receipt = await broadcastedTx.wait();
// console.log('Transaction confirmed:', receipt);