예제 #1
0
    public async Task RevokeTokenCoinsRequiresGrantKeySignature()
    {
        await using var fxAccount = await TestAccount.CreateAsync(_network);

        await using var fxToken = await TestToken.CreateAsync(_network, null, fxAccount);

        var circulation = fxToken.Params.Circulation;
        var xferAmount  = circulation / 3;

        await AssertHg.TokenStatusAsync(fxToken, fxAccount, TokenKycStatus.Revoked);

        await fxToken.Client.GrantTokenKycAsync(fxToken, fxAccount, fxToken.GrantPrivateKey);

        await AssertHg.TokenStatusAsync(fxToken, fxAccount, TokenKycStatus.Granted);

        await fxToken.Client.TransferTokensAsync(fxToken, fxToken.TreasuryAccount, fxAccount, (long)xferAmount, fxToken.TreasuryAccount);

        var tex = await Assert.ThrowsAsync <TransactionException>(async() =>
        {
            await fxToken.Client.RevokeTokenKycAsync(fxToken.Record.Token, fxAccount);
        });

        Assert.Equal(ResponseCode.InvalidSignature, tex.Status);
        Assert.StartsWith("Unable to Revoke Token, status: InvalidSignature", tex.Message);

        await AssertHg.TokenStatusAsync(fxToken, fxAccount, TokenKycStatus.Granted);
    }
예제 #2
0
        public async Task CanSuspendAResumedAccount()
        {
            await using var fxAccount = await TestAccount.CreateAsync(_network);

            await using var fxToken = await TestToken.CreateAsync(_network, fx =>
            {
                fx.Params.GrantKycEndorsement = null;
                fx.Params.InitializeSuspended = true;
            }, fxAccount);

            var circulation = fxToken.Params.Circulation;
            var xferAmount  = circulation / 3;

            await AssertHg.TokenStatusAsync(fxToken, fxAccount, TokenTradableStatus.Suspended);

            await fxToken.Client.ResumeTokenAsync(fxToken.Record.Token, fxAccount, fxToken.SuspendPrivateKey);

            await AssertHg.TokenStatusAsync(fxToken, fxAccount, TokenTradableStatus.Tradable);

            await fxToken.Client.SuspendTokenAsync(fxToken.Record.Token, fxAccount, fxToken.SuspendPrivateKey);

            await AssertHg.TokenStatusAsync(fxToken, fxAccount, TokenTradableStatus.Suspended);

            var tex = await Assert.ThrowsAsync <TransactionException>(async() =>
            {
                await fxToken.Client.TransferTokensAsync(fxToken, fxToken.TreasuryAccount, fxAccount, (long)xferAmount, fxToken.TreasuryAccount);
            });

            Assert.Equal(ResponseCode.AccountFrozenForToken, tex.Status);
            Assert.StartsWith("Unable to execute transfers, status: AccountFrozenForToken", tex.Message);

            await AssertHg.TokenStatusAsync(fxToken, fxAccount, TokenTradableStatus.Suspended);
        }
예제 #3
0
    public async Task CanReumeTokenCoinTradingAndGetRecord()
    {
        await using var fxAccount = await TestAccount.CreateAsync(_network);

        await using var fxToken = await TestToken.CreateAsync(_network, fx =>
        {
            fx.Params.GrantKycEndorsement = null;
            fx.Params.InitializeSuspended = true;
        }, fxAccount);

        var circulation = fxToken.Params.Circulation;
        var xferAmount  = circulation / 3;

        await AssertHg.TokenStatusAsync(fxToken, fxAccount, TokenTradableStatus.Suspended);

        var record = await fxToken.Client.ResumeTokenWithRecordAsync(fxToken.Record.Token, fxAccount, fxToken.SuspendPrivateKey);

        Assert.Equal(ResponseCode.Success, record.Status);
        Assert.False(record.Hash.IsEmpty);
        Assert.NotNull(record.Concensus);
        Assert.NotNull(record.CurrentExchangeRate);
        Assert.NotNull(record.NextExchangeRate);
        Assert.NotEmpty(record.Hash.ToArray());
        Assert.Empty(record.Memo);
        Assert.InRange(record.Fee, 0UL, ulong.MaxValue);
        Assert.Equal(_network.Payer, record.Id.Address);

        await AssertHg.TokenStatusAsync(fxToken, fxAccount, TokenTradableStatus.Tradable);

        await fxToken.Client.TransferTokensAsync(fxToken, fxToken.TreasuryAccount, fxAccount, (long)xferAmount, fxToken.TreasuryAccount);

        await AssertHg.TokenStatusAsync(fxToken, fxAccount, TokenTradableStatus.Tradable);
    }
