Documentation
¶
Index ¶
- Variables
- func AsCells(plans []MessagePlanRaw) []*tlbe.Cell[tlb.InternalMessage]
- type AnySequenceInput
- type AnySequenceOutput
- type CompiledContract
- type ContractCodeProvider
- type ContractMetadata
- type DeployInput
- type DeployMessage
- type DeployOutput
- type InternalMessage
- type MessagePlanRaw
- type MessageSender
- type Planner
- type PlannerOption
- type SendMessagesInput
- type SendMessagesOutput
- type SendMessagesRawInput
- type StateInit
Constants ¶
This section is empty.
Variables ¶
var AnySequence = operations.NewSequence( "ton/sequences/any", semver.MustParse("0.1.0"), "Executes and/or plans a sequence of operations as defined by the inputs", anySeqHandler, )
var Deploy = operations.NewOperation( "ton/ops/deploy", semver.MustParse("0.2.0"), "Deploys contracts by sending messages with code loaded from the provider", func(b operations.Bundle, dp *dep.DependencyProvider, in DeployInput) (DeployOutput, error) { _messages := make([]InternalMessage[any], len(in.Messages)) for i, u := range in.Messages { contractProvider, err := dep.Resolve[ContractCodeProvider](dp) if err != nil { return DeployOutput{}, fmt.Errorf("failed to resolve contract provider: %w", err) } c, err := contractProvider.GetContract(u.ContractMeta) if err != nil { return DeployOutput{}, fmt.Errorf("failed to get contract code: %w", err) } var data *cell.Cell if u.Data != nil { data, err = encodeDataCellFor(u.Data) if err != nil { return DeployOutput{}, fmt.Errorf("failed to encode data cell: %w", err) } } m := u.Message _messages[i] = InternalMessage[any]{ Bounce: m.Bounce, DstAddr: m.DstAddr, Amount: m.Amount, Body: m.Body, StateInit: &StateInit{ Code: c.Code, Data: data, }, } } _in := SendMessagesInput{ Messages: _messages, Plan: in.Plan, } r, err := operations.ExecuteOperation(b, SendMessages, dp, _in) if err != nil { return DeployOutput{}, fmt.Errorf("failed to exec send messages operation: %w", err) } return DeployOutput(r.Output), nil }, )
var SendMessages = cldf_ops.NewOperation( "ton/ops/send-messages", semver.MustParse("0.1.0"), "Sends and/or plans messages as defined by the inputs", func(b cldf_ops.Bundle, dp *dep.DependencyProvider, in SendMessagesInput) (SendMessagesOutput, error) { msgs := make([]*tlbe.Cell[tlb.InternalMessage], 0, len(in.Messages)) plans := make([]MessagePlanRaw, 0, len(in.Messages)) for _, m := range in.Messages { _im, err := m.ToMessage() if err != nil { return SendMessagesOutput{}, fmt.Errorf("failed to convert internal message to message: %w", err) } opcode, err := tvm.ExtractOpcode(_im.Body) if err != nil { return SendMessagesOutput{}, fmt.Errorf("failed to extract opcode from message body: %w", err) } if _im.DstAddr == nil || _im.DstAddr.IsAddrNone() || _im.DstAddr.Equals(tvm.ZeroAddress) { return SendMessagesOutput{}, fmt.Errorf("internal message (%x) destination cannot be nil or zero address", opcode) } if _im.Body == nil || tvm.CellEquals(_im.Body, tvm.EmptyCell) { if !m.Bounce { return SendMessagesOutput{}, errors.New("empty body messages must have bounce enabled") } } _imc, err := tlbe.NewCellFrom(*_im) if err != nil { return SendMessagesOutput{}, fmt.Errorf("failed to convert internal message to cell: %w", err) } plan := MessagePlanRaw{ Opcode: opcode, DstAddr: _im.DstAddr, Amount: m.Amount, Cell: _imc, } plans = append(plans, plan) msgs = append(msgs, _imc) } if in.Plan { return SendMessagesOutput{Plans: plans}, nil } out, err := cldf_ops.ExecuteOperation(b, SendMessagesRaw, dp, SendMessagesRawInput{Messages: msgs}) if err != nil { return SendMessagesOutput{}, fmt.Errorf("failed to send messages: %w", err) } return out.Output, nil }, )
var SendMessagesRaw = cldf_ops.NewOperation( "ton/ops/send-messages-raw", semver.MustParse("0.1.0"), "Sends (raw) messages as defined by the inputs", func(b cldf_ops.Bundle, dp *dep.DependencyProvider, in SendMessagesRawInput) (SendMessagesOutput, error) { ctx := b.GetContext() n := len(in.Messages) msgs := make([]*wallet.Message, 0, n) for _, m := range in.Messages { _im, err := m.ToValue() if err != nil { return SendMessagesOutput{}, fmt.Errorf("failed to decode internal message from cell: %w", err) } msgs = append(msgs, &wallet.Message{ Mode: wallet.PayGasSeparately | wallet.IgnoreErrors, InternalMessage: &_im, }) } chain, err := dep.Resolve[cldf_ton.Chain](dp) if err != nil { return SendMessagesOutput{}, fmt.Errorf("failed to resolve chain: %w", err) } b.Logger.Infow("Sending messages", "msgs", msgs) _tx, block, err := chain.Wallet.SendManyWaitTransaction(ctx, msgs) if err != nil { return SendMessagesOutput{}, fmt.Errorf("failed to send transaction: %w", err) } b.Logger.Infow("Transaction sent", "blockID", block, "tx", _tx) err = tracetracking.WaitForTrace(ctx, chain.Client, _tx) if err != nil { return SendMessagesOutput{}, fmt.Errorf("failed to wait for trace: %w", err) } tx, err := tlbe.NewCellFrom(*_tx) if err != nil { return SendMessagesOutput{}, fmt.Errorf("failed to convert transaction to cell: %w", err) } return SendMessagesOutput{ Transaction: tx, BlockInfo: block, }, nil }, )
Functions ¶
func AsCells ¶
func AsCells(plans []MessagePlanRaw) []*tlbe.Cell[tlb.InternalMessage]
Types ¶
type AnySequenceInput ¶
type AnySequenceInput struct {
// Definitions and Inputs should be of the same length and order
Defs []operations.Definition `json:"defs"`
Inputs []any `json:"inputs"` // Each element should be the corresponding input type for its operation
}
type AnySequenceOutput ¶
type AnySequenceOutput struct {
Plans []MessagePlanRaw `json:"plans"`
Transactions []*tlbe.Cell[tlb.Transaction] `json:"transactions"`
}
TODO: reuse PlannerOption, Planner, MessageSender interfaces for sequences as well. The interfaces would need to return a collection of plans/txs, where an operation or a sequence may plan/produce multiple messages.
func (AnySequenceOutput) GetPlans ¶
func (o AnySequenceOutput) GetPlans() []MessagePlanRaw
type CompiledContract ¶
type CompiledContract struct {
Metadata ContractMetadata
Code *cell.Cell
}
CompiledContract represents a compiled TON contract with its name and code (cell).
type ContractCodeProvider ¶
type ContractCodeProvider interface {
GetContract(meta ContractMetadata) (CompiledContract, error)
}
ContractCodeProvider provides compiled contract code based on metadata.
type ContractMetadata ¶
type ContractMetadata struct {
Package string `json:"package"` // Name of the package where the contract is defined (e.g., "github.com/smartcontractkit/chainlink-ton")
Version *semver.Version `json:"version"` // Version of the contract package (e.g., semver.MustParse("0.1.0"))
ID string `json:"id"` // Contract identifier within the package (e.g., "mcms.RBACTimelock") (can be a path, or maps to a path within the package)
}
func (ContractMetadata) Key ¶
func (m ContractMetadata) Key() string
type DeployInput ¶
type DeployInput struct {
Messages []DeployMessage[any, any] `json:"messages"`
Plan bool `json:"plan"`
}
func (DeployInput) IsPlan ¶
func (in DeployInput) IsPlan() bool
type DeployMessage ¶
type DeployMessage[T any, D any] struct { ContractMeta ContractMetadata `json:"contractMeta"` Data *D `json:"data"` Message InternalMessage[T] `json:"message"` }
type DeployOutput ¶
type DeployOutput SendMessagesOutput
func (DeployOutput) GetPlans ¶
func (o DeployOutput) GetPlans() []MessagePlanRaw
func (DeployOutput) GetTransaction ¶
func (o DeployOutput) GetTransaction() *tlbe.Cell[tlb.Transaction]
type InternalMessage ¶
type InternalMessage[T any] struct { Bounce bool `json:"bounce"` DstAddr *address.Address `json:"dstAddr"` Amount tlb.Coins `json:"amount"` Body *codec.MessageEnvelope[T] `json:"body,omitempty"` StateInit *StateInit `json:"stateInit,omitempty"` }
&tlb.InternalMessage representation
func (*InternalMessage[T]) ToMessage ¶
func (im *InternalMessage[T]) ToMessage() (*tlb.InternalMessage, error)
type MessagePlanRaw ¶
type MessagePlanRaw struct {
// High level info about the message
Opcode uint32 `json:"opcode"`
DstAddr *address.Address `json:"dstAddr"`
Amount tlb.Coins `json:"amount"`
// Raw cell of the internal message
Cell *tlbe.Cell[tlb.InternalMessage] `json:"cell"`
}
MessagePlanRaw represents a raw message plan with high-level info and the raw cell.
type MessageSender ¶
type MessageSender interface {
GetTransaction() *tlbe.Cell[tlb.Transaction]
}
MessageSender is an interface for op OUT types that can provide transaction info.
type Planner ¶
type Planner[T any] interface { GetPlans() []T }
Planner is an interface for op OUT types that can produce a message plan.
type PlannerOption ¶
type PlannerOption interface {
IsPlan() bool
}
PlannerOption is an interface an op IN type providing an option to produce a message plan.
type SendMessagesInput ¶
type SendMessagesInput struct {
Messages []InternalMessage[any] `json:"messages"`
Plan bool `json:"plan"`
}
func (SendMessagesInput) IsPlan ¶
func (in SendMessagesInput) IsPlan() bool
type SendMessagesOutput ¶
type SendMessagesOutput struct {
Plans []MessagePlanRaw `json:"plans"`
Transaction *tlbe.Cell[tlb.Transaction] `json:"transaction,omitempty"`
BlockInfo *ton.BlockIDExt `json:"blockInfo,omitempty"`
}
func (SendMessagesOutput) GetPlans ¶
func (o SendMessagesOutput) GetPlans() []MessagePlanRaw
func (SendMessagesOutput) GetTransaction ¶
func (o SendMessagesOutput) GetTransaction() *tlbe.Cell[tlb.Transaction]
type SendMessagesRawInput ¶
type SendMessagesRawInput struct {
Messages []*tlbe.Cell[tlb.InternalMessage] `json:"messages"`
}