|
8 | 8 | "github.com/tonkeeper/tongo/abi"
|
9 | 9 | "github.com/tonkeeper/tongo/tlb"
|
10 | 10 | "net/http"
|
| 11 | + "sort" |
11 | 12 | "strings"
|
12 | 13 |
|
13 | 14 | "github.com/tonkeeper/opentonapi/pkg/bath"
|
@@ -54,85 +55,83 @@ func jettonMetadata(account ton.AccountID, meta NormalizedMetadata) oas.JettonMe
|
54 | 55 | return metadata
|
55 | 56 | }
|
56 | 57 |
|
57 |
| -func (h *Handler) convertJettonHistory(ctx context.Context, account ton.AccountID, master *ton.AccountID, history []core.JettonOperation, acceptLanguage oas.OptString) ([]oas.AccountEvent, int64, error) { |
| 58 | +func (h *Handler) convertJettonHistory(ctx context.Context, account ton.AccountID, master *ton.AccountID, history map[core.TraceID][]core.JettonOperation, acceptLanguage oas.OptString) ([]oas.AccountEvent, int64, error) { |
58 | 59 | var lastLT uint64
|
59 | 60 | var events []oas.AccountEvent
|
60 |
| - res := make(map[core.TraceID]oas.AccountEvent) |
61 | 61 |
|
62 |
| - for _, op := range history { |
63 |
| - event, ok := res[op.TraceID] |
64 |
| - if !ok { |
65 |
| - event = oas.AccountEvent{ |
66 |
| - EventID: op.TraceID.Hash.Hex(), |
67 |
| - Account: convertAccountAddress(account, h.addressBook), |
68 |
| - Timestamp: op.TraceID.UTime, |
69 |
| - IsScam: false, |
70 |
| - Lt: int64(op.TraceID.Lt), |
71 |
| - Extra: 0, |
72 |
| - } |
| 62 | + for id, ops := range history { |
| 63 | + event := oas.AccountEvent{ |
| 64 | + EventID: id.Hash.Hex(), |
| 65 | + Account: convertAccountAddress(account, h.addressBook), |
| 66 | + Timestamp: id.UTime, // TODO: or first/last op Utime |
| 67 | + IsScam: false, |
| 68 | + Lt: int64(id.Lt), // TODO: or first/last op Lt |
| 69 | + Extra: 0, |
73 | 70 | }
|
74 |
| - |
75 |
| - var action bath.Action |
76 |
| - switch op.Operation { |
77 |
| - case core.TransferJettonOperation: |
78 |
| - transferAction := bath.JettonTransferAction{ |
79 |
| - Jetton: op.JettonMaster, |
80 |
| - Recipient: op.Destination, |
81 |
| - Sender: op.Source, |
82 |
| - Amount: tlb.VarUInteger16(*op.Amount.BigInt()), |
| 71 | + for _, op := range ops { |
| 72 | + var action bath.Action |
| 73 | + switch op.Operation { |
| 74 | + case core.TransferJettonOperation: |
| 75 | + transferAction := bath.JettonTransferAction{ |
| 76 | + Jetton: op.JettonMaster, |
| 77 | + Recipient: op.Destination, |
| 78 | + Sender: op.Source, |
| 79 | + Amount: tlb.VarUInteger16(*op.Amount.BigInt()), |
| 80 | + } |
| 81 | + action.Type = "JettonTransfer" |
| 82 | + action.JettonTransfer = &transferAction |
| 83 | + var payload abi.JettonPayload |
| 84 | + err := json.Unmarshal([]byte(op.ForwardPayload), &payload) |
| 85 | + if err != nil { |
| 86 | + break |
| 87 | + } |
| 88 | + switch p := payload.Value.(type) { |
| 89 | + case abi.TextCommentJettonPayload: |
| 90 | + comment := string(p.Text) |
| 91 | + action.JettonTransfer.Comment = &comment |
| 92 | + case abi.EncryptedTextCommentJettonPayload: |
| 93 | + action.JettonTransfer.EncryptedComment = &bath.EncryptedComment{EncryptionType: "simple", CipherText: p.CipherText} |
| 94 | + } |
| 95 | + case core.MintJettonOperation: |
| 96 | + mintAction := bath.JettonMintAction{ |
| 97 | + Jetton: op.JettonMaster, |
| 98 | + Recipient: *op.Destination, |
| 99 | + Amount: tlb.VarUInteger16(*op.Amount.BigInt()), |
| 100 | + } |
| 101 | + action.Type = "JettonMint" |
| 102 | + action.JettonMint = &mintAction |
| 103 | + case core.BurnJettonOperation: |
| 104 | + burnAction := bath.JettonBurnAction{ |
| 105 | + Jetton: op.JettonMaster, |
| 106 | + Sender: *op.Source, |
| 107 | + Amount: tlb.VarUInteger16(*op.Amount.BigInt()), |
| 108 | + } |
| 109 | + action.Type = "JettonTransfer" |
| 110 | + action.JettonBurn = &burnAction |
| 111 | + default: |
| 112 | + continue |
83 | 113 | }
|
84 |
| - action.Type = "JettonTransfer" |
85 |
| - action.JettonTransfer = &transferAction |
86 |
| - var payload abi.JettonPayload |
87 |
| - err := json.Unmarshal([]byte(op.ForwardPayload), &payload) |
| 114 | + convertedAction, err := h.convertAction(ctx, &account, action, acceptLanguage) |
88 | 115 | if err != nil {
|
89 |
| - break |
90 |
| - } |
91 |
| - switch p := payload.Value.(type) { |
92 |
| - case abi.TextCommentJettonPayload: |
93 |
| - comment := string(p.Text) |
94 |
| - action.JettonTransfer.Comment = &comment |
95 |
| - case abi.EncryptedTextCommentJettonPayload: |
96 |
| - action.JettonTransfer.EncryptedComment = &bath.EncryptedComment{EncryptionType: "simple", CipherText: p.CipherText} |
| 116 | + return nil, 0, err |
97 | 117 | }
|
98 |
| - case core.MintJettonOperation: |
99 |
| - mintAction := bath.JettonMintAction{ |
100 |
| - Jetton: op.JettonMaster, |
101 |
| - Recipient: *op.Destination, |
102 |
| - Amount: tlb.VarUInteger16(*op.Amount.BigInt()), |
| 118 | + event.Actions = append(event.Actions, convertedAction) |
| 119 | + if lastLT == 0 { |
| 120 | + lastLT = op.Lt |
103 | 121 | }
|
104 |
| - action.Type = "JettonMint" |
105 |
| - action.JettonMint = &mintAction |
106 |
| - case core.BurnJettonOperation: |
107 |
| - burnAction := bath.JettonBurnAction{ |
108 |
| - Jetton: op.JettonMaster, |
109 |
| - Sender: *op.Source, |
110 |
| - Amount: tlb.VarUInteger16(*op.Amount.BigInt()), |
| 122 | + if op.Lt < lastLT { |
| 123 | + lastLT = op.Lt |
111 | 124 | }
|
112 |
| - action.Type = "JettonTransfer" |
113 |
| - action.JettonBurn = &burnAction |
114 |
| - default: |
115 |
| - continue |
116 |
| - } |
117 |
| - convertedAction, err := h.convertAction(ctx, &account, action, acceptLanguage) |
118 |
| - if err != nil { |
119 |
| - return nil, 0, err |
120 | 125 | }
|
121 |
| - event.Actions = append(event.Actions, convertedAction) |
122 |
| - if op.Lt > lastLT { |
123 |
| - lastLT = op.Lt |
124 |
| - } |
125 |
| - res[op.TraceID] = event |
126 |
| - } |
127 |
| - |
128 |
| - for _, event := range res { |
129 |
| - event.IsScam = h.spamFilter.CheckActions(event.Actions, &account, nil) |
130 | 126 | if len(event.Actions) == 0 {
|
131 | 127 | continue
|
132 | 128 | }
|
| 129 | + event.IsScam = h.spamFilter.CheckActions(event.Actions, &account, nil) |
133 | 130 | events = append(events, event)
|
134 | 131 | }
|
135 |
| - |
| 132 | + sort.Slice(events, func(i, j int) bool { |
| 133 | + return events[i].Lt > events[j].Lt |
| 134 | + }) |
136 | 135 | return events, int64(lastLT), nil
|
137 | 136 | }
|
138 | 137 |
|
|
0 commit comments