bath

package
v1.13.13 Latest Latest
Warning

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

Go to latest
Published: Oct 18, 2025 License: MIT Imports: 27 Imported by: 2

Documentation

Index

Constants

View Source
const (
	GetGemsAuction  NftAuctionType = "getgems"
	DnsTonAuction                  = "DNS.ton"
	DnsTgAuction                   = "DNS.tg"
	NumberTgAuction                = "NUMBER.tg"
)

Variables

View Source
var BidaskJettonSwapStraw = Straw[BubbleJettonSwap]{
	CheckFuncs: []bubbleCheck{IsJettonTransfer, func(bubble *Bubble) bool {
		jettonTx := bubble.Info.(BubbleJettonTransfer)
		swap, ok := jettonTx.payload.Value.(abi.BidaskSwapJettonPayload)
		if !ok {
			return false
		}
		if swap.ToAddress != jettonTx.sender.Address.ToMsgAddress() {
			return false
		}
		return true
	}},
	Builder: func(newAction *BubbleJettonSwap, bubble *Bubble) error {
		jettonTx := bubble.Info.(BubbleJettonTransfer)
		newAction.Dex = references.Bidask
		newAction.UserWallet = jettonTx.sender.Address
		newAction.Router = jettonTx.recipient.Address
		newAction.In.JettonMaster = jettonTx.master
		newAction.In.JettonWallet = jettonTx.senderWallet
		newAction.In.Amount = big.Int(jettonTx.amount)
		return nil
	},
	SingleChild: &Straw[BubbleJettonSwap]{
		CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.BidaskInternalSwapMsgOp), HasInterface(abi.BidaskRange)},
		SingleChild: &Straw[BubbleJettonSwap]{
			CheckFuncs: []bubbleCheck{
				IsTx,
				Or(HasOperation(abi.BidaskSwapSuccessMsgOp), HasOperation(abi.BidaskSwapSuccessV2MsgOp)),
				HasInterface(abi.BidaskPool),
			},
			SingleChild: &Straw[BubbleJettonSwap]{
				CheckFuncs: []bubbleCheck{IsJettonTransfer},
				Builder: func(newAction *BubbleJettonSwap, bubble *Bubble) error {
					jettonTx := bubble.Info.(BubbleJettonTransfer)
					newAction.Out.JettonMaster = jettonTx.master
					newAction.Out.JettonWallet = jettonTx.recipientWallet
					newAction.Out.Amount = big.Int(jettonTx.amount)
					newAction.Success = jettonTx.success
					return nil
				},
			},
		},
	},
}
View Source
var BidaskLiquidityDepositBothJettonStraw = Straw[BubbleLiquidityDeposit]{
	CheckFuncs: []bubbleCheck{},
	Children: []Straw[BubbleLiquidityDeposit]{
		{
			CheckFuncs: []bubbleCheck{IsJettonTransfer},
			Builder: func(newAction *BubbleLiquidityDeposit, bubble *Bubble) error {
				jettonTx := bubble.Info.(BubbleJettonTransfer)
				newAction.Protocol = core.Protocol{
					Name:  string(references.Bidask),
					Image: &references.BidaskImage,
				}
				newAction.From = jettonTx.sender.Address
				depositJetton := core.VaultDepositInfo{
					Price: core.Price{
						Currency: core.Currency{
							Type:   core.CurrencyJetton,
							Jetton: &jettonTx.master,
						},
						Amount: big.Int(jettonTx.amount),
					},
					Vault: jettonTx.recipientWallet,
				}
				newAction.Tokens = append(newAction.Tokens, depositJetton)
				return nil
			},
			SingleChild: &Straw[BubbleLiquidityDeposit]{
				CheckFuncs: []bubbleCheck{IsTx, HasInterface(abi.BidaskInternalLiquidityVault)},
				SingleChild: &Straw[BubbleLiquidityDeposit]{
					CheckFuncs: []bubbleCheck{Is(BubbleContractDeploy{})},
					Optional:   true,
				},
			},
		},
		{
			CheckFuncs: []bubbleCheck{IsJettonTransfer},
			Builder: func(newAction *BubbleLiquidityDeposit, bubble *Bubble) error {
				jettonTx := bubble.Info.(BubbleJettonTransfer)
				newAction.Protocol = core.Protocol{
					Name:  string(references.Bidask),
					Image: &references.BidaskImage,
				}
				newAction.From = jettonTx.sender.Address
				depositJetton := core.VaultDepositInfo{
					Price: core.Price{
						Currency: core.Currency{
							Type:   core.CurrencyJetton,
							Jetton: &jettonTx.master,
						},
						Amount: big.Int(jettonTx.amount),
					},
					Vault: jettonTx.recipientWallet,
				}
				newAction.Tokens = append(newAction.Tokens, depositJetton)
				return nil
			},
			SingleChild: &Straw[BubbleLiquidityDeposit]{
				CheckFuncs: []bubbleCheck{IsTx, HasInterface(abi.BidaskInternalLiquidityVault)},
				Builder: func(newAction *BubbleLiquidityDeposit, bubble *Bubble) error {
					tx := bubble.Info.(BubbleTx)
					newAction.Success = tx.success
					return nil
				},
				SingleChild: &Straw[BubbleLiquidityDeposit]{
					CheckFuncs: []bubbleCheck{IsTx, HasInterface(abi.BidaskPool)},
					SingleChild: &Straw[BubbleLiquidityDeposit]{
						CheckFuncs: []bubbleCheck{IsTx, HasInterface(abi.BidaskRange)},
						SingleChild: &Straw[BubbleLiquidityDeposit]{
							CheckFuncs: []bubbleCheck{IsTx, HasInterface(abi.BidaskLpMultitoken)},
							Children: []Straw[BubbleLiquidityDeposit]{
								{
									CheckFuncs: []bubbleCheck{IsTx, HasInterface(abi.Wallet)},
									Builder: func(newAction *BubbleLiquidityDeposit, bubble *Bubble) error {
										tx := bubble.Info.(BubbleTx)
										newAction.Success = tx.success
										return nil
									},
								},
								{
									CheckFuncs: []bubbleCheck{Is(BubbleContractDeploy{})},
								},
							},
						},
					},
				},
			},
		},
	},
}
View Source
var BidaskLiquidityDepositBothNativeStraw = Straw[BubbleLiquidityDeposit]{
	CheckFuncs: []bubbleCheck{IsJettonTransfer, JettonTransferOperation(abi.BidaskProvideBothJettonOp)},
	Builder: func(newAction *BubbleLiquidityDeposit, bubble *Bubble) error {
		jettonTx := bubble.Info.(BubbleJettonTransfer)
		newAction.Protocol = core.Protocol{
			Name:  string(references.Bidask),
			Image: &references.BidaskImage,
		}
		newAction.From = jettonTx.sender.Address
		payload := jettonTx.payload.Value.(abi.BidaskProvideBothJettonPayload)
		tonAmount := new(big.Int)
		tonAmount.SetUint64(uint64(payload.TonAmount))
		depositTon := core.VaultDepositInfo{
			Price: core.Price{
				Currency: core.Currency{
					Type: core.CurrencyTON,
				},
				Amount: *tonAmount,
			},
			Vault: jettonTx.recipient.Address,
		}
		newAction.Tokens = append(newAction.Tokens, depositTon)
		depositJetton := core.VaultDepositInfo{
			Price: core.Price{
				Currency: core.Currency{
					Type:   core.CurrencyJetton,
					Jetton: &jettonTx.master,
				},
				Amount: big.Int(jettonTx.amount),
			},
			Vault: jettonTx.recipientWallet,
		}
		newAction.Tokens = append(newAction.Tokens, depositJetton)
		return nil
	},
	SingleChild: &Straw[BubbleLiquidityDeposit]{
		CheckFuncs: []bubbleCheck{IsTx, HasInterface(abi.BidaskRange)},
		Children: []Straw[BubbleLiquidityDeposit]{
			{
				CheckFuncs: []bubbleCheck{IsTx, HasInterface(abi.BidaskPool)},
				SingleChild: &Straw[BubbleLiquidityDeposit]{
					CheckFuncs: []bubbleCheck{IsJettonTransfer},
				},
				Optional: true,
			},
			{
				CheckFuncs: []bubbleCheck{IsTx, HasInterface(abi.BidaskLpMultitoken)},
				Children: []Straw[BubbleLiquidityDeposit]{
					{
						CheckFuncs: []bubbleCheck{IsTx, HasInterface(abi.Wallet)},
						Builder: func(newAction *BubbleLiquidityDeposit, bubble *Bubble) error {
							tx := bubble.Info.(BubbleTx)
							newAction.Success = tx.success
							return nil
						},
					},
					{
						CheckFuncs: []bubbleCheck{Is(BubbleContractDeploy{})},
					},
				},
			},
		},
	},
}
View Source
var BidaskLiquidityDepositJettonStraw = Straw[BubbleLiquidityDeposit]{
	CheckFuncs: []bubbleCheck{IsJettonTransfer},
	Builder: func(newAction *BubbleLiquidityDeposit, bubble *Bubble) error {
		jettonTx := bubble.Info.(BubbleJettonTransfer)
		newAction.Protocol = core.Protocol{
			Name:  string(references.Bidask),
			Image: &references.BidaskImage,
		}
		newAction.From = jettonTx.sender.Address
		depositJetton := core.VaultDepositInfo{
			Price: core.Price{
				Currency: core.Currency{
					Type:   core.CurrencyJetton,
					Jetton: &jettonTx.master,
				},
				Amount: big.Int(jettonTx.amount),
			},
			Vault: jettonTx.recipientWallet,
		}
		newAction.Tokens = append(newAction.Tokens, depositJetton)
		return nil
	},
	SingleChild: &Straw[BubbleLiquidityDeposit]{
		CheckFuncs: []bubbleCheck{IsTx, HasInterface(abi.BidaskRange)},
		Children: []Straw[BubbleLiquidityDeposit]{
			{
				CheckFuncs: []bubbleCheck{IsTx, HasInterface(abi.BidaskPool)},
				SingleChild: &Straw[BubbleLiquidityDeposit]{
					CheckFuncs: []bubbleCheck{IsJettonTransfer},
				},
				Optional: true,
			},
			{
				CheckFuncs: []bubbleCheck{IsTx, HasInterface(abi.BidaskLpMultitoken)},
				Children: []Straw[BubbleLiquidityDeposit]{
					{
						CheckFuncs: []bubbleCheck{IsTx, HasInterface(abi.Wallet)},
						Builder: func(newAction *BubbleLiquidityDeposit, bubble *Bubble) error {
							tx := bubble.Info.(BubbleTx)
							newAction.Success = tx.success
							return nil
						},
					},
					{
						CheckFuncs: []bubbleCheck{Is(BubbleContractDeploy{})},
					},
				},
			},
		},
	},
}
View Source
var BidaskSwapStraw = Straw[BubbleJettonSwap]{
	CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.BidaskSwapMsgOp), HasInterface(abi.BidaskPool), func(bubble *Bubble) bool {
		tx := bubble.Info.(BubbleTx)
		return tx.decodedBody.Value.(abi.BidaskSwapMsgBody).ToAddress == tx.inputFrom.Address.ToMsgAddress()
	}},
	Builder: func(newAction *BubbleJettonSwap, bubble *Bubble) error {
		tx := bubble.Info.(BubbleTx)
		newAction.Dex = references.Bidask
		newAction.UserWallet = tx.inputFrom.Address
		newAction.Router = tx.account.Address
		body := tx.decodedBody.Value.(abi.BidaskSwapMsgBody)
		newAction.In.Amount = *big.NewInt(int64(body.NativeAmount))
		newAction.In.IsTon = true
		return nil
	},
	SingleChild: &Straw[BubbleJettonSwap]{
		CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.BidaskInternalSwapMsgOp), HasInterface(abi.BidaskRange)},
		SingleChild: &Straw[BubbleJettonSwap]{
			CheckFuncs: []bubbleCheck{
				IsTx,
				Or(HasOperation(abi.BidaskSwapSuccessMsgOp), HasOperation(abi.BidaskSwapSuccessV2MsgOp)),
				HasInterface(abi.BidaskPool),
			},
			SingleChild: &Straw[BubbleJettonSwap]{
				CheckFuncs: []bubbleCheck{IsJettonTransfer},
				Builder: func(newAction *BubbleJettonSwap, bubble *Bubble) error {
					jettonTx := bubble.Info.(BubbleJettonTransfer)
					newAction.Out.JettonMaster = jettonTx.master
					newAction.Out.JettonWallet = jettonTx.recipientWallet
					newAction.Out.Amount = big.Int(jettonTx.amount)
					newAction.Success = jettonTx.success
					return nil
				},
			},
		},
	},
}
View Source
var BidaskSwapStrawReverse = Straw[BubbleJettonSwap]{
	CheckFuncs: []bubbleCheck{IsJettonTransfer, func(bubble *Bubble) bool {
		jettonTx := bubble.Info.(BubbleJettonTransfer)
		swap, ok := jettonTx.payload.Value.(abi.BidaskSwapJettonPayload)
		if !ok {
			return false
		}
		if swap.ToAddress != jettonTx.sender.Address.ToMsgAddress() {
			return false
		}
		return true
	}},
	Builder: func(newAction *BubbleJettonSwap, bubble *Bubble) error {
		jettonTx := bubble.Info.(BubbleJettonTransfer)
		newAction.Dex = references.Bidask
		newAction.UserWallet = jettonTx.sender.Address
		newAction.Router = jettonTx.recipient.Address
		newAction.In.JettonMaster = jettonTx.master
		newAction.In.JettonWallet = jettonTx.senderWallet
		newAction.In.Amount = big.Int(jettonTx.amount)
		return nil
	},
	SingleChild: &Straw[BubbleJettonSwap]{
		CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.BidaskInternalSwapMsgOp), HasInterface(abi.BidaskRange)},
		SingleChild: &Straw[BubbleJettonSwap]{
			CheckFuncs: []bubbleCheck{
				IsTx,
				Or(HasOperation(abi.BidaskSwapSuccessMsgOp), HasOperation(abi.BidaskSwapSuccessV2MsgOp)),
				HasInterface(abi.BidaskPool),
			},
			SingleChild: &Straw[BubbleJettonSwap]{
				CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.BidaskNativeTransferNotificationMsgOp)},
				Builder: func(newAction *BubbleJettonSwap, bubble *Bubble) error {
					tx := bubble.Info.(BubbleTx)
					newAction.Out.IsTon = true
					body, ok := tx.decodedBody.Value.(abi.BidaskNativeTransferNotificationMsgBody)
					if !ok {
						return fmt.Errorf("body is not a bidask native transfer notification")
					}
					newAction.Out.Amount = *big.NewInt(int64(body.NativeAmount))
					newAction.Success = tx.success
					return nil
				},
			},
		},
	},
}
View Source
var DNSRenewStraw = Straw[BubbleDnsItemRenew]{
	CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.DeleteDnsRecordMsgOp), HasInterface(abi.NftItem), func(bubble *Bubble) bool {
		return bubble.Info.(BubbleTx).decodedBody.Value.(abi.DeleteDnsRecordMsgBody).Key.Equal(tlb.Bits256{})
	}},
	Builder: func(newAction *BubbleDnsItemRenew, bubble *Bubble) error {
		tx := bubble.Info.(BubbleTx)
		newAction.Renewer = tx.inputFrom.Address
		newAction.Item = tx.account.Address
		newAction.Success = tx.success
		return nil
	},
	SingleChild: &Straw[BubbleDnsItemRenew]{
		Optional:   true,
		CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.BounceMsgOp)},
	},
}
View Source
var DepositEthenaStakeStraw = Straw[BubbleDepositTokenStake]{
	CheckFuncs: []bubbleCheck{IsJettonTransfer, JettonRecipientAccount(references.EthenaPool)},
	Builder: func(newAction *BubbleDepositTokenStake, bubble *Bubble) error {
		tx := bubble.Info.(BubbleJettonTransfer)
		newAction.Staker = tx.sender.Address
		amount := big.Int(tx.amount)
		newAction.Protocol = core.Protocol{
			Name:  references.Ethena,
			Image: &references.EthenaImage,
		}
		newAction.StakeMeta = &core.Price{
			Currency: core.Currency{
				Type:   core.CurrencyJetton,
				Jetton: &tx.master,
			},
			Amount: amount,
		}
		return nil
	},
	SingleChild: &Straw[BubbleDepositTokenStake]{
		CheckFuncs: []bubbleCheck{Is(BubbleJettonMint{})},
		Builder: func(newAction *BubbleDepositTokenStake, bubble *Bubble) error {
			tx := bubble.Info.(BubbleJettonMint)
			newAction.Success = tx.success
			return nil
		},
	},
}
View Source
var DepositLiquidStakeStraw = Straw[BubbleDepositStake]{
	CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.TonstakePoolDepositMsgOp)},
	Builder: func(newAction *BubbleDepositStake, bubble *Bubble) error {
		tx := bubble.Info.(BubbleTx)
		newAction.Pool = tx.account.Address
		newAction.Staker = tx.inputFrom.Address
		newAction.Amount = tx.inputAmount - int64(ton.OneTON)
		if newAction.Amount < 0 {
			newAction.Amount = 0
		}
		newAction.Success = tx.success
		newAction.Implementation = core.StakingImplementationLiquidTF
		return nil
	},
	SingleChild: &Straw[BubbleDepositStake]{
		CheckFuncs: []bubbleCheck{IsBounced},
		Optional:   true,
	},
}
View Source
var DepositTFStakeStraw = Straw[BubbleDepositStake]{
	CheckFuncs: []bubbleCheck{IsTx, HasInterface(abi.TvPool), HasTextComment("d")},
	Builder: func(newAction *BubbleDepositStake, bubble *Bubble) error {
		tx := bubble.Info.(BubbleTx)
		newAction.Pool = tx.account.Address
		newAction.Staker = tx.inputFrom.Address
		newAction.Amount = tx.inputAmount
		newAction.Success = tx.success
		newAction.Implementation = core.StakingImplementationTF
		return nil
	},
	SingleChild: &Straw[BubbleDepositStake]{
		CheckFuncs: []bubbleCheck{IsBounced},
		Optional:   true,
	},
}
View Source
var ElectionsDepositStakeStraw = Straw[BubbleElectionsDepositStake]{
	CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.ElectorNewStakeMsgOp), IsAccount(config.ElectorAddress())},
	Builder: func(newAction *BubbleElectionsDepositStake, bubble *Bubble) error {
		bubbleTx := bubble.Info.(BubbleTx)
		newAction.Amount = bubbleTx.inputAmount
		newAction.Staker = bubbleTx.inputFrom.Address
		return nil
	},
	Children: []Straw[BubbleElectionsDepositStake]{
		{
			CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.ElectorNewStakeConfirmationMsgOp)},
			Builder: func(newAction *BubbleElectionsDepositStake, bubble *Bubble) error {
				newAction.Success = true
				return nil
			},
		},
	},
}
View Source
var ElectionsRecoverStakeStraw = Straw[BubbleElectionsRecoverStake]{
	CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.ElectorRecoverStakeRequestMsgOp), IsAccount(config.ElectorAddress())},
	Builder: func(newAction *BubbleElectionsRecoverStake, bubble *Bubble) error {
		bubbleTx := bubble.Info.(BubbleTx)
		newAction.Staker = bubbleTx.inputFrom.Address
		return nil
	},
	Children: []Straw[BubbleElectionsRecoverStake]{
		{
			CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.ElectorRecoverStakeResponseMsgOp)},
			Builder: func(newAction *BubbleElectionsRecoverStake, bubble *Bubble) error {
				newAction.Amount = bubble.Info.(BubbleTx).inputAmount
				newAction.Success = true
				return nil
			},
		},
	},
}
View Source
var GasRelayerStraw = Straw[GasRelayBubble]{
	CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.WalletSignedInternalV5R1MsgOp), HasInterface(abi.WalletV5R1), func(bubble *Bubble) bool {
		tx := bubble.Info.(BubbleTx)
		return tx.inputFrom != nil && slices.Contains(knownRelayers, tx.inputFrom.Address)
	}},
	Builder: func(newAction *GasRelayBubble, bubble *Bubble) error {
		tx := bubble.Info.(BubbleTx)
		newAction.Relayer = tx.inputFrom.Address
		newAction.Target = tx.account.Address
		newAction.Amount = tx.inputAmount
		return nil
	},
}
View Source
var InvoicePaymentStrawJetton = Straw[BubbleInvoicePayment]{
	CheckFuncs: []bubbleCheck{func(bubble *Bubble) bool {
		jettonTx, ok := bubble.Info.(BubbleJettonTransfer)
		if !ok {
			return false
		}
		if jettonTx.sender == nil || jettonTx.recipient == nil {
			return false
		}
		if jettonTx.payload.SumType != abi.InvoicePayloadJettonOp {
			return false
		}
		return true
	}},
	Builder: func(newAction *BubbleInvoicePayment, bubble *Bubble) error {
		jettonTx := bubble.Info.(BubbleJettonTransfer)

		invoicePayload := jettonTx.payload.Value.(abi.InvoicePayloadJettonPayload)
		id, err := uuid.FromBytes(invoicePayload.Id[:])
		if err != nil {
			return err
		}
		newAction.InvoiceID = id
		newAction.Price = core.Price{
			Currency: core.Currency{
				Type:   core.CurrencyJetton,
				Jetton: &jettonTx.master,
			},
			Amount: big.Int(jettonTx.amount),
		}

		newAction.Sender = jettonTx.sender.Address
		newAction.Recipient = jettonTx.recipient.Address
		newAction.Success = jettonTx.success
		return nil
	},
}
View Source
var InvoicePaymentStrawNative = Straw[BubbleInvoicePayment]{
	CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.InvoicePayloadMsgOp), AmountInterval(1, 1<<62)},
	Builder: func(newAction *BubbleInvoicePayment, bubble *Bubble) error {
		tx := bubble.Info.(BubbleTx)
		invoicePayload := tx.decodedBody.Value.(abi.InvoicePayloadMsgBody)
		id, err := uuid.FromBytes(invoicePayload.Id[:])
		if err != nil {
			return err
		}
		newAction.InvoiceID = id
		price := core.Price{
			Currency: core.Currency{Type: core.CurrencyTON},
			Amount:   *big.NewInt(tx.inputAmount),
		}
		for c, am := range tx.inputExtraAmount {
			price.Currency = core.Currency{
				Type:       core.CurrencyExtra,
				CurrencyID: &c,
			}
			price.Amount = big.Int(am)
			break
		}
		if tx.inputFrom == nil {
			return errors.New("empty input")
		}
		newAction.Sender = tx.inputFrom.Address
		newAction.Recipient = tx.account.Address
		newAction.Price = price
		newAction.Success = tx.success
		return nil
	},
}
View Source
var JettonBurnStraw = Straw[BubbleJettonBurn]{
	CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.JettonBurnMsgOp)},
	Builder: func(newAction *BubbleJettonBurn, bubble *Bubble) error {
		tx := bubble.Info.(BubbleTx)
		msg := tx.decodedBody.Value.(abi.JettonBurnMsgBody)
		newAction.amount = msg.Amount
		if tx.inputFrom != nil {
			newAction.sender = *tx.inputFrom
		}
		if tx.additionalInfo != nil {
			if master, ok := tx.additionalInfo.JettonMaster(tx.account.Address); ok {

				newAction.master = master
			}
		}
		newAction.senderWallet = tx.account.Address
		newAction.success = tx.success
		return nil
	},
	SingleChild: &Straw[BubbleJettonBurn]{
		CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.JettonBurnNotificationMsgOp)},
		Builder: func(newAction *BubbleJettonBurn, bubble *Bubble) error {
			newAction.master = bubble.Info.(BubbleTx).account.Address
			return nil
		},
		ValueFlowUpdater: func(newAction *BubbleJettonBurn, flow *ValueFlow) {
			if newAction.success {
				flow.SubJettons(newAction.sender.Address, newAction.master, big.Int(newAction.amount))
			}
		},
		Optional: true,
	},
}
View Source
var JettonMintFromMasterStraw = Straw[BubbleJettonMint]{
	CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.JettonInternalTransferMsgOp), HasInterface(abi.JettonWallet), func(bubble *Bubble) bool {
		tx := bubble.Info.(BubbleTx)
		return tx.inputFrom != nil && tx.inputFrom.Is(abi.JettonMaster)
	}},

	Builder: func(newAction *BubbleJettonMint, bubble *Bubble) error {
		tx := bubble.Info.(BubbleTx)
		msg := tx.decodedBody.Value.(abi.JettonInternalTransferMsgBody)
		newAction.amount = msg.Amount
		newAction.master = tx.inputFrom.Address
		newAction.recipientWallet = tx.account.Address
		newAction.success = tx.success
		return nil
	},
	Children: []Straw[BubbleJettonMint]{
		{
			CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.JettonNotifyMsgOp)},
			Builder: func(newAction *BubbleJettonMint, bubble *Bubble) error {
				tx := bubble.Info.(BubbleTx)
				newAction.recipient = tx.account
				return nil
			},
			ValueFlowUpdater: func(newAction *BubbleJettonMint, flow *ValueFlow) {
				if newAction.success {
					flow.AddJettons(newAction.recipient.Address, newAction.master, big.Int(newAction.amount))
				}
			},
		},
		{CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.ExcessMsgOp)}, Optional: true},
	},
}

