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

            var transferAmount = (long)Generator.Integer(10, 100);
            var newBalance     = await fx.Client.GetAccountBalanceAsync(fx.Record.Address);

            Assert.Equal(fx.CreateParams.InitialBalance, newBalance);

            var record = await fx.Client.TransferWithRecordAsync(_network.Payer, fx.Record.Address, transferAmount);

            Assert.Equal(ResponseCode.Success, record.Status);
            Assert.Equal(4, record.Transfers.Count);
            Assert.Equal(-transferAmount - (long)record.Fee, record.Transfers[_network.Payer]);
            Assert.Equal(transferAmount, record.Transfers[fx.Record.Address]);
            Assert.Empty(record.TokenTransfers);

            var newBalanceAfterTransfer = await fx.Client.GetAccountBalanceAsync(fx.Record.Address);

            Assert.Equal(fx.CreateParams.InitialBalance + (ulong)transferAmount, newBalanceAfterTransfer);
        }
예제 #2
0
        public async Task CanUpdateTreasury()
        {
            await using var fxAccount = await TestAccount.CreateAsync(_network);

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

            var updateParams = new UpdateTokenParams
            {
                Token     = fxToken.Record.Token,
                Treasury  = fxAccount.Record.Address,
                Signatory = new Signatory(fxToken.AdminPrivateKey, fxAccount.PrivateKey)
            };

            var receipt = await fxToken.Client.UpdateTokenAsync(updateParams);

            Assert.Equal(ResponseCode.Success, receipt.Status);

            var info = await fxToken.Client.GetTokenInfoAsync(fxToken.Record.Token);

            Assert.Equal(fxAccount.Record.Address, info.Treasury);
        }
예제 #3
0
    public async Task CantUpdateAutoAssociateValueToGreatherThanOneThousand()
    {
        await using var fxAccount = await TestAccount.CreateAsync(_network);

        var ex = await Assert.ThrowsAsync <ArgumentOutOfRangeException>(async() =>
        {
            var record = await fxAccount.Client.UpdateAccountWithRecordAsync(new UpdateAccountParams
            {
                Address = fxAccount,
                AutoAssociationLimit = 1001,
                Signatory            = fxAccount
            });
        });

        Assert.Equal("AutoAssociationLimit", ex.ParamName);
        Assert.StartsWith("The maximum number of auto-associaitons must be between zero and 1000.", ex.Message);

        var info = await fxAccount.Client.GetAccountInfoAsync(fxAccount);

        Assert.Equal(fxAccount.CreateParams.AutoAssociationLimit, info.AutoAssociationLimit);
    }
예제 #4
0
        public async Task NoTokenBalanceRecordExistsWhenDissociated()
        {
            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);

            var receipt = await fxAccount.Client.DissociateTokenAsync(fxToken.Record.Token, fxAccount.Record.Address, fxAccount.PrivateKey);

            Assert.Equal(ResponseCode.Success, receipt.Status);

            await AssertHg.TokenNotAssociatedAsync(fxToken, fxAccount);
        }
예제 #5
0
        public async Task CanUpdateProxyStake()
        {
            var fx = await TestAccount.CreateAsync(_network);

            var originalInfo = await fx.Client.GetAccountInfoAsync(fx.Record.Address);

            Assert.Equal(new Address(0, 0, 0), originalInfo.Proxy);

            var updateResult = await fx.Client.UpdateAccountAsync(new UpdateAccountParams
            {
                Address   = fx.Record.Address,
                Signatory = fx.PrivateKey,
                Proxy     = _network.Gateway
            });

            Assert.Equal(ResponseCode.Success, updateResult.Status);

            var updatedInfo = await fx.Client.GetAccountInfoAsync(fx.Record.Address);

            Assert.Equal(_network.Gateway, updatedInfo.Proxy);
        }
