github.com/stafiprotocol/go-substrate-rpc-client@v1.4.7/client/sub_query.go (about) 1 package client 2 3 import ( 4 "encoding/json" 5 "errors" 6 "fmt" 7 "strings" 8 "time" 9 10 "github.com/ethereum/go-ethereum/common/hexutil" 11 "github.com/gorilla/websocket" 12 scalecodec "github.com/itering/scale.go" 13 scaleTypes "github.com/itering/scale.go/types" 14 scaleBytes "github.com/itering/scale.go/types/scaleBytes" 15 "github.com/itering/scale.go/utiles" 16 "github.com/itering/substrate-api-rpc/rpc" 17 "github.com/stafiprotocol/go-substrate-rpc-client/config" 18 "github.com/stafiprotocol/go-substrate-rpc-client/pkg/stafidecoder" 19 gsrpc "github.com/stafiprotocol/go-substrate-rpc-client/rpc" 20 "github.com/stafiprotocol/go-substrate-rpc-client/types" 21 commonTypes "github.com/stafiprotocol/go-substrate-rpc-client/types/common" 22 ) 23 24 func (sc *GsrpcClient) FlashApi() (*gsrpc.RPCS, error) { 25 _, err := sc.rpcs.Chain.GetBlockHashLatest() 26 if err != nil { 27 var rpcs *gsrpc.RPCS 28 for i := 0; i < 3; i++ { 29 rpcs, err = gsrpc.NewRPCS(sc.endpoint) 30 if err == nil { 31 break 32 } else { 33 time.Sleep(time.Millisecond * 100) 34 } 35 } 36 if rpcs != nil { 37 sc.rpcs = rpcs 38 } 39 } 40 return sc.rpcs, nil 41 } 42 43 func (sc *GsrpcClient) Address() string { 44 return sc.key.Address 45 } 46 47 func (sc *GsrpcClient) GetLatestBlockNumber() (uint64, error) { 48 h, err := sc.GetHeaderLatest() 49 if err != nil { 50 return 0, err 51 } 52 53 return uint64(h.Number), nil 54 } 55 56 func (sc *GsrpcClient) GetFinalizedBlockNumber() (uint64, error) { 57 hash, err := sc.GetFinalizedHead() 58 if err != nil { 59 return 0, err 60 } 61 62 header, err := sc.GetHeader(hash) 63 if err != nil { 64 return 0, err 65 } 66 67 return uint64(header.Number), nil 68 } 69 70 func (sc *GsrpcClient) GetHeaderLatest() (*types.Header, error) { 71 api, err := sc.FlashApi() 72 if err != nil { 73 return nil, err 74 } 75 return api.Chain.GetHeaderLatest() 76 } 77 78 func (sc *GsrpcClient) GetFinalizedHead() (types.Hash, error) { 79 api, err := sc.FlashApi() 80 if err != nil { 81 return types.NewHash([]byte{}), err 82 } 83 return api.Chain.GetFinalizedHead() 84 } 85 86 func (sc *GsrpcClient) GetHeader(blockHash types.Hash) (*types.Header, error) { 87 api, err := sc.FlashApi() 88 if err != nil { 89 return nil, err 90 } 91 return api.Chain.GetHeader(blockHash) 92 } 93 94 func (sc *GsrpcClient) GetBlockNumber(blockHash types.Hash) (uint64, error) { 95 head, err := sc.GetHeader(blockHash) 96 if err != nil { 97 return 0, err 98 } 99 100 return uint64(head.Number), nil 101 } 102 103 // queryStorage performs a storage lookup. Arguments may be nil, result must be a pointer. 104 func (sc *GsrpcClient) QueryStorage(prefix, method string, arg1, arg2 []byte, result interface{}) (bool, error) { 105 entry, err := sc.FindStorageEntryMetadata(prefix, method) 106 if err != nil { 107 return false, err 108 } 109 110 var key types.StorageKey 111 keySeted := false 112 if entry.IsNMap() { 113 hashers, err := entry.Hashers() 114 if err != nil { 115 return false, err 116 } 117 118 if len(hashers) == 1 { 119 key, err = types.CreateStorageKeyWithEntryMeta(uint8(sc.metaDataVersion), entry, prefix, method, arg1) 120 if err != nil { 121 return false, err 122 } 123 keySeted = true 124 } 125 } 126 127 if !keySeted { 128 key, err = types.CreateStorageKeyWithEntryMeta(uint8(sc.metaDataVersion), entry, prefix, method, arg1, arg2) 129 if err != nil { 130 return false, err 131 } 132 } 133 134 api, err := sc.FlashApi() 135 if err != nil { 136 return false, err 137 } 138 sc.log.Trace("QueryStorage", "entry.IsNMap", entry.IsNMap(), "metaDataVersion", sc.metaDataVersion, "prefix", prefix, "method", method, "arg1", arg1, "arg2", arg2, "storageKey", hexutil.Encode(key)) 139 140 ok, err := api.State.GetStorageLatest(key, result) 141 if err != nil { 142 return false, err 143 } 144 145 return ok, nil 146 } 147 148 func (sc *GsrpcClient) GetLatestRuntimeVersion() (*types.RuntimeVersion, error) { 149 api, err := sc.FlashApi() 150 if err != nil { 151 return nil, err 152 } 153 rv, err := api.State.GetRuntimeVersionLatest() 154 if err != nil { 155 return nil, err 156 } 157 158 return rv, nil 159 } 160 161 func (sc *GsrpcClient) GetLatestNonce() (types.U32, error) { 162 ac, err := sc.GetAccountInfo() 163 if err != nil { 164 return 0, err 165 } 166 167 return ac.Nonce, nil 168 } 169 170 func (sc *GsrpcClient) GetAccountInfo() (*types.AccountInfo, error) { 171 ac := new(types.AccountInfo) 172 exist, err := sc.QueryStorage("System", "Account", sc.key.PublicKey, nil, &ac) 173 if err != nil { 174 return nil, err 175 } 176 177 if !exist { 178 return nil, errors.New("account not exist") 179 } 180 181 return ac, nil 182 } 183 184 func (sc *GsrpcClient) PublicKey() []byte { 185 return sc.key.PublicKey 186 } 187 188 func (sc *GsrpcClient) StakingLedger(ac types.AccountID) (*StakingLedger, error) { 189 s := new(StakingLedger) 190 exist, err := sc.QueryStorage(config.StakingModuleId, config.StorageLedger, ac[:], nil, s) 191 if err != nil { 192 return nil, err 193 } 194 195 if !exist { 196 return nil, fmt.Errorf("can not get active for account: %s", hexutil.Encode(ac[:])) 197 } 198 199 return s, nil 200 } 201 202 func (sc *GsrpcClient) FreeBalance(who []byte) (types.U128, error) { 203 if sc.addressType == AddressTypeMultiAddress { 204 info, err := sc.NewVersionAccountInfo(who) 205 if err != nil { 206 return types.U128{}, err 207 } 208 return info.Data.Free, nil 209 } 210 211 info, err := sc.AccountInfo(who) 212 if err != nil { 213 return types.U128{}, err 214 } 215 216 return info.Data.Free, nil 217 } 218 219 func (sc *GsrpcClient) AccountInfo(who []byte) (*types.AccountInfo, error) { 220 ac := new(types.AccountInfo) 221 exist, err := sc.QueryStorage(config.SystemModuleId, config.StorageAccount, who, nil, ac) 222 if err != nil { 223 return nil, err 224 } 225 226 if !exist { 227 return nil, fmt.Errorf("can not get accountInfo for account: %s", hexutil.Encode(who)) 228 } 229 230 return ac, nil 231 } 232 233 func (sc *GsrpcClient) NewVersionAccountInfo(who []byte) (*AccountInfo, error) { 234 ac := new(AccountInfo) 235 exist, err := sc.QueryStorage(config.SystemModuleId, config.StorageAccount, who, nil, ac) 236 if err != nil { 237 return nil, err 238 } 239 240 if !exist { 241 return nil, fmt.Errorf("can not get accountInfo for account: %s", hexutil.Encode(who)) 242 } 243 return ac, nil 244 } 245 246 func (sc *GsrpcClient) ExistentialDeposit() (types.U128, error) { 247 _, err := sc.FlashApi() 248 if err != nil { 249 return types.U128{}, err 250 } 251 var e types.U128 252 err = sc.GetConst(config.BalancesModuleId, config.ConstExistentialDeposit, &e) 253 if err != nil { 254 return types.U128{}, err 255 } 256 return e, nil 257 } 258 259 func (sc *GsrpcClient) GetConst(prefix, name string, res interface{}) error { 260 261 switch sc.chainType { 262 case ChainTypeStafi: 263 return sc.rpcs.State.GetConst(prefix, name, &res) 264 case ChainTypePolkadot: 265 blockHash, err := sc.GetFinalizedHead() 266 if err != nil { 267 return err 268 } 269 md, err := sc.getPolkaMetaDecoder(blockHash.Hex()) 270 if err != nil { 271 return err 272 } 273 274 for _, mod := range md.Metadata.Metadata.Modules { 275 if string(mod.Prefix) == prefix { 276 for _, cons := range mod.Constants { 277 if cons.Name == name { 278 279 return types.DecodeFromHexString(cons.ConstantsValue, res) 280 } 281 } 282 } 283 } 284 return fmt.Errorf("could not find constant %s.%s", prefix, name) 285 default: 286 return errors.New("GetConst chainType not supported") 287 } 288 } 289 290 func (sc *GsrpcClient) FindStorageEntryMetadata(module string, fn string) (types.StorageEntryMetadata, error) { 291 switch sc.chainType { 292 case ChainTypeStafi: 293 meta, err := sc.rpcs.State.GetMetadataLatest() 294 if err != nil { 295 return nil, err 296 } 297 298 return meta.FindStorageEntryMetadata(module, fn) 299 case ChainTypePolkadot: 300 blockHash, err := sc.GetFinalizedHead() 301 if err != nil { 302 return nil, err 303 } 304 md, err := sc.getPolkaMetaDecoder(blockHash.Hex()) 305 if err != nil { 306 return nil, err 307 } 308 309 for _, mod := range md.Metadata.Metadata.Modules { 310 if string(mod.Prefix) != module { 311 continue 312 } 313 for _, s := range mod.Storage { 314 if string(s.Name) != fn { 315 continue 316 } 317 318 sfm := types.StorageFunctionMetadataV13{ 319 Name: types.Text(s.Name), 320 } 321 322 if s.Type.PlainType != nil { 323 sfm.Type = types.StorageFunctionTypeV13{ 324 IsType: true, 325 AsType: types.Type(*s.Type.PlainType), 326 } 327 } 328 329 if s.Type.DoubleMapType != nil { 330 dmt := types.DoubleMapTypeV10{ 331 Key1: types.Type(s.Type.DoubleMapType.Key), 332 Key2: types.Type(s.Type.DoubleMapType.Key2), 333 Value: types.Type(s.Type.DoubleMapType.Value), 334 Hasher: TransformHasher(s.Type.DoubleMapType.Hasher), 335 Key2Hasher: TransformHasher(s.Type.DoubleMapType.Key2Hasher), 336 } 337 338 sfm.Type = types.StorageFunctionTypeV13{ 339 IsDoubleMap: true, 340 AsDoubleMap: dmt, 341 } 342 } 343 344 if s.Type.MapType != nil { 345 mt := types.MapTypeV10{ 346 Key: types.Type(s.Type.MapType.Key), 347 Value: types.Type(s.Type.MapType.Value), 348 Linked: s.Type.MapType.IsLinked, 349 Hasher: TransformHasher(s.Type.MapType.Hasher), 350 } 351 352 sfm.Type = types.StorageFunctionTypeV13{ 353 IsMap: true, 354 AsMap: mt, 355 } 356 } 357 358 if s.Type.NMapType != nil { 359 keys := make([]types.Type, 0) 360 for _, key := range s.Type.NMapType.KeyVec { 361 keys = append(keys, types.Type(key)) 362 } 363 364 hashers := make([]types.StorageHasherV10, 0) 365 for _, hasher := range s.Type.NMapType.Hashers { 366 hashers = append(hashers, TransformHasher(hasher)) 367 } 368 369 nmt := types.NMapTypeV13{ 370 Keys: keys, 371 Hashers: hashers, 372 Value: types.Type(s.Type.NMapType.Value), 373 } 374 375 sfm.Type = types.StorageFunctionTypeV13{ 376 IsNMap: true, 377 AsNMap: nmt, 378 } 379 } 380 381 return sfm, nil 382 } 383 return nil, fmt.Errorf("storage %v not found within module %v", fn, module) 384 } 385 return nil, fmt.Errorf("module %v not found in metadata", module) 386 default: 387 return nil, errors.New("chainType not supported") 388 } 389 } 390 391 func (sc *GsrpcClient) FindCallIndex(call string) (types.CallIndex, error) { 392 switch sc.chainType { 393 case ChainTypeStafi: 394 meta, err := sc.rpcs.State.GetMetadataLatest() 395 if err != nil { 396 return types.CallIndex{}, err 397 } 398 399 return meta.FindCallIndex(call) 400 case ChainTypePolkadot: 401 blockHash, err := sc.GetFinalizedHead() 402 if err != nil { 403 return types.CallIndex{}, err 404 } 405 406 md, err := sc.getPolkaMetaDecoder(blockHash.Hex()) 407 if err != nil { 408 return types.CallIndex{}, err 409 } 410 s := strings.Split(call, ".") 411 412 for _, mod := range md.Metadata.Metadata.Modules { 413 if string(mod.Name) != s[0] { 414 continue 415 } 416 for ci, f := range mod.Calls { 417 if string(f.Name) == s[1] { 418 return types.CallIndex{SectionIndex: uint8(mod.Index), MethodIndex: uint8(ci)}, nil 419 } 420 } 421 return types.CallIndex{}, fmt.Errorf("method %v not found within module %v for call %v", s[1], mod.Name, call) 422 } 423 return types.CallIndex{}, fmt.Errorf("module %v not found in metadata for call %v", s[0], call) 424 425 default: 426 return types.CallIndex{}, errors.New("FindCallIndex chainType not supported") 427 } 428 } 429 430 func TransformHasher(Hasher string) types.StorageHasherV10 { 431 if Hasher == "Blake2_128" { 432 return types.StorageHasherV10{IsBlake2_128: true} 433 } 434 435 if Hasher == "Blake2_256" { 436 return types.StorageHasherV10{IsBlake2_256: true} 437 } 438 439 if Hasher == "Blake2_128Concat" { 440 return types.StorageHasherV10{IsBlake2_128Concat: true} 441 } 442 443 if Hasher == "Twox128" { 444 return types.StorageHasherV10{IsTwox128: true} 445 } 446 447 if Hasher == "Twox256" { 448 return types.StorageHasherV10{IsTwox256: true} 449 } 450 451 if Hasher == "Twox64Concat" { 452 return types.StorageHasherV10{IsTwox64Concat: true} 453 } 454 455 return types.StorageHasherV10{IsIdentity: true} 456 } 457 458 func (sc *GsrpcClient) sendWsRequest(v interface{}, action []byte) error { 459 460 retry := 0 461 for { 462 if retry >= 100 { 463 return fmt.Errorf("sendWsRequest reach retry limit") 464 } 465 466 if poolConn, err := sc.initial(); err != nil { 467 return err 468 } else { 469 470 if err = poolConn.Conn.WriteMessage(websocket.TextMessage, action); err != nil { 471 poolConn.MarkUnusable() 472 sc.wsPool.Put(poolConn) 473 474 sc.log.Debug("websocket send error", "err", err) 475 time.Sleep(time.Millisecond * 100) 476 retry++ 477 continue 478 } 479 480 if err = poolConn.Conn.ReadJSON(v); err != nil { 481 poolConn.MarkUnusable() 482 sc.wsPool.Put(poolConn) 483 484 sc.log.Debug("websocket read error", "err", err) 485 time.Sleep(time.Millisecond * 100) 486 retry++ 487 continue 488 } 489 490 sc.wsPool.Put(poolConn) 491 return nil 492 } 493 } 494 } 495 496 func (sc *GsrpcClient) GetBlock(blockHash string) (*rpc.Block, error) { 497 v := &rpc.JsonRpcResult{} 498 if err := sc.sendWsRequest(v, rpc.ChainGetBlock(wsId, blockHash)); err != nil { 499 return nil, err 500 } 501 rpcBlock := v.ToBlock() 502 return &rpcBlock.Block, nil 503 } 504 505 func (sc *GsrpcClient) GetExtrinsics(blockHash string) ([]*Transaction, error) { 506 blk, err := sc.GetBlock(blockHash) 507 if err != nil { 508 return nil, err 509 } 510 511 exts := make([]*Transaction, 0) 512 switch sc.chainType { 513 case ChainTypeStafi: 514 md, err := sc.getStafiMetaDecoder(blockHash) 515 if err != nil { 516 return nil, err 517 } 518 e := new(stafi_decoder.ExtrinsicDecoder) 519 option := stafi_decoder.ScaleDecoderOption{Metadata: &md.Metadata} 520 for _, raw := range blk.Extrinsics { 521 e.Init(stafi_decoder.ScaleBytes{Data: utiles.HexToBytes(raw)}, &option) 522 e.Process() 523 if e.ExtrinsicHash != "" && e.ContainsTransaction { 524 ext := &Transaction{ 525 ExtrinsicHash: e.ExtrinsicHash, 526 CallModuleName: e.CallModule.Name, 527 CallName: e.Call.Name, 528 Address: e.Address, 529 Params: e.Params, 530 } 531 exts = append(exts, ext) 532 } 533 } 534 return exts, nil 535 case ChainTypePolkadot: 536 md, err := sc.getPolkaMetaDecoder(blockHash) 537 if err != nil { 538 return nil, err 539 } 540 e := new(scalecodec.ExtrinsicDecoder) 541 option := scaleTypes.ScaleDecoderOption{Metadata: &md.Metadata} 542 for _, raw := range blk.Extrinsics { 543 e.Init(scaleBytes.ScaleBytes{Data: utiles.HexToBytes(raw)}, &option) 544 e.Process() 545 decodeExtrinsic := e.Value.(map[string]interface{}) 546 var ce ChainExtrinsic 547 eb, _ := json.Marshal(decodeExtrinsic) 548 _ = json.Unmarshal(eb, &ce) 549 if e.ExtrinsicHash != "" && e.ContainsTransaction { 550 params := make([]commonTypes.ExtrinsicParam, 0) 551 for _, p := range e.Params { 552 params = append(params, commonTypes.ExtrinsicParam{ 553 Name: p.Name, 554 Type: p.Type, 555 Value: p.Value, 556 }) 557 } 558 559 ext := &Transaction{ 560 ExtrinsicHash: e.ExtrinsicHash, 561 CallModuleName: ce.CallModule, 562 CallName: ce.CallModuleFunction, 563 Address: e.Address, 564 Params: params, 565 } 566 exts = append(exts, ext) 567 } 568 } 569 return exts, nil 570 default: 571 return nil, errors.New("chainType not supported") 572 } 573 } 574 575 func (sc *GsrpcClient) GetBlockHash(blockNum uint64) (string, error) { 576 v := &rpc.JsonRpcResult{} 577 if err := sc.sendWsRequest(v, rpc.ChainGetBlockHash(wsId, int(blockNum))); err != nil { 578 return "", fmt.Errorf("websocket get block hash error: %v", err) 579 } 580 581 blockHash, err := v.ToString() 582 if err != nil { 583 return "", fmt.Errorf("ChainGetBlockHash get error %v", err) 584 } 585 if blockHash == "" { 586 return "", fmt.Errorf("ChainGetBlockHash error, blockHash empty") 587 } 588 589 return blockHash, nil 590 } 591 592 func (sc *GsrpcClient) GetChainEvents(blockHash string) ([]*ChainEvent, error) { 593 v := &rpc.JsonRpcResult{} 594 if err := sc.sendWsRequest(v, rpc.StateGetStorage(wsId, storageKey, blockHash)); err != nil { 595 return nil, fmt.Errorf("websocket get event raw error: %v", err) 596 } 597 eventRaw, err := v.ToString() 598 if err != nil { 599 return nil, err 600 } 601 602 var events []*ChainEvent 603 switch sc.chainType { 604 case ChainTypeStafi: 605 md, err := sc.getStafiMetaDecoder(blockHash) 606 if err != nil { 607 return nil, err 608 } 609 e := stafi_decoder.EventsDecoder{} 610 option := stafi_decoder.ScaleDecoderOption{Metadata: &md.Metadata} 611 e.Init(stafi_decoder.ScaleBytes{Data: utiles.HexToBytes(eventRaw)}, &option) 612 e.Process() 613 b, err := json.Marshal(e.Value) 614 if err != nil { 615 return nil, err 616 } 617 err = json.Unmarshal(b, &events) 618 if err != nil { 619 return nil, err 620 } 621 622 case ChainTypePolkadot: 623 md, err := sc.getPolkaMetaDecoder(blockHash) 624 if err != nil { 625 return nil, err 626 } 627 option := scaleTypes.ScaleDecoderOption{Metadata: &md.Metadata} 628 629 e := scalecodec.EventsDecoder{} 630 e.Init(scaleBytes.ScaleBytes{Data: utiles.HexToBytes(eventRaw)}, &option) 631 632 e.Process() 633 634 b, err := json.Marshal(e.Value) 635 if err != nil { 636 return nil, err 637 } 638 err = json.Unmarshal(b, &events) 639 if err != nil { 640 return nil, err 641 } 642 643 default: 644 return nil, errors.New("chainType not supported") 645 } 646 647 return events, nil 648 } 649 650 func (sc *GsrpcClient) GetEvents(blockNum uint64) ([]*ChainEvent, error) { 651 blockHash, err := sc.GetBlockHash(blockNum) 652 if err != nil { 653 return nil, err 654 } 655 656 evts, err := sc.GetChainEvents(blockHash) 657 if err != nil { 658 return nil, err 659 } 660 661 return evts, nil 662 } 663 664 func (sc *GsrpcClient) GetBlockTimestampAndExtrinsics(height uint64) (uint64, map[int]*Transaction, error) { 665 blockHash, err := sc.GetBlockHash(height) 666 if err != nil { 667 return 0, nil, err 668 } 669 670 blk, err := sc.GetBlock(blockHash) 671 if err != nil { 672 return 0, nil, err 673 } 674 if len(blk.Extrinsics) == 0 { 675 return 0, nil, fmt.Errorf("no set time extrinsic in block: %d", height) 676 } 677 678 exts := make(map[int]*Transaction) 679 switch sc.chainType { 680 case ChainTypeStafi: 681 e := new(stafi_decoder.ExtrinsicDecoder) 682 md, err := sc.getStafiMetaDecoder(blockHash) 683 if err != nil { 684 return 0, nil, err 685 } 686 687 option := stafi_decoder.ScaleDecoderOption{Metadata: &md.Metadata, Spec: md.Spec} 688 689 raw := blk.Extrinsics[0] 690 e.Init(stafi_decoder.ScaleBytes{Data: utiles.HexToBytes(raw)}, &option) 691 e.Process() 692 if len(e.Params) == 0 { 693 return 0, nil, fmt.Errorf("no params") 694 } 695 stamp, ok := e.Params[0].Value.(int) 696 if !ok { 697 return 0, nil, fmt.Errorf("interface not ok: %s", e.Params[0].Value) 698 } 699 700 for index, raw := range blk.Extrinsics { 701 e.Init(stafi_decoder.ScaleBytes{Data: utiles.HexToBytes(raw)}, &option) 702 e.Process() 703 if e.ExtrinsicHash != "" && e.ContainsTransaction { 704 ext := &Transaction{ 705 ExtrinsicHash: utiles.AddHex(e.ExtrinsicHash), 706 CallModuleName: e.CallModule.Name, 707 CallName: e.Call.Name, 708 Address: e.Address, 709 Params: e.Params, 710 } 711 exts[index] = ext 712 } 713 } 714 return uint64(stamp), exts, nil 715 case ChainTypePolkadot: 716 e := new(scalecodec.ExtrinsicDecoder) 717 md, err := sc.getPolkaMetaDecoder(blockHash) 718 if err != nil { 719 return 0, nil, err 720 } 721 option := scaleTypes.ScaleDecoderOption{Metadata: &md.Metadata, Spec: md.Spec} 722 723 raw := blk.Extrinsics[0] 724 e.Init(scaleBytes.ScaleBytes{Data: utiles.HexToBytes(raw)}, &option) 725 e.Process() 726 727 if len(e.Params) == 0 { 728 return 0, nil, fmt.Errorf("no params") 729 } 730 stamp, ok := e.Params[0].Value.(int) 731 if !ok { 732 return 0, nil, fmt.Errorf("interface not ok: %s", e.Params[0].Value) 733 } 734 735 for index, raw := range blk.Extrinsics { 736 e.Init(scaleBytes.ScaleBytes{Data: utiles.HexToBytes(raw)}, &option) 737 e.Process() 738 739 call, exist := e.Metadata.CallIndex[e.CallIndex] 740 if !exist { 741 return 0, nil, fmt.Errorf("callIndex: %s not exist metaData", e.CallIndex) 742 } 743 744 if e.ExtrinsicHash != "" && e.ContainsTransaction { 745 params := make([]commonTypes.ExtrinsicParam, 0) 746 for _, p := range e.Params { 747 params = append(params, commonTypes.ExtrinsicParam{ 748 Name: p.Name, 749 Type: p.Type, 750 Value: p.Value, 751 }) 752 } 753 ext := &Transaction{ 754 ExtrinsicHash: utiles.AddHex(e.ExtrinsicHash), 755 CallModuleName: call.Module.Name, 756 CallName: call.Call.Name, 757 Address: e.Address, 758 Params: params, 759 } 760 exts[index] = ext 761 } 762 } 763 764 return uint64(stamp), exts, nil 765 default: 766 return 0, nil, errors.New("chainType not supported") 767 } 768 } 769 770 func (sc *GsrpcClient) GetPaymentQueryInfo(encodedExtrinsic string) (paymentInfo *rpc.PaymentQueryInfo, err error) { 771 v := &rpc.JsonRpcResult{} 772 if err = sc.sendWsRequest(v, rpc.SystemPaymentQueryInfo(wsId, encodedExtrinsic)); err != nil { 773 return 774 } 775 776 paymentInfo = v.ToPaymentQueryInfo() 777 if paymentInfo == nil { 778 return nil, fmt.Errorf("get PaymentQueryInfo error") 779 } 780 return 781 } 782 783 func (c *GsrpcClient) CurrentEra() (uint32, error) { 784 var index uint32 785 exist, err := c.QueryStorage(config.StakingModuleId, config.StorageActiveEra, nil, nil, &index) 786 if err != nil { 787 return 0, err 788 } 789 790 if !exist { 791 return 0, fmt.Errorf("unable to get activeEraInfo") 792 } 793 794 return index, nil 795 }