Conversation
…-beta and indexer v1.18.59. Added examples also for new vouchers functionality
Replace hardcoded hex keys in InitCosmosKeyring call sites with
os.Getenv("INJECTIVE_PRIVATE_KEY"), call godotenv.Load() at startup, and
document variables in .env.example. Ignore .env in git.
…19_0_beta [IC-986] sync_with_version_v1_19_0_beta
…_v1_60_0 [CHORE] Solved merge issues between master and dev branches
…t_for_release [CHORE] final v1.19 alignment for release
… release/update_master_for_v1_61
📝 WalkthroughWalkthroughAdds environment-driven example configuration (.env.example + .gitignore), broad example updates to load INJECTIVE_PRIVATE_KEY via godotenv, registers MsgClaimVoucher, introduces voucher query APIs, streaming oracle RPCs, and multiple exchange/oracle/peggy/type/param/logic changes across the chain modules. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Poem
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
|
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
There was a problem hiding this comment.
Actionable comments posted: 9
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
examples/chain/13_BroadcastMsgWithoutSimulation/example.go (1)
21-37:⚠️ Potential issue | 🟡 MinorHandle
godotenv.Load()error silentlyThe pattern
_ = godotenv.Load()silently ignores errors from loading the.envfile. If the file doesn't exist or has parse errors, the application will proceed without warning. Consider logging or handling the error explicitly:if err := godotenv.Load(); err != nil { // Handle error: log warning, fail gracefully, or continue based on requirements }The subsequent call to
os.Getenv("INJECTIVE_PRIVATE_KEY")is intentionally designed with a fallback: if the environment variable is not set,InitCosmosKeyringwill use the keyring backend (specified by the "inj-user" key name incosmosKeyFrom), as documented in the function's behavior.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@examples/chain/13_BroadcastMsgWithoutSimulation/example.go` around lines 21 - 37, Replace the silent discard of godotenv.Load() in main with explicit error handling: call godotenv.Load() and if it returns an error log a non-fatal warning (or decide to exit) so missing or malformed .env files are visible; update the call site in main where godotenv.Load() is currently assigned to _ and ensure the behavior still lets InitCosmosKeyring use os.Getenv("INJECTIVE_PRIVATE_KEY") as its documented fallback when the env var is absent.
🧹 Nitpick comments (12)
chain/peggy/types/key.go (1)
314-367: Usecommon.Addressfor ERC20 parameters to align with the file's established pattern.The new helpers at lines 314–367 all accept raw
[]bytefor ERC20 addresses, inconsistent with existing key builders in this file (GetOutgoingTxBatchKey,GetBatchConfirmKey,GetFeeSecondIndexKey,GetERC20ToCosmosDenomKey) which all usecommon.Address. The typed parameter enforces a 20-byte invariant and prevents accidental malformed key construction. Changing these seven functions to acceptcommon.Addressinstead of[]bytewould keep the API consistent and safer.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@chain/peggy/types/key.go` around lines 314 - 367, These helpers accept raw []byte for ERC20 but should use common.Address for consistency and to enforce 20-byte addresses; change the parameter type of GetRateLimitKey, GetMintAmountERC20Key, GetTokenInflowPrefix, GetTokenInflowByBlockKey, GetTokenOutflowPrefix, GetTokenOutflowByBlockKey, and GetTokenNetOutflowKey to common.Address, replace uses of erc20 and len(erc20) with addr.Bytes() and common.AddressLength (or len(addr.Bytes())), and update the append calls to append(addr.Bytes()...) and capacity calculations accordingly; also add the github.com/ethereum/go-ethereum/common import and update any callers to pass a common.Address.chain/wasmx/types/params.go (1)
17-19: Contribution of overflow-safe gas constants is solid.The derived constants clearly express the relationships:
MinExecutionGasLimitcorrectly sums all required gas componentsMaxSafeExecutionGasLimitbounds contract gas to prevent overflow when multiplied byExecutionGasFeeMultiplierMinor suggestion for clarity: Consider using
math.MaxUint64instead of^uint64(0)for explicit readability, though both are equivalent.const ( GasForFeeDeduction uint64 = 13419 GasForFeeRefund uint64 = 13419 DefaultGasContractCall uint64 = 63558 ExecutionGasFeeMultiplier uint64 = 3 MinExecutionGasLimit uint64 = GasForFeeDeduction + GasForFeeRefund + DefaultGasContractCall - MaxSafeExecutionGasLimit uint64 = ^uint64(0) / ExecutionGasFeeMultiplier + MaxSafeExecutionGasLimit uint64 = math.MaxUint64 / ExecutionGasFeeMultiplier )🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@chain/wasmx/types/params.go` around lines 17 - 19, Replace the bit-twiddling max value with the explicit constant: change the computation of MaxSafeExecutionGasLimit to use math.MaxUint64 divided by ExecutionGasFeeMultiplier, and add the necessary import for the math package; this touches the constants ExecutionGasFeeMultiplier and MaxSafeExecutionGasLimit in params.go.examples/chain/ibc/channel/query/13_NextSequenceReceive/example.go (1)
4-16: Minor import ordering inconsistency.The
osimport at line 15 is separated from other standard library imports. Standard Go convention groups all stdlib imports together. This is a minor formatting issue that doesn't affect functionality.The
godotenvimport is correctly placed among third-party imports.♻️ Optional: Consolidate standard library imports
import ( "context" "encoding/json" "fmt" + "os" "github.com/InjectiveLabs/sdk-go/client" "github.com/joho/godotenv" chainclient "github.com/InjectiveLabs/sdk-go/client/chain" "github.com/InjectiveLabs/sdk-go/client/common" rpchttp "github.com/cometbft/cometbft/rpc/client/http" - - "os" )🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@examples/chain/ibc/channel/query/13_NextSequenceReceive/example.go` around lines 4 - 16, The import ordering in example.go is inconsistent: the standard library import "os" is separated from the other stdlib imports ("context", "encoding/json", "fmt"); move "os" into the first import group so all standard library packages are grouped together, keeping third-party imports (github.com/..., rpchttp) and local aliases (chainclient, common) in their respective groups; update the import block around the file-level imports to reflect the standard Go grouping convention.examples/chain/exchange/query/18_SubaccountOrders/example.go (1)
17-17: Consider logging when.envfile is not found.The error from
godotenv.Load()is silently discarded. While this allows the.envfile to be optional (env vars can be set directly in the shell), logging a warning when the file doesn't exist would improve debugging experience for developers using these examples.♻️ Optional improvement
-func main() { - _ = godotenv.Load() +func main() { + if err := godotenv.Load(); err != nil { + fmt.Printf("Warning: .env file not found, using environment variables: %v\n", err) + }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@examples/chain/exchange/query/18_SubaccountOrders/example.go` at line 17, The call to godotenv.Load() currently discards errors; change it to check the returned error and log a warning when the .env file is missing or any load error occurs so developers know why defaults/env vars might be absent. Specifically, replace the standalone godotenv.Load() invocation with an error check around godotenv.Load() (in example.go, where godotenv.Load() is called), and use the log package to emit a warning like " .env not found: %v" when os.IsNotExist(err) (or a generic "failed to load .env: %v" for other errors) so missing or problematic .env files are visible during debugging.examples/chain/exchange/query/51_OptedOutOfRewardsAccounts/example.go (2)
17-18: Consider handling.envload errors explicitly.The error from
godotenv.Load()is silently discarded. If the.envfile is missing or malformed, the application continues without any indication, andINJECTIVE_PRIVATE_KEYmay be unset, causing confusing downstream errors in keyring initialization.♻️ Optional improvement for error handling
func main() { - _ = godotenv.Load() + if err := godotenv.Load(); err != nil && !os.IsNotExist(err) { + fmt.Printf("Warning: failed to load .env file: %v\n", err) + }Alternatively, if silent failure is intentional (e.g.,
.envis optional), consider adding a comment clarifying this.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@examples/chain/exchange/query/51_OptedOutOfRewardsAccounts/example.go` around lines 17 - 18, The call to godotenv.Load() in main currently ignores errors; change this so the error is handled or documented: check the returned error from godotenv.Load() in main and either log/warn/fatal the error (so missing/malformed .env is visible before keyring initialization that uses INJECTIVE_PRIVATE_KEY) or add a comment explaining that .env is intentionally optional; ensure the fix references the godotenv.Load() invocation and the subsequent keyring/private key usage so users won’t get silent failures.
25-32: ValidateINJECTIVE_PRIVATE_KEYbefore use.If
INJECTIVE_PRIVATE_KEYis not set,os.Getenvreturns an empty string, which gets passed toInitCosmosKeyring. This could cause unclear errors downstream. Consider adding a validation check with a clear error message.🛡️ Optional validation
senderAddress, cosmosKeyring, err := chainclient.InitCosmosKeyring( os.Getenv("HOME")+"/.injectived", "injectived", "file", "inj-user", "12345678", - os.Getenv("INJECTIVE_PRIVATE_KEY"), // keyring will be used if pk not provided + func() string { + pk := os.Getenv("INJECTIVE_PRIVATE_KEY") + if pk == "" { + fmt.Println("Warning: INJECTIVE_PRIVATE_KEY not set, falling back to keyring") + } + return pk + }(), false, )🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@examples/chain/exchange/query/51_OptedOutOfRewardsAccounts/example.go` around lines 25 - 32, The code calls InitCosmosKeyring with os.Getenv("INJECTIVE_PRIVATE_KEY") without validating it, which can lead to unclear downstream errors; before calling InitCosmosKeyring, check that the INJECTIVE_PRIVATE_KEY env var is non-empty and return or log a clear error if missing (e.g., set a descriptive error and exit or propagate it), so update the logic around the call that assigns senderAddress, cosmosKeyring, err to validate the env var and handle the missing-key case explicitly.examples/chain/distribution/query/9_CommunityPool/example.go (1)
18-18: Consider handlinggodotenv.Load()errors explicitly.Silently discarding the error with
_ = godotenv.Load()means the program will silently proceed even if the.envfile doesn't exist or has syntax errors. For example code, this may be acceptable sinceINJECTIVE_PRIVATE_KEYcan come from the shell environment. If this pattern is intended as a reference for production integrations, consider adding at least a warning log when the file fails to load.If the key is intended to be optional (falling back to keyring), the comment on line 31 already documents that behavior. However, for security-sensitive credentials, you may want to validate that either the key is provided or keyring is available before proceeding.
💡 Optional: Add validation for private key presence
func main() { - _ = godotenv.Load() + if err := godotenv.Load(); err != nil { + // .env is optional; env vars may come from shell environment + fmt.Printf("Note: .env file not loaded: %v\n", err) + } + + privateKey := os.Getenv("INJECTIVE_PRIVATE_KEY") + if privateKey == "" { + fmt.Println("Warning: INJECTIVE_PRIVATE_KEY not set, will use keyring") + }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@examples/chain/distribution/query/9_CommunityPool/example.go` at line 18, Replace the silent ignore of godotenv.Load() with explicit error handling: call godotenv.Load() and if it returns an error, log a warning (via your logger or fmt.Printf) that the .env file failed to load and include the error text; additionally validate presence of the INJECTIVE_PRIVATE_KEY environment variable (or detect keyring fallback) before proceeding and log/fatal if neither is available. Locate the call to godotenv.Load() and the code that reads INJECTIVE_PRIVATE_KEY to add these checks and messages.examples/chain/13_BroadcastMsgWithoutSimulation/example.go (1)
21-22: Consider logging a warning when.envfile fails to load.The current implementation silently discards errors from
godotenv.Load(). While this allows the program to continue using system environment variables, it may mask configuration issues during development.🔧 Optional: Log warning on .env load failure
-func main() { - _ = godotenv.Load() +func main() { + if err := godotenv.Load(); err != nil { + // Non-fatal: .env is optional, environment variables may still be set + fmt.Printf("Warning: .env file not loaded: %v\n", err) + }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@examples/chain/13_BroadcastMsgWithoutSimulation/example.go` around lines 21 - 22, In main(), currently the return value from godotenv.Load() is ignored; change this to check the error from godotenv.Load() and call your logger (or log.Printf/log.Warn) to emit a warning when loading .env fails (e.g., "warning: failed to load .env: %v"), while still allowing the program to continue; update the code around the godotenv.Load() call in main() to capture err and log the warning when err != nil.examples/chain/insurance/1_MsgClaimVoucher/example.go (1)
20-20: Consider checking godotenv.Load error.While
_discard is acceptable for optional.envloading, it would be helpful to log a warning when the file exists but fails to parse. However, this is acceptable for example code.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@examples/chain/insurance/1_MsgClaimVoucher/example.go` at line 20, The call to godotenv.Load() currently discards any error; change it to capture the returned error from godotenv.Load() in example.go (the call site referencing godotenv.Load) and if err != nil, log a brief warning (e.g., using log.Printf or fmt.Println) indicating the .env file failed to load and include the error message so failures to parse are visible in examples; keep behavior non-fatal so the example continues running.examples/chain/insurance/query/2_Voucher/example.go (1)
65-68: Same error handling issue as auction query example.Consider matching error handling patterns across similar examples (panic vs print-and-continue).
♻️ Consistent error handling
res, err := chainClient.FetchInsuranceVoucher(ctx, denom, address) if err != nil { - fmt.Println(err) + panic(err) } str, _ := json.MarshalIndent(res, "", "\t")🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@examples/chain/insurance/query/2_Voucher/example.go` around lines 65 - 68, The error handling for the FetchInsuranceVoucher call is inconsistent with other examples: locate the FetchInsuranceVoucher call (res, err := chainClient.FetchInsuranceVoucher(ctx, denom, address)) and replace the fmt.Println(err) branch with the project's standard error pattern used in similar examples (e.g., panic(err) or log.Fatalf with a contextual message) so failures abort/exit consistently; ensure you preserve the existing variable names (res, err) and context (ctx, denom, address) when updating the handler.examples/chain/auction/query/2_Voucher/example.go (1)
65-68: Error handling pattern inconsistent with other examples.On error, this example prints the error but continues to process and print the result (which will be nil). Consider returning early on error or using the same panic pattern as other examples for consistency.
♻️ Consistent error handling
res, err := chainClient.FetchAuctionVoucher(ctx, denom, address) if err != nil { - fmt.Println(err) + panic(err) } str, _ := json.MarshalIndent(res, "", "\t")🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@examples/chain/auction/query/2_Voucher/example.go` around lines 65 - 68, The example calls chainClient.FetchAuctionVoucher and prints the error but continues to use res; update the error handling in the FetchAuctionVoucher call (res, err := chainClient.FetchAuctionVoucher(ctx, denom, address)) to return early or panic on err (matching other examples) instead of just fmt.Println(err), so the function exits when err != nil and does not attempt to print or use a nil res.examples/exchange/oracle/5_StreamOracleList/example.go (1)
30-43: Stream loop lacks graceful error handling and context cancellation pattern.The
selectwithctx.Done()is unreachable inside thedefaultbranch sincestream.Recv()is blocking. Consider using a goroutine or restructure to properly check context cancellation. Also, for examples intended for demonstration, consider adding timeout handling forstream.Recv().♻️ Refactor stream loop for proper cancellation
for { - select { - case <-ctx.Done(): - return - default: - res, err := stream.Recv() - if err != nil { - fmt.Println(err) - return - } - str, _ := json.MarshalIndent(res, "", "\t") - fmt.Print(string(str)) - } + res, err := stream.Recv() + if err != nil { + fmt.Println(err) + return + } + str, _ := json.MarshalIndent(res, "", "\t") + fmt.Print(string(str)) }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@examples/exchange/oracle/5_StreamOracleList/example.go` around lines 30 - 43, The current loop blocks on stream.Recv() so the ctx.Done() case is never reached; refactor to perform Recv in a dedicated goroutine that sends either the received message or its error on channels, then select between ctx.Done(), the recv channel, and an optional timeout (time.After) to handle cancellation and timeouts gracefully. Specifically, create a recv goroutine that calls stream.Recv() and sends results to a msgChan/errChan, then in the main loop select on ctx.Done() to return, on msgChan to marshal/print the message, on errChan to log/handle the error and break, and optionally a timeout case to cancel long waits; reference the existing ctx and stream.Recv() to locate where to change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@chain/exchange/types/v2/position.go`:
- Around line 351-385: In ApplyBankruptCloseWithoutPayouts, guard against a
negative closingQuantity by returning early (e.g., return math.LegacyZeroDec(),
nil) when closingQuantity.IsNegative(); then compute the closed slice's margin
and remove it from the remaining position instead of keeping the whole pre-close
margin: capture origMargin := p.Margin and origQty := p.Quantity, compute
closedMargin := origMargin.Mul(closingQuantity.Quo(origQty)) (use LegacyDec
Mul/Quo), compute pnl := p.GetPayoutFromPnl(closingPrice, closingQuantity) as
you already do, and set remainingMargin :=
origMargin.Sub(closedMargin).Add(pnl); set remainingQuantity :=
origQty.Sub(closingQuantity); if remainingQuantity.IsZero() call
p.ClosePositionWithoutPayouts() else assign p.Quantity = remainingQuantity and
p.Margin = remainingMargin; keep constructing PositionDelta as you already do
(ExecutionQuantity = closingQuantity, ExecutionPrice = closingPrice, IsLong =
!p.IsLong).
In `@chain/oracle/types/pyth.go`:
- Around line 8-23: NewPythPriceState currently converts publishTime int64 to
uint64 directly which silently wraps negative times; update NewPythPriceState to
validate publishTime is >= 0 and return an error for negative values (change
signature to NewPythPriceState(...) (*PythPriceState, error)), or alternatively
accept a uint64 publishTime so callers must provide a non-negative value; ensure
you adjust the creation of PythPriceState.PriceState to use NewPriceState(price,
blockTime) as before and update all callers to handle the new error/return
signature.
- Around line 42-49: The current check in PriceAttestation.Validate is
ineffective because GetPriceIDHash uses common.HexToHash which always returns a
32-byte value; instead, validate the raw p.PriceId string itself: strip an
optional "0x" prefix, verify the hex string length equals 64 characters (32
bytes), attempt to hex-decode it (e.g., with hex.DecodeString) and return
ErrInvalidPythPriceID if decoding fails or length is wrong; after this
validation you can still use GetPriceIDHash() safely. Ensure you update
PriceAttestation.Validate (and keep ErrInvalidPythPriceID) and do not rely on
common.HexToHash for input validation.
In `@chain/peggy/types/key.go`:
- Around line 120-121: Add deprecated aliases for the renamed exported keys so
downstream consumers don’t break: keep the new exported constants RateLimitKey
and MintAmountERC20Key as-is and add variables with the old names RateLimitsKey
and MintAmountsERC20Key that point to those same byte slices (marked/decorated
as deprecated in comments). Update key.go to define RateLimitsKey = RateLimitKey
and MintAmountsERC20Key = MintAmountERC20Key so the underlying prefix bytes
remain unchanged while preserving the old symbol names for this release.
In `@chain/peggy/types/msgs.go`:
- Around line 556-563: The Members field (b.Members, type []*BridgeValidator) is
being printed with "%s", producing non-canonical "%!s(...)" output and breaking
deterministic hashing in ClaimHash(); replace that with a deterministic
serialization: iterate over b.Members in order and build a canonical string
(e.g., join(fmt.Sprintf("%s/%d", member.GetAddress(), member.Power) for each
member) or marshal each member with a deterministic codec) and use that
canonical string in the tmhash.Sum input so ClaimHash() hashes the explicit,
ordered validator contents rather than Go's default "%s" representation.
In `@examples/chain/auction/query/1_Vouchers/example.go`:
- Around line 65-71: If FetchAuctionVouchers (call to
chainClient.FetchAuctionVouchers) returns an error, stop the example instead of
continuing: check err and return/exit non‑zero with a helpful message; do the
same for json.MarshalIndent — check its error and abort on failure. Concretely,
after calling FetchAuctionVouchers, if err != nil log/print the error and
os.Exit(1) (or return), and when calling json.MarshalIndent(res, "", "\t")
capture the marshal error, handle it the same way instead of ignoring it; this
ensures you don't print a zero-value res on failures and the example returns a
non‑zero status on errors.
In `@examples/chain/ibc/channel/query/10_PacketAcknowledgements/example.go`:
- Line 21: The call to godotenv.Load() in example.go is cwd-dependent and won't
find the repo-level .env when running the example from its folder; update the
example to load the .env via an explicit path instead of relying on the working
directory (e.g., resolve the example file's directory with runtime.Caller or
compute the repo-root relative path and call godotenv.Load(resolvedPath)) so the
.env is loaded predictably when running the example; change the godotenv.Load()
invocation in this file to load the resolved path.
In `@examples/chain/insurance/query/1_Vouchers/example.go`:
- Around line 65-71: The example currently ignores errors from
chainClient.FetchInsuranceVouchers and json.MarshalIndent and proceeds to print
potentially invalid output; modify the handler around
chainClient.FetchInsuranceVouchers(ctx, denom) so that if err != nil you fail
fast (return or log.Fatal/exit) instead of continuing, and check the error
returned by json.MarshalIndent(res, "", "\t") storing to str and err (or
marshalErr) and fail fast on marshal errors as well; update references to res,
err, and str so errors are handled immediately after each call to
FetchInsuranceVouchers and json.MarshalIndent.
In `@examples/exchange/oracle/6_StreamPricesByMarkets/example.go`:
- Line 13: The network name string passed to common.LoadNetwork is misspelled;
update the call in the example where network := common.LoadNetwork("tstnet",
"lb") to use the correct network name "testnet" (i.e.,
common.LoadNetwork("testnet", "lb")) so the LoadNetwork invocation and the
variable network receive the proper environment name.
---
Outside diff comments:
In `@examples/chain/13_BroadcastMsgWithoutSimulation/example.go`:
- Around line 21-37: Replace the silent discard of godotenv.Load() in main with
explicit error handling: call godotenv.Load() and if it returns an error log a
non-fatal warning (or decide to exit) so missing or malformed .env files are
visible; update the call site in main where godotenv.Load() is currently
assigned to _ and ensure the behavior still lets InitCosmosKeyring use
os.Getenv("INJECTIVE_PRIVATE_KEY") as its documented fallback when the env var
is absent.
---
Nitpick comments:
In `@chain/peggy/types/key.go`:
- Around line 314-367: These helpers accept raw []byte for ERC20 but should use
common.Address for consistency and to enforce 20-byte addresses; change the
parameter type of GetRateLimitKey, GetMintAmountERC20Key, GetTokenInflowPrefix,
GetTokenInflowByBlockKey, GetTokenOutflowPrefix, GetTokenOutflowByBlockKey, and
GetTokenNetOutflowKey to common.Address, replace uses of erc20 and len(erc20)
with addr.Bytes() and common.AddressLength (or len(addr.Bytes())), and update
the append calls to append(addr.Bytes()...) and capacity calculations
accordingly; also add the github.com/ethereum/go-ethereum/common import and
update any callers to pass a common.Address.
In `@chain/wasmx/types/params.go`:
- Around line 17-19: Replace the bit-twiddling max value with the explicit
constant: change the computation of MaxSafeExecutionGasLimit to use
math.MaxUint64 divided by ExecutionGasFeeMultiplier, and add the necessary
import for the math package; this touches the constants
ExecutionGasFeeMultiplier and MaxSafeExecutionGasLimit in params.go.
In `@examples/chain/13_BroadcastMsgWithoutSimulation/example.go`:
- Around line 21-22: In main(), currently the return value from godotenv.Load()
is ignored; change this to check the error from godotenv.Load() and call your
logger (or log.Printf/log.Warn) to emit a warning when loading .env fails (e.g.,
"warning: failed to load .env: %v"), while still allowing the program to
continue; update the code around the godotenv.Load() call in main() to capture
err and log the warning when err != nil.
In `@examples/chain/auction/query/2_Voucher/example.go`:
- Around line 65-68: The example calls chainClient.FetchAuctionVoucher and
prints the error but continues to use res; update the error handling in the
FetchAuctionVoucher call (res, err := chainClient.FetchAuctionVoucher(ctx,
denom, address)) to return early or panic on err (matching other examples)
instead of just fmt.Println(err), so the function exits when err != nil and does
not attempt to print or use a nil res.
In `@examples/chain/distribution/query/9_CommunityPool/example.go`:
- Line 18: Replace the silent ignore of godotenv.Load() with explicit error
handling: call godotenv.Load() and if it returns an error, log a warning (via
your logger or fmt.Printf) that the .env file failed to load and include the
error text; additionally validate presence of the INJECTIVE_PRIVATE_KEY
environment variable (or detect keyring fallback) before proceeding and
log/fatal if neither is available. Locate the call to godotenv.Load() and the
code that reads INJECTIVE_PRIVATE_KEY to add these checks and messages.
In `@examples/chain/exchange/query/18_SubaccountOrders/example.go`:
- Line 17: The call to godotenv.Load() currently discards errors; change it to
check the returned error and log a warning when the .env file is missing or any
load error occurs so developers know why defaults/env vars might be absent.
Specifically, replace the standalone godotenv.Load() invocation with an error
check around godotenv.Load() (in example.go, where godotenv.Load() is called),
and use the log package to emit a warning like " .env not found: %v" when
os.IsNotExist(err) (or a generic "failed to load .env: %v" for other errors) so
missing or problematic .env files are visible during debugging.
In `@examples/chain/exchange/query/51_OptedOutOfRewardsAccounts/example.go`:
- Around line 17-18: The call to godotenv.Load() in main currently ignores
errors; change this so the error is handled or documented: check the returned
error from godotenv.Load() in main and either log/warn/fatal the error (so
missing/malformed .env is visible before keyring initialization that uses
INJECTIVE_PRIVATE_KEY) or add a comment explaining that .env is intentionally
optional; ensure the fix references the godotenv.Load() invocation and the
subsequent keyring/private key usage so users won’t get silent failures.
- Around line 25-32: The code calls InitCosmosKeyring with
os.Getenv("INJECTIVE_PRIVATE_KEY") without validating it, which can lead to
unclear downstream errors; before calling InitCosmosKeyring, check that the
INJECTIVE_PRIVATE_KEY env var is non-empty and return or log a clear error if
missing (e.g., set a descriptive error and exit or propagate it), so update the
logic around the call that assigns senderAddress, cosmosKeyring, err to validate
the env var and handle the missing-key case explicitly.
In `@examples/chain/ibc/channel/query/13_NextSequenceReceive/example.go`:
- Around line 4-16: The import ordering in example.go is inconsistent: the
standard library import "os" is separated from the other stdlib imports
("context", "encoding/json", "fmt"); move "os" into the first import group so
all standard library packages are grouped together, keeping third-party imports
(github.com/..., rpchttp) and local aliases (chainclient, common) in their
respective groups; update the import block around the file-level imports to
reflect the standard Go grouping convention.
In `@examples/chain/insurance/1_MsgClaimVoucher/example.go`:
- Line 20: The call to godotenv.Load() currently discards any error; change it
to capture the returned error from godotenv.Load() in example.go (the call site
referencing godotenv.Load) and if err != nil, log a brief warning (e.g., using
log.Printf or fmt.Println) indicating the .env file failed to load and include
the error message so failures to parse are visible in examples; keep behavior
non-fatal so the example continues running.
In `@examples/chain/insurance/query/2_Voucher/example.go`:
- Around line 65-68: The error handling for the FetchInsuranceVoucher call is
inconsistent with other examples: locate the FetchInsuranceVoucher call (res,
err := chainClient.FetchInsuranceVoucher(ctx, denom, address)) and replace the
fmt.Println(err) branch with the project's standard error pattern used in
similar examples (e.g., panic(err) or log.Fatalf with a contextual message) so
failures abort/exit consistently; ensure you preserve the existing variable
names (res, err) and context (ctx, denom, address) when updating the handler.
In `@examples/exchange/oracle/5_StreamOracleList/example.go`:
- Around line 30-43: The current loop blocks on stream.Recv() so the ctx.Done()
case is never reached; refactor to perform Recv in a dedicated goroutine that
sends either the received message or its error on channels, then select between
ctx.Done(), the recv channel, and an optional timeout (time.After) to handle
cancellation and timeouts gracefully. Specifically, create a recv goroutine that
calls stream.Recv() and sends results to a msgChan/errChan, then in the main
loop select on ctx.Done() to return, on msgChan to marshal/print the message, on
errChan to log/handle the error and break, and optionally a timeout case to
cancel long waits; reference the existing ctx and stream.Recv() to locate where
to change.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: cf8cea67-60d5-4e5d-8007-e37755eea345
⛔ Files ignored due to path filters (27)
chain/auction/types/auction.pb.gois excluded by!**/*.pb.gochain/auction/types/genesis.pb.gois excluded by!**/*.pb.gochain/auction/types/query.pb.gois excluded by!**/*.pb.gochain/auction/types/tx.pb.gois excluded by!**/*.pb.gochain/common/vouchers/types/vouchers.pb.gois excluded by!**/*.pb.gochain/exchange/types/exchange.pb.gois excluded by!**/*.pb.gochain/exchange/types/v2/exchange.pb.gois excluded by!**/*.pb.gochain/insurance/types/events.pb.gois excluded by!**/*.pb.gochain/insurance/types/genesis.pb.gois excluded by!**/*.pb.gochain/insurance/types/insurance.pb.gois excluded by!**/*.pb.gochain/insurance/types/query.pb.gois excluded by!**/*.pb.gochain/insurance/types/tx.pb.gois excluded by!**/*.pb.gochain/oracle/types/events.pb.gois excluded by!**/*.pb.gochain/oracle/types/genesis.pb.gois excluded by!**/*.pb.gochain/oracle/types/oracle.pb.gois excluded by!**/*.pb.gochain/peggy/types/genesis.pb.gois excluded by!**/*.pb.gochain/peggy/types/msgs.pb.gois excluded by!**/*.pb.gochain/peggy/types/rate_limit.pb.gois excluded by!**/*.pb.gochain/permissions/types/events.pb.gois excluded by!**/*.pb.gochain/permissions/types/genesis.pb.gois excluded by!**/*.pb.gochain/permissions/types/params.pb.gois excluded by!**/*.pb.gochain/permissions/types/permissions.pb.gois excluded by!**/*.pb.gochain/permissions/types/query.pb.gois excluded by!**/*.pb.gochain/txfees/types/tx.pb.gois excluded by!**/*.pb.gochain/txfees/types/txfees.pb.gois excluded by!**/*.pb.gochain/wasmx/types/tx.pb.gois excluded by!**/*.pb.goexchange/accounts_rpc/pb/goadesign_goagen_injective_accounts_rpc.pb.gois excluded by!**/*.pb.go
📒 Files selected for processing (273)
.env.example.github/workflows/golangci-lint.yml.gitignoreMakefilechain/auction/types/codec.gochain/downtime-detector/types/keys.gochain/evm/types/errors.gochain/exchange/types/authz_common.gochain/exchange/types/common_utils.gochain/exchange/types/errors.gochain/exchange/types/key.gochain/exchange/types/msgs.gochain/exchange/types/params.gochain/exchange/types/proposal.gochain/exchange/types/v2/authz.gochain/exchange/types/v2/derivative.gochain/exchange/types/v2/derivative_orders.gochain/exchange/types/v2/fee_discounts.gochain/exchange/types/v2/msgs.gochain/exchange/types/v2/params.gochain/exchange/types/v2/position.gochain/exchange/types/v2/proposal.gochain/insurance/types/codec.gochain/oracle/types/chainlink_data_streams.gochain/oracle/types/codec.gochain/oracle/types/oracle.gochain/oracle/types/params.gochain/oracle/types/pyth.gochain/peggy/types/key.gochain/peggy/types/msgs.gochain/types/config.gochain/types/util.gochain/wasmx/types/params.goclient/chain/chain_test_support.goclient/chain/chain_v2.goclient/exchange/exchange.goexamples/chain/13_BroadcastMsgWithoutSimulation/example.goexamples/chain/14_HistoricalQueryByHeight/example.goexamples/chain/1_LocalOrderHash/example.goexamples/chain/2_MsgBatchCancelSpotOrders/example.goexamples/chain/3_MsgBatchCancelDerivativeOrders/example.goexamples/chain/4_MsgBatchCreateSpotLimitOrders/example.goexamples/chain/5_MsgBatchCreateDerivativeLimitOrders/example.goexamples/chain/6_MsgRegisterAsDMM/example.goexamples/chain/8_OfflineSigning/example.goexamples/chain/auction/1_MsgBid/example.goexamples/chain/auction/2_MsgClaimVoucher/example.goexamples/chain/auction/query/1_Vouchers/example.goexamples/chain/auction/query/2_Voucher/example.goexamples/chain/auth/query/1_Account/example.goexamples/chain/authz/1_MsgGrant/example.goexamples/chain/authz/2_MsgExec/example.goexamples/chain/authz/3_MsgRevoke/example.goexamples/chain/authz/query/1_Grants/example.goexamples/chain/bank/1_MsgSend/example.goexamples/chain/bank/2_MsgMultiSend/example.goexamples/chain/bank/query/10_BankSendEnabled/example.goexamples/chain/bank/query/1_BankBalance/example.goexamples/chain/bank/query/2_BankBalances/example.goexamples/chain/bank/query/3_BankSpendableBalances/example.goexamples/chain/bank/query/4_BankSpendableBalancesByDenom/example.goexamples/chain/bank/query/5_BankTotalSupply/example.goexamples/chain/bank/query/6_BankSupplyOf/example.goexamples/chain/bank/query/7_DenomMetadata/example.goexamples/chain/bank/query/8_DenomsMetadata/example.goexamples/chain/bank/query/9_DenomOwners/example.goexamples/chain/distribution/1_SetWithdrawAddress/example.goexamples/chain/distribution/2_MsgWithdrawDelegatorReward/example.goexamples/chain/distribution/3_WithdrawValidatorCommission/example.goexamples/chain/distribution/4_FundCommunityPool/example.goexamples/chain/distribution/query/1_ValidatorDistributionInfo/example.goexamples/chain/distribution/query/2_ValidatorOutstandingRewards/example.goexamples/chain/distribution/query/3_ValidatorCommission/example.goexamples/chain/distribution/query/4_ValidatorSlashes/example.goexamples/chain/distribution/query/5_DelegationRewards/example.goexamples/chain/distribution/query/6_DelegationTotalRewards/example.goexamples/chain/distribution/query/7_DelegatorValidators/example.goexamples/chain/distribution/query/8_DelegatorWithdrawAddress/example.goexamples/chain/distribution/query/9_CommunityPool/example.goexamples/chain/erc20/1_CreateTokenPair/example.goexamples/chain/erc20/2_DeleteTokenPair/example.goexamples/chain/erc20/query/1_AllTokenPairs/example.goexamples/chain/erc20/query/2_TokenPairByDenom/example.goexamples/chain/erc20/query/3_TokenPairByERC20Address/example.goexamples/chain/evm/query/1_Account/example.goexamples/chain/evm/query/2_CosmosAccount/example.goexamples/chain/evm/query/3_ValidatorAccount/example.goexamples/chain/evm/query/4_Balance/example.goexamples/chain/evm/query/5_Storage/example.goexamples/chain/evm/query/6_Code/example.goexamples/chain/evm/query/7_BaseFee/example.goexamples/chain/exchange/10_MsgCreateDerivativeLimitOrder/example.goexamples/chain/exchange/11_MsgCreateDerivativeMarketOrder/example.goexamples/chain/exchange/12_MsgCancelDerivativeOrder/example.goexamples/chain/exchange/13_MsgInstantBinaryOptionsMarketLaunch/example.goexamples/chain/exchange/14_MsgSubaccountTransfer/example.goexamples/chain/exchange/15_MsgExternalTransfer/example.goexamples/chain/exchange/16_MsgLiquidatePosition/example.goexamples/chain/exchange/17_MsgIncreasePositionMargin/example.goexamples/chain/exchange/1_MsgDeposit/example.goexamples/chain/exchange/21_MsgRewardsOptOut/example.goexamples/chain/exchange/23_MsgDecreasePositionMargin/example.goexamples/chain/exchange/24_MsgUpdateSpotMarket/example.goexamples/chain/exchange/25_MsgUpdateDerivativeMarket/example.goexamples/chain/exchange/26_MsgAuthorizeStakeGrants/example.goexamples/chain/exchange/27_MsgActivateStakeGrant/example.goexamples/chain/exchange/28_MsgCreateGTBSpotLimitOrder/example.goexamples/chain/exchange/29_MsgCreateGTBDerivativeLimitOrder/example.goexamples/chain/exchange/2_MsgWithdraw/example.goexamples/chain/exchange/30_MsgOffsetPosition/example.goexamples/chain/exchange/3_MsgInstantSpotMarketLaunch/example.goexamples/chain/exchange/4_MsgInstantPerpetualMarketLaunch/example.goexamples/chain/exchange/5_MsgInstantExpiryFuturesMarketLaunch/example.goexamples/chain/exchange/6_MsgCreateSpotLimitOrder/example.goexamples/chain/exchange/7_MsgCreateSpotMarketOrder/example.goexamples/chain/exchange/8_MsgCancelSpotOrder/example.goexamples/chain/exchange/9_MsgBatchUpdateOrders/example.goexamples/chain/exchange/query/10_SpotMarkets/example.goexamples/chain/exchange/query/11_SpotMarket/example.goexamples/chain/exchange/query/12_FullSpotMarkets/example.goexamples/chain/exchange/query/13_FullSpotMarket/example.goexamples/chain/exchange/query/14_SpotOrderbook/example.goexamples/chain/exchange/query/15_TraderSpotOrders/example.goexamples/chain/exchange/query/16_AccountAddressSpotOrders/example.goexamples/chain/exchange/query/17_SpotOrdersByHashes/example.goexamples/chain/exchange/query/18_SubaccountOrders/example.goexamples/chain/exchange/query/19_TraderSpotTransientOrders/example.goexamples/chain/exchange/query/1_SubaccountDeposits/example.goexamples/chain/exchange/query/20_SpotMidPriceAndTOB/example.goexamples/chain/exchange/query/21_DerivativeMidPriceAndTOB/example.goexamples/chain/exchange/query/22_DerivativeOrderbook/example.goexamples/chain/exchange/query/23_TraderDerivativeOrders/example.goexamples/chain/exchange/query/24_AccountAddressDerivativeOrders/example.goexamples/chain/exchange/query/25_DerivativeOrdersByHashes/example.goexamples/chain/exchange/query/26_TraderDerivativeTransientOrders/example.goexamples/chain/exchange/query/27_DerivativeMarkets/example.goexamples/chain/exchange/query/28_DerivativeMarket/example.goexamples/chain/exchange/query/29_DerivativeMarketAddress/example.goexamples/chain/exchange/query/2_SubaccountDeposit/example.goexamples/chain/exchange/query/30_SubaccountTradeNonce/example.goexamples/chain/exchange/query/31_Positions/example.goexamples/chain/exchange/query/32_SubaccountPositions/example.goexamples/chain/exchange/query/33_SubaccountPositionInMarket/example.goexamples/chain/exchange/query/34_SubaccountEffectivePositionInMarket/example.goexamples/chain/exchange/query/35_PerpetualMarketInfo/example.goexamples/chain/exchange/query/36_ExpiryFuturesMarketInfo/example.goexamples/chain/exchange/query/37_PerpetualMarketFunding/example.goexamples/chain/exchange/query/38_SubaccountOrderMetadata/example.goexamples/chain/exchange/query/39_TradeRewardPoints/example.goexamples/chain/exchange/query/3_ExchangeBalances/example.goexamples/chain/exchange/query/40_PendingTradeRewardPoints/example.goexamples/chain/exchange/query/41_TradeRewardCampaign/example.goexamples/chain/exchange/query/42_FeeDiscountAccountInfo/example.goexamples/chain/exchange/query/43_FeeDiscountSchedule/example.goexamples/chain/exchange/query/44_BalanceMismatches/example.goexamples/chain/exchange/query/45_BalanceWithBalanceHolds/example.goexamples/chain/exchange/query/46_FeeDiscountTierStatistics/example.goexamples/chain/exchange/query/47_MitoVaultInfos/example.goexamples/chain/exchange/query/48_QueryMarketIDFromVault/example.goexamples/chain/exchange/query/49_HistoricalTradeRecords/example.goexamples/chain/exchange/query/4_AggregateVolume/example.goexamples/chain/exchange/query/50_IsOptedOutOfRewards/example.goexamples/chain/exchange/query/51_OptedOutOfRewardsAccounts/example.goexamples/chain/exchange/query/52_MarketVolatility/example.goexamples/chain/exchange/query/53_BinaryOptionsMarkets/example.goexamples/chain/exchange/query/54_TraderDerivativeConditionalOrders/example.goexamples/chain/exchange/query/55_MarketAtomicExecutionFeeMultiplier/example.goexamples/chain/exchange/query/56_ActivateStakeGrant/example.goexamples/chain/exchange/query/57_GrantAuthorization/example.goexamples/chain/exchange/query/57_GrantAuthorization/injective_data/ofac.jsonexamples/chain/exchange/query/58_GrantAuthorizations/example.goexamples/chain/exchange/query/59_MarketBalance/example.goexamples/chain/exchange/query/5_AggregateVolumes/example.goexamples/chain/exchange/query/60_MarketBalances/example.goexamples/chain/exchange/query/61_DenomMinNotional/example.goexamples/chain/exchange/query/62_DenomMinNotionals/example.goexamples/chain/exchange/query/63_L3DerivativeOrderBook/example.goexamples/chain/exchange/query/64_L3SpotOrderBook/example.goexamples/chain/exchange/query/65_PositionsInMarket/example.goexamples/chain/exchange/query/66_OpenInterest/example.goexamples/chain/exchange/query/6_AggregateMarketVolume/example.goexamples/chain/exchange/query/7_AggregateMarketVolumes/example.goexamples/chain/exchange/query/8_AuctionExchangeTransferDenomDecimal/example.goexamples/chain/exchange/query/9_AuctionExchangeTransferDenomDecimals/example.goexamples/chain/ibc/channel/query/10_PacketAcknowledgements/example.goexamples/chain/ibc/channel/query/11_UnreceivedPackets/example.goexamples/chain/ibc/channel/query/12_UnreceivedAcks/example.goexamples/chain/ibc/channel/query/13_NextSequenceReceive/example.goexamples/chain/ibc/channel/query/1_Channel/example.goexamples/chain/ibc/channel/query/2_Channels/example.goexamples/chain/ibc/channel/query/3_ConnectionChannels/example.goexamples/chain/ibc/channel/query/4_ChannelClientState/example.goexamples/chain/ibc/channel/query/5_ChannelConsensusState/example.goexamples/chain/ibc/channel/query/6_PacketCommitment/example.goexamples/chain/ibc/channel/query/7_PacketCommitments/example.goexamples/chain/ibc/channel/query/8_PacketReceipt/example.goexamples/chain/ibc/channel/query/9_PacketAcknowledgement/example.goexamples/chain/ibc/client/query/1_ClientState/example.goexamples/chain/ibc/client/query/2_ClientStates/example.goexamples/chain/ibc/client/query/3_ConsensusState/example.goexamples/chain/ibc/client/query/4_ConsensusStates/example.goexamples/chain/ibc/client/query/5_ConsensusStateHeight/example.goexamples/chain/ibc/client/query/6_ClientStatus/example.goexamples/chain/ibc/client/query/7_ClientParams/example.goexamples/chain/ibc/client/query/8_UpgradedClientState/example.goexamples/chain/ibc/client/query/9_UpgradedConsensusState/example.goexamples/chain/ibc/connection/query/1_Connection/example.goexamples/chain/ibc/connection/query/2_Connections/example.goexamples/chain/ibc/connection/query/3_ClientConnections/example.goexamples/chain/ibc/connection/query/4_ConnectionClientState/example.goexamples/chain/ibc/connection/query/5_ConnectionConsensusState/example.goexamples/chain/ibc/connection/query/6_ConnectionParams/example.goexamples/chain/ibc/transfer/1_MsgTransfer/example.goexamples/chain/ibc/transfer/query/1_DenomTrace/example.goexamples/chain/ibc/transfer/query/2_DenomTraces/example.goexamples/chain/ibc/transfer/query/3_DenomHash/example.goexamples/chain/ibc/transfer/query/4_EscrowAddress/example.goexamples/chain/ibc/transfer/query/5_TotalEscrowForDenom/example.goexamples/chain/insurance/1_MsgClaimVoucher/example.goexamples/chain/insurance/query/1_Vouchers/example.goexamples/chain/insurance/query/2_Voucher/example.goexamples/chain/oracle/1_MsgRelayPriceFeedPrice/example.goexamples/chain/peggy/1_MsgSendToEth/example.goexamples/chain/permissions/1_MsgCreateNamespace/example.goexamples/chain/permissions/2_MsgUpdateNamespace/example.goexamples/chain/permissions/3_MsgUpdateActorRoles/example.goexamples/chain/permissions/4_MsgClaimVoucher/example.goexamples/chain/permissions/query/10_Vouchers/example.goexamples/chain/permissions/query/11_Voucher/example.goexamples/chain/permissions/query/12_PermissionsModuleState/example.goexamples/chain/permissions/query/1_NamespaceDenoms/example.goexamples/chain/permissions/query/2_Namespaces/example.goexamples/chain/permissions/query/3_Namespace/example.goexamples/chain/permissions/query/4_RolesByActor/example.goexamples/chain/permissions/query/5_ActorsByRole/example.goexamples/chain/permissions/query/6_RoleManagers/example.goexamples/chain/permissions/query/7_RoleManager/example.goexamples/chain/permissions/query/8_PolicyStatuses/example.goexamples/chain/permissions/query/9_PolicyManagerCapabilities/example.goexamples/chain/staking/1_MsgDelegate/example.goexamples/chain/tendermint/query/1_GetNodeInfo/example.goexamples/chain/tendermint/query/2_GetSyncing/example.goexamples/chain/tendermint/query/3_GetLatestBlock/example.goexamples/chain/tendermint/query/4_GetBlockByHeight/example.goexamples/chain/tendermint/query/5_GetLatestValidatorSet/example.goexamples/chain/tendermint/query/6_GetValidatorSetByHeight/example.goexamples/chain/tokenfactory/1_CreateDenom/example.goexamples/chain/tokenfactory/2_MsgMint/example.goexamples/chain/tokenfactory/3_MsgBurn/example.goexamples/chain/tokenfactory/4_MsgSetDenomMetadata/example.goexamples/chain/tokenfactory/5_MsgChangeAdmin/example.goexamples/chain/tokenfactory/query/1_DenomAuthorityMetadata/example.goexamples/chain/tokenfactory/query/2_DenomsFromCreator/example.goexamples/chain/tokenfactory/query/3_TokenfactoryModuleState/example.goexamples/chain/tx/query/1_GetTx/example.goexamples/chain/txfees/query/1_GetEipBaseFee/example.goexamples/chain/wasm/query/10_ContractsByCreator/example.goexamples/chain/wasm/query/1_ContractInfo/example.goexamples/chain/wasm/query/2_ContractHistory/example.goexamples/chain/wasm/query/3_ContractsByCode/example.goexamples/chain/wasm/query/4_AllContractsState/example.goexamples/chain/wasm/query/5_RawContractState/example.goexamples/chain/wasm/query/6_SmartContractState/example.goexamples/chain/wasm/query/7_SmartContractCode/example.goexamples/chain/wasm/query/8_SmartContractCodes/example.goexamples/chain/wasm/query/9_SmartContractPinnedCodes/example.goexamples/chain/wasmx/1_MsgExecuteContractCompat/example.goexamples/exchange/oracle/1_StreamPrices/example.goexamples/exchange/oracle/1_StreamPrices/injective_data/ofac.jsonexamples/exchange/oracle/2_Price/example.goexamples/exchange/oracle/4_PriceV2/example.goexamples/exchange/oracle/5_StreamOracleList/example.goexamples/exchange/oracle/6_StreamPricesByMarkets/example.go
💤 Files with no reviewable changes (2)
- examples/chain/exchange/query/57_GrantAuthorization/injective_data/ofac.json
- examples/exchange/oracle/1_StreamPrices/injective_data/ofac.json
| func (p *Position) ApplyBankruptCloseWithoutPayouts( | ||
| closingPrice, closingQuantity math.LegacyDec, | ||
| ) (pnl math.LegacyDec, positionDelta *PositionDelta) { | ||
| if p == nil { | ||
| return math.LegacyZeroDec(), nil | ||
| } | ||
|
|
||
| if p.Quantity.IsZero() || closingQuantity.IsZero() { | ||
| return math.LegacyZeroDec(), &PositionDelta{ | ||
| IsLong: !p.IsLong, | ||
| ExecutionQuantity: math.LegacyZeroDec(), | ||
| ExecutionMargin: math.LegacyZeroDec(), | ||
| ExecutionPrice: closingPrice, | ||
| } | ||
| } | ||
|
|
||
| closingQuantity = math.LegacyMinDec(p.Quantity, closingQuantity) | ||
| positionDelta = &PositionDelta{ | ||
| IsLong: !p.IsLong, | ||
| ExecutionQuantity: closingQuantity, | ||
| ExecutionMargin: math.LegacyZeroDec(), | ||
| ExecutionPrice: closingPrice, | ||
| } | ||
|
|
||
| pnl = p.GetPayoutFromPnl(closingPrice, closingQuantity) | ||
| remainingMargin := p.Margin.Add(pnl) | ||
| remainingQuantity := p.Quantity.Sub(closingQuantity) | ||
|
|
||
| if remainingQuantity.IsZero() { | ||
| p.ClosePositionWithoutPayouts() | ||
| return pnl, positionDelta | ||
| } | ||
|
|
||
| p.Quantity = remainingQuantity | ||
| p.Margin = remainingMargin |
There was a problem hiding this comment.
Guard closingQuantity and fix the partial-close margin accounting.
A negative closingQuantity currently makes this method increase p.Quantity (remainingQuantity := p.Quantity.Sub(closingQuantity)), and the partial-close path keeps all pre-close margin on the reduced position via p.Margin = p.Margin.Add(pnl). That produces invalid state unless callers always pass the exact bankruptcy price for the closed slice. Please reject negative quantities up front and apportion/remove the closed slice’s margin explicitly in the partial-close branch.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@chain/exchange/types/v2/position.go` around lines 351 - 385, In
ApplyBankruptCloseWithoutPayouts, guard against a negative closingQuantity by
returning early (e.g., return math.LegacyZeroDec(), nil) when
closingQuantity.IsNegative(); then compute the closed slice's margin and remove
it from the remaining position instead of keeping the whole pre-close margin:
capture origMargin := p.Margin and origQty := p.Quantity, compute closedMargin
:= origMargin.Mul(closingQuantity.Quo(origQty)) (use LegacyDec Mul/Quo), compute
pnl := p.GetPayoutFromPnl(closingPrice, closingQuantity) as you already do, and
set remainingMargin := origMargin.Sub(closedMargin).Add(pnl); set
remainingQuantity := origQty.Sub(closingQuantity); if remainingQuantity.IsZero()
call p.ClosePositionWithoutPayouts() else assign p.Quantity = remainingQuantity
and p.Margin = remainingMargin; keep constructing PositionDelta as you already
do (ExecutionQuantity = closingQuantity, ExecutionPrice = closingPrice, IsLong =
!p.IsLong).
| func NewPythPriceState( | ||
| priceID common.Hash, | ||
| emaPrice, emaConf, conf math.LegacyDec, | ||
| publishTime int64, | ||
| price math.LegacyDec, | ||
| blockTime int64, | ||
| ) *PythPriceState { | ||
| return &PythPriceState{ | ||
| PriceId: priceID.Hex(), | ||
| EmaPrice: emaPrice, | ||
| EmaConf: emaConf, | ||
| Conf: conf, | ||
| PublishTime: uint64(publishTime), | ||
| PriceState: *NewPriceState(price, blockTime), | ||
| } | ||
| } |
There was a problem hiding this comment.
Avoid wrapping negative publish times into huge uint64 values.
Line 20 converts publishTime from int64 to uint64 without validation. A negative input becomes a very large timestamp instead of being rejected, which lets this helper construct an invalid PythPriceState.
💡 Safer direction
func NewPythPriceState(
priceID common.Hash,
emaPrice, emaConf, conf math.LegacyDec,
- publishTime int64,
+ publishTime uint64,
price math.LegacyDec,
blockTime int64,
) *PythPriceState {
return &PythPriceState{
PriceId: priceID.Hex(),
EmaPrice: emaPrice,
EmaConf: emaConf,
Conf: conf,
- PublishTime: uint64(publishTime),
+ PublishTime: publishTime,
PriceState: *NewPriceState(price, blockTime),
}
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| func NewPythPriceState( | |
| priceID common.Hash, | |
| emaPrice, emaConf, conf math.LegacyDec, | |
| publishTime int64, | |
| price math.LegacyDec, | |
| blockTime int64, | |
| ) *PythPriceState { | |
| return &PythPriceState{ | |
| PriceId: priceID.Hex(), | |
| EmaPrice: emaPrice, | |
| EmaConf: emaConf, | |
| Conf: conf, | |
| PublishTime: uint64(publishTime), | |
| PriceState: *NewPriceState(price, blockTime), | |
| } | |
| } | |
| func NewPythPriceState( | |
| priceID common.Hash, | |
| emaPrice, emaConf, conf math.LegacyDec, | |
| publishTime uint64, | |
| price math.LegacyDec, | |
| blockTime int64, | |
| ) *PythPriceState { | |
| return &PythPriceState{ | |
| PriceId: priceID.Hex(), | |
| EmaPrice: emaPrice, | |
| EmaConf: emaConf, | |
| Conf: conf, | |
| PublishTime: publishTime, | |
| PriceState: *NewPriceState(price, blockTime), | |
| } | |
| } |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@chain/oracle/types/pyth.go` around lines 8 - 23, NewPythPriceState currently
converts publishTime int64 to uint64 directly which silently wraps negative
times; update NewPythPriceState to validate publishTime is >= 0 and return an
error for negative values (change signature to NewPythPriceState(...)
(*PythPriceState, error)), or alternatively accept a uint64 publishTime so
callers must provide a non-negative value; ensure you adjust the creation of
PythPriceState.PriceState to use NewPriceState(price, blockTime) as before and
update all callers to handle the new error/return signature.
| func (p *PriceAttestation) GetPriceIDHash() common.Hash { | ||
| return common.HexToHash(p.PriceId) | ||
| } | ||
|
|
||
| func (p *PriceAttestation) Validate() error { | ||
| if len(p.GetPriceIDHash().Bytes()) != 32 { | ||
| return ErrInvalidPythPriceID | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
In go-ethereum v1.15.x, what does common.HexToHash do with short or malformed hex strings, and does common.Hash.Bytes() always return 32 bytes?
💡 Result:
In go-ethereum v1.15.x, common.HexToHash(s string) Hash converts the hex string s (with optional "0x" prefix) to a common.Hash by first calling FromHex(s), which strips the prefix if present, pads odd-length hex strings with a leading zero, and decodes using hex.DecodeString (ignoring decode errors). The resulting bytes are then converted to a fixed-size [32]byte Hash via BytesToHash, which right-pads short byte arrays with zeros to 32 bytes or takes the rightmost 32 bytes if longer. For short hex strings (e.g., fewer than 64 hex chars), it produces a Hash with leading zero bytes (right-padded). For malformed hex strings (invalid chars), hex.DecodeString returns partial bytes up to the first invalid char (no error returned), so it produces a Hash from those bytes (right-padded if short). common.Hash.Bytes always returns a 32-byte slice, as Hash is type [32]byte and Bytes returns h[:], the full fixed array. v1.15.x releases (e.g., v1.15.8) use the same common package implementation as shown in master and v1.14.12 sources.
Citations:
- 1: https://github.com/ethereum/go-ethereum/blob/v1.14.12/common/bytes.go
- 2: https://godoc.org/github.com/ethereum/go-ethereum/common
- 3: https://pkg.go.dev/github.com/ethereum/go-ethereum/common
- 4: https://github.com/ethereum/go-ethereum/blob/master/common/types.go
- 5: https://github.com/ethereum/go-ethereum/blob/master/common/bytes.go
- 6: https://pkg.go.dev/github.com/FHigher/go-ethereum/common
- 7: https://github.com/ethereum/go-ethereum/releases/tag/v1.15.8
- 8: https://github.com/ethereum/go-ethereum/releases/tag/v1.15.4
- 9: https://github.com/ethereum/go-ethereum/tags
🏁 Script executed:
# First, locate and read the pyth.go file
fd -t f "pyth.go" | head -5Repository: InjectiveLabs/sdk-go
Length of output: 91
🏁 Script executed:
# Find the pyth.go file
find . -name "pyth.go" -type f 2>/dev/nullRepository: InjectiveLabs/sdk-go
Length of output: 93
🏁 Script executed:
# Read the pyth.go file to verify the code
cat -n chain/oracle/types/pyth.go | head -80Repository: InjectiveLabs/sdk-go
Length of output: 2226
🏁 Script executed:
# Check the imports in the file
head -20 chain/oracle/types/pyth.goRepository: InjectiveLabs/sdk-go
Length of output: 483
The price ID length check is ineffective.
common.HexToHash always normalizes input into a fixed 32-byte common.Hash, padding short byte sequences with zeros. The check len(p.GetPriceIDHash().Bytes()) != 32 will always succeed regardless of input validity, failing to reject short or malformed hex strings (e.g., "0x1", "0xZZ"). Validate the original hex string before conversion instead.
🔎 Suggested fix
import (
+ "encoding/hex"
+ "strings"
+
"cosmossdk.io/math"
"github.com/ethereum/go-ethereum/common"
)
@@
func (p *PriceAttestation) Validate() error {
- if len(p.GetPriceIDHash().Bytes()) != 32 {
+ raw := strings.TrimPrefix(p.PriceId, "0x")
+ decoded, err := hex.DecodeString(raw)
+ if err != nil || len(decoded) != common.HashLength {
return ErrInvalidPythPriceID
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| func (p *PriceAttestation) GetPriceIDHash() common.Hash { | |
| return common.HexToHash(p.PriceId) | |
| } | |
| func (p *PriceAttestation) Validate() error { | |
| if len(p.GetPriceIDHash().Bytes()) != 32 { | |
| return ErrInvalidPythPriceID | |
| } | |
| func (p *PriceAttestation) GetPriceIDHash() common.Hash { | |
| return common.HexToHash(p.PriceId) | |
| } | |
| func (p *PriceAttestation) Validate() error { | |
| raw := strings.TrimPrefix(p.PriceId, "0x") | |
| decoded, err := hex.DecodeString(raw) | |
| if err != nil || len(decoded) != common.HashLength { | |
| return ErrInvalidPythPriceID | |
| } |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@chain/oracle/types/pyth.go` around lines 42 - 49, The current check in
PriceAttestation.Validate is ineffective because GetPriceIDHash uses
common.HexToHash which always returns a 32-byte value; instead, validate the raw
p.PriceId string itself: strip an optional "0x" prefix, verify the hex string
length equals 64 characters (32 bytes), attempt to hex-decode it (e.g., with
hex.DecodeString) and return ErrInvalidPythPriceID if decoding fails or length
is wrong; after this validation you can still use GetPriceIDHash() safely.
Ensure you update PriceAttestation.Validate (and keep ErrInvalidPythPriceID) and
do not rely on common.HexToHash for input validation.
| RateLimitKey = []byte{0x1e} | ||
| MintAmountERC20Key = []byte{0x1f} |
There was a problem hiding this comment.
Keep deprecated aliases for the renamed exported keys.
Lines 120-121 rename exported symbols in a public package. That is a source-breaking change for downstream consumers still importing RateLimitsKey or MintAmountsERC20Key, even though the underlying prefix bytes did not change. Please keep the old names as deprecated aliases for this release and remove them in the next major version instead.
Suggested compatibility shim
var (
- RateLimitKey = []byte{0x1e}
- MintAmountERC20Key = []byte{0x1f}
+ RateLimitKey = []byte{0x1e}
+ // Deprecated: use RateLimitKey.
+ RateLimitsKey = RateLimitKey
+ MintAmountERC20Key = []byte{0x1f}
+ // Deprecated: use MintAmountERC20Key.
+ MintAmountsERC20Key = MintAmountERC20Key
RateLimitInflowKey = []byte{0x20}
RateLimitOutflowKey = []byte{0x21}
RateLimitNetOutflowKey = []byte{0x22}
)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@chain/peggy/types/key.go` around lines 120 - 121, Add deprecated aliases for
the renamed exported keys so downstream consumers don’t break: keep the new
exported constants RateLimitKey and MintAmountERC20Key as-is and add variables
with the old names RateLimitsKey and MintAmountsERC20Key that point to those
same byte slices (marked/decorated as deprecated in comments). Update key.go to
define RateLimitsKey = RateLimitKey and MintAmountsERC20Key = MintAmountERC20Key
so the underlying prefix bytes remain unchanged while preserving the old symbol
names for this release.
| return tmhash.Sum([]byte(fmt.Sprintf("%d/%d/%d/%s/%s/%s", | ||
| b.ValsetNonce, | ||
| b.EventNonce, | ||
| b.BlockHeight, | ||
| b.Members, | ||
| b.RewardToken, | ||
| b.RewardAmount.String(), | ||
| ))) |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== Locate MsgValsetUpdatedClaim and inspect Members type =="
rg -n -C2 'type MsgValsetUpdatedClaim struct|Members ' --glob '*.go'
echo
echo "== Inspect this ClaimHash implementation =="
rg -n -C3 'func \(b \*MsgValsetUpdatedClaim\) ClaimHash\(\)' --glob '*.go'
echo
echo "== Find chain/sdk peers that serialize valset members for hashing =="
rg -n -C3 'ValsetUpdatedClaim|ClaimHash\(\)|EthereumAddress.*Power|strings\.Join\(members' --glob '*.go'Repository: InjectiveLabs/sdk-go
Length of output: 36515
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== Find BridgeValidator struct definition =="
rg -n 'type BridgeValidator struct' --glob '*.go' -A 10
echo
echo "== Check if there are canonical serialization patterns for members elsewhere =="
rg -n 'for.*Members|for.*members' --glob 'chain/peggy/types/*.go' -B 2 -A 3 | head -80
echo
echo "== Look for any existing member serialization in chain code =="
rg -n 'EthereumAddress.*Power|marshal.*[Mm]ember' --glob 'chain/peggy/**/*.go' -i | head -40Repository: InjectiveLabs/sdk-go
Length of output: 5832
🏁 Script executed:
#!/bin/bash
set -euo pipefail
cat > /tmp/test_format.go << 'EOF'
package main
import (
"fmt"
)
type BridgeValidator struct {
Power uint64
EthereumAddress string
}
func main() {
members := []*BridgeValidator{
{Power: 1, EthereumAddress: "0xabc123"},
{Power: 2, EthereumAddress: "0xdef456"},
}
// Test what %s produces
output := fmt.Sprintf("%s", members)
fmt.Printf("Output with %%s: %s\n", output)
fmt.Printf("Output length: %d\n", len(output))
// Test multiple times to check if deterministic
output2 := fmt.Sprintf("%s", members)
fmt.Printf("Second output matches first: %v\n", output == output2)
// What about with %v?
output3 := fmt.Sprintf("%v", members)
fmt.Printf("Output with %%v: %s\n", output3)
}
EOF
go run /tmp/test_format.go 2>&1 || echo "Go test failed - checking environment"Repository: InjectiveLabs/sdk-go
Length of output: 264
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== Get the full ClaimHash method and context =="
sed -n '554,565p' chain/peggy/types/msgs.go
echo
echo "== Check what other ClaimHash methods look like =="
rg -n 'func \(.*\) ClaimHash\(\)' --glob 'chain/peggy/types/*.go' -A 5 | head -100Repository: InjectiveLabs/sdk-go
Length of output: 2124
Use canonical member serialization instead of %s for the Members field.
b.Members is []*BridgeValidator, not a string. Using %s produces Go's error marker format (%!s(...)) rather than the validator contents, which breaks deterministic hashing. Since ClaimHash() is the canonical claim identifier for validator agreement, non-canonical serialization will cause hash mismatches with the chain and other clients, invalidating claim consensus.
Suggested fix
+members := make([]string, 0, len(b.Members))
+for _, m := range b.Members {
+ members = append(members, fmt.Sprintf("%s/%d", m.EthereumAddress, m.Power))
+}
- return tmhash.Sum([]byte(fmt.Sprintf("%d/%d/%d/%s/%s/%s",
+ return tmhash.Sum([]byte(fmt.Sprintf("%d/%d/%d/%s/%s/%s",
b.ValsetNonce,
b.EventNonce,
b.BlockHeight,
- b.Members,
+ strings.Join(members, ","),
b.RewardToken,
b.RewardAmount.String(),
)))🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@chain/peggy/types/msgs.go` around lines 556 - 563, The Members field
(b.Members, type []*BridgeValidator) is being printed with "%s", producing
non-canonical "%!s(...)" output and breaking deterministic hashing in
ClaimHash(); replace that with a deterministic serialization: iterate over
b.Members in order and build a canonical string (e.g., join(fmt.Sprintf("%s/%d",
member.GetAddress(), member.Power) for each member) or marshal each member with
a deterministic codec) and use that canonical string in the tmhash.Sum input so
ClaimHash() hashes the explicit, ordered validator contents rather than Go's
default "%s" representation.
| res, err := chainClient.FetchAuctionVouchers(ctx, denom) | ||
| if err != nil { | ||
| fmt.Println(err) | ||
| } | ||
|
|
||
| str, _ := json.MarshalIndent(res, "", "\t") | ||
| fmt.Print(string(str)) |
There was a problem hiding this comment.
Stop on query/marshal failures instead of printing misleading output.
If FetchAuctionVouchers fails, the example still continues to marshal/print the zero-value response and exits successfully. Line 70 also drops the marshal error. This makes broken setups look like successful runs.
Suggested fix
res, err := chainClient.FetchAuctionVouchers(ctx, denom)
if err != nil {
- fmt.Println(err)
+ fmt.Fprintln(os.Stderr, err)
+ os.Exit(1)
}
- str, _ := json.MarshalIndent(res, "", "\t")
+ str, err := json.MarshalIndent(res, "", "\t")
+ if err != nil {
+ fmt.Fprintln(os.Stderr, err)
+ os.Exit(1)
+ }
fmt.Print(string(str))📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| res, err := chainClient.FetchAuctionVouchers(ctx, denom) | |
| if err != nil { | |
| fmt.Println(err) | |
| } | |
| str, _ := json.MarshalIndent(res, "", "\t") | |
| fmt.Print(string(str)) | |
| res, err := chainClient.FetchAuctionVouchers(ctx, denom) | |
| if err != nil { | |
| fmt.Fprintln(os.Stderr, err) | |
| os.Exit(1) | |
| } | |
| str, err := json.MarshalIndent(res, "", "\t") | |
| if err != nil { | |
| fmt.Fprintln(os.Stderr, err) | |
| os.Exit(1) | |
| } | |
| fmt.Print(string(str)) |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@examples/chain/auction/query/1_Vouchers/example.go` around lines 65 - 71, If
FetchAuctionVouchers (call to chainClient.FetchAuctionVouchers) returns an
error, stop the example instead of continuing: check err and return/exit
non‑zero with a helpful message; do the same for json.MarshalIndent — check its
error and abort on failure. Concretely, after calling FetchAuctionVouchers, if
err != nil log/print the error and os.Exit(1) (or return), and when calling
json.MarshalIndent(res, "", "\t") capture the marshal error, handle it the same
way instead of ignoring it; this ensures you don't print a zero-value res on
failures and the example returns a non‑zero status on errors.
| ) | ||
|
|
||
| func main() { | ||
| _ = godotenv.Load() |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
In github.com/joho/godotenv v1.5.1, when godotenv.Load() is called with no arguments, does it only read .env from the current working directory, or does it also search parent directories?
💡 Result:
In github.com/joho/godotenv v1.5.1, when godotenv.Load is called with no arguments, it only reads .env from the current working directory. It does not search parent directories.
Citations:
- 1: https://github.com/joho/godotenv/blob/v1.5.1/godotenv.go
- 2: https://github.com/joho/godotenv/blob/v1.5.1/parser.go
godotenv.Load() is cwd-dependent here.
These examples sit several directories below the repo root. Calling Load() without arguments only reads .env from the current working directory, so running go run example.go from this folder will not pick up a repo-level .env file. Either resolve the file path explicitly or document that examples must be run from the repository root.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@examples/chain/ibc/channel/query/10_PacketAcknowledgements/example.go` at
line 21, The call to godotenv.Load() in example.go is cwd-dependent and won't
find the repo-level .env when running the example from its folder; update the
example to load the .env via an explicit path instead of relying on the working
directory (e.g., resolve the example file's directory with runtime.Caller or
compute the repo-root relative path and call godotenv.Load(resolvedPath)) so the
.env is loaded predictably when running the example; change the godotenv.Load()
invocation in this file to load the resolved path.
| res, err := chainClient.FetchInsuranceVouchers(ctx, denom) | ||
| if err != nil { | ||
| fmt.Println(err) | ||
| } | ||
|
|
||
| str, _ := json.MarshalIndent(res, "", "\t") | ||
| fmt.Print(string(str)) |
There was a problem hiding this comment.
Fail fast when the query or JSON encoding fails.
This example prints the fetch error but still marshals and prints the response, so a failed run can still look successful. The marshal error is also ignored.
Suggested fix
res, err := chainClient.FetchInsuranceVouchers(ctx, denom)
if err != nil {
- fmt.Println(err)
+ fmt.Fprintln(os.Stderr, err)
+ os.Exit(1)
}
- str, _ := json.MarshalIndent(res, "", "\t")
+ str, err := json.MarshalIndent(res, "", "\t")
+ if err != nil {
+ fmt.Fprintln(os.Stderr, err)
+ os.Exit(1)
+ }
fmt.Print(string(str))📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| res, err := chainClient.FetchInsuranceVouchers(ctx, denom) | |
| if err != nil { | |
| fmt.Println(err) | |
| } | |
| str, _ := json.MarshalIndent(res, "", "\t") | |
| fmt.Print(string(str)) | |
| res, err := chainClient.FetchInsuranceVouchers(ctx, denom) | |
| if err != nil { | |
| fmt.Fprintln(os.Stderr, err) | |
| os.Exit(1) | |
| } | |
| str, err := json.MarshalIndent(res, "", "\t") | |
| if err != nil { | |
| fmt.Fprintln(os.Stderr, err) | |
| os.Exit(1) | |
| } | |
| fmt.Print(string(str)) |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@examples/chain/insurance/query/1_Vouchers/example.go` around lines 65 - 71,
The example currently ignores errors from chainClient.FetchInsuranceVouchers and
json.MarshalIndent and proceeds to print potentially invalid output; modify the
handler around chainClient.FetchInsuranceVouchers(ctx, denom) so that if err !=
nil you fail fast (return or log.Fatal/exit) instead of continuing, and check
the error returned by json.MarshalIndent(res, "", "\t") storing to str and err
(or marshalErr) and fail fast on marshal errors as well; update references to
res, err, and str so errors are handled immediately after each call to
FetchInsuranceVouchers and json.MarshalIndent.
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@examples/exchange/oracle/6_StreamPricesByMarkets/example.go`:
- Around line 21-25: The comment for market selection is inconsistent: the
variable marketIds in example.go is documented as "Pass an empty slice to
receive price updates for all markets" but is populated with two explicit market
IDs; either make marketIds an empty slice to match the comment or update the
comment to state that these two IDs will limit updates to those markets. Locate
the marketIds declaration in the 6_StreamPricesByMarkets example and choose one
fix: set marketIds to an empty slice (to subscribe to all markets) or change the
comment to describe that the listed IDs (e.g., the INJ/USDT and BTC/USDT perp
IDs) restrict updates to those markets.
- Around line 42-43: The code currently ignores the error returned by
json.MarshalIndent when serializing res; update the example (around the
stream.Recv() handling that produces res) to check the error from
json.MarshalIndent(res, "", "\t") and handle it explicitly: if marshalling
fails, print/log the error (e.g., fmt.Fprintf(os.Stderr, "marshal error: %v\n",
err)) and return or continue as appropriate instead of discarding the error,
then only call fmt.Print(string(str)) when err == nil so the example
demonstrates proper error handling.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 8cde9115-d881-429f-a04d-33e34bb10a1c
📒 Files selected for processing (1)
examples/exchange/oracle/6_StreamPricesByMarkets/example.go
| // Pass an empty slice to receive price updates for all markets. | ||
| marketIds := []string{ | ||
| "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6", // INJ/USDT perp | ||
| "0x54d4505adef6a5cef26bc403a33d595620ded4e15b9e2bc3dd489b714813366a", // BTC/USDT perp | ||
| } |
There was a problem hiding this comment.
Comment and implementation conflict on market selection.
Line 21 says an empty slice is used to receive all markets, but Lines 22-25 pass two explicit market IDs. Please align the comment with the actual example behavior (or make the slice empty).
✏️ Suggested fix
- // Pass an empty slice to receive price updates for all markets.
+ // Pass specific market IDs to receive price updates for those markets.
marketIds := []string{
"0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6", // INJ/USDT perp
"0x54d4505adef6a5cef26bc403a33d595620ded4e15b9e2bc3dd489b714813366a", // BTC/USDT perp
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| // Pass an empty slice to receive price updates for all markets. | |
| marketIds := []string{ | |
| "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6", // INJ/USDT perp | |
| "0x54d4505adef6a5cef26bc403a33d595620ded4e15b9e2bc3dd489b714813366a", // BTC/USDT perp | |
| } | |
| // Pass specific market IDs to receive price updates for those markets. | |
| marketIds := []string{ | |
| "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6", // INJ/USDT perp | |
| "0x54d4505adef6a5cef26bc403a33d595620ded4e15b9e2bc3dd489b714813366a", // BTC/USDT perp | |
| } |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@examples/exchange/oracle/6_StreamPricesByMarkets/example.go` around lines 21
- 25, The comment for market selection is inconsistent: the variable marketIds
in example.go is documented as "Pass an empty slice to receive price updates for
all markets" but is populated with two explicit market IDs; either make
marketIds an empty slice to match the comment or update the comment to state
that these two IDs will limit updates to those markets. Locate the marketIds
declaration in the 6_StreamPricesByMarkets example and choose one fix: set
marketIds to an empty slice (to subscribe to all markets) or change the comment
to describe that the listed IDs (e.g., the INJ/USDT and BTC/USDT perp IDs)
restrict updates to those markets.
| str, _ := json.MarshalIndent(res, "", "\t") | ||
| fmt.Print(string(str)) |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
find . -name "example.go" -path "*/6_StreamPricesByMarkets/*" -type fRepository: InjectiveLabs/sdk-go
Length of output: 126
🏁 Script executed:
sed -n '35,50p' ./examples/exchange/oracle/6_StreamPricesByMarkets/example.goRepository: InjectiveLabs/sdk-go
Length of output: 252
🏁 Script executed:
sed -n '20,50p' ./examples/exchange/oracle/6_StreamPricesByMarkets/example.goRepository: InjectiveLabs/sdk-go
Length of output: 667
🏁 Script executed:
sed -n '1,35p' ./examples/exchange/oracle/6_StreamPricesByMarkets/example.goRepository: InjectiveLabs/sdk-go
Length of output: 857
Handle JSON marshal failures explicitly.
Line 42 discards the json.MarshalIndent error, which can hide serialization failures and print incomplete output. Although res is guaranteed valid from the preceding stream.Recv() check, explicit error handling demonstrates proper patterns for example code.
🛠️ Suggested fix
- str, _ := json.MarshalIndent(res, "", "\t")
- fmt.Print(string(str))
+ str, err := json.MarshalIndent(res, "", "\t")
+ if err != nil {
+ fmt.Println(err)
+ continue
+ }
+ fmt.Print(string(str))📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| str, _ := json.MarshalIndent(res, "", "\t") | |
| fmt.Print(string(str)) | |
| str, err := json.MarshalIndent(res, "", "\t") | |
| if err != nil { | |
| fmt.Println(err) | |
| continue | |
| } | |
| fmt.Print(string(str)) |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@examples/exchange/oracle/6_StreamPricesByMarkets/example.go` around lines 42
- 43, The code currently ignores the error returned by json.MarshalIndent when
serializing res; update the example (around the stream.Recv() handling that
produces res) to check the error from json.MarshalIndent(res, "", "\t") and
handle it explicitly: if marshalling fails, print/log the error (e.g.,
fmt.Fprintf(os.Stderr, "marshal error: %v\n", err)) and return or continue as
appropriate instead of discarding the error, then only call
fmt.Print(string(str)) when err == nil so the example demonstrates proper error
handling.
PR to submit changes in
devfor v1.19.0 chain upgrade intomaster, to release the v1.61.0 versionSummary by CodeRabbit
New Features
Bug Fixes
Chores