Closed khssnv closed 7 months ago
+1 How did you solve this one?
Hey there,
One option would be to use the following:
...
who, err := registry.ProcessDecodedFieldValue[*types.AccountID](
event.Fields,
func(fieldIndex int, field *registry.DecodedField) bool {
return field.Name == "sp_core.crypto.AccountId32.who"
},
func(value any) (*types.AccountID, error) {
fields, ok := value.(registry.DecodedFields)
if !ok {
return nil, fmt.Errorf("unexpected value: %v", value)
}
accByteSlice, err := registry.GetDecodedFieldAsSliceOfType[types.U8](fields, func(fieldIndex int, field *registry.DecodedField) bool {
return fieldIndex == 0
})
if err != nil {
return nil, err
}
var accBytes []byte
for _, accByte := range accByteSlice {
accBytes = append(accBytes, byte(accByte))
}
return types.NewAccountID(accBytes)
},
)
...
Alternatively, you could use a field override for the slice of bytes that we manually convert above, as follows:
...
// 1 is the lookup index for the `[u8; 32]` field on Centrifuge chain, on your chain it might differ, make sure to double-check this.
retriever, err := NewDefaultEventRetriever(state.NewEventProvider(api.RPC.State), api.RPC.State, registry.FieldOverride{
FieldLookupIndex: 1,
FieldDecoder: ®istry.ValueDecoder[types.AccountID]{},
})
...
who, err := registry.ProcessDecodedFieldValue[types.AccountID](
event.Fields,
func(fieldIndex int, field *registry.DecodedField) bool {
return field.Name == "sp_core.crypto.AccountId32.who"
},
func(value any) (types.AccountID, error) {
fields, ok := value.(registry.DecodedFields)
if !ok {
return types.AccountID{}, fmt.Errorf("unexpected value: %v", value)
}
return registry.GetDecodedFieldAsType[types.AccountID](fields, func(fieldIndex int, field *registry.DecodedField) bool {
return fieldIndex == 0
})
},
)
@khssnv @Dancia Can I go ahead and close this or do you still need support here?
Thank you @cdamian, your solution works for me. Could you also tell is there a general rule to decide when to use ProcessDecodedFieldValue
as you show for AccountID and when an easier GetDecodedFieldAsType
should work like it works for the U128 from my initial message?
Hello. Could you tell how to use
GetDecodedFieldAsType
properly? For instance, an attempt to decodeBalances.Deposit.who
field totypes.AccountID
returns the following error:At the same time there is no error with decoding
Balances.Deposit.amount
field totypes.U128
.Please find a code sample which generates the mentioned error below.
Thank you!
main.go
```go package main import ( "fmt" gsrpc "github.com/centrifuge/go-substrate-rpc-client/v4" "github.com/centrifuge/go-substrate-rpc-client/v4/registry" "github.com/centrifuge/go-substrate-rpc-client/v4/registry/retriever" "github.com/centrifuge/go-substrate-rpc-client/v4/registry/state" "github.com/centrifuge/go-substrate-rpc-client/v4/types" ) // Event type definition in substrate: // https://github.com/paritytech/polkadot-sdk/blob/a250652/substrate/frame/balances/src/lib.rs#L360 type Deposit struct { Who types.AccountID Amount types.U128 } func main() { api, _ := gsrpc.NewSubstrateAPI("ws://localhost:9944") eventsRetriever, _ := retriever.NewDefaultEventRetriever( state.NewEventProvider(api.RPC.State), api.RPC.State, ) sub, _ := api.RPC.Chain.SubscribeNewHeads() defer sub.Unsubscribe() for header := range sub.Chan() { blockHash, _ := api.RPC.Chain.GetBlockHash(uint64(header.Number)) events, _ := eventsRetriever.GetEvents(blockHash) for _, event := range events { if event.Name == "Balances.Deposit" { who, err := registry.GetDecodedFieldAsType[types.AccountID]( event.Fields, func(fieldIndex int, field *registry.DecodedField) bool { return fieldIndex == 0 }, ) if err != nil { fmt.Printf("Balances.Deposit.Who: %s\n", err.Error()) } fmt.Printf("Who: %s \n", who) amount, err := registry.GetDecodedFieldAsType[types.U128]( event.Fields, func(fieldIndex int, field *registry.DecodedField) bool { return fieldIndex == 1 }, ) if err != nil { fmt.Printf("Amount parsing err: %s\n", err.Error()) } fmt.Printf("Amount: %s \n", amount) deposit := &Deposit{ Who: who, Amount: amount, } fmt.Printf("Deposit: %v \n", deposit) } } } } ``` ```console $ go run main.go Balances.Deposit.Who: decoded field value processing error: decoded field value type mismatch: expected types.AccountID, got registry.DecodedFields Who: Amount: 195024070 Deposit: &{[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] 195024070} Balances.Deposit.Who: decoded field value processing error: decoded field value type mismatch: expected types.AccountID, got registry.DecodedFields Who: Amount: 195024070 Deposit: &{[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] 195024070} ```