Esempio n. 1
0
        private static Task <Member> CreateMember(TokenClient tokenClient)
        {
            // An alias is a human-readable way to identify a member, e.g., a domain or email address.
            // If a domain alias is used instead of an email, please contact Token
            // with the domain and member ID for verification.
            // See https://developer.token.io/sdk/#aliases for more information.
            var email = "ascsharp-" + Util.Nonce().ToLower() + "*****@*****.**";
            var alias = new Alias
            {
                Type  = Alias.Types.Type.Email,
                Value = email
            };

            return(tokenClient.CreateMember(alias)
                   .FlatMap(async(mem) =>
            {
                // A member's profile has a display name and picture.
                // The Token UI shows this (and the alias) to the user when requesting access.
                await mem.SetProfile(new Profile
                {
                    DisplayNameFirst = "Demo PFM"
                });
                byte[] pict = System.IO.File.ReadAllBytes(Path.Combine(rootLocation, "Content/southside.png"));
                await mem.SetProfilePicture("image/png", pict);

                return mem;
            }));
        }
Esempio n. 2
0
        public void RecoveryComplex()
        {
            using (Tokenio.Tpp.TokenClient tokenClient = TestUtil.CreateClient())
            {
                MemberRecoverySample mrs = new MemberRecoverySample();

                Tokenio.Tpp.TokenClient agentTokenIO = TestUtil.CreateClient();
                Alias     agentAlias  = TestUtil.RandomAlias();
                TppMember agentMember = agentTokenIO.CreateMemberBlocking(agentAlias);

                mrs.agentMember = agentMember;

                // set up
                Alias     originalAlias  = TestUtil.RandomAlias();
                TppMember originalMember = tokenClient.CreateMemberBlocking(originalAlias);
                mrs.SetUpComplexRecoveryRule(originalMember, tokenClient, agentAlias);

                // recover
                Tokenio.Tpp.TokenClient otherTokenClient = TestUtil.CreateClient();
                TppMember recoveredMember = mrs.RecoverWithComplexRule(
                    otherTokenClient,
                    originalAlias);
                // make sure it worked
                Alias recoveredAlias = recoveredMember.GetFirstAliasBlocking();
                Assert.Equal(recoveredAlias, originalAlias);
            }
        }
Esempio n. 3
0
        public void RecoverEidasTest()
        {
            using (Tokenio.Tpp.TokenClient tokenClient = TestUtil.CreateClient())
                using (Tokenio.Tpp.TokenClient anotherTokenClient = TestUtil.CreateClient()) {
                    var    tppAuthNumber = RandomNumeric(15);
                    var    keyPair       = GenerateKeyPair();
                    string certificate   = GenerateCert(keyPair, tppAuthNumber);
                    string bankId        = "gold";

                    // create and verify member first
                    Member verifiedTppMember = EidasMethodsSample.VerifyEidas(
                        tokenClient,
                        tppAuthNumber,
                        certificate,
                        bankId,
                        keyPair.ParseRsaKeyPair().PrivateKey);

                    // now pretend we lost the keys and need to recover the member
                    Member recoveredMember = EidasMethodsSample.RecoverEidas(
                        anotherTokenClient,
                        verifiedTppMember.MemberId(),
                        tppAuthNumber,
                        certificate,
                        keyPair.ParseRsaKeyPair().PrivateKey);

                    IList <Alias> verifiedAliases = recoveredMember.GetAliasesBlocking();

                    Assert.Equal(1, verifiedAliases.Count);
                    Assert.Equal(tppAuthNumber, verifiedAliases[0].Value);
                    Assert.Equal(Alias.Types.Type.Eidas, verifiedAliases[0].Type);
                }
        }
