Module: Solace::Programs::TokenProgramInterface

Included in:
SplToken, Token2022
Defined in:
lib/solace/programs/token_program_interface.rb

Overview

Mixin describing the common surface of a token-program client.

The legacy SPL Token program and Token-2022 expose a wire-compatible base instruction set (Transfer, TransferChecked, CloseAccount, MintTo, InitializeMint). This module captures the shape of a client that speaks that surface — the public methods create_mint, mint_to, transfer, transfer_checked and their compose_* pairs — without binding to either program.

State (connection, program_id) lives on Base; this module is purely behavior. Including classes must implement four private readers that name the composer class for each operation:

  • #initialize_mint_composer_class

  • #mint_to_composer_class

  • #transfer_composer_class

  • #transfer_checked_composer_class

Each composer returned by those readers is itself bound to a single on-chain program, which is how this mixin keeps the boundary clean: SplToken and Token2022 share methods but never share a composer.

rubocop:disable Metrics/ModuleLength

See Also:

Since:

  • 0.1.5

Instance Method Summary collapse

Instance Method Details

#compose_create_mint(funder:, decimals:, mint_authority:, freeze_authority: nil, mint_account: Solace::Keypair.generate) ⇒ TransactionComposer

Prepares a new mint transaction.

rubocop:disable Metrics/MethodLength