예제 #6
0
        public async Task CanCreateAClaimAsync()
        {
            await using var test = await TestAccount.CreateAsync(_network);

            var(publicKey1, privateKey1) = Generator.KeyPair();
            var(publicKey2, privateKey2) = Generator.KeyPair();
            var claim = new Claim
            {
                Address       = test.Record.Address,
                Hash          = Generator.SHA384Hash(),
                Endorsements  = new Endorsement[] { publicKey1, publicKey2 },
                ClaimDuration = TimeSpan.FromDays(Generator.Integer(10, 20))
            };

            var receipt = await test.Client.AddClaimAsync(claim, ctx =>
            {
                ctx.Payer = _network.PayerWithKeys(privateKey1, privateKey2);
            });

            Assert.Equal(ResponseCode.Success, receipt.Status);
        }
예제 #7
0
    public async Task CanNotScheduleADeleteFile()
    {
        await using var fxPayer = await TestAccount.CreateAsync(_network, fx => fx.CreateParams.InitialBalance = 20_00_000_000);

        await using var fxFile = await TestFile.CreateAsync(_network);

        var tex = await Assert.ThrowsAsync <TransactionException>(async() =>
        {
            await fxFile.Client.DeleteFileAsync(
                fxFile.Record.File,
                new Signatory(
                    fxFile.PrivateKey,
                    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 CanMultiTransferCryptoToNewAccount()
        {
            await using var fx = await TestAccount.CreateAsync(_network);

            var transferAmount = (long)Generator.Integer(10, 100);
            var newBalance     = await fx.Client.GetAccountBalanceAsync(fx.Record.Address);

            Assert.Equal(fx.CreateParams.InitialBalance, newBalance);

            var transfers = new TransferParams
            {
                CryptoTransfers = new Dictionary <Address, long> {
                    { _network.Payer, -transferAmount }, { fx.Record.Address, transferAmount }
                }
            };
            var receipt = await fx.Client.TransferAsync(transfers);

            var newBalanceAfterTransfer = await fx.Client.GetAccountBalanceAsync(fx.Record.Address);

            Assert.Equal(fx.CreateParams.InitialBalance + (ulong)transferAmount, newBalanceAfterTransfer);
        }
예제 #9
0
    public async Task CanConfiscateAnAssetGetRecord()
    {
        await using var fxAccount = await TestAccount.CreateAsync(_network);

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

        var initialCirculation      = (ulong)fxAsset.Metadata.Length;
        var xferAmount              = 2ul;
        var expectedTreasury        = initialCirculation - xferAmount;
        var serialNumbersTransfered = Enumerable.Range(1, 2).Select(i => (long)i);

        var transferParams = new TransferParams
        {
            AssetTransfers = serialNumbersTransfered.Select(sn => new AssetTransfer(new Asset(fxAsset.Record.Token, sn), fxAsset.TreasuryAccount, fxAccount)),
            Signatory      = fxAsset.TreasuryAccount
        };

        await fxAsset.Client.TransferAsync(transferParams);

        Assert.Equal(xferAmount, await fxAccount.Client.GetAccountTokenBalanceAsync(fxAccount, fxAsset));
        Assert.Equal(expectedTreasury, await fxAccount.Client.GetAccountTokenBalanceAsync(fxAsset.TreasuryAccount, fxAsset));
        Assert.Equal(initialCirculation, (await fxAsset.Client.GetTokenInfoAsync(fxAsset)).Circulation);

        var record = await fxAsset.Client.ConfiscateAssetWithRecordAsync(new Asset(fxAsset.Record.Token, 1), fxAccount, fxAsset.ConfiscatePrivateKey);

        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);
        Assert.Equal(initialCirculation - 1, record.Circulation);
        Assert.Equal(1ul, await fxAccount.Client.GetAccountTokenBalanceAsync(fxAccount, fxAsset));
        Assert.Equal(expectedTreasury, await fxAccount.Client.GetAccountTokenBalanceAsync(fxAsset.TreasuryAccount, fxAsset));
        Assert.Equal(initialCirculation - 1, (await fxAsset.Client.GetTokenInfoAsync(fxAsset)).Circulation);
        Assert.Null(record.ParentTransactionConcensus);
    }
예제 #10
0
        public async Task CanExecuteMultiTransferTokensAndCrypto()
        {
            await using var fxAccount1 = await TestAccount.CreateAsync(_network);

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

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

            var tokenAmount      = fxToken.Params.Circulation / 3;
            var expectedTreasury = fxToken.Params.Circulation - 2 * tokenAmount;
            var cryptoAmount     = (long)Generator.Integer(100, 200);
            var transfers        = new TransferParams
            {
                CryptoTransfers = new Dictionary <Address, long>
                {
                    { _network.Payer, -2 * cryptoAmount },
                    { fxAccount1, cryptoAmount },
                    { fxAccount2, cryptoAmount }
                },
                TokenTransfers = new TokenTransfer[]
                {
                    new TokenTransfer(fxToken, fxAccount1, (long)tokenAmount),
                    new TokenTransfer(fxToken, fxAccount2, (long)tokenAmount),
                    new TokenTransfer(fxToken, fxToken.TreasuryAccount, -2 * (long)tokenAmount)
                },
                Signatory = new Signatory(_network.Signatory, fxToken.TreasuryAccount.PrivateKey)
            };
            var receipt = await fxToken.Client.TransferAsync(transfers);

            Assert.Equal(ResponseCode.Success, receipt.Status);
            Assert.NotNull(receipt.CurrentExchangeRate);
            Assert.NotNull(receipt.NextExchangeRate);
            Assert.Equal(_network.Payer, receipt.Id.Address);

            Assert.Equal(fxAccount1.CreateParams.InitialBalance + (ulong)cryptoAmount, await fxAccount1.Client.GetAccountBalanceAsync(fxAccount1));
            Assert.Equal(fxAccount2.CreateParams.InitialBalance + (ulong)cryptoAmount, await fxAccount2.Client.GetAccountBalanceAsync(fxAccount2));
            Assert.Equal(tokenAmount, await fxAccount1.Client.GetAccountTokenBalanceAsync(fxAccount1, fxToken));
            Assert.Equal(tokenAmount, await fxAccount2.Client.GetAccountTokenBalanceAsync(fxAccount2, fxToken));
            Assert.Equal(expectedTreasury, await fxToken.Client.GetAccountTokenBalanceAsync(fxToken.TreasuryAccount, fxToken));
        }
예제 #11
0
    public async Task CannotConfiscateWhenNoConfiscationEndorsement()
    {
        await using var fxAccount = await TestAccount.CreateAsync(_network);

        await using var fxAsset = await TestAsset.CreateAsync(_network, fx =>
        {
            fx.Params.GrantKycEndorsement   = null;
            fx.Params.ConfiscateEndorsement = null;
        }, fxAccount);

        var initialCirculation      = (ulong)fxAsset.Metadata.Length;
        var xferAmount              = 2ul;
        var expectedTreasury        = initialCirculation - xferAmount;
        var serialNumbersTransfered = Enumerable.Range(1, 2).Select(i => (long)i);

        var transferParams = new TransferParams
        {
            AssetTransfers = serialNumbersTransfered.Select(sn => new AssetTransfer(new Asset(fxAsset.Record.Token, sn), fxAsset.TreasuryAccount, fxAccount)),
            Signatory      = fxAsset.TreasuryAccount
        };

        await fxAsset.Client.TransferAsync(transferParams);

        Assert.Equal(xferAmount, await fxAccount.Client.GetAccountTokenBalanceAsync(fxAccount, fxAsset));
        Assert.Equal(expectedTreasury, await fxAccount.Client.GetAccountTokenBalanceAsync(fxAsset.TreasuryAccount, fxAsset));
        Assert.Equal(initialCirculation, (await fxAsset.Client.GetTokenInfoAsync(fxAsset)).Circulation);

        var tex = await Assert.ThrowsAsync <TransactionException>(async() =>
        {
            await fxAsset.Client.ConfiscateAssetAsync(new Asset(fxAsset, 1), fxAccount, fxAsset.ConfiscatePrivateKey);
        });

        Assert.Equal(ResponseCode.TokenHasNoWipeKey, tex.Status);
        Assert.Equal(ResponseCode.TokenHasNoWipeKey, tex.Receipt.Status);
        Assert.StartsWith("Unable to Confiscate Token, status: TokenHasNoWipeKey", tex.Message);

        Assert.Equal(xferAmount, await fxAccount.Client.GetAccountTokenBalanceAsync(fxAccount, fxAsset));
        Assert.Equal(expectedTreasury, await fxAccount.Client.GetAccountTokenBalanceAsync(fxAsset.TreasuryAccount, fxAsset));
        Assert.Equal(initialCirculation, (await fxAsset.Client.GetTokenInfoAsync(fxAsset)).Circulation);
    }
예제 #12
0
        public async Task CanUpdateMultiplePropertiesAtOnce()
        {
            await using var fxAccount = await TestAccount.CreateAsync(_network);

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

            var record = await fxAccount.Client.UpdateAccountWithRecordAsync(new UpdateAccountParams
            {
                Address                 = fxAccount,
                Signatory               = new Signatory(fxAccount, fxTempate),
                Endorsement             = fxTempate.CreateParams.Endorsement,
                RequireReceiveSignature = fxTempate.CreateParams.RequireReceiveSignature,
                Proxy = fxTempate,
                Memo  = fxTempate.CreateParams.Memo
            });

            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);

            var info = await fxAccount.Client.GetAccountInfoAsync(fxAccount);

            Assert.Equal(fxAccount.Record.Address, info.Address);
            Assert.NotNull(info.SmartContractId);
            Assert.False(info.Deleted);
            Assert.Equal(fxTempate.Record.Address, info.Proxy);
            Assert.Equal(0, info.ProxiedToAccount);
            Assert.Equal(fxTempate.PublicKey, info.Endorsement);
            Assert.Equal(fxAccount.CreateParams.InitialBalance, info.Balance);
            Assert.Equal(fxTempate.CreateParams.RequireReceiveSignature, info.ReceiveSignatureRequired);
            Assert.True(info.AutoRenewPeriod.TotalSeconds > 0);
            Assert.True(info.Expiration > DateTime.MinValue);
            Assert.Equal(fxTempate.CreateParams.Memo, info.Memo);
        }
예제 #13
0
        public async Task CanScheduleCreateAccount()
        {
            // Not whitelisted on testnet.
            var tex = await Assert.ThrowsAsync <TransactionException>(async() =>
            {
                await using var fxPayer = await TestAccount.CreateAsync(_network, fx => fx.CreateParams.InitialBalance = 20_00_000_000);

                var fxAccount = await TestAccount.CreateAsync(_network, fx =>
                {
                    fx.CreateParams.Signatory = new PendingParams
                    {
                        PendingPayer = fxPayer
                    };
                });

                // When this is whitelisted, the fillowing should pass.
                var transactionReceipt = await fxPayer.Client.SignPendingTransactionAsync(fxAccount.Record.Pending.Id, fxPayer);
                var pendingReceipt     = await fxPayer.Client.GetReceiptAsync(fxAccount.Record.Pending.TxId);
                Assert.Equal(ResponseCode.Success, pendingReceipt.Status);

                var createReceipt = Assert.IsType <CreateAccountReceipt>(pendingReceipt);
                var account       = createReceipt.Address;

                var info = await fxPayer.Client.GetAccountInfoAsync(account);
                Assert.Equal(account, info.Address);
                Assert.NotNull(info.SmartContractId);
                Assert.False(info.Deleted);
                Assert.NotNull(info.Proxy);
                Assert.Equal(Address.None, info.Proxy);
                Assert.Equal(0, info.ProxiedToAccount);
                Assert.Equal(fxAccount.CreateParams.Endorsement, info.Endorsement);
                Assert.Equal(fxAccount.CreateParams.InitialBalance, info.Balance);
                Assert.Equal(fxAccount.CreateParams.RequireReceiveSignature, info.ReceiveSignatureRequired);
                Assert.Equal(fxAccount.CreateParams.AutoRenewPeriod.TotalSeconds, info.AutoRenewPeriod.TotalSeconds);
                Assert.True(info.Expiration > DateTime.MinValue);
            });

            Assert.Equal(ResponseCode.ScheduledTransactionNotInWhitelist, tex.Status);
            Assert.StartsWith("Unable to schedule transaction, status: ScheduledTransactionNotInWhitelist", tex.Message);
        }
예제 #14
0
    public async Task ResumeAssetRequiresSuspendKeyToSignTransaction()
    {
        await using var fxAccount = await TestAccount.CreateAsync(_network);

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

        var circulation = fxAsset.Metadata.Length;
        var xferAmount  = circulation / 3;

        await AssertHg.AssetStatusAsync(fxAsset, fxAccount, TokenTradableStatus.Suspended);

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

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

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

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

        tex = await Assert.ThrowsAsync <TransactionException>(async() =>
        {
            await fxAsset.Client.TransferAssetAsync(new Asset(fxAsset, 1), fxAsset.TreasuryAccount, fxAccount, fxAsset.TreasuryAccount);
        });

        Assert.Equal(ResponseCode.AccountFrozenForToken, tex.Status);
        Assert.Equal(ResponseCode.AccountFrozenForToken, tex.Receipt.Status);
        Assert.StartsWith("Unable to execute transfers, status: AccountFrozenForToken", tex.Message);
    }
예제 #15
0
        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);
        }
예제 #16
0
        public async Task CanNotScheduleCallContract()
        {
            await using var fxPayer = await TestAccount.CreateAsync(_network, fx => fx.CreateParams.InitialBalance = 20_00_000_000);

            await using var fxContract = await StatefulContract.CreateAsync(_network);

            var tex = await Assert.ThrowsAsync <TransactionException>(async() =>
            {
                await fxContract.Client.CallContractWithRecordAsync(new CallContractParams
                {
                    Contract     = fxContract.ContractRecord.Contract,
                    Gas          = await _network.TinybarsFromGas(400),
                    FunctionName = "get_message",
                    Signatory    = new PendingParams {
                        PendingPayer = fxPayer
                    }
                });
            });

            Assert.Equal(ResponseCode.ScheduledTransactionNotInWhitelist, tex.Status);
            Assert.StartsWith("Unable to schedule transaction, status: ScheduledTransactionNotInWhitelist", tex.Message);
        }
예제 #17
0
    public async Task CanRevokeTokensAndGetRecord()
    {
        await using var fxAccount = await TestAccount.CreateAsync(_network);

        await using var fxAsset = await TestAsset.CreateAsync(_network, null, fxAccount);

        var circulation = (ulong)fxAsset.Metadata.Length;

        await AssertHg.AssetStatusAsync(fxAsset, fxAccount, TokenKycStatus.Revoked);

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

        await AssertHg.AssetStatusAsync(fxAsset, fxAccount, TokenKycStatus.Granted);

        await fxAsset.Client.TransferAssetAsync(new Asset(fxAsset, 1), fxAsset.TreasuryAccount, fxAccount, fxAsset.TreasuryAccount);

        var record = await fxAsset.Client.RevokeTokenKycWithRecordAsync(fxAsset.Record.Token, fxAccount, fxAsset.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.AssetStatusAsync(fxAsset, fxAccount, TokenKycStatus.Revoked);

        var tex = await Assert.ThrowsAsync <TransactionException>(async() =>
        {
            await fxAsset.Client.TransferAssetAsync(new Asset(fxAsset, 2), fxAsset.TreasuryAccount, fxAccount, fxAsset.TreasuryAccount);
        });

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

            var(publicKey1, privateKey1) = Generator.KeyPair();
            var(publicKey2, privateKey2) = Generator.KeyPair();
            var claim = new Claim
            {
                Address       = test.Record.Address,
                Hash          = Generator.SHA384Hash(),
                Endorsements  = new Endorsement[] { publicKey1, publicKey2 },
                ClaimDuration = TimeSpan.FromDays(Generator.Integer(10, 20))
            };

            var exception = await Assert.ThrowsAsync <ArgumentNullException>(async() =>
            {
                await test.Client.GetClaimAsync(null, claim.Hash);
            });

            Assert.Equal("address", exception.ParamName);
            Assert.StartsWith("Account Address is missing. Please check that it is not null.", exception.Message);
        }
예제 #19
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);
        }
