hearn-oracle-sdk 1.0.3 → 1.0.4

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/index.d.ts CHANGED
@@ -15,7 +15,7 @@ export declare class OracleClient {
15
15
  getPriceByType(assetType: string, clockId?: string): Promise<bigint>;
16
16
  /**
17
17
  * Batch query feed object ids for multiple asset types in a single devInspect.
18
- * Returns a map from assetType -> { priceObjectId, aggregatorId }.
18
+ * Returns a map from assetType -> { priceObjectId, aggregatorId? }.
19
19
  */
20
20
  private getFeedObjectIdsByTypes;
21
21
  /**
@@ -26,8 +26,9 @@ export declare class OracleClient {
26
26
  */
27
27
  getPricesByTypes(assetTypes: string[], clockId?: string): Promise<bigint[]>;
28
28
  /**
29
- * Update prices for multiple assets by calling adaptor_oracle::update_price in a loop.
30
- * This builds a transaction that updates multiple assets' prices.
29
+ * Update prices for multiple assets by calling:
30
+ * - `adaptor_pyth::update_price`
31
+ * - `adaptor_switchboard::update_price` (only when a Switchboard feed is configured)
31
32
  * @param assetTypes Array of asset types (e.g. '0x2::sui::SUI')
32
33
  * @param clockId The ID of the Clock object
33
34
  * @returns A Promise that resolves to a TransactionBlock that can be signed and executed
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAgCvD,qBAAa,YAAY;IACrB,OAAO,CAAC,QAAQ,CAAY;IAC5B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,QAAQ,CAAS;IAGzB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAS;gBAErC,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;IAMpE;;;;;OAKG;IACG,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,GAAE,MAAsC,GAAG,OAAO,CAAC,MAAM,CAAC;IA2BzG;;;OAGG;YACW,uBAAuB;IAoDrC;;;;;OAKG;IACG,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,OAAO,GAAE,MAAsC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAKhH;;;;;;OAMG;IACG,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;CAoBlF"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAgCvD,qBAAa,YAAY;IACrB,OAAO,CAAC,QAAQ,CAAY;IAC5B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,QAAQ,CAAS;IAGzB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAS;gBAErC,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;IAMpE;;;;;OAKG;IACG,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,GAAE,MAAsC,GAAG,OAAO,CAAC,MAAM,CAAC;IA8CzG;;;OAGG;YACW,uBAAuB;IAqErC;;;;;OAKG;IACG,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,OAAO,GAAE,MAAsC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAKhH;;;;;;;OAOG;IACG,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;CA2BlF"}
package/dist/index.js CHANGED
@@ -51,12 +51,28 @@ class OracleClient {
51
51
  transactionBlock: tx,
52
52
  sender: '0x0000000000000000000000000000000000000000000000000000000000000000', // dummy sender for read-only
53
53
  });
54
- if (!result.results || result.results.length === 0) {
55
- throw new Error('No results from transaction inspection');
54
+ // devInspect can "succeed" at the RPC layer but still abort in Move; in that case
55
+ // `results` is often empty and the reason is only present in `error`/`effects.status`.
56
+ const status = result?.effects?.status;
57
+ const statusKind = status?.status ?? status?.kind;
58
+ const statusError = status?.error;
59
+ if (result?.error || statusKind === 'failure' || statusError) {
60
+ const msg = [
61
+ `devInspect failed for price_by_type<${assetType}>`,
62
+ result?.error ? `rpcError=${String(result.error)}` : undefined,
63
+ statusKind ? `status=${String(statusKind)}` : undefined,
64
+ statusError ? `moveError=${String(statusError)}` : undefined,
65
+ ]
66
+ .filter(Boolean)
67
+ .join(' | ');
68
+ throw new Error(msg);
69
+ }
70
+ if (!result?.results || result.results.length === 0) {
71
+ throw new Error(`No results from transaction inspection for price_by_type<${assetType}> (check oracleId/clockId and feed config)`);
56
72
  }
57
73
  const returnValue = result.results[0].returnValues?.[0];
58
74
  if (!returnValue) {
59
- throw new Error('No return value from price_by_type');
75
+ throw new Error(`No return value from price_by_type<${assetType}>`);
60
76
  }
61
77
  // Return is BCS-encoded u128 (little-endian). Parse via BCS.
62
78
  const priceU128Str = bcs_1.bcs.u128().parse(new Uint8Array(returnValue[0]));
@@ -64,7 +80,7 @@ class OracleClient {
64
80
  }
65
81
  /**
66
82
  * Batch query feed object ids for multiple asset types in a single devInspect.
67
- * Returns a map from assetType -> { priceObjectId, aggregatorId }.
83
+ * Returns a map from assetType -> { priceObjectId, aggregatorId? }.
68
84
  */
69
85
  async getFeedObjectIdsByTypes(assetTypes) {
70
86
  const queryTx = new transactions_1.Transaction();
@@ -83,6 +99,20 @@ class OracleClient {
83
99
  transactionBlock: queryTx,
84
100
  sender: '0x0000000000000000000000000000000000000000000000000000000000000000',
85
101
  });
102
+ const qStatus = queryResult?.effects?.status;
103
+ const qStatusKind = qStatus?.status ?? qStatus?.kind;
104
+ const qStatusError = qStatus?.error;
105
+ if (queryResult?.error || qStatusKind === 'failure' || qStatusError) {
106
+ const msg = [
107
+ `devInspect failed for get_feed_object_addresses_batch`,
108
+ queryResult?.error ? `rpcError=${String(queryResult.error)}` : undefined,
109
+ qStatusKind ? `status=${String(qStatusKind)}` : undefined,
110
+ qStatusError ? `moveError=${String(qStatusError)}` : undefined,
111
+ ]
112
+ .filter(Boolean)
113
+ .join(' | ');
114
+ throw new Error(msg);
115
+ }
86
116
  if (!queryResult.results || queryResult.results.length !== 1) {
87
117
  throw new Error(`Unexpected results length from get_feed_object_addresses_batch: ${queryResult.results?.length ?? 0}`);
88
118
  }
@@ -99,9 +129,11 @@ class OracleClient {
99
129
  const out = {};
100
130
  for (let i = 0; i < assetTypes.length; i++) {
101
131
  const assetType = assetTypes[i];
132
+ const sbBytes = Buffer.from(sbAddrBytesVec[i]);
133
+ const sbIsZero = sbBytes.equals(Buffer.alloc(32));
102
134
  out[assetType] = {
103
135
  priceObjectId: '0x' + Buffer.from(pythAddrBytesVec[i]).toString('hex'),
104
- aggregatorId: '0x' + Buffer.from(sbAddrBytesVec[i]).toString('hex'),
136
+ aggregatorId: sbIsZero ? undefined : '0x' + sbBytes.toString('hex'),
105
137
  };
106
138
  }
107
139
  return out;
@@ -117,8 +149,9 @@ class OracleClient {
117
149
  return Promise.all(promises);
118
150
  }
119
151
  /**
120
- * Update prices for multiple assets by calling adaptor_oracle::update_price in a loop.
121
- * This builds a transaction that updates multiple assets' prices.
152
+ * Update prices for multiple assets by calling:
153
+ * - `adaptor_pyth::update_price`
154
+ * - `adaptor_switchboard::update_price` (only when a Switchboard feed is configured)
122
155
  * @param assetTypes Array of asset types (e.g. '0x2::sui::SUI')
123
156
  * @param clockId The ID of the Clock object
124
157
  * @returns A Promise that resolves to a TransactionBlock that can be signed and executed
@@ -131,15 +164,21 @@ class OracleClient {
131
164
  // NOTE: caller guarantees `assetTypes` has no duplicates and order does not matter.
132
165
  for (const [assetType, ids] of Object.entries(feedObjectIdsByType)) {
133
166
  tx.moveCall({
134
- target: `${this.packageId}::adaptor_oracle::update_price`,
167
+ target: `${this.packageId}::adaptor_pyth::update_price`,
135
168
  typeArguments: [assetType],
136
169
  arguments: [
137
170
  tx.object(this.oracleId),
138
171
  tx.object(ids.priceObjectId),
139
- tx.object(ids.aggregatorId),
140
172
  tx.object(clockId),
141
173
  ],
142
174
  });
175
+ if (ids.aggregatorId) {
176
+ tx.moveCall({
177
+ target: `${this.packageId}::adaptor_switchboard::update_price`,
178
+ typeArguments: [assetType],
179
+ arguments: [tx.object(this.oracleId), tx.object(ids.aggregatorId)],
180
+ });
181
+ }
143
182
  }
144
183
  return tx;
145
184
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,12 +1,9 @@
1
1
  {
2
2
  "name": "hearn-oracle-sdk",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "description": "SDK for interacting with Hearn Oracle on Sui blockchain",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
- "files": [
8
- "dist"
9
- ],
10
7
  "scripts": {
11
8
  "build": "tsc",
12
9
  "dev": "tsc --watch"
package/src/example.ts ADDED
@@ -0,0 +1,57 @@
1
+ // Example usage of Hearn Oracle SDK
2
+ // This file demonstrates how to use the OracleClient in a frontend application
3
+
4
+ import { SuiClient } from '@mysten/sui/client';
5
+ import { OracleClient } from './index'; // or 'hearn-oracle-sdk' if installed
6
+
7
+ async function main() {
8
+ // Initialize Sui client
9
+ const provider = new SuiClient({
10
+ url: 'https://fullnode.mainnet.sui.io:443'
11
+ });
12
+
13
+ // These IDs should come from your deployment
14
+ const packageId = '0x...'; // Replace with actual deployed package ID
15
+ const oracleId = '0x...'; // Replace with actual oracle object ID
16
+
17
+ // Create OracleClient instance
18
+ const oracleClient = new OracleClient(provider, packageId, oracleId);
19
+
20
+ try {
21
+ // Example 1: Get price for SUI
22
+ console.log('Fetching SUI price...');
23
+ const suiPrice = await oracleClient.getPriceByType('0x2::sui::SUI');
24
+ console.log('SUI Price:', suiPrice);
25
+
26
+ // Example 2: Get prices for multiple assets
27
+ console.log('Fetching multiple prices...');
28
+ const assetTypes = [
29
+ '0x2::sui::SUI',
30
+ // Add more asset types as needed
31
+ // '0x...::btc::BTC',
32
+ // '0x...::eth::ETH'
33
+ ];
34
+ const prices = await oracleClient.getPricesByTypes(assetTypes);
35
+ console.log('Prices:', prices);
36
+
37
+ // Example 3: Update prices for multiple assets
38
+ console.log('Building transaction to update prices...');
39
+ const clockId = '0x6'; // Standard Clock object ID in Sui
40
+ const updateTx = await oracleClient.updatePrices(assetTypes, clockId);
41
+ console.log('Update transaction built:', updateTx);
42
+
43
+ // To execute the transaction, you need a signer:
44
+ // const signer = ...; // Your wallet signer
45
+ // const result = await signer.signAndExecuteTransactionBlock({
46
+ // transactionBlock: updateTx,
47
+ // });
48
+ // console.log('Update result:', result);
49
+
50
+ // Example 4: Handle errors
51
+ } catch (error) {
52
+ console.error('Error:', error);
53
+ }
54
+ }
55
+
56
+ // Run the example
57
+ main();
package/src/index.ts ADDED
@@ -0,0 +1,219 @@
1
+ import { SuiClient } from '@mysten/sui/client';
2
+ import { Transaction } from '@mysten/sui/transactions';
3
+ import { bcs } from '@mysten/bcs';
4
+
5
+ // BCS schema for `std::type_name::TypeName` used by the Move contract.
6
+ // In Sui Move stdlib, `TypeName` is:
7
+ // struct TypeName { name: std::ascii::String }
8
+ // and `std::ascii::String` is:
9
+ // struct String { bytes: vector<u8> }
10
+ const AsciiStringBcs = bcs.struct('AsciiString', {
11
+ bytes: bcs.vector(bcs.u8()),
12
+ });
13
+
14
+ const TypeNameBcs = bcs.struct('TypeName', {
15
+ name: AsciiStringBcs,
16
+ });
17
+
18
+ // Convert a Move type tag string into the exact `std::type_name::TypeName.name` format.
19
+ // Move stdlib encodes addresses as lowercase hex WITHOUT 0x and padded to 32 bytes (64 hex chars).
20
+ function normalizeTypeNameString(typeTag: string): string {
21
+ const sep = '::';
22
+ const idx = typeTag.indexOf(sep);
23
+ if (idx < 0) {
24
+ throw new Error(`Invalid type tag (missing '::'): ${typeTag}`);
25
+ }
26
+
27
+ const addrPart = typeTag.slice(0, idx);
28
+ const rest = typeTag.slice(idx + sep.length);
29
+ const hex = (addrPart.startsWith('0x') ? addrPart.slice(2) : addrPart).toLowerCase();
30
+ const padded = hex.padStart(64, '0');
31
+ return `${padded}${sep}${rest}`;
32
+ }
33
+
34
+ export class OracleClient {
35
+ private provider: SuiClient;
36
+ private packageId: string;
37
+ private oracleId: string;
38
+ // Sui system Clock shared object id.
39
+ // See: `0x2::clock::Clock` (typically `0x6` on Sui networks).
40
+ private static readonly DEFAULT_CLOCK_ID = '0x6';
41
+
42
+ constructor(provider: SuiClient, packageId: string, oracleId: string) {
43
+ this.provider = provider;
44
+ this.packageId = packageId;
45
+ this.oracleId = oracleId;
46
+ }
47
+
48
+ /**
49
+ * Get the price of a single asset by its type.
50
+ * @param assetType The type of the asset, e.g., '0x2::sui::SUI'
51
+ * @param clockId The ID of the Clock object (defaults to 0x6)
52
+ * @returns The price as a bigint in WAD (1e18) precision.
53
+ */
54
+ async getPriceByType(assetType: string, clockId: string = OracleClient.DEFAULT_CLOCK_ID): Promise<bigint> {
55
+ const tx = new Transaction();
56
+ tx.moveCall({
57
+ target: `${this.packageId}::pyth_oracle::price_by_type`,
58
+ typeArguments: [assetType],
59
+ arguments: [tx.object(this.oracleId), tx.object(clockId)],
60
+ });
61
+
62
+ const result: any = await this.provider.devInspectTransactionBlock({
63
+ transactionBlock: tx,
64
+ sender: '0x0000000000000000000000000000000000000000000000000000000000000000', // dummy sender for read-only
65
+ });
66
+
67
+ // devInspect can "succeed" at the RPC layer but still abort in Move; in that case
68
+ // `results` is often empty and the reason is only present in `error`/`effects.status`.
69
+ const status = result?.effects?.status;
70
+ const statusKind: string | undefined = status?.status ?? status?.kind;
71
+ const statusError: string | undefined = status?.error;
72
+ if (result?.error || statusKind === 'failure' || statusError) {
73
+ const msg = [
74
+ `devInspect failed for price_by_type<${assetType}>`,
75
+ result?.error ? `rpcError=${String(result.error)}` : undefined,
76
+ statusKind ? `status=${String(statusKind)}` : undefined,
77
+ statusError ? `moveError=${String(statusError)}` : undefined,
78
+ ]
79
+ .filter(Boolean)
80
+ .join(' | ');
81
+ throw new Error(msg);
82
+ }
83
+
84
+ if (!result?.results || result.results.length === 0) {
85
+ throw new Error(
86
+ `No results from transaction inspection for price_by_type<${assetType}> (check oracleId/clockId and feed config)`,
87
+ );
88
+ }
89
+
90
+ const returnValue = result.results[0].returnValues?.[0];
91
+ if (!returnValue) {
92
+ throw new Error(`No return value from price_by_type<${assetType}>`);
93
+ }
94
+
95
+ // Return is BCS-encoded u128 (little-endian). Parse via BCS.
96
+ const priceU128Str = bcs.u128().parse(new Uint8Array(returnValue[0] as any));
97
+ return BigInt(priceU128Str);
98
+ }
99
+
100
+ /**
101
+ * Batch query feed object ids for multiple asset types in a single devInspect.
102
+ * Returns a map from assetType -> { priceObjectId, aggregatorId? }.
103
+ */
104
+ private async getFeedObjectIdsByTypes(
105
+ assetTypes: string[],
106
+ ): Promise<Record<string, { priceObjectId: string; aggregatorId?: string }>> {
107
+ const queryTx = new Transaction();
108
+ const typeNames = assetTypes.map((assetType) => {
109
+ // `get_feed_object_addresses_batch` expects `vector<std::type_name::TypeName>`.
110
+ // We encode TypeName as { name: { bytes } } where bytes are ASCII bytes of the normalized type string.
111
+ const normalized = normalizeTypeNameString(assetType);
112
+ const bytes = Array.from(Buffer.from(normalized, 'ascii'));
113
+ return { name: { bytes } };
114
+ });
115
+
116
+ queryTx.moveCall({
117
+ target: `${this.packageId}::pyth_oracle::get_feed_object_addresses_batch`,
118
+ arguments: [queryTx.object(this.oracleId), queryTx.pure(bcs.vector(TypeNameBcs).serialize(typeNames))],
119
+ });
120
+
121
+ const queryResult: any = await this.provider.devInspectTransactionBlock({
122
+ transactionBlock: queryTx,
123
+ sender: '0x0000000000000000000000000000000000000000000000000000000000000000',
124
+ });
125
+
126
+ const qStatus = queryResult?.effects?.status;
127
+ const qStatusKind: string | undefined = qStatus?.status ?? qStatus?.kind;
128
+ const qStatusError: string | undefined = qStatus?.error;
129
+ if (queryResult?.error || qStatusKind === 'failure' || qStatusError) {
130
+ const msg = [
131
+ `devInspect failed for get_feed_object_addresses_batch`,
132
+ queryResult?.error ? `rpcError=${String(queryResult.error)}` : undefined,
133
+ qStatusKind ? `status=${String(qStatusKind)}` : undefined,
134
+ qStatusError ? `moveError=${String(qStatusError)}` : undefined,
135
+ ]
136
+ .filter(Boolean)
137
+ .join(' | ');
138
+ throw new Error(msg);
139
+ }
140
+
141
+ if (!queryResult.results || queryResult.results.length !== 1) {
142
+ throw new Error(`Unexpected results length from get_feed_object_addresses_batch: ${queryResult.results?.length ?? 0}`);
143
+ }
144
+
145
+ const returnValues = queryResult.results[0]?.returnValues;
146
+ if (!returnValues || returnValues.length < 2) {
147
+ throw new Error('Invalid return values from get_feed_object_addresses_batch');
148
+ }
149
+
150
+ // Each return is a BCS-encoded `vector<address>`.
151
+ const pythAddrBytesVec = bcs.vector(bcs.bytes(32)).parse(new Uint8Array(returnValues[0]![0] as any));
152
+ const sbAddrBytesVec = bcs.vector(bcs.bytes(32)).parse(new Uint8Array(returnValues[1]![0] as any));
153
+
154
+ if (pythAddrBytesVec.length !== assetTypes.length || sbAddrBytesVec.length !== assetTypes.length) {
155
+ throw new Error(
156
+ `Unexpected address vector lengths from get_feed_object_addresses_batch: pyth=${pythAddrBytesVec.length}, sb=${sbAddrBytesVec.length}, expected=${assetTypes.length}`,
157
+ );
158
+ }
159
+
160
+ const out: Record<string, { priceObjectId: string; aggregatorId?: string }> = {};
161
+ for (let i = 0; i < assetTypes.length; i++) {
162
+ const assetType = assetTypes[i]!;
163
+ const sbBytes = Buffer.from(sbAddrBytesVec[i]!);
164
+ const sbIsZero = sbBytes.equals(Buffer.alloc(32));
165
+ out[assetType] = {
166
+ priceObjectId: '0x' + Buffer.from(pythAddrBytesVec[i]!).toString('hex'),
167
+ aggregatorId: sbIsZero ? undefined : '0x' + sbBytes.toString('hex'),
168
+ };
169
+ }
170
+ return out;
171
+ }
172
+
173
+ /**
174
+ * Get the prices of multiple assets by their types.
175
+ * @param assetTypes Array of asset types
176
+ * @param clockId The ID of the Clock object (defaults to 0x6)
177
+ * @returns Array of prices
178
+ */
179
+ async getPricesByTypes(assetTypes: string[], clockId: string = OracleClient.DEFAULT_CLOCK_ID): Promise<bigint[]> {
180
+ const promises = assetTypes.map(assetType => this.getPriceByType(assetType, clockId));
181
+ return Promise.all(promises);
182
+ }
183
+
184
+ /**
185
+ * Update prices for multiple assets by calling:
186
+ * - `adaptor_pyth::update_price`
187
+ * - `adaptor_switchboard::update_price` (only when a Switchboard feed is configured)
188
+ * @param assetTypes Array of asset types (e.g. '0x2::sui::SUI')
189
+ * @param clockId The ID of the Clock object
190
+ * @returns A Promise that resolves to a TransactionBlock that can be signed and executed
191
+ */
192
+ async updatePrices(assetTypes: string[], clockId: string): Promise<Transaction> {
193
+ const tx = new Transaction();
194
+ // 1) Batch query feed object ids (single devInspect).
195
+ const feedObjectIdsByType = await this.getFeedObjectIdsByTypes(assetTypes);
196
+ // 2) Add update calls using the queried ids.
197
+ // NOTE: caller guarantees `assetTypes` has no duplicates and order does not matter.
198
+ for (const [assetType, ids] of Object.entries(feedObjectIdsByType)) {
199
+ tx.moveCall({
200
+ target: `${this.packageId}::adaptor_pyth::update_price`,
201
+ typeArguments: [assetType],
202
+ arguments: [
203
+ tx.object(this.oracleId),
204
+ tx.object(ids.priceObjectId),
205
+ tx.object(clockId),
206
+ ],
207
+ });
208
+
209
+ if (ids.aggregatorId) {
210
+ tx.moveCall({
211
+ target: `${this.packageId}::adaptor_switchboard::update_price`,
212
+ typeArguments: [assetType],
213
+ arguments: [tx.object(this.oracleId), tx.object(ids.aggregatorId)],
214
+ });
215
+ }
216
+ }
217
+ return tx;
218
+ }
219
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,18 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "module": "commonjs",
5
+ "lib": ["ES2020"],
6
+ "outDir": "./dist",
7
+ "rootDir": "./src",
8
+ "strict": true,
9
+ "esModuleInterop": true,
10
+ "skipLibCheck": true,
11
+ "forceConsistentCasingInFileNames": true,
12
+ "declaration": true,
13
+ "declarationMap": true,
14
+ "sourceMap": true
15
+ },
16
+ "include": ["src/**/*"],
17
+ "exclude": ["node_modules", "dist"]
18
+ }