Skip to content

Commit

Permalink
add infuse token
Browse files Browse the repository at this point in the history
  • Loading branch information
zlayine committed Oct 11, 2024
1 parent f5d2f33 commit 49f78c4
Show file tree
Hide file tree
Showing 5 changed files with 223 additions and 0 deletions.
2 changes: 2 additions & 0 deletions resources/js/api/mutations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import OperatorTransferToken from '~/graphql/mutation/token/OperatorTransferToke
import SimpleTransferToken from '~/graphql/mutation/token/SimpleTransferToken';
import RemoveTokenAttribute from '~/graphql/mutation/token/RemoveTokenAttribute';
import SetTokenAttribute from '~/graphql/mutation/token/SetTokenAttribute';
import InfuseToken from '~/graphql/mutation/token/InfuseToken';

import RemoveAllAttributes from '~/graphql/mutation/RemoveAllAttributes';
import Freeze from '~/graphql/mutation/Freeze';
Expand Down Expand Up @@ -90,6 +91,7 @@ export default {
OperatorTransferToken,
RemoveTokenAttribute,
SetTokenAttribute,
InfuseToken,

RemoveAllAttributes,
Freeze,
Expand Down
16 changes: 16 additions & 0 deletions resources/js/api/token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,4 +186,20 @@ export class TokenApi {

return ApiService.sendPlatformRequest(data);
}

static async infuseToken(infuseTokenData: Record<string, unknown>) {
const data = {
query: mutations.InfuseToken,
variables: {
collectionId: infuseTokenData.collectionId,
tokenId: infuseTokenData.tokenId,
amount: infuseTokenData.amount,
signingAccount: infuseTokenData.signingAccount,
idempotencyKey: infuseTokenData.idempotencyKey,
skipValidation: infuseTokenData.skipValidation,
},
};

return ApiService.sendPlatformRequest(data);
}
}
5 changes: 5 additions & 0 deletions resources/js/components/pages/Tokens.vue
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,11 @@ const actions = [
name: 'Mutate',
component: 'MutateTokenSlideover',
},
{
key: 'infuse',
name: 'Infuse',
component: 'InfuseTokenSlideover',
},
{
key: 'transfer',
name: 'Transfer',
Expand Down
188 changes: 188 additions & 0 deletions resources/js/components/slideovers/token/InfuseTokenSlideover.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
<template>
<Form
ref="formRef"
class="flex h-full flex-col divide-y divide-light-stroke dark:divide-dark-stroke bg-light-surface-primary dark:bg-dark-surface-primary shadow-xl"
:validation-schema="validation"
@invalid-submit="invalidSubmit"
@submit="infuseToken"
>
<h3 class="text-xl font-semibold px-4 sm:px-6 py-4 text-light-content-strong dark:text-dark-content-strong">
Infuse Token
</h3>
<div class="h-0 flex-1 overflow-y-auto">
<div class="flex flex-1 flex-col justify-between">
<div class="divide-y divide-light-stroke dark:divide-dark-stroke px-4 sm:px-6">
<div class="space-y-6 pt-6 pb-5">
<FormInput
v-model="collectionId"
name="collectionId"
label="Collection ID"
description="The collection ID to use in this operation.."
type="number"
disabled
required
/>
<TokenIdInput
v-model="tokenId"
label="Token ID"
description="The token that will be infused."
disabled
required
/>
<FormInput
v-model="amount"
name="amount"
label="Amount"
description="The amount of ENJ to infuse."
type="number"
:prefix="currencySymbol"
required
/>
<FormInput
v-model="signingAccount"
name="signingAccount"
label="Signing Account"
description="The signing wallet for this transaction. Defaults to wallet daemon."
/>
<FormInput
v-if="useAppStore().advanced"
v-model="idempotencyKey"
name="idempotencyKey"
label="Idempotency Key"
description="The idempotency key to set. It is recommended to use a UUID for this."
tooltip="In mathematical and computer science terms, idempotency is a property of certain operations that can be applied repeated times without changing the initial result of the application."
readmore="Idempotency Key"
/>
<FormCheckbox
v-if="useAppStore().advanced"
v-model="skipValidation"
name="skipValidation"
label="Skip validation"
description="Skip all validation rules, use with caution. Defaults to false."
/>
</div>
</div>
</div>
</div>
<div class="flex space-x-3 flex-shrink-0 justify-end px-4 py-4">
<Btn @click="closeSlide">Cancel</Btn>
<Btn :loading="isLoading" :disabled="isLoading" primary is-submit>Mutate</Btn>
</div>
</Form>
</template>

<script setup lang="ts">
import { Form } from 'vee-validate';
import * as yup from 'yup';
import { computed, ref } from 'vue';
import FormInput from '~/components/FormInput.vue';
import FormCheckbox from '~/components/FormCheckbox.vue';
import Btn from '~/components/Btn.vue';
import { TokenApi } from '~/api/token';
import snackbar from '~/util/snackbar';
import { currencySymbolByNetwork, formatData, formatPriceToENJ, formatToken, snackbarErrors } from '~/util';
import { TokenIdSelectType } from '~/types/types.enums';
import TokenIdInput from '~/components/TokenIdInput.vue';
import { useAppStore } from '~/store';
import {
booleanNotRequiredSchema,
collectionIdRequiredSchema,
numberRequiredSchema,
stringNotRequiredSchema,
stringRequiredSchema,
} from '~/util/schemas';
const emit = defineEmits(['close']);
const props = withDefaults(
defineProps<{
item?: {
tokenId: string;
collectionId: number;
isCurrency: boolean;
listingForbidden: boolean;
royalty: {
beneficiary: string;
percentage: number;
} | null;
};
}>(),
{
item: undefined,
}
);
const isLoading = ref(false);
const tokenId = ref({
tokenType: TokenIdSelectType.Integer,
tokenId: props.item?.tokenId!,
});
const collectionId = ref(props.item?.collectionId);
const amount = ref();
const signingAccount = ref('');
const idempotencyKey = ref('');
const skipValidation = ref(false);
const formRef = ref();
const validation = yup.object({
tokenId: stringRequiredSchema,
collectionId: collectionIdRequiredSchema,
amount: numberRequiredSchema.min(1),
signingAccount: stringNotRequiredSchema,
idempotencyKey: stringNotRequiredSchema,
skipValidation: booleanNotRequiredSchema,
});
const currencySymbol = computed(() => currencySymbolByNetwork(useAppStore().config.network));
const invalidSubmit = () => {
snackbar.error({
title: 'Form validation',
text: 'Please verify that all the fields are valid',
});
};
const infuseToken = async () => {
await formRef.value?.validate();
if (!formRef.value?.getMeta().valid) {
return;
}
try {
isLoading.value = true;
const res = await TokenApi.infuseToken(
formatData({
collectionId: props.item?.collectionId,
tokenId: formatToken(tokenId.value),
amount: formatPriceToENJ(amount.value),
signingAccount: signingAccount.value,
idempotencyKey: idempotencyKey.value,
skipValidation: skipValidation.value,
})
);
const id = res.data?.MutateToken?.id;
if (id) {
snackbar.success({
title: 'Token Infused',
text: `Token infused with transaction id ${id}`,
event: id,
});
closeSlide();
}
} catch (e) {
if (snackbarErrors(e)) return;
snackbar.error({
title: 'Token infusion',
text: 'Token infusion failed',
});
} finally {
isLoading.value = false;
}
};
const closeSlide = () => {
emit('close');
};
</script>
12 changes: 12 additions & 0 deletions resources/js/graphql/mutation/token/InfuseToken.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export default `mutation InfuseToken($collectionId: BigInt!, $tokenId: EncodableTokenIdInput!, $amount: BigInt!, $signingAccount: String, $idempotencyKey: String, $skipValidation: Boolean! = false) {
InfuseToken(
collectionId: $collectionId
tokenId: $tokenId
amount: $amount
signingAccount: $signingAccount
idempotencyKey: $idempotencyKey
skipValidation: $skipValidation
) {
id
}
}`;

0 comments on commit 49f78c4

Please sign in to comment.