예제 #4
0
        public async Task CanGrantTokenCoinsFromWnyAccountWithGrantKey()
        {
            await using var fxOther = await TestAccount.CreateAsync(_network, fx => fx.CreateParams.InitialBalance = 120_00_000_000);

            await using var fxAccount = await TestAccount.CreateAsync(_network);

            await using var fxToken = await TestToken.CreateAsync(_network, null, fxAccount);

            var circulation = fxToken.Params.Circulation;
            var xferAmount  = circulation / 3;

            await AssertHg.TokenStatusAsync(fxToken, fxAccount, TokenKycStatus.Revoked);

            await fxToken.Client.GrantTokenKycAsync(fxToken.Record.Token, fxAccount, fxToken.GrantPrivateKey, ctx =>
            {
                ctx.Payer     = fxOther.Record.Address;
                ctx.Signatory = fxOther.PrivateKey;
            });

            await AssertHg.TokenStatusAsync(fxToken, fxAccount, TokenKycStatus.Granted);

            await fxToken.Client.TransferTokensAsync(fxToken, fxToken.TreasuryAccount, fxAccount, (long)xferAmount, fxToken.TreasuryAccount);

            await AssertHg.TokenStatusAsync(fxToken, fxAccount, TokenKycStatus.Granted);
        }
예제 #5
0
        public async Task CannotSuspendTokenWhenFreezeNotEnabled()
        {
            await using var fxAccount = await TestAccount.CreateAsync(_network);

            await using var fxToken = await TestToken.CreateAsync(_network, fx =>
            {
                fx.Params.GrantKycEndorsement = null;
                fx.Params.SuspendEndorsement  = null;
                fx.Params.InitializeSuspended = false;
            }, fxAccount);

            var circulation = fxToken.Params.Circulation;
            var xferAmount  = circulation / 3;

            await AssertHg.TokenStatusAsync(fxToken, fxAccount, TokenTradableStatus.NotApplicable);

            var tex = await Assert.ThrowsAsync <TransactionException>(async() =>
            {
                await fxToken.Client.SuspendTokenAsync(fxToken.Record.Token, fxAccount, fxToken.SuspendPrivateKey);
            });

            Assert.Equal(ResponseCode.TokenHasNoFreezeKey, tex.Status);
            Assert.StartsWith("Unable to Suspend Token, status: TokenHasNoFreezeKey", tex.Message);

            await AssertHg.TokenStatusAsync(fxToken, fxAccount, TokenTradableStatus.NotApplicable);

            await fxToken.Client.TransferTokensAsync(fxToken, fxToken.TreasuryAccount, fxAccount, (long)xferAmount, fxToken.TreasuryAccount);

            await AssertHg.TokenStatusAsync(fxToken, fxAccount, TokenTradableStatus.NotApplicable);
        }
예제 #6
0
    public async Task CanGrantTokensToAliasAccountDefect()
    {
        // Associating an asset with an account using its alias address has not yet been
        // implemented by the network, although it will accept the transaction.
        var testFailException = (await Assert.ThrowsAsync <TransactionException>(CanGrantTokensToAliasAccount));

        Assert.StartsWith("Unable to Grant Token, status: InvalidAccountId", testFailException.Message);

        //[Fact(DisplayName = "Grant Tokens: Can Grant Token Coins to Alias Account")]
        async Task CanGrantTokensToAliasAccount()
        {
            await using var fxAccount = await TestAliasAccount.CreateAsync(_network);

            await using var fxToken = await TestToken.CreateAsync(_network);

            await fxToken.Client.AssociateTokenAsync(fxToken.Record.Token, fxAccount, fxAccount.PrivateKey);

            var circulation = fxToken.Params.Circulation;
            var xferAmount  = circulation / 3;

            await AssertHg.TokenStatusAsync(fxToken, fxAccount, TokenKycStatus.Revoked);

            await fxToken.Client.GrantTokenKycAsync(fxToken.Record.Token, fxAccount.Alias, fxToken.GrantPrivateKey);

            await AssertHg.TokenStatusAsync(fxToken, fxAccount, TokenKycStatus.Granted);

            await fxToken.Client.TransferTokensAsync(fxToken, fxToken.TreasuryAccount, fxAccount, (long)xferAmount, fxToken.TreasuryAccount);

            await AssertHg.TokenStatusAsync(fxToken, fxAccount, TokenKycStatus.Granted);
        }
    }
