Skip to content

Commit defbfca

Browse files
bjoerndotsoldehesa
authored andcommitted
feat: solana-tools
1 parent 89163d6 commit defbfca

File tree

4 files changed

+162
-0
lines changed

4 files changed

+162
-0
lines changed
3.03 KB
Loading
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#!/bin/bash
2+
3+
# Required parameters:
4+
# @raycast.schemaVersion 1
5+
# @raycast.title Extract Transaction from Blink Response
6+
# @raycast.mode silent
7+
# @raycast.packageName Solana
8+
9+
# Optional parameters:
10+
# @raycast.icon ./images/solana-logo.png
11+
12+
# Documentation:
13+
# @raycast.description Extract transaction from Blink endpoint in clipboard and replaces with the transaction
14+
# @raycast.author bjoerndotsol
15+
# @raycast.authorURL https://github.com/bjoerndotsol
16+
17+
# Get clipboard content
18+
input=$(pbpaste)
19+
20+
# Check if "transactions" (plural) exists
21+
if echo "$input" | grep -q '"transactions"'; then
22+
echo "❌ Error: Multiple transactions detected. This script only works with a single transaction."
23+
exit 1
24+
fi
25+
26+
# Extract transaction value using grep and sed
27+
transaction=$(echo "$input" | grep -o '"transaction"\s*:\s*"[^"]*"' | sed 's/"transaction"\s*:\s*"\([^"]*\)"/\1/')
28+
29+
# Check if transaction was found
30+
if [ -z "$transaction" ]; then
31+
echo "❌ Error: No transaction property found in the input."
32+
exit 1
33+
fi
34+
35+
# Copy transaction to clipboard
36+
echo "$transaction" | pbcopy
37+
38+
# Show success message
39+
echo "✅ Transaction copied to clipboard!"
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#!/bin/bash
2+
3+
# Required parameters:
4+
# @raycast.schemaVersion 1
5+
# @raycast.title View Solana Transaction
6+
# @raycast.mode silent
7+
# @raycast.packageName Solana
8+
9+
# Optional parameters:
10+
# @raycast.icon ./images/solana-logo.png
11+
# @raycast.argument1 { "type": "text", "placeholder": "Transaction Signature" }
12+
# @raycast.argument2 { "type": "text", "placeholder": "Network", "optional": true }
13+
14+
# Documentation:
15+
# @raycast.description Opens a Solana transaction in Solscan. Network: empty/mainnet, d/dev/devnet, t/test/testnet
16+
# @raycast.author bjoerndotsol
17+
# @raycast.authorURL https://github.com/bjoerndotsol
18+
19+
# Get transaction signature from first argument
20+
SIGNATURE="$1"
21+
22+
# Get network parameter (optional, defaults to mainnet)
23+
NETWORK_PARAM=$(echo "$2" | tr '[:upper:]' '[:lower:]') # Convert to lowercase
24+
25+
# Determine the network cluster based on the parameter
26+
if [[ -z "$NETWORK_PARAM" ]]; then
27+
# Empty or not provided = mainnet
28+
CLUSTER=""
29+
elif [[ "$NETWORK_PARAM" == d* ]]; then
30+
# Starts with 'd' = devnet
31+
CLUSTER="?cluster=devnet"
32+
elif [[ "$NETWORK_PARAM" == t* ]]; then
33+
# Starts with 't' = testnet
34+
CLUSTER="?cluster=testnet"
35+
else
36+
# Default to mainnet for unrecognized input
37+
CLUSTER=""
38+
fi
39+
40+
# Construct the Solscan URL
41+
URL="https://solscan.io/tx/${SIGNATURE}${CLUSTER}"
42+
43+
# Open the URL in the default browser
44+
open "$URL"
45+
46+
echo "Opening transaction in Solscan: $URL"
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
#!/bin/bash
2+
3+
# Required parameters:
4+
# @raycast.schemaVersion 1
5+
# @raycast.title Open in Solana Inspector
6+
# @raycast.mode silent
7+
# @raycast.packageName Solana
8+
9+
# Optional parameters:
10+
# @raycast.icon ./images/solana-logo.png
11+
# @raycast.argument1 { "type": "text", "placeholder": "Signed transaction (base64)" }
12+
13+
# Documentation:
14+
# @raycast.description Extracts the message from a signed Solana transaction and opens Explorer's Inspector with it.
15+
# @raycast.author bjoerndotsol
16+
# @raycast.authorURL https://github.com/bjoerndotsol
17+
18+
# This script decodes a full signed Solana transaction (base64)
19+
# and reconstructs a Solana Explorer Inspector link.
20+
# Supports both legacy and versioned transactions.
21+
22+
TX_BASE64=$(printf "%s" "$1" | tr -d '[:space:]')
23+
24+
if [[ -z "$TX_BASE64" ]]; then
25+
echo "❌ Please provide a base64-encoded transaction."
26+
exit 1
27+
fi
28+
29+
# Use Python to extract the message portion (skip signatures)
30+
MESSAGE_BASE64=$(python3 - "$TX_BASE64" <<'PY'
31+
import sys, base64, binascii, urllib.parse
32+
33+
try:
34+
tx_b64 = sys.argv[1]
35+
b = base64.b64decode(tx_b64)
36+
except (binascii.Error, ValueError) as e:
37+
print(f"Error decoding base64: {e}", file=sys.stderr)
38+
sys.exit(1)
39+
40+
# Transaction format:
41+
# [u8: num_signatures] [signatures * 64 bytes] [message...]
42+
# The message may start with a version byte (0x80 | version) for versioned transactions
43+
if not b or len(b) < 2:
44+
print("Transaction too short", file=sys.stderr)
45+
sys.exit(1)
46+
47+
num_signatures = b[0]
48+
offset = 1 + num_signatures * 64
49+
50+
if offset >= len(b):
51+
print(f"Invalid transaction: offset {offset} >= length {len(b)}", file=sys.stderr)
52+
sys.exit(1)
53+
54+
# Extract message (includes version byte if present)
55+
msg = b[offset:]
56+
msg_b64 = base64.b64encode(msg).decode()
57+
58+
# URL encode (double encoding for Explorer)
59+
encoded = urllib.parse.quote(msg_b64, safe='')
60+
print(encoded)
61+
PY
62+
)
63+
64+
# Check if extraction failed
65+
if [[ $? -ne 0 ]] || [[ -z "$MESSAGE_BASE64" ]]; then
66+
echo "❌ Could not extract transaction message."
67+
exit 1
68+
fi
69+
70+
# Dummy signature array for Inspector (Explorer only needs valid JSON)
71+
DUMMY_SIGS='["1111111111111111111111111111111111111111111111111111111111111111"]'
72+
ENCODED_SIGS=$(python3 -c "import urllib.parse,sys;print(urllib.parse.quote(sys.argv[1]))" "$DUMMY_SIGS")
73+
74+
URL="https://explorer.solana.com/tx/inspector?signatures=${ENCODED_SIGS}&message=${MESSAGE_BASE64}"
75+
76+
open "$URL"
77+
echo "✅ Opening Solana Explorer Inspector"

0 commit comments

Comments
 (0)