Esempio n. 4
0
        }                                                           /* this simple sample uses a no op */

        /// <summary>
        /// Illustrate setting up a recovery rule more complex than "normal consumer"
        /// mode, without the "normal consumer" shortcuts.
        /// </summary>
        /// <param name="newMember">newly-created member we are setting up</param>
        /// <param name="tokenClient">SDK client</param>
        /// <param name="agentAlias">Alias of recovery agent.</param>
        public void SetUpComplexRecoveryRule(
            TppMember newMember,
            Tokenio.Tpp.TokenClient tokenClient,
            Alias agentAlias)
        {
            // setUpComplex begin snippet to include in docs
            // Someday in the future, this user might ask the recovery agent
            // "Please tell Token that I am the member with ID m:12345678 ."
            // While we're setting up this new member, we need to tell the
            // recovery agent the new member ID so the agent can "remember" later.
            TellRecoveryAgentMemberId(newMember.MemberId());

            string agentId = tokenClient.GetMemberIdBlocking(agentAlias);

            RecoveryRule recoveryRule = new RecoveryRule {
                PrimaryAgent = agentId
            };

            // This example doesn't call .setSecondaryAgents ,
            // but could have. If it had, then recovery would have
            // required one secondary agent authorization along with
            // the primary agent authorization.
            newMember.AddRecoveryRuleBlocking(recoveryRule);
            // setUpComplex done snippet to include in docs
        }
Esempio n. 5
0
 public void StoreTokenRequestAndSetTransferDestinationsTest()
 {
     using (Tokenio.Tpp.TokenClient tokenClient = TestUtil.CreateClient())
     {
         TppMember payee     = tokenClient.CreateMemberBlocking(TestUtil.RandomAlias());
         string    requestId = StoreAndRetrieveTokenRequestSample
                               .StoreTransferTokenRequestWithDestinationsCallback(
             payee,
             setTransferDestinationsUrl);
         StoreAndRetrieveTokenRequestSample.SetTokenRequestTransferDestinations(
             payee,
             requestId,
             tokenClient,
             setTransferDestinationsCallback);
         TokenRequest request = tokenClient.RetrieveTokenRequestBlocking(requestId);
         Assert.NotNull(request);
         Assert.NotEqual(0, request
                         .GetTokenRequestPayload()
                         .TransferBody
                         .Instructions
                         .TransferDestinations.Count);
         Assert.True(request
                     .GetTokenRequestPayload()
                     .TransferBody
                     .Instructions
                     .TransferDestinations[0].FasterPayments != null);
     }
 }
Esempio n. 6
0
        public void GetTransactionsTest()
        {
            using (Tokenio.Tpp.TokenClient tokenClient = TestUtil.CreateClient())
            {
                UserMember payer      = TestUtil.CreateUserMember();
                Alias      payeeAlias = TestUtil.RandomAlias();
                TppMember  payee      = tokenClient.CreateMemberBlocking(payeeAlias);

                Account payeeAccount = payee.CreateTestBankAccountBlocking(1000, "EUR");

                Token token = TestUtil.CreateTransferToken(payer, payeeAlias);

                Transfer transfer = RedeemTransferTokenSample.RedeemTransferToken(
                    payee,
                    payeeAccount.Id(),
                    token.Id);

                string      transactionId = transfer.TransactionId;
                Transaction transaction   = payer.GetTransactionBlocking(
                    payer.GetAccountsBlocking()[0].Id(),
                    transactionId,
                    Key.Types.Level.Standard);
                Assert.Equal(transaction.TokenId, token.Id);
            }
        }
Esempio n. 7
0
        public void ProfilesTest()
        {
            using  (Tokenio.Tpp.TokenClient tokenClient = TestUtil.CreateClient()) {
                TppMember member  = tokenClient.CreateMemberBlocking(TestUtil.RandomAlias());
                Profile   profile = MemberMethodsSample.Profiles(member);

                Assert.NotEmpty(profile.DisplayNameFirst);
            }
        }
Esempio n. 8
0
        private static Task <Member> InitializeMember(TokenClient tokenClient)
        {
            var keyDir    = Directory.GetFiles(Path.Combine(rootLocation, "keys"));
            var memberIds = keyDir.Where(d => d.Contains("_")).Select(d => d.Replace("_", ":"));

            return(!memberIds.Any()
                ? CreateMember(tokenClient)
                : LoadMember(tokenClient, Path.GetFileName(memberIds.First())));
        }
