From cc36bb4bf6efd493686d53fa37bc8a979987f5c8 Mon Sep 17 00:00:00 2001 From: Andre Borges Medeiros Date: Tue, 31 Oct 2023 16:34:29 -0300 Subject: [PATCH 01/62] Chnage Kadena derivation path to account --- .../src/providers/kadena/types/kadena-network.ts | 2 +- packages/keyring/src/utils.ts | 1 + packages/signers/kadena/src/index.ts | 2 +- packages/signers/kadena/tests/generate.test.ts | 16 ++++++++-------- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/packages/extension/src/providers/kadena/types/kadena-network.ts b/packages/extension/src/providers/kadena/types/kadena-network.ts index cabdf4eb9..dd6430b3d 100644 --- a/packages/extension/src/providers/kadena/types/kadena-network.ts +++ b/packages/extension/src/providers/kadena/types/kadena-network.ts @@ -56,7 +56,7 @@ export class KadenaNetwork extends BaseNetwork { }; const baseOptions: BaseNetworkOptions = { - basePath: "m/44'/626'/0'/0'", + basePath: "m/44'/626'", identicon: createIcon, signer: [SignerType.ed25519kda], provider: ProviderName.kadena, diff --git a/packages/keyring/src/utils.ts b/packages/keyring/src/utils.ts index ea18ffa05..3e12f2143 100644 --- a/packages/keyring/src/utils.ts +++ b/packages/keyring/src/utils.ts @@ -11,5 +11,6 @@ export const pathParser = ( ) { return index === 0 ? "" : `//${--index}`; // polkadotjs extension use "" for 0 index/root } + return `${basePath}/${index}`; }; diff --git a/packages/signers/kadena/src/index.ts b/packages/signers/kadena/src/index.ts index cc101b4ab..d8be68531 100644 --- a/packages/signers/kadena/src/index.ts +++ b/packages/signers/kadena/src/index.ts @@ -7,7 +7,7 @@ import { derivePath } from "./libs/ed25519"; class Signer implements SignerInterface { async generate(mnemonic: string, derivationPath = ""): Promise { const seed = bufferToHex(mnemonicToSeedSync(mnemonic), true); - const dPathSegments = `${derivationPath}'`.split("/"); + const dPathSegments = `${derivationPath}'/0'/0'`.split("/"); const keys = derivePath(dPathSegments.join("/"), seed); const keyPair = tweetSign.keyPair.fromSeed(keys.key); diff --git a/packages/signers/kadena/tests/generate.test.ts b/packages/signers/kadena/tests/generate.test.ts index 62ddbbb72..fe6355554 100644 --- a/packages/signers/kadena/tests/generate.test.ts +++ b/packages/signers/kadena/tests/generate.test.ts @@ -5,32 +5,32 @@ describe("Kadena address generate", () => { const MNEMONIC = "favorite service senior cluster chicken shift square endorse casual kidney doll exhibit"; - it("should generate Kadena addresses correctly", async () => { + it.only("should generate Kadena addresses correctly", async () => { // Arrange const kadenaSigner = new Signer(); // Act & Assert - let keypair = await kadenaSigner.generate(MNEMONIC, "m/44'/626'/0'/0'/0"); + let keypair = await kadenaSigner.generate(MNEMONIC, "m/44'/626'/0"); expect(keypair.address).equals( "0x40a9305bd53a921c44cf19dc9bac4e5d73465fc6a46343ab313defe6b0bfb0a3" ); // Act & Assert - keypair = await kadenaSigner.generate(MNEMONIC, "m/44'/626'/0'/0'/1"); + keypair = await kadenaSigner.generate(MNEMONIC, "m/44'/626'/1"); expect(keypair.address).equals( - "0x50d824cb62578b1fcf8e4afb122e98884d5f04070950b93a102e1ba1e1f3d1bb" + "0xea14c16c053a5543b831e73f55086e4fccb8cc7be764cd74d362179a1d588416" ); // Act & Assert - keypair = await kadenaSigner.generate(MNEMONIC, "m/44'/626'/0'/0'/2"); + keypair = await kadenaSigner.generate(MNEMONIC, "m/44'/626'/2"); expect(keypair.address).equals( - "0x287b9cdbd0894fbff67c664b4cc1e7da9eca9b03ef94fd5baa2cfabe2cd3c6a5" + "0xaf2a1ff42a9e652d1a8ed1f4f3c7bffcb36a9788c632a53544d7aff07d2a1678" ); // Act & Assert - keypair = await kadenaSigner.generate(MNEMONIC, "m/44'/626'/0'/0'/3"); + keypair = await kadenaSigner.generate(MNEMONIC, "m/44'/626'/3"); expect(keypair.address).equals( - "0xe00a31c57aabe95554ad71c700c723153c0dd67b072b569916209138e419c122" + "0xaeb2b28c7cddfa5fd8963acd9df13a858d8329590537e5495b1d5dbc3eeadd92" ); }); }); From 666ae8b4fadaaaf74debdcf8e21de6f5d72c0c0d Mon Sep 17 00:00:00 2001 From: Glaicon Date: Thu, 9 Nov 2023 10:16:57 -0500 Subject: [PATCH 02/62] update send transaction page to show the right KDA currency name --- .../src/providers/kadena/ui/send-transaction/index.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/extension/src/providers/kadena/ui/send-transaction/index.vue b/packages/extension/src/providers/kadena/ui/send-transaction/index.vue index 5bb6495c3..75667d0e6 100644 --- a/packages/extension/src/providers/kadena/ui/send-transaction/index.vue +++ b/packages/extension/src/providers/kadena/ui/send-transaction/index.vue @@ -71,7 +71,7 @@
From c5cedbf3fbf1f64490ea7a9e11f9c21f0e4e63a9 Mon Sep 17 00:00:00 2001 From: Glaicon Date: Mon, 20 Nov 2023 15:04:59 -0500 Subject: [PATCH 03/62] WIP - Add multi-chain --- .../kadena/libs/accounts-state/index.ts | 6 + .../kadena/libs/accounts-state/types.ts | 1 + .../providers/kadena/index.ts | 1 + .../src/providers/kadena/libs/api.ts | 25 +++- .../kadena/methods/kda_getBalance.ts | 6 +- .../providers/kadena/types/kadena-network.ts | 18 ++- .../src/providers/kadena/types/kda-token.ts | 16 ++- packages/extension/src/ui/action/App.vue | 25 ++++ .../components/chainId-list-item.vue | 80 +++++++++++ .../components/header-accounts.vue | 68 +++++++-- .../components/accounts-header/index.vue | 1 + .../extension/src/ui/action/types/account.ts | 1 + .../action/views/network-activity/index.vue | 133 ++++++++++-------- .../ui/action/views/network-assets/index.vue | 27 +++- 14 files changed, 315 insertions(+), 93 deletions(-) create mode 100644 packages/extension/src/ui/action/components/accounts-header/components/chainId-list-item.vue diff --git a/packages/extension/src/providers/kadena/libs/accounts-state/index.ts b/packages/extension/src/providers/kadena/libs/accounts-state/index.ts index ba84a0e05..3486620f1 100644 --- a/packages/extension/src/providers/kadena/libs/accounts-state/index.ts +++ b/packages/extension/src/providers/kadena/libs/accounts-state/index.ts @@ -29,6 +29,11 @@ class AccountState { await this.#storage.set(StorageKeys.accountsState, allStates); } } + async setChainId(domain: string, chainId: string): Promise { + const state = await this.getStateByDomain(domain); + state.chainId = chainId; + await this.setState(state, domain); + } async isConnected(domain: string): Promise { return this.getStateByDomain(domain).then((res) => res.isApproved); } @@ -45,6 +50,7 @@ class AccountState { if (!allStates[domain]) return { isApproved: false, + chainId: "1", }; else return allStates[domain]; } diff --git a/packages/extension/src/providers/kadena/libs/accounts-state/types.ts b/packages/extension/src/providers/kadena/libs/accounts-state/types.ts index b20ca5a8a..55d7c0547 100644 --- a/packages/extension/src/providers/kadena/libs/accounts-state/types.ts +++ b/packages/extension/src/providers/kadena/libs/accounts-state/types.ts @@ -3,4 +3,5 @@ export enum StorageKeys { } export interface IState { isApproved: boolean; + chainId: string; } diff --git a/packages/extension/src/providers/kadena/libs/activity-handlers/providers/kadena/index.ts b/packages/extension/src/providers/kadena/libs/activity-handlers/providers/kadena/index.ts index 2f19f4c12..ad032a02f 100644 --- a/packages/extension/src/providers/kadena/libs/activity-handlers/providers/kadena/index.ts +++ b/packages/extension/src/providers/kadena/libs/activity-handlers/providers/kadena/index.ts @@ -79,6 +79,7 @@ export default async ( isIncoming: activity.fromAccount !== address, network: network.name, rawInfo: activity, + chainId: activity.chain.toString(), status: activity.idx === 1 ? ActivityStatus.success : ActivityStatus.failed, timestamp: new Date(activity.blockTime).getTime(), diff --git a/packages/extension/src/providers/kadena/libs/api.ts b/packages/extension/src/providers/kadena/libs/api.ts index 32b4407d4..29c2a82d1 100644 --- a/packages/extension/src/providers/kadena/libs/api.ts +++ b/packages/extension/src/providers/kadena/libs/api.ts @@ -34,16 +34,27 @@ class API implements ProviderAPIInterface { async init(): Promise {} async getTransactionStatus(hash: string): Promise { + return this.getTransactionStatusChainId(hash, this.chainId); + } + + async getTransactionStatusChainId( + hash: string, + chainId: string + ): Promise { const Pact = require("pact-lang-api"); + const urlApiHost = `${this.node}/${this.networkId}/chain/${chainId}/pact`; const cmd = { requestKeys: [hash] }; - const transactions = await Pact.fetch.poll(cmd, this.apiHost); + const transactions = await Pact.fetch.poll(cmd, urlApiHost); return transactions[hash]; } - async getBalance(address: string): Promise { - const balance = await this.getBalanceAPI(this.displayAddress(address)); + async getBalance(address: string, chainId?: string): Promise { + const balance = await this.getBalanceAPI( + this.displayAddress(address), + chainId ?? this.chainId + ); if (balance.result.error) { return toBase("0", this.decimals); @@ -56,9 +67,9 @@ class API implements ProviderAPIInterface { return toBase(balanceValue, this.decimals); } - async getBalanceAPI(account: string) { + async getBalanceAPI(account: string, chainId: string) { const Pact = require("pact-lang-api"); - + const urlApiHost = `${this.node}/${this.networkId}/chain/${chainId}/pact`; const cmd = { networkId: this.networkId, pactCode: `(coin.get-balance "${account}")`, @@ -67,13 +78,13 @@ class API implements ProviderAPIInterface { creationTime: Math.round(new Date().getTime() / 1000), ttl: 600, gasLimit: 600, - chainId: this.chainId, + chainId: chainId, gasPrice: 0.0000001, sender: "", }, }; - return Pact.fetch.local(cmd, this.apiHost); + return Pact.fetch.local(cmd, urlApiHost); } async sendLocalTransaction( diff --git a/packages/extension/src/providers/kadena/methods/kda_getBalance.ts b/packages/extension/src/providers/kadena/methods/kda_getBalance.ts index f42dddb54..77b10f012 100644 --- a/packages/extension/src/providers/kadena/methods/kda_getBalance.ts +++ b/packages/extension/src/providers/kadena/methods/kda_getBalance.ts @@ -15,8 +15,12 @@ const method: MiddlewareFunction = function ( return res(getCustomError("kda_getBalance: invalid params")); } + const address = payload.params[0]; + // should accept params without chainId + const chainId = + payload.params[1] ?? this.network.options.kadenaApiOptions.chainId; this.network.api().then((api) => { - api.getBalance(payload.params![0]).then((bal) => { + api.getBalance(address, chainId).then((bal) => { res(null, bal); }); }); diff --git a/packages/extension/src/providers/kadena/types/kadena-network.ts b/packages/extension/src/providers/kadena/types/kadena-network.ts index df89b43c2..40a17df9e 100644 --- a/packages/extension/src/providers/kadena/types/kadena-network.ts +++ b/packages/extension/src/providers/kadena/types/kadena-network.ts @@ -74,7 +74,14 @@ export class KadenaNetwork extends BaseNetwork { } public async getAllTokens(pubkey: string): Promise { - const assets = await this.getAllTokenInfo(pubkey); + throw new Error("Method not implemented."); + } + + public async getAllTokensByChainId( + pubkey: string, + chainId: string + ): Promise { + const assets = await this.getAllTokenInfoChainId(pubkey, chainId); return assets.map((token) => { const bTokenOptions: BaseTokenOptions = { @@ -92,7 +99,14 @@ export class KadenaNetwork extends BaseNetwork { } public async getAllTokenInfo(pubkey: string): Promise { - const balance = await (await this.api()).getBalance(pubkey); + throw new Error("Method not implemented."); + } + + public async getAllTokenInfoChainId( + pubkey: string, + chainId: string | undefined + ): Promise { + const balance = await (await this.api()).getBalance(pubkey, chainId); let marketData: (CoinGeckoTokenMarket | null)[] = []; if (this.coingeckoID) { diff --git a/packages/extension/src/providers/kadena/types/kda-token.ts b/packages/extension/src/providers/kadena/types/kda-token.ts index 06195be90..26532481b 100644 --- a/packages/extension/src/providers/kadena/types/kda-token.ts +++ b/packages/extension/src/providers/kadena/types/kda-token.ts @@ -30,7 +30,7 @@ export class KDAToken extends KDABaseToken { api: KadenaAPI, pubkey: string ): Promise { - return api.getBalance(pubkey); + throw new Error("KDA-getLatestUserBalance is not implemented here"); } public async send(): Promise { @@ -41,7 +41,8 @@ export class KDAToken extends KDABaseToken { to: string, from: EnkryptAccount | any, amount: string, - network: KadenaNetwork + network: KadenaNetwork, + chainId?: string ): Promise { to = network.displayAddress(to); const accountDetails = await this.getAccountDetails(to, network); @@ -65,7 +66,8 @@ export class KDAToken extends KDABaseToken { withCap("coin.GAS"), ]) .setMeta({ - chainId: network.options.kadenaApiOptions.chainId as ChainId, + chainId: (chainId ?? + network.options.kadenaApiOptions.chainId) as ChainId, senderAccount: network.displayAddress(from.address), }) .setNetworkId(network.options.kadenaApiOptions.networkId) @@ -92,12 +94,16 @@ export class KDAToken extends KDABaseToken { public async getAccountDetails( account: string, - network: KadenaNetwork + network: KadenaNetwork, + chainId?: string ): Promise { const modules = Pact.modules as any; const unsignedTransaction = Pact.builder .execution(modules.coin.details(account)) - .setMeta({ chainId: network.options.kadenaApiOptions.chainId as ChainId }) + .setMeta({ + chainId: (chainId ?? + network.options.kadenaApiOptions.chainId) as ChainId, + }) .setNetworkId(network.options.kadenaApiOptions.networkId) .createTransaction(); diff --git a/packages/extension/src/ui/action/App.vue b/packages/extension/src/ui/action/App.vue index cfc8dbbde..278ca4459 100644 --- a/packages/extension/src/ui/action/App.vue +++ b/packages/extension/src/ui/action/App.vue @@ -47,6 +47,7 @@ :show-deposit="showDepositWindow" @update:init="init" @address-changed="onSelectedAddressChanged" + @chain-changed="onSelectedChainIdChanged" @toggle:deposit="toggleDepositWindow" /> @@ -125,6 +126,7 @@ import { onClickOutside } from "@vueuse/core"; import RateState from "@/libs/rate-state"; import SwapLookingAnimation from "@action/icons/swap/swap-looking-animation.vue"; import { addNetworkSelectMetrics } from "@/libs/metrics"; +import KadenaAPI from "@/providers/kadena/libs/api"; const domainState = new DomainState(); const networksState = new NetworksState(); @@ -136,6 +138,7 @@ const accountHeaderData = ref({ inactiveAccounts: [], selectedAccount: null, activeBalances: [], + chainId: null, }); const isOpenMore = ref(false); let timeout: ReturnType | null = null; @@ -252,6 +255,7 @@ const setNetwork = async (network: BaseNetwork) => { inactiveAccounts, selectedAccount, activeBalances: activeAccounts.map(() => "~"), + chainId: accountHeaderData.value.chainId, }; currentNetwork.value = network; router.push({ name: "assets", params: { id: network.name } }); @@ -324,6 +328,27 @@ const setNetwork = async (network: BaseNetwork) => { } } }; +const onSelectedChainIdChanged = async (chainId: string) => { + try { + const activeAccounts = await getAccountsByNetworkName( + currentNetwork.value.name + ); + const thisNetworkName = currentNetwork.value.name; + const kadenaAPI = (await currentNetwork.value.api()) as KadenaAPI; + const activeBalancePromises = activeAccounts.map( + async (acc) => await kadenaAPI.getBalance(acc.address, chainId) + ); + accountHeaderData.value.chainId = chainId; + Promise.all(activeBalancePromises).then((balances) => { + if (thisNetworkName === currentNetwork.value.name) + accountHeaderData.value.activeBalances = balances.map((bal) => + fromBase(bal, currentNetwork.value.decimals) + ); + }); + } catch (e) { + console.error(e); + } +}; const onSelectedAddressChanged = async (newAccount: EnkryptAccount) => { accountHeaderData.value.selectedAccount = newAccount; diff --git a/packages/extension/src/ui/action/components/accounts-header/components/chainId-list-item.vue b/packages/extension/src/ui/action/components/accounts-header/components/chainId-list-item.vue new file mode 100644 index 000000000..6acee4630 --- /dev/null +++ b/packages/extension/src/ui/action/components/accounts-header/components/chainId-list-item.vue @@ -0,0 +1,80 @@ + + + + + diff --git a/packages/extension/src/ui/action/components/accounts-header/components/header-accounts.vue b/packages/extension/src/ui/action/components/accounts-header/components/header-accounts.vue index 58e8a9dad..fbb15dc11 100644 --- a/packages/extension/src/ui/action/components/accounts-header/components/header-accounts.vue +++ b/packages/extension/src/ui/action/components/accounts-header/components/header-accounts.vue @@ -9,20 +9,27 @@ - - -
-

{{ "Chain 1" }}

-
- -
-
+
+ + + +
+

- {{ cryptoAmount }} {{ symbol }} + {{ cryptoAmount }} {{ network.currencyName }}

-

{{ fiatAmount }}

+

+ {{ currentChainId }} · + {{ fiatAmount }} +

diff --git a/packages/extension/src/providers/kadena/ui/send-transaction/index.vue b/packages/extension/src/providers/kadena/ui/send-transaction/index.vue index 24ce15fb2..36440f385 100644 --- a/packages/extension/src/providers/kadena/ui/send-transaction/index.vue +++ b/packages/extension/src/providers/kadena/ui/send-transaction/index.vue @@ -8,14 +8,6 @@ -

- {{ errorMsg }} -

- + +
@@ -111,6 +105,7 @@ import SendTokenSelect from "./components/send-token-select.vue"; import AssetsSelectList from "@action/views/assets-select-list/index.vue"; import SendInputAmount from "./components/send-input-amount.vue"; import SendFeeSelect from "./components/send-fee-select.vue"; +import SendAlert from "./components/send-alert.vue"; import BaseButton from "@action/components/base-button/index.vue"; import { AccountsHeaderData } from "@action/types/account"; import { GasFeeInfo } from "@/providers/ethereum/ui/types"; diff --git a/packages/extension/src/providers/kadena/ui/send-transaction/verify-transaction/index.vue b/packages/extension/src/providers/kadena/ui/send-transaction/verify-transaction/index.vue index cfe500b6e..cf577fa63 100644 --- a/packages/extension/src/providers/kadena/ui/send-transaction/verify-transaction/index.vue +++ b/packages/extension/src/providers/kadena/ui/send-transaction/verify-transaction/index.vue @@ -12,13 +12,7 @@
-

- {{ errorMsg }} -

+

Double check the information and confirm transaction

@@ -42,6 +36,10 @@
+
+ +
+
{ right: 0 !important; } } + + &__error { + position: absolute; + top: 480px; + width: 100%; + background-color: white; + } } From 046886a70c826ec4d50c3b32a6167df52d3e834c Mon Sep 17 00:00:00 2001 From: Andre Borges Medeiros Date: Tue, 6 Feb 2024 14:26:59 -0300 Subject: [PATCH 60/62] Linting issues --- .../kadena/ui/send-transaction/components/send-alert.vue | 2 +- .../src/providers/kadena/ui/send-transaction/index.vue | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/extension/src/providers/kadena/ui/send-transaction/components/send-alert.vue b/packages/extension/src/providers/kadena/ui/send-transaction/components/send-alert.vue index a58e4c045..627b1588b 100644 --- a/packages/extension/src/providers/kadena/ui/send-transaction/components/send-alert.vue +++ b/packages/extension/src/providers/kadena/ui/send-transaction/components/send-alert.vue @@ -12,7 +12,7 @@ interface IProps { errorMsg: string; } -const props = defineProps(); +defineProps();