hearn-oracle-sdk 1.0.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/README.md +76 -0
- package/dist/example.d.ts +2 -0
- package/dist/example.d.ts.map +1 -0
- package/dist/example.js +51 -0
- package/dist/example.js.map +1 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +137 -0
- package/dist/index.js.map +1 -0
- package/package.json +19 -0
- package/src/example.ts +57 -0
- package/src/index.ts +159 -0
- package/tsconfig.json +18 -0
package/README.md
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Hearn Oracle SDK
|
|
2
|
+
|
|
3
|
+
This SDK provides a TypeScript interface to interact with the Hearn Oracle on the Sui blockchain, mimicking the Pyth SDK for batch price fetching.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
First, build the SDK:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install
|
|
11
|
+
npm run build
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Then, in your frontend project, you can install it locally or copy the `dist` folder.
|
|
15
|
+
|
|
16
|
+
### Option 1: Local Installation (Recommended for Development)
|
|
17
|
+
|
|
18
|
+
In your frontend project directory:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install /path/to/hearn/move/Oracle/sdk
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Replace `/path/to/hearn/move/Oracle/sdk` with the actual path.
|
|
25
|
+
|
|
26
|
+
### Option 2: Copy Files
|
|
27
|
+
|
|
28
|
+
Copy the `dist` folder from this SDK to your frontend project's `node_modules/hearn-oracle-sdk/dist` or a similar location, and ensure the package.json is updated accordingly.
|
|
29
|
+
|
|
30
|
+
## Usage
|
|
31
|
+
|
|
32
|
+
```typescript
|
|
33
|
+
import { SuiClient } from '@mysten/sui/client';
|
|
34
|
+
import { OracleClient } from 'hearn-oracle-sdk';
|
|
35
|
+
|
|
36
|
+
const provider = new SuiClient({ url: 'https://fullnode.mainnet.sui.io:443' });
|
|
37
|
+
const packageId = '0x...'; // Replace with actual package ID from deployment
|
|
38
|
+
const oracleId = '0x...'; // Replace with actual oracle object ID
|
|
39
|
+
|
|
40
|
+
const client = new OracleClient(provider, packageId, oracleId);
|
|
41
|
+
|
|
42
|
+
// Get price for a single asset
|
|
43
|
+
const price = await client.getPriceByType('0x2::sui::SUI');
|
|
44
|
+
console.log('SUI Price:', price);
|
|
45
|
+
|
|
46
|
+
// Get prices for multiple assets
|
|
47
|
+
const prices = await client.getPricesByTypes(['0x2::sui::SUI', '0x...::btc::BTC']);
|
|
48
|
+
console.log('Prices:', prices);
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## API Reference
|
|
52
|
+
|
|
53
|
+
### OracleClient
|
|
54
|
+
|
|
55
|
+
- `constructor(provider: SuiClient, packageId: string, oracleId: string)`
|
|
56
|
+
- `getPriceByType(assetType: string): Promise<number>` - Get price for one asset
|
|
57
|
+
- `getPricesByTypes(assetTypes: string[]): Promise<number[]>` - Get prices for multiple assets
|
|
58
|
+
- `updatePrices(updateDatas: UpdateData[], clockId: string): Promise<Transaction>` - Build transaction to update prices for multiple assets
|
|
59
|
+
|
|
60
|
+
### UpdateData
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
interface UpdateData {
|
|
64
|
+
assetType: string;
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Prices are returned as numbers (divided by 1e18 for wad format).
|
|
69
|
+
|
|
70
|
+
## Building
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
npm run build
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
This compiles TypeScript to JavaScript in the `dist` directory.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"example.d.ts","sourceRoot":"","sources":["../src/example.ts"],"names":[],"mappings":""}
|
package/dist/example.js
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Example usage of Hearn Oracle SDK
|
|
3
|
+
// This file demonstrates how to use the OracleClient in a frontend application
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
const client_1 = require("@mysten/sui/client");
|
|
6
|
+
const index_1 = require("./index"); // or 'hearn-oracle-sdk' if installed
|
|
7
|
+
async function main() {
|
|
8
|
+
// Initialize Sui client
|
|
9
|
+
const provider = new client_1.SuiClient({
|
|
10
|
+
url: 'https://fullnode.mainnet.sui.io:443'
|
|
11
|
+
});
|
|
12
|
+
// These IDs should come from your deployment
|
|
13
|
+
const packageId = '0x...'; // Replace with actual deployed package ID
|
|
14
|
+
const oracleId = '0x...'; // Replace with actual oracle object ID
|
|
15
|
+
// Create OracleClient instance
|
|
16
|
+
const oracleClient = new index_1.OracleClient(provider, packageId, oracleId);
|
|
17
|
+
try {
|
|
18
|
+
// Example 1: Get price for SUI
|
|
19
|
+
console.log('Fetching SUI price...');
|
|
20
|
+
const suiPrice = await oracleClient.getPriceByType('0x2::sui::SUI');
|
|
21
|
+
console.log('SUI Price:', suiPrice);
|
|
22
|
+
// Example 2: Get prices for multiple assets
|
|
23
|
+
console.log('Fetching multiple prices...');
|
|
24
|
+
const assetTypes = [
|
|
25
|
+
'0x2::sui::SUI',
|
|
26
|
+
// Add more asset types as needed
|
|
27
|
+
// '0x...::btc::BTC',
|
|
28
|
+
// '0x...::eth::ETH'
|
|
29
|
+
];
|
|
30
|
+
const prices = await oracleClient.getPricesByTypes(assetTypes);
|
|
31
|
+
console.log('Prices:', prices);
|
|
32
|
+
// Example 3: Update prices for multiple assets
|
|
33
|
+
console.log('Building transaction to update prices...');
|
|
34
|
+
const clockId = '0x6'; // Standard Clock object ID in Sui
|
|
35
|
+
const updateTx = await oracleClient.updatePrices(assetTypes, clockId);
|
|
36
|
+
console.log('Update transaction built:', updateTx);
|
|
37
|
+
// To execute the transaction, you need a signer:
|
|
38
|
+
// const signer = ...; // Your wallet signer
|
|
39
|
+
// const result = await signer.signAndExecuteTransactionBlock({
|
|
40
|
+
// transactionBlock: updateTx,
|
|
41
|
+
// });
|
|
42
|
+
// console.log('Update result:', result);
|
|
43
|
+
// Example 4: Handle errors
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
console.error('Error:', error);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
// Run the example
|
|
50
|
+
main();
|
|
51
|
+
//# sourceMappingURL=example.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"example.js","sourceRoot":"","sources":["../src/example.ts"],"names":[],"mappings":";AAAA,oCAAoC;AACpC,+EAA+E;;AAE/E,+CAA+C;AAC/C,mCAAuC,CAAC,qCAAqC;AAE7E,KAAK,UAAU,IAAI;IACf,wBAAwB;IACxB,MAAM,QAAQ,GAAG,IAAI,kBAAS,CAAC;QAC3B,GAAG,EAAE,qCAAqC;KAC7C,CAAC,CAAC;IAEH,6CAA6C;IAC7C,MAAM,SAAS,GAAG,OAAO,CAAC,CAAC,0CAA0C;IACrE,MAAM,QAAQ,GAAG,OAAO,CAAC,CAAC,uCAAuC;IAEjE,+BAA+B;IAC/B,MAAM,YAAY,GAAG,IAAI,oBAAY,CAAC,QAAQ,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;IAErE,IAAI,CAAC;QACD,+BAA+B;QAC/B,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;QACrC,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC;QACpE,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;QAEpC,4CAA4C;QAC5C,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC;QAC3C,MAAM,UAAU,GAAG;YACf,eAAe;YACf,iCAAiC;YACjC,qBAAqB;YACrB,oBAAoB;SACvB,CAAC;QACF,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC;QAC/D,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QAE/B,+CAA+C;QAC/C,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC;QACxD,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,kCAAkC;QACzD,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACtE,OAAO,CAAC,GAAG,CAAC,2BAA2B,EAAE,QAAQ,CAAC,CAAC;QAEnD,iDAAiD;QACjD,4CAA4C;QAC5C,+DAA+D;QAC/D,kCAAkC;QAClC,MAAM;QACN,yCAAyC;QAEzC,2BAA2B;IAC/B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IACnC,CAAC;AACL,CAAC;AAED,kBAAkB;AAClB,IAAI,EAAE,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { SuiClient } from '@mysten/sui/client';
|
|
2
|
+
import { Transaction } from '@mysten/sui/transactions';
|
|
3
|
+
export declare class OracleClient {
|
|
4
|
+
private provider;
|
|
5
|
+
private packageId;
|
|
6
|
+
private oracleId;
|
|
7
|
+
constructor(provider: SuiClient, packageId: string, oracleId: string);
|
|
8
|
+
/**
|
|
9
|
+
* Get the price of a single asset by its type.
|
|
10
|
+
* @param assetType The type of the asset, e.g., '0x2::sui::SUI'
|
|
11
|
+
* @returns The price as a number (assuming wad format, divided by 1e18)
|
|
12
|
+
*/
|
|
13
|
+
getPriceByType(assetType: string): Promise<number>;
|
|
14
|
+
/**
|
|
15
|
+
* Batch query feed object ids for multiple asset types in a single devInspect.
|
|
16
|
+
* Returns a map from assetType -> { priceObjectId, aggregatorId }.
|
|
17
|
+
*/
|
|
18
|
+
private getFeedObjectIdsByTypes;
|
|
19
|
+
/**
|
|
20
|
+
* Get the prices of multiple assets by their types.
|
|
21
|
+
* @param assetTypes Array of asset types
|
|
22
|
+
* @returns Array of prices
|
|
23
|
+
*/
|
|
24
|
+
getPricesByTypes(assetTypes: string[]): Promise<number[]>;
|
|
25
|
+
/**
|
|
26
|
+
* Update prices for multiple assets by calling adaptor_oracle::update_price in a loop.
|
|
27
|
+
* This builds a transaction that updates multiple assets' prices.
|
|
28
|
+
* @param updateDatas Array of update data for each asset
|
|
29
|
+
* @param clockId The ID of the Clock object
|
|
30
|
+
* @returns A Promise that resolves to a TransactionBlock that can be signed and executed
|
|
31
|
+
*/
|
|
32
|
+
updatePrices(assetTypes: string[], clockId: string): Promise<Transaction>;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +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;AAuBvD,qBAAa,YAAY;IACrB,OAAO,CAAC,QAAQ,CAAY;IAC5B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,QAAQ,CAAS;gBAEb,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;IAMpE;;;;OAIG;IACG,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IA4BxD;;;OAGG;YACW,uBAAuB;IAiDrC;;;;OAIG;IACG,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAK/D;;;;;;OAMG;IACG,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;CAoBlF"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OracleClient = void 0;
|
|
4
|
+
const transactions_1 = require("@mysten/sui/transactions");
|
|
5
|
+
const bcs_1 = require("@mysten/bcs");
|
|
6
|
+
// BCS schema for `TypeName` used by the Move contract.
|
|
7
|
+
// NOTE: This matches the struct shape expected on-chain.
|
|
8
|
+
const TypeNameBcs = bcs_1.bcs.struct('TypeName', {
|
|
9
|
+
// Move `address` is BCS-encoded as 32 bytes in Sui.
|
|
10
|
+
addr: bcs_1.bcs.bytes(32),
|
|
11
|
+
module: bcs_1.bcs.string(),
|
|
12
|
+
name: bcs_1.bcs.string(),
|
|
13
|
+
});
|
|
14
|
+
function suiAddressToBytes(address) {
|
|
15
|
+
const hex = address.startsWith('0x') ? address.slice(2) : address;
|
|
16
|
+
// 32 bytes = 64 hex chars
|
|
17
|
+
const padded = hex.padStart(64, '0');
|
|
18
|
+
const buf = Buffer.from(padded, 'hex');
|
|
19
|
+
if (buf.length !== 32) {
|
|
20
|
+
throw new Error(`Invalid Sui address length: expected 32 bytes, got ${buf.length}`);
|
|
21
|
+
}
|
|
22
|
+
return new Uint8Array(buf);
|
|
23
|
+
}
|
|
24
|
+
class OracleClient {
|
|
25
|
+
constructor(provider, packageId, oracleId) {
|
|
26
|
+
this.provider = provider;
|
|
27
|
+
this.packageId = packageId;
|
|
28
|
+
this.oracleId = oracleId;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Get the price of a single asset by its type.
|
|
32
|
+
* @param assetType The type of the asset, e.g., '0x2::sui::SUI'
|
|
33
|
+
* @returns The price as a number (assuming wad format, divided by 1e18)
|
|
34
|
+
*/
|
|
35
|
+
async getPriceByType(assetType) {
|
|
36
|
+
const tx = new transactions_1.Transaction();
|
|
37
|
+
tx.moveCall({
|
|
38
|
+
target: `${this.packageId}::oracle::price_by_type`,
|
|
39
|
+
typeArguments: [assetType],
|
|
40
|
+
arguments: [tx.object(this.oracleId)],
|
|
41
|
+
});
|
|
42
|
+
const result = await this.provider.devInspectTransactionBlock({
|
|
43
|
+
transactionBlock: tx,
|
|
44
|
+
sender: '0x0000000000000000000000000000000000000000000000000000000000000000', // dummy sender for read-only
|
|
45
|
+
});
|
|
46
|
+
if (!result.results || result.results.length === 0) {
|
|
47
|
+
throw new Error('No results from transaction inspection');
|
|
48
|
+
}
|
|
49
|
+
const returnValue = result.results[0].returnValues?.[0];
|
|
50
|
+
if (!returnValue) {
|
|
51
|
+
throw new Error('No return value from price_by_type');
|
|
52
|
+
}
|
|
53
|
+
// Assuming return is u128 as bytes, convert to bigint
|
|
54
|
+
const priceBigInt = BigInt('0x' + Buffer.from(returnValue[0]).toString('hex'));
|
|
55
|
+
// Assuming wad format, divide by 1e18
|
|
56
|
+
return Number(priceBigInt) / 1e18;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Batch query feed object ids for multiple asset types in a single devInspect.
|
|
60
|
+
* Returns a map from assetType -> { priceObjectId, aggregatorId }.
|
|
61
|
+
*/
|
|
62
|
+
async getFeedObjectIdsByTypes(assetTypes) {
|
|
63
|
+
const queryTx = new transactions_1.Transaction();
|
|
64
|
+
const typeNames = assetTypes.map((assetType) => {
|
|
65
|
+
const [address, module, name] = assetType.split('::');
|
|
66
|
+
return { addr: suiAddressToBytes(address), module, name };
|
|
67
|
+
});
|
|
68
|
+
queryTx.moveCall({
|
|
69
|
+
target: `${this.packageId}::pyth_oracle::get_feed_object_addresses_batch`,
|
|
70
|
+
arguments: [queryTx.object(this.oracleId), queryTx.pure(bcs_1.bcs.vector(TypeNameBcs).serialize(typeNames))],
|
|
71
|
+
});
|
|
72
|
+
const queryResult = await this.provider.devInspectTransactionBlock({
|
|
73
|
+
transactionBlock: queryTx,
|
|
74
|
+
sender: '0x0000000000000000000000000000000000000000000000000000000000000000',
|
|
75
|
+
});
|
|
76
|
+
if (!queryResult.results || queryResult.results.length !== 1) {
|
|
77
|
+
throw new Error(`Unexpected results length from get_feed_object_addresses_batch: ${queryResult.results?.length ?? 0}`);
|
|
78
|
+
}
|
|
79
|
+
const returnValues = queryResult.results[0]?.returnValues;
|
|
80
|
+
if (!returnValues || returnValues.length < 2) {
|
|
81
|
+
throw new Error('Invalid return values from get_feed_object_addresses_batch');
|
|
82
|
+
}
|
|
83
|
+
// Each return is a BCS-encoded `vector<address>`.
|
|
84
|
+
const pythAddrBytesVec = bcs_1.bcs.vector(bcs_1.bcs.bytes(32)).parse(new Uint8Array(returnValues[0][0]));
|
|
85
|
+
const sbAddrBytesVec = bcs_1.bcs.vector(bcs_1.bcs.bytes(32)).parse(new Uint8Array(returnValues[1][0]));
|
|
86
|
+
if (pythAddrBytesVec.length !== assetTypes.length || sbAddrBytesVec.length !== assetTypes.length) {
|
|
87
|
+
throw new Error(`Unexpected address vector lengths from get_feed_object_addresses_batch: pyth=${pythAddrBytesVec.length}, sb=${sbAddrBytesVec.length}, expected=${assetTypes.length}`);
|
|
88
|
+
}
|
|
89
|
+
const out = {};
|
|
90
|
+
for (let i = 0; i < assetTypes.length; i++) {
|
|
91
|
+
const assetType = assetTypes[i];
|
|
92
|
+
out[assetType] = {
|
|
93
|
+
priceObjectId: '0x' + Buffer.from(pythAddrBytesVec[i]).toString('hex'),
|
|
94
|
+
aggregatorId: '0x' + Buffer.from(sbAddrBytesVec[i]).toString('hex'),
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
return out;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Get the prices of multiple assets by their types.
|
|
101
|
+
* @param assetTypes Array of asset types
|
|
102
|
+
* @returns Array of prices
|
|
103
|
+
*/
|
|
104
|
+
async getPricesByTypes(assetTypes) {
|
|
105
|
+
const promises = assetTypes.map(assetType => this.getPriceByType(assetType));
|
|
106
|
+
return Promise.all(promises);
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Update prices for multiple assets by calling adaptor_oracle::update_price in a loop.
|
|
110
|
+
* This builds a transaction that updates multiple assets' prices.
|
|
111
|
+
* @param updateDatas Array of update data for each asset
|
|
112
|
+
* @param clockId The ID of the Clock object
|
|
113
|
+
* @returns A Promise that resolves to a TransactionBlock that can be signed and executed
|
|
114
|
+
*/
|
|
115
|
+
async updatePrices(assetTypes, clockId) {
|
|
116
|
+
const tx = new transactions_1.Transaction();
|
|
117
|
+
// 1) Batch query feed object ids (single devInspect).
|
|
118
|
+
const feedObjectIdsByType = await this.getFeedObjectIdsByTypes(assetTypes);
|
|
119
|
+
// 2) Add update calls using the queried ids.
|
|
120
|
+
// NOTE: caller guarantees `assetTypes` has no duplicates and order does not matter.
|
|
121
|
+
for (const [assetType, ids] of Object.entries(feedObjectIdsByType)) {
|
|
122
|
+
tx.moveCall({
|
|
123
|
+
target: `${this.packageId}::adaptor_oracle::update_price`,
|
|
124
|
+
typeArguments: [assetType],
|
|
125
|
+
arguments: [
|
|
126
|
+
tx.object(this.oracleId),
|
|
127
|
+
tx.object(ids.priceObjectId),
|
|
128
|
+
tx.object(ids.aggregatorId),
|
|
129
|
+
tx.object(clockId),
|
|
130
|
+
],
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
return tx;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
exports.OracleClient = OracleClient;
|
|
137
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "hearn-oracle-sdk",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "SDK for interacting with Hearn Oracle on Sui blockchain",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "tsc",
|
|
9
|
+
"dev": "tsc --watch"
|
|
10
|
+
},
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"@mysten/sui": "^1.45.2",
|
|
13
|
+
"@mysten/bcs": "^1.9.2"
|
|
14
|
+
},
|
|
15
|
+
"devDependencies": {
|
|
16
|
+
"typescript": "^5.0.0",
|
|
17
|
+
"@types/node": "^20.0.0"
|
|
18
|
+
}
|
|
19
|
+
}
|
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,159 @@
|
|
|
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 `TypeName` used by the Move contract.
|
|
6
|
+
// NOTE: This matches the struct shape expected on-chain.
|
|
7
|
+
const TypeNameBcs = bcs.struct('TypeName', {
|
|
8
|
+
// Move `address` is BCS-encoded as 32 bytes in Sui.
|
|
9
|
+
addr: bcs.bytes(32),
|
|
10
|
+
module: bcs.string(),
|
|
11
|
+
name: bcs.string(),
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
function suiAddressToBytes(address: string): Uint8Array {
|
|
15
|
+
const hex = address.startsWith('0x') ? address.slice(2) : address;
|
|
16
|
+
// 32 bytes = 64 hex chars
|
|
17
|
+
const padded = hex.padStart(64, '0');
|
|
18
|
+
const buf = Buffer.from(padded, 'hex');
|
|
19
|
+
if (buf.length !== 32) {
|
|
20
|
+
throw new Error(`Invalid Sui address length: expected 32 bytes, got ${buf.length}`);
|
|
21
|
+
}
|
|
22
|
+
return new Uint8Array(buf);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export class OracleClient {
|
|
26
|
+
private provider: SuiClient;
|
|
27
|
+
private packageId: string;
|
|
28
|
+
private oracleId: string;
|
|
29
|
+
|
|
30
|
+
constructor(provider: SuiClient, packageId: string, oracleId: string) {
|
|
31
|
+
this.provider = provider;
|
|
32
|
+
this.packageId = packageId;
|
|
33
|
+
this.oracleId = oracleId;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Get the price of a single asset by its type.
|
|
38
|
+
* @param assetType The type of the asset, e.g., '0x2::sui::SUI'
|
|
39
|
+
* @returns The price as a number (assuming wad format, divided by 1e18)
|
|
40
|
+
*/
|
|
41
|
+
async getPriceByType(assetType: string): Promise<number> {
|
|
42
|
+
const tx = new Transaction();
|
|
43
|
+
tx.moveCall({
|
|
44
|
+
target: `${this.packageId}::oracle::price_by_type`,
|
|
45
|
+
typeArguments: [assetType],
|
|
46
|
+
arguments: [tx.object(this.oracleId)],
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
const result = await this.provider.devInspectTransactionBlock({
|
|
50
|
+
transactionBlock: tx,
|
|
51
|
+
sender: '0x0000000000000000000000000000000000000000000000000000000000000000', // dummy sender for read-only
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
if (!result.results || result.results.length === 0) {
|
|
55
|
+
throw new Error('No results from transaction inspection');
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const returnValue = result.results[0].returnValues?.[0];
|
|
59
|
+
if (!returnValue) {
|
|
60
|
+
throw new Error('No return value from price_by_type');
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Assuming return is u128 as bytes, convert to bigint
|
|
64
|
+
const priceBigInt = BigInt('0x' + Buffer.from(returnValue[0]).toString('hex'));
|
|
65
|
+
// Assuming wad format, divide by 1e18
|
|
66
|
+
return Number(priceBigInt) / 1e18;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Batch query feed object ids for multiple asset types in a single devInspect.
|
|
71
|
+
* Returns a map from assetType -> { priceObjectId, aggregatorId }.
|
|
72
|
+
*/
|
|
73
|
+
private async getFeedObjectIdsByTypes(
|
|
74
|
+
assetTypes: string[],
|
|
75
|
+
): Promise<Record<string, { priceObjectId: string; aggregatorId: string }>> {
|
|
76
|
+
const queryTx = new Transaction();
|
|
77
|
+
const typeNames = assetTypes.map((assetType) => {
|
|
78
|
+
const [address, module, name] = assetType.split('::');
|
|
79
|
+
return { addr: suiAddressToBytes(address), module, name };
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
queryTx.moveCall({
|
|
83
|
+
target: `${this.packageId}::pyth_oracle::get_feed_object_addresses_batch`,
|
|
84
|
+
arguments: [queryTx.object(this.oracleId), queryTx.pure(bcs.vector(TypeNameBcs).serialize(typeNames))],
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
const queryResult = await this.provider.devInspectTransactionBlock({
|
|
88
|
+
transactionBlock: queryTx,
|
|
89
|
+
sender: '0x0000000000000000000000000000000000000000000000000000000000000000',
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
if (!queryResult.results || queryResult.results.length !== 1) {
|
|
93
|
+
throw new Error(`Unexpected results length from get_feed_object_addresses_batch: ${queryResult.results?.length ?? 0}`);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const returnValues = queryResult.results[0]?.returnValues;
|
|
97
|
+
if (!returnValues || returnValues.length < 2) {
|
|
98
|
+
throw new Error('Invalid return values from get_feed_object_addresses_batch');
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Each return is a BCS-encoded `vector<address>`.
|
|
102
|
+
const pythAddrBytesVec = bcs.vector(bcs.bytes(32)).parse(new Uint8Array(returnValues[0]![0] as any));
|
|
103
|
+
const sbAddrBytesVec = bcs.vector(bcs.bytes(32)).parse(new Uint8Array(returnValues[1]![0] as any));
|
|
104
|
+
|
|
105
|
+
if (pythAddrBytesVec.length !== assetTypes.length || sbAddrBytesVec.length !== assetTypes.length) {
|
|
106
|
+
throw new Error(
|
|
107
|
+
`Unexpected address vector lengths from get_feed_object_addresses_batch: pyth=${pythAddrBytesVec.length}, sb=${sbAddrBytesVec.length}, expected=${assetTypes.length}`,
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const out: Record<string, { priceObjectId: string; aggregatorId: string }> = {};
|
|
112
|
+
for (let i = 0; i < assetTypes.length; i++) {
|
|
113
|
+
const assetType = assetTypes[i]!;
|
|
114
|
+
out[assetType] = {
|
|
115
|
+
priceObjectId: '0x' + Buffer.from(pythAddrBytesVec[i]!).toString('hex'),
|
|
116
|
+
aggregatorId: '0x' + Buffer.from(sbAddrBytesVec[i]!).toString('hex'),
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
return out;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Get the prices of multiple assets by their types.
|
|
124
|
+
* @param assetTypes Array of asset types
|
|
125
|
+
* @returns Array of prices
|
|
126
|
+
*/
|
|
127
|
+
async getPricesByTypes(assetTypes: string[]): Promise<number[]> {
|
|
128
|
+
const promises = assetTypes.map(assetType => this.getPriceByType(assetType));
|
|
129
|
+
return Promise.all(promises);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Update prices for multiple assets by calling adaptor_oracle::update_price in a loop.
|
|
134
|
+
* This builds a transaction that updates multiple assets' prices.
|
|
135
|
+
* @param updateDatas Array of update data for each asset
|
|
136
|
+
* @param clockId The ID of the Clock object
|
|
137
|
+
* @returns A Promise that resolves to a TransactionBlock that can be signed and executed
|
|
138
|
+
*/
|
|
139
|
+
async updatePrices(assetTypes: string[], clockId: string): Promise<Transaction> {
|
|
140
|
+
const tx = new Transaction();
|
|
141
|
+
// 1) Batch query feed object ids (single devInspect).
|
|
142
|
+
const feedObjectIdsByType = await this.getFeedObjectIdsByTypes(assetTypes);
|
|
143
|
+
// 2) Add update calls using the queried ids.
|
|
144
|
+
// NOTE: caller guarantees `assetTypes` has no duplicates and order does not matter.
|
|
145
|
+
for (const [assetType, ids] of Object.entries(feedObjectIdsByType)) {
|
|
146
|
+
tx.moveCall({
|
|
147
|
+
target: `${this.packageId}::adaptor_oracle::update_price`,
|
|
148
|
+
typeArguments: [assetType],
|
|
149
|
+
arguments: [
|
|
150
|
+
tx.object(this.oracleId),
|
|
151
|
+
tx.object(ids.priceObjectId),
|
|
152
|
+
tx.object(ids.aggregatorId),
|
|
153
|
+
tx.object(clockId),
|
|
154
|
+
],
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
return tx;
|
|
158
|
+
}
|
|
159
|
+
}
|
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
|
+
}
|