65 lines
2.0 KiB
Nim
65 lines
2.0 KiB
Nim
|
import pkg/eth/keys
|
||
|
import pkg/eth/rlp
|
||
|
import pkg/eth/common/transaction as eth
|
||
|
import ../basics
|
||
|
import ../transaction as ethers
|
||
|
import ./error
|
||
|
|
||
|
type
|
||
|
Transaction = ethers.Transaction
|
||
|
SignableTransaction = eth.Transaction
|
||
|
|
||
|
func toSignableTransaction(transaction: Transaction): SignableTransaction =
|
||
|
var signable: SignableTransaction
|
||
|
|
||
|
without nonce =? transaction.nonce:
|
||
|
raiseWalletError "missing nonce"
|
||
|
|
||
|
without chainId =? transaction.chainId:
|
||
|
raiseWalletError "missing chain id"
|
||
|
|
||
|
without gasLimit =? transaction.gasLimit:
|
||
|
raiseWalletError "missing gas limit"
|
||
|
|
||
|
signable.nonce = nonce.truncate(uint64)
|
||
|
signable.chainId = ChainId(chainId.truncate(uint64))
|
||
|
signable.gasLimit = GasInt(gasLimit.truncate(uint64))
|
||
|
signable.to = some EthAddress(transaction.to)
|
||
|
signable.value = transaction.value
|
||
|
signable.payload = transaction.data
|
||
|
|
||
|
if maxFee =? transaction.maxFee and
|
||
|
maxPriorityFee =? transaction.maxPriorityFee:
|
||
|
signable.txType = TxEip1559
|
||
|
signable.maxFee = GasInt(maxFee.truncate(uint64))
|
||
|
signable.maxPriorityFee = GasInt(maxPriorityFee.truncate(uint64))
|
||
|
elif gasPrice =? transaction.gasPrice:
|
||
|
signable.txType = TxLegacy
|
||
|
signable.gasPrice = GasInt(gasPrice.truncate(uint64))
|
||
|
else:
|
||
|
raiseWalletError "missing gas price"
|
||
|
|
||
|
signable
|
||
|
|
||
|
func sign(key: PrivateKey, transaction: SignableTransaction): seq[byte] =
|
||
|
var transaction = transaction
|
||
|
|
||
|
# Temporary V value, used to signal to the hashing function
|
||
|
# that we'd like to use an EIP-155 signature
|
||
|
transaction.V = int64(uint64(transaction.chainId)) * 2 + 35
|
||
|
|
||
|
let hash = transaction.txHashNoSignature().data
|
||
|
let signature = key.sign(SkMessage(hash)).toRaw()
|
||
|
|
||
|
transaction.R = UInt256.fromBytesBE(signature[0..<32])
|
||
|
transaction.S = UInt256.fromBytesBE(signature[32..<64])
|
||
|
transaction.V = int64(signature[64])
|
||
|
|
||
|
if transaction.txType == TxLegacy:
|
||
|
transaction.V += int64(uint64(transaction.chainId)) * 2 + 35
|
||
|
|
||
|
rlp.encode(transaction)
|
||
|
|
||
|
func sign*(key: PrivateKey, transaction: Transaction): seq[byte] =
|
||
|
key.sign(transaction.toSignableTransaction())
|