Skip to content

Commit

Permalink
Finish subscribeTransactionStatus
Browse files Browse the repository at this point in the history
  • Loading branch information
thiagodeev committed Jan 16, 2025
1 parent d01082f commit f386d32
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 0 deletions.
5 changes: 5 additions & 0 deletions rpc/types_transaction_receipt.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,11 @@ type TxnStatusResp struct {
FailureReason string `json:"failure_reason,omitempty"`
}

type NewTxnStatusResp struct {
TransactionHash *felt.Felt `json:"transaction_hash"`
Status TxnStatusResp `json:"status"`
}

type TransactionReceiptWithBlockInfo struct {
TransactionReceipt
BlockHash *felt.Felt `json:"block_hash,omitempty"`
Expand Down
24 changes: 24 additions & 0 deletions rpc/websocket.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,27 @@ func (provider *WsProvider) SubscribeEvents(ctx context.Context, events chan<- *
}
return sub, nil
}

// Transaction Status subscription.
// Creates a WebSocket stream which at first fires an event with the current known transaction status,
// followed by events for every transaction status update
//
// Parameters:
// - ctx: The context.Context object for controlling the function call
// - newStatus: The channel to send the new transaction status to
// - transactionHash: The transaction hash to fetch status updates for
// Returns:
// - clientSubscription: The client subscription object, used to unsubscribe from the stream and to get errors
// - error: An error, if any
func (provider *WsProvider) SubscribeTransactionStatus(ctx context.Context, newStatus chan<- *NewTxnStatusResp, transactionHash *felt.Felt) (*client.ClientSubscription, error) {
sub, err := provider.c.SubscribeWithSliceArgs(ctx, "starknet", "_subscribeTransactionStatus", newStatus, transactionHash, WithBlockTag("latest"))
if err != nil {
return nil, tryUnwrapToRPCErr(err, ErrTooManyBlocksBack, ErrBlockNotFound)
}
// TODO: wait for Juno to implement this. This is the correct implementation by the spec
// sub, err := provider.c.SubscribeWithSliceArgs(ctx, "starknet", "_subscribeTransactionStatus", newStatus, transactionHash)
// if err != nil {
// return nil, tryUnwrapToRPCErr(err)
// }
return sub, nil
}
50 changes: 50 additions & 0 deletions rpc/websocket_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -346,3 +346,53 @@ func TestSubscribeEvents(t *testing.T) {
}
})
}

func TestSubscribeTransactionStatus(t *testing.T) {
if testEnv != "testnet" {
t.Skip("Skipping test as it requires a testnet environment")
}

testConfig := beforeEach(t)
require.NotNil(t, testConfig.wsBase, "wsProvider base is not set")

provider := testConfig.provider
blockInterface, err := provider.BlockWithTxHashes(context.Background(), WithBlockTag("latest"))
require.NoError(t, err)
block := blockInterface.(*BlockTxHashes)

txHash := new(felt.Felt)
for _, tx := range block.Transactions {
status, err := provider.GetTransactionStatus(context.Background(), tx)
require.NoError(t, err)
if status.FinalityStatus == TxnStatus_Accepted_On_L2 {
txHash = tx
break
}
}

t.Run("normal call", func(t *testing.T) {
wsProvider, err := NewWebsocketProvider(testConfig.wsBase)
require.NoError(t, err)
defer wsProvider.Close()

events := make(chan *NewTxnStatusResp)
sub, err := wsProvider.SubscribeTransactionStatus(context.Background(), events, txHash)
require.NoError(t, err)
require.NotNil(t, sub)
defer sub.Unsubscribe()

for {
select {
case resp := <-events:
require.IsType(t, &NewTxnStatusResp{}, resp)
require.Equal(t, txHash, resp.TransactionHash)
require.Equal(t, TxnStatus_Accepted_On_L2, resp.Status.FinalityStatus)
return
case err := <-sub.Err():
require.NoError(t, err)
case <-time.After(4 * time.Second):
t.Fatal("timeout waiting for events")
}
}
})
}

0 comments on commit f386d32

Please sign in to comment.