How to send SOL in Solana NET SDK? - c#

The documentation shows how to make a transfer from one wallet to another. In one account.
// Initialize the rpc client and a wallet
var rpcClient = ClientFactory.GetClient(Cluster.TestNet);
var wallet = new Wallet();
// Get the source account
var fromAccount = wallet.GetAccount(0);
// Get the destination account
var toAccount = wallet.GetAccount(1);
// Get a recent block hash to include in the transaction
var blockHash = rpcClient.GetRecentBlockHash();
// Initialize a transaction builder and chain as many instructions as you want before building the message
var tx = new TransactionBuilder().
SetRecentBlockHash(blockHash.Result.Value.Blockhash).
SetFeePayer(fromAccount).
AddInstruction(MemoProgram.NewMemo(fromAccount, "Hello from Sol.Net :)")).
AddInstruction(SystemProgram.Transfer(fromAccount, toAccount.GetPublicKey, 100000)).
Build(fromAccount);
var firstSig = rpcClient.SendTransaction(tx);
How to make a transfer to another account?
Do I need to know the private key of the account to which I will transfer?

Your example has all of the pieces you need. To transfer to another account, you need to create a transaction (using TransactionBuilder), and specifically add a SystemProgram.Transfer instruction to your transaction. Also, in your example, you're sending from fromAccount, which has the private key, to toAccount.PublicKey. You're using the PublicKey of toAccount, so no need for the private key of the recipient.
Note that the example appears to be incorrect, so you should base your code from this example instead: https://github.com/bmresearch/Solnet/blob/8369ac166ed90a7e6b07060178ed70745bd97bc3/src/Solnet.Examples/TransactionBuilderExample.cs#L22

Related

Expanding a Source object in a Stripe API call to StripeBalenceService doesn't return any customer info

I'm making a c# call to the Stripe.net API to fetch a balance history for a connected account. I'm trying to expand on the balance transaction object to see where the charge is coming from (ex. the customer who made the charge) as all the charges to connected accounts on my platform are from charge objects with a destination property to the connected account.
Here is my code and a screenshot of what the expanded source looks like, but think I should see a charge id or a customer or something refering me to the initial customer somewhere, but I don't...
var balanceService = new StripeBalanceService();
balanceService.ExpandSource = true;
var list = new List <string> () {
"data.source.source_transfer"
};
StripeList <StripeBalanceTransaction> balanceTransactions
= balanceService.List(
new StripeBalanceTransactionListOptions() {
Limit = 20,
Type = "payment",
Expand = list
},
new StripeRequestOptions() {
StripeConnectAccountId = accountId
}
);
foreach(var transaction in balanceTransactions) {
var test = transaction;
}
I feel like I should see a charge id (ex. ch_xxx) or a Customer value (which is null) all I see of any relevance is a payment id (ex. py_xxx)
It is possible to get the charge object(ch_xxx), it is just a little involved!
As you are using destination charges, the charge(ch_xxx) takes place on the platform account, and then a transfer(tr_xxx) is made to the connected account. That transfer creates a payment(py_xxx) on the connected account, which results in a balance transaction(txn_xxx).
As your code expands the source of those balance transactions, you get the payment(py_xxx). The payment is equivalent to a charge, so it has a source_transfer field. You can expand this field also! This will give you the transfer object(tr_xxx). Finally, the transfer has a source_transaction field, and this can be exapanded to give the original charge(ch_xxx)!
Putting that all together, you will want to expand on "data.source.source_transfer.source_transaction".
If you use a Stripe library in a dynamic language you can see this in action ... unfortunately, stripe-dotnet has an open issue right now which means that you can not do this directly. Instead, you will need to make the API calls manually by calling the various Retrieve functions on the IDs, instead of doing a single expansion. It would look something like this:
var paymentId = transaction.Source.Id;
var chargeService = new StripeChargeService();
var payment = chargeService.Get(
paymentId,
new StripeRequestOptions()
{
StripeConnectAccountId = accountId
}
);
var transferService = new StripeTransferService();
transferService.ExpandSourceTransaction = true;
var transfer = transferService.Get(payment.SourceTransferId);
var charge = transfer.SourceTransaction;
Console.WriteLine(charge.Id);

