Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add state and action queries for guild system and delegation #2688

Merged
merged 4 commits into from
Jan 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions NineChronicles.Headless.Tests/GraphTypes/DelegatorTypeTest.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Numerics;
using System.Threading.Tasks;
using GraphQL.Execution;
using Lib9c;
using Libplanet.Types.Tx;
using Nekoyume.ValidatorDelegation;
using NineChronicles.Headless.GraphTypes;
using Xunit;
using Xunit.Abstractions;

namespace NineChronicles.Headless.Tests.GraphTypes
{
Expand Down
147 changes: 143 additions & 4 deletions NineChronicles.Headless/GraphTypes/ActionQuery.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
using Nekoyume.Action.ValidatorDelegation;
using Nekoyume.Action.Guild.Migration;
using Lib9c;
using Nekoyume.Action.Guild;
using Nekoyume.TypedAddress;
using System.Globalization;

namespace NineChronicles.Headless.GraphTypes
{
Expand All @@ -33,14 +36,20 @@ public ActionQuery(StandaloneContext standaloneContext)
Name = "amount",
Description = "An amount to stake.",
},
new QueryArgument<NonNullGraphType<AddressType>>
new QueryArgument<AddressType>
{
Name = "avatarAddress",
Description = "Address of avatar.",
}),
resolve: context => Encode(
context,
new Stake(context.GetArgument<BigInteger>("amount"), context.GetArgument<Address>("avatarAddress"))));
resolve: context =>
{
var amount = context.GetArgument<BigInteger>("amount");
var avatarAddress = context.GetArgument<Address?>("avatarAddress");
var stake = avatarAddress is not null
? new Stake(amount, avatarAddress.Value)
: new Stake(amount);
return Encode(context, stake);
});

Field<ByteStringType>(
name: "claimStakeReward",
Expand Down Expand Up @@ -563,6 +572,42 @@ public ActionQuery(StandaloneContext standaloneContext)
currency));
});

Field<ByteStringType>(
name: "unjailValidator",
resolve: context => Encode(context, new UnjailValidator()));

Field<ByteStringType>(
name: "delegateValidator",
arguments: new QueryArguments(
new QueryArgument<NonNullGraphType<StringGraphType>>
{
Description = "A string value of guild gold to delegate.",
Name = "amount",
}),
resolve: context =>
{
var fav = FungibleAssetValue.Parse(
currency: Currencies.GuildGold,
value: context.GetArgument<string>("amount"));
return Encode(context, new DelegateValidator(fav));
});

Field<ByteStringType>(
name: "undelegateValidator",
arguments: new QueryArguments(
new QueryArgument<NonNullGraphType<StringGraphType>>
{
Description = "A string value of share to undelegate.",
Name = "share",
}),
resolve: context =>
{
var share = BigInteger.Parse(
value: context.GetArgument<string>("share"),
style: NumberStyles.Number);
return Encode(context, new UndelegateValidator(share));
});

Field<ByteStringType>(
name: "migrateDelegationHeight",
arguments: new QueryArguments(new QueryArgument<LongGraphType>
Expand All @@ -574,6 +619,100 @@ public ActionQuery(StandaloneContext standaloneContext)
context,
new MigrateDelegationHeight(context.GetArgument<long>("amount"))));

Field<ByteStringType>(
name: "makeGuild",
arguments: new QueryArguments(
new QueryArgument<NonNullGraphType<AddressType>>
{
Name = "validatorAddress",
Description = "The validator address to create a guild."
}),
resolve: context =>
{
var validatorAddress = context.GetArgument<Address>("validatorAddress");
return Encode(context, new MakeGuild(validatorAddress));
});

Field<ByteStringType>(
name: "removeGuild",
resolve: context => Encode(context, new RemoveGuild()));

Field<ByteStringType>(
name: "joinGuild",
arguments: new QueryArguments(
new QueryArgument<NonNullGraphType<AddressType>>
{
Name = "guildAddress",
Description = "The guild address to join."
}),
resolve: context =>
{
var address = context.GetArgument<Address>("guildAddress");
var guildAddress = new GuildAddress(address);
return Encode(context, new JoinGuild(guildAddress));
});

Field<ByteStringType>(
name: "quitGuild",
resolve: context => Encode(context, new QuitGuild()));

Field<ByteStringType>(
name: "moveGuild",
arguments: new QueryArguments(
new QueryArgument<NonNullGraphType<AddressType>>
{
Name = "guildAddress",
Description = "The guild address to move."
}),
resolve: context =>
{
var address = context.GetArgument<Address>("guildAddress");
var guildAddress = new GuildAddress(address);
return Encode(context, new MoveGuild(guildAddress));
});

Field<ByteStringType>(
name: "banGuildMember",
arguments: new QueryArguments(
new QueryArgument<NonNullGraphType<AddressType>>
{
Name = "agentAddress",
Description = "The agent address to ban."
}),
resolve: context =>
{
var address = context.GetArgument<Address>("agentAddress");
var agentAddress = new AgentAddress(address);
return Encode(context, new BanGuildMember(agentAddress));
});

Field<ByteStringType>(
name: "unbanGuildMember",
arguments: new QueryArguments(
new QueryArgument<NonNullGraphType<AddressType>>
{
Name = "agentAddress",
Description = "The agent address to unban."
}),
resolve: context =>
{
var address = context.GetArgument<Address>("agentAddress");
var agentAddress = new AgentAddress(address);
return Encode(context, new UnbanGuildMember(agentAddress));
});

Field<ByteStringType>(
name: "claimReward",
resolve: context => Encode(context, new ClaimReward()));

