Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: show tlv records in transaction popup #365

Merged
merged 23 commits into from
Aug 9, 2024
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
33a5714
feat: show tlv records in transaction popup
im-adithya Jul 29, 2024
832bbf4
chore: add podcastinginfo component
im-adithya Jul 30, 2024
10afe14
chore: remove ? in podcasting info component
im-adithya Jul 30, 2024
65e6752
Merge branch 'master' into task-tlv-records
im-adithya Aug 5, 2024
308e4ff
chore: decode tlv record values in backend
im-adithya Aug 6, 2024
185895f
chore: add backup for tx description
im-adithya Aug 6, 2024
eb84d63
feat: add boostagram column and use jsonb in metadata
im-adithya Aug 6, 2024
a6406a8
chore: do not modify metadata while parsing
im-adithya Aug 7, 2024
25064af
chore: combine boostagram and metadata migration
im-adithya Aug 7, 2024
d9d99c0
feat: extract description from custom records
im-adithya Aug 8, 2024
178410f
chore: fix keysend tests
im-adithya Aug 8, 2024
4ee56dc
chore: change metadata param type in makeinvoice
im-adithya Aug 8, 2024
41c290b
chore: fix make invoice tests
im-adithya Aug 8, 2024
e12433e
chore: metadata fixes
im-adithya Aug 8, 2024
168d7cf
Merge remote-tracking branch 'origin/master' into task-tlv-records
rolznz Aug 8, 2024
3b96728
fix: boostragram and metadata migration
rolznz Aug 8, 2024
7c29b25
chore: set metadata json column to null if empty
im-adithya Aug 8, 2024
8760830
fix: remove jsonb from migration
im-adithya Aug 8, 2024
fe59323
chore: code cleanup, rename api models, fix metadata usage
rolznz Aug 9, 2024
662c01d
fix: metadata format
rolznz Aug 9, 2024
fb30ae6
chore: remove unused contant
rolznz Aug 9, 2024
e6d9930
fix: tests
rolznz Aug 9, 2024
268b69a
chore: improve tests
rolznz Aug 9, 2024
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
22 changes: 21 additions & 1 deletion api/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,27 @@ type Transaction struct {
CreatedAt string `json:"created_at"`
SettledAt *string `json:"settled_at"`
AppId *uint `json:"app_id"`
Metadata interface{} `json:"metadata,omitempty"`
Metadata *Metadata `json:"metadata,omitempty"`
rolznz marked this conversation as resolved.
Show resolved Hide resolved
Boostagram *Boostagram `json:"boostagram,omitempty"`
}

type Metadata = lnclient.Metadata

type Boostagram struct {
AppName string `json:"appName"`
Name string `json:"name"`
Podcast string `json:"podcast"`
URL string `json:"url"`
Episode string `json:"episode,omitempty"`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@im-adithya why do some have omitempty others not? is it required?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I took this from LBE repo here, whereever we have ?: in the Boostagram type there, I've omitted

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but it looks completely arbitrary and doesn't seem to follow the spec - https://github.com/lightning/blips/blob/master/blip-0010.md#fields

FeedId string `json:"feedId,omitempty"`
ItemId string `json:"itemId,omitempty"`
Timestamp int64 `json:"ts,omitempty"`
Message string `json:"message,omitempty"`
SenderId string `json:"senderId"`
SenderName string `json:"senderName"`
Time string `json:"time"`
Action string `json:"action"`
ValueMsatTotal int64 `json:"valueMsatTotal"`
}

// debug api
Expand Down
39 changes: 36 additions & 3 deletions api/transactions.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,9 @@ func toApiTransaction(transaction *transactions.Transaction) *Transaction {
preimage = transaction.Preimage
}

