diff --git a/constant/index.ts b/constant/index.ts
index 96345be34..5d054feb3 100644
--- a/constant/index.ts
+++ b/constant/index.ts
@@ -15,6 +15,10 @@ export const LIKER_NFT_FEE_WALLET = IS_TESTNET
? 'like1yney2cqn5qdrlc50yr5l53898ufdhxafqz9gxp'
: 'like10ywsmztkxjl55xarxnhlxwc83z9v2hkxtsajwl'
+export const LIKER_NFT_TARGET_ADDRESS = IS_TESTNET
+ ? 'like1yney2cqn5qdrlc50yr5l53898ufdhxafqz9gxp'
+ : 'like10ywsmztkxjl55xarxnhlxwc83z9v2hkxtsajwl'
+
export const LIKE_CO_API = `https://api.${IS_TESTNET ? 'rinkeby.' : ''}like.co`
export const APP_LIKE_CO_URL = `https://app.${IS_TESTNET ? 'rinkeby.' : ''}like.co`
export const LIKER_LAND_URL = `https://${LIKER_LAND_HOST}`
diff --git a/pages/nft-book-store/new.vue b/pages/nft-book-store/new.vue
index 250bf4785..fd5008de0 100644
--- a/pages/nft-book-store/new.vue
+++ b/pages/nft-book-store/new.vue
@@ -78,7 +78,20 @@
- updatePrice(e, 'stock', index)" />
+ updatePrice(e, 'stock', index)" />
+
+
+
+
+
+ updatePrice(e, 'autoMemo', index)" />
([{
price: MINIMAL_PRICE,
+ deliverMethod: 'auto',
+ autoMemo: '',
stock: Number(route.query.count as string || 1),
nameEn: 'Standard Edition',
nameZh: '標準版',
@@ -455,7 +471,7 @@ const toolbarOptions = ref([
'preview'
])
-const isEditMode = computed(() => route.params.editingClassId && editionIndex.value)
+const isEditMode = computed(() => Boolean(route.params.editingClassId && editionIndex.value))
const pageTitle = computed(() => isEditMode.value ? 'Edit Current Edition' : 'New NFT Book Listing')
const submitButtonText = computed(() => isEditMode.value ? 'Save Changes' : 'Submit')
const editionInfo = ref({})
@@ -590,6 +606,8 @@ function addMorePrice () {
prices.value.push({
index: uuidv4(),
price: MINIMAL_PRICE,
+ deliverMethod: 'auto',
+ autoMemo: '',
stock: 1,
nameEn: `Tier ${nextPriceIndex.value}`,
nameZh: `級別 ${nextPriceIndex.value}`,
@@ -655,6 +673,8 @@ function mapPrices (prices:any) {
priceInDecimal: Math.round(Number(p.price) * 100),
price: Number(p.price),
stock: Number(p.stock),
+ isAutoDeliver: p.deliverMethod === 'auto',
+ autoMemo: p.deliverMethod === 'auto' ? (p.autoMemo || '') : '',
hasShipping: p.hasShipping || false
}))
}
@@ -712,6 +732,26 @@ async function submitNewClass () {
}))
: undefined
+ const autoDeliverCount = p
+ .filter(price => price.isAutoDeliver)
+ .reduce((acc, price) => acc + price.stock, 0)
+
+ let autoDeliverNFTsTxHash = ''
+ if (autoDeliverCount > 0) {
+ if (!wallet.value || !signer.value) {
+ await connect()
+ }
+ if (!wallet.value || !signer.value) {
+ throw new Error('Unable to connect to wallet')
+ }
+ autoDeliverNFTsTxHash = await sendNFTsToAPIWallet(
+ classIdInput.value as string,
+ autoDeliverCount,
+ signer.value,
+ wallet.value
+ )
+ }
+
await newBookListing(classIdInput.value as string, {
defaultPaymentCurrency,
connectedWallets,
@@ -720,7 +760,8 @@ async function submitNewClass () {
prices: p,
shippingRates: s,
mustClaimToView,
- hideDownload
+ hideDownload,
+ autoDeliverNFTsTxHash
})
router.push({ name: 'nft-book-store' })
} catch (err) {
diff --git a/pages/nft-book-store/send/[classId].vue b/pages/nft-book-store/send/[classId].vue
index ad5a3e0f5..00fb81706 100644
--- a/pages/nft-book-store/send/[classId].vue
+++ b/pages/nft-book-store/send/[classId].vue
@@ -146,7 +146,7 @@ import { useBookStoreApiStore } from '~/stores/book-store-api'
import { useWalletStore } from '~/stores/wallet'
import { useNftStore } from '~/stores/nft'
import { parseImageURLFromMetadata } from '~/utils'
-import { signExecNFTSendAuthz, signSendNFT } from '~/utils/cosmos'
+import { signExecNFTSendAuthz, signSendNFTs } from '~/utils/cosmos'
const store = useWalletStore()
const { wallet, signer } = storeToRefs(store)
@@ -304,10 +304,10 @@ async function onSendNFTStart () {
let res: DeliverTxResponse | undefined
if (userIsOwner.value) {
- res = await signSendNFT(
+ res = await signSendNFTs(
orderInfo.value.wallet,
- classId.value,
- targetNftId,
+ [classId.value],
+ [targetNftId],
signer.value,
wallet.value,
memo.value
diff --git a/pages/nft-book-store/status/[classId]/edit/[editionIndex].vue b/pages/nft-book-store/status/[classId]/edit/[editionIndex].vue
index 54a884e4e..5d1df0263 100644
--- a/pages/nft-book-store/status/[classId]/edit/[editionIndex].vue
+++ b/pages/nft-book-store/status/[classId]/edit/[editionIndex].vue
@@ -45,7 +45,21 @@
-
+
+
+
+
+
+
+
classData?.value?.prices?.length > 1)
const price = ref(MINIMAL_PRICE)
const stock = ref(1)
+const deliverMethod = ref('auto')
+const autoMemo = ref('')
const nameEn = ref('Standard Edition')
const nameZh = ref('標準版')
const descriptionEn = ref('')
@@ -226,6 +243,7 @@ const shippingRates = ref([{
const hasMultipleShippingRates = computed(() => shippingRates.value.length > 1)
const priceItemLabel = computed(() => hasMultiplePrices.value ? 'edition' : 'book')
+const isAutoDeliver = computed(() => deliverMethod.value === 'auto')
const toolbarOptions = ref([
'bold',
@@ -276,6 +294,8 @@ onMounted(async () => {
if (currentEdition) {
price.value = currentEdition.price || 0
stock.value = currentEdition.stock || 0
+ deliverMethod.value = currentEdition.isAutoDeliver ? 'auto' : 'manual'
+ autoMemo.value = currentEdition.autoMemo || ''
nameEn.value = currentEdition.name?.en || currentEdition.name || ''
nameZh.value = currentEdition.name?.zh || currentEdition.name || ''
const legacyDescription = typeof currentEdition.description === 'string' ? currentEdition.description : undefined
@@ -351,6 +371,8 @@ async function handleSubmit () {
priceInDecimal: Math.round(Number(price.value) * 100),
price: Number(price.value),
stock: Number(stock.value),
+ isAutoDeliver: isAutoDeliver.value,
+ autoMemo: autoMemo.value || '',
hasShipping: hasShipping.value || false
}
diff --git a/pages/nft-book-store/status/[classId]/edit/new.vue b/pages/nft-book-store/status/[classId]/edit/new.vue
index ae998a27c..4bef21db4 100644
--- a/pages/nft-book-store/status/[classId]/edit/new.vue
+++ b/pages/nft-book-store/status/[classId]/edit/new.vue
@@ -45,7 +45,20 @@
-
+
+
+
+
+
+
+
classData?.value?.prices?.length > 1)
const price = ref(MINIMAL_PRICE)
const stock = ref(1)
+const deliverMethod = ref('auto')
+const autoMemo = ref('')
const nameEn = ref('Standard Edition')
const nameZh = ref('標準版')
const descriptionEn = ref('')
@@ -338,6 +356,8 @@ async function handleSubmit () {
priceInDecimal: Math.round(Number(price.value) * 100),
price: Number(price.value),
stock: Number(stock.value),
+ isAutoDeliver: deliverMethod.value === 'auto',
+ autoMemo: deliverMethod.value === 'auto' ? (autoMemo.value || '') : '',
hasShipping: hasShipping.value || false
}
@@ -362,8 +382,25 @@ async function handleSubmit () {
isLoading.value = true
+ let autoDeliverNFTsTxHash = ''
+ if (editedPrice.isAutoDeliver && editedPrice.stock > 0) {
+ if (!wallet.value || !signer.value) {
+ await connect()
+ }
+ if (!wallet.value || !signer.value) {
+ throw new Error('Unable to connect to wallet')
+ }
+ autoDeliverNFTsTxHash = await sendNFTsToAPIWallet(
+ classId.value as string,
+ editedPrice.stock,
+ signer.value,
+ wallet.value
+ )
+ }
+
await bookStoreApiStore.addEditionPrice(classId.value as string, priceIndex.value, {
- price: editedPrice
+ price: editedPrice,
+ autoDeliverNFTsTxHash
})
router.push({
diff --git a/utils/cosmos.ts b/utils/cosmos.ts
index 3f4ad741b..9edc41324 100644
--- a/utils/cosmos.ts
+++ b/utils/cosmos.ts
@@ -9,7 +9,7 @@ import { parseAuthzGrant } from '@likecoin/iscn-js/dist/messages/parsing'
import { GenericAuthorization } from 'cosmjs-types/cosmos/authz/v1beta1/authz'
import { formatMsgSend } from '@likecoin/iscn-js/dist/messages/likenft'
import { addParamToUrl } from '.'
-import { RPC_URL, LIKER_NFT_FEE_WALLET } from '~/constant'
+import { RPC_URL, LIKER_NFT_FEE_WALLET, LIKER_NFT_TARGET_ADDRESS } from '~/constant'
import network from '~/constant/network'
const DEFAULT_GAS_AMOUNT = 200000
@@ -233,26 +233,6 @@ export async function signMintNFT (
return res
}
-export async function signSendNFT (
- targetAddress: string,
- classId: string,
- nftId: string,
- signer: OfflineSigner,
- address: string,
- memo?: string
-) {
- const signingClient = await getSigningClient()
- await signingClient.connectWithSigner(RPC_URL, signer)
- const res = await signingClient.sendNFTs(
- address,
- targetAddress,
- classId,
- [nftId],
- { memo }
- ) as DeliverTxResponse
- return res
-}
-
export async function signSendNFTs (
targetAddress: string,
classIds: string[],
@@ -342,3 +322,42 @@ export function shortenWalletAddress (address: string) {
if (!address) { return '-' }
return `${address.slice(0, 10)}...${address.slice(-6)}`
}
+
+export async function sendNFTsToAPIWallet (
+ classId: string,
+ nftCount: number,
+ signer: OfflineSigner,
+ ownerAddress: string
+) {
+ if (nftCount <= 0) { return '' }
+
+ if (!ownerAddress) {
+ throw new Error('Missing owner address')
+ }
+
+ if (!signer) {
+ throw new Error('Missing signer')
+ }
+
+ const { nfts } = await getNFTs({
+ classId,
+ owner: ownerAddress,
+ needCount: nftCount
+ })
+ const nftIds = nfts.map(nft => nft.id).slice(0, nftCount)
+ const classIds = nftIds.map(_ => classId)
+
+ const { transactionHash, code } = await signSendNFTs(
+ LIKER_NFT_TARGET_ADDRESS,
+ classIds,
+ nftIds,
+ signer,
+ ownerAddress,
+ 'Send auto delivering NFT Book to API wallet'
+ )
+
+ if (!transactionHash || code !== 0) {
+ throw new Error('Failed to sign and send NFTs')
+ }
+ return transactionHash
+}
diff --git a/utils/index.ts b/utils/index.ts
index bdcb43408..7f5ab4826 100644
--- a/utils/index.ts
+++ b/utils/index.ts
@@ -97,3 +97,14 @@ function convertArrayOfObjectsToCSV (data: Record[]): string {
export function getPortfolioURL (wallet: string) {
return `https://${LIKER_LAND_HOST}/${wallet}`
}
+
+export const deliverMethodOptions = [
+ {
+ value: 'auto',
+ label: 'Automatic deliver NFT'
+ },
+ {
+ value: 'manual',
+ label: 'Sign memo and manually deliver each NFT'
+ }
+]