def safe_sign_transaction( transaction: Transaction, wallet: Wallet, check_fee: bool = True, ) -> Transaction: """ Signs a transaction locally, without trusting external rippled nodes. Args: transaction: the transaction to be signed. wallet: the wallet with which to sign the transaction. check_fee: whether to check if the fee is higher than the expected transaction type fee. Defaults to True. Returns: The signed transaction blob. """ if check_fee: _check_fee(transaction) transaction_json = _prepare_transaction(transaction, wallet) serialized_for_signing = encode_for_signing(transaction_json) serialized_bytes = bytes.fromhex(serialized_for_signing) signature = sign(serialized_bytes, wallet.private_key) transaction_json["TxnSignature"] = signature return cast(Transaction, Transaction.from_xrpl(transaction_json))
def test_from_xrpl_set_fee(self): reference_fee_units = 10 reserve_base = 20000000 reserve_increment = 5000000 base_fee = "000000000000000A" set_fee_dict = { "Account": "rrrrrrrrrrrrrrrrrrrrrhoLvTp", "BaseFee": base_fee, "Fee": "0", "ReferenceFeeUnits": reference_fee_units, "ReserveBase": reserve_base, "ReserveIncrement": reserve_increment, "Sequence": 0, "SigningPubKey": "", "TransactionType": "SetFee", } expected = SetFee( reference_fee_units=reference_fee_units, reserve_base=reserve_base, reserve_increment=reserve_increment, base_fee=base_fee, ) actual = Transaction.from_xrpl(set_fee_dict) self.assertEqual(actual, expected) full_dict = {**set_fee_dict, "Flags": 0, "TxnSignature": ""} self.assertEqual(actual.to_xrpl(), full_dict)
def test_from_xrpl(self): dirname = os.path.dirname(__file__) full_filename = "x-codec-fixtures.json" absolute_path = os.path.join(dirname, full_filename) with open(absolute_path) as fixtures_file: fixtures_json = json.load(fixtures_file) for test in fixtures_json["transactions"]: x_json = test["xjson"] r_json = test["rjson"] with self.subTest(json=x_json): tx = Transaction.from_xrpl(x_json) translated_tx = tx.to_xrpl() self.assertEqual(x_json, translated_tx) with self.subTest(json=r_json): tx = Transaction.from_xrpl(r_json) translated_tx = tx.to_xrpl() self.assertEqual(r_json, translated_tx)
def from_dict(cls: Type[SubmitMultisigned], value: Dict[str, Any]) -> SubmitMultisigned: """ Construct a new SubmitMultisigned object from a dictionary of parameters. Args: value: The value to construct the SubmitMultisigned from. Returns: A new SubmitMultisigned object, constructed using the given parameters. """ fixed_value = {**value} if "TransactionType" in fixed_value["tx_json"]: # xrpl format fixed_value["tx_json"] = Transaction.from_xrpl( fixed_value["tx_json"]) return cast(SubmitMultisigned, super(SubmitMultisigned, cls).from_dict(fixed_value))
def safe_sign_transaction( transaction: Transaction, wallet: Wallet, ) -> Transaction: """ Signs a transaction locally, without trusting external rippled nodes. Args: transaction: the transaction to be signed. wallet: the wallet with which to sign the transaction. Returns: The signed transaction blob. """ transaction_json = _prepare_transaction(transaction, wallet) serialized_for_signing = encode_for_signing(transaction_json) serialized_bytes = bytes.fromhex(serialized_for_signing) signature = sign(serialized_bytes, wallet.private_key) transaction_json["TxnSignature"] = signature return cast(Transaction, Transaction.from_xrpl(transaction_json))
def test_from_xrpl_memos(self): memo_type = "687474703a2f2f6578616d706c652e636f6d2f6d656d6f2f67656e65726963" tx = { "Account": "rnoGkgSpt6AX1nQxZ2qVGx7Fgw6JEcoQas", "TransactionType": "TrustSet", "Fee": "10", "Sequence": 17892983, "Flags": 131072, "Memos": [{ "Memo": { "MemoType": memo_type, "MemoData": "72656e74", } }], "SigningPubKey": "", "LimitAmount": { "currency": "USD", "issuer": "rBPvTKisx7UCGLDtiUZ6mDssXNREuVuL8Y", "value": "10", }, } expected = TrustSet( account="rnoGkgSpt6AX1nQxZ2qVGx7Fgw6JEcoQas", fee="10", sequence=17892983, flags=131072, memos=[Memo( memo_type=memo_type, memo_data="72656e74", )], limit_amount=IssuedCurrencyAmount( currency="USD", issuer="rBPvTKisx7UCGLDtiUZ6mDssXNREuVuL8Y", value="10"), ) self.assertEqual(Transaction.from_xrpl(tx), expected)
def test_from_xrpl_signers(self): txn_sig1 = ( "F80E201FE295AA08678F8542D8FC18EA18D582A0BD19BE77B9A24479418ADBCF4CAD28E7BD" "96137F88DE7736827C7AC6204FBA8DDADB7394E6D704CD1F4CD609") txn_sig2 = ( "036E95B8100EBA2A4A447A3AF24500261BF480A0E8D62EE15D03A697C85E73237A5202BD9A" "F2D9C68B8E8A5FA8B8DA4F8DABABE95E8401C5E57EC783291EF80C") pubkey1 = "ED621D6D4FF54E809397195C4E24EF05E8500A7CE45CDD211F523A892CDBCDCDB2" pubkey2 = "EDD3ABCFF008ECE9ED3073B41913619341519BFF01F07331B56E5D6D2EC4A94A57" tx = { "Account": "rnoGkgSpt6AX1nQxZ2qVGx7Fgw6JEcoQas", "TransactionType": "TrustSet", "Fee": "10", "Sequence": 17892983, "Flags": 131072, "Signers": [ { "Signer": { "Account": "rGVXgBz4NraZcwi5vqpmwPW6P4y74A4YvX", "TxnSignature": txn_sig1, "SigningPubKey": pubkey1, } }, { "Signer": { "Account": "rB5q2wsHeXdQeh2KFzBb1CujNAfSKys6GN", "TxnSignature": txn_sig2, "SigningPubKey": pubkey2, } }, ], "SigningPubKey": "", "LimitAmount": { "currency": "USD", "issuer": "rBPvTKisx7UCGLDtiUZ6mDssXNREuVuL8Y", "value": "10", }, } expected = TrustSet( account="rnoGkgSpt6AX1nQxZ2qVGx7Fgw6JEcoQas", fee="10", sequence=17892983, flags=131072, signers=[ Signer( account="rGVXgBz4NraZcwi5vqpmwPW6P4y74A4YvX", txn_signature=txn_sig1, signing_pub_key=pubkey1, ), Signer( account="rB5q2wsHeXdQeh2KFzBb1CujNAfSKys6GN", txn_signature=txn_sig2, signing_pub_key=pubkey2, ), ], limit_amount=IssuedCurrencyAmount( currency="USD", issuer="rBPvTKisx7UCGLDtiUZ6mDssXNREuVuL8Y", value="10"), ) self.assertEqual(Transaction.from_xrpl(tx), expected)