@fuul/mcp-server 1.10.0 → 1.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/currencies/currency-handlers.d.ts +6 -0
- package/dist/currencies/currency-handlers.d.ts.map +1 -0
- package/dist/currencies/currency-handlers.js +59 -0
- package/dist/currencies/currency-handlers.js.map +1 -0
- package/dist/currencies/fetch-price-references.d.ts +11 -0
- package/dist/currencies/fetch-price-references.d.ts.map +1 -0
- package/dist/currencies/fetch-price-references.js +40 -0
- package/dist/currencies/fetch-price-references.js.map +1 -0
- package/dist/currencies/resolve-token-holder-price-reference.d.ts +26 -0
- package/dist/currencies/resolve-token-holder-price-reference.d.ts.map +1 -0
- package/dist/currencies/resolve-token-holder-price-reference.js +113 -0
- package/dist/currencies/resolve-token-holder-price-reference.js.map +1 -0
- package/dist/incentives/incentive-write-handlers.d.ts +2 -2
- package/dist/incentives/incentive-write-handlers.d.ts.map +1 -1
- package/dist/incentives/incentive-write-handlers.js +18 -12
- package/dist/incentives/incentive-write-handlers.js.map +1 -1
- package/dist/index.js +54 -11
- package/dist/index.js.map +1 -1
- package/dist/metadata-scope/resolve-draft-ids.d.ts +21 -0
- package/dist/metadata-scope/resolve-draft-ids.d.ts.map +1 -0
- package/dist/metadata-scope/resolve-draft-ids.js +91 -0
- package/dist/metadata-scope/resolve-draft-ids.js.map +1 -0
- package/dist/tools/tool-descriptions.d.ts +3 -0
- package/dist/tools/tool-descriptions.d.ts.map +1 -1
- package/dist/tools/tool-descriptions.js +32 -5
- package/dist/tools/tool-descriptions.js.map +1 -1
- package/dist/tools/tool-schemas.d.ts +291 -232
- package/dist/tools/tool-schemas.d.ts.map +1 -1
- package/dist/tools/tool-schemas.js +27 -0
- package/dist/tools/tool-schemas.js.map +1 -1
- package/dist/triggers/price-reference-guide.d.ts +38 -0
- package/dist/triggers/price-reference-guide.d.ts.map +1 -0
- package/dist/triggers/price-reference-guide.js +55 -0
- package/dist/triggers/price-reference-guide.js.map +1 -0
- package/dist/triggers/trigger-create-payload-guide.d.ts +26 -1
- package/dist/triggers/trigger-create-payload-guide.d.ts.map +1 -1
- package/dist/triggers/trigger-create-payload-guide.js +40 -7
- package/dist/triggers/trigger-create-payload-guide.js.map +1 -1
- package/dist/triggers/trigger-write-handlers.d.ts +1 -1
- package/dist/triggers/trigger-write-handlers.d.ts.map +1 -1
- package/dist/triggers/trigger-write-handlers.js +30 -6
- package/dist/triggers/trigger-write-handlers.js.map +1 -1
- package/dist/triggers/validate-token-holder-price-reference.d.ts +8 -0
- package/dist/triggers/validate-token-holder-price-reference.d.ts.map +1 -0
- package/dist/triggers/validate-token-holder-price-reference.js +49 -0
- package/dist/triggers/validate-token-holder-price-reference.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { FuulApiClient } from '../http/fuul-api-client.js';
|
|
2
|
+
import type { ListPriceReferencesInput, ResolveTokenHolderPriceReferenceInput } from '../tools/tool-schemas.js';
|
|
3
|
+
export declare function runListPriceReferences(api: FuulApiClient, input: ListPriceReferencesInput): Promise<unknown>;
|
|
4
|
+
export declare function runResolveTokenHolderPriceReference(api: FuulApiClient, input: ResolveTokenHolderPriceReferenceInput): Promise<unknown>;
|
|
5
|
+
export declare function enrichPriceReferencesResponse(raw: unknown): unknown;
|
|
6
|
+
//# sourceMappingURL=currency-handlers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"currency-handlers.d.ts","sourceRoot":"","sources":["../../src/currencies/currency-handlers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,KAAK,EAAE,wBAAwB,EAAE,qCAAqC,EAAE,MAAM,0BAA0B,CAAC;AAOhH,wBAAsB,sBAAsB,CAAC,GAAG,EAAE,aAAa,EAAE,KAAK,EAAE,wBAAwB,GAAG,OAAO,CAAC,OAAO,CAAC,CAalH;AAED,wBAAsB,mCAAmC,CAAC,GAAG,EAAE,aAAa,EAAE,KAAK,EAAE,qCAAqC,GAAG,OAAO,CAAC,OAAO,CAAC,CAuB5I;AAeD,wBAAgB,6BAA6B,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAYnE"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { TOKEN_HOLDER_PRICE_REFERENCE_GUIDE } from '../triggers/price-reference-guide.js';
|
|
2
|
+
import { fetchPriceReferences } from './fetch-price-references.js';
|
|
3
|
+
import { chainIdentifierFromChainId, resolveTokenHolderPriceReference } from './resolve-token-holder-price-reference.js';
|
|
4
|
+
const CURRENCIES_PATH = '/api/v1/currencies';
|
|
5
|
+
export async function runListPriceReferences(api, input) {
|
|
6
|
+
const query = {
|
|
7
|
+
price_reference: true,
|
|
8
|
+
page: 1,
|
|
9
|
+
page_size: 100,
|
|
10
|
+
};
|
|
11
|
+
if (input.chain_identifier != null && input.chain_identifier !== '') {
|
|
12
|
+
query.chain_identifier = input.chain_identifier;
|
|
13
|
+
}
|
|
14
|
+
const data = await api.getJson(CURRENCIES_PATH, { query });
|
|
15
|
+
return enrichPriceReferencesResponse(data);
|
|
16
|
+
}
|
|
17
|
+
export async function runResolveTokenHolderPriceReference(api, input) {
|
|
18
|
+
const chainIdentifier = resolveChainIdentifier(input);
|
|
19
|
+
const priceReferences = await fetchPriceReferences(api, chainIdentifier);
|
|
20
|
+
const result = resolveTokenHolderPriceReference({
|
|
21
|
+
token_address: input.token_address,
|
|
22
|
+
chain_identifier: chainIdentifier,
|
|
23
|
+
token_kind: input.token_kind,
|
|
24
|
+
decimals: input.decimals,
|
|
25
|
+
}, priceReferences);
|
|
26
|
+
return {
|
|
27
|
+
...result,
|
|
28
|
+
next_step: result.status === 'needs_user_input'
|
|
29
|
+
? 'Ask the user the questions_for_user, then call resolve_token_holder_price_reference again with token_kind and decimals before create_trigger.'
|
|
30
|
+
: result.status === 'resolved' || result.status === 'listed_use_same_address'
|
|
31
|
+
? `Set trigger.context.volume_currency_expression to ${result.volume_currency_expression}, then create_trigger (dry_run then confirmed).`
|
|
32
|
+
: 'Review matching_references_by_decimals or contact Fuul support.',
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
function resolveChainIdentifier(input) {
|
|
36
|
+
if (input.chain_identifier != null && input.chain_identifier !== '') {
|
|
37
|
+
return input.chain_identifier;
|
|
38
|
+
}
|
|
39
|
+
if (input.chain_id != null) {
|
|
40
|
+
const mapped = chainIdentifierFromChainId(input.chain_id);
|
|
41
|
+
if (mapped) {
|
|
42
|
+
return mapped;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
throw new Error('Provide chain_identifier (e.g. "ethereum") or a supported chain_id (e.g. 1).');
|
|
46
|
+
}
|
|
47
|
+
export function enrichPriceReferencesResponse(raw) {
|
|
48
|
+
if (!raw || typeof raw !== 'object') {
|
|
49
|
+
return {
|
|
50
|
+
results: [],
|
|
51
|
+
token_holder_price_reference_guide: TOKEN_HOLDER_PRICE_REFERENCE_GUIDE,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
return {
|
|
55
|
+
...raw,
|
|
56
|
+
token_holder_price_reference_guide: TOKEN_HOLDER_PRICE_REFERENCE_GUIDE,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=currency-handlers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"currency-handlers.js","sourceRoot":"","sources":["../../src/currencies/currency-handlers.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kCAAkC,EAAE,MAAM,sCAAsC,CAAC;AAC1F,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,0BAA0B,EAAE,gCAAgC,EAAE,MAAM,2CAA2C,CAAC;AAEzH,MAAM,eAAe,GAAG,oBAAoB,CAAC;AAE7C,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,GAAkB,EAAE,KAA+B;IAC9F,MAAM,KAAK,GAA4B;QACrC,eAAe,EAAE,IAAI;QACrB,IAAI,EAAE,CAAC;QACP,SAAS,EAAE,GAAG;KACf,CAAC;IAEF,IAAI,KAAK,CAAC,gBAAgB,IAAI,IAAI,IAAI,KAAK,CAAC,gBAAgB,KAAK,EAAE,EAAE,CAAC;QACpE,KAAK,CAAC,gBAAgB,GAAG,KAAK,CAAC,gBAAgB,CAAC;IAClD,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;IAC3D,OAAO,6BAA6B,CAAC,IAAI,CAAC,CAAC;AAC7C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mCAAmC,CAAC,GAAkB,EAAE,KAA4C;IACxH,MAAM,eAAe,GAAG,sBAAsB,CAAC,KAAK,CAAC,CAAC;IACtD,MAAM,eAAe,GAAG,MAAM,oBAAoB,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;IAEzE,MAAM,MAAM,GAAG,gCAAgC,CAC7C;QACE,aAAa,EAAE,KAAK,CAAC,aAAa;QAClC,gBAAgB,EAAE,eAAe;QACjC,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,QAAQ,EAAE,KAAK,CAAC,QAAQ;KACzB,EACD,eAAe,CAChB,CAAC;IAEF,OAAO;QACL,GAAG,MAAM;QACT,SAAS,EACP,MAAM,CAAC,MAAM,KAAK,kBAAkB;YAClC,CAAC,CAAC,+IAA+I;YACjJ,CAAC,CAAC,MAAM,CAAC,MAAM,KAAK,UAAU,IAAI,MAAM,CAAC,MAAM,KAAK,yBAAyB;gBAC3E,CAAC,CAAC,qDAAqD,MAAM,CAAC,0BAA0B,iDAAiD;gBACzI,CAAC,CAAC,iEAAiE;KAC1E,CAAC;AACJ,CAAC;AAED,SAAS,sBAAsB,CAAC,KAA4C;IAC1E,IAAI,KAAK,CAAC,gBAAgB,IAAI,IAAI,IAAI,KAAK,CAAC,gBAAgB,KAAK,EAAE,EAAE,CAAC;QACpE,OAAO,KAAK,CAAC,gBAAgB,CAAC;IAChC,CAAC;IACD,IAAI,KAAK,CAAC,QAAQ,IAAI,IAAI,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAG,0BAA0B,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAC1D,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,MAAM,CAAC;QAChB,CAAC;IACH,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,8EAA8E,CAAC,CAAC;AAClG,CAAC;AAED,MAAM,UAAU,6BAA6B,CAAC,GAAY;IACxD,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QACpC,OAAO;YACL,OAAO,EAAE,EAAE;YACX,kCAAkC,EAAE,kCAAkC;SACvE,CAAC;IACJ,CAAC;IAED,OAAO;QACL,GAAI,GAA+B;QACnC,kCAAkC,EAAE,kCAAkC;KACvE,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { FuulApiClient } from '../http/fuul-api-client.js';
|
|
2
|
+
export type PriceReferenceRow = {
|
|
3
|
+
id: string;
|
|
4
|
+
name: string;
|
|
5
|
+
identifier: string;
|
|
6
|
+
chain_identifier: string;
|
|
7
|
+
decimals: number;
|
|
8
|
+
};
|
|
9
|
+
export declare function fetchPriceReferences(api: FuulApiClient, chainIdentifier: string): Promise<PriceReferenceRow[]>;
|
|
10
|
+
export declare function parsePriceReferenceResults(raw: unknown): PriceReferenceRow[];
|
|
11
|
+
//# sourceMappingURL=fetch-price-references.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch-price-references.d.ts","sourceRoot":"","sources":["../../src/currencies/fetch-price-references.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAIhE,MAAM,MAAM,iBAAiB,GAAG;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,wBAAsB,oBAAoB,CAAC,GAAG,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAWpH;AAED,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,OAAO,GAAG,iBAAiB,EAAE,CA6B5E"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
const CURRENCIES_PATH = '/api/v1/currencies';
|
|
2
|
+
export async function fetchPriceReferences(api, chainIdentifier) {
|
|
3
|
+
const data = await api.getJson(CURRENCIES_PATH, {
|
|
4
|
+
query: {
|
|
5
|
+
price_reference: true,
|
|
6
|
+
chain_identifier: chainIdentifier,
|
|
7
|
+
page: 1,
|
|
8
|
+
page_size: 100,
|
|
9
|
+
},
|
|
10
|
+
});
|
|
11
|
+
return parsePriceReferenceResults(data);
|
|
12
|
+
}
|
|
13
|
+
export function parsePriceReferenceResults(raw) {
|
|
14
|
+
if (!raw || typeof raw !== 'object') {
|
|
15
|
+
return [];
|
|
16
|
+
}
|
|
17
|
+
const results = raw.results;
|
|
18
|
+
if (!Array.isArray(results)) {
|
|
19
|
+
return [];
|
|
20
|
+
}
|
|
21
|
+
const rows = [];
|
|
22
|
+
for (const row of results) {
|
|
23
|
+
if (!row || typeof row !== 'object') {
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
const r = row;
|
|
27
|
+
if (typeof r.identifier !== 'string' || typeof r.name !== 'string' || typeof r.decimals !== 'number') {
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
rows.push({
|
|
31
|
+
id: typeof r.id === 'string' ? r.id : '',
|
|
32
|
+
name: r.name,
|
|
33
|
+
identifier: r.identifier,
|
|
34
|
+
chain_identifier: typeof r.chain_identifier === 'string' ? r.chain_identifier : '',
|
|
35
|
+
decimals: r.decimals,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
return rows;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=fetch-price-references.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch-price-references.js","sourceRoot":"","sources":["../../src/currencies/fetch-price-references.ts"],"names":[],"mappings":"AAEA,MAAM,eAAe,GAAG,oBAAoB,CAAC;AAU7C,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,GAAkB,EAAE,eAAuB;IACpF,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,eAAe,EAAE;QAC9C,KAAK,EAAE;YACL,eAAe,EAAE,IAAI;YACrB,gBAAgB,EAAE,eAAe;YACjC,IAAI,EAAE,CAAC;YACP,SAAS,EAAE,GAAG;SACf;KACF,CAAC,CAAC;IAEH,OAAO,0BAA0B,CAAC,IAAI,CAAC,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,GAAY;IACrD,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QACpC,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,OAAO,GAAI,GAA6B,CAAC,OAAO,CAAC;IACvD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,IAAI,GAAwB,EAAE,CAAC;IACrC,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;QAC1B,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;YACpC,SAAS;QACX,CAAC;QACD,MAAM,CAAC,GAAG,GAA8B,CAAC;QACzC,IAAI,OAAO,CAAC,CAAC,UAAU,KAAK,QAAQ,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,IAAI,OAAO,CAAC,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YACrG,SAAS;QACX,CAAC;QACD,IAAI,CAAC,IAAI,CAAC;YACR,EAAE,EAAE,OAAO,CAAC,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE;YACxC,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,UAAU,EAAE,CAAC,CAAC,UAAU;YACxB,gBAAgB,EAAE,OAAO,CAAC,CAAC,gBAAgB,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE;YAClF,QAAQ,EAAE,CAAC,CAAC,QAAQ;SACrB,CAAC,CAAC;IACL,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { PriceReferenceRow } from './fetch-price-references.js';
|
|
2
|
+
export type TokenKind = 'stablecoin' | 'variable';
|
|
3
|
+
export type TokenDecimals = 6 | 18;
|
|
4
|
+
export type ResolveTokenHolderPriceReferenceInput = {
|
|
5
|
+
token_address: string;
|
|
6
|
+
chain_identifier: string;
|
|
7
|
+
token_kind?: TokenKind;
|
|
8
|
+
decimals?: TokenDecimals;
|
|
9
|
+
};
|
|
10
|
+
export type ResolveTokenHolderPriceReferenceResult = {
|
|
11
|
+
token_address: string;
|
|
12
|
+
chain_identifier: string;
|
|
13
|
+
token_is_listed_as_price_reference: boolean;
|
|
14
|
+
status: 'listed_use_same_address' | 'resolved' | 'needs_user_input' | 'no_matching_reference';
|
|
15
|
+
volume_currency_expression: string | null;
|
|
16
|
+
assigned_reference: Pick<PriceReferenceRow, 'identifier' | 'name' | 'decimals'> | null;
|
|
17
|
+
reason: string;
|
|
18
|
+
questions_for_user?: string[];
|
|
19
|
+
matching_references_by_decimals?: Array<Pick<PriceReferenceRow, 'identifier' | 'name' | 'decimals'>>;
|
|
20
|
+
};
|
|
21
|
+
export declare function resolveTokenHolderPriceReference(input: ResolveTokenHolderPriceReferenceInput, priceReferences: PriceReferenceRow[]): ResolveTokenHolderPriceReferenceResult;
|
|
22
|
+
export declare function pickPriceReference(rows: PriceReferenceRow[], tokenKind: TokenKind, decimals: TokenDecimals): PriceReferenceRow | null;
|
|
23
|
+
/** chain_id (EVM) → currencies API chain_identifier */
|
|
24
|
+
export declare const CHAIN_ID_TO_IDENTIFIER: Record<number, string>;
|
|
25
|
+
export declare function chainIdentifierFromChainId(chainId: number): string | null;
|
|
26
|
+
//# sourceMappingURL=resolve-token-holder-price-reference.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-token-holder-price-reference.d.ts","sourceRoot":"","sources":["../../src/currencies/resolve-token-holder-price-reference.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAErE,MAAM,MAAM,SAAS,GAAG,YAAY,GAAG,UAAU,CAAC;AAClD,MAAM,MAAM,aAAa,GAAG,CAAC,GAAG,EAAE,CAAC;AAEnC,MAAM,MAAM,qCAAqC,GAAG;IAClD,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB,QAAQ,CAAC,EAAE,aAAa,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,sCAAsC,GAAG;IACnD,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,kCAAkC,EAAE,OAAO,CAAC;IAC5C,MAAM,EAAE,yBAAyB,GAAG,UAAU,GAAG,kBAAkB,GAAG,uBAAuB,CAAC;IAC9F,0BAA0B,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1C,kBAAkB,EAAE,IAAI,CAAC,iBAAiB,EAAE,YAAY,GAAG,MAAM,GAAG,UAAU,CAAC,GAAG,IAAI,CAAC;IACvF,MAAM,EAAE,MAAM,CAAC;IACf,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B,+BAA+B,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,iBAAiB,EAAE,YAAY,GAAG,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC;CACtG,CAAC;AAMF,wBAAgB,gCAAgC,CAC9C,KAAK,EAAE,qCAAqC,EAC5C,eAAe,EAAE,iBAAiB,EAAE,GACnC,sCAAsC,CAiExC;AAWD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,iBAAiB,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,aAAa,GAAG,iBAAiB,GAAG,IAAI,CAuBrI;AAgBD,uDAAuD;AACvD,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAMzD,CAAC;AAEF,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAEzE"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { isTokenListedAsPriceReference, normalizeEvmAddress } from '../triggers/price-reference-guide.js';
|
|
2
|
+
const STABLECOIN_18_PREFERRED_NAMES = ['DAI'];
|
|
3
|
+
const STABLECOIN_6_PREFERRED_NAMES = ['USDC'];
|
|
4
|
+
const VARIABLE_18_PREFERRED_NAMES = ['WETH', 'ETH', 'WSTETH'];
|
|
5
|
+
export function resolveTokenHolderPriceReference(input, priceReferences) {
|
|
6
|
+
const tokenAddress = input.token_address.trim();
|
|
7
|
+
const chainIdentifier = input.chain_identifier.trim();
|
|
8
|
+
const base = {
|
|
9
|
+
token_address: tokenAddress,
|
|
10
|
+
chain_identifier: chainIdentifier,
|
|
11
|
+
token_is_listed_as_price_reference: isTokenListedAsPriceReference(tokenAddress, priceReferences),
|
|
12
|
+
};
|
|
13
|
+
if (base.token_is_listed_as_price_reference) {
|
|
14
|
+
return {
|
|
15
|
+
...base,
|
|
16
|
+
status: 'listed_use_same_address',
|
|
17
|
+
volume_currency_expression: tokenAddress,
|
|
18
|
+
assigned_reference: findListedRow(tokenAddress, priceReferences),
|
|
19
|
+
reason: 'Token is already a price reference in Fuul. Set context.volume_currency_expression to the same address as token_address, then create_trigger.',
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
if (input.token_kind == null || input.decimals == null) {
|
|
23
|
+
return {
|
|
24
|
+
...base,
|
|
25
|
+
status: 'needs_user_input',
|
|
26
|
+
volume_currency_expression: null,
|
|
27
|
+
assigned_reference: null,
|
|
28
|
+
reason: 'Token is not a listed price reference. Ask the user before create_trigger, then call this tool again with token_kind and decimals.',
|
|
29
|
+
questions_for_user: [
|
|
30
|
+
'Is this a stablecoin or a variable-price token? (stablecoin | variable)',
|
|
31
|
+
'How many decimals does the token have? (6 or 18 — verify on Etherscan/Arbiscan/etc.)',
|
|
32
|
+
],
|
|
33
|
+
matching_references_by_decimals: undefined,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
const assigned = pickPriceReference(priceReferences, input.token_kind, input.decimals);
|
|
37
|
+
if (!assigned) {
|
|
38
|
+
const withDecimals = priceReferences.filter((r) => r.decimals === input.decimals);
|
|
39
|
+
return {
|
|
40
|
+
...base,
|
|
41
|
+
status: 'no_matching_reference',
|
|
42
|
+
volume_currency_expression: null,
|
|
43
|
+
assigned_reference: null,
|
|
44
|
+
reason: `No price reference with ${input.decimals} decimals on ${chainIdentifier}. Contact Fuul support or pick manually from list_price_references.`,
|
|
45
|
+
matching_references_by_decimals: withDecimals.map((r) => ({
|
|
46
|
+
identifier: r.identifier,
|
|
47
|
+
name: r.name,
|
|
48
|
+
decimals: r.decimals,
|
|
49
|
+
})),
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
return {
|
|
53
|
+
...base,
|
|
54
|
+
status: 'resolved',
|
|
55
|
+
volume_currency_expression: assigned.identifier,
|
|
56
|
+
assigned_reference: {
|
|
57
|
+
identifier: assigned.identifier,
|
|
58
|
+
name: assigned.name,
|
|
59
|
+
decimals: assigned.decimals,
|
|
60
|
+
},
|
|
61
|
+
reason: buildResolvedReason(input.token_kind, input.decimals, assigned),
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
function findListedRow(tokenAddress, rows) {
|
|
65
|
+
const normalized = normalizeEvmAddress(tokenAddress);
|
|
66
|
+
const row = rows.find((r) => normalizeEvmAddress(r.identifier) === normalized);
|
|
67
|
+
if (!row) {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
return { identifier: row.identifier, name: row.name, decimals: row.decimals };
|
|
71
|
+
}
|
|
72
|
+
export function pickPriceReference(rows, tokenKind, decimals) {
|
|
73
|
+
const matchingDecimals = rows.filter((r) => r.decimals === decimals);
|
|
74
|
+
if (matchingDecimals.length === 0) {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
const preferredNames = tokenKind === 'stablecoin'
|
|
78
|
+
? decimals === 18
|
|
79
|
+
? STABLECOIN_18_PREFERRED_NAMES
|
|
80
|
+
: STABLECOIN_6_PREFERRED_NAMES
|
|
81
|
+
: decimals === 18
|
|
82
|
+
? VARIABLE_18_PREFERRED_NAMES
|
|
83
|
+
: STABLECOIN_6_PREFERRED_NAMES;
|
|
84
|
+
for (const name of preferredNames) {
|
|
85
|
+
const hit = matchingDecimals.find((r) => nameMatches(r.name, name));
|
|
86
|
+
if (hit) {
|
|
87
|
+
return hit;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return matchingDecimals[0] ?? null;
|
|
91
|
+
}
|
|
92
|
+
function nameMatches(currencyName, preferred) {
|
|
93
|
+
const n = currencyName.trim().toUpperCase();
|
|
94
|
+
const p = preferred.toUpperCase();
|
|
95
|
+
return n === p || n.startsWith(`${p} `) || n.startsWith(p);
|
|
96
|
+
}
|
|
97
|
+
function buildResolvedReason(tokenKind, decimals, assigned) {
|
|
98
|
+
return (`Assigned ${assigned.name} (${assigned.identifier}) as volume_currency_expression: ` +
|
|
99
|
+
`${tokenKind} with ${decimals} decimals → use a listed reference with matching decimals ` +
|
|
100
|
+
`(e.g. 18-decimal stablecoin on Ethereum → DAI). Put this address in context.volume_currency_expression, not the held token address.`);
|
|
101
|
+
}
|
|
102
|
+
/** chain_id (EVM) → currencies API chain_identifier */
|
|
103
|
+
export const CHAIN_ID_TO_IDENTIFIER = {
|
|
104
|
+
1: 'ethereum',
|
|
105
|
+
10: 'optimistic-ethereum',
|
|
106
|
+
137: 'polygon',
|
|
107
|
+
42161: 'arbitrum',
|
|
108
|
+
8453: 'base',
|
|
109
|
+
};
|
|
110
|
+
export function chainIdentifierFromChainId(chainId) {
|
|
111
|
+
return CHAIN_ID_TO_IDENTIFIER[chainId] ?? null;
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=resolve-token-holder-price-reference.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-token-holder-price-reference.js","sourceRoot":"","sources":["../../src/currencies/resolve-token-holder-price-reference.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { FuulApiClient } from '../http/fuul-api-client.js';
|
|
2
2
|
import type { CreateIncentiveInput, DeleteIncentiveInput } from '../tools/tool-schemas.js';
|
|
3
|
-
export declare function runCreateIncentive(api: FuulApiClient, input: CreateIncentiveInput): Promise<unknown>;
|
|
4
|
-
export declare function runDeleteIncentive(api: FuulApiClient, input: DeleteIncentiveInput): Promise<unknown>;
|
|
3
|
+
export declare function runCreateIncentive(api: FuulApiClient, input: CreateIncentiveInput, toolTimeoutMs: number): Promise<unknown>;
|
|
4
|
+
export declare function runDeleteIncentive(api: FuulApiClient, input: DeleteIncentiveInput, toolTimeoutMs: number): Promise<unknown>;
|
|
5
5
|
//# sourceMappingURL=incentive-write-handlers.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"incentive-write-handlers.d.ts","sourceRoot":"","sources":["../../src/incentives/incentive-write-handlers.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"incentive-write-handlers.d.ts","sourceRoot":"","sources":["../../src/incentives/incentive-write-handlers.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAOhE,OAAO,KAAK,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAU3F,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,aAAa,EAClB,KAAK,EAAE,oBAAoB,EAC3B,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,OAAO,CAAC,CAyBlB;AAED,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,aAAa,EAClB,KAAK,EAAE,oBAAoB,EAC3B,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,OAAO,CAAC,CAsBlB"}
|
|
@@ -1,34 +1,40 @@
|
|
|
1
1
|
import { assertWriteConfirmedOrDryRun } from '../agent/write-confirmation.js';
|
|
2
|
+
import { attachDraftIdResolution, resolveDraftConversionIdForWrite, resolveDraftTriggerIdsForWrite, } from '../metadata-scope/resolve-draft-ids.js';
|
|
2
3
|
import { normalizePayoutTermBodyForPatch } from '../payouts/normalize-payout-term-body.js';
|
|
3
|
-
function buildCreateIncentiveBody(input) {
|
|
4
|
+
function buildCreateIncentiveBody(input, triggerIds) {
|
|
4
5
|
return {
|
|
5
6
|
name: input.name,
|
|
6
|
-
trigger_ids:
|
|
7
|
+
trigger_ids: triggerIds,
|
|
7
8
|
payout_terms: input.payout_terms.map((term) => normalizePayoutTermBodyForPatch(term)),
|
|
8
9
|
};
|
|
9
10
|
}
|
|
10
|
-
export async function runCreateIncentive(api, input) {
|
|
11
|
+
export async function runCreateIncentive(api, input, toolTimeoutMs) {
|
|
11
12
|
assertWriteConfirmedOrDryRun(input);
|
|
13
|
+
const triggerResolutions = await resolveDraftTriggerIdsForWrite(api, input.project_id, input.trigger_ids, toolTimeoutMs);
|
|
14
|
+
const resolvedTriggerIds = triggerResolutions.map((row) => row.resolved_draft_trigger_id);
|
|
12
15
|
const path = `/api/v1/projects/${input.project_id}/incentives`;
|
|
13
|
-
const body = buildCreateIncentiveBody(input);
|
|
16
|
+
const body = buildCreateIncentiveBody(input, resolvedTriggerIds);
|
|
14
17
|
if (input.dry_run === true) {
|
|
15
|
-
return {
|
|
18
|
+
return attachDraftIdResolution({
|
|
16
19
|
dry_run: true,
|
|
17
20
|
would_post: path,
|
|
18
21
|
body,
|
|
19
|
-
};
|
|
22
|
+
}, { triggers: triggerResolutions });
|
|
20
23
|
}
|
|
21
|
-
|
|
24
|
+
const result = await api.postJson(path, body);
|
|
25
|
+
return attachDraftIdResolution(result, { triggers: triggerResolutions });
|
|
22
26
|
}
|
|
23
|
-
export async function runDeleteIncentive(api, input) {
|
|
27
|
+
export async function runDeleteIncentive(api, input, toolTimeoutMs) {
|
|
24
28
|
assertWriteConfirmedOrDryRun(input);
|
|
25
|
-
const
|
|
29
|
+
const resolution = await resolveDraftConversionIdForWrite(api, input.project_id, input.conversion_id, toolTimeoutMs);
|
|
30
|
+
const path = `/api/v1/projects/${input.project_id}/incentives/${resolution.resolved_draft_conversion_id}`;
|
|
26
31
|
if (input.dry_run === true) {
|
|
27
|
-
return {
|
|
32
|
+
return attachDraftIdResolution({
|
|
28
33
|
dry_run: true,
|
|
29
34
|
would_delete: path,
|
|
30
|
-
};
|
|
35
|
+
}, resolution);
|
|
31
36
|
}
|
|
32
|
-
|
|
37
|
+
const result = await api.deleteJson(path);
|
|
38
|
+
return attachDraftIdResolution(result ?? { ok: true }, resolution);
|
|
33
39
|
}
|
|
34
40
|
//# sourceMappingURL=incentive-write-handlers.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"incentive-write-handlers.js","sourceRoot":"","sources":["../../src/incentives/incentive-write-handlers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;AAE9E,OAAO,EAAE,+BAA+B,EAAE,MAAM,0CAA0C,CAAC;AAG3F,SAAS,wBAAwB,CAAC,KAA2B;
|
|
1
|
+
{"version":3,"file":"incentive-write-handlers.js","sourceRoot":"","sources":["../../src/incentives/incentive-write-handlers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;AAE9E,OAAO,EACL,uBAAuB,EACvB,gCAAgC,EAChC,8BAA8B,GAC/B,MAAM,wCAAwC,CAAC;AAChD,OAAO,EAAE,+BAA+B,EAAE,MAAM,0CAA0C,CAAC;AAG3F,SAAS,wBAAwB,CAAC,KAA2B,EAAE,UAAoB;IACjF,OAAO;QACL,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,WAAW,EAAE,UAAU;QACvB,YAAY,EAAE,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,+BAA+B,CAAC,IAA+B,CAAC,CAAC;KACjH,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,GAAkB,EAClB,KAA2B,EAC3B,aAAqB;IAErB,4BAA4B,CAAC,KAAK,CAAC,CAAC;IACpC,MAAM,kBAAkB,GAAG,MAAM,8BAA8B,CAC7D,GAAG,EACH,KAAK,CAAC,UAAU,EAChB,KAAK,CAAC,WAAW,EACjB,aAAa,CACd,CAAC;IACF,MAAM,kBAAkB,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;IAC1F,MAAM,IAAI,GAAG,oBAAoB,KAAK,CAAC,UAAU,aAAa,CAAC;IAC/D,MAAM,IAAI,GAAG,wBAAwB,CAAC,KAAK,EAAE,kBAAkB,CAAC,CAAC;IAEjE,IAAI,KAAK,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;QAC3B,OAAO,uBAAuB,CAC5B;YACE,OAAO,EAAE,IAAI;YACb,UAAU,EAAE,IAAI;YAChB,IAAI;SACL,EACD,EAAE,QAAQ,EAAE,kBAAkB,EAAE,CACjC,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC9C,OAAO,uBAAuB,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,kBAAkB,EAAE,CAAC,CAAC;AAC3E,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,GAAkB,EAClB,KAA2B,EAC3B,aAAqB;IAErB,4BAA4B,CAAC,KAAK,CAAC,CAAC;IACpC,MAAM,UAAU,GAAG,MAAM,gCAAgC,CACvD,GAAG,EACH,KAAK,CAAC,UAAU,EAChB,KAAK,CAAC,aAAa,EACnB,aAAa,CACd,CAAC;IACF,MAAM,IAAI,GAAG,oBAAoB,KAAK,CAAC,UAAU,eAAe,UAAU,CAAC,4BAA4B,EAAE,CAAC;IAE1G,IAAI,KAAK,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;QAC3B,OAAO,uBAAuB,CAC5B;YACE,OAAO,EAAE,IAAI;YACb,YAAY,EAAE,IAAI;SACnB,EACD,UAAU,CACX,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IAC1C,OAAO,uBAAuB,CAAC,MAAM,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,UAAU,CAAC,CAAC;AACrE,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -7,6 +7,7 @@ import { assertWriteConfirmedOrDryRun, WriteNotConfirmedError } from './agent/wr
|
|
|
7
7
|
import { OAuthClient } from './auth/oauth-client.js';
|
|
8
8
|
import { TokenStore } from './auth/token-store.js';
|
|
9
9
|
import { loadEnv } from './config/env.js';
|
|
10
|
+
import { runListPriceReferences, runResolveTokenHolderPriceReference } from './currencies/currency-handlers.js';
|
|
10
11
|
import { runCheckEventStatus, runSendBatchEvents, runSendEvent } from './events/events-handlers.js';
|
|
11
12
|
import { ApiRequestError, FuulApiClient, NotLoggedInError } from './http/fuul-api-client.js';
|
|
12
13
|
import { MissingProjectApiKeyError, resolveProjectApiKeyBearer } from './http/project-api-key-bearer.js';
|
|
@@ -14,11 +15,12 @@ import { enrichPayoutSchemasResponse } from './incentives/incentive-create-paylo
|
|
|
14
15
|
import { runCreateIncentive, runDeleteIncentive } from './incentives/incentive-write-handlers.js';
|
|
15
16
|
import { MetadataService } from './metadata/metadata-service.js';
|
|
16
17
|
import { loadIncentivesListWithMetadataScope, loadIncentiveWithMetadataScope, loadProjectWithMetadataScope, } from './metadata-scope/fetch-project-config.js';
|
|
18
|
+
import { attachDraftIdResolution, resolveDraftConversionIdForWrite, resolveDraftTriggerIdForWrite } from './metadata-scope/resolve-draft-ids.js';
|
|
17
19
|
import { normalizePayoutTermBodyForPatch } from './payouts/normalize-payout-term-body.js';
|
|
18
20
|
import { runPayoutBatchAction } from './payouts/payout-batch-handlers.js';
|
|
19
21
|
import { runDeleteUserReferrer, runGetUserReferrer, runRemoveUserFromReferralCode, runSwapUserReferralCode, runUpdateUserReferrer, runUseReferralCode, } from './referral-attribution/referral-attribution-handlers.js';
|
|
20
|
-
import { APPROVE_PAYOUTS_DESCRIPTION, CHECK_EVENT_STATUS_DESCRIPTION, CREATE_INCENTIVE_DESCRIPTION, CREATE_PROJECT_AFFILIATE_PUBLIC_DESCRIPTION, CREATE_TRIGGER_DESCRIPTION, DELETE_INCENTIVE_DESCRIPTION, DELETE_TRIGGER_DESCRIPTION, DELETE_USER_REFERRER_DESCRIPTION, GET_AFFILIATE_PORTAL_STATS_DESCRIPTION, GET_INCENTIVE_DESCRIPTION, GET_PROJECT_AFFILIATE_PUBLIC_DESCRIPTION, GET_PROJECT_AFFILIATE_TOTAL_STATS_DESCRIPTION, GET_PROJECT_AFFILIATES_BREAKDOWN_DESCRIPTION, GET_PROJECT_DESCRIPTION, GET_TRIGGER_DESCRIPTION, GET_USER_REFERRER_DESCRIPTION, LIST_CHAINS_DESCRIPTION, LIST_INCENTIVES_DESCRIPTION, LIST_PAYOUT_SCHEMAS_DESCRIPTION, LIST_PAYOUTS_PENDING_APPROVAL_DESCRIPTION, LIST_PROJECTS_DESCRIPTION, LIST_REWARDS_PAYOUTS_DESCRIPTION, LIST_TRIGGER_TYPES_DESCRIPTION, PING_DESCRIPTION, REJECT_PAYOUTS_DESCRIPTION, REMOVE_USER_FROM_REFERRAL_CODE_DESCRIPTION, SEND_BATCH_EVENTS_DESCRIPTION, SEND_EVENT_DESCRIPTION, SWAP_USER_REFERRAL_CODE_DESCRIPTION, UPDATE_AUDIENCE_DESCRIPTION, UPDATE_PAYOUT_TERM_DESCRIPTION, UPDATE_PROJECT_AFFILIATE_PUBLIC_DESCRIPTION, UPDATE_PROJECT_TIER_DESCRIPTION, UPDATE_TRIGGER_DESCRIPTION, UPDATE_USER_REFERRER_DESCRIPTION, USE_REFERRAL_CODE_DESCRIPTION, WHOAMI_DESCRIPTION, } from './tools/tool-descriptions.js';
|
|
21
|
-
import { checkEventStatusFieldsSchema, checkEventStatusInputSchema, createIncentiveFieldsSchema, createIncentiveInputSchema, createProjectAffiliatePublicFieldsSchema, createProjectAffiliatePublicInputSchema, createTriggerFieldsSchema, createTriggerInputSchema, deleteIncentiveFieldsSchema, deleteIncentiveInputSchema, deleteTriggerFieldsSchema, deleteTriggerInputSchema, deleteUserReferrerFieldsSchema, deleteUserReferrerInputSchema, getAffiliatePortalStatsSchema, getIncentiveInputSchema, getProjectAffiliatePublicInputSchema, getProjectAffiliatesBreakdownSchema, getProjectAffiliateTotalStatsSchema, getTriggerInputSchema, getUserReferrerFieldsSchema, getUserReferrerInputSchema, listPayoutsPendingApprovalSchema, listProjectsInputSchema, listRewardsPayoutsSchema, payoutBatchActionInputSchema, projectIdParamSchema, removeUserFromReferralCodeFieldsSchema, removeUserFromReferralCodeInputSchema, sendBatchEventsFieldsSchema, sendBatchEventsInputSchema, sendEventFieldsSchema, sendEventInputSchema, swapUserReferralCodeFieldsSchema, swapUserReferralCodeInputSchema, updateAudienceFieldsSchema, updateAudienceInputSchema, updatePayoutTermInputSchema, updateProjectAffiliatePublicFieldsSchema, updateProjectAffiliatePublicInputSchema, updateProjectTierFieldsSchema, updateProjectTierInputSchema, updateTriggerFieldsSchema, updateTriggerInputSchema, updateUserReferrerFieldsSchema, updateUserReferrerInputSchema, useReferralCodeFieldsSchema, useReferralCodeInputSchema, } from './tools/tool-schemas.js';
|
|
22
|
+
import { APPROVE_PAYOUTS_DESCRIPTION, CHECK_EVENT_STATUS_DESCRIPTION, CREATE_INCENTIVE_DESCRIPTION, CREATE_PROJECT_AFFILIATE_PUBLIC_DESCRIPTION, CREATE_TRIGGER_DESCRIPTION, DELETE_INCENTIVE_DESCRIPTION, DELETE_TRIGGER_DESCRIPTION, DELETE_USER_REFERRER_DESCRIPTION, GET_AFFILIATE_PORTAL_STATS_DESCRIPTION, GET_INCENTIVE_DESCRIPTION, GET_PROJECT_AFFILIATE_PUBLIC_DESCRIPTION, GET_PROJECT_AFFILIATE_TOTAL_STATS_DESCRIPTION, GET_PROJECT_AFFILIATES_BREAKDOWN_DESCRIPTION, GET_PROJECT_DESCRIPTION, GET_TRIGGER_DESCRIPTION, GET_USER_REFERRER_DESCRIPTION, LIST_CHAINS_DESCRIPTION, LIST_INCENTIVES_DESCRIPTION, LIST_PAYOUT_SCHEMAS_DESCRIPTION, LIST_PAYOUTS_PENDING_APPROVAL_DESCRIPTION, LIST_PRICE_REFERENCES_DESCRIPTION, LIST_PROJECTS_DESCRIPTION, LIST_REWARDS_PAYOUTS_DESCRIPTION, LIST_TRIGGER_TYPES_DESCRIPTION, PING_DESCRIPTION, REJECT_PAYOUTS_DESCRIPTION, REMOVE_USER_FROM_REFERRAL_CODE_DESCRIPTION, RESOLVE_TOKEN_HOLDER_PRICE_REFERENCE_DESCRIPTION, SEND_BATCH_EVENTS_DESCRIPTION, SEND_EVENT_DESCRIPTION, SWAP_USER_REFERRAL_CODE_DESCRIPTION, UPDATE_AUDIENCE_DESCRIPTION, UPDATE_PAYOUT_TERM_DESCRIPTION, UPDATE_PROJECT_AFFILIATE_PUBLIC_DESCRIPTION, UPDATE_PROJECT_TIER_DESCRIPTION, UPDATE_TRIGGER_DESCRIPTION, UPDATE_USER_REFERRER_DESCRIPTION, USE_REFERRAL_CODE_DESCRIPTION, WHOAMI_DESCRIPTION, } from './tools/tool-descriptions.js';
|
|
23
|
+
import { checkEventStatusFieldsSchema, checkEventStatusInputSchema, createIncentiveFieldsSchema, createIncentiveInputSchema, createProjectAffiliatePublicFieldsSchema, createProjectAffiliatePublicInputSchema, createTriggerFieldsSchema, createTriggerInputSchema, deleteIncentiveFieldsSchema, deleteIncentiveInputSchema, deleteTriggerFieldsSchema, deleteTriggerInputSchema, deleteUserReferrerFieldsSchema, deleteUserReferrerInputSchema, getAffiliatePortalStatsSchema, getIncentiveInputSchema, getProjectAffiliatePublicInputSchema, getProjectAffiliatesBreakdownSchema, getProjectAffiliateTotalStatsSchema, getTriggerInputSchema, getUserReferrerFieldsSchema, getUserReferrerInputSchema, listPayoutsPendingApprovalSchema, listPriceReferencesInputSchema, listProjectsInputSchema, listRewardsPayoutsSchema, payoutBatchActionInputSchema, projectIdParamSchema, removeUserFromReferralCodeFieldsSchema, removeUserFromReferralCodeInputSchema, resolveTokenHolderPriceReferenceFieldsSchema, resolveTokenHolderPriceReferenceInputSchema, sendBatchEventsFieldsSchema, sendBatchEventsInputSchema, sendEventFieldsSchema, sendEventInputSchema, swapUserReferralCodeFieldsSchema, swapUserReferralCodeInputSchema, updateAudienceFieldsSchema, updateAudienceInputSchema, updatePayoutTermInputSchema, updateProjectAffiliatePublicFieldsSchema, updateProjectAffiliatePublicInputSchema, updateProjectTierFieldsSchema, updateProjectTierInputSchema, updateTriggerFieldsSchema, updateTriggerInputSchema, updateUserReferrerFieldsSchema, updateUserReferrerInputSchema, useReferralCodeFieldsSchema, useReferralCodeInputSchema, } from './tools/tool-schemas.js';
|
|
22
24
|
import { enrichTriggerTypesResponse } from './triggers/trigger-create-payload-guide.js';
|
|
23
25
|
import { runCreateTrigger, runDeleteTrigger } from './triggers/trigger-write-handlers.js';
|
|
24
26
|
import { compactQuery } from './util/compact-query.js';
|
|
@@ -84,6 +86,26 @@ async function main() {
|
|
|
84
86
|
return toolErrorPayload(e);
|
|
85
87
|
}
|
|
86
88
|
});
|
|
89
|
+
server.tool('list_price_references', LIST_PRICE_REFERENCES_DESCRIPTION, listPriceReferencesInputSchema.shape, async (args) => {
|
|
90
|
+
try {
|
|
91
|
+
const parsed = listPriceReferencesInputSchema.parse(args);
|
|
92
|
+
const data = await withTimeout(runListPriceReferences(api, parsed), toolTimeoutMs, 'list_price_references');
|
|
93
|
+
return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
|
|
94
|
+
}
|
|
95
|
+
catch (e) {
|
|
96
|
+
return toolErrorPayload(e, 'Failed to list price references');
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
server.tool('resolve_token_holder_price_reference', RESOLVE_TOKEN_HOLDER_PRICE_REFERENCE_DESCRIPTION, resolveTokenHolderPriceReferenceFieldsSchema.shape, async (args) => {
|
|
100
|
+
try {
|
|
101
|
+
const parsed = resolveTokenHolderPriceReferenceInputSchema.parse(args);
|
|
102
|
+
const data = await withTimeout(runResolveTokenHolderPriceReference(api, parsed), toolTimeoutMs, 'resolve_token_holder_price_reference');
|
|
103
|
+
return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
|
|
104
|
+
}
|
|
105
|
+
catch (e) {
|
|
106
|
+
return toolErrorPayload(e, 'Failed to resolve token holder price reference');
|
|
107
|
+
}
|
|
108
|
+
});
|
|
87
109
|
server.tool('list_trigger_types', LIST_TRIGGER_TYPES_DESCRIPTION, {}, async () => {
|
|
88
110
|
try {
|
|
89
111
|
const data = await withTimeout(metadata.getTriggerTypes(), toolTimeoutMs, 'list_trigger_types');
|
|
@@ -174,7 +196,7 @@ async function main() {
|
|
|
174
196
|
server.tool('delete_trigger', DELETE_TRIGGER_DESCRIPTION, deleteTriggerFieldsSchema.shape, async (args) => {
|
|
175
197
|
try {
|
|
176
198
|
const parsed = deleteTriggerInputSchema.parse(args);
|
|
177
|
-
const data = await withTimeout(runDeleteTrigger(api, parsed), toolTimeoutMs, 'delete_trigger');
|
|
199
|
+
const data = await withTimeout(runDeleteTrigger(api, parsed, toolTimeoutMs), toolTimeoutMs, 'delete_trigger');
|
|
178
200
|
return { content: [{ type: 'text', text: stringifyToolPayload(data ?? { ok: true }, parsed.dry_run) }] };
|
|
179
201
|
}
|
|
180
202
|
catch (e) {
|
|
@@ -184,7 +206,7 @@ async function main() {
|
|
|
184
206
|
server.tool('create_incentive', CREATE_INCENTIVE_DESCRIPTION, createIncentiveFieldsSchema.shape, async (args) => {
|
|
185
207
|
try {
|
|
186
208
|
const parsed = createIncentiveInputSchema.parse(args);
|
|
187
|
-
const data = await withTimeout(runCreateIncentive(api, parsed), toolTimeoutMs, 'create_incentive');
|
|
209
|
+
const data = await withTimeout(runCreateIncentive(api, parsed, toolTimeoutMs), toolTimeoutMs, 'create_incentive');
|
|
188
210
|
return { content: [{ type: 'text', text: stringifyToolPayload(data, parsed.dry_run) }] };
|
|
189
211
|
}
|
|
190
212
|
catch (e) {
|
|
@@ -194,7 +216,7 @@ async function main() {
|
|
|
194
216
|
server.tool('delete_incentive', DELETE_INCENTIVE_DESCRIPTION, deleteIncentiveFieldsSchema.shape, async (args) => {
|
|
195
217
|
try {
|
|
196
218
|
const parsed = deleteIncentiveInputSchema.parse(args);
|
|
197
|
-
const data = await withTimeout(runDeleteIncentive(api, parsed), toolTimeoutMs, 'delete_incentive');
|
|
219
|
+
const data = await withTimeout(runDeleteIncentive(api, parsed, toolTimeoutMs), toolTimeoutMs, 'delete_incentive');
|
|
198
220
|
return { content: [{ type: 'text', text: stringifyToolPayload(data ?? { ok: true }, parsed.dry_run) }] };
|
|
199
221
|
}
|
|
200
222
|
catch (e) {
|
|
@@ -435,20 +457,28 @@ async function main() {
|
|
|
435
457
|
try {
|
|
436
458
|
const parsed = updatePayoutTermInputSchema.parse(args);
|
|
437
459
|
assertWriteConfirmedOrDryRun(parsed);
|
|
438
|
-
const
|
|
460
|
+
const conversionResolution = await resolveDraftConversionIdForWrite(api, parsed.project_id, parsed.conversion_id, toolTimeoutMs);
|
|
461
|
+
const path = `/api/v1/projects/${parsed.project_id}/conversions/${conversionResolution.resolved_draft_conversion_id}/payout_terms/${parsed.payout_term_id}`;
|
|
439
462
|
const patchBody = normalizePayoutTermBodyForPatch(parsed.payout_term);
|
|
440
463
|
if (parsed.dry_run === true) {
|
|
441
464
|
return {
|
|
442
465
|
content: [
|
|
443
466
|
{
|
|
444
467
|
type: 'text',
|
|
445
|
-
text: JSON.stringify({ dry_run: true, would_patch: path, body: patchBody }, null, 2),
|
|
468
|
+
text: JSON.stringify(attachDraftIdResolution({ dry_run: true, would_patch: path, body: patchBody }, conversionResolution), null, 2),
|
|
446
469
|
},
|
|
447
470
|
],
|
|
448
471
|
};
|
|
449
472
|
}
|
|
450
473
|
const data = await withTimeout(api.patchJson(path, patchBody), toolTimeoutMs, 'update_payout_term');
|
|
451
|
-
return {
|
|
474
|
+
return {
|
|
475
|
+
content: [
|
|
476
|
+
{
|
|
477
|
+
type: 'text',
|
|
478
|
+
text: stringifyToolPayload(attachDraftIdResolution(data, conversionResolution), parsed.dry_run),
|
|
479
|
+
},
|
|
480
|
+
],
|
|
481
|
+
};
|
|
452
482
|
}
|
|
453
483
|
catch (e) {
|
|
454
484
|
return toolErrorPayload(e, 'Failed to update payout term');
|
|
@@ -485,7 +515,8 @@ async function main() {
|
|
|
485
515
|
try {
|
|
486
516
|
const parsed = updateTriggerInputSchema.parse(args);
|
|
487
517
|
assertWriteConfirmedOrDryRun(parsed);
|
|
488
|
-
const
|
|
518
|
+
const triggerResolution = await resolveDraftTriggerIdForWrite(api, parsed.project_id, parsed.trigger_id, toolTimeoutMs);
|
|
519
|
+
const path = `/api/v1/projects/${parsed.project_id}/triggers/${triggerResolution.resolved_draft_trigger_id}`;
|
|
489
520
|
const body = {};
|
|
490
521
|
if (parsed.name !== undefined) {
|
|
491
522
|
body.name = parsed.name;
|
|
@@ -534,11 +565,23 @@ async function main() {
|
|
|
534
565
|
}
|
|
535
566
|
if (parsed.dry_run === true) {
|
|
536
567
|
return {
|
|
537
|
-
content: [
|
|
568
|
+
content: [
|
|
569
|
+
{
|
|
570
|
+
type: 'text',
|
|
571
|
+
text: JSON.stringify(attachDraftIdResolution({ dry_run: true, would_patch: path, body }, triggerResolution), null, 2),
|
|
572
|
+
},
|
|
573
|
+
],
|
|
538
574
|
};
|
|
539
575
|
}
|
|
540
576
|
const data = await withTimeout(api.patchJson(path, body), toolTimeoutMs, 'update_trigger');
|
|
541
|
-
return {
|
|
577
|
+
return {
|
|
578
|
+
content: [
|
|
579
|
+
{
|
|
580
|
+
type: 'text',
|
|
581
|
+
text: stringifyToolPayload(attachDraftIdResolution(data, triggerResolution), parsed.dry_run),
|
|
582
|
+
},
|
|
583
|
+
],
|
|
584
|
+
};
|
|
542
585
|
}
|
|
543
586
|
catch (e) {
|
|
544
587
|
return toolErrorPayload(e, 'Failed to update trigger');
|