Skip to content

Commit

Permalink
feat(station): enable station top up from the cycles ledger balance
Browse files Browse the repository at this point in the history
  • Loading branch information
jedna committed Jan 9, 2025
1 parent ed91d9f commit 8caa665
Show file tree
Hide file tree
Showing 23 changed files with 269 additions and 38 deletions.
39 changes: 19 additions & 20 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 4 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ byteorder = "1.5"
canbench-rs = "0.1.1"
candid = "0.10.3"
candid_parser = "0.1.3"
canfund = "0.4.0"
# canfund = "0.4.0"
canfund = { path = "../canfund/canfund-rs" }
cap-std = "3.4.1"
ciborium = "0.2.2"
clap = { version = "4.5.7", features = ["derive"] }
Expand All @@ -55,8 +56,8 @@ ic-http-certification = { git = "https://github.com/dfinity/response-verificatio
ic-representation-independent-hash = { git = "https://github.com/dfinity/response-verification", rev = "da70db93832f88ecc556ae082612aedec47d3816" }
ic-cdk = "0.16.0"
ic-cdk-macros = "0.16.0"
ic-cdk-timers = "0.9.0"
ic-ledger-types = "0.12.0"
ic-cdk-timers = "0.11.0"
ic-ledger-types = "0.14.0"
ic-stable-structures = "0.6.6"
icrc-ledger-types = "0.1.6"
ic-utils = "0.38"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import { variantIs } from '~/utils/helper.utils.ts';
import { requiredRule } from '~/utils/form.utils.ts';
import { mdiCog } from '@mdi/js';
import { CanisterMonitorModel } from '~/components/external-canisters/external-canisters.types.ts';
import MintFromNativeToken from '~/components/settings/obtain-cycle/MintFromNativeToken.vue';
import MintFromNativeToken from '~/components/settings/obtain-cycles/MintFromNativeToken.vue';
import { ObtainCyclesStrategyEnum } from '~/components/external-canisters/monitor/monitor.types.ts';
const props = withDefaults(
Expand Down
35 changes: 32 additions & 3 deletions apps/wallet/src/components/settings/ManageSystemInfoForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,13 @@
:variant="isViewMode ? 'plain' : 'filled'"
:disabled="isViewMode"
></MintFromNativeToken>
<WithdrawFromCyclesLedger
v-if="cycleObtainStrategySelected == 'WithdrawFromCyclesLedger'"
v-model="withdrawFromCyclesLedgerAccountId"
:variant="isViewMode ? 'plain' : 'filled'"
:disabled="isViewMode"
></WithdrawFromCyclesLedger>
<template v-else-if="cycleObtainStrategySelected == 'Disabled'"></template>
<template v-else>{{ unreachable(cycleObtainStrategySelected) }}</template>
</template>
</VForm>
</template>
Expand All @@ -46,8 +51,9 @@ import { cycleObtainStrategyInputToKey } from '~/mappers/obtain-cycles.mapper';
import { VFormValidation } from '~/types/helper.types';
import { CycleObtainStrategyEnum } from '~/types/obtain-cycles.types';
import { maxLengthRule, requiredRule } from '~/utils/form.utils';
import { unreachable, variantIs } from '~/utils/helper.utils';
import MintFromNativeToken from './obtain-cycle/MintFromNativeToken.vue';
import { variantIs } from '~/utils/helper.utils';
import MintFromNativeToken from '~/components/settings/obtain-cycles/MintFromNativeToken.vue';
import WithdrawFromCyclesLedger from '~/components/settings/obtain-cycles/WithdrawFromCyclesLedger.vue';
const i18n = useI18n();
Expand Down Expand Up @@ -91,9 +97,17 @@ const mintFromNativeTokenAccountId = ref<UUID | null>(
: null,
);
const withdrawFromCyclesLedgerAccountId = ref<UUID | null>(
model.value.cycle_obtain_strategy?.[0] &&
variantIs(model.value.cycle_obtain_strategy?.[0], 'WithdrawFromCyclesLedger')
? model.value.cycle_obtain_strategy?.[0].WithdrawFromCyclesLedger.account_id
: null,
);
const cycleObtainStrategyKeys = ref<CycleObtainStrategyEnum[]>([
CycleObtainStrategyEnum.Disabled,
CycleObtainStrategyEnum.MintFromNativeToken,
CycleObtainStrategyEnum.WithdrawFromCyclesLedger,
]);
const cycleObtainStrategies = computed(() => {
Expand Down Expand Up @@ -131,6 +145,21 @@ watch(
},
);
watch(
() => withdrawFromCyclesLedgerAccountId.value,
newValue => {
if (newValue) {
model.value.cycle_obtain_strategy = [
{
WithdrawFromCyclesLedger: {
account_id: newValue,
},
},
];
}
},
);
watch(
() => isFormValid.value,
isValid => emit('valid', isValid ?? false),
Expand Down
10 changes: 9 additions & 1 deletion apps/wallet/src/components/settings/StationInfoCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@
</VListItemSubtitle>
</VListItem>
</template>
<VListItem class="px-0" v-else-if="loadingSystemInfoError">
<VListItem v-else-if="loadingSystemInfoError" class="px-0">
<VListItemTitle class="font-weight-bold">{{ $t(`terms.upgrader_id`) }}</VListItemTitle>
<VListItemSubtitle>
<VAlert type="error" variant="tonal" density="compact" class="mb-4 mt-2">
Expand Down Expand Up @@ -402,6 +402,12 @@ function cycleObtainStrategyToInput(strategy: CycleObtainStrategy): CycleObtainS
account_id: strategy.MintFromNativeToken.account_id,
},
};
} else if (variantIs(strategy, 'WithdrawFromCyclesLedger')) {
return {
WithdrawFromCyclesLedger: {
account_id: strategy.WithdrawFromCyclesLedger.account_id,
},
};
} else if (variantIs(strategy, 'Disabled')) {
return { Disabled: null };
} else {
Expand Down Expand Up @@ -434,6 +440,8 @@ const submitManageSystemInfoOperation = async ({
const cycleObtainStrategy = computed(() => {
if (variantIs(station.configuration.cycleObtainStrategy, 'MintFromNativeToken')) {
return `${i18n.global.t('pages.administration.cycle_obtain_strategy_mint_from_native_token')} "${station.configuration.cycleObtainStrategy.MintFromNativeToken.account_name}"`;
} else if (variantIs(station.configuration.cycleObtainStrategy, 'WithdrawFromCyclesLedger')) {
return `${i18n.global.t('pages.administration.cycle_obtain_strategy_withdraw_from_cycles_ledger')} "${station.configuration.cycleObtainStrategy.WithdrawFromCyclesLedger.account_name}"`;
} else if (variantIs(station.configuration.cycleObtainStrategy, 'Disabled')) {
return i18n.global.t('pages.administration.cycle_obtain_strategy_disabled');
} else {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<template>
<VAutocomplete
v-model="model"
v-bind="$attrs"
class="mt-2"
name="account_id"
:label="$t('terms.account')"
:loading="autocomplete.loading.value"
:items="accountList"
chips
clearable
:rules="[requiredRule]"
:variant="isViewMode ? 'plain' : 'filled'"
:disabled="isViewMode"
@update:search="autocomplete.searchItems"
/>
</template>

<script lang="ts" setup>
import { computed, onMounted } from 'vue';
import { useAccountsAutocomplete } from '~/composables/autocomplete.composable';
import { UUID } from '~/generated/station/station.did';
import { requiredRule } from '~/utils/form.utils';
import { useStationStore } from '~/stores/station.store.ts';
import { CYCLES_LEDGER_CANISTER_ID } from '~/core/constants.core.ts';
const autocomplete = useAccountsAutocomplete();
const props = withDefaults(
defineProps<{
modelValue: UUID | null;
valid?: boolean;
triggerSubmit?: boolean;
mode?: 'view' | 'edit';
}>(),
{
valid: true,
triggerSubmit: false,
mode: 'edit',
},
);
const emit = defineEmits<{
(event: 'update:modelValue', payload: UUID | null): void;
}>();
const model = computed({
get: () => props.modelValue,
set: value => emit('update:modelValue', value),
});
const station = useStationStore();
const [cyclesAsset] = station.configuration.details.supported_assets.filter(asset =>
asset.metadata.some(
data => data.key === 'ledger_canister_id' && data.value === CYCLES_LEDGER_CANISTER_ID,
),
);
const accountList = computed(() => {
if (!cyclesAsset) {
return [];
}
return autocomplete.results.value
.filter(account => account.assets.some(asset => asset.asset_id === cyclesAsset.id))
.map(group => ({
title: group.name,
value: group.id,
}));
});
const isViewMode = computed(() => props.mode === 'view');
onMounted(() => {
autocomplete.searchItems();
});
</script>
1 change: 1 addition & 0 deletions apps/wallet/src/core/constants.core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ export const REQUEST_DIALOG_QUERY_PARAM = 'reqid';
export const STATION_ID_QUERY_PARAM = 'sid';
export const CONTROL_PANEL_USER_STATION_LABEL = 'orbit-wallet';
export const ICP_LEDGER_CANISTER_ID = 'ryjl3-tyaaa-aaaaa-aaaba-cai';
export const CYCLES_LEDGER_CANISTER_ID = 'um5iw-rqaaa-aaaaq-qaaba-cai';
12 changes: 12 additions & 0 deletions apps/wallet/src/generated/station/station.did
Original file line number Diff line number Diff line change
Expand Up @@ -2010,6 +2010,11 @@ type CycleObtainStrategyInput = variant {
// The Orbit account ID to use for minting cycles.
account_id : UUID;
};
// Use the Cycles Ledger balance to obtain cycles.
WithdrawFromCyclesLedger : record {
// The Orbit account ID to use for obtaining cycles.
account_id : UUID;
};
};

// Strategy defining how the station canister tops up its own cycles.
Expand All @@ -2023,6 +2028,13 @@ type CycleObtainStrategy = variant {
// The Orbit account name.
account_name : opt text;
};
// Use the Cycles Ledger balance to obtain cycles.
WithdrawFromCyclesLedger : record {
// The Orbit account ID to use for obtaining cycles.
account_id : UUID;
// The Orbit account name.
account_name : opt text;
};
};

// The system information.
Expand Down
9 changes: 8 additions & 1 deletion apps/wallet/src/generated/station/station.did.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -314,9 +314,16 @@ export type CycleObtainStrategy = { 'Disabled' : null } |
'account_id' : UUID,
'account_name' : [] | [string],
}
} |
{
'WithdrawFromCyclesLedger' : {
'account_id' : UUID,
'account_name' : [] | [string],
}
};
export type CycleObtainStrategyInput = { 'Disabled' : null } |
{ 'MintFromNativeToken' : { 'account_id' : UUID } };
{ 'MintFromNativeToken' : { 'account_id' : UUID } } |
{ 'WithdrawFromCyclesLedger' : { 'account_id' : UUID } };
export interface DefiniteCanisterSettings {
'freezing_threshold' : bigint,
'controllers' : Array<Principal>,
Expand Down
5 changes: 5 additions & 0 deletions apps/wallet/src/generated/station/station.did.js
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,7 @@ export const idlFactory = ({ IDL }) => {
const CycleObtainStrategyInput = IDL.Variant({
'Disabled' : IDL.Null,
'MintFromNativeToken' : IDL.Record({ 'account_id' : UUID }),
'WithdrawFromCyclesLedger' : IDL.Record({ 'account_id' : UUID }),
});
const MonitoringExternalCanisterCyclesThresholdInput = IDL.Record({
'fund_cycles' : IDL.Nat,
Expand Down Expand Up @@ -1568,6 +1569,10 @@ export const idlFactory = ({ IDL }) => {
'account_id' : UUID,
'account_name' : IDL.Opt(IDL.Text),
}),
'WithdrawFromCyclesLedger' : IDL.Record({
'account_id' : UUID,
'account_name' : IDL.Opt(IDL.Text),
}),
});
const SystemInfo = IDL.Record({
'disaster_recovery' : IDL.Opt(DisasterRecovery),
Expand Down
Loading

0 comments on commit 8caa665

Please sign in to comment.