Esempio n. 9
0
        private static TokenClient InitializeSDK()
        {
            var key = Directory.CreateDirectory(Path.Combine(rootLocation, "keys"));

            return(TokenClient.NewBuilder()
                   .ConnectTo(TokenCluster.SANDBOX)
                   .WithKeyStore(new UnsecuredFileSystemKeyStore(key.FullName))
                   .Build());
        }
Esempio n. 10
0
 public void StoreAndRetrieveAccessTokenTest()
 {
     using (Tokenio.Tpp.TokenClient tokenClient = TestUtil.CreateClient())
     {
         TppMember    grantee   = tokenClient.CreateMemberBlocking(TestUtil.RandomAlias());
         string       requestId = StoreAndRetrieveTokenRequestSample.StoreTransferTokenRequest(grantee);
         TokenRequest request   = tokenClient.RetrieveTokenRequestBlocking(requestId);
         Assert.NotNull(request);
     }
 }
        public void KeysTest()
        {
            using (Tokenio.Tpp.TokenClient tokenClient = TestUtil.CreateClient()) {
                IKeyStore     keyStore     = new InMemoryKeyStore();
                ICryptoEngine cryptoEngine = new TokenCryptoEngine("member-id", keyStore);

                TppMember member = tokenClient.CreateMemberBlocking(TestUtil.RandomAlias());
                MemberMethodsSample.Keys(cryptoEngine, member);
            }
        }
Esempio n. 12
0
        public void AccountGetBalanceSampleTest()
        {
            using (Tokenio.Tpp.TokenClient tokenClient = TestUtil.CreateClient())
            {
                TppMember member = tokenClient.CreateMemberBlocking(TestUtil.RandomAlias());
                member.CreateTestBankAccountBlocking(1000.0, "EUR");

                var sums = GetBalanceSample.AccountGetBalanceSample(member);
                Assert.Equal(sums["EUR"], 1000.0);
            }
        }
Esempio n. 13
0
 private static Task <Member> LoadMember(TokenClient tokenClient, string memberId)
 {
     try
     {
         return(tokenClient.GetMember(memberId));
     }
     catch (KeyNotFoundException)
     {
         // it looks like we have a key but the member it belongs to does not exist in the DB
         throw new Exception("Couldn't log in saved member, not found. Remove keys dir and try again.");
     }
 }
        public void CancelTransferTokenByGranteeTest()
        {
            using (Tokenio.Tpp.TokenClient tokenClient = TestUtil.CreateClient()) {
                UserMember grantor      = TestUtil.CreateUserMember();
                Alias      granteeAlias = TestUtil.RandomAlias();
                TppMember  grantee      = tokenClient.CreateMemberBlocking(granteeAlias);

                Token token = TestUtil.CreateTransferToken(grantor, granteeAlias);
                TokenOperationResult result = CancelTransferTokenSample.CancelTransferToken(grantee, token.Id);
                Assert.Equal(result.Status, TokenOperationResult.Types.Status.Success);
            }
        }
Esempio n. 15
0
        public void TriggerBalanceStepUpNotificationTest()
        {
            using (Tokenio.Tpp.TokenClient tokenClient = TestUtil.CreateClient())
            {
                TppMember member = tokenClient.CreateMemberBlocking(TestUtil.RandomAlias());

                NotifyStatus status = member.TriggerBalanceStepUpNotificationBlocking(
                    (new[] { "123", "456" }).ToImmutableList());

                Assert.NotNull(status);
            }
        }
Esempio n. 16
0
        public void CancelAccessTokenByGranteeTest()
        {
            using  (Tokenio.Tpp.TokenClient tokenClient = TestUtil.CreateClient()) {
                Tokenio.User.Member grantor = TestUtil.CreateUserMember();
                string    accountId         = grantor.GetAccountsBlocking()[0].Id();
                Alias     granteeAlias      = TestUtil.RandomAlias();
                TppMember grantee           = tokenClient.CreateMemberBlocking(granteeAlias);

                Token token = TestUtil.CreateAccessToken(grantor, accountId, granteeAlias);
                TokenOperationResult result = CancelAccessTokenSample.CancelAccessToken(grantee, token.Id);
                Assert.Equal(result.Status, TokenOperationResult.Types.Status.Success);
            }
        }
