Skip to main content

Tổng quan

LaserStream là dịch vụ truyền phát Solana gRPC được quản lý. Dịch vụ này tương thích ở cấp giao thức truyền dẫn với giao thức Yellowstone gRPC mở — vì vậy mọi ứng dụng khách Yellowstone đều hoạt động ngay — đồng thời bổ sung các tính năng dành cho môi trường production như phát lại dữ liệu lịch sử, chuyển đổi dự phòng đa nút và môi trường được quản lý hoàn toàn. LaserStream sử dụng giao thức gRPC mã nguồn mở, bảo đảm không bị phụ thuộc vào nhà cung cấp và có khả năng tương thích tối đa với các triển khai gRPC hiện có. Bạn có thể kết nối bằng ứng dụng khách @triton-one/yellowstone-grpc tiêu chuẩn hoặc sử dụng Helius LaserStream SDK đã được tối ưu hóa hiệu năng để nhận thêm các lợi ích như thông lượng cao hơn, tự động kết nối lại, quản lý đăng ký, xử lý lỗi và nhiều tính năng khác.

LaserStream SDK is 40x Faster vs. JavaScript Yellowstone Clients

Tìm hiểu cách chúng tôi sử dụng Rust Core với các liên kết NAPI không sao chép để tối đa hóa hiệu năng của JavaScript SDK
Lưu ý về hiệu năng: Nếu kết nối LaserStream bị trễ hoặc gặp vấn đề về hiệu năng, hãy tham khảo phần Khắc phục sự cố để biết các nguyên nhân và giải pháp thường gặp.

Điểm cuối và khu vực

LaserStream có mặt tại nhiều khu vực trên toàn thế giới. Chọn điểm cuối gần ứng dụng nhất để có hiệu năng tối ưu:

Điểm cuối Mainnet

Điểm cuối Devnet

Chọn mạng và khu vực:
  • Với ứng dụng production, hãy chọn điểm cuối mainnet gần máy chủ nhất để có hiệu năng tốt nhất (ví dụ: nếu triển khai tại châu Âu, hãy dùng Amsterdam (ams) hoặc Frankfurt (fra))
  • Để kiểm thử, hãy dùng: https://laserstream-devnet-ewr.helius-rpc.com.

Nén zstd

Tất cả điểm cuối LaserStream gRPC đều hỗ trợ nén zstd. Tính năng nén là tùy chọn: phản hồi vẫn không được nén trừ khi ứng dụng khách thông báo hỗ trợ zstd. Bật zstd trong Helius LaserStream TypeScript SDK:
zstd giảm băng thông mạng nhưng làm tăng khối lượng xử lý nén. Hãy đo điểm chuẩn với khối lượng công việc đăng ký trước khi bật tính năng này cho các luồng nhạy cảm với độ trễ.

Cắt ngắn nhật ký

Theo mặc định, LaserStream cắt ngắn thông báo nhật ký giao dịch ở mức 10 KB để cải thiện tốc độ và hiệu năng. Nếu cần nhật ký đầy đủ, bạn có thể dùng các điểm cuối chuyên dụng không cắt ngắn — xem Cắt ngắn nhật ký.

Bắt đầu nhanh

Bắt đầu sử dụng LaserStream từ Bảng điều khiển Helius. Mainnet yêu cầu gói Business hoặc Professional; Devnet dành cho gói Developer trở lên. Xem Gói dịch vụ và giá để biết chi tiết.
1

Create a New Project

2

Install Dependencies

Chúng tôi dùng tsx vì npx tsc --init mặc định trên TypeScript 5.x đặt verbatimModuleSyntax, module: "nodenext" và types: [], khiến thao tác chạy nhanh bằng ts-node index.ts bị lỗi. tsx chạy các tệp .ts mà không cần tsconfig.
3

Obtain Your API Key