예제 #20
0
    public async Task CanGrantAssetCoinsFromWnyAccountWithGrantKey()
    {
        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 fxAsset = await TestAsset.CreateAsync(_network, null, fxAccount);

        await AssertHg.AssetStatusAsync(fxAsset, fxAccount, TokenKycStatus.Revoked);

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

        await AssertHg.AssetStatusAsync(fxAsset, fxAccount, TokenKycStatus.Granted);

        await fxAsset.Client.TransferAssetAsync(new Asset(fxAsset, 1), fxAsset.TreasuryAccount, fxAccount, fxAsset.TreasuryAccount);

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

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

            var tex = await Assert.ThrowsAsync <TransactionException>(async() =>
            {
                await fxToken.Client.MintTokenAsync(
                    fxToken.Record.Token,
                    fxToken.Params.Circulation,
                    new Signatory(
                        fxToken.SupplyPrivateKey,
                        new PendingParams
                {
                    PendingPayer = fxPayer
                }));
            });

            Assert.Equal(ResponseCode.ScheduledTransactionNotInWhitelist, tex.Status);
            Assert.StartsWith("Unable to schedule transaction, status: ScheduledTransactionNotInWhitelist", tex.Message);
        }
예제 #22
0
    public async Task DissociationRequiresAccount()
    {
        await using var fxAccount = await TestAccount.CreateAsync(_network);

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

        var ane = await Assert.ThrowsAsync <ArgumentNullException>(async() =>
        {
            await fxAccount.Client.DissociateTokenAsync(fxToken.Record.Token, null);
        });

        Assert.Equal("account", ane.ParamName);
        Assert.StartsWith("Account Address/Alias is missing. Please check that it is not null.", ane.Message);

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

        Assert.Equal(ResponseCode.InvalidAccountId, tex.Status);
        Assert.StartsWith("Unable to Dissociate Token from Account, status: InvalidAccountId", tex.Message);
    }
