Skip to content

Commit a056d28

Browse files
committed
Add block explorer link to tx
1 parent 44983fb commit a056d28

9 files changed

Lines changed: 96 additions & 2 deletions

File tree

internal/transactions/build.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ func build(
127127
return &transactionResult{
128128
tx: tx.FlowTransaction(),
129129
include: []string{"code", "payload", "signatures"},
130+
network: flow.Network().Name,
130131
}, nil
131132
}
132133

internal/transactions/decode.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,5 +69,6 @@ func decode(
6969
return &transactionResult{
7070
tx: tx.FlowTransaction(),
7171
include: decodeFlags.Include,
72+
network: "", // decode doesn't have network context
7273
}, nil
7374
}

internal/transactions/get-system.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,5 +76,6 @@ func getSystemTransaction(
7676
tx: tx,
7777
include: getSystemFlags.Include,
7878
exclude: getSystemFlags.Exclude,
79+
network: flow.Network().Name,
7980
}, nil
8081
}

internal/transactions/get.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,5 +70,6 @@ func get(
7070
tx: tx,
7171
include: getFlags.Include,
7272
exclude: getFlags.Exclude,
73+
network: flow.Network().Name,
7374
}, nil
7475
}

internal/transactions/send-signed.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,5 +88,6 @@ func sendSigned(
8888
tx: sentTx,
8989
include: sendSignedFlags.Include,
9090
exclude: sendSignedFlags.Exclude,
91+
network: flow.Network().Name,
9192
}, nil
9293
}

internal/transactions/send.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,5 +157,6 @@ func SendTransaction(code []byte, args []string, location string, flow flowkit.S
157157
tx: tx,
158158
include: sendFlags.Include,
159159
exclude: sendFlags.Exclude,
160+
network: flow.Network().Name,
160161
}, nil
161162
}

internal/transactions/sign.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ func sign(
141141
return &transactionResult{
142142
tx: signed.FlowTransaction(),
143143
include: signFlags.Include,
144+
network: flow.Network().Name,
144145
}, nil
145146
}
146147

internal/transactions/transactions.go

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,22 +58,51 @@ type transactionResult struct {
5858
tx *flow.Transaction
5959
include []string
6060
exclude []string
61+
network string
6162
}
6263

6364
func NewTransactionResult(tx *flow.Transaction, result *flow.TransactionResult) *transactionResult {
6465
return &transactionResult{
65-
result: result,
66-
tx: tx,
66+
result: result,
67+
tx: tx,
68+
network: "", // Default to empty, should be set by caller
6769
}
6870
}
6971