JettonMintFromMasterStraw example: https://tonviewer.com/transaction/6d33487c44249d7844db8fac38a5cecf1502ec7e0c09d266e98e95a2b1be17b5

View Source
var JettonMintStrawGovernance = Straw[BubbleJettonMint]{
	CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.JettonMintMsgOp), HasInterface(abi.JettonMaster)},
	Builder: func(newAction *BubbleJettonMint, bubble *Bubble) error {
		tx := bubble.Info.(BubbleTx)
		msg := tx.decodedBody.Value.(abi.JettonMintMsgBody)
		dest, err := tongo.AccountIDFromTlb(msg.ToAddress)
		if err == nil && dest != nil {
			newAction.recipient = Account{Address: *dest}
		}
		return nil
	},
	SingleChild: &Straw[BubbleJettonMint]{
		CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.JettonInternalTransferMsgOp), HasInterface(abi.JettonWallet)},
		Builder: func(newAction *BubbleJettonMint, bubble *Bubble) error {
			tx := bubble.Info.(BubbleTx)
			msg := tx.decodedBody.Value.(abi.JettonInternalTransferMsgBody)
			newAction.amount = msg.Amount
			newAction.recipientWallet = tx.account.Address
			newAction.master = tx.inputFrom.Address
			newAction.success = tx.success
			return nil
		},
		SingleChild: &Straw[BubbleJettonMint]{
			Optional:   true,
			CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.ExcessMsgOp)},
		},
	},
}
View Source
var JettonTransferClassicStraw = Straw[BubbleJettonTransfer]{
	CheckFuncs: []bubbleCheck{IsTx, HasInterface(abi.JettonWallet), HasOperation(abi.JettonTransferMsgOp)},
	Builder: func(newAction *BubbleJettonTransfer, bubble *Bubble) error {
		tx := bubble.Info.(BubbleTx)
		newAction.master, _ = tx.additionalInfo.JettonMaster(tx.account.Address)
		newAction.senderWallet = tx.account.Address
		newAction.sender = tx.inputFrom
		body := tx.decodedBody.Value.(abi.JettonTransferMsgBody)
		newAction.amount = body.Amount
		newAction.payload = body.ForwardPayload.Value
		recipient, err := ton.AccountIDFromTlb(body.Destination)
		if err == nil && recipient != nil {
			newAction.recipient = &Account{Address: *recipient}
			bubble.Accounts = append(bubble.Accounts, *recipient)
		}
		return nil
	},
	SingleChild: &Straw[BubbleJettonTransfer]{
		CheckFuncs: []bubbleCheck{IsTx, Or(HasInterface(abi.JettonWallet), HasOperation(abi.JettonInternalTransferMsgOp))},
		Optional:   true,
		Builder: func(newAction *BubbleJettonTransfer, bubble *Bubble) error {
			tx := bubble.Info.(BubbleTx)
			newAction.recipientWallet = tx.account.Address
			if newAction.master.IsZero() {
				newAction.master, _ = tx.additionalInfo.JettonMaster(tx.account.Address)
			}
			newAction.success = tx.success
			return nil
		},
		ValueFlowUpdater: func(newAction *BubbleJettonTransfer, flow *ValueFlow) {
			if newAction.success {
				if newAction.recipient != nil {
					flow.AddJettons(newAction.recipient.Address, newAction.master, big.Int(newAction.amount))
				}
				if newAction.sender != nil {
					flow.SubJettons(newAction.sender.Address, newAction.master, big.Int(newAction.amount))
				}
			}
		},
		Children: []Straw[BubbleJettonTransfer]{
			{
				CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.JettonNotifyMsgOp)},
				Builder: func(newAction *BubbleJettonTransfer, bubble *Bubble) error {
					tx := bubble.Info.(BubbleTx)
					newAction.success = true
					body := tx.decodedBody.Value.(abi.JettonNotifyMsgBody)
					newAction.amount = body.Amount
					newAction.payload = body.ForwardPayload.Value
					newAction.recipient = &tx.account
					if newAction.sender == nil {
						sender, err := ton.AccountIDFromTlb(body.Sender)
						if err == nil {
							newAction.sender = &Account{Address: *sender}
						}
					}
					return nil
				},
				ValueFlowUpdater: func(newAction *BubbleJettonTransfer, flow *ValueFlow) {
					if newAction.recipient != nil {
						flow.AddJettons(newAction.recipient.Address, newAction.master, big.Int(newAction.amount))
					}
					if newAction.sender != nil {
						flow.SubJettons(newAction.sender.Address, newAction.master, big.Int(newAction.amount))
					}
				},
				Optional: true,
			},
			{
				CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.ExcessMsgOp)},
				Optional:   true,
			},
		},
	},
}
View Source
var JettonTransferMinimalStraw = Straw[BubbleJettonTransfer]{
	CheckFuncs: []bubbleCheck{IsTx, HasInterface(abi.JettonWallet), HasOpcode(abi.JettonTransferMsgOpCode)},
	Builder: func(newAction *BubbleJettonTransfer, bubble *Bubble) error {
		tx := bubble.Info.(BubbleTx)
		newAction.master, _ = tx.additionalInfo.JettonMaster(tx.account.Address)
		newAction.senderWallet = tx.account.Address
		newAction.sender = tx.inputFrom
		return nil
	},
	SingleChild: &Straw[BubbleJettonTransfer]{
		CheckFuncs: []bubbleCheck{IsTx, HasInterface(abi.JettonWallet), HasOperation(abi.JettonInternalTransferMsgOp)},
		Optional:   true,
		Builder: func(newAction *BubbleJettonTransfer, bubble *Bubble) error {
			tx := bubble.Info.(BubbleTx)
			newAction.recipientWallet = tx.account.Address
			if newAction.master.IsZero() {
				newAction.master, _ = tx.additionalInfo.JettonMaster(tx.account.Address)
			}
			newAction.success = tx.success
			body, _ := tx.decodedBody.Value.(abi.JettonInternalTransferMsgBody)
			newAction.amount = body.Amount
			return nil
		},
		ValueFlowUpdater: func(newAction *BubbleJettonTransfer, flow *ValueFlow) {
			if newAction.success {
				if newAction.recipient != nil {
					flow.AddJettons(newAction.recipient.Address, newAction.master, big.Int(newAction.amount))
				}
				if newAction.sender != nil {
					flow.SubJettons(newAction.sender.Address, newAction.master, big.Int(newAction.amount))
				}
			}
		},
		Children: []Straw[BubbleJettonTransfer]{
			{
				CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.JettonNotifyMsgOp)},
				Builder: func(newAction *BubbleJettonTransfer, bubble *Bubble) error {
					tx := bubble.Info.(BubbleTx)
					newAction.success = true
					body := tx.decodedBody.Value.(abi.JettonNotifyMsgBody)
					newAction.amount = body.Amount
					newAction.payload = body.ForwardPayload.Value
					newAction.recipient = &tx.account
					if newAction.sender == nil {
						sender, err := ton.AccountIDFromTlb(body.Sender)
						if err == nil {
							newAction.sender = &Account{Address: *sender}
						}
					}
					return nil
				},
				ValueFlowUpdater: func(newAction *BubbleJettonTransfer, flow *ValueFlow) {
					if newAction.recipient != nil {
						flow.AddJettons(newAction.recipient.Address, newAction.master, big.Int(newAction.amount))
					}
					if newAction.sender != nil {
						flow.SubJettons(newAction.sender.Address, newAction.master, big.Int(newAction.amount))
					}
				},
				Optional: true,
			},
			{
				CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.ExcessMsgOp)},
				Optional:   true,
			},
		},
	},
}
View Source
var MegatonFiJettonSwap = Straw[BubbleJettonSwap]{
	CheckFuncs: []bubbleCheck{IsJettonTransfer, IsJettonReceiver(abi.MegatonfiRouter)},
	Builder: func(newAction *BubbleJettonSwap, bubble *Bubble) error {
		tx := bubble.Info.(BubbleJettonTransfer)
		newAction.UserWallet = tx.sender.Address
		newAction.In.Amount = big.Int(tx.amount)
		newAction.In.IsTon = tx.isWrappedTon
		newAction.Router = tx.recipient.Address
		newAction.In.JettonWallet = tx.senderWallet
		newAction.In.JettonMaster = tx.master
		newAction.Dex = references.Megatonfi
		return nil
	},
	Children: []Straw[BubbleJettonSwap]{
		{
			CheckFuncs: []bubbleCheck{IsJettonTransfer, IsJettonReceiver(abi.MegatonfiExchange)},
			Children: []Straw[BubbleJettonSwap]{
				{
					CheckFuncs: []bubbleCheck{IsJettonTransfer, IsJettonReceiver(abi.MegatonfiRouter)},
					Children: []Straw[BubbleJettonSwap]{
						{
							CheckFuncs: []bubbleCheck{IsJettonTransfer},
							Builder: func(newAction *BubbleJettonSwap, bubble *Bubble) error {
								tx := bubble.Info.(BubbleJettonTransfer)
								newAction.Success = tx.success
								newAction.Out.Amount = big.Int(tx.amount)
								newAction.Out.IsTon = tx.isWrappedTon
								newAction.Out.JettonWallet = tx.recipientWallet
								newAction.Out.JettonMaster = tx.master
								return nil
							},
						},
					},
				},
			},
		},
	},
}