How to create a direct charge by using a shared customer?

I am attempting to create a direct charge to a connected account from my platform. I have been advised by Stripe support to do this by using a shared customer, however that has just created more issues.
The code itself is very simple, if it worked. It updates the platform customer with the src_... token provided by an iOS app. This works. It then attempts to create a shared customer using the StripeTokenService(). This does not work, despite following the documentation to the letter. The error I receive is:
You provided a customer without specifying a source. The default source of the customer is a source and cannot be shared from existing customers.
I can see no method of providing a source to the shared customer in the Stripe .Net SDK. All I can provide is a Card or BankAccount, neither of which I want to do as the API should remain agnostic of sensitive user information.
What exactly am I doing wrong here?
StripeConfiguration.SetApiKey(Settings.Stripe.SecretKey);
var businessRequestOptions = new StripeRequestOptions { StripeConnectAccountId = businessOwner.StripeAccountId };
var customerService = new StripeCustomerService();
customerService.Update(userDetail.StripeCustomerId, new StripeCustomerUpdateOptions
{
SourceToken = stripeToken // = 'src_...'
});
var tokenService = new StripeTokenService();
// this is the call that generates the error I mentioned above \/ \/
var token = tokenService.Create(new StripeTokenCreateOptions
{
CustomerId = userDetail.StripeCustomerId // = 'cus_...'
}, businessRequestOptions);
// create a direct charge to the business account (taking out application fee)
var chargeService = new StripeChargeService();
var stripeCharge = chargeService.Create(new StripeChargeCreateOptions
{
Amount = Convert.ToInt32(fee),
Currency = currency,
Description = $"Payment to {businessOwner.BusinessName} through Service X",
ApplicationFee = applicationFee,
SourceTokenOrExistingSourceId = token.Id, // use shared customerId here
}, businessRequestOptions);
When using Sources you have to use a different approach which is documented here: https://stripe.com/docs/sources/connect#shared-card-sources
The idea is that you are going to "clone" the Source from the platform to the connected account. This is done using the original_source when creating a new Source. You will then get a new Source object with a different id src_XXXX that you can then charge directly on the connected account.

Updating MetaData on Connected account fails

I am using stripe connect(destination payment) with the help of stripe.net library from Jaymedavis.
The problem that I am facing is that I am not able to retrieve the destination payment ID to update the metadata in the connected account. The following line returns a null preventing me from updating meta data on the connected account. But the strange thing is that when I log in to the dashboard the destination payment ID exists. I am not sure why I am not able to retreive it in code.
Is the charge creation asynchronous?. I am not sure. Stripe's connect documentation does not help either. The following line returns a null. My code is down below. Seeking help.
String deschargeID = result.Transfer.DestinationPayment;
Here is the code that I am using
var service = new StripeChargeService(ZambreroSecretKey);
var result = (Stripe.StripeCharge) null;
try {
result = service.Create(newCharge);
if (result.Paid) {
//get the chargeID on the newgen account and update the metadata.
//Returns null even though it exists in the dashboard
String deschargeID = result.Transfer.DestinationPayment;
var chargeService = new StripeChargeService(newgenSecretKey);
StripeCharge charge = chargeService.Get(deschargeID);
charge.Metadata = myDict;
Response.Redirect("PgeCustSuccess.aspx?OrderID=" + OrderID);
}
} catch (StripeException stripeException) {
Debug.WriteLine(stripeException.Message);
stripe.Text = stripeException.Message;
}
The charge object's transfer attribute is not expanded by default, meaning it's just a string with the ID of the transfer object ("tr_..."), not a full transfer object.
According to Stripe.net's documentation, you can expand the transfer attribute by adding this line:
service.ExpandTransfer = True
before sending the charge creation request.

