Aptos SDK - multiple payloads in one transaction - sdk

Sending one payload is easy, for example:
let payload1 = txBuilder.buildTransactionPayload("0x1::aptos_account::transfer",[],[to.address(),100000])
let raw = await client.generateRawTransaction(acc.address(),payload1)
let signed = await client.signTransaction(acc,raw);
let res = await client.submitTransaction(signed);
console.log(res)
let waiting = await client.waitForTransaction(res.hash);
But how do I send more than one payload in a transaction? is it possible in Aptos?

This is not possible, you can only send one payload per transaction. However, if your goal is to do multiple things in a single transaction, that is possible with Move scripts. These posts explain that approach in more detail:
How do I execute a Move script with the Aptos CLI?
How do I execute a Move script on Aptos using the Rust SDK?

Related

How to run multiple API call simultaneously using async/await in swift?

As per the new Structured Concurrency in Swift, we can await a API call which is done in an async context,
But I want to make multiple API calls simultaneously,
for example, currently If add the API calls one after another,
profileData = await viewModel.getProfileData()
userCardData = await viewModel.getCardDetails()
The problem in the above case is CardDetails is fetched only after fetching the profile data.
It can be achieved using the async let.
This special syntax allows you to group several asynchronous calls and await them together,
Example,
async let profileData = viewModel.getProfileData()
async let userCardData = viewModel.getCardDetails()
The above statement indicated that profileData and userCardData, will be available at some point of time in future, just like a promise.
Now in order to use profileData and userCardData we need to use await, incase the data is fetched and available it would return immediately, or it suspend until the data is available.
The value from the above request can be used like,
let (fetchedProfileData, fetchedUserCardData) = try await (profileData, userCardData)

Is there a way to tell when a document has been synced with the database from the cache?

