Skip to content

Commit 65e6ba1

Browse files
authored
fix: swap shows incorrect token status in smart account activity (#5001)
1 parent 2d27d48 commit 65e6ba1

File tree

3 files changed

+151
-40
lines changed

3 files changed

+151
-40
lines changed

packages/scaffold-ui/src/partials/w3m-activity-list/index.ts

Lines changed: 6 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { LitElement, html } from 'lit'
22
import { property, state } from 'lit/decorators.js'
33

44
import { DateUtil } from '@reown/appkit-common'
5-
import type { Transaction, TransactionImage } from '@reown/appkit-common'
5+
import type { Transaction } from '@reown/appkit-common'
66
import {
77
ChainController,
88
CoreHelperUtil,
@@ -159,42 +159,8 @@ export class W3mActivityList extends LitElement {
159159
}
160160

161161
private templateRenderTransaction(transaction: Transaction, isLastTransaction: boolean) {
162-
const { date, descriptions, direction, isAllNFT, images, status, transfers, type } =
162+
const { date, descriptions, direction, images, status, type, transfers, isAllNFT } =
163163
this.getTransactionListItemProps(transaction)
164-
const hasMultipleTransfers = transfers?.length > 1
165-
const hasTwoTransfers = transfers?.length === 2
166-
167-
if (hasTwoTransfers && !isAllNFT) {
168-
return html`
169-
<wui-transaction-list-item
170-
date=${date}
171-
.direction=${direction}
172-
id=${isLastTransaction && this.next ? PAGINATOR_ID : ''}
173-
status=${status}
174-
type=${type}
175-
.images=${images}
176-
.descriptions=${descriptions}
177-
></wui-transaction-list-item>
178-
`
179-
}
180-
181-
if (hasMultipleTransfers) {
182-
return transfers.map((transfer, index) => {
183-
const description = TransactionUtil.getTransferDescription(transfer)
184-
const isLastTransfer = isLastTransaction && index === transfers.length - 1
185-
186-
return html` <wui-transaction-list-item
187-
date=${date}
188-
direction=${transfer.direction}
189-
id=${isLastTransfer && this.next ? PAGINATOR_ID : ''}
190-
status=${status}
191-
type=${type}
192-
.onlyDirectionIcon=${true}
193-
.images=${[images[index]] as TransactionImage[]}
194-
.descriptions=${[description]}
195-
></wui-transaction-list-item>`
196-
})
197-
}
198164

199165
return html`
200166
<wui-transaction-list-item
@@ -204,6 +170,7 @@ export class W3mActivityList extends LitElement {
204170
status=${status}
205171
type=${type}
206172
.images=${images}
173+
.onlyDirectionIcon=${isAllNFT || transfers.length === 1}
207174
.descriptions=${descriptions}
208175
></wui-transaction-list-item>
209176
`
@@ -323,10 +290,9 @@ export class W3mActivityList extends LitElement {
323290
const date = DateUtil.formatDate(transaction?.metadata?.minedAt)
324291
const descriptions = TransactionUtil.getTransactionDescriptions(transaction)
325292

326-
const transfers = transaction?.transfers
327-
const transfer = transaction?.transfers?.[0]
328-
const isAllNFT =
329-
Boolean(transfer) && transaction?.transfers?.every(item => Boolean(item.nft_info))
293+
const transfers = TransactionUtil.mergeTransfers(transaction?.transfers)
294+
const transfer = transfers?.[0]
295+
const isAllNFT = Boolean(transfer) && transfers?.every(item => Boolean(item.nft_info))
330296
const images = TransactionUtil.getTransactionImages(transfers)
331297

332298
return {

packages/ui/src/utils/TransactionUtil.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,28 @@ export const TransactionUtil = {
145145

146146
return description
147147
},
148+
mergeTransfers(transfers: TransactionTransfer[]) {
149+
let mergedTransfers = transfers
150+
// If we have more than two transfers, we need to merge transfers with same direction and same token
151+
if (transfers?.length > 1) {
152+
mergedTransfers = transfers.reduce<TransactionTransfer[]>((acc, t) => {
153+
const name = t?.fungible_info?.name
154+
const existingTransfer = acc.find(
155+
({ fungible_info }) => name && name === fungible_info?.name
156+
)
157+
if (existingTransfer) {
158+
const quantity = Number(existingTransfer.quantity.numeric) + Number(t.quantity.numeric)
159+
existingTransfer.quantity.numeric = quantity.toString()
160+
} else {
161+
acc.push(t)
162+
}
163+
164+
return acc
165+
}, [])
166+
}
167+
168+
return mergedTransfers
169+
},
148170

149171
getQuantityFixedValue(value: string | undefined) {
150172
if (!value) {

packages/ui/tests/TransactionUtil.test.ts

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,3 +122,126 @@ describe('TransactionUtil.getTransactionDescriptions', () => {
122122
expect(desc[0]).toBe('success')
123123
})
124124
})
125+
126+
describe('TransactionUtil.mergeTransfers', () => {
127+
const createToken1Transfer = (quantity = '100') => ({
128+
fungible_info: {
129+
name: 'Token1',
130+
symbol: 'TOK1',
131+
icon: { url: 'token1-url' }
132+
},
133+
direction: 'in' as const,
134+
quantity: { numeric: quantity }
135+
})
136+
137+
const createToken2Transfer = (quantity = '200') => ({
138+
fungible_info: {
139+
name: 'Token2',
140+
symbol: 'TOK2',
141+
icon: { url: 'token2-url' }
142+
},
143+
direction: 'in' as const,
144+
quantity: { numeric: quantity }
145+
})
146+
147+
it('returns empty array for empty input', () => {
148+
const result = TransactionUtil.mergeTransfers([])
149+
expect(result).toEqual([])
150+
})
151+
152+
it('returns single transfer unchanged', () => {
153+
const token1Transfer = createToken1Transfer()
154+
const result = TransactionUtil.mergeTransfers([token1Transfer])
155+
expect(result).toEqual([token1Transfer])
156+
})
157+
158+
it('returns multiple transfers with different names unchanged', () => {
159+
const token1Transfer = createToken1Transfer()
160+
const token2Transfer = createToken2Transfer()
161+
const result = TransactionUtil.mergeTransfers([token1Transfer, token2Transfer])
162+
expect(result).toEqual([token1Transfer, token2Transfer])
163+
})
164+
165+
it('merges transfers with same token name', () => {
166+
const token1Transfer = createToken1Transfer('100')
167+
const token1Transfer2 = createToken1Transfer('50')
168+
const result = TransactionUtil.mergeTransfers([token1Transfer, token1Transfer2])
169+
expect(result.length).toBe(1)
170+
expect(result[0]?.fungible_info?.name).toBe('Token1')
171+
expect(result[0]?.quantity.numeric).toBe('150')
172+
})
173+
174+
it('merges multiple transfers with mixed same and different names', () => {
175+
const token1Transfer = createToken1Transfer('100')
176+
const token2Transfer = createToken2Transfer('200')
177+
const token1Transfer2 = createToken1Transfer('50')
178+
const result = TransactionUtil.mergeTransfers([token1Transfer, token2Transfer, token1Transfer2])
179+
expect(result.length).toBe(2)
180+
181+
// Find the merged Token1 transfer
182+
const token1Merged = result.find(t => t?.fungible_info?.name === 'Token1')
183+
expect(token1Merged?.quantity.numeric).toBe('150') // '100' + '50'
184+
185+
// Token2 should remain unchanged
186+
const token2Result = result.find(t => t?.fungible_info?.name === 'Token2')
187+
expect(token2Result?.quantity.numeric).toBe('200')
188+
})
189+
190+
it('handles transfers with undefined fungible_info gracefully', () => {
191+
const token1Transfer = createToken1Transfer()
192+
const transferWithoutFungible = {
193+
direction: 'in' as const,
194+
quantity: { numeric: '100' }
195+
} as any
196+
197+
const result = TransactionUtil.mergeTransfers([token1Transfer, transferWithoutFungible])
198+
expect(result.length).toBe(2)
199+
expect(result).toContain(token1Transfer)
200+
expect(result).toContain(transferWithoutFungible)
201+
})
202+
203+
it('does not merge transfers with undefined fungible_info name', () => {
204+
const transferWithoutName = {
205+
fungible_info: {
206+
symbol: 'TOK1',
207+
icon: { url: 'token1-url' }
208+
// name is undefined
209+
},
210+
direction: 'in' as const,
211+
quantity: { numeric: '100' }
212+
}
213+
214+
const anotherTransferWithoutName = {
215+
fungible_info: {
216+
symbol: 'TOK1',
217+
icon: { url: 'token1-url' }
218+
// name is undefined
219+
},
220+
direction: 'in' as const,
221+
quantity: { numeric: '50' }
222+
}
223+
224+
const result = TransactionUtil.mergeTransfers([transferWithoutName, anotherTransferWithoutName])
225+
expect(result.length).toBe(2) // Should not merge because names are undefined
226+
expect(result[0]?.quantity.numeric).toBe('100')
227+
expect(result[1]?.quantity.numeric).toBe('50')
228+
})
229+
230+
it('does not merge transfer with undefined name with named transfer', () => {
231+
const namedTransfer = createToken1Transfer('100')
232+
const transferWithoutName = {
233+
fungible_info: {
234+
symbol: 'TOK1',
235+
icon: { url: 'token1-url' }
236+
// name is undefined
237+
},
238+
direction: 'in' as const,
239+
quantity: { numeric: '50' }
240+
}
241+
242+
const result = TransactionUtil.mergeTransfers([namedTransfer, transferWithoutName])
243+
expect(result.length).toBe(2) // Should not merge because one has undefined name
244+
expect(result.find(t => t?.fungible_info?.name === 'Token1')?.quantity.numeric).toBe('100')
245+
expect(result.find(t => !t?.fungible_info?.name)?.quantity.numeric).toBe('50')
246+
})
247+
})

0 commit comments

Comments
 (0)