MegatonFiJettonSwap creates a BubbleJettonSwap if there is a jetton swap in a trace.

View Source
var MooncxSwapStraw = Straw[BubbleJettonSwap]{
	CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.MoonSwapMsgOp), HasInterface(abi.MoonPool), func(bubble *Bubble) bool {
		tx, ok := bubble.Info.(BubbleTx)
		if !ok {
			return false
		}
		swap, ok := tx.decodedBody.Value.(abi.MoonSwapMsgBody)
		if !ok {
			return false
		}
		if swap.SwapParams.NextFulfill != nil && swap.SwapParams.NextFulfill.Recipient != tx.inputFrom.Address.ToMsgAddress() {
			return false
		}
		return true
	}},
	Builder: func(newAction *BubbleJettonSwap, bubble *Bubble) error {
		tx := bubble.Info.(BubbleTx)
		newAction.Dex = references.Mooncx
		newAction.UserWallet = tx.inputFrom.Address
		newAction.Router = tx.account.Address
		body := tx.decodedBody.Value.(abi.MoonSwapMsgBody)
		amount := big.Int(body.Amount)
		newAction.In.Amount = amount
		newAction.In.IsTon = true
		return nil
	},
	SingleChild: &Straw[BubbleJettonSwap]{
		CheckFuncs: []bubbleCheck{IsJettonTransfer},
		Builder: func(newAction *BubbleJettonSwap, bubble *Bubble) error {
			tx := bubble.Info.(BubbleJettonTransfer)
			newAction.Out.JettonMaster = tx.master
			newAction.Out.JettonWallet = tx.recipientWallet
			amount := big.Int(tx.amount)
			newAction.Out.Amount = amount
			newAction.Success = tx.success
			return nil
		},
	},
}
View Source
var MooncxSwapStrawReverse = Straw[BubbleJettonSwap]{
	CheckFuncs: []bubbleCheck{func(bubble *Bubble) bool {
		tx, ok := bubble.Info.(BubbleJettonTransfer)
		if !ok {
			return false
		}
		swap, ok := tx.payload.Value.(abi.MoonSwapJettonPayload)
		if !ok {
			return false
		}
		if swap.SwapParams.NextFulfill != nil && swap.SwapParams.NextFulfill.Recipient != tx.sender.Address.ToMsgAddress() {
			return false
		}
		return true
	}},
	Builder: func(newAction *BubbleJettonSwap, bubble *Bubble) error {
		tx := bubble.Info.(BubbleJettonTransfer)
		newAction.Dex = references.Mooncx
		newAction.UserWallet = tx.sender.Address
		newAction.Router = tx.recipient.Address
		newAction.In.JettonMaster = tx.master
		newAction.In.JettonWallet = tx.senderWallet
		amount := big.Int(tx.amount)
		newAction.In.Amount = amount
		body := tx.payload.Value.(abi.MoonSwapJettonPayload)
		newAction.Out.Amount = big.Int(body.SwapParams.MinOut)
		newAction.Out.IsTon = true
		return nil
	},
	SingleChild: &Straw[BubbleJettonSwap]{
		CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.MoonSwapSucceedMsgOp)},
		Builder: func(newAction *BubbleJettonSwap, bubble *Bubble) error {
			tx := bubble.Info.(BubbleTx)
			newAction.Success = tx.success
			return nil
		},
	},
}
View Source
var NftPurchaseStraw = Straw[BubbleNftPurchase]{
	CheckFuncs: []bubbleCheck{
		IsTx,
		Or(HasInterface(abi.NftSaleV2), HasInterface(abi.NftSaleV1)),
		HasEmptyBody,
		AmountInterval(1, 1<<62),
		func(bubble *Bubble) bool {
			tx := bubble.Info.(BubbleTx)
			return tx.additionalInfo != nil && tx.additionalInfo.NftSaleContract != nil && tx.additionalInfo.NftSaleContract.Owner != nil
		}},
	Builder: func(newAction *BubbleNftPurchase, bubble *Bubble) error {
		tx := bubble.Info.(BubbleTx)
		sale := tx.additionalInfo.NftSaleContract
		newAction.Seller = *sale.Owner
		newAction.AuctionType = GetGemsAuction
		newAction.Buyer = tx.inputFrom.Address
		newAction.Price = sale.NftPrice
		if tx.additionalInfo.NftSaleContract != nil {
			newAction.Nft = tx.additionalInfo.NftSaleContract.Item
		}
		return nil
	},
	SingleChild: &Straw[BubbleNftPurchase]{
		CheckFuncs: []bubbleCheck{IsNftTransfer},
		Builder: func(newAction *BubbleNftPurchase, bubble *Bubble) error {
			newAction.Success = bubble.Info.(BubbleNftTransfer).success
			newAction.Nft = bubble.Info.(BubbleNftTransfer).account.Address
			return nil
		},
		Optional: true,
	},
}
View Source
var NftTransferNotifyStraw = Straw[BubbleNftTransfer]{
	CheckFuncs: []bubbleCheck{IsTx, HasInterface(abi.NftItem)},
	Builder: func(newAction *BubbleNftTransfer, bubble *Bubble) error {
		tx := bubble.Info.(BubbleTx)
		if tx.inputFrom != nil {
			newAction.sender = tx.inputFrom
		}
		return nil
	},
	Children: []Straw[BubbleNftTransfer]{
		{
			CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.NftOwnershipAssignedMsgOp)},
			Builder: func(newAction *BubbleNftTransfer, bubble *Bubble) error {
				receiverTx := bubble.Info.(BubbleTx)
				transfer := receiverTx.decodedBody.Value.(abi.NftOwnershipAssignedMsgBody)
				newAction.success = true
				if receiverTx.inputFrom == nil {
					return fmt.Errorf("nft transfer notify without sender")
				}
				newAction.account = *receiverTx.inputFrom
				newAction.recipient = &receiverTx.account
				newAction.payload = transfer.ForwardPayload.Value
				return nil
			},
		},
		{
			CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.ExcessMsgOp)},
			Optional:   true,
		},
	},
}
View Source
var NftTransferStraw = Straw[BubbleNftTransfer]{
	CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.NftTransferMsgOp), HasInterface(abi.NftItem)},
	Builder: func(newAction *BubbleNftTransfer, bubble *Bubble) error {
		tx := bubble.Info.(BubbleTx)
		transfer := tx.decodedBody.Value.(abi.NftTransferMsgBody)
		newAction.account = tx.account
		newAction.success = tx.success
		newAction.sender = tx.inputFrom
		newAction.payload = transfer.ForwardPayload.Value
		if newAction.recipient == nil {
			newAction.recipient = parseAccount(transfer.NewOwner)
			if newAction.recipient != nil {
				bubble.Accounts = append(bubble.Accounts, newAction.recipient.Address)
			}
		}
		return nil
	},
	Children: []Straw[BubbleNftTransfer]{
		{
			CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.NftOwnershipAssignedMsgOp)},
			Optional:   true,
			Builder: func(newAction *BubbleNftTransfer, bubble *Bubble) error {
				receiverTx := bubble.Info.(BubbleTx)
				transfer := receiverTx.decodedBody.Value.(abi.NftOwnershipAssignedMsgBody)
				newAction.success = true
				newAction.payload = transfer.ForwardPayload.Value
				return nil
			},
		},
		{
			CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.ExcessMsgOp)},
			Optional:   true,
		},
	},
}
View Source
var OldPendingWithdrawRequestLiquidStraw = Straw[BubbleWithdrawStakeRequest]{
	CheckFuncs: []bubbleCheck{Is(BubbleJettonBurn{})},
	Builder: func(newAction *BubbleWithdrawStakeRequest, bubble *Bubble) error {
		newAction.Staker = bubble.Info.(BubbleJettonBurn).sender.Address
		newAction.Success = true
		newAction.Implementation = core.StakingImplementationLiquidTF
		amount := big.Int(bubble.Info.(BubbleJettonBurn).amount)
		i := amount.Int64()
		newAction.Amount = &i
		return nil
	},
	SingleChild: &Straw[BubbleWithdrawStakeRequest]{
		CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.TonstakePoolWithdrawMsgOp)},
		Builder: func(newAction *BubbleWithdrawStakeRequest, bubble *Bubble) error {
			newAction.Pool = bubble.Info.(BubbleTx).account.Address
			newAction.Success = true
			newAction.attachedAmount = bubble.Info.(BubbleTx).inputAmount
			return nil
		},
		SingleChild: &Straw[BubbleWithdrawStakeRequest]{
			CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.TonstakePayoutMintJettonsMsgOp)},
			SingleChild: &Straw[BubbleWithdrawStakeRequest]{
				CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.TonstakeNftInitMsgOp)},
				SingleChild: &Straw[BubbleWithdrawStakeRequest]{
					CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.NftOwnershipAssignedMsgOp)},
					Builder: func(newAction *BubbleWithdrawStakeRequest, bubble *Bubble) error {
						newAction.Success = true
						return nil
					},
				},
			},
		},
	},
}
View Source
var PendingWithdrawRequestLiquidStraw = Straw[BubbleWithdrawStakeRequest]{
	CheckFuncs: []bubbleCheck{Is(BubbleJettonBurn{})},
	Builder: func(newAction *BubbleWithdrawStakeRequest, bubble *Bubble) error {
		newAction.Staker = bubble.Info.(BubbleJettonBurn).sender.Address
		newAction.Success = true
		newAction.Implementation = core.StakingImplementationLiquidTF
		amount := big.Int(bubble.Info.(BubbleJettonBurn).amount)
		i := amount.Int64()
		newAction.Amount = &i
		return nil
	},
	SingleChild: &Straw[BubbleWithdrawStakeRequest]{
		CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.TonstakePoolWithdrawMsgOp)},
		Builder: func(newAction *BubbleWithdrawStakeRequest, bubble *Bubble) error {
			newAction.Pool = bubble.Info.(BubbleTx).account.Address
			newAction.Success = true
			newAction.attachedAmount = bubble.Info.(BubbleTx).inputAmount
			return nil
		},
		SingleChild: &Straw[BubbleWithdrawStakeRequest]{
			CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.TonstakePayoutMintJettonsMsgOp)},
			SingleChild: &Straw[BubbleWithdrawStakeRequest]{
				CheckFuncs: []bubbleCheck{Is(BubbleNftTransfer{})},
				Builder: func(newAction *BubbleWithdrawStakeRequest, bubble *Bubble) error {
					newAction.Success = true
					return nil
				},
			},
		},
	},
}
View Source
var StonfiLiquidityDepositBoth = Straw[BubbleLiquidityDeposit]{
	CheckFuncs: []bubbleCheck{},
	Children: []Straw[BubbleLiquidityDeposit]{
		{
			CheckFuncs: []bubbleCheck{func(bubble *Bubble) bool {
				tx, ok := bubble.Info.(BubbleLiquidityDeposit)
				if !ok {
					return false
				}
				if tx.Protocol.Name != string(references.Stonfi) {
					return false
				}
				return true
			}},
			Builder: func(newAction *BubbleLiquidityDeposit, bubble *Bubble) error {
				tx := bubble.Info.(BubbleLiquidityDeposit)
				newAction.Protocol = tx.Protocol
				newAction.From = tx.From
				newAction.Tokens = append(newAction.Tokens, tx.Tokens...)
				return nil
			},
			Children: []Straw[BubbleLiquidityDeposit]{},
		},
		{
			CheckFuncs: []bubbleCheck{IsJettonTransfer},
			Builder: func(newAction *BubbleLiquidityDeposit, bubble *Bubble) error {
				jettonTx := bubble.Info.(BubbleJettonTransfer)
				if jettonTx.isWrappedTon {
					newAction.Tokens = append(newAction.Tokens, core.VaultDepositInfo{
						Price: core.Price{
							Currency: core.Currency{
								Type: core.CurrencyTON,
							},
							Amount: big.Int(jettonTx.amount),
						},
						Vault: jettonTx.recipient.Address,
					})
				} else {
					newAction.Tokens = append(newAction.Tokens, core.VaultDepositInfo{
						Price: core.Price{
							Currency: core.Currency{
								Type:   core.CurrencyJetton,
								Jetton: &jettonTx.master,
							},
							Amount: big.Int(jettonTx.amount),
						},
						Vault: jettonTx.recipientWallet,
					})
				}
				return nil
			},
			SingleChild: &Straw[BubbleLiquidityDeposit]{
				CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.StonfiProvideLpV2MsgOp), HasInterface(abi.StonfiPoolV2)},
				SingleChild: &Straw[BubbleLiquidityDeposit]{
					CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.StonfiAddLiquidityV2MsgOp)},
					Children: []Straw[BubbleLiquidityDeposit]{
						{
							CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.ExcessMsgOp)},
							Builder: func(newAction *BubbleLiquidityDeposit, bubble *Bubble) error {
								tx := bubble.Info.(BubbleTx)
								newAction.Success = tx.success
								return nil
							},
						},
						{
							Optional:   true,
							CheckFuncs: []bubbleCheck{Is(BubbleContractDeploy{})},
						},
					},
				},
			},
		},
	},
}
View Source
var StonfiLiquidityDepositSingle = Straw[BubbleLiquidityDeposit]{
	CheckFuncs: []bubbleCheck{IsJettonTransfer, func(bubble *Bubble) bool {
		tx := bubble.Info.(BubbleJettonTransfer)
		body, ok := tx.payload.Value.(abi.StonfiProvideLpV2JettonPayload)
		if !ok {
			return false
		}
		if body.CrossProvideLpBody.ToAddress != tx.sender.Address.ToMsgAddress() {
			return false
		}
		_, ok = references.StonfiWhitelistVaults[tx.recipient.Address]
		if !ok {
			return false
		}
		return true
	}},
	Builder: func(newAction *BubbleLiquidityDeposit, bubble *Bubble) error {
		jettonTx := bubble.Info.(BubbleJettonTransfer)
		newAction.Protocol = core.Protocol{
			Name:  string(references.Stonfi),
			Image: &references.StonfiImage,
		}
		newAction.From = jettonTx.sender.Address
		if jettonTx.isWrappedTon {
			newAction.Tokens = append(newAction.Tokens, core.VaultDepositInfo{
				Price: core.Price{
					Currency: core.Currency{
						Type: core.CurrencyTON,
					},
					Amount: big.Int(jettonTx.amount),
				},
				Vault: jettonTx.recipient.Address,
			})
		} else {
			newAction.Tokens = append(newAction.Tokens, core.VaultDepositInfo{
				Price: core.Price{
					Currency: core.Currency{
						Type:   core.CurrencyJetton,
						Jetton: &jettonTx.master,
					},
					Amount: big.Int(jettonTx.amount),
				},
				Vault: jettonTx.recipientWallet,
			})
		}
		return nil
	},
	SingleChild: &Straw[BubbleLiquidityDeposit]{
		CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.StonfiProvideLpV2MsgOp), HasInterface(abi.StonfiPoolV2)},
		SingleChild: &Straw[BubbleLiquidityDeposit]{
			CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.StonfiAddLiquidityV2MsgOp)},
			Children: []Straw[BubbleLiquidityDeposit]{
				{
					CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.StonfiCbAddLiquidityV2MsgOp), HasInterface(abi.StonfiPoolV2)},
					Children: []Straw[BubbleLiquidityDeposit]{
						{
							Optional:   true,
							CheckFuncs: []bubbleCheck{Is(BubbleJettonMint{})},
							SingleChild: &Straw[BubbleLiquidityDeposit]{
								CheckFuncs: []bubbleCheck{IsTx, HasInterface(abi.NftItem)},
								Children: []Straw[BubbleLiquidityDeposit]{
									{
										CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.ExcessMsgOp)},
										Builder: func(newAction *BubbleLiquidityDeposit, bubble *Bubble) error {
											tx := bubble.Info.(BubbleTx)
											newAction.Success = tx.success
											return nil
										},
									},
									{
										Optional:   true,
										CheckFuncs: []bubbleCheck{Is(BubbleContractDeploy{})},
									},
								},
							},
						},
						{
							Optional:   true,
							CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.JettonInternalTransferMsgOp)},
							SingleChild: &Straw[BubbleLiquidityDeposit]{
								CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.ExcessMsgOp)},
								Builder: func(newAction *BubbleLiquidityDeposit, bubble *Bubble) error {
									tx := bubble.Info.(BubbleTx)
									newAction.Success = tx.success
									return nil
								},
							},
						},
					},
				},
				{
					Optional:   true,
					CheckFuncs: []bubbleCheck{Is(BubbleContractDeploy{})},
				},
			},
		},
	},
}
View Source
var StonfiSwapStraw = Straw[BubbleJettonSwap]{
	CheckFuncs: []bubbleCheck{func(bubble *Bubble) bool {
		jettonTx, ok := bubble.Info.(BubbleJettonTransfer)
		if !ok {
			return false
		}
		if jettonTx.sender == nil {
			return false
		}
		if jettonTx.payload.SumType != abi.StonfiSwapJettonOp {
			return false
		}
		swap, ok := jettonTx.payload.Value.(abi.StonfiSwapJettonPayload)
		if !ok {
			return false
		}
		to, err := ton.AccountIDFromTlb(swap.ToAddress)
		if err != nil || to == nil {
			return false
		}
		if jettonTx.sender.Address != *to {
			return false
		}
		return true
	}},
	Builder: func(newAction *BubbleJettonSwap, bubble *Bubble) error {
		newAction.Dex = references.Stonfi
		jettonTx := bubble.Info.(BubbleJettonTransfer)
		newAction.UserWallet = jettonTx.sender.Address
		newAction.In.Amount = big.Int(jettonTx.amount)
		newAction.In.IsTon = jettonTx.isWrappedTon
		newAction.In.JettonMaster = jettonTx.master
		return nil
	},
	SingleChild: &Straw[BubbleJettonSwap]{
		CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.StonfiSwapMsgOp), HasInterface(abi.StonfiPool)},
		Builder: func(newAction *BubbleJettonSwap, bubble *Bubble) error {
			tx := bubble.Info.(BubbleTx)
			a, b := tx.additionalInfo.STONfiPool.Token0, tx.additionalInfo.STONfiPool.Token1
			body := tx.decodedBody.Value.(abi.StonfiSwapMsgBody)
			newAction.Out.Amount = big.Int(body.MinOut)
			s, err := tongo.AccountIDFromTlb(body.SenderAddress)
			if err != nil {
				return err
			}
			if s != nil && *s == b {
				a, b = b, a
			}
			newAction.In.JettonWallet = a
			newAction.Out.JettonWallet = b
			if tx.additionalInfo != nil {
				newAction.In.JettonMaster, _ = tx.additionalInfo.JettonMaster(a)
				newAction.Out.JettonMaster, _ = tx.additionalInfo.JettonMaster(b)
			}
			return nil
		},
		SingleChild: &Straw[BubbleJettonSwap]{
			CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.StonfiPaymentRequestMsgOp)},
			Builder: func(newAction *BubbleJettonSwap, bubble *Bubble) error {
				tx := bubble.Info.(BubbleTx)
				newAction.Router = tx.account.Address
				return nil
			},
			SingleChild: &Straw[BubbleJettonSwap]{
				CheckFuncs: []bubbleCheck{Is(BubbleJettonTransfer{}), Or(JettonTransferOperation(abi.StonfiSwapOkJettonOp), JettonTransferOpCode(0x5ffe1295))},
				Builder: func(newAction *BubbleJettonSwap, bubble *Bubble) error {
					jettonTx := bubble.Info.(BubbleJettonTransfer)
					if jettonTx.senderWallet != newAction.Out.JettonWallet {

						return nil
					}
					newAction.Out.Amount = big.Int(jettonTx.amount)
					newAction.Out.IsTon = jettonTx.isWrappedTon
					newAction.Success = true
					return nil
				},
			},
		},
	},
}
View Source
var StonfiSwapV2Straw = Straw[BubbleJettonSwap]{
	CheckFuncs: []bubbleCheck{func(bubble *Bubble) bool {
		jettonTx, ok := bubble.Info.(BubbleJettonTransfer)
		if !ok {
			return false
		}
		if jettonTx.sender == nil {
			return false
		}
		if jettonTx.payload.SumType != abi.StonfiSwapV2JettonOp {
			return false
		}
		swap, ok := jettonTx.payload.Value.(abi.StonfiSwapV2JettonPayload)
		if !ok {
			return false
		}
		to, err := ton.AccountIDFromTlb(swap.CrossSwapBody.Receiver)
		if err != nil || to == nil {
			return false
		}
		if jettonTx.sender.Address != *to {
			return false
		}
		return true
	}},
	Builder: func(newAction *BubbleJettonSwap, bubble *Bubble) error {
		newAction.Dex = references.Stonfi
		jettonTx := bubble.Info.(BubbleJettonTransfer)
		newAction.UserWallet = jettonTx.sender.Address
		newAction.In.Amount = big.Int(jettonTx.amount)
		newAction.In.IsTon = jettonTx.isWrappedTon
		newAction.In.JettonMaster = jettonTx.master
		return nil
	},
	SingleChild: &Straw[BubbleJettonSwap]{
		CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.StonfiSwapV2MsgOp), HasInterface(abi.StonfiPoolV2), func(bubble *Bubble) bool {
			tx, ok := bubble.Info.(BubbleTx)
			if !ok {
				return false
			}
			if tx.additionalInfo.STONfiPool == nil {
				return false
			}
			return true
		}},
		Builder: func(newAction *BubbleJettonSwap, bubble *Bubble) error {
			tx := bubble.Info.(BubbleTx)
			a, b := tx.additionalInfo.STONfiPool.Token0, tx.additionalInfo.STONfiPool.Token1
			body := tx.decodedBody.Value.(abi.StonfiSwapV2MsgBody)
			if body.QueryId > 0 && a.IsZero() && b.IsZero() {
				return nil
			}
			s, err := tongo.AccountIDFromTlb(body.DexPayload.TokenWallet1)
			if err != nil {
				return err
			}
			if s != nil && *s == a {
				a, b = b, a
			}
			newAction.In.JettonWallet = a
			newAction.Out.JettonWallet = b
			if tx.additionalInfo != nil {
				newAction.In.JettonMaster, _ = tx.additionalInfo.JettonMaster(a)
				newAction.Out.JettonMaster, _ = tx.additionalInfo.JettonMaster(b)
			}
			return nil
		},
		Children: []Straw[BubbleJettonSwap]{
			{
				CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.StonfiPayToV2MsgOp)},
				Builder: func(newAction *BubbleJettonSwap, bubble *Bubble) error {
					tx := bubble.Info.(BubbleTx)
					newAction.Router = tx.account.Address
					return nil
				},
				SingleChild: &Straw[BubbleJettonSwap]{
					CheckFuncs: []bubbleCheck{Is(BubbleJettonTransfer{})},
					Builder: func(newAction *BubbleJettonSwap, bubble *Bubble) error {
						jettonTx := bubble.Info.(BubbleJettonTransfer)
						if jettonTx.senderWallet != newAction.Out.JettonWallet {

							return nil
						}
						newAction.Out.Amount = big.Int(jettonTx.amount)
						newAction.Out.IsTon = jettonTx.isWrappedTon
						newAction.Success = true
						return nil
					},
				},
			},
			{
				CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.StonfiPayVaultV2MsgOp)},
				Optional:   true,
				SingleChild: &Straw[BubbleJettonSwap]{
					CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.StonfiDepositRefFeeV2MsgOp)},
					SingleChild: &Straw[BubbleJettonSwap]{
						CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.ExcessMsgOp)},
						Optional:   true,
					},
				},
			},
		},
	},
}
View Source
var StonfiV1PTONStraw = Straw[BubbleJettonTransfer]{
	CheckFuncs: []bubbleCheck{IsTx, HasInterface(abi.JettonWallet), HasOperation(abi.JettonTransferMsgOp)},
	Builder: func(newAction *BubbleJettonTransfer, bubble *Bubble) error {
		tx := bubble.Info.(BubbleTx)
		newAction.master, _ = tx.additionalInfo.JettonMaster(tx.account.Address)
		newAction.senderWallet = tx.account.Address
		newAction.sender = tx.inputFrom
		body := tx.decodedBody.Value.(abi.JettonTransferMsgBody)
		newAction.amount = body.Amount
		newAction.isWrappedTon = true
		recipient, err := ton.AccountIDFromTlb(body.Destination)
		if err == nil && recipient != nil {
			newAction.recipient = &Account{Address: *recipient}
			bubble.Accounts = append(bubble.Accounts, *recipient)
		}
		return nil
	},
	SingleChild: &Straw[BubbleJettonTransfer]{
		CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.JettonNotifyMsgOp)},
		Builder: func(newAction *BubbleJettonTransfer, bubble *Bubble) error {
			tx := bubble.Info.(BubbleTx)
			newAction.success = true
			body := tx.decodedBody.Value.(abi.JettonNotifyMsgBody)
			newAction.amount = body.Amount
			newAction.payload = body.ForwardPayload.Value
			newAction.recipient = &tx.account
			return nil
		},
	},
}
View Source
var StonfiV2PTONStraw = Straw[BubbleJettonTransfer]{
	CheckFuncs: []bubbleCheck{IsTx, HasInterface(abi.JettonWallet), HasOperation(abi.PtonTonTransferMsgOp)},
	Builder: func(newAction *BubbleJettonTransfer, bubble *Bubble) error {
		tx := bubble.Info.(BubbleTx)
		newAction.master, _ = tx.additionalInfo.JettonMaster(tx.account.Address)
		newAction.senderWallet = tx.account.Address
		newAction.sender = tx.inputFrom
		body := tx.decodedBody.Value.(abi.PtonTonTransferMsgBody)
		newAction.amount = tlb.VarUInteger16(*big.NewInt(int64(body.TonAmount)))
		newAction.isWrappedTon = true
		recipient, err := ton.AccountIDFromTlb(body.RefundAddress)
		if err == nil {
			newAction.recipient = &Account{Address: *recipient}
		}
		return nil
	},
	SingleChild: &Straw[BubbleJettonTransfer]{
		CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.JettonNotifyMsgOp)},
		Builder: func(newAction *BubbleJettonTransfer, bubble *Bubble) error {
			tx := bubble.Info.(BubbleTx)
			newAction.success = true
			body := tx.decodedBody.Value.(abi.JettonNotifyMsgBody)
			newAction.amount = body.Amount
			newAction.payload = body.ForwardPayload.Value
			newAction.recipient = &tx.account
			return nil
		},
	},
}
View Source
var StonfiV2PTONStrawReverse = Straw[BubbleJettonTransfer]{
	CheckFuncs: []bubbleCheck{IsTx, HasInterface(abi.JettonWallet), HasOperation(abi.JettonTransferMsgOp)},
	Builder: func(newAction *BubbleJettonTransfer, bubble *Bubble) error {
		tx := bubble.Info.(BubbleTx)
		newAction.master, _ = tx.additionalInfo.JettonMaster(tx.account.Address)
		newAction.senderWallet = tx.account.Address
		newAction.sender = tx.inputFrom
		body := tx.decodedBody.Value.(abi.JettonTransferMsgBody)
		newAction.amount = body.Amount
		newAction.isWrappedTon = true
		newAction.payload = body.ForwardPayload.Value
		recipient, err := ton.AccountIDFromTlb(body.Destination)
		if err == nil {
			newAction.recipient = &Account{Address: *recipient}
		}
		return nil
	},
	Children: []Straw[BubbleJettonTransfer]{
		{
			CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.PtonTonTransferMsgOp)},
			Builder: func(newAction *BubbleJettonTransfer, bubble *Bubble) error {
				tx := bubble.Info.(BubbleTx)
				newAction.success = true
				newAction.recipient = &tx.account
				return nil
			},
		},
		{
			CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.ExcessMsgOp)},
			Optional:   true,
		},
	},
}
View Source
var StrawAuctionBigGetgems = Straw[AuctionBidBubble]{
	CheckFuncs: []bubbleCheck{IsTx, HasInterface(abi.NftAuctionV1), HasEmptyBody, AmountInterval(1, 1<<62)},
	Builder: func(newAction *AuctionBidBubble, bubble *Bubble) error {
		tx := bubble.Info.(BubbleTx)
		newAction.Auction = tx.account.Address
		newAction.Bidder = tx.inputFrom.Address
		newAction.Amount = tx.inputAmount
		newAction.Success = tx.success
		newAction.Type = GetGemsAuction
		if tx.additionalInfo != nil && tx.additionalInfo.NftSaleContract != nil {
			newAction.NftAddress = &tx.additionalInfo.NftSaleContract.Item
		}
		return nil
	},
}
View Source
var StrawAuctionBuyFragments = Straw[BubbleNftPurchase]{
	CheckFuncs: []bubbleCheck{Is(AuctionBidBubble{})},
	Builder: func(newAction *BubbleNftPurchase, bubble *Bubble) error {
		bid := bubble.Info.(AuctionBidBubble)
		newAction.Buyer = bid.Bidder
		newAction.Nft = *bid.NftAddress
		newAction.Price = bid.Amount
		newAction.AuctionType = bid.Type
		newAction.Success = bid.Success
		return nil
	},
	SingleChild: &Straw[BubbleNftPurchase]{
		CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.NftOwnershipAssignedMsgOp)},
		Builder: func(newAction *BubbleNftPurchase, bubble *Bubble) error {
			seller := parseAccount(bubble.Info.(BubbleTx).decodedBody.Value.(abi.NftOwnershipAssignedMsgBody).PrevOwner)
			if seller != nil {
				newAction.Seller = seller.Address
			}
			return nil
		},
	},
}
View Source
var StrawAuctionBuyGetgems = Straw[BubbleNftPurchase]{
	CheckFuncs: []bubbleCheck{Is(AuctionBidBubble{})},
	Builder: func(newAction *BubbleNftPurchase, bubble *Bubble) error {
		bid := bubble.Info.(AuctionBidBubble)
		newAction.Buyer = bid.Bidder
		newAction.Nft = *bid.NftAddress
		newAction.Price = bid.Amount
		newAction.AuctionType = bid.Type
		newAction.Success = bid.Success
		return nil
	},
	SingleChild: &Straw[BubbleNftPurchase]{
		CheckFuncs: []bubbleCheck{IsNftTransfer},
	},
}
View Source
var StrawFindAuctionBidFragmentSimple = Straw[AuctionBidBubble]{
	CheckFuncs: []bubbleCheck{IsTx, HasInterface(abi.Teleitem), HasEmptyBody, AmountInterval(1, 1<<62)},
	Builder: func(newAction *AuctionBidBubble, bubble *Bubble) error {
		tx := bubble.Info.(BubbleTx)
		newAction.Type = DnsTgAuction
		newAction.Amount = tx.inputAmount
		newAction.Bidder = tx.inputFrom.Address
		newAction.Success = tx.success
		newAction.Auction = tx.account.Address
		newAction.NftAddress = &tx.account.Address
		return nil
	},
}
View Source
var SubscriptionDeployStraw = Straw[BubbleSubscription]{
	CheckFuncs: []bubbleCheck{IsTx},
	Builder: func(newAction *BubbleSubscription, bubble *Bubble) error {
		tx := bubble.Info.(BubbleTx)
		newAction.Subscriber = tx.account.Address
		newAction.First = true
		newAction.Success = tx.success
		return nil
	},
	Children: []Straw[BubbleSubscription]{
		{
			CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.SubscriptionDeployMsgOp)},
			Builder: func(newAction *BubbleSubscription, bubble *Bubble) error {
				tx := bubble.Info.(BubbleTx)
				newAction.Subscription = tx.account.Address
				if tx.additionalInfo != nil && tx.additionalInfo.SubscriptionInfo != nil {
					newAction.Admin = tx.additionalInfo.SubscriptionInfo.Admin
					newAction.WithdrawTo = tx.additionalInfo.SubscriptionInfo.WithdrawTo
					if len(bubble.Children) > 1 {
						newAction.Amount = tx.additionalInfo.SubscriptionInfo.PaymentPerPeriod
					}
				}
				newAction.Success = newAction.Success && tx.success
				return nil
			},
			Children: []Straw[BubbleSubscription]{
				{
					CheckFuncs: []bubbleCheck{Is(BubbleContractDeploy{})},
					Builder: func(newAction *BubbleSubscription, bubble *Bubble) error {
						newAction.Success = newAction.Success && bubble.Info.(BubbleContractDeploy).Success
						return nil
					},
				},
			},
		},
		{
			CheckFuncs: []bubbleCheck{Is(BubbleAddExtension{})},
			Builder: func(newAction *BubbleSubscription, bubble *Bubble) error {
				addExtTx := bubble.Info.(BubbleAddExtension)

				newAction.Success = newAction.Success && addExtTx.Success
				return nil
			},
		},
	},
}
View Source
var SubscriptionPaymentStraw = Straw[BubbleSubscription]{
	CheckFuncs: []bubbleCheck{
		IsTx,
		Or(HasInterface(abi.SubscriptionV1), HasInterface(abi.SubscriptionV2)),
		HasOperation(abi.PaymentConfirmedMsgOp),
		AmountInterval(1, 1<<62)},
	Builder: func(newAction *BubbleSubscription, bubble *Bubble) error {
		tx := bubble.Info.(BubbleTx)
		newAction.Subscription = tx.account.Address
		if tx.additionalInfo != nil && tx.additionalInfo.SubscriptionInfo != nil {
			newAction.Subscriber = tx.additionalInfo.SubscriptionInfo.Wallet
			newAction.Admin = tx.additionalInfo.SubscriptionInfo.Admin
			newAction.WithdrawTo = tx.additionalInfo.SubscriptionInfo.WithdrawTo
			newAction.Amount = tx.additionalInfo.SubscriptionInfo.PaymentPerPeriod
		}
		if len(bubble.Children) > 0 {
			newAction.Success = tx.success
		}
		return nil
	},
}
View Source
var SubscriptionPaymentWithRequestFundsStraw = Straw[BubbleSubscription]{
	CheckFuncs: []bubbleCheck{
		IsTx,
		Or(HasInterface(abi.SubscriptionV1), HasInterface(abi.SubscriptionV2))},
	Builder: func(newAction *BubbleSubscription, bubble *Bubble) error {
		tx := bubble.Info.(BubbleTx)
		newAction.Subscription = tx.account.Address
		if tx.additionalInfo != nil && tx.additionalInfo.SubscriptionInfo != nil {
			newAction.Subscriber = tx.additionalInfo.SubscriptionInfo.Wallet
			newAction.Admin = tx.additionalInfo.SubscriptionInfo.Admin
			newAction.WithdrawTo = tx.additionalInfo.SubscriptionInfo.WithdrawTo
			newAction.Amount = tx.additionalInfo.SubscriptionInfo.PaymentPerPeriod
		}
		newAction.First = false
		newAction.Success = false
		return nil
	},
	SingleChild: &Straw[BubbleSubscription]{
		CheckFuncs: []bubbleCheck{
			IsTx,
			Or(HasOperation(abi.PaymentRequestMsgOp), HasOperation(abi.WalletExtensionActionV5R1MsgOp)),
			func(bubble *Bubble) bool {
				if body, ok := bubble.Info.(BubbleTx).decodedBody.Value.(abi.WalletExtensionActionV5R1MsgBody); ok {
					return body.Extended == nil || len(*body.Extended) == 0
				}
				return true
			},
		},
		SingleChild: &Straw[BubbleSubscription]{
			Optional:   true,
			CheckFuncs: []bubbleCheck{Is(BubbleSubscription{})},
			Builder: func(newAction *BubbleSubscription, bubble *Bubble) error {
				sub := bubble.Info.(BubbleSubscription)
				newAction.Success = sub.Success
				return nil
			},
		},
	},
}
View Source
var TgAuctionV1InitialBidStraw = Straw[AuctionBidBubble]{
	CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.TelemintDeployMsgOp)},
	Builder: func(newAction *AuctionBidBubble, bubble *Bubble) error {
		tx := bubble.Info.(BubbleTx)
		body := tx.decodedBody.Value.(abi.TelemintDeployMsgBody)
		newAction.Type = DnsTgAuction
		newAction.Amount = tx.inputAmount
		newAction.Bidder = tx.inputFrom.Address
		newAction.Username = string(body.Msg.Username)
		return nil
	},
	SingleChild: &Straw[AuctionBidBubble]{
		CheckFuncs: []bubbleCheck{IsTx, HasOpcode(0x299a3e15)},
		Builder: func(newAction *AuctionBidBubble, bubble *Bubble) error {
			tx := bubble.Info.(BubbleTx)
			newAction.Success = tx.success

			newAction.Auction = tx.account.Address
			newAction.NftAddress = &tx.account.Address
			if tx.additionalInfo.EmulatedTeleitemNFT != nil {
				newAction.Nft = &core.NftItem{
					Address:           tx.account.Address,
					Index:             tx.additionalInfo.EmulatedTeleitemNFT.Index,
					CollectionAddress: tx.additionalInfo.EmulatedTeleitemNFT.CollectionAddress,
					Verified:          tx.additionalInfo.EmulatedTeleitemNFT.Verified,
					Transferable:      false,
					Metadata: map[string]interface{}{
						"name":  newAction.Username,
						"image": fmt.Sprintf("https://nft.fragment.com/username/%v.webp", newAction.Username),
					},
				}
			}
			return nil
		},
	},
}
View Source
var ToncoDepositLiquidityBothStraw = Straw[BubbleLiquidityDeposit]{
	CheckFuncs: []bubbleCheck{},
	Children: []Straw[BubbleLiquidityDeposit]{
		{
			CheckFuncs: []bubbleCheck{Is(BubbleLiquidityDeposit{})},
			Builder: func(newAction *BubbleLiquidityDeposit, bubble *Bubble) error {
				tx := bubble.Info.(BubbleLiquidityDeposit)
				newAction.From = tx.From
				newAction.Protocol = tx.Protocol
				newAction.Tokens = append(newAction.Tokens, tx.Tokens...)
				newAction.Success = tx.Success
				return nil
			},
		},
		{
			CheckFuncs: []bubbleCheck{IsJettonTransfer, JettonRecipientAccount(references.ToncoRouter)},
			Builder: func(newAction *BubbleLiquidityDeposit, bubble *Bubble) error {
				jettonTx := bubble.Info.(BubbleJettonTransfer)
				if jettonTx.isWrappedTon {
					newAction.Tokens = append(newAction.Tokens, core.VaultDepositInfo{
						Price: core.Price{
							Currency: core.Currency{
								Type: core.CurrencyTON,
							},
							Amount: big.Int(jettonTx.amount),
						},
						Vault: jettonTx.recipient.Address,
					})
				} else {
					newAction.Tokens = append(newAction.Tokens, core.VaultDepositInfo{
						Price: core.Price{
							Currency: core.Currency{
								Type:   core.CurrencyJetton,
								Jetton: &jettonTx.master,
							},
							Amount: big.Int(jettonTx.amount),
						},
						Vault: jettonTx.recipientWallet,
					})
				}
				return nil
			},
			SingleChild: &Straw[BubbleLiquidityDeposit]{
				CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.Poolv3FundAccountMsgOp), HasInterface(abi.ToncoPool)},
				Builder: func(newAction *BubbleLiquidityDeposit, bubble *Bubble) error {
					return nil
				},
				SingleChild: &Straw[BubbleLiquidityDeposit]{
					CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.Accountv3AddLiquidityMsgOp)},
					Builder: func(newAction *BubbleLiquidityDeposit, bubble *Bubble) error {
						return nil
					},
				},
			},
		},
	},
}
View Source
var ToncoDepositLiquiditySingleStraw = Straw[BubbleLiquidityDeposit]{
	CheckFuncs: []bubbleCheck{IsJettonTransfer, JettonRecipientAccount(references.ToncoRouter)},
	Builder: func(newAction *BubbleLiquidityDeposit, bubble *Bubble) error {
		jettonTx := bubble.Info.(BubbleJettonTransfer)
		newAction.Protocol = core.Protocol{
			Name:  string(references.Tonco),
			Image: &references.ToncoImage,
		}
		newAction.From = jettonTx.sender.Address
		if jettonTx.isWrappedTon {
			newAction.Tokens = append(newAction.Tokens, core.VaultDepositInfo{
				Price: core.Price{
					Currency: core.Currency{
						Type: core.CurrencyTON,
					},
					Amount: big.Int(jettonTx.amount),
				},
				Vault: jettonTx.recipient.Address,
			})
		} else {
			newAction.Tokens = append(newAction.Tokens, core.VaultDepositInfo{
				Price: core.Price{
					Currency: core.Currency{
						Type:   core.CurrencyJetton,
						Jetton: &jettonTx.master,
					},
					Amount: big.Int(jettonTx.amount),
				},
				Vault: jettonTx.recipientWallet,
			})
		}
		return nil
	},
	SingleChild: &Straw[BubbleLiquidityDeposit]{
		CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.Poolv3FundAccountMsgOp), HasInterface(abi.ToncoPool)},
		Builder: func(newAction *BubbleLiquidityDeposit, bubble *Bubble) error {
			return nil
		},
		SingleChild: &Straw[BubbleLiquidityDeposit]{
			CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.Accountv3AddLiquidityMsgOp)},
			Builder: func(newAction *BubbleLiquidityDeposit, bubble *Bubble) error {
				return nil
			},
			SingleChild: &Straw[BubbleLiquidityDeposit]{
				CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.Poolv3MintMsgOp), HasInterface(abi.ToncoPool)},
				Builder: func(newAction *BubbleLiquidityDeposit, bubble *Bubble) error {
					tx := bubble.Info.(BubbleTx)
					newAction.Success = tx.success
					return nil
				},
				Children: []Straw[BubbleLiquidityDeposit]{
					{
						CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.PositionnftV3PositionInitMsgOp), HasInterface(abi.NftItem)},
						Builder: func(newAction *BubbleLiquidityDeposit, bubble *Bubble) error {
							tx := bubble.Info.(BubbleTx)
							newAction.Success = newAction.Success && tx.success
							return nil
						},
						SingleChild: &Straw[BubbleLiquidityDeposit]{
							Optional:   true,
							CheckFuncs: []bubbleCheck{Is(BubbleContractDeploy{})},
						},
					},
					{
						Optional:   true,
						CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.ExcessMsgOp)},
						Builder: func(newAction *BubbleLiquidityDeposit, bubble *Bubble) error {
							tx := bubble.Info.(BubbleTx)
							newAction.Success = newAction.Success && tx.success
							return nil
						},
					},
				},
			},
		},
	},
}
View Source
var ToncoDepositLiquidityWithRefundStraw = Straw[BubbleLiquidityDeposit]{
	CheckFuncs: []bubbleCheck{Is(BubbleLiquidityDeposit{})},
	Builder: func(newAction *BubbleLiquidityDeposit, bubble *Bubble) error {
		tx := bubble.Info.(BubbleLiquidityDeposit)
		newAction.From = tx.From
		newAction.Tokens = tx.Tokens
		newAction.Protocol = tx.Protocol
		newAction.Success = tx.Success
		return nil
	},
	SingleChild: &Straw[BubbleLiquidityDeposit]{
		CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.PayToMsgOp), HasInterface(abi.ToncoRouter)},
		Builder: func(newAction *BubbleLiquidityDeposit, bubble *Bubble) error {
			tx := bubble.Info.(BubbleTx)
			newAction.Success = newAction.Success && tx.success
			return nil
		},
		Children: []Straw[BubbleLiquidityDeposit]{
			{
				CheckFuncs: []bubbleCheck{IsJettonTransfer},
				Builder: func(newAction *BubbleLiquidityDeposit, bubble *Bubble) error {
					tx := bubble.Info.(BubbleJettonTransfer)
					amount := big.Int(tx.amount)
					for i, token := range newAction.Tokens {
						if (token.Price.Currency.Type == core.CurrencyTON && !tx.isWrappedTon) ||
							(token.Price.Currency.Type != core.CurrencyTON && *token.Price.Currency.Jetton != tx.master) {
							continue
						}

						newAction.Tokens[i].Price.Amount = *new(big.Int).Sub(&newAction.Tokens[i].Price.Amount, &amount)
					}
					newAction.Success = newAction.Success && tx.success
					return nil
				},
			},
			{
				CheckFuncs: []bubbleCheck{IsJettonTransfer},
				Builder: func(newAction *BubbleLiquidityDeposit, bubble *Bubble) error {
					tx := bubble.Info.(BubbleJettonTransfer)
					amount := big.Int(tx.amount)
					for i, token := range newAction.Tokens {
						if (token.Price.Currency.Type == core.CurrencyTON && !tx.isWrappedTon) ||
							(token.Price.Currency.Type != core.CurrencyTON && *token.Price.Currency.Jetton != tx.master) {
							continue
						}

						newAction.Tokens[i].Price.Amount = *new(big.Int).Sub(&newAction.Tokens[i].Price.Amount, &amount)
					}
					newAction.Success = newAction.Success && tx.success
					return nil
				},
			},
		},
	},
}
View Source
var ToncoSwapStraw = Straw[BubbleJettonSwap]{
	CheckFuncs: []bubbleCheck{IsJettonTransfer},
	Builder: func(newAction *BubbleJettonSwap, bubble *Bubble) error {
		tx := bubble.Info.(BubbleJettonTransfer)
		newAction.Dex = references.Tonco
		newAction.UserWallet = tx.sender.Address
		newAction.Router = tx.recipient.Address
		newAction.In.IsTon = tx.isWrappedTon
		newAction.In.Amount = big.Int(tx.amount)
		if !newAction.In.IsTon {
			newAction.In.JettonWallet = tx.senderWallet
			newAction.In.JettonMaster = tx.master
		}
		return nil
	},
	SingleChild: &Straw[BubbleJettonSwap]{
		CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.Poolv3SwapMsgOp), HasInterface(abi.ToncoPool)},
		Builder: func(newAction *BubbleJettonSwap, bubble *Bubble) error {
			tx := bubble.Info.(BubbleTx)
			body, ok := tx.decodedBody.Value.(abi.Poolv3SwapMsgBody)
			if !ok {
				return fmt.Errorf("not a tonco pool_v3_swap_msg_body")
			}
			if body.PayloadsCell.TargetAddress != newAction.UserWallet.ToMsgAddress() {
				return fmt.Errorf("not a user wallet")
			}
			return nil
		},
		SingleChild: &Straw[BubbleJettonSwap]{
			CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.PayToMsgOp), HasInterface(abi.ToncoRouter), func(bubble *Bubble) bool {
				tx := bubble.Info.(BubbleTx)
				body, ok := tx.decodedBody.Value.(abi.PayToMsgBody)
				if !ok {
					return false
				}
				if body.PayTo.SumType != "PayToCode200" && body.PayTo.SumType != "PayToCode230" {
					return false
				}
				return true
			}},
			Builder: func(newAction *BubbleJettonSwap, bubble *Bubble) error {
				tx := bubble.Info.(BubbleTx)

				newAction.Success = tx.decodedBody.Value.(abi.PayToMsgBody).PayTo.SumType == "PayToCode200"
				return nil
			},
			SingleChild: &Straw[BubbleJettonSwap]{
				CheckFuncs: []bubbleCheck{IsJettonTransfer},
				Builder: func(newAction *BubbleJettonSwap, bubble *Bubble) error {
					tx := bubble.Info.(BubbleJettonTransfer)
					newAction.Out.IsTon = tx.isWrappedTon
					newAction.Out.Amount = big.Int(tx.amount)
					if !newAction.Out.IsTon {
						newAction.Out.JettonWallet = tx.recipientWallet
						newAction.Out.JettonMaster = tx.master
					}
					return nil
				},
			},
		},
	},
}
View Source
var UnSubscriptionByBeneficiaryOrExpiredStraw = Straw[BubbleUnSubscription]{
	CheckFuncs: []bubbleCheck{
		IsTx,
		Or(IsExternal, HasOperation(abi.WalletPluginDestructMsgOp)),
		Or(HasInterface(abi.SubscriptionV1), HasInterface(abi.SubscriptionV2)),
	},
	Builder: func(newAction *BubbleUnSubscription, bubble *Bubble) error {
		tx := bubble.Info.(BubbleTx)
		newAction.Subscription = tx.account.Address
		newAction.Success = tx.success
		if tx.additionalInfo != nil && tx.additionalInfo.SubscriptionInfo != nil {
			newAction.Subscriber = tx.additionalInfo.SubscriptionInfo.Wallet
			newAction.Admin = tx.additionalInfo.SubscriptionInfo.Admin
			newAction.WithdrawTo = tx.additionalInfo.SubscriptionInfo.WithdrawTo
		}
		return nil
	},
	Children: []Straw[BubbleUnSubscription]{
		{
			CheckFuncs: []bubbleCheck{IsTx},
			Builder: func(newAction *BubbleUnSubscription, bubble *Bubble) error {
				newAction.Success = newAction.Success && bubble.Info.(BubbleTx).success
				return nil
			},
			SingleChild: &Straw[BubbleUnSubscription]{
				CheckFuncs: []bubbleCheck{Is(BubbleRemoveExtension{})},
				Builder: func(newAction *BubbleUnSubscription, bubble *Bubble) error {
					removeExtTx := bubble.Info.(BubbleRemoveExtension)
					if removeExtTx.Extension != newAction.Subscription {
						newAction.Success = false
					}
					newAction.Success = newAction.Success && removeExtTx.Success
					return nil
				},
			},
		},
	},
}
View Source
var UnSubscriptionBySubscriberStraw = Straw[BubbleUnSubscription]{
	CheckFuncs: []bubbleCheck{IsTx},
	Builder: func(newAction *BubbleUnSubscription, bubble *Bubble) error {
		newAction.Success = true
		return nil
	},
	Children: []Straw[BubbleUnSubscription]{
		{
			CheckFuncs: []bubbleCheck{
				IsTx,
				HasOperation(abi.WalletPluginDestructMsgOp),
				Or(HasInterface(abi.SubscriptionV1), HasInterface(abi.SubscriptionV2)),
			},
			Builder: func(newAction *BubbleUnSubscription, bubble *Bubble) error {
				tx := bubble.Info.(BubbleTx)
				newAction.Subscription = tx.account.Address
				if tx.additionalInfo != nil && tx.additionalInfo.SubscriptionInfo != nil {
					newAction.Subscriber = tx.additionalInfo.SubscriptionInfo.Wallet
					newAction.Admin = tx.additionalInfo.SubscriptionInfo.Admin
					newAction.WithdrawTo = tx.additionalInfo.SubscriptionInfo.WithdrawTo
				}
				newAction.Success = tx.success
				return nil
			},
		},
		{

			CheckFuncs: []bubbleCheck{Is(BubbleRemoveExtension{})},
			Builder: func(newAction *BubbleUnSubscription, bubble *Bubble) error {
				removeExtTx := bubble.Info.(BubbleRemoveExtension)
				if removeExtTx.Extension != newAction.Subscription {
					newAction.Success = false
				}
				newAction.Success = newAction.Success && removeExtTx.Success
				return nil
			},
		},
	},
}
View Source
var WithdrawEthenaStakeRequestStraw = Straw[BubbleWithdrawTokenStakeRequest]{
	CheckFuncs: []bubbleCheck{IsJettonTransfer, JettonRecipientAccount(references.EthenaPool)},
	Builder: func(newAction *BubbleWithdrawTokenStakeRequest, bubble *Bubble) error {
		tx := bubble.Info.(BubbleJettonTransfer)
		newAction.Staker = tx.sender.Address
		amount := big.Int(tx.amount)
		newAction.Protocol = core.Protocol{
			Name:  references.Ethena,
			Image: &references.EthenaImage,
		}
		newAction.StakeMeta = &core.Price{
			Currency: core.Currency{
				Type:   core.CurrencyJetton,
				Jetton: &tx.master,
			},
			Amount: amount,
		}
		return nil
	},
	SingleChild: &Straw[BubbleWithdrawTokenStakeRequest]{
		CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.JettonMintMsgOp)},
		SingleChild: &Straw[BubbleWithdrawTokenStakeRequest]{
			CheckFuncs: []bubbleCheck{IsTx},
			Builder: func(newAction *BubbleWithdrawTokenStakeRequest, bubble *Bubble) error {
				tx := bubble.Info.(BubbleTx)
				newAction.Success = tx.success
				return nil
			},
		},
	},
}
View Source
var WithdrawLiquidStake = Straw[BubbleWithdrawStake]{
	CheckFuncs: []bubbleCheck{Is(BubbleWithdrawStakeRequest{})},
	Builder: func(newAction *BubbleWithdrawStake, bubble *Bubble) error {
		request := bubble.Info.(BubbleWithdrawStakeRequest)
		newAction.Amount -= request.attachedAmount
		newAction.Pool = request.Pool
		newAction.Staker = request.Staker
		newAction.Implementation = request.Implementation
		return nil
	},
	SingleChild: &Straw[BubbleWithdrawStake]{
		CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.TonstakePoolWithdrawalMsgOp)},
		Builder: func(newAction *BubbleWithdrawStake, bubble *Bubble) error {
			newAction.Amount += bubble.Info.(BubbleTx).inputAmount
			return nil
		},
	},
}
View Source
var WithdrawStakeImmediatelyStraw = Straw[BubbleWithdrawStake]{
	CheckFuncs: []bubbleCheck{Is(BubbleWithdrawStakeRequest{})},
	Builder: func(newAction *BubbleWithdrawStake, bubble *Bubble) error {
		req := bubble.Info.(BubbleWithdrawStakeRequest)
		newAction.Pool = req.Pool
		newAction.Staker = req.Staker
		newAction.Amount = -req.attachedAmount
		newAction.Implementation = req.Implementation
		return nil
	},
	SingleChild: &Straw[BubbleWithdrawStake]{
		CheckFuncs: []bubbleCheck{IsTx, AmountInterval(int64(ton.OneTON), 1<<63-1)},
		Builder: func(newAction *BubbleWithdrawStake, bubble *Bubble) error {
			newAction.Amount += bubble.Info.(BubbleTx).inputAmount
			return nil
		},
	},
}
View Source
var WithdrawTFStakeRequestStraw = Straw[BubbleWithdrawStakeRequest]{
	CheckFuncs: []bubbleCheck{IsTx, HasInterface(abi.TvPool), HasTextComment("w")},
	Builder: func(newAction *BubbleWithdrawStakeRequest, bubble *Bubble) error {
		tx := bubble.Info.(BubbleTx)
		newAction.Pool = tx.account.Address
		newAction.Staker = tx.inputFrom.Address
		newAction.Success = tx.success
		newAction.attachedAmount = tx.inputAmount
		newAction.Implementation = core.StakingImplementationTF
		return nil
	},
	Children: []Straw[BubbleWithdrawStakeRequest]{
		{
			Optional:   true,
			CheckFuncs: []bubbleCheck{IsTx, AmountInterval(0, int64(ton.OneTON))},
		},
	},
}
View Source
var WtonMintStraw = Straw[BubbleJettonMint]{
	CheckFuncs: []bubbleCheck{IsTx, HasOpcode(0x77a33521)},
	Builder: func(newAction *BubbleJettonMint, bubble *Bubble) error {
		newAction.recipient = bubble.Info.(BubbleTx).account
		return nil
	},
	Children: []Straw[BubbleJettonMint]{
		{
			CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.JettonInternalTransferMsgOp)},
			Builder: func(newAction *BubbleJettonMint, bubble *Bubble) error {
				tx := bubble.Info.(BubbleTx)
				body := tx.decodedBody.Value.(abi.JettonInternalTransferMsgBody)
				newAction.amount = body.Amount
				if tx.additionalInfo != nil {
					if master, ok := tx.additionalInfo.JettonMaster(tx.account.Address); ok {
						newAction.master = master
					}
				}
				newAction.recipientWallet = tx.account.Address
				newAction.success = tx.success
				return nil
			},
			Children: []Straw[BubbleJettonMint]{
				{
					CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.JettonNotifyMsgOp)},
					Optional:   true,
				},
				{
					CheckFuncs: []bubbleCheck{Is(BubbleContractDeploy{})},
					Optional:   true,
				},
			},
		},
		{
			CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.ExcessMsgOp)},
			Optional:   true,
		},
	},
}