예제 #7
0
    public async Task CanNotScheduleReumeTokenCoinTrading()
    {
        await using var fxPayer = await TestAccount.CreateAsync(_network, fx => fx.CreateParams.InitialBalance = 20_00_000_000);

        await using var fxAccount = await TestAccount.CreateAsync(_network);

        await using var fxToken = await TestToken.CreateAsync(_network, fx =>
        {
            fx.Params.GrantKycEndorsement = null;
            fx.Params.InitializeSuspended = true;
        }, fxAccount);

        await AssertHg.TokenStatusAsync(fxToken, fxAccount, TokenTradableStatus.Suspended);

        var tex = await Assert.ThrowsAsync <TransactionException>(async() =>
        {
            await fxToken.Client.ResumeTokenAsync(
                fxToken.Record.Token,
                fxAccount,
                new Signatory(
                    fxToken.SuspendPrivateKey,
                    new PendingParams
            {
                PendingPayer = fxPayer
            }));
        });

        Assert.Equal(ResponseCode.ScheduledTransactionNotInWhitelist, tex.Status);
        Assert.StartsWith("Unable to schedule transaction, status: ScheduledTransactionNotInWhitelist", tex.Message);
    }
예제 #8
0
    public async Task CanReusmeTokenCoinTradingWithAiasAccountDefect()
    {
        // Resuming a token with an account using its alias address has not yet been
        // implemented by the network, although it will accept the transaction.
        var testFailException = (await Assert.ThrowsAsync <TransactionException>(CanReusmeTokenCoinTradingWithAiasAccount));

        Assert.StartsWith("Unable to Resume Token, status: InvalidAccountId", testFailException.Message);

        //[Fact(DisplayName = "Resume Tokens: Can Reume Token Coin Trading with Alias Account")]
        async Task CanReusmeTokenCoinTradingWithAiasAccount()
        {
            await using var fxAccount = await TestAliasAccount.CreateAsync(_network);

            await using var fxToken = await TestToken.CreateAsync(_network, fx =>
            {
                fx.Params.GrantKycEndorsement = null;
                fx.Params.InitializeSuspended = true;
            });

            await fxToken.Client.AssociateTokenAsync(fxToken.Record.Token, fxAccount, fxAccount.PrivateKey);

            var circulation = fxToken.Params.Circulation;
            var xferAmount  = circulation / 3;

            await AssertHg.TokenStatusAsync(fxToken, fxAccount, TokenTradableStatus.Suspended);

            await fxToken.Client.ResumeTokenAsync(fxToken.Record.Token, fxAccount.Alias, fxToken.SuspendPrivateKey);

            await AssertHg.TokenStatusAsync(fxToken, fxAccount, TokenTradableStatus.Tradable);

            await fxToken.Client.TransferTokensAsync(fxToken, fxToken.TreasuryAccount, fxAccount, (long)xferAmount, fxToken.TreasuryAccount);

            await AssertHg.TokenStatusAsync(fxToken, fxAccount, TokenTradableStatus.Tradable);
        }
    }
예제 #9
0
    public async Task ResumingAnUnfrozenAccountIsNoop()
    {
        await using var fxAccount = await TestAccount.CreateAsync(_network);

        await using var fxToken = await TestToken.CreateAsync(_network, fx =>
        {
            fx.Params.GrantKycEndorsement = null;
            fx.Params.InitializeSuspended = false;
        }, fxAccount);

        var circulation = fxToken.Params.Circulation;
        var xferAmount  = circulation / 3;

        await AssertHg.TokenStatusAsync(fxToken, fxAccount, TokenTradableStatus.Tradable);

        await fxToken.Client.ResumeTokenAsync(fxToken.Record.Token, fxAccount, fxToken.SuspendPrivateKey);

        var info = (await fxAccount.Client.GetAccountInfoAsync(fxAccount)).Tokens.FirstOrDefault(t => t.Token == fxToken.Record.Token);

        Assert.Equal(0Ul, info.Balance);
        Assert.Equal(fxToken.Params.Decimals, info.Decimals);
        Assert.Equal(TokenTradableStatus.Tradable, info.TradableStatus);
        Assert.False(info.AutoAssociated);

        await fxToken.Client.TransferTokensAsync(fxToken, fxToken.TreasuryAccount, fxAccount, (long)xferAmount, fxToken.TreasuryAccount);

        info = (await fxAccount.Client.GetAccountInfoAsync(fxAccount)).Tokens.FirstOrDefault(t => t.Token == fxToken.Record.Token);
        Assert.Equal(xferAmount, info.Balance);
        Assert.Equal(fxToken.Params.Decimals, info.Decimals);
        Assert.Equal(TokenTradableStatus.Tradable, info.TradableStatus);
        Assert.False(info.AutoAssociated);
    }
