@kairoguard/sdk 0.0.13 → 0.0.14
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/client.js +25 -11
- package/dist/price.d.ts +2 -0
- package/dist/price.js +65 -0
- package/package.json +1 -1
package/dist/client.js
CHANGED
|
@@ -14,6 +14,7 @@ import { Curve, fetchProtocolParams, deriveEncryptionKeys, generateSeed, generat
|
|
|
14
14
|
import { Hash, SignatureAlgorithm, createUserSignMessageWithPublicOutput } from "@ika.xyz/sdk";
|
|
15
15
|
import { computeEvmIntentFromUnsignedTxBytes } from "./evmIntent.js";
|
|
16
16
|
import { keccak256, recoverTransactionAddress, serializeTransaction, } from "viem";
|
|
17
|
+
import { convertWeiToUsdMicros, fetchEthUsdMicros } from "./price.js";
|
|
17
18
|
const FALLBACK_SUI_RPC = "https://fullnode.testnet.sui.io:443";
|
|
18
19
|
async function testRpcEndpoint(url) {
|
|
19
20
|
try {
|
|
@@ -752,17 +753,30 @@ export class KairoClient {
|
|
|
752
753
|
if (!wallet.policyObjectId || !wallet.bindingObjectId) {
|
|
753
754
|
throw new Error("Wallet is missing policy binding metadata. Provision the wallet via dashboard or SDK before signing.");
|
|
754
755
|
}
|
|
755
|
-
const mintOnce = () =>
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
756
|
+
const mintOnce = async () => {
|
|
757
|
+
let normalizedNativeValue = ctx.nativeValue;
|
|
758
|
+
// MaxNativeValue rules are encoded in USD-micros; normalize EVM wei inputs.
|
|
759
|
+
if (ctx.namespace === 1) {
|
|
760
|
+
try {
|
|
761
|
+
const ethUsdMicros = await fetchEthUsdMicros();
|
|
762
|
+
normalizedNativeValue = convertWeiToUsdMicros(ctx.nativeValue, ethUsdMicros);
|
|
763
|
+
}
|
|
764
|
+
catch {
|
|
765
|
+
// Keep raw value as fallback if price feed is unavailable.
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
return this.backend.mintReceipt({
|
|
769
|
+
policyObjectId: wallet.policyObjectId ?? undefined,
|
|
770
|
+
bindingObjectId: wallet.bindingObjectId,
|
|
771
|
+
namespace: ctx.namespace,
|
|
772
|
+
// chainId is encoded as u64 bytes (16 hex chars)
|
|
773
|
+
chainId: ctx.chainId.toString(16).padStart(16, "0"),
|
|
774
|
+
intentHashHex: stripHexPrefix(ctx.intentHashHex),
|
|
775
|
+
destinationHex: stripHexPrefix(ctx.destinationHex),
|
|
776
|
+
nativeValueHex: normalizedNativeValue.toString(16).padStart(64, "0"),
|
|
777
|
+
contextDataHex: ctx.contextDataHex ? stripHexPrefix(ctx.contextDataHex) : undefined,
|
|
778
|
+
});
|
|
779
|
+
};
|
|
766
780
|
let response = await mintOnce();
|
|
767
781
|
const initialError = String(response?.error ?? "");
|
|
768
782
|
if (response.success === false && this.isReaffirmRequiredError(initialError)) {
|
package/dist/price.d.ts
ADDED
package/dist/price.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
const WEI_PER_ETH = 1000000000000000000n;
|
|
2
|
+
const USD_MICROS_SCALE = 1000000n;
|
|
3
|
+
const CACHE_MS = 60_000;
|
|
4
|
+
let cachedEthUsdMicros = null;
|
|
5
|
+
function parseUsdToMicros(input) {
|
|
6
|
+
const s = input.trim();
|
|
7
|
+
if (!s)
|
|
8
|
+
throw new Error("ETH/USD response is empty");
|
|
9
|
+
if (!/^\d+(\.\d+)?$/.test(s)) {
|
|
10
|
+
throw new Error(`Invalid ETH/USD amount: ${s}`);
|
|
11
|
+
}
|
|
12
|
+
const [wholeRaw, fracRaw = ""] = s.split(".");
|
|
13
|
+
const whole = BigInt(wholeRaw);
|
|
14
|
+
const frac = BigInt((fracRaw + "000000").slice(0, 6));
|
|
15
|
+
return whole * USD_MICROS_SCALE + frac;
|
|
16
|
+
}
|
|
17
|
+
async function fetchJsonWithTimeout(url, timeoutMs) {
|
|
18
|
+
const ctrl = new AbortController();
|
|
19
|
+
const timer = setTimeout(() => ctrl.abort(), timeoutMs);
|
|
20
|
+
try {
|
|
21
|
+
const resp = await fetch(url, { signal: ctrl.signal });
|
|
22
|
+
if (!resp.ok) {
|
|
23
|
+
throw new Error(`HTTP ${resp.status} from ${url}`);
|
|
24
|
+
}
|
|
25
|
+
return await resp.json();
|
|
26
|
+
}
|
|
27
|
+
finally {
|
|
28
|
+
clearTimeout(timer);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
export async function fetchEthUsdMicros() {
|
|
32
|
+
const now = Date.now();
|
|
33
|
+
if (cachedEthUsdMicros && now - cachedEthUsdMicros.atMs < CACHE_MS) {
|
|
34
|
+
return cachedEthUsdMicros.value;
|
|
35
|
+
}
|
|
36
|
+
const providers = [
|
|
37
|
+
async () => {
|
|
38
|
+
const j = await fetchJsonWithTimeout("https://api.coinbase.com/v2/prices/ETH-USD/spot", 7000);
|
|
39
|
+
const amount = String(j?.data?.amount ?? "").trim();
|
|
40
|
+
return parseUsdToMicros(amount);
|
|
41
|
+
},
|
|
42
|
+
async () => {
|
|
43
|
+
const j = await fetchJsonWithTimeout("https://api.coingecko.com/api/v3/simple/price?ids=ethereum&vs_currencies=usd", 7000);
|
|
44
|
+
const amount = String(j?.ethereum?.usd ?? "").trim();
|
|
45
|
+
return parseUsdToMicros(amount);
|
|
46
|
+
},
|
|
47
|
+
];
|
|
48
|
+
let lastErr = null;
|
|
49
|
+
for (const getPrice of providers) {
|
|
50
|
+
try {
|
|
51
|
+
const value = await getPrice();
|
|
52
|
+
if (value > 0n) {
|
|
53
|
+
cachedEthUsdMicros = { value, atMs: now };
|
|
54
|
+
return value;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
lastErr = error;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
throw new Error(`Could not fetch ETH/USD price${lastErr ? `: ${lastErr instanceof Error ? lastErr.message : String(lastErr)}` : ""}`);
|
|
62
|
+
}
|
|
63
|
+
export function convertWeiToUsdMicros(weiValue, ethUsdMicros) {
|
|
64
|
+
return (weiValue * ethUsdMicros) / WEI_PER_ETH;
|
|
65
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kairoguard/sdk",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.14",
|
|
4
4
|
"description": "Kairo SDK for multi-chain policy-based transaction signing with dWallet support (EVM, Bitcoin, Solana, Sui)",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Kairo <mehraab@thewidercollective.com>",
|