GetRecords that are approved in ServiceNow API

ServiceNow - GetRecords
Code:
var proxy = new ServiceNow_dmn_demand()
{
Url = "https://<instance>.service-now.com/dmn_demand.do?SOAP",
Credentials = new NetworkCredential("username", "password")
};
var objRecord = new Service.getRecords
{
// Here, I want to filter the records that are approved..
};
var recordResults = proxy.getRecords(objRecord);
I am getting all the records.
I want to get the records that are only approved. But I don't know the
exact field name used to filter the Approved records.
You are looking for the state field, and specifically where state=8. This table extends the Task where the State field is defined. If you look at the choice list for that state field on task you will see value=8, has label of approved. If you query for only dmn_demand records where state = 8 this should give you what you want. Also consider using the ServiceNow REST API and the ServiceNow REST API Explorer (in Fuji release) to help you build and test these requests.

NHIbernate & Rhino-Security does not save unless I call session.Flush()

I am having an issue using nHibernate and Rhino.Security. After struggling for hours to get the right config setup, I finally got the code to run without any errors. However, no entries are being saved to the database unless I call session.Flush().
Looking at various examples on the net; I should not have to call flush.
Here’s my config code:
var cfg = new Configuration()
.SetProperty(Environment.ConnectionDriver, typeof(SqlClientDriver).AssemblyQualifiedName)
.SetProperty(Environment.Dialect, typeof(MsSql2008Dialect).AssemblyQualifiedName)
.SetProperty(Environment.ConnectionString, "………")
.SetProperty(Environment.ProxyFactoryFactoryClass, typeof(ProxyFactoryFactory).AssemblyQualifiedName)
.SetProperty(Environment.ReleaseConnections, "on_close")
.SetProperty(Environment.UseSecondLevelCache, "true")
.SetProperty(Environment.UseQueryCache, "true")
.SetProperty(Environment.CacheProvider, typeof(HashtableCacheProvider).AssemblyQualifiedName)
.AddAssembly("GA.CAP.Website")
;
Security.Configure<AspNetUser>(cfg, SecurityTableStructure.Prefix);
var factory = cfg.BuildSessionFactory();
var session = factory.OpenSession();
var authorizationRepository = new AuthorizationRepository(session);
IoC.Container.RegisterInstance<IAuthorizationRepository>(authorizationRepository);
var permissionBuilderService = new PermissionsBuilderService(session, authorizationRepository);
IoC.Container.RegisterInstance<IPermissionsBuilderService>(permissionBuilderService);
var permissionService = new PermissionsService(authorizationRepository, session);
IoC.Container.RegisterInstance<IPermissionsService>(permissionService);
var authService = new AuthorizationService(permissionService, authorizationRepository);
IoC.Container.RegisterInstance<IAuthorizationService>(authService);
Test code:
authorizationRepository.CreateUsersGroup("GAAdmins");
var group = authorizationRepository.GetUsersGroupByName("GAAdmins");
The GetUsersGroupByName call returns null. If I add a session.Flush call in between the two calls, it works fine and returns the group.
Based on examples in various blogs, such as this one, I should not have to call flush. In addition, the test cases included with the Rhino.Security code do not do any flushing as shown here:
This is straight out of Rhino.Security's test case fixture:
// on first deploy
Operation operation = authorizationRepository.CreateOperation("/Account/View");
// when creating account
UsersGroup group = authorizationRepository.CreateUsersGroup("Belongs to " + account.Name);
// setting permission so only associated users can view
permissionsBuilderService
.Allow(operation)
.For(group)
.On(account)
.DefaultLevel()
.Save();
// when adding user to account
authorizationRepository.AssociateUserWith(user, group);
bool allowed = authorizationService.IsAllowed(user, account, "/Account/View");
Assert.True(allowed);
Is there some setting I am missing somewhere?
Thanks,
Rick
That is expected, RS uses the same session as your code, and calling Flush internally may result in unintended consequences.
Commit your transaction or call Flush

Categories