Use black-box signatures to sign any ECDSA-secp256k1 payload and enable support for chains that Fordefi does not yet support.
When certain chains are not yet supported, Blackbox signing allows you to add a chain where you will need to manage the blockchain integration and leverage Fordefi's MPC signing capabilities.
Examples
The following sample shows how to sign an transaction using a blackbox secp256k1 vault. The request should be inside the body, as demonstrated here.
import base64
import datetime
import hashlib
import ecdsa
import json
import requests
from eth_account._utils.legacy_transactions import serializable_unsigned_transaction_from_dict, encode_transaction
chain_id = 1 # mainnet
# Build the signature request
transaction_dict = {
'to': '0x95524e2Ab866D3615F81C6921C6A8fb6e85fA823',
'value': 1,
'gas': 21000,
'gasPrice': 500000000,
'nonce': 0,
'chainId': chain_id,
}
unsigned_transaction = serializable_unsigned_transaction_from_dict(transaction_dict)
payload_encoded = base64.b64encode(unsigned_transaction.hash()).decode()
request_json = {
"vault_id": vault_id,
"signer_type": "api_signer",
"type": "black_box_signature",
"details": {
"format": "hash_binary",
"hash_binary": payload_encoded,
},
}
request_body = json.dumps(request_json)
private_key_file = "private.pem"
timestamp = datetime.datetime.now().strftime("%s")
payload = f"/api/v1/transactions|{timestamp}|{request_body}"
with open(private_key_file, "r") as f:
signing_key = ecdsa.SigningKey.from_pem(f.read())
signature = signing_key.sign(data=payload.encode(), hashfunc=hashlib.sha256, sigencode=ecdsa.util.sigencode_der)
resp_tx = requests.post(
f"https://{gateway_host}/api/v1/transactions",
headers={
"Authorization": f"Bearer {access_token}",
"x-signature": base64.b64encode(signature),
"x-timestamp": timestamp.encode(),
},
data=request_body,
).json()
transaction_id = resp_tx["id"]
# Obtain the signature result
signed_transaction = requests.get(
f"https://{gateway_host}/api/v1/transactions/{transaction_id}",
headers={
"Authorization": f"Bearer {access_token}",
}
).json()
r = int(signed_transaction["details"]["signature"]["r"], 16)
s = int(signed_transaction["details"]["signature"]["s"], 16)
v = signed_transaction["details"]["signature"]["v"] + 35 + 2 * chain_id
encoded_transaction = encode_transaction(unsigned_transaction, vrs=(v, r, s))
hex_to_send = "0x" + encoded_transaction.hex()