Functions

func AmountInterval added in v1.1.0

func AmountInterval(min, max int64) bubbleCheck

func CollectActionsAndValueFlow

func CollectActionsAndValueFlow(bubble *Bubble, forAccount *tongo.AccountID) ([]Action, *ValueFlow)

func HasEmptyBody added in v1.2.0

func HasEmptyBody(b *Bubble) bool

func HasInterface added in v1.1.0

func HasInterface(iface abi.ContractInterface) bubbleCheck

func HasOpcode added in v1.1.0

func HasOpcode(op uint32) bubbleCheck

func HasOperation added in v1.1.0

func HasOperation(name abi.MsgOpName) bubbleCheck

func HasTextComment added in v1.1.0

func HasTextComment(comment string) bubbleCheck

func Is added in v1.1.0

func Is(t actioner) bubbleCheck

func IsAccount added in v1.1.0

func IsAccount(id tongo.AccountID) bubbleCheck

func IsBounced added in v1.1.0

func IsBounced(bubble *Bubble) bool

func IsExternal added in v1.3.1

func IsExternal(bubble *Bubble) bool

func IsJettonReceiver added in v1.1.0

func IsJettonReceiver(iface abi.ContractInterface) bubbleCheck

func IsJettonTransfer added in v1.1.0

func IsJettonTransfer(b *Bubble) bool