예제 #10
0
    public async Task CanNotResumeTokenWhenFreezeNotEnabled()
    {
        await using var fxAccount = await TestAccount.CreateAsync(_network);

        await using var fxToken = await TestToken.CreateAsync(_network, fx =>
        {
            fx.Params.GrantKycEndorsement = null;
            fx.Params.SuspendEndorsement  = null;
            fx.Params.InitializeSuspended = false;
        }, fxAccount);

        var circulation = fxToken.Params.Circulation;
        var xferAmount  = circulation / 3;

        await AssertHg.TokenStatusAsync(fxToken, fxAccount, TokenTradableStatus.NotApplicable);

        var tex = await Assert.ThrowsAsync <TransactionException>(async() =>
        {
            await fxToken.Client.ResumeTokenAsync(fxToken.Record.Token, fxAccount, fxToken.SuspendPrivateKey);
        });

        Assert.Equal(ResponseCode.TokenHasNoFreezeKey, tex.Status);
        Assert.StartsWith("Unable to Resume Token, status: TokenHasNoFreezeKey", tex.Message);

        var info = (await fxAccount.Client.GetAccountInfoAsync(fxAccount)).Tokens.FirstOrDefault(t => t.Token == fxToken.Record.Token);

        Assert.Equal(0Ul, info.Balance);
        Assert.Equal(fxToken.Params.Decimals, info.Decimals);
        Assert.Equal(TokenTradableStatus.NotApplicable, info.TradableStatus);
        Assert.False(info.AutoAssociated);

        await fxToken.Client.TransferTokensAsync(fxToken, fxToken.TreasuryAccount, fxAccount, (long)xferAmount, fxToken.TreasuryAccount);

        await AssertHg.TokenStatusAsync(fxToken, fxAccount, TokenTradableStatus.NotApplicable);
    }
예제 #11
0
    public async Task CanResumeASuspendedAccount()
    {
        await using var fxAccount = await TestAccount.CreateAsync(_network);

        await using var fxToken = await TestToken.CreateAsync(_network, fx =>
        {
            fx.Params.GrantKycEndorsement = null;
            fx.Params.InitializeSuspended = false;
        }, fxAccount);

        var circulation = fxToken.Params.Circulation;
        var xferAmount  = circulation / 3;

        await AssertHg.TokenStatusAsync(fxToken, fxAccount, TokenTradableStatus.Tradable);

        await fxToken.Client.SuspendTokenAsync(fxToken.Record.Token, fxAccount, fxToken.SuspendPrivateKey);

        await AssertHg.TokenStatusAsync(fxToken, fxAccount, TokenTradableStatus.Suspended);

        await fxToken.Client.ResumeTokenAsync(fxToken.Record.Token, fxAccount, fxToken.SuspendPrivateKey);

        await AssertHg.TokenStatusAsync(fxToken, fxAccount, TokenTradableStatus.Tradable);

        await fxToken.Client.TransferTokensAsync(fxToken, fxToken.TreasuryAccount, fxAccount, (long)xferAmount, fxToken.TreasuryAccount);

        await AssertHg.TokenStatusAsync(fxToken, fxAccount, TokenTradableStatus.Tradable);
    }
