Skip to content

Commit cc146bd

Browse files
authored
Merge pull request #81 from mircial/feature/transaction
Feature/transaction
2 parents 65d06c9 + 505b721 commit cc146bd

File tree

4 files changed

+53
-11
lines changed

4 files changed

+53
-11
lines changed

solathon/client.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from __future__ import annotations
22

3-
from typing import Any, List, Literal, Optional, Text, Union
3+
from typing import Any, Dict, List, Literal, Optional, Text, Union
44

55
from .utils import RPCRequestError, validate_commitment
66
from .publickey import PublicKey
@@ -765,12 +765,13 @@ def request_airdrop(
765765
"""
766766
return self.build_and_send_request("requestAirdrop", [public_key, lamports])
767767

768-
def send_transaction(self, transaction: Transaction) -> RPCResponse[str] | str:
768+
def send_transaction(self, transaction: Transaction, options: Optional[Dict] = None) -> RPCResponse[str] | str:
769769
"""
770770
Sends a transaction to the Solana network.
771771
772772
Args:
773773
transaction (Transaction): The transaction to send.
774+
options (Dict): Options for sending transactions
774775
775776
Returns:
776777
RPCResponse: The response from the Solana network.
@@ -780,10 +781,15 @@ def send_transaction(self, transaction: Transaction) -> RPCResponse[str] | str:
780781
if recent_blockhash is None:
781782
blockhash_resp = self.get_latest_blockhash()
782783
recent_blockhash = blockhash_resp.blockhash
784+
785+
if options:
786+
options = options
787+
else:
788+
options = {"encoding": "base64"}
783789

784790
transaction.recent_blockhash = recent_blockhash
785791
transaction.sign()
786792

787793
return self.build_and_send_request(
788-
"sendTransaction", [transaction.serialize(), {"encoding": "base64"}]
794+
"sendTransaction", [transaction.serialize(), options]
789795
)

solathon/core/instructions.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,19 @@ class Instruction(NamedTuple):
2323
program_id: PublicKey
2424
data: bytes = bytes(0)
2525

26+
def _to_json(self):
27+
return {
28+
"keys": [
29+
{
30+
"pubkey": key.public_key.base58_encode(),
31+
"isSigner": key.is_signer,
32+
"isWritable": key.is_writable
33+
}
34+
for key in self.keys
35+
],
36+
"programId": self.program_id.base58_encode(),
37+
"data": list(self.data)
38+
}
2639

2740
def create_account(
2841
from_public_key: PublicKey,

solathon/core/message.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,8 @@ def serialize(self) -> bytes:
137137

138138
return bytes(message_buffer)
139139

140-
@classmethod
141-
def from_buffer(cls, buffer: bytes) -> Message:
140+
@staticmethod
141+
def from_buffer(buffer: bytes) -> Message:
142142
# Reference: https://github.com/solana-labs/solana-web3.js/blob/a1fafee/packages/library-legacy/src/message/legacy.ts#L267
143143

144144
buffer_array = list(buffer)

solathon/transaction.py

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@ def __init__(self, **config):
3131
self.fee_payer: PublicKey = config.get("fee_payer")
3232
self.nonce_info = config.get("nonce_info")
3333
self.recent_blockhash = config.get("recent_blockhash")
34-
self.signers: List[PublicKey] | List[Keypair] = config.get("signers")
35-
self.instructions: List[Instruction] = []
36-
self.signatures: List[PKSigPair] = []
34+
self.signers: list[PublicKey] | list[Keypair] = config.get("signers")
35+
self.instructions: list[Instruction] = []
36+
self.signatures: list[PKSigPair] = config.get("signatures", [])
3737
if "instructions" in config:
3838
instructions: Instruction = config.get("instructions")
3939
if (
@@ -60,9 +60,29 @@ def to_public_key(signer: PublicKey | Keypair) -> PublicKey:
6060
public_key=to_public_key(signer)
6161
) for signer in self.signers]
6262

63-
self.signatures = pk_sig_pairs
64-
63+
if not self.signatures:
64+
self.signatures = pk_sig_pairs
65+
66+
self._message: Message = None
67+
self.json = None
68+
69+
def _to_json(self):
70+
return {
71+
"recentBlockhash": self.recent_blockhash if hasattr(self, 'recent_blockhash') else None,
72+
"feePayer": self.fee_payer.base58_encode() if hasattr(self, 'fee_payer') else None,
73+
"nonceInfo": {
74+
"nonce": self.nonce_info.nonce,
75+
"nonceInstruction": self.nonce_info.nonce_instruction._to_json()
76+
} if self.nonce_info else None,
77+
"instructions": [instruction._to_json() for instruction in self.instructions],
78+
"signers": [signature.public_key.base58_encode() for signature in self.signatures]
79+
}
80+
6581
def compile_transaction(self) -> bytes:
82+
# Reference: https://github.com/solana-labs/solana-web3.js/blob/a1fafee/packages/library-legacy/src/transaction/legacy.ts#L367
83+
if self._message and self._to_json() == self.json:
84+
return self._message.serialize()
85+
6686
if self.nonce_info:
6787
self.recent_blockhash = self.nonce_info.nonce
6888

@@ -282,13 +302,16 @@ def populate(self, message: Message, signatures: List[bytes], signers: List[Keyp
282302
))
283303

284304
fee_payer = message.account_keys[0] if message.header.num_required_signatures > 0 else None
285-
return Transaction(
305+
transaction = Transaction(
286306
fee_payer=fee_payer,
287307
recent_blockhash=message.recent_blockhash,
288308
signatures=decoded_signatures,
289309
instructions=instructions,
290310
signers = signers
291311
)
312+
transaction._message = message
313+
transaction.json = transaction._to_json()
314+
return transaction
292315

293316
@classmethod
294317
def from_buffer(self, buffer: bytes, signers: List[Keypair]) -> Transaction:

0 commit comments

Comments
 (0)