func IsNftTransfer added in v1.2.0

func IsNftTransfer(b *Bubble) bool

func IsTx added in v1.1.0

func IsTx(b *Bubble) bool

func JettonRecipientAccount added in v1.3.3

func JettonRecipientAccount(id tongo.AccountID) bubbleCheck

func JettonTransferOpCode added in v1.1.0

func JettonTransferOpCode(opCode uint32) bubbleCheck

func JettonTransferOperation added in v1.1.0

func JettonTransferOperation(op abi.JettonOpName) bubbleCheck

func MergeAllBubbles

func MergeAllBubbles(bubble *Bubble, straws []Merger)

func Or added in v1.1.0

func Or(check1, check2 bubbleCheck) bubbleCheck

Types

type Account

type Account struct {
	Address    tongo.AccountID
	Interfaces []abi.ContractInterface
}

func (*Account) Addr

func (a *Account) Addr() *tongo.AccountID

func (Account) Is

type AccountValueFlow

type AccountValueFlow struct {
	Ton     int64
	Fees    int64
	Jettons map[tongo.AccountID]big.Int
	NFTs    [2]int // 0 - added, 1 - removed
}

AccountValueFlow contains a change of assets for a particular account.

type Action

type Action struct {
	TonTransfer               *TonTransferAction               `json:",omitempty"`
	ExtraCurrencyTransfer     *ExtraCurrencyTransferAction     `json:",omitempty"`
	SmartContractExec         *SmartContractAction             `json:",omitempty"`
	GasRelay                  *GasRelayAction                  `json:",omitempty"`
	NftItemTransfer           *NftTransferAction               `json:",omitempty"`
	NftPurchase               *NftPurchaseAction               `json:",omitempty"`
	JettonTransfer            *JettonTransferAction            `json:",omitempty"`
	JettonMint                *JettonMintAction                `json:",omitempty"`
	JettonBurn                *JettonBurnAction                `json:",omitempty"`
	ContractDeploy            *ContractDeployAction            `json:",omitempty"`
	Subscribe                 *SubscribeAction                 `json:",omitempty"`
	UnSubscribe               *UnSubscribeAction               `json:",omitempty"`
	AuctionBid                *AuctionBidAction                `json:",omitempty"`
	ElectionsDepositStake     *ElectionsDepositStakeAction     `json:",omitempty"`
	ElectionsRecoverStake     *ElectionsRecoverStakeAction     `json:",omitempty"`
	DepositStake              *DepositStakeAction              `json:",omitempty"`
	WithdrawStake             *WithdrawStakeAction             `json:",omitempty"`
	WithdrawStakeRequest      *WithdrawStakeRequestAction      `json:",omitempty"`
	DepositTokenStake         *DepositTokenStakeAction         `json:",omitempty"`
	WithdrawTokenStakeRequest *WithdrawTokenStakeRequestAction `json:",omitempty"`
	JettonSwap                *JettonSwapAction                `json:",omitempty"`
	DnsRenew                  *DnsRenewAction                  `json:",omitempty"`
	Purchase                  *PurchaseAction                  `json:",omitempty"`
	AddExtension              *AddExtensionAction              `json:",omitempty"`
	RemoveExtension           *RemoveExtensionAction           `json:",omitempty"`
	SetSignatureAllowed       *SetSignatureAllowedAction       `json:",omitempty"`
	LiquidityDepositAction    *LiquidityDepositAction          `json:",omitempty"`
	Success                   bool
	Type                      ActionType
	Error                     *string `json:",omitempty"`
	BaseTransactions          []ton.Bits256
}

