Class: SolanaRuby::TransactionHelper

Inherits:
Object
  • Object
show all
Defined in:
lib/solana_ruby/transaction_helper.rb

Constant Summary collapse

SYSTEM_PROGRAM_ID =

Constants for program IDs

'11111111111111111111111111111111'
TOKEN_PROGRAM_ID =
'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'
ASSOCIATED_TOKEN_PROGRAM_ID =
'ATokenGP3evbxxpQ7bYPLNNaxD2c4bqtvWjpKbmz6HjH'
INSTRUCTION_LAYOUTS =
{
  # Native SOL transfer
  sol_transfer: {
    instruction: :uint32,
    lamports: :near_int64
  },
  # SPL token transfer
  spl_transfer: {
    instruction: :uint8,
    amount: :uint64
  },
# Create account layout
  create_account: {
    instruction: :uint32,
    lamports: :uint64,
    space: :uint64,
    program_id: :blob32
  }
}

Class Method Summary collapse

Class Method Details

.account_instruction(from_pubkey, new_account_pubkey, lamports, space, program_id) ⇒ Object

Method to create a system account (e.g., for SPL token or SOL)



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/solana_ruby/transaction_helper.rb', line 32

def self.(from_pubkey, , lamports, space, program_id)
  # Encode the instruction data
  instruction_data = encode_data(
    INSTRUCTION_LAYOUTS[:create_account],
    {
      instruction: 0,      # '0' corresponds to the Create Account instruction
      lamports: lamports,  # The amount of lamports to transfer to the new account
      space: space,        # Amount of space allocated for the account's data
      program_id: Base58.base58_to_binary(program_id, :bitcoin).bytes # Convert public key to binary
    }
  )

  # Construct the transaction instruction
   = TransactionInstruction.new(
    keys: [
      { pubkey: from_pubkey, is_signer: true, is_writable: true },  # Funder's account
      { pubkey: , is_signer: true, is_writable: true } # New account
    ],
    program_id: program_id,  # Use Solana's system program for account creation
    data: instruction_data   # Encoded instruction data
  )

  # return instruction data
  
end

.create_account(from_pubkey, new_account_pubkey, lamports, space, recent_blockhash, program_id = SYSTEM_PROGRAM_ID) ⇒ Object



59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/solana_ruby/transaction_helper.rb', line 59

def self.(from_pubkey, , lamports, space, recent_blockhash, program_id = SYSTEM_PROGRAM_ID)
  # Create the transaction
  transaction = Transaction.new
  transaction.set_fee_payer(from_pubkey)
  transaction.set_recent_blockhash(recent_blockhash)

  # Add the create account instruction to the transaction
  instruction = (from_pubkey, , lamports, space, program_id)
  transaction.add_instruction(instruction)
  
  # return the transaction for signing
  transaction
end

.create_associated_token_account(payer, mint, owner) ⇒ Object

Method to create an associated token account for a given token mint



123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/solana_ruby/transaction_helper.rb', line 123

def self.(payer, mint, owner)
  data = [0, 0, 0, 0]  # No data required for account creation
   = TransactionInstruction.new(
    keys: [
      { pubkey: payer, is_signer: true, is_writable: true },
      { pubkey: associated_token, is_signer: false, is_writable: true },
      { pubkey: owner, is_signer: false, is_writable: false },
      { pubkey: mint, is_signer: false, is_writable: false },
      { pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, is_signer: false, is_writable: false },
      { pubkey: SYSTEM_PROGRAM_ID, is_signer: false, is_writable: false }
    ],
    program_id: ASSOCIATED_TOKEN_PROGRAM_ID,
    data: data
  )
  
end

.decode_data(fields, data) ⇒ Object

Utility to decode data using predefined layouts



147
148
149
150
# File 'lib/solana_ruby/transaction_helper.rb', line 147

def self.decode_data(fields, data)
  layout = SolanaRuby::DataTypes::Layout.new(fields)
  layout.deserialize(data)
end

.encode_data(fields, data) ⇒ Object

Utility to encode data using predefined layouts



141
142
143
144
# File 'lib/solana_ruby/transaction_helper.rb', line 141

def self.encode_data(fields, data)
  layout = SolanaRuby::DataTypes::Layout.new(fields)
  layout.serialize(data)
end

.new_spl_token_transaction(source, destination, owner, amount, recent_blockhash) ⇒ Object

Helper to create a new transaction for SPL token transfer



113
114
115
116
117
118
119
120
# File 'lib/solana_ruby/transaction_helper.rb', line 113

def self.new_spl_token_transaction(source, destination, owner, amount, recent_blockhash)
  transaction = Transaction.new
  transaction.set_fee_payer(owner)
  transaction.set_recent_blockhash(recent_blockhash)
  transfer_instruction = transfer_spl_token(source, destination, owner, amount)
  transaction.add_instruction(transfer_instruction)
  transaction
end

.sol_transfer(from_pubkey, to_pubkey, lamports, recent_blockhash) ⇒ Object

Helper to create a new transaction for SOL transfer



88
89
90
91
92
93
94
95
# File 'lib/solana_ruby/transaction_helper.rb', line 88

def self.sol_transfer(from_pubkey, to_pubkey, lamports, recent_blockhash)
  transaction = Transaction.new
  transaction.set_fee_payer(from_pubkey)
  transaction.set_recent_blockhash(recent_blockhash)
  transfer_instruction = transfer_sol_instruction(from_pubkey, to_pubkey, lamports)
  transaction.add_instruction(transfer_instruction)
  transaction
end

.transfer_sol_instruction(from_pubkey, to_pubkey, lamports) ⇒ Object

Method to create a SOL transfer instruction



74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/solana_ruby/transaction_helper.rb', line 74

def self.transfer_sol_instruction(from_pubkey, to_pubkey, lamports)
  fields = INSTRUCTION_LAYOUTS[:sol_transfer]
  data = encode_data(fields, { instruction: 2, lamports: lamports })
  TransactionInstruction.new(
    keys: [
      { pubkey: from_pubkey, is_signer: true, is_writable: true },
      { pubkey: to_pubkey, is_signer: false, is_writable: true }
    ],
    program_id: SYSTEM_PROGRAM_ID,
    data: data
  )
end

.transfer_spl_token(source, destination, owner, amount) ⇒ Object

Method to create an SPL token transfer instruction



98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/solana_ruby/transaction_helper.rb', line 98

def self.transfer_spl_token(source, destination, owner, amount)
  fields = INSTRUCTION_LAYOUTS[:spl_transfer]
  data = encode_data(fields, { instruction: 3, amount: amount }) # Instruction type 3: Transfer tokens
  TransactionInstruction.new(
    keys: [
      { pubkey: source, is_signer: false, is_writable: true },
      { pubkey: destination, is_signer: false, is_writable: true },
      { pubkey: owner, is_signer: true, is_writable: false }
    ],
    program_id: TOKEN_PROGRAM_ID,
    data: data
  )
end