From cc9c26da9ecddb8aeb75461aa01ed62f67b8ce19 Mon Sep 17 00:00:00 2001 From: jiahuihu Date: Wed, 19 Aug 2026 14:06:16 -0400 Subject: [PATCH 1/4] feat(graphql): add simulateStateChanges query and simulated state-change types --- internal/serve/graphql/generated/generated.go | 2380 ++++++++++++++--- .../serve/graphql/generated/models_gen.go | 140 + .../graphql/resolvers/queries.resolvers.go | 6 + .../resolvers/statechange.resolvers.go | 40 +- .../serve/graphql/schema/queries.graphqls | 8 + .../serve/graphql/schema/simulation.graphqls | 102 + 6 files changed, 2209 insertions(+), 467 deletions(-) create mode 100644 internal/serve/graphql/schema/simulation.graphqls diff --git a/internal/serve/graphql/generated/generated.go b/internal/serve/graphql/generated/generated.go index 57ff739b7..195b4120b 100644 --- a/internal/serve/graphql/generated/generated.go +++ b/internal/serve/graphql/generated/generated.go @@ -303,9 +303,10 @@ type ComplexityRoot struct { } Query struct { - AccountByAddress func(childComplexity int, address string) int - OperationByID func(childComplexity int, id int64) int - TransactionByHash func(childComplexity int, hash string) int + AccountByAddress func(childComplexity int, address string) int + OperationByID func(childComplexity int, id int64) int + SimulateStateChanges func(childComplexity int, transactionXdr string) int + TransactionByHash func(childComplexity int, hash string) int } SACBalance struct { @@ -388,6 +389,46 @@ type ComplexityRoot struct { Transaction func(childComplexity int) int } + SimulatedAccountCreatedChange struct { + AccountAddress func(childComplexity int) int + Category func(childComplexity int) int + CreatorAddress func(childComplexity int) int + Reason func(childComplexity int) int + } + + SimulatedAllowanceChange struct { + AccountAddress func(childComplexity int) int + Amount func(childComplexity int) int + Category func(childComplexity int) int + ExpirationLedger func(childComplexity int) int + Reason func(childComplexity int) int + Spender func(childComplexity int) int + TokenID func(childComplexity int) int + } + + SimulatedBalanceAuthorizationChange struct { + AccountAddress func(childComplexity int) int + Category func(childComplexity int) int + Flags func(childComplexity int) int + LiquidityPoolID func(childComplexity int) int + Reason func(childComplexity int) int + TokenID func(childComplexity int) int + } + + SimulatedBalanceChange struct { + AccountAddress func(childComplexity int) int + Amount func(childComplexity int) int + Category func(childComplexity int) int + Reason func(childComplexity int) int + ToMuxedID func(childComplexity int) int + TokenID func(childComplexity int) int + } + + SimulatedStateChanges struct { + LatestLedger func(childComplexity int) int + StateChanges func(childComplexity int) int + } + StateChangeConnection struct { Edges func(childComplexity int) int PageInfo func(childComplexity int) int @@ -626,6 +667,7 @@ type QueryResolver interface { TransactionByHash(ctx context.Context, hash string) (*types.Transaction, error) AccountByAddress(ctx context.Context, address string) (*types.Account, error) OperationByID(ctx context.Context, id int64) (*types.Operation, error) + SimulateStateChanges(ctx context.Context, transactionXdr string) (*SimulatedStateChanges, error) } type SignerAddedChangeResolver interface { Category(ctx context.Context, obj *types.SignerAddedChangeModel) (types.StateChangeCategory, error) @@ -1821,6 +1863,17 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin } return e.ComplexityRoot.Query.OperationByID(childComplexity, args["id"].(int64)), true + case "Query.simulateStateChanges": + if e.ComplexityRoot.Query.SimulateStateChanges == nil { + break + } + + args, err := ec.field_Query_simulateStateChanges_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.ComplexityRoot.Query.SimulateStateChanges(childComplexity, args["transactionXdr"].(string)), true case "Query.transactionByHash": if e.ComplexityRoot.Query.TransactionByHash == nil { break @@ -2177,6 +2230,161 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.SignerUpdatedChange.Transaction(childComplexity), true + case "SimulatedAccountCreatedChange.accountAddress": + if e.ComplexityRoot.SimulatedAccountCreatedChange.AccountAddress == nil { + break + } + + return e.ComplexityRoot.SimulatedAccountCreatedChange.AccountAddress(childComplexity), true + case "SimulatedAccountCreatedChange.category": + if e.ComplexityRoot.SimulatedAccountCreatedChange.Category == nil { + break + } + + return e.ComplexityRoot.SimulatedAccountCreatedChange.Category(childComplexity), true + case "SimulatedAccountCreatedChange.creatorAddress": + if e.ComplexityRoot.SimulatedAccountCreatedChange.CreatorAddress == nil { + break + } + + return e.ComplexityRoot.SimulatedAccountCreatedChange.CreatorAddress(childComplexity), true + case "SimulatedAccountCreatedChange.reason": + if e.ComplexityRoot.SimulatedAccountCreatedChange.Reason == nil { + break + } + + return e.ComplexityRoot.SimulatedAccountCreatedChange.Reason(childComplexity), true + + case "SimulatedAllowanceChange.accountAddress": + if e.ComplexityRoot.SimulatedAllowanceChange.AccountAddress == nil { + break + } + + return e.ComplexityRoot.SimulatedAllowanceChange.AccountAddress(childComplexity), true + case "SimulatedAllowanceChange.amount": + if e.ComplexityRoot.SimulatedAllowanceChange.Amount == nil { + break + } + + return e.ComplexityRoot.SimulatedAllowanceChange.Amount(childComplexity), true + case "SimulatedAllowanceChange.category": + if e.ComplexityRoot.SimulatedAllowanceChange.Category == nil { + break + } + + return e.ComplexityRoot.SimulatedAllowanceChange.Category(childComplexity), true + case "SimulatedAllowanceChange.expirationLedger": + if e.ComplexityRoot.SimulatedAllowanceChange.ExpirationLedger == nil { + break + } + + return e.ComplexityRoot.SimulatedAllowanceChange.ExpirationLedger(childComplexity), true + case "SimulatedAllowanceChange.reason": + if e.ComplexityRoot.SimulatedAllowanceChange.Reason == nil { + break + } + + return e.ComplexityRoot.SimulatedAllowanceChange.Reason(childComplexity), true + case "SimulatedAllowanceChange.spender": + if e.ComplexityRoot.SimulatedAllowanceChange.Spender == nil { + break + } + + return e.ComplexityRoot.SimulatedAllowanceChange.Spender(childComplexity), true + case "SimulatedAllowanceChange.tokenId": + if e.ComplexityRoot.SimulatedAllowanceChange.TokenID == nil { + break + } + + return e.ComplexityRoot.SimulatedAllowanceChange.TokenID(childComplexity), true + + case "SimulatedBalanceAuthorizationChange.accountAddress": + if e.ComplexityRoot.SimulatedBalanceAuthorizationChange.AccountAddress == nil { + break + } + + return e.ComplexityRoot.SimulatedBalanceAuthorizationChange.AccountAddress(childComplexity), true + case "SimulatedBalanceAuthorizationChange.category": + if e.ComplexityRoot.SimulatedBalanceAuthorizationChange.Category == nil { + break + } + + return e.ComplexityRoot.SimulatedBalanceAuthorizationChange.Category(childComplexity), true + case "SimulatedBalanceAuthorizationChange.flags": + if e.ComplexityRoot.SimulatedBalanceAuthorizationChange.Flags == nil { + break + } + + return e.ComplexityRoot.SimulatedBalanceAuthorizationChange.Flags(childComplexity), true + case "SimulatedBalanceAuthorizationChange.liquidityPoolId": + if e.ComplexityRoot.SimulatedBalanceAuthorizationChange.LiquidityPoolID == nil { + break + } + + return e.ComplexityRoot.SimulatedBalanceAuthorizationChange.LiquidityPoolID(childComplexity), true + case "SimulatedBalanceAuthorizationChange.reason": + if e.ComplexityRoot.SimulatedBalanceAuthorizationChange.Reason == nil { + break + } + + return e.ComplexityRoot.SimulatedBalanceAuthorizationChange.Reason(childComplexity), true + case "SimulatedBalanceAuthorizationChange.tokenId": + if e.ComplexityRoot.SimulatedBalanceAuthorizationChange.TokenID == nil { + break + } + + return e.ComplexityRoot.SimulatedBalanceAuthorizationChange.TokenID(childComplexity), true + + case "SimulatedBalanceChange.accountAddress": + if e.ComplexityRoot.SimulatedBalanceChange.AccountAddress == nil { + break + } + + return e.ComplexityRoot.SimulatedBalanceChange.AccountAddress(childComplexity), true + case "SimulatedBalanceChange.amount": + if e.ComplexityRoot.SimulatedBalanceChange.Amount == nil { + break + } + + return e.ComplexityRoot.SimulatedBalanceChange.Amount(childComplexity), true + case "SimulatedBalanceChange.category": + if e.ComplexityRoot.SimulatedBalanceChange.Category == nil { + break + } + + return e.ComplexityRoot.SimulatedBalanceChange.Category(childComplexity), true + case "SimulatedBalanceChange.reason": + if e.ComplexityRoot.SimulatedBalanceChange.Reason == nil { + break + } + + return e.ComplexityRoot.SimulatedBalanceChange.Reason(childComplexity), true + case "SimulatedBalanceChange.toMuxedId": + if e.ComplexityRoot.SimulatedBalanceChange.ToMuxedID == nil { + break + } + + return e.ComplexityRoot.SimulatedBalanceChange.ToMuxedID(childComplexity), true + case "SimulatedBalanceChange.tokenId": + if e.ComplexityRoot.SimulatedBalanceChange.TokenID == nil { + break + } + + return e.ComplexityRoot.SimulatedBalanceChange.TokenID(childComplexity), true + + case "SimulatedStateChanges.latestLedger": + if e.ComplexityRoot.SimulatedStateChanges.LatestLedger == nil { + break + } + + return e.ComplexityRoot.SimulatedStateChanges.LatestLedger(childComplexity), true + case "SimulatedStateChanges.stateChanges": + if e.ComplexityRoot.SimulatedStateChanges.StateChanges == nil { + break + } + + return e.ComplexityRoot.SimulatedStateChanges.StateChanges(childComplexity), true + case "StateChangeConnection.edges": if e.ComplexityRoot.StateChangeConnection.Edges == nil { break @@ -3160,6 +3368,14 @@ type Query { """Look up an operation by its ID (TOID).""" operationById(id: Int64!): Operation + + """ + Simulate an unsubmitted transaction and return the state changes it would + produce if submitted, in the same variant structure as the history API. + Currently accepts contract (Soroban) transactions, whose changes come from + RPC simulation; classic transactions are rejected as UNSUPPORTED_TRANSACTION. + """ + simulateStateChanges(transactionXdr: String!): SimulatedStateChanges! } `, BuiltIn: false}, {Name: "../schema/scalars.graphqls", Input: `"""RFC 3339 timestamp.""" @@ -3177,6 +3393,109 @@ this scalar carries larger values such as operation IDs (TOIDs) and stroop amounts. """ scalar Int64 +`, BuiltIn: false}, + {Name: "../schema/simulation.graphqls", Input: `""" +Result of simulating an unsubmitted transaction: the state changes the +indexer would produce if the transaction were submitted and included in a +ledger, in the same variant structure as the history API's state changes. +""" +type SimulatedStateChanges { + """Latest ledger the simulation was evaluated against.""" + latestLedger: UInt32! + """State changes the transaction would produce.""" + stateChanges: [BaseSimulatedStateChange!]! +} + +""" +Common contract implemented by every simulated state change. Simulated +variants mirror the history API's state-change types (same names with a +` + "`" + `Simulated` + "`" + ` prefix, same ` + "`" + `(category, reason)` + "`" + ` pairs and variant fields) but +omit the fields that only exist after a transaction is included in a ledger: +` + "`" + `ingestedAt` + "`" + `, ` + "`" + `ledgerCreatedAt` + "`" + `, ` + "`" + `ledgerNumber` + "`" + `, ` + "`" + `operation` + "`" + `, and +` + "`" + `transaction` + "`" + `. The affected account is exposed as a plain address rather than +an ` + "`" + `Account` + "`" + ` entity, since the account may not be indexed yet. + +The set of concrete types grows with the transaction sources the simulation +supports; today it covers the variants a contract (Soroban) transaction can +produce. +""" +interface BaseSimulatedStateChange { + """Category of account state this change affects.""" + category: StateChangeCategory! + """Why the change occurred. Each concrete type documents its valid reasons.""" + reason: StateChangeReason! + """Address of the account whose state would change.""" + accountAddress: String! +} + +""" +Simulated mirror of BalanceChange. The transaction-fee row is (BALANCE, DEBIT) +on the fee-paying account, estimated from the simulation's resource fee. +Pairs: (BALANCE, DEBIT), (BALANCE, CREDIT), (BALANCE, MINT), (BALANCE, BURN). +""" +type SimulatedBalanceChange implements BaseSimulatedStateChange { + category: StateChangeCategory! + reason: StateChangeReason! + accountAddress: String! + + """Contract ID of the token whose balance would move.""" + tokenId: String! + """Amount moved, as a decimal string in the token's smallest unit.""" + amount: String! + """CAP-67 destination memo carried by SEP-41 transfer/mint events (CREDIT and MINT only).""" + toMuxedId: String +} + +""" +Simulated mirror of AccountCreatedChange. For a contract deployment, +` + "`" + `accountAddress` + "`" + ` is the deployed contract's C-address. +Pair: (ACCOUNT, CREATE). +""" +type SimulatedAccountCreatedChange implements BaseSimulatedStateChange { + category: StateChangeCategory! + reason: StateChangeReason! + accountAddress: String! + + """Account that would create this one: the funder or the contract deployer.""" + creatorAddress: String! +} + +""" +Simulated mirror of AllowanceChange. +Pair: (ALLOWANCE, UPDATE). +""" +type SimulatedAllowanceChange implements BaseSimulatedStateChange { + category: StateChangeCategory! + reason: StateChangeReason! + accountAddress: String! + + """Contract ID of the token the allowance applies to.""" + tokenId: String! + """Address authorized to spend from the holder's balance.""" + spender: String! + """Approved allowance, as a decimal string in the token's smallest unit.""" + amount: String! + """Last ledger sequence at which the allowance is live.""" + expirationLedger: UInt32! +} + +""" +Simulated mirror of BalanceAuthorizationChange. Exactly one of tokenId / +liquidityPoolId is set. +Pairs: (BALANCE_AUTHORIZATION, SET), (BALANCE_AUTHORIZATION, CLEAR). +""" +type SimulatedBalanceAuthorizationChange implements BaseSimulatedStateChange { + category: StateChangeCategory! + reason: StateChangeReason! + accountAddress: String! + + """Contract ID of the asset; null for liquidity-pool-share trustlines.""" + tokenId: String + """Liquidity pool ID for pool-share trustlines; null for asset trustlines.""" + liquidityPoolId: String + """Trustline flags that would change; null for SAC contract-holder authorization, which has no flags.""" + flags: [TrustlineFlag!] +} `, BuiltIn: false}, {Name: "../schema/statechange.graphqls", Input: `""" Common contract implemented by every state change. A state change records one @@ -3879,6 +4198,17 @@ func (ec *executionContext) field_Query_operationById_args(ctx context.Context, return args, nil } +func (ec *executionContext) field_Query_simulateStateChanges_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := graphql.ProcessArgField(ctx, rawArgs, "transactionXdr", ec.unmarshalNString2string) + if err != nil { + return nil, err + } + args["transactionXdr"] = arg0 + return args, nil +} + func (ec *executionContext) field_Query_transactionByHash_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { var err error args := map[string]any{} @@ -10099,6 +10429,53 @@ func (ec *executionContext) fieldContext_Query_operationById(ctx context.Context return fc, nil } +func (ec *executionContext) _Query_simulateStateChanges(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_Query_simulateStateChanges, + func(ctx context.Context) (any, error) { + fc := graphql.GetFieldContext(ctx) + return ec.Resolvers.Query().SimulateStateChanges(ctx, fc.Args["transactionXdr"].(string)) + }, + nil, + ec.marshalNSimulatedStateChanges2ᚖgithubᚗcomᚋstellarᚋwalletᚑbackendᚋinternalᚋserveᚋgraphqlᚋgeneratedᚐSimulatedStateChanges, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_Query_simulateStateChanges(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "latestLedger": + return ec.fieldContext_SimulatedStateChanges_latestLedger(ctx, field) + case "stateChanges": + return ec.fieldContext_SimulatedStateChanges_stateChanges(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type SimulatedStateChanges", field.Name) + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field_Query_simulateStateChanges_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + func (ec *executionContext) _Query___type(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -12041,117 +12418,101 @@ func (ec *executionContext) fieldContext_SignerUpdatedChange_newWeight(_ context return fc, nil } -func (ec *executionContext) _StateChangeConnection_edges(ctx context.Context, field graphql.CollectedField, obj *StateChangeConnection) (ret graphql.Marshaler) { +func (ec *executionContext) _SimulatedAccountCreatedChange_category(ctx context.Context, field graphql.CollectedField, obj *SimulatedAccountCreatedChange) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, - ec.fieldContext_StateChangeConnection_edges, + ec.fieldContext_SimulatedAccountCreatedChange_category, func(ctx context.Context) (any, error) { - return obj.Edges, nil + return obj.Category, nil }, nil, - ec.marshalNStateChangeEdge2ᚕᚖgithubᚗcomᚋstellarᚋwalletᚑbackendᚋinternalᚋserveᚋgraphqlᚋgeneratedᚐStateChangeEdgeᚄ, + ec.marshalNStateChangeCategory2githubᚗcomᚋstellarᚋwalletᚑbackendᚋinternalᚋindexerᚋtypesᚐStateChangeCategory, true, true, ) } -func (ec *executionContext) fieldContext_StateChangeConnection_edges(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_SimulatedAccountCreatedChange_category(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "StateChangeConnection", + Object: "SimulatedAccountCreatedChange", Field: field, IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "node": - return ec.fieldContext_StateChangeEdge_node(ctx, field) - case "cursor": - return ec.fieldContext_StateChangeEdge_cursor(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type StateChangeEdge", field.Name) + return nil, errors.New("field of type StateChangeCategory does not have child fields") }, } return fc, nil } -func (ec *executionContext) _StateChangeConnection_pageInfo(ctx context.Context, field graphql.CollectedField, obj *StateChangeConnection) (ret graphql.Marshaler) { +func (ec *executionContext) _SimulatedAccountCreatedChange_reason(ctx context.Context, field graphql.CollectedField, obj *SimulatedAccountCreatedChange) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, - ec.fieldContext_StateChangeConnection_pageInfo, + ec.fieldContext_SimulatedAccountCreatedChange_reason, func(ctx context.Context) (any, error) { - return obj.PageInfo, nil + return obj.Reason, nil }, nil, - ec.marshalNPageInfo2ᚖgithubᚗcomᚋstellarᚋwalletᚑbackendᚋinternalᚋserveᚋgraphqlᚋgeneratedᚐPageInfo, + ec.marshalNStateChangeReason2githubᚗcomᚋstellarᚋwalletᚑbackendᚋinternalᚋindexerᚋtypesᚐStateChangeReason, true, true, ) } -func (ec *executionContext) fieldContext_StateChangeConnection_pageInfo(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_SimulatedAccountCreatedChange_reason(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "StateChangeConnection", + Object: "SimulatedAccountCreatedChange", Field: field, IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "startCursor": - return ec.fieldContext_PageInfo_startCursor(ctx, field) - case "endCursor": - return ec.fieldContext_PageInfo_endCursor(ctx, field) - case "hasNextPage": - return ec.fieldContext_PageInfo_hasNextPage(ctx, field) - case "hasPreviousPage": - return ec.fieldContext_PageInfo_hasPreviousPage(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type PageInfo", field.Name) + return nil, errors.New("field of type StateChangeReason does not have child fields") }, } return fc, nil } -func (ec *executionContext) _StateChangeEdge_node(ctx context.Context, field graphql.CollectedField, obj *StateChangeEdge) (ret graphql.Marshaler) { +func (ec *executionContext) _SimulatedAccountCreatedChange_accountAddress(ctx context.Context, field graphql.CollectedField, obj *SimulatedAccountCreatedChange) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, - ec.fieldContext_StateChangeEdge_node, + ec.fieldContext_SimulatedAccountCreatedChange_accountAddress, func(ctx context.Context) (any, error) { - return obj.Node, nil + return obj.AccountAddress, nil }, nil, - ec.marshalNBaseStateChange2githubᚗcomᚋstellarᚋwalletᚑbackendᚋinternalᚋserveᚋgraphqlᚋgeneratedᚐBaseStateChange, + ec.marshalNString2string, true, true, ) } -func (ec *executionContext) fieldContext_StateChangeEdge_node(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_SimulatedAccountCreatedChange_accountAddress(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "StateChangeEdge", + Object: "SimulatedAccountCreatedChange", Field: field, IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("FieldContext.Child cannot be called on type INTERFACE") + return nil, errors.New("field of type String does not have child fields") }, } return fc, nil } -func (ec *executionContext) _StateChangeEdge_cursor(ctx context.Context, field graphql.CollectedField, obj *StateChangeEdge) (ret graphql.Marshaler) { +func (ec *executionContext) _SimulatedAccountCreatedChange_creatorAddress(ctx context.Context, field graphql.CollectedField, obj *SimulatedAccountCreatedChange) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, - ec.fieldContext_StateChangeEdge_cursor, + ec.fieldContext_SimulatedAccountCreatedChange_creatorAddress, func(ctx context.Context) (any, error) { - return obj.Cursor, nil + return obj.CreatorAddress, nil }, nil, ec.marshalNString2string, @@ -12160,9 +12521,9 @@ func (ec *executionContext) _StateChangeEdge_cursor(ctx context.Context, field g ) } -func (ec *executionContext) fieldContext_StateChangeEdge_cursor(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_SimulatedAccountCreatedChange_creatorAddress(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "StateChangeEdge", + Object: "SimulatedAccountCreatedChange", Field: field, IsMethod: false, IsResolver: false, @@ -12173,14 +12534,14 @@ func (ec *executionContext) fieldContext_StateChangeEdge_cursor(_ context.Contex return fc, nil } -func (ec *executionContext) _ThresholdChange_category(ctx context.Context, field graphql.CollectedField, obj *types.ThresholdChangeModel) (ret graphql.Marshaler) { +func (ec *executionContext) _SimulatedAllowanceChange_category(ctx context.Context, field graphql.CollectedField, obj *SimulatedAllowanceChange) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, - ec.fieldContext_ThresholdChange_category, + ec.fieldContext_SimulatedAllowanceChange_category, func(ctx context.Context) (any, error) { - return ec.Resolvers.ThresholdChange().Category(ctx, obj) + return obj.Category, nil }, nil, ec.marshalNStateChangeCategory2githubᚗcomᚋstellarᚋwalletᚑbackendᚋinternalᚋindexerᚋtypesᚐStateChangeCategory, @@ -12189,12 +12550,12 @@ func (ec *executionContext) _ThresholdChange_category(ctx context.Context, field ) } -func (ec *executionContext) fieldContext_ThresholdChange_category(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_SimulatedAllowanceChange_category(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "ThresholdChange", + Object: "SimulatedAllowanceChange", Field: field, - IsMethod: true, - IsResolver: true, + IsMethod: false, + IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { return nil, errors.New("field of type StateChangeCategory does not have child fields") }, @@ -12202,14 +12563,14 @@ func (ec *executionContext) fieldContext_ThresholdChange_category(_ context.Cont return fc, nil } -func (ec *executionContext) _ThresholdChange_reason(ctx context.Context, field graphql.CollectedField, obj *types.ThresholdChangeModel) (ret graphql.Marshaler) { +func (ec *executionContext) _SimulatedAllowanceChange_reason(ctx context.Context, field graphql.CollectedField, obj *SimulatedAllowanceChange) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, - ec.fieldContext_ThresholdChange_reason, + ec.fieldContext_SimulatedAllowanceChange_reason, func(ctx context.Context) (any, error) { - return ec.Resolvers.ThresholdChange().Reason(ctx, obj) + return obj.Reason, nil }, nil, ec.marshalNStateChangeReason2githubᚗcomᚋstellarᚋwalletᚑbackendᚋinternalᚋindexerᚋtypesᚐStateChangeReason, @@ -12218,12 +12579,12 @@ func (ec *executionContext) _ThresholdChange_reason(ctx context.Context, field g ) } -func (ec *executionContext) fieldContext_ThresholdChange_reason(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_SimulatedAllowanceChange_reason(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "ThresholdChange", + Object: "SimulatedAllowanceChange", Field: field, - IsMethod: true, - IsResolver: true, + IsMethod: false, + IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { return nil, errors.New("field of type StateChangeReason does not have child fields") }, @@ -12231,349 +12592,289 @@ func (ec *executionContext) fieldContext_ThresholdChange_reason(_ context.Contex return fc, nil } -func (ec *executionContext) _ThresholdChange_ingestedAt(ctx context.Context, field graphql.CollectedField, obj *types.ThresholdChangeModel) (ret graphql.Marshaler) { +func (ec *executionContext) _SimulatedAllowanceChange_accountAddress(ctx context.Context, field graphql.CollectedField, obj *SimulatedAllowanceChange) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, - ec.fieldContext_ThresholdChange_ingestedAt, + ec.fieldContext_SimulatedAllowanceChange_accountAddress, func(ctx context.Context) (any, error) { - return obj.IngestedAt, nil + return obj.AccountAddress, nil }, nil, - ec.marshalNTime2timeᚐTime, + ec.marshalNString2string, true, true, ) } -func (ec *executionContext) fieldContext_ThresholdChange_ingestedAt(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_SimulatedAllowanceChange_accountAddress(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "ThresholdChange", + Object: "SimulatedAllowanceChange", Field: field, IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Time does not have child fields") + return nil, errors.New("field of type String does not have child fields") }, } return fc, nil } -func (ec *executionContext) _ThresholdChange_ledgerCreatedAt(ctx context.Context, field graphql.CollectedField, obj *types.ThresholdChangeModel) (ret graphql.Marshaler) { +func (ec *executionContext) _SimulatedAllowanceChange_tokenId(ctx context.Context, field graphql.CollectedField, obj *SimulatedAllowanceChange) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, - ec.fieldContext_ThresholdChange_ledgerCreatedAt, + ec.fieldContext_SimulatedAllowanceChange_tokenId, func(ctx context.Context) (any, error) { - return obj.LedgerCreatedAt, nil + return obj.TokenID, nil }, nil, - ec.marshalNTime2timeᚐTime, + ec.marshalNString2string, true, true, ) } -func (ec *executionContext) fieldContext_ThresholdChange_ledgerCreatedAt(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_SimulatedAllowanceChange_tokenId(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "ThresholdChange", + Object: "SimulatedAllowanceChange", Field: field, IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Time does not have child fields") + return nil, errors.New("field of type String does not have child fields") }, } return fc, nil } -func (ec *executionContext) _ThresholdChange_ledgerNumber(ctx context.Context, field graphql.CollectedField, obj *types.ThresholdChangeModel) (ret graphql.Marshaler) { +func (ec *executionContext) _SimulatedAllowanceChange_spender(ctx context.Context, field graphql.CollectedField, obj *SimulatedAllowanceChange) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, - ec.fieldContext_ThresholdChange_ledgerNumber, + ec.fieldContext_SimulatedAllowanceChange_spender, func(ctx context.Context) (any, error) { - return obj.LedgerNumber, nil + return obj.Spender, nil }, nil, - ec.marshalNUInt322uint32, + ec.marshalNString2string, true, true, ) } -func (ec *executionContext) fieldContext_ThresholdChange_ledgerNumber(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_SimulatedAllowanceChange_spender(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "ThresholdChange", + Object: "SimulatedAllowanceChange", Field: field, IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type UInt32 does not have child fields") + return nil, errors.New("field of type String does not have child fields") }, } return fc, nil } -func (ec *executionContext) _ThresholdChange_account(ctx context.Context, field graphql.CollectedField, obj *types.ThresholdChangeModel) (ret graphql.Marshaler) { +func (ec *executionContext) _SimulatedAllowanceChange_amount(ctx context.Context, field graphql.CollectedField, obj *SimulatedAllowanceChange) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, - ec.fieldContext_ThresholdChange_account, + ec.fieldContext_SimulatedAllowanceChange_amount, func(ctx context.Context) (any, error) { - return ec.Resolvers.ThresholdChange().Account(ctx, obj) + return obj.Amount, nil }, nil, - ec.marshalNAccount2ᚖgithubᚗcomᚋstellarᚋwalletᚑbackendᚋinternalᚋindexerᚋtypesᚐAccount, + ec.marshalNString2string, true, true, ) } -func (ec *executionContext) fieldContext_ThresholdChange_account(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_SimulatedAllowanceChange_amount(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "ThresholdChange", + Object: "SimulatedAllowanceChange", Field: field, - IsMethod: true, - IsResolver: true, + IsMethod: false, + IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "address": - return ec.fieldContext_Account_address(ctx, field) - case "balances": - return ec.fieldContext_Account_balances(ctx, field) - case "transactions": - return ec.fieldContext_Account_transactions(ctx, field) - case "operations": - return ec.fieldContext_Account_operations(ctx, field) - case "stateChanges": - return ec.fieldContext_Account_stateChanges(ctx, field) - case "sep41Allowances": - return ec.fieldContext_Account_sep41Allowances(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type Account", field.Name) + return nil, errors.New("field of type String does not have child fields") }, } return fc, nil } -func (ec *executionContext) _ThresholdChange_operation(ctx context.Context, field graphql.CollectedField, obj *types.ThresholdChangeModel) (ret graphql.Marshaler) { +func (ec *executionContext) _SimulatedAllowanceChange_expirationLedger(ctx context.Context, field graphql.CollectedField, obj *SimulatedAllowanceChange) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, - ec.fieldContext_ThresholdChange_operation, + ec.fieldContext_SimulatedAllowanceChange_expirationLedger, func(ctx context.Context) (any, error) { - return ec.Resolvers.ThresholdChange().Operation(ctx, obj) + return obj.ExpirationLedger, nil }, nil, - ec.marshalNOperation2ᚖgithubᚗcomᚋstellarᚋwalletᚑbackendᚋinternalᚋindexerᚋtypesᚐOperation, + ec.marshalNUInt322uint32, true, true, ) } -func (ec *executionContext) fieldContext_ThresholdChange_operation(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_SimulatedAllowanceChange_expirationLedger(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "ThresholdChange", + Object: "SimulatedAllowanceChange", Field: field, - IsMethod: true, - IsResolver: true, + IsMethod: false, + IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "id": - return ec.fieldContext_Operation_id(ctx, field) - case "type": - return ec.fieldContext_Operation_type(ctx, field) - case "operationXdr": - return ec.fieldContext_Operation_operationXdr(ctx, field) - case "resultCode": - return ec.fieldContext_Operation_resultCode(ctx, field) - case "successful": - return ec.fieldContext_Operation_successful(ctx, field) - case "ledgerNumber": - return ec.fieldContext_Operation_ledgerNumber(ctx, field) - case "ledgerCreatedAt": - return ec.fieldContext_Operation_ledgerCreatedAt(ctx, field) - case "ingestedAt": - return ec.fieldContext_Operation_ingestedAt(ctx, field) - case "transaction": - return ec.fieldContext_Operation_transaction(ctx, field) - case "accounts": - return ec.fieldContext_Operation_accounts(ctx, field) - case "stateChanges": - return ec.fieldContext_Operation_stateChanges(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type Operation", field.Name) + return nil, errors.New("field of type UInt32 does not have child fields") }, } return fc, nil } -func (ec *executionContext) _ThresholdChange_transaction(ctx context.Context, field graphql.CollectedField, obj *types.ThresholdChangeModel) (ret graphql.Marshaler) { +func (ec *executionContext) _SimulatedBalanceAuthorizationChange_category(ctx context.Context, field graphql.CollectedField, obj *SimulatedBalanceAuthorizationChange) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, - ec.fieldContext_ThresholdChange_transaction, + ec.fieldContext_SimulatedBalanceAuthorizationChange_category, func(ctx context.Context) (any, error) { - return ec.Resolvers.ThresholdChange().Transaction(ctx, obj) + return obj.Category, nil }, nil, - ec.marshalNTransaction2ᚖgithubᚗcomᚋstellarᚋwalletᚑbackendᚋinternalᚋindexerᚋtypesᚐTransaction, + ec.marshalNStateChangeCategory2githubᚗcomᚋstellarᚋwalletᚑbackendᚋinternalᚋindexerᚋtypesᚐStateChangeCategory, true, true, ) } -func (ec *executionContext) fieldContext_ThresholdChange_transaction(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_SimulatedBalanceAuthorizationChange_category(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "ThresholdChange", + Object: "SimulatedBalanceAuthorizationChange", Field: field, - IsMethod: true, - IsResolver: true, + IsMethod: false, + IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "hash": - return ec.fieldContext_Transaction_hash(ctx, field) - case "feeCharged": - return ec.fieldContext_Transaction_feeCharged(ctx, field) - case "resultCode": - return ec.fieldContext_Transaction_resultCode(ctx, field) - case "ledgerNumber": - return ec.fieldContext_Transaction_ledgerNumber(ctx, field) - case "ledgerCreatedAt": - return ec.fieldContext_Transaction_ledgerCreatedAt(ctx, field) - case "isFeeBump": - return ec.fieldContext_Transaction_isFeeBump(ctx, field) - case "ingestedAt": - return ec.fieldContext_Transaction_ingestedAt(ctx, field) - case "operations": - return ec.fieldContext_Transaction_operations(ctx, field) - case "accounts": - return ec.fieldContext_Transaction_accounts(ctx, field) - case "stateChanges": - return ec.fieldContext_Transaction_stateChanges(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type Transaction", field.Name) + return nil, errors.New("field of type StateChangeCategory does not have child fields") }, } return fc, nil } -func (ec *executionContext) _ThresholdChange_threshold(ctx context.Context, field graphql.CollectedField, obj *types.ThresholdChangeModel) (ret graphql.Marshaler) { +func (ec *executionContext) _SimulatedBalanceAuthorizationChange_reason(ctx context.Context, field graphql.CollectedField, obj *SimulatedBalanceAuthorizationChange) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, - ec.fieldContext_ThresholdChange_threshold, + ec.fieldContext_SimulatedBalanceAuthorizationChange_reason, func(ctx context.Context) (any, error) { - return ec.Resolvers.ThresholdChange().Threshold(ctx, obj) + return obj.Reason, nil }, nil, - ec.marshalNThresholdLevel2githubᚗcomᚋstellarᚋwalletᚑbackendᚋinternalᚋindexerᚋtypesᚐThresholdLevel, + ec.marshalNStateChangeReason2githubᚗcomᚋstellarᚋwalletᚑbackendᚋinternalᚋindexerᚋtypesᚐStateChangeReason, true, true, ) } -func (ec *executionContext) fieldContext_ThresholdChange_threshold(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_SimulatedBalanceAuthorizationChange_reason(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "ThresholdChange", + Object: "SimulatedBalanceAuthorizationChange", Field: field, - IsMethod: true, - IsResolver: true, + IsMethod: false, + IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type ThresholdLevel does not have child fields") + return nil, errors.New("field of type StateChangeReason does not have child fields") }, } return fc, nil } -func (ec *executionContext) _ThresholdChange_oldThreshold(ctx context.Context, field graphql.CollectedField, obj *types.ThresholdChangeModel) (ret graphql.Marshaler) { +func (ec *executionContext) _SimulatedBalanceAuthorizationChange_accountAddress(ctx context.Context, field graphql.CollectedField, obj *SimulatedBalanceAuthorizationChange) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, - ec.fieldContext_ThresholdChange_oldThreshold, + ec.fieldContext_SimulatedBalanceAuthorizationChange_accountAddress, func(ctx context.Context) (any, error) { - return ec.Resolvers.ThresholdChange().OldThreshold(ctx, obj) + return obj.AccountAddress, nil }, nil, - ec.marshalNInt2int32, + ec.marshalNString2string, true, true, ) } -func (ec *executionContext) fieldContext_ThresholdChange_oldThreshold(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_SimulatedBalanceAuthorizationChange_accountAddress(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "ThresholdChange", + Object: "SimulatedBalanceAuthorizationChange", Field: field, - IsMethod: true, - IsResolver: true, + IsMethod: false, + IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Int does not have child fields") + return nil, errors.New("field of type String does not have child fields") }, } return fc, nil } -func (ec *executionContext) _ThresholdChange_newThreshold(ctx context.Context, field graphql.CollectedField, obj *types.ThresholdChangeModel) (ret graphql.Marshaler) { +func (ec *executionContext) _SimulatedBalanceAuthorizationChange_tokenId(ctx context.Context, field graphql.CollectedField, obj *SimulatedBalanceAuthorizationChange) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, - ec.fieldContext_ThresholdChange_newThreshold, + ec.fieldContext_SimulatedBalanceAuthorizationChange_tokenId, func(ctx context.Context) (any, error) { - return ec.Resolvers.ThresholdChange().NewThreshold(ctx, obj) + return obj.TokenID, nil }, nil, - ec.marshalNInt2int32, - true, + ec.marshalOString2ᚖstring, true, + false, ) } -func (ec *executionContext) fieldContext_ThresholdChange_newThreshold(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_SimulatedBalanceAuthorizationChange_tokenId(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "ThresholdChange", + Object: "SimulatedBalanceAuthorizationChange", Field: field, - IsMethod: true, - IsResolver: true, + IsMethod: false, + IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Int does not have child fields") + return nil, errors.New("field of type String does not have child fields") }, } return fc, nil } -func (ec *executionContext) _Transaction_hash(ctx context.Context, field graphql.CollectedField, obj *types.Transaction) (ret graphql.Marshaler) { +func (ec *executionContext) _SimulatedBalanceAuthorizationChange_liquidityPoolId(ctx context.Context, field graphql.CollectedField, obj *SimulatedBalanceAuthorizationChange) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, - ec.fieldContext_Transaction_hash, + ec.fieldContext_SimulatedBalanceAuthorizationChange_liquidityPoolId, func(ctx context.Context) (any, error) { - return ec.Resolvers.Transaction().Hash(ctx, obj) + return obj.LiquidityPoolID, nil }, nil, - ec.marshalNString2string, - true, + ec.marshalOString2ᚖstring, true, + false, ) } -func (ec *executionContext) fieldContext_Transaction_hash(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_SimulatedBalanceAuthorizationChange_liquidityPoolId(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "Transaction", + Object: "SimulatedBalanceAuthorizationChange", Field: field, - IsMethod: true, - IsResolver: true, + IsMethod: false, + IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { return nil, errors.New("field of type String does not have child fields") }, @@ -12581,192 +12882,993 @@ func (ec *executionContext) fieldContext_Transaction_hash(_ context.Context, fie return fc, nil } -func (ec *executionContext) _Transaction_feeCharged(ctx context.Context, field graphql.CollectedField, obj *types.Transaction) (ret graphql.Marshaler) { +func (ec *executionContext) _SimulatedBalanceAuthorizationChange_flags(ctx context.Context, field graphql.CollectedField, obj *SimulatedBalanceAuthorizationChange) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, - ec.fieldContext_Transaction_feeCharged, + ec.fieldContext_SimulatedBalanceAuthorizationChange_flags, func(ctx context.Context) (any, error) { - return obj.FeeCharged, nil + return obj.Flags, nil }, nil, - ec.marshalNInt642int64, - true, + ec.marshalOTrustlineFlag2ᚕgithubᚗcomᚋstellarᚋwalletᚑbackendᚋinternalᚋindexerᚋtypesᚐTrustlineFlagᚄ, true, + false, ) } -func (ec *executionContext) fieldContext_Transaction_feeCharged(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_SimulatedBalanceAuthorizationChange_flags(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "Transaction", + Object: "SimulatedBalanceAuthorizationChange", Field: field, IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Int64 does not have child fields") + return nil, errors.New("field of type TrustlineFlag does not have child fields") }, } return fc, nil } -func (ec *executionContext) _Transaction_resultCode(ctx context.Context, field graphql.CollectedField, obj *types.Transaction) (ret graphql.Marshaler) { +func (ec *executionContext) _SimulatedBalanceChange_category(ctx context.Context, field graphql.CollectedField, obj *SimulatedBalanceChange) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, - ec.fieldContext_Transaction_resultCode, + ec.fieldContext_SimulatedBalanceChange_category, func(ctx context.Context) (any, error) { - return obj.ResultCode, nil + return obj.Category, nil }, nil, - ec.marshalNString2string, + ec.marshalNStateChangeCategory2githubᚗcomᚋstellarᚋwalletᚑbackendᚋinternalᚋindexerᚋtypesᚐStateChangeCategory, true, true, ) } -func (ec *executionContext) fieldContext_Transaction_resultCode(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_SimulatedBalanceChange_category(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "Transaction", + Object: "SimulatedBalanceChange", Field: field, IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") + return nil, errors.New("field of type StateChangeCategory does not have child fields") }, } return fc, nil } -func (ec *executionContext) _Transaction_ledgerNumber(ctx context.Context, field graphql.CollectedField, obj *types.Transaction) (ret graphql.Marshaler) { +func (ec *executionContext) _SimulatedBalanceChange_reason(ctx context.Context, field graphql.CollectedField, obj *SimulatedBalanceChange) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, - ec.fieldContext_Transaction_ledgerNumber, + ec.fieldContext_SimulatedBalanceChange_reason, func(ctx context.Context) (any, error) { - return obj.LedgerNumber, nil + return obj.Reason, nil }, nil, - ec.marshalNUInt322uint32, + ec.marshalNStateChangeReason2githubᚗcomᚋstellarᚋwalletᚑbackendᚋinternalᚋindexerᚋtypesᚐStateChangeReason, true, true, ) } -func (ec *executionContext) fieldContext_Transaction_ledgerNumber(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_SimulatedBalanceChange_reason(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "Transaction", + Object: "SimulatedBalanceChange", Field: field, IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type UInt32 does not have child fields") + return nil, errors.New("field of type StateChangeReason does not have child fields") }, } return fc, nil } -func (ec *executionContext) _Transaction_ledgerCreatedAt(ctx context.Context, field graphql.CollectedField, obj *types.Transaction) (ret graphql.Marshaler) { +func (ec *executionContext) _SimulatedBalanceChange_accountAddress(ctx context.Context, field graphql.CollectedField, obj *SimulatedBalanceChange) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, - ec.fieldContext_Transaction_ledgerCreatedAt, + ec.fieldContext_SimulatedBalanceChange_accountAddress, func(ctx context.Context) (any, error) { - return obj.LedgerCreatedAt, nil + return obj.AccountAddress, nil }, nil, - ec.marshalNTime2timeᚐTime, + ec.marshalNString2string, true, true, ) } -func (ec *executionContext) fieldContext_Transaction_ledgerCreatedAt(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_SimulatedBalanceChange_accountAddress(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "Transaction", + Object: "SimulatedBalanceChange", Field: field, IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Time does not have child fields") + return nil, errors.New("field of type String does not have child fields") }, } return fc, nil } -func (ec *executionContext) _Transaction_isFeeBump(ctx context.Context, field graphql.CollectedField, obj *types.Transaction) (ret graphql.Marshaler) { +func (ec *executionContext) _SimulatedBalanceChange_tokenId(ctx context.Context, field graphql.CollectedField, obj *SimulatedBalanceChange) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, - ec.fieldContext_Transaction_isFeeBump, + ec.fieldContext_SimulatedBalanceChange_tokenId, func(ctx context.Context) (any, error) { - return obj.IsFeeBump, nil + return obj.TokenID, nil }, nil, - ec.marshalNBoolean2bool, + ec.marshalNString2string, true, true, ) } -func (ec *executionContext) fieldContext_Transaction_isFeeBump(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_SimulatedBalanceChange_tokenId(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "Transaction", + Object: "SimulatedBalanceChange", Field: field, IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Boolean does not have child fields") + return nil, errors.New("field of type String does not have child fields") }, } return fc, nil } -func (ec *executionContext) _Transaction_ingestedAt(ctx context.Context, field graphql.CollectedField, obj *types.Transaction) (ret graphql.Marshaler) { +func (ec *executionContext) _SimulatedBalanceChange_amount(ctx context.Context, field graphql.CollectedField, obj *SimulatedBalanceChange) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, - ec.fieldContext_Transaction_ingestedAt, + ec.fieldContext_SimulatedBalanceChange_amount, func(ctx context.Context) (any, error) { - return obj.IngestedAt, nil + return obj.Amount, nil }, nil, - ec.marshalNTime2timeᚐTime, + ec.marshalNString2string, true, true, ) } -func (ec *executionContext) fieldContext_Transaction_ingestedAt(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_SimulatedBalanceChange_amount(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "Transaction", + Object: "SimulatedBalanceChange", Field: field, IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Time does not have child fields") + return nil, errors.New("field of type String does not have child fields") }, } return fc, nil } -func (ec *executionContext) _Transaction_operations(ctx context.Context, field graphql.CollectedField, obj *types.Transaction) (ret graphql.Marshaler) { +func (ec *executionContext) _SimulatedBalanceChange_toMuxedId(ctx context.Context, field graphql.CollectedField, obj *SimulatedBalanceChange) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, - ec.fieldContext_Transaction_operations, + ec.fieldContext_SimulatedBalanceChange_toMuxedId, func(ctx context.Context) (any, error) { - fc := graphql.GetFieldContext(ctx) - return ec.Resolvers.Transaction().Operations(ctx, obj, fc.Args["first"].(*int32), fc.Args["after"].(*string), fc.Args["last"].(*int32), fc.Args["before"].(*string)) + return obj.ToMuxedID, nil }, nil, - ec.marshalNOperationConnection2ᚖgithubᚗcomᚋstellarᚋwalletᚑbackendᚋinternalᚋserveᚋgraphqlᚋgeneratedᚐOperationConnection, + ec.marshalOString2ᚖstring, + true, + false, + ) +} + +func (ec *executionContext) fieldContext_SimulatedBalanceChange_toMuxedId(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "SimulatedBalanceChange", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _SimulatedStateChanges_latestLedger(ctx context.Context, field graphql.CollectedField, obj *SimulatedStateChanges) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_SimulatedStateChanges_latestLedger, + func(ctx context.Context) (any, error) { + return obj.LatestLedger, nil + }, + nil, + ec.marshalNUInt322uint32, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_SimulatedStateChanges_latestLedger(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "SimulatedStateChanges", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type UInt32 does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _SimulatedStateChanges_stateChanges(ctx context.Context, field graphql.CollectedField, obj *SimulatedStateChanges) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_SimulatedStateChanges_stateChanges, + func(ctx context.Context) (any, error) { + return obj.StateChanges, nil + }, + nil, + ec.marshalNBaseSimulatedStateChange2ᚕgithubᚗcomᚋstellarᚋwalletᚑbackendᚋinternalᚋserveᚋgraphqlᚋgeneratedᚐBaseSimulatedStateChangeᚄ, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_SimulatedStateChanges_stateChanges(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "SimulatedStateChanges", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("FieldContext.Child cannot be called on type INTERFACE") + }, + } + return fc, nil +} + +func (ec *executionContext) _StateChangeConnection_edges(ctx context.Context, field graphql.CollectedField, obj *StateChangeConnection) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_StateChangeConnection_edges, + func(ctx context.Context) (any, error) { + return obj.Edges, nil + }, + nil, + ec.marshalNStateChangeEdge2ᚕᚖgithubᚗcomᚋstellarᚋwalletᚑbackendᚋinternalᚋserveᚋgraphqlᚋgeneratedᚐStateChangeEdgeᚄ, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_StateChangeConnection_edges(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "StateChangeConnection", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "node": + return ec.fieldContext_StateChangeEdge_node(ctx, field) + case "cursor": + return ec.fieldContext_StateChangeEdge_cursor(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type StateChangeEdge", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _StateChangeConnection_pageInfo(ctx context.Context, field graphql.CollectedField, obj *StateChangeConnection) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_StateChangeConnection_pageInfo, + func(ctx context.Context) (any, error) { + return obj.PageInfo, nil + }, + nil, + ec.marshalNPageInfo2ᚖgithubᚗcomᚋstellarᚋwalletᚑbackendᚋinternalᚋserveᚋgraphqlᚋgeneratedᚐPageInfo, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_StateChangeConnection_pageInfo(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "StateChangeConnection", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "startCursor": + return ec.fieldContext_PageInfo_startCursor(ctx, field) + case "endCursor": + return ec.fieldContext_PageInfo_endCursor(ctx, field) + case "hasNextPage": + return ec.fieldContext_PageInfo_hasNextPage(ctx, field) + case "hasPreviousPage": + return ec.fieldContext_PageInfo_hasPreviousPage(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type PageInfo", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _StateChangeEdge_node(ctx context.Context, field graphql.CollectedField, obj *StateChangeEdge) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_StateChangeEdge_node, + func(ctx context.Context) (any, error) { + return obj.Node, nil + }, + nil, + ec.marshalNBaseStateChange2githubᚗcomᚋstellarᚋwalletᚑbackendᚋinternalᚋserveᚋgraphqlᚋgeneratedᚐBaseStateChange, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_StateChangeEdge_node(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "StateChangeEdge", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("FieldContext.Child cannot be called on type INTERFACE") + }, + } + return fc, nil +} + +func (ec *executionContext) _StateChangeEdge_cursor(ctx context.Context, field graphql.CollectedField, obj *StateChangeEdge) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_StateChangeEdge_cursor, + func(ctx context.Context) (any, error) { + return obj.Cursor, nil + }, + nil, + ec.marshalNString2string, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_StateChangeEdge_cursor(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "StateChangeEdge", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ThresholdChange_category(ctx context.Context, field graphql.CollectedField, obj *types.ThresholdChangeModel) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_ThresholdChange_category, + func(ctx context.Context) (any, error) { + return ec.Resolvers.ThresholdChange().Category(ctx, obj) + }, + nil, + ec.marshalNStateChangeCategory2githubᚗcomᚋstellarᚋwalletᚑbackendᚋinternalᚋindexerᚋtypesᚐStateChangeCategory, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_ThresholdChange_category(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ThresholdChange", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type StateChangeCategory does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ThresholdChange_reason(ctx context.Context, field graphql.CollectedField, obj *types.ThresholdChangeModel) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_ThresholdChange_reason, + func(ctx context.Context) (any, error) { + return ec.Resolvers.ThresholdChange().Reason(ctx, obj) + }, + nil, + ec.marshalNStateChangeReason2githubᚗcomᚋstellarᚋwalletᚑbackendᚋinternalᚋindexerᚋtypesᚐStateChangeReason, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_ThresholdChange_reason(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ThresholdChange", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type StateChangeReason does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ThresholdChange_ingestedAt(ctx context.Context, field graphql.CollectedField, obj *types.ThresholdChangeModel) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_ThresholdChange_ingestedAt, + func(ctx context.Context) (any, error) { + return obj.IngestedAt, nil + }, + nil, + ec.marshalNTime2timeᚐTime, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_ThresholdChange_ingestedAt(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ThresholdChange", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Time does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ThresholdChange_ledgerCreatedAt(ctx context.Context, field graphql.CollectedField, obj *types.ThresholdChangeModel) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_ThresholdChange_ledgerCreatedAt, + func(ctx context.Context) (any, error) { + return obj.LedgerCreatedAt, nil + }, + nil, + ec.marshalNTime2timeᚐTime, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_ThresholdChange_ledgerCreatedAt(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ThresholdChange", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Time does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ThresholdChange_ledgerNumber(ctx context.Context, field graphql.CollectedField, obj *types.ThresholdChangeModel) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_ThresholdChange_ledgerNumber, + func(ctx context.Context) (any, error) { + return obj.LedgerNumber, nil + }, + nil, + ec.marshalNUInt322uint32, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_ThresholdChange_ledgerNumber(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ThresholdChange", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type UInt32 does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ThresholdChange_account(ctx context.Context, field graphql.CollectedField, obj *types.ThresholdChangeModel) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_ThresholdChange_account, + func(ctx context.Context) (any, error) { + return ec.Resolvers.ThresholdChange().Account(ctx, obj) + }, + nil, + ec.marshalNAccount2ᚖgithubᚗcomᚋstellarᚋwalletᚑbackendᚋinternalᚋindexerᚋtypesᚐAccount, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_ThresholdChange_account(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ThresholdChange", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "address": + return ec.fieldContext_Account_address(ctx, field) + case "balances": + return ec.fieldContext_Account_balances(ctx, field) + case "transactions": + return ec.fieldContext_Account_transactions(ctx, field) + case "operations": + return ec.fieldContext_Account_operations(ctx, field) + case "stateChanges": + return ec.fieldContext_Account_stateChanges(ctx, field) + case "sep41Allowances": + return ec.fieldContext_Account_sep41Allowances(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Account", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _ThresholdChange_operation(ctx context.Context, field graphql.CollectedField, obj *types.ThresholdChangeModel) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_ThresholdChange_operation, + func(ctx context.Context) (any, error) { + return ec.Resolvers.ThresholdChange().Operation(ctx, obj) + }, + nil, + ec.marshalNOperation2ᚖgithubᚗcomᚋstellarᚋwalletᚑbackendᚋinternalᚋindexerᚋtypesᚐOperation, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_ThresholdChange_operation(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ThresholdChange", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Operation_id(ctx, field) + case "type": + return ec.fieldContext_Operation_type(ctx, field) + case "operationXdr": + return ec.fieldContext_Operation_operationXdr(ctx, field) + case "resultCode": + return ec.fieldContext_Operation_resultCode(ctx, field) + case "successful": + return ec.fieldContext_Operation_successful(ctx, field) + case "ledgerNumber": + return ec.fieldContext_Operation_ledgerNumber(ctx, field) + case "ledgerCreatedAt": + return ec.fieldContext_Operation_ledgerCreatedAt(ctx, field) + case "ingestedAt": + return ec.fieldContext_Operation_ingestedAt(ctx, field) + case "transaction": + return ec.fieldContext_Operation_transaction(ctx, field) + case "accounts": + return ec.fieldContext_Operation_accounts(ctx, field) + case "stateChanges": + return ec.fieldContext_Operation_stateChanges(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Operation", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _ThresholdChange_transaction(ctx context.Context, field graphql.CollectedField, obj *types.ThresholdChangeModel) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_ThresholdChange_transaction, + func(ctx context.Context) (any, error) { + return ec.Resolvers.ThresholdChange().Transaction(ctx, obj) + }, + nil, + ec.marshalNTransaction2ᚖgithubᚗcomᚋstellarᚋwalletᚑbackendᚋinternalᚋindexerᚋtypesᚐTransaction, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_ThresholdChange_transaction(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ThresholdChange", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "hash": + return ec.fieldContext_Transaction_hash(ctx, field) + case "feeCharged": + return ec.fieldContext_Transaction_feeCharged(ctx, field) + case "resultCode": + return ec.fieldContext_Transaction_resultCode(ctx, field) + case "ledgerNumber": + return ec.fieldContext_Transaction_ledgerNumber(ctx, field) + case "ledgerCreatedAt": + return ec.fieldContext_Transaction_ledgerCreatedAt(ctx, field) + case "isFeeBump": + return ec.fieldContext_Transaction_isFeeBump(ctx, field) + case "ingestedAt": + return ec.fieldContext_Transaction_ingestedAt(ctx, field) + case "operations": + return ec.fieldContext_Transaction_operations(ctx, field) + case "accounts": + return ec.fieldContext_Transaction_accounts(ctx, field) + case "stateChanges": + return ec.fieldContext_Transaction_stateChanges(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Transaction", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _ThresholdChange_threshold(ctx context.Context, field graphql.CollectedField, obj *types.ThresholdChangeModel) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_ThresholdChange_threshold, + func(ctx context.Context) (any, error) { + return ec.Resolvers.ThresholdChange().Threshold(ctx, obj) + }, + nil, + ec.marshalNThresholdLevel2githubᚗcomᚋstellarᚋwalletᚑbackendᚋinternalᚋindexerᚋtypesᚐThresholdLevel, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_ThresholdChange_threshold(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ThresholdChange", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ThresholdLevel does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ThresholdChange_oldThreshold(ctx context.Context, field graphql.CollectedField, obj *types.ThresholdChangeModel) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_ThresholdChange_oldThreshold, + func(ctx context.Context) (any, error) { + return ec.Resolvers.ThresholdChange().OldThreshold(ctx, obj) + }, + nil, + ec.marshalNInt2int32, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_ThresholdChange_oldThreshold(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ThresholdChange", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ThresholdChange_newThreshold(ctx context.Context, field graphql.CollectedField, obj *types.ThresholdChangeModel) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_ThresholdChange_newThreshold, + func(ctx context.Context) (any, error) { + return ec.Resolvers.ThresholdChange().NewThreshold(ctx, obj) + }, + nil, + ec.marshalNInt2int32, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_ThresholdChange_newThreshold(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ThresholdChange", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Transaction_hash(ctx context.Context, field graphql.CollectedField, obj *types.Transaction) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_Transaction_hash, + func(ctx context.Context) (any, error) { + return ec.Resolvers.Transaction().Hash(ctx, obj) + }, + nil, + ec.marshalNString2string, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_Transaction_hash(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Transaction", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Transaction_feeCharged(ctx context.Context, field graphql.CollectedField, obj *types.Transaction) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_Transaction_feeCharged, + func(ctx context.Context) (any, error) { + return obj.FeeCharged, nil + }, + nil, + ec.marshalNInt642int64, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_Transaction_feeCharged(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Transaction", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int64 does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Transaction_resultCode(ctx context.Context, field graphql.CollectedField, obj *types.Transaction) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_Transaction_resultCode, + func(ctx context.Context) (any, error) { + return obj.ResultCode, nil + }, + nil, + ec.marshalNString2string, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_Transaction_resultCode(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Transaction", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Transaction_ledgerNumber(ctx context.Context, field graphql.CollectedField, obj *types.Transaction) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_Transaction_ledgerNumber, + func(ctx context.Context) (any, error) { + return obj.LedgerNumber, nil + }, + nil, + ec.marshalNUInt322uint32, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_Transaction_ledgerNumber(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Transaction", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type UInt32 does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Transaction_ledgerCreatedAt(ctx context.Context, field graphql.CollectedField, obj *types.Transaction) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_Transaction_ledgerCreatedAt, + func(ctx context.Context) (any, error) { + return obj.LedgerCreatedAt, nil + }, + nil, + ec.marshalNTime2timeᚐTime, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_Transaction_ledgerCreatedAt(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Transaction", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Time does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Transaction_isFeeBump(ctx context.Context, field graphql.CollectedField, obj *types.Transaction) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_Transaction_isFeeBump, + func(ctx context.Context) (any, error) { + return obj.IsFeeBump, nil + }, + nil, + ec.marshalNBoolean2bool, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_Transaction_isFeeBump(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Transaction", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Transaction_ingestedAt(ctx context.Context, field graphql.CollectedField, obj *types.Transaction) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_Transaction_ingestedAt, + func(ctx context.Context) (any, error) { + return obj.IngestedAt, nil + }, + nil, + ec.marshalNTime2timeᚐTime, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_Transaction_ingestedAt(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Transaction", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Time does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Transaction_operations(ctx context.Context, field graphql.CollectedField, obj *types.Transaction) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_Transaction_operations, + func(ctx context.Context) (any, error) { + fc := graphql.GetFieldContext(ctx) + return ec.Resolvers.Transaction().Operations(ctx, obj, fc.Args["first"].(*int32), fc.Args["after"].(*string), fc.Args["last"].(*int32), fc.Args["before"].(*string)) + }, + nil, + ec.marshalNOperationConnection2ᚖgithubᚗcomᚋstellarᚋwalletᚑbackendᚋinternalᚋserveᚋgraphqlᚋgeneratedᚐOperationConnection, true, true, ) @@ -15926,6 +17028,47 @@ func (ec *executionContext) _Balance(ctx context.Context, sel ast.SelectionSet, } } +func (ec *executionContext) _BaseSimulatedStateChange(ctx context.Context, sel ast.SelectionSet, obj BaseSimulatedStateChange) graphql.Marshaler { + switch obj := (obj).(type) { + case nil: + return graphql.Null + case SimulatedBalanceChange: + return ec._SimulatedBalanceChange(ctx, sel, &obj) + case *SimulatedBalanceChange: + if obj == nil { + return graphql.Null + } + return ec._SimulatedBalanceChange(ctx, sel, obj) + case SimulatedBalanceAuthorizationChange: + return ec._SimulatedBalanceAuthorizationChange(ctx, sel, &obj) + case *SimulatedBalanceAuthorizationChange: + if obj == nil { + return graphql.Null + } + return ec._SimulatedBalanceAuthorizationChange(ctx, sel, obj) + case SimulatedAllowanceChange: + return ec._SimulatedAllowanceChange(ctx, sel, &obj) + case *SimulatedAllowanceChange: + if obj == nil { + return graphql.Null + } + return ec._SimulatedAllowanceChange(ctx, sel, obj) + case SimulatedAccountCreatedChange: + return ec._SimulatedAccountCreatedChange(ctx, sel, &obj) + case *SimulatedAccountCreatedChange: + if obj == nil { + return graphql.Null + } + return ec._SimulatedAccountCreatedChange(ctx, sel, obj) + default: + if typedObj, ok := obj.(graphql.Marshaler); ok { + return typedObj + } else { + panic(fmt.Errorf("unexpected type %T; non-generated variants of BaseSimulatedStateChange must implement graphql.Marshaler", obj)) + } + } +} + func (ec *executionContext) _BaseStateChange(ctx context.Context, sel ast.SelectionSet, obj BaseStateChange) graphql.Marshaler { switch obj := (obj).(type) { case nil: @@ -20772,6 +21915,28 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) } + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "simulateStateChanges": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_simulateStateChanges(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) case "__type": out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { @@ -21492,7 +22657,151 @@ func (ec *executionContext) _SignerRemovedChange(ctx context.Context, sel ast.Se if out.Values[i] == graphql.Null { atomic.AddUint32(&out.Invalids, 1) } - case "account": + case "account": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._SignerRemovedChange_account(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + if field.Deferrable != nil { + dfs, ok := deferred[field.Deferrable.Label] + di := 0 + if ok { + dfs.AddField(field) + di = len(dfs.Values) - 1 + } else { + dfs = graphql.NewFieldSet([]graphql.CollectedField{field}) + deferred[field.Deferrable.Label] = dfs + } + dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler { + return innerFunc(ctx, dfs) + }) + + // don't run the out.Concurrently() call below + out.Values[i] = graphql.Null + continue + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + case "operation": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._SignerRemovedChange_operation(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + if field.Deferrable != nil { + dfs, ok := deferred[field.Deferrable.Label] + di := 0 + if ok { + dfs.AddField(field) + di = len(dfs.Values) - 1 + } else { + dfs = graphql.NewFieldSet([]graphql.CollectedField{field}) + deferred[field.Deferrable.Label] = dfs + } + dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler { + return innerFunc(ctx, dfs) + }) + + // don't run the out.Concurrently() call below + out.Values[i] = graphql.Null + continue + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + case "transaction": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._SignerRemovedChange_transaction(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + if field.Deferrable != nil { + dfs, ok := deferred[field.Deferrable.Label] + di := 0 + if ok { + dfs.AddField(field) + di = len(dfs.Values) - 1 + } else { + dfs = graphql.NewFieldSet([]graphql.CollectedField{field}) + deferred[field.Deferrable.Label] = dfs + } + dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler { + return innerFunc(ctx, dfs) + }) + + // don't run the out.Concurrently() call below + out.Values[i] = graphql.Null + continue + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + case "signerAddress": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._SignerRemovedChange_signerAddress(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + if field.Deferrable != nil { + dfs, ok := deferred[field.Deferrable.Label] + di := 0 + if ok { + dfs.AddField(field) + di = len(dfs.Values) - 1 + } else { + dfs = graphql.NewFieldSet([]graphql.CollectedField{field}) + deferred[field.Deferrable.Label] = dfs + } + dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler { + return innerFunc(ctx, dfs) + }) + + // don't run the out.Concurrently() call below + out.Values[i] = graphql.Null + continue + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + case "oldWeight": field := field innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { @@ -21501,7 +22810,7 @@ func (ec *executionContext) _SignerRemovedChange(ctx context.Context, sel ast.Se ec.Error(ctx, ec.Recover(ctx, r)) } }() - res = ec._SignerRemovedChange_account(ctx, field, obj) + res = ec._SignerRemovedChange_oldWeight(ctx, field, obj) if res == graphql.Null { atomic.AddUint32(&fs.Invalids, 1) } @@ -21528,7 +22837,41 @@ func (ec *executionContext) _SignerRemovedChange(ctx context.Context, sel ast.Se } out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) - case "operation": + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.Deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.ProcessDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var signerUpdatedChangeImplementors = []string{"SignerUpdatedChange", "BaseStateChange"} + +func (ec *executionContext) _SignerUpdatedChange(ctx context.Context, sel ast.SelectionSet, obj *types.SignerUpdatedChangeModel) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, signerUpdatedChangeImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("SignerUpdatedChange") + case "category": field := field innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { @@ -21537,7 +22880,7 @@ func (ec *executionContext) _SignerRemovedChange(ctx context.Context, sel ast.Se ec.Error(ctx, ec.Recover(ctx, r)) } }() - res = ec._SignerRemovedChange_operation(ctx, field, obj) + res = ec._SignerUpdatedChange_category(ctx, field, obj) if res == graphql.Null { atomic.AddUint32(&fs.Invalids, 1) } @@ -21564,7 +22907,7 @@ func (ec *executionContext) _SignerRemovedChange(ctx context.Context, sel ast.Se } out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) - case "transaction": + case "reason": field := field innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { @@ -21573,7 +22916,7 @@ func (ec *executionContext) _SignerRemovedChange(ctx context.Context, sel ast.Se ec.Error(ctx, ec.Recover(ctx, r)) } }() - res = ec._SignerRemovedChange_transaction(ctx, field, obj) + res = ec._SignerUpdatedChange_reason(ctx, field, obj) if res == graphql.Null { atomic.AddUint32(&fs.Invalids, 1) } @@ -21600,7 +22943,22 @@ func (ec *executionContext) _SignerRemovedChange(ctx context.Context, sel ast.Se } out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) - case "signerAddress": + case "ingestedAt": + out.Values[i] = ec._SignerUpdatedChange_ingestedAt(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "ledgerCreatedAt": + out.Values[i] = ec._SignerUpdatedChange_ledgerCreatedAt(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "ledgerNumber": + out.Values[i] = ec._SignerUpdatedChange_ledgerNumber(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "account": field := field innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { @@ -21609,7 +22967,7 @@ func (ec *executionContext) _SignerRemovedChange(ctx context.Context, sel ast.Se ec.Error(ctx, ec.Recover(ctx, r)) } }() - res = ec._SignerRemovedChange_signerAddress(ctx, field, obj) + res = ec._SignerUpdatedChange_account(ctx, field, obj) if res == graphql.Null { atomic.AddUint32(&fs.Invalids, 1) } @@ -21636,7 +22994,7 @@ func (ec *executionContext) _SignerRemovedChange(ctx context.Context, sel ast.Se } out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) - case "oldWeight": + case "operation": field := field innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { @@ -21645,7 +23003,7 @@ func (ec *executionContext) _SignerRemovedChange(ctx context.Context, sel ast.Se ec.Error(ctx, ec.Recover(ctx, r)) } }() - res = ec._SignerRemovedChange_oldWeight(ctx, field, obj) + res = ec._SignerUpdatedChange_operation(ctx, field, obj) if res == graphql.Null { atomic.AddUint32(&fs.Invalids, 1) } @@ -21672,41 +23030,7 @@ func (ec *executionContext) _SignerRemovedChange(ctx context.Context, sel ast.Se } out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - out.Dispatch(ctx) - if out.Invalids > 0 { - return graphql.Null - } - - atomic.AddInt32(&ec.Deferred, int32(len(deferred))) - - for label, dfs := range deferred { - ec.ProcessDeferredGroup(graphql.DeferredGroup{ - Label: label, - Path: graphql.GetPath(ctx), - FieldSet: dfs, - Context: ctx, - }) - } - - return out -} - -var signerUpdatedChangeImplementors = []string{"SignerUpdatedChange", "BaseStateChange"} - -func (ec *executionContext) _SignerUpdatedChange(ctx context.Context, sel ast.SelectionSet, obj *types.SignerUpdatedChangeModel) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, signerUpdatedChangeImplementors) - - out := graphql.NewFieldSet(fields) - deferred := make(map[string]*graphql.FieldSet) - for i, field := range fields { - switch field.Name { - case "__typename": - out.Values[i] = graphql.MarshalString("SignerUpdatedChange") - case "category": + case "transaction": field := field innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { @@ -21715,7 +23039,7 @@ func (ec *executionContext) _SignerUpdatedChange(ctx context.Context, sel ast.Se ec.Error(ctx, ec.Recover(ctx, r)) } }() - res = ec._SignerUpdatedChange_category(ctx, field, obj) + res = ec._SignerUpdatedChange_transaction(ctx, field, obj) if res == graphql.Null { atomic.AddUint32(&fs.Invalids, 1) } @@ -21742,7 +23066,7 @@ func (ec *executionContext) _SignerUpdatedChange(ctx context.Context, sel ast.Se } out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) - case "reason": + case "signerAddress": field := field innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { @@ -21751,7 +23075,7 @@ func (ec *executionContext) _SignerUpdatedChange(ctx context.Context, sel ast.Se ec.Error(ctx, ec.Recover(ctx, r)) } }() - res = ec._SignerUpdatedChange_reason(ctx, field, obj) + res = ec._SignerUpdatedChange_signerAddress(ctx, field, obj) if res == graphql.Null { atomic.AddUint32(&fs.Invalids, 1) } @@ -21778,22 +23102,7 @@ func (ec *executionContext) _SignerUpdatedChange(ctx context.Context, sel ast.Se } out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) - case "ingestedAt": - out.Values[i] = ec._SignerUpdatedChange_ingestedAt(ctx, field, obj) - if out.Values[i] == graphql.Null { - atomic.AddUint32(&out.Invalids, 1) - } - case "ledgerCreatedAt": - out.Values[i] = ec._SignerUpdatedChange_ledgerCreatedAt(ctx, field, obj) - if out.Values[i] == graphql.Null { - atomic.AddUint32(&out.Invalids, 1) - } - case "ledgerNumber": - out.Values[i] = ec._SignerUpdatedChange_ledgerNumber(ctx, field, obj) - if out.Values[i] == graphql.Null { - atomic.AddUint32(&out.Invalids, 1) - } - case "account": + case "oldWeight": field := field innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { @@ -21802,7 +23111,7 @@ func (ec *executionContext) _SignerUpdatedChange(ctx context.Context, sel ast.Se ec.Error(ctx, ec.Recover(ctx, r)) } }() - res = ec._SignerUpdatedChange_account(ctx, field, obj) + res = ec._SignerUpdatedChange_oldWeight(ctx, field, obj) if res == graphql.Null { atomic.AddUint32(&fs.Invalids, 1) } @@ -21829,7 +23138,7 @@ func (ec *executionContext) _SignerUpdatedChange(ctx context.Context, sel ast.Se } out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) - case "operation": + case "newWeight": field := field innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { @@ -21838,7 +23147,7 @@ func (ec *executionContext) _SignerUpdatedChange(ctx context.Context, sel ast.Se ec.Error(ctx, ec.Recover(ctx, r)) } }() - res = ec._SignerUpdatedChange_operation(ctx, field, obj) + res = ec._SignerUpdatedChange_newWeight(ctx, field, obj) if res == graphql.Null { atomic.AddUint32(&fs.Invalids, 1) } @@ -21864,151 +23173,290 @@ func (ec *executionContext) _SignerUpdatedChange(ctx context.Context, sel ast.Se continue } - out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) - case "transaction": - field := field + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.Deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.ProcessDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var simulatedAccountCreatedChangeImplementors = []string{"SimulatedAccountCreatedChange", "BaseSimulatedStateChange"} + +func (ec *executionContext) _SimulatedAccountCreatedChange(ctx context.Context, sel ast.SelectionSet, obj *SimulatedAccountCreatedChange) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, simulatedAccountCreatedChangeImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("SimulatedAccountCreatedChange") + case "category": + out.Values[i] = ec._SimulatedAccountCreatedChange_category(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "reason": + out.Values[i] = ec._SimulatedAccountCreatedChange_reason(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "accountAddress": + out.Values[i] = ec._SimulatedAccountCreatedChange_accountAddress(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "creatorAddress": + out.Values[i] = ec._SimulatedAccountCreatedChange_creatorAddress(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.Deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.ProcessDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var simulatedAllowanceChangeImplementors = []string{"SimulatedAllowanceChange", "BaseSimulatedStateChange"} + +func (ec *executionContext) _SimulatedAllowanceChange(ctx context.Context, sel ast.SelectionSet, obj *SimulatedAllowanceChange) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, simulatedAllowanceChangeImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("SimulatedAllowanceChange") + case "category": + out.Values[i] = ec._SimulatedAllowanceChange_category(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "reason": + out.Values[i] = ec._SimulatedAllowanceChange_reason(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "accountAddress": + out.Values[i] = ec._SimulatedAllowanceChange_accountAddress(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "tokenId": + out.Values[i] = ec._SimulatedAllowanceChange_tokenId(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "spender": + out.Values[i] = ec._SimulatedAllowanceChange_spender(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "amount": + out.Values[i] = ec._SimulatedAllowanceChange_amount(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "expirationLedger": + out.Values[i] = ec._SimulatedAllowanceChange_expirationLedger(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.Deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.ProcessDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} - innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - } - }() - res = ec._SignerUpdatedChange_transaction(ctx, field, obj) - if res == graphql.Null { - atomic.AddUint32(&fs.Invalids, 1) - } - return res - } +var simulatedBalanceAuthorizationChangeImplementors = []string{"SimulatedBalanceAuthorizationChange", "BaseSimulatedStateChange"} - if field.Deferrable != nil { - dfs, ok := deferred[field.Deferrable.Label] - di := 0 - if ok { - dfs.AddField(field) - di = len(dfs.Values) - 1 - } else { - dfs = graphql.NewFieldSet([]graphql.CollectedField{field}) - deferred[field.Deferrable.Label] = dfs - } - dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler { - return innerFunc(ctx, dfs) - }) +func (ec *executionContext) _SimulatedBalanceAuthorizationChange(ctx context.Context, sel ast.SelectionSet, obj *SimulatedBalanceAuthorizationChange) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, simulatedBalanceAuthorizationChangeImplementors) - // don't run the out.Concurrently() call below - out.Values[i] = graphql.Null - continue + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("SimulatedBalanceAuthorizationChange") + case "category": + out.Values[i] = ec._SimulatedBalanceAuthorizationChange_category(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "reason": + out.Values[i] = ec._SimulatedBalanceAuthorizationChange_reason(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "accountAddress": + out.Values[i] = ec._SimulatedBalanceAuthorizationChange_accountAddress(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ } + case "tokenId": + out.Values[i] = ec._SimulatedBalanceAuthorizationChange_tokenId(ctx, field, obj) + case "liquidityPoolId": + out.Values[i] = ec._SimulatedBalanceAuthorizationChange_liquidityPoolId(ctx, field, obj) + case "flags": + out.Values[i] = ec._SimulatedBalanceAuthorizationChange_flags(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } - out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) - case "signerAddress": - field := field + atomic.AddInt32(&ec.Deferred, int32(len(deferred))) - innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - } - }() - res = ec._SignerUpdatedChange_signerAddress(ctx, field, obj) - if res == graphql.Null { - atomic.AddUint32(&fs.Invalids, 1) - } - return res - } + for label, dfs := range deferred { + ec.ProcessDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } - if field.Deferrable != nil { - dfs, ok := deferred[field.Deferrable.Label] - di := 0 - if ok { - dfs.AddField(field) - di = len(dfs.Values) - 1 - } else { - dfs = graphql.NewFieldSet([]graphql.CollectedField{field}) - deferred[field.Deferrable.Label] = dfs - } - dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler { - return innerFunc(ctx, dfs) - }) + return out +} - // don't run the out.Concurrently() call below - out.Values[i] = graphql.Null - continue - } +var simulatedBalanceChangeImplementors = []string{"SimulatedBalanceChange", "BaseSimulatedStateChange"} - out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) - case "oldWeight": - field := field +func (ec *executionContext) _SimulatedBalanceChange(ctx context.Context, sel ast.SelectionSet, obj *SimulatedBalanceChange) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, simulatedBalanceChangeImplementors) - innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - } - }() - res = ec._SignerUpdatedChange_oldWeight(ctx, field, obj) - if res == graphql.Null { - atomic.AddUint32(&fs.Invalids, 1) - } - return res + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("SimulatedBalanceChange") + case "category": + out.Values[i] = ec._SimulatedBalanceChange_category(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ } + case "reason": + out.Values[i] = ec._SimulatedBalanceChange_reason(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "accountAddress": + out.Values[i] = ec._SimulatedBalanceChange_accountAddress(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "tokenId": + out.Values[i] = ec._SimulatedBalanceChange_tokenId(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "amount": + out.Values[i] = ec._SimulatedBalanceChange_amount(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "toMuxedId": + out.Values[i] = ec._SimulatedBalanceChange_toMuxedId(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } - if field.Deferrable != nil { - dfs, ok := deferred[field.Deferrable.Label] - di := 0 - if ok { - dfs.AddField(field) - di = len(dfs.Values) - 1 - } else { - dfs = graphql.NewFieldSet([]graphql.CollectedField{field}) - deferred[field.Deferrable.Label] = dfs - } - dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler { - return innerFunc(ctx, dfs) - }) + atomic.AddInt32(&ec.Deferred, int32(len(deferred))) - // don't run the out.Concurrently() call below - out.Values[i] = graphql.Null - continue - } + for label, dfs := range deferred { + ec.ProcessDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } - out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) - case "newWeight": - field := field + return out +} - innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - } - }() - res = ec._SignerUpdatedChange_newWeight(ctx, field, obj) - if res == graphql.Null { - atomic.AddUint32(&fs.Invalids, 1) - } - return res - } +var simulatedStateChangesImplementors = []string{"SimulatedStateChanges"} - if field.Deferrable != nil { - dfs, ok := deferred[field.Deferrable.Label] - di := 0 - if ok { - dfs.AddField(field) - di = len(dfs.Values) - 1 - } else { - dfs = graphql.NewFieldSet([]graphql.CollectedField{field}) - deferred[field.Deferrable.Label] = dfs - } - dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler { - return innerFunc(ctx, dfs) - }) +func (ec *executionContext) _SimulatedStateChanges(ctx context.Context, sel ast.SelectionSet, obj *SimulatedStateChanges) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, simulatedStateChangesImplementors) - // don't run the out.Concurrently() call below - out.Values[i] = graphql.Null - continue + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("SimulatedStateChanges") + case "latestLedger": + out.Values[i] = ec._SimulatedStateChanges_latestLedger(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "stateChanges": + out.Values[i] = ec._SimulatedStateChanges_stateChanges(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ } - - out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -24265,6 +25713,32 @@ func (ec *executionContext) marshalNBalanceEdge2ᚖgithubᚗcomᚋstellarᚋwall return ec._BalanceEdge(ctx, sel, v) } +func (ec *executionContext) marshalNBaseSimulatedStateChange2githubᚗcomᚋstellarᚋwalletᚑbackendᚋinternalᚋserveᚋgraphqlᚋgeneratedᚐBaseSimulatedStateChange(ctx context.Context, sel ast.SelectionSet, v BaseSimulatedStateChange) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + graphql.AddErrorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._BaseSimulatedStateChange(ctx, sel, v) +} + +func (ec *executionContext) marshalNBaseSimulatedStateChange2ᚕgithubᚗcomᚋstellarᚋwalletᚑbackendᚋinternalᚋserveᚋgraphqlᚋgeneratedᚐBaseSimulatedStateChangeᚄ(ctx context.Context, sel ast.SelectionSet, v []BaseSimulatedStateChange) graphql.Marshaler { + ret := graphql.MarshalSliceConcurrently(ctx, len(v), 0, false, func(ctx context.Context, i int) graphql.Marshaler { + fc := graphql.GetFieldContext(ctx) + fc.Result = &v[i] + return ec.marshalNBaseSimulatedStateChange2githubᚗcomᚋstellarᚋwalletᚑbackendᚋinternalᚋserveᚋgraphqlᚋgeneratedᚐBaseSimulatedStateChange(ctx, sel, v[i]) + }) + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + func (ec *executionContext) marshalNBaseStateChange2githubᚗcomᚋstellarᚋwalletᚑbackendᚋinternalᚋserveᚋgraphqlᚋgeneratedᚐBaseStateChange(ctx context.Context, sel ast.SelectionSet, v BaseStateChange) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { @@ -24512,6 +25986,20 @@ func (ec *executionContext) marshalNSEP41AllowanceEdge2ᚖgithubᚗcomᚋstellar return ec._SEP41AllowanceEdge(ctx, sel, v) } +func (ec *executionContext) marshalNSimulatedStateChanges2githubᚗcomᚋstellarᚋwalletᚑbackendᚋinternalᚋserveᚋgraphqlᚋgeneratedᚐSimulatedStateChanges(ctx context.Context, sel ast.SelectionSet, v SimulatedStateChanges) graphql.Marshaler { + return ec._SimulatedStateChanges(ctx, sel, &v) +} + +func (ec *executionContext) marshalNSimulatedStateChanges2ᚖgithubᚗcomᚋstellarᚋwalletᚑbackendᚋinternalᚋserveᚋgraphqlᚋgeneratedᚐSimulatedStateChanges(ctx context.Context, sel ast.SelectionSet, v *SimulatedStateChanges) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + graphql.AddErrorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._SimulatedStateChanges(ctx, sel, v) +} + func (ec *executionContext) unmarshalNStateChangeCategory2githubᚗcomᚋstellarᚋwalletᚑbackendᚋinternalᚋindexerᚋtypesᚐStateChangeCategory(ctx context.Context, v any) (types.StateChangeCategory, error) { tmp, err := graphql.UnmarshalString(v) res := types.StateChangeCategory(tmp) diff --git a/internal/serve/graphql/generated/models_gen.go b/internal/serve/graphql/generated/models_gen.go index bbaef16da..f1c7e5f7f 100644 --- a/internal/serve/graphql/generated/models_gen.go +++ b/internal/serve/graphql/generated/models_gen.go @@ -23,6 +23,27 @@ type Balance interface { GetTokenType() TokenType } +// Common contract implemented by every simulated state change. Simulated +// variants mirror the history API's state-change types (same names with a +// `Simulated` prefix, same `(category, reason)` pairs and variant fields) but +// omit the fields that only exist after a transaction is included in a ledger: +// `ingestedAt`, `ledgerCreatedAt`, `ledgerNumber`, `operation`, and +// `transaction`. The affected account is exposed as a plain address rather than +// an `Account` entity, since the account may not be indexed yet. +// +// The set of concrete types grows with the transaction sources the simulation +// supports; today it covers the variants a contract (Soroban) transaction can +// produce. +type BaseSimulatedStateChange interface { + IsBaseSimulatedStateChange() + // Category of account state this change affects. + GetCategory() types.StateChangeCategory + // Why the change occurred. Each concrete type documents its valid reasons. + GetReason() types.StateChangeReason + // Address of the account whose state would change. + GetAccountAddress() string +} + // Common contract implemented by every state change. A state change records one // modification to one account's ledger state, attributed to the transaction (and, // except for transaction fees, the operation) that caused it. @@ -251,6 +272,125 @@ func (this SEP41Balance) GetTokenID() string { return this.TokenID } // Classification of the token. func (this SEP41Balance) GetTokenType() TokenType { return this.TokenType } +// Simulated mirror of AccountCreatedChange. For a contract deployment, +// `accountAddress` is the deployed contract's C-address. +// Pair: (ACCOUNT, CREATE). +type SimulatedAccountCreatedChange struct { + Category types.StateChangeCategory `json:"category"` + Reason types.StateChangeReason `json:"reason"` + AccountAddress string `json:"accountAddress"` + // Account that would create this one: the funder or the contract deployer. + CreatorAddress string `json:"creatorAddress"` +} + +func (SimulatedAccountCreatedChange) IsBaseSimulatedStateChange() {} + +// Category of account state this change affects. +func (this SimulatedAccountCreatedChange) GetCategory() types.StateChangeCategory { + return this.Category +} + +// Why the change occurred. Each concrete type documents its valid reasons. +func (this SimulatedAccountCreatedChange) GetReason() types.StateChangeReason { return this.Reason } + +// Address of the account whose state would change. +func (this SimulatedAccountCreatedChange) GetAccountAddress() string { return this.AccountAddress } + +// Simulated mirror of AllowanceChange. +// Pair: (ALLOWANCE, UPDATE). +type SimulatedAllowanceChange struct { + Category types.StateChangeCategory `json:"category"` + Reason types.StateChangeReason `json:"reason"` + AccountAddress string `json:"accountAddress"` + // Contract ID of the token the allowance applies to. + TokenID string `json:"tokenId"` + // Address authorized to spend from the holder's balance. + Spender string `json:"spender"` + // Approved allowance, as a decimal string in the token's smallest unit. + Amount string `json:"amount"` + // Last ledger sequence at which the allowance is live. + ExpirationLedger uint32 `json:"expirationLedger"` +} + +func (SimulatedAllowanceChange) IsBaseSimulatedStateChange() {} + +// Category of account state this change affects. +func (this SimulatedAllowanceChange) GetCategory() types.StateChangeCategory { return this.Category } + +// Why the change occurred. Each concrete type documents its valid reasons. +func (this SimulatedAllowanceChange) GetReason() types.StateChangeReason { return this.Reason } + +// Address of the account whose state would change. +func (this SimulatedAllowanceChange) GetAccountAddress() string { return this.AccountAddress } + +// Simulated mirror of BalanceAuthorizationChange. Exactly one of tokenId / +// liquidityPoolId is set. +// Pairs: (BALANCE_AUTHORIZATION, SET), (BALANCE_AUTHORIZATION, CLEAR). +type SimulatedBalanceAuthorizationChange struct { + Category types.StateChangeCategory `json:"category"` + Reason types.StateChangeReason `json:"reason"` + AccountAddress string `json:"accountAddress"` + // Contract ID of the asset; null for liquidity-pool-share trustlines. + TokenID *string `json:"tokenId,omitempty"` + // Liquidity pool ID for pool-share trustlines; null for asset trustlines. + LiquidityPoolID *string `json:"liquidityPoolId,omitempty"` + // Trustline flags that would change; null for SAC contract-holder authorization, which has no flags. + Flags []types.TrustlineFlag `json:"flags,omitempty"` +} + +func (SimulatedBalanceAuthorizationChange) IsBaseSimulatedStateChange() {} + +// Category of account state this change affects. +func (this SimulatedBalanceAuthorizationChange) GetCategory() types.StateChangeCategory { + return this.Category +} + +// Why the change occurred. Each concrete type documents its valid reasons. +func (this SimulatedBalanceAuthorizationChange) GetReason() types.StateChangeReason { + return this.Reason +} + +// Address of the account whose state would change. +func (this SimulatedBalanceAuthorizationChange) GetAccountAddress() string { + return this.AccountAddress +} + +// Simulated mirror of BalanceChange. The transaction-fee row is (BALANCE, DEBIT) +// on the fee-paying account, estimated from the simulation's resource fee. +// Pairs: (BALANCE, DEBIT), (BALANCE, CREDIT), (BALANCE, MINT), (BALANCE, BURN). +type SimulatedBalanceChange struct { + Category types.StateChangeCategory `json:"category"` + Reason types.StateChangeReason `json:"reason"` + AccountAddress string `json:"accountAddress"` + // Contract ID of the token whose balance would move. + TokenID string `json:"tokenId"` + // Amount moved, as a decimal string in the token's smallest unit. + Amount string `json:"amount"` + // CAP-67 destination memo carried by SEP-41 transfer/mint events (CREDIT and MINT only). + ToMuxedID *string `json:"toMuxedId,omitempty"` +} + +func (SimulatedBalanceChange) IsBaseSimulatedStateChange() {} + +// Category of account state this change affects. +func (this SimulatedBalanceChange) GetCategory() types.StateChangeCategory { return this.Category } + +// Why the change occurred. Each concrete type documents its valid reasons. +func (this SimulatedBalanceChange) GetReason() types.StateChangeReason { return this.Reason } + +// Address of the account whose state would change. +func (this SimulatedBalanceChange) GetAccountAddress() string { return this.AccountAddress } + +// Result of simulating an unsubmitted transaction: the state changes the +// indexer would produce if the transaction were submitted and included in a +// ledger, in the same variant structure as the history API's state changes. +type SimulatedStateChanges struct { + // Latest ledger the simulation was evaluated against. + LatestLedger uint32 `json:"latestLedger"` + // State changes the transaction would produce. + StateChanges []BaseSimulatedStateChange `json:"stateChanges"` +} + // Relay-style page of state changes. type StateChangeConnection struct { Edges []*StateChangeEdge `json:"edges"` diff --git a/internal/serve/graphql/resolvers/queries.resolvers.go b/internal/serve/graphql/resolvers/queries.resolvers.go index aa1ba2130..f9c881076 100644 --- a/internal/serve/graphql/resolvers/queries.resolvers.go +++ b/internal/serve/graphql/resolvers/queries.resolvers.go @@ -7,6 +7,7 @@ package resolvers import ( "context" + "fmt" "strings" "github.com/vektah/gqlparser/v2/gqlerror" @@ -53,6 +54,11 @@ func (r *queryResolver) OperationByID(ctx context.Context, id int64) (*types.Ope return r.models.Operations.GetByID(ctx, id, strings.Join(dbColumns, ", ")) } +// SimulateStateChanges is the resolver for the simulateStateChanges field. +func (r *queryResolver) SimulateStateChanges(ctx context.Context, transactionXdr string) (*graphql1.SimulatedStateChanges, error) { + panic(fmt.Errorf("not implemented: SimulateStateChanges - simulateStateChanges")) +} + // Query returns graphql1.QueryResolver implementation. func (r *Resolver) Query() graphql1.QueryResolver { return &queryResolver{r} } diff --git a/internal/serve/graphql/resolvers/statechange.resolvers.go b/internal/serve/graphql/resolvers/statechange.resolvers.go index 5568abca7..3b5b775d2 100644 --- a/internal/serve/graphql/resolvers/statechange.resolvers.go +++ b/internal/serve/graphql/resolvers/statechange.resolvers.go @@ -865,24 +865,22 @@ func (r *Resolver) TrustlineUpdatedChange() graphql1.TrustlineUpdatedChangeResol return &trustlineUpdatedChangeResolver{r} } -type ( - accountCreatedChangeResolver struct{ *Resolver } - accountFlagsChangeResolver struct{ *Resolver } - accountMergedChangeResolver struct{ *Resolver } - allowanceChangeResolver struct{ *Resolver } - balanceAuthorizationChangeResolver struct{ *Resolver } - balanceChangeResolver struct{ *Resolver } - dataEntryAddedChangeResolver struct{ *Resolver } - dataEntryRemovedChangeResolver struct{ *Resolver } - dataEntryUpdatedChangeResolver struct{ *Resolver } - homeDomainClearedChangeResolver struct{ *Resolver } - homeDomainSetChangeResolver struct{ *Resolver } - homeDomainUpdatedChangeResolver struct{ *Resolver } - signerAddedChangeResolver struct{ *Resolver } - signerRemovedChangeResolver struct{ *Resolver } - signerUpdatedChangeResolver struct{ *Resolver } - thresholdChangeResolver struct{ *Resolver } - trustlineAddedChangeResolver struct{ *Resolver } - trustlineRemovedChangeResolver struct{ *Resolver } - trustlineUpdatedChangeResolver struct{ *Resolver } -) +type accountCreatedChangeResolver struct{ *Resolver } +type accountFlagsChangeResolver struct{ *Resolver } +type accountMergedChangeResolver struct{ *Resolver } +type allowanceChangeResolver struct{ *Resolver } +type balanceAuthorizationChangeResolver struct{ *Resolver } +type balanceChangeResolver struct{ *Resolver } +type dataEntryAddedChangeResolver struct{ *Resolver } +type dataEntryRemovedChangeResolver struct{ *Resolver } +type dataEntryUpdatedChangeResolver struct{ *Resolver } +type homeDomainClearedChangeResolver struct{ *Resolver } +type homeDomainSetChangeResolver struct{ *Resolver } +type homeDomainUpdatedChangeResolver struct{ *Resolver } +type signerAddedChangeResolver struct{ *Resolver } +type signerRemovedChangeResolver struct{ *Resolver } +type signerUpdatedChangeResolver struct{ *Resolver } +type thresholdChangeResolver struct{ *Resolver } +type trustlineAddedChangeResolver struct{ *Resolver } +type trustlineRemovedChangeResolver struct{ *Resolver } +type trustlineUpdatedChangeResolver struct{ *Resolver } diff --git a/internal/serve/graphql/schema/queries.graphqls b/internal/serve/graphql/schema/queries.graphqls index 5287eb4d3..ef4088480 100644 --- a/internal/serve/graphql/schema/queries.graphqls +++ b/internal/serve/graphql/schema/queries.graphqls @@ -8,4 +8,12 @@ type Query { """Look up an operation by its ID (TOID).""" operationById(id: Int64!): Operation + + """ + Simulate an unsubmitted transaction and return the state changes it would + produce if submitted, in the same variant structure as the history API. + Currently accepts contract (Soroban) transactions, whose changes come from + RPC simulation; classic transactions are rejected as UNSUPPORTED_TRANSACTION. + """ + simulateStateChanges(transactionXdr: String!): SimulatedStateChanges! } diff --git a/internal/serve/graphql/schema/simulation.graphqls b/internal/serve/graphql/schema/simulation.graphqls new file mode 100644 index 000000000..962b756c2 --- /dev/null +++ b/internal/serve/graphql/schema/simulation.graphqls @@ -0,0 +1,102 @@ +""" +Result of simulating an unsubmitted transaction: the state changes the +indexer would produce if the transaction were submitted and included in a +ledger, in the same variant structure as the history API's state changes. +""" +type SimulatedStateChanges { + """Latest ledger the simulation was evaluated against.""" + latestLedger: UInt32! + """State changes the transaction would produce.""" + stateChanges: [BaseSimulatedStateChange!]! +} + +""" +Common contract implemented by every simulated state change. Simulated +variants mirror the history API's state-change types (same names with a +`Simulated` prefix, same `(category, reason)` pairs and variant fields) but +omit the fields that only exist after a transaction is included in a ledger: +`ingestedAt`, `ledgerCreatedAt`, `ledgerNumber`, `operation`, and +`transaction`. The affected account is exposed as a plain address rather than +an `Account` entity, since the account may not be indexed yet. + +The set of concrete types grows with the transaction sources the simulation +supports; today it covers the variants a contract (Soroban) transaction can +produce. +""" +interface BaseSimulatedStateChange { + """Category of account state this change affects.""" + category: StateChangeCategory! + """Why the change occurred. Each concrete type documents its valid reasons.""" + reason: StateChangeReason! + """Address of the account whose state would change.""" + accountAddress: String! +} + +""" +Simulated mirror of BalanceChange. The transaction-fee row is (BALANCE, DEBIT) +on the fee-paying account, estimated from the simulation's resource fee. +Pairs: (BALANCE, DEBIT), (BALANCE, CREDIT), (BALANCE, MINT), (BALANCE, BURN). +""" +type SimulatedBalanceChange implements BaseSimulatedStateChange { + category: StateChangeCategory! + reason: StateChangeReason! + accountAddress: String! + + """Contract ID of the token whose balance would move.""" + tokenId: String! + """Amount moved, as a decimal string in the token's smallest unit.""" + amount: String! + """CAP-67 destination memo carried by SEP-41 transfer/mint events (CREDIT and MINT only).""" + toMuxedId: String +} + +""" +Simulated mirror of AccountCreatedChange. For a contract deployment, +`accountAddress` is the deployed contract's C-address. +Pair: (ACCOUNT, CREATE). +""" +type SimulatedAccountCreatedChange implements BaseSimulatedStateChange { + category: StateChangeCategory! + reason: StateChangeReason! + accountAddress: String! + + """Account that would create this one: the funder or the contract deployer.""" + creatorAddress: String! +} + +""" +Simulated mirror of AllowanceChange. +Pair: (ALLOWANCE, UPDATE). +""" +type SimulatedAllowanceChange implements BaseSimulatedStateChange { + category: StateChangeCategory! + reason: StateChangeReason! + accountAddress: String! + + """Contract ID of the token the allowance applies to.""" + tokenId: String! + """Address authorized to spend from the holder's balance.""" + spender: String! + """Approved allowance, as a decimal string in the token's smallest unit.""" + amount: String! + """Last ledger sequence at which the allowance is live.""" + expirationLedger: UInt32! +} + +""" +Simulated mirror of BalanceAuthorizationChange. Exactly one of tokenId / +liquidityPoolId is set. +Pairs: (BALANCE_AUTHORIZATION, SET), (BALANCE_AUTHORIZATION, CLEAR). +""" +type SimulatedBalanceAuthorizationChange implements BaseSimulatedStateChange { + category: StateChangeCategory! + reason: StateChangeReason! + accountAddress: String! + + """Contract ID of the asset; null for liquidity-pool-share trustlines.""" + tokenId: String + """Liquidity pool ID for pool-share trustlines; null for asset trustlines.""" + liquidityPoolId: String + """Trustline flags that would change; null for SAC contract-holder authorization, which has no flags.""" + flags: [TrustlineFlag!] +} From 1d0bf031dd3f64f71bfa25b766d4046a9523f9b1 Mon Sep 17 00:00:00 2001 From: jiahuihu Date: Wed, 19 Aug 2026 14:52:37 -0400 Subject: [PATCH 2/4] feat(services): TransactionSimulationService skeleton wired to simulateStateChanges --- .../graphql/resolvers/queries.resolvers.go | 31 +++- internal/serve/graphql/resolvers/resolver.go | 24 ++-- .../serve/graphql/resolvers/simulation.go | 135 ++++++++++++++++++ internal/serve/serve.go | 8 ++ internal/services/transaction_simulation.go | 106 ++++++++++++++ 5 files changed, 292 insertions(+), 12 deletions(-) create mode 100644 internal/serve/graphql/resolvers/simulation.go create mode 100644 internal/services/transaction_simulation.go diff --git a/internal/serve/graphql/resolvers/queries.resolvers.go b/internal/serve/graphql/resolvers/queries.resolvers.go index f9c881076..ff9a28a79 100644 --- a/internal/serve/graphql/resolvers/queries.resolvers.go +++ b/internal/serve/graphql/resolvers/queries.resolvers.go @@ -7,6 +7,7 @@ package resolvers import ( "context" + "errors" "fmt" "strings" @@ -14,6 +15,7 @@ import ( "github.com/stellar/wallet-backend/internal/indexer/types" graphql1 "github.com/stellar/wallet-backend/internal/serve/graphql/generated" + "github.com/stellar/wallet-backend/internal/services" "github.com/stellar/wallet-backend/internal/utils" ) @@ -55,8 +57,35 @@ func (r *queryResolver) OperationByID(ctx context.Context, id int64) (*types.Ope } // SimulateStateChanges is the resolver for the simulateStateChanges field. +// It delegates to the transaction simulation service and maps its sentinel +// errors onto the GraphQL error convention (extensions.code). func (r *queryResolver) SimulateStateChanges(ctx context.Context, transactionXdr string) (*graphql1.SimulatedStateChanges, error) { - panic(fmt.Errorf("not implemented: SimulateStateChanges - simulateStateChanges")) + result, err := r.simulationService.SimulateStateChanges(ctx, transactionXdr) + if err != nil { + switch { + case errors.Is(err, services.ErrInvalidTransactionXDR): + return nil, &gqlerror.Error{ + Message: err.Error(), + Extensions: map[string]interface{}{"code": "INVALID_TRANSACTION_XDR"}, + } + case errors.Is(err, services.ErrUnsupportedTransaction): + return nil, &gqlerror.Error{ + Message: err.Error(), + Extensions: map[string]interface{}{"code": "UNSUPPORTED_TRANSACTION"}, + } + default: + return nil, fmt.Errorf("simulating state changes: %w", err) + } + } + + stateChanges, err := r.convertToSimulatedStateChanges(result.StateChanges) + if err != nil { + return nil, fmt.Errorf("converting simulated state changes: %w", err) + } + return &graphql1.SimulatedStateChanges{ + LatestLedger: result.LatestLedger, + StateChanges: stateChanges, + }, nil } // Query returns graphql1.QueryResolver implementation. diff --git a/internal/serve/graphql/resolvers/resolver.go b/internal/serve/graphql/resolvers/resolver.go index b938d2749..751850460 100644 --- a/internal/serve/graphql/resolvers/resolver.go +++ b/internal/serve/graphql/resolvers/resolver.go @@ -50,21 +50,23 @@ var ErrNotStateChange = errors.New("object is not a StateChange") // Resolver is the main resolver struct for gqlgen. // It holds dependencies needed by all resolver functions. type Resolver struct { - models *data.Models - rpcService services.RPCService - balanceReader BalanceReader - metrics *metrics.Metrics - config ResolverConfig + models *data.Models + rpcService services.RPCService + balanceReader BalanceReader + metrics *metrics.Metrics + config ResolverConfig + simulationService services.TransactionSimulationService } // NewResolver creates a new resolver instance with required dependencies. -func NewResolver(models *data.Models, rpcService services.RPCService, balanceReader BalanceReader, m *metrics.Metrics, config ResolverConfig) *Resolver { +func NewResolver(models *data.Models, rpcService services.RPCService, balanceReader BalanceReader, m *metrics.Metrics, config ResolverConfig, simulationService services.TransactionSimulationService) *Resolver { return &Resolver{ - models: models, - rpcService: rpcService, - balanceReader: balanceReader, - metrics: m, - config: config, + models: models, + rpcService: rpcService, + balanceReader: balanceReader, + metrics: m, + config: config, + simulationService: simulationService, } } diff --git a/internal/serve/graphql/resolvers/simulation.go b/internal/serve/graphql/resolvers/simulation.go new file mode 100644 index 000000000..0e71729d7 --- /dev/null +++ b/internal/serve/graphql/resolvers/simulation.go @@ -0,0 +1,135 @@ +package resolvers + +import ( + "fmt" + "math" + + "github.com/stellar/wallet-backend/internal/indexer/types" + graphql1 "github.com/stellar/wallet-backend/internal/serve/graphql/generated" +) + +// convertToSimulatedStateChanges resolves the concrete simulated GraphQL type for +// each state change produced by the simulation pipeline. Unlike the history types +// (convertStateChangeTypes), simulated types are plain structs built eagerly: the +// data never touches the DB, so there are no lazy column-backed resolvers. +func (r *Resolver) convertToSimulatedStateChanges(stateChanges []types.StateChange) ([]graphql1.BaseSimulatedStateChange, error) { + converted := make([]graphql1.BaseSimulatedStateChange, len(stateChanges)) + for i, stateChange := range stateChanges { + c, err := r.convertToSimulatedStateChange(stateChange) + if err != nil { + return nil, err + } + converted[i] = c + } + return converted, nil +} + +// convertToSimulatedStateChange dispatches on (category, reason), mirroring +// convertStateChangeTypes. A change matching no arm means the simulation pipeline +// emitted a variant the simulated schema does not expose yet, and surfaces as an +// error rather than a silently dropped row. +func (r *Resolver) convertToSimulatedStateChange(sc types.StateChange) (graphql1.BaseSimulatedStateChange, error) { + accountAddress := string(sc.AccountID) + + switch sc.StateChangeCategory { + case types.StateChangeCategoryBalance: + switch sc.StateChangeReason { + case types.StateChangeReasonDebit, types.StateChangeReasonCredit, types.StateChangeReasonMint, types.StateChangeReasonBurn: + tokenID, err := r.resolveRequiredAddress(sc.TokenID, "tokenId") + if err != nil { + return nil, err + } + amount, err := r.resolveRequiredString(sc.Amount, "amount") + if err != nil { + return nil, err + } + return graphql1.SimulatedBalanceChange{ + Category: sc.StateChangeCategory, + Reason: sc.StateChangeReason, + AccountAddress: accountAddress, + TokenID: tokenID, + Amount: amount, + ToMuxedID: r.resolveNullableString(sc.ToMuxedID), + }, nil + default: // invalid reason for BALANCE; falls through to the error below + } + case types.StateChangeCategoryAccount: + switch sc.StateChangeReason { + case types.StateChangeReasonCreate: + creatorAddress, err := r.resolveRequiredAddress(sc.CreatorAccountID, "creatorAddress") + if err != nil { + return nil, err + } + return graphql1.SimulatedAccountCreatedChange{ + Category: sc.StateChangeCategory, + Reason: sc.StateChangeReason, + AccountAddress: accountAddress, + CreatorAddress: creatorAddress, + }, nil + default: // invalid reason for ACCOUNT; falls through to the error below + } + case types.StateChangeCategoryAllowance: + switch sc.StateChangeReason { + case types.StateChangeReasonUpdate: + tokenID, err := r.resolveRequiredAddress(sc.TokenID, "tokenId") + if err != nil { + return nil, err + } + spender, err := r.resolveRequiredAddress(sc.SpenderAccountID, "spender") + if err != nil { + return nil, err + } + amount, err := r.resolveRequiredString(sc.Amount, "amount") + if err != nil { + return nil, err + } + expirationLedger, ok := keyValueUint32(sc.KeyValue, "live_until_ledger") + if !ok { + return nil, fmt.Errorf("state change is missing required expirationLedger") + } + return graphql1.SimulatedAllowanceChange{ + Category: sc.StateChangeCategory, + Reason: sc.StateChangeReason, + AccountAddress: accountAddress, + TokenID: tokenID, + Spender: spender, + Amount: amount, + ExpirationLedger: expirationLedger, + }, nil + default: // invalid reason for ALLOWANCE; falls through to the error below + } + case types.StateChangeCategoryBalanceAuthorization: + switch sc.StateChangeReason { + case types.StateChangeReasonSet, types.StateChangeReasonClear: + var flags []types.TrustlineFlag + if sc.Flags.Valid { + flags = types.DecodeTrustlineFlags(sc.Flags.Int16) + } + return graphql1.SimulatedBalanceAuthorizationChange{ + Category: sc.StateChangeCategory, + Reason: sc.StateChangeReason, + AccountAddress: accountAddress, + TokenID: r.resolveNullableAddress(sc.TokenID), + LiquidityPoolID: r.resolveNullableString(sc.LiquidityPoolID), + Flags: flags, + }, nil + default: // invalid reason for BALANCE_AUTHORIZATION; falls through to the error below + } + } + return nil, fmt.Errorf("state change has no simulated GraphQL type for (category=%s, reason=%s)", + sc.StateChangeCategory, sc.StateChangeReason) +} + +// keyValueUint32 reads a uint32 from a KeyValue JSONB payload, where JSON +// unmarshal exposes numbers as float64. +func keyValueUint32(kv types.NullableJSONB, key string) (uint32, bool) { + raw, ok := kv[key] + if !ok { + return 0, false + } + f, ok := raw.(float64) + if !ok || f < 0 || f > math.MaxUint32 { + return 0, false + } + return uint32(f), true +} diff --git a/internal/serve/serve.go b/internal/serve/serve.go index 8158f171c..844834abb 100644 --- a/internal/serve/serve.go +++ b/internal/serve/serve.go @@ -112,6 +112,7 @@ type handlerDeps struct { // Services Metrics *metrics.Metrics RPCService services.RPCService + SimulationService services.TransactionSimulationService TrustlineBalanceModel data.TrustlineBalanceModelInterface NativeBalanceModel data.NativeBalanceModelInterface SACBalanceModel data.SACBalanceModelInterface @@ -203,12 +204,18 @@ func initHandlerDeps(ctx context.Context, cfg Configs) (handlerDeps, error) { return handlerDeps{}, fmt.Errorf("instantiating rpc service: %w", err) } + simulationService, err := services.NewTransactionSimulationService(rpcService, cfg.NetworkPassphrase) + if err != nil { + return handlerDeps{}, fmt.Errorf("instantiating transaction simulation service: %w", err) + } + return handlerDeps{ Models: models, RequestAuthVerifier: requestAuthVerifier, SupportedAssets: cfg.SupportedAssets, Metrics: m, RPCService: rpcService, + SimulationService: simulationService, TrustlineBalanceModel: models.TrustlineBalance, NativeBalanceModel: models.NativeBalance, SACBalanceModel: models.SACBalance, @@ -271,6 +278,7 @@ func handler(deps handlerDeps) http.Handler { resolvers.NewBalanceReader(deps.TrustlineBalanceModel, deps.NativeBalanceModel, deps.SACBalanceModel, deps.LiquidityPoolBalanceModel, deps.SEP41BalanceModel, deps.SEP41AllowanceModel), deps.Metrics, resolvers.ResolverConfig{}, + deps.SimulationService, ) config := generated.Config{ diff --git a/internal/services/transaction_simulation.go b/internal/services/transaction_simulation.go new file mode 100644 index 000000000..a8b1aa29c --- /dev/null +++ b/internal/services/transaction_simulation.go @@ -0,0 +1,106 @@ +package services + +import ( + "context" + "errors" + "fmt" + "runtime" + + "github.com/alitto/pond/v2" + "github.com/stellar/go-stellar-sdk/ingest" + "github.com/stellar/go-stellar-sdk/xdr" + + "github.com/stellar/wallet-backend/internal/indexer" + "github.com/stellar/wallet-backend/internal/indexer/types" +) + +// Sentinel errors the GraphQL resolver maps onto extensions.code values. +var ( + // ErrInvalidTransactionXDR means the transaction envelope failed to decode. + ErrInvalidTransactionXDR = errors.New("invalid transaction XDR") + // ErrUnsupportedTransaction means the transaction (or one of its operations) + // is not supported by the implemented simulation sources. + ErrUnsupportedTransaction = errors.New("unsupported transaction") +) + +// SimulatedStateChanges is the result of simulating an unsubmitted transaction: +// the state changes the indexer would produce if it were submitted, evaluated +// against LatestLedger. +type SimulatedStateChanges struct { + LatestLedger uint32 + StateChanges []types.StateChange +} + +// TransactionSimulationService previews the state changes an unsubmitted +// transaction would produce, by rebuilding the transaction's ledger-entry +// changes (contract transactions via RPC simulateTransaction) and running them +// through the same ingestion processors that produce the history API's state +// changes — in memory, without persisting. +type TransactionSimulationService interface { + SimulateStateChanges(ctx context.Context, transactionXDR string) (*SimulatedStateChanges, error) +} + +type transactionSimulationService struct { + rpcService RPCService + ledgerIndexer *indexer.Indexer +} + +var _ TransactionSimulationService = (*transactionSimulationService)(nil) + +func NewTransactionSimulationService(rpcService RPCService, networkPassphrase string) (*transactionSimulationService, error) { + if rpcService == nil { + return nil, errors.New("rpcService cannot be nil") + } + // The indexer runs with nil ingestion metrics: simulation is a read-only + // preview, not ingestion, so it must not feed the ingestion dashboards. + ledgerIndexer, err := indexer.NewIndexer(networkPassphrase, pond.NewPool(runtime.NumCPU()), nil) + if err != nil { + return nil, fmt.Errorf("creating indexer: %w", err) + } + return &transactionSimulationService{ + rpcService: rpcService, + ledgerIndexer: ledgerIndexer, + }, nil +} + +func (s *transactionSimulationService) SimulateStateChanges(ctx context.Context, transactionXDR string) (*SimulatedStateChanges, error) { + var envelope xdr.TransactionEnvelope + if err := xdr.SafeUnmarshalBase64(transactionXDR, &envelope); err != nil { + return nil, fmt.Errorf("%w: %w", ErrInvalidTransactionXDR, err) + } + if len(envelope.Operations()) == 0 { + return nil, fmt.Errorf("%w: transaction has no operations", ErrInvalidTransactionXDR) + } + + if !isSorobanTransaction(envelope) { + return nil, fmt.Errorf("%w: classic transactions are not supported", ErrUnsupportedTransaction) + } + + // TODO(#618, phase 1): call rpcService.SimulateTransaction, map its + // stateChanges/events into a synthesized ingest.LedgerTransaction, and run + // it through stateChangesForTransaction. + return nil, fmt.Errorf("%w: contract transaction simulation is not implemented yet", ErrUnsupportedTransaction) +} + +// isSorobanTransaction reports whether the envelope carries a Soroban operation +// (InvokeHostFunction, ExtendFootprintTtl, or RestoreFootprint). A Soroban +// transaction has exactly one operation, so inspecting the first is enough. +func isSorobanTransaction(envelope xdr.TransactionEnvelope) bool { + switch envelope.Operations()[0].Body.Type { + case xdr.OperationTypeInvokeHostFunction, xdr.OperationTypeExtendFootprintTtl, xdr.OperationTypeRestoreFootprint: + return true + default: + return false + } +} + +// stateChangesForTransaction runs a synthesized ledger transaction through the +// ingestion pipeline into an in-memory buffer — the same processors real +// ingestion uses, with no persistence — and returns the resulting state changes. +func (s *transactionSimulationService) stateChangesForTransaction(ctx context.Context, tx ingest.LedgerTransaction) ([]types.StateChange, error) { + buffer := indexer.NewIndexerBuffer() + if _, err := s.ledgerIndexer.ProcessLedgerTransactions(ctx, []ingest.LedgerTransaction{tx}, buffer); err != nil { + return nil, fmt.Errorf("processing transaction through indexer: %w", err) + } + return buffer.GetStateChanges(), nil +} From 3ed702575c9482986a51eae400a0b9c46038d32f Mon Sep 17 00:00:00 2001 From: jiahuihu Date: Wed, 19 Aug 2026 14:53:14 -0400 Subject: [PATCH 3/4] test(services): walking skeleton proves in-memory pipeline for simulated txs --- .../services/transaction_simulation_test.go | 215 ++++++++++++++++++ 1 file changed, 215 insertions(+) create mode 100644 internal/services/transaction_simulation_test.go diff --git a/internal/services/transaction_simulation_test.go b/internal/services/transaction_simulation_test.go new file mode 100644 index 000000000..55ae923fd --- /dev/null +++ b/internal/services/transaction_simulation_test.go @@ -0,0 +1,215 @@ +package services + +import ( + "context" + "math/big" + "testing" + + "github.com/stellar/go-stellar-sdk/ingest" + "github.com/stellar/go-stellar-sdk/keypair" + "github.com/stellar/go-stellar-sdk/network" + "github.com/stellar/go-stellar-sdk/support/contractevents" + "github.com/stellar/go-stellar-sdk/txnbuild" + "github.com/stellar/go-stellar-sdk/xdr" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/stellar/wallet-backend/internal/indexer/types" +) + +func TestTransactionSimulationService_SimulateStateChanges_errors(t *testing.T) { + svc, err := NewTransactionSimulationService(&RPCServiceMock{}, network.TestNetworkPassphrase) + require.NoError(t, err) + ctx := context.Background() + + t.Run("🔴 invalid XDR", func(t *testing.T) { + _, err := svc.SimulateStateChanges(ctx, "not-xdr") + assert.ErrorIs(t, err, ErrInvalidTransactionXDR) + }) + + t.Run("🔴 classic transaction unsupported", func(t *testing.T) { + _, err := svc.SimulateStateChanges(ctx, buildTxXDR(t, &txnbuild.Payment{ + Destination: keypair.MustRandom().Address(), + Amount: "1", + Asset: txnbuild.NativeAsset{}, + })) + assert.ErrorIs(t, err, ErrUnsupportedTransaction) + }) + + t.Run("🔴 soroban transaction not implemented yet", func(t *testing.T) { + nativeContractID, err := xdr.Asset{Type: xdr.AssetTypeAssetTypeNative}.ContractID(network.TestNetworkPassphrase) + require.NoError(t, err) + contractID := xdr.ContractId(nativeContractID) + _, err = svc.SimulateStateChanges(ctx, buildTxXDR(t, &txnbuild.InvokeHostFunction{ + HostFunction: xdr.HostFunction{ + Type: xdr.HostFunctionTypeHostFunctionTypeInvokeContract, + InvokeContract: &xdr.InvokeContractArgs{ + ContractAddress: xdr.ScAddress{Type: xdr.ScAddressTypeScAddressTypeContract, ContractId: &contractID}, + FunctionName: "transfer", + }, + }, + })) + assert.ErrorIs(t, err, ErrUnsupportedTransaction) + }) +} + +// TestTransactionSimulationService_walkingSkeleton proves Phase 0's core +// assumption: a synthesized ingest.LedgerTransaction — the shape the Soroban +// source will build from RPC simulateTransaction results — runs through the +// real ingestion processors in-memory (no DB) and yields the same state +// changes ingestion would produce. It hardcodes a native-SAC transfer: the +// token-transfer processor must emit a DEBIT for the sender and a CREDIT for +// the receiver. +func TestTransactionSimulationService_walkingSkeleton(t *testing.T) { + svc, err := NewTransactionSimulationService(&RPCServiceMock{}, network.TestNetworkPassphrase) + require.NoError(t, err) + + from := keypair.MustRandom().Address() + to := keypair.MustRandom().Address() + amount := big.NewInt(10_000_000) // 1 XLM in stroops + nativeAsset := xdr.Asset{Type: xdr.AssetTypeAssetTypeNative} + + transferEvent := contractevents.GenerateEvent( + contractevents.EventTypeTransfer, + from, to, "", + nativeAsset, + amount, + network.TestNetworkPassphrase, + ) + tx := synthesizeSorobanTransaction(t, from, transferEvent) + + stateChanges, err := svc.stateChangesForTransaction(context.Background(), tx) + require.NoError(t, err) + require.NotEmpty(t, stateChanges, "the pipeline must emit state changes for the synthesized transfer") + + nativeContractID, err := nativeAsset.ContractID(network.TestNetworkPassphrase) + require.NoError(t, err) + nativeContractAddress, err := strkeyContractID(nativeContractID) + require.NoError(t, err) + + byReason := map[types.StateChangeReason]types.StateChange{} + for _, sc := range stateChanges { + if sc.StateChangeCategory == types.StateChangeCategoryBalance { + byReason[sc.StateChangeReason] = sc + } + } + + debit, ok := byReason[types.StateChangeReasonDebit] + require.True(t, ok, "expected a DEBIT balance change for the sender") + assert.Equal(t, from, string(debit.AccountID)) + assert.Equal(t, "10000000", debit.Amount.String) + assert.Equal(t, nativeContractAddress, debit.TokenID.String()) + + credit, ok := byReason[types.StateChangeReasonCredit] + require.True(t, ok, "expected a CREDIT balance change for the receiver") + assert.Equal(t, to, string(credit.AccountID)) + assert.Equal(t, "10000000", credit.Amount.String) + assert.Equal(t, nativeContractAddress, credit.TokenID.String()) +} + +// synthesizeSorobanTransaction assembles the minimal ingest.LedgerTransaction +// the processors need: an InvokeHostFunction envelope, a successful result, +// and a V3 meta carrying the given contract events — the same synthesis the +// Soroban source will perform on RPC simulateTransaction output. The envelope +// operation must be fully encodable (the pipeline marshals it), so it carries +// real invoke-contract args. +func synthesizeSorobanTransaction(t *testing.T, sourceAccount string, events ...xdr.ContractEvent) ingest.LedgerTransaction { + t.Helper() + + nativeContractID, err := xdr.Asset{Type: xdr.AssetTypeAssetTypeNative}.ContractID(network.TestNetworkPassphrase) + require.NoError(t, err) + contractID := xdr.ContractId(nativeContractID) + + sourceAID := xdr.MustAddress(sourceAccount) + return ingest.LedgerTransaction{ + Index: 1, + Ledger: xdr.LedgerCloseMeta{ + V: 0, + V0: &xdr.LedgerCloseMetaV0{ + LedgerHeader: xdr.LedgerHeaderHistoryEntry{ + Header: xdr.LedgerHeader{ + LedgerSeq: xdr.Uint32(12345), + ScpValue: xdr.StellarValue{CloseTime: xdr.TimePoint(1234500)}, + }, + }, + }, + }, + Hash: xdr.Hash{1}, + Envelope: xdr.TransactionEnvelope{ + Type: xdr.EnvelopeTypeEnvelopeTypeTx, + V1: &xdr.TransactionV1Envelope{ + Tx: xdr.Transaction{ + SourceAccount: sourceAID.ToMuxedAccount(), + SeqNum: xdr.SequenceNumber(1), + Operations: []xdr.Operation{{ + Body: xdr.OperationBody{ + Type: xdr.OperationTypeInvokeHostFunction, + InvokeHostFunctionOp: &xdr.InvokeHostFunctionOp{ + HostFunction: xdr.HostFunction{ + Type: xdr.HostFunctionTypeHostFunctionTypeInvokeContract, + InvokeContract: &xdr.InvokeContractArgs{ + ContractAddress: xdr.ScAddress{Type: xdr.ScAddressTypeScAddressTypeContract, ContractId: &contractID}, + FunctionName: "transfer", + }, + }, + }, + }, + }}, + }, + }, + }, + Result: xdr.TransactionResultPair{ + TransactionHash: xdr.Hash{1}, + Result: xdr.TransactionResult{ + FeeCharged: xdr.Int64(100), + Result: xdr.TransactionResultResult{ + Code: xdr.TransactionResultCodeTxSuccess, + // One result per operation: the token-transfer processor + // indexes operation results positionally. + Results: &[]xdr.OperationResult{{ + Code: xdr.OperationResultCodeOpInner, + Tr: &xdr.OperationResultTr{ + Type: xdr.OperationTypeInvokeHostFunction, + InvokeHostFunctionResult: &xdr.InvokeHostFunctionResult{ + Code: xdr.InvokeHostFunctionResultCodeInvokeHostFunctionSuccess, + Success: &xdr.Hash{}, + }, + }, + }}, + }, + }, + }, + UnsafeMeta: xdr.TransactionMeta{ + V: 3, + V3: &xdr.TransactionMetaV3{ + Operations: []xdr.OperationMeta{{}}, + SorobanMeta: &xdr.SorobanTransactionMeta{ + Events: events, + }, + }, + }, + } +} + +// buildTxXDR builds an unsigned single-op transaction envelope. +func buildTxXDR(t *testing.T, op txnbuild.Operation) string { + t.Helper() + src := txnbuild.SimpleAccount{AccountID: keypair.MustRandom().Address(), Sequence: 1} + tx, err := txnbuild.NewTransaction(txnbuild.TransactionParams{ + SourceAccount: &src, + Operations: []txnbuild.Operation{op}, + BaseFee: txnbuild.MinBaseFee, + Preconditions: txnbuild.Preconditions{TimeBounds: txnbuild.NewTimeout(300)}, + IncrementSequenceNum: true, + }) + require.NoError(t, err) + b64, err := tx.Base64() + require.NoError(t, err) + return b64 +} + +// strkeyContractID renders a 32-byte contract id as a C... strkey address. +func strkeyContractID(contractID [32]byte) (string, error) { + addr := xdr.ScAddress{Type: xdr.ScAddressTypeScAddressTypeContract, ContractId: (*xdr.ContractId)(&contractID)} + return addr.String() +} From dbdd460cbbc85dcbca9d5cbb43985e24529f9f4a Mon Sep 17 00:00:00 2001 From: jiahuihu Date: Wed, 19 Aug 2026 16:44:45 -0400 Subject: [PATCH 4/4] fix(graphql): satisfy exhaustive lint in simulated state-change converter --- internal/serve/graphql/resolvers/simulation.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/internal/serve/graphql/resolvers/simulation.go b/internal/serve/graphql/resolvers/simulation.go index 0e71729d7..eb3d4fef3 100644 --- a/internal/serve/graphql/resolvers/simulation.go +++ b/internal/serve/graphql/resolvers/simulation.go @@ -115,6 +115,11 @@ func (r *Resolver) convertToSimulatedStateChange(sc types.StateChange) (graphql1 }, nil default: // invalid reason for BALANCE_AUTHORIZATION; falls through to the error below } + case types.StateChangeCategorySigner, types.StateChangeCategorySignatureThreshold, + types.StateChangeCategoryDataEntry, types.StateChangeCategoryHomeDomain, + types.StateChangeCategoryFlags, types.StateChangeCategoryTrustline: + // Classic-source variants: the simulated schema doesn't expose them yet. + // They land with the classic derivation source; falls through to the error below. } return nil, fmt.Errorf("state change has no simulated GraphQL type for (category=%s, reason=%s)", sc.StateChangeCategory, sc.StateChangeReason)