From afc693e946bc5f83723c1e7b52ed4634f2845149 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 22 Feb 2024 02:26:15 +0000 Subject: [PATCH 01/10] chore(deps): bump ip from 1.1.8 to 1.1.9 Bumps [ip](https://github.com/indutny/node-ip) from 1.1.8 to 1.1.9. - [Commits](https://github.com/indutny/node-ip/compare/v1.1.8...v1.1.9) --- updated-dependencies: - dependency-name: ip dependency-type: indirect ... Signed-off-by: dependabot[bot] --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 20293b30..348c79e4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6305,9 +6305,9 @@ ip-regex@^4.1.0: integrity sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q== ip@^1.1.5: - version "1.1.8" - resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.8.tgz#ae05948f6b075435ed3307acce04629da8cdbf48" - integrity sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg== + version "1.1.9" + resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.9.tgz#8dfbcc99a754d07f425310b86a99546b1151e396" + integrity sha512-cyRxvOEpNHNtchU3Ln9KC/auJgup87llfQpQ+t5ghoC/UhL16SWzbueiCsdTnWmqAWl7LadfuwhlqmtOaqMHdQ== ipaddr.js@1.9.1: version "1.9.1" From 80f70fe08ea69e85d694eaf821e45a46f3ce2fd7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 16 Mar 2024 23:12:09 +0000 Subject: [PATCH 02/10] chore(deps): bump follow-redirects from 1.15.4 to 1.15.6 Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.15.4 to 1.15.6. - [Release notes](https://github.com/follow-redirects/follow-redirects/releases) - [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.15.4...v1.15.6) --- updated-dependencies: - dependency-name: follow-redirects dependency-type: indirect ... Signed-off-by: dependabot[bot] --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 348c79e4..9361d38c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5498,9 +5498,9 @@ flatted@^3.1.0: integrity sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg== follow-redirects@^1.0.0, follow-redirects@^1.14.0: - version "1.15.4" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.4.tgz#cdc7d308bf6493126b17ea2191ea0ccf3e535adf" - integrity sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw== + version "1.15.6" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.6.tgz#7f815c0cda4249c74ff09e95ef97c23b5fd0399b" + integrity sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA== for-in@^1.0.2: version "1.0.2" From 6a6d2e56eef872f38fed13947140b9d1dc45ffe6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 23 Mar 2024 06:33:05 +0000 Subject: [PATCH 03/10] chore(deps): bump webpack-dev-middleware from 5.3.3 to 5.3.4 Bumps [webpack-dev-middleware](https://github.com/webpack/webpack-dev-middleware) from 5.3.3 to 5.3.4. - [Release notes](https://github.com/webpack/webpack-dev-middleware/releases) - [Changelog](https://github.com/webpack/webpack-dev-middleware/blob/v5.3.4/CHANGELOG.md) - [Commits](https://github.com/webpack/webpack-dev-middleware/compare/v5.3.3...v5.3.4) --- updated-dependencies: - dependency-name: webpack-dev-middleware dependency-type: indirect ... Signed-off-by: dependabot[bot] --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 9361d38c..c1566d5b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11462,9 +11462,9 @@ webpack-chain@6.5.1: javascript-stringify "^2.0.1" webpack-dev-middleware@^5.3.1: - version "5.3.3" - resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz#efae67c2793908e7311f1d9b06f2a08dcc97e51f" - integrity sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA== + version "5.3.4" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz#eb7b39281cbce10e104eb2b8bf2b63fce49a3517" + integrity sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q== dependencies: colorette "^2.0.10" memfs "^3.4.3" From f88529ddd6db1076cbe709bb874e8256bbc42440 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viterbo=20Rodr=C3=ADguez?= Date: Thu, 4 Apr 2024 18:39:04 -0300 Subject: [PATCH 04/10] fixing the math for isApproved proposal --- src/config/ConfigManager.ts | 14 ++++++++++++-- src/pages/ProposalItem.vue | 29 +++++++++++++++++++---------- 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/src/config/ConfigManager.ts b/src/config/ConfigManager.ts index 4bfb994a..1a0645bc 100644 --- a/src/config/ConfigManager.ts +++ b/src/config/ConfigManager.ts @@ -96,13 +96,23 @@ export default class ConfigManager { } private findChain(chainName: string) { - const fromMainnet = this.mainnets.find( + let fromMainnet = this.mainnets.find( c => c.getName() === chainName, ); if (fromMainnet) { return fromMainnet; + } else { + fromMainnet = this.testnets.find(c => c.getName() === chainName); } - return this.testnets.find(c => c.getName() === chainName); + if (fromMainnet) { + return fromMainnet; + } else { + if (typeof chainName === 'string') { + throw new Error(`Chain '${chainName}' not found`); + } else { + throw new Error('CHAIN_NAME env variable not found'); + } + } } } diff --git a/src/pages/ProposalItem.vue b/src/pages/ProposalItem.vue index 4f1b3257..52013c3d 100644 --- a/src/pages/ProposalItem.vue +++ b/src/pages/ProposalItem.vue @@ -40,6 +40,8 @@ export default defineComponent({ const multsigTransactionData = ref([]); const requestedApprovalsRows = ref([]); + const activeProducers = ref([]); + const activeProducersApproved = ref([]); const requestedApprovalsColumns = [ { @@ -99,15 +101,7 @@ export default defineComponent({ !isCanceled.value )); - const producersApprovalStatus = computed(() => { - const allProducers = requestedApprovalsRows.value.filter( - item => item.isBp, - ); - const producersHaveAlreadyApproved = allProducers.filter( - item => item.status, - ); - return `${producersHaveAlreadyApproved.length}/${allProducers.length}`; - }); + const producersApprovalStatus = computed(() => `${activeProducersApproved.value.length}/${activeProducers.value.length}`); function handleError(e: unknown, defaultMessage: string) { const error = JSON.parse(JSON.stringify(e)) as Error; @@ -282,7 +276,6 @@ export default defineComponent({ proposer.value = proposal.proposer; const totalRequestedApprovals = proposal.provided_approvals.length + proposal.requested_approvals.length; - isApproved.value = proposal.provided_approvals.length === totalRequestedApprovals; approvalStatus.value = `${proposal.provided_approvals.length}/${totalRequestedApprovals}`; isExecuted.value = proposal.executed; @@ -302,6 +295,22 @@ export default defineComponent({ requestedApprovalsRows.value = requestedApprovalsRowsValue; multsigTransactionData.value = multsigTransactionDataValue; + activeProducers.value = requestedApprovalsRows.value.filter( + item => item.isBp, + ); + activeProducersApproved.value = activeProducers.value.filter( + item => item.status, + ); + + if (activeProducers.value.length === 0) { + // No BPs are involved in the proposal, so we need to 100% of the requested approvals + isApproved.value = proposal.provided_approvals.length === totalRequestedApprovals; + } else { + // If BPs are involved, we need 2/3 (+1) of the BPs to approve the proposal + const approval = (activeProducers.value.length * 2 / 3) + 1; + isApproved.value = activeProducersApproved.value.length >= Math.floor(approval); + } + const transactions = await handleTransactionHistory(proposal.block_num); isCanceled.value = transactions.some( From d7964242ec4e1145f18d22f8a2244c19560cb5af Mon Sep 17 00:00:00 2001 From: lvyaoting Date: Mon, 8 Apr 2024 14:05:32 +0800 Subject: [PATCH 05/10] chore: fix some comments Signed-off-by: lvyaoting --- README.md | 4 ++-- test/jest/__tests__/store/account/actions.spec.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 57a0f713..bafa55ca 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ This includes following key features: - BP Voting and Governance - Premium Name bids -Following, excelent products can be taken as reference points for further features: +Following, excellent products can be taken as reference points for further features: - [EOS Authority](https://eosauthority.com/) - [Blocks](https://bloks.io/) @@ -112,7 +112,7 @@ app running at localhost:4000 [Vue 2 documentation](https://vuejs.org/v2/api/) -[Vue 3 documenation](https://v3.vuejs.org/) +[Vue 3 documentation](https://v3.vuejs.org/) [Testing Quasar with Jest](https://github.com/quasarframework/quasar-testing/tree/next/packages/unit-jest) diff --git a/test/jest/__tests__/store/account/actions.spec.ts b/test/jest/__tests__/store/account/actions.spec.ts index e7512228..e039e273 100644 --- a/test/jest/__tests__/store/account/actions.spec.ts +++ b/test/jest/__tests__/store/account/actions.spec.ts @@ -129,7 +129,7 @@ describe('Store - Account Actions', () => { }); describe('login()', () => { - test('when not account provided it should should request account', async () => { + test('when not account provided it should request account', async () => { authenticator = newAuthenticatorMock(true); // call the action login From 210b1451c948d7d786df70f76e476da4a0433123 Mon Sep 17 00:00:00 2001 From: Viterbo Date: Fri, 17 May 2024 13:33:24 -0300 Subject: [PATCH 06/10] removing account store unit test --- test/jest/__tests__/stores/account.spec.ts | 244 --------------------- 1 file changed, 244 deletions(-) delete mode 100644 test/jest/__tests__/stores/account.spec.ts diff --git a/test/jest/__tests__/stores/account.spec.ts b/test/jest/__tests__/stores/account.spec.ts deleted file mode 100644 index cabee198..00000000 --- a/test/jest/__tests__/stores/account.spec.ts +++ /dev/null @@ -1,244 +0,0 @@ -// import { AccountStateInterface } from 'src/stores/account'; - -import { Authenticator, User, UALError, ButtonStyle, Chain } from 'universal-authenticator-library'; -import { createPinia, setActivePinia } from 'pinia'; -import { useAccountStore } from 'src/stores/account'; - -const localStorageMock = { - getItem: jest.fn(), - setItem: jest.fn(), - removeItem:jest.fn(), -}; - -Object.defineProperty(window, 'localStorage', { value: localStorageMock }); - -const transactionHeaders = { - context_free_actions: [] as never[], - delay_sec: 123, - expiration: new Date(new Date().getTime() + 30000), - max_cpu_usage_ms: 99, - max_net_usage_words: 0, - ref_block_num: 0, - ref_block_prefix: 0, - transaction_extensions: [] as never[], -}; - -jest.mock('@greymass/eosio', () => ({ - Name: { - from: (s: string) => ({ toString: () => s }), - }, - UInt64: { - from: (i: number) => Number(i), - }, - APIClient: jest.fn().mockImplementation(() => ({ - v1: { - chain: { - get_info: () => ({ - getTransactionHeader: () => transactionHeaders, - }), - get_abi: () => Promise.resolve({ abi: 'abi' }), - push_transaction: () => ({ - transaction_id: 'transaction_id', - processed: { receipt: { status: 'status' } }, - }), - }, - }, - })), -})); - -jest.mock('src/api/fuel', () => ({ - FuelUserWrapper: class { - constructor() { - jest.fn(); - } - getAccountName() { - return 'john.doe'; - } - requestPermission = ''; - }, -})); -const chainIdMock = 'chainIdMock'; - -const users = [{ - name: 'John Doe', - getAccountName: jest.fn().mockResolvedValue('john.doe'), -} as unknown as User]; - -class MockAuthenticator extends Authenticator { - reset(): void { - throw new Error('Method not implemented.'); - } - isErrored(): boolean { - throw new Error('Method not implemented.'); - } - getOnboardingLink(): string { - throw new Error('Method not implemented.'); - } - getError(): UALError { - throw new Error('Method not implemented.'); - } - isLoading(): boolean { - throw new Error('Method not implemented.'); - } - getStyle(): ButtonStyle { - throw new Error('Method not implemented.'); - } - shouldRender(): boolean { - throw new Error('Method not implemented.'); - } - shouldAutoLogin(): boolean { - throw new Error('Method not implemented.'); - } - login(accountName?: string): Promise { - return Promise.resolve(users); - } - logout(): Promise { - throw new Error('Method not implemented.'); - } - requiresGetKeyConfirmation(): boolean { - throw new Error('Method not implemented.'); - } - getName(): string { - return 'autoLogin'; - } - init(): Promise { - // Implementation for initialization logic - return Promise.resolve(); - } - shouldRequestAccountName(): Promise { - return Promise.resolve(true); - } - chains: Chain[] = [{ - chainId: chainIdMock, - }] as unknown as Chain[] -} - -describe('Store - Account Actions', () => { - beforeEach(() => { - jest.clearAllMocks(); - setActivePinia(createPinia()); - - }); - - describe('login()', () => { - test('when no account is provided it should request account', async () => { - const accountStore = useAccountStore(); - - const authenticator = new MockAuthenticator(null); - - const accountStoreLoginSpy = jest.spyOn(accountStore, 'login'); - const mockInit = jest.spyOn(authenticator, 'init'); - const mockShouldRequestAccountName = jest.spyOn(authenticator, 'shouldRequestAccountName'); - - // call the action login - await accountStore.login( - { account: null, authenticator }, - ); - - // verify that the action called correctly the init function of the authenticator - expect(accountStoreLoginSpy).toHaveBeenCalledWith({ account: null, authenticator }); - - // // Verify that the action called correctly the commit mutation 'setRequestAccount' with the value true - expect(mockInit).toHaveBeenCalledTimes(1); - - expect(mockShouldRequestAccountName).toHaveBeenCalledTimes(1); - - }); - - test('when not account provided but not needed', async () => { - const accountStore = useAccountStore(); - const authenticator = new MockAuthenticator(null); - - const requestAccountSpy = jest.spyOn(authenticator, 'shouldRequestAccountName'); - const authenticatorInit = jest.spyOn(authenticator, 'init'); - const authenticatorLogin = jest.spyOn(authenticator, 'login'); - requestAccountSpy.mockResolvedValue(false); - - // call the action login - await accountStore.login( - { account: null, authenticator }, - ); - - // verify that the action called correctly the init function of the authenticator - expect(authenticatorInit).toHaveBeenCalled(); - - expect(requestAccountSpy).toHaveBeenCalled(); - expect(accountStore.requestAccount).toEqual(false); - - // Verify that the action called the login method of the authenticator - expect(authenticatorLogin).toHaveBeenCalled(); - expect(accountStore.accountPermission).toBe('active'); - expect(accountStore.isAuthenticated).toBe(true); - expect(accountStore.accountName).toBe('john.doe'); - expect(localStorageMock.setItem).toHaveBeenCalledWith('account_' + chainIdMock, 'john.doe'); - expect(localStorageMock.setItem).toHaveBeenCalledWith('autoLogin_' + chainIdMock, 'autoLogin'); - - }); - - test('when account provided - Normal case', async () => { - const accountStore = useAccountStore(); - const authenticator = new MockAuthenticator(null); - - const requestAccountSpy = jest.spyOn(authenticator, 'shouldRequestAccountName'); - const authenticatorInit = jest.spyOn(authenticator, 'init'); - const authenticatorLogin = jest.spyOn(authenticator, 'login'); - requestAccountSpy.mockResolvedValue(false); - - // call the action login - await accountStore.login( - { account: 'john.doe', authenticator }, - ); - - // Verify that the action called correctly the init function of the authenticator - expect(authenticatorInit).toHaveBeenCalled(); - - // Verify that the action called the login method of the authenticator - expect(authenticatorLogin).toHaveBeenCalled(); - expect(accountStore.accountPermission).toBe('active'); - expect(accountStore.isAuthenticated).toBe(true); - expect(accountStore.accountName).toBe('john.doe'); - expect(localStorageMock.setItem).toHaveBeenCalledWith('account_' + chainIdMock, 'john.doe'); - expect(localStorageMock.setItem).toHaveBeenCalledWith('autoLogin_' + chainIdMock, 'autoLogin'); - }); - - }); - - describe('logout()', () => { - beforeEach(async () => { - jest.clearAllMocks(); - - // Logs in - const accountStore = useAccountStore(); - const authenticator = new MockAuthenticator(null); - await accountStore.login( - { account: 'john.doe', authenticator }, - ); - }); - - test('normal case', () => { - const accountStore = useAccountStore(); - - expect(accountStore.user).not.toBe(null); - expect(accountStore.accountPermission).toBe('active'); - expect(accountStore.isAuthenticated).toBe(true); - expect(accountStore.accountName).toBe('john.doe'); - - // call the action logout - accountStore.logout(); - - expect(accountStore.user).toBe(null); - expect(accountStore.isAuthenticated).toBe(false); - expect(accountStore.accountName).toBe(''); - - expect(localStorageMock.removeItem).toHaveBeenCalledWith('account_' + chainIdMock); - expect(localStorageMock.removeItem).toHaveBeenCalledWith('autoLogin_' + chainIdMock); - }); - }); -}); - - - - - - - From f757de3d73fc34b04fd1a758e8f8db843cc75748 Mon Sep 17 00:00:00 2001 From: Karyne Mayer Date: Wed, 17 Apr 2024 19:56:07 -0700 Subject: [PATCH 07/10] Replaces UAL and cleos with wharfkit --- package.json | 10 +- quasar.conf.js | 2 +- src/api/eosio_core.ts | 2 +- src/api/fuel.ts | 573 ------------------ src/boot/fuel.ts | 14 - src/boot/ual.ts | 174 ------ src/boot/wharf.ts | 45 ++ src/components/AccountCard.vue | 2 +- src/components/KeyAccountsCard.vue | 2 +- src/components/KeyToggle.vue | 2 +- src/components/KeysPanel.vue | 2 +- src/components/LoginHandler.vue | 57 +- src/components/LoginHandlerDropdown.vue | 17 +- src/components/ProposalAuthorization.vue | 2 +- src/components/WalletModal.vue | 46 +- src/components/contract/ContractActions.vue | 6 +- src/components/resources/BuyRam.vue | 2 +- src/components/resources/RefundTab.vue | 11 +- src/components/resources/ResourcesInfo.vue | 2 +- src/components/resources/SellRam.vue | 2 +- src/components/staking/ProcessingTab.vue | 2 +- src/components/staking/SavingsTab.vue | 2 +- src/components/staking/StakeFromResources.vue | 2 +- src/components/staking/StakingDialog.vue | 37 +- src/components/staking/StakingInfo.vue | 2 +- src/components/staking/StakingTab.vue | 2 +- src/components/staking/UnstakingTab.vue | 2 +- src/components/validators/ValidatorData.vue | 2 +- src/config/BaseChain.ts | 7 +- src/config/chains/eos/index.ts | 21 +- src/config/chains/jungle/index.ts | 15 +- src/config/chains/telos-testnet/index.ts | 15 +- src/config/chains/telos/index.ts | 21 +- src/config/chains/ux/index.ts | 15 +- src/config/chains/wax/index.ts | 15 +- src/pages/Key.vue | 2 +- src/pages/ProposalItem.vue | 22 +- src/pages/ProposalNew.vue | 27 +- src/stores/account.ts | 187 ++---- src/types/Actions.ts | 2 +- src/types/Api.ts | 2 +- src/types/Chain.d.ts | 2 +- src/types/vue-global.d.ts | 6 +- test/jest/__tests__/api/fuel.spec.ts | 348 ----------- test/jest/__tests__/boot/ual.spec.ts | 144 ----- test/jest/__tests__/stores/account.spec.ts | 128 ++++ test/jest/__tests__/stores/resources.spec.ts | 6 +- yarn.lock | 362 ++++++----- 48 files changed, 549 insertions(+), 1822 deletions(-) delete mode 100644 src/api/fuel.ts delete mode 100644 src/boot/fuel.ts delete mode 100644 src/boot/ual.ts create mode 100644 src/boot/wharf.ts delete mode 100644 test/jest/__tests__/api/fuel.spec.ts delete mode 100644 test/jest/__tests__/boot/ual.spec.ts create mode 100644 test/jest/__tests__/stores/account.spec.ts diff --git a/package.json b/package.json index 6021a9fd..dd1e8c21 100644 --- a/package.json +++ b/package.json @@ -13,9 +13,13 @@ "test:coverage": "jest --coverage" }, "dependencies": { - "@greymass/eosio": "^0.6.8", "@quasar/extras": "^1.13.4", - "@telosnetwork/ual-cleos": "^1.13.1", + "@wharfkit/session": "^1.2.8", + "@wharfkit/transact-plugin-resource-provider": "^1.1.1", + "@wharfkit/wallet-plugin-anchor": "^1.3.4", + "@wharfkit/wallet-plugin-cleos": "^1.1.1", + "@wharfkit/wallet-plugin-privatekey": "^1.1.0", + "@wharfkit/web-renderer": "^1.2.4", "axios": "^0.21.1", "core-js": "^3.6.5", "csvtojson": "^2.0.10", @@ -26,8 +30,6 @@ "ol": "^6.14.1", "pinia": "^2.1.6", "quasar": "^2.6.2", - "ual-anchor": "1.3.0", - "universal-authenticator-library": "^0.3.0", "vue": "^3.3.0", "vue-json-viewer": "^3.0.4", "vue-router": "^4.0.0", diff --git a/quasar.conf.js b/quasar.conf.js index 9c5eea74..a22292dd 100644 --- a/quasar.conf.js +++ b/quasar.conf.js @@ -30,7 +30,7 @@ module.exports = configure(function (ctx) { // app boot file (/src/boot) // --> boot files are part of "main.js" // https://quasar.dev/quasar-cli/boot-files - boot: ['config', 'fathom', 'api', 'ual', 'fuel'], + boot: ['config', 'fathom', 'api', 'wharf'], // https://quasar.dev/quasar-cli/quasar-conf-js#Property%3A-css css: ['app.sass'], diff --git a/src/api/eosio_core.ts b/src/api/eosio_core.ts index c8af814a..196b7aba 100644 --- a/src/api/eosio_core.ts +++ b/src/api/eosio_core.ts @@ -9,7 +9,7 @@ import { Serializer, PublicKey, Name, -} from '@greymass/eosio'; +} from '@wharfkit/session'; import { GetTableRowsParams } from 'src/types'; import { Chain } from 'src/types/Chain'; import { getChain } from 'src/config/ConfigManager'; diff --git a/src/api/fuel.ts b/src/api/fuel.ts deleted file mode 100644 index 71de5b60..00000000 --- a/src/api/fuel.ts +++ /dev/null @@ -1,573 +0,0 @@ -/* eslint-disable quotes */ -/* eslint-disable @typescript-eslint/no-unsafe-assignment */ -// Most of this code was taken and addapted from https://gist.github.com/aaroncox/d74a73b3d9fbc20836c32ea9deda5d70 -import { - SignTransactionConfig, - SignTransactionResponse, - User, -} from 'universal-authenticator-library'; -import { - AnyTransaction, - APIClient, - Name, - NameType, - PackedTransaction, - PermissionLevel, - Serializer, - Signature, - SignedTransaction, - Transaction, -} from '@greymass/eosio'; -import { getChain } from 'src/config/ConfigManager'; -import { Dialog } from 'quasar'; -import { formatCurrency } from "src/utils/string-utils"; - -// The maximum fee per transaction this script is willing to accept -const maxFee = 0.05; - -// expire time in millisec -const expireSeconds = 3600; - -const chain = getChain(); -const client = new APIClient({ - url: chain.getHyperionEndpoint(), -}); - -const fuelrpc = chain.getFuelRPCEndpoint(); -const resourceProviderEndpoint = `${fuelrpc?.protocol}://${fuelrpc?.host}:${fuelrpc?.port}/v1/resource_provider/request_transaction`; - -// Auxiliar interfaces -interface ResourceProviderResponse { - code: number; - data: ResponseData; -} - -interface CostsType { - ram: string; - cpu: string; - net: string; -} - -interface ResponseData { - request: [string, SignedTransaction]; - signatures: Signature[]; - version: number; - costs?: CostsType; -} - -interface SignedTransactionResponse extends SignTransactionResponse { - transaction: { signatures: Signature[] }; -} - -// Wrapper for the user to intersect the signTransaction call -export class FuelUserWrapper extends User { - constructor(private user: User) { - super(); - } - - async signTransaction( - originalTransaction: AnyTransaction, - originalconfig?: SignTransactionConfig, - ): Promise { - try { - // if fuel is not supported, just let the normal implementation perform - if (!fuelrpc) { - return this.user.signTransaction(originalTransaction, originalconfig); - } - - // Retrieve transaction headers - const info = await client.v1.chain.get_info(); - const header = info.getTransactionHeader(expireSeconds); - - // collect all contract abis - const abi_promises = originalTransaction.actions.map(a => - client.v1.chain.get_abi(a.account), - ); - const responses = await Promise.all(abi_promises); - const abis = responses.map(x => x.abi); - const abis_and_names = originalTransaction.actions.map((x, i) => ({ - contract: x.account, - abi: abis[i], - })); - - // create complete well formed transaction - const transaction = Transaction.from( - { - ...header, - actions: originalTransaction.actions, - }, - abis_and_names, - ); - - // Pack the transaction for transport - const packedTransaction = PackedTransaction.from({ - signatures: [], - packed_context_free_data: '', - packed_trx: Serializer.encode({ object: transaction }), - }); - - const signer = PermissionLevel.from({ - actor: (await this.user.getAccountName()) as NameType, - permission: this.requestPermission, - }); - - // Submit the transaction to the resource provider endpoint - const cosigned = await fetch(resourceProviderEndpoint, { - body: JSON.stringify({ - signer, - packedTransaction, - }), - method: 'POST', - }); - - // Interpret the resulting JSON - const rpResponse = - (await cosigned.json()) as unknown as ResourceProviderResponse; - - switch (rpResponse.code) { - case 402: { - // Resource Provider provided signature in exchange for a fee - // is ok to treat them with the same logic of code = 200? - // Yes acording to this: https://gist.github.com/aaroncox/d74a73b3d9fbc20836c32ea9deda5d70#file-fuel-core-presign-js-L128-L159 - // Aron rightly suggests that we should show and confirm the fee costs for this service: - // https://github.com/telosnetwork/open-block-explorer/pull/477#discussion_r1053417964 - } - case 200: { - // Resource Provider provided signature for free - - const { data } = rpResponse; - const [, returnedTransaction] = data.request; - const modifiedTransaction: SignedTransaction = returnedTransaction; - - // Ensure the modifed transaction is what the application expects - // These validation methods will throw an exception if invalid data exists - const fees: string | null = validateTransaction( - signer, - modifiedTransaction, - transaction, - data.costs, - ); - - // validate with the user whether to use the service at all - try { - await confirmWithUser(this.user, fees); - } catch (e) { - // The user refuseed to use the service - break; - } - - modifiedTransaction.signatures = [...data.signatures]; - // Sign the modified transaction - const locallySigned: SignedTransactionResponse = - (await this.user.signTransaction( - modifiedTransaction, - Object.assign({ broadcast: false }, originalconfig), - )) as SignedTransactionResponse; - - // When using CleosAuthenticator the transaction returns empty - if (!locallySigned.transaction.signatures) { - return Promise.reject( - 'The transaction was not broadcasted because no signatures were obtained', - ); - } - - // Merge signatures from the user and the cosigned responsetab - modifiedTransaction.signatures = [ - ...locallySigned.transaction.signatures, - ...data.signatures, - ]; - - // Broadcast the signed transaction to the blockchain - const pushResponse = await client.v1.chain.push_transaction( - modifiedTransaction, - ); - - // we compose the final response - const finalResponse: SignTransactionResponse = { - wasBroadcast: true, - transactionId: pushResponse.transaction_id, - status: pushResponse.processed.receipt.status, - transaction: modifiedTransaction, - }; - - return Promise.resolve(finalResponse); - } - case 400: { - // Resource Provider refused to sign the transaction, aborting - break; - } - default: - throw ( - 'Code ' + - (+rpResponse.code).toString() + - ' not expected from resource provider endpoint: ' + - resourceProviderEndpoint - ); - } - - // If we got here it means the resource provider will not participate in this transaction - return this.user.signTransaction(originalTransaction, originalconfig); - } catch (e) { - throw e; - } - } - - // since this is a wrapper is also wraps the posible requestPermission hidden property - get requestPermission() { - return ( - (this.user as unknown as { requestPermission: string }) - .requestPermission || 'active' - ); - } - - // These functions are just proxies - signArbitrary = async ( - publicKey: string, - data: string, - helpText: string, - ): Promise => this.user.signArbitrary(publicKey, data, helpText); - verifyKeyOwnership = async (challenge: string): Promise => - this.user.verifyKeyOwnership(challenge); - getAccountName = async (): Promise => this.user.getAccountName(); - getChainId = async (): Promise => this.user.getChainId(); - getKeys = async (): Promise => this.user.getKeys(); -} - -// Auxiliar functions to validate with the user the use of the service -interface Preference { - remember?: boolean; - approve?: boolean; -} -export default class GreymassFuelService { - static preferences: { [account: string]: Preference } = {}; - static globals: Record string> = null; - static save() { - localStorage.setItem( - 'fuel_preferences', - JSON.stringify(GreymassFuelService.preferences), - ); - } - static drop() { - localStorage.removeItem('fuel_preferences'); - } - static load() { - try { - GreymassFuelService.preferences = GreymassFuelService.preferences || {}; - const str = localStorage.getItem('fuel_preferences'); - if (str) { - GreymassFuelService.preferences = JSON.parse(str); - } - } catch (e) { - console.error('ERROR: ', e); - } - } - - static setPreferences(account: string, p: Preference) { - GreymassFuelService.preferences[account] = { - ...GreymassFuelService.preferences[account], - ...p, - }; - if (GreymassFuelService.preferences[account].remember) { - GreymassFuelService.save(); - } else { - GreymassFuelService.drop(); - } - } - static setGlobals(g: Record string>) { - GreymassFuelService.globals = g; - } -} - -async function confirmWithUser(user: User, fees: string | null) { - const username = await user.getAccountName(); - let mymodel: string[] = []; - mymodel = []; - - return new Promise((resolve, reject) => { - // Try and see if the user already answer (remembered) - if ( - GreymassFuelService.preferences[username] && - GreymassFuelService.preferences[username].remember - ) { - // ok, the user did. What's the answer? - if (GreymassFuelService.preferences[username].approve) { - resolve(); - } else { - reject(); - } - return; - } - - const handler = function (approve: boolean) { - GreymassFuelService.setPreferences(username, { approve }); - if (approve) { - resolve(); - } else { - reject(); - } - }; - - // this are the normal texts for random wallet. - const cancel: string | boolean = 'Reject'; - const ok = 'Confirm'; - let message = - "Your account doesn't have sufficient resources (CPU, NET, or RAM) to pay for your next transaction. " + - 'Don\'t worry! Telos has partnered with Greymass to proceed with your transaction using "Greymass Fuel", allowing you to continue for free.

' + - 'We recommend powering up your account with at least 0.5 TLOS in CPU and NET each and purchasing RAM, as this service is not supported on all dAPPs in our ecosystem. Please click here to proceed and power up your account'; - - // If the wallet is Greymass Anchor is not possible to avoid Fuel service (it is incorporated) - try { - if (typeof fees === 'string') { - message = - "Your account doesn't have sufficient resources (CPU, NET, or RAM) to pay for your next transaction and it can not be processed without fees. " + - 'Telos has partnered with Greymass to proceed with your transaction using "Greymass Fuel", reducing cost significantly.

' + - 'Please confirm fees below to proceed.

' + - `
${fees}

` + - 'We recommend powering up your account with at least 0.5 TLOS in CPU and NET each and purchasing RAM, as this service is not supported on all dAPPs in our ecosystem. Please click here to proceed and power up your account'; - } - } catch (e) {} - - Dialog.create({ - title: 'Resource Warning!', - message, - html: true, - cancel, - ok, - persistent: true, - options: { - type: 'checkbox', - model: mymodel, - isValid: (model: string | string[]) => { - GreymassFuelService.setPreferences(username, { - remember: model.length === 1, - }); - return true; - }, - items: [ - { label: 'Remember my decision', value: 'remember', color: 'primary' }, - ], - }, - }) - // all answers should save the preferences - .onOk(() => handler(true)) - .onCancel(() => handler(false)); - }); -} - -// Auxiliar functions to validate modified transaction returned by the resourse provider - -// Validate the transaction -function validateTransaction( - signer: PermissionLevel, - modifiedTransaction: Transaction, - transaction: Transaction, - costs: CostsType | null = null, -): string | null { - // Ensure the first action is the `greymassnoop:noop` - validateNoop(modifiedTransaction); - - // Ensure the actions within the transaction match what was provided - return validateActions(signer, modifiedTransaction, transaction, costs); -} - -// Validate the actions of the modified transaction vs the original transaction -function validateActions( - signer: PermissionLevel, - modifiedTransaction: Transaction, - transaction: Transaction, - costs: CostsType | null, -): string | null { - // Determine how many actions we expect to have been added to the transaction based on the costs - const expectedNewActions = determineExpectedActionsLength(costs); - - // Ensure the proper number of actions was returned - validateActionsLength(expectedNewActions, modifiedTransaction, transaction); - - // Ensure the appended actions were expected - return validateActionsContent( - signer, - expectedNewActions, - modifiedTransaction, - transaction, - ); -} - -// Validate the number of actions is the number expected -function determineExpectedActionsLength(costs: CostsType | null) { - // By default, 1 new action is appended (noop) - let expectedNewActions = 1; - - // If there are costs associated with this transaction, 1 new actions is added (the fee) - if (costs) { - expectedNewActions += 1; - - // RAM cost is in format '0.000 TLOS' - const ramCostAsNumber = +(costs.ram.replace(/[^0-9.]/g, '')); - - // If there is a RAM cost associated with this transaction, 1 new action is added (the ram purchase) - if (ramCostAsNumber !== 0) { - expectedNewActions += 1; - } - } - - return expectedNewActions; -} - -// Validate the contents of each action -function validateActionsContent( - signer: PermissionLevel, - expectedNewActions: number, - modifiedTransaction: Transaction, - transaction: Transaction, -): string | null { - // Make sure the originally requested actions are still intact and unmodified - validateActionsOriginalContent( - expectedNewActions, - modifiedTransaction, - transaction, - ); - - // If a fee has been added, ensure the fee is set properly - if (expectedNewActions > 1) { - let totalFee: null | number = null; - totalFee = validateActionsFeeContent(signer, modifiedTransaction); - // If a ram purchase has been added, ensure the purchase was set properly - if (expectedNewActions > 2) { - validateActionsRamContent(signer, modifiedTransaction); - } - return formatCurrency(totalFee, 4, 'TLOS', true); - } else { - return null; - } -} - -interface AuxTransactionData { - [key: string]: string; -} - -function descerialize(data: unknown): AuxTransactionData { - return data as AuxTransactionData; -} - -// Ensure the transaction fee transfer is valid -function validateActionsFeeContent( - signer: PermissionLevel, - modifiedTransaction: Transaction, -): number { - const feeAction = modifiedTransaction.actions[1]; - const data = descerialize(feeAction.data); - const amount = parseFloat(data.quantity?.split(' ')[0]); - if (amount > maxFee) { - throw new Error(`Fee of ${amount} exceeds the maximum fee of ${maxFee}.`); - } - if ( - feeAction.account.toString() !== 'eosio.token' || - feeAction.name.toString() !== 'transfer' || - data.to.toString() !== 'fuel.gm' - ) { - throw new Error('Fee action was deemed invalid.'); - } - return amount; -} - -// Ensure the RAM purchasing action is valid -function validateActionsRamContent( - signer: PermissionLevel, - modifiedTransaction: Transaction, -): number { - const ramAction = modifiedTransaction.actions[2]; - const data = descerialize(ramAction.data); - const amount = parseFloat(data.quant?.split(' ')[0]); - - if ( - ramAction.account.toString() !== 'eosio' || - !['buyram', 'buyrambytes'].includes(String(ramAction.name)) || - data.payer.toString() !== 'greymassfuel' || - data.receiver.toString() !== signer.actor.toString() - ) { - throw new Error('RAM action was deemed invalid.'); - } - return amount; -} - -// Make sure the actions returned in the API response match what was submitted -function validateActionsOriginalContent( - expectedNewActions: number, - modifiedTransaction: Transaction, - transaction: Transaction, -) { - for (const [i] of modifiedTransaction.actions.entries()) { - // Skip the expected new actions - if (i < expectedNewActions) { - continue; - } - // Compare each action to the originally generated actions - const original = transaction.actions[i - expectedNewActions]; - const action = modifiedTransaction.actions[i]; - const matchesAccount = - action.account.toString() === original.account.toString(); - const matchesAction = action.name.toString() === original.name.toString(); - const matchesLength = - action.authorization.length === original.authorization.length; - const matchesActor = - action.authorization[0].actor.toString() === - original.authorization[0].actor.toString(); - const matchesPermission = - action.authorization[0].permission.toString() === - original.authorization[0].permission.toString(); - const matchesData = action.data.toString() === original.data.toString(); - if ( - !action || - !matchesAccount || - !matchesAction || - !matchesLength || - !matchesActor || - !matchesPermission || - !matchesData - ) { - const { account, name } = original; - throw new Error( - `Transaction returned by API has non-matching action at index ${i} (${account.toString()}:${name.toString()})`, - ); - } - } -} - -// Ensure no unexpected actions were appended in the response -function validateActionsLength( - expectedNewActions: number, - modifiedTransaction: Transaction, - transaction: Transaction, -) { - if ( - modifiedTransaction.actions.length !== - transaction.actions.length + expectedNewActions - ) { - throw new Error('transaction returned contains additional actions.'); - } -} - -const expectedCosignerContract = Name.from('greymassnoop'); -const expectedCosignerAction = Name.from('noop'); -const expectedCosignerAccountName = Name.from('greymassfuel'); -const expectedCosignerAccountPermission = Name.from('cosign'); - -// Make sure the first action is the greymassnoop:noop and properly defined -function validateNoop(modifiedTransaction: Transaction) { - const [firstAction] = modifiedTransaction.actions; - const [firstAuthorization] = firstAction.authorization; - if ( - firstAction.account.toString() !== expectedCosignerContract.toString() || - firstAction.name.toString() !== expectedCosignerAction.toString() || - firstAuthorization.actor.toString() !== - expectedCosignerAccountName.toString() || - firstAuthorization.permission.toString() !== - expectedCosignerAccountPermission.toString() || - (JSON.stringify(firstAction.data) !== '""' && - JSON.stringify(firstAction.data) !== '{}') - ) { - throw new Error( - `First action within transaction response is not valid noop (${expectedCosignerContract.toString()}:${expectedCosignerAction.toString()} signed by ${expectedCosignerAccountName.toString()}:${expectedCosignerAccountPermission.toString()}).`, - ); - } -} diff --git a/src/boot/fuel.ts b/src/boot/fuel.ts deleted file mode 100644 index d07093d9..00000000 --- a/src/boot/fuel.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { boot } from 'quasar/wrappers'; -import GreymassFuelService from 'src/api/fuel'; - -declare module '@vue/runtime-core' { - interface ComponentCustomProperties { - $fuel: GreymassFuelService; - } -} - -export default boot(({ app }) => { - app.config.globalProperties.$fuel = GreymassFuelService; - GreymassFuelService.setGlobals(app.config.globalProperties); - GreymassFuelService.load(); -}); diff --git a/src/boot/ual.ts b/src/boot/ual.ts deleted file mode 100644 index 3c83f6f4..00000000 --- a/src/boot/ual.ts +++ /dev/null @@ -1,174 +0,0 @@ -import { boot } from 'quasar/wrappers'; -import { - Authenticator, - RpcEndpoint, - UAL, - User, -} from 'universal-authenticator-library'; -import { Anchor } from 'ual-anchor'; -import { getChain } from 'src/config/ConfigManager'; -import { CleosAuthenticator } from '@telosnetwork/ual-cleos'; -import { Dialog, Notify, copyToClipboard } from 'quasar'; -import { isValidAccount } from 'src/utils/string-utils'; - -declare module '@vue/runtime-core' { - interface ComponentCustomProperties { - $ual: UAL; - $user: User; - } -} - -async function loginHandler() { - let accountName = 'eosio'; - let permission = 'active'; - if (localStorage.getItem('autoLogin_' + getChain().getChainId()) === 'cleos') { - accountName = localStorage.getItem('account_' + getChain().getChainId()); - } else { - await new Promise((resolve) => { - Dialog.create({ - color: 'primary', - title: 'Connect to cleos', - message: 'Account name (.,a-z,1-5)', - prompt: { - model: '', - type: 'text', - isValid: val => isValidAccount(val), - }, - cancel: true, - persistent: true, - }) - .onOk((data: string) => { - accountName = data !== '' ? data : 'eosio'; - }) - .onCancel(() => { - throw 'Cancelled!'; - }) - .onDismiss(() => { - resolve(true); - }); - }); - await new Promise((resolve) => { - Dialog.create({ - color: 'primary', - title: 'Connect to cleos', - message: 'Account permission', - options: { - type: 'radio', - model: [], - items: [ - { label: 'Active', value: 'active' }, - { label: 'Owner', value: 'owner' }, - ], - }, - cancel: true, - persistent: true, - }) - .onOk((data: string) => { - permission = data; - }) - .onCancel(() => { - throw 'Cancelled!'; - }) - .onDismiss(() => { - resolve(true); - }); - }); - } - return { - accountName, - permission, - }; -} - -async function signHandler(rpc: RpcEndpoint, trx: string) { - const trxJSON: string = JSON.stringify( - Object.assign( - { - delay_sec: 0, - max_cpu_usage_ms: 0, - }, - trx, - ), - null, - 4, - ); - await new Promise((resolve) => { - Dialog.create({ - color: 'primary', - message: `
cleos -u ${rpc.protocol}://${rpc.host}:${rpc.port} push transaction '${trxJSON}'
`, - html: true, - cancel: true, - fullWidth: true, - ok: { - label: 'Copy', - }, - }) - .onOk(() => { - copyToClipboard( - `cleos -u ${rpc.protocol}://${rpc.host}:${rpc.port} push transaction '${trxJSON}'`, - ) - .then((): void => { - Notify.create({ - color: 'green-4', - textColor: 'white', - message: 'Copied to clipboard', - timeout: 1000, - }); - }) - .catch(() => { - Notify.create({ - color: 'red-8', - textColor: 'white', - message: 'Could not copy', - timeout: 1000, - }); - }); - }) - .onCancel(() => { - throw 'Cancelled!'; - }) - .onDismiss(() => { - resolve(true); - }); - }); -} - -async function signHandlerForMainChain(trx: string) { - return signHandler(getChain().getRPCEndpoint(), trx); -} - -function getMainChain() { - return { - chainId: getChain().getChainId(), - rpcEndpoints: [getChain().getRPCEndpoint()], - }; -} - -const authenticators: Authenticator[] = []; - -export const getAuthenticators = () => { - // we initialize the authenticators inside this function on demand - if (authenticators.length === 0) { - // UAL is not looking at the chain when checking the sessionStorage for an already logged in account - // A quick fix is to add the chain in appName until we move forward with WharfKit - const mainChain = getMainChain(); - authenticators.push(new Anchor([mainChain], { appName: `${process.env.APP_NAME}_${mainChain.chainId}` })), - authenticators.push(new CleosAuthenticator([mainChain], { - appName: `${process.env.APP_NAME}_${mainChain.chainId}`, - loginHandler, - signHandler: signHandlerForMainChain, - })); - } - return authenticators; -}; - -export const resetUalState = () => { - authenticators.length = 0; -}; - -export default boot(({ app }) => { - const authenticators = getAuthenticators(); - const ual = new UAL([getMainChain()], 'ual', authenticators); - - app.config.globalProperties.$ual = ual; -}); diff --git a/src/boot/wharf.ts b/src/boot/wharf.ts new file mode 100644 index 00000000..a70e613d --- /dev/null +++ b/src/boot/wharf.ts @@ -0,0 +1,45 @@ +import { Session, SessionKit } from '@wharfkit/session'; +import { TransactPluginResourceProvider } from '@wharfkit/transact-plugin-resource-provider'; +import { WalletPluginAnchor } from '@wharfkit/wallet-plugin-anchor'; +import { WalletPluginCleos } from '@wharfkit/wallet-plugin-cleos'; +import { WalletPluginPrivateKey } from '@wharfkit/wallet-plugin-privatekey'; +import WebRenderer from '@wharfkit/web-renderer'; +import { boot } from 'quasar/wrappers'; +import { getChain } from 'src/config/ConfigManager'; +import { Chain } from 'src/types/Chain'; + +const chain: Chain = getChain(); + +declare module 'vue' { + interface ComponentCustomProperties { + $kit: SessionKit; + $user: Session; + } +} + +export const ui = new WebRenderer(); + +export const kit = new SessionKit({ + appName: process.env.APP_NAME, + chains: [ + { + id: chain.getChainId(), + url: String(chain.getRPCEndpoint()), + }, + ], + ui, + walletPlugins: [ + new WalletPluginAnchor(), + new WalletPluginCleos(), + new WalletPluginPrivateKey('5Jtoxgny5tT7NiNFp1MLogviuPJ9NniWjnU4wKzaX4t7pL4kJ8s'), + ], +}, +{ + transactPlugins: [ + new TransactPluginResourceProvider(), + ], +}); + +export default boot(({ app }) => { + app.config.globalProperties.$kit = kit; +}); diff --git a/src/components/AccountCard.vue b/src/components/AccountCard.vue index 0e7d28d4..d5bb35dd 100644 --- a/src/components/AccountCard.vue +++ b/src/components/AccountCard.vue @@ -11,7 +11,7 @@ import { getChain } from 'src/config/ConfigManager'; import { api } from 'src/api'; import { useRouter } from 'vue-router'; import { TableIndexType } from 'src/types/Api'; -import { API, UInt64 } from '@greymass/eosio'; +import { API, UInt64 } from '@wharfkit/session'; import { formatCurrency } from 'src/utils/string-utils'; import ConfigManager from 'src/config/ConfigManager'; import { isSystemAccount } from 'src/utils/systemAccount'; diff --git a/src/components/KeyAccountsCard.vue b/src/components/KeyAccountsCard.vue index 62a18122..7d203355 100644 --- a/src/components/KeyAccountsCard.vue +++ b/src/components/KeyAccountsCard.vue @@ -3,7 +3,7 @@ import { useQuasar } from 'quasar'; import { defineComponent, PropType, computed, ref } from 'vue'; import { copyToClipboard } from 'quasar'; import { getChain } from 'src/config/ConfigManager'; -import { Name, PublicKey } from '@greymass/eosio'; +import { Name, PublicKey } from '@wharfkit/session'; export default defineComponent({ name: 'KeyAccountsCard', diff --git a/src/components/KeyToggle.vue b/src/components/KeyToggle.vue index 4516492d..48944151 100644 --- a/src/components/KeyToggle.vue +++ b/src/components/KeyToggle.vue @@ -2,7 +2,7 @@ import { useQuasar } from 'quasar'; import { computed, defineComponent, ref } from 'vue'; import { copyToClipboard } from 'quasar'; -import { PublicKey, Weight } from '@greymass/eosio'; +import { PublicKey, Weight } from '@wharfkit/session'; export default defineComponent({ name: 'KeyToggle', diff --git a/src/components/KeysPanel.vue b/src/components/KeysPanel.vue index 98aed1f9..462a22a1 100644 --- a/src/components/KeysPanel.vue +++ b/src/components/KeysPanel.vue @@ -4,7 +4,7 @@ import PermissionCard from 'components/PermissionCard.vue'; import { computed, defineComponent, onMounted, ref, watch } from 'vue'; import { api } from 'src/api'; import { useQuasar } from 'quasar'; -import { API } from '@greymass/eosio'; +import { API } from '@wharfkit/session'; export default defineComponent({ name: 'KeysPanel', diff --git a/src/components/LoginHandler.vue b/src/components/LoginHandler.vue index d572f959..606faa6d 100644 --- a/src/components/LoginHandler.vue +++ b/src/components/LoginHandler.vue @@ -1,42 +1,56 @@