From 497255c8a7ef72da3155b95a42ddc606f066bab8 Mon Sep 17 00:00:00 2001 From: NeOMakinG <14963751+NeOMakinG@users.noreply.github.com> Date: Tue, 3 Dec 2024 10:33:17 +0800 Subject: [PATCH 1/9] feat: turn jupiter flag on (#8245) --- .env.base | 4 ++-- .env.dev | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.env.base b/.env.base index 9ab070fe2aa..70b7475d4a3 100644 --- a/.env.base +++ b/.env.base @@ -62,7 +62,7 @@ REACT_APP_FEATURE_READ_ONLY_ASSETS=true # Swapper chain-specific flags. Use me if you're working on a swapper which brings first time swapper support for a chain, # meaning we don't want to enable the selection for said chain in prod just yet # Or alternatively, if we know that a given chain is very unstable and we may want to disable it in swapper altogether. -REACT_APP_FEATURE_SWAPPER_SOLANA=false +REACT_APP_FEATURE_SWAPPER_SOLANA=true # Swapper feature flags - other .env files will override these REACT_APP_FEATURE_CHAINFLIP_SWAP=false @@ -72,7 +72,7 @@ REACT_APP_FEATURE_LIFI_SWAP=true REACT_APP_FEATURE_THOR_SWAP=true REACT_APP_FEATURE_THOR_SWAP_STREAMING_SWAPS=true REACT_APP_FEATURE_ZRX_SWAP=true -REACT_APP_FEATURE_JUPITER_SWAP=false +REACT_APP_FEATURE_JUPITER_SWAP=true # chat woot REACT_APP_CHATWOOT_TOKEN=jmoXp9BPMSPEYHeJX5YKT15Q diff --git a/.env.dev b/.env.dev index 1a04a7112a2..160e68be569 100644 --- a/.env.dev +++ b/.env.dev @@ -8,7 +8,6 @@ REACT_APP_FEATURE_CHAINFLIP_SWAP=true REACT_APP_FEATURE_CHAINFLIP_SWAP_DCA=false REACT_APP_FEATURE_PUBLIC_TRADE_ROUTE=true REACT_APP_FEATURE_LIMIT_ORDERS=true -REACT_APP_FEATURE_JUPITER_SWAP=true # logging REACT_APP_REDUX_WINDOW=false From c87ead9ca11a2047ebc5a6e11c01370fab39a229 Mon Sep 17 00:00:00 2001 From: gomes <17035424+gomesalexandre@users.noreply.github.com> Date: Tue, 3 Dec 2024 20:04:46 +0800 Subject: [PATCH 2/9] feat: update xdefi hardcoded mipd info post-renaming (#8252) --- src/lib/mipd.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/mipd.ts b/src/lib/mipd.ts index 53a836e0810..b945ba7d495 100644 --- a/src/lib/mipd.ts +++ b/src/lib/mipd.ts @@ -34,8 +34,8 @@ export const staticMipdProviders = [ provider: undefined, info: { uuid: 'f932d0ca-0e8b-405d-aa9a-2d9dcddff53d', - name: 'XDEFI', - icon: 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTEyIiBoZWlnaHQ9IjUxMiIgdmlld0JveD0iMCAwIDUxMiA1MTIiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMF8yMTkxXzQyOTApIj4KPHJlY3Qgd2lkdGg9IjUxMiIgaGVpZ2h0PSI1MTIiIHJ4PSIxMDQiIGZpbGw9IiMzMzVERTUiLz4KPHBhdGggZD0iTTQ2My40MzggMjQxLjI0N0M0NjAuNzY1IDIwNS4xMzUgNDQ4LjU4IDE3MC4zMzggNDI4LjA4NyAxNDAuMjcxQzQwNy41OTkgMTEwLjIwOSAzNzkuNTA5IDg1LjkxODIgMzQ2LjU3OSA2OS43OTZDMzEzLjY1MyA1My42NzggMjc3LjAzMiA0Ni4yODA0IDI0MC4zMiA0OC4zMzYzQzIwMy42MDUgNTAuMzkyMSAxNjguMDY5IDYxLjgyNTUgMTM3LjIxMiA4MS41MjAxQzEwNi4zNTQgMTAxLjIxIDgxLjIzOTQgMTI4LjQ4IDY0LjMzODYgMTYwLjYzNkw2My41MzYgMTYyLjI1N0M1OC4xOTcxIDE3My4xMjYgNTQuNTg3OCAxODQuNzQ1IDUyLjg0MTEgMTk2LjY5N0M0Ny44NDU1IDIzMi4wMjEgNTUuNTkyIDI2My40NiA3NS44Mjc1IDI4Ny42NjdDOTcuOTU5OSAzMTQuMTM2IDEzMy45OTMgMzI5Ljg3OSAxNzcuMjE1IDMzMS45NDdDMjI5LjgzMiAzMzQuNTU1IDI4Mi4xNDggMzIwLjQzNCAzMTkuMjc1IDI5NC40NThMMzQxLjI4NyAzMDcuMzUzQzMyMC4yNTggMzI1LjI5MSAyNzEuNjM3IDM1Ny41OTQgMTkxLjExMiAzNjIuMDA5QzEwMC43MTkgMzY2LjkzIDYzLjA0MjUgMzM4LjAwMSA2Mi42OTA1IDMzNy43MDZMNTYuMzUxNyAzNDUuNDAzTDQ4IDM1NS4yNzNDNDkuNjAwOCAzNTYuNiA4NS43Mjg1IDM4NS4zMzUgMTcwLjU3NiAzODUuMzM1QzE3Ny41MiAzODUuMzM1IDE4NC44MTYgMzg1LjMzNSAxOTIuNDEyIDM4NC43NDZDMjg5Ljg3MyAzNzkuMzkxIDM0My40NzYgMzM3LjU3NSAzNjIuMjMxIDMxOS42MjlMMzgwLjY0MiAzMzAuNjM3QzM2OC4yNjEgMzQ2LjY1OCAzNTMuMDI1IDM2MC4zMzMgMzM1LjY3IDM3MC45ODJDMjc0LjUwNCA0MDkuODQ5IDE5Ni43MDggNDE0Ljg2NyAxNDIuMjQyIDQxMi4xNjJMMTQxLjA5NiA0MzQuODMxQzE1MC4yNDIgNDM1LjI3MyAxNTkuMDM1IDQzNS40NzEgMTY3LjU4IDQzNS40NzFDMzIxLjA0OCA0MzUuNDcxIDM4My4xMzIgMzY2LjcxOSA0MDAuNTM5IDM0Mi4wNjJMNDE0LjkyNSAzNTAuNDg3QzQwMS4xMzUgMzczLjYwMyAzODIuMzkzIDM5My41NjcgMzU5LjkzMSA0MDguOTM5QzMzMy4wMzQgNDI3LjM0NSAzMDEuNzM1IDQzOC41MzggMjY5LjExNCA0NDEuNDE1TDI3MS4xMTQgNDY0QzMwNy43MzkgNDYwLjc4NiAzNDIuODg4IDQ0OC4yMzYgMzczLjA4OSA0MjcuNTgxQzQwMy4yOSA0MDYuOTI2IDQyNy41MDggMzc4Ljg4MSA0NDMuMzQ5IDM0Ni4yMDdDNDU5LjE4NSAzMTMuNTI5IDQ2Ni4xMTYgMjc3LjM1OCA0NjMuNDM4IDI0MS4yNDdaTTM3NC44MSAyNDQuNzM5QzM2NC42MjYgMjQ0LjczOSAzNTYuMzY4IDIzNi42MTMgMzU2LjM2OCAyMjYuNTg2QzM1Ni4zNjggMjE2LjU2IDM2NC42MjEgMjA4LjQzMyAzNzQuODEgMjA4LjQzM0MzODQuOTkgMjA4LjQzMyAzOTMuMjQ3IDIxNi41NiAzOTMuMjQ3IDIyNi41ODZDMzkzLjI0NyAyMzYuNjEzIDM4NC45OTQgMjQ0LjczOSAzNzQuODEgMjQ0LjczOVoiIGZpbGw9IiNFQ0VDRUMiLz4KPC9nPgo8ZGVmcz4KPGNsaXBQYXRoIGlkPSJjbGlwMF8yMTkxXzQyOTAiPgo8cmVjdCB3aWR0aD0iNTEyIiBoZWlnaHQ9IjUxMiIgZmlsbD0id2hpdGUiLz4KPC9jbGlwUGF0aD4KPC9kZWZzPgo8L3N2Zz4K', + name: 'Ctrl Wallet', + icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAMAAABrrFhUAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA0NpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDkuMS1jMDAyIDc5LmYzNTRlZmM3MCwgMjAyMy8xMS8wOS0xMjowNTo1MyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIDI1LjQgKDIwMjMxMjIwLm0uMjQzOSBjZWI5OWVmKSAgKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6RjNGRDkwNzlFRjRGMTFFRTlFRjJERDZFQkZDREE0OTUiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6RjNGRDkwN0FFRjRGMTFFRTlFRjJERDZFQkZDREE0OTUiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpGM0ZEOTA3N0VGNEYxMUVFOUVGMkRENkVCRkNEQTQ5NSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpGM0ZEOTA3OEVGNEYxMUVFOUVGMkRENkVCRkNEQTQ5NSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pp1Y9zMAAAD8UExURf///+/w7+/x7+/x8N/h4N/i4M/T0M/T0b/EwL/Ewa+1sK+2sZ+noY+YkY+YkoCKgoCKg3+JgX+JgnB7c3B8c296cW96cm97cmBsZGBtY19sYl9sY1BeVE9dU0BPRDBANDBBNDBBNSAyJCAyJRAjFBAjFQAUBRAiFRAjFSAxJCAxJSAyJCAyJTBANDBBNEBPRFBdVFBeU1BeVF9sY2BsY2BtY297cnB6cnB7cnB7c3+Jgn+KgoCJgoCKgo+YkY+YkpCYkpCZkp+moZ+noaCnoa+1sa+2sLC1sb/EwL/Ewc/S0M/T0M/T0d/h39/h4N/i39/i4O/w7+/x7////9thEPoAAAAmdFJOUwAQEBAgIDAwQEBQUGBwcH9/gICPj5CQkJ+foKCvsL/Pz8/f3+/vvw5Z9wAADB1JREFUeNrtnX1jmzgSxun5pXZC7nZ9uca9+uwcqRVCyrJ1zYbtkQ2L422ovQ6E7/9dTgL8ltiJBIxWRZ1/Y8c8P/QyMxpJigJltXr9dbutqmqn0znuYutjO9VSQzss+xP5WL+HP3+Mv4i/3m636/WaIrzVsFxVPep0uz0iE5VuCRpCRT3ESGqCaD5Uj46x4ucEG4ZhWpZlY3NcYjf+Xkv+7jr4oyP8FQt/df//fX+KeWAcmAZf2UR1p9s71d4/fSgdax3Ztuv6/jQIwjCMS7AwnAfBlNBxbMsyDX1X88CdpnN0CMiiVs9kP5U8wm/W94N5+BBzsocQE7lJeBg7GkYXN4vXJfaRmnp8+v6RaouInnLU/FwLCQLfdUaWud003vePDxslqP+hv5Y9snEHnoexsBaShmFvoOirxRi0U/WmczMV4mXTd5J5cOOYycP32sXk67b/TUnfwjAdJyOkml++dfPNqs8YTD4QBOwdofZPIj+IK2AB6QpvGRG08XR3WQn5xEgrYOsH5PV/foirY5+xoB+o5TdOEfppFlfKQtwITim7QQM3/18e4qrZFe1Y2MRe301cQfsNoWGTSr8+iytpM52CANZ/eR9X1PBA8BKBRpX1pwQaL4x/eoX1YwL68yMhnv9mcaXtDs+G+/X/o6Lj/6O54HiffhXP/3HlDfsD7b0DwGX19ceRibS/7QTwFqF7CQDEsz2doInQ/2IpzN3dCeToAEkn+ID6O0fAiSQAyFzY3tEArFgas542gQOEAnkA7GgCfWlGgN1NoCHRCEDMQ2jbFzhCeiQTgEhHnUc9YBxLZePtPoB7wFQuAP52H8BzQCQXgAihzYWCN8iMJTMTnWwNAQ448sBJyl5etpHLwyO52kqMDJEH/HvX5ywFURe3HCbC4Vr/K2g3cGGy1oT9Cg3gy+YoiCPhOah+g70qDnpaDhF6vQLQgp0EIiNPXSBwG8DTwOFGKKzDOh257A6WgL4xD3ZAZ8FFztJQ4PDc2HCG34H+2DhvcSxsE/iIupwiASMvAFjfZIz+swIwQC7oaCNkH3CRxscPCnIDuAAOh9aeEGgsKCoA7AltBMOBfABmCNXXftC9fAA2XMEDhGL5AMRrV/AI1BEUFsDaFYR1BIUFsHYFYR1BYQFYK1ewh0YyAli7grAJMWEBrJNiGqQnLC4Ab+ULI3QrI4C1LwybERQWwCor2JAUwMoXhvWExQWw8oVboJ6wuABWvrAqK4ClL9yB/SVxASx94Q5s7klcAMv10XeyAljmhYGrQ8QFsAwGgNfGxQVwlZXJgCbFRQawTIwDFwd8ERaAnwGAjYVIOZKwABCP6ghXWABBGg0Bx0J4shEVQBYNAcdCsSksgCwagi4PQcICiNKacdhlkQKTADiAOC2WFLM+hguANBwEDgYNgQGk4SDsutAECQzATAC8AQ0GLZEBpGtDoNHwAokMII2HQaPhsdAA0ngYMhqeIsEB9BMALuAwKzQAN1kdBFwZdJHoALQEAFQ0HCDBAaQJAbB0wMIQHwACLBIsrB9+M3NSKgiVD4nMovrh9zElGRGgfMiiuH743dwByYg0QLbLfDWK64ffzR0SACAJIe+8uH4Oe1lDkhEBALCwSpDP40SfJYCSR7/rMl4/+hRzMFIhUHJ1wLwc+ZxOdCI5sTIBhF4pjZ/fcbYpADaHKwx2mu85I9Z3rxs79w7bN4/lR/OAyuas6W0DA2BKCUbXRjmvWLduAtpjSycMzcq6ZQTQYQLgnZfUwqf0Z7ayehQXd8wAaF3u6Ody5Dss0+4t+/+/ZsuK0udEy9H/M5PX8Ueen/idISt6Qp8TdcuQz3hc9yJXn9P/ZEkL0wJYlPL6Gc9rzplTtdgAjCCfZctYj+vLDf2OGnBX6VFmxUuY/5jPK72CziQQAJTLArO/QH/+0oILagB9WgBfuLf/xFPNa0wAqNqL/xfoLwDgnraP9WnXRYpOgrnSO+AAXG4A8h3YzQHAKe3CkMt7AOQEQOMDIGd+szoAJpIDyJvgBgfgJQBuwQFMRAXg8wGQe4WjKgDGQgNA8ADmAgNAHADkX+OrCICR7AA82QEEsgOIJAdQoBi/GgBM2QFY3wF8B/AdQD6LZAcQyg5gJjuAQHYAnuwArmQHYMkOAEkOIOADQBMWwJgHAE1gAIbkAIpsu2YD4IkJwOIAgMvaoMV/CKwEAENyAIVGACYAAyEBFN11KVKNkMXbB2AGAFwmlwdA4cJspjK5MSyAHEuDfxTVz1YoCVwqy346wdfCG1NMBgDvKOsXdG5Lg8X1U5dkkENEaAHk7ZbM1QG3JWxMooX+kWHDRJSzCUx4j3+IecME5cd/y/UsPzHO/6XsvLxnAUC/aepTng7AVCNc0rZj+rpcsmmK4SixT7D6S5LPUpdsMW6c/Mz4KCx7pAKnHPlM+9JYd47GofOBvjDCpn6U0HdK2pJrsY25BADr5ukHun3MQfj0Fe++eNlk1a6b9o0/3fmbjLvyks3TwLcLLK2k/o10J3go76kQLwBlnCmTtPCSzxUgAFocACwMIeUTAG3wY4XjvBcvFxreKQdfAqAJD8ApQ/8vDzEMgAY4gDK2XesTiCebZSdJAZ9YclVC85+BPFlylNYrcADFZ4BLoDaaHi8PfWZVJKz+7OZd4PsVSth3PoN6tPRARQ0YQMAxumMGoIFft1gcAOCpx+mhqgOxAVzeQwI4hb9nqSiACeCjpRcN9YQGAHqwanqy9DvQS3c5LfTns4/wp8sXBQD7aFZy3RzsBQsFAcD6aOkFC0fAJzgXAQB8sGx6xQbwJSuFAMAOz9klK9A5sSIAgMO09NZV4IuWigCAbZrLi5agU0KBqHNAmhBSgM7WLgUArI+e5kPgr9sLRJ0El9ftQScECgCYwwJI8yHgCYECACJYAD4aZgAEvXQVesVmeemqsNfuAs+Cq2t3e/JevNzPrt4eyQnAyq7efgMbDooMIL19HjgcFBeAkQEADgfFBZAGg8mtq5GUANJQADwaEhZAuAQAHA0JCyCLhZJoaCopgCQWUpQhaDAgLIDs8nnwYEBYAMtQgKwOOjICWIYC0MGAsADGKwCwa0PCAliGAtC3jwsLwMw8YWhfWFgAOvp7BuAANPciLIB0WQTeFxYVwMoThvaFRQWw8oShE+OiAviycgQV2mM08tlMUABelhRXoAvF8leKwi4NpiViPFzB3LsFYC9eXjuC0Hnh3NXisNUBa0cQ2hXMezAkcH3M2hEET4vmbAITPilRDmnR6EMe/cAX70ZrP0gB3zYT5iDwCTgljGfn1ysAr6BrEdgJgF+8vM4IpllBD/j3PjMh4HDx8qYfBL5CntjUsejs6cXLsAkxDuujIpqZ1Amv50HochTRLFpnA7JR8FYuADgWbChbg8BYLgDjjVCI2I9Il6oPROuE4KoPeDIBmDzqAaQPWDIBMLYmQSWtGb+TR3+wPQfI1wQsdPZYv1RNYII2QuGNJnARSTMCPG0ASRO4lkO/i1BzBwDlX4Ab1UWyBUJvd+lXXp0hM5KjAzR2AiCd4Nfq63d2joCrTvB71fV7aCMb/MQGlZ8LvyL03/36lcYZ0v+s9AB4vncAyAgM0UWFCSwMNHxWv6I0q0yA6G8qyosE9Iq6A8E5hf6EQDXnAjz+0+hPRsIK+gMRnv/PGgqVNfBsWLWB4KuJ5z9K/UmKsFqRUXSNBZ0oDKbibnBRmUx5YODm31KYrPFvPkt0POST88pPagqrNc9IodbtNx4fRh6R328peYz0A3Q+nn6zDCLfPs8vPykd6Ser1abjBfNvCkMUTj0nPcqygPxkLDgaLBftz03Ldr3p00OzxbFwPvVde2SsjrHu/1hTClvj4KQ/3KpfICgc1w/EYEFUe45tGdundw8HJ2oJ6pdWa7bUTrc/GD4u5jCsBMYU04j4NfB54PuuY49M4/GZ5UOt1+2oB80StT+yeuvgCKPoaztKW84NM+Hh+oTIPCylhYRhGARTLNi17ZH1VHKiepDKris8rVZv4WaRwBjur/cxDIMUvoxsm5Ah5u+19O82seTgfeOZMltN6/e6J4nqmiKAERoHGMcJ5jHQNFS6adoAK+52OqraEkTzS0QwkpaqYiiYSrfb6xPTUtutMLEB+Rj+PH67RKx60GrVAfX+H4bAlyrre0h5AAAAAElFTkSuQmCC', rdns: 'io.xdefi', }, }, From ac33e6cc622ab31a190df9280a76454943488dac Mon Sep 17 00:00:00 2001 From: NeOMakinG <14963751+NeOMakinG@users.noreply.github.com> Date: Tue, 3 Dec 2024 22:55:28 +0800 Subject: [PATCH 3/9] fix: apps crash randomly while navigating (#8255) --- src/components/Modal/components/DialogCloseButton.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Modal/components/DialogCloseButton.tsx b/src/components/Modal/components/DialogCloseButton.tsx index 2d39b2e9d96..5fc28a6cd8e 100644 --- a/src/components/Modal/components/DialogCloseButton.tsx +++ b/src/components/Modal/components/DialogCloseButton.tsx @@ -1,10 +1,10 @@ import type { ModalCloseButtonProps } from '@chakra-ui/react' import { IconButton, ModalCloseButton, useMediaQuery } from '@chakra-ui/react' import { useCallback } from 'react' -import { isMobile } from 'react-device-detect' import { IoClose } from 'react-icons/io5' import { Drawer } from 'vaul' import { useDialog } from 'context/DialogContextProvider/DialogContextProvider' +import { isMobile } from 'lib/globals' import { breakpoints } from 'theme/theme' type DialogCloseButtonProps = ModalCloseButtonProps From 4b2b3b561878b1b4a95b549d12ca22ebad29e8ca Mon Sep 17 00:00:00 2001 From: gomes <17035424+gomesalexandre@users.noreply.github.com> Date: Tue, 3 Dec 2024 23:06:17 +0800 Subject: [PATCH 4/9] feat: jupiter auto-slippage (#8253) --- packages/swapper/src/constants.ts | 16 ++++-- .../swapperApi/getTradeQuote.ts | 4 +- .../swapperApi/getTradeQuote.ts | 55 +++++++++---------- .../JupiterSwapper/swapperApi/getTradeRate.ts | 55 +++++++++---------- .../swappers/JupiterSwapper/utils/helpers.ts | 4 +- .../getPortalsTradeQuote.ts | 8 +-- .../getPortalsTradeRate.tsx | 8 +-- packages/swapper/src/utils.ts | 2 +- .../SharedSlippagePopover.tsx | 2 +- src/state/slices/tradeQuoteSlice/selectors.ts | 15 +++-- 10 files changed, 88 insertions(+), 81 deletions(-) diff --git a/packages/swapper/src/constants.ts b/packages/swapper/src/constants.ts index bb6999ee60f..04c2aafd869 100644 --- a/packages/swapper/src/constants.ts +++ b/packages/swapper/src/constants.ts @@ -105,10 +105,9 @@ const DEFAULT_LIFI_SLIPPAGE_DECIMAL_PERCENTAGE = '0.005' // .5% const DEFAULT_THOR_SLIPPAGE_DECIMAL_PERCENTAGE = '0.01' // 1% const DEFAULT_ARBITRUM_BRIDGE_SLIPPAGE_DECIMAL_PERCENTAGE = '0' // no slippage for Arbitrum Bridge, so no slippage tolerance const DEFAULT_CHAINFLIP_SLIPPAGE_DECIMAL_PERCENTAGE = '0.02' // 2% -const DEFAULT_JUPITER_SLIPPAGE_DECIMAL_PERCENTAGE = '0.01' // 1% export const getDefaultSlippageDecimalPercentageForSwapper = ( - swapperName?: SwapperName, + swapperName: SwapperName | undefined, ): string => { if (swapperName === undefined) return DEFAULT_SLIPPAGE_DECIMAL_PERCENTAGE switch (swapperName) { @@ -128,8 +127,17 @@ export const getDefaultSlippageDecimalPercentageForSwapper = ( case SwapperName.Chainflip: return DEFAULT_CHAINFLIP_SLIPPAGE_DECIMAL_PERCENTAGE case SwapperName.Jupiter: - return DEFAULT_JUPITER_SLIPPAGE_DECIMAL_PERCENTAGE + throw new Error('Default slippage not supported by Jupiter') default: - assertUnreachable(swapperName) + return assertUnreachable(swapperName) + } +} + +export const isAutoSlippageSupportedBySwapper = (swapperName: SwapperName): boolean => { + switch (swapperName) { + case SwapperName.Jupiter: + return true + default: + return false } } diff --git a/packages/swapper/src/swappers/ChainflipSwapper/swapperApi/getTradeQuote.ts b/packages/swapper/src/swappers/ChainflipSwapper/swapperApi/getTradeQuote.ts index 040b672ed5d..7e9bf462fa8 100644 --- a/packages/swapper/src/swappers/ChainflipSwapper/swapperApi/getTradeQuote.ts +++ b/packages/swapper/src/swappers/ChainflipSwapper/swapperApi/getTradeQuote.ts @@ -18,7 +18,7 @@ import type { TradeQuote, } from '../../../types' import { SwapperName, TradeQuoteError } from '../../../types' -import { getRate, makeSwapErrorRight } from '../../../utils' +import { getInputOutputRate, makeSwapErrorRight } from '../../../utils' import { CHAINFLIP_BAAS_COMMISSION, CHAINFLIP_BOOST_SWAP_SOURCE, @@ -226,7 +226,7 @@ export const _getTradeQuote = async ( } const getQuoteRate = (sellAmountCryptoBaseUnit: string, buyAmountCryptoBaseUnit: string) => { - return getRate({ + return getInputOutputRate({ sellAmountCryptoBaseUnit, buyAmountCryptoBaseUnit, sellAsset, diff --git a/packages/swapper/src/swappers/JupiterSwapper/swapperApi/getTradeQuote.ts b/packages/swapper/src/swappers/JupiterSwapper/swapperApi/getTradeQuote.ts index e050a4b36d3..c305cda2e1b 100644 --- a/packages/swapper/src/swappers/JupiterSwapper/swapperApi/getTradeQuote.ts +++ b/packages/swapper/src/swappers/JupiterSwapper/swapperApi/getTradeQuote.ts @@ -11,7 +11,7 @@ import { } from '@shapeshiftoss/caip' import type { GetFeeDataInput } from '@shapeshiftoss/chain-adapters' import type { KnownChainIds } from '@shapeshiftoss/types' -import { bnOrZero, convertDecimalPercentageToBasisPoints } from '@shapeshiftoss/utils' +import { bn, bnOrZero, convertDecimalPercentageToBasisPoints } from '@shapeshiftoss/utils' import type { Result } from '@sniptt/monads' import { Err, Ok } from '@sniptt/monads' import type { TransactionInstruction } from '@solana/web3.js' @@ -19,7 +19,6 @@ import { PublicKey } from '@solana/web3.js' import type { AxiosError } from 'axios' import { v4 as uuid } from 'uuid' -import { getDefaultSlippageDecimalPercentageForSwapper } from '../../..' import type { CommonTradeQuoteInput, ProtocolFee, @@ -28,7 +27,7 @@ import type { TradeQuote, } from '../../../types' import { SwapperName, TradeQuoteError } from '../../../types' -import { getRate, makeSwapErrorRight } from '../../../utils' +import { getInputOutputRate, makeSwapErrorRight } from '../../../utils' import { JUPITER_COMPUTE_UNIT_MARGIN_MULTIPLIER } from '../utils/constants' import { getJupiterPrice, getJupiterSwapInstructions, isSupportedChainId } from '../utils/helpers' @@ -44,7 +43,7 @@ export const getTradeQuote = async ( accountNumber, sendAddress, sellAmountIncludingProtocolFeesCryptoBaseUnit: sellAmount, - slippageTolerancePercentageDecimal, + slippageTolerancePercentageDecimal: _slippageTolerancePercentageDecimal, } = input const { assetsById } = deps @@ -95,10 +94,9 @@ export const getTradeQuote = async ( destinationAsset: buyAsset.assetId === solAssetId ? wrappedSolAssetId : buyAsset.assetId, commissionBps: affiliateBps, amount: sellAmount, - slippageBps: convertDecimalPercentageToBasisPoints( - slippageTolerancePercentageDecimal ?? - getDefaultSlippageDecimalPercentageForSwapper(SwapperName.Jupiter), - ).toFixed(), + slippageBps: _slippageTolerancePercentageDecimal + ? convertDecimalPercentageToBasisPoints(_slippageTolerancePercentageDecimal).toFixed() + : undefined, }) if (maybePriceResponse.isErr()) { @@ -110,7 +108,12 @@ export const getTradeQuote = async ( ) } - const { data: quoteResponse } = maybePriceResponse.unwrap() + const { data: priceResponse } = maybePriceResponse.unwrap() + + const slippageTolerancePercentageDecimal = + // Divide by 100 to get actual decimal percentage from bps + // e.g for 0.5% bps, Jupiter represents this as 50. 50/100 = 0.5, then we div by 100 again to honour our decimal format e.g 0.5/100 = 0.005 + bn(priceResponse.slippageBps).div(100).div(100).toString() const contractAddress = buyAsset.assetId === solAssetId ? undefined : fromAssetId(buyAsset.assetId).assetReference @@ -132,9 +135,9 @@ export const getTradeQuote = async ( apiUrl: jupiterUrl, fromAddress: sendAddress, toAddress: isCrossAccountTrade ? destinationTokenAccount?.toString() : undefined, - rawQuote: quoteResponse, + rawQuote: priceResponse, // Shared account is not supported for simple AMMs - useSharedAccounts: quoteResponse.routePlan.length > 1 && isCrossAccountTrade ? true : false, + useSharedAccounts: priceResponse.routePlan.length > 1 && isCrossAccountTrade ? true : false, }) if (maybeSwapResponse.isErr()) { @@ -191,7 +194,7 @@ export const getTradeQuote = async ( } } - const protocolFees: Record = quoteResponse.routePlan.reduce( + const protocolFees: Record = priceResponse.routePlan.reduce( (acc, route) => { const feeAssetId = toAssetId({ assetReference: route.swapInfo.feeMint, @@ -216,20 +219,16 @@ export const getTradeQuote = async ( {} as Record, ) - const getQuoteRate = (sellAmountCryptoBaseUnit: string, buyAmountCryptoBaseUnit: string) => { - return getRate({ - sellAmountCryptoBaseUnit, - buyAmountCryptoBaseUnit, - sellAsset, - buyAsset, - }) - } - const quotes: TradeQuote[] = [] const feeData = await getFeeData() - const rate = getQuoteRate(quoteResponse.inAmount, quoteResponse.outAmount) + const rate = getInputOutputRate({ + sellAmountCryptoBaseUnit: priceResponse.inAmount, + buyAmountCryptoBaseUnit: priceResponse.outAmount, + sellAsset, + buyAsset, + }) const tradeQuote: TradeQuote = { id: uuid(), @@ -237,16 +236,14 @@ export const getTradeQuote = async ( potentialAffiliateBps: affiliateBps, affiliateBps, receiveAddress, - slippageTolerancePercentageDecimal: - slippageTolerancePercentageDecimal ?? - getDefaultSlippageDecimalPercentageForSwapper(SwapperName.Jupiter), + slippageTolerancePercentageDecimal, steps: [ { accountNumber, - buyAmountBeforeFeesCryptoBaseUnit: quoteResponse.outAmount, - buyAmountAfterFeesCryptoBaseUnit: quoteResponse.outAmount, - sellAmountIncludingProtocolFeesCryptoBaseUnit: quoteResponse.inAmount, - jupiterQuoteResponse: quoteResponse, + buyAmountBeforeFeesCryptoBaseUnit: priceResponse.outAmount, + buyAmountAfterFeesCryptoBaseUnit: priceResponse.outAmount, + sellAmountIncludingProtocolFeesCryptoBaseUnit: priceResponse.inAmount, + jupiterQuoteResponse: priceResponse, jupiterTransactionMetadata: { addressLookupTableAddresses: swapResponse.addressLookupTableAddresses, instructions, diff --git a/packages/swapper/src/swappers/JupiterSwapper/swapperApi/getTradeRate.ts b/packages/swapper/src/swappers/JupiterSwapper/swapperApi/getTradeRate.ts index 27f8f2838fc..6c2d32b69aa 100644 --- a/packages/swapper/src/swappers/JupiterSwapper/swapperApi/getTradeRate.ts +++ b/packages/swapper/src/swappers/JupiterSwapper/swapperApi/getTradeRate.ts @@ -10,12 +10,11 @@ import { } from '@shapeshiftoss/caip' import type { GetFeeDataInput } from '@shapeshiftoss/chain-adapters' import type { KnownChainIds } from '@shapeshiftoss/types' -import { bnOrZero, convertDecimalPercentageToBasisPoints } from '@shapeshiftoss/utils' +import { bn, bnOrZero, convertDecimalPercentageToBasisPoints } from '@shapeshiftoss/utils' import type { Result } from '@sniptt/monads' import { Err, Ok } from '@sniptt/monads' import { v4 as uuid } from 'uuid' -import { getDefaultSlippageDecimalPercentageForSwapper } from '../../..' import type { GetTradeRateInput, ProtocolFee, @@ -24,7 +23,7 @@ import type { TradeRate, } from '../../../types' import { SwapperName, TradeQuoteError } from '../../../types' -import { getRate, makeSwapErrorRight } from '../../../utils' +import { getInputOutputRate, makeSwapErrorRight } from '../../../utils' import { SOLANA_RANDOM_ADDRESS } from '../utils/constants' import { getJupiterPrice, isSupportedChainId } from '../utils/helpers' @@ -39,7 +38,7 @@ export const getTradeRate = async ( affiliateBps, receiveAddress, accountNumber, - slippageTolerancePercentageDecimal, + slippageTolerancePercentageDecimal: _slippageTolerancePercentageDecimal, } = input const { assetsById } = deps @@ -81,10 +80,9 @@ export const getTradeRate = async ( destinationAsset: buyAsset.assetId === solAssetId ? wrappedSolAssetId : buyAsset.assetId, commissionBps: affiliateBps, amount: sellAmount, - slippageBps: convertDecimalPercentageToBasisPoints( - slippageTolerancePercentageDecimal ?? - getDefaultSlippageDecimalPercentageForSwapper(SwapperName.Jupiter), - ).toFixed(), + slippageBps: _slippageTolerancePercentageDecimal + ? convertDecimalPercentageToBasisPoints(_slippageTolerancePercentageDecimal).toFixed() + : undefined, }) if (maybePriceResponse.isErr()) { @@ -96,7 +94,7 @@ export const getTradeRate = async ( ) } - const { data: quoteResponse } = maybePriceResponse.unwrap() + const { data: priceResponse } = maybePriceResponse.unwrap() const getFeeData = async () => { const sellAdapter = deps.assertGetSolanaChainAdapter(sellAsset.chainId) @@ -116,7 +114,7 @@ export const getTradeRate = async ( return { networkFeeCryptoBaseUnit: fast.txFee } } - const protocolFees: Record = quoteResponse.routePlan.reduce( + const protocolFees: Record = priceResponse.routePlan.reduce( (acc, route) => { const feeAssetId = toAssetId({ assetReference: route.swapInfo.feeMint, @@ -141,42 +139,41 @@ export const getTradeRate = async ( {} as Record, ) - const getQuoteRate = (sellAmountCryptoBaseUnit: string, buyAmountCryptoBaseUnit: string) => { - return getRate({ - sellAmountCryptoBaseUnit, - buyAmountCryptoBaseUnit, - sellAsset, - buyAsset, - }) - } - const rates: TradeRate[] = [] const feeData = await getFeeData() - const rate = getQuoteRate(quoteResponse.inAmount, quoteResponse.outAmount) + const inputOutputRate = getInputOutputRate({ + sellAmountCryptoBaseUnit: priceResponse.inAmount, + buyAmountCryptoBaseUnit: priceResponse.outAmount, + sellAsset, + buyAsset, + }) + + const slippageTolerancePercentageDecimal = + // Divide by 100 to get actual decimal percentage from bps + // e.g for 0.5% bps, Jupiter represents this as 50. 50/100 = 0.5, then we div by 100 again to honour our decimal format e.g 0.5/100 = 0.005 + bn(priceResponse.slippageBps).div(100).div(100).toString() const tradeRate: TradeRate = { id: uuid(), - rate, + rate: inputOutputRate, receiveAddress, potentialAffiliateBps: affiliateBps, affiliateBps, accountNumber, - slippageTolerancePercentageDecimal: - slippageTolerancePercentageDecimal ?? - getDefaultSlippageDecimalPercentageForSwapper(SwapperName.Jupiter), + slippageTolerancePercentageDecimal, steps: [ { - buyAmountBeforeFeesCryptoBaseUnit: quoteResponse.outAmount, - buyAmountAfterFeesCryptoBaseUnit: quoteResponse.outAmount, - sellAmountIncludingProtocolFeesCryptoBaseUnit: quoteResponse.inAmount, - jupiterQuoteResponse: quoteResponse, + buyAmountBeforeFeesCryptoBaseUnit: priceResponse.outAmount, + buyAmountAfterFeesCryptoBaseUnit: priceResponse.outAmount, + sellAmountIncludingProtocolFeesCryptoBaseUnit: priceResponse.inAmount, + jupiterQuoteResponse: priceResponse, feeData: { protocolFees, ...feeData, }, - rate, + rate: inputOutputRate, source: SwapperName.Jupiter, buyAsset, sellAsset, diff --git a/packages/swapper/src/swappers/JupiterSwapper/utils/helpers.ts b/packages/swapper/src/swappers/JupiterSwapper/utils/helpers.ts index eae52dceb79..a6ee7ccf62a 100644 --- a/packages/swapper/src/swappers/JupiterSwapper/utils/helpers.ts +++ b/packages/swapper/src/swappers/JupiterSwapper/utils/helpers.ts @@ -21,7 +21,7 @@ type GetJupiterQuoteArgs = { destinationAsset: string commissionBps: string amount: string - slippageBps: string + slippageBps: string | undefined } type GetJupiterSwapArgs = { @@ -45,7 +45,7 @@ export const getJupiterPrice = ({ `?inputMint=${fromAssetId(sourceAsset).assetReference}` + `&outputMint=${fromAssetId(destinationAsset).assetReference}` + `&amount=${amount}` + - `&slippageBps=${slippageBps}` + + (slippageBps ? `&slippageBps=${slippageBps}` : `&autoSlippage=true`) + `&maxAccounts=${JUPITER_TRANSACTION_MAX_ACCOUNTS}` + `&platformFeeBps=${commissionBps}`, ) diff --git a/packages/swapper/src/swappers/PortalsSwapper/getPortalsTradeQuote/getPortalsTradeQuote.ts b/packages/swapper/src/swappers/PortalsSwapper/getPortalsTradeQuote/getPortalsTradeQuote.ts index c116b9c0732..ec1a76b9522 100644 --- a/packages/swapper/src/swappers/PortalsSwapper/getPortalsTradeQuote/getPortalsTradeQuote.ts +++ b/packages/swapper/src/swappers/PortalsSwapper/getPortalsTradeQuote/getPortalsTradeQuote.ts @@ -16,7 +16,7 @@ import type { TradeQuote, } from '../../../types' import { SwapperName, TradeQuoteError } from '../../../types' -import { getRate, makeSwapErrorRight } from '../../../utils' +import { getInputOutputRate, makeSwapErrorRight } from '../../../utils' import { getTreasuryAddressFromChainId, isNativeEvmAsset } from '../../utils/helpers/helpers' import { chainIdToPortalsNetwork } from '../constants' import { fetchPortalsTradeOrder } from '../utils/fetchPortalsTradeOrder' @@ -135,7 +135,7 @@ export async function getPortalsTradeQuote( if (!tx) throw new Error('Portals Tx simulation failed upstream') - const rate = getRate({ + const inputOutputRate = getInputOutputRate({ sellAmountCryptoBaseUnit: input.sellAmountIncludingProtocolFeesCryptoBaseUnit, buyAmountCryptoBaseUnit: buyAmountAfterFeesCryptoBaseUnit, sellAsset, @@ -162,13 +162,13 @@ export async function getPortalsTradeQuote( receiveAddress: input.receiveAddress, affiliateBps, potentialAffiliateBps, - rate, + rate: inputOutputRate, slippageTolerancePercentageDecimal, steps: [ { accountNumber, allowanceContract, - rate, + rate: inputOutputRate, buyAsset, sellAsset, buyAmountBeforeFeesCryptoBaseUnit, diff --git a/packages/swapper/src/swappers/PortalsSwapper/getPortalsTradeRate/getPortalsTradeRate.tsx b/packages/swapper/src/swappers/PortalsSwapper/getPortalsTradeRate/getPortalsTradeRate.tsx index 43ac4d97414..11c6f7833fa 100644 --- a/packages/swapper/src/swappers/PortalsSwapper/getPortalsTradeRate/getPortalsTradeRate.tsx +++ b/packages/swapper/src/swappers/PortalsSwapper/getPortalsTradeRate/getPortalsTradeRate.tsx @@ -17,7 +17,7 @@ import type { TradeRate, } from '../../../types' import { SwapperName, TradeQuoteError } from '../../../types' -import { getRate, makeSwapErrorRight } from '../../../utils' +import { getInputOutputRate, makeSwapErrorRight } from '../../../utils' import { isNativeEvmAsset } from '../../utils/helpers/helpers' import { chainIdToPortalsNetwork } from '../constants' import { fetchPortalsTradeEstimate } from '../utils/fetchPortalsTradeOrder' @@ -113,7 +113,7 @@ export async function getPortalsTradeRate( }) // Use the quote estimate endpoint to get a quote without a wallet - const rate = getRate({ + const inputOutputRate = getInputOutputRate({ sellAmountCryptoBaseUnit: input.sellAmountIncludingProtocolFeesCryptoBaseUnit, buyAmountCryptoBaseUnit: quoteEstimateResponse?.context.outputAmount, sellAsset, @@ -137,14 +137,14 @@ export async function getPortalsTradeRate( receiveAddress: undefined, affiliateBps, potentialAffiliateBps, - rate, + rate: inputOutputRate, slippageTolerancePercentageDecimal, steps: [ { estimatedExecutionTimeMs: undefined, // Portals doesn't provide this info allowanceContract, accountNumber, - rate, + rate: inputOutputRate, buyAsset, sellAsset, // Before slippage on the right vs. before fees on the left is not a mistake. diff --git a/packages/swapper/src/utils.ts b/packages/swapper/src/utils.ts index cc0f76dfedc..f2cc3dd2449 100644 --- a/packages/swapper/src/utils.ts +++ b/packages/swapper/src/utils.ts @@ -286,7 +286,7 @@ export const checkEvmSwapStatus = async ({ } } -export const getRate = ({ +export const getInputOutputRate = ({ sellAmountCryptoBaseUnit, buyAmountCryptoBaseUnit, sellAsset, diff --git a/src/components/MultiHopTrade/components/SharedTradeInput/SharedSlippagePopover.tsx b/src/components/MultiHopTrade/components/SharedTradeInput/SharedSlippagePopover.tsx index a2e0d042ddb..e77ebe82cee 100644 --- a/src/components/MultiHopTrade/components/SharedTradeInput/SharedSlippagePopover.tsx +++ b/src/components/MultiHopTrade/components/SharedTradeInput/SharedSlippagePopover.tsx @@ -38,7 +38,7 @@ const focusStyle = { '&[aria-invalid=true]': { borderColor: 'red.500' } } const faGear = type SharedSlippagePopoverProps = { - defaultSlippagePercentage: string + defaultSlippagePercentage: string | undefined isDisabled?: boolean quoteSlippagePercentage: string | undefined tooltipTranslation?: string diff --git a/src/state/slices/tradeQuoteSlice/selectors.ts b/src/state/slices/tradeQuoteSlice/selectors.ts index d01d2040f9f..4a937f4ffb4 100644 --- a/src/state/slices/tradeQuoteSlice/selectors.ts +++ b/src/state/slices/tradeQuoteSlice/selectors.ts @@ -4,6 +4,7 @@ import type { ProtocolFee, SupportedTradeQuoteStepIndex, TradeQuote } from '@sha import { getDefaultSlippageDecimalPercentageForSwapper, getHopByIndex, + isAutoSlippageSupportedBySwapper, SwapperName, } from '@shapeshiftoss/swapper' import type { Asset } from '@shapeshiftoss/types' @@ -466,11 +467,15 @@ export const selectTotalNetworkFeeUserCurrency: Selector = createSelector( - selectActiveSwapperName, - activeSwapperName => - bn(getDefaultSlippageDecimalPercentageForSwapper(activeSwapperName)).times(100).toString(), -) +export const selectDefaultSlippagePercentage: Selector = + createSelector(selectActiveSwapperName, activeSwapperName => { + if (!activeSwapperName) return undefined + // Auto-slippage means we do not have, nor do we ever want to have a default + if (isAutoSlippageSupportedBySwapper(activeSwapperName)) return undefined + return bn(getDefaultSlippageDecimalPercentageForSwapper(activeSwapperName)) + .times(100) + .toString() + }) // Returns the trade slippage in priority order: user preference, quote derived, default export const selectTradeSlippagePercentageDecimal: Selector = createSelector( From fa7bc8b36ae8fe4767b433a50ae130013bf985ee Mon Sep 17 00:00:00 2001 From: gomes <17035424+gomesalexandre@users.noreply.github.com> Date: Tue, 3 Dec 2024 23:15:09 +0800 Subject: [PATCH 5/9] feat: enable chainflip flag (#8201) --- .env.base | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.env.base b/.env.base index 70b7475d4a3..e95f0a6cd67 100644 --- a/.env.base +++ b/.env.base @@ -65,7 +65,7 @@ REACT_APP_FEATURE_READ_ONLY_ASSETS=true REACT_APP_FEATURE_SWAPPER_SOLANA=true # Swapper feature flags - other .env files will override these -REACT_APP_FEATURE_CHAINFLIP_SWAP=false +REACT_APP_FEATURE_CHAINFLIP_SWAP=true REACT_APP_FEATURE_CHAINFLIP_SWAP_DCA=false REACT_APP_FEATURE_COWSWAP=true REACT_APP_FEATURE_LIFI_SWAP=true From cc235da2d18184f141df50d18c8edc1eb9d2b9cc Mon Sep 17 00:00:00 2001 From: NeOMakinG <14963751+NeOMakinG@users.noreply.github.com> Date: Tue, 3 Dec 2024 23:37:23 +0800 Subject: [PATCH 6/9] fix: asset list overflowing because of large numbers (#8254) --- src/components/Amount/Amount.tsx | 3 +++ src/hooks/useLocaleFormatter/useLocaleFormatter.ts | 10 ++++++++++ .../Dashboard/components/AccountList/AccountTable.tsx | 2 ++ 3 files changed, 15 insertions(+) diff --git a/src/components/Amount/Amount.tsx b/src/components/Amount/Amount.tsx index f8ef3d27af4..80c7268ffa5 100644 --- a/src/components/Amount/Amount.tsx +++ b/src/components/Amount/Amount.tsx @@ -12,6 +12,7 @@ export type AmountProps = { suffix?: string omitDecimalTrailingZeros?: boolean abbreviated?: boolean + truncateLargeNumbers?: boolean maximumFractionDigits?: number } & TextProps @@ -60,6 +61,7 @@ const Crypto = ({ suffix, omitDecimalTrailingZeros = false, abbreviated = false, + truncateLargeNumbers = false, ...props }: CryptoAmountProps) => { const { @@ -70,6 +72,7 @@ const Crypto = ({ maximumFractionDigits, omitDecimalTrailingZeros, abbreviated, + truncateLargeNumbers, }) return ( diff --git a/src/hooks/useLocaleFormatter/useLocaleFormatter.ts b/src/hooks/useLocaleFormatter/useLocaleFormatter.ts index 4b80d7955f4..d9d079fb330 100644 --- a/src/hooks/useLocaleFormatter/useLocaleFormatter.ts +++ b/src/hooks/useLocaleFormatter/useLocaleFormatter.ts @@ -1,3 +1,4 @@ +import truncate from 'lodash/truncate' import { useCallback, useMemo } from 'react' import type { BigNumber } from 'lib/bignumber/bignumber' import { bnOrZero } from 'lib/bignumber/bignumber' @@ -6,6 +7,7 @@ import { selectCurrencyFormat, selectSelectedCurrency } from 'state/slices/selec import { useAppSelector } from 'state/store' const CRYPTO_PRECISION = 8 +const MAXIMUM_LARGE_NUMBER_CHARS = 18 export type NumberValue = number | string export type DateValue = number | string | Date @@ -29,6 +31,7 @@ export type NumberFormatOptions = { fiatType?: string abbreviated?: boolean omitDecimalTrailingZeros?: boolean + truncateLargeNumbers?: boolean } export type NumberFormatter = { @@ -190,6 +193,13 @@ export const useLocaleFormatter = (args?: useLocaleFormatterArgs): NumberFormatt symbol = 'BTC', options?: NumberFormatOptions, ): string => { + if ( + options?.truncateLargeNumbers && + bnOrZero(num).toFixed(0).length > MAXIMUM_LARGE_NUMBER_CHARS + ) { + return `${truncate(bnOrZero(num).toFixed(0), { length: 16, omission: '...' })} ${symbol}` + } + const maximumFractionDigits = options?.maximumFractionDigits !== undefined ? options.maximumFractionDigits diff --git a/src/pages/Dashboard/components/AccountList/AccountTable.tsx b/src/pages/Dashboard/components/AccountList/AccountTable.tsx index 0f084c074aa..cddddf58b05 100644 --- a/src/pages/Dashboard/components/AccountList/AccountTable.tsx +++ b/src/pages/Dashboard/components/AccountList/AccountTable.tsx @@ -10,6 +10,7 @@ import { import type { Property } from 'csstype' import { range, truncate } from 'lodash' import { memo, useCallback, useMemo } from 'react' +import { isMobile } from 'react-device-detect' import { useSelector } from 'react-redux' import { useHistory } from 'react-router-dom' import type { Column, Row } from 'react-table' @@ -76,6 +77,7 @@ export const AccountTable = memo(() => { data-test={`account-row-asset-crypto-${row.original.symbol}`} value={row.original.cryptoAmount} symbol={truncate(row.original.symbol, { length: 6 })} + truncateLargeNumbers={isMobile ? true : false} /> ), From 35c005c0232ef9b3b66d64f50fa9f4589906e99b Mon Sep 17 00:00:00 2001 From: NeOMakinG <14963751+NeOMakinG@users.noreply.github.com> Date: Wed, 4 Dec 2024 01:45:09 +0800 Subject: [PATCH 7/9] fix: update trade complete screen (#8240) --- src/assets/translations/en/main.json | 2 +- src/assets/translations/fr/main.json | 2 +- src/components/AnimatedCheck.tsx | 76 ++++++++++++++++ .../MultiHopTradeConfirm.tsx | 18 +++- .../components/TradeSuccess/TradeSuccess.tsx | 87 +++++++++++-------- 5 files changed, 142 insertions(+), 43 deletions(-) create mode 100644 src/components/AnimatedCheck.tsx diff --git a/src/assets/translations/en/main.json b/src/assets/translations/en/main.json index 14e887802a7..f460629804b 100644 --- a/src/assets/translations/en/main.json +++ b/src/assets/translations/en/main.json @@ -994,7 +994,7 @@ "allowanceApprovalTxName": "Allowance approval tx:", "tradeComplete": "You now have %{cryptoAmountFormatted} in your wallet on %{chainName}.", "doAnotherTrade": "Do another trade", - "showDetails": "Show Details", + "summary": "Trade Summary", "transactionSuccessful": "Transaction successful, waiting for confirmations", "temp": { "tradeSuccess": "Trade complete", diff --git a/src/assets/translations/fr/main.json b/src/assets/translations/fr/main.json index 57aade6aca2..e58b895dce2 100644 --- a/src/assets/translations/fr/main.json +++ b/src/assets/translations/fr/main.json @@ -993,7 +993,7 @@ "allowanceApprovalTxName": "Tx. d'autorisation d'allocation :", "tradeComplete": "Vous disposez maintenant de %{cryptoAmountFormatted} dans votre porte-monnaie sur %{chainName}.", "doAnotherTrade": "Faire un autre échange", - "showDetails": "Afficher les détails", + "summary": "Afficher le sommaire", "transactionSuccessful": "Transaction réussie, en attente de confirmations", "temp": { "tradeSuccess": "Échange terminé", diff --git a/src/components/AnimatedCheck.tsx b/src/components/AnimatedCheck.tsx new file mode 100644 index 00000000000..0678f11b342 --- /dev/null +++ b/src/components/AnimatedCheck.tsx @@ -0,0 +1,76 @@ +import type { BoxProps } from '@chakra-ui/react' +import { Box } from '@chakra-ui/react' +import { motion } from 'framer-motion' +import { useMemo } from 'react' + +export const AnimatedCheck = ({ + defaultDuration = 1000, + boxSize = 24, + color = 'green.500', +}: { + defaultDuration?: number + boxSize?: BoxProps['boxSize'] + color?: BoxProps['color'] +}) => { + const placeholderDuration = useMemo(() => defaultDuration / 1000 + 2, [defaultDuration]) + + const draw = useMemo(() => { + const drawDelay = placeholderDuration / 1.5 > 10 ? 5 : placeholderDuration / 1.5 + return { + hidden: { pathLength: 0, opacity: 0 }, + visible: () => ({ + pathLength: 1, + opacity: 1, + transition: { + pathLength: { + delay: drawDelay, + type: 'spring', + duration: 2, + bounce: 0, + }, + opacity: { delay: drawDelay, duration: 2 }, + }, + }), + } + }, [placeholderDuration]) + + const border = useMemo(() => { + return { + hidden: { pathLength: 0 }, + visible: () => ({ + pathLength: 1, + transition: { + pathLength: { + type: 'spring', + duration: placeholderDuration > 10 ? 10 : placeholderDuration, + bounce: 0, + }, + }, + }), + } + }, [placeholderDuration]) + + return ( + + + {/* Outer circle */} + + + {/* Checkmark */} + + + + ) +} diff --git a/src/components/MultiHopTrade/components/MultiHopTradeConfirm/MultiHopTradeConfirm.tsx b/src/components/MultiHopTrade/components/MultiHopTradeConfirm/MultiHopTradeConfirm.tsx index 58f7e8e21d7..b0f0dcfba8a 100644 --- a/src/components/MultiHopTrade/components/MultiHopTradeConfirm/MultiHopTradeConfirm.tsx +++ b/src/components/MultiHopTrade/components/MultiHopTradeConfirm/MultiHopTradeConfirm.tsx @@ -10,9 +10,11 @@ import { TradeSlideTransition } from 'components/MultiHopTrade/TradeSlideTransit import { TradeRoutePaths } from 'components/MultiHopTrade/types' import { Text } from 'components/Text' import { bnOrZero } from 'lib/bignumber/bignumber' +import { fromBaseUnit } from 'lib/math' import { selectActiveQuote, selectConfirmedTradeExecutionState, + selectLastHop, } from 'state/slices/tradeQuoteSlice/selectors' import { tradeQuoteSlice } from 'state/slices/tradeQuoteSlice/tradeQuoteSlice' import { TradeExecutionState } from 'state/slices/tradeQuoteSlice/types' @@ -38,6 +40,7 @@ export const MultiHopTradeConfirm = memo(() => { const [shouldShowWarningAcknowledgement, setShouldShowWarningAcknowledgement] = useState(false) const activeQuote = useAppSelector(selectActiveQuote) const { isModeratePriceImpact, priceImpactPercentage } = usePriceImpact(activeQuote) + const lastHop = useAppSelector(selectLastHop) const initialActiveTradeIdRef = useRef(activeQuote?.id ?? '') @@ -136,15 +139,22 @@ export const MultiHopTradeConfirm = memo(() => { - {isTradeComplete ? ( + {isTradeComplete && activeQuote && lastHop ? ( void children: JSX.Element titleTranslation?: string | [string, InterpolationOptions] - descriptionTranslation?: string | [string, InterpolationOptions] + sellAsset?: Asset + buyAsset?: Asset + sellAmountCryptoPrecision?: string + buyAmountCryptoPrecision?: string } -const pairProps = { showFirst: true } - export const TradeSuccess = ({ handleBack, titleTranslation, - descriptionTranslation, children, + sellAmountCryptoPrecision, + sellAsset, + buyAsset, + buyAmountCryptoPrecision, }: TradeSuccessProps) => { const translate = useTranslate() @@ -42,29 +52,32 @@ export const TradeSuccess = ({ const lastHop = useAppSelector(selectLastHop) - const subText = useMemo(() => { - if (!lastHop) return '' - - const manager = getChainAdapterManager() - const adapter = manager.get(lastHop.buyAsset.chainId) - - if (!adapter) return '' + const AmountsLine = useCallback(() => { + if (!(sellAsset && buyAsset)) return null + if (!(sellAmountCryptoPrecision && buyAmountCryptoPrecision)) return null - const chainName = adapter.getDisplayName() - - if (descriptionTranslation) - return typeof descriptionTranslation === 'string' - ? translate(descriptionTranslation, { - symbol: lastHop.buyAsset.symbol, - chainName, - }) - : translate(...descriptionTranslation) - - return translate('trade.temp.tradeComplete', { - symbol: lastHop.buyAsset.symbol, - chainName, - }) - }, [lastHop, translate, descriptionTranslation]) + return ( + + + + + + + + + + + + ) + }, [sellAsset, buyAsset, sellAmountCryptoPrecision, buyAmountCryptoPrecision]) if (!lastHop) return null @@ -72,13 +85,13 @@ export const TradeSuccess = ({ <> - - - - - {subText} - - + + + + + + + @@ -88,7 +101,7 @@ export const TradeSuccess = ({ From 9918e89e06b2dffe58b72cf0900fa070b8eaf343 Mon Sep 17 00:00:00 2001 From: kevin <35275952+kaladinlight@users.noreply.github.com> Date: Tue, 3 Dec 2024 18:26:42 -0700 Subject: [PATCH 8/9] feat: propagate chain adapter errors (#8258) Co-authored-by: woody <125113430+woodenfurniture@users.noreply.github.com> --- .../src/evm/base/BaseChainAdapter.ts | 85 ++++++++------ .../src/evm/bnbsmartchain/BscChainAdapter.ts | 107 ++++++++++-------- .../src/evm/optimism/OptimismChainAdapter.ts | 85 ++++++++------ .../hooks/useTradeExecution.tsx | 10 +- .../{useErrorToast.ts => useErrorToast.tsx} | 14 ++- 5 files changed, 178 insertions(+), 123 deletions(-) rename src/hooks/useErrorToast/{useErrorToast.ts => useErrorToast.tsx} (52%) diff --git a/packages/chain-adapters/src/evm/base/BaseChainAdapter.ts b/packages/chain-adapters/src/evm/base/BaseChainAdapter.ts index 5127770f954..95919c2a0f2 100644 --- a/packages/chain-adapters/src/evm/base/BaseChainAdapter.ts +++ b/packages/chain-adapters/src/evm/base/BaseChainAdapter.ts @@ -5,6 +5,7 @@ import { KnownChainIds } from '@shapeshiftoss/types' import * as unchained from '@shapeshiftoss/unchained-client' import BigNumber from 'bignumber.js' +import { ErrorHandler } from '../../error/ErrorHandler' import type { FeeDataEstimate, GetFeeDataInput } from '../../types' import { ChainAdapterDisplayName } from '../../types' import { bnOrZero } from '../../utils' @@ -64,48 +65,60 @@ export class ChainAdapter extends EvmBaseAdapter { } async getGasFeeData(): Promise { - const { fast, average, slow, l1GasPrice } = await this.api.getGasFees() - - return { - fast: { ...fast, l1GasPrice }, - average: { ...average, l1GasPrice }, - slow: { ...slow, l1GasPrice }, + try { + const { fast, average, slow, l1GasPrice } = await this.api.getGasFees() + + return { + fast: { ...fast, l1GasPrice }, + average: { ...average, l1GasPrice }, + slow: { ...slow, l1GasPrice }, + } + } catch (err) { + return ErrorHandler(err, { + translation: 'chainAdapters.errors.getGasFeeData', + }) } } async getFeeData( input: GetFeeDataInput, ): Promise> { - const req = await this.buildEstimateGasRequest(input) - - const { gasLimit, l1GasLimit } = await this.api.estimateGas(req) - const { fast, average, slow } = await this.getGasFeeData() - - return { - fast: { - txFee: bnOrZero( - BigNumber.max(fast.gasPrice, fast.maxFeePerGas ?? 0) - .times(gasLimit) - .plus(bnOrZero(fast.l1GasPrice).times(l1GasLimit)), - ).toFixed(0), - chainSpecific: { gasLimit, l1GasLimit, ...fast }, - }, - average: { - txFee: bnOrZero( - BigNumber.max(average.gasPrice, average.maxFeePerGas ?? 0) - .times(gasLimit) - .plus(bnOrZero(average.l1GasPrice).times(l1GasLimit)), - ).toFixed(0), - chainSpecific: { gasLimit, l1GasLimit, ...average }, - }, - slow: { - txFee: bnOrZero( - BigNumber.max(slow.gasPrice, slow.maxFeePerGas ?? 0) - .times(gasLimit) - .plus(bnOrZero(slow.l1GasPrice).times(l1GasLimit)), - ).toFixed(0), - chainSpecific: { gasLimit, l1GasLimit, ...slow }, - }, + try { + const req = await this.buildEstimateGasRequest(input) + + const { gasLimit, l1GasLimit } = await this.api.estimateGas(req) + const { fast, average, slow } = await this.getGasFeeData() + + return { + fast: { + txFee: bnOrZero( + BigNumber.max(fast.gasPrice, fast.maxFeePerGas ?? 0) + .times(gasLimit) + .plus(bnOrZero(fast.l1GasPrice).times(l1GasLimit)), + ).toFixed(0), + chainSpecific: { gasLimit, l1GasLimit, ...fast }, + }, + average: { + txFee: bnOrZero( + BigNumber.max(average.gasPrice, average.maxFeePerGas ?? 0) + .times(gasLimit) + .plus(bnOrZero(average.l1GasPrice).times(l1GasLimit)), + ).toFixed(0), + chainSpecific: { gasLimit, l1GasLimit, ...average }, + }, + slow: { + txFee: bnOrZero( + BigNumber.max(slow.gasPrice, slow.maxFeePerGas ?? 0) + .times(gasLimit) + .plus(bnOrZero(slow.l1GasPrice).times(l1GasLimit)), + ).toFixed(0), + chainSpecific: { gasLimit, l1GasLimit, ...slow }, + }, + } + } catch (err) { + return ErrorHandler(err, { + translation: 'chainAdapters.errors.getFeeData', + }) } } } diff --git a/packages/chain-adapters/src/evm/bnbsmartchain/BscChainAdapter.ts b/packages/chain-adapters/src/evm/bnbsmartchain/BscChainAdapter.ts index d7fe93df7c9..09005f36d37 100644 --- a/packages/chain-adapters/src/evm/bnbsmartchain/BscChainAdapter.ts +++ b/packages/chain-adapters/src/evm/bnbsmartchain/BscChainAdapter.ts @@ -5,6 +5,7 @@ import { KnownChainIds } from '@shapeshiftoss/types' import * as unchained from '@shapeshiftoss/unchained-client' import BigNumber from 'bignumber.js' +import { ErrorHandler } from '../../error/ErrorHandler' import type { FeeDataEstimate, GetFeeDataInput } from '../../types' import { ChainAdapterDisplayName } from '../../types' import { bn, bnOrZero } from '../../utils/bignumber' @@ -63,57 +64,69 @@ export class ChainAdapter extends EvmBaseAdapter { - const { fast, average, slow, baseFeePerGas } = await this.providers.http.getGasFees() - return { fast, average, slow, baseFeePerGas } + try { + const { fast, average, slow, baseFeePerGas } = await this.providers.http.getGasFees() + return { fast, average, slow, baseFeePerGas } + } catch (err) { + return ErrorHandler(err, { + translation: 'chainAdapters.errors.getGasFeeData', + }) + } } async getFeeData( input: GetFeeDataInput, ): Promise> { - const req = await this.buildEstimateGasRequest(input) - - const { gasLimit } = await this.providers.http.estimateGas(req) - const { fast, average, slow, baseFeePerGas } = await this.getGasFeeData() - - // Binance official JSON-RPC endpoint has a minimum enforced gas price of 3 Gwei - const MIN_GAS_PRICE = '3000000000' - - ;[fast, average, slow].forEach(estimate => { - estimate.gasPrice = BigNumber.max(estimate.gasPrice, MIN_GAS_PRICE).toFixed(0) - - if (estimate.maxFeePerGas) { - estimate.maxFeePerGas = BigNumber.max(estimate.maxFeePerGas, MIN_GAS_PRICE).toFixed(0) - } - - if (estimate.maxPriorityFeePerGas) { - estimate.maxPriorityFeePerGas = BigNumber.max( - bn(estimate.maxPriorityFeePerGas).plus(bnOrZero(baseFeePerGas)), - MIN_GAS_PRICE, - ) - .minus(bnOrZero(baseFeePerGas)) - .toFixed(0) - } - }) - - return { - fast: { - txFee: bnOrZero( - BigNumber.max(fast.gasPrice, fast.maxFeePerGas ?? 0).times(gasLimit), - ).toFixed(0), - chainSpecific: { gasLimit, ...fast, gasPrice: fast.gasPrice }, - }, - average: { - txFee: bnOrZero( - BigNumber.max(average.gasPrice, average.maxFeePerGas ?? 0).times(gasLimit), - ).toFixed(0), - chainSpecific: { gasLimit, ...average, gasPrice: average.gasPrice }, - }, - slow: { - txFee: bnOrZero( - BigNumber.max(slow.gasPrice, slow.maxFeePerGas ?? 0).times(gasLimit), - ).toFixed(0), - chainSpecific: { gasLimit, ...slow, gasPrice: slow.gasPrice }, - }, - } as FeeDataEstimate + try { + const req = await this.buildEstimateGasRequest(input) + + const { gasLimit } = await this.providers.http.estimateGas(req) + const { fast, average, slow, baseFeePerGas } = await this.getGasFeeData() + + // Binance official JSON-RPC endpoint has a minimum enforced gas price of 3 Gwei + const MIN_GAS_PRICE = '3000000000' + + ;[fast, average, slow].forEach(estimate => { + estimate.gasPrice = BigNumber.max(estimate.gasPrice, MIN_GAS_PRICE).toFixed(0) + + if (estimate.maxFeePerGas) { + estimate.maxFeePerGas = BigNumber.max(estimate.maxFeePerGas, MIN_GAS_PRICE).toFixed(0) + } + + if (estimate.maxPriorityFeePerGas) { + estimate.maxPriorityFeePerGas = BigNumber.max( + bn(estimate.maxPriorityFeePerGas).plus(bnOrZero(baseFeePerGas)), + MIN_GAS_PRICE, + ) + .minus(bnOrZero(baseFeePerGas)) + .toFixed(0) + } + }) + + return { + fast: { + txFee: bnOrZero( + BigNumber.max(fast.gasPrice, fast.maxFeePerGas ?? 0).times(gasLimit), + ).toFixed(0), + chainSpecific: { gasLimit, ...fast, gasPrice: fast.gasPrice }, + }, + average: { + txFee: bnOrZero( + BigNumber.max(average.gasPrice, average.maxFeePerGas ?? 0).times(gasLimit), + ).toFixed(0), + chainSpecific: { gasLimit, ...average, gasPrice: average.gasPrice }, + }, + slow: { + txFee: bnOrZero( + BigNumber.max(slow.gasPrice, slow.maxFeePerGas ?? 0).times(gasLimit), + ).toFixed(0), + chainSpecific: { gasLimit, ...slow, gasPrice: slow.gasPrice }, + }, + } as FeeDataEstimate + } catch (err) { + return ErrorHandler(err, { + translation: 'chainAdapters.errors.getFeeData', + }) + } } } diff --git a/packages/chain-adapters/src/evm/optimism/OptimismChainAdapter.ts b/packages/chain-adapters/src/evm/optimism/OptimismChainAdapter.ts index c2804599ed3..a50beb057d6 100644 --- a/packages/chain-adapters/src/evm/optimism/OptimismChainAdapter.ts +++ b/packages/chain-adapters/src/evm/optimism/OptimismChainAdapter.ts @@ -5,6 +5,7 @@ import { KnownChainIds } from '@shapeshiftoss/types' import * as unchained from '@shapeshiftoss/unchained-client' import BigNumber from 'bignumber.js' +import { ErrorHandler } from '../../error/ErrorHandler' import type { FeeDataEstimate, GetFeeDataInput } from '../../types' import { ChainAdapterDisplayName } from '../../types' import { bnOrZero } from '../../utils' @@ -66,48 +67,60 @@ export class ChainAdapter extends EvmBaseAdapter } async getGasFeeData(): Promise { - const { fast, average, slow, l1GasPrice } = await this.api.getGasFees() - - return { - fast: { ...fast, l1GasPrice }, - average: { ...average, l1GasPrice }, - slow: { ...slow, l1GasPrice }, + try { + const { fast, average, slow, l1GasPrice } = await this.api.getGasFees() + + return { + fast: { ...fast, l1GasPrice }, + average: { ...average, l1GasPrice }, + slow: { ...slow, l1GasPrice }, + } + } catch (err) { + return ErrorHandler(err, { + translation: 'chainAdapters.errors.getGasFeeData', + }) } } async getFeeData( input: GetFeeDataInput, ): Promise> { - const req = await this.buildEstimateGasRequest(input) - - const { gasLimit, l1GasLimit } = await this.api.estimateGas(req) - const { fast, average, slow } = await this.getGasFeeData() - - return { - fast: { - txFee: bnOrZero( - BigNumber.max(fast.gasPrice, fast.maxFeePerGas ?? 0) - .times(gasLimit) - .plus(bnOrZero(fast.l1GasPrice).times(l1GasLimit)), - ).toFixed(0), - chainSpecific: { gasLimit, l1GasLimit, ...fast }, - }, - average: { - txFee: bnOrZero( - BigNumber.max(average.gasPrice, average.maxFeePerGas ?? 0) - .times(gasLimit) - .plus(bnOrZero(average.l1GasPrice).times(l1GasLimit)), - ).toFixed(0), - chainSpecific: { gasLimit, l1GasLimit, ...average }, - }, - slow: { - txFee: bnOrZero( - BigNumber.max(slow.gasPrice, slow.maxFeePerGas ?? 0) - .times(gasLimit) - .plus(bnOrZero(slow.l1GasPrice).times(l1GasLimit)), - ).toFixed(0), - chainSpecific: { gasLimit, l1GasLimit, ...slow }, - }, + try { + const req = await this.buildEstimateGasRequest(input) + + const { gasLimit, l1GasLimit } = await this.api.estimateGas(req) + const { fast, average, slow } = await this.getGasFeeData() + + return { + fast: { + txFee: bnOrZero( + BigNumber.max(fast.gasPrice, fast.maxFeePerGas ?? 0) + .times(gasLimit) + .plus(bnOrZero(fast.l1GasPrice).times(l1GasLimit)), + ).toFixed(0), + chainSpecific: { gasLimit, l1GasLimit, ...fast }, + }, + average: { + txFee: bnOrZero( + BigNumber.max(average.gasPrice, average.maxFeePerGas ?? 0) + .times(gasLimit) + .plus(bnOrZero(average.l1GasPrice).times(l1GasLimit)), + ).toFixed(0), + chainSpecific: { gasLimit, l1GasLimit, ...average }, + }, + slow: { + txFee: bnOrZero( + BigNumber.max(slow.gasPrice, slow.maxFeePerGas ?? 0) + .times(gasLimit) + .plus(bnOrZero(slow.l1GasPrice).times(l1GasLimit)), + ).toFixed(0), + chainSpecific: { gasLimit, l1GasLimit, ...slow }, + }, + } + } catch (err) { + return ErrorHandler(err, { + translation: 'chainAdapters.errors.getFeeData', + }) } } } diff --git a/src/components/MultiHopTrade/components/MultiHopTradeConfirm/hooks/useTradeExecution.tsx b/src/components/MultiHopTrade/components/MultiHopTradeConfirm/hooks/useTradeExecution.tsx index 21da049bfc4..90bc66929b9 100644 --- a/src/components/MultiHopTrade/components/MultiHopTradeConfirm/hooks/useTradeExecution.tsx +++ b/src/components/MultiHopTrade/components/MultiHopTradeConfirm/hooks/useTradeExecution.tsx @@ -1,7 +1,7 @@ import type { StdSignDoc } from '@keplr-wallet/types' import { bchAssetId, CHAIN_NAMESPACE, fromChainId } from '@shapeshiftoss/caip' import type { evm, SignTx, SignTypedDataInput } from '@shapeshiftoss/chain-adapters' -import { toAddressNList } from '@shapeshiftoss/chain-adapters' +import { ChainAdapterError, toAddressNList } from '@shapeshiftoss/chain-adapters' import type { BTCSignTx, ETHSignTypedData, @@ -132,7 +132,13 @@ export const useTradeExecution = ( dispatch(tradeQuoteSlice.actions.setSwapTxPending({ hopIndex, id: confirmedTradeId })) const onFail = (e: unknown) => { - const { message } = (e ?? { message: undefined }) as { message?: string } + const message = (() => { + if (e instanceof ChainAdapterError) { + return translate(e.metadata.translation, e.metadata.options) + } + return (e as Error).message ?? undefined + })() + dispatch( tradeQuoteSlice.actions.setSwapTxMessage({ hopIndex, message, id: confirmedTradeId }), ) diff --git a/src/hooks/useErrorToast/useErrorToast.ts b/src/hooks/useErrorToast/useErrorToast.tsx similarity index 52% rename from src/hooks/useErrorToast/useErrorToast.ts rename to src/hooks/useErrorToast/useErrorToast.tsx index d4e88bc4939..3335d318392 100644 --- a/src/hooks/useErrorToast/useErrorToast.ts +++ b/src/hooks/useErrorToast/useErrorToast.tsx @@ -1,6 +1,9 @@ import { useToast } from '@chakra-ui/react' +import { ChainAdapterError } from '@shapeshiftoss/chain-adapters' import { useCallback } from 'react' import { useTranslate } from 'react-polyglot' +import { InlineCopyButton } from 'components/InlineCopyButton' +import { RawText } from 'components/Text' export const useErrorHandler = () => { const toast = useToast() @@ -8,13 +11,20 @@ export const useErrorHandler = () => { const showErrorToast = useCallback( (error: unknown) => { - const description = translate('common.generalError') + const description = + error instanceof ChainAdapterError + ? translate(error.metadata.translation, error.metadata.options) + : translate('common.generalError') console.error(error) toast({ title: translate('trade.errors.title'), - description, + description: ( + + {description} + + ), status: 'error', duration: 9000, isClosable: true, From 2a32a2fe3f996fe293e005c9447a9c9b8ff96e7a Mon Sep 17 00:00:00 2001 From: kevin <35275952+kaladinlight@users.noreply.github.com> Date: Wed, 4 Dec 2024 10:31:39 -0700 Subject: [PATCH 9/9] chore: turn jupiter and chainflip flags off (#8263) --- .env.base | 4 ++-- .env.dev | 1 + .env.develop | 4 +++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.env.base b/.env.base index e95f0a6cd67..59e2bdb40b3 100644 --- a/.env.base +++ b/.env.base @@ -65,14 +65,14 @@ REACT_APP_FEATURE_READ_ONLY_ASSETS=true REACT_APP_FEATURE_SWAPPER_SOLANA=true # Swapper feature flags - other .env files will override these -REACT_APP_FEATURE_CHAINFLIP_SWAP=true +REACT_APP_FEATURE_CHAINFLIP_SWAP=false REACT_APP_FEATURE_CHAINFLIP_SWAP_DCA=false REACT_APP_FEATURE_COWSWAP=true REACT_APP_FEATURE_LIFI_SWAP=true REACT_APP_FEATURE_THOR_SWAP=true REACT_APP_FEATURE_THOR_SWAP_STREAMING_SWAPS=true REACT_APP_FEATURE_ZRX_SWAP=true -REACT_APP_FEATURE_JUPITER_SWAP=true +REACT_APP_FEATURE_JUPITER_SWAP=false # chat woot REACT_APP_CHATWOOT_TOKEN=jmoXp9BPMSPEYHeJX5YKT15Q diff --git a/.env.dev b/.env.dev index 160e68be569..1a04a7112a2 100644 --- a/.env.dev +++ b/.env.dev @@ -8,6 +8,7 @@ REACT_APP_FEATURE_CHAINFLIP_SWAP=true REACT_APP_FEATURE_CHAINFLIP_SWAP_DCA=false REACT_APP_FEATURE_PUBLIC_TRADE_ROUTE=true REACT_APP_FEATURE_LIMIT_ORDERS=true +REACT_APP_FEATURE_JUPITER_SWAP=true # logging REACT_APP_REDUX_WINDOW=false diff --git a/.env.develop b/.env.develop index 45a2c7236f3..e3c5906fe30 100644 --- a/.env.develop +++ b/.env.develop @@ -5,9 +5,11 @@ REACT_APP_FEATURE_SWAPPER_SOLANA=true # Swapper feature flags -REACT_APP_FEATURE_LIMIT_ORDERS=true REACT_APP_FEATURE_CHAINFLIP_SWAP=true REACT_APP_FEATURE_CHAINFLIP_SWAP_DCA=false +REACT_APP_FEATURE_PUBLIC_TRADE_ROUTE=true +REACT_APP_FEATURE_LIMIT_ORDERS=true +REACT_APP_FEATURE_JUPITER_SWAP=true # mixpanel REACT_APP_MIXPANEL_TOKEN=1c1369f6ea23a6404bac41b42817cc4b