예제 #23
0
    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);
    }
예제 #24
0
    public async Task CanAssociateAssetWithAccount()
    {
        await using var fxAccount = await TestAccount.CreateAsync(_network);

        await using var fxAsset = await TestAsset.CreateAsync(_network, fx => fx.Metadata = null);

        await AssertHg.AssetNotAssociatedAsync(fxAsset, fxAccount);

        var receipt = await fxAccount.Client.AssociateTokenAsync(fxAsset.Record.Token, fxAccount.Record.Address, fxAccount.PrivateKey);

        Assert.Equal(ResponseCode.Success, receipt.Status);

        var association = await AssertHg.AssetIsAssociatedAsync(fxAsset, fxAccount);

        Assert.Equal(fxAsset.Record.Token, association.Token);
        Assert.Equal(fxAsset.Params.Symbol, association.Symbol);
        Assert.Equal(0UL, association.Balance);
        Assert.Equal(0UL, association.Decimals);
        Assert.Equal(TokenKycStatus.Revoked, association.KycStatus);
        Assert.Equal(TokenTradableStatus.Tradable, association.TradableStatus);
        Assert.False(association.AutoAssociated);
    }
예제 #25
0
    public async Task CanSendFromAliasAccount()
    {
        await using var fxAccount = await TestAccount.CreateAsync(_network);

        await using var fxAlias = await TestAliasAccount.CreateAsync(_network);

        var aliasStartingBalance = await fxAlias.Client.GetAccountBalanceAsync(fxAlias.Alias);

        var transferAmount = (aliasStartingBalance) / 2 + 1;

        var accountStartingBalance = await fxAlias.Client.GetAccountBalanceAsync(fxAccount);

        var receipt = await fxAlias.Client.TransferAsync(fxAlias.Alias, fxAccount.Record.Address, (long)transferAmount, fxAlias.PrivateKey);

        var accountEndingBalance = await fxAlias.Client.GetAccountBalanceAsync(fxAccount);

        Assert.Equal(accountStartingBalance + (ulong)transferAmount, accountEndingBalance);

        var aliasEndingBalance = await fxAlias.Client.GetAccountBalanceAsync(fxAlias.Alias);

        Assert.Equal(aliasStartingBalance - (ulong)transferAmount, aliasEndingBalance);
    }
