Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 122 additions & 0 deletions pkg/indexer/store/model.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
package store

import (
"time"

"github.com/uptrace/bun"

"github.com/chainsafe/canton-middleware/pkg/indexer"
)

// EventDao maps to the 'indexer_events' table.
// ContractID is the idempotency key — one row per TokenTransferEvent contract.
type EventDao struct {
bun.BaseModel `bun:"table:indexer_events"`
ContractID string `bun:",pk,type:varchar(255)"`
InstrumentID string `bun:",notnull,type:varchar(255)"`
InstrumentAdmin string `bun:",notnull,type:varchar(255)"`
Issuer string `bun:",notnull,type:varchar(255)"`
EventType string `bun:",notnull,type:varchar(20)"`
Amount string `bun:",notnull,type:text"`
FromPartyID *string `bun:",type:varchar(255)"`
ToPartyID *string `bun:",type:varchar(255)"`
ExternalTxID *string `bun:",type:varchar(255)"`
ExternalAddress *string `bun:",type:varchar(255)"`
Fingerprint *string `bun:",type:varchar(255)"`
TxID string `bun:",notnull,type:varchar(255)"`
LedgerOffset int64 `bun:",notnull"`
Timestamp time.Time `bun:",notnull"`
EffectiveTime time.Time `bun:",notnull"`
}

// TokenDao maps to the 'indexer_tokens' table.
// The composite key (InstrumentAdmin, InstrumentID) uniquely identifies a token.
type TokenDao struct {
bun.BaseModel `bun:"table:indexer_tokens"`
InstrumentAdmin string `bun:",pk,type:varchar(255)"`
InstrumentID string `bun:",pk,type:varchar(255)"`
Issuer string `bun:",notnull,type:varchar(255)"`
TotalSupply string `bun:",notnull,type:text,default:'0'"`
HolderCount int64 `bun:",notnull,default:0"`
FirstSeenOffset int64 `bun:",notnull"`
FirstSeenAt time.Time `bun:",notnull"`
}

// BalanceDao maps to the 'indexer_balances' table.
// The composite key (PartyID, InstrumentAdmin, InstrumentID) is unique per holding.
type BalanceDao struct {
bun.BaseModel `bun:"table:indexer_balances"`
PartyID string `bun:",pk,type:varchar(255)"`
InstrumentAdmin string `bun:",pk,type:varchar(255)"`
InstrumentID string `bun:",pk,type:varchar(255)"`
Amount string `bun:",notnull,type:text"`
}

// OffsetDao maps to the 'indexer_offsets' table.
// A single row (ID=1) holds the latest persisted ledger offset.
type OffsetDao struct {
bun.BaseModel `bun:"table:indexer_offsets"`
ID int `bun:",pk,default:1"`
LedgerOffset int64 `bun:",notnull,default:0"`
}

func toEventDao(e *indexer.ParsedEvent) *EventDao {
return &EventDao{
ContractID: e.ContractID,
InstrumentID: e.InstrumentID,
InstrumentAdmin: e.InstrumentAdmin,
Issuer: e.Issuer,
EventType: string(e.EventType),
Amount: e.Amount,
FromPartyID: e.FromPartyID,
ToPartyID: e.ToPartyID,
ExternalTxID: e.ExternalTxID,
ExternalAddress: e.ExternalAddress,
Fingerprint: e.Fingerprint,
TxID: e.TxID,
LedgerOffset: e.LedgerOffset,
Timestamp: e.Timestamp,
EffectiveTime: e.EffectiveTime,
}
}

func fromEventDao(d *EventDao) *indexer.ParsedEvent {
return &indexer.ParsedEvent{
ContractID: d.ContractID,
InstrumentID: d.InstrumentID,
InstrumentAdmin: d.InstrumentAdmin,
Issuer: d.Issuer,
EventType: indexer.EventType(d.EventType),
Amount: d.Amount,
FromPartyID: d.FromPartyID,
ToPartyID: d.ToPartyID,
ExternalTxID: d.ExternalTxID,
ExternalAddress: d.ExternalAddress,
Fingerprint: d.Fingerprint,
TxID: d.TxID,
LedgerOffset: d.LedgerOffset,
Timestamp: d.Timestamp,
EffectiveTime: d.EffectiveTime,
}
}

func fromTokenDao(d *TokenDao) *indexer.Token {
return &indexer.Token{
InstrumentAdmin: d.InstrumentAdmin,
InstrumentID: d.InstrumentID,
Issuer: d.Issuer,
TotalSupply: d.TotalSupply,
HolderCount: d.HolderCount,
FirstSeenOffset: d.FirstSeenOffset,
FirstSeenAt: d.FirstSeenAt,
}
}

func fromBalanceDao(d *BalanceDao) *indexer.Balance {
return &indexer.Balance{
PartyID: d.PartyID,
InstrumentAdmin: d.InstrumentAdmin,
InstrumentID: d.InstrumentID,
Amount: d.Amount,
}
}
Loading
Loading