Tạo khóa từ Bảng điều khiển Helius.Khóa này sẽ được dùng làm token xác thực cho LaserStream.
Yêu cầu về gói dịch vụ: LaserStream devnet có trong tất cả gói dịch vụ. LaserStream mainnet yêu cầu gói Business hoặc Professional.
4

Create a Subscription Script

Tạo index.ts với nội dung sau:
5

Replace Your API Key and Choose Your Region

Trong index.ts, hãy cập nhật đối tượng config bằng:
  1. Khóa API thực tế từ Bảng điều khiển Helius
  2. Điểm cuối LaserStream gần vị trí máy chủ nhất
Ví dụ chọn mạng và khu vực:
  • Cho production (Mainnet):
    • Châu Âu: Dùng fra (Frankfurt), ams (Amsterdam) hoặc lon (London)
    • Miền Đông Hoa Kỳ: Dùng ewr (New York)
    • Miền Tây Hoa Kỳ: Dùng slc (Salt Lake City) hoặc lax (Los Angeles)
    • Châu Á: Dùng tyo (Tokyo) hoặc sgp (Singapore)
  • Cho phát triển (Devnet):
    • Dùng https://laserstream-devnet-ewr.helius-rpc.com
6

Run and View Results

Bất cứ khi nào giao dịch token confirmed có liên quan đến TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA, dữ liệu sẽ xuất hiện trong bảng điều khiển.

Quy trình làm việc phổ biến

Hướng dẫn từng bước cho các quy trình làm việc thường gặp nhất. Mỗi hướng dẫn đều sử dụng SDK helius-laserstream, tích hợp sẵn tính năng tự động kết nối lại và phát lại dữ liệu lịch sử.

Account Subscriptions

Theo dõi thay đổi về số dư, dữ liệu và quyền sở hữu trên các tài khoản cụ thể bằng bộ lọc.

Transaction Monitoring

Truyền phát các giao dịch liên quan đến tài khoản mục tiêu; lọc theo chương trình, phiếu bầu hoặc trạng thái thất bại.

Slot & Block Monitoring

Theo dõi sự đồng thuận của mạng, quá trình tạo khối và các lần chuyển đổi cấp độ cam kết.

Decoding Transaction Data

Phân tích các tải trọng nhị phân transactionUpdate thành giao dịch Solana có thể đọc được.

Stream Pump AMM Data

Ví dụ thực tế: theo dõi giao dịch Pump AMM bằng các bộ lọc an toàn khi kết nối lại.
Ứng dụng khách @triton-one/yellowstone-grpc hoạt động với cùng các điểm cuối nếu bạn muốn dùng giao thức Yellowstone thô. Xem tài liệu tham khảo Yellowstone gRPC để biết chi tiết ở cấp giao thức.

Yêu cầu đăng ký

