ton

package
v0.0.0-...-afe7c12 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 11, 2026 License: MIT Imports: 16 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
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,
)
View Source
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
	},
)
View Source
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
	},
)
View Source
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]) ToCell

func (im *InternalMessage[T]) ToCell() (*cell.Cell, error)

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"`
}

type StateInit

type StateInit struct {
	Code *cell.Cell `json:"code,omitempty"`
	Data *cell.Cell `json:"data,omitempty"`
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL