@reflectmoney/oracle.ts 1.0.1 → 2.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 +23 -10
- package/dist/index.d.ts +11 -16
- package/dist/index.js +39 -29
- package/package.json +1 -1
package/README.md
CHANGED
@@ -25,7 +25,7 @@ yarn add @reflectmoney/oracle.ts
|
|
25
25
|
### Initialize Doppler
|
26
26
|
|
27
27
|
```typescript
|
28
|
-
import { Doppler,
|
28
|
+
import { Doppler, U8Array8Serializer, createPricePayload } from "@reflectmoney/oracle.ts";
|
29
29
|
import { Connection, Keypair } from "@solana/web3.js";
|
30
30
|
|
31
31
|
const connection = new Connection("https://api.mainnet-beta.solana.com");
|
@@ -41,26 +41,39 @@ import { PublicKey } from "@solana/web3.js";
|
|
41
41
|
|
42
42
|
const oraclePublicKey = new PublicKey("ORACLE_ADDRESS");
|
43
43
|
|
44
|
+
// Create a price payload (8 bytes representing a u64 value)
|
45
|
+
const pricePayload = createPricePayload(BigInt(1_000_000)); // 1 USDC
|
46
|
+
|
44
47
|
await doppler.updateOracle(
|
45
48
|
oraclePublicKey,
|
46
49
|
{
|
47
|
-
|
48
|
-
|
50
|
+
slot: BigInt(Date.now()),
|
51
|
+
payload: pricePayload,
|
49
52
|
},
|
50
|
-
new
|
53
|
+
new U8Array8Serializer(),
|
51
54
|
);
|
52
55
|
```
|
53
56
|
|
54
57
|
### Fetch Oracle Data
|
55
58
|
|
56
59
|
```typescript
|
60
|
+
import { readPriceFromPayload } from "@reflectmoney/oracle.ts";
|
61
|
+
|
57
62
|
const oracleData = await doppler.fetchOracle(
|
58
63
|
oraclePublicKey,
|
59
|
-
new
|
64
|
+
new U8Array8Serializer(),
|
60
65
|
);
|
61
66
|
|
62
|
-
|
63
|
-
|
67
|
+
if (oracleData) {
|
68
|
+
console.log("Slot:", oracleData.slot);
|
69
|
+
|
70
|
+
// Extract price from the 8-byte payload
|
71
|
+
const price = readPriceFromPayload(oracleData.payload);
|
72
|
+
console.log("Price:", price);
|
73
|
+
}
|
74
|
+
// Output:
|
75
|
+
// Slot: 1728662400000n
|
76
|
+
// Price: 1000000n
|
64
77
|
```
|
65
78
|
|
66
79
|
### Create an Oracle Account
|
@@ -68,10 +81,10 @@ console.log(oracleData);
|
|
68
81
|
```typescript
|
69
82
|
const oracleAccount = await doppler.createOracleAccount(
|
70
83
|
"my-oracle-seed",
|
71
|
-
new
|
84
|
+
new U8Array8Serializer(),
|
72
85
|
{
|
73
|
-
|
74
|
-
|
86
|
+
slot: 0n,
|
87
|
+
payload: createPricePayload(BigInt(1_000_000)),
|
75
88
|
}
|
76
89
|
);
|
77
90
|
```
|
package/dist/index.d.ts
CHANGED
@@ -3,10 +3,10 @@ import { Buffer } from 'buffer';
|
|
3
3
|
export declare const DOPPLER_PROGRAM_ID: PublicKey;
|
4
4
|
export declare const ADMIN_PUBKEY: PublicKey;
|
5
5
|
/**
|
6
|
-
* Generic Oracle data structure
|
6
|
+
* Generic Oracle data structure matching Rust implementation
|
7
7
|
*/
|
8
8
|
export interface Oracle<T> {
|
9
|
-
|
9
|
+
slot: bigint;
|
10
10
|
payload: T;
|
11
11
|
}
|
12
12
|
/**
|
@@ -18,27 +18,22 @@ export interface PayloadSerializer<T> {
|
|
18
18
|
size(): number;
|
19
19
|
}
|
20
20
|
/**
|
21
|
-
* Built-in serializer for
|
21
|
+
* Built-in serializer for [u8; 8] payloads (used for price feeds)
|
22
|
+
* The payload is simply 8 bytes representing data in little-endian format
|
22
23
|
*/
|
23
|
-
export declare class
|
24
|
-
serialize(payload:
|
25
|
-
deserialize(buffer: Buffer):
|
24
|
+
export declare class U8Array8Serializer implements PayloadSerializer<Buffer> {
|
25
|
+
serialize(payload: Buffer): Buffer;
|
26
|
+
deserialize(buffer: Buffer): Buffer;
|
26
27
|
size(): number;
|
27
28
|
}
|
28
29
|
/**
|
29
|
-
*
|
30
|
+
* Helper function to create a [u8; 8] payload from a bigint price value
|
30
31
|
*/
|
31
|
-
export
|
32
|
-
price: bigint;
|
33
|
-
}
|
32
|
+
export declare function createPricePayload(price: bigint): Buffer;
|
34
33
|
/**
|
35
|
-
*
|
34
|
+
* Helper function to read a price value from a [u8; 8] payload
|
36
35
|
*/
|
37
|
-
export declare
|
38
|
-
serialize(payload: PriceFeed): Buffer;
|
39
|
-
deserialize(buffer: Buffer): PriceFeed;
|
40
|
-
size(): number;
|
41
|
-
}
|
36
|
+
export declare function readPriceFromPayload(payload: Buffer): bigint;
|
42
37
|
/**
|
43
38
|
* Transaction builder for Doppler oracle updates
|
44
39
|
*/
|
package/dist/index.js
CHANGED
@@ -9,7 +9,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
9
9
|
});
|
10
10
|
};
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
12
|
-
exports.Doppler = exports.TransactionBuilder = exports.
|
12
|
+
exports.Doppler = exports.TransactionBuilder = exports.U8Array8Serializer = exports.ADMIN_PUBKEY = exports.DOPPLER_PROGRAM_ID = void 0;
|
13
|
+
exports.createPricePayload = createPricePayload;
|
14
|
+
exports.readPriceFromPayload = readPriceFromPayload;
|
13
15
|
const web3_js_1 = require("@solana/web3.js");
|
14
16
|
const buffer_1 = require("buffer");
|
15
17
|
const compute_budget_1 = require("@solana-program/compute-budget");
|
@@ -28,41 +30,44 @@ const COMPUTE_BUDGET_DATA_LIMIT_SIZE = 5;
|
|
28
30
|
const COMPUTE_BUDGET_PROGRAM_SIZE = 22;
|
29
31
|
const ORACLE_PROGRAM_SIZE = 36;
|
30
32
|
/**
|
31
|
-
* Built-in serializer for
|
33
|
+
* Built-in serializer for [u8; 8] payloads (used for price feeds)
|
34
|
+
* The payload is simply 8 bytes representing data in little-endian format
|
32
35
|
*/
|
33
|
-
class
|
36
|
+
class U8Array8Serializer {
|
34
37
|
serialize(payload) {
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
+
if (payload.length !== 8) {
|
39
|
+
throw new Error('Payload must be exactly 8 bytes');
|
40
|
+
}
|
41
|
+
return payload;
|
38
42
|
}
|
39
43
|
deserialize(buffer) {
|
40
|
-
|
44
|
+
if (buffer.length < 8) {
|
45
|
+
throw new Error('Buffer must be at least 8 bytes');
|
46
|
+
}
|
47
|
+
return buffer.subarray(0, 8);
|
41
48
|
}
|
42
49
|
size() {
|
43
50
|
return 8;
|
44
51
|
}
|
45
52
|
}
|
46
|
-
exports.
|
53
|
+
exports.U8Array8Serializer = U8Array8Serializer;
|
47
54
|
/**
|
48
|
-
*
|
55
|
+
* Helper function to create a [u8; 8] payload from a bigint price value
|
49
56
|
*/
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
size() {
|
62
|
-
return 8;
|
57
|
+
function createPricePayload(price) {
|
58
|
+
const buf = buffer_1.Buffer.alloc(8);
|
59
|
+
buf.writeBigUInt64LE(price);
|
60
|
+
return buf;
|
61
|
+
}
|
62
|
+
/**
|
63
|
+
* Helper function to read a price value from a [u8; 8] payload
|
64
|
+
*/
|
65
|
+
function readPriceFromPayload(payload) {
|
66
|
+
if (payload.length < 8) {
|
67
|
+
throw new Error('Payload must be at least 8 bytes');
|
63
68
|
}
|
69
|
+
return payload.readBigUInt64LE(0);
|
64
70
|
}
|
65
|
-
exports.PriceFeedSerializer = PriceFeedSerializer;
|
66
71
|
/**
|
67
72
|
* Transaction builder for Doppler oracle updates
|
68
73
|
*/
|
@@ -83,7 +88,7 @@ class TransactionBuilder {
|
|
83
88
|
addOracleUpdate(oraclePubkey, oracle, serializer) {
|
84
89
|
const instruction = this.createUpdateInstruction(oraclePubkey, oracle, serializer);
|
85
90
|
const payloadSize = serializer.size();
|
86
|
-
const oracleSize = 8 + payloadSize; //
|
91
|
+
const oracleSize = 8 + payloadSize; // slot + payload
|
87
92
|
this.computeUnits +=
|
88
93
|
SEQUENCE_CHECK_CU +
|
89
94
|
ADMIN_VERIFICATION_CU +
|
@@ -149,15 +154,20 @@ class TransactionBuilder {
|
|
149
154
|
isSigner: false,
|
150
155
|
isWritable: true,
|
151
156
|
},
|
157
|
+
{
|
158
|
+
pubkey: web3_js_1.SYSVAR_CLOCK_PUBKEY,
|
159
|
+
isSigner: false,
|
160
|
+
isWritable: false,
|
161
|
+
},
|
152
162
|
],
|
153
163
|
data,
|
154
164
|
});
|
155
165
|
}
|
156
166
|
serializeOracle(oracle, serializer) {
|
157
|
-
const
|
158
|
-
|
167
|
+
const slotBuffer = buffer_1.Buffer.alloc(8);
|
168
|
+
slotBuffer.writeBigUInt64LE(oracle.slot);
|
159
169
|
const payloadBuffer = serializer.serialize(oracle.payload);
|
160
|
-
return buffer_1.Buffer.concat([
|
170
|
+
return buffer_1.Buffer.concat([slotBuffer, payloadBuffer]);
|
161
171
|
}
|
162
172
|
}
|
163
173
|
exports.TransactionBuilder = TransactionBuilder;
|
@@ -201,10 +211,10 @@ class Doppler {
|
|
201
211
|
if (data.length < expectedSize) {
|
202
212
|
throw new Error(`Invalid oracle data size. Expected at least ${expectedSize}, got ${data.length}`);
|
203
213
|
}
|
204
|
-
const
|
214
|
+
const slot = data.readBigUInt64LE(0);
|
205
215
|
const payloadBuffer = data.subarray(8, 8 + serializer.size());
|
206
216
|
const payload = serializer.deserialize(payloadBuffer);
|
207
|
-
return {
|
217
|
+
return { slot, payload };
|
208
218
|
}
|
209
219
|
/**
|
210
220
|
* Create an oracle account with a seed
|