예제 #12
0
    public async Task CanRevokeTokenCoinsFromAnyAccountWithGrantKey()
    {
        await using var fxOther = await TestAccount.CreateAsync(_network, fx => fx.CreateParams.InitialBalance = 120_00_000_000);

        await using var fxAccount = await TestAccount.CreateAsync(_network);

        await using var fxToken = await TestToken.CreateAsync(_network, null, fxAccount);

        var circulation = fxToken.Params.Circulation;
        var xferAmount  = circulation / 3;

        await AssertHg.TokenStatusAsync(fxToken, fxAccount, TokenKycStatus.Revoked);

        await fxToken.Client.GrantTokenKycAsync(fxToken, fxAccount, fxToken.GrantPrivateKey);

        await AssertHg.TokenStatusAsync(fxToken, fxAccount, TokenKycStatus.Granted);

        await fxToken.Client.TransferTokensAsync(fxToken, fxToken.TreasuryAccount, fxAccount, (long)xferAmount, fxToken.TreasuryAccount);

        await fxToken.Client.RevokeTokenKycAsync(fxToken.Record.Token, fxAccount, fxToken.GrantPrivateKey, ctx =>
        {
            ctx.Payer     = fxOther.Record.Address;
            ctx.Signatory = fxOther.PrivateKey;
        });

        await AssertHg.TokenStatusAsync(fxToken, fxAccount, TokenKycStatus.Revoked);

        var tex = await Assert.ThrowsAsync <TransactionException>(async() =>
        {
            await fxToken.Client.TransferTokensAsync(fxToken, fxToken.TreasuryAccount, fxAccount, (long)xferAmount, fxToken.TreasuryAccount);
        });

        Assert.Equal(ResponseCode.AccountKycNotGrantedForToken, tex.Status);
        Assert.StartsWith("Unable to execute transfers, status: AccountKycNotGrantedForToken", tex.Message);
    }
예제 #13
0
    public async Task CanReumeTokenCoinTradingFromAnyAccountWithSuspendKey()
    {
        await using var fxOther = await TestAccount.CreateAsync(_network, fx => fx.CreateParams.InitialBalance = 100_00_000_000);

        await using var fxAccount = await TestAccount.CreateAsync(_network);

        await using var fxToken = await TestToken.CreateAsync(_network, fx =>
        {
            fx.Params.GrantKycEndorsement = null;
            fx.Params.InitializeSuspended = true;
        }, fxAccount);

        var circulation = fxToken.Params.Circulation;
        var xferAmount  = circulation / 3;

        await AssertHg.TokenStatusAsync(fxToken, fxAccount, TokenTradableStatus.Suspended);

        await fxToken.Client.ResumeTokenAsync(fxToken.Record.Token, fxAccount, fxToken.SuspendPrivateKey, ctx =>
        {
            ctx.Payer     = fxOther.Record.Address;
            ctx.Signatory = fxOther.PrivateKey;
        });

        await AssertHg.TokenStatusAsync(fxToken, fxAccount, TokenTradableStatus.Tradable);

        await fxToken.Client.TransferTokensAsync(fxToken, fxToken.TreasuryAccount, fxAccount, (long)xferAmount, fxToken.TreasuryAccount);

        await AssertHg.TokenStatusAsync(fxToken, fxAccount, TokenTradableStatus.Tradable);
    }
예제 #14
0
        public async Task CanNotScheduleGrantTokenCoins()
        {
            await using var fxPayer = await TestAccount.CreateAsync(_network, fx => fx.CreateParams.InitialBalance = 20_00_000_000);

            await using var fxAccount = await TestAccount.CreateAsync(_network);

            await using var fxToken = await TestToken.CreateAsync(_network, null, fxAccount);

            var circulation = fxToken.Params.Circulation;
            var xferAmount  = circulation / 3;
            await AssertHg.TokenStatusAsync(fxToken, fxAccount, TokenKycStatus.Revoked);

            var tex = await Assert.ThrowsAsync <TransactionException>(async() =>
            {
                await fxToken.Client.GrantTokenKycAsync(
                    fxToken.Record.Token,
                    fxAccount,
                    new Signatory(
                        fxToken.GrantPrivateKey,
                        new PendingParams
                {
                    PendingPayer = fxPayer
                }));
            });

            Assert.Equal(ResponseCode.ScheduledTransactionNotInWhitelist, tex.Status);
            Assert.StartsWith("Unable to schedule transaction, status: ScheduledTransactionNotInWhitelist", tex.Message);
        }