func (Action) ContributeToExtra

func (a Action) ContributeToExtra(account tongo.AccountID) int64

func (Action) IsSubject added in v1.0.0

func (a Action) IsSubject(account tongo.AccountID) bool

func (Action) String

func (a Action) String() string

type ActionType

type ActionType string
const (
	TonTransfer               ActionType = "TonTransfer"
	ExtraCurrencyTransfer     ActionType = "ExtraCurrencyTransfer"
	SmartContractExec         ActionType = "SmartContractExec"
	GasRelay                  ActionType = "GasRelay"
	NftItemTransfer           ActionType = "NftItemTransfer"
	NftPurchase               ActionType = "NftPurchase"
	JettonTransfer            ActionType = "JettonTransfer"
	JettonMint                ActionType = "JettonMint"
	JettonBurn                ActionType = "JettonBurn"
	ContractDeploy            ActionType = "ContractDeploy"
	Subscribe                 ActionType = "Subscribe"
	UnSubscribe               ActionType = "UnSubscribe"
	ElectionsDepositStake     ActionType = "ElectionsDepositStake"
	ElectionsRecoverStake     ActionType = "ElectionsRecoverStake"
	DepositStake              ActionType = "DepositStake"
	WithdrawStake             ActionType = "WithdrawStake"
	WithdrawStakeRequest      ActionType = "WithdrawStakeRequest"
	DepositTokenStake         ActionType = "DepositTokenStake"
	WithdrawTokenStakeRequest ActionType = "WithdrawTokenStakeRequest"
	JettonSwap                ActionType = "JettonSwap"
	AuctionBid                ActionType = "AuctionBid"
	DomainRenew               ActionType = "DomainRenew"
	Purchase                  ActionType = "Purchase"
	AddExtension              ActionType = "AddExtension"
	RemoveExtension           ActionType = "RemoveExtension"
	SetSignatureAllowed       ActionType = "SetSignatureAllowed"
	LiquidityDeposit          ActionType = "LiquidityDeposit"
	Unknown                   ActionType = "Unknown"
)

