diff --git a/.yarn/patches/gridplus-sdk-npm-4.0.0-0e9f598de2.patch b/.yarn/patches/gridplus-sdk-npm-4.0.0-0e9f598de2.patch new file mode 100644 index 0000000000..aae686e963 --- /dev/null +++ b/.yarn/patches/gridplus-sdk-npm-4.0.0-0e9f598de2.patch @@ -0,0 +1,92 @@ +diff --git a/dist/index.cjs b/dist/index.cjs +index a78eb62001f784924eabc712b1e4234b5ee53c23..7086870ebf44cd239d86e02c23d9f52e9bc9a2f9 100644 +--- a/dist/index.cjs ++++ b/dist/index.cjs +@@ -601,6 +601,7 @@ var EXTERNAL = { + ENCODINGS: { + NONE: 1 /* none */, + SOLANA: 2 /* solana */, ++ COSMOS: 3 /* cosmos */, + EVM: 4 /* evm */, + ETH_DEPOSIT: 5 /* eth_deposit */, + EIP7702_AUTH: 6 /* eip7702_auth */, +@@ -867,7 +868,8 @@ function getFwVersionConst(v) { + c.genericSigning.curveTypes = EXTERNAL.SIGNING.CURVES; + c.genericSigning.encodingTypes = { + NONE: EXTERNAL.SIGNING.ENCODINGS.NONE, +- SOLANA: EXTERNAL.SIGNING.ENCODINGS.SOLANA ++ SOLANA: EXTERNAL.SIGNING.ENCODINGS.SOLANA, ++ COSMOS: EXTERNAL.SIGNING.ENCODINGS.COSMOS + }; + c.getAddressFlags = [ + EXTERNAL.GET_ADDR_FLAGS.ED25519_PUB, +diff --git a/dist/index.d.cts b/dist/index.d.cts +index cb84cb787b10ac0cc86ee3fc2af42f68e79d9ad2..ace42ec7a680da40732e24fab73650b6c89f66f7 100644 +--- a/dist/index.d.cts ++++ b/dist/index.d.cts +@@ -81,6 +81,7 @@ declare const EXTERNAL$1: { + readonly ENCODINGS: { + readonly NONE: LatticeSignEncoding.none; + readonly SOLANA: LatticeSignEncoding.solana; ++ readonly COSMOS: LatticeSignEncoding.cosmos; + readonly EVM: LatticeSignEncoding.evm; + readonly ETH_DEPOSIT: LatticeSignEncoding.eth_deposit; + readonly EIP7702_AUTH: LatticeSignEncoding.eip7702_auth; +@@ -205,6 +206,7 @@ interface GenericSigningData { + encodingTypes: { + NONE: typeof EXTERNAL$1.SIGNING.ENCODINGS.NONE; + SOLANA: typeof EXTERNAL$1.SIGNING.ENCODINGS.SOLANA; ++ COSMOS?: typeof EXTERNAL$1.SIGNING.ENCODINGS.COSMOS; + EVM?: typeof EXTERNAL$1.SIGNING.ENCODINGS.EVM; + }; + } +diff --git a/dist/index.d.ts b/dist/index.d.ts +index cb84cb787b10ac0cc86ee3fc2af42f68e79d9ad2..7870e7670246edb0a16c03f6804e3e2f2964bc3e 100644 +--- a/dist/index.d.ts ++++ b/dist/index.d.ts +@@ -43,6 +43,7 @@ declare enum LatticeSignCurve { + declare enum LatticeSignEncoding { + none = 1, + solana = 2, ++ cosmos = 3, + evm = 4, + eth_deposit = 5, + eip7702_auth = 6, +@@ -81,6 +82,7 @@ declare const EXTERNAL$1: { + readonly ENCODINGS: { + readonly NONE: LatticeSignEncoding.none; + readonly SOLANA: LatticeSignEncoding.solana; ++ readonly COSMOS: LatticeSignEncoding.cosmos; + readonly EVM: LatticeSignEncoding.evm; + readonly ETH_DEPOSIT: LatticeSignEncoding.eth_deposit; + readonly EIP7702_AUTH: LatticeSignEncoding.eip7702_auth; +@@ -205,6 +207,7 @@ interface GenericSigningData { + encodingTypes: { + NONE: typeof EXTERNAL$1.SIGNING.ENCODINGS.NONE; + SOLANA: typeof EXTERNAL$1.SIGNING.ENCODINGS.SOLANA; ++ COSMOS?: typeof EXTERNAL$1.SIGNING.ENCODINGS.COSMOS; + EVM?: typeof EXTERNAL$1.SIGNING.ENCODINGS.EVM; + }; + } +diff --git a/dist/index.mjs b/dist/index.mjs +index 793949dd1f22aec3542aa667b267b02c7c670cb8..ad69e977479e14afa2d138a7fe7c835fe2df64e1 100644 +--- a/dist/index.mjs ++++ b/dist/index.mjs +@@ -527,6 +527,7 @@ var EXTERNAL = { + ENCODINGS: { + NONE: 1 /* none */, + SOLANA: 2 /* solana */, ++ COSMOS: 3 /* cosmos */, + EVM: 4 /* evm */, + ETH_DEPOSIT: 5 /* eth_deposit */, + EIP7702_AUTH: 6 /* eip7702_auth */, +@@ -793,7 +794,8 @@ function getFwVersionConst(v) { + c.genericSigning.curveTypes = EXTERNAL.SIGNING.CURVES; + c.genericSigning.encodingTypes = { + NONE: EXTERNAL.SIGNING.ENCODINGS.NONE, +- SOLANA: EXTERNAL.SIGNING.ENCODINGS.SOLANA ++ SOLANA: EXTERNAL.SIGNING.ENCODINGS.SOLANA, ++ COSMOS: EXTERNAL.SIGNING.ENCODINGS.COSMOS + }; + c.getAddressFlags = [ + EXTERNAL.GET_ADDR_FLAGS.ED25519_PUB, diff --git a/apps/extension/package.json b/apps/extension/package.json index c0d66bbd88..9274e81f45 100644 --- a/apps/extension/package.json +++ b/apps/extension/package.json @@ -71,6 +71,7 @@ "color": "^4.2.3", "crypto-browserify": "^3.12.0", "delay": "^4.4.0", + "gridplus-sdk": "patch:gridplus-sdk@npm:4.0.0#../../.yarn/patches/gridplus-sdk-npm-4.0.0-0e9f598de2.patch", "https-browserify": "^1.0.0", "joi": "^17.5.0", "js-yaml": "^4.1.0", diff --git a/apps/extension/src/components/icon/lattice1.tsx b/apps/extension/src/components/icon/lattice1.tsx new file mode 100644 index 0000000000..86a1ed443c --- /dev/null +++ b/apps/extension/src/components/icon/lattice1.tsx @@ -0,0 +1,38 @@ +import React, { FunctionComponent } from "react"; +import { IconProps } from "./types"; + +export const Lattice1Icon: FunctionComponent = ({ + width = "auto", + height = "0.875rem", + color, +}) => { + const colors: { [key: string]: { color1: string } } = { + dark: { + color1: "#f5f8ff", + }, + light: { + color1: "#000000", + }, + }; + + const colorValue = color && color in colors ? colors[color].color1 : color; + + return ( + + + + + ); +}; diff --git a/apps/extension/src/hooks/key-info/use-key-info-sort.ts b/apps/extension/src/hooks/key-info/use-key-info-sort.ts index d19a8950f6..edc806af28 100644 --- a/apps/extension/src/hooks/key-info/use-key-info-sort.ts +++ b/apps/extension/src/hooks/key-info/use-key-info-sort.ts @@ -6,6 +6,7 @@ export const KEY_INFO_SORT_KEY = { MNEMONIC: "sort-mnemonic", PRIVATE_KEY: "sort-private-key", LEDGER: "sort-ledger", + LATTICE1: "sort-lattice1", KEYSTONE: "sort-keystone", UNKNOWN: "sort-unknown", }; @@ -85,6 +86,12 @@ export const useGetKeyInfosSeparatedByType = (keyInfos: KeyInfo[]) => { }); }, [keyInfos]); + const lattice1Keys = useMemo(() => { + return keyInfos.filter((keyInfo) => { + return keyInfo.type === "lattice1"; + }); + }, [keyInfos]); + const keystoneKeys = useMemo(() => { return keyInfos.filter((keyInfo) => { return keyInfo.type === "keystone"; @@ -94,6 +101,7 @@ export const useGetKeyInfosSeparatedByType = (keyInfos: KeyInfo[]) => { const unknownKeys = useMemo(() => { const knownKeys = mnemonicKeys .concat(ledgerKeys) + .concat(lattice1Keys) .concat(privateKeyInfos) .concat(socialPrivateKeyInfos) .concat(keystoneKeys); @@ -103,6 +111,7 @@ export const useGetKeyInfosSeparatedByType = (keyInfos: KeyInfo[]) => { }, [ keyInfos, ledgerKeys, + lattice1Keys, mnemonicKeys, privateKeyInfos, socialPrivateKeyInfos, @@ -161,6 +170,7 @@ export const useGetKeyInfosSeparatedByType = (keyInfos: KeyInfo[]) => { socialPrivateKeyInfoByType, privateKeyInfos, ledgerKeys, + lattice1Keys, keystoneKeys, unknownKeys, }; @@ -173,6 +183,7 @@ export const useGetAllSortedKeyInfos = (keyInfos: KeyInfo[]) => { socialPrivateKeyInfoByType, privateKeyInfos, ledgerKeys, + lattice1Keys, keystoneKeys, unknownKeys, } = useGetKeyInfosSeparatedByType(keyInfos); @@ -222,6 +233,14 @@ export const useGetAllSortedKeyInfos = (keyInfos: KeyInfo[]) => { res.push(...sortKeyInfos(ledgerKeys, indexMap)); } + if (lattice1Keys.length > 0) { + const indexMap = + uiConfigStore.selectWalletConfig.getKeyToSortVaultIdsMapIndex( + KEY_INFO_SORT_KEY.LATTICE1 + ); + res.push(...sortKeyInfos(lattice1Keys, indexMap)); + } + if (keystoneKeys.length > 0) { const indexMap = uiConfigStore.selectWalletConfig.getKeyToSortVaultIdsMapIndex( @@ -243,6 +262,7 @@ export const useGetAllSortedKeyInfos = (keyInfos: KeyInfo[]) => { socialPrivateKeyInfoByType, privateKeyInfos, ledgerKeys, + lattice1Keys, keystoneKeys, unknownKeys, uiConfigStore.selectWalletConfig, diff --git a/apps/extension/src/languages/en.json b/apps/extension/src/languages/en.json index d0e2612207..837643d74d 100644 --- a/apps/extension/src/languages/en.json +++ b/apps/extension/src/languages/en.json @@ -83,6 +83,7 @@ "pages.register.connect-hardware.content.title": "Select a hardware wallet that you would like to use with Keplr", "pages.register.connect-hardware.connect-ledger-button": "Connect Ledger", "pages.register.connect-hardware.connect-keystone-button": "Connect Keystone", + "pages.register.connect-hardware.connect-lattice1-button": "Connect Lattice1", "pages.register.new-mnemonic.title": "New Recovery Phrase", "pages.register.new-mnemonic.12-words-tab": "12 words", @@ -139,6 +140,14 @@ "pages.register.connect-ledger.use-hid-confirm-title": "Unable to use Web HID", "pages.register.connect-ledger.use-hid-confirm-paragraph": "Please enable ‘experimental web platform features’ to use Web HID", + "pages.register.connect-lattice1.title": "Connect your Lattice1", + "pages.register.connect-lattice1.paragraph": "Pair your Lattice1 and confirm the connection.", + "pages.register.connect-lattice1.step-1": "Open Lattice Connect to pair your device.", + "pages.register.connect-lattice1.step-2": "Unlock your Lattice1 and confirm the connection.", + "pages.register.connect-lattice1.error-title": "Unable to connect to Lattice1", + "pages.register.connect-lattice1.error-permission": "Check your Lattice Manager permissions. If you removed this wallet in Keplr, remove the Keplr permission in Lattice Manager and try again.", + "pages.register.connect-lattice1.error-permission-link": "Lattice Manager troubleshooting guide", + "pages.register.connect-keystone.paragraph": "Please unlock your Keystone device and connect it to your computer via USB.", "pages.register.connect-keystone.step-text": "Step {num}", "pages.register.connect-keystone.step-1": "Tap “Connect Software Wallet” at the bottom left corner on the Keystone device.", @@ -592,6 +601,11 @@ "page.sign.components.ledger-guide.box.sign-on-ledger-title": "Sign on Ledger", "page.sign.components.ledger-guide.box.sign-on-ledger-paragraph": "To proceed, please review and approve the transaction on your Ledger device.", + "page.sign.components.lattice1-guide.box.error-title": "Error", + "page.sign.components.lattice1-guide.box.sign-on-lattice1-title": "Sign on Lattice1", + "page.sign.components.lattice1-guide.box.sign-on-lattice1-paragraph": "Review and approve the request on your Lattice1.", + "page.sign.components.lattice1-guide.box.connect-lattice1-paragraph": "Make sure your Lattice1 is unlocked and on the same network.", + "page.sign.keystone.title": "Scan the QR Code", "page.sign.keystone.scan-qrcode": "Scan the QR code via your Keystone device", "page.sign.keystone.click-get-signature": "Click on the 'Get Signature' button after signing the transaction with your Keystone device.", diff --git a/apps/extension/src/languages/ko.json b/apps/extension/src/languages/ko.json index 12b7b4e3f8..b19b73fe98 100644 --- a/apps/extension/src/languages/ko.json +++ b/apps/extension/src/languages/ko.json @@ -83,6 +83,7 @@ "pages.register.connect-hardware.content.title": "케플러와 연결하고 싶은 하드웨어 지갑을 선택해주세요.", "pages.register.connect-hardware.connect-ledger-button": "렛저 계정 연결하기", "pages.register.connect-hardware.connect-keystone-button": "키스톤 계정 연결하기", + "pages.register.connect-hardware.connect-lattice1-button": "Lattice1 연결하기", "pages.register.new-mnemonic.title": "새로운 복구 문구", "pages.register.new-mnemonic.12-words-tab": "12 단어", @@ -140,6 +141,14 @@ "pages.register.connect-ledger.use-hid-confirm-title": "웹 HID를 사용할 수 없습니다.", "pages.register.connect-ledger.use-hid-confirm-paragraph": "웹 HID를 사용하시려면, ‘실험적 웹 플랫폼 기능’을 활성화해야 합니다.", + "pages.register.connect-lattice1.title": "Lattice1을 연결하세요", + "pages.register.connect-lattice1.paragraph": "Lattice1을 페어링하고 연결을 승인하세요.", + "pages.register.connect-lattice1.step-1": "Lattice Connect를 열어 기기를 페어링하세요.", + "pages.register.connect-lattice1.step-2": "Lattice1을 잠금 해제하고 연결을 승인하세요.", + "pages.register.connect-lattice1.error-title": "Lattice1에 연결할 수 없습니다", + "pages.register.connect-lattice1.error-permission": "Lattice Manager 권한을 확인하세요. Keplr에서 이 지갑을 삭제했다면 Lattice Manager에서 Keplr 권한을 제거한 다음 다시 시도하세요.", + "pages.register.connect-lattice1.error-permission-link": "Lattice Manager 문제 해결 안내", + "pages.register.connect-keystone.title": "하드웨어 지갑을 연결해주세요.", "pages.register.connect-keystone.step-text": "{num} 단계", "pages.register.connect-keystone.step-1": "키스톤 장치 왼쪽 하단의 “소프트웨어 지갑 연결” 버튼을 누르세요.", @@ -575,6 +584,11 @@ "page.sign.components.ledger-guide.box.sign-on-ledger-title": "렛저에서 서명하기", "page.sign.components.ledger-guide.box.sign-on-ledger-paragraph": "계속 하시려면, 렛저에서 트랜잭션을 확인하고 승인해야 합니다.", + "page.sign.components.lattice1-guide.box.error-title": "오류", + "page.sign.components.lattice1-guide.box.sign-on-lattice1-title": "Lattice1에서 서명하기", + "page.sign.components.lattice1-guide.box.sign-on-lattice1-paragraph": "Lattice1에서 요청 내용을 확인하고 승인하세요.", + "page.sign.components.lattice1-guide.box.connect-lattice1-paragraph": "Lattice1이 잠금 해제되어 있고 동일한 네트워크에 있는지 확인하세요.", + "page.sign.keystone.title": "QR 코드를 스캔하세요", "page.sign.keystone.scan-qrcode": "키스톤 장치로 QR 코드를 스캔하세요", "page.sign.keystone.click-get-signature": "키스톤 장치에서 트랜잭션을 서명한 후, '서명정보 받아오기' 버튼을 누르세요.", diff --git a/apps/extension/src/languages/zh-cn.json b/apps/extension/src/languages/zh-cn.json index 69462ec6b7..d9e7d1bafd 100644 --- a/apps/extension/src/languages/zh-cn.json +++ b/apps/extension/src/languages/zh-cn.json @@ -82,6 +82,7 @@ "pages.register.connect-hardware.content.title": "选择你想要与Keplr一起使用的硬件钱包", "pages.register.connect-hardware.connect-ledger-button": "连接Ledger", "pages.register.connect-hardware.connect-keystone-button": "连接Keystone", + "pages.register.connect-hardware.connect-lattice1-button": "连接Lattice1", "pages.register.new-mnemonic.title": "新助记词", "pages.register.new-mnemonic.12-words-tab": "12个词", @@ -137,6 +138,14 @@ "pages.register.connect-ledger.use-hid-confirm-title": "无法使用Web HID", "pages.register.connect-ledger.use-hid-confirm-paragraph": "请启用“实验性Web平台功能”以使用Web HID", + "pages.register.connect-lattice1.title": "连接你的Lattice1", + "pages.register.connect-lattice1.paragraph": "配对 Lattice1 并确认连接。", + "pages.register.connect-lattice1.step-1": "打开 Lattice Connect 以配对设备。", + "pages.register.connect-lattice1.step-2": "解锁你的 Lattice1 并确认连接。", + "pages.register.connect-lattice1.error-title": "无法连接到 Lattice1", + "pages.register.connect-lattice1.error-permission": "请检查 Lattice Manager 权限。如果你在 Keplr 中删除了此钱包,请在 Lattice Manager 中移除 Keplr 权限后重试。", + "pages.register.connect-lattice1.error-permission-link": "Lattice Manager 故障排除指南", + "pages.register.connect-keystone.title": "请连接你的硬件钱包", "pages.register.connect-keystone.step-text": "步骤 {num}", "pages.register.connect-keystone.step-1": "点击Keystone设备左下角的“连接软件钱包”。", @@ -541,6 +550,11 @@ "page.sign.components.ledger-guide.box.sign-on-ledger-title": "Ledger签名", "page.sign.components.ledger-guide.box.sign-on-ledger-paragraph": "要继续,请在你的Ledger设备上查看并确认交易。", + "page.sign.components.lattice1-guide.box.error-title": "错误", + "page.sign.components.lattice1-guide.box.sign-on-lattice1-title": "在 Lattice1 上签名", + "page.sign.components.lattice1-guide.box.sign-on-lattice1-paragraph": "请在你的 Lattice1 上查看并批准请求。", + "page.sign.components.lattice1-guide.box.connect-lattice1-paragraph": "请确保你的 Lattice1 已解锁并连接到同一网络。", + "page.sign.keystone.title": "扫描二维码", "page.sign.keystone.scan-qrcode": "通过你的Keystone设备扫描二维码", "page.sign.keystone.click-get-signature": "使用Keystone设备签名交易后,点击“获取签名”按钮。", diff --git a/apps/extension/src/pages/bitcoin/sign/message/view.tsx b/apps/extension/src/pages/bitcoin/sign/message/view.tsx index 9652308c31..845cdb77ca 100644 --- a/apps/extension/src/pages/bitcoin/sign/message/view.tsx +++ b/apps/extension/src/pages/bitcoin/sign/message/view.tsx @@ -10,6 +10,7 @@ import { useUnmount } from "../../../../hooks/use-unmount"; import { handleExternalInteractionWithNoProceedNext } from "../../../../utils"; import { KeplrError } from "@keplr-wallet/router"; import { ErrModuleLedgerSign } from "../../../sign/utils/ledger-types"; +import { ErrModuleLattice1Sign } from "../../../sign/utils/lattice1"; import { CancelIcon } from "../../../../components/button/cancel-icon"; import { BackButton } from "../../../../layouts/header/components"; import { HeaderLayout } from "../../../../layouts/header"; @@ -17,12 +18,16 @@ import { ColorPalette } from "../../../../styles"; import { ApproveIcon } from "../../../../components/button"; import { Gutter } from "../../../../components/gutter"; import { LedgerGuideBox } from "../../../sign/components/ledger-guide-box"; +import { Lattice1GuideBox } from "../../../sign/components/lattice1-guide-box"; import { ArbitraryMsgDataView } from "../../../sign/components/arbitrary-message/arbitrary-message-data-view"; import { ArbitraryMsgSignHeader } from "../../../sign/components/arbitrary-message/arbitrary-message-header"; import { ArbitraryMsgRequestOrigin } from "../../../sign/components/arbitrary-message/arbitrary-message-origin"; import { ArbitraryMsgWalletDetails } from "../../../sign/components/arbitrary-message/arbitrary-message-wallet-details"; import { Box } from "../../../../components/box"; -import { connectAndSignMessageWithLedger } from "../../../sign/utils/handle-bitcoin-sign"; +import { + connectAndSignMessageWithLedger, + connectAndSignMessageWithLattice1, +} from "../../../sign/utils/handle-bitcoin-sign"; export const SignBitcoinMessageView: FunctionComponent<{ interactionData: NonNullable< @@ -71,6 +76,10 @@ export const SignBitcoinMessageView: FunctionComponent<{ const [ledgerInteractingError, setLedgerInteractingError] = useState< Error | undefined >(undefined); + const [isLattice1Interacting, setIsLattice1Interacting] = useState(false); + const [lattice1InteractingError, setLattice1InteractingError] = useState< + Error | undefined + >(undefined); useUnmount(() => { unmountPromise.resolver(); @@ -90,6 +99,13 @@ export const SignBitcoinMessageView: FunctionComponent<{ useWebHID: uiConfigStore.useWebHIDLedger, } ); + } else if (interactionData.data.keyType === "lattice1") { + setIsLattice1Interacting(true); + setLattice1InteractingError(undefined); + signature = await connectAndSignMessageWithLattice1( + interactionData, + modularChainInfo + ); } await signBitcoinMessageInteractionStore.approveWithProceedNext( @@ -132,14 +148,19 @@ export const SignBitcoinMessageView: FunctionComponent<{ if (e instanceof KeplrError) { if (e.module === ErrModuleLedgerSign) { setLedgerInteractingError(e); + } else if (e.module === ErrModuleLattice1Sign) { + setLattice1InteractingError(e); } else { setLedgerInteractingError(undefined); + setLattice1InteractingError(undefined); } } else { setLedgerInteractingError(undefined); + setLattice1InteractingError(undefined); } } finally { setIsLedgerInteracting(false); + setIsLattice1Interacting(false); } }; @@ -184,7 +205,7 @@ export const SignBitcoinMessageView: FunctionComponent<{ style: { width: "3.25rem", }, - isLoading: isLedgerInteracting, + isLoading: isLedgerInteracting || isLattice1Interacting, onClick: async () => { await signBitcoinMessageInteractionStore.rejectWithProceedNext( interactionData.id, @@ -253,6 +274,10 @@ export const SignBitcoinMessageView: FunctionComponent<{ ledgerInteractingError={ledgerInteractingError} isInternal={interactionData.isInternal} /> + ); diff --git a/apps/extension/src/pages/bitcoin/sign/tx/view.tsx b/apps/extension/src/pages/bitcoin/sign/tx/view.tsx index 1eda674814..41a17c3c45 100644 --- a/apps/extension/src/pages/bitcoin/sign/tx/view.tsx +++ b/apps/extension/src/pages/bitcoin/sign/tx/view.tsx @@ -72,8 +72,13 @@ import { BitcoinGuideBox } from "../../components/guide-box"; import { HeaderProps } from "../../../../layouts/header/types"; import { KeplrError } from "@keplr-wallet/router"; import { ErrModuleLedgerSign } from "../../../sign/utils/ledger-types"; +import { ErrModuleLattice1Sign } from "../../../sign/utils/lattice1"; import { LedgerGuideBox } from "../../../sign/components/ledger-guide-box"; -import { connectAndSignPsbtsWithLedger } from "../../../sign/utils/handle-bitcoin-sign"; +import { Lattice1GuideBox } from "../../../sign/components/lattice1-guide-box"; +import { + connectAndSignPsbtsWithLedger, + connectAndSignPsbtsWithLattice1, +} from "../../../sign/utils/handle-bitcoin-sign"; export const SignBitcoinTxView: FunctionComponent<{ interactionData: NonNullable; @@ -321,6 +326,10 @@ export const SignBitcoinTxView: FunctionComponent<{ const [ledgerInteractingError, setLedgerInteractingError] = useState< Error | undefined >(undefined); + const [isLattice1Interacting, setIsLattice1Interacting] = useState(false); + const [lattice1InteractingError, setLattice1InteractingError] = useState< + Error | undefined + >(undefined); const isTestnet = modularChainInfo.bitcoin.bip44.coinType === 1; @@ -346,7 +355,9 @@ export const SignBitcoinTxView: FunctionComponent<{ const isLoading = signBitcoinTxInteractionStore.isObsoleteInteractionApproved( interactionData.id - ) || isLedgerInteracting; + ) || + isLedgerInteracting || + isLattice1Interacting; const isExternal = interactionInfo.interaction && !interactionInfo.interactionInternal; @@ -402,6 +413,14 @@ export const SignBitcoinTxView: FunctionComponent<{ modularChainInfo, { useWebHID: uiConfigStore.useWebHIDLedger } ); + } else if (interactionData.data.keyType === "lattice1") { + setIsLattice1Interacting(true); + setLattice1InteractingError(undefined); + signedPsbtsHexes = await connectAndSignPsbtsWithLattice1( + interactionData, + psbtSignData, + modularChainInfo + ); } await signBitcoinTxInteractionStore.approveWithProceedNext( @@ -444,14 +463,19 @@ export const SignBitcoinTxView: FunctionComponent<{ if (e instanceof KeplrError) { if (e.module === ErrModuleLedgerSign) { setLedgerInteractingError(e); + } else if (e.module === ErrModuleLattice1Sign) { + setLattice1InteractingError(e); } else { setLedgerInteractingError(undefined); + setLattice1InteractingError(undefined); } } else { setLedgerInteractingError(undefined); + setLattice1InteractingError(undefined); } } finally { setIsLedgerInteracting(false); + setIsLattice1Interacting(false); } }; @@ -605,6 +629,13 @@ export const SignBitcoinTxView: FunctionComponent<{ isInternal={interactionData.isInternal} /> ) : undefined; + const lattice1GuideBox = + interactionData.data.keyType === "lattice1" ? ( + + ) : undefined; return ( ) : ( @@ -650,6 +682,7 @@ export const SignBitcoinTxView: FunctionComponent<{ origin={interactionData.data.origin} validatedPsbt={validatedPsbts?.[0]} ledgerGuideBox={ledgerGuideBox} + lattice1GuideBox={lattice1GuideBox} criticalValidationError={criticalValidationError} /> ) @@ -662,6 +695,7 @@ export const SignBitcoinTxView: FunctionComponent<{ } ledgerGuideBox={ledgerGuideBox} + lattice1GuideBox={lattice1GuideBox} /> )} @@ -674,6 +708,7 @@ const InternalSendBitcoinTxReview: FunctionComponent<{ chainId: string; feeSummary: React.ReactNode; ledgerGuideBox?: React.ReactNode; + lattice1GuideBox?: React.ReactNode; }> = observer( ({ validatedPsbt, @@ -681,6 +716,7 @@ const InternalSendBitcoinTxReview: FunctionComponent<{ feeSummary, isUnableToGetUTXOs, ledgerGuideBox, + lattice1GuideBox, }) => { const theme = useTheme(); const { chainStore } = useStore(); @@ -920,6 +956,7 @@ const InternalSendBitcoinTxReview: FunctionComponent<{
{feeSummary} {ledgerGuideBox} + {lattice1GuideBox} ); } @@ -938,6 +975,7 @@ const PsbtDetailsView: FunctionComponent<{ totalPsbts?: number; currentPsbtIndex?: number; ledgerGuideBox?: React.ReactNode; + lattice1GuideBox?: React.ReactNode; criticalValidationError?: Error; }> = observer( ({ @@ -950,6 +988,7 @@ const PsbtDetailsView: FunctionComponent<{ totalPsbts, currentPsbtIndex, ledgerGuideBox, + lattice1GuideBox, criticalValidationError, }) => { const theme = useTheme(); @@ -1024,6 +1063,10 @@ const PsbtDetailsView: FunctionComponent<{ totalPsbts && currentPsbtIndex !== undefined ? currentPsbtIndex === totalPsbts - 1 && ledgerGuideBox : ledgerGuideBox; + const hasLattice1GuideBox = + totalPsbts && currentPsbtIndex !== undefined + ? currentPsbtIndex === totalPsbts - 1 && lattice1GuideBox + : lattice1GuideBox; const isSidePanel = isRunningInSidePanel(); @@ -1047,7 +1090,10 @@ const PsbtDetailsView: FunctionComponent<{ criticalValidationError={criticalValidationError} /> {ledgerGuideBox} - {(hasGuideBox || hasLedgerGuideBox) && } + {lattice1GuideBox} + {(hasGuideBox || hasLedgerGuideBox || hasLattice1GuideBox) && ( + + )} {totalPsbts && totalPsbts > 1 && currentPsbtIndex !== undefined && ( diff --git a/apps/extension/src/pages/main/components/account-icon/index.tsx b/apps/extension/src/pages/main/components/account-icon/index.tsx index bcf8666d45..fa313b0e8b 100644 --- a/apps/extension/src/pages/main/components/account-icon/index.tsx +++ b/apps/extension/src/pages/main/components/account-icon/index.tsx @@ -27,6 +27,12 @@ export const AccountNameIcon = ({ switch (keyInfoType) { case "ledger": return theme.mode === "light" ? <_LedgerIconLM /> : <_LedgerIconDM />; + case "lattice1": + return theme.mode === "light" ? ( + <_Lattice1IconLM /> + ) : ( + <_Lattice1IconDM /> + ); case "keystone": return theme.mode === "light" ? ( <_KeystoneIconLM /> @@ -161,3 +167,51 @@ const _KeystoneIconDM = () => { ); }; + +const _Lattice1IconLM = () => { + return ( + + + + + + + + ); +}; + +const _Lattice1IconDM = () => { + return ( + + + + + + + + ); +}; diff --git a/apps/extension/src/pages/main/components/token-found-modal/index.tsx b/apps/extension/src/pages/main/components/token-found-modal/index.tsx index b211dd696b..6a2b59c458 100644 --- a/apps/extension/src/pages/main/components/token-found-modal/index.tsx +++ b/apps/extension/src/pages/main/components/token-found-modal/index.tsx @@ -142,12 +142,12 @@ export const TokenFoundModal: FunctionComponent<{ if ( tokenScan.infos.length === 1 && - tokenScan.infos[0].coinType != null + tokenScan.infos[0]["coinType"] != null ) { await keyRingStore.finalizeKeyCoinType( keyRingStore.selectedKeyInfo.id, enable, - tokenScan.infos[0].coinType + tokenScan.infos[0]["coinType"] ); } } @@ -421,7 +421,7 @@ const FoundChainView: FunctionComponent<{ ...acc, ...cur.assets.map((asset) => ({ ...asset, - paymentType: cur.bitcoinAddress?.paymentType, + paymentType: cur["bitcoinAddress"]?.paymentType, })), ]; }, [] as (RequiredCurrencyTokenScan["infos"][number]["assets"][number] & { paymentType?: SupportedPaymentType })[]); diff --git a/apps/extension/src/pages/register/connect-hardware/index.tsx b/apps/extension/src/pages/register/connect-hardware/index.tsx index 903ed972ec..12dcf14b41 100644 --- a/apps/extension/src/pages/register/connect-hardware/index.tsx +++ b/apps/extension/src/pages/register/connect-hardware/index.tsx @@ -13,6 +13,7 @@ import { Box } from "../../../components/box"; import { FormattedMessage, useIntl } from "react-intl"; import { useTheme } from "styled-components"; import { KeystoneIcon } from "../../../components/icon/keystone"; +import { Lattice1Icon } from "../../../components/icon/lattice1"; export const ConnectHardwareWalletScene: FunctionComponent = () => { const sceneTransition = useSceneTransition(); @@ -85,6 +86,19 @@ export const ConnectHardwareWalletScene: FunctionComponent = () => { }); }} /> +