Esempio n. 17
0
        /// <summary>
        /// Recovers a TPP member and verifies its EIDAS alias using eIDAS certificate.
        ///
        /// </summary>
        /// <param name="client">token client</param>
        /// <param name="memberId">id of the member to be recovered</param>
        /// <param name="tppAuthNumber">authNumber of the TPP</param>
        /// <param name="certificate">base64 encoded eIDAS certificate</param>
        /// <param name="certificatePrivateKey">private key corresponding to the public key in the certificate</param>
        /// <returns>verified business member</returns>
        public static Member RecoverEidas(
            Tokenio.Tpp.TokenClient client,
            string memberId,
            string tppAuthNumber,
            string certificate,
            byte[] certificatePrivateKey)
        {
            // create a signer using the certificate private key
            Algorithm signingAlgorithm = Algorithm.Rs256;
            ISigner   payloadSigner    = new Rs256Signer("eidas", certificatePrivateKey);

            // generate a new privileged key to add to the member
            ICryptoEngine cryptoEngine = new TokenCryptoEngine(memberId, new InMemoryKeyStore());
            Key           newKey       = cryptoEngine.GenerateKey(Level.Privileged);

            // construct a payload with all the required data
            EidasRecoveryPayload payload = new EidasRecoveryPayload
            {
                MemberId    = memberId,
                Certificate = certificate,
                Algorithm   = signingAlgorithm,
                Key         = newKey
            };

            Tokenio.Tpp.Member recoveredMember = client
                                                 .RecoverEidasMember(payload, payloadSigner.Sign(payload), cryptoEngine)
                                                 .Result;

            // the eidas alias becomes unverified after the recovery, so we need to verify it again
            Alias eidasAlias = new Alias
            {
                Value   = tppAuthNumber.Trim(),
                RealmId = recoveredMember.RealmId(),
                Type    = Alias.Types.Type.Eidas
            };

            VerifyEidasPayload verifyPayload = new VerifyEidasPayload
            {
                MemberId    = memberId,
                Alias       = eidasAlias,
                Certificate = certificate,
                Algorithm   = signingAlgorithm
            };

            VerifyEidasResponse response = recoveredMember
                                           .VerifyEidas(verifyPayload, payloadSigner.Sign(verifyPayload))
                                           .Result;

            return(recoveredMember);
        }
Esempio n. 18
0
        public void RedeemAccessTokenTest()
        {
            using (Tokenio.Tpp.TokenClient tokenClient = TestUtil.CreateClient())
            {
                UserMember grantor      = TestUtil.CreateUserMember();
                string     accountId    = grantor.GetAccountsBlocking()[0].Id();
                Alias      granteeAlias = TestUtil.RandomAlias();
                TppMember  grantee      = tokenClient.CreateMemberBlocking(granteeAlias);

                Token token    = TestUtil.CreateAccessToken(grantor, accountId, granteeAlias);
                Money balance0 = RedeemAccessTokenSample.RedeemAccessToken(grantee, token.Id);

                Assert.True(Convert.ToDecimal(balance0.Value) > (decimal.One * 10));
            }
        }
Esempio n. 19
0
        public void WebhookTest()
        {
            using (Tokenio.Tpp.TokenClient tokenClient = TestUtil.CreateClient())
            {
                TppMember tpp = tokenClient.CreateMemberBlocking(TestUtil.RandomAlias());

                Assert.Throws <AggregateException>(() => WebhookSample.GetWebhookConfig(tpp));

                WebhookSample.SetWebhookConfig(tpp);
                Assert.NotNull(WebhookSample.GetWebhookConfig(tpp));

                WebhookSample.DeleteWebhookConfig(tpp);
                Assert.Throws <AggregateException>(() => WebhookSample.GetWebhookConfig(tpp));
            }
        }
