@citrate/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.
@@ -0,0 +1,207 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ContractInstance = exports.ContractManager = void 0;
4
+ const ethers_1 = require("ethers");
5
+ class ContractManager {
6
+ constructor(rpcClient, config) {
7
+ this.rpcClient = rpcClient;
8
+ this.config = config;
9
+ }
10
+ /**
11
+ * Deploy a contract
12
+ */
13
+ async deploy(bytecode, abi, constructorArgs, value) {
14
+ const data = bytecode.startsWith('0x') ? bytecode : `0x${bytecode}`;
15
+ // If constructor args provided, encode them
16
+ let deployData = data;
17
+ if (abi && constructorArgs && constructorArgs.length > 0) {
18
+ const iface = new ethers_1.ethers.Interface(abi);
19
+ const constructor = abi.find(item => item.type === 'constructor');
20
+ if (constructor) {
21
+ const encoded = iface.encodeDeploy(constructorArgs);
22
+ deployData = ethers_1.ethers.concat([data, encoded]);
23
+ }
24
+ }
25
+ const response = await this.rpcCall('eth_sendTransaction', [{
26
+ from: this.config.defaultAccount,
27
+ data: deployData,
28
+ value: value || '0x0',
29
+ gas: `0x${(this.config.gasLimit || 3000000).toString(16)}`,
30
+ gasPrice: this.config.gasPrice || '0x3b9aca00' // 1 gwei
31
+ }]);
32
+ // Wait for transaction receipt
33
+ const receipt = await this.waitForReceipt(response);
34
+ if (!receipt.contractAddress) {
35
+ throw new Error('Contract deployment failed');
36
+ }
37
+ return receipt.contractAddress;
38
+ }
39
+ /**
40
+ * Call a contract method (transaction)
41
+ */
42
+ async call(address, abi, method, args = [], value) {
43
+ const iface = new ethers_1.ethers.Interface(abi);
44
+ const data = iface.encodeFunctionData(method, args);
45
+ const response = await this.rpcCall('eth_sendTransaction', [{
46
+ from: this.config.defaultAccount,
47
+ to: address,
48
+ data,
49
+ value: value || '0x0',
50
+ gas: `0x${(this.config.gasLimit || 100000).toString(16)}`,
51
+ gasPrice: this.config.gasPrice || '0x3b9aca00'
52
+ }]);
53
+ const receipt = await this.waitForReceipt(response);
54
+ // Decode logs if any
55
+ const logs = receipt.logs.map((log) => {
56
+ try {
57
+ return iface.parseLog({
58
+ topics: log.topics,
59
+ data: log.data
60
+ });
61
+ }
62
+ catch {
63
+ return log;
64
+ }
65
+ });
66
+ return { receipt, logs };
67
+ }
68
+ /**
69
+ * Read contract state (call without transaction)
70
+ */
71
+ async read(address, abi, method, args = []) {
72
+ const iface = new ethers_1.ethers.Interface(abi);
73
+ const data = iface.encodeFunctionData(method, args);
74
+ const response = await this.rpcCall('eth_call', [{
75
+ to: address,
76
+ data
77
+ }, 'latest']);
78
+ // Decode the result
79
+ const result = iface.decodeFunctionResult(method, response);
80
+ // If single return value, return it directly
81
+ if (result.length === 1) {
82
+ return result[0];
83
+ }
84
+ return result;
85
+ }
86
+ /**
87
+ * Get contract code
88
+ */
89
+ async getCode(address) {
90
+ return await this.rpcCall('eth_getCode', [address, 'latest']);
91
+ }
92
+ /**
93
+ * Get contract info
94
+ */
95
+ async getContractInfo(address) {
96
+ const code = await this.getCode(address);
97
+ return {
98
+ address,
99
+ bytecode: code,
100
+ verified: false // Would check verification status
101
+ };
102
+ }
103
+ /**
104
+ * Verify contract source code
105
+ */
106
+ async verify(address, sourceCode, compilerVersion, optimizationEnabled = false) {
107
+ const response = await this.rpcCall('citrate_verifyContract', [{
108
+ address,
109
+ source_code: sourceCode,
110
+ compiler_version: compilerVersion,
111
+ optimization_enabled: optimizationEnabled
112
+ }]);
113
+ return response.verification_id;
114
+ }
115
+ /**
116
+ * Create contract instance with ABI
117
+ */
118
+ createInstance(address, abi) {
119
+ return new ContractInstance(address, abi, this);
120
+ }
121
+ async waitForReceipt(txHash) {
122
+ let receipt = null;
123
+ let attempts = 0;
124
+ while (!receipt && attempts < 30) {
125
+ attempts++;
126
+ await new Promise(resolve => setTimeout(resolve, 2000));
127
+ try {
128
+ receipt = await this.rpcCall('eth_getTransactionReceipt', [txHash]);
129
+ }
130
+ catch {
131
+ // Not yet mined
132
+ }
133
+ }
134
+ if (!receipt) {
135
+ throw new Error('Transaction timeout');
136
+ }
137
+ if (receipt.status === '0x0') {
138
+ throw new Error('Transaction failed');
139
+ }
140
+ return receipt;
141
+ }
142
+ async rpcCall(method, params) {
143
+ const response = await this.rpcClient.post('', {
144
+ jsonrpc: '2.0',
145
+ method,
146
+ params,
147
+ id: Date.now()
148
+ });
149
+ if (response.data.error) {
150
+ throw new Error(response.data.error.message);
151
+ }
152
+ return response.data.result;
153
+ }
154
+ }
155
+ exports.ContractManager = ContractManager;
156
+ /**
157
+ * Contract instance helper class
158
+ */
159
+ class ContractInstance {
160
+ constructor(address, abi, manager) {
161
+ this.address = address;
162
+ this.abi = abi;
163
+ this.manager = manager;
164
+ this.iface = new ethers_1.ethers.Interface(abi);
165
+ }
166
+ /**
167
+ * Call a method (transaction)
168
+ */
169
+ async send(method, args = [], value) {
170
+ return this.manager.call(this.address, this.abi, method, args, value);
171
+ }
172
+ /**
173
+ * Read state (no transaction)
174
+ */
175
+ async call(method, args = []) {
176
+ return this.manager.read(this.address, this.abi, method, args);
177
+ }
178
+ /**
179
+ * Encode method call data
180
+ */
181
+ encodeCall(method, args = []) {
182
+ return this.iface.encodeFunctionData(method, args);
183
+ }
184
+ /**
185
+ * Decode method result
186
+ */
187
+ decodeResult(method, data) {
188
+ return this.iface.decodeFunctionResult(method, data);
189
+ }
190
+ /**
191
+ * Parse event logs
192
+ */
193
+ parseLogs(logs) {
194
+ return logs.map(log => {
195
+ try {
196
+ return this.iface.parseLog({
197
+ topics: log.topics,
198
+ data: log.data
199
+ });
200
+ }
201
+ catch {
202
+ return log;
203
+ }
204
+ });
205
+ }
206
+ }
207
+ exports.ContractInstance = ContractInstance;
@@ -0,0 +1,5 @@
1
+ export { CitrateSDK } from './sdk';
2
+ export { ModelRegistry } from './model';
3
+ export { ContractManager } from './contract';
4
+ export { AccountManager } from './account';
5
+ export * from './types';
@@ -0,0 +1,13 @@
1
+ Object.defineProperty(exports, "__esModule", { value: true });
2
+ exports.AccountManager = exports.ContractManager = exports.ModelRegistry = exports.CitrateSDK = void 0;
3
+ const tslib_1 = require("tslib");
4
+ var sdk_1 = require("./sdk");
5
+ Object.defineProperty(exports, "CitrateSDK", { enumerable: true, get: function () { return sdk_1.CitrateSDK; } });
6
+ var model_1 = require("./model");
7
+ Object.defineProperty(exports, "ModelRegistry", { enumerable: true, get: function () { return model_1.ModelRegistry; } });
8
+ var contract_1 = require("./contract");
9
+ Object.defineProperty(exports, "ContractManager", { enumerable: true, get: function () { return contract_1.ContractManager; } });
10
+ var account_1 = require("./account");
11
+ Object.defineProperty(exports, "AccountManager", { enumerable: true, get: function () { return account_1.AccountManager; } });
12
+ tslib_1.__exportStar(require("./types"), exports);
13
+ //# sourceMappingURL=index.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.esm.js","sources":["../src/index.ts"],"sourcesContent":["export { CitrateSDK } from './sdk';\nexport { ModelRegistry } from './model';\nexport { ContractManager } from './contract';\nexport { AccountManager } from './account';\nexport * from './types';"],"names":[],"mappings":";;;AAAA,IAAA,KAAA,GAAA,OAAA,CAAA,OAAA,CAAA;AAAS,MAAA,CAAA,cAAA,CAAA,OAAA,EAAA,YAAA,EAAA,EAAA,UAAA,EAAA,IAAA,EAAA,GAAA,EAAA,YAAA,EAAA,OAAA,KAAA,CAAA,UAAU,CAAA,CAAA,CAAA,EAAA,CAAA;AACnB,IAAA,OAAA,GAAA,OAAA,CAAA,SAAA,CAAA;AAAS,MAAA,CAAA,cAAA,CAAA,OAAA,EAAA,eAAA,EAAA,EAAA,UAAA,EAAA,IAAA,EAAA,GAAA,EAAA,YAAA,EAAA,OAAA,OAAA,CAAA,aAAa,CAAA,CAAA,CAAA,EAAA,CAAA;AACtB,IAAA,UAAA,GAAA,OAAA,CAAA,YAAA,CAAA;AAAS,MAAA,CAAA,cAAA,CAAA,OAAA,EAAA,iBAAA,EAAA,EAAA,UAAA,EAAA,IAAA,EAAA,GAAA,EAAA,YAAA,EAAA,OAAA,UAAA,CAAA,eAAe,CAAA,CAAA,CAAA,EAAA,CAAA;AACxB,IAAA,SAAA,GAAA,OAAA,CAAA,WAAA,CAAA;AAAS,MAAA,CAAA,cAAA,CAAA,OAAA,EAAA,gBAAA,EAAA,EAAA,UAAA,EAAA,IAAA,EAAA,GAAA,EAAA,YAAA,EAAA,OAAA,SAAA,CAAA,cAAc,CAAA,CAAA,CAAA,EAAA,CAAA;AACvB,OAAA,CAAA,YAAA,CAAA,OAAA,CAAA,SAAA,CAAA,EAAA,OAAA,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,15 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.AccountManager = exports.ContractManager = exports.ModelRegistry = exports.CitrateSDK = void 0;
5
+ const tslib_1 = require("tslib");
6
+ var sdk_1 = require("./sdk");
7
+ Object.defineProperty(exports, "CitrateSDK", { enumerable: true, get: function () { return sdk_1.CitrateSDK; } });
8
+ var model_1 = require("./model");
9
+ Object.defineProperty(exports, "ModelRegistry", { enumerable: true, get: function () { return model_1.ModelRegistry; } });
10
+ var contract_1 = require("./contract");
11
+ Object.defineProperty(exports, "ContractManager", { enumerable: true, get: function () { return contract_1.ContractManager; } });
12
+ var account_1 = require("./account");
13
+ Object.defineProperty(exports, "AccountManager", { enumerable: true, get: function () { return account_1.AccountManager; } });
14
+ tslib_1.__exportStar(require("./types"), exports);
15
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["export { CitrateSDK } from './sdk';\nexport { ModelRegistry } from './model';\nexport { ContractManager } from './contract';\nexport { AccountManager } from './account';\nexport * from './types';"],"names":[],"mappings":";;;;;AAAA,IAAA,KAAA,GAAA,OAAA,CAAA,OAAA,CAAA;AAAS,MAAA,CAAA,cAAA,CAAA,OAAA,EAAA,YAAA,EAAA,EAAA,UAAA,EAAA,IAAA,EAAA,GAAA,EAAA,YAAA,EAAA,OAAA,KAAA,CAAA,UAAU,CAAA,CAAA,CAAA,EAAA,CAAA;AACnB,IAAA,OAAA,GAAA,OAAA,CAAA,SAAA,CAAA;AAAS,MAAA,CAAA,cAAA,CAAA,OAAA,EAAA,eAAA,EAAA,EAAA,UAAA,EAAA,IAAA,EAAA,GAAA,EAAA,YAAA,EAAA,OAAA,OAAA,CAAA,aAAa,CAAA,CAAA,CAAA,EAAA,CAAA;AACtB,IAAA,UAAA,GAAA,OAAA,CAAA,YAAA,CAAA;AAAS,MAAA,CAAA,cAAA,CAAA,OAAA,EAAA,iBAAA,EAAA,EAAA,UAAA,EAAA,IAAA,EAAA,GAAA,EAAA,YAAA,EAAA,OAAA,UAAA,CAAA,eAAe,CAAA,CAAA,CAAA,EAAA,CAAA;AACxB,IAAA,SAAA,GAAA,OAAA,CAAA,WAAA,CAAA;AAAS,MAAA,CAAA,cAAA,CAAA,OAAA,EAAA,gBAAA,EAAA,EAAA,UAAA,EAAA,IAAA,EAAA,GAAA,EAAA,YAAA,EAAA,OAAA,SAAA,CAAA,cAAc,CAAA,CAAA,CAAA,EAAA,CAAA;AACvB,OAAA,CAAA,YAAA,CAAA,OAAA,CAAA,SAAA,CAAA,EAAA,OAAA,CAAA;;"}
@@ -0,0 +1,38 @@
1
+ import { AxiosInstance } from 'axios';
2
+ import { CitrateConfig, ModelMetadata, ModelInfo, InferenceResult } from './types';
3
+ export declare class ModelRegistry {
4
+ private rpcClient;
5
+ private config;
6
+ constructor(rpcClient: AxiosInstance, config: CitrateConfig);
7
+ /**
8
+ * Deploy a model to the network
9
+ */
10
+ deploy(modelData: Buffer | Uint8Array, metadata: ModelMetadata): Promise<string>;
11
+ /**
12
+ * Run inference on a model
13
+ */
14
+ runInference(modelId: string, input: any, options?: {
15
+ withProof?: boolean;
16
+ timeout?: number;
17
+ }): Promise<InferenceResult>;
18
+ /**
19
+ * Get model information
20
+ */
21
+ getModel(modelId: string): Promise<ModelInfo>;
22
+ /**
23
+ * List models
24
+ */
25
+ listModels(options?: {
26
+ owner?: string;
27
+ type?: string;
28
+ limit?: number;
29
+ offset?: number;
30
+ }): Promise<ModelInfo[]>;
31
+ /**
32
+ * Update model metadata
33
+ */
34
+ updateMetadata(modelId: string, metadata: Partial<ModelMetadata>): Promise<void>;
35
+ grantPermission(): Promise<never>;
36
+ revokePermission(): Promise<never>;
37
+ private rpcCall;
38
+ }
package/dist/model.js ADDED
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ModelRegistry = void 0;
4
+ class ModelRegistry {
5
+ constructor(rpcClient, config) {
6
+ this.rpcClient = rpcClient;
7
+ this.config = config;
8
+ }
9
+ /**
10
+ * Deploy a model to the network
11
+ */
12
+ async deploy(modelData, metadata) {
13
+ const base64Data = Buffer.from(modelData).toString('base64');
14
+ const response = await this.rpcCall('citrate_deployModel', {
15
+ from: this.config.defaultAccount,
16
+ model_data: base64Data,
17
+ metadata,
18
+ gas_price: this.config.gasPrice,
19
+ gas_limit: this.config.gasLimit
20
+ });
21
+ return response.model_id;
22
+ }
23
+ /**
24
+ * Run inference on a model
25
+ */
26
+ async runInference(modelId, input, options) {
27
+ const response = await this.rpcCall('citrate_runInference', {
28
+ model_id: modelId,
29
+ input,
30
+ with_proof: options?.withProof || false,
31
+ timeout: options?.timeout
32
+ });
33
+ return {
34
+ output: response.output,
35
+ executionTime: response.execution_time_ms,
36
+ proofId: response.proof,
37
+ gasUsed: response.gas_used
38
+ };
39
+ }
40
+ /**
41
+ * Get model information
42
+ */
43
+ async getModel(modelId) {
44
+ const response = await this.rpcCall('citrate_getModel', {
45
+ model_id: modelId
46
+ });
47
+ return response.model;
48
+ }
49
+ /**
50
+ * List models
51
+ */
52
+ async listModels(options) {
53
+ // RPC expects positional params: (owner, limit)
54
+ const response = await this.rpcCall('citrate_listModels', [
55
+ options?.owner || null,
56
+ options?.limit || null,
57
+ ]);
58
+ return response.models;
59
+ }
60
+ /**
61
+ * Update model metadata
62
+ */
63
+ async updateMetadata(modelId, metadata) {
64
+ await this.rpcCall('citrate_updateModel', {
65
+ model_id: modelId,
66
+ metadata,
67
+ from: this.config.defaultAccount
68
+ });
69
+ }
70
+ // The following permission endpoints are not yet available on the RPC server.
71
+ // Keep stubs that throw to avoid silent failures if called.
72
+ async grantPermission() {
73
+ throw new Error('Not implemented: model permission RPCs are not available yet');
74
+ }
75
+ async revokePermission() {
76
+ throw new Error('Not implemented: model permission RPCs are not available yet');
77
+ }
78
+ async rpcCall(method, params) {
79
+ const response = await this.rpcClient.post('', {
80
+ jsonrpc: '2.0',
81
+ method,
82
+ params,
83
+ id: Date.now()
84
+ });
85
+ if (response.data.error) {
86
+ throw new Error(response.data.error.message);
87
+ }
88
+ return response.data.result;
89
+ }
90
+ }
91
+ exports.ModelRegistry = ModelRegistry;
package/dist/sdk.d.ts ADDED
@@ -0,0 +1,86 @@
1
+ import { EventEmitter } from 'events';
2
+ import { ModelRegistry } from './model';
3
+ import { ContractManager } from './contract';
4
+ import { AccountManager } from './account';
5
+ import { CitrateConfig, NetworkInfo, BlockInfo, ArtifactProviderStatus, ArtifactPinResult } from './types';
6
+ /**
7
+ * Main Citrate SDK class
8
+ */
9
+ export declare class CitrateSDK extends EventEmitter {
10
+ private rpcClient;
11
+ private config;
12
+ models: ModelRegistry;
13
+ contracts: ContractManager;
14
+ accounts: AccountManager;
15
+ constructor(config: CitrateConfig);
16
+ /**
17
+ * Deploy a model to the network
18
+ */
19
+ deployModel(modelData: Buffer | Uint8Array, metadata: {
20
+ name: string;
21
+ version: string;
22
+ format: string;
23
+ description?: string;
24
+ }): Promise<string>;
25
+ /**
26
+ * Run inference on a deployed model
27
+ */
28
+ runInference(modelId: string, input: any, options?: {
29
+ withProof?: boolean;
30
+ timeout?: number;
31
+ }): Promise<{
32
+ output: any;
33
+ executionTime: number;
34
+ proofId?: string;
35
+ }>;
36
+ /**
37
+ * Get proof for an execution
38
+ */
39
+ getProof(executionId: string): Promise<any>;
40
+ /**
41
+ * Verify a proof
42
+ */
43
+ verifyProof(proof: any, expectedOutput?: string): Promise<boolean>;
44
+ pinArtifact(cid: string, replicas?: number): Promise<ArtifactPinResult>;
45
+ getArtifactStatus(cid: string): Promise<ArtifactProviderStatus[]>;
46
+ listModelArtifacts(modelIdHex: string): Promise<string[]>;
47
+ /**
48
+ * Get network information
49
+ */
50
+ getNetworkInfo(): Promise<NetworkInfo>;
51
+ /**
52
+ * Get block information
53
+ */
54
+ getBlock(blockNumber: number | 'latest'): Promise<BlockInfo>;
55
+ /**
56
+ * Get DAG statistics
57
+ */
58
+ getDagStats(): Promise<{
59
+ totalBlocks: number;
60
+ blueBlocks: number;
61
+ redBlocks: number;
62
+ tipsCount: number;
63
+ maxBlueScore: number;
64
+ currentTips: string[];
65
+ height: number;
66
+ ghostdagParams: {
67
+ k: number;
68
+ maxParents: number;
69
+ maxBlueScoreDiff: number;
70
+ pruningWindow: number;
71
+ finalityDepth: number;
72
+ };
73
+ }>;
74
+ /**
75
+ * Subscribe to new blocks
76
+ */
77
+ subscribeToBlocks(callback: (block: BlockInfo) => void): () => void;
78
+ /**
79
+ * Make an RPC call
80
+ */
81
+ rpcCall(method: string, params?: any): Promise<any>;
82
+ /**
83
+ * Wait for a transaction to be mined
84
+ */
85
+ waitForTransaction(txHash: string, confirmations?: number): Promise<any>;
86
+ }