From 663bc4f028ba351adb78c6b9ed8d5a1f70ca08f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lancelot=20de=20Ferri=C3=A8re?= Date: Mon, 4 Dec 2023 11:21:46 +0100 Subject: [PATCH] Swap briq factory text, fix exporting sets, add migration TX to factory --- src/builder/ChainBriqs.ts | 2 +- src/builder/ChainBriqsLegacy.ts | 24 +++++++++++++++++---- src/chain/Marketplaces.ts | 4 ++++ src/chain/contracts/briq_factory.ts | 8 +++---- src/components/BuyBriqsWidget.vue | 8 ++++--- src/components/builder/modals/ExportSet.vue | 24 ++++++++++++++++++--- 6 files changed, 55 insertions(+), 15 deletions(-) diff --git a/src/builder/ChainBriqs.ts b/src/builder/ChainBriqs.ts index 922dcb1f..8028d4d8 100644 --- a/src/builder/ChainBriqs.ts +++ b/src/builder/ChainBriqs.ts @@ -12,7 +12,7 @@ import { legacyChainBriqs } from './ChainBriqsLegacy'; // TODO: there can technically be more than whatever is supported by number type BALANCE = { ft_balance: number; nft_ids: string[] }; -class NotEnoughBriqs extends Error { +export class NotEnoughBriqs extends Error { material: string; constructor(material: string) { super(`Not enough Briqs with material ${material}`); diff --git a/src/builder/ChainBriqsLegacy.ts b/src/builder/ChainBriqsLegacy.ts index 1ee9c3a6..12dfbb92 100644 --- a/src/builder/ChainBriqsLegacy.ts +++ b/src/builder/ChainBriqsLegacy.ts @@ -8,6 +8,7 @@ import { maybeStore } from '@/chain/WalletLoading'; import { setChainBriqsStoreComplete } from './ChainBriqsAsync'; import { Notification } from '@/Notifications'; import { getPremigrationNetwork } from '@/chain/Network'; +import { NotEnoughBriqs } from './ChainBriqs'; /** * Responsible for maintaining the state of 'on-chain' briqs, as opposed to local set-briqs. @@ -121,6 +122,8 @@ export class LegacyChainBriqs implements perUserStorable { } if (update.status === 'DELETING_SOON') bal -= update.quantity; + else + bal += update.quantity; } this.balance = bal; for (const item of promises) @@ -133,10 +136,23 @@ export class LegacyChainBriqs implements perUserStorable { return this.balance; } - migrateBriqs() { - if (this.getNbBriqs() <= 0) - return; - // TODO -> TX + /** + * Check that we have enough on-chain briqs available, + * and if not return NFTs that can be used to complement. + * Note that this function won't swap existing NFTs that are unavailable. + * @param usageByMaterial entry balance + * @returns a list of NFT briqs to replace. + */ + findRealBriqs(usageByMaterial: { [material: string]: { ft_balance: number; nft_ids: string[] } }) { + const swaps = [] as Briq[]; + for (const mat in usageByMaterial) + if (usageByMaterial[mat].ft_balance > this.balance) + throw new NotEnoughBriqs(mat); + return swaps; + } + + show(quantity: number, tx_hash: string, date?: number) { + return this._add('TENTATIVE', quantity, tx_hash, false, date); } hide(quantity: number, tx_hash: string, date?: number) { diff --git a/src/chain/Marketplaces.ts b/src/chain/Marketplaces.ts index c9780b0d..7db79511 100644 --- a/src/chain/Marketplaces.ts +++ b/src/chain/Marketplaces.ts @@ -41,3 +41,7 @@ export function getBoxLink(marketplace: string, network: CHAIN_NETWORKS, collect export function getSetMarketplaceUrl() { return 'https://unframed.co/collection/0x01435498bf393da86b4733b9264a86b58a42b31f8d8b8ba309593e5c17847672'; } + +export function getBriqLink(marketplace: string, network: CHAIN_NETWORKS) { + return 'https://element.market/collections/briq-token'; +} diff --git a/src/chain/contracts/briq_factory.ts b/src/chain/contracts/briq_factory.ts index 47647b29..dd274b08 100644 --- a/src/chain/contracts/briq_factory.ts +++ b/src/chain/contracts/briq_factory.ts @@ -34,11 +34,11 @@ export default class BriqContract { } buyTransaction(erc20_contract: ERC20Contract, amount: number, approval: number.BigNumberish) { - return migrateBriqsIfNeeded([ + return [ erc20_contract.contract.populateTransaction['approve'](this.contract.address, cairo.uint256(BigInt(approval))), this.contract.populateTransaction.buy(`${amount}`), erc20_contract.contract.populateTransaction['approve'](this.contract.address, cairo.uint256(0n)), - ]); + ]; } async buy(erc20_contract: ERC20Contract, amount: number, approval: number.BigNumberish) { @@ -49,7 +49,7 @@ export default class BriqContract { export class BriqFactoryOnDojoContract extends BriqContract { buyTransaction(erc20_contract: ERC20Contract, amount: number, approval: number.BigNumberish) { - return [ + return migrateBriqsIfNeeded([ erc20_contract.contract.populateTransaction['approve'](this.contract.address, cairo.uint256(BigInt(approval))), { contractAddress: this.contract.address, @@ -57,6 +57,6 @@ export class BriqFactoryOnDojoContract extends BriqContract { calldata: [1, `${amount}`], }, erc20_contract.contract.populateTransaction['approve'](this.contract.address, cairo.uint256(0n)), - ] + ]); } } diff --git a/src/components/BuyBriqsWidget.vue b/src/components/BuyBriqsWidget.vue index 5939c74c..a6d46664 100644 --- a/src/components/BuyBriqsWidget.vue +++ b/src/components/BuyBriqsWidget.vue @@ -12,9 +12,10 @@ import { chainBriqs } from '@/builder/ChainBriqs'; import MenuLike from './generic/MenuLike.vue'; import Tooltip from './generic/Tooltip.vue'; import { APP_ENV } from '@/Meta'; -import { getSetMarketplaceUrl } from '@/chain/Marketplaces'; +import { getBriqLink } from '@/chain/Marketplaces'; import { backendManager } from '@/Backend'; import { maybeStore } from '@/chain/WalletLoading'; +import { getCurrentNetwork } from '@/chain/Network'; const props = defineProps<{ @@ -198,8 +199,9 @@ const cancelBuy = () => {

