diff --git a/README.md b/README.md index 9d20954..b9417f9 100644 --- a/README.md +++ b/README.md @@ -34,13 +34,23 @@ const result = await client.assess("0x1234...", { }); console.log(result.decision, result.decision_reasons); -// Browse agents -const agents = await client.getAgents({ chain: "base", limit: 10 }); -console.log(agents.items.length, agents.count); +// Compliance assessment with verification policy +const gated = await client.assess("0x1234...", { + policy: { + require_kyc: true, + require_sanctions_clear: true, + min_age: 21, + }, +}); + +if (gated.decision === "deny") { + console.log(gated.decision_reasons); // ["kyc_required"] + console.log(gated.verify_url); // URL for operator verification +} -// Ecosystem stats -const stats = await client.getStats(); -console.log(stats.erc8004?.known_agents); +// Check verification level on reputation +const verified = await client.getReputation("0x1234..."); +console.log(verified.verification_level); // "none" | "wallet_claimed" | "kyc_verified" ``` ## Configuration diff --git a/bun.lock b/bun.lock index 0efa447..accf45a 100644 --- a/bun.lock +++ b/bun.lock @@ -7,6 +7,7 @@ "devDependencies": { "@eslint/js": "^9.39.4", "@vitest/coverage-v8": "^4.1.2", + "dotenv": "^17.4.1", "eslint": "^9.39.4", "eslint-plugin-import": "^2.32.0", "eslint-plugin-unused-imports": "^4.4.1", @@ -346,6 +347,8 @@ "doctrine": ["doctrine@2.1.0", "", { "dependencies": { "esutils": "^2.0.2" } }, "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw=="], + "dotenv": ["dotenv@17.4.1", "", {}, "sha512-k8DaKGP6r1G30Lx8V4+pCsLzKr8vLmV2paqEj1Y55GdAgJuIqpRp5FfajGF8KtwMxCz9qJc6wUIJnm053d/WCw=="], + "dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="], "es-abstract": ["es-abstract@1.24.1", "", { "dependencies": { "array-buffer-byte-length": "^1.0.2", "arraybuffer.prototype.slice": "^1.0.4", "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", "call-bound": "^1.0.4", "data-view-buffer": "^1.0.2", "data-view-byte-length": "^1.0.2", "data-view-byte-offset": "^1.0.1", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "es-set-tostringtag": "^2.1.0", "es-to-primitive": "^1.3.0", "function.prototype.name": "^1.1.8", "get-intrinsic": "^1.3.0", "get-proto": "^1.0.1", "get-symbol-description": "^1.1.0", "globalthis": "^1.0.4", "gopd": "^1.2.0", "has-property-descriptors": "^1.0.2", "has-proto": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "internal-slot": "^1.1.0", "is-array-buffer": "^3.0.5", "is-callable": "^1.2.7", "is-data-view": "^1.0.2", "is-negative-zero": "^2.0.3", "is-regex": "^1.2.1", "is-set": "^2.0.3", "is-shared-array-buffer": "^1.0.4", "is-string": "^1.1.1", "is-typed-array": "^1.1.15", "is-weakref": "^1.1.1", "math-intrinsics": "^1.1.0", "object-inspect": "^1.13.4", "object-keys": "^1.1.1", "object.assign": "^4.1.7", "own-keys": "^1.0.1", "regexp.prototype.flags": "^1.5.4", "safe-array-concat": "^1.1.3", "safe-push-apply": "^1.0.0", "safe-regex-test": "^1.1.0", "set-proto": "^1.0.0", "stop-iteration-iterator": "^1.1.0", "string.prototype.trim": "^1.2.10", "string.prototype.trimend": "^1.0.9", "string.prototype.trimstart": "^1.0.8", "typed-array-buffer": "^1.0.3", "typed-array-byte-length": "^1.0.3", "typed-array-byte-offset": "^1.0.4", "typed-array-length": "^1.0.7", "unbox-primitive": "^1.1.0", "which-typed-array": "^1.1.19" } }, "sha512-zHXBLhP+QehSSbsS9Pt23Gg964240DPd6QCf8WpkqEXxQ7fhdZzYsocOr5u7apWonsS5EjZDmTF+/slGMyasvw=="], diff --git a/package.json b/package.json index 78e15a1..ddd499f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@agent-score/sdk", - "version": "1.3.0", + "version": "1.4.0", "description": "TypeScript client for the AgentScore trust and reputation API", "main": "./dist/index.cjs", "module": "./dist/index.js", @@ -52,6 +52,7 @@ "devDependencies": { "@eslint/js": "^9.39.4", "@vitest/coverage-v8": "^4.1.2", + "dotenv": "^17.4.1", "eslint": "^9.39.4", "eslint-plugin-import": "^2.32.0", "eslint-plugin-unused-imports": "^4.4.1", diff --git a/src/index.ts b/src/index.ts index f9eac83..2187d6b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,13 +2,10 @@ import { AgentScoreError } from './errors'; import type { AgentScoreConfig, AgentScoreErrorBody, - AgentsListResponse, AssessOptions, AssessResponse, - GetAgentsOptions, GetReputationOptions, ReputationResponse, - StatsResponse, } from './types'; export { AgentScoreError } from './errors'; @@ -57,27 +54,12 @@ export class AgentScore { }); } - async getAgents(options?: GetAgentsOptions): Promise { - const params = new URLSearchParams(); - if (options) { - for (const [key, value] of Object.entries(options)) { - if (value !== undefined) params.set(key, String(value)); - } - } - const qs = params.toString(); - return this.request(`/v1/agents${qs ? `?${qs}` : ''}`); - } - - async getStats(): Promise { - return this.request('/v1/stats'); - } - private async request(path: string, options?: RequestInit): Promise { const url = `${this.baseUrl}${path}`; const headers: Record = { ...(options?.headers as Record), - Authorization: `Bearer ${this.apiKey}`, + 'X-API-Key': this.apiKey, 'User-Agent': `agentscore-sdk/${__VERSION__}`, }; diff --git a/src/types.ts b/src/types.ts index be7138c..6e00c7c 100644 --- a/src/types.ts +++ b/src/types.ts @@ -6,7 +6,7 @@ export interface AgentScoreConfig { export type Grade = 'A' | 'B' | 'C' | 'D' | 'F'; export type EntityType = 'agent' | 'service' | 'hybrid' | 'wallet' | 'bot' | 'unknown'; -export type ReputationStatus = 'unknown' | 'known_unscored' | 'scored' | 'stale' | 'indexing'; +export type ReputationStatus = 'scored' | 'stale' | 'known_unscored'; export interface Subject { chains: string[]; @@ -34,8 +34,8 @@ export interface Score { export interface ChainScore { value: number | null; grade: Grade | null; - confidence: number | null; - dimensions: Record | null; + confidence?: number | null; + dimensions?: Record | null; scored_at: string | null; status: ReputationStatus; version: string; @@ -64,30 +64,14 @@ export interface Activity { } export interface EvidenceSummary { - candidate_tx_count?: number; - confirmed_or_likely_tx?: number; - endpoint_count?: number; - github_stars?: number | null; - github_url?: string | null; - has_a2a_agent_card?: boolean; - has_ens?: boolean; - has_github?: boolean; - has_website?: boolean; - healthy_endpoints?: number; - is_erc8004?: boolean; - metadata_kind?: string | null; - metadata_quality?: string | null; - multi_chain_count?: number; - reputation_feedback_count?: number; - reputation_trust_avg?: number | null; - reputation_uptime_avg?: number | null; - reputation_activity_avg?: number | null; - reputation_client_count?: number; - verified_tx_count?: number; - website_mentions_mcp?: boolean; - website_mentions_x402?: boolean; - website_reachable?: boolean; - website_url?: string | null; + metadata_kind: string | null; + has_a2a_agent_card: boolean; + website_url: string | null; + website_reachable: boolean; + website_mentions_mcp: boolean; + website_mentions_x402: boolean; + github_url: string | null; + github_stars: number | null; } export interface Reputation { @@ -102,8 +86,8 @@ export interface Reputation { export interface OperatorScore { score: number; grade: Grade; - agent_count: number; - chains_active: string[]; + agent_count?: number; + chains_active?: string[]; } export interface AgentSummary { @@ -114,13 +98,17 @@ export interface AgentSummary { grade: Grade; } +export interface RedactedClassification { + entity_type: EntityType; +} + export interface ChainEntry { chain: string; score: ChainScore; - classification: Classification; - identity: Identity; - activity: Activity; - evidence_summary: EvidenceSummary; + classification: Classification | RedactedClassification; + identity?: Identity; + activity?: Activity; + evidence_summary?: EvidenceSummary; } export interface ReputationResponse { @@ -133,12 +121,27 @@ export interface ReputationResponse { reputation?: Reputation; operator_score?: OperatorScore; agents?: AgentSummary[]; + verification_level?: VerificationLevel; +} + +export type VerificationLevel = 'none' | 'wallet_claimed' | 'kyc_verified'; + +export interface OperatorVerification { + level: VerificationLevel; + operator_type?: string | null; + claimed_at?: string | null; + verified_at?: string | null; } export interface DecisionPolicy { min_grade?: Grade; min_score?: number; require_verified_payment_activity?: boolean; + require_kyc?: boolean; + require_sanctions_clear?: boolean; + min_age?: number; + blocked_jurisdictions?: string[]; + require_entity_type?: string; } export interface AssessRequest { @@ -161,60 +164,9 @@ export interface AssessResponse { operator_score?: OperatorScore; reputation?: Reputation; agents?: AgentSummary[]; -} - -export interface AgentRecord { - chain: string; - token_id: number; - owner_address: string; - agent_wallet: string | null; - name: string | null; - description: string | null; - metadata_quality: string; - score: number | null; - grade: Grade | null; - entity_type: EntityType | null; - endpoint_count: number; - website_url: string | null; - github_url: string | null; - has_candidate_payment_activity: boolean; - has_verified_payment_activity: boolean; - agents_sharing_owner?: number; - updated_at: string; -} - -export interface AgentsListResponse { - items: AgentRecord[]; - next_cursor: string | null; - count: number; - version: string; -} - -export interface StatsPayments { - addresses_with_candidate_payment_activity: number; - addresses_with_verified_payment_activity: number; - total_candidate_transactions: number; - total_verified_transactions: number; - verification_status_summary: Record; -} - -export interface StatsResponse { - version: string; - as_of_time: string; - data_semantics: string; - erc8004?: { - known_agents: number; - by_chain: Record; - metadata_quality_distribution: Record; - }; - reputation?: { - total_addresses: number; - scored_addresses: number; - entity_distribution: Record; - score_distribution: Record; - }; - payments: StatsPayments; - caveats: string[]; + operator_verification?: OperatorVerification; + resolved_operator?: string; + verify_url?: string; } export interface AgentScoreErrorBody { @@ -225,20 +177,6 @@ export interface AgentScoreErrorBody { }; } -export interface GetAgentsOptions { - chain?: string; - limit?: number; - offset?: number; - cursor?: string; - metadata_quality?: string; - grade?: Grade; - min_score?: number; - has_endpoint?: boolean; - entity_type?: EntityType; - has_candidate_payment_activity?: boolean; - has_verified_payment_activity?: boolean; -} - export interface GetReputationOptions { chain?: string; } diff --git a/tests/index.test.ts b/tests/index.test.ts index 4da8fdd..09a0b78 100644 --- a/tests/index.test.ts +++ b/tests/index.test.ts @@ -27,7 +27,7 @@ function mockFetchError(status: number, errorBody?: { error: { code: string; mes const REPUTATION_RESPONSE = { subject: { chains: ['base'], address: WALLET }, score: { value: 85, grade: 'A', status: 'scored' }, - chains: [{ chain: 'base', score: { value: 85, grade: 'A' }, classification: { entity_type: 'agent' }, identity: {}, activity: {}, evidence_summary: {} }], + chains: [{ chain: 'base', score: { value: 85, grade: 'A' }, classification: { entity_type: 'agent' }, identity: {}, activity: {}, evidence_summary: { metadata_kind: null, has_a2a_agent_card: false, website_url: null, website_reachable: false, website_mentions_mcp: false, website_mentions_x402: false, github_url: null, github_stars: null } }], data_semantics: 'v1', caveats: [], updated_at: '2024-01-01T00:00:00Z', @@ -36,7 +36,7 @@ const REPUTATION_RESPONSE = { const ASSESS_RESPONSE = { subject: { chains: ['base'], address: WALLET }, score: { value: 85, grade: 'A', status: 'scored' }, - chains: [{ chain: 'base', score: { value: 85, grade: 'A' }, classification: { entity_type: 'agent' }, identity: {}, activity: {}, evidence_summary: {} }], + chains: [{ chain: 'base', score: { value: 85, grade: 'A' }, classification: { entity_type: 'agent' }, identity: {}, activity: {}, evidence_summary: { metadata_kind: null, has_a2a_agent_card: false, website_url: null, website_reachable: false, website_mentions_mcp: false, website_mentions_x402: false, github_url: null, github_stars: null } }], decision: 'allow', decision_reasons: [], on_the_fly: false, @@ -46,27 +46,6 @@ const ASSESS_RESPONSE = { agents: [], }; -const AGENTS_RESPONSE = { - items: [], - next_cursor: null, - count: 0, - version: '1', -}; - -const STATS_RESPONSE = { - version: '1', - as_of_time: '2024-01-01T00:00:00Z', - data_semantics: 'v1', - payments: { - addresses_with_candidate_payment_activity: 100, - addresses_with_verified_payment_activity: 50, - total_candidate_transactions: 1000, - total_verified_transactions: 500, - verification_status_summary: {}, - }, - caveats: [], -}; - // --------------------------------------------------------------------------- // Constructor // --------------------------------------------------------------------------- @@ -136,7 +115,7 @@ describe('AgentScore.getReputation()', () => { expect(global.fetch).toHaveBeenCalledWith( `https://api.agentscore.sh/v1/reputation/${WALLET}`, expect.objectContaining({ - headers: expect.objectContaining({ Authorization: `Bearer ${API_KEY}` }), + headers: expect.objectContaining({ 'X-API-Key': API_KEY }), }), ); }); @@ -266,94 +245,6 @@ describe('AgentScore.assess()', () => { }); }); -// --------------------------------------------------------------------------- -// getAgents -// --------------------------------------------------------------------------- - -describe('AgentScore.getAgents()', () => { - afterEach(() => { - vi.restoreAllMocks(); - }); - - it('returns agents list on success', async () => { - mockFetchOk(AGENTS_RESPONSE); - const client = new AgentScore({ apiKey: API_KEY }); - const result = await client.getAgents(); - expect(result).toMatchObject(AGENTS_RESPONSE); - }); - - it('sends GET to /v1/agents', async () => { - mockFetchOk(AGENTS_RESPONSE); - const client = new AgentScore({ apiKey: API_KEY }); - await client.getAgents(); - expect(global.fetch).toHaveBeenCalledWith( - 'https://api.agentscore.sh/v1/agents', - expect.anything(), - ); - }); - - it('appends options as query params', async () => { - mockFetchOk(AGENTS_RESPONSE); - const client = new AgentScore({ apiKey: API_KEY }); - await client.getAgents({ chain: 'base', limit: 10 }); - expect(global.fetch).toHaveBeenCalledWith( - expect.stringContaining('chain=base'), - expect.anything(), - ); - expect(global.fetch).toHaveBeenCalledWith( - expect.stringContaining('limit=10'), - expect.anything(), - ); - }); - - it('converts boolean filter has_endpoint: true to query param "true"', async () => { - mockFetchOk(AGENTS_RESPONSE); - const client = new AgentScore({ apiKey: API_KEY }); - await client.getAgents({ has_endpoint: true }); - expect(global.fetch).toHaveBeenCalledWith( - expect.stringContaining('has_endpoint=true'), - expect.anything(), - ); - }); - - it('converts boolean filter has_endpoint: false to query param "false"', async () => { - mockFetchOk(AGENTS_RESPONSE); - const client = new AgentScore({ apiKey: API_KEY }); - await client.getAgents({ has_endpoint: false }); - expect(global.fetch).toHaveBeenCalledWith( - expect.stringContaining('has_endpoint=false'), - expect.anything(), - ); - }); -}); - -// --------------------------------------------------------------------------- -// getStats -// --------------------------------------------------------------------------- - -describe('AgentScore.getStats()', () => { - afterEach(() => { - vi.restoreAllMocks(); - }); - - it('returns stats data on success', async () => { - mockFetchOk(STATS_RESPONSE); - const client = new AgentScore({ apiKey: API_KEY }); - const result = await client.getStats(); - expect(result).toMatchObject(STATS_RESPONSE); - }); - - it('sends GET to /v1/stats', async () => { - mockFetchOk(STATS_RESPONSE); - const client = new AgentScore({ apiKey: API_KEY }); - await client.getStats(); - expect(global.fetch).toHaveBeenCalledWith( - 'https://api.agentscore.sh/v1/stats', - expect.anything(), - ); - }); -}); - // --------------------------------------------------------------------------- // Timeout & Network Errors // --------------------------------------------------------------------------- @@ -441,16 +332,6 @@ describe('Edge cases', () => { } }); - it('getAgents omits undefined option values from query params', async () => { - mockFetchOk(AGENTS_RESPONSE); - const client = new AgentScore({ apiKey: API_KEY }); - await client.getAgents({ chain: 'base', limit: undefined }); - const call = (global.fetch as ReturnType).mock.calls[0]; - const url = call[0] as string; - expect(url).toContain('chain=base'); - expect(url).not.toContain('limit'); - }); - it('assess sends chain, refresh, and policy all at once', async () => { mockFetchOk(ASSESS_RESPONSE); const client = new AgentScore({ apiKey: API_KEY }); @@ -491,15 +372,6 @@ describe('Edge cases', () => { expect(global.fetch).toHaveBeenCalledTimes(2); }); - it('getAgents passes through empty items array', async () => { - const emptyResponse = { items: [], next_cursor: null, count: 0, version: '1' }; - mockFetchOk(emptyResponse); - const client = new AgentScore({ apiKey: API_KEY }); - const result = await client.getAgents({ chain: 'base' }); - expect(result.items).toEqual([]); - expect(result.count).toBe(0); - }); - it('assess includes refresh: false in request body', async () => { mockFetchOk(ASSESS_RESPONSE); const client = new AgentScore({ apiKey: API_KEY }); @@ -519,3 +391,164 @@ describe('Edge cases', () => { expect(url).toBe(`https://api.agentscore.sh/v1/reputation/${WALLET}?chain=ethereum`); }); }); + +// --------------------------------------------------------------------------- +// Verification / Compliance types and fields +// --------------------------------------------------------------------------- + +describe('Verification and compliance fields', () => { + afterEach(() => vi.restoreAllMocks()); + + it('getReputation returns verification_level when present', async () => { + const response = { + ...REPUTATION_RESPONSE, + verification_level: 'kyc_verified' as const, + }; + mockFetchOk(response); + const client = new AgentScore({ apiKey: API_KEY }); + const result = await client.getReputation(WALLET); + expect(result.verification_level).toBe('kyc_verified'); + }); + + it('getReputation omits verification_level when not present', async () => { + mockFetchOk(REPUTATION_RESPONSE); + const client = new AgentScore({ apiKey: API_KEY }); + const result = await client.getReputation(WALLET); + expect(result.verification_level).toBeUndefined(); + }); + + it('assess response includes operator_verification when present', async () => { + const response = { + ...ASSESS_RESPONSE, + operator_verification: { + level: 'kyc_verified', + operator_type: 'business', + claimed_at: '2024-06-01T00:00:00Z', + verified_at: '2024-06-15T00:00:00Z', + }, + }; + mockFetchOk(response); + const client = new AgentScore({ apiKey: API_KEY }); + const result = await client.assess(WALLET); + expect(result.operator_verification).toBeDefined(); + expect(result.operator_verification!.level).toBe('kyc_verified'); + expect(result.operator_verification!.operator_type).toBe('business'); + expect(result.operator_verification!.claimed_at).toBe('2024-06-01T00:00:00Z'); + expect(result.operator_verification!.verified_at).toBe('2024-06-15T00:00:00Z'); + }); + + it('assess response includes verify_url when present', async () => { + const response = { + ...ASSESS_RESPONSE, + decision: 'deny', + decision_reasons: ['kyc_required'], + verify_url: 'https://agentscore.sh/verify/abc123', + }; + mockFetchOk(response); + const client = new AgentScore({ apiKey: API_KEY }); + const result = await client.assess(WALLET); + expect(result.verify_url).toBe('https://agentscore.sh/verify/abc123'); + expect(result.decision).toBe('deny'); + }); + + it('assess response omits operator_verification and verify_url when not present', async () => { + mockFetchOk(ASSESS_RESPONSE); + const client = new AgentScore({ apiKey: API_KEY }); + const result = await client.assess(WALLET); + expect(result.operator_verification).toBeUndefined(); + expect(result.verify_url).toBeUndefined(); + }); + + it('assess sends new compliance policy fields', async () => { + mockFetchOk(ASSESS_RESPONSE); + const client = new AgentScore({ apiKey: API_KEY }); + await client.assess(WALLET, { + policy: { + require_kyc: true, + require_sanctions_clear: true, + min_age: 90, + blocked_jurisdictions: ['KP', 'IR'], + require_entity_type: 'agent', + }, + }); + const call = (global.fetch as ReturnType).mock.calls[0]; + const body = JSON.parse(call[1].body as string) as Record; + const policy = body.policy as Record; + expect(policy.require_kyc).toBe(true); + expect(policy.require_sanctions_clear).toBe(true); + expect(policy.min_age).toBe(90); + expect(policy.blocked_jurisdictions).toEqual(['KP', 'IR']); + expect(policy.require_entity_type).toBe('agent'); + }); + + it('assess sends resolved_operator when present in response', async () => { + const response = { + ...ASSESS_RESPONSE, + resolved_operator: '0xoperator456', + }; + mockFetchOk(response); + const client = new AgentScore({ apiKey: API_KEY }); + const result = await client.assess(WALLET); + expect(result.resolved_operator).toBe('0xoperator456'); + }); +}); + +// --------------------------------------------------------------------------- +// Integration-style: compliance deny with verify_url +// --------------------------------------------------------------------------- + +describe('Integration: compliance policy deny with verify_url', () => { + afterEach(() => vi.restoreAllMocks()); + + it('full assess flow returns deny with verify_url for compliance policy', async () => { + const complianceDenyResponse = { + subject: { chains: ['base'], address: WALLET }, + score: { value: 72, grade: 'C', status: 'scored' }, + chains: [{ + chain: 'base', + score: { value: 72, grade: 'C' }, + classification: { entity_type: 'wallet' }, + identity: {}, + activity: {}, + evidence_summary: { metadata_kind: null, has_a2a_agent_card: false, website_url: null, website_reachable: false, website_mentions_mcp: false, website_mentions_x402: false, github_url: null, github_stars: null }, + }], + decision: 'deny', + decision_reasons: ['kyc_required', 'sanctions_check_pending'], + on_the_fly: false, + data_semantics: 'v1', + caveats: [], + updated_at: '2024-01-01T00:00:00Z', + agents: [], + operator_verification: { + level: 'none', + operator_type: null, + claimed_at: null, + verified_at: null, + }, + verify_url: 'https://agentscore.sh/verify/xyz789', + }; + + mockFetchOk(complianceDenyResponse); + + const client = new AgentScore({ apiKey: API_KEY }); + const result = await client.assess(WALLET, { + policy: { + require_kyc: true, + require_sanctions_clear: true, + }, + }); + + expect(result.decision).toBe('deny'); + expect(result.decision_reasons).toContain('kyc_required'); + expect(result.decision_reasons).toContain('sanctions_check_pending'); + expect(result.verify_url).toBe('https://agentscore.sh/verify/xyz789'); + expect(result.operator_verification).toBeDefined(); + expect(result.operator_verification!.level).toBe('none'); + + const call = (global.fetch as ReturnType).mock.calls[0]; + const body = JSON.parse(call[1].body as string) as Record; + const policy = body.policy as Record; + expect(policy.require_kyc).toBe(true); + expect(policy.require_sanctions_clear).toBe(true); + }); +}); diff --git a/tests/integration.test.ts b/tests/integration.test.ts index 0149450..39e1b3b 100644 --- a/tests/integration.test.ts +++ b/tests/integration.test.ts @@ -128,17 +128,4 @@ describeIf('integration: real API', { timeout: 15_000 }, () => { expect(rep.subject.address.toLowerCase()).toBe(TEST_ADDRESS.toLowerCase()); }); - it('getAgents returns items matching browse results', async () => { - const result = await client.getAgents(); - - expect(result.items).toBeInstanceOf(Array); - expect(result.items.length).toBeGreaterThan(0); - - for (const item of result.items) { - expect(item.owner_address).toBeDefined(); - expect(item.chain).toBeDefined(); - expect(typeof item.token_id).toBe('number'); - expect('name' in item).toBe(true); - } - }); }); diff --git a/vitest.config.ts b/vitest.config.ts index 88e2719..b30df1b 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -7,6 +7,7 @@ export default defineConfig({ define: { __VERSION__: JSON.stringify(version) }, test: { environment: 'node', + setupFiles: ['dotenv/config'], coverage: { provider: 'v8', reporter: ['text', 'json-summary'],