Field<ByteStringType>(
name: "claimGuildReward",
resolve: context => Encode(context, new ClaimGuildReward()));

Field<ByteStringType>(
name: "claimUnbonded",
resolve: context => Encode(context, new ClaimUnbonded()));

RegisterHackAndSlash();
RegisterHackAndSlashSweep();
RegisterDailyReward();
Expand Down
22 changes: 22 additions & 0 deletions NineChronicles.Headless/GraphTypes/DelegateeRepositoryType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using GraphQL.Types;

namespace NineChronicles.Headless.GraphTypes;

public class DelegateeRepositoryType : ObjectGraphType<DelegateeRepositoryType>
{
public DelegateeType? GuildDelegatee { get; set; }

public DelegateeType? ValidatorDelegatee { get; set; }

public DelegateeRepositoryType()
{
Field<NonNullGraphType<DelegateeType>>(
nameof(GuildDelegatee),
description: "Delegatee of the guild repository",
resolve: context => context.Source.GuildDelegatee);
Field<NonNullGraphType<DelegateeType>>(
nameof(ValidatorDelegatee),
description: "Delegatee of the validator repository",
resolve: context => context.Source.ValidatorDelegatee);
}
}
75 changes: 75 additions & 0 deletions NineChronicles.Headless/GraphTypes/DelegateeType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
using System.Numerics;
using GraphQL.Types;
using Libplanet.Crypto;
using Libplanet.Types.Assets;
using Nekoyume.Model.Guild;
using Nekoyume.ValidatorDelegation;

namespace NineChronicles.Headless.GraphTypes;

public class DelegateeType : ObjectGraphType<DelegateeType>
{
public BigInteger TotalShares { get; set; }

public bool Jailed { get; set; }

public long JailedUntil { get; set; }

public bool Tombstoned { get; set; }

public FungibleAssetValue TotalDelegated { get; set; }

public BigInteger CommissionPercentage { get; set; }

public DelegateeType()
{
Field<NonNullGraphType<StringGraphType>>(
nameof(TotalShares),
description: "Total shares of delegatee",
resolve: context => context.Source.TotalShares.ToString("N0"));
Field<NonNullGraphType<BooleanGraphType>>(
nameof(Jailed),
description: "Specifies whether the delegatee is jailed.",
resolve: context => context.Source.Jailed);
Field<NonNullGraphType<LongGraphType>>(
nameof(JailedUntil),
description: "Block height until which the delegatee is jailed.",
resolve: context => context.Source.JailedUntil);
Field<NonNullGraphType<BooleanGraphType>>(
nameof(Tombstoned),
description: "Specifies whether the delegatee is tombstoned.",
resolve: context => context.Source.Tombstoned);
Field<NonNullGraphType<FungibleAssetValueType>>(
nameof(TotalDelegated),
description: "Total delegated amount of the delegatee.",
resolve: context => context.Source.TotalDelegated);
}

public static DelegateeType From(GuildRepository guildRepository, Address validatorAddress)
{
var delegatee = guildRepository.GetDelegatee(validatorAddress);

return new DelegateeType
{
TotalShares = delegatee.TotalShares,
Jailed = delegatee.Jailed,
JailedUntil = delegatee.JailedUntil,
Tombstoned = delegatee.Tombstoned,
TotalDelegated = delegatee.TotalDelegated,
};
}

public static DelegateeType From(ValidatorRepository validatorRepository, Address validatorAddress)
{
var delegatee = validatorRepository.GetDelegatee(validatorAddress);

return new DelegateeType
{
TotalShares = delegatee.TotalShares,
Jailed = delegatee.Jailed,
JailedUntil = delegatee.JailedUntil,
Tombstoned = delegatee.Tombstoned,
TotalDelegated = delegatee.TotalDelegated,
};
}
}
50 changes: 50 additions & 0 deletions NineChronicles.Headless/GraphTypes/DelegatorRepositoryType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using GraphQL.Types;
using Libplanet.Crypto;
using Nekoyume.Model.Guild;
using Nekoyume.ValidatorDelegation;

namespace NineChronicles.Headless.GraphTypes;

public class DelegatorRepositoryType : ObjectGraphType<DelegatorRepositoryType>
{
public DelegatorType? GuildDelegator { get; set; }

public DelegatorType? ValidatorDelegator { get; set; }

public DelegatorRepositoryType()
{
Field<DelegatorType>(
nameof(GuildDelegator),
description: "Delegator of the guild repository",
resolve: context => context.Source.GuildDelegator);
Field<DelegatorType>(
nameof(ValidatorDelegator),
description: "Delegator of the validator repository",
resolve: context => context.Source.ValidatorDelegator);
}

public static DelegatorRepositoryType From(GuildRepository guildRepository, GuildParticipant guildParticipant)
{
var validatorRepository = new ValidatorRepository(
guildRepository.World, guildRepository.ActionContext);
var guild = guildRepository.GetGuild(guildParticipant.GuildAddress);

return new DelegatorRepositoryType
{
GuildDelegator = DelegatorType.From(guildRepository, guildParticipant),
ValidatorDelegator = DelegatorType.From(validatorRepository, guild),
};
}

public static DelegatorRepositoryType From(ValidatorRepository validatorRepository, Address validatorAddress)
{
var guildRepository = new GuildRepository(
validatorRepository.World, validatorRepository.ActionContext);

return new DelegatorRepositoryType
{
GuildDelegator = DelegatorType.From(guildRepository, validatorAddress),
ValidatorDelegator = DelegatorType.From(validatorRepository, validatorAddress),
};
}
}
Loading
Loading