Parameters:

  • funder (#to_s, PublicKey)

    The keypair that will pay for rent of the new mint account.

  • decimals (Integer)

    The number of decimal places for the token.

  • mint_authority (#to_s, PublicKey)

    The base58 public key for the mint authority.

  • freeze_authority (#to_s, PublicKey) (defaults to: nil)

    (Optional) The base58 public key for the freeze authority.

  • mint_account (#to_s, PublicKey) (defaults to: Solace::Keypair.generate)

    (Optional) The keypair for the new mint.

Returns:

Since:

  • 0.1.5



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/solace/programs/token_program_interface.rb', line 75

def compose_create_mint(
  funder:,
  decimals:,
  mint_authority:,
  freeze_authority: nil,
  mint_account: Solace::Keypair.generate
)
  # Mint accounts need 82 bytes of space, and we need to fund it with enough lamports to be rent-exempt
  rent_lamports = connection.get_minimum_lamports_for_rent_exemption(82)

  # Build the account for the mint
   = Composers::SystemProgramCreateAccountComposer.new(
    from: funder,
    new_account: ,
    owner: program_id,
    lamports: rent_lamports,
    space: 82
  )

  # Build the initialize mint composer (per-program class supplied by includer)
  initialize_mint_ix = initialize_mint_composer_class.new(
    decimals: decimals,
    mint_account: ,
    mint_authority: mint_authority,
    freeze_authority: freeze_authority
  )

  TransactionComposer
    .new(connection: connection)
    .add_instruction()
    .add_instruction(initialize_mint_ix)
end

#compose_mint_to(mint:, amount:, destination:, mint_authority:) ⇒ TransactionComposer

Prepares a mint_to instruction.

Parameters:

  • amount (Integer)

    The amount of tokens to mint.

  • mint (#to_s, PublicKey)

    The mint of the token.

  • destination (#to_s, PublicKey)

    The destination token account.

  • mint_authority (#to_s, PublicKey)

    The mint authority.

Returns:

Since:

  • 0.1.5



149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/solace/programs/token_program_interface.rb', line 149

def compose_mint_to(
  mint:,
  amount:,
  destination:,
  mint_authority:
)
  ix = mint_to_composer_class.new(
    amount: amount,
    mint: mint,
    destination: destination,
    mint_authority: mint_authority
  )

  TransactionComposer
    .new(connection: connection)
    .add_instruction(ix)
end

#compose_transfer(amount:, source:, destination:, owner:) ⇒ TransactionComposer

Prepares a transfer instruction.

Parameters:

  • source (#to_s, PublicKey)

    The source token account address.

  • destination (#to_s, PublicKey)

    The destination token account address.

  • amount (Integer)

    The number of tokens to transfer.

  • owner (#to_s, PublicKey)

    The owner of the source account.

Returns:

Since:

  • 0.1.5



206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
# File 'lib/solace/programs/token_program_interface.rb', line 206

def compose_transfer(
  amount:,
  source:,
  destination:,
  owner:
)
  ix = transfer_composer_class.new(
    amount: amount,
    owner: owner,
    source: source,
    destination: destination
  )

  TransactionComposer
    .new(connection: connection)
    .add_instruction(ix)
end

#compose_transfer_checked(to:, from:, mint:, authority:, amount:, decimals:) ⇒ TransactionComposer

Prepares a transfer_checked instruction.

Parameters:

  • amount (Integer)

    The number of tokens to transfer.

  • decimals (Integer)

    The number of decimals for the token.

  • from (#to_s, PublicKey)

    The source token account address.

  • to (#to_s, PublicKey)

    The destination token account address.

  • mint (#to_s, PublicKey)

    The mint address.

  • authority (#to_s, PublicKey)

    The owner of the source account.

Returns:

Since:

  • 0.1.5



266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
# File 'lib/solace/programs/token_program_interface.rb', line 266

def compose_transfer_checked(
  to:,
  from:,
  mint:,
  authority:,
  amount:,
  decimals:
)
  ix = transfer_checked_composer_class.new(
    to: to,
    from: from,
    mint: mint,
    authority: authority,
    amount: amount,
    decimals: decimals
  )

  TransactionComposer
    .new(connection: connection)
    .add_instruction(ix)
end

#create_mint(payer:, sign: true, execute: true, **composer_opts) {|composer| ... } ⇒ Transaction

Creates a new mint, signs it, and (optionally) sends it.

Parameters:

  • payer (#to_s, PublicKey)

    The keypair that will pay for fees and rent.

  • sign (Boolean) (defaults to: true)

    Whether to sign the transaction.

  • execute (Boolean) (defaults to: true)

    Whether to execute the transaction.

  • composer_opts (Hash)

    Options for #compose_create_mint.

Yields:

  • (composer)

Returns:

Since:

  • 0.1.5



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/solace/programs/token_program_interface.rb', line 39

def create_mint(
  payer:,
  sign: true,
  execute: true,
  **composer_opts
)
  composer = compose_create_mint(**composer_opts)

  yield composer if block_given?

  tx = composer
       .set_fee_payer(payer)
       .compose_transaction

  if sign
    tx.sign(
      payer,
      composer_opts[:funder],
      composer_opts[:mint_account]
    )

    connection.send_transaction(tx.serialize) if execute
  end

  tx
end

#mint_to(payer:, sign: true, execute: true, **composer_opts) {|composer| ... } ⇒ Transaction

Mints tokens to a token account.

Parameters:

  • payer (#to_s, PublicKey)

    The keypair that will pay for fees and rent.

  • sign (Boolean) (defaults to: true)

    Whether to sign the transaction.

  • execute (Boolean) (defaults to: true)

    Whether to execute the transaction.

  • composer_opts (Hash)

    Options for #compose_mint_to.

Yields:

  • (composer)

Returns:

Since:

  • 0.1.5



116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/solace/programs/token_program_interface.rb', line 116

def mint_to(
  payer:,
  sign: true,
  execute: true,
  **composer_opts
)
  composer = compose_mint_to(**composer_opts)

  yield composer if block_given?

  tx = composer
       .set_fee_payer(payer)
       .compose_transaction

  if sign
    tx.sign(
      payer,
      composer_opts[:mint_authority]
    )

    connection.send_transaction(tx.serialize) if execute
  end

  tx
end

#transfer(payer:, sign: true, execute: true, **composer_opts) {|composer| ... } ⇒ Transaction

Transfers tokens from one account to another.

Parameters:

  • payer (#to_s, PublicKey)

    The keypair that will pay for fees and rent.

  • sign (Boolean) (defaults to: true)

    Whether to sign the transaction.

  • execute (Boolean) (defaults to: true)

    Whether to execute the transaction.

  • composer_opts (Hash)

    Options for #compose_transfer.

Yields:

  • (composer)

Returns:

Since:

  • 0.1.5



174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
# File 'lib/solace/programs/token_program_interface.rb', line 174

def transfer(
  payer:,
  sign: true,
  execute: true,
  **composer_opts
)
  composer = compose_transfer(**composer_opts)

  yield composer if block_given?

  tx = composer
       .set_fee_payer(payer)
       .compose_transaction

  if sign
    tx.sign(
      payer,
      composer_opts[:owner]
    )

    connection.send_transaction(tx.serialize) if execute
  end
  tx
end

#transfer_checked(payer:, sign: true, execute: true, **composer_opts) {|composer| ... } ⇒ Transaction

Transfers tokens with decimal precision and validation checks.

Parameters:

  • payer (#to_s, PublicKey)

    The keypair that will pay for fees and rent.

  • sign (Boolean) (defaults to: true)

    Whether to sign the transaction.

  • execute (Boolean) (defaults to: true)

    Whether to execute the transaction.

  • composer_opts (Hash)

Yields:

  • (composer)

Returns:

Since:

  • 0.1.5



231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
# File 'lib/solace/programs/token_program_interface.rb', line 231

def transfer_checked(
  payer:,
  sign: true,
  execute: true,
  **composer_opts
)
  composer = compose_transfer_checked(**composer_opts)

  yield composer if block_given?

  tx = composer
       .set_fee_payer(payer)
       .compose_transaction

  if sign
    tx.sign(
      payer,
      composer_opts[:authority]
    )

    connection.send_transaction(tx.serialize) if execute
  end

  tx
end