@pythnetwork/price-pusher 5.4.2 → 5.4.8
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 +4 -3
- package/lib/aptos/aptos.d.ts +5 -2
- package/lib/aptos/aptos.d.ts.map +1 -1
- package/lib/aptos/aptos.js +70 -40
- package/lib/aptos/command.d.ts.map +1 -1
- package/lib/aptos/command.js +3 -0
- package/lib/injective/injective.d.ts.map +1 -1
- package/lib/injective/injective.js +16 -6
- package/lib/sui/command.js +5 -5
- package/lib/sui/sui.d.ts +1 -0
- package/lib/sui/sui.d.ts.map +1 -1
- package/lib/sui/sui.js +27 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@ Pyth is a cross-chain oracle that streams price updates over the peer-to-peer [W
|
|
|
8
8
|
These price updates can be consumed on any chain that has a deployment of the Pyth contract.
|
|
9
9
|
By default, Pyth does not automatically update the on-chain price every time the off-chain price changes;
|
|
10
10
|
instead, anyone can permissionlessly update the on-chain price prior to using it.
|
|
11
|
-
For more information please refer to [this document](https://docs.pyth.network/
|
|
11
|
+
For more information please refer to [this document](https://docs.pyth.network/documentation/how-pyth-works).
|
|
12
12
|
|
|
13
13
|
Protocols integrating with can update the on-chain Pyth prices in two different ways.
|
|
14
14
|
The first approach is on-demand updates: package a Pyth price update together with each transaction that depends on it.
|
|
@@ -79,8 +79,9 @@ npm run start -- injective --grpc-endpoint https://grpc-endpoint.com \
|
|
|
79
79
|
--pyth-contract-address inj1z60tg0... --price-service-endpoint "https://example-pyth-price.com" \
|
|
80
80
|
--price-config-file "path/to/price-config.testnet.sample.yaml" \
|
|
81
81
|
--mnemonic-file "path/to/mnemonic.txt" \
|
|
82
|
+
--network testnet \
|
|
82
83
|
[--pushing-frequency 10] \
|
|
83
|
-
[--polling-frequency 5]
|
|
84
|
+
[--polling-frequency 5]
|
|
84
85
|
|
|
85
86
|
# For Aptos
|
|
86
87
|
npm run start -- aptos --endpoint https://fullnode.testnet.aptoslabs.com/v1 \
|
|
@@ -88,7 +89,7 @@ npm run start -- aptos --endpoint https://fullnode.testnet.aptoslabs.com/v1 \
|
|
|
88
89
|
--price-config-file "./price-config.testnet.sample.yaml" \
|
|
89
90
|
--mnemonic-file "path/to/mnemonic.txt" \
|
|
90
91
|
[--pushing-frequency 10] \
|
|
91
|
-
[--polling-frequency 5]
|
|
92
|
+
[--polling-frequency 5]
|
|
92
93
|
|
|
93
94
|
# For Sui
|
|
94
95
|
npm run start -- sui \
|
package/lib/aptos/aptos.d.ts
CHANGED
|
@@ -9,14 +9,15 @@ export declare class AptosPriceListener extends ChainPriceListener {
|
|
|
9
9
|
});
|
|
10
10
|
getOnChainPriceInfo(priceId: string): Promise<PriceInfo | undefined>;
|
|
11
11
|
}
|
|
12
|
+
export declare const APTOS_ACCOUNT_HD_PATH = "m/44'/637'/0'/0'/0'";
|
|
12
13
|
export declare class AptosPricePusher implements IPricePusher {
|
|
13
14
|
private priceServiceConnection;
|
|
14
15
|
private pythContractAddress;
|
|
15
16
|
private endpoint;
|
|
16
17
|
private mnemonic;
|
|
17
18
|
private overrideGasPriceMultiplier;
|
|
18
|
-
private
|
|
19
|
-
private
|
|
19
|
+
private lastSequenceNumber;
|
|
20
|
+
private sequenceNumberLocked;
|
|
20
21
|
constructor(priceServiceConnection: PriceServiceConnection, pythContractAddress: string, endpoint: string, mnemonic: string, overrideGasPriceMultiplier: number);
|
|
21
22
|
/**
|
|
22
23
|
* Gets price update data which then can be submitted to the Pyth contract to update the prices.
|
|
@@ -27,5 +28,7 @@ export declare class AptosPricePusher implements IPricePusher {
|
|
|
27
28
|
*/
|
|
28
29
|
getPriceFeedsUpdateData(priceIds: string[]): Promise<number[][]>;
|
|
29
30
|
updatePriceFeed(priceIds: string[], pubTimesToPush: number[]): Promise<void>;
|
|
31
|
+
private waitForTransactionConfirmation;
|
|
32
|
+
private tryGetNextSequenceNumber;
|
|
30
33
|
}
|
|
31
34
|
//# sourceMappingURL=aptos.d.ts.map
|
package/lib/aptos/aptos.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aptos.d.ts","sourceRoot":"","sources":["../../src/aptos/aptos.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,YAAY,EACZ,SAAS,EACT,SAAS,EACV,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,CAAC;
|
|
1
|
+
{"version":3,"file":"aptos.d.ts","sourceRoot":"","sources":["../../src/aptos/aptos.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,YAAY,EACZ,SAAS,EACT,SAAS,EACV,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,CAAC;AAE3E,qBAAa,kBAAmB,SAAQ,kBAAkB;IAEtD,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,QAAQ;gBADR,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EACxB,UAAU,EAAE,SAAS,EAAE,EACvB,MAAM,EAAE;QACN,gBAAgB,EAAE,iBAAiB,CAAC;KACrC;IAKG,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;CA6C3E;AAGD,eAAO,MAAM,qBAAqB,wBAAwB,CAAC;AAC3D,qBAAa,gBAAiB,YAAW,YAAY;IAOjD,OAAO,CAAC,sBAAsB;IAC9B,OAAO,CAAC,mBAAmB;IAC3B,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,0BAA0B;IATpC,OAAO,CAAC,kBAAkB,CAAqB;IAE/C,OAAO,CAAC,oBAAoB,CAAU;gBAG5B,sBAAsB,EAAE,sBAAsB,EAC9C,mBAAmB,EAAE,MAAM,EAC3B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,0BAA0B,EAAE,MAAM;IAK5C;;;;;;OAMG;IACG,uBAAuB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;IAQhE,eAAe,CACnB,QAAQ,EAAE,MAAM,EAAE,EAClB,cAAc,EAAE,MAAM,EAAE,GACvB,OAAO,CAAC,IAAI,CAAC;YAiEF,8BAA8B;YAsB9B,wBAAwB;CA+BvC"}
|
package/lib/aptos/aptos.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.AptosPricePusher = exports.AptosPriceListener = void 0;
|
|
3
|
+
exports.AptosPricePusher = exports.APTOS_ACCOUNT_HD_PATH = exports.AptosPriceListener = void 0;
|
|
4
4
|
const interface_1 = require("../interface");
|
|
5
5
|
const aptos_1 = require("aptos");
|
|
6
6
|
class AptosPriceListener extends interface_1.ChainPriceListener {
|
|
@@ -42,20 +42,25 @@ class AptosPriceListener extends interface_1.ChainPriceListener {
|
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
exports.AptosPriceListener = AptosPriceListener;
|
|
45
|
+
// Derivation path for aptos accounts
|
|
46
|
+
exports.APTOS_ACCOUNT_HD_PATH = "m/44'/637'/0'/0'/0'";
|
|
45
47
|
class AptosPricePusher {
|
|
46
48
|
priceServiceConnection;
|
|
47
49
|
pythContractAddress;
|
|
48
50
|
endpoint;
|
|
49
51
|
mnemonic;
|
|
50
52
|
overrideGasPriceMultiplier;
|
|
51
|
-
|
|
52
|
-
|
|
53
|
+
// The last sequence number that has a transaction submitted.
|
|
54
|
+
lastSequenceNumber;
|
|
55
|
+
// If true, we are trying to fetch the most recent sequence number from the blockchain.
|
|
56
|
+
sequenceNumberLocked;
|
|
53
57
|
constructor(priceServiceConnection, pythContractAddress, endpoint, mnemonic, overrideGasPriceMultiplier) {
|
|
54
58
|
this.priceServiceConnection = priceServiceConnection;
|
|
55
59
|
this.pythContractAddress = pythContractAddress;
|
|
56
60
|
this.endpoint = endpoint;
|
|
57
61
|
this.mnemonic = mnemonic;
|
|
58
62
|
this.overrideGasPriceMultiplier = overrideGasPriceMultiplier;
|
|
63
|
+
this.sequenceNumberLocked = false;
|
|
59
64
|
}
|
|
60
65
|
/**
|
|
61
66
|
* Gets price update data which then can be submitted to the Pyth contract to update the prices.
|
|
@@ -86,54 +91,79 @@ class AptosPricePusher {
|
|
|
86
91
|
return;
|
|
87
92
|
}
|
|
88
93
|
try {
|
|
89
|
-
const account = aptos_1.AptosAccount.fromDerivePath(
|
|
94
|
+
const account = aptos_1.AptosAccount.fromDerivePath(exports.APTOS_ACCOUNT_HD_PATH, this.mnemonic);
|
|
90
95
|
const client = new aptos_1.AptosClient(this.endpoint);
|
|
96
|
+
const sequenceNumber = await this.tryGetNextSequenceNumber(client, account);
|
|
91
97
|
const rawTx = await client.generateTransaction(account.address(), {
|
|
92
|
-
function: `${this.pythContractAddress}::pyth::
|
|
98
|
+
function: `${this.pythContractAddress}::pyth::update_price_feeds_with_funder`,
|
|
93
99
|
type_arguments: [],
|
|
94
|
-
arguments: [
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
pubTimesToPush,
|
|
98
|
-
],
|
|
100
|
+
arguments: [priceFeedUpdateData],
|
|
101
|
+
}, {
|
|
102
|
+
sequence_number: sequenceNumber.toFixed(),
|
|
99
103
|
});
|
|
100
|
-
const
|
|
101
|
-
estimateGasUnitPrice: true,
|
|
102
|
-
estimateMaxGasAmount: true,
|
|
103
|
-
estimatePrioritizedGasUnitPrice: true,
|
|
104
|
-
});
|
|
105
|
-
// Transactions on Aptos can be prioritized by paying a higher gas unit price.
|
|
106
|
-
// We are storing the gas unit price paid for the last transaction.
|
|
107
|
-
// If that transaction is not added to the block, we are increasing the gas unit price
|
|
108
|
-
// by multiplying the old gas unit price with `this.overrideGasPriceMultiplier`.
|
|
109
|
-
// After which we are sending a transaction with the same sequence number as the last
|
|
110
|
-
// transaction. Since they have the same sequence number only one of them will be added to
|
|
111
|
-
// the block and we won't be paying fees twice.
|
|
112
|
-
let gasUnitPrice = Number(simulation[0].gas_unit_price);
|
|
113
|
-
if (this.lastPushAttempt !== undefined &&
|
|
114
|
-
Number(simulation[0].sequence_number) === this.lastPushAttempt.nonce) {
|
|
115
|
-
const newGasUnitPrice = Number(this.lastPushAttempt.gasPrice * this.overrideGasPriceMultiplier);
|
|
116
|
-
if (gasUnitPrice < newGasUnitPrice)
|
|
117
|
-
gasUnitPrice = newGasUnitPrice;
|
|
118
|
-
}
|
|
119
|
-
const gasUsed = Number(simulation[0].gas_used) * 1.5;
|
|
120
|
-
const maxGasAmount = Number(gasUnitPrice * gasUsed);
|
|
121
|
-
const rawTxWithFee = new aptos_1.TxnBuilderTypes.RawTransaction(rawTx.sender, rawTx.sequence_number, rawTx.payload, BigInt(maxGasAmount.toFixed()), BigInt(gasUnitPrice.toFixed()), rawTx.expiration_timestamp_secs, rawTx.chain_id);
|
|
122
|
-
const signedTx = await client.signTransaction(account, rawTxWithFee);
|
|
104
|
+
const signedTx = await client.signTransaction(account, rawTx);
|
|
123
105
|
const pendingTx = await client.submitTransaction(signedTx);
|
|
124
|
-
console.log("
|
|
125
|
-
//
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
106
|
+
console.log("Successfully broadcasted txHash:", pendingTx.hash);
|
|
107
|
+
// Sometimes broadcasted txs don't make it on-chain and they cause our sequence number
|
|
108
|
+
// to go out of sync. Missing transactions are rare and we don't want this check to block
|
|
109
|
+
// the next price update. So we use spawn a promise without awaiting on it to wait for the
|
|
110
|
+
// transaction to be confirmed and if it fails, it resets the sequence number and return.
|
|
111
|
+
this.waitForTransactionConfirmation(client, pendingTx.hash);
|
|
130
112
|
return;
|
|
131
113
|
}
|
|
132
114
|
catch (e) {
|
|
133
115
|
console.error("Error executing messages");
|
|
134
|
-
console.
|
|
116
|
+
console.error(e);
|
|
117
|
+
// Reset the sequence number to re-sync it (in case that was the issue)
|
|
118
|
+
this.lastSequenceNumber = undefined;
|
|
135
119
|
return;
|
|
136
120
|
}
|
|
137
121
|
}
|
|
122
|
+
// Wait for the transaction to be confirmed. If it fails, reset the sequence number.
|
|
123
|
+
async waitForTransactionConfirmation(client, txHash) {
|
|
124
|
+
try {
|
|
125
|
+
await client.waitForTransaction(txHash, {
|
|
126
|
+
checkSuccess: true,
|
|
127
|
+
timeoutSecs: 10,
|
|
128
|
+
});
|
|
129
|
+
console.log(`Transaction with txHash "${txHash}" confirmed.`);
|
|
130
|
+
}
|
|
131
|
+
catch (e) {
|
|
132
|
+
console.error(`Transaction with txHash "${txHash}" failed to confirm.`);
|
|
133
|
+
console.error(e);
|
|
134
|
+
this.lastSequenceNumber = undefined;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
// Try to get the next sequence number for account. This function uses a local cache
|
|
138
|
+
// to predict the next sequence number if possible; if not, it fetches the number from
|
|
139
|
+
// the blockchain itself (and caches it for later).
|
|
140
|
+
async tryGetNextSequenceNumber(client, account) {
|
|
141
|
+
if (this.lastSequenceNumber !== undefined) {
|
|
142
|
+
this.lastSequenceNumber += 1;
|
|
143
|
+
return this.lastSequenceNumber;
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
// Fetch from the blockchain if we don't have the local cache.
|
|
147
|
+
// Note that this is locked so that only 1 fetch occurs regardless of how many updates
|
|
148
|
+
// happen during that fetch.
|
|
149
|
+
if (!this.sequenceNumberLocked) {
|
|
150
|
+
try {
|
|
151
|
+
this.sequenceNumberLocked = true;
|
|
152
|
+
this.lastSequenceNumber = Number((await client.getAccount(account.address())).sequence_number);
|
|
153
|
+
console.log(`Fetched account sequence number: ${this.lastSequenceNumber}`);
|
|
154
|
+
return this.lastSequenceNumber;
|
|
155
|
+
}
|
|
156
|
+
catch (e) {
|
|
157
|
+
throw new Error("Failed to retrieve sequence number");
|
|
158
|
+
}
|
|
159
|
+
finally {
|
|
160
|
+
this.sequenceNumberLocked = false;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
throw new Error("Waiting for sequence number in another thread.");
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
138
168
|
}
|
|
139
169
|
exports.AptosPricePusher = AptosPricePusher;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../src/aptos/command.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../src/aptos/command.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;;;;;;;;;;;;;;oBAkCL,GAAG;;AA1B9B,wBA2FE"}
|
package/lib/aptos/command.js
CHANGED
|
@@ -33,6 +33,7 @@ const fs_1 = __importDefault(require("fs"));
|
|
|
33
33
|
const pyth_price_listener_1 = require("../pyth-price-listener");
|
|
34
34
|
const controller_1 = require("../controller");
|
|
35
35
|
const aptos_1 = require("./aptos");
|
|
36
|
+
const aptos_2 = require("aptos");
|
|
36
37
|
exports.default = {
|
|
37
38
|
command: "aptos",
|
|
38
39
|
describe: "run price pusher for aptos",
|
|
@@ -72,6 +73,8 @@ exports.default = {
|
|
|
72
73
|
},
|
|
73
74
|
});
|
|
74
75
|
const mnemonic = fs_1.default.readFileSync(mnemonicFile, "utf-8").trim();
|
|
76
|
+
const account = aptos_2.AptosAccount.fromDerivePath(aptos_1.APTOS_ACCOUNT_HD_PATH, mnemonic);
|
|
77
|
+
console.log(`Pushing from account address: ${account.address()}`);
|
|
75
78
|
const priceItems = priceConfigs.map(({ id, alias }) => ({ id, alias }));
|
|
76
79
|
const pythListener = new pyth_price_listener_1.PythPriceListener(priceServiceConnection, priceItems);
|
|
77
80
|
const aptosListener = new aptos_1.AptosPriceListener(pythContractAddress, endpoint, priceItems, { pollingFrequency });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"injective.d.ts","sourceRoot":"","sources":["../../src/injective/injective.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EACT,sBAAsB,EACvB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EACL,YAAY,EACZ,SAAS,EACT,kBAAkB,EAClB,SAAS,EACV,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAiC7C,qBAAa,sBAAuB,SAAQ,kBAAkB;IAE1D,OAAO,CAAC,mBAAmB;IAC3B,OAAO,CAAC,YAAY;gBADZ,mBAAmB,EAAE,MAAM,EAC3B,YAAY,EAAE,MAAM,EAC5B,UAAU,EAAE,SAAS,EAAE,EACvB,MAAM,EAAE;QACN,gBAAgB,EAAE,iBAAiB,CAAC;KACrC;IAKG,mBAAmB,CACvB,OAAO,EAAE,SAAS,GACjB,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;CA6BlC;AAED,KAAK,eAAe,GAAG;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AACF,qBAAa,oBAAqB,YAAW,YAAY;IAMrD,OAAO,CAAC,sBAAsB;IAC9B,OAAO,CAAC,mBAAmB;IAC3B,OAAO,CAAC,YAAY;IAPtB,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,OAAO,CAAwB;gBAG7B,sBAAsB,EAAE,sBAAsB,EAC9C,mBAAmB,EAAE,MAAM,EAC3B,YAAY,EAAE,MAAM,EAC5B,QAAQ,EAAE,MAAM,EAChB,WAAW,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC;IAWxC,OAAO,CAAC,gBAAgB;YAIV,mBAAmB;IAkE3B,wBAAwB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC;IAU1D,eAAe,CACnB,QAAQ,EAAE,MAAM,EAAE,EAClB,cAAc,EAAE,MAAM,EAAE,GACvB,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"injective.d.ts","sourceRoot":"","sources":["../../src/injective/injective.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EACT,sBAAsB,EACvB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EACL,YAAY,EACZ,SAAS,EACT,kBAAkB,EAClB,SAAS,EACV,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAiC7C,qBAAa,sBAAuB,SAAQ,kBAAkB;IAE1D,OAAO,CAAC,mBAAmB;IAC3B,OAAO,CAAC,YAAY;gBADZ,mBAAmB,EAAE,MAAM,EAC3B,YAAY,EAAE,MAAM,EAC5B,UAAU,EAAE,SAAS,EAAE,EACvB,MAAM,EAAE;QACN,gBAAgB,EAAE,iBAAiB,CAAC;KACrC;IAKG,mBAAmB,CACvB,OAAO,EAAE,SAAS,GACjB,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;CA6BlC;AAED,KAAK,eAAe,GAAG;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AACF,qBAAa,oBAAqB,YAAW,YAAY;IAMrD,OAAO,CAAC,sBAAsB;IAC9B,OAAO,CAAC,mBAAmB;IAC3B,OAAO,CAAC,YAAY;IAPtB,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,OAAO,CAAwB;gBAG7B,sBAAsB,EAAE,sBAAsB,EAC9C,mBAAmB,EAAE,MAAM,EAC3B,YAAY,EAAE,MAAM,EAC5B,QAAQ,EAAE,MAAM,EAChB,WAAW,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC;IAWxC,OAAO,CAAC,gBAAgB;YAIV,mBAAmB;IAkE3B,wBAAwB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC;IAU1D,eAAe,CACnB,QAAQ,EAAE,MAAM,EAAE,EAClB,cAAc,EAAE,MAAM,EAAE,GACvB,OAAO,CAAC,IAAI,CAAC;CAmEjB"}
|
|
@@ -134,12 +134,22 @@ class InjectivePricePusher {
|
|
|
134
134
|
console.error(e);
|
|
135
135
|
return;
|
|
136
136
|
}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
137
|
+
let updateFeeQueryResponse;
|
|
138
|
+
try {
|
|
139
|
+
const api = new sdk_ts_1.ChainGrpcWasmApi(this.grpcEndpoint);
|
|
140
|
+
const { data } = await api.fetchSmartContractState(this.pythContractAddress, Buffer.from(JSON.stringify({
|
|
141
|
+
get_update_fee: {
|
|
142
|
+
vaas: priceFeedUpdateObject.update_price_feeds.data,
|
|
143
|
+
},
|
|
144
|
+
})).toString("base64"));
|
|
145
|
+
const json = Buffer.from(data).toString();
|
|
146
|
+
updateFeeQueryResponse = JSON.parse(json);
|
|
147
|
+
}
|
|
148
|
+
catch (e) {
|
|
149
|
+
console.error("Error fetching update fee");
|
|
150
|
+
console.error(e);
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
143
153
|
try {
|
|
144
154
|
const executeMsg = sdk_ts_1.MsgExecuteContract.fromJSON({
|
|
145
155
|
sender: this.injectiveAddress(),
|
package/lib/sui/command.js
CHANGED
|
@@ -50,31 +50,31 @@ exports.default = {
|
|
|
50
50
|
},
|
|
51
51
|
"pyth-package-id": {
|
|
52
52
|
description: "Pyth Package Id. Can be found here" +
|
|
53
|
-
"https://docs.pyth.network/pythnet-price-feeds/sui",
|
|
53
|
+
"https://docs.pyth.network/documentation/pythnet-price-feeds/sui",
|
|
54
54
|
type: "string",
|
|
55
55
|
required: true,
|
|
56
56
|
},
|
|
57
57
|
"pyth-state-id": {
|
|
58
58
|
description: "Pyth State Id. Can be found here" +
|
|
59
|
-
"https://docs.pyth.network/pythnet-price-feeds/sui",
|
|
59
|
+
"https://docs.pyth.network/documentation/pythnet-price-feeds/sui",
|
|
60
60
|
type: "string",
|
|
61
61
|
required: true,
|
|
62
62
|
},
|
|
63
63
|
"wormhole-package-id": {
|
|
64
64
|
description: "Wormhole Package Id. Can be found here" +
|
|
65
|
-
"https://docs.pyth.network/pythnet-price-feeds/sui",
|
|
65
|
+
"https://docs.pyth.network/documentation/pythnet-price-feeds/sui",
|
|
66
66
|
type: "string",
|
|
67
67
|
required: true,
|
|
68
68
|
},
|
|
69
69
|
"wormhole-state-id": {
|
|
70
70
|
description: "Wormhole State Id. Can be found here" +
|
|
71
|
-
"https://docs.pyth.network/pythnet-price-feeds/sui",
|
|
71
|
+
"https://docs.pyth.network/documentation/pythnet-price-feeds/sui",
|
|
72
72
|
type: "string",
|
|
73
73
|
required: true,
|
|
74
74
|
},
|
|
75
75
|
"price-feed-to-price-info-object-table-id": {
|
|
76
76
|
description: "This is the id of the table which stored the information related to price data. You can find it here: " +
|
|
77
|
-
"https://docs.pyth.network/pythnet-price-feeds/sui",
|
|
77
|
+
"https://docs.pyth.network/documentation/pythnet-price-feeds/sui",
|
|
78
78
|
type: "string",
|
|
79
79
|
required: true,
|
|
80
80
|
},
|
package/lib/sui/sui.d.ts
CHANGED
|
@@ -35,6 +35,7 @@ export declare class SuiPricePusher implements IPricePusher {
|
|
|
35
35
|
/** Send a single transaction block using a gas coin from the pool. */
|
|
36
36
|
private sendTransactionBlock;
|
|
37
37
|
private static initializeGasPool;
|
|
38
|
+
private static tryRefreshObjectReference;
|
|
38
39
|
private static getAllGasCoins;
|
|
39
40
|
private static splitGasCoinEqually;
|
|
40
41
|
private static mergeGasCoinsIntoOne;
|
package/lib/sui/sui.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sui.d.ts","sourceRoot":"","sources":["../../src/sui/sui.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,YAAY,EACZ,SAAS,EACT,SAAS,EACV,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,CAAC;AAC3E,OAAO,EAIL,SAAS,EAIT,YAAY,EAKb,MAAM,gBAAgB,CAAC;AAMxB,qBAAa,gBAAiB,SAAQ,kBAAkB;IAEpD,OAAO,CAAC,aAAa;IACrB,OAAO,CAAC,iCAAiC;IACzC,OAAO,CAAC,QAAQ;gBAFR,aAAa,EAAE,MAAM,EACrB,iCAAiC,EAAE,MAAM,EACzC,QAAQ,EAAE,MAAM,EACxB,UAAU,EAAE,SAAS,EAAE,EACvB,MAAM,EAAE;QACN,gBAAgB,EAAE,iBAAiB,CAAC;KACrC;IAKG,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;CAmD3E;AAED,qBAAa,cAAe,YAAW,YAAY;IAE/C,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,sBAAsB;IAC9B,OAAO,CAAC,aAAa;IACrB,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,iBAAiB;IACzB,OAAO,CAAC,eAAe;IACvB,OAAO,CAAC,iCAAiC;IACzC,OAAO,CAAC,aAAa;IAGrB,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,OAAO;gBAXE,MAAM,EAAE,SAAS,EAC1B,sBAAsB,EAAE,sBAAsB,EAC9C,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,EACnB,iBAAiB,EAAE,MAAM,EACzB,eAAe,EAAE,MAAM,EACvB,iCAAiC,EAAE,MAAM,EACzC,aAAa,EAAE,MAAM,EAC7B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EACR,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,YAAY,EAAE;IAGjC;;;OAGG;WACU,0BAA0B,CACrC,sBAAsB,EAAE,sBAAsB,EAC9C,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,EACnB,iBAAiB,EAAE,MAAM,EACzB,eAAe,EAAE,MAAM,EACvB,iCAAiC,EAAE,MAAM,EACzC,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,cAAc,CAAC;IAiCpB,eAAe,CACnB,QAAQ,EAAE,MAAM,EAAE,EAClB,cAAc,EAAE,MAAM,EAAE,GACvB,OAAO,CAAC,IAAI,CAAC;YAsDF,4BAA4B;IA2E1C,iGAAiG;YACnF,qBAAqB;IAMnC,sEAAsE;YACxD,oBAAoB;
|
|
1
|
+
{"version":3,"file":"sui.d.ts","sourceRoot":"","sources":["../../src/sui/sui.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,YAAY,EACZ,SAAS,EACT,SAAS,EACV,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,CAAC;AAC3E,OAAO,EAIL,SAAS,EAIT,YAAY,EAKb,MAAM,gBAAgB,CAAC;AAMxB,qBAAa,gBAAiB,SAAQ,kBAAkB;IAEpD,OAAO,CAAC,aAAa;IACrB,OAAO,CAAC,iCAAiC;IACzC,OAAO,CAAC,QAAQ;gBAFR,aAAa,EAAE,MAAM,EACrB,iCAAiC,EAAE,MAAM,EACzC,QAAQ,EAAE,MAAM,EACxB,UAAU,EAAE,SAAS,EAAE,EACvB,MAAM,EAAE;QACN,gBAAgB,EAAE,iBAAiB,CAAC;KACrC;IAKG,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;CAmD3E;AAED,qBAAa,cAAe,YAAW,YAAY;IAE/C,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,sBAAsB;IAC9B,OAAO,CAAC,aAAa;IACrB,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,iBAAiB;IACzB,OAAO,CAAC,eAAe;IACvB,OAAO,CAAC,iCAAiC;IACzC,OAAO,CAAC,aAAa;IAGrB,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,OAAO;gBAXE,MAAM,EAAE,SAAS,EAC1B,sBAAsB,EAAE,sBAAsB,EAC9C,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,EACnB,iBAAiB,EAAE,MAAM,EACzB,eAAe,EAAE,MAAM,EACvB,iCAAiC,EAAE,MAAM,EACzC,aAAa,EAAE,MAAM,EAC7B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EACR,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,YAAY,EAAE;IAGjC;;;OAGG;WACU,0BAA0B,CACrC,sBAAsB,EAAE,sBAAsB,EAC9C,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,EACnB,iBAAiB,EAAE,MAAM,EACzB,eAAe,EAAE,MAAM,EACvB,iCAAiC,EAAE,MAAM,EACzC,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,cAAc,CAAC;IAiCpB,eAAe,CACnB,QAAQ,EAAE,MAAM,EAAE,EAClB,cAAc,EAAE,MAAM,EAAE,GACvB,OAAO,CAAC,IAAI,CAAC;YAsDF,4BAA4B;IA2E1C,iGAAiG;YACnF,qBAAqB;IAMnC,sEAAsE;YACxD,oBAAoB;mBAsDb,iBAAiB;mBA8BjB,yBAAyB;mBAoBzB,cAAc;mBAiCd,mBAAmB;mBAsCnB,oBAAoB;CA2C1C"}
|
package/lib/sui/sui.js
CHANGED
|
@@ -222,9 +222,14 @@ class SuiPricePusher {
|
|
|
222
222
|
console.warn(`The balance of gas object ${gasObject.objectId} is too low. Removing from pool.`);
|
|
223
223
|
}
|
|
224
224
|
else {
|
|
225
|
-
|
|
225
|
+
// Refresh the coin object here in case the error is caused by an object version mismatch.
|
|
226
|
+
nextGasObject = await SuiPricePusher.tryRefreshObjectReference(this.signer.provider, gasObject);
|
|
226
227
|
}
|
|
227
228
|
console.error(e);
|
|
229
|
+
if ("data" in e) {
|
|
230
|
+
console.error("Error has .data field:");
|
|
231
|
+
console.error(JSON.stringify(e.data));
|
|
232
|
+
}
|
|
228
233
|
}
|
|
229
234
|
if (nextGasObject !== undefined) {
|
|
230
235
|
this.gasPool.push(nextGasObject);
|
|
@@ -243,6 +248,27 @@ class SuiPricePusher {
|
|
|
243
248
|
console.log("Gas pool is filled with coins: ", gasPool);
|
|
244
249
|
return gasPool;
|
|
245
250
|
}
|
|
251
|
+
// Attempt to refresh the version of the provided object reference to point to the current version
|
|
252
|
+
// of the object. Return the provided object reference if an error occurs or the object could not
|
|
253
|
+
// be retrieved.
|
|
254
|
+
static async tryRefreshObjectReference(provider, ref) {
|
|
255
|
+
try {
|
|
256
|
+
const objectResponse = await provider.getObject({ id: ref.objectId });
|
|
257
|
+
if (objectResponse.data !== undefined) {
|
|
258
|
+
return {
|
|
259
|
+
digest: objectResponse.data.digest,
|
|
260
|
+
objectId: objectResponse.data.objectId,
|
|
261
|
+
version: objectResponse.data.version,
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
else {
|
|
265
|
+
return ref;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
catch (error) {
|
|
269
|
+
return ref;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
246
272
|
static async getAllGasCoins(provider, owner) {
|
|
247
273
|
let hasNextPage = true;
|
|
248
274
|
let cursor;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pythnetwork/price-pusher",
|
|
3
|
-
"version": "5.4.
|
|
3
|
+
"version": "5.4.8",
|
|
4
4
|
"description": "Pyth Price Pusher",
|
|
5
5
|
"homepage": "https://pyth.network",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -63,5 +63,5 @@
|
|
|
63
63
|
"yaml": "^2.1.1",
|
|
64
64
|
"yargs": "^17.5.1"
|
|
65
65
|
},
|
|
66
|
-
"gitHead": "
|
|
66
|
+
"gitHead": "55129e5b891b0ce0271dbee69a8b4b7512a222d1"
|
|
67
67
|
}
|