type ActionsList

type ActionsList struct {
	Actions   []Action
	ValueFlow *ValueFlow
}

func EnrichWithIntentions added in v1.3.0

func EnrichWithIntentions(trace *core.Trace, actions *ActionsList) *ActionsList

func FindActions

func FindActions(ctx context.Context, trace *core.Trace, opts ...Option) (*ActionsList, error)

FindActions finds known action patterns in the given trace and returns a list of actions.

func (*ActionsList) Extra

func (l *ActionsList) Extra(account tongo.AccountID) int64

type AddExtensionAction added in v1.3.1

type AddExtensionAction struct {
	Wallet    tongo.AccountID
	Extension tongo.AccountID
}

func (*AddExtensionAction) SubjectAccounts added in v1.3.1

func (a *AddExtensionAction) SubjectAccounts() []tongo.AccountID

type AuctionBidAction

type AuctionBidAction struct {
	Type       NftAuctionType
	Amount     core.Price
	Nft        *core.NftItem
	NftAddress *tongo.AccountID
	Bidder     tongo.AccountID
	Auction    tongo.AccountID
}

func (*AuctionBidAction) SubjectAccounts added in v1.0.0

func (a *AuctionBidAction) SubjectAccounts() []tongo.AccountID

type AuctionBidBubble added in v1.1.0

type AuctionBidBubble struct {
	Type           NftAuctionType
	Amount         int64
	Nft            *core.NftItem
	NftAddress     *tongo.AccountID
	Bidder         tongo.AccountID
	Auction        tongo.AccountID
	PreviousBidder *tongo.AccountID //maybe don't requered
	Username       string
	Success        bool
}

func (AuctionBidBubble) ToAction added in v1.1.0

func (a AuctionBidBubble) ToAction() *Action

type Bubble

type Bubble struct {
	Info        actioner
	Accounts    []tongo.AccountID
	Children    []*Bubble
	ValueFlow   *ValueFlow
	Transaction []ton.Bits256
}

Bubble represents a transaction in the beginning. But we can merge neighbour bubbles together if we find a known action pattern like an NFT Transfer or a SmartContractExecution in a trace.

func ProcessChildren

func ProcessChildren(children []*Bubble, fns ...func(child *Bubble) *Merge) []*Bubble

func (Bubble) String

func (b Bubble) String() string

type BubbleAddExtension added in v1.3.1

type BubbleAddExtension struct {
	Wallet    tongo.AccountID
	Extension tongo.AccountID
	Success   bool
}

func (BubbleAddExtension) ToAction added in v1.3.1

func (b BubbleAddExtension) ToAction() *Action

type BubbleContractDeploy added in v1.0.0

type BubbleContractDeploy struct {
	Contract tongo.AccountID
	// AccountInitInterfaces is a list of interfaces implemented by the stateInit.Code.
	// This list can differ from the current list of interfaces.
	// TODO: AccountInitInterfaces is an empty list in opentonapi, fix.
	AccountInitInterfaces []abi.ContractInterface
	Success               bool
}

func (BubbleContractDeploy) ToAction added in v1.0.0

func (b BubbleContractDeploy) ToAction() *Action

type BubbleDepositStake added in v0.1.1

type BubbleDepositStake struct {
	Staker         tongo.AccountID
	Amount         int64
	Success        bool
	Pool           tongo.AccountID
	Implementation core.StakingImplementation
}

func (BubbleDepositStake) ToAction added in v0.1.1

func (ds BubbleDepositStake) ToAction() *Action

type BubbleDepositTokenStake added in v1.3.3

type BubbleDepositTokenStake struct {
	Staker    tongo.AccountID
	Success   bool
	Protocol  core.Protocol
	StakeMeta *core.Price
}

func (BubbleDepositTokenStake) ToAction added in v1.3.3

func (dts BubbleDepositTokenStake) ToAction() *Action

type BubbleDnsItemRenew added in v1.2.0

type BubbleDnsItemRenew struct {
	DnsRenewAction
	Success bool
}

func (BubbleDnsItemRenew) ToAction added in v1.2.0

func (b BubbleDnsItemRenew) ToAction() *Action

type BubbleElectionsDepositStake added in v1.1.0

type BubbleElectionsDepositStake struct {
	Staker  tongo.AccountID
	Amount  int64
	Success bool
}

func (BubbleElectionsDepositStake) ToAction added in v1.1.0

func (ds BubbleElectionsDepositStake) ToAction() *Action

type BubbleElectionsRecoverStake added in v1.1.0

type BubbleElectionsRecoverStake struct {
	Staker  tongo.AccountID
	Amount  int64
	Success bool
}

func (BubbleElectionsRecoverStake) ToAction added in v1.1.0

func (b BubbleElectionsRecoverStake) ToAction() *Action

type BubbleInvoicePayment added in v1.3.0

type BubbleInvoicePayment struct {
	Sender, Recipient tongo.AccountID
	InvoiceID         uuid.UUID
	Price             core.Price
	Success           bool
}

func (BubbleInvoicePayment) ToAction added in v1.3.0

func (b BubbleInvoicePayment) ToAction() (action *Action)

type BubbleJettonBurn added in v1.1.0

type BubbleJettonBurn struct {
	// contains filtered or unexported fields
}

func (BubbleJettonBurn) ToAction added in v1.1.0

func (b BubbleJettonBurn) ToAction() (action *Action)

type BubbleJettonMint added in v1.1.0

type BubbleJettonMint struct {
	// contains filtered or unexported fields
}

func (BubbleJettonMint) ToAction added in v1.1.0

func (b BubbleJettonMint) ToAction() (action *Action)

type BubbleJettonSwap added in v1.1.0

type BubbleJettonSwap struct {
	Dex        references.Dex
	UserWallet tongo.AccountID
	Router     tongo.AccountID
	Out        assetTransfer
	In         assetTransfer
	Success    bool
}

BubbleJettonSwap contains information about a jetton swap operation at a dex.

func (BubbleJettonSwap) ToAction added in v1.1.0

func (b BubbleJettonSwap) ToAction() *Action

type BubbleJettonTransfer

type BubbleJettonTransfer struct {
	// contains filtered or unexported fields
}

func (BubbleJettonTransfer) ToAction

func (b BubbleJettonTransfer) ToAction() (action *Action)

type BubbleLiquidityDeposit added in v1.3.6

type BubbleLiquidityDeposit struct {
	Protocol core.Protocol
	From     tongo.AccountID
	Tokens   []core.VaultDepositInfo
	Success  bool
}

func (BubbleLiquidityDeposit) ToAction added in v1.3.6

func (b BubbleLiquidityDeposit) ToAction() *Action

type BubbleNftPurchase added in v0.1.0

type BubbleNftPurchase struct {
	Success     bool
	Buyer       tongo.AccountID
	Seller      tongo.AccountID
	Nft         tongo.AccountID
	AuctionType NftAuctionType
	Price       int64
}

func (BubbleNftPurchase) ToAction added in v0.1.0

func (b BubbleNftPurchase) ToAction() *Action

type BubbleNftTransfer

type BubbleNftTransfer struct {
	// contains filtered or unexported fields
}

func (BubbleNftTransfer) ToAction

func (b BubbleNftTransfer) ToAction() (action *Action)

type BubbleRemoveExtension added in v1.3.1

type BubbleRemoveExtension struct {
	Wallet    tongo.AccountID
	Extension tongo.AccountID
	Success   bool
}

func (BubbleRemoveExtension) ToAction added in v1.3.1

func (b BubbleRemoveExtension) ToAction() *Action

type BubbleSetSignatureAllowed added in v1.3.1

type BubbleSetSignatureAllowed struct {
	Wallet           tongo.AccountID
	SignatureAllowed bool
	Success          bool
}

