@sardis/sdk 0.2.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/CHANGELOG.md +47 -0
- package/LICENSE +21 -0
- package/README.md +439 -0
- package/dist/browser/index.js +7049 -0
- package/dist/browser/index.js.map +1 -0
- package/dist/browser/sardis.umd.js +7071 -0
- package/dist/browser/sardis.umd.js.map +1 -0
- package/dist/cjs/client.js +644 -0
- package/dist/cjs/client.js.map +1 -0
- package/dist/cjs/demo.js +699 -0
- package/dist/cjs/demo.js.map +1 -0
- package/dist/cjs/errors.js +630 -0
- package/dist/cjs/errors.js.map +1 -0
- package/dist/cjs/index.js +131 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/integrations/index.js +21 -0
- package/dist/cjs/integrations/index.js.map +1 -0
- package/dist/cjs/integrations/langchain.js +339 -0
- package/dist/cjs/integrations/langchain.js.map +1 -0
- package/dist/cjs/integrations/openai.js +505 -0
- package/dist/cjs/integrations/openai.js.map +1 -0
- package/dist/cjs/integrations/vercel-ai.js +198 -0
- package/dist/cjs/integrations/vercel-ai.js.map +1 -0
- package/dist/cjs/resources/a2a.js +158 -0
- package/dist/cjs/resources/a2a.js.map +1 -0
- package/dist/cjs/resources/agents.js +142 -0
- package/dist/cjs/resources/agents.js.map +1 -0
- package/dist/cjs/resources/base.js +124 -0
- package/dist/cjs/resources/base.js.map +1 -0
- package/dist/cjs/resources/cards.js +43 -0
- package/dist/cjs/resources/cards.js.map +1 -0
- package/dist/cjs/resources/holds.js +64 -0
- package/dist/cjs/resources/holds.js.map +1 -0
- package/dist/cjs/resources/index.js +31 -0
- package/dist/cjs/resources/index.js.map +1 -0
- package/dist/cjs/resources/ledger.js +43 -0
- package/dist/cjs/resources/ledger.js.map +1 -0
- package/dist/cjs/resources/marketplace.js +88 -0
- package/dist/cjs/resources/marketplace.js.map +1 -0
- package/dist/cjs/resources/payments.js +33 -0
- package/dist/cjs/resources/payments.js.map +1 -0
- package/dist/cjs/resources/policies.js +31 -0
- package/dist/cjs/resources/policies.js.map +1 -0
- package/dist/cjs/resources/transactions.js +37 -0
- package/dist/cjs/resources/transactions.js.map +1 -0
- package/dist/cjs/resources/ucp.js +133 -0
- package/dist/cjs/resources/ucp.js.map +1 -0
- package/dist/cjs/resources/wallets.js +109 -0
- package/dist/cjs/resources/wallets.js.map +1 -0
- package/dist/cjs/resources/webhooks.js +81 -0
- package/dist/cjs/resources/webhooks.js.map +1 -0
- package/dist/cjs/types.js +11 -0
- package/dist/cjs/types.js.map +1 -0
- package/dist/client.d.ts +419 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +637 -0
- package/dist/client.js.map +1 -0
- package/dist/demo.d.ts +335 -0
- package/dist/demo.d.ts.map +1 -0
- package/dist/demo.js +694 -0
- package/dist/demo.js.map +1 -0
- package/dist/errors.d.ts +522 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +612 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +83 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +85 -0
- package/dist/index.js.map +1 -0
- package/dist/integrations/index.d.ts +4 -0
- package/dist/integrations/index.d.ts.map +1 -0
- package/dist/integrations/index.js +5 -0
- package/dist/integrations/index.js.map +1 -0
- package/dist/integrations/langchain.d.ts +68 -0
- package/dist/integrations/langchain.d.ts.map +1 -0
- package/dist/integrations/langchain.js +335 -0
- package/dist/integrations/langchain.js.map +1 -0
- package/dist/integrations/openai.d.ts +97 -0
- package/dist/integrations/openai.d.ts.map +1 -0
- package/dist/integrations/openai.js +467 -0
- package/dist/integrations/openai.js.map +1 -0
- package/dist/integrations/vercel-ai.d.ts +180 -0
- package/dist/integrations/vercel-ai.d.ts.map +1 -0
- package/dist/integrations/vercel-ai.js +194 -0
- package/dist/integrations/vercel-ai.js.map +1 -0
- package/dist/resources/a2a.d.ts +254 -0
- package/dist/resources/a2a.d.ts.map +1 -0
- package/dist/resources/a2a.js +154 -0
- package/dist/resources/a2a.js.map +1 -0
- package/dist/resources/agents.d.ts +111 -0
- package/dist/resources/agents.d.ts.map +1 -0
- package/dist/resources/agents.js +138 -0
- package/dist/resources/agents.js.map +1 -0
- package/dist/resources/base.d.ts +115 -0
- package/dist/resources/base.d.ts.map +1 -0
- package/dist/resources/base.js +120 -0
- package/dist/resources/base.js.map +1 -0
- package/dist/resources/cards.d.ts +19 -0
- package/dist/resources/cards.d.ts.map +1 -0
- package/dist/resources/cards.js +39 -0
- package/dist/resources/cards.js.map +1 -0
- package/dist/resources/holds.d.ts +44 -0
- package/dist/resources/holds.d.ts.map +1 -0
- package/dist/resources/holds.js +60 -0
- package/dist/resources/holds.js.map +1 -0
- package/dist/resources/index.d.ts +16 -0
- package/dist/resources/index.d.ts.map +1 -0
- package/dist/resources/index.js +16 -0
- package/dist/resources/index.js.map +1 -0
- package/dist/resources/ledger.d.ts +38 -0
- package/dist/resources/ledger.d.ts.map +1 -0
- package/dist/resources/ledger.js +39 -0
- package/dist/resources/ledger.js.map +1 -0
- package/dist/resources/marketplace.d.ts +60 -0
- package/dist/resources/marketplace.d.ts.map +1 -0
- package/dist/resources/marketplace.js +84 -0
- package/dist/resources/marketplace.js.map +1 -0
- package/dist/resources/payments.d.ts +24 -0
- package/dist/resources/payments.d.ts.map +1 -0
- package/dist/resources/payments.js +29 -0
- package/dist/resources/payments.js.map +1 -0
- package/dist/resources/policies.d.ts +23 -0
- package/dist/resources/policies.d.ts.map +1 -0
- package/dist/resources/policies.js +27 -0
- package/dist/resources/policies.js.map +1 -0
- package/dist/resources/transactions.d.ts +32 -0
- package/dist/resources/transactions.d.ts.map +1 -0
- package/dist/resources/transactions.js +33 -0
- package/dist/resources/transactions.js.map +1 -0
- package/dist/resources/ucp.d.ts +218 -0
- package/dist/resources/ucp.d.ts.map +1 -0
- package/dist/resources/ucp.js +129 -0
- package/dist/resources/ucp.js.map +1 -0
- package/dist/resources/wallets.d.ts +71 -0
- package/dist/resources/wallets.d.ts.map +1 -0
- package/dist/resources/wallets.js +105 -0
- package/dist/resources/wallets.js.map +1 -0
- package/dist/resources/webhooks.d.ts +57 -0
- package/dist/resources/webhooks.d.ts.map +1 -0
- package/dist/resources/webhooks.js +77 -0
- package/dist/resources/webhooks.js.map +1 -0
- package/dist/types.d.ts +1045 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +10 -0
- package/dist/types.js.map +1 -0
- package/package.json +114 -0
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAI Function Calling Integration for Sardis SDK
|
|
3
|
+
*
|
|
4
|
+
* Provides OpenAI-compatible function schemas and execution handlers
|
|
5
|
+
* for AI agents to execute payments through Sardis MPC wallets.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import OpenAI from 'openai';
|
|
10
|
+
* import { SardisClient } from '@sardis/sdk';
|
|
11
|
+
* import { createSardisOpenAITools, handleSardisFunctionCall } from '@sardis/sdk/integrations/openai';
|
|
12
|
+
*
|
|
13
|
+
* const sardis = new SardisClient({ apiKey: 'your-api-key' });
|
|
14
|
+
* const openai = new OpenAI();
|
|
15
|
+
*
|
|
16
|
+
* const tools = createSardisOpenAITools();
|
|
17
|
+
*
|
|
18
|
+
* const response = await openai.chat.completions.create({
|
|
19
|
+
* model: 'gpt-4',
|
|
20
|
+
* messages: [{ role: 'user', content: 'Pay $50 to OpenAI' }],
|
|
21
|
+
* tools
|
|
22
|
+
* });
|
|
23
|
+
*
|
|
24
|
+
* // Handle tool calls
|
|
25
|
+
* for (const toolCall of response.choices[0].message.tool_calls || []) {
|
|
26
|
+
* const result = await handleSardisFunctionCall(sardis, toolCall, { walletId: 'wallet_123' });
|
|
27
|
+
* console.log(result);
|
|
28
|
+
* }
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
import { SardisClient } from '../client.js';
|
|
32
|
+
/**
|
|
33
|
+
* OpenAI tool definition
|
|
34
|
+
*/
|
|
35
|
+
export interface OpenAITool {
|
|
36
|
+
type: 'function';
|
|
37
|
+
function: {
|
|
38
|
+
name: string;
|
|
39
|
+
description: string;
|
|
40
|
+
parameters: {
|
|
41
|
+
type: 'object';
|
|
42
|
+
properties: Record<string, {
|
|
43
|
+
type: string;
|
|
44
|
+
description: string;
|
|
45
|
+
enum?: string[];
|
|
46
|
+
}>;
|
|
47
|
+
required?: string[];
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* OpenAI function call from response
|
|
53
|
+
*/
|
|
54
|
+
export interface OpenAIFunctionCall {
|
|
55
|
+
id: string;
|
|
56
|
+
type: 'function';
|
|
57
|
+
function: {
|
|
58
|
+
name: string;
|
|
59
|
+
arguments: string;
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Options for Sardis OpenAI integration
|
|
64
|
+
*/
|
|
65
|
+
export interface SardisOpenAIOptions {
|
|
66
|
+
/** Default wallet ID to use for payments */
|
|
67
|
+
walletId?: string;
|
|
68
|
+
/** Default agent ID */
|
|
69
|
+
agentId?: string;
|
|
70
|
+
/** Default chain for transactions */
|
|
71
|
+
chain?: 'base' | 'base_sepolia' | 'polygon' | 'polygon_amoy' | 'ethereum' | 'ethereum_sepolia';
|
|
72
|
+
/** Default token */
|
|
73
|
+
token?: 'USDC' | 'USDT' | 'PYUSD' | 'EURC';
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Create OpenAI-compatible tool definitions for Sardis functions.
|
|
77
|
+
* Use these with the OpenAI Chat Completions API.
|
|
78
|
+
*/
|
|
79
|
+
export declare function createSardisOpenAITools(): OpenAITool[];
|
|
80
|
+
/**
|
|
81
|
+
* Handle an OpenAI function call and execute the corresponding Sardis operation.
|
|
82
|
+
*
|
|
83
|
+
* @param client - Initialized SardisClient instance
|
|
84
|
+
* @param toolCall - The tool call from OpenAI response
|
|
85
|
+
* @param options - Configuration options including walletId
|
|
86
|
+
* @returns JSON string with the result
|
|
87
|
+
*/
|
|
88
|
+
export declare function handleSardisFunctionCall(client: SardisClient, toolCall: OpenAIFunctionCall, options?: SardisOpenAIOptions): Promise<string>;
|
|
89
|
+
/**
|
|
90
|
+
* Helper to create tool response message for OpenAI conversation
|
|
91
|
+
*/
|
|
92
|
+
export declare function createToolResponse(toolCallId: string, content: string): {
|
|
93
|
+
role: 'tool';
|
|
94
|
+
tool_call_id: string;
|
|
95
|
+
content: string;
|
|
96
|
+
};
|
|
97
|
+
//# sourceMappingURL=openai.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../src/integrations/openai.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAG5C;;GAEG;AACH,MAAM,WAAW,UAAU;IACvB,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,UAAU,EAAE;YACR,IAAI,EAAE,QAAQ,CAAC;YACf,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE;gBACvB,IAAI,EAAE,MAAM,CAAC;gBACb,WAAW,EAAE,MAAM,CAAC;gBACpB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;aACnB,CAAC,CAAC;YACH,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;SACvB,CAAC;KACL,CAAC;CACL;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,EAAE,MAAM,CAAC;KACrB,CAAC;CACL;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAChC,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uBAAuB;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qCAAqC;IACrC,KAAK,CAAC,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,GAAG,cAAc,GAAG,UAAU,GAAG,kBAAkB,CAAC;IAC/F,oBAAoB;IACpB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;CAC9C;AA+CD;;;GAGG;AACH,wBAAgB,uBAAuB,IAAI,UAAU,EAAE,CA8FtD;AAED;;;;;;;GAOG;AACH,wBAAsB,wBAAwB,CAC1C,MAAM,EAAE,YAAY,EACpB,QAAQ,EAAE,kBAAkB,EAC5B,OAAO,GAAE,mBAAwB,GAClC,OAAO,CAAC,MAAM,CAAC,CAmDjB;AAuRD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG;IACrE,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACnB,CAMA"}
|
|
@@ -0,0 +1,467 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAI Function Calling Integration for Sardis SDK
|
|
3
|
+
*
|
|
4
|
+
* Provides OpenAI-compatible function schemas and execution handlers
|
|
5
|
+
* for AI agents to execute payments through Sardis MPC wallets.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import OpenAI from 'openai';
|
|
10
|
+
* import { SardisClient } from '@sardis/sdk';
|
|
11
|
+
* import { createSardisOpenAITools, handleSardisFunctionCall } from '@sardis/sdk/integrations/openai';
|
|
12
|
+
*
|
|
13
|
+
* const sardis = new SardisClient({ apiKey: 'your-api-key' });
|
|
14
|
+
* const openai = new OpenAI();
|
|
15
|
+
*
|
|
16
|
+
* const tools = createSardisOpenAITools();
|
|
17
|
+
*
|
|
18
|
+
* const response = await openai.chat.completions.create({
|
|
19
|
+
* model: 'gpt-4',
|
|
20
|
+
* messages: [{ role: 'user', content: 'Pay $50 to OpenAI' }],
|
|
21
|
+
* tools
|
|
22
|
+
* });
|
|
23
|
+
*
|
|
24
|
+
* // Handle tool calls
|
|
25
|
+
* for (const toolCall of response.choices[0].message.tool_calls || []) {
|
|
26
|
+
* const result = await handleSardisFunctionCall(sardis, toolCall, { walletId: 'wallet_123' });
|
|
27
|
+
* console.log(result);
|
|
28
|
+
* }
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
/**
|
|
32
|
+
* Generate a unique mandate ID
|
|
33
|
+
*
|
|
34
|
+
* SECURITY: Uses crypto.randomUUID() for cryptographically secure IDs.
|
|
35
|
+
* Math.random() is not suitable for security-relevant identifiers.
|
|
36
|
+
*/
|
|
37
|
+
function generateMandateId() {
|
|
38
|
+
const id = (typeof crypto !== 'undefined' && crypto.randomUUID)
|
|
39
|
+
? crypto.randomUUID().replace(/-/g, '').substring(0, 16)
|
|
40
|
+
: Array.from((typeof crypto !== 'undefined' && crypto.getRandomValues)
|
|
41
|
+
? crypto.getRandomValues(new Uint8Array(8))
|
|
42
|
+
: (() => { throw new Error('No cryptographic RNG available for mandate IDs'); })()).map((b) => b.toString(16).padStart(2, '0')).join('');
|
|
43
|
+
return `mnd_${id}`;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Create a SHA-256 hash for audit purposes
|
|
47
|
+
*
|
|
48
|
+
* SECURITY: The fallback uses Node.js crypto module instead of a
|
|
49
|
+
* predictable timestamp string. Audit hashes must provide collision
|
|
50
|
+
* resistance for financial integrity.
|
|
51
|
+
*/
|
|
52
|
+
async function createAuditHash(data) {
|
|
53
|
+
if (typeof crypto !== 'undefined' && crypto.subtle) {
|
|
54
|
+
const encoder = new TextEncoder();
|
|
55
|
+
const dataBuffer = encoder.encode(data);
|
|
56
|
+
const hashBuffer = await crypto.subtle.digest('SHA-256', dataBuffer);
|
|
57
|
+
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
|
58
|
+
return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
|
|
59
|
+
}
|
|
60
|
+
// Fallback: use Node.js crypto (always available in Node environments)
|
|
61
|
+
try {
|
|
62
|
+
const { createHash } = await import('node:crypto');
|
|
63
|
+
return createHash('sha256').update(data).digest('hex');
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
// SECURITY: Refuse to produce a fake hash — fail-closed.
|
|
67
|
+
throw new Error('No cryptographic hash function available. '
|
|
68
|
+
+ 'Audit integrity cannot be guaranteed without SHA-256.');
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Create OpenAI-compatible tool definitions for Sardis functions.
|
|
73
|
+
* Use these with the OpenAI Chat Completions API.
|
|
74
|
+
*/
|
|
75
|
+
export function createSardisOpenAITools() {
|
|
76
|
+
return [
|
|
77
|
+
{
|
|
78
|
+
type: 'function',
|
|
79
|
+
function: {
|
|
80
|
+
name: 'sardis_pay',
|
|
81
|
+
description: 'Execute a secure payment using Sardis MPC wallet. Validates against spending policies before execution. Returns transaction details on success or error message if blocked by policy.',
|
|
82
|
+
parameters: {
|
|
83
|
+
type: 'object',
|
|
84
|
+
properties: {
|
|
85
|
+
amount: {
|
|
86
|
+
type: 'number',
|
|
87
|
+
description: 'The amount to pay in USD (or token units)'
|
|
88
|
+
},
|
|
89
|
+
vendor: {
|
|
90
|
+
type: 'string',
|
|
91
|
+
description: 'The name of the merchant or service provider (e.g., "OpenAI", "GitHub", "Vercel")'
|
|
92
|
+
},
|
|
93
|
+
vendor_address: {
|
|
94
|
+
type: 'string',
|
|
95
|
+
description: 'The wallet address of the vendor (0x...). Optional - will be resolved if not provided.'
|
|
96
|
+
},
|
|
97
|
+
purpose: {
|
|
98
|
+
type: 'string',
|
|
99
|
+
description: 'The reason for the payment, used for policy validation and audit trail'
|
|
100
|
+
},
|
|
101
|
+
token: {
|
|
102
|
+
type: 'string',
|
|
103
|
+
description: 'The stablecoin to use for payment. Defaults to USDC.',
|
|
104
|
+
enum: ['USDC', 'USDT', 'PYUSD', 'EURC']
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
required: ['amount', 'vendor']
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
type: 'function',
|
|
113
|
+
function: {
|
|
114
|
+
name: 'sardis_check_balance',
|
|
115
|
+
description: 'Check the current balance of the Sardis wallet. Use this before making payments to ensure sufficient funds are available.',
|
|
116
|
+
parameters: {
|
|
117
|
+
type: 'object',
|
|
118
|
+
properties: {
|
|
119
|
+
token: {
|
|
120
|
+
type: 'string',
|
|
121
|
+
description: 'The token to check balance for. Defaults to USDC.',
|
|
122
|
+
enum: ['USDC', 'USDT', 'PYUSD', 'EURC']
|
|
123
|
+
},
|
|
124
|
+
chain: {
|
|
125
|
+
type: 'string',
|
|
126
|
+
description: 'The blockchain to check balance on (e.g., "base", "polygon", "ethereum")'
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
type: 'function',
|
|
134
|
+
function: {
|
|
135
|
+
name: 'sardis_get_wallet',
|
|
136
|
+
description: 'Get information about the Sardis wallet including spending limits, policy settings, and configured addresses.',
|
|
137
|
+
parameters: {
|
|
138
|
+
type: 'object',
|
|
139
|
+
properties: {}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
type: 'function',
|
|
145
|
+
function: {
|
|
146
|
+
name: 'sardis_check_policy',
|
|
147
|
+
description: 'Check if a payment would be allowed by the spending policy without executing it. Use this to validate payments before execution.',
|
|
148
|
+
parameters: {
|
|
149
|
+
type: 'object',
|
|
150
|
+
properties: {
|
|
151
|
+
amount: {
|
|
152
|
+
type: 'number',
|
|
153
|
+
description: 'The amount to pay in USD'
|
|
154
|
+
},
|
|
155
|
+
vendor: {
|
|
156
|
+
type: 'string',
|
|
157
|
+
description: 'The name of the merchant or service provider'
|
|
158
|
+
},
|
|
159
|
+
purpose: {
|
|
160
|
+
type: 'string',
|
|
161
|
+
description: 'The reason for the payment'
|
|
162
|
+
}
|
|
163
|
+
},
|
|
164
|
+
required: ['amount', 'vendor']
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
];
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Handle an OpenAI function call and execute the corresponding Sardis operation.
|
|
172
|
+
*
|
|
173
|
+
* @param client - Initialized SardisClient instance
|
|
174
|
+
* @param toolCall - The tool call from OpenAI response
|
|
175
|
+
* @param options - Configuration options including walletId
|
|
176
|
+
* @returns JSON string with the result
|
|
177
|
+
*/
|
|
178
|
+
export async function handleSardisFunctionCall(client, toolCall, options = {}) {
|
|
179
|
+
const { function: func } = toolCall;
|
|
180
|
+
// SECURITY: LLMs can produce malformed JSON. Without try/catch, a parse
|
|
181
|
+
// failure during a payment flow crashes the process and may leave the
|
|
182
|
+
// system in an inconsistent state (e.g., hold created but never captured).
|
|
183
|
+
let args;
|
|
184
|
+
try {
|
|
185
|
+
args = JSON.parse(func.arguments);
|
|
186
|
+
}
|
|
187
|
+
catch (parseError) {
|
|
188
|
+
return JSON.stringify({
|
|
189
|
+
success: false,
|
|
190
|
+
error: 'INVALID_FUNCTION_ARGUMENTS',
|
|
191
|
+
message: `Failed to parse function arguments: ${parseError instanceof Error ? parseError.message : 'malformed JSON'}`,
|
|
192
|
+
raw_arguments: func.arguments.substring(0, 200),
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
const defaultWalletId = options.walletId || process.env.SARDIS_WALLET_ID || '';
|
|
196
|
+
const defaultAgentId = options.agentId || process.env.SARDIS_AGENT_ID || '';
|
|
197
|
+
const defaultChain = options.chain || 'base_sepolia';
|
|
198
|
+
const defaultToken = options.token || 'USDC';
|
|
199
|
+
switch (func.name) {
|
|
200
|
+
case 'sardis_pay':
|
|
201
|
+
return handlePayment(client, args, {
|
|
202
|
+
walletId: defaultWalletId,
|
|
203
|
+
agentId: defaultAgentId,
|
|
204
|
+
chain: defaultChain,
|
|
205
|
+
token: defaultToken
|
|
206
|
+
});
|
|
207
|
+
case 'sardis_check_balance':
|
|
208
|
+
return handleCheckBalance(client, args, {
|
|
209
|
+
walletId: defaultWalletId,
|
|
210
|
+
chain: defaultChain,
|
|
211
|
+
token: defaultToken
|
|
212
|
+
});
|
|
213
|
+
case 'sardis_get_wallet':
|
|
214
|
+
return handleGetWallet(client, defaultWalletId);
|
|
215
|
+
case 'sardis_check_policy':
|
|
216
|
+
return handleCheckPolicy(client, args, defaultWalletId);
|
|
217
|
+
default:
|
|
218
|
+
return JSON.stringify({
|
|
219
|
+
success: false,
|
|
220
|
+
error: `Unknown function: ${func.name}`
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
async function handlePayment(client, args, options) {
|
|
225
|
+
const { walletId, agentId, chain, token: defaultToken } = options;
|
|
226
|
+
if (!walletId) {
|
|
227
|
+
return JSON.stringify({
|
|
228
|
+
success: false,
|
|
229
|
+
error: 'No wallet ID configured. Set walletId in options or SARDIS_WALLET_ID env var.'
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
// SECURITY: Validate LLM-provided arguments before passing to API.
|
|
233
|
+
// LLMs can produce out-of-range values, injection payloads, or garbage strings.
|
|
234
|
+
const amount = args.amount;
|
|
235
|
+
const vendor = args.vendor;
|
|
236
|
+
const vendorAddress = args.vendor_address;
|
|
237
|
+
const purpose = args.purpose;
|
|
238
|
+
const token = args.token || defaultToken;
|
|
239
|
+
// Amount validation: must be positive, finite, and within sane bounds
|
|
240
|
+
if (typeof amount !== 'number' || !Number.isFinite(amount) || amount <= 0) {
|
|
241
|
+
return JSON.stringify({
|
|
242
|
+
success: false,
|
|
243
|
+
error: 'INVALID_AMOUNT',
|
|
244
|
+
message: 'Amount must be a positive finite number',
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
if (amount > 1_000_000) {
|
|
248
|
+
return JSON.stringify({
|
|
249
|
+
success: false,
|
|
250
|
+
error: 'AMOUNT_EXCEEDS_MAXIMUM',
|
|
251
|
+
message: 'Amount exceeds maximum allowed ($1,000,000). Use the dashboard for larger transfers.',
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
// Vendor name validation: length limit and safe characters
|
|
255
|
+
if (typeof vendor !== 'string' || vendor.length === 0 || vendor.length > 200) {
|
|
256
|
+
return JSON.stringify({
|
|
257
|
+
success: false,
|
|
258
|
+
error: 'INVALID_VENDOR',
|
|
259
|
+
message: 'Vendor name must be 1-200 characters',
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
// Purpose validation: length limit
|
|
263
|
+
if (purpose !== undefined && (typeof purpose !== 'string' || purpose.length > 500)) {
|
|
264
|
+
return JSON.stringify({
|
|
265
|
+
success: false,
|
|
266
|
+
error: 'INVALID_PURPOSE',
|
|
267
|
+
message: 'Purpose must be a string of 500 characters or fewer',
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
// Vendor address validation: must be a valid hex address if provided
|
|
271
|
+
if (vendorAddress !== undefined) {
|
|
272
|
+
if (typeof vendorAddress !== 'string' || !/^0x[0-9a-fA-F]{40}$/.test(vendorAddress)) {
|
|
273
|
+
return JSON.stringify({
|
|
274
|
+
success: false,
|
|
275
|
+
error: 'INVALID_VENDOR_ADDRESS',
|
|
276
|
+
message: 'Vendor address must be a valid Ethereum address (0x followed by 40 hex characters)',
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
// Token validation
|
|
281
|
+
const validTokens = new Set(['USDC', 'USDT', 'PYUSD', 'EURC']);
|
|
282
|
+
if (!validTokens.has(token)) {
|
|
283
|
+
return JSON.stringify({
|
|
284
|
+
success: false,
|
|
285
|
+
error: 'INVALID_TOKEN',
|
|
286
|
+
message: `Token must be one of: ${[...validTokens].join(', ')}`,
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
try {
|
|
290
|
+
const mandateId = generateMandateId();
|
|
291
|
+
const timestamp = new Date().toISOString();
|
|
292
|
+
const amountMinor = Math.round(amount * 1_000_000).toString();
|
|
293
|
+
const auditData = JSON.stringify({
|
|
294
|
+
mandate_id: mandateId,
|
|
295
|
+
subject: walletId,
|
|
296
|
+
destination: vendorAddress || `pending:${vendor}`,
|
|
297
|
+
amount_minor: amountMinor,
|
|
298
|
+
token,
|
|
299
|
+
purpose: purpose || `Payment to ${vendor}`,
|
|
300
|
+
timestamp
|
|
301
|
+
});
|
|
302
|
+
const auditHash = await createAuditHash(auditData);
|
|
303
|
+
const mandate = {
|
|
304
|
+
mandate_id: mandateId,
|
|
305
|
+
subject: walletId,
|
|
306
|
+
destination: vendorAddress || `pending:${vendor}`,
|
|
307
|
+
amount_minor: amountMinor,
|
|
308
|
+
token,
|
|
309
|
+
chain,
|
|
310
|
+
purpose: purpose || `Payment to ${vendor}`,
|
|
311
|
+
vendor_name: vendor,
|
|
312
|
+
agent_id: agentId,
|
|
313
|
+
timestamp,
|
|
314
|
+
audit_hash: auditHash,
|
|
315
|
+
metadata: {
|
|
316
|
+
vendor,
|
|
317
|
+
category: 'saas',
|
|
318
|
+
initiated_by: 'ai_agent',
|
|
319
|
+
tool: 'openai_function_calling'
|
|
320
|
+
}
|
|
321
|
+
};
|
|
322
|
+
const result = await client.payments.executeMandate(mandate);
|
|
323
|
+
return JSON.stringify({
|
|
324
|
+
success: true,
|
|
325
|
+
status: result.status,
|
|
326
|
+
payment_id: result.payment_id,
|
|
327
|
+
transaction_hash: result.tx_hash,
|
|
328
|
+
chain: result.chain,
|
|
329
|
+
ledger_tx_id: result.ledger_tx_id,
|
|
330
|
+
audit_anchor: result.audit_anchor,
|
|
331
|
+
message: `Payment of $${amount} ${token} to ${vendor} ${result.status === 'completed' ? 'completed' : 'initiated'}.`
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
catch (error) {
|
|
335
|
+
const errorMessage = error instanceof Error ? error.message : 'Payment failed';
|
|
336
|
+
if (errorMessage.includes('policy') || errorMessage.includes('blocked') || errorMessage.includes('limit')) {
|
|
337
|
+
return JSON.stringify({
|
|
338
|
+
success: false,
|
|
339
|
+
blocked: true,
|
|
340
|
+
error: errorMessage,
|
|
341
|
+
message: `Payment to ${vendor} blocked by policy: ${errorMessage}`
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
return JSON.stringify({
|
|
345
|
+
success: false,
|
|
346
|
+
error: errorMessage
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
async function handleCheckBalance(client, args, options) {
|
|
351
|
+
const { walletId } = options;
|
|
352
|
+
if (!walletId) {
|
|
353
|
+
return JSON.stringify({
|
|
354
|
+
success: false,
|
|
355
|
+
error: 'No wallet ID configured'
|
|
356
|
+
});
|
|
357
|
+
}
|
|
358
|
+
const token = args.token || options.token;
|
|
359
|
+
const chain = args.chain || options.chain;
|
|
360
|
+
try {
|
|
361
|
+
const balance = await client.wallets.getBalance(walletId, chain, token);
|
|
362
|
+
return JSON.stringify({
|
|
363
|
+
success: true,
|
|
364
|
+
wallet_id: balance.wallet_id,
|
|
365
|
+
balance: balance.balance,
|
|
366
|
+
token: balance.token,
|
|
367
|
+
chain: balance.chain,
|
|
368
|
+
address: balance.address
|
|
369
|
+
});
|
|
370
|
+
}
|
|
371
|
+
catch (error) {
|
|
372
|
+
return JSON.stringify({
|
|
373
|
+
success: false,
|
|
374
|
+
error: error instanceof Error ? error.message : 'Failed to get balance'
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
async function handleGetWallet(client, walletId) {
|
|
379
|
+
if (!walletId) {
|
|
380
|
+
return JSON.stringify({
|
|
381
|
+
success: false,
|
|
382
|
+
error: 'No wallet ID configured'
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
try {
|
|
386
|
+
const wallet = await client.wallets.get(walletId);
|
|
387
|
+
return JSON.stringify({
|
|
388
|
+
success: true,
|
|
389
|
+
wallet: {
|
|
390
|
+
id: wallet.id,
|
|
391
|
+
agent_id: wallet.agent_id,
|
|
392
|
+
currency: wallet.currency,
|
|
393
|
+
limit_per_tx: wallet.limit_per_tx,
|
|
394
|
+
limit_total: wallet.limit_total,
|
|
395
|
+
is_active: wallet.is_active,
|
|
396
|
+
addresses: wallet.addresses
|
|
397
|
+
}
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
catch (error) {
|
|
401
|
+
return JSON.stringify({
|
|
402
|
+
success: false,
|
|
403
|
+
error: error instanceof Error ? error.message : 'Failed to get wallet'
|
|
404
|
+
});
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
async function handleCheckPolicy(client, args, walletId) {
|
|
408
|
+
if (!walletId) {
|
|
409
|
+
return JSON.stringify({
|
|
410
|
+
success: false,
|
|
411
|
+
error: 'No wallet ID configured'
|
|
412
|
+
});
|
|
413
|
+
}
|
|
414
|
+
const amount = args.amount;
|
|
415
|
+
const vendor = args.vendor;
|
|
416
|
+
try {
|
|
417
|
+
const wallet = await client.wallets.get(walletId);
|
|
418
|
+
const limitPerTx = parseFloat(wallet.limit_per_tx);
|
|
419
|
+
const checks = [];
|
|
420
|
+
if (amount <= limitPerTx) {
|
|
421
|
+
checks.push({ name: 'per_transaction_limit', passed: true });
|
|
422
|
+
}
|
|
423
|
+
else {
|
|
424
|
+
checks.push({
|
|
425
|
+
name: 'per_transaction_limit',
|
|
426
|
+
passed: false,
|
|
427
|
+
reason: `Amount $${amount} exceeds per-transaction limit of $${limitPerTx}`
|
|
428
|
+
});
|
|
429
|
+
}
|
|
430
|
+
if (wallet.is_active) {
|
|
431
|
+
checks.push({ name: 'wallet_active', passed: true });
|
|
432
|
+
}
|
|
433
|
+
else {
|
|
434
|
+
checks.push({
|
|
435
|
+
name: 'wallet_active',
|
|
436
|
+
passed: false,
|
|
437
|
+
reason: 'Wallet is not active'
|
|
438
|
+
});
|
|
439
|
+
}
|
|
440
|
+
const allPassed = checks.every(c => c.passed);
|
|
441
|
+
return JSON.stringify({
|
|
442
|
+
success: true,
|
|
443
|
+
allowed: allPassed,
|
|
444
|
+
checks,
|
|
445
|
+
summary: allPassed
|
|
446
|
+
? `Payment of $${amount} to ${vendor} would be allowed`
|
|
447
|
+
: `Payment of $${amount} to ${vendor} would be blocked: ${checks.filter(c => !c.passed).map(c => c.reason).join('; ')}`
|
|
448
|
+
});
|
|
449
|
+
}
|
|
450
|
+
catch (error) {
|
|
451
|
+
return JSON.stringify({
|
|
452
|
+
success: false,
|
|
453
|
+
error: error instanceof Error ? error.message : 'Failed to check policy'
|
|
454
|
+
});
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
/**
|
|
458
|
+
* Helper to create tool response message for OpenAI conversation
|
|
459
|
+
*/
|
|
460
|
+
export function createToolResponse(toolCallId, content) {
|
|
461
|
+
return {
|
|
462
|
+
role: 'tool',
|
|
463
|
+
tool_call_id: toolCallId,
|
|
464
|
+
content
|
|
465
|
+
};
|
|
466
|
+
}
|
|
467
|
+
//# sourceMappingURL=openai.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai.js","sourceRoot":"","sources":["../../src/integrations/openai.ts"],"names":[],"mappings":"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"}
|