diff --git a/pkg/bath/actions.go b/pkg/bath/actions.go index ef99fc074..a98a4dadb 100644 --- a/pkg/bath/actions.go +++ b/pkg/bath/actions.go @@ -40,6 +40,7 @@ const ( DomainRenew ActionType = "DomainRenew" Purchase ActionType = "Purchase" Unknown ActionType = "Unknown" + AirdropClaim ActionType = "AirdropClaim" ) type ActionType string @@ -85,6 +86,7 @@ type ( JettonSwap *JettonSwapAction `json:",omitempty"` DnsRenew *DnsRenewAction `json:",omitempty"` Purchase *PurchaseAction `json:",omitempty"` + AirdropClaim *AirdropClaimAction `json:",omitempty"` Success bool Type ActionType Error *string `json:",omitempty"` @@ -226,6 +228,12 @@ type ( InvoiceID uuid.UUID Price core.Price } + + AirdropClaimAction struct { + Distributor tongo.AccountID + Recipient *tongo.AccountID + Claimed assetTransfer + } ) func (a Action) String() string { diff --git a/pkg/bath/airdrop.go b/pkg/bath/airdrop.go new file mode 100644 index 000000000..00933c545 --- /dev/null +++ b/pkg/bath/airdrop.go @@ -0,0 +1,66 @@ +package bath + +import ( + "github.com/tonkeeper/tongo" + "math/big" +) + +type BubbleAirdropClaim struct { + Distributor tongo.AccountID + Recipient *Account + RecipientJettonWallet tongo.AccountID + ClaimedAmount big.Int + JettonMaster tongo.AccountID + Success bool +} + +func (b BubbleAirdropClaim) ToAction() *Action { + return &Action{ + AirdropClaim: &AirdropClaimAction{ + Distributor: b.Distributor, + Recipient: b.Recipient.Addr(), + Claimed: assetTransfer{ + Amount: b.ClaimedAmount, + JettonMaster: b.JettonMaster, + JettonWallet: b.RecipientJettonWallet, + }, + }, + Type: AirdropClaim, + Success: b.Success, + } +} + +var AirdropClaimStraw = Straw[BubbleAirdropClaim]{ + CheckFuncs: []bubbleCheck{IsTx, HasOpcode(0x3a86f1a0)}, // todo use const from tongo.abi + Builder: func(newAction *BubbleAirdropClaim, bubble *Bubble) error { + tx := bubble.Info.(BubbleTx) + newAction.Recipient = tx.inputFrom + return nil + }, + Children: []Straw[BubbleAirdropClaim]{ + { + CheckFuncs: []bubbleCheck{Is(BubbleContractDeploy{})}, + }, + { + CheckFuncs: []bubbleCheck{ + IsTx, + }, + Builder: func(newAction *BubbleAirdropClaim, bubble *Bubble) error { + tx := bubble.Info.(BubbleTx) + newAction.Distributor = tx.account.Address + return nil + }, + SingleChild: &Straw[BubbleAirdropClaim]{ + CheckFuncs: []bubbleCheck{IsJettonTransfer}, + Builder: func(newAction *BubbleAirdropClaim, bubble *Bubble) error { + tx := bubble.Info.(BubbleJettonTransfer) + newAction.RecipientJettonWallet = tx.recipientWallet + newAction.JettonMaster = tx.master + newAction.ClaimedAmount = big.Int(tx.amount) + newAction.Success = tx.success && newAction.Recipient.Address == tx.recipient.Address + return nil + }, + }, + }, + }, +} diff --git a/pkg/bath/bath_test.go b/pkg/bath/bath_test.go index e4235c980..a7dedfa4e 100644 --- a/pkg/bath/bath_test.go +++ b/pkg/bath/bath_test.go @@ -176,6 +176,10 @@ func TestFindActions(t *testing.T) { tongo.MustParseBlockID("(0,2000000000000000,46145069)"), tongo.MustParseBlockID("(0,6000000000000000,46151880)"), tongo.MustParseBlockID("(0,2000000000000000,46145074)"), + // airdrop claim + tongo.MustParseBlockID("(0,e000000000000000,54137798)"), + tongo.MustParseBlockID("(0,2000000000000000,54479001)"), + tongo.MustParseBlockID("(0,a000000000000000,54118958)"), }), ) @@ -289,9 +293,9 @@ func TestFindActions(t *testing.T) { filenamePrefix: "stonfi-purchase-jUSDT", }, { - name: "failed stonfi swap", - hash: "77f5acb88fd863e9c00a164eb551ef83c17088d1f603bf463f64f952b93406b0", - filenamePrefix: "stonfi-failed-swap", + name: "claim airdrop", + hash: "5da05a55dea13d511097daff8fbd227a7c2d04fb583552cd5c75f2bd56ae8266", + filenamePrefix: "claim-airdrop", }, { name: "deploy contract action", diff --git a/pkg/bath/straws.go b/pkg/bath/straws.go index c47c9be46..234c9abf3 100644 --- a/pkg/bath/straws.go +++ b/pkg/bath/straws.go @@ -74,6 +74,7 @@ var DefaultStraws = []Merger{ WithdrawStakeImmediatelyStraw, WithdrawLiquidStake, DNSRenewStraw, + AirdropClaimStraw, } var JettonTransferClassicStraw = Straw[BubbleJettonTransfer]{ diff --git a/pkg/bath/testdata/claim-airdrop.json b/pkg/bath/testdata/claim-airdrop.json new file mode 100644 index 000000000..af8612b72 --- /dev/null +++ b/pkg/bath/testdata/claim-airdrop.json @@ -0,0 +1,67 @@ +{ + "Actions": [ + { + "AirdropClaim": { + "Distributor": "0:9e32eb8b51bd1d9c4c6a5da85f8c88a58649ab287863d70f421b2b954edd38da", + "Recipient": "0:c05d61797f2c1ef2fcf0b6c97239ed9c525fcf59107d97dd6c7913ed1d343a13", + "Claimed": { + "Amount": 1270000000000, + "IsTon": false, + "JettonMaster": "0:1477d9dd4a416f50e82a10b4b3fac7e7e57cd37fce13fbfc33885fa36c108005", + "JettonWallet": "0:972bb4e6c35f45317096cae4f97bcc85e9df1fe6328714f3487772381fb11fc8" + } + }, + "Success": true, + "Type": "AirdropClaim", + "BaseTransactions": [ + "2f9db7f85937f9053248f6111ccf78996e3f401e8db09e176addf823c8063888", + "f6a3ee672260d913bfd3ee5c6166a80914131a6effd61ebeb93614ade8c82914", + "f448fe47d5595f2b67abd51bd6149cbdf16bd676bc92a5ff70a8b4f73ebd89b5", + "52f7eb7c0073f18e96788e4c5591cf93fd145830d40fb8fcd26905164d3946e7", + "7e0df449e50d0eccb95bc9dab88548e5e8ad56e0a9bb6d88685ddcff62112f37" + ] + } + ], + "Accounts": [ + { + "Account": "0:11b67015bcfffa5b7ba5ce501bb0488ee427b5fe24bdd90f33190b421dc13892", + "Ton": 0, + "Fee": 3929200, + "Jettons": null + }, + { + "Account": "0:90950a41c7471a3ec9992e2b1c61df7bd636aec56b294f64591a1047940cf479", + "Ton": -109, + "Fee": 7562109, + "Jettons": null + }, + { + "Account": "0:972bb4e6c35f45317096cae4f97bcc85e9df1fe6328714f3487772381fb11fc8", + "Ton": 6889091, + "Fee": 3510909, + "Jettons": null + }, + { + "Account": "0:9e32eb8b51bd1d9c4c6a5da85f8c88a58649ab287863d70f421b2b954edd38da", + "Ton": 121167720, + "Fee": 6941080, + "Jettons": [ + { + "Address": "0:1477d9dd4a416f50e82a10b4b3fac7e7e57cd37fce13fbfc33885fa36c108005", + "Quantity": -1270000000000 + } + ] + }, + { + "Account": "0:c05d61797f2c1ef2fcf0b6c97239ed9c525fcf59107d97dd6c7913ed1d343a13", + "Ton": -159632004, + "Fee": 9632004, + "Jettons": [ + { + "Address": "0:1477d9dd4a416f50e82a10b4b3fac7e7e57cd37fce13fbfc33885fa36c108005", + "Quantity": 1270000000000 + } + ] + } + ] + } \ No newline at end of file