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
1 change: 1 addition & 0 deletions internal/transactions/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ func build(
return &transactionResult{
tx: tx.FlowTransaction(),
include: []string{"code", "payload", "signatures"},
network: flow.Network().Name,
}, nil
}

Expand Down
1 change: 1 addition & 0 deletions internal/transactions/decode.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,5 +69,6 @@ func decode(
return &transactionResult{
tx: tx.FlowTransaction(),
include: decodeFlags.Include,
network: "", // decode doesn't have network context
}, nil
}
1 change: 1 addition & 0 deletions internal/transactions/get-system.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,5 +76,6 @@ func getSystemTransaction(
tx: tx,
include: getSystemFlags.Include,
exclude: getSystemFlags.Exclude,
network: flow.Network().Name,
}, nil
}
1 change: 1 addition & 0 deletions internal/transactions/get.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,5 +70,6 @@ func get(
tx: tx,
include: getFlags.Include,
exclude: getFlags.Exclude,
network: flow.Network().Name,
}, nil
}
1 change: 1 addition & 0 deletions internal/transactions/send-signed.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,5 +88,6 @@ func sendSigned(
tx: sentTx,
include: sendSignedFlags.Include,
exclude: sendSignedFlags.Exclude,
network: flow.Network().Name,
}, nil
}
1 change: 1 addition & 0 deletions internal/transactions/send.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,5 +157,6 @@ func SendTransaction(code []byte, args []string, location string, flow flowkit.S
tx: tx,
include: sendFlags.Include,
exclude: sendFlags.Exclude,
network: flow.Network().Name,
}, nil
}
1 change: 1 addition & 0 deletions internal/transactions/sign.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ func sign(
return &transactionResult{
tx: signed.FlowTransaction(),
include: signFlags.Include,
network: flow.Network().Name,
}, nil
}

Expand Down
37 changes: 35 additions & 2 deletions internal/transactions/transactions.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,22 +58,50 @@ type transactionResult struct {
tx *flow.Transaction
include []string
exclude []string
network string
}

func NewTransactionResult(tx *flow.Transaction, result *flow.TransactionResult) *transactionResult {
return &transactionResult{
result: result,
tx: tx,
result: result,
tx: tx,
network: "", // Default to empty, should be set by caller
}
}

// getBlockExplorerLink returns the block explorer link for the transaction if it's on mainnet or testnet
func (r *transactionResult) getBlockExplorerLink() string {
if r.network == "" {
return ""
}

// Only show block explorer links for mainnet and testnet
if r.network != "mainnet" && r.network != "testnet" {
return ""
}

txID := r.tx.ID().String()

if r.network == "mainnet" {
return fmt.Sprintf("https://www.flowscan.io/tx/%s", txID)
} else if r.network == "testnet" {
return fmt.Sprintf("https://testnet.flowscan.io/tx/%s", txID)
}

return ""
}

func (r *transactionResult) JSON() any {
result := make(map[string]any)
result["id"] = r.tx.ID().String()
result["payload"] = fmt.Sprintf("%x", r.tx.Encode())
result["authorizers"] = fmt.Sprintf("%s", r.tx.Authorizers)
result["payer"] = r.tx.Payer.String()

if blockExplorerLink := r.getBlockExplorerLink(); blockExplorerLink != "" {
result["view_on_block_explorer"] = blockExplorerLink
}

if r.result != nil {
result["block_id"] = r.result.BlockID.String()
result["block_height"] = r.result.BlockHeight
Expand Down Expand Up @@ -120,6 +148,7 @@ func (r *transactionResult) String() string {
}

_, _ = fmt.Fprintf(writer, "ID\t%s\n", r.tx.ID())

_, _ = fmt.Fprintf(writer, "Payer\t%s\n", r.tx.Payer.Hex())
_, _ = fmt.Fprintf(writer, "Authorizers\t%s\n", r.tx.Authorizers)

Expand Down Expand Up @@ -212,6 +241,10 @@ func (r *transactionResult) String() string {
_, _ = fmt.Fprint(writer, "\n\nFee Events (hidden, use --include fee-events)")
}

if blockExplorerLink := r.getBlockExplorerLink(); blockExplorerLink != "" {
_, _ = fmt.Fprintf(writer, "\n\n🔗 View on Block Explorer:\n%s", blockExplorerLink)
}

_ = writer.Flush()
return b.String()
}
Expand Down
52 changes: 52 additions & 0 deletions internal/transactions/transactions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -591,4 +591,56 @@ Code (hidden, use --include code)

Payload (hidden, use --include payload)`, output.OkEmoji()), "\n"), result.String())
})

t.Run("Block explorer link for mainnet", func(t *testing.T) {
result := transactionResult{tx: tx, result: txResult, network: "mainnet"}

output := result.String()
assert.Contains(t, output, "🔗 View on Block Explorer:")
assert.Contains(t, output, "https://www.flowscan.io/tx/e913d1f3e431c7df49c99845bea9ebff9db11bbf25d507b9ad0fad45652d515f")

jsonResult := result.JSON()
jsonMap, ok := jsonResult.(map[string]any)
assert.True(t, ok)
assert.Contains(t, jsonMap, "view_on_block_explorer")
assert.Equal(t, "https://www.flowscan.io/tx/e913d1f3e431c7df49c99845bea9ebff9db11bbf25d507b9ad0fad45652d515f", jsonMap["view_on_block_explorer"])
})

t.Run("Block explorer link for testnet", func(t *testing.T) {
result := transactionResult{tx: tx, result: txResult, network: "testnet"}

output := result.String()
assert.Contains(t, output, "🔗 View on Block Explorer:")
assert.Contains(t, output, "https://testnet.flowscan.io/tx/e913d1f3e431c7df49c99845bea9ebff9db11bbf25d507b9ad0fad45652d515f")

jsonResult := result.JSON()
jsonMap, ok := jsonResult.(map[string]any)
assert.True(t, ok)
assert.Contains(t, jsonMap, "view_on_block_explorer")
assert.Equal(t, "https://testnet.flowscan.io/tx/e913d1f3e431c7df49c99845bea9ebff9db11bbf25d507b9ad0fad45652d515f", jsonMap["view_on_block_explorer"])
})

t.Run("No block explorer link for emulator", func(t *testing.T) {
result := transactionResult{tx: tx, result: txResult, network: "emulator"}

output := result.String()
assert.NotContains(t, output, "🔗 View on Block Explorer:")

jsonResult := result.JSON()
jsonMap, ok := jsonResult.(map[string]any)
assert.True(t, ok)
assert.NotContains(t, jsonMap, "view_on_block_explorer")
})

t.Run("No block explorer link for empty network", func(t *testing.T) {
result := transactionResult{tx: tx, result: txResult, network: ""}

output := result.String()
assert.NotContains(t, output, "🔗 View on Block Explorer:")

jsonResult := result.JSON()
jsonMap, ok := jsonResult.(map[string]any)
assert.True(t, ok)
assert.NotContains(t, jsonMap, "view_on_block_explorer")
})
}
Loading