Esempio n. 20
0
        public void MemberGetBalancesSampleTest()
        {
            using (Tokenio.Tpp.TokenClient tokenClient = TestUtil.CreateClient())
            {
                TppMember member = tokenClient.CreateMemberBlocking(TestUtil.RandomAlias());
                member.CreateTestBankAccountBlocking(1000.0, "EUR");

                member.CreateTestBankAccountBlocking(500.0, "EUR");
                List <Balance> balances = (List <Balance>)GetBalanceSample.memberGetBalanceListSample(member);

                Assert.Equal(balances.Count, 2);
                Assert.True(balances.Exists(b => double.Parse(b.Current.Value).Equals(500.0)));
                Assert.True(balances.Exists(b => double.Parse(b.Current.Value).Equals(1000.0)));
            }
        }
Esempio n. 21
0
        public void DeleteMemberTest()
        {
            using (Tokenio.Tpp.TokenClient tokenClient = TestUtil.CreateClient())
            {
                TppMember member = tokenClient.CreateMemberBlocking(TestUtil.RandomAlias());

                Assert.Equal(tokenClient.GetMemberBlocking(member.MemberId()).MemberId(), member.MemberId());

                member.DeleteMemberBlocking();


                Assert.Throws <AggregateException>(() =>
                                                   tokenClient.GetMemberBlocking(member.MemberId())

                                                   );
            }
        }
Esempio n. 22
0
        /// <summary>
        /// Resolves a user's alias.
        /// </summary>
        /// <param name="client">token client</param>
        public static void ResolveAlias(Tokenio.Tpp.TokenClient client)
        {
            Alias alias = new Alias
            {
                Value = "*****@*****.**"
            };


            // If this call fails then the alias does not correspond to an existing member.
            TokenMember resolved = client.ResolveAliasBlocking(alias);

            // resolved member ID from alias
            string memberId = resolved.Id;

            // The resolved alias
            // will have the correct type, e.g. EMAIL.
            Alias resolvedAlias = resolved.Alias;
        }
Esempio n. 23
0
        public void GetTokenTest()
        {
            using  (Tokenio.Tpp.TokenClient tokenClient = TestUtil.CreateClient()) {
                UserMember payer      = TestUtil.CreateUserMember();
                Alias      payeeAlias = TestUtil.RandomAlias();
                TppMember  payee      = tokenClient.CreateMemberBlocking(payeeAlias);

                Token token = TestUtil.CreateTransferToken(payer, payeeAlias);

                Assert.Equal(GetTokensSample.GetToken(payee, token.Id).Id, token.Id);
                var sigList = GetTokensSample.GetToken(payee, token.Id).PayloadSignatures.Where(sig => sig.Action == TokenSignature.Types.Action.Cancelled).ToList();
                Assert.Empty(sigList);
                // cancel token
                payee.CancelTokenBlocking(token);
                sigList = GetTokensSample.GetToken(payee, token.Id).PayloadSignatures.Where(sig => sig.Action == TokenSignature.Types.Action.Cancelled).ToList();
                Assert.NotEmpty(sigList);
            }
        }
        public void RedeemPaymentTokenTest()
        {
            using (Tokenio.Tpp.TokenClient tokenClient = TestUtil.CreateClient()) {
                UserMember payer      = TestUtil.CreateUserMember();
                Alias      payeeAlias = TestUtil.RandomAlias();
                TppMember  payee      = tokenClient.CreateMemberBlocking(payeeAlias);

                Account payeeAccount = payee.CreateTestBankAccountBlocking(1000, "EUR");

                Token token = TestUtil.CreateTransferToken(payer, payeeAlias);

                Transfer transfer = RedeemTransferTokenSample.RedeemTransferToken(
                    payee,
                    payeeAccount.Id(),
                    token.Id);
                Assert.NotNull(transfer);
            }
        }
Esempio n. 25
0
        public void RecoveryDefault()
        { // "normal consumer" recovery using "shortcuts"
            using (Tokenio.Tpp.TokenClient tokenClient = TestUtil.CreateClient()) {
                MemberRecoverySample mrs = new MemberRecoverySample();

                // set up
                Alias     originalAlias  = TestUtil.RandomAlias();
                TppMember originalMember = tokenClient.CreateMemberBlocking(originalAlias);
                mrs.SetUpDefaultRecoveryRule(originalMember);

                Tokenio.Tpp.TokenClient otherTokenClient = TestUtil.CreateClient();
                TppMember recoveredMember = mrs.RecoverWithDefaultRule(
                    otherTokenClient,
                    originalAlias);
                Alias recoveredAlias = recoveredMember.GetFirstAliasBlocking();
                Assert.Equal(recoveredAlias, originalAlias);
            }
        }
