Documentation
¶
Overview ¶
Package tx implements the shared Heimdall transaction builder used by `polycli heimdall mktx`, `send`, and `estimate`. The builder assembles a cosmos.tx.v1beta1.TxRaw from one or more messages, fetches the signer's account number + sequence (unless overridden), signs with a secp256k1-eth key, and — via the broadcast helper — submits it through the REST gateway.
The signing scheme is the Heimdall v2 `PubKeySecp256k1eth` variant: curve secp256k1, but the digest is keccak256 (not sha256) and the 65-byte (r||s||v) output from eth signing is truncated to 64 bytes (r||s) before landing in TxRaw.signatures. This matches heimdall-v2 /crypto/keys/secp256k1.PrivKey.Sign.
Index ¶
- Variables
- func EthAddress(priv *ecdsa.PrivateKey) common.Address
- func RequireForce(msgType string, force bool) error
- func WaitForConfirmations(ctx context.Context, rpc *client.RPCClient, txHeight uint64, ...) error
- func WaitForInclusion(ctx context.Context, rpc *client.RPCClient, txHash string, ...) (uint64, []byte, error)
- type Account
- type AccountFetcher
- type BackfillSpansMsg
- type BroadcastMode
- type BroadcastResult
- type Builder
- func (b *Builder) AddMsg(m Msg) *Builder
- func (b *Builder) ResolveAccount(ctx context.Context, fetcher AccountFetcher, addr string) error
- func (b *Builder) Sign(priv *ecdsa.PrivateKey) ([]byte, error)
- func (b *Builder) SignAndEncode(priv *ecdsa.PrivateKey) (raw []byte, b64, hex string, err error)
- func (b *Builder) WithAccountNumber(n uint64) *Builder
- func (b *Builder) WithChainID(id string) *Builder
- func (b *Builder) WithFee(coins ...hproto.Coin) *Builder
- func (b *Builder) WithFeeGranter(addr string) *Builder
- func (b *Builder) WithFeePayer(addr string) *Builder
- func (b *Builder) WithGasLimit(g uint64) *Builder
- func (b *Builder) WithMemo(memo string) *Builder
- func (b *Builder) WithSequence(s uint64) *Builder
- func (b *Builder) WithSignMode(m SignMode) *Builder
- func (b *Builder) WithTimeoutHeight(h uint64) *Builder
- type CheckpointMsg
- type ClerkEventRecordMsg
- type CpAckMsg
- type CpNoAckMsg
- type Msg
- type ProposeSpanMsg
- type RESTAccountFetcher
- type SetProducerDowntimeMsg
- type SignMode
- type SignerUpdateMsg
- type SimulateResult
- type StakeUpdateMsg
- type TopupMsg
- type ValidatorExitMsg
- type ValidatorJoinMsg
- type VoteProducersMsg
- type WithdrawFeeMsg
Constants ¶
This section is empty.
Variables ¶
var L1MirroringMsgTypes = map[string]struct{}{
"MsgTopupTx": {},
"MsgCheckpointAck": {},
"MsgCpAck": {},
"MsgCheckpointNoAck": {},
"MsgCpNoAck": {},
"MsgEventRecordRequest": {},
"MsgEventRecord": {},
"MsgClerkRecord": {},
"MsgValidatorJoin": {},
"MsgStakeJoin": {},
"MsgValidatorUpdate": {},
"MsgStakeUpdate": {},
"MsgSignerUpdate": {},
"MsgValidatorExit": {},
"MsgStakeExit": {},
}
L1MirroringMsgTypes is the set of Msg types that are produced by the Heimdall bridge after observing an L1 event. Operators almost never hand-build these, and submitting one manually is either a no-op or a replay that competes with the real bridge path.
Subcommands flagged for these types call RequireForce before building; it returns a user-facing refusal error unless the caller has set --force.
Wording is taken verbatim from HEIMDALLCAST_REQUIREMENTS.md §3.3.
Functions ¶
func EthAddress ¶
func EthAddress(priv *ecdsa.PrivateKey) common.Address
EthAddress derives the 20-byte Ethereum-style address that Heimdall uses for the `proposer` / `from` fields on messages. Matches PubKey.Address() in heimdall-v2's secp256k1 package (keccak256 of the uncompressed pubkey minus the 0x04 prefix, right-most 20 bytes).
func RequireForce ¶
RequireForce returns an error if msgType is an L1-mirroring type and force is false. Returns nil for safe types or when force is true.
The error text matches HEIMDALLCAST_REQUIREMENTS.md §3.3:
"this message is produced by the bridge after observing an L1 event; you almost certainly do not want to build one by hand. Re-run with --force to bypass."
msgType is matched against the short name only (the last segment of the type URL, e.g. "MsgTopupTx" rather than the full URL) to keep call-sites short. Both short and fully-qualified names are accepted.
func WaitForConfirmations ¶
func WaitForConfirmations(ctx context.Context, rpc *client.RPCClient, txHeight uint64, confirmations uint64, pollInterval time.Duration) error
WaitForConfirmations waits until the chain's latest_block_height is at least txHeight + confirmations. When confirmations is zero the function returns immediately.
func WaitForInclusion ¶
func WaitForInclusion(ctx context.Context, rpc *client.RPCClient, txHash string, pollInterval time.Duration) (uint64, []byte, error)
WaitForInclusion polls CometBFT /tx for txHash until the tx is found or ctx is cancelled. pollInterval defaults to 500ms when zero. Returns the height and raw /tx JSON body.
Callers who need `--confirmations N` should call this to get inclusion height, then poll /status until latest_block_height >= height + N.
Types ¶
type Account ¶
Account is the subset of /cosmos/auth/v1beta1/accounts/{addr} that the builder reads. Exposed for tests / advanced callers who want to fetch once and feed into multiple builders.
type AccountFetcher ¶
AccountFetcher is the narrow interface the builder uses to look up signer accounts. The production implementation wraps client.RESTClient; tests inject a fake.
type BackfillSpansMsg ¶
type BackfillSpansMsg struct {
Proposer string
ChainID string
LatestSpanID uint64
LatestBorSpanID uint64
}
BackfillSpansMsg wraps MsgBackfillSpans.
func (*BackfillSpansMsg) AminoJSON ¶
func (m *BackfillSpansMsg) AminoJSON() (any, error)
func (*BackfillSpansMsg) AminoName ¶
func (m *BackfillSpansMsg) AminoName() string
func (*BackfillSpansMsg) Marshal ¶
func (m *BackfillSpansMsg) Marshal() ([]byte, error)
func (*BackfillSpansMsg) TypeURL ¶
func (m *BackfillSpansMsg) TypeURL() string
type BroadcastMode ¶
type BroadcastMode string
BroadcastMode mirrors cosmos.tx.v1beta1.BroadcastMode. We expose only SYNC (wait for CheckTx) and ASYNC (return immediately) — BLOCK is deprecated in cosmos-sdk and Heimdall has instant finality so SYNC + polling covers the real inclusion flow.
const ( BroadcastModeSync BroadcastMode = "BROADCAST_MODE_SYNC" BroadcastModeAsync BroadcastMode = "BROADCAST_MODE_ASYNC" )
type BroadcastResult ¶
type BroadcastResult struct {
TxHash string
Code int
Codespace string
RawLog string
Height uint64
// Raw is the undecoded JSON body of the /cosmos/tx/v1beta1/txs
// response. May be nil if the transport short-circuited (--curl).
Raw []byte
}
BroadcastResult carries the fields polycli's send command surfaces after a broadcast round-trip. Raw holds the undecoded JSON response so --json callers can pass it through verbatim.
func Broadcast ¶
func Broadcast(ctx context.Context, rest *client.RESTClient, txBytes []byte, mode BroadcastMode) (*BroadcastResult, error)
Broadcast submits txBytes via /cosmos/tx/v1beta1/txs and returns the decoded tx response. Callers typically pass the bytes returned by Builder.Sign; this function base64-encodes them before POSTing.
On non-zero CheckTx code the function returns BroadcastResult with code/raw_log populated AND a non-nil error so callers can surface both without double-handling.
type Builder ¶
type Builder struct {
// contains filtered or unexported fields
}
Builder constructs a TxRaw. Call the With* setters, then Sign (which produces the raw bytes) or SignAndEncode (which also base64/hex encodes them). Builders are single-use; reuse after Sign is undefined.
func NewBuilder ¶
func NewBuilder() *Builder
NewBuilder returns a fresh Builder with direct sign mode and a zero-value fee. The caller must populate at least WithChainID and one Msg before Sign.
func (*Builder) AddMsg ¶
AddMsg appends a Msg to the builder's TxBody. Repeatable; order is preserved and determines the order of signer_infos.
func (*Builder) ResolveAccount ¶
ResolveAccount populates the builder's accountNumber and sequence by asking fetcher for the given signer address. Callers that set both values via WithAccountNumber and WithSequence can skip this step.
func (*Builder) Sign ¶
func (b *Builder) Sign(priv *ecdsa.PrivateKey) ([]byte, error)
Sign builds the TxRaw bytes using priv as the single signing key. chainID and accountNumber must be set (via WithChainID and either WithAccountNumber or ResolveAccount). Returns the canonical TxRaw proto-encoded bytes, ready for /cosmos/tx/v1beta1/txs.
func (*Builder) SignAndEncode ¶
SignAndEncode signs and returns the TxRaw bytes in both base64 and hex encodings. Callers typically print one or both.
func (*Builder) WithAccountNumber ¶
WithAccountNumber overrides the auto-fetched account number.
func (*Builder) WithChainID ¶
WithChainID sets the chain id used for SIGN_MODE_DIRECT replay protection.
func (*Builder) WithFee ¶
WithFee sets the fee amount coins. Gas limit is set separately via WithGasLimit.
func (*Builder) WithFeeGranter ¶
WithFeeGranter sets the optional fee granter address on Fee.
func (*Builder) WithFeePayer ¶
WithFeePayer sets the optional fee payer address on Fee.
func (*Builder) WithGasLimit ¶
WithGasLimit sets the TxBody gas limit.
func (*Builder) WithSequence ¶
WithSequence overrides the auto-fetched sequence.
func (*Builder) WithSignMode ¶
WithSignMode sets the signing mode (direct or amino-json).
func (*Builder) WithTimeoutHeight ¶
WithTimeoutHeight sets the absolute block height after which the tx is invalid. Default 0 (no timeout).
type CheckpointMsg ¶
type CheckpointMsg struct {
Proposer string
StartBlock uint64
EndBlock uint64
RootHash []byte
AccountRootHash []byte
BorChainID string
}
CheckpointMsg wraps heimdallv2.checkpoint.MsgCheckpoint for the builder. All fields must be supplied by the caller; the builder performs no semantic validation beyond "proposer non-empty".
func (*CheckpointMsg) AminoJSON ¶
func (m *CheckpointMsg) AminoJSON() (any, error)
AminoJSON implements Msg.
func (*CheckpointMsg) AminoName ¶
func (m *CheckpointMsg) AminoName() string
AminoName implements Msg.
func (*CheckpointMsg) Marshal ¶
func (m *CheckpointMsg) Marshal() ([]byte, error)
Marshal implements Msg.
type ClerkEventRecordMsg ¶
type ClerkEventRecordMsg struct {
From string
TxHash string
LogIndex uint64
BlockNumber uint64
ContractAddress string
Data []byte
ID uint64
ChainID string
}
ClerkEventRecordMsg wraps MsgEventRecord.
func (*ClerkEventRecordMsg) AminoJSON ¶
func (m *ClerkEventRecordMsg) AminoJSON() (any, error)
func (*ClerkEventRecordMsg) AminoName ¶
func (m *ClerkEventRecordMsg) AminoName() string
func (*ClerkEventRecordMsg) Marshal ¶
func (m *ClerkEventRecordMsg) Marshal() ([]byte, error)
func (*ClerkEventRecordMsg) TypeURL ¶
func (m *ClerkEventRecordMsg) TypeURL() string
type CpAckMsg ¶
type CpAckMsg struct {
From string
Number uint64
Proposer string
StartBlock uint64
EndBlock uint64
RootHash []byte
}
CpAckMsg wraps MsgCpAck.
type CpNoAckMsg ¶
type CpNoAckMsg struct {
From string
}
CpNoAckMsg wraps MsgCpNoAck.
func (*CpNoAckMsg) AminoJSON ¶
func (m *CpNoAckMsg) AminoJSON() (any, error)
func (*CpNoAckMsg) AminoName ¶
func (m *CpNoAckMsg) AminoName() string
func (*CpNoAckMsg) Marshal ¶
func (m *CpNoAckMsg) Marshal() ([]byte, error)
func (*CpNoAckMsg) TypeURL ¶
func (m *CpNoAckMsg) TypeURL() string
type Msg ¶
type Msg interface {
// TypeURL is the Any.type_url for the message, e.g.
// "/heimdallv2.topup.MsgWithdrawFeeTx".
TypeURL() string
// Marshal returns the proto-serialized message (the payload that
// goes inside Any.value).
Marshal() ([]byte, error)
// AminoName is the amino.name option on the message, used for
// SIGN_MODE_LEGACY_AMINO_JSON. Return "" if amino-JSON is not
// supported for this message; the builder will refuse to sign.
AminoName() string
// AminoJSON returns the message as a JSON-serializable Go value
// (typically map[string]any) for the legacy amino-JSON sign doc.
// Implementations should emit uint64 / int64 fields as decimal
// strings to match cosmos-sdk behavior.
AminoJSON() (any, error)
}
Msg is a Heimdall / Cosmos SDK message that can be packed into a google.protobuf.Any and serialized as part of a TxBody.
Implementations are tiny — one per concrete Msg type — and live with the command that builds them (W3/W4 wave). The first implementation, for MsgWithdrawFeeTx, ships with this package to exercise the builder end-to-end.
type ProposeSpanMsg ¶
type ProposeSpanMsg struct {
SpanID uint64
Proposer string
StartBlock uint64
EndBlock uint64
ChainID string
Seed []byte
SeedAuthor string
}
ProposeSpanMsg wraps MsgProposeSpan.
func (*ProposeSpanMsg) AminoJSON ¶
func (m *ProposeSpanMsg) AminoJSON() (any, error)
func (*ProposeSpanMsg) AminoName ¶
func (m *ProposeSpanMsg) AminoName() string
func (*ProposeSpanMsg) Marshal ¶
func (m *ProposeSpanMsg) Marshal() ([]byte, error)
func (*ProposeSpanMsg) TypeURL ¶
func (m *ProposeSpanMsg) TypeURL() string
type RESTAccountFetcher ¶
type RESTAccountFetcher struct {
Client *client.RESTClient
}
RESTAccountFetcher is the default AccountFetcher. It calls /cosmos/auth/v1beta1/accounts/{addr} and parses the BaseAccount response.
func (*RESTAccountFetcher) FetchAccount ¶
FetchAccount implements AccountFetcher.
type SetProducerDowntimeMsg ¶
SetProducerDowntimeMsg wraps MsgSetProducerDowntime.
func (*SetProducerDowntimeMsg) AminoJSON ¶
func (m *SetProducerDowntimeMsg) AminoJSON() (any, error)
func (*SetProducerDowntimeMsg) AminoName ¶
func (m *SetProducerDowntimeMsg) AminoName() string
func (*SetProducerDowntimeMsg) Marshal ¶
func (m *SetProducerDowntimeMsg) Marshal() ([]byte, error)
func (*SetProducerDowntimeMsg) TypeURL ¶
func (m *SetProducerDowntimeMsg) TypeURL() string
type SignMode ¶
type SignMode int32
SignMode is the signing mode used to compute the signature pre-image.
const ( // SignModeDirect signs the SIGN_MODE_DIRECT doc (proto-serialized // SignDoc). This is the default and matches cosmos-sdk's default. SignModeDirect SignMode = SignMode(proto.SignModeDirect) // SignModeAminoJSON signs the legacy amino-JSON document. Kept for // compatibility with older tooling; not otherwise recommended. SignModeAminoJSON SignMode = SignMode(proto.SignModeAminoJSON) )
func ParseSignMode ¶
ParseSignMode maps the flag-style name ("direct" / "amino-json") to a SignMode. Unknown names return an error so usage mistakes surface at the boundary rather than silently falling back.
type SignerUpdateMsg ¶
type SignerUpdateMsg struct {
From string
ValID uint64
NewSignerPubKey []byte
TxHash []byte
LogIndex uint64
BlockNumber uint64
Nonce uint64
}
SignerUpdateMsg wraps MsgSignerUpdate.
func (*SignerUpdateMsg) AminoJSON ¶
func (m *SignerUpdateMsg) AminoJSON() (any, error)
func (*SignerUpdateMsg) AminoName ¶
func (m *SignerUpdateMsg) AminoName() string
func (*SignerUpdateMsg) Marshal ¶
func (m *SignerUpdateMsg) Marshal() ([]byte, error)
func (*SignerUpdateMsg) TypeURL ¶
func (m *SignerUpdateMsg) TypeURL() string
type SimulateResult ¶
SimulateResult carries the gas estimate plus the raw response JSON.
func Simulate ¶
func Simulate(ctx context.Context, rest *client.RESTClient, txBytes []byte) (*SimulateResult, error)
Simulate calls /cosmos/tx/v1beta1/simulate with txBytes and returns the simulation result. Used by `estimate` and by `--gas auto`. Callers sign the tx before simulating — simulate still validates signatures, so a throwaway sig produced over the final doc works.
type StakeUpdateMsg ¶
type StakeUpdateMsg struct {
From string
ValID uint64
NewAmount string
TxHash []byte
LogIndex uint64
BlockNumber uint64
Nonce uint64
}
StakeUpdateMsg wraps MsgStakeUpdate.
func (*StakeUpdateMsg) AminoJSON ¶
func (m *StakeUpdateMsg) AminoJSON() (any, error)
func (*StakeUpdateMsg) AminoName ¶
func (m *StakeUpdateMsg) AminoName() string
func (*StakeUpdateMsg) Marshal ¶
func (m *StakeUpdateMsg) Marshal() ([]byte, error)
func (*StakeUpdateMsg) TypeURL ¶
func (m *StakeUpdateMsg) TypeURL() string
type TopupMsg ¶
type TopupMsg struct {
Proposer string
User string
Fee string
TxHash []byte
LogIndex uint64
BlockNumber uint64
}
TopupMsg wraps MsgTopupTx (L1-mirroring; gated by RequireForce).
type ValidatorExitMsg ¶
type ValidatorExitMsg struct {
From string
ValID uint64
DeactivationEpoch uint64
TxHash []byte
LogIndex uint64
BlockNumber uint64
Nonce uint64
}
ValidatorExitMsg wraps MsgValidatorExit.
func (*ValidatorExitMsg) AminoJSON ¶
func (m *ValidatorExitMsg) AminoJSON() (any, error)
func (*ValidatorExitMsg) AminoName ¶
func (m *ValidatorExitMsg) AminoName() string
func (*ValidatorExitMsg) Marshal ¶
func (m *ValidatorExitMsg) Marshal() ([]byte, error)
func (*ValidatorExitMsg) TypeURL ¶
func (m *ValidatorExitMsg) TypeURL() string
type ValidatorJoinMsg ¶
type ValidatorJoinMsg struct {
From string
ValID uint64
ActivationEpoch uint64
Amount string
SignerPubKey []byte
TxHash []byte
LogIndex uint64
BlockNumber uint64
Nonce uint64
}
ValidatorJoinMsg wraps MsgValidatorJoin.
func (*ValidatorJoinMsg) AminoJSON ¶
func (m *ValidatorJoinMsg) AminoJSON() (any, error)
func (*ValidatorJoinMsg) AminoName ¶
func (m *ValidatorJoinMsg) AminoName() string
func (*ValidatorJoinMsg) Marshal ¶
func (m *ValidatorJoinMsg) Marshal() ([]byte, error)
func (*ValidatorJoinMsg) TypeURL ¶
func (m *ValidatorJoinMsg) TypeURL() string
type VoteProducersMsg ¶
VoteProducersMsg wraps MsgVoteProducers.
func (*VoteProducersMsg) AminoJSON ¶
func (m *VoteProducersMsg) AminoJSON() (any, error)
func (*VoteProducersMsg) AminoName ¶
func (m *VoteProducersMsg) AminoName() string
func (*VoteProducersMsg) Marshal ¶
func (m *VoteProducersMsg) Marshal() ([]byte, error)
func (*VoteProducersMsg) TypeURL ¶
func (m *VoteProducersMsg) TypeURL() string
type WithdrawFeeMsg ¶
WithdrawFeeMsg is the starter Msg for MsgWithdrawFeeTx. Additional Msg types land alongside their subcommands in W3/W4.
func (*WithdrawFeeMsg) AminoJSON ¶
func (m *WithdrawFeeMsg) AminoJSON() (any, error)
AminoJSON implements Msg.
func (*WithdrawFeeMsg) AminoName ¶
func (m *WithdrawFeeMsg) AminoName() string
AminoName implements Msg.
func (*WithdrawFeeMsg) Marshal ¶
func (m *WithdrawFeeMsg) Marshal() ([]byte, error)
Marshal implements Msg.