Trong yêu cầu đăng ký, bạn cần đưa vào các tham số chung sau:
Phát lại dữ liệu lịch sử: Bạn có thể tùy chọn thêm trường fromSlot (một số u64) vào đối tượng SubscribeRequest chính để phát lại dữ liệu từ một slot cụ thể trở đi. Hiện tại, phạm vi phát lại được giới hạn trong khoảng 48 giờ gần nhất (~691.200 slot theo tốc độ mạng hiện tại); lưu ý rằng các bản phát lại cũ hơn khoảng 20 phút chỉ trả về dữ liệu đã hoàn tất.
enum
Chỉ định cấp độ cam kết, có thể là processed, confirmed hoặc finalized.
array
Một mảng đối tượng { offset: uint64, length: uint64 } cho phép chỉ nhận các lát dữ liệu cần thiết từ tài khoản.
boolean
Một số nhà cung cấp đám mây (như Cloudflare) có thể đóng các luồng không hoạt động sau một khoảng thời gian. Để ngăn điều này và duy trì kết nối mà không cần gửi lại bộ lọc, hãy đặt giá trị này thành true. Máy chủ sẽ phản hồi bằng thông báo Pong sau mỗi 15 giây.
Tiếp theo, bạn cần chỉ định các bộ lọc cho dữ liệu muốn đăng ký, chẳng hạn như tài khoản, khối, slot hoặc giao dịch.
Xác định bộ lọc cho các bản cập nhật slot. Khóa bạn sử dụng (ví dụ: mySlotLabel) là nhãn do người dùng xác định cho cấu hình bộ lọc cụ thể này, cho phép bạn xác định nhiều cấu hình có tên nếu cần (mặc dù thông thường chỉ cần một cấu hình).
boolean
Theo mặc định, slot được gửi cho mọi cấp độ cam kết. Với bộ lọc này, bạn có thể chọn chỉ nhận cấp độ cam kết đã chọn.
boolean
Cho phép đăng ký nhận thông tin cập nhật về các thay đổi bên trong một slot, không chỉ ở đầu các slot mới. Tính năng này hữu ích để nhận dữ liệu slot chi tiết hơn với độ trễ thấp.
Xác định bộ lọc cho các bản cập nhật dữ liệu tài khoản. Khóa bạn sử dụng (ví dụ: tokenAccounts) là nhãn do người dùng xác định cho cấu hình bộ lọc cụ thể này.
array
Khớp với bất kỳ khóa công khai nào trong mảng được cung cấp.
array
Khóa công khai của chủ sở hữu tài khoản. Khớp với bất kỳ khóa công khai nào trong mảng được cung cấp.
array
Tương tự các bộ lọc trong getProgramAccounts. Đây là một mảng các bộ lọc datasize và/hoặc memcmp. Với memcmp, giá trị so sánh được đặt trong một trong các trường bytes, base58 hoặc base64 trực tiếp trên đối tượng memcmp.
enum
không còn sử dụng
Không dùng nữa — không có tác dụng kể từ Agave 4.2. Việc đặt notifyOn không có tác dụng. Trường này sẽ bị xóa trong tương lai.
Nếu tất cả trường đều trống, mọi tài khoản sẽ được phát. Nếu không:
  • Các trường hoạt động theo phép logic AND.
  • Các giá trị trong mảng hoạt động theo phép logic OR (ngoại trừ trong filters, nơi chúng hoạt động theo phép logic AND).
Theo dõi hơn ~10.000 tài khoản? Thay vì dùng danh sách pubkey tường minh (32 byte cho mỗi tài khoản), hãy dùng bộ lọc cuckoo nén (~3–4 byte cho mỗi tài khoản) để đăng ký hàng trăm nghìn tài khoản trong một luồng duy nhất. Có trong SDK Rust và JavaScript.
Xác định bộ lọc cho các bản cập nhật giao dịch. Khóa bạn sử dụng (ví dụ: myTxSubscription) là nhãn do người dùng xác định cho cấu hình bộ lọc cụ thể này.
boolean
Bật hoặc tắt việc phát các giao dịch bỏ phiếu.
boolean
Bật hoặc tắt việc phát các giao dịch thất bại.
string
Chỉ phát các giao dịch khớp với chữ ký đã chỉ định.
array
Lọc các giao dịch liên quan đến bất kỳ tài khoản nào trong danh sách được cung cấp.
array
Loại trừ các giao dịch liên quan đến bất kỳ tài khoản nào trong danh sách được cung cấp (ngược với accountInclude).
array
Lọc các giao dịch liên quan đến tất cả tài khoản trong danh sách được cung cấp (phải sử dụng mọi tài khoản).
string
Phần mở rộng tokenAccounts (tài khoản token liên kết) tùy chọn. Khi được đặt, ví accountInclude cũng khớp với các giao dịch mà ví đó sở hữu số dư token SPL — ví dụ: giao dịch chuyển token đến tác động vào tài khoản token của ví thay vì pubkey của ví. Chấp nhận "balanceChanged" (khớp theo chênh lệch số dư), "all" (mọi tham chiếu, khối lượng cao hơn) hoặc "none" (không mở rộng, mặc định). SDK chuyển đổi chuỗi thành enum TokenAccountExpansionControlFlag ở cấp giao thức truyền dẫn (thuộc yellowstone-grpc-proto 12.5.0+). Xem Lọc tài khoản token (ATA) để biết chức năng và cách hoạt động.
boolean
Cờ matchMints tùy chọn (mặc định là false). Khi là true, các danh sách accountInclude, accountExclude và accountRequired cũng được đối chiếu với các mint trong số dư token trước/sau giao dịch, thay vì chỉ với khóa tài khoản. Đặt một mint vào accountInclude để nhận mọi giao dịch tác động đến token đó, bao gồm cả các giao dịch chuyển SPL thông thường không bao giờ tham chiếu đến mint trong khóa tài khoản. Đây là tính năng tùy chọn và không ảnh hưởng đến các bộ lọc hiện có. Yêu cầu helius-laserstream 0.8.5+ (JS), 0.6.4+ (Rust) hoặc go/v0.3.0+ (Go). Xem Lọc mint token để biết ngữ nghĩa và ví dụ.
Nếu tất cả trường đều để trống, mọi giao dịch sẽ được phát. Nếu không:
  • Các trường hoạt động theo phép logic AND.
  • Các giá trị trong mảng được xử lý theo phép logic OR (ngoại trừ accountRequired, nơi tất cả giá trị đều phải khớp).