Esempio n. 26
0
 public void VerifyEidasTest()
 {
     using (Tokenio.Tpp.TokenClient tokenClient = TestUtil.CreateClient())
     {
         var    tppAuthNumber     = RandomNumeric(15);
         var    keyPair           = GenerateKeyPair();
         string certificate       = GenerateCert(keyPair, tppAuthNumber);
         Member verifiedTppMember = EidasMethodsSample.VerifyEidas(
             tokenClient,
             tppAuthNumber,
             certificate,
             "gold",
             keyPair.ParseRsaKeyPair().PrivateKey);
         IList <Alias> verifiedAliases = verifiedTppMember.GetAliasesBlocking();
         Assert.Equal(1, verifiedAliases.Count);
         Assert.Equal(tppAuthNumber, verifiedAliases[0].Value);
         Assert.Equal(Alias.Types.Type.Eidas, verifiedAliases[0].Type);
     }
 }
Esempio n. 27
0
        /// <summary>
        /// Illustrate recovery using a not-normal-"consumer mode" recovery agent.
        /// </summary>
        /// <param name="tokenClient">SDK client</param>
        /// <param name="alias">Alias of member to recover</param>
        /// <returns>recovered member</returns>
        public TppMember RecoverWithComplexRule(
            Tokenio.Tpp.TokenClient tokenClient,
            Alias alias)
        {
            // complexRecovery begin snippet to include in docs
            string memberId = tokenClient.GetMemberIdBlocking(alias);

            ICryptoEngine cryptoEngine = new TokenCryptoEngine(memberId, new InMemoryKeyStore());
            Key           newKey       = cryptoEngine.GenerateKey(Key.Types.Level.Privileged);

            string verificationId = tokenClient.BeginRecoveryBlocking(alias);

            MemberRecoveryOperation.Types.Authorization authorization = tokenClient.CreateRecoveryAuthorizationBlocking(
                memberId,
                newKey);

            // ask recovery agent to verify that I really am this member
            Signature agentSignature = getRecoveryAgentSignature(authorization);

            // We have all the signed authorizations we need.
            // (In this example, "all" is just one.)
            MemberRecoveryOperation mro = new MemberRecoveryOperation
            {
                Authorization  = authorization,
                AgentSignature = agentSignature
            };
            TppMember recoveredMember = tokenClient.CompleteRecoveryBlocking(
                memberId,
                (new[] { mro }).ToList(),
                newKey,
                cryptoEngine);

            // after recovery, aliases aren't verified

            // In the real world, we'd prompt the user to enter the code emailed to them.
            // Since our test member uses an auto-verify email address, any string will work,
            // so we use "1thru6".
            recoveredMember.VerifyAliasBlocking(verificationId, "1thru6");
            // complexRecovery done snippet to include in docs

            return(recoveredMember);
        }