예제 #15
0
        public async Task CanSuspendTokenCoinTradingFromAnyAccountWithSuspendKey()
        {
            await using var fxOther = await TestAccount.CreateAsync(_network, fx => fx.CreateParams.InitialBalance = 120_00_000_000);

            await using var fxAccount = await TestAccount.CreateAsync(_network);

            await using var fxToken = await TestToken.CreateAsync(_network, fx =>
            {
                fx.Params.GrantKycEndorsement = null;
                fx.Params.InitializeSuspended = false;
            }, fxAccount);

            var circulation = fxToken.Params.Circulation;
            var xferAmount  = circulation / 3;

            await AssertHg.TokenStatusAsync(fxToken, fxAccount, TokenTradableStatus.Tradable);

            await fxToken.Client.SuspendTokenAsync(fxToken.Record.Token, fxAccount, fxToken.SuspendPrivateKey, ctx =>
            {
                ctx.Payer     = fxOther.Record.Address;
                ctx.Signatory = fxOther.PrivateKey;
            });

            await AssertHg.TokenStatusAsync(fxToken, fxAccount, TokenTradableStatus.Suspended);

            var tex = await Assert.ThrowsAsync <TransactionException>(async() =>
            {
                await fxToken.Client.TransferTokensAsync(fxToken, fxToken.TreasuryAccount, fxAccount, (long)xferAmount, fxToken.TreasuryAccount);
            });

            Assert.Equal(ResponseCode.AccountFrozenForToken, tex.Status);
            Assert.StartsWith("Unable to execute transfers, status: AccountFrozenForToken", tex.Message);

            await AssertHg.TokenStatusAsync(fxToken, fxAccount, TokenTradableStatus.Suspended);
        }
예제 #16
0
        public async Task CanGrantTokensAndGetRecordWithoutExtraSignatory()
        {
            await using var fxAccount = await TestAccount.CreateAsync(_network);

            await using var fxToken = await TestToken.CreateAsync(_network, null, fxAccount);

            var circulation = fxToken.Params.Circulation;
            var xferAmount  = circulation / 3;

            await AssertHg.TokenStatusAsync(fxToken, fxAccount, TokenKycStatus.Revoked);

            var record = await fxToken.Client.GrantTokenKycWithRecordAsync(fxToken.Record.Token, fxAccount, ctx => ctx.Signatory = new Signatory(_network.Signatory, fxToken.GrantPrivateKey));

            Assert.Equal(ResponseCode.Success, record.Status);
            Assert.False(record.Hash.IsEmpty);
            Assert.NotNull(record.Concensus);
            Assert.NotNull(record.CurrentExchangeRate);
            Assert.NotNull(record.NextExchangeRate);
            Assert.NotEmpty(record.Hash.ToArray());
            Assert.Empty(record.Memo);
            Assert.InRange(record.Fee, 0UL, ulong.MaxValue);
            Assert.Equal(_network.Payer, record.Id.Address);

            await AssertHg.TokenStatusAsync(fxToken, fxAccount, TokenKycStatus.Granted);

            await fxToken.Client.TransferTokensAsync(fxToken, fxToken.TreasuryAccount, fxAccount, (long)xferAmount, fxToken.TreasuryAccount);

            await AssertHg.TokenStatusAsync(fxToken, fxAccount, TokenKycStatus.Granted);
        }
예제 #17
0
        public async Task CannotGrantTokenCoinsWhenGrantKYCTurnedOff()
        {
            await using var fxAccount = await TestAccount.CreateAsync(_network);

            await using var fxToken = await TestToken.CreateAsync(_network, fx => fx.Params.GrantKycEndorsement = null, fxAccount);

            await AssertHg.TokenStatusAsync(fxToken, fxAccount, TokenKycStatus.NotApplicable);

            var tex = await Assert.ThrowsAsync <TransactionException>(async() =>
            {
                await fxToken.Client.GrantTokenKycAsync(fxToken.Record.Token, fxAccount, fxToken.GrantPrivateKey);
            });

            Assert.Equal(ResponseCode.TokenHasNoKycKey, tex.Status);
            Assert.StartsWith("Unable to Grant Token, status: TokenHasNoKycKey", tex.Message);
        }