var metadata interface{}
if transaction.Metadata != "" {
jsonErr := json.Unmarshal([]byte(transaction.Metadata), &metadata)
var metadata *Metadata
rolznz marked this conversation as resolved.
Show resolved Hide resolved
if transaction.Metadata != nil {
jsonErr := json.Unmarshal(transaction.Metadata, &metadata)
if jsonErr != nil {
logger.Logger.WithError(jsonErr).WithFields(logrus.Fields{
"id": transaction.ID,
Expand All @@ -84,6 +84,19 @@ func toApiTransaction(transaction *transactions.Transaction) *Transaction {
}
}

var boostagram *Boostagram
rolznz marked this conversation as resolved.
Show resolved Hide resolved
if transaction.Boostagram != nil {
var txBoostagram *transactions.Boostagram
jsonErr := json.Unmarshal(transaction.Boostagram, &txBoostagram)
if jsonErr != nil {
logger.Logger.WithError(jsonErr).WithFields(logrus.Fields{
"id": transaction.ID,
rolznz marked this conversation as resolved.
Show resolved Hide resolved
"boostagram": transaction.Boostagram,
}).Error("Failed to deserialize transaction boostagram info")
}
boostagram = toApiBoostagram(txBoostagram)
}

return &Transaction{
Type: transaction.Type,
Invoice: transaction.PaymentRequest,
Expand All @@ -97,5 +110,25 @@ func toApiTransaction(transaction *transactions.Transaction) *Transaction {
CreatedAt: createdAt,
SettledAt: settledAt,
Metadata: metadata,
Boostagram: boostagram,
}
}

func toApiBoostagram(boostagram *transactions.Boostagram) *Boostagram {
return &Boostagram{
AppName: boostagram.AppName,
Name: boostagram.Name,
Podcast: boostagram.Podcast,
URL: boostagram.URL,
Episode: boostagram.Episode,
FeedId: boostagram.FeedId,
ItemId: boostagram.ItemId,
Timestamp: boostagram.Timestamp,
Message: boostagram.Message,
SenderId: boostagram.SenderId,
SenderName: boostagram.SenderName,
Time: boostagram.Time,
Action: boostagram.Action,
ValueMsatTotal: boostagram.ValueMsatTotal,
}
}
30 changes: 30 additions & 0 deletions db/migrations/202408061737_add_boostagrams_and_use_json.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package migrations

import (
_ "embed"

"github.com/go-gormigrate/gormigrate/v2"
"gorm.io/gorm"
)

// This migration adds boostagram column to transactions
var _202408061737_add_boostagrams_and_use_json = &gormigrate.Migration{
ID: "202408061737_add_boostagrams_and_use_json",
Migrate: func(db *gorm.DB) error {
err := db.Transaction(func(tx *gorm.DB) error {
return tx.Exec(`
ALTER TABLE transactions ADD COLUMN boostagram JSONB;
ALTER TABLE transactions ADD COLUMN metadata_temp JSONB;
UPDATE transactions SET metadata_temp = "";
UPDATE transactions SET metadata_temp = json(metadata) where metadata != "";
rolznz marked this conversation as resolved.
Show resolved Hide resolved
im-adithya marked this conversation as resolved.
Show resolved Hide resolved
ALTER TABLE transactions DROP COLUMN metadata;
ALTER TABLE transactions RENAME COLUMN metadata_temp TO metadata;
`).Error
})

return err
},
Rollback: func(tx *gorm.DB) error {
return nil
},
}
1 change: 1 addition & 0 deletions db/migrations/migrate.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ func Migrate(gormDB *gorm.DB) error {
_202407151352_autoincrement,
_202407201604_transactions_indexes,
_202407262257_remove_invalid_scopes,
_202408061737_add_boostagrams_and_use_json,
})

return m.Migrate()
Expand Down
9 changes: 7 additions & 2 deletions db/models.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package db

import "time"
import (
"time"

"gorm.io/datatypes"
)

type UserConfig struct {
ID uint
Expand Down Expand Up @@ -75,8 +79,9 @@ type Transaction struct {
ExpiresAt *time.Time
UpdatedAt time.Time
SettledAt *time.Time
Metadata string
Metadata datatypes.JSON
SelfPayment bool
Boostagram datatypes.JSON
}

type DBService interface {
Expand Down
63 changes: 63 additions & 0 deletions frontend/src/components/PodcastingInfo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { Boostagram } from "src/types";

function PodcastingInfo({ boost }: { boost: Boostagram }) {
return (
<>
{boost.message && (
<div className="mt-6">
<p>Message</p>
<p className="text-muted-foreground break-all">{boost.message}</p>
</div>
)}
{boost.podcast && (
<div className="mt-6">
<p>Podcast</p>
<p className="text-muted-foreground break-all">{boost.podcast}</p>
</div>
)}
{boost.episode && (
<div className="mt-6">
<p>Episode</p>
<p className="text-muted-foreground break-all">{boost.episode}</p>
</div>
)}
{boost.action && (
<div className="mt-6">
<p>Action</p>
<p className="text-muted-foreground break-all">{boost.action}</p>
</div>
)}
{boost.ts && (
<div className="mt-6">
<p>Timestamp</p>
<p className="text-muted-foreground break-all">{boost.ts}</p>
</div>
)}
{boost.value_msat_total && (
<div className="mt-6">
<p>Total amount</p>
<p className="text-muted-foreground break-all">
{new Intl.NumberFormat(undefined, {}).format(
Math.floor(boost.value_msat_total / 1000)
)}{" "}
{Math.floor(boost.value_msat_total / 1000) == 1 ? "sat" : "sats"}
</p>
</div>
)}
{boost.sender_name && (
rolznz marked this conversation as resolved.
Show resolved Hide resolved
<div className="mt-6">
<p>Sender</p>
<p className="text-muted-foreground break-all">{boost.sender_name}</p>
</div>
)}
{boost.app_name && (
<div className="mt-6">
<p>App</p>
<p className="text-muted-foreground break-all">{boost.app_name}</p>
</div>
)}
</>
);
}

export default PodcastingInfo;
92 changes: 48 additions & 44 deletions frontend/src/components/TransactionItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
} from "lucide-react";
import React from "react";
import AppAvatar from "src/components/AppAvatar";
import PodcastingInfo from "src/components/PodcastingInfo";
import {
Credenza,
CredenzaBody,
Expand Down Expand Up @@ -191,52 +192,55 @@ function TransactionItem({ tx }: Props) {
</div>
)}
</CredenzaBody>
<CredenzaFooter className="!justify-start mt-4 !flex-col">
<div
className="flex items-center gap-2 cursor-pointer"
onClick={() => setShowDetails(!showDetails)}
>
Details
{showDetails ? (
<ChevronUp className="w-4 h-4" />
) : (
<ChevronDown className="w-4 h-4" />
)}
</div>
{showDetails && (
<>
<div className="mt-6 !ml-0">
<p>Preimage</p>
<div className="flex items-center gap-4">
<p className="text-muted-foreground break-all">
{tx.preimage}
</p>
<CopyIcon
className="cursor-pointer text-muted-foreground w-6 h-6"
onClick={() => {
if (tx.preimage) {
copy(tx.preimage);
}
}}
/>
<CredenzaFooter>
<div className="mt-4 w-full">
<div
className="flex items-center gap-2 cursor-pointer"
onClick={() => setShowDetails(!showDetails)}
>
Details
{showDetails ? (
<ChevronUp className="w-4 h-4" />
) : (
<ChevronDown className="w-4 h-4" />
)}
</div>
{showDetails && (
<>
{tx.boostagram && <PodcastingInfo boost={tx.boostagram} />}
<div className="mt-6">
<p>Preimage</p>
<div className="flex items-center gap-4">
<p className="text-muted-foreground break-all">
{tx.preimage}
</p>
<CopyIcon
className="cursor-pointer text-muted-foreground w-6 h-6"
onClick={() => {
if (tx.preimage) {
copy(tx.preimage);
}
}}
/>
</div>
</div>
</div>
<div className="mt-6 !ml-0">
<p>Hash</p>
<div className="flex items-center gap-4">
<p className="text-muted-foreground break-all">
{tx.payment_hash}
</p>
<CopyIcon
className="cursor-pointer text-muted-foreground w-6 h-6"
onClick={() => {
copy(tx.payment_hash);
}}
/>
<div className="mt-6">
<p>Hash</p>
<div className="flex items-center gap-4">
<p className="text-muted-foreground break-all">
{tx.payment_hash}
</p>
<CopyIcon
className="cursor-pointer text-muted-foreground w-6 h-6"
onClick={() => {
copy(tx.payment_hash);
}}
/>
</div>
</div>
</div>
</>
)}
</>
)}
</div>
</CredenzaFooter>
</CredenzaContent>
</Credenza>
Expand Down
20 changes: 19 additions & 1 deletion frontend/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,25 @@ export type Transaction = {
fees_paid: number;
created_at: string;
settled_at: string | undefined;
metadata: unknown;
metadata?: Record<string, unknown>;
boostagram?: Boostagram;
};

export type Boostagram = {
app_name: string;
rolznz marked this conversation as resolved.
Show resolved Hide resolved
name: string;
podcast: string;
url: string;
episode?: string;
feedID?: string;
itemID?: string;
ts?: number;
message?: string;
sender_id: string;
sender_name: string;
time: string;
action: "boost";
value_msat_total: number;
};

export type NewChannelOrderStatus = "pay" | "paid" | "success" | "opening";
Expand Down
6 changes: 5 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ require (
)

require (
filippo.io/edwards25519 v1.1.0 // indirect
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
github.com/BurntSushi/toml v1.2.1 // indirect
github.com/DataDog/datadog-go/v5 v5.3.0 // indirect
Expand Down Expand Up @@ -70,6 +71,7 @@ require (
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-macaroon-bakery/macaroonpb v1.0.0 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/go-sql-driver/mysql v1.8.1 // indirect
github.com/gobwas/httphead v0.1.0 // indirect
github.com/gobwas/pool v0.2.1 // indirect
github.com/gobwas/ws v1.2.1 // indirect
Expand Down Expand Up @@ -100,7 +102,7 @@ require (
github.com/jackc/pgio v1.0.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgproto3/v2 v2.3.3 // indirect
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 // indirect
github.com/jackc/pgtype v1.14.0 // indirect
github.com/jackc/pgx/v4 v4.18.3 // indirect
github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e // indirect
Expand Down Expand Up @@ -212,6 +214,7 @@ require (
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
gorm.io/driver/mysql v1.5.6 // indirect
modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 // indirect
modernc.org/libc v1.49.3 // indirect
modernc.org/mathutil v1.6.0 // indirect
Expand All @@ -234,6 +237,7 @@ require (
github.com/lightningnetwork/lnd v0.17.4-beta
github.com/sirupsen/logrus v1.9.3
golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 // indirect
gorm.io/datatypes v1.2.1
)

// See https://github.com/lightningnetwork/lnd/blob/v0.17.4-beta/go.mod#L12C58-L12C70
Expand Down
Loading
Loading