72+
// getBlockExplorerLink returns the block explorer link for the transaction if it's on mainnet or testnet
73+
func (r *transactionResult) getBlockExplorerLink() string {
74+
if r.network == "" {
75+
return ""
76+
}
77+
78+
// Only show block explorer links for mainnet and testnet
79+
if r.network != "mainnet" && r.network != "testnet" {
80+
return ""
81+
}
82+
83+
txID := r.tx.ID().String()
84+
85+
if r.network == "mainnet" {
86+
return fmt.Sprintf("https://www.flowscan.io/tx/%s", txID)
87+
} else if r.network == "testnet" {
88+
return fmt.Sprintf("https://testnet.flowscan.io/tx/%s", txID)
89+
}
90+
91+
return ""
92+
}
93+
7094
func (r *transactionResult) JSON() any {
7195
result := make(map[string]any)
7296
result["id"] = r.tx.ID().String()
7397
result["payload"] = fmt.Sprintf("%x", r.tx.Encode())
7498
result["authorizers"] = fmt.Sprintf("%s", r.tx.Authorizers)
7599
result["payer"] = r.tx.Payer.String()
76100

101+
// Add block explorer link for mainnet and testnet
102+
if blockExplorerLink := r.getBlockExplorerLink(); blockExplorerLink != "" {
103+
result["view_on_block_explorer"] = blockExplorerLink
104+
}
105+
77106
if r.result != nil {
78107
result["block_id"] = r.result.BlockID.String()
79108
result["block_height"] = r.result.BlockHeight
@@ -120,6 +149,12 @@ func (r *transactionResult) String() string {
120149
}
121150

122151
_, _ = fmt.Fprintf(writer, "ID\t%s\n", r.tx.ID())
152+
153+
// Add block explorer link for mainnet and testnet
154+
if blockExplorerLink := r.getBlockExplorerLink(); blockExplorerLink != "" {
155+
_, _ = fmt.Fprintf(writer, "🔗 View on Block Explorer\t%s\n", blockExplorerLink)
156+
}
157+
123158
_, _ = fmt.Fprintf(writer, "Payer\t%s\n", r.tx.Payer.Hex())
124159
_, _ = fmt.Fprintf(writer, "Authorizers\t%s\n", r.tx.Authorizers)
125160

internal/transactions/transactions_test.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -591,4 +591,56 @@ Code (hidden, use --include code)
591591
592592
Payload (hidden, use --include payload)`, output.OkEmoji()), "\n"), result.String())
593593
})
594+
595+
t.Run("Block explorer link for mainnet", func(t *testing.T) {
596+
result := transactionResult{tx: tx, result: txResult, network: "mainnet"}
597+
598+
output := result.String()
599+
assert.Contains(t, output, "🔗 View on Block Explorer")
600+
assert.Contains(t, output, "https://www.flowscan.io/tx/e913d1f3e431c7df49c99845bea9ebff9db11bbf25d507b9ad0fad45652d515f")
601+
602+
jsonResult := result.JSON()
603+
jsonMap, ok := jsonResult.(map[string]any)
604+
assert.True(t, ok)
605+
assert.Contains(t, jsonMap, "view_on_block_explorer")
606+
assert.Equal(t, "https://www.flowscan.io/tx/e913d1f3e431c7df49c99845bea9ebff9db11bbf25d507b9ad0fad45652d515f", jsonMap["view_on_block_explorer"])
607+
})
608+
609+
t.Run("Block explorer link for testnet", func(t *testing.T) {
610+
result := transactionResult{tx: tx, result: txResult, network: "testnet"}
611+
612+
output := result.String()
613+
assert.Contains(t, output, "🔗 View on Block Explorer")
614+
assert.Contains(t, output, "https://testnet.flowscan.io/tx/e913d1f3e431c7df49c99845bea9ebff9db11bbf25d507b9ad0fad45652d515f")
615+
616+
jsonResult := result.JSON()
617+
jsonMap, ok := jsonResult.(map[string]any)
618+
assert.True(t, ok)
619+
assert.Contains(t, jsonMap, "view_on_block_explorer")
620+
assert.Equal(t, "https://testnet.flowscan.io/tx/e913d1f3e431c7df49c99845bea9ebff9db11bbf25d507b9ad0fad45652d515f", jsonMap["view_on_block_explorer"])
621+
})
622+
623+
t.Run("No block explorer link for emulator", func(t *testing.T) {
624+
result := transactionResult{tx: tx, result: txResult, network: "emulator"}
625+
626+
output := result.String()
627+
assert.NotContains(t, output, "🔗 View on Block Explorer")
628+
629+
jsonResult := result.JSON()
630+
jsonMap, ok := jsonResult.(map[string]any)
631+
assert.True(t, ok)
632+
assert.NotContains(t, jsonMap, "view_on_block_explorer")
633+
})
634+
635+
t.Run("No block explorer link for empty network", func(t *testing.T) {
636+
result := transactionResult{tx: tx, result: txResult, network: ""}
637+
638+
output := result.String()
639+
assert.NotContains(t, output, "🔗 View on Block Explorer")
640+
641+
jsonResult := result.JSON()
642+
jsonMap, ok := jsonResult.(map[string]any)
643+
assert.True(t, ok)
644+
assert.NotContains(t, jsonMap, "view_on_block_explorer")
645+
})
594646
}

0 commit comments

Comments
 (0)