예제 #26
0
    public async Task CanLowerLimitTokenAutoAssociation()
    {
        await using var fxAccount = await TestAccount.CreateAsync(_network, fx => fx.CreateParams.AutoAssociationLimit = 100);

        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 = 1,
            Signatory            = fxAccount
        });

        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);
    }
예제 #27
0
    public async Task CanConfiscateAnAssetFromAnyAccountWithConfiscateKey()
    {
        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 fxAsset = await TestAsset.CreateAsync(_network, fx => fx.Params.GrantKycEndorsement = null, fxAccount);


        var initialCirculation      = (ulong)fxAsset.Metadata.Length;
        var xferAmount              = 2ul;
        var expectedTreasury        = initialCirculation - xferAmount;
        var serialNumbersTransfered = Enumerable.Range(1, 2).Select(i => (long)i);

        var transferParams = new TransferParams
        {
            AssetTransfers = serialNumbersTransfered.Select(sn => new AssetTransfer(new Asset(fxAsset.Record.Token, sn), fxAsset.TreasuryAccount, fxAccount)),
            Signatory      = fxAsset.TreasuryAccount
        };

        await fxAsset.Client.TransferAsync(transferParams);

        Assert.Equal(xferAmount, await fxAccount.Client.GetAccountTokenBalanceAsync(fxAccount, fxAsset));
        Assert.Equal(expectedTreasury, await fxAccount.Client.GetAccountTokenBalanceAsync(fxAsset.TreasuryAccount, fxAsset));
        Assert.Equal(initialCirculation, (await fxAsset.Client.GetTokenInfoAsync(fxAsset)).Circulation);

        var receipt = await fxAsset.Client.ConfiscateAssetAsync(new Asset(fxAsset, 1), fxAccount, fxAsset.ConfiscatePrivateKey, ctx =>
        {
            ctx.Payer     = fxOther.Record.Address;
            ctx.Signatory = fxOther.PrivateKey;
        });

        Assert.Equal(ResponseCode.Success, receipt.Status);
        Assert.Equal(initialCirculation - 1, receipt.Circulation);

        Assert.Equal(1ul, await fxAccount.Client.GetAccountTokenBalanceAsync(fxAccount, fxAsset));
        Assert.Equal(expectedTreasury, await fxAccount.Client.GetAccountTokenBalanceAsync(fxAsset.TreasuryAccount, fxAsset));
        Assert.Equal(initialCirculation - 1, (await fxAsset.Client.GetTokenInfoAsync(fxAsset)).Circulation);
    }