예제 #18
0
        public async Task CanGrantTokens()
        {
            await using var fxAccount = await TestAccount.CreateAsync(_network);

            await using var fxToken = await TestToken.CreateAsync(_network, null, fxAccount);

            var circulation = fxToken.Params.Circulation;
            var xferAmount  = circulation / 3;

            await AssertHg.TokenStatusAsync(fxToken, fxAccount, TokenKycStatus.Revoked);

            await fxToken.Client.GrantTokenKycAsync(fxToken.Record.Token, fxAccount, fxToken.GrantPrivateKey);

            await AssertHg.TokenStatusAsync(fxToken, fxAccount, TokenKycStatus.Granted);

            await fxToken.Client.TransferTokensAsync(fxToken, fxToken.TreasuryAccount, fxAccount, (long)xferAmount, fxToken.TreasuryAccount);

            await AssertHg.TokenStatusAsync(fxToken, fxAccount, TokenKycStatus.Granted);
        }
예제 #19
0
    public async Task CanSuspendTokenCoinTradingWithAliasAddressDefect()
    {
        // Associating an asset with an account using its alias address has not yet been
        // implemented by the network, although it will accept the transaction.
        var testFailException = (await Assert.ThrowsAsync <TransactionException>(CanSuspendTokenCoinTradingWithAliasAddress));

        Assert.StartsWith("Unable to Suspend Token, status: InvalidAccountId", testFailException.Message);

        //[Fact(DisplayName = "Suspend Tokens: Can Suspend Token Coin Trading with Alias Address")]
        async Task CanSuspendTokenCoinTradingWithAliasAddress()
        {
            await using var fxAccount = await TestAliasAccount.CreateAsync(_network);

            await using var fxToken = await TestToken.CreateAsync(_network, fx =>
            {
                fx.Params.GrantKycEndorsement = null;
                fx.Params.InitializeSuspended = false;
            });

            await fxToken.Client.AssociateTokenAsync(fxToken.Record.Token, fxAccount, fxAccount.PrivateKey);

            var circulation = fxToken.Params.Circulation;
            var xferAmount  = circulation / 3;

            await AssertHg.TokenStatusAsync(fxToken, fxAccount, TokenTradableStatus.Tradable);

            await fxToken.Client.SuspendTokenAsync(fxToken.Record.Token, fxAccount.Alias, fxToken.SuspendPrivateKey);

            await AssertHg.TokenStatusAsync(fxToken, fxAccount, TokenTradableStatus.Suspended);

            var tex = await Assert.ThrowsAsync <TransactionException>(async() =>
            {
                await fxToken.Client.TransferTokensAsync(fxToken, fxToken.TreasuryAccount, fxAccount, (long)xferAmount, fxToken.TreasuryAccount);
            });

            Assert.Equal(ResponseCode.AccountFrozenForToken, tex.Status);
            Assert.StartsWith("Unable to execute transfers, status: AccountFrozenForToken", tex.Message);

            await AssertHg.TokenStatusAsync(fxToken, fxAccount, TokenTradableStatus.Suspended);
        }
    }
예제 #20
0
    public async Task CanRevokeTokensAndGetRecord()
    {
        await using var fxAccount = await TestAccount.CreateAsync(_network);

        await using var fxToken = await TestToken.CreateAsync(_network, null, fxAccount);

        var circulation = fxToken.Params.Circulation;
        var xferAmount  = circulation / 3;

        await AssertHg.TokenStatusAsync(fxToken, fxAccount, TokenKycStatus.Revoked);

        await fxToken.Client.GrantTokenKycAsync(fxToken, fxAccount, fxToken.GrantPrivateKey);

        await AssertHg.TokenStatusAsync(fxToken, fxAccount, TokenKycStatus.Granted);

        await fxToken.Client.TransferTokensAsync(fxToken, fxToken.TreasuryAccount, fxAccount, (long)xferAmount, fxToken.TreasuryAccount);

        var record = await fxToken.Client.RevokeTokenKycWithRecordAsync(fxToken.Record.Token, fxAccount, fxToken.GrantPrivateKey);

        Assert.Equal(ResponseCode.Success, record.Status);
        Assert.False(record.Hash.IsEmpty);
        Assert.NotNull(record.Concensus);
        Assert.NotNull(record.CurrentExchangeRate);
        Assert.NotNull(record.NextExchangeRate);
        Assert.NotEmpty(record.Hash.ToArray());
        Assert.Empty(record.Memo);
        Assert.InRange(record.Fee, 0UL, ulong.MaxValue);
        Assert.Equal(_network.Payer, record.Id.Address);

        await AssertHg.TokenStatusAsync(fxToken, fxAccount, TokenKycStatus.Revoked);

        var tex = await Assert.ThrowsAsync <TransactionException>(async() =>
        {
            await fxToken.Client.TransferTokensAsync(fxToken, fxToken.TreasuryAccount, fxAccount, (long)xferAmount, fxToken.TreasuryAccount);
        });

        Assert.Equal(ResponseCode.AccountKycNotGrantedForToken, tex.Status);
        Assert.StartsWith("Unable to execute transfers, status: AccountKycNotGrantedForToken", tex.Message);
    }