I am building an instant messaging app, akin to WhatsApp, and I need to display the send status of the message: Sending, Sent; sending being if it is the Firebase cache, due to being offline, and sent if the message is on the online database.
Is there a way to tell if a specific document has been uploaded to the database?
I currently have a live update listener listening on the messages collection in firestore that fires when either the cache or database updates. It can tell where the update came from but that returns all of the messages and doesn't specify any individual documents.
Here is a snippet of the completion block for the listener.
let source = snapshot.metadata.isFromCache ? "local cache" : "server"
print ("metadata: data fetched from DB: \(source)")
for diff in snapshot.documentChanges {
print("diffData: \(diff.type.rawValue)")
print("messageId: \(diff.document.documentID)")
switch diff.type {
case .added:
print("added")
case .removed:
print("removed")
case .modified:
print("modified")
}
}
var messages: [ChatEntry] = []
let deletedIds = [String]()
let permanentlyDeletedIds = [String]()
for document in snapshot.documents {
if document.exists {
let message = ChatEntry(fromSnapshot: document)
print("MessageId: \(message?.id ?? "null")")
print("messageText: \(message?.message ?? "Null")")
}
}
The callback runs when either the cache or DB updates, but if one updates, then the other updates then the document changes is emptied. meaning the I can't tell what happened.
Any advice would be appreciated, Thanks in advance.
You can find precisely that information in the SnapshotMetadata of a QuerySnapshot, which has an isFromCache property that:
Returns YES if the snapshot was created from cached data rather than guaranteed up-to-date server data.
You'll want to listen for metadata changes to be able to update the UI once the data is synchronized to the server.
My suggestion on this this would be to:
Set the status to "Sending" when you write a value to Firebase from the client - regardless of if you are online or offline (Firebase already handles this process for you so don't reinvent it).
Use your existing callback to notify you of new messages matching that one which you can then mark as "Sent" once you receive them (via the callback).
To make this easier you may even want to create a temporary array of ID's that you expect will be coming back from Firebase once written to the Firebase DB. This will allow you to easily validate that the message sent was the one you expected back.
Let me know if this helps.
Andrew

Twilio Video - How to get current number of participants in a room?

I would like to know how many people are currently connected to a room when using Twilio Video.
Twilio has a REST API to get a room resource, but it does not return current number of participants.
https://www.twilio.com/docs/api/video/rooms-resource#get-by-sid
Only way i see is to subscribe to status callback to "participant connected" and disconnected events and manually keep track of how many participants are connected or left the room.
Is there a better way to do this ?
You can use twilio server side sdk, Let me share NodeJS example so you get better idea on implementation.
First lets define function that init twilio client and fetch connected participants of room.
async function getConnectedParticipants(roomName) {
var Twilio = require('twilio');
var apiKeySid = "YOUR_TWILIO_API_KEY_SID_HERE";
var apiKeySecret = "YOUR_TWILIO_API_SECRET_HERE";
var accountSid = "YOUR_TWILIO_ACCOUNT_SID_HERE";
var client = new Twilio(apiKeySid, apiKeySecret, {accountSid: accountSid});
var list = await client.video.rooms(roomName)
.participants
.list({status: 'connected'});
return list;
}
Now let's use our function that return you connected participants.
var connectedParticipants = await getConnectedParticipants("YourRoomName");
// print all connected participants
console.log('connectedParticipants', connectedParticipants);
Note: I have used async and await in this example, please check more on that before implementation.
Twilio developer evangelist here.
Keeping a server side list of the participants' identities based on the participant connected and disconnected events is probably the best way to work this out right now.
One alternative is to get this information from the front end. The JavaScript library allows you to query the participants in a room. You could periodically, or based on events, query that property and send it to your server via Ajax too.
Let me know if that helps.
Update
The Rooms API now allows you to retrieve information on participants that have connected to a room. To get the currently connected users in a room using Node.js, for example, the code would look like:
var client = new Twilio(apiKeySid, apiKeySecret, {accountSid: accountSid});
client.video.rooms(roomSid).participants
.list({status: 'connected'}, (err, participants) => {
if (err) { console.error(err); return; }
console.log(participants.length);
});

How to guarantee the correct order in async request

I have a iOS application that use Alamofire to make URL requests. I sometimes find the requests arriving in the wrong order when there is very little time between them. This has to do with the nature of async requests as I understand. Is there any way to guarantee the correct order of the requests? I've been thinking you could wait for each request to finish because you have a completion handler or maybe you could handle this at the server side with a timestamp on each request so the server can discard requests that has a lower timestamp. I don't know what's the best solution though.
My code so far:
Alamofire.request(
defaults.string(forKey: "APIurl")! + path,
method: httpMethod,
parameters: parameters,
encoding: JSONEncoding.default,
headers: headers).responseJSON
{ response in
// Check if the request was successful
var success = false
if (response.result.isSuccess) {
let statusCode = response.response!.statusCode
if (statusCode == 200) {
success = true
} else {
showAlert("COULD_NOT_COMPLETE_TASK_TITLE", message: "TRY_AGAIN_LATER")
}
}
}
I use sliders to change a value between 0 and 100. So in my case the order of the requests are crucial. Let's say I change a slider from 50 to 60. With async requests it sometimes execute first 60 and then 50. This is an issue as it's sent to my API that way and saves the latest value (in this case 50) in the database even though my desired value was 60.
If the thread is serial which in your case it is then the order will always be the same as you input it. So calling a few operations asynchronously on a same serial thread will force the operations to preserve that order.
The problem in your case is that you are not calling these operations, Alamofire is calling them. The order is preserved but it depends on when the responses are received and parsed. That means you may have no control over the order of the async operations being called.
You have 2 ways of serializing responses:
You need to wait for each response to be completed before you call the next request. If your responses are standard (all look alike) you only need some manager that will store an array of requests and will not call the new one until the previous one is completed. This might be a bit slow since there is no reason (or at least it seems that way in your case) not to perform the requests at the same time.
Serialize the responses so they are called in the same order as input. This means you call the requests whenever and responses will be called whenever. But once the response is received you will check for other responses being complete and only if they are you will trigger a callback on this one. That would again mean having some manager that serializes there responses.
So for the second one you would need something like:
SerializedRequestManager.performRequest(request, myCallbackClosure)
The manager would then save the request into some array of request wrappers like:
let requestWrapper = RequestWrapper(request, myCallbackClosure, isCompleted: false)
self.requestPool.append(requestWrapper)
AF.performRequest(request, myInternalClosure)
Then on response (myInternalClosure) you need to set the correct wrapper to have response to true and then flush the responses from the start of the array. All the responses finished then must be removed from the array:
requestWrapper.responseData = data // Same wrapper that was just added into the array
requestWrapper.responseError = error // Same wrapper that was just added into the array
requestWrapper.isCompleted = true
self.flushResponses()
So then flushResponses:
var newPool = [RequestWrapper]() // This is where all the pending items will stay
var shouldFlushResponse = true // Will be set to false with first request that was not completed
self.requestPool.forEach { wrapper in
if wrapper.isCompleted && shouldFlushResponse {
wrapper.callback(wrapper.responseData, wrapper.responseError) // perform response closure
} else {
shouldFlushResponse = false
newPool.append(wrapper)
}
}
self.requestPool = newPool
But you need to be very careful about the multithreading here. All the operation on the array requestPool should be done on the same thread but it may be any thread you want.
Well if the order of requests in crucial in your case then you should go for the NSOperationQueue that is the only way to make sure the order of your requests.
Follow this tutorial to have a border idea

handling byte array of image in node js server

I am following this below library for my applications where user have to chat with other user.
SocketChat
There I can chat with other users. Now my prime concern is to send images to server and then that image is going to reflect in the chat of the other user's window. Its like Group chat.
I am done with image sending from iOS app
I don't know what to write to handle byte array which is of the image I sent from one of the client.
clientSocket.on('images', function(clientNickname, message){
var currentDateTime = new Date().toLocaleString();
var dataType = "imageType"
delete typingUsers[clientNickname];
io.emit("userTypingUpdate", typingUsers);
io.emit('newChatMessage', clientNickname, message, currentDateTime,dataType);
});
I think its not working. Its good for the string type data. Can you please let me know what to write there in order to receive image and send that back.

Resources