Xác định bộ lọc cho các bản cập nhật khối. Khóa bạn sử dụng (ví dụ: myBlockLabel) là nhãn do người dùng xác định cho cấu hình bộ lọc cụ thể này.
array
Lọc các giao dịch và tài khoản liên quan đến bất kỳ tài khoản nào trong danh sách được cung cấp.
boolean
Bao gồm tất cả giao dịch trong nội dung phát.
boolean
Bao gồm tất cả bản cập nhật tài khoản trong nội dung phát.
boolean
Bao gồm tất cả mục nhập trong nội dung phát.
Hoạt động tương tự Blocks nhưng không bao gồm giao dịch, tài khoản và mục nhập. Khóa bạn sử dụng (ví dụ: blockmetadata) là nhãn do người dùng xác định cho đăng ký này. Hiện tại không có bộ lọc cho siêu dữ liệu khối — theo mặc định, mọi thông báo đều được phát.
Đăng ký các mục nhập sổ cái. Khóa bạn sử dụng (ví dụ: entrySubscribe) là nhãn do người dùng xác định cho đăng ký này. Hiện tại không có bộ lọc cho mục nhập; tất cả mục nhập đều được phát.

Ví dụ mã (LaserStream SDK)

Tùy chọn SDK

Chúng tôi cung cấp SDK chính thức cho nhiều ngôn ngữ lập trình: Với các ngôn ngữ khác hoặc triển khai tùy chỉnh, bạn có thể dùng trực tiếp các tệp proto Yellowstone gRPC để tạo ứng dụng khách gRPC cho ngôn ngữ mong muốn.

Khắc phục sự cố / Câu hỏi thường gặp

Trả lời: Các vấn đề về hiệu năng của kết nối LaserStream thường do:
  • Ứng dụng khách Javascript chậm: Ứng dụng khách JavaScript có thể bị chậm khi xử lý quá nhiều thông báo hoặc sử dụng quá nhiều băng thông. Hãy cân nhắc thu hẹp bộ lọc đăng ký để giảm số lượng thông báo, chuyển sang LaserStream JavaScript SDK hoặc thử dùng ngôn ngữ khác.
  • Băng thông cục bộ hạn chế: Các đăng ký có lưu lượng lớn có thể làm quá tải ứng dụng khách có băng thông mạng hạn chế. Theo dõi mức sử dụng mạng và cân nhắc nâng cấp kết nối hoặc thu hẹp phạm vi đăng ký.
  • Khoảng cách địa lý: Tuyến mạng dài làm tăng độ trễ và tỷ lệ mất gói. Hãy dùng điểm cuối gần máy chủ nhất. Với kết nối có độ trễ cao, hãy tăng kích thước bộ đệm đọc mạng (có thể cải thiện băng thông hơn 5 lần):
    Để duy trì thiết lập sau khi khởi động lại, hãy thêm vào /etc/sysctl.conf:
    Tăng kích thước cửa sổ luồng và kết nối HTTP/2 lên 64MB để tránh nút thắt cổ chai do điều khiển luồng. Cần tăng cả hai — nếu chỉ tăng cửa sổ luồng, cửa sổ cấp kết nối vẫn là giới hạn ràng buộc:
  • Nút thắt xử lý phía ứng dụng khách: Bảo đảm logic xử lý thông báo được tối ưu hóa và không chặn luồng chính trong thời gian dài.