예제 #21
0
        public async Task CanSuspendTokenCoinTradingAndGetRecordNoExtraSignatory()
        {
            await using var fxAccount = await TestAccount.CreateAsync(_network);

            await using var fxToken = await TestToken.CreateAsync(_network, fx =>
            {
                fx.Params.GrantKycEndorsement = null;
                fx.Params.InitializeSuspended = false;
            }, fxAccount);

            var circulation = fxToken.Params.Circulation;
            var xferAmount  = circulation / 3;

            await AssertHg.TokenStatusAsync(fxToken, fxAccount, TokenTradableStatus.Tradable);

            var record = await fxToken.Client.SuspendTokenWithRecordAsync(fxToken.Record.Token, fxAccount, ctx => ctx.Signatory = new Signatory(_network.Signatory, fxToken.SuspendPrivateKey));

            Assert.Equal(ResponseCode.Success, record.Status);
            Assert.False(record.Hash.IsEmpty);
            Assert.NotNull(record.Concensus);
            Assert.NotNull(record.CurrentExchangeRate);
            Assert.NotNull(record.NextExchangeRate);
            Assert.NotEmpty(record.Hash.ToArray());
            Assert.Empty(record.Memo);
            Assert.InRange(record.Fee, 0UL, ulong.MaxValue);
            Assert.Equal(_network.Payer, record.Id.Address);

            await AssertHg.TokenStatusAsync(fxToken, fxAccount, TokenTradableStatus.Suspended);

            var tex = await Assert.ThrowsAsync <TransactionException>(async() =>
            {
                await fxToken.Client.TransferTokensAsync(fxToken, fxToken.TreasuryAccount, fxAccount, (long)xferAmount, fxToken.TreasuryAccount);
            });

            Assert.Equal(ResponseCode.AccountFrozenForToken, tex.Status);
            Assert.StartsWith("Unable to execute transfers, status: AccountFrozenForToken", tex.Message);

            await AssertHg.TokenStatusAsync(fxToken, fxAccount, TokenTradableStatus.Suspended);
        }
예제 #22
0
    public async Task ResumeTokenRequiresSuspendKeyToSignTransaction()
    {
        await using var fxAccount = await TestAccount.CreateAsync(_network);

        await using var fxToken = await TestToken.CreateAsync(_network, fx =>
        {
            fx.Params.GrantKycEndorsement = null;
            fx.Params.InitializeSuspended = true;
        }, fxAccount);

        var circulation = fxToken.Params.Circulation;
        var xferAmount  = circulation / 3;

        await AssertHg.TokenStatusAsync(fxToken, fxAccount, TokenTradableStatus.Suspended);

        var tex = await Assert.ThrowsAsync <TransactionException>(async() =>
        {
            await fxToken.Client.ResumeTokenAsync(fxToken.Record.Token, fxAccount);
        });

        Assert.Equal(ResponseCode.InvalidSignature, tex.Status);
        Assert.StartsWith("Unable to Resume Token, status: InvalidSignature", tex.Message);

        var info = (await fxAccount.Client.GetAccountInfoAsync(fxAccount)).Tokens.FirstOrDefault(t => t.Token == fxToken.Record.Token);

        Assert.Equal(0Ul, info.Balance);
        Assert.Equal(fxToken.Params.Decimals, info.Decimals);
        Assert.Equal(TokenTradableStatus.Suspended, info.TradableStatus);
        Assert.False(info.AutoAssociated);

        tex = await Assert.ThrowsAsync <TransactionException>(async() =>
        {
            await fxToken.Client.TransferTokensAsync(fxToken, fxToken.TreasuryAccount, fxAccount, (long)xferAmount, fxToken.TreasuryAccount);
        });

        Assert.Equal(ResponseCode.AccountFrozenForToken, tex.Status);
        Assert.StartsWith("Unable to execute transfers, status: AccountFrozenForToken", tex.Message);
    }