1 briq = {{ readableNumber(price_ber_briq) }} {{ readableUnit(price_ber_briq) }}

-

- Please be aware that the price of briq is currently very high due to demand. You can also get briqs by buying sets from Unframed and disassembling them. +

+ You can also buy briqs on the secondary market!
+ Check out Element marketplace.

diff --git a/src/components/builder/modals/ExportSet.vue b/src/components/builder/modals/ExportSet.vue index 31404664..7dd50cf8 100644 --- a/src/components/builder/modals/ExportSet.vue +++ b/src/components/builder/modals/ExportSet.vue @@ -104,8 +104,13 @@ watch([setData, toRef(chainBriqs.value, 'byMaterial')], () => { try { es.swapForRealBriqs(chainBriqs.value!); } catch (err) { - exportSet.value = undefined; - return; + // Temp for migration + try { + es.swapForRealBriqs(legacyChainBriqs.current!); + } catch (err) { + exportSet.value = undefined; + return; + } } exportSet.value = es; }, { @@ -141,6 +146,11 @@ const buyBriqsAndMint = async (data: unknown) => { briqTransaction.value = contractStore.briq_factory?.buyTransaction(contractStore.eth_bridge_contract!, data.briqs, data.price); // Don't notify in case we stop. briqPendingObject.value = chainBriqs.value?.show('0x1', data.briqs, ''); + if (legacyChainBriqs.current?.getNbBriqs()) { + const legacyBriqNb = legacyChainBriqs.current?.getNbBriqs() || 0; + chainBriqs.value?.show('0x1', legacyBriqNb, 'hack', false); + legacyChainBriqs.current?.hide(legacyBriqNb, 'hack'); + } // This will update ExportSet through watchers, but might take some time, so nextTick. nextTick(() => { startMinting(); @@ -242,8 +252,16 @@ const startMinting = async () => { } catch (err: any) { // Reset the briqs if we bought some. // TODO: this is fairly hacky. - if (briqPendingObject.value) + if (briqPendingObject.value) { chainBriqs.value!.removeMetadataItem(briqPendingObject.value); + // Super hacky part. + const legacyHacks = legacyChainBriqs.current?.metadata.filter(x => x.tx_hash === 'hack'); + for (const hack of legacyHacks || []) { + const legacyBriqNb = hack.quantity; + chainBriqs.value?.hide('0x1', legacyBriqNb, 'hack'); + legacyChainBriqs.current?.show(legacyBriqNb, 'hack'); + } + } if (err?.message === 'User abort') { pushPopup('error', 'Mint error', 'Minting transaction aborted.');