Class: Solrengine::Sdp::TokenBurn

Inherits:
ActiveRecord::Base
  • Object
show all
Defined in:
app/models/solrengine/sdp/token_burn.rb

Overview

Engine-owned record of every burn attempted through SDP — the redeem-path counterpart to TokenMint, with the same never-double-* discipline.

Status: burning → in_flight → burned | failed | unknown (see TokenMint for the rationale; a timed-out burn stays ‘unknown` — never re-sent, no listing to reconcile against).

Unlike a mint (signed by the token’s mint authority), a burn is signed by the SOURCE wallet’s owner: signing_wallet_id is the user’s custodial wallet, not the treasury.

Constant Summary collapse

MEMO_TOKEN_PREFIX =
"sdpburn-"
MEMO_SEPARATOR =
" | "
STATUSES =
%w[burning in_flight burned failed unknown].freeze
TERMINAL_STATUSES =
%w[burned failed unknown].freeze

Instance Method Summary collapse

Instance Method Details

#claim!Object

Atomic claim: burning → in_flight in one UPDATE, so a crash + retry or two workers can never send the same burn twice.



39
40
41
42
43
# File 'app/models/solrengine/sdp/token_burn.rb', line 39

def claim!
  won = self.class.where(id: id, status: "burning").update_all(status: "in_flight", updated_at: Time.current)
  reload if won == 1
  won == 1
end

#composed_memoObject



69
70
71
# File 'app/models/solrengine/sdp/token_burn.rb', line 69

def composed_memo
  [ memo, memo_token ].compact.join(MEMO_SEPARATOR)
end

#pending?Boolean

Returns:

  • (Boolean)


33
34
35
# File 'app/models/solrengine/sdp/token_burn.rb', line 33

def pending?
  %w[burning in_flight].include?(status)
end

#submit_to_sdp!Object

The single, never-retried burn POST.



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'app/models/solrengine/sdp/token_burn.rb', line 46

def submit_to_sdp!
  tx = Solrengine::Sdp.client.burn_token(
    token.sdp_token_id,
    signing_wallet_id: signing_wallet_id,
    source: source,
    amount: amount,
    memo: composed_memo
  )
  update!(
    status: terminal_for(tx.status),
    signature: tx.signature,
    sdp_transaction_id: tx.id,
    sdp_error: tx.error,
    settled_at: Time.current
  )
rescue ::Sdp::Timeout
  update!(status: "unknown")
rescue ::Sdp::Unavailable => e
  update!(status: "failed", sdp_error: "unsent: #{e.message}", settled_at: Time.current)
rescue ::Sdp::Error => e
  update!(status: "failed", sdp_error: e.message, settled_at: Time.current)
end