func (BubbleSetSignatureAllowed) ToAction added in v1.3.1

func (b BubbleSetSignatureAllowed) ToAction() *Action

type BubbleSubscription

type BubbleSubscription struct {
	Subscription, Subscriber tongo.AccountID
	Admin, WithdrawTo        tongo.AccountID
	Amount                   int64
	Success                  bool
	First                    bool
}

func (BubbleSubscription) ToAction

func (b BubbleSubscription) ToAction() (action *Action)

type BubbleTx

type BubbleTx struct {
	// contains filtered or unexported fields
}

func (BubbleTx) String

func (b BubbleTx) String() string

func (BubbleTx) ToAction

func (b BubbleTx) ToAction() *Action

type BubbleUnSubscription added in v1.0.0

type BubbleUnSubscription struct {
	Subscription, Subscriber tongo.AccountID
	Admin, WithdrawTo        tongo.AccountID // beneficiary != withdraw_to address for subscription V2
	Success                  bool
}

func (BubbleUnSubscription) ToAction added in v1.0.0

func (b BubbleUnSubscription) ToAction() (action *Action)

type BubbleWithdrawStake added in v1.1.0

type BubbleWithdrawStake struct {
	Staker         tongo.AccountID
	Amount         int64
	Pool           tongo.AccountID
	Implementation core.StakingImplementation
}

func (BubbleWithdrawStake) ToAction added in v1.1.0

func (ds BubbleWithdrawStake) ToAction() *Action

type BubbleWithdrawStakeRequest added in v1.1.0

type BubbleWithdrawStakeRequest struct {
	Staker         tongo.AccountID
	Amount         *int64
	Success        bool
	Pool           tongo.AccountID
	Implementation core.StakingImplementation
	// contains filtered or unexported fields
}

func (BubbleWithdrawStakeRequest) ToAction added in v1.1.0

func (ds BubbleWithdrawStakeRequest) ToAction() *Action

type BubbleWithdrawTokenStakeRequest added in v1.3.3

type BubbleWithdrawTokenStakeRequest struct {
	Staker    tongo.AccountID
	Success   bool
	Protocol  core.Protocol
	StakeMeta *core.Price
}

func (BubbleWithdrawTokenStakeRequest) ToAction added in v1.3.3

func (wts BubbleWithdrawTokenStakeRequest) ToAction() *Action

type ContractDeployAction

type ContractDeployAction struct {
	Address    tongo.AccountID
	Interfaces []abi.ContractInterface
}

func (*ContractDeployAction) SubjectAccounts added in v1.0.0

func (a *ContractDeployAction) SubjectAccounts() []tongo.AccountID

type ContractDeployment added in v1.0.0

type ContractDeployment struct {
	// contains filtered or unexported fields
}

ContractDeployment holds information about initialization of a contract.

type DepositStakeAction added in v0.1.1

type DepositStakeAction struct {
	Staker         tongo.AccountID
	Amount         int64
	Pool           tongo.AccountID
	Implementation core.StakingImplementation
}

func (*DepositStakeAction) SubjectAccounts added in v1.0.0

func (a *DepositStakeAction) SubjectAccounts() []tongo.AccountID

type DepositTokenStakeAction added in v1.3.3

type DepositTokenStakeAction struct {
	Staker    tongo.AccountID
	Protocol  core.Protocol
	StakeMeta *core.Price
}

func (*DepositTokenStakeAction) SubjectAccounts added in v1.3.3

func (a *DepositTokenStakeAction) SubjectAccounts() []tongo.AccountID

type DnsRenewAction added in v1.2.0

type DnsRenewAction struct {
	Item    ton.AccountID
	Renewer ton.AccountID
}

func (DnsRenewAction) SubjectAccounts added in v1.2.0

func (a DnsRenewAction) SubjectAccounts() []ton.AccountID

type ElectionsDepositStakeAction added in v1.1.0

type ElectionsDepositStakeAction struct {
	Amount  int64
	Elector tongo.AccountID
	Staker  tongo.AccountID
}

func (*ElectionsDepositStakeAction) SubjectAccounts added in v1.1.0

func (a *ElectionsDepositStakeAction) SubjectAccounts() []tongo.AccountID

type ElectionsRecoverStakeAction added in v1.1.0

type ElectionsRecoverStakeAction struct {
	Amount  int64
	Elector tongo.AccountID
	Staker  tongo.AccountID
}

func (*ElectionsRecoverStakeAction) SubjectAccounts added in v1.1.0

func (a *ElectionsRecoverStakeAction) SubjectAccounts() []tongo.AccountID

type EncryptedComment added in v1.0.0

type EncryptedComment struct {
	EncryptionType string
	CipherText     []byte
}

type ExtraCurrencyTransferAction added in v1.3.0

type ExtraCurrencyTransferAction struct {
	CurrencyID       int32
	Amount           tlb.VarUInteger32
	Comment          *string
	EncryptedComment *EncryptedComment
	Recipient        tongo.AccountID
	Sender           tongo.AccountID
}

func (*ExtraCurrencyTransferAction) SubjectAccounts added in v1.3.0

func (a *ExtraCurrencyTransferAction) SubjectAccounts() []tongo.AccountID

type GasRelayAction added in v1.3.0

type GasRelayAction struct {
	Amount  int64
	Relayer ton.AccountID
	Target  ton.AccountID
}

func (GasRelayAction) SubjectAccounts added in v1.3.0

func (a GasRelayAction) SubjectAccounts() []ton.AccountID

type GasRelayBubble added in v1.3.0

type GasRelayBubble struct {
	Amount  int64
	Relayer ton.AccountID
	Target  ton.AccountID
}

func (GasRelayBubble) ToAction added in v1.3.0

func (b GasRelayBubble) ToAction() *Action

type JettonBurnAction added in v1.1.0

type JettonBurnAction struct {
	Jetton        tongo.AccountID
	Sender        tongo.AccountID
	SendersWallet tongo.AccountID
	Amount        tlb.VarUInteger16
}

func (*JettonBurnAction) SubjectAccounts added in v1.1.0

func (a *JettonBurnAction) SubjectAccounts() []tongo.AccountID

type JettonMintAction added in v1.1.0

type JettonMintAction struct {
	Jetton           tongo.AccountID
	Recipient        tongo.AccountID
	RecipientsWallet tongo.AccountID
	Amount           tlb.VarUInteger16
}

func (*JettonMintAction) SubjectAccounts added in v1.1.0

func (a *JettonMintAction) SubjectAccounts() []tongo.AccountID

type JettonSwapAction added in v1.1.0

type JettonSwapAction struct {
	Dex        references.Dex
	UserWallet tongo.AccountID
	Router     tongo.AccountID
	In         assetTransfer
	Out        assetTransfer
}

func (*JettonSwapAction) SubjectAccounts added in v1.1.0

func (a *JettonSwapAction) SubjectAccounts() []tongo.AccountID

type JettonTransferAction

type JettonTransferAction struct {
	Comment          *string
	EncryptedComment *EncryptedComment
	Jetton           tongo.AccountID
	Recipient        *tongo.AccountID
	Sender           *tongo.AccountID
	RecipientsWallet tongo.AccountID
	SendersWallet    tongo.AccountID
	Amount           tlb.VarUInteger16
	Refund           *Refund
	// contains filtered or unexported fields
}

func (*JettonTransferAction) PayloadFromABI added in v1.3.0

func (jta *JettonTransferAction) PayloadFromABI(payload abi.JettonPayload)

func (*JettonTransferAction) SubjectAccounts added in v1.0.0

func (a *JettonTransferAction) SubjectAccounts() []tongo.AccountID

type LiquidityDepositAction added in v1.3.6

type LiquidityDepositAction struct {
	Protocol core.Protocol
	From     tongo.AccountID
	Tokens   []core.VaultDepositInfo
}

func (*LiquidityDepositAction) SubjectAccounts added in v1.3.6

func (a *LiquidityDepositAction) SubjectAccounts() []tongo.AccountID

type Merge

type Merge struct {
	// contains filtered or unexported fields
}

type Merger added in v1.3.0

type Merger interface {
	// Merge extracts information from the given bubble and its children and modifies the bubble if needed.
	// If the bubble is modified this function return true.
	Merge(bubble *Bubble) (success bool)
}

type NftAuctionType added in v0.1.0

type NftAuctionType string

type NftPurchaseAction added in v0.1.0

type NftPurchaseAction struct {
	Nft         tongo.AccountID
	Buyer       tongo.AccountID
	Seller      tongo.AccountID
	AuctionType NftAuctionType
	Price       core.Price
}

func (*NftPurchaseAction) SubjectAccounts added in v1.0.0

func (a *NftPurchaseAction) SubjectAccounts() []tongo.AccountID

type NftTransferAction

type NftTransferAction struct {
	Comment          *string
	EncryptedComment *EncryptedComment
	Recipient        *tongo.AccountID
	Sender           *tongo.AccountID
	Nft              tongo.AccountID
	Refund           *Refund
}

func (*NftTransferAction) SubjectAccounts added in v1.0.0

func (a *NftTransferAction) SubjectAccounts() []tongo.AccountID

type Option

type Option func(*Options)

func ForAccount

func ForAccount(a tongo.AccountID) Option

func WithInformationSource added in v0.1.0

func WithInformationSource(source core.InformationSource) Option

func WithStraws

func WithStraws(straws []Merger) Option

WithStraws provides functions to find actions in a trace.

type Options

type Options struct {
	// contains filtered or unexported fields
}

type OutMessage added in v1.3.0

type OutMessage struct {
	// contains filtered or unexported fields
}

type PurchaseAction added in v1.3.0

type PurchaseAction struct {
	Source, Destination tongo.AccountID
	InvoiceID           uuid.UUID
	Price               core.Price
}

func (*PurchaseAction) SubjectAccounts added in v1.3.0

func (a *PurchaseAction) SubjectAccounts() []tongo.AccountID

type Refund

type Refund struct {
	Type   RefundType
	Origin string
}

type RefundType

type RefundType string

type RemoveExtensionAction added in v1.3.1

type RemoveExtensionAction struct {
	Wallet    tongo.AccountID
	Extension tongo.AccountID
}

func (*RemoveExtensionAction) SubjectAccounts added in v1.3.1

func (a *RemoveExtensionAction) SubjectAccounts() []tongo.AccountID

type SetSignatureAllowedAction added in v1.3.1

type SetSignatureAllowedAction struct {
	Wallet           tongo.AccountID
	SignatureAllowed bool
}

func (*SetSignatureAllowedAction) SubjectAccounts added in v1.3.1

func (a *SetSignatureAllowedAction) SubjectAccounts() []tongo.AccountID

type SmartContractAction

type SmartContractAction struct {
	TonAttached int64
	Executor    tongo.AccountID
	Contract    tongo.AccountID
	Operation   string
	Payload     string
}

func (*SmartContractAction) SubjectAccounts added in v1.0.0

func (a *SmartContractAction) SubjectAccounts() []tongo.AccountID

type Straw

type Straw[newBubbleT actioner] struct {
	CheckFuncs       []bubbleCheck
	Builder          func(newAction *newBubbleT, bubble *Bubble) error //uses to convert old bubble to new Bubble.Info
	ValueFlowUpdater func(newAction *newBubbleT, flow *ValueFlow)
	SingleChild      *Straw[newBubbleT]
	Children         []Straw[newBubbleT]
	Optional         bool
}

func Optional added in v1.1.0

func Optional[T actioner](s Straw[T]) Straw[T]

Optional returns copy of declarative straw but optional

func (Straw[newBubbleT]) Merge added in v1.1.0

func (s Straw[newBubbleT]) Merge(bubble *Bubble) bool

type SubscribeAction added in v1.3.1

type SubscribeAction struct {
	Subscription tongo.AccountID
	Subscriber   tongo.AccountID
	Admin        tongo.AccountID
	WithdrawTo   tongo.AccountID
	Price        core.Price
	First        bool
}

func (*SubscribeAction) SubjectAccounts added in v1.3.1

func (a *SubscribeAction) SubjectAccounts() []tongo.AccountID

type TonTransferAction

type TonTransferAction struct {
	Amount           int64
	Comment          *string
	EncryptedComment *EncryptedComment
	Recipient        tongo.AccountID
	Sender           tongo.AccountID
	Refund           *Refund
}

func (*TonTransferAction) SubjectAccounts added in v1.0.0

func (a *TonTransferAction) SubjectAccounts() []tongo.AccountID

type UnSubscribeAction added in v1.3.1

type UnSubscribeAction struct {
	Subscription tongo.AccountID
	Subscriber   tongo.AccountID
	Admin        tongo.AccountID
	WithdrawTo   tongo.AccountID
}

func (*UnSubscribeAction) SubjectAccounts added in v1.3.1

func (a *UnSubscribeAction) SubjectAccounts() []tongo.AccountID

type UniversalDedustStraw added in v1.3.0

type UniversalDedustStraw struct{}

func (UniversalDedustStraw) Merge added in v1.3.0

func (s UniversalDedustStraw) Merge(b *Bubble) bool

type ValueFlow

type ValueFlow struct {
	Accounts map[tongo.AccountID]*AccountValueFlow
}

ValueFlow contains a change of assets for each account involved in a trace.

func (*ValueFlow) AddFee

func (flow *ValueFlow) AddFee(accountID tongo.AccountID, amount int64)

func (*ValueFlow) AddJettons

func (flow *ValueFlow) AddJettons(accountID tongo.AccountID, jettonMaster tongo.AccountID, value big.Int)

func (*ValueFlow) AddTons

func (flow *ValueFlow) AddTons(accountID tongo.AccountID, amount int64)

func (*ValueFlow) Merge

func (flow *ValueFlow) Merge(other *ValueFlow)

func (*ValueFlow) SubJettons added in v1.2.0

func (flow *ValueFlow) SubJettons(accountID tongo.AccountID, jettonMaster tongo.AccountID, value big.Int)

type WithdrawStakeAction added in v1.1.0

type WithdrawStakeAction struct {
	Staker         tongo.AccountID
	Amount         int64
	Pool           tongo.AccountID
	Implementation core.StakingImplementation
}

func (*WithdrawStakeAction) SubjectAccounts added in v1.1.0

func (a *WithdrawStakeAction) SubjectAccounts() []tongo.AccountID

type WithdrawStakeRequestAction added in v1.1.0

type WithdrawStakeRequestAction struct {
	Staker         tongo.AccountID
	Amount         *int64
	Pool           tongo.AccountID
	Implementation core.StakingImplementation
}

func (*WithdrawStakeRequestAction) SubjectAccounts added in v1.1.0

func (a *WithdrawStakeRequestAction) SubjectAccounts() []tongo.AccountID

type WithdrawTokenStakeRequestAction added in v1.3.3

type WithdrawTokenStakeRequestAction struct {
	Staker    tongo.AccountID
	Protocol  core.Protocol
	StakeMeta *core.Price
}

func (*WithdrawTokenStakeRequestAction) SubjectAccounts added in v1.3.3

func (a *WithdrawTokenStakeRequestAction) SubjectAccounts() []tongo.AccountID

Jump to

Keyboard shortcuts

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