Gỡ lỗi độ trễ ứng dụng khách: Để hỗ trợ gỡ lỗi ứng dụng khách, chúng tôi đã xây dựng một công cụ kiểm tra băng thông tối đa từ nút của bạn đến máy chủ Laserstream gRPC. Để sử dụng, hãy chạy:
Kết quả trả về dung lượng mạng tối đa giữa máy chủ của bạn và máy chủ Laserstream. Tối thiểu, bạn cần 10MB/giây để đăng ký toàn bộ dữ liệu giao dịch và 80MB/giây để đăng ký toàn bộ dữ liệu tài khoản. Để có hiệu năng tối ưu, chúng tôi khuyên dùng dung lượng ít nhất gấp 2 lần mức yêu cầu.
Trả lời: Xác minh rằng khóa API và điểm cuối là chính xác, đồng thời mạng cho phép kết nối gRPC đi đến điểm cuối được chỉ định. Kiểm tra trang trạng thái Helius để xem có sự cố nào đang diễn ra hay không.
Trả lời: Kiểm tra lại các toán tử logic (AND/OR) được mô tả trong phần bộ lọc. Bảo đảm các khóa công khai là chính xác. Kiểm tra cấp độ cam kết được chỉ định trong yêu cầu.
Trả lời: Có, bạn có thể xác định cấu hình bộ lọc dưới nhiều khóa (ví dụ: accounts, transactions) trong cùng một đối tượng SubscribeRequest.
Trả lời: Chúng tôi không triển khai nhóm người tiêu dùng. Thay vào đó, LaserStream cung cấp những kết quả mà các nhóm cần: tiếp tục, phát lại và độ tin cậy đa nút mà không cần lớp điều phối (cũng như độ trễ và chi phí phát sinh đi kèm). Chúng tôi cho rằng hầu hết khối lượng công việc không cần nhóm người tiêu dùng, vì chúng làm tăng độ trễ và chi phí vận hành. Ví dụ: một kết nối LaserStream gRPC duy nhất có thể phát ra lượng dữ liệu giao dịch + tài khoản gấp tối đa 10 lần Solana, trong khi hầu hết ứng dụng khách chỉ đăng ký một phần nhỏ đã lọc. Việc dùng nhóm người tiêu dùng trong trường hợp này làm lãng phí dư địa hiệu năng và tạo thêm một điểm lỗi.
Trả lời: Theo mặc định, LaserStream cắt ngắn thông báo nhật ký giao dịch ở mức 10 KB để cải thiện tốc độ và hiệu năng. Nếu cần nhật ký đầy đủ, hãy kết nối với một điểm cuối chuyên dụng không cắt ngắn — xem Cắt ngắn nhật ký để biết danh sách.
Trả lời: Việc đưa trường ping vào SubscribeRequest ban đầu khiến LaserStream âm thầm bỏ qua mọi bộ lọc đăng ký — hệ thống chỉ trả về Pong mà không có dữ liệu tài khoản, giao dịch hoặc slot. Để khắc phục, hãy xóa ping khỏi yêu cầu đăng ký ban đầu, sau đó gửi ping riêng qua sink của luồng sau khi đăng ký được thiết lập. Cách này duy trì kết nối mà không ảnh hưởng đến bộ lọc.