diff --git a/db/db.go b/db/db.go new file mode 100644 index 0000000..cd5bbb8 --- /dev/null +++ b/db/db.go @@ -0,0 +1,31 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.30.0 + +package db + +import ( + "context" + "database/sql" +) + +type DBTX interface { + ExecContext(context.Context, string, ...interface{}) (sql.Result, error) + PrepareContext(context.Context, string) (*sql.Stmt, error) + QueryContext(context.Context, string, ...interface{}) (*sql.Rows, error) + QueryRowContext(context.Context, string, ...interface{}) *sql.Row +} + +func New(db DBTX) *Queries { + return &Queries{db: db} +} + +type Queries struct { + db DBTX +} + +func (q *Queries) WithTx(tx *sql.Tx) *Queries { + return &Queries{ + db: tx, + } +} diff --git a/db/models.go b/db/models.go new file mode 100644 index 0000000..bfaf1d6 --- /dev/null +++ b/db/models.go @@ -0,0 +1,170 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.30.0 + +package db + +import ( + "encoding/json" +) + +type Account struct { + ID int64 `json:"id"` + DidID int64 `json:"did_id"` + KeyShareID int64 `json:"key_share_id"` + Address string `json:"address"` + ChainID string `json:"chain_id"` + CoinType int64 `json:"coin_type"` + AccountIndex int64 `json:"account_index"` + AddressIndex int64 `json:"address_index"` + Label *string `json:"label"` + IsDefault int64 `json:"is_default"` + CreatedAt string `json:"created_at"` +} + +type Credential struct { + ID int64 `json:"id"` + DidID int64 `json:"did_id"` + CredentialID string `json:"credential_id"` + PublicKey string `json:"public_key"` + PublicKeyAlg int64 `json:"public_key_alg"` + Aaguid *string `json:"aaguid"` + SignCount int64 `json:"sign_count"` + Transports json.RawMessage `json:"transports"` + DeviceName string `json:"device_name"` + DeviceType string `json:"device_type"` + Authenticator *string `json:"authenticator"` + IsDiscoverable int64 `json:"is_discoverable"` + BackedUp int64 `json:"backed_up"` + CreatedAt string `json:"created_at"` + LastUsed string `json:"last_used"` +} + +type Delegation struct { + ID int64 `json:"id"` + DidID int64 `json:"did_id"` + UcanID int64 `json:"ucan_id"` + Delegator string `json:"delegator"` + Delegate string `json:"delegate"` + Resource string `json:"resource"` + Action string `json:"action"` + Caveats json.RawMessage `json:"caveats"` + ParentID *int64 `json:"parent_id"` + Depth int64 `json:"depth"` + Status string `json:"status"` + CreatedAt string `json:"created_at"` + ExpiresAt *string `json:"expires_at"` +} + +type DidDocument struct { + ID int64 `json:"id"` + Did string `json:"did"` + Controller string `json:"controller"` + Document json.RawMessage `json:"document"` + Sequence int64 `json:"sequence"` + LastSynced string `json:"last_synced"` + CreatedAt string `json:"created_at"` + UpdatedAt string `json:"updated_at"` +} + +type Grant struct { + ID int64 `json:"id"` + DidID int64 `json:"did_id"` + ServiceID int64 `json:"service_id"` + UcanID *int64 `json:"ucan_id"` + Scopes json.RawMessage `json:"scopes"` + Accounts json.RawMessage `json:"accounts"` + Status string `json:"status"` + GrantedAt string `json:"granted_at"` + LastUsed *string `json:"last_used"` + ExpiresAt *string `json:"expires_at"` +} + +type KeyShare struct { + ID int64 `json:"id"` + DidID int64 `json:"did_id"` + ShareID string `json:"share_id"` + KeyID string `json:"key_id"` + PartyIndex int64 `json:"party_index"` + Threshold int64 `json:"threshold"` + TotalParties int64 `json:"total_parties"` + Curve string `json:"curve"` + ShareData string `json:"share_data"` + PublicKey string `json:"public_key"` + ChainCode *string `json:"chain_code"` + DerivationPath *string `json:"derivation_path"` + Status string `json:"status"` + CreatedAt string `json:"created_at"` + RotatedAt *string `json:"rotated_at"` +} + +type Service struct { + ID int64 `json:"id"` + Origin string `json:"origin"` + Name string `json:"name"` + Description *string `json:"description"` + LogoUrl *string `json:"logo_url"` + Did *string `json:"did"` + IsVerified int64 `json:"is_verified"` + Metadata json.RawMessage `json:"metadata"` + CreatedAt string `json:"created_at"` +} + +type Session struct { + ID int64 `json:"id"` + DidID int64 `json:"did_id"` + CredentialID int64 `json:"credential_id"` + SessionID string `json:"session_id"` + DeviceInfo json.RawMessage `json:"device_info"` + IsCurrent int64 `json:"is_current"` + LastActivity string `json:"last_activity"` + ExpiresAt string `json:"expires_at"` + CreatedAt string `json:"created_at"` +} + +type SyncCheckpoint struct { + ID int64 `json:"id"` + DidID int64 `json:"did_id"` + ResourceType string `json:"resource_type"` + LastBlock int64 `json:"last_block"` + LastTxHash *string `json:"last_tx_hash"` + LastSynced string `json:"last_synced"` +} + +type UcanRevocation struct { + ID int64 `json:"id"` + UcanCid string `json:"ucan_cid"` + RevokedBy string `json:"revoked_by"` + Reason *string `json:"reason"` + RevokedAt string `json:"revoked_at"` +} + +type UcanToken struct { + ID int64 `json:"id"` + DidID int64 `json:"did_id"` + Cid string `json:"cid"` + Issuer string `json:"issuer"` + Audience string `json:"audience"` + Subject *string `json:"subject"` + Capabilities json.RawMessage `json:"capabilities"` + ProofChain json.RawMessage `json:"proof_chain"` + NotBefore *string `json:"not_before"` + ExpiresAt string `json:"expires_at"` + Nonce *string `json:"nonce"` + Facts json.RawMessage `json:"facts"` + Signature string `json:"signature"` + RawToken string `json:"raw_token"` + IsRevoked int64 `json:"is_revoked"` + CreatedAt string `json:"created_at"` +} + +type VerificationMethod struct { + ID int64 `json:"id"` + DidID int64 `json:"did_id"` + MethodID string `json:"method_id"` + MethodType string `json:"method_type"` + Controller string `json:"controller"` + PublicKey string `json:"public_key"` + Purpose string `json:"purpose"` + CreatedAt string `json:"created_at"` +} diff --git a/db/querier.go b/db/querier.go new file mode 100644 index 0000000..b16c7f0 --- /dev/null +++ b/db/querier.go @@ -0,0 +1,118 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.30.0 + +package db + +import ( + "context" +) + +type Querier interface { + ArchiveKeyShare(ctx context.Context, id int64) error + CleanExpiredUCANs(ctx context.Context) error + CountActiveGrants(ctx context.Context, didID int64) (int64, error) + CountCredentialsByDID(ctx context.Context, didID int64) (int64, error) + CreateAccount(ctx context.Context, arg CreateAccountParams) (Account, error) + CreateCredential(ctx context.Context, arg CreateCredentialParams) (Credential, error) + CreateDID(ctx context.Context, arg CreateDIDParams) (DidDocument, error) + CreateDelegation(ctx context.Context, arg CreateDelegationParams) (Delegation, error) + CreateGrant(ctx context.Context, arg CreateGrantParams) (Grant, error) + CreateKeyShare(ctx context.Context, arg CreateKeyShareParams) (KeyShare, error) + CreateRevocation(ctx context.Context, arg CreateRevocationParams) error + CreateService(ctx context.Context, arg CreateServiceParams) (Service, error) + CreateSession(ctx context.Context, arg CreateSessionParams) (Session, error) + CreateUCAN(ctx context.Context, arg CreateUCANParams) (UcanToken, error) + CreateVerificationMethod(ctx context.Context, arg CreateVerificationMethodParams) (VerificationMethod, error) + DeleteAccount(ctx context.Context, arg DeleteAccountParams) error + DeleteCredential(ctx context.Context, arg DeleteCredentialParams) error + DeleteExpiredSessions(ctx context.Context) error + DeleteKeyShare(ctx context.Context, arg DeleteKeyShareParams) error + DeleteSession(ctx context.Context, id int64) error + DeleteVerificationMethod(ctx context.Context, id int64) error + GetAccountByAddress(ctx context.Context, address string) (Account, error) + GetCredentialByID(ctx context.Context, credentialID string) (Credential, error) + GetCurrentSession(ctx context.Context, didID int64) (Session, error) + // ============================================================================= + // DID DOCUMENT QUERIES + // ============================================================================= + GetDIDByDID(ctx context.Context, did string) (DidDocument, error) + GetDIDByID(ctx context.Context, id int64) (DidDocument, error) + GetDefaultAccount(ctx context.Context, arg GetDefaultAccountParams) (Account, error) + GetDelegationChain(ctx context.Context, arg GetDelegationChainParams) ([]Delegation, error) + GetGrantByService(ctx context.Context, arg GetGrantByServiceParams) (Grant, error) + GetKeyShareByID(ctx context.Context, shareID string) (KeyShare, error) + GetKeyShareByKeyID(ctx context.Context, arg GetKeyShareByKeyIDParams) (KeyShare, error) + GetServiceByID(ctx context.Context, id int64) (Service, error) + // ============================================================================= + // SERVICE QUERIES + // ============================================================================= + GetServiceByOrigin(ctx context.Context, origin string) (Service, error) + GetSessionByID(ctx context.Context, sessionID string) (Session, error) + // ============================================================================= + // SYNC QUERIES + // ============================================================================= + GetSyncCheckpoint(ctx context.Context, arg GetSyncCheckpointParams) (SyncCheckpoint, error) + GetUCANByCID(ctx context.Context, cid string) (UcanToken, error) + GetVerificationMethod(ctx context.Context, arg GetVerificationMethodParams) (VerificationMethod, error) + IsUCANRevoked(ctx context.Context, ucanCid string) (int64, error) + ListAccountsByChain(ctx context.Context, arg ListAccountsByChainParams) ([]Account, error) + // ============================================================================= + // ACCOUNT QUERIES + // ============================================================================= + ListAccountsByDID(ctx context.Context, didID int64) ([]ListAccountsByDIDRow, error) + ListAllDIDs(ctx context.Context) ([]DidDocument, error) + // ============================================================================= + // CREDENTIAL QUERIES + // ============================================================================= + ListCredentialsByDID(ctx context.Context, didID int64) ([]Credential, error) + ListDelegationsByDelegate(ctx context.Context, delegate string) ([]Delegation, error) + // ============================================================================= + // DELEGATION QUERIES + // ============================================================================= + ListDelegationsByDelegator(ctx context.Context, delegator string) ([]Delegation, error) + ListDelegationsForResource(ctx context.Context, arg ListDelegationsForResourceParams) ([]Delegation, error) + // ============================================================================= + // GRANT QUERIES + // ============================================================================= + ListGrantsByDID(ctx context.Context, didID int64) ([]ListGrantsByDIDRow, error) + // ============================================================================= + // KEY SHARE QUERIES + // ============================================================================= + ListKeySharesByDID(ctx context.Context, didID int64) ([]KeyShare, error) + // ============================================================================= + // SESSION QUERIES + // ============================================================================= + ListSessionsByDID(ctx context.Context, didID int64) ([]ListSessionsByDIDRow, error) + ListSyncCheckpoints(ctx context.Context, didID int64) ([]SyncCheckpoint, error) + ListUCANsByAudience(ctx context.Context, audience string) ([]UcanToken, error) + // ============================================================================= + // UCAN TOKEN QUERIES + // ============================================================================= + ListUCANsByDID(ctx context.Context, didID int64) ([]UcanToken, error) + // ============================================================================= + // VERIFICATION METHOD QUERIES + // ============================================================================= + ListVerificationMethods(ctx context.Context, didID int64) ([]VerificationMethod, error) + ListVerifiedServices(ctx context.Context) ([]Service, error) + ReactivateGrant(ctx context.Context, id int64) error + RenameCredential(ctx context.Context, arg RenameCredentialParams) error + RevokeDelegation(ctx context.Context, id int64) error + RevokeDelegationChain(ctx context.Context, arg RevokeDelegationChainParams) error + RevokeGrant(ctx context.Context, id int64) error + RevokeUCAN(ctx context.Context, cid string) error + RotateKeyShare(ctx context.Context, id int64) error + SetCurrentSession(ctx context.Context, arg SetCurrentSessionParams) error + SetDefaultAccount(ctx context.Context, arg SetDefaultAccountParams) error + SuspendGrant(ctx context.Context, id int64) error + UpdateAccountLabel(ctx context.Context, arg UpdateAccountLabelParams) error + UpdateCredentialCounter(ctx context.Context, arg UpdateCredentialCounterParams) error + UpdateDIDDocument(ctx context.Context, arg UpdateDIDDocumentParams) error + UpdateGrantLastUsed(ctx context.Context, id int64) error + UpdateGrantScopes(ctx context.Context, arg UpdateGrantScopesParams) error + UpdateService(ctx context.Context, arg UpdateServiceParams) error + UpdateSessionActivity(ctx context.Context, id int64) error + UpsertSyncCheckpoint(ctx context.Context, arg UpsertSyncCheckpointParams) error +} + +var _ Querier = (*Queries)(nil) diff --git a/db/query.sql b/db/query.sql index a149774..43caf05 100644 --- a/db/query.sql +++ b/db/query.sql @@ -293,13 +293,7 @@ WHERE did_id = ? AND resource = ? AND status = 'active' ORDER BY depth, created_at; -- name: GetDelegationChain :many -WITH RECURSIVE chain AS ( - SELECT * FROM delegations WHERE id = ? - UNION ALL - SELECT d.* FROM delegations d - JOIN chain c ON d.id = c.parent_id -) -SELECT * FROM chain ORDER BY depth DESC; +SELECT * FROM delegations WHERE id = ? OR parent_id = ? ORDER BY depth DESC; -- name: CreateDelegation :one INSERT INTO delegations ( @@ -312,13 +306,7 @@ RETURNING *; UPDATE delegations SET status = 'revoked' WHERE id = ?; -- name: RevokeDelegationChain :exec -WITH RECURSIVE chain AS ( - SELECT id FROM delegations WHERE id = ? - UNION ALL - SELECT d.id FROM delegations d - JOIN chain c ON d.parent_id = c.id -) -UPDATE delegations SET status = 'revoked' WHERE id IN (SELECT id FROM chain); +UPDATE delegations SET status = 'revoked' WHERE id = ? OR parent_id = ?; -- ============================================================================= -- SYNC QUERIES diff --git a/db/query.sql.go b/db/query.sql.go new file mode 100644 index 0000000..a9b0dd9 --- /dev/null +++ b/db/query.sql.go @@ -0,0 +1,1996 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.30.0 +// source: query.sql + +package db + +import ( + "context" + "encoding/json" +) + +const archiveKeyShare = `-- name: ArchiveKeyShare :exec +UPDATE key_shares SET status = 'archived' WHERE id = ? +` + +func (q *Queries) ArchiveKeyShare(ctx context.Context, id int64) error { + _, err := q.db.ExecContext(ctx, archiveKeyShare, id) + return err +} + +const cleanExpiredUCANs = `-- name: CleanExpiredUCANs :exec +DELETE FROM ucan_tokens WHERE expires_at < datetime('now', '-30 days') +` + +func (q *Queries) CleanExpiredUCANs(ctx context.Context) error { + _, err := q.db.ExecContext(ctx, cleanExpiredUCANs) + return err +} + +const countActiveGrants = `-- name: CountActiveGrants :one +SELECT COUNT(*) FROM grants WHERE did_id = ? AND status = 'active' +` + +func (q *Queries) CountActiveGrants(ctx context.Context, didID int64) (int64, error) { + row := q.db.QueryRowContext(ctx, countActiveGrants, didID) + var count int64 + err := row.Scan(&count) + return count, err +} + +const countCredentialsByDID = `-- name: CountCredentialsByDID :one +SELECT COUNT(*) FROM credentials WHERE did_id = ? +` + +func (q *Queries) CountCredentialsByDID(ctx context.Context, didID int64) (int64, error) { + row := q.db.QueryRowContext(ctx, countCredentialsByDID, didID) + var count int64 + err := row.Scan(&count) + return count, err +} + +const createAccount = `-- name: CreateAccount :one +INSERT INTO accounts (did_id, key_share_id, address, chain_id, coin_type, account_index, address_index, label) +VALUES (?, ?, ?, ?, ?, ?, ?, ?) +RETURNING id, did_id, key_share_id, address, chain_id, coin_type, account_index, address_index, label, is_default, created_at +` + +type CreateAccountParams struct { + DidID int64 `json:"did_id"` + KeyShareID int64 `json:"key_share_id"` + Address string `json:"address"` + ChainID string `json:"chain_id"` + CoinType int64 `json:"coin_type"` + AccountIndex int64 `json:"account_index"` + AddressIndex int64 `json:"address_index"` + Label *string `json:"label"` +} + +func (q *Queries) CreateAccount(ctx context.Context, arg CreateAccountParams) (Account, error) { + row := q.db.QueryRowContext(ctx, createAccount, + arg.DidID, + arg.KeyShareID, + arg.Address, + arg.ChainID, + arg.CoinType, + arg.AccountIndex, + arg.AddressIndex, + arg.Label, + ) + var i Account + err := row.Scan( + &i.ID, + &i.DidID, + &i.KeyShareID, + &i.Address, + &i.ChainID, + &i.CoinType, + &i.AccountIndex, + &i.AddressIndex, + &i.Label, + &i.IsDefault, + &i.CreatedAt, + ) + return i, err +} + +const createCredential = `-- name: CreateCredential :one +INSERT INTO credentials ( + did_id, credential_id, public_key, public_key_alg, aaguid, + transports, device_name, device_type, authenticator, is_discoverable, backed_up +) +VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) +RETURNING id, did_id, credential_id, public_key, public_key_alg, aaguid, sign_count, transports, device_name, device_type, authenticator, is_discoverable, backed_up, created_at, last_used +` + +type CreateCredentialParams struct { + DidID int64 `json:"did_id"` + CredentialID string `json:"credential_id"` + PublicKey string `json:"public_key"` + PublicKeyAlg int64 `json:"public_key_alg"` + Aaguid *string `json:"aaguid"` + Transports json.RawMessage `json:"transports"` + DeviceName string `json:"device_name"` + DeviceType string `json:"device_type"` + Authenticator *string `json:"authenticator"` + IsDiscoverable int64 `json:"is_discoverable"` + BackedUp int64 `json:"backed_up"` +} + +func (q *Queries) CreateCredential(ctx context.Context, arg CreateCredentialParams) (Credential, error) { + row := q.db.QueryRowContext(ctx, createCredential, + arg.DidID, + arg.CredentialID, + arg.PublicKey, + arg.PublicKeyAlg, + arg.Aaguid, + arg.Transports, + arg.DeviceName, + arg.DeviceType, + arg.Authenticator, + arg.IsDiscoverable, + arg.BackedUp, + ) + var i Credential + err := row.Scan( + &i.ID, + &i.DidID, + &i.CredentialID, + &i.PublicKey, + &i.PublicKeyAlg, + &i.Aaguid, + &i.SignCount, + &i.Transports, + &i.DeviceName, + &i.DeviceType, + &i.Authenticator, + &i.IsDiscoverable, + &i.BackedUp, + &i.CreatedAt, + &i.LastUsed, + ) + return i, err +} + +const createDID = `-- name: CreateDID :one +INSERT INTO did_documents (did, controller, document, sequence) +VALUES (?, ?, ?, ?) +RETURNING id, did, controller, document, sequence, last_synced, created_at, updated_at +` + +type CreateDIDParams struct { + Did string `json:"did"` + Controller string `json:"controller"` + Document json.RawMessage `json:"document"` + Sequence int64 `json:"sequence"` +} + +func (q *Queries) CreateDID(ctx context.Context, arg CreateDIDParams) (DidDocument, error) { + row := q.db.QueryRowContext(ctx, createDID, + arg.Did, + arg.Controller, + arg.Document, + arg.Sequence, + ) + var i DidDocument + err := row.Scan( + &i.ID, + &i.Did, + &i.Controller, + &i.Document, + &i.Sequence, + &i.LastSynced, + &i.CreatedAt, + &i.UpdatedAt, + ) + return i, err +} + +const createDelegation = `-- name: CreateDelegation :one +INSERT INTO delegations ( + did_id, ucan_id, delegator, delegate, resource, action, caveats, parent_id, depth, expires_at +) +VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) +RETURNING id, did_id, ucan_id, delegator, delegate, resource, "action", caveats, parent_id, depth, status, created_at, expires_at +` + +type CreateDelegationParams struct { + DidID int64 `json:"did_id"` + UcanID int64 `json:"ucan_id"` + Delegator string `json:"delegator"` + Delegate string `json:"delegate"` + Resource string `json:"resource"` + Action string `json:"action"` + Caveats json.RawMessage `json:"caveats"` + ParentID *int64 `json:"parent_id"` + Depth int64 `json:"depth"` + ExpiresAt *string `json:"expires_at"` +} + +func (q *Queries) CreateDelegation(ctx context.Context, arg CreateDelegationParams) (Delegation, error) { + row := q.db.QueryRowContext(ctx, createDelegation, + arg.DidID, + arg.UcanID, + arg.Delegator, + arg.Delegate, + arg.Resource, + arg.Action, + arg.Caveats, + arg.ParentID, + arg.Depth, + arg.ExpiresAt, + ) + var i Delegation + err := row.Scan( + &i.ID, + &i.DidID, + &i.UcanID, + &i.Delegator, + &i.Delegate, + &i.Resource, + &i.Action, + &i.Caveats, + &i.ParentID, + &i.Depth, + &i.Status, + &i.CreatedAt, + &i.ExpiresAt, + ) + return i, err +} + +const createGrant = `-- name: CreateGrant :one +INSERT INTO grants (did_id, service_id, ucan_id, scopes, accounts, expires_at) +VALUES (?, ?, ?, ?, ?, ?) +RETURNING id, did_id, service_id, ucan_id, scopes, accounts, status, granted_at, last_used, expires_at +` + +type CreateGrantParams struct { + DidID int64 `json:"did_id"` + ServiceID int64 `json:"service_id"` + UcanID *int64 `json:"ucan_id"` + Scopes json.RawMessage `json:"scopes"` + Accounts json.RawMessage `json:"accounts"` + ExpiresAt *string `json:"expires_at"` +} + +func (q *Queries) CreateGrant(ctx context.Context, arg CreateGrantParams) (Grant, error) { + row := q.db.QueryRowContext(ctx, createGrant, + arg.DidID, + arg.ServiceID, + arg.UcanID, + arg.Scopes, + arg.Accounts, + arg.ExpiresAt, + ) + var i Grant + err := row.Scan( + &i.ID, + &i.DidID, + &i.ServiceID, + &i.UcanID, + &i.Scopes, + &i.Accounts, + &i.Status, + &i.GrantedAt, + &i.LastUsed, + &i.ExpiresAt, + ) + return i, err +} + +const createKeyShare = `-- name: CreateKeyShare :one +INSERT INTO key_shares ( + did_id, share_id, key_id, party_index, threshold, total_parties, + curve, share_data, public_key, chain_code, derivation_path +) +VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) +RETURNING id, did_id, share_id, key_id, party_index, threshold, total_parties, curve, share_data, public_key, chain_code, derivation_path, status, created_at, rotated_at +` + +type CreateKeyShareParams struct { + DidID int64 `json:"did_id"` + ShareID string `json:"share_id"` + KeyID string `json:"key_id"` + PartyIndex int64 `json:"party_index"` + Threshold int64 `json:"threshold"` + TotalParties int64 `json:"total_parties"` + Curve string `json:"curve"` + ShareData string `json:"share_data"` + PublicKey string `json:"public_key"` + ChainCode *string `json:"chain_code"` + DerivationPath *string `json:"derivation_path"` +} + +func (q *Queries) CreateKeyShare(ctx context.Context, arg CreateKeyShareParams) (KeyShare, error) { + row := q.db.QueryRowContext(ctx, createKeyShare, + arg.DidID, + arg.ShareID, + arg.KeyID, + arg.PartyIndex, + arg.Threshold, + arg.TotalParties, + arg.Curve, + arg.ShareData, + arg.PublicKey, + arg.ChainCode, + arg.DerivationPath, + ) + var i KeyShare + err := row.Scan( + &i.ID, + &i.DidID, + &i.ShareID, + &i.KeyID, + &i.PartyIndex, + &i.Threshold, + &i.TotalParties, + &i.Curve, + &i.ShareData, + &i.PublicKey, + &i.ChainCode, + &i.DerivationPath, + &i.Status, + &i.CreatedAt, + &i.RotatedAt, + ) + return i, err +} + +const createRevocation = `-- name: CreateRevocation :exec +INSERT INTO ucan_revocations (ucan_cid, revoked_by, reason) +VALUES (?, ?, ?) +` + +type CreateRevocationParams struct { + UcanCid string `json:"ucan_cid"` + RevokedBy string `json:"revoked_by"` + Reason *string `json:"reason"` +} + +func (q *Queries) CreateRevocation(ctx context.Context, arg CreateRevocationParams) error { + _, err := q.db.ExecContext(ctx, createRevocation, arg.UcanCid, arg.RevokedBy, arg.Reason) + return err +} + +const createService = `-- name: CreateService :one +INSERT INTO services (origin, name, description, logo_url, did, is_verified, metadata) +VALUES (?, ?, ?, ?, ?, ?, ?) +RETURNING id, origin, name, description, logo_url, did, is_verified, metadata, created_at +` + +type CreateServiceParams struct { + Origin string `json:"origin"` + Name string `json:"name"` + Description *string `json:"description"` + LogoUrl *string `json:"logo_url"` + Did *string `json:"did"` + IsVerified int64 `json:"is_verified"` + Metadata json.RawMessage `json:"metadata"` +} + +func (q *Queries) CreateService(ctx context.Context, arg CreateServiceParams) (Service, error) { + row := q.db.QueryRowContext(ctx, createService, + arg.Origin, + arg.Name, + arg.Description, + arg.LogoUrl, + arg.Did, + arg.IsVerified, + arg.Metadata, + ) + var i Service + err := row.Scan( + &i.ID, + &i.Origin, + &i.Name, + &i.Description, + &i.LogoUrl, + &i.Did, + &i.IsVerified, + &i.Metadata, + &i.CreatedAt, + ) + return i, err +} + +const createSession = `-- name: CreateSession :one +INSERT INTO sessions (did_id, credential_id, session_id, device_info, is_current, expires_at) +VALUES (?, ?, ?, ?, ?, ?) +RETURNING id, did_id, credential_id, session_id, device_info, is_current, last_activity, expires_at, created_at +` + +type CreateSessionParams struct { + DidID int64 `json:"did_id"` + CredentialID int64 `json:"credential_id"` + SessionID string `json:"session_id"` + DeviceInfo json.RawMessage `json:"device_info"` + IsCurrent int64 `json:"is_current"` + ExpiresAt string `json:"expires_at"` +} + +func (q *Queries) CreateSession(ctx context.Context, arg CreateSessionParams) (Session, error) { + row := q.db.QueryRowContext(ctx, createSession, + arg.DidID, + arg.CredentialID, + arg.SessionID, + arg.DeviceInfo, + arg.IsCurrent, + arg.ExpiresAt, + ) + var i Session + err := row.Scan( + &i.ID, + &i.DidID, + &i.CredentialID, + &i.SessionID, + &i.DeviceInfo, + &i.IsCurrent, + &i.LastActivity, + &i.ExpiresAt, + &i.CreatedAt, + ) + return i, err +} + +const createUCAN = `-- name: CreateUCAN :one +INSERT INTO ucan_tokens ( + did_id, cid, issuer, audience, subject, capabilities, + proof_chain, not_before, expires_at, nonce, facts, signature, raw_token +) +VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) +RETURNING id, did_id, cid, issuer, audience, subject, capabilities, proof_chain, not_before, expires_at, nonce, facts, signature, raw_token, is_revoked, created_at +` + +type CreateUCANParams struct { + DidID int64 `json:"did_id"` + Cid string `json:"cid"` + Issuer string `json:"issuer"` + Audience string `json:"audience"` + Subject *string `json:"subject"` + Capabilities json.RawMessage `json:"capabilities"` + ProofChain json.RawMessage `json:"proof_chain"` + NotBefore *string `json:"not_before"` + ExpiresAt string `json:"expires_at"` + Nonce *string `json:"nonce"` + Facts json.RawMessage `json:"facts"` + Signature string `json:"signature"` + RawToken string `json:"raw_token"` +} + +func (q *Queries) CreateUCAN(ctx context.Context, arg CreateUCANParams) (UcanToken, error) { + row := q.db.QueryRowContext(ctx, createUCAN, + arg.DidID, + arg.Cid, + arg.Issuer, + arg.Audience, + arg.Subject, + arg.Capabilities, + arg.ProofChain, + arg.NotBefore, + arg.ExpiresAt, + arg.Nonce, + arg.Facts, + arg.Signature, + arg.RawToken, + ) + var i UcanToken + err := row.Scan( + &i.ID, + &i.DidID, + &i.Cid, + &i.Issuer, + &i.Audience, + &i.Subject, + &i.Capabilities, + &i.ProofChain, + &i.NotBefore, + &i.ExpiresAt, + &i.Nonce, + &i.Facts, + &i.Signature, + &i.RawToken, + &i.IsRevoked, + &i.CreatedAt, + ) + return i, err +} + +const createVerificationMethod = `-- name: CreateVerificationMethod :one +INSERT INTO verification_methods (did_id, method_id, method_type, controller, public_key, purpose) +VALUES (?, ?, ?, ?, ?, ?) +RETURNING id, did_id, method_id, method_type, controller, public_key, purpose, created_at +` + +type CreateVerificationMethodParams struct { + DidID int64 `json:"did_id"` + MethodID string `json:"method_id"` + MethodType string `json:"method_type"` + Controller string `json:"controller"` + PublicKey string `json:"public_key"` + Purpose string `json:"purpose"` +} + +func (q *Queries) CreateVerificationMethod(ctx context.Context, arg CreateVerificationMethodParams) (VerificationMethod, error) { + row := q.db.QueryRowContext(ctx, createVerificationMethod, + arg.DidID, + arg.MethodID, + arg.MethodType, + arg.Controller, + arg.PublicKey, + arg.Purpose, + ) + var i VerificationMethod + err := row.Scan( + &i.ID, + &i.DidID, + &i.MethodID, + &i.MethodType, + &i.Controller, + &i.PublicKey, + &i.Purpose, + &i.CreatedAt, + ) + return i, err +} + +const deleteAccount = `-- name: DeleteAccount :exec +DELETE FROM accounts WHERE id = ? AND did_id = ? +` + +type DeleteAccountParams struct { + ID int64 `json:"id"` + DidID int64 `json:"did_id"` +} + +func (q *Queries) DeleteAccount(ctx context.Context, arg DeleteAccountParams) error { + _, err := q.db.ExecContext(ctx, deleteAccount, arg.ID, arg.DidID) + return err +} + +const deleteCredential = `-- name: DeleteCredential :exec +DELETE FROM credentials WHERE id = ? AND did_id = ? +` + +type DeleteCredentialParams struct { + ID int64 `json:"id"` + DidID int64 `json:"did_id"` +} + +func (q *Queries) DeleteCredential(ctx context.Context, arg DeleteCredentialParams) error { + _, err := q.db.ExecContext(ctx, deleteCredential, arg.ID, arg.DidID) + return err +} + +const deleteExpiredSessions = `-- name: DeleteExpiredSessions :exec +DELETE FROM sessions WHERE expires_at < datetime('now') +` + +func (q *Queries) DeleteExpiredSessions(ctx context.Context) error { + _, err := q.db.ExecContext(ctx, deleteExpiredSessions) + return err +} + +const deleteKeyShare = `-- name: DeleteKeyShare :exec +DELETE FROM key_shares WHERE id = ? AND did_id = ? +` + +type DeleteKeyShareParams struct { + ID int64 `json:"id"` + DidID int64 `json:"did_id"` +} + +func (q *Queries) DeleteKeyShare(ctx context.Context, arg DeleteKeyShareParams) error { + _, err := q.db.ExecContext(ctx, deleteKeyShare, arg.ID, arg.DidID) + return err +} + +const deleteSession = `-- name: DeleteSession :exec +DELETE FROM sessions WHERE id = ? +` + +func (q *Queries) DeleteSession(ctx context.Context, id int64) error { + _, err := q.db.ExecContext(ctx, deleteSession, id) + return err +} + +const deleteVerificationMethod = `-- name: DeleteVerificationMethod :exec +DELETE FROM verification_methods WHERE id = ? +` + +func (q *Queries) DeleteVerificationMethod(ctx context.Context, id int64) error { + _, err := q.db.ExecContext(ctx, deleteVerificationMethod, id) + return err +} + +const getAccountByAddress = `-- name: GetAccountByAddress :one +SELECT id, did_id, key_share_id, address, chain_id, coin_type, account_index, address_index, label, is_default, created_at FROM accounts WHERE address = ? LIMIT 1 +` + +func (q *Queries) GetAccountByAddress(ctx context.Context, address string) (Account, error) { + row := q.db.QueryRowContext(ctx, getAccountByAddress, address) + var i Account + err := row.Scan( + &i.ID, + &i.DidID, + &i.KeyShareID, + &i.Address, + &i.ChainID, + &i.CoinType, + &i.AccountIndex, + &i.AddressIndex, + &i.Label, + &i.IsDefault, + &i.CreatedAt, + ) + return i, err +} + +const getCredentialByID = `-- name: GetCredentialByID :one +SELECT id, did_id, credential_id, public_key, public_key_alg, aaguid, sign_count, transports, device_name, device_type, authenticator, is_discoverable, backed_up, created_at, last_used FROM credentials WHERE credential_id = ? LIMIT 1 +` + +func (q *Queries) GetCredentialByID(ctx context.Context, credentialID string) (Credential, error) { + row := q.db.QueryRowContext(ctx, getCredentialByID, credentialID) + var i Credential + err := row.Scan( + &i.ID, + &i.DidID, + &i.CredentialID, + &i.PublicKey, + &i.PublicKeyAlg, + &i.Aaguid, + &i.SignCount, + &i.Transports, + &i.DeviceName, + &i.DeviceType, + &i.Authenticator, + &i.IsDiscoverable, + &i.BackedUp, + &i.CreatedAt, + &i.LastUsed, + ) + return i, err +} + +const getCurrentSession = `-- name: GetCurrentSession :one +SELECT id, did_id, credential_id, session_id, device_info, is_current, last_activity, expires_at, created_at FROM sessions WHERE did_id = ? AND is_current = 1 LIMIT 1 +` + +func (q *Queries) GetCurrentSession(ctx context.Context, didID int64) (Session, error) { + row := q.db.QueryRowContext(ctx, getCurrentSession, didID) + var i Session + err := row.Scan( + &i.ID, + &i.DidID, + &i.CredentialID, + &i.SessionID, + &i.DeviceInfo, + &i.IsCurrent, + &i.LastActivity, + &i.ExpiresAt, + &i.CreatedAt, + ) + return i, err +} + +const getDIDByDID = `-- name: GetDIDByDID :one + +SELECT id, did, controller, document, sequence, last_synced, created_at, updated_at FROM did_documents WHERE did = ? LIMIT 1 +` + +// ============================================================================= +// DID DOCUMENT QUERIES +// ============================================================================= +func (q *Queries) GetDIDByDID(ctx context.Context, did string) (DidDocument, error) { + row := q.db.QueryRowContext(ctx, getDIDByDID, did) + var i DidDocument + err := row.Scan( + &i.ID, + &i.Did, + &i.Controller, + &i.Document, + &i.Sequence, + &i.LastSynced, + &i.CreatedAt, + &i.UpdatedAt, + ) + return i, err +} + +const getDIDByID = `-- name: GetDIDByID :one +SELECT id, did, controller, document, sequence, last_synced, created_at, updated_at FROM did_documents WHERE id = ? LIMIT 1 +` + +func (q *Queries) GetDIDByID(ctx context.Context, id int64) (DidDocument, error) { + row := q.db.QueryRowContext(ctx, getDIDByID, id) + var i DidDocument + err := row.Scan( + &i.ID, + &i.Did, + &i.Controller, + &i.Document, + &i.Sequence, + &i.LastSynced, + &i.CreatedAt, + &i.UpdatedAt, + ) + return i, err +} + +const getDefaultAccount = `-- name: GetDefaultAccount :one +SELECT id, did_id, key_share_id, address, chain_id, coin_type, account_index, address_index, label, is_default, created_at FROM accounts WHERE did_id = ? AND chain_id = ? AND is_default = 1 LIMIT 1 +` + +type GetDefaultAccountParams struct { + DidID int64 `json:"did_id"` + ChainID string `json:"chain_id"` +} + +func (q *Queries) GetDefaultAccount(ctx context.Context, arg GetDefaultAccountParams) (Account, error) { + row := q.db.QueryRowContext(ctx, getDefaultAccount, arg.DidID, arg.ChainID) + var i Account + err := row.Scan( + &i.ID, + &i.DidID, + &i.KeyShareID, + &i.Address, + &i.ChainID, + &i.CoinType, + &i.AccountIndex, + &i.AddressIndex, + &i.Label, + &i.IsDefault, + &i.CreatedAt, + ) + return i, err +} + +const getDelegationChain = `-- name: GetDelegationChain :many +SELECT id, did_id, ucan_id, delegator, delegate, resource, "action", caveats, parent_id, depth, status, created_at, expires_at FROM delegations WHERE id = ? OR parent_id = ? ORDER BY depth DESC +` + +type GetDelegationChainParams struct { + ID int64 `json:"id"` + ParentID *int64 `json:"parent_id"` +} + +func (q *Queries) GetDelegationChain(ctx context.Context, arg GetDelegationChainParams) ([]Delegation, error) { + rows, err := q.db.QueryContext(ctx, getDelegationChain, arg.ID, arg.ParentID) + if err != nil { + return nil, err + } + defer rows.Close() + items := []Delegation{} + for rows.Next() { + var i Delegation + if err := rows.Scan( + &i.ID, + &i.DidID, + &i.UcanID, + &i.Delegator, + &i.Delegate, + &i.Resource, + &i.Action, + &i.Caveats, + &i.ParentID, + &i.Depth, + &i.Status, + &i.CreatedAt, + &i.ExpiresAt, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const getGrantByService = `-- name: GetGrantByService :one +SELECT id, did_id, service_id, ucan_id, scopes, accounts, status, granted_at, last_used, expires_at FROM grants WHERE did_id = ? AND service_id = ? LIMIT 1 +` + +type GetGrantByServiceParams struct { + DidID int64 `json:"did_id"` + ServiceID int64 `json:"service_id"` +} + +func (q *Queries) GetGrantByService(ctx context.Context, arg GetGrantByServiceParams) (Grant, error) { + row := q.db.QueryRowContext(ctx, getGrantByService, arg.DidID, arg.ServiceID) + var i Grant + err := row.Scan( + &i.ID, + &i.DidID, + &i.ServiceID, + &i.UcanID, + &i.Scopes, + &i.Accounts, + &i.Status, + &i.GrantedAt, + &i.LastUsed, + &i.ExpiresAt, + ) + return i, err +} + +const getKeyShareByID = `-- name: GetKeyShareByID :one +SELECT id, did_id, share_id, key_id, party_index, threshold, total_parties, curve, share_data, public_key, chain_code, derivation_path, status, created_at, rotated_at FROM key_shares WHERE share_id = ? LIMIT 1 +` + +func (q *Queries) GetKeyShareByID(ctx context.Context, shareID string) (KeyShare, error) { + row := q.db.QueryRowContext(ctx, getKeyShareByID, shareID) + var i KeyShare + err := row.Scan( + &i.ID, + &i.DidID, + &i.ShareID, + &i.KeyID, + &i.PartyIndex, + &i.Threshold, + &i.TotalParties, + &i.Curve, + &i.ShareData, + &i.PublicKey, + &i.ChainCode, + &i.DerivationPath, + &i.Status, + &i.CreatedAt, + &i.RotatedAt, + ) + return i, err +} + +const getKeyShareByKeyID = `-- name: GetKeyShareByKeyID :one +SELECT id, did_id, share_id, key_id, party_index, threshold, total_parties, curve, share_data, public_key, chain_code, derivation_path, status, created_at, rotated_at FROM key_shares WHERE did_id = ? AND key_id = ? AND status = 'active' LIMIT 1 +` + +type GetKeyShareByKeyIDParams struct { + DidID int64 `json:"did_id"` + KeyID string `json:"key_id"` +} + +func (q *Queries) GetKeyShareByKeyID(ctx context.Context, arg GetKeyShareByKeyIDParams) (KeyShare, error) { + row := q.db.QueryRowContext(ctx, getKeyShareByKeyID, arg.DidID, arg.KeyID) + var i KeyShare + err := row.Scan( + &i.ID, + &i.DidID, + &i.ShareID, + &i.KeyID, + &i.PartyIndex, + &i.Threshold, + &i.TotalParties, + &i.Curve, + &i.ShareData, + &i.PublicKey, + &i.ChainCode, + &i.DerivationPath, + &i.Status, + &i.CreatedAt, + &i.RotatedAt, + ) + return i, err +} + +const getServiceByID = `-- name: GetServiceByID :one +SELECT id, origin, name, description, logo_url, did, is_verified, metadata, created_at FROM services WHERE id = ? LIMIT 1 +` + +func (q *Queries) GetServiceByID(ctx context.Context, id int64) (Service, error) { + row := q.db.QueryRowContext(ctx, getServiceByID, id) + var i Service + err := row.Scan( + &i.ID, + &i.Origin, + &i.Name, + &i.Description, + &i.LogoUrl, + &i.Did, + &i.IsVerified, + &i.Metadata, + &i.CreatedAt, + ) + return i, err +} + +const getServiceByOrigin = `-- name: GetServiceByOrigin :one + +SELECT id, origin, name, description, logo_url, did, is_verified, metadata, created_at FROM services WHERE origin = ? LIMIT 1 +` + +// ============================================================================= +// SERVICE QUERIES +// ============================================================================= +func (q *Queries) GetServiceByOrigin(ctx context.Context, origin string) (Service, error) { + row := q.db.QueryRowContext(ctx, getServiceByOrigin, origin) + var i Service + err := row.Scan( + &i.ID, + &i.Origin, + &i.Name, + &i.Description, + &i.LogoUrl, + &i.Did, + &i.IsVerified, + &i.Metadata, + &i.CreatedAt, + ) + return i, err +} + +const getSessionByID = `-- name: GetSessionByID :one +SELECT id, did_id, credential_id, session_id, device_info, is_current, last_activity, expires_at, created_at FROM sessions WHERE session_id = ? LIMIT 1 +` + +func (q *Queries) GetSessionByID(ctx context.Context, sessionID string) (Session, error) { + row := q.db.QueryRowContext(ctx, getSessionByID, sessionID) + var i Session + err := row.Scan( + &i.ID, + &i.DidID, + &i.CredentialID, + &i.SessionID, + &i.DeviceInfo, + &i.IsCurrent, + &i.LastActivity, + &i.ExpiresAt, + &i.CreatedAt, + ) + return i, err +} + +const getSyncCheckpoint = `-- name: GetSyncCheckpoint :one + +SELECT id, did_id, resource_type, last_block, last_tx_hash, last_synced FROM sync_checkpoints WHERE did_id = ? AND resource_type = ? LIMIT 1 +` + +type GetSyncCheckpointParams struct { + DidID int64 `json:"did_id"` + ResourceType string `json:"resource_type"` +} + +// ============================================================================= +// SYNC QUERIES +// ============================================================================= +func (q *Queries) GetSyncCheckpoint(ctx context.Context, arg GetSyncCheckpointParams) (SyncCheckpoint, error) { + row := q.db.QueryRowContext(ctx, getSyncCheckpoint, arg.DidID, arg.ResourceType) + var i SyncCheckpoint + err := row.Scan( + &i.ID, + &i.DidID, + &i.ResourceType, + &i.LastBlock, + &i.LastTxHash, + &i.LastSynced, + ) + return i, err +} + +const getUCANByCID = `-- name: GetUCANByCID :one +SELECT id, did_id, cid, issuer, audience, subject, capabilities, proof_chain, not_before, expires_at, nonce, facts, signature, raw_token, is_revoked, created_at FROM ucan_tokens WHERE cid = ? LIMIT 1 +` + +func (q *Queries) GetUCANByCID(ctx context.Context, cid string) (UcanToken, error) { + row := q.db.QueryRowContext(ctx, getUCANByCID, cid) + var i UcanToken + err := row.Scan( + &i.ID, + &i.DidID, + &i.Cid, + &i.Issuer, + &i.Audience, + &i.Subject, + &i.Capabilities, + &i.ProofChain, + &i.NotBefore, + &i.ExpiresAt, + &i.Nonce, + &i.Facts, + &i.Signature, + &i.RawToken, + &i.IsRevoked, + &i.CreatedAt, + ) + return i, err +} + +const getVerificationMethod = `-- name: GetVerificationMethod :one +SELECT id, did_id, method_id, method_type, controller, public_key, purpose, created_at FROM verification_methods WHERE did_id = ? AND method_id = ? LIMIT 1 +` + +type GetVerificationMethodParams struct { + DidID int64 `json:"did_id"` + MethodID string `json:"method_id"` +} + +func (q *Queries) GetVerificationMethod(ctx context.Context, arg GetVerificationMethodParams) (VerificationMethod, error) { + row := q.db.QueryRowContext(ctx, getVerificationMethod, arg.DidID, arg.MethodID) + var i VerificationMethod + err := row.Scan( + &i.ID, + &i.DidID, + &i.MethodID, + &i.MethodType, + &i.Controller, + &i.PublicKey, + &i.Purpose, + &i.CreatedAt, + ) + return i, err +} + +const isUCANRevoked = `-- name: IsUCANRevoked :one +SELECT EXISTS(SELECT 1 FROM ucan_revocations WHERE ucan_cid = ?) as revoked +` + +func (q *Queries) IsUCANRevoked(ctx context.Context, ucanCid string) (int64, error) { + row := q.db.QueryRowContext(ctx, isUCANRevoked, ucanCid) + var revoked int64 + err := row.Scan(&revoked) + return revoked, err +} + +const listAccountsByChain = `-- name: ListAccountsByChain :many +SELECT id, did_id, key_share_id, address, chain_id, coin_type, account_index, address_index, label, is_default, created_at FROM accounts WHERE did_id = ? AND chain_id = ? ORDER BY account_index, address_index +` + +type ListAccountsByChainParams struct { + DidID int64 `json:"did_id"` + ChainID string `json:"chain_id"` +} + +func (q *Queries) ListAccountsByChain(ctx context.Context, arg ListAccountsByChainParams) ([]Account, error) { + rows, err := q.db.QueryContext(ctx, listAccountsByChain, arg.DidID, arg.ChainID) + if err != nil { + return nil, err + } + defer rows.Close() + items := []Account{} + for rows.Next() { + var i Account + if err := rows.Scan( + &i.ID, + &i.DidID, + &i.KeyShareID, + &i.Address, + &i.ChainID, + &i.CoinType, + &i.AccountIndex, + &i.AddressIndex, + &i.Label, + &i.IsDefault, + &i.CreatedAt, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const listAccountsByDID = `-- name: ListAccountsByDID :many + +SELECT a.id, a.did_id, a.key_share_id, a.address, a.chain_id, a.coin_type, a.account_index, a.address_index, a.label, a.is_default, a.created_at, k.public_key, k.curve +FROM accounts a +JOIN key_shares k ON a.key_share_id = k.id +WHERE a.did_id = ? +ORDER BY a.is_default DESC, a.created_at +` + +type ListAccountsByDIDRow struct { + ID int64 `json:"id"` + DidID int64 `json:"did_id"` + KeyShareID int64 `json:"key_share_id"` + Address string `json:"address"` + ChainID string `json:"chain_id"` + CoinType int64 `json:"coin_type"` + AccountIndex int64 `json:"account_index"` + AddressIndex int64 `json:"address_index"` + Label *string `json:"label"` + IsDefault int64 `json:"is_default"` + CreatedAt string `json:"created_at"` + PublicKey string `json:"public_key"` + Curve string `json:"curve"` +} + +// ============================================================================= +// ACCOUNT QUERIES +// ============================================================================= +func (q *Queries) ListAccountsByDID(ctx context.Context, didID int64) ([]ListAccountsByDIDRow, error) { + rows, err := q.db.QueryContext(ctx, listAccountsByDID, didID) + if err != nil { + return nil, err + } + defer rows.Close() + items := []ListAccountsByDIDRow{} + for rows.Next() { + var i ListAccountsByDIDRow + if err := rows.Scan( + &i.ID, + &i.DidID, + &i.KeyShareID, + &i.Address, + &i.ChainID, + &i.CoinType, + &i.AccountIndex, + &i.AddressIndex, + &i.Label, + &i.IsDefault, + &i.CreatedAt, + &i.PublicKey, + &i.Curve, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const listAllDIDs = `-- name: ListAllDIDs :many +SELECT id, did, controller, document, sequence, last_synced, created_at, updated_at FROM did_documents ORDER BY created_at DESC +` + +func (q *Queries) ListAllDIDs(ctx context.Context) ([]DidDocument, error) { + rows, err := q.db.QueryContext(ctx, listAllDIDs) + if err != nil { + return nil, err + } + defer rows.Close() + items := []DidDocument{} + for rows.Next() { + var i DidDocument + if err := rows.Scan( + &i.ID, + &i.Did, + &i.Controller, + &i.Document, + &i.Sequence, + &i.LastSynced, + &i.CreatedAt, + &i.UpdatedAt, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const listCredentialsByDID = `-- name: ListCredentialsByDID :many + +SELECT id, did_id, credential_id, public_key, public_key_alg, aaguid, sign_count, transports, device_name, device_type, authenticator, is_discoverable, backed_up, created_at, last_used FROM credentials WHERE did_id = ? ORDER BY last_used DESC +` + +// ============================================================================= +// CREDENTIAL QUERIES +// ============================================================================= +func (q *Queries) ListCredentialsByDID(ctx context.Context, didID int64) ([]Credential, error) { + rows, err := q.db.QueryContext(ctx, listCredentialsByDID, didID) + if err != nil { + return nil, err + } + defer rows.Close() + items := []Credential{} + for rows.Next() { + var i Credential + if err := rows.Scan( + &i.ID, + &i.DidID, + &i.CredentialID, + &i.PublicKey, + &i.PublicKeyAlg, + &i.Aaguid, + &i.SignCount, + &i.Transports, + &i.DeviceName, + &i.DeviceType, + &i.Authenticator, + &i.IsDiscoverable, + &i.BackedUp, + &i.CreatedAt, + &i.LastUsed, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const listDelegationsByDelegate = `-- name: ListDelegationsByDelegate :many +SELECT id, did_id, ucan_id, delegator, delegate, resource, "action", caveats, parent_id, depth, status, created_at, expires_at FROM delegations +WHERE delegate = ? AND status = 'active' AND (expires_at IS NULL OR expires_at > datetime('now')) +ORDER BY created_at DESC +` + +func (q *Queries) ListDelegationsByDelegate(ctx context.Context, delegate string) ([]Delegation, error) { + rows, err := q.db.QueryContext(ctx, listDelegationsByDelegate, delegate) + if err != nil { + return nil, err + } + defer rows.Close() + items := []Delegation{} + for rows.Next() { + var i Delegation + if err := rows.Scan( + &i.ID, + &i.DidID, + &i.UcanID, + &i.Delegator, + &i.Delegate, + &i.Resource, + &i.Action, + &i.Caveats, + &i.ParentID, + &i.Depth, + &i.Status, + &i.CreatedAt, + &i.ExpiresAt, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const listDelegationsByDelegator = `-- name: ListDelegationsByDelegator :many + +SELECT id, did_id, ucan_id, delegator, delegate, resource, "action", caveats, parent_id, depth, status, created_at, expires_at FROM delegations +WHERE delegator = ? AND status = 'active' +ORDER BY created_at DESC +` + +// ============================================================================= +// DELEGATION QUERIES +// ============================================================================= +func (q *Queries) ListDelegationsByDelegator(ctx context.Context, delegator string) ([]Delegation, error) { + rows, err := q.db.QueryContext(ctx, listDelegationsByDelegator, delegator) + if err != nil { + return nil, err + } + defer rows.Close() + items := []Delegation{} + for rows.Next() { + var i Delegation + if err := rows.Scan( + &i.ID, + &i.DidID, + &i.UcanID, + &i.Delegator, + &i.Delegate, + &i.Resource, + &i.Action, + &i.Caveats, + &i.ParentID, + &i.Depth, + &i.Status, + &i.CreatedAt, + &i.ExpiresAt, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const listDelegationsForResource = `-- name: ListDelegationsForResource :many +SELECT id, did_id, ucan_id, delegator, delegate, resource, "action", caveats, parent_id, depth, status, created_at, expires_at FROM delegations +WHERE did_id = ? AND resource = ? AND status = 'active' +ORDER BY depth, created_at +` + +type ListDelegationsForResourceParams struct { + DidID int64 `json:"did_id"` + Resource string `json:"resource"` +} + +func (q *Queries) ListDelegationsForResource(ctx context.Context, arg ListDelegationsForResourceParams) ([]Delegation, error) { + rows, err := q.db.QueryContext(ctx, listDelegationsForResource, arg.DidID, arg.Resource) + if err != nil { + return nil, err + } + defer rows.Close() + items := []Delegation{} + for rows.Next() { + var i Delegation + if err := rows.Scan( + &i.ID, + &i.DidID, + &i.UcanID, + &i.Delegator, + &i.Delegate, + &i.Resource, + &i.Action, + &i.Caveats, + &i.ParentID, + &i.Depth, + &i.Status, + &i.CreatedAt, + &i.ExpiresAt, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const listGrantsByDID = `-- name: ListGrantsByDID :many + +SELECT g.id, g.did_id, g.service_id, g.ucan_id, g.scopes, g.accounts, g.status, g.granted_at, g.last_used, g.expires_at, s.name as service_name, s.origin as service_origin, s.logo_url as service_logo +FROM grants g +JOIN services s ON g.service_id = s.id +WHERE g.did_id = ? AND g.status = 'active' +ORDER BY g.last_used DESC NULLS LAST +` + +type ListGrantsByDIDRow struct { + ID int64 `json:"id"` + DidID int64 `json:"did_id"` + ServiceID int64 `json:"service_id"` + UcanID *int64 `json:"ucan_id"` + Scopes json.RawMessage `json:"scopes"` + Accounts json.RawMessage `json:"accounts"` + Status string `json:"status"` + GrantedAt string `json:"granted_at"` + LastUsed *string `json:"last_used"` + ExpiresAt *string `json:"expires_at"` + ServiceName string `json:"service_name"` + ServiceOrigin string `json:"service_origin"` + ServiceLogo *string `json:"service_logo"` +} + +// ============================================================================= +// GRANT QUERIES +// ============================================================================= +func (q *Queries) ListGrantsByDID(ctx context.Context, didID int64) ([]ListGrantsByDIDRow, error) { + rows, err := q.db.QueryContext(ctx, listGrantsByDID, didID) + if err != nil { + return nil, err + } + defer rows.Close() + items := []ListGrantsByDIDRow{} + for rows.Next() { + var i ListGrantsByDIDRow + if err := rows.Scan( + &i.ID, + &i.DidID, + &i.ServiceID, + &i.UcanID, + &i.Scopes, + &i.Accounts, + &i.Status, + &i.GrantedAt, + &i.LastUsed, + &i.ExpiresAt, + &i.ServiceName, + &i.ServiceOrigin, + &i.ServiceLogo, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const listKeySharesByDID = `-- name: ListKeySharesByDID :many + +SELECT id, did_id, share_id, key_id, party_index, threshold, total_parties, curve, share_data, public_key, chain_code, derivation_path, status, created_at, rotated_at FROM key_shares WHERE did_id = ? AND status = 'active' ORDER BY created_at +` + +// ============================================================================= +// KEY SHARE QUERIES +// ============================================================================= +func (q *Queries) ListKeySharesByDID(ctx context.Context, didID int64) ([]KeyShare, error) { + rows, err := q.db.QueryContext(ctx, listKeySharesByDID, didID) + if err != nil { + return nil, err + } + defer rows.Close() + items := []KeyShare{} + for rows.Next() { + var i KeyShare + if err := rows.Scan( + &i.ID, + &i.DidID, + &i.ShareID, + &i.KeyID, + &i.PartyIndex, + &i.Threshold, + &i.TotalParties, + &i.Curve, + &i.ShareData, + &i.PublicKey, + &i.ChainCode, + &i.DerivationPath, + &i.Status, + &i.CreatedAt, + &i.RotatedAt, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const listSessionsByDID = `-- name: ListSessionsByDID :many + +SELECT s.id, s.did_id, s.credential_id, s.session_id, s.device_info, s.is_current, s.last_activity, s.expires_at, s.created_at, c.device_name, c.authenticator +FROM sessions s +JOIN credentials c ON s.credential_id = c.id +WHERE s.did_id = ? AND s.expires_at > datetime('now') +ORDER BY s.last_activity DESC +` + +type ListSessionsByDIDRow struct { + ID int64 `json:"id"` + DidID int64 `json:"did_id"` + CredentialID int64 `json:"credential_id"` + SessionID string `json:"session_id"` + DeviceInfo json.RawMessage `json:"device_info"` + IsCurrent int64 `json:"is_current"` + LastActivity string `json:"last_activity"` + ExpiresAt string `json:"expires_at"` + CreatedAt string `json:"created_at"` + DeviceName string `json:"device_name"` + Authenticator *string `json:"authenticator"` +} + +// ============================================================================= +// SESSION QUERIES +// ============================================================================= +func (q *Queries) ListSessionsByDID(ctx context.Context, didID int64) ([]ListSessionsByDIDRow, error) { + rows, err := q.db.QueryContext(ctx, listSessionsByDID, didID) + if err != nil { + return nil, err + } + defer rows.Close() + items := []ListSessionsByDIDRow{} + for rows.Next() { + var i ListSessionsByDIDRow + if err := rows.Scan( + &i.ID, + &i.DidID, + &i.CredentialID, + &i.SessionID, + &i.DeviceInfo, + &i.IsCurrent, + &i.LastActivity, + &i.ExpiresAt, + &i.CreatedAt, + &i.DeviceName, + &i.Authenticator, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const listSyncCheckpoints = `-- name: ListSyncCheckpoints :many +SELECT id, did_id, resource_type, last_block, last_tx_hash, last_synced FROM sync_checkpoints WHERE did_id = ? +` + +func (q *Queries) ListSyncCheckpoints(ctx context.Context, didID int64) ([]SyncCheckpoint, error) { + rows, err := q.db.QueryContext(ctx, listSyncCheckpoints, didID) + if err != nil { + return nil, err + } + defer rows.Close() + items := []SyncCheckpoint{} + for rows.Next() { + var i SyncCheckpoint + if err := rows.Scan( + &i.ID, + &i.DidID, + &i.ResourceType, + &i.LastBlock, + &i.LastTxHash, + &i.LastSynced, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const listUCANsByAudience = `-- name: ListUCANsByAudience :many +SELECT id, did_id, cid, issuer, audience, subject, capabilities, proof_chain, not_before, expires_at, nonce, facts, signature, raw_token, is_revoked, created_at FROM ucan_tokens +WHERE audience = ? AND is_revoked = 0 AND expires_at > datetime('now') +ORDER BY created_at DESC +` + +func (q *Queries) ListUCANsByAudience(ctx context.Context, audience string) ([]UcanToken, error) { + rows, err := q.db.QueryContext(ctx, listUCANsByAudience, audience) + if err != nil { + return nil, err + } + defer rows.Close() + items := []UcanToken{} + for rows.Next() { + var i UcanToken + if err := rows.Scan( + &i.ID, + &i.DidID, + &i.Cid, + &i.Issuer, + &i.Audience, + &i.Subject, + &i.Capabilities, + &i.ProofChain, + &i.NotBefore, + &i.ExpiresAt, + &i.Nonce, + &i.Facts, + &i.Signature, + &i.RawToken, + &i.IsRevoked, + &i.CreatedAt, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const listUCANsByDID = `-- name: ListUCANsByDID :many + +SELECT id, did_id, cid, issuer, audience, subject, capabilities, proof_chain, not_before, expires_at, nonce, facts, signature, raw_token, is_revoked, created_at FROM ucan_tokens +WHERE did_id = ? AND is_revoked = 0 AND expires_at > datetime('now') +ORDER BY created_at DESC +` + +// ============================================================================= +// UCAN TOKEN QUERIES +// ============================================================================= +func (q *Queries) ListUCANsByDID(ctx context.Context, didID int64) ([]UcanToken, error) { + rows, err := q.db.QueryContext(ctx, listUCANsByDID, didID) + if err != nil { + return nil, err + } + defer rows.Close() + items := []UcanToken{} + for rows.Next() { + var i UcanToken + if err := rows.Scan( + &i.ID, + &i.DidID, + &i.Cid, + &i.Issuer, + &i.Audience, + &i.Subject, + &i.Capabilities, + &i.ProofChain, + &i.NotBefore, + &i.ExpiresAt, + &i.Nonce, + &i.Facts, + &i.Signature, + &i.RawToken, + &i.IsRevoked, + &i.CreatedAt, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const listVerificationMethods = `-- name: ListVerificationMethods :many + +SELECT id, did_id, method_id, method_type, controller, public_key, purpose, created_at FROM verification_methods WHERE did_id = ? ORDER BY created_at +` + +// ============================================================================= +// VERIFICATION METHOD QUERIES +// ============================================================================= +func (q *Queries) ListVerificationMethods(ctx context.Context, didID int64) ([]VerificationMethod, error) { + rows, err := q.db.QueryContext(ctx, listVerificationMethods, didID) + if err != nil { + return nil, err + } + defer rows.Close() + items := []VerificationMethod{} + for rows.Next() { + var i VerificationMethod + if err := rows.Scan( + &i.ID, + &i.DidID, + &i.MethodID, + &i.MethodType, + &i.Controller, + &i.PublicKey, + &i.Purpose, + &i.CreatedAt, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const listVerifiedServices = `-- name: ListVerifiedServices :many +SELECT id, origin, name, description, logo_url, did, is_verified, metadata, created_at FROM services WHERE is_verified = 1 ORDER BY name +` + +func (q *Queries) ListVerifiedServices(ctx context.Context) ([]Service, error) { + rows, err := q.db.QueryContext(ctx, listVerifiedServices) + if err != nil { + return nil, err + } + defer rows.Close() + items := []Service{} + for rows.Next() { + var i Service + if err := rows.Scan( + &i.ID, + &i.Origin, + &i.Name, + &i.Description, + &i.LogoUrl, + &i.Did, + &i.IsVerified, + &i.Metadata, + &i.CreatedAt, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const reactivateGrant = `-- name: ReactivateGrant :exec +UPDATE grants SET status = 'active' WHERE id = ? AND status = 'suspended' +` + +func (q *Queries) ReactivateGrant(ctx context.Context, id int64) error { + _, err := q.db.ExecContext(ctx, reactivateGrant, id) + return err +} + +const renameCredential = `-- name: RenameCredential :exec +UPDATE credentials SET device_name = ? WHERE id = ? +` + +type RenameCredentialParams struct { + DeviceName string `json:"device_name"` + ID int64 `json:"id"` +} + +func (q *Queries) RenameCredential(ctx context.Context, arg RenameCredentialParams) error { + _, err := q.db.ExecContext(ctx, renameCredential, arg.DeviceName, arg.ID) + return err +} + +const revokeDelegation = `-- name: RevokeDelegation :exec +UPDATE delegations SET status = 'revoked' WHERE id = ? +` + +func (q *Queries) RevokeDelegation(ctx context.Context, id int64) error { + _, err := q.db.ExecContext(ctx, revokeDelegation, id) + return err +} + +const revokeDelegationChain = `-- name: RevokeDelegationChain :exec +UPDATE delegations SET status = 'revoked' WHERE id = ? OR parent_id = ? +` + +type RevokeDelegationChainParams struct { + ID int64 `json:"id"` + ParentID *int64 `json:"parent_id"` +} + +func (q *Queries) RevokeDelegationChain(ctx context.Context, arg RevokeDelegationChainParams) error { + _, err := q.db.ExecContext(ctx, revokeDelegationChain, arg.ID, arg.ParentID) + return err +} + +const revokeGrant = `-- name: RevokeGrant :exec +UPDATE grants SET status = 'revoked' WHERE id = ? +` + +func (q *Queries) RevokeGrant(ctx context.Context, id int64) error { + _, err := q.db.ExecContext(ctx, revokeGrant, id) + return err +} + +const revokeUCAN = `-- name: RevokeUCAN :exec +UPDATE ucan_tokens SET is_revoked = 1 WHERE cid = ? +` + +func (q *Queries) RevokeUCAN(ctx context.Context, cid string) error { + _, err := q.db.ExecContext(ctx, revokeUCAN, cid) + return err +} + +const rotateKeyShare = `-- name: RotateKeyShare :exec +UPDATE key_shares +SET status = 'rotating', rotated_at = datetime('now') +WHERE id = ? +` + +func (q *Queries) RotateKeyShare(ctx context.Context, id int64) error { + _, err := q.db.ExecContext(ctx, rotateKeyShare, id) + return err +} + +const setCurrentSession = `-- name: SetCurrentSession :exec +UPDATE sessions +SET is_current = CASE WHEN id = ? THEN 1 ELSE 0 END +WHERE did_id = ? +` + +type SetCurrentSessionParams struct { + ID int64 `json:"id"` + DidID int64 `json:"did_id"` +} + +func (q *Queries) SetCurrentSession(ctx context.Context, arg SetCurrentSessionParams) error { + _, err := q.db.ExecContext(ctx, setCurrentSession, arg.ID, arg.DidID) + return err +} + +const setDefaultAccount = `-- name: SetDefaultAccount :exec +UPDATE accounts +SET is_default = CASE WHEN id = ? THEN 1 ELSE 0 END +WHERE did_id = ? AND chain_id = ? +` + +type SetDefaultAccountParams struct { + ID int64 `json:"id"` + DidID int64 `json:"did_id"` + ChainID string `json:"chain_id"` +} + +func (q *Queries) SetDefaultAccount(ctx context.Context, arg SetDefaultAccountParams) error { + _, err := q.db.ExecContext(ctx, setDefaultAccount, arg.ID, arg.DidID, arg.ChainID) + return err +} + +const suspendGrant = `-- name: SuspendGrant :exec +UPDATE grants SET status = 'suspended' WHERE id = ? +` + +func (q *Queries) SuspendGrant(ctx context.Context, id int64) error { + _, err := q.db.ExecContext(ctx, suspendGrant, id) + return err +} + +const updateAccountLabel = `-- name: UpdateAccountLabel :exec +UPDATE accounts SET label = ? WHERE id = ? +` + +type UpdateAccountLabelParams struct { + Label *string `json:"label"` + ID int64 `json:"id"` +} + +func (q *Queries) UpdateAccountLabel(ctx context.Context, arg UpdateAccountLabelParams) error { + _, err := q.db.ExecContext(ctx, updateAccountLabel, arg.Label, arg.ID) + return err +} + +const updateCredentialCounter = `-- name: UpdateCredentialCounter :exec +UPDATE credentials +SET sign_count = ?, last_used = datetime('now') +WHERE id = ? +` + +type UpdateCredentialCounterParams struct { + SignCount int64 `json:"sign_count"` + ID int64 `json:"id"` +} + +func (q *Queries) UpdateCredentialCounter(ctx context.Context, arg UpdateCredentialCounterParams) error { + _, err := q.db.ExecContext(ctx, updateCredentialCounter, arg.SignCount, arg.ID) + return err +} + +const updateDIDDocument = `-- name: UpdateDIDDocument :exec +UPDATE did_documents +SET document = ?, sequence = ?, last_synced = datetime('now') +WHERE id = ? +` + +type UpdateDIDDocumentParams struct { + Document json.RawMessage `json:"document"` + Sequence int64 `json:"sequence"` + ID int64 `json:"id"` +} + +func (q *Queries) UpdateDIDDocument(ctx context.Context, arg UpdateDIDDocumentParams) error { + _, err := q.db.ExecContext(ctx, updateDIDDocument, arg.Document, arg.Sequence, arg.ID) + return err +} + +const updateGrantLastUsed = `-- name: UpdateGrantLastUsed :exec +UPDATE grants SET last_used = datetime('now') WHERE id = ? +` + +func (q *Queries) UpdateGrantLastUsed(ctx context.Context, id int64) error { + _, err := q.db.ExecContext(ctx, updateGrantLastUsed, id) + return err +} + +const updateGrantScopes = `-- name: UpdateGrantScopes :exec +UPDATE grants SET scopes = ?, accounts = ? WHERE id = ? +` + +type UpdateGrantScopesParams struct { + Scopes json.RawMessage `json:"scopes"` + Accounts json.RawMessage `json:"accounts"` + ID int64 `json:"id"` +} + +func (q *Queries) UpdateGrantScopes(ctx context.Context, arg UpdateGrantScopesParams) error { + _, err := q.db.ExecContext(ctx, updateGrantScopes, arg.Scopes, arg.Accounts, arg.ID) + return err +} + +const updateService = `-- name: UpdateService :exec +UPDATE services +SET name = ?, description = ?, logo_url = ?, metadata = ? +WHERE id = ? +` + +type UpdateServiceParams struct { + Name string `json:"name"` + Description *string `json:"description"` + LogoUrl *string `json:"logo_url"` + Metadata json.RawMessage `json:"metadata"` + ID int64 `json:"id"` +} + +func (q *Queries) UpdateService(ctx context.Context, arg UpdateServiceParams) error { + _, err := q.db.ExecContext(ctx, updateService, + arg.Name, + arg.Description, + arg.LogoUrl, + arg.Metadata, + arg.ID, + ) + return err +} + +const updateSessionActivity = `-- name: UpdateSessionActivity :exec +UPDATE sessions SET last_activity = datetime('now') WHERE id = ? +` + +func (q *Queries) UpdateSessionActivity(ctx context.Context, id int64) error { + _, err := q.db.ExecContext(ctx, updateSessionActivity, id) + return err +} + +const upsertSyncCheckpoint = `-- name: UpsertSyncCheckpoint :exec +INSERT INTO sync_checkpoints (did_id, resource_type, last_block, last_tx_hash) +VALUES (?, ?, ?, ?) +ON CONFLICT(did_id, resource_type) DO UPDATE SET + last_block = excluded.last_block, + last_tx_hash = excluded.last_tx_hash, + last_synced = datetime('now') +` + +type UpsertSyncCheckpointParams struct { + DidID int64 `json:"did_id"` + ResourceType string `json:"resource_type"` + LastBlock int64 `json:"last_block"` + LastTxHash *string `json:"last_tx_hash"` +} + +func (q *Queries) UpsertSyncCheckpoint(ctx context.Context, arg UpsertSyncCheckpointParams) error { + _, err := q.db.ExecContext(ctx, upsertSyncCheckpoint, + arg.DidID, + arg.ResourceType, + arg.LastBlock, + arg.LastTxHash, + ) + return err +}