public async Task CanDissociateMultipleTokensWithAccountNoExtraSignatory() { await using var fxAccount = await TestAccount.CreateAsync(_network, fx => fx.CreateParams.InitialBalance = 120_00_000_000); await using var fxToken1 = await TestToken.CreateAsync(_network, null, fxAccount); await using var fxToken2 = await TestToken.CreateAsync(_network, null, fxAccount); var tokens = new Address[] { fxToken1.Record.Token, fxToken2.Record.Token }; await AssertHg.TokenIsAssociatedAsync(fxToken1, fxAccount); await AssertHg.TokenIsAssociatedAsync(fxToken2, fxAccount); var receipt = await fxAccount.Client.DissociateTokensAsync(tokens, fxAccount.Record.Address, ctx => { ctx.Payer = fxAccount.Record.Address; ctx.Signatory = fxAccount.PrivateKey; }); Assert.Equal(ResponseCode.Success, receipt.Status); await AssertHg.TokenNotAssociatedAsync(fxToken1, fxAccount); await AssertHg.TokenNotAssociatedAsync(fxToken2, fxAccount); }
public async Task CanAssociateTokenWithAccountAndGetRecordNoExtraSignatory() { await using var fxAccount = await TestAccount.CreateAsync(_network, fx => fx.CreateParams.InitialBalance = 120_00_000_000); await using var fxToken = await TestToken.CreateAsync(_network); await AssertHg.TokenNotAssociatedAsync(fxToken, fxAccount); var record = await fxAccount.Client.AssociateTokenWithRecordAsync(fxToken.Record.Token, fxAccount.Record.Address, ctx => { ctx.Payer = fxAccount.Record.Address; ctx.Signatory = fxAccount.PrivateKey; }); Assert.Equal(ResponseCode.Success, record.Status); 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(fxAccount.Record.Address, record.Id.Address); var association = await AssertHg.TokenIsAssociatedAsync(fxToken, fxAccount); Assert.Equal(fxToken.Record.Token, association.Token); Assert.Equal(fxToken.Params.Symbol, association.Symbol); Assert.Equal(0UL, association.Balance); Assert.Equal(TokenKycStatus.Revoked, association.KycStatus); Assert.Equal(TokenTradableStatus.Tradable, association.TradableStatus); }
public async Task SuspendTokenRequiresSuspendKeyToSignTransaciton() { 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; }); var circulation = fxToken.Params.Circulation; var xferAmount = circulation / 3; await AssertHg.TokenNotAssociatedAsync(fxToken, fxAccount); var tex = await Assert.ThrowsAsync <TransactionException>(async() => { await fxToken.Client.SuspendTokenAsync(fxToken.Record.Token, fxAccount); }); Assert.Equal(ResponseCode.InvalidSignature, tex.Status); Assert.StartsWith("Unable to Suspend Token, status: InvalidSignature", tex.Message); await AssertHg.TokenNotAssociatedAsync(fxToken, fxAccount); }
public async Task CanAssociateMultipleTokensWithAccount() { await using var fxAccount = await TestAccount.CreateAsync(_network); await using var fxToken1 = await TestToken.CreateAsync(_network); await using var fxToken2 = await TestToken.CreateAsync(_network); var tokens = new Address[] { fxToken1.Record.Token, fxToken2.Record.Token }; await AssertHg.TokenNotAssociatedAsync(fxToken1, fxAccount); await AssertHg.TokenNotAssociatedAsync(fxToken2, fxAccount); var receipt = await fxAccount.Client.AssociateTokensAsync(tokens, fxAccount.Record.Address, fxAccount.PrivateKey); Assert.Equal(ResponseCode.Success, receipt.Status); var association = await AssertHg.TokenIsAssociatedAsync(fxToken1, fxAccount); Assert.Equal(fxToken1.Record.Token, association.Token); Assert.Equal(fxToken1.Params.Symbol, association.Symbol); Assert.Equal(0UL, association.Balance); Assert.Equal(TokenKycStatus.Revoked, association.KycStatus); Assert.Equal(TokenTradableStatus.Tradable, association.TradableStatus); association = await AssertHg.TokenIsAssociatedAsync(fxToken2, fxAccount); Assert.Equal(fxToken2.Record.Token, association.Token); Assert.Equal(fxToken2.Params.Symbol, association.Symbol); Assert.Equal(0UL, association.Balance); Assert.Equal(TokenKycStatus.Revoked, association.KycStatus); Assert.Equal(TokenTradableStatus.Tradable, association.TradableStatus); }
public async Task CanDissociateTokenFromAliasAccountDefect() { // Disassociating a token from 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>(CanDissociateTokenFromAliasAccount)); Assert.StartsWith("Unable to Dissociate Token from Account, status: InvalidAccountId", testFailException.Message); //[Fact(DisplayName = "Dissociate Tokens: Can Dissociate token from Alias Account")] async Task CanDissociateTokenFromAliasAccount() { 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 association = await AssertHg.TokenIsAssociatedAsync(fxToken, fxAccount); Assert.Equal(fxToken.Record.Token, association.Token); Assert.Equal(fxToken.Params.Symbol, association.Symbol); Assert.Equal(0UL, association.Balance); Assert.Equal(fxToken.Params.Decimals, association.Decimals); Assert.Equal(TokenKycStatus.Revoked, association.KycStatus); Assert.Equal(TokenTradableStatus.Tradable, association.TradableStatus); Assert.False(association.AutoAssociated); var receipt = await fxAccount.Client.DissociateTokenAsync(fxToken.Record.Token, fxAccount.Alias, fxAccount.PrivateKey); Assert.Equal(ResponseCode.Success, receipt.Status); await AssertHg.TokenNotAssociatedAsync(fxToken, fxAccount); } }
public async Task CanDissociateTokenFromAccountAndGetRecord() { await using var fxAccount = await TestAccount.CreateAsync(_network); await using var fxToken = await TestToken.CreateAsync(_network, null, fxAccount); var association = await AssertHg.TokenIsAssociatedAsync(fxToken, fxAccount); Assert.Equal(fxToken.Record.Token, association.Token); Assert.Equal(fxToken.Params.Symbol, association.Symbol); Assert.Equal(0UL, association.Balance); Assert.Equal(fxToken.Params.Decimals, association.Decimals); Assert.Equal(TokenKycStatus.Revoked, association.KycStatus); Assert.Equal(TokenTradableStatus.Tradable, association.TradableStatus); Assert.False(association.AutoAssociated); var record = await fxAccount.Client.DissociateTokenWithRecordAsync(fxToken.Record.Token, fxAccount.Record.Address, fxAccount.PrivateKey); Assert.Equal(ResponseCode.Success, record.Status); 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.TokenNotAssociatedAsync(fxToken, fxAccount); }
public async Task CanDissociateTokenFromAccountNoExtraSignatory() { await using var fxAccount = await TestAccount.CreateAsync(_network, fx => fx.CreateParams.InitialBalance = 120_00_000_000); await using var fxToken = await TestToken.CreateAsync(_network, null, fxAccount); var association = await AssertHg.TokenIsAssociatedAsync(fxToken, fxAccount); Assert.Equal(fxToken.Record.Token, association.Token); Assert.Equal(fxToken.Params.Symbol, association.Symbol); Assert.Equal(0UL, association.Balance); Assert.Equal(fxToken.Params.Decimals, association.Decimals); Assert.Equal(TokenKycStatus.Revoked, association.KycStatus); Assert.Equal(TokenTradableStatus.Tradable, association.TradableStatus); Assert.False(association.AutoAssociated); var receipt = await fxAccount.Client.DissociateTokenAsync(fxToken.Record.Token, fxAccount.Record.Address, ctx => { ctx.Payer = fxAccount.Record.Address; ctx.Signatory = fxAccount.PrivateKey; }); Assert.Equal(ResponseCode.Success, receipt.Status); await AssertHg.TokenNotAssociatedAsync(fxToken, fxAccount); }
public async Task CanDissociateMultipleTokensWithAccountAndGetRecordNoExtraSignatory() { await using var fxAccount = await TestAccount.CreateAsync(_network, fx => fx.CreateParams.InitialBalance = 120_00_000_000); await using var fxToken1 = await TestToken.CreateAsync(_network, null, fxAccount); await using var fxToken2 = await TestToken.CreateAsync(_network, null, fxAccount); var tokens = new Address[] { fxToken1.Record.Token, fxToken2.Record.Token }; await AssertHg.TokenIsAssociatedAsync(fxToken1, fxAccount); await AssertHg.TokenIsAssociatedAsync(fxToken2, fxAccount); var record = await fxAccount.Client.DissociateTokensWithRecordAsync(tokens, fxAccount.Record.Address, ctx => { ctx.Payer = fxAccount.Record.Address; ctx.Signatory = fxAccount.PrivateKey; }); Assert.Equal(ResponseCode.Success, record.Status); 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(fxAccount.Record.Address, record.Id.Address); await AssertHg.TokenNotAssociatedAsync(fxToken1, fxAccount); await AssertHg.TokenNotAssociatedAsync(fxToken2, fxAccount); }
public async Task CanNotScheduleAssociateTokenWithAccount() { await using var fxPayer = await TestAccount.CreateAsync(_network); await using var fxAccount = await TestAccount.CreateAsync(_network); await using var fxToken = await TestToken.CreateAsync(_network); await AssertHg.TokenNotAssociatedAsync(fxToken, fxAccount); var tex = await Assert.ThrowsAsync <TransactionException>(async() => { await fxAccount.Client.AssociateTokenAsync( fxToken.Record.Token, fxAccount.Record.Address, new Signatory( fxAccount.PrivateKey, new PendingParams { PendingPayer = fxPayer })); }); Assert.Equal(ResponseCode.ScheduledTransactionNotInWhitelist, tex.Status); Assert.StartsWith("Unable to schedule transaction, status: ScheduledTransactionNotInWhitelist", tex.Message); }
public async Task CanLimitTokenAutoAssociation() { await using var fxAccount = await TestAccount.CreateAsync(_network, fx => fx.CreateParams.AutoAssociationLimit = 1); await using var fxToken1 = await TestToken.CreateAsync(_network, fx => fx.Params.GrantKycEndorsement = null); await using var fxToken2 = await TestToken.CreateAsync(_network, fx => fx.Params.GrantKycEndorsement = null); await AssertHg.TokenNotAssociatedAsync(fxToken1, fxAccount); await AssertHg.TokenNotAssociatedAsync(fxToken2, fxAccount); var xferAmount1 = fxToken1.Params.Circulation / 2; var receipt = await fxToken1.Client.TransferTokensAsync(fxToken1, fxToken1.TreasuryAccount, fxAccount, (long)xferAmount1, fxToken1.TreasuryAccount); Assert.Equal(ResponseCode.Success, receipt.Status); var tex = await Assert.ThrowsAsync <TransactionException>(async() => { var xferAmount2 = fxToken2.Params.Circulation / 2; var receipt2 = await fxToken2.Client.TransferTokensAsync(fxToken2, fxToken2.TreasuryAccount, fxAccount, (long)xferAmount2, fxToken2.TreasuryAccount); }); Assert.Equal(ResponseCode.NoRemainingAutomaticAssociations, tex.Status); Assert.StartsWith("Unable to execute transfers, status: NoRemainingAutomaticAssociations", tex.Message); await AssertHg.TokenIsAssociatedAsync(fxToken1, fxAccount); await AssertHg.TokenNotAssociatedAsync(fxToken2, fxAccount); await AssertHg.TokenBalanceAsync(fxToken1, fxAccount, xferAmount1); }
public async Task GrantTokenCoinsRequiresGrantKeySignature() { await using var fxAccount = await TestAccount.CreateAsync(_network); await using var fxToken = await TestToken.CreateAsync(_network); await AssertHg.TokenNotAssociatedAsync(fxToken, fxAccount); var tex = await Assert.ThrowsAsync <TransactionException>(async() => { await fxToken.Client.GrantTokenKycAsync(fxToken.Record.Token, fxAccount); }); Assert.Equal(ResponseCode.InvalidSignature, tex.Status); Assert.StartsWith("Unable to Grant Token, status: InvalidSignature", tex.Message); }
public async Task AssociationRequiresSigningByTargetAccount() { await using var fxAccount = await TestAccount.CreateAsync(_network); await using var fxToken = await TestToken.CreateAsync(_network); await AssertHg.TokenNotAssociatedAsync(fxToken, fxAccount); var tex = await Assert.ThrowsAsync <TransactionException>(async() => { await fxAccount.Client.AssociateTokenAsync(fxToken.Record.Token, fxAccount.Record.Address); }); Assert.Equal(ResponseCode.InvalidSignature, tex.Status); Assert.StartsWith("Unable to associate Token with Account, status: InvalidSignature", tex.Message); await AssertHg.TokenNotAssociatedAsync(fxToken, fxAccount); }
public async Task NoTokenAutoAssociationResultsInError() { await using var fxAccount = await TestAccount.CreateAsync(_network, fx => fx.CreateParams.AutoAssociationLimit = 0); await using var fxToken = await TestToken.CreateAsync(_network, fx => fx.Params.GrantKycEndorsement = null); await AssertHg.TokenNotAssociatedAsync(fxToken, fxAccount); var tex = await Assert.ThrowsAsync <TransactionException>(async() => { var xferAmount2 = fxToken.Params.Circulation / 2; await fxToken.Client.TransferTokensAsync(fxToken, fxToken.TreasuryAccount, fxAccount, (long)xferAmount2, fxToken.TreasuryAccount); }); Assert.Equal(ResponseCode.TokenNotAssociatedToAccount, tex.Status); Assert.StartsWith("Unable to execute transfers, status: TokenNotAssociatedToAccount", tex.Message); await AssertHg.TokenNotAssociatedAsync(fxToken, fxAccount); }
public async Task NoTokenBalanceRecordExistsWhenNotAssociated() { await using var fxAccount = await TestAccount.CreateAsync(_network); await using var fxToken = await TestToken.CreateAsync(_network); await AssertHg.TokenNotAssociatedAsync(fxToken, fxAccount); var receipt = await fxAccount.Client.AssociateTokenAsync(fxToken.Record.Token, fxAccount.Record.Address, fxAccount.PrivateKey); Assert.Equal(ResponseCode.Success, receipt.Status); var association = await AssertHg.TokenIsAssociatedAsync(fxToken, fxAccount); Assert.Equal(fxToken.Record.Token, association.Token); Assert.Equal(fxToken.Params.Symbol, association.Symbol); Assert.Equal(0UL, association.Balance); Assert.Equal(TokenKycStatus.Revoked, association.KycStatus); Assert.Equal(TokenTradableStatus.Tradable, association.TradableStatus); }
public async Task CanAssociateMultipleTokensWithAccountNoExtraSignatory() { await using var fxAccount = await TestAccount.CreateAsync(_network, fx => fx.CreateParams.InitialBalance = 120_00_000_000); await using var fxToken1 = await TestToken.CreateAsync(_network); await using var fxToken2 = await TestToken.CreateAsync(_network); var tokens = new Address[] { fxToken1.Record.Token, fxToken2.Record.Token }; await AssertHg.TokenNotAssociatedAsync(fxToken1, fxAccount); await AssertHg.TokenNotAssociatedAsync(fxToken2, fxAccount); var receipt = await fxAccount.Client.AssociateTokensAsync(tokens, fxAccount.Record.Address, ctx => { ctx.Payer = fxAccount.Record.Address; ctx.Signatory = fxAccount.PrivateKey; }); Assert.Equal(ResponseCode.Success, receipt.Status); var association = await AssertHg.TokenIsAssociatedAsync(fxToken1, fxAccount); Assert.Equal(fxToken1.Record.Token, association.Token); Assert.Equal(fxToken1.Params.Symbol, association.Symbol); Assert.Equal(0UL, association.Balance); Assert.Equal(fxToken1.Params.Decimals, association.Decimals); Assert.Equal(TokenKycStatus.Revoked, association.KycStatus); Assert.Equal(TokenTradableStatus.Tradable, association.TradableStatus); association = await AssertHg.TokenIsAssociatedAsync(fxToken2, fxAccount); Assert.Equal(fxToken2.Record.Token, association.Token); Assert.Equal(fxToken2.Params.Symbol, association.Symbol); Assert.Equal(0UL, association.Balance); Assert.Equal(fxToken2.Params.Decimals, association.Decimals); Assert.Equal(TokenKycStatus.Revoked, association.KycStatus); Assert.Equal(TokenTradableStatus.Tradable, association.TradableStatus); }
public async Task CanDissociateMultipleTokensWithAccount() { await using var fxAccount = await TestAccount.CreateAsync(_network); await using var fxToken1 = await TestToken.CreateAsync(_network, null, fxAccount); await using var fxToken2 = await TestToken.CreateAsync(_network, null, fxAccount); var tokens = new Address[] { fxToken1.Record.Token, fxToken2.Record.Token }; await AssertHg.TokenIsAssociatedAsync(fxToken1, fxAccount); await AssertHg.TokenIsAssociatedAsync(fxToken2, fxAccount); var receipt = await fxAccount.Client.DissociateTokensAsync(tokens, fxAccount.Record.Address, fxAccount.PrivateKey); Assert.Equal(ResponseCode.Success, receipt.Status); await AssertHg.TokenNotAssociatedAsync(fxToken1, fxAccount); await AssertHg.TokenNotAssociatedAsync(fxToken2, fxAccount); }
public async Task CanRaiseLimitTokenAutoAssociation() { await using var fxAccount = await TestAccount.CreateAsync(_network, fx => fx.CreateParams.AutoAssociationLimit = 1); await using var fxToken1 = await TestToken.CreateAsync(_network, fx => fx.Params.GrantKycEndorsement = null); await using var fxToken2 = await TestToken.CreateAsync(_network, fx => fx.Params.GrantKycEndorsement = null); await AssertHg.TokenNotAssociatedAsync(fxToken1, fxAccount); await AssertHg.TokenNotAssociatedAsync(fxToken2, fxAccount); var xferAmount1 = fxToken1.Params.Circulation / 2; var receipt = await fxToken1.Client.TransferTokensAsync(fxToken1, fxToken1.TreasuryAccount, fxAccount, (long)xferAmount1, fxToken1.TreasuryAccount); Assert.Equal(ResponseCode.Success, receipt.Status); await fxAccount.Client.UpdateAccountAsync(new UpdateAccountParams { Address = fxAccount, AutoAssociationLimit = 2, Signatory = fxAccount }); var xferAmount2 = fxToken2.Params.Circulation / 2; var receipt2 = await fxToken2.Client.TransferTokensAsync(fxToken2, fxToken2.TreasuryAccount, fxAccount, (long)xferAmount2, fxToken2.TreasuryAccount); Assert.Equal(ResponseCode.Success, receipt2.Status); await AssertHg.TokenIsAssociatedAsync(fxToken1, fxAccount); await AssertHg.TokenIsAssociatedAsync(fxToken2, fxAccount); await AssertHg.TokenBalanceAsync(fxToken1, fxAccount, xferAmount1); await AssertHg.TokenBalanceAsync(fxToken2, fxAccount, xferAmount2); }
public async Task CanAutoAssociateTokenWithAccount() { await using var fxAccount = await TestAccount.CreateAsync(_network); await using var fxToken = await TestToken.CreateAsync(_network, fx => fx.Params.GrantKycEndorsement = null); await AssertHg.TokenNotAssociatedAsync(fxToken, fxAccount); var xferAmount = fxToken.Params.Circulation / 2; var receipt = await fxToken.Client.TransferTokensAsync(fxToken, fxToken.TreasuryAccount, fxAccount, (long)xferAmount, fxToken.TreasuryAccount); Assert.Equal(ResponseCode.Success, receipt.Status); var association = await AssertHg.TokenIsAssociatedAsync(fxToken, fxAccount); Assert.Equal(fxToken.Record.Token, association.Token); Assert.Equal(fxToken.Params.Symbol, association.Symbol); Assert.Equal(xferAmount, association.Balance); Assert.Equal(fxToken.Params.Decimals, association.Decimals); Assert.Equal(TokenKycStatus.NotApplicable, association.KycStatus); Assert.Equal(TokenTradableStatus.Tradable, association.TradableStatus); Assert.True(association.AutoAssociated); var info = await fxAccount.Client.GetAccountInfoAsync(fxAccount); Assert.Equal(fxAccount.CreateParams.AutoAssociationLimit, info.AutoAssociationLimit); Assert.Single(info.Tokens); var balance = info.Tokens[0]; Assert.Equal(fxToken.Record.Token, balance.Token); Assert.Equal(fxToken.Params.Symbol, balance.Symbol); Assert.Equal(TokenKycStatus.NotApplicable, balance.KycStatus); Assert.Equal(TokenTradableStatus.Tradable, balance.TradableStatus); Assert.True(balance.AutoAssociated); }