diff --git a/api/openapi.yml b/api/openapi.yml index af660c7..c620296 100644 --- a/api/openapi.yml +++ b/api/openapi.yml @@ -10,13 +10,88 @@ servers: - url: "https://tonapi.io" - url: "https://testnet.tonapi.io" - url: "http://localhost:8081" + +tags: + - name: Accounts + externalDocs: + description: Additional documentation + url: https://docs.tonconsole.com/tonapi/rest-api/accounts + - name: NFT + externalDocs: + description: Additional documentation + url: https://docs.tonconsole.com/tonapi/rest-api/nft + - name: Jettons + externalDocs: + description: Additional documentation + url: https://docs.tonconsole.com/tonapi/rest-api/jettons + - name: DNS + externalDocs: + description: Additional documentation + url: https://docs.tonconsole.com/tonapi/rest-api/dns + - name: Wallet + externalDocs: + description: Additional documentation + url: https://docs.tonconsole.com/tonapi/rest-api/wallet + - name: Rates + externalDocs: + description: Additional documentation + url: https://docs.tonconsole.com/tonapi/rest-api/rates + - name: Staking + externalDocs: + description: Additional documentation + url: https://docs.tonconsole.com/tonapi/rest-api/staking + - name: Traces + externalDocs: + description: Additional documentation + url: https://docs.tonconsole.com/tonapi/rest-api/traces + - name: Events + externalDocs: + description: Additional documentation + url: https://docs.tonconsole.com/tonapi/rest-api/events + - name: Storage + externalDocs: + description: Additional documentation + url: https://docs.tonconsole.com/tonapi/rest-api/storage + - name: Connect + externalDocs: + description: Additional documentation + url: https://docs.tonconsole.com/tonapi/rest-api/connect + - name: Gasless + externalDocs: + description: Additional documentation + url: https://docs.tonconsole.com/tonapi/rest-api/gasless + - name: Multisig + externalDocs: + description: Additional documentation + url: https://docs.tonconsole.com/tonapi/rest-api/multisig + - name: Blockchain + externalDocs: + description: Additional documentation + url: https://docs.tonconsole.com/tonapi/rest-api/blockchain + - name: Lite Server + externalDocs: + description: Additional documentation + url: https://docs.tonconsole.com/tonapi/rest-api/liteserver + - name: Emulation + externalDocs: + description: Additional documentation + url: https://docs.tonconsole.com/tonapi/rest-api/emulation + - name: Inscriptions + externalDocs: + description: Additional documentation + url: https://docs.tonconsole.com/tonapi/rest-api/inscriptions + - name: Utilities + externalDocs: + description: Additional documentation + url: https://docs.tonconsole.com/tonapi/rest-api/utilities + paths: /v2/status: get: description: Status operationId: status tags: - - Blockchain + - Utilities responses: '200': description: status @@ -390,29 +465,12 @@ paths: $ref: '#/components/schemas/BlockchainAccountInspect' 'default': $ref: '#/components/responses/Error' - /v2/message/decode: - post: - description: Decode a given message. Only external incoming messages can be decoded currently. - operationId: decodeMessage - tags: - - Emulation - requestBody: - $ref: "#/components/requestBodies/Boc" - responses: - '200': - description: decoded message - content: - application/json: - schema: - $ref: '#/components/schemas/DecodedMessage' - 'default': - $ref: '#/components/responses/Error' /v2/address/{account_id}/parse: get: description: parse address and display in all formats operationId: addressParse tags: - - Accounts + - Utilities parameters: - $ref: '#/components/parameters/accountIDParameter' responses: @@ -459,99 +517,6 @@ paths: type: boolean default: $ref: '#/components/responses/Error' - - /v2/events/emulate: - post: - description: Emulate sending message to blockchain - operationId: emulateMessageToEvent - tags: - - Emulation - parameters: - - $ref: '#/components/parameters/i18n' - - name: ignore_signature_check - in: query - required: false - schema: - type: boolean - requestBody: - $ref: "#/components/requestBodies/Boc" - responses: - '200': - description: emulated event - content: - application/json: - schema: - $ref: '#/components/schemas/Event' - 'default': - $ref: '#/components/responses/Error' - /v2/traces/emulate: - post: - description: Emulate sending message to blockchain - operationId: emulateMessageToTrace - tags: - - Emulation - parameters: - - name: ignore_signature_check - in: query - required: false - schema: - type: boolean - requestBody: - $ref: "#/components/requestBodies/Boc" - responses: - '200': - description: emulated trace - content: - application/json: - schema: - $ref: '#/components/schemas/Trace' - 'default': - $ref: '#/components/responses/Error' - /v2/wallet/emulate: - post: - description: Emulate sending message to blockchain - operationId: emulateMessageToWallet - tags: - - Emulation - parameters: - - $ref: '#/components/parameters/i18n' - requestBody: - $ref: "#/components/requestBodies/EmulationBoc" - responses: - '200': - description: emulated message - content: - application/json: - schema: - $ref: '#/components/schemas/MessageConsequences' - 'default': - $ref: '#/components/responses/Error' - /v2/accounts/{account_id}/events/emulate: - post: - description: Emulate sending message to blockchain - operationId: emulateMessageToAccountEvent - tags: - - Emulation - parameters: - - $ref: '#/components/parameters/i18n' - - $ref: '#/components/parameters/accountIDParameter' - - name: ignore_signature_check - in: query - required: false - schema: - type: boolean - requestBody: - $ref: "#/components/requestBodies/Boc" - responses: - '200': - description: emulated message to account - content: - application/json: - schema: - $ref: '#/components/schemas/AccountEvent' - 'default': - $ref: '#/components/responses/Error' - /v2/accounts/_bulk: post: description: Get human-friendly information about several accounts without low-level details. @@ -634,6 +599,7 @@ paths: - $ref: '#/components/parameters/accountIDParameter' - $ref: '#/components/parameters/jettonIDParameter' - $ref: '#/components/parameters/currenciesQuery' + - $ref: '#/components/parameters/supportedExtensions' responses: '200': description: account jetton balance @@ -771,6 +737,7 @@ paths: $ref: '#/components/responses/Error' /v2/accounts/{account_id}/nfts/history: get: + x-question: duplicate of getNftHistoryByID ? description: Get the transfer nft history operationId: getAccountNftHistory tags: @@ -1981,9 +1948,26 @@ paths: example: "NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2ODQ3..." 'default': $ref: '#/components/responses/Error' + /v2/wallet/{account_id}/seqno: + get: + description: Get account seqno + operationId: getAccountSeqno + tags: + - Wallet + parameters: + - $ref: '#/components/parameters/accountIDParameter' + responses: + '200': + description: account seqno + content: + application/json: + schema: + $ref: '#/components/schemas/Seqno' + 'default': + $ref: '#/components/responses/Error' /v2/gasless/config: get: - description: "Returns configuration of gasless transfers" + description: Returns configuration of gasless transfers operationId: gaslessConfig tags: - Gasless @@ -1998,7 +1982,7 @@ paths: $ref: '#/components/responses/Error' /v2/gasless/estimate/{master_id}: post: - description: "Estimates the cost of the given messages and returns a payload to sign." + description: Estimates the cost of the given messages and returns a payload to sign operationId: gaslessEstimate parameters: - name: master_id @@ -2024,6 +2008,7 @@ paths: $ref: '#/components/responses/Error' /v2/gasless/send: post: + description: Submits the signed gasless transaction message to the network operationId: gaslessSend tags: - Gasless @@ -2051,23 +2036,6 @@ paths: $ref: '#/components/schemas/Accounts' 'default': $ref: '#/components/responses/Error' - /v2/wallet/{account_id}/seqno: - get: - description: Get account seqno - operationId: getAccountSeqno - tags: - - Wallet - parameters: - - $ref: '#/components/parameters/accountIDParameter' - responses: - '200': - description: account seqno - content: - application/json: - schema: - $ref: '#/components/schemas/Seqno' - 'default': - $ref: '#/components/responses/Error' /v2/liteserver/get_masterchain_info: get: @@ -2725,7 +2693,118 @@ paths: $ref: '#/components/schemas/Multisig' 'default': $ref: '#/components/responses/Error' - + /v2/message/decode: + post: + description: Decode a given message. Only external incoming messages can be decoded currently. + operationId: decodeMessage + tags: + - Emulation + requestBody: + $ref: "#/components/requestBodies/Boc" + responses: + '200': + description: decoded message + content: + application/json: + schema: + $ref: '#/components/schemas/DecodedMessage' + 'default': + $ref: '#/components/responses/Error' + /v2/events/emulate: + post: + description: Emulate sending message to blockchain + operationId: emulateMessageToEvent + tags: + - Emulation + - Events + parameters: + - $ref: '#/components/parameters/i18n' + - name: ignore_signature_check + in: query + required: false + schema: + type: boolean + requestBody: + $ref: "#/components/requestBodies/Boc" + responses: + '200': + description: emulated event + content: + application/json: + schema: + $ref: '#/components/schemas/Event' + 'default': + $ref: '#/components/responses/Error' + /v2/traces/emulate: + post: + description: Emulate sending message to blockchain + operationId: emulateMessageToTrace + tags: + - Emulation + - Traces + parameters: + - name: ignore_signature_check + in: query + required: false + schema: + type: boolean + requestBody: + $ref: "#/components/requestBodies/Boc" + responses: + '200': + description: emulated trace + content: + application/json: + schema: + $ref: '#/components/schemas/Trace' + 'default': + $ref: '#/components/responses/Error' + /v2/wallet/emulate: + post: + description: Emulate sending message to blockchain + operationId: emulateMessageToWallet + tags: + - Emulation + - Wallet + parameters: + - $ref: '#/components/parameters/i18n' + requestBody: + $ref: "#/components/requestBodies/EmulationBoc" + responses: + '200': + description: emulated message + content: + application/json: + schema: + $ref: '#/components/schemas/MessageConsequences' + 'default': + $ref: '#/components/responses/Error' + /v2/accounts/{account_id}/events/emulate: + post: + description: Emulate sending message to blockchain + operationId: emulateMessageToAccountEvent + tags: + - Emulation + - Accounts + parameters: + - $ref: '#/components/parameters/i18n' + - $ref: '#/components/parameters/accountIDParameter' + - name: ignore_signature_check + in: query + required: false + schema: + type: boolean + requestBody: + $ref: "#/components/requestBodies/Boc" + responses: + '200': + description: emulated message to account + content: + application/json: + schema: + $ref: '#/components/schemas/AccountEvent' + 'default': + $ref: '#/components/responses/Error' components: parameters: masterchainSeqno: @@ -3013,7 +3092,7 @@ components: type: array items: type: string - example: ["custom_payload"] + example: [ "custom_payload" ] currencyQuery: in: query name: currency @@ -3588,9 +3667,9 @@ components: format: cell example: b5ee9c72010106010044000114ff00f4a413f4bcf2c80b01020120020302014804050004f2300038d06c21d31f30ed44d0d33f3001c00197a4c8cb3fc9ed549330f206e20011a13431da89a1a67e61 interfaces: - type: array - items: - type: string + type: array + items: + type: string Message: type: object required: @@ -5266,6 +5345,8 @@ components: example: https://cache.tonapi.io/images/jetton.jpg verification: $ref: '#/components/schemas/JettonVerificationType' + custom_payload_api_uri: # todo: maybe remove + type: string JettonBalance: type: object required: @@ -5495,6 +5576,8 @@ components: - approvals_num - expiration_date - risk + - creation_date + - signed_by properties: address: type: string @@ -5524,6 +5607,15 @@ components: format: int64 risk: $ref: '#/components/schemas/Risk' + creation_date: + type: integer + format: int64 + signed_by: + type: array + items: + type: string + format: address + example: "0:da6b1b6663a0e4d18cc8574ccd9db5296e367dd9324706f3bbd9eb1cd2caf0bf" Refund: type: object required: @@ -6707,6 +6799,9 @@ components: items: type: string example: [ "https://coinmarketcap.com/currencies/drv/", "https://www.coingecko.com/en/coins/durov" ] + custom_payload_api_uri: + type: string + example: "https://claim-api.tonapi.io/jettons/TESTMINT" InscriptionBalances: type: object required: @@ -6807,7 +6902,7 @@ components: JettonTransferPayload: type: object required: - - payload + - payload properties: custom_payload: type: string diff --git a/oas_client_gen.go b/oas_client_gen.go index 0f963cb..8934ad4 100644 --- a/oas_client_gen.go +++ b/oas_client_gen.go @@ -97,6 +97,8 @@ type Invoker interface { GaslessEstimate(ctx context.Context, request *GaslessEstimateReq, params GaslessEstimateParams) (*SignRawParams, error) // GaslessSend invokes gaslessSend operation. // + // Submits the signed gasless transaction message to the network. + // // POST /v2/gasless/send GaslessSend(ctx context.Context, request *GaslessSendReq) error // GetAccount invokes getAccount operation. @@ -1874,6 +1876,8 @@ func (c *Client) sendGaslessEstimate(ctx context.Context, request *GaslessEstima // GaslessSend invokes gaslessSend operation. // +// Submits the signed gasless transaction message to the network. +// // POST /v2/gasless/send func (c *Client) GaslessSend(ctx context.Context, request *GaslessSendReq) error { _, err := c.sendGaslessSend(ctx, request) @@ -3261,6 +3265,29 @@ func (c *Client) sendGetAccountJettonBalance(ctx context.Context, params GetAcco return res, errors.Wrap(err, "encode query") } } + { + // Encode "supported_extensions" parameter. + cfg := uri.QueryParameterEncodingConfig{ + Name: "supported_extensions", + Style: uri.QueryStyleForm, + Explode: false, + } + + if err := q.EncodeParam(cfg, func(e uri.Encoder) error { + return e.EncodeArray(func(e uri.Encoder) error { + for i, item := range params.SupportedExtensions { + if err := func() error { + return e.EncodeValue(conv.StringToString(item)) + }(); err != nil { + return errors.Wrapf(err, "[%d]", i) + } + } + return nil + }) + }); err != nil { + return res, errors.Wrap(err, "encode query") + } + } u.RawQuery = q.Values().Encode() stage = "EncodeRequest" diff --git a/oas_json_gen.go b/oas_json_gen.go index e913ea4..3b00c56 100644 --- a/oas_json_gen.go +++ b/oas_json_gen.go @@ -23286,9 +23286,15 @@ func (s *JettonMetadata) encodeFields(e *jx.Encoder) { e.ArrEnd() } } + { + if s.CustomPayloadAPIURI.Set { + e.FieldStart("custom_payload_api_uri") + s.CustomPayloadAPIURI.Encode(e) + } + } } -var jsonFieldsNameOfJettonMetadata = [9]string{ +var jsonFieldsNameOfJettonMetadata = [10]string{ 0: "address", 1: "name", 2: "symbol", @@ -23298,6 +23304,7 @@ var jsonFieldsNameOfJettonMetadata = [9]string{ 6: "social", 7: "websites", 8: "catalogs", + 9: "custom_payload_api_uri", } // Decode decodes JettonMetadata from json. @@ -23434,6 +23441,16 @@ func (s *JettonMetadata) Decode(d *jx.Decoder) error { }(); err != nil { return errors.Wrap(err, "decode field \"catalogs\"") } + case "custom_payload_api_uri": + if err := func() error { + s.CustomPayloadAPIURI.Reset() + if err := s.CustomPayloadAPIURI.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"custom_payload_api_uri\"") + } default: return d.Skip() } @@ -23667,15 +23684,22 @@ func (s *JettonPreview) encodeFields(e *jx.Encoder) { e.FieldStart("verification") s.Verification.Encode(e) } + { + if s.CustomPayloadAPIURI.Set { + e.FieldStart("custom_payload_api_uri") + s.CustomPayloadAPIURI.Encode(e) + } + } } -var jsonFieldsNameOfJettonPreview = [6]string{ +var jsonFieldsNameOfJettonPreview = [7]string{ 0: "address", 1: "name", 2: "symbol", 3: "decimals", 4: "image", 5: "verification", + 6: "custom_payload_api_uri", } // Decode decodes JettonPreview from json. @@ -23757,6 +23781,16 @@ func (s *JettonPreview) Decode(d *jx.Decoder) error { }(); err != nil { return errors.Wrap(err, "decode field \"verification\"") } + case "custom_payload_api_uri": + if err := func() error { + s.CustomPayloadAPIURI.Reset() + if err := s.CustomPayloadAPIURI.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"custom_payload_api_uri\"") + } default: return d.Skip() } @@ -26321,9 +26355,21 @@ func (s *MultisigOrder) encodeFields(e *jx.Encoder) { e.FieldStart("risk") s.Risk.Encode(e) } + { + e.FieldStart("creation_date") + e.Int64(s.CreationDate) + } + { + e.FieldStart("signed_by") + e.ArrStart() + for _, elem := range s.SignedBy { + e.Str(elem) + } + e.ArrEnd() + } } -var jsonFieldsNameOfMultisigOrder = [8]string{ +var jsonFieldsNameOfMultisigOrder = [10]string{ 0: "address", 1: "order_seqno", 2: "threshold", @@ -26332,6 +26378,8 @@ var jsonFieldsNameOfMultisigOrder = [8]string{ 5: "approvals_num", 6: "expiration_date", 7: "risk", + 8: "creation_date", + 9: "signed_by", } // Decode decodes MultisigOrder from json. @@ -26339,7 +26387,7 @@ func (s *MultisigOrder) Decode(d *jx.Decoder) error { if s == nil { return errors.New("invalid: unable to decode MultisigOrder to nil") } - var requiredBitSet [1]uint8 + var requiredBitSet [2]uint8 if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { switch string(k) { @@ -26445,6 +26493,38 @@ func (s *MultisigOrder) Decode(d *jx.Decoder) error { }(); err != nil { return errors.Wrap(err, "decode field \"risk\"") } + case "creation_date": + requiredBitSet[1] |= 1 << 0 + if err := func() error { + v, err := d.Int64() + s.CreationDate = int64(v) + if err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"creation_date\"") + } + case "signed_by": + requiredBitSet[1] |= 1 << 1 + if err := func() error { + s.SignedBy = make([]string, 0) + if err := d.Arr(func(d *jx.Decoder) error { + var elem string + v, err := d.Str() + elem = string(v) + if err != nil { + return err + } + s.SignedBy = append(s.SignedBy, elem) + return nil + }); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"signed_by\"") + } default: return d.Skip() } @@ -26454,8 +26534,9 @@ func (s *MultisigOrder) Decode(d *jx.Decoder) error { } // Validate required fields. var failures []validate.FieldError - for i, mask := range [1]uint8{ + for i, mask := range [2]uint8{ 0b11111111, + 0b00000011, } { if result := (requiredBitSet[i] & mask) ^ mask; result != 0 { // Mask only required fields and check equality to mask using XOR. diff --git a/oas_parameters_gen.go b/oas_parameters_gen.go index a0ed28a..a635ff4 100644 --- a/oas_parameters_gen.go +++ b/oas_parameters_gen.go @@ -151,6 +151,8 @@ type GetAccountJettonBalanceParams struct { JettonID string // Accept ton and all possible fiat currencies, separated by commas. Currencies []string + // Comma separated list supported extensions. + SupportedExtensions []string } // GetAccountJettonHistoryByIDParams is parameters of getAccountJettonHistoryByID operation. diff --git a/oas_schemas_gen.go b/oas_schemas_gen.go index 7a494bf..821da98 100644 --- a/oas_schemas_gen.go +++ b/oas_schemas_gen.go @@ -7691,15 +7691,16 @@ func (s *JettonInfo) SetHoldersCount(val int32) { // Ref: #/components/schemas/JettonMetadata type JettonMetadata struct { - Address string `json:"address"` - Name string `json:"name"` - Symbol string `json:"symbol"` - Decimals string `json:"decimals"` - Image OptString `json:"image"` - Description OptString `json:"description"` - Social []string `json:"social"` - Websites []string `json:"websites"` - Catalogs []string `json:"catalogs"` + Address string `json:"address"` + Name string `json:"name"` + Symbol string `json:"symbol"` + Decimals string `json:"decimals"` + Image OptString `json:"image"` + Description OptString `json:"description"` + Social []string `json:"social"` + Websites []string `json:"websites"` + Catalogs []string `json:"catalogs"` + CustomPayloadAPIURI OptString `json:"custom_payload_api_uri"` } // GetAddress returns the value of Address. @@ -7747,6 +7748,11 @@ func (s *JettonMetadata) GetCatalogs() []string { return s.Catalogs } +// GetCustomPayloadAPIURI returns the value of CustomPayloadAPIURI. +func (s *JettonMetadata) GetCustomPayloadAPIURI() OptString { + return s.CustomPayloadAPIURI +} + // SetAddress sets the value of Address. func (s *JettonMetadata) SetAddress(val string) { s.Address = val @@ -7792,6 +7798,11 @@ func (s *JettonMetadata) SetCatalogs(val []string) { s.Catalogs = val } +// SetCustomPayloadAPIURI sets the value of CustomPayloadAPIURI. +func (s *JettonMetadata) SetCustomPayloadAPIURI(val OptString) { + s.CustomPayloadAPIURI = val +} + // Ref: #/components/schemas/JettonMintAction type JettonMintAction struct { Recipient AccountAddress `json:"recipient"` @@ -7843,12 +7854,13 @@ func (s *JettonMintAction) SetJetton(val JettonPreview) { // Ref: #/components/schemas/JettonPreview type JettonPreview struct { - Address string `json:"address"` - Name string `json:"name"` - Symbol string `json:"symbol"` - Decimals int `json:"decimals"` - Image string `json:"image"` - Verification JettonVerificationType `json:"verification"` + Address string `json:"address"` + Name string `json:"name"` + Symbol string `json:"symbol"` + Decimals int `json:"decimals"` + Image string `json:"image"` + Verification JettonVerificationType `json:"verification"` + CustomPayloadAPIURI OptString `json:"custom_payload_api_uri"` } // GetAddress returns the value of Address. @@ -7881,6 +7893,11 @@ func (s *JettonPreview) GetVerification() JettonVerificationType { return s.Verification } +// GetCustomPayloadAPIURI returns the value of CustomPayloadAPIURI. +func (s *JettonPreview) GetCustomPayloadAPIURI() OptString { + return s.CustomPayloadAPIURI +} + // SetAddress sets the value of Address. func (s *JettonPreview) SetAddress(val string) { s.Address = val @@ -7911,6 +7928,11 @@ func (s *JettonPreview) SetVerification(val JettonVerificationType) { s.Verification = val } +// SetCustomPayloadAPIURI sets the value of CustomPayloadAPIURI. +func (s *JettonPreview) SetCustomPayloadAPIURI(val OptString) { + s.CustomPayloadAPIURI = val +} + // Ref: #/components/schemas/JettonQuantity type JettonQuantity struct { Quantity string `json:"quantity"` @@ -8959,6 +8981,8 @@ type MultisigOrder struct { ApprovalsNum int32 `json:"approvals_num"` ExpirationDate int64 `json:"expiration_date"` Risk Risk `json:"risk"` + CreationDate int64 `json:"creation_date"` + SignedBy []string `json:"signed_by"` } // GetAddress returns the value of Address. @@ -9001,6 +9025,16 @@ func (s *MultisigOrder) GetRisk() Risk { return s.Risk } +// GetCreationDate returns the value of CreationDate. +func (s *MultisigOrder) GetCreationDate() int64 { + return s.CreationDate +} + +// GetSignedBy returns the value of SignedBy. +func (s *MultisigOrder) GetSignedBy() []string { + return s.SignedBy +} + // SetAddress sets the value of Address. func (s *MultisigOrder) SetAddress(val string) { s.Address = val @@ -9041,6 +9075,16 @@ func (s *MultisigOrder) SetRisk(val Risk) { s.Risk = val } +// SetCreationDate sets the value of CreationDate. +func (s *MultisigOrder) SetCreationDate(val int64) { + s.CreationDate = val +} + +// SetSignedBy sets the value of SignedBy. +func (s *MultisigOrder) SetSignedBy(val []string) { + s.SignedBy = val +} + // Ref: #/components/schemas/Multisigs type Multisigs struct { Multisigs []Multisig `json:"multisigs"` diff --git a/oas_validators_gen.go b/oas_validators_gen.go index 9a060da..e5b4b57 100644 --- a/oas_validators_gen.go +++ b/oas_validators_gen.go @@ -3308,6 +3308,17 @@ func (s *MultisigOrder) Validate() error { Error: err, }) } + if err := func() error { + if s.SignedBy == nil { + return errors.New("nil is invalid value") + } + return nil + }(); err != nil { + failures = append(failures, validate.FieldError{ + Name: "signed_by", + Error: err, + }) + } if len(failures) > 0 { return &validate.Error{Fields: failures} }