starknet.js icon indicating copy to clipboard operation
starknet.js copied to clipboard

feat: transactionResponse

Open PhilippeR26 opened this issue 2 years ago • 9 comments

Motivation and Resolution

Solve issue #796 Create a new helper to detect what response type the user get, as it's rather complicated today.

Usage related changes

Users can now use a transaction receipt as input for a transactionResponse function, and obtain an object that mimics a Rust Enum. Example :

const result = await account.execute(myCall);
const txReceipt = await provider.waitForTransaction(result.transaction_hash);
const txR = transactionResponse(txReceipt);
console.log(txR.match({
    Success: () => "success!",
    _: () => "unsuccess"
}));

console.log(txR.content);
console.log(txR.status);
console.log(txR.isSuccess());
console.log(txR.isRejected());

txR.match({
    Success: (txR: SuccessfulTransactionReceiptResponse) => { console.log("Success =", txR) },
    Rejected: (txR: RejectedTransactionReceiptResponse) => { console.log("Rejected =", txR) },
    Reverted: (txR: RevertedTransactionReceiptResponse) => { console.log("Reverted =", txR) },
    Error: (err: Error) => { console.log("An error occured =", err) },
});

Development related changes

  • A new txResponse directory has been created in utils.
  • A new class has been created : TxResponseVariant
  • A proxyFactory is created, and when the variant is defined, the Proxy creates an instance of TxResponseVariant
  • tests : As I didn't found how to force the node/devnet to provide a Rejected response, I didn't tested this case. As the test duration is currently of 62s on my PC, I didn't added a declare Success test (can be easily added if necessary).

Checklist:

  • [x] Performed a self-review of the code
  • [x] Rebased to the last commit of the target branch (or merged it into my branch)
  • [x] Linked the issues which this PR resolves
  • [x] Documented the changes in code (API docs will be generated automatically)
  • [x] Updated the tests
  • [x] All tests are passing

PhilippeR26 avatar Nov 22 '23 18:11 PhilippeR26

Deploy Preview for starknetjs ready!

Name Link
Latest commit 2dfb843196a3325c9d329213a5a9703f9c3f111c
Latest deploy log https://app.netlify.com/sites/starknetjs/deploys/6578a58df09eaa000817fae1
Deploy Preview https://deploy-preview-851--starknetjs.netlify.app
Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

netlify[bot] avatar Nov 22 '23 18:11 netlify[bot]

I opened PR#1 with some modifications.

It boils down to two main alterations: changed the names so it is more apparent that the new entities are related to each other; merged the logic from src/utils/txResponse/index.ts and src/utils/txResponse/txResponseVariant.ts to simplify them.

penovicp avatar Nov 27 '23 07:11 penovicp

I opened PR#1 with some modifications.

It boils down to two main alterations: changed the names so it is more apparent that the new entities are related to each other; merged the logic from src/utils/txResponse/index.ts and src/utils/txResponse/txResponseVariant.ts to simplify them.

PR merged. Small question : is it still useful to perform checks on sequencer?

PhilippeR26 avatar Nov 28 '23 09:11 PhilippeR26

I opened PR#1 with some modifications. It boils down to two main alterations: changed the names so it is more apparent that the new entities are related to each other; merged the logic from src/utils/txResponse/index.ts and src/utils/txResponse/txResponseVariant.ts to simplify them.

PR merged. Small question : is it still useful to perform checks on sequencer?

Not now, maybe we will have Seqeuncer as a Service later

tabaktoni avatar Dec 05 '23 11:12 tabaktoni

All looks great, nice effort, the only issue I have with this is a diversion from the original idea, How do we now add this method to the response object? Originally we would map it as a non-enumerable prop.

tabaktoni avatar Dec 05 '23 11:12 tabaktoni

All looks great, nice effort, the only issue I have with this is a diversion from the original idea, How do we now add this method to the response object? Originally we would map it as a non-enumerable prop.

Not sure to have understood. I see 2 possibilities :

  • As waitForTransaction is an old and a very common method, do not change anything to its output. Then create something that will analyse this output. It's what I proposed.
  • Break the compatibility with the current interface, and the response of waitForTransaction becomes a complex object/class including some analysis functions. Do you see a third way? Or may be return a such type as response (will be clash with status property) :
export type GetTransactionReceiptResponse = (
  | SuccessfulTransactionReceiptResponse
  | RevertedTransactionReceiptResponse
  | RejectedTransactionReceiptResponse
) &
  TransactionReceiptUtility;

PhilippeR26 avatar Dec 05 '23 13:12 PhilippeR26

All looks great, nice effort, the only issue I have with this is a diversion from the original idea, How do we now add this method to the response object? Originally we would map it as a non-enumerable prop.

Not sure to have understood. I see 2 possibilities :

  • As waitForTransaction is an old and a very common method, do not change anything to its output. Then create something that will analyse this output. It's what I proposed.
  • Break the compatibility with the current interface, and the response of waitForTransaction becomes a complex object/class including some analysis functions. Do you see a third way? Or may be return a such type as response (will be clash with status property) :
export type GetTransactionReceiptResponse = (
  | SuccessfulTransactionReceiptResponse
  | RevertedTransactionReceiptResponse
  | RejectedTransactionReceiptResponse
) &
  TransactionReceiptUtility;

Adding none enumerable methods would not break anything, you would have same object props, and the object will inherit from its proto methods like isSuccess, isRejected, isReverted, and isError.

with this one can do:

const txReceipt = await provider.waitForTransaction(result.transaction_hash);
txReceipt.isSuccess(() => {
  ... whatever on success do
})

But enumerable props from txReceipt will be the same.

Or one could also do for continuation:

const txReceipt = await provider.waitForTransaction(result.transaction_hash);
if(txReceipt.isSuccess()){
 ... whatever on success do
}

tabaktoni avatar Dec 11 '23 09:12 tabaktoni

OK. What I made : I modified the Receipt class constructor, setting all existing keys to enumerable: false, and adding all the properties of the received data, with enumerable: true.

I have added :

export type GetTransactionReceiptResponse = GetTransactionReceiptResponseWoHelper & Receipt;

and getTransactionReceipt() ends with :

return new Receipt(txReceiptWoHelper) as GetTransactionReceiptResponse;

and it works as you requested.

PhilippeR26 avatar Dec 12 '23 18:12 PhilippeR26

Is it possible to refactor this to target beta, and drop all sequencer stuff? @PhilippeR26

tabaktoni avatar Jan 23 '24 09:01 tabaktoni

superseded by https://github.com/starknet-io/starknet.js/pull/1020

ivpavici avatar Mar 19 '24 14:03 ivpavici