예제 #28
0
    public async Task CanRevokeTokensAndGetRecordWithoutExtraSignatory()
    {
        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, 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.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);
    }
예제 #29
0
        public async Task AssociationRequiresAccount()
        {
            await using var fxAccount = await TestAccount.CreateAsync(_network);

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

            var ane = await Assert.ThrowsAsync <ArgumentNullException>(async() =>
            {
                await fxAccount.Client.AssociateTokenAsync(fxToken.Record.Token, null);
            });

            Assert.Equal("account", ane.ParamName);
            Assert.StartsWith("Account Address is missing. Please check that it is not null or empty", ane.Message);

            ane = await Assert.ThrowsAsync <ArgumentNullException>(async() =>
            {
                await fxAccount.Client.AssociateTokenAsync(fxToken.Record.Token, Address.None);
            });

            Assert.Equal("account", ane.ParamName);
            Assert.StartsWith("Account Address is missing. Please check that it is not null or empty", ane.Message);
        }
예제 #30
0
    public async Task CanCreateTokenWithFixedRoyalty()
    {
        await using var fxAccount = await TestAccount.CreateAsync(_network);

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

        await using var fxToken = await TestToken.CreateAsync(_network, fx =>
        {
            fx.Params.Royalties = new FixedRoyalty[]
            {
                new FixedRoyalty(fxAccount, comToken, 100)
            };
        }, fxAccount);

        Assert.Equal(ResponseCode.Success, fxToken.Record.Status);

        var info = await fxToken.Client.GetTokenInfoAsync(fxToken.Record.Token);

        Assert.Single(info.Royalties);

        Assert.Equal(fxToken.Params.Royalties.First(), info.Royalties[0]);
    }