diff --git a/src/components/MainFooter.vue b/src/components/MainFooter.vue index 1bce43d..b7d3072 100644 --- a/src/components/MainFooter.vue +++ b/src/components/MainFooter.vue @@ -47,9 +47,10 @@ import { useWalletStore } from 'src/stores/wallet'; import { useQuasar } from 'quasar' import { useRouter } from 'vue-router' -import { defineComponent, computed } from 'vue' +import { defineComponent, computed, onMounted } from 'vue' import SetAmountFormDialog from 'src/components/SetAmountFormDialog.vue' +import { Wallet } from 'src/wallet' export default defineComponent({ @@ -61,6 +62,20 @@ export default defineComponent({ const selectedCurrency = computed(() => walletStore.preferences.selectedCurrency) + async function generateFirstReceivingAddress () { + const wallet = new Wallet({ + xPubKey: walletStore.xPubKey, + walletHash: walletStore.walletHash, + posId: walletStore.posId, + }) + const addressSet = await wallet.generateReceivingAddress(1, { skipSubscription: false }) + return addressSet.receiving + } + onMounted(async () => { + const firstReceivingAddress = await generateFirstReceivingAddress() + walletStore.$patch({ firstReceivingAddress }) + }) + function promptAmount () { $q.dialog({ component: SetAmountFormDialog, diff --git a/src/components/marketplace/storefront/settings/StorefrontInfoForm.vue b/src/components/marketplace/storefront/settings/StorefrontInfoForm.vue index c32bba2..2daee08 100644 --- a/src/components/marketplace/storefront/settings/StorefrontInfoForm.vue +++ b/src/components/marketplace/storefront/settings/StorefrontInfoForm.vue @@ -33,8 +33,20 @@ />
-
Receiving address
+
+
Receiving address
+ +
-
@@ -92,9 +96,10 @@ import { Product } from 'src/marketplace/objects' import { backend } from 'src/marketplace/backend' import { errorParser } from 'src/marketplace/utils' +import { asyncSleep } from 'src/wallet/utils' import { useMarketplaceStore } from 'src/stores/marketplace' import { useAddressesStore } from 'src/stores/addresses' -import { defineComponent, ref } from 'vue' +import { defineComponent, onMounted, ref } from 'vue' import UploadImageField from 'src/components/marketplace/UploadImageField.vue' import ProductSearchPanel from 'src/components/marketplace/ProductSearchPanel.vue' @@ -122,23 +127,49 @@ export default defineComponent({ subscribeProducts: [].map(Product.parse) }) - function updateReceivingAddress() { - let address = formData.value.receivingAddress - - const opts = addressesStore.addressSets - .map(addressSet => addressSet?.receiving) - .filter((e, i, s) => s.indexOf(e) === i) - .filter(Boolean) - - if (opts?.length <= 0) return + onMounted(() => { + if (!marketplaceStore.storefrontData?.id && !formData.value?.receivingAddress) { + updateReceivingAddress() + } + }) - const index = opts.indexOf(address) - // we want to change address like it's rotating around the address sets stored - const rotatedOpts = [ - ...opts.slice(index+1), - ...opts.slice(0, index+1), - ] - formData.value.receivingAddress = rotatedOpts.find(addr => addr != address) + const updatingReceivingAddress = ref(false) + async function updateReceivingAddress() { + try { + updatingReceivingAddress.value = true + let address = formData.value.receivingAddress + if (!addressesStore.addressSets.length) await addressesStore.fillAddressSets().catch(console.error) + else await asyncSleep(250).catch(console.error) + + const opts = addressesStore.addressSets + .map(addressSet => addressSet?.receiving) + .filter((e, i, s) => s.indexOf(e) === i) + .filter(Boolean) + + if (opts?.length <= 0) return + + const index = opts.indexOf(address) + // we want to change address like it's rotating around the address sets stored + const rotatedOpts = [ + ...opts.slice(index+1), + ...opts.slice(0, index+1), + ] + + const newAddress = rotatedOpts.find(addr => addr != address) + const noNewAddressError = 'Unable to find new address' + if (!newAddress) { + if (!formErrors.value.receivingAddress) { + formErrors.value.receivingAddress = noNewAddressError + } + return + } + formData.value.receivingAddress = newAddress + if (noNewAddressError == formErrors.value.receivingAddress) { + formErrors.value.receivingAddress = '' + } + } finally { + updatingReceivingAddress.value = false + } } const formErrors = ref({ @@ -208,6 +239,7 @@ export default defineComponent({ loading, formData, + updatingReceivingAddress, updateReceivingAddress, formErrors, diff --git a/src/pages/Home.vue b/src/pages/Home.vue index 8d6b80f..297a32f 100644 --- a/src/pages/Home.vue +++ b/src/pages/Home.vue @@ -95,10 +95,10 @@ export default defineComponent({ onMounted(() => fetchTransactions()) onMounted(() => walletStore.refetchSalesReport()) - onMounted(() => walletStore.refetchMerchantInfo()) + // onMounted(() => walletStore.refetchMerchantInfo()) onMounted(() => walletStore.refetchDeviceInfo()) onMounted(() => walletStore.refetchPreferences()) - watch(() => [walletStore.walletHash], () => walletStore.refetchMerchantInfo()) + // watch(() => [walletStore.walletHash], () => walletStore.refetchMerchantInfo()) watch(() => [walletStore.walletHash, walletStore.posId], () => walletStore.refetchDeviceInfo()) watch(() => [walletStore.walletHash], () => walletStore.refetchPreferences()) diff --git a/src/pages/ReceivePage.vue b/src/pages/ReceivePage.vue index ccd82f7..b6bc699 100644 --- a/src/pages/ReceivePage.vue +++ b/src/pages/ReceivePage.vue @@ -419,7 +419,7 @@ export default defineComponent({ const expiryDuration = currencyRateUpdateRate / 1000 const expirationTimestamp = Math.floor(currentTimestamp + expiryDuration) const diffSeconds = networkTimeDiff.value ? networkTimeDiff.value / 1000 : 0 - const adjustedExpirationTimestamp = expirationTimestamp + diffSeconds + const adjustedExpirationTimestamp = expirationTimestamp + diffSeconds paymentUri += `&expires=${adjustedExpirationTimestamp}` } @@ -436,7 +436,8 @@ export default defineComponent({ const websocketUrl = `${process.env.WATCHTOWER_WEBSOCKET}/watch/bch` const merchantReceivingAddress = addressSet.value?.receiving const websocketInits = [ - merchantReceivingAddress + merchantReceivingAddress, + walletStore.firstReceivingAddress, ] .filter(Boolean) .map(address => { @@ -446,7 +447,9 @@ export default defineComponent({ } }) - const websockets = ref(websocketInits) + + const isZerothAddress = walletStore.firstReceivingAddress === merchantReceivingAddress + const websockets = ref(isZerothAddress ? websocketInits.slice(0,1) : websocketInits) const websocketsReady = computed(() => { const readySockets = websockets.value.filter((websocket) => websocket.instance?.readyState === 1) return readySockets.length === websockets.value.length @@ -479,6 +482,7 @@ export default defineComponent({ if (newVal) { closeWebsocket() stopQrExpirationCountdown() + addressesStore.dequeueAddress() setTimeout(() => triggerSecondConfetti.value = true, 1500) } }) @@ -557,23 +561,6 @@ export default defineComponent({ displayReceivedTransaction(transaction) } - function updateClaimTxnAttr (txid) { - const posId = walletStore.posId - const key = `voucher_claim_${posId}` - - const payload = { - wallet_hash: walletStore.merchantInfo?.walletHash, - value: "Voucher Claim", - remove: false, - txid, - key - } - const watchtowerTxnAttrUrl = `${process.env.WATCHTOWER_API}/transactions/attributes/` - axios.post(watchtowerTxnAttrUrl, payload) - .then(response => console.log('Added transaction attribute as voucher claim: ', response)) - .catch(err => console.log('Error on adding transaction attribute as voucher claim: ', err)) - } - function processLiveUpdate (data) { const updateType = data?.update_type let message = null @@ -594,10 +581,6 @@ export default defineComponent({ qrScanned.value = false refreshQrCountdown() } - else if (updateType === 'voucher_claimed') { - if (!data?.txid || !data?.category) return - updateClaimTxnAttr(data.txid) - } if (message) { $q.notify({ diff --git a/src/stores/wallet.js b/src/stores/wallet.js index cf8ea00..3342128 100644 --- a/src/stores/wallet.js +++ b/src/stores/wallet.js @@ -6,7 +6,6 @@ import { sha256, decodePaymentUri, getPubkeyAt, - pubkeyToCashAddress, } from 'src/wallet/utils'; @@ -16,11 +15,13 @@ export const useWalletStore = defineStore('wallet', { walletHash: null, xPubKey: null, linkCode: null, + firstReceivingAddress: null, deviceInfo: { name: '', posId: -1, walletHash: null, + merchantId: null, branchId: null, linkedDevice: { linkCode: '', @@ -51,14 +52,6 @@ export const useWalletStore = defineStore('wallet', { country: '', longitude: null, latitude: null, - }, - vault: { - receiving: { - address: '', - pubkey: '', - }, - address: '', - tokenAddress: '', } }, @@ -224,8 +217,6 @@ export const useWalletStore = defineStore('wallet', { * @param {String} data.wallet_hash * @param {String} data.primary_contact_number * - * @param {String} data.receiving_pubkey - * * @param {Object} [data.location] * @param {String} data.location.landmark * @param {String} data.location.location @@ -234,10 +225,6 @@ export const useWalletStore = defineStore('wallet', { * @param {String} data.location.country * @param {String} data.location.longitude * @param {String} data.location.latitude - * - * @param {Object} [data.vault] - * @param {String} data.vault.address - * @param {String} data.vault.token_address */ setMerchantInfo(data) { const merchantInfo = { @@ -254,22 +241,16 @@ export const useWalletStore = defineStore('wallet', { longitude: data?.location?.longitude, latitude: data?.location?.latitude, }, - vault: { - receiving: { - address: pubkeyToCashAddress(data?.receiving_pubkey), - pubkey: data?.receiving_pubkey, - }, - address: data?.vault?.address, - tokenAddress: data?.vault?.token_address, - } } this.merchantInfo = merchantInfo }, refetchMerchantInfo() { - if (!this.walletHash) return this.setMerchantInfo(null) + if (!this.walletHash || Number.isNaN(this.deviceInfo.merchantId)) return this.setMerchantInfo(null) + if (!this.deviceInfo.merchantId) return this.setMerchantInfo(null) + const watchtower = new Watchtower() - return watchtower.BCH._api.get(`paytacapos/merchants/${this.walletHash}/`) + return watchtower.BCH._api.get(`paytacapos/merchants/${this.deviceInfo.merchantId}/`) .then(response => { if (response?.data?.wallet_hash == this.walletHash) { this.setMerchantInfo(response.data) @@ -280,14 +261,17 @@ export const useWalletStore = defineStore('wallet', { .catch(error => { if (error?.response.status === 404) { this.setMerchantInfo(null) + return } + return Promise.reject(error) }) }, /** * @param {Object} data * @param {String} data.wallet_hash * @param {Number} data.posid - * @param {Number} [data.branch_id] + * @param {Number} data.branch_id + * @param {Number} data.merchant_id * @param {Object} [data.linked_device] * @param {String} [data.linked_device.link_code] * @param {String} [data.linked_device.name] @@ -307,6 +291,7 @@ export const useWalletStore = defineStore('wallet', { walletHash: data?.wallet_hash, posId: data?.posid, branchId: data?.branch_id, + merchantId: data?.merchant_id, linkedDevice: { linkCode: data?.linked_device?.link_code, name: data?.linked_device?.name, @@ -341,10 +326,13 @@ export const useWalletStore = defineStore('wallet', { .catch(error => { if (error?.response.status === 404) { this.setDeviceInfo(null) + return } + return Promise.reject(error) }) .finally(() => { this.refetchBranchInfo() + this.refetchMerchantInfo() }) }, confirmUnlinkRequest() {