Esempio n. 28
0
        /// <summary>
        /// Creates a TPP member and verifies it using eIDAS certificate.
        ///
        /// </summary>
        /// <param name="client">token client</param>
        /// <param name="tppAuthNumber">authNumber of the TPP</param>
        /// <param name="certificate">base64 encoded eIDAS certificate</param>
        /// <param name="bankId">id of the bank the TPP trying to get access to</param>
        /// <param name="privateKey">private key corresponding to the public key in the certificate</param>
        /// <returns>verified business member</returns>
        public static Member VerifyEidas(
            Tokenio.Tpp.TokenClient client,
            string tppAuthNumber,
            string certificate,
            string bankId,
            byte[] privateKey)
        {
            Algorithm signingAlgorithm = Algorithm.Rs256;
            ISigner   signer           = new Rs256Signer("eidas", privateKey);

            // resolve memberId of the bank TPP is trying to get access to
            string bankMemberId = client
                                  .ResolveAliasBlocking(new Alias {
                Value = bankId, Type = Alias.Types.Type.Bank
            })
                                  .Id;
            // create an eIDAS alias under realm of the target bank
            Alias eidasAlias = new Alias
            {
                Value   = tppAuthNumber.Trim(),
                RealmId = bankMemberId,
                Type    = Alias.Types.Type.Eidas
            };

            // create a member under realm of the bank with eIDAS alias
            Tokenio.Tpp.Member tpp = client.CreateMember(eidasAlias, null, bankMemberId).Result;
            // construct a payload with all the required data
            VerifyEidasPayload payload = new VerifyEidasPayload
            {
                Algorithm   = signingAlgorithm,
                Alias       = eidasAlias,
                Certificate = certificate,
                MemberId    = tpp.MemberId()
            };

            // verify eIDAS
            VerifyEidasResponse response = tpp
                                           .VerifyEidas(payload, signer.Sign(payload))
                                           .Result;

            return(tpp);
        }
Esempio n. 29
0
        /// <summary>
        /// Recover previously-created member, assuming they were
        /// configured with a "normal consumer" recovery rule.
        /// </summary>
        /// <param name="tokenClient">SDK client</param>
        /// <param name="alias">alias of member to recoverWithDefaultRule</param>
        /// <returns>recovered member</returns>
        public TppMember RecoverWithDefaultRule(Tokenio.Tpp.TokenClient tokenClient, Alias alias)
        {
            string verificationId = tokenClient.BeginRecoveryBlocking(alias);
            // recoverWithDefault begin snippet to include in docs
            string        memberId     = tokenClient.GetMemberIdBlocking(alias);
            ICryptoEngine cryptoEngine = new TokenCryptoEngine(memberId, new InMemoryKeyStore());

            // In the real world, we'd prompt the user to enter the code emailed to them.
            // Since our test member uses an auto-verify email address, any string will work,
            // so we use "1thru6".
            TppMember recoveredMember = tokenClient.CompleteRecoveryWithDefaultRuleBlocking(
                memberId,
                verificationId,
                "1thru6",
                cryptoEngine);

            // We can use the same verification code to re-claim this alias.
            recoveredMember.VerifyAliasBlocking(verificationId, "1thru6");
            // recoverWithDefault done snippet to include in docs

            return(recoveredMember);
        }
        /**
         * Sets transfer destinations for a given token request.
         *
         * @param payee Payee Token member (the member requesting the transfer token be created)
         * @param requestId token request id
         * @param tokenClient Token SDK client
         * @param setTransferDestinationsCallback callback url
         */

        /// <summary>
        /// Sets transfer destinations for a given token request.
        /// </summary>
        /// <param name="payee">Payee Token member (the member requesting the transfer token be created)</param>
        /// <param name="requestId">token request id</param>
        /// <param name="tokenClient">Token SDK client</param>
        /// <param name="setTransferDestinationsCallback">callback url</param>
        public static void SetTokenRequestTransferDestinations(
            TppMember payee,
            string requestId,
            Tokenio.Tpp.TokenClient tokenClient,
            string setTransferDestinationsCallback)
        {
            TokenRequestTransferDestinationsCallbackParameters parameters =
                tokenClient.ParseSetTransferDestinationsUrl(setTransferDestinationsCallback);

            IList <TransferDestination> transferDestinations = new List <TransferDestination>();

            if (parameters.SupportedTransferDestinationTypes
                .Contains(DestinationCase.FasterPayments))
            {
                TransferDestination destination = new TransferDestination
                {
                    FasterPayments = new TransferDestination.Types.FasterPayments
                    {
                        SortCode      = Util.Nonce(),
                        AccountNumber = Util.Nonce()
                    }
                };
                transferDestinations.Add(destination);
            }
            else
            {
                transferDestinations.Add(new TransferDestination
                {
                    Sepa = new TransferDestination.Types.Sepa
                    {
                        Bic  = Util.Nonce(),
                        Iban = Util.Nonce()
                    }
                });
            }

            payee.SetTokenRequestTransferDestinationsBlocking(requestId, transferDestinations);
        }