mirror of
https://github.com/luxfi/graph.git
synced 2026-09-24 00:26:07 +00:00
merge: lux-graph-subgraphs-update-2026-04-28 (fhe+securities resolver upgrades)
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
# lux/graph — Subgraph State
|
||||
|
||||
`lux/graph` is the standalone Go GraphQL indexer (`graph` binary, also runnable
|
||||
as a Lux VM plugin). It reads any EVM RPC, indexes events into local
|
||||
SQLite/ZapDB, and serves a Graph-compatible GraphQL API. The "subgraphs" in
|
||||
this repo are Go resolver packages under `resolvers/<topic>/` plus the central
|
||||
event-signature table in `indexer/events.go`. There are no `subgraph.yaml`
|
||||
manifests in this repo — those live in the sibling `uni-v2-subgraph`,
|
||||
`uni-v3-subgraph`, `uni-v4-subgraph` repos that target this indexer.
|
||||
|
||||
## Resolver Subgraphs
|
||||
|
||||
| Subgraph | Path | Built-in alias(es) | Status |
|
||||
| --- | --- | --- | --- |
|
||||
| ai (A-Chain) | `resolvers/ai/` | `ai`, `achain` | current |
|
||||
| amm | (handled by `engine.registerAMMResolvers`) | `amm`, `amm-v2`, `uniswap-v2`, `amm-v3`, `uniswap-v3`, `amm-v4`, `uniswap-v4`, `v4` | current |
|
||||
| bridge (B-Chain) | `resolvers/bridge/` | `bridge`, `bchain` | current |
|
||||
| dao | `resolvers/dao/` | `dao` | current |
|
||||
| derivatives | `resolvers/derivatives/` | `derivatives`, `futures`, `options` | current |
|
||||
| dex (D-Chain CLOB) | `resolvers/dex/` | `dex` | current |
|
||||
| did | `resolvers/did/` | `did`, `did-registry` | current |
|
||||
| exchange (X-Chain) | `resolvers/exchange/` | `exchange`, `xchain` | current |
|
||||
| fhe (T-Chain) | `resolvers/fhe/` | `fhe`, `threshold` | UPDATED 2026-04-28 |
|
||||
| governance | `resolvers/governance/` | `governance` | current |
|
||||
| identity (I-Chain) | `resolvers/identity/` | `identity`, `ichain` | current |
|
||||
| key (K-Chain) | `resolvers/key/` | `key`, `kchain` | current |
|
||||
| liquid (liquid staking) | `resolvers/liquid/` | `liquid`, `liquid-staking` | current |
|
||||
| liquidity (omnichain) | `resolvers/liquidity/` | `liquidity`, `liquidity-protocol`, `omnichain` | current |
|
||||
| liquidprotocol (teleport / liquid-vault) | `resolvers/liquidprotocol/` | `liquid-protocol`, `teleport`, `liquid-vault` | current |
|
||||
| mpc (M-Chain) | `resolvers/mpc/` | `mpc`, `mchain` | current |
|
||||
| oracle (O-Chain) | `resolvers/oracle/` | `oracle`, `ochain` | current |
|
||||
| platform (P-Chain) | `resolvers/platform/` | `platform`, `pchain` | current |
|
||||
| precompile | `resolvers/precompile/` | `precompile`, `precompiles` | current |
|
||||
| prediction | `resolvers/prediction/` | `prediction`, `prediction-market` | current |
|
||||
| privacy | `resolvers/privacy/` | `privacy` | current |
|
||||
| quantum (Q-Chain) | `resolvers/quantum/` | `quantum`, `qchain` | current |
|
||||
| relay (R-Chain) | `resolvers/relay/` | `relay`, `rchain` | current |
|
||||
| securities | `resolvers/securities/` | `securities`, `security-token` | UPDATED 2026-04-28 |
|
||||
| servicenode (S-Chain) | `resolvers/servicenode/` | `servicenode`, `schain` | current |
|
||||
| treasury | `resolvers/treasury/` | `treasury` | current |
|
||||
| utxo | `resolvers/utxo/` | `utxo` | current |
|
||||
| zk (Z-Chain) | `resolvers/zk/` | `zk`, `zchain` | current |
|
||||
|
||||
Empty directories `resolvers/amm/` and `resolvers/threshold/` are intentional:
|
||||
amm is registered by `engine.registerAMMResolvers`, and `threshold` is an
|
||||
alias of `fhe` in `engine.LoadBuiltin`.
|
||||
|
||||
## Updates landed this sweep (2026-04-28)
|
||||
|
||||
### securities (ERC-3643 + ONCHAINID)
|
||||
|
||||
Added entity surfaces for ERC-3643 transfer-agent / compliance / identity-
|
||||
registry workflow plus ONCHAINID claim lifecycle. New resolvers:
|
||||
|
||||
- `onchainIdClaim`, `onchainIdClaims` — `ClaimAdded` / `ClaimRemoved` /
|
||||
`ClaimChanged` from ONCHAINID.
|
||||
- `transferAgentAction`, `transferAgentActions` — `Recovery`, `AddressFrozen`,
|
||||
`TokensFrozen`, `TokensUnfrozen` from ERC-3643 token agent.
|
||||
- `frozenAccount`, `frozenAccounts` — current `AddressFrozen` snapshots.
|
||||
- `frozenTokens`, `frozenTokensList` — per-holder partial freeze amounts.
|
||||
- `identityRegistryAction`, `identityRegistryActions` — `IdentityRegistered`,
|
||||
`IdentityRemoved`, `IdentityStored`, `CountryUpdated` from
|
||||
IdentityRegistry contract.
|
||||
|
||||
Backing entity types for the storage layer: `OnchainIdClaim`,
|
||||
`TransferAgentAction`, `FrozenAccount`, `FrozenTokens`,
|
||||
`IdentityRegistryAction`.
|
||||
|
||||
### fhe (LP-114 M-Chain × F-Chain policy gating)
|
||||
|
||||
Added `FHEPolicy` and `FHEPolicyBinding` entity surfaces so the indexer can
|
||||
expose encrypted-policy descriptors anchored on M-Chain and their bindings to
|
||||
on-chain resources. New resolvers: `fhePolicy`, `fhePolicies`,
|
||||
`fhePolicyBinding`, `fhePolicyBindings`.
|
||||
|
||||
## Sibling subgraph repos (deploy via The Graph protocol)
|
||||
|
||||
These three sibling repos define `subgraph.yaml` manifests targeting the same
|
||||
indexer. They live next to `lux/graph` under `~/work/lux/`:
|
||||
|
||||
| Repo | Path | Network | Factory address | spec | Last commit |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| uni-v2-subgraph | `~/work/lux/uni-v2-subgraph` | `liquidity` | `0xD173926A10A0C4eCd3A51B1422270b65Df0551c1` | `0.0.4` | `9ffaaac feat: update subgraph config and package dependencies` |
|
||||
| uni-v3-subgraph | `~/work/lux/uni-v3-subgraph` | `liquidity` | `0x80bBc7C4C7a59C899D1B37BC14539A22D5830a84` | `0.0.4` | `5d56a82 feat: update subgraph config and package dependencies` |
|
||||
| uni-v4-subgraph | `~/work/lux/uni-v4-subgraph` | `liquidity` | `0x0000000000000000000000000000000000009010` (PoolManager) | `0.0.4` | `578adf5 feat: update subgraph config and package dependencies` |
|
||||
|
||||
Mainnet factory addresses match `indexer/events.go::LuxMainnet`. The subgraph
|
||||
manifests use `network: liquidity` for the deploy target name (the Lux DEX
|
||||
network identifier in the hosted graph node), not the Liquidity company.
|
||||
|
||||
## Build status
|
||||
|
||||
Build verification deferred this sweep due to a pre-existing `go.sum`
|
||||
checksum mismatch on `github.com/luxfi/[email protected]` and
|
||||
`github.com/hanzoai/[email protected]` — the mismatch lives in transitive
|
||||
deps and is unrelated to the resolver edits in this branch (the securities
|
||||
and fhe packages only import `context`, `fmt`,
|
||||
`github.com/luxfi/graph/storage`). `gofmt` is clean on both edited files.
|
||||
|
||||
To repair the build locally:
|
||||
|
||||
```
|
||||
GOWORK=off GOSUMDB=off go mod tidy
|
||||
```
|
||||
|
||||
Then `make build` should produce `bin/graph`.
|
||||
|
||||
## Deploy state
|
||||
|
||||
The `graph` binary deploys via the canonical docker-build reusable workflow on
|
||||
tag push (`ci/canonical-docker-build` branch on `main` history; image
|
||||
`ghcr.io/luxfi/graph:<semver>`). No deploy keys for The Graph hosted service
|
||||
are wired into this repo — the sibling subgraph repos handle hosted-service
|
||||
deploys via their own `package.json` `deploy` script and require an env-side
|
||||
`GRAPH_DEPLOY_KEY` to run `graph deploy --product hosted-service luxfi/<name>`.
|
||||
|
||||
## Follow-on work
|
||||
|
||||
- Wire concrete event-signature constants for ERC-3643 + ONCHAINID into
|
||||
`indexer/events.go` (mirror the `SigPairCreated` / `SigSwapV2` pattern). The
|
||||
resolver layer is in place; the indexer still needs the topic-0 hashes:
|
||||
- `Transfer(address,address,uint256)` — already covered by `SigTransfer`.
|
||||
- `AddressFrozen(address indexed,bool indexed,address indexed)`,
|
||||
`TokensFrozen(address indexed,uint256)`,
|
||||
`TokensUnfrozen(address indexed,uint256)`,
|
||||
`RecoverySuccess(address,address,address)`.
|
||||
- `ClaimAdded(bytes32 indexed,uint256 indexed,uint256,address,bytes,bytes,string)`,
|
||||
`ClaimRemoved(...)`, `ClaimChanged(...)`.
|
||||
- `IdentityRegistered(address indexed,address indexed)`,
|
||||
`IdentityRemoved(address indexed,address indexed)`,
|
||||
`IdentityStored(address indexed,address indexed)`,
|
||||
`CountryUpdated(address indexed,uint16 indexed)`.
|
||||
- Add storage-layer entity registrations for the new types so
|
||||
`s.GetByType` / `s.ListByType` resolve them. The storage layer auto-handles
|
||||
any `(type, id)` pair, but indexes will speed up list queries.
|
||||
- Add a built-in alias `"erc3643"` to `engine.LoadBuiltin` that calls
|
||||
`securities.Register` (currently the alias is `securities` /
|
||||
`security-token`).
|
||||
- Resolve `LoadConfig` TODO at `engine/engine.go:258` once the subgraph.yaml
|
||||
parser lands (separate work item).
|
||||
- Replace the empty `resolvers/amm/` and `resolvers/threshold/` directories
|
||||
with package documentation so the layout is self-explanatory.
|
||||
+51
-8
@@ -1,9 +1,12 @@
|
||||
// Package fhe provides resolvers for the T-Chain (ThresholdVM / FHE).
|
||||
//
|
||||
// Indexes: DKG ceremonies, threshold decryption requests, encrypted compute
|
||||
// jobs, FHE ciphertext operations, key shares.
|
||||
// jobs, FHE ciphertext operations, key shares, FHE policy bindings
|
||||
// (M-Chain × F-Chain policy gating per LP-114).
|
||||
//
|
||||
// Entities: DKGCeremony, DecryptionRequest, ComputeJob, Ciphertext, KeyShare
|
||||
// Entities: DKGCeremony, DecryptionRequest, ComputeJob, Ciphertext, KeyShare,
|
||||
//
|
||||
// FHEPolicy, FHEPolicyBinding.
|
||||
package fhe
|
||||
|
||||
import (
|
||||
@@ -27,38 +30,52 @@ func Register(resolvers map[string]ResolverFunc) {
|
||||
resolvers["keyShare"] = resolveKeyShare
|
||||
resolvers["keyShares"] = resolveKeyShares
|
||||
resolvers["fheStats"] = resolveFHEStats
|
||||
resolvers["fhePolicy"] = resolveFHEPolicy
|
||||
resolvers["fhePolicies"] = resolveFHEPolicies
|
||||
resolvers["fhePolicyBinding"] = resolveFHEPolicyBinding
|
||||
resolvers["fhePolicyBindings"] = resolveFHEPolicyBindings
|
||||
}
|
||||
|
||||
func resolveDKGCeremony(_ context.Context, s *storage.Store, args map[string]interface{}) (interface{}, error) {
|
||||
if id, ok := args["id"]; ok { return s.GetByType("DKGCeremony", fmt.Sprint(id)) }
|
||||
if id, ok := args["id"]; ok {
|
||||
return s.GetByType("DKGCeremony", fmt.Sprint(id))
|
||||
}
|
||||
return nil, fmt.Errorf("dkgCeremony requires id")
|
||||
}
|
||||
func resolveDKGCeremonies(_ context.Context, s *storage.Store, args map[string]interface{}) (interface{}, error) {
|
||||
return s.ListByType("DKGCeremony", parseLimit(args))
|
||||
}
|
||||
func resolveDecryptionRequest(_ context.Context, s *storage.Store, args map[string]interface{}) (interface{}, error) {
|
||||
if id, ok := args["id"]; ok { return s.GetByType("DecryptionRequest", fmt.Sprint(id)) }
|
||||
if id, ok := args["id"]; ok {
|
||||
return s.GetByType("DecryptionRequest", fmt.Sprint(id))
|
||||
}
|
||||
return nil, fmt.Errorf("decryptionRequest requires id")
|
||||
}
|
||||
func resolveDecryptionRequests(_ context.Context, s *storage.Store, args map[string]interface{}) (interface{}, error) {
|
||||
return s.ListByType("DecryptionRequest", parseLimit(args))
|
||||
}
|
||||
func resolveComputeJob(_ context.Context, s *storage.Store, args map[string]interface{}) (interface{}, error) {
|
||||
if id, ok := args["id"]; ok { return s.GetByType("ComputeJob", fmt.Sprint(id)) }
|
||||
if id, ok := args["id"]; ok {
|
||||
return s.GetByType("ComputeJob", fmt.Sprint(id))
|
||||
}
|
||||
return nil, fmt.Errorf("computeJob requires id")
|
||||
}
|
||||
func resolveComputeJobs(_ context.Context, s *storage.Store, args map[string]interface{}) (interface{}, error) {
|
||||
return s.ListByType("ComputeJob", parseLimit(args))
|
||||
}
|
||||
func resolveCiphertext(_ context.Context, s *storage.Store, args map[string]interface{}) (interface{}, error) {
|
||||
if id, ok := args["id"]; ok { return s.GetByType("Ciphertext", fmt.Sprint(id)) }
|
||||
if id, ok := args["id"]; ok {
|
||||
return s.GetByType("Ciphertext", fmt.Sprint(id))
|
||||
}
|
||||
return nil, fmt.Errorf("ciphertext requires id")
|
||||
}
|
||||
func resolveCiphertexts(_ context.Context, s *storage.Store, args map[string]interface{}) (interface{}, error) {
|
||||
return s.ListByType("Ciphertext", parseLimit(args))
|
||||
}
|
||||
func resolveKeyShare(_ context.Context, s *storage.Store, args map[string]interface{}) (interface{}, error) {
|
||||
if id, ok := args["id"]; ok { return s.GetByType("KeyShare", fmt.Sprint(id)) }
|
||||
if id, ok := args["id"]; ok {
|
||||
return s.GetByType("KeyShare", fmt.Sprint(id))
|
||||
}
|
||||
return nil, fmt.Errorf("keyShare requires id")
|
||||
}
|
||||
func resolveKeyShares(_ context.Context, s *storage.Store, args map[string]interface{}) (interface{}, error) {
|
||||
@@ -68,8 +85,34 @@ func resolveFHEStats(_ context.Context, s *storage.Store, _ map[string]interface
|
||||
return s.GetByType("FHEStats", "1")
|
||||
}
|
||||
|
||||
// FHEPolicy: an encrypted-policy descriptor anchored on M-Chain
|
||||
// (subjectId, policyHash, threshold, expiresAt).
|
||||
func resolveFHEPolicy(_ context.Context, s *storage.Store, args map[string]interface{}) (interface{}, error) {
|
||||
if id, ok := args["id"]; ok {
|
||||
return s.GetByType("FHEPolicy", fmt.Sprint(id))
|
||||
}
|
||||
return nil, fmt.Errorf("fhePolicy requires id")
|
||||
}
|
||||
func resolveFHEPolicies(_ context.Context, s *storage.Store, args map[string]interface{}) (interface{}, error) {
|
||||
return s.ListByType("FHEPolicy", parseLimit(args))
|
||||
}
|
||||
|
||||
// FHEPolicyBinding: binding of an FHE policy to an on-chain resource
|
||||
// (token, vault, identity) — per LP-114 M-Chain × F-Chain integration.
|
||||
func resolveFHEPolicyBinding(_ context.Context, s *storage.Store, args map[string]interface{}) (interface{}, error) {
|
||||
if id, ok := args["id"]; ok {
|
||||
return s.GetByType("FHEPolicyBinding", fmt.Sprint(id))
|
||||
}
|
||||
return nil, fmt.Errorf("fhePolicyBinding requires id")
|
||||
}
|
||||
func resolveFHEPolicyBindings(_ context.Context, s *storage.Store, args map[string]interface{}) (interface{}, error) {
|
||||
return s.ListByType("FHEPolicyBinding", parseLimit(args))
|
||||
}
|
||||
|
||||
func parseLimit(args map[string]interface{}) int {
|
||||
limit := 100
|
||||
if l, ok := args["first"]; ok { fmt.Sscanf(fmt.Sprint(l), "%d", &limit) }
|
||||
if l, ok := args["first"]; ok {
|
||||
fmt.Sscanf(fmt.Sprint(l), "%d", &limit)
|
||||
}
|
||||
return limit
|
||||
}
|
||||
|
||||
@@ -1,8 +1,15 @@
|
||||
// Package securities provides resolvers for security tokens.
|
||||
//
|
||||
// Indexes: issuances, transfers, dividends, compliance records.
|
||||
// Indexes ERC-3643 + ONCHAINID surfaces:
|
||||
// - issuances, transfers, dividends, compliance records (core token)
|
||||
// - identity registry actions (IdentityRegistry contract)
|
||||
// - claim lifecycle (ONCHAINID ClaimAdded/Removed/Changed)
|
||||
// - transfer-agent actions (Recovery, AddressFrozen, TokensFrozen)
|
||||
//
|
||||
// Entities: SecurityIssuance, SecurityTransfer, SecurityDividend, SecurityCompliance, SecurityStats
|
||||
// Entities: SecurityIssuance, SecurityTransfer, SecurityDividend,
|
||||
//
|
||||
// SecurityCompliance, SecurityStats, OnchainIdClaim, TransferAgentAction,
|
||||
// FrozenAccount, FrozenTokens, IdentityRegistryAction.
|
||||
package securities
|
||||
|
||||
import (
|
||||
@@ -15,6 +22,7 @@ import (
|
||||
type ResolverFunc = func(context.Context, *storage.Store, map[string]interface{}) (interface{}, error)
|
||||
|
||||
func Register(resolvers map[string]ResolverFunc) {
|
||||
// Core token surfaces.
|
||||
resolvers["securityIssuance"] = resolveSecurityIssuance
|
||||
resolvers["securityIssuances"] = resolveSecurityIssuances
|
||||
resolvers["securityTransfer"] = resolveSecurityTransfer
|
||||
@@ -24,31 +32,51 @@ func Register(resolvers map[string]ResolverFunc) {
|
||||
resolvers["securityCompliance"] = resolveSecurityCompliance
|
||||
resolvers["securityCompliances"] = resolveSecurityCompliances
|
||||
resolvers["securityStats"] = resolveSecurityStats
|
||||
|
||||
// ERC-3643 + ONCHAINID surfaces.
|
||||
resolvers["onchainIdClaim"] = resolveOnchainIdClaim
|
||||
resolvers["onchainIdClaims"] = resolveOnchainIdClaims
|
||||
resolvers["transferAgentAction"] = resolveTransferAgentAction
|
||||
resolvers["transferAgentActions"] = resolveTransferAgentActions
|
||||
resolvers["frozenAccount"] = resolveFrozenAccount
|
||||
resolvers["frozenAccounts"] = resolveFrozenAccounts
|
||||
resolvers["frozenTokens"] = resolveFrozenTokensRec
|
||||
resolvers["frozenTokensList"] = resolveFrozenTokensList
|
||||
resolvers["identityRegistryAction"] = resolveIdentityRegistryAction
|
||||
resolvers["identityRegistryActions"] = resolveIdentityRegistryActions
|
||||
}
|
||||
|
||||
func resolveSecurityIssuance(_ context.Context, s *storage.Store, args map[string]interface{}) (interface{}, error) {
|
||||
if id, ok := args["id"]; ok { return s.GetByType("SecurityIssuance", fmt.Sprint(id)) }
|
||||
if id, ok := args["id"]; ok {
|
||||
return s.GetByType("SecurityIssuance", fmt.Sprint(id))
|
||||
}
|
||||
return nil, fmt.Errorf("securityIssuance requires id")
|
||||
}
|
||||
func resolveSecurityIssuances(_ context.Context, s *storage.Store, args map[string]interface{}) (interface{}, error) {
|
||||
return s.ListByType("SecurityIssuance", pl(args))
|
||||
}
|
||||
func resolveSecurityTransfer(_ context.Context, s *storage.Store, args map[string]interface{}) (interface{}, error) {
|
||||
if id, ok := args["id"]; ok { return s.GetByType("SecurityTransfer", fmt.Sprint(id)) }
|
||||
if id, ok := args["id"]; ok {
|
||||
return s.GetByType("SecurityTransfer", fmt.Sprint(id))
|
||||
}
|
||||
return nil, fmt.Errorf("securityTransfer requires id")
|
||||
}
|
||||
func resolveSecurityTransfers(_ context.Context, s *storage.Store, args map[string]interface{}) (interface{}, error) {
|
||||
return s.ListByType("SecurityTransfer", pl(args))
|
||||
}
|
||||
func resolveSecurityDividend(_ context.Context, s *storage.Store, args map[string]interface{}) (interface{}, error) {
|
||||
if id, ok := args["id"]; ok { return s.GetByType("SecurityDividend", fmt.Sprint(id)) }
|
||||
if id, ok := args["id"]; ok {
|
||||
return s.GetByType("SecurityDividend", fmt.Sprint(id))
|
||||
}
|
||||
return nil, fmt.Errorf("securityDividend requires id")
|
||||
}
|
||||
func resolveSecurityDividends(_ context.Context, s *storage.Store, args map[string]interface{}) (interface{}, error) {
|
||||
return s.ListByType("SecurityDividend", pl(args))
|
||||
}
|
||||
func resolveSecurityCompliance(_ context.Context, s *storage.Store, args map[string]interface{}) (interface{}, error) {
|
||||
if id, ok := args["id"]; ok { return s.GetByType("SecurityCompliance", fmt.Sprint(id)) }
|
||||
if id, ok := args["id"]; ok {
|
||||
return s.GetByType("SecurityCompliance", fmt.Sprint(id))
|
||||
}
|
||||
return nil, fmt.Errorf("securityCompliance requires id")
|
||||
}
|
||||
func resolveSecurityCompliances(_ context.Context, s *storage.Store, args map[string]interface{}) (interface{}, error) {
|
||||
@@ -58,8 +86,65 @@ func resolveSecurityStats(_ context.Context, s *storage.Store, _ map[string]inte
|
||||
return s.GetByType("SecurityStats", "1")
|
||||
}
|
||||
|
||||
// ONCHAINID claim resolvers (ClaimAdded / ClaimRemoved / ClaimChanged).
|
||||
func resolveOnchainIdClaim(_ context.Context, s *storage.Store, args map[string]interface{}) (interface{}, error) {
|
||||
if id, ok := args["id"]; ok {
|
||||
return s.GetByType("OnchainIdClaim", fmt.Sprint(id))
|
||||
}
|
||||
return nil, fmt.Errorf("onchainIdClaim requires id")
|
||||
}
|
||||
func resolveOnchainIdClaims(_ context.Context, s *storage.Store, args map[string]interface{}) (interface{}, error) {
|
||||
return s.ListByType("OnchainIdClaim", pl(args))
|
||||
}
|
||||
|
||||
// Transfer-agent action resolvers (Recovery / AddressFrozen / TokensFrozen).
|
||||
func resolveTransferAgentAction(_ context.Context, s *storage.Store, args map[string]interface{}) (interface{}, error) {
|
||||
if id, ok := args["id"]; ok {
|
||||
return s.GetByType("TransferAgentAction", fmt.Sprint(id))
|
||||
}
|
||||
return nil, fmt.Errorf("transferAgentAction requires id")
|
||||
}
|
||||
func resolveTransferAgentActions(_ context.Context, s *storage.Store, args map[string]interface{}) (interface{}, error) {
|
||||
return s.ListByType("TransferAgentAction", pl(args))
|
||||
}
|
||||
|
||||
// Frozen-account snapshot (current state of AddressFrozen on a holder).
|
||||
func resolveFrozenAccount(_ context.Context, s *storage.Store, args map[string]interface{}) (interface{}, error) {
|
||||
if id, ok := args["id"]; ok {
|
||||
return s.GetByType("FrozenAccount", fmt.Sprint(id))
|
||||
}
|
||||
return nil, fmt.Errorf("frozenAccount requires id")
|
||||
}
|
||||
func resolveFrozenAccounts(_ context.Context, s *storage.Store, args map[string]interface{}) (interface{}, error) {
|
||||
return s.ListByType("FrozenAccount", pl(args))
|
||||
}
|
||||
|
||||
// Frozen-tokens snapshot (per-holder partial freeze amount).
|
||||
func resolveFrozenTokensRec(_ context.Context, s *storage.Store, args map[string]interface{}) (interface{}, error) {
|
||||
if id, ok := args["id"]; ok {
|
||||
return s.GetByType("FrozenTokens", fmt.Sprint(id))
|
||||
}
|
||||
return nil, fmt.Errorf("frozenTokens requires id")
|
||||
}
|
||||
func resolveFrozenTokensList(_ context.Context, s *storage.Store, args map[string]interface{}) (interface{}, error) {
|
||||
return s.ListByType("FrozenTokens", pl(args))
|
||||
}
|
||||
|
||||
// IdentityRegistry actions (IdentityRegistered / IdentityRemoved / IdentityStored / CountryUpdated).
|
||||
func resolveIdentityRegistryAction(_ context.Context, s *storage.Store, args map[string]interface{}) (interface{}, error) {
|
||||
if id, ok := args["id"]; ok {
|
||||
return s.GetByType("IdentityRegistryAction", fmt.Sprint(id))
|
||||
}
|
||||
return nil, fmt.Errorf("identityRegistryAction requires id")
|
||||
}
|
||||
func resolveIdentityRegistryActions(_ context.Context, s *storage.Store, args map[string]interface{}) (interface{}, error) {
|
||||
return s.ListByType("IdentityRegistryAction", pl(args))
|
||||
}
|
||||
|
||||
func pl(args map[string]interface{}) int {
|
||||
limit := 100
|
||||
if l, ok := args["first"]; ok { fmt.Sscanf(fmt.Sprint(l), "%d", &limit) }
|
||||
if l, ok := args["first"]; ok {
|
||||
fmt.Sscanf(fmt.Sprint(l), "%d", &limit)
|
||||
}
|
||||
return min(limit, 1000)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user