lampamazaza-new-intents-sdk 0.47.1
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/LICENSE +21 -0
- package/README.md +1083 -0
- package/dist/_virtual/rolldown_runtime.cjs +29 -0
- package/dist/index.cjs +124 -0
- package/dist/index.d.cts +22 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.js +19 -0
- package/dist/src/bridges/aurora-engine-bridge/aurora-engine-bridge-constants.cjs +10 -0
- package/dist/src/bridges/aurora-engine-bridge/aurora-engine-bridge-constants.js +7 -0
- package/dist/src/bridges/aurora-engine-bridge/aurora-engine-bridge-utils.cjs +44 -0
- package/dist/src/bridges/aurora-engine-bridge/aurora-engine-bridge-utils.js +42 -0
- package/dist/src/bridges/aurora-engine-bridge/aurora-engine-bridge.cjs +111 -0
- package/dist/src/bridges/aurora-engine-bridge/aurora-engine-bridge.js +110 -0
- package/dist/src/bridges/direct-bridge/direct-bridge-constants.cjs +8 -0
- package/dist/src/bridges/direct-bridge/direct-bridge-constants.js +6 -0
- package/dist/src/bridges/direct-bridge/direct-bridge-utils.cjs +47 -0
- package/dist/src/bridges/direct-bridge/direct-bridge-utils.js +44 -0
- package/dist/src/bridges/direct-bridge/direct-bridge.cjs +155 -0
- package/dist/src/bridges/direct-bridge/direct-bridge.js +154 -0
- package/dist/src/bridges/direct-bridge/error.cjs +16 -0
- package/dist/src/bridges/direct-bridge/error.d.cts +12 -0
- package/dist/src/bridges/direct-bridge/error.d.ts +12 -0
- package/dist/src/bridges/direct-bridge/error.js +15 -0
- package/dist/src/bridges/hot-bridge/error.cjs +23 -0
- package/dist/src/bridges/hot-bridge/error.d.cts +19 -0
- package/dist/src/bridges/hot-bridge/error.d.ts +19 -0
- package/dist/src/bridges/hot-bridge/error.js +21 -0
- package/dist/src/bridges/hot-bridge/hot-bridge-chains.cjs +21 -0
- package/dist/src/bridges/hot-bridge/hot-bridge-chains.d.cts +6 -0
- package/dist/src/bridges/hot-bridge/hot-bridge-chains.d.ts +6 -0
- package/dist/src/bridges/hot-bridge/hot-bridge-chains.js +20 -0
- package/dist/src/bridges/hot-bridge/hot-bridge-constants.cjs +11 -0
- package/dist/src/bridges/hot-bridge/hot-bridge-constants.js +9 -0
- package/dist/src/bridges/hot-bridge/hot-bridge-utils.cjs +66 -0
- package/dist/src/bridges/hot-bridge/hot-bridge-utils.js +61 -0
- package/dist/src/bridges/hot-bridge/hot-bridge.cjs +241 -0
- package/dist/src/bridges/hot-bridge/hot-bridge.js +239 -0
- package/dist/src/bridges/intents-bridge/intents-bridge.cjs +59 -0
- package/dist/src/bridges/intents-bridge/intents-bridge.js +59 -0
- package/dist/src/bridges/omni-bridge/error.cjs +54 -0
- package/dist/src/bridges/omni-bridge/error.d.cts +41 -0
- package/dist/src/bridges/omni-bridge/error.d.ts +41 -0
- package/dist/src/bridges/omni-bridge/error.js +49 -0
- package/dist/src/bridges/omni-bridge/omni-bridge-constants.cjs +12 -0
- package/dist/src/bridges/omni-bridge/omni-bridge-constants.js +8 -0
- package/dist/src/bridges/omni-bridge/omni-bridge-utils.cjs +153 -0
- package/dist/src/bridges/omni-bridge/omni-bridge-utils.js +143 -0
- package/dist/src/bridges/omni-bridge/omni-bridge.cjs +316 -0
- package/dist/src/bridges/omni-bridge/omni-bridge.js +314 -0
- package/dist/src/bridges/poa-bridge/poa-bridge-utils.cjs +76 -0
- package/dist/src/bridges/poa-bridge/poa-bridge-utils.js +73 -0
- package/dist/src/bridges/poa-bridge/poa-bridge.cjs +175 -0
- package/dist/src/bridges/poa-bridge/poa-bridge.js +173 -0
- package/dist/src/bridges/poa-bridge/poa-constants.cjs +6 -0
- package/dist/src/bridges/poa-bridge/poa-constants.js +5 -0
- package/dist/src/classes/errors.cjs +87 -0
- package/dist/src/classes/errors.d.cts +48 -0
- package/dist/src/classes/errors.d.ts +48 -0
- package/dist/src/classes/errors.js +81 -0
- package/dist/src/constants/bridge-name-enum.cjs +11 -0
- package/dist/src/constants/bridge-name-enum.d.cts +11 -0
- package/dist/src/constants/bridge-name-enum.d.ts +11 -0
- package/dist/src/constants/bridge-name-enum.js +10 -0
- package/dist/src/constants/poa-tokens-routable-through-omni-bridge.cjs +17 -0
- package/dist/src/constants/poa-tokens-routable-through-omni-bridge.d.cts +12 -0
- package/dist/src/constants/poa-tokens-routable-through-omni-bridge.d.ts +12 -0
- package/dist/src/constants/poa-tokens-routable-through-omni-bridge.js +16 -0
- package/dist/src/constants/public-rpc-urls.cjs +25 -0
- package/dist/src/constants/public-rpc-urls.js +24 -0
- package/dist/src/constants/route-enum.cjs +13 -0
- package/dist/src/constants/route-enum.d.cts +13 -0
- package/dist/src/constants/route-enum.d.ts +13 -0
- package/dist/src/constants/route-enum.js +12 -0
- package/dist/src/constants/withdrawal-timing.cjs +68 -0
- package/dist/src/constants/withdrawal-timing.js +68 -0
- package/dist/src/core/withdrawal-watcher.cjs +86 -0
- package/dist/src/core/withdrawal-watcher.d.cts +18 -0
- package/dist/src/core/withdrawal-watcher.d.ts +19 -0
- package/dist/src/core/withdrawal-watcher.js +82 -0
- package/dist/src/intents/expirable-nonce.cjs +90 -0
- package/dist/src/intents/expirable-nonce.d.cts +44 -0
- package/dist/src/intents/expirable-nonce.d.ts +45 -0
- package/dist/src/intents/expirable-nonce.js +82 -0
- package/dist/src/intents/intent-executer-impl/intent-executer.cjs +85 -0
- package/dist/src/intents/intent-executer-impl/intent-executer.d.cts +20 -0
- package/dist/src/intents/intent-executer-impl/intent-executer.d.ts +24 -0
- package/dist/src/intents/intent-executer-impl/intent-executer.js +85 -0
- package/dist/src/intents/intent-hash.cjs +48 -0
- package/dist/src/intents/intent-hash.d.cts +8 -0
- package/dist/src/intents/intent-hash.d.ts +8 -0
- package/dist/src/intents/intent-hash.js +47 -0
- package/dist/src/intents/intent-hashes/erc191.cjs +38 -0
- package/dist/src/intents/intent-hashes/erc191.js +37 -0
- package/dist/src/intents/intent-hashes/nep413.cjs +23 -0
- package/dist/src/intents/intent-hashes/nep413.js +22 -0
- package/dist/src/intents/intent-hashes/raw-ed25519.cjs +26 -0
- package/dist/src/intents/intent-hashes/raw-ed25519.js +25 -0
- package/dist/src/intents/intent-hashes/sep53.cjs +36 -0
- package/dist/src/intents/intent-hashes/sep53.js +35 -0
- package/dist/src/intents/intent-hashes/tip191.cjs +39 -0
- package/dist/src/intents/intent-hashes/tip191.js +38 -0
- package/dist/src/intents/intent-hashes/ton-connect.cjs +105 -0
- package/dist/src/intents/intent-hashes/ton-connect.js +104 -0
- package/dist/src/intents/intent-hashes/webauthn.cjs +26 -0
- package/dist/src/intents/intent-hashes/webauthn.js +25 -0
- package/dist/src/intents/intent-payload-builder.cjs +208 -0
- package/dist/src/intents/intent-payload-builder.d.cts +161 -0
- package/dist/src/intents/intent-payload-builder.d.ts +161 -0
- package/dist/src/intents/intent-payload-builder.js +207 -0
- package/dist/src/intents/intent-payload-factory.cjs +23 -0
- package/dist/src/intents/intent-payload-factory.js +21 -0
- package/dist/src/intents/intent-relayer-impl/intent-relayer-public.cjs +43 -0
- package/dist/src/intents/intent-relayer-impl/intent-relayer-public.js +42 -0
- package/dist/src/intents/intent-signer-impl/factories.cjs +19 -0
- package/dist/src/intents/intent-signer-impl/factories.d.cts +11 -0
- package/dist/src/intents/intent-signer-impl/factories.d.ts +11 -0
- package/dist/src/intents/intent-signer-impl/factories.js +17 -0
- package/dist/src/intents/intent-signer-impl/intent-signer-near-keypair.cjs +22 -0
- package/dist/src/intents/intent-signer-impl/intent-signer-near-keypair.d.cts +15 -0
- package/dist/src/intents/intent-signer-impl/intent-signer-near-keypair.d.ts +16 -0
- package/dist/src/intents/intent-signer-impl/intent-signer-near-keypair.js +21 -0
- package/dist/src/intents/intent-signer-impl/intent-signer-nep413.cjs +37 -0
- package/dist/src/intents/intent-signer-impl/intent-signer-nep413.d.cts +14 -0
- package/dist/src/intents/intent-signer-impl/intent-signer-nep413.d.ts +14 -0
- package/dist/src/intents/intent-signer-impl/intent-signer-nep413.js +36 -0
- package/dist/src/intents/intent-signer-impl/intent-signer-noop.cjs +8 -0
- package/dist/src/intents/intent-signer-impl/intent-signer-noop.js +7 -0
- package/dist/src/intents/intent-signer-impl/intent-signer-viem.cjs +31 -0
- package/dist/src/intents/intent-signer-impl/intent-signer-viem.d.cts +17 -0
- package/dist/src/intents/intent-signer-impl/intent-signer-viem.d.ts +17 -0
- package/dist/src/intents/intent-signer-impl/intent-signer-viem.js +30 -0
- package/dist/src/intents/interfaces/intent-executer.d.ts +2 -0
- package/dist/src/intents/interfaces/intent-relayer.d.cts +43 -0
- package/dist/src/intents/interfaces/intent-relayer.d.ts +43 -0
- package/dist/src/intents/interfaces/intent-signer.d.cts +8 -0
- package/dist/src/intents/interfaces/intent-signer.d.ts +8 -0
- package/dist/src/intents/interfaces/salt-manager.d.cts +9 -0
- package/dist/src/intents/interfaces/salt-manager.d.ts +9 -0
- package/dist/src/intents/salt-manager.cjs +74 -0
- package/dist/src/intents/salt-manager.js +72 -0
- package/dist/src/intents/shared-types.d.cts +20 -0
- package/dist/src/intents/shared-types.d.ts +20 -0
- package/dist/src/lib/array.cjs +11 -0
- package/dist/src/lib/array.js +10 -0
- package/dist/src/lib/caip2.cjs +50 -0
- package/dist/src/lib/caip2.d.cts +38 -0
- package/dist/src/lib/caip2.d.ts +38 -0
- package/dist/src/lib/caip2.js +48 -0
- package/dist/src/lib/configure-rpc-config.cjs +20 -0
- package/dist/src/lib/configure-rpc-config.js +18 -0
- package/dist/src/lib/estimate-fee.cjs +96 -0
- package/dist/src/lib/estimate-fee.js +94 -0
- package/dist/src/lib/hex.cjs +11 -0
- package/dist/src/lib/hex.js +10 -0
- package/dist/src/lib/nep413.cjs +42 -0
- package/dist/src/lib/nep413.d.cts +14 -0
- package/dist/src/lib/nep413.d.ts +14 -0
- package/dist/src/lib/nep413.js +41 -0
- package/dist/src/lib/object.cjs +10 -0
- package/dist/src/lib/object.js +9 -0
- package/dist/src/lib/parse-defuse-asset-id.cjs +15 -0
- package/dist/src/lib/parse-defuse-asset-id.js +14 -0
- package/dist/src/lib/route-config-factory.cjs +43 -0
- package/dist/src/lib/route-config-factory.d.cts +13 -0
- package/dist/src/lib/route-config-factory.d.ts +13 -0
- package/dist/src/lib/route-config-factory.js +37 -0
- package/dist/src/lib/tokensUsdPricesHttpClient/apis.cjs +17 -0
- package/dist/src/lib/tokensUsdPricesHttpClient/apis.js +16 -0
- package/dist/src/lib/validateAddress.cjs +271 -0
- package/dist/src/lib/validateAddress.d.cts +14 -0
- package/dist/src/lib/validateAddress.d.ts +14 -0
- package/dist/src/lib/validateAddress.js +270 -0
- package/dist/src/sdk.cjs +435 -0
- package/dist/src/sdk.d.cts +231 -0
- package/dist/src/sdk.d.ts +231 -0
- package/dist/src/sdk.js +433 -0
- package/dist/src/shared-types.d.cts +378 -0
- package/dist/src/shared-types.d.ts +378 -0
- package/package.json +62 -0
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { getWithdrawalStatsForChain } from "../constants/withdrawal-timing.js";
|
|
2
|
+
import { BaseError, POLL_PENDING, PollTimeoutError, poll } from "lampamazaza-internal-utils";
|
|
3
|
+
|
|
4
|
+
//#region src/core/withdrawal-watcher.ts
|
|
5
|
+
const MAX_CONSECUTIVE_ERRORS = 3;
|
|
6
|
+
async function watchWithdrawal(args) {
|
|
7
|
+
const stats = getWithdrawalStatsForChain({
|
|
8
|
+
chain: args.wid.landingChain,
|
|
9
|
+
bridgeRoute: args.bridge.route
|
|
10
|
+
});
|
|
11
|
+
let consecutiveErrors = 0;
|
|
12
|
+
try {
|
|
13
|
+
return await poll(async () => {
|
|
14
|
+
try {
|
|
15
|
+
const status = await args.bridge.describeWithdrawal({
|
|
16
|
+
...args.wid,
|
|
17
|
+
logger: args.logger
|
|
18
|
+
});
|
|
19
|
+
consecutiveErrors = 0;
|
|
20
|
+
if (status.status === "completed") return status.txHash != null ? { hash: status.txHash } : { hash: null };
|
|
21
|
+
if (status.status === "failed") throw new WithdrawalFailedError(status.reason);
|
|
22
|
+
return POLL_PENDING;
|
|
23
|
+
} catch (err) {
|
|
24
|
+
if (err instanceof WithdrawalFailedError) throw err;
|
|
25
|
+
consecutiveErrors++;
|
|
26
|
+
if (consecutiveErrors >= MAX_CONSECUTIVE_ERRORS) throw new WithdrawalWatchError(err);
|
|
27
|
+
args.logger?.warn(`Transient error (${consecutiveErrors}/${MAX_CONSECUTIVE_ERRORS}): ${err}`);
|
|
28
|
+
return POLL_PENDING;
|
|
29
|
+
}
|
|
30
|
+
}, {
|
|
31
|
+
stats,
|
|
32
|
+
signal: args.signal
|
|
33
|
+
});
|
|
34
|
+
} catch (err) {
|
|
35
|
+
if (err instanceof PollTimeoutError) throw new WithdrawalWatchError(err);
|
|
36
|
+
throw err;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
async function createWithdrawalIdentifiers(args) {
|
|
40
|
+
const indexes = /* @__PURE__ */ new Map();
|
|
41
|
+
const results = [];
|
|
42
|
+
for (const w of args.withdrawalParams) {
|
|
43
|
+
const bridge = await findBridgeForWithdrawal(args.bridges, w);
|
|
44
|
+
if (bridge == null) throw new BridgeNotFoundError();
|
|
45
|
+
const currentIndex = indexes.get(bridge.route) ?? 0;
|
|
46
|
+
indexes.set(bridge.route, currentIndex + 1);
|
|
47
|
+
const wid = bridge.createWithdrawalIdentifier({
|
|
48
|
+
withdrawalParams: w,
|
|
49
|
+
index: currentIndex,
|
|
50
|
+
tx: args.intentTx
|
|
51
|
+
});
|
|
52
|
+
results.push({
|
|
53
|
+
bridge,
|
|
54
|
+
wid
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
return results;
|
|
58
|
+
}
|
|
59
|
+
async function findBridgeForWithdrawal(bridges, params) {
|
|
60
|
+
for (const bridge of bridges) if (await bridge.supports(params)) return bridge;
|
|
61
|
+
}
|
|
62
|
+
var BridgeNotFoundError = class extends BaseError {
|
|
63
|
+
constructor() {
|
|
64
|
+
super("Bridge adapter not found", { name: "BridgeNotFoundError" });
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
var WithdrawalFailedError = class extends BaseError {
|
|
68
|
+
constructor(reason) {
|
|
69
|
+
super(`Withdrawal failed: ${reason}`, { name: "WithdrawalFailedError" });
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
var WithdrawalWatchError = class extends BaseError {
|
|
73
|
+
constructor(cause) {
|
|
74
|
+
super("Withdrawal watch failed", {
|
|
75
|
+
name: "WithdrawalWatchError",
|
|
76
|
+
cause
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
//#endregion
|
|
82
|
+
export { WithdrawalFailedError, WithdrawalWatchError, createWithdrawalIdentifiers, watchWithdrawal };
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
const require_rolldown_runtime = require('../../_virtual/rolldown_runtime.cjs');
|
|
2
|
+
let _scure_base = require("@scure/base");
|
|
3
|
+
let valibot = require("valibot");
|
|
4
|
+
valibot = require_rolldown_runtime.__toESM(valibot);
|
|
5
|
+
let near_api_js_lib_utils_serialize = require("near-api-js/lib/utils/serialize");
|
|
6
|
+
|
|
7
|
+
//#region src/intents/expirable-nonce.ts
|
|
8
|
+
const VERSIONED_MAGIC_PREFIX = new Uint8Array([
|
|
9
|
+
86,
|
|
10
|
+
40,
|
|
11
|
+
246,
|
|
12
|
+
198
|
|
13
|
+
]);
|
|
14
|
+
const LATEST_VERSION = 0;
|
|
15
|
+
/**
|
|
16
|
+
* Schema for validating decoded salted nonce structure.
|
|
17
|
+
* The decoded value from `VersionedNonceBuilder.decodeNonce()` should match this structure.
|
|
18
|
+
*/
|
|
19
|
+
const saltedNonceSchema = valibot.object({
|
|
20
|
+
salt: valibot.array(valibot.number()),
|
|
21
|
+
inner: valibot.object({
|
|
22
|
+
deadline: valibot.bigint(),
|
|
23
|
+
nonce: valibot.array(valibot.number())
|
|
24
|
+
})
|
|
25
|
+
});
|
|
26
|
+
/**
|
|
27
|
+
* VersionedNonce class representing a versioned expirable nonce
|
|
28
|
+
*
|
|
29
|
+
* @property version The version of the nonce
|
|
30
|
+
* @property value The current value of nonce, it is unknown to allow for future version types
|
|
31
|
+
*/
|
|
32
|
+
var VersionedNonce = class VersionedNonce {
|
|
33
|
+
constructor(version, value) {
|
|
34
|
+
this.version = version;
|
|
35
|
+
this.value = value;
|
|
36
|
+
}
|
|
37
|
+
static latest(saltedNonce) {
|
|
38
|
+
return new VersionedNonce(LATEST_VERSION, saltedNonce);
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
const SALTED_NONCE_BORSH_SCHEMA = { struct: {
|
|
42
|
+
salt: { array: {
|
|
43
|
+
type: "u8",
|
|
44
|
+
len: 4
|
|
45
|
+
} },
|
|
46
|
+
inner: { struct: {
|
|
47
|
+
deadline: "u64",
|
|
48
|
+
nonce: { array: {
|
|
49
|
+
type: "u8",
|
|
50
|
+
len: 15
|
|
51
|
+
} }
|
|
52
|
+
} }
|
|
53
|
+
} };
|
|
54
|
+
let VersionedNonceBuilder;
|
|
55
|
+
(function(_VersionedNonceBuilder) {
|
|
56
|
+
function encodeNonce(salt, deadline) {
|
|
57
|
+
if (salt.length !== 4) throw new Error(`Invalid salt length: ${salt.length}, expected 4`);
|
|
58
|
+
const deadlineBigInt = BigInt(deadline.getTime()) * 1000000n;
|
|
59
|
+
const nonceBytes = crypto.getRandomValues(new Uint8Array(15));
|
|
60
|
+
const borshBytes = new Uint8Array(27);
|
|
61
|
+
borshBytes.set(salt, 0);
|
|
62
|
+
new DataView(borshBytes.buffer, borshBytes.byteOffset, borshBytes.byteLength).setBigUint64(4, deadlineBigInt, true);
|
|
63
|
+
borshBytes.set(nonceBytes, 12);
|
|
64
|
+
const result = new Uint8Array(5 + borshBytes.length);
|
|
65
|
+
result.set(VERSIONED_MAGIC_PREFIX, 0);
|
|
66
|
+
result.set([LATEST_VERSION], 4);
|
|
67
|
+
result.set(borshBytes, 5);
|
|
68
|
+
return _scure_base.base64.encode(result);
|
|
69
|
+
}
|
|
70
|
+
_VersionedNonceBuilder.encodeNonce = encodeNonce;
|
|
71
|
+
function decodeNonce(encoded) {
|
|
72
|
+
const bytes = _scure_base.base64.decode(encoded);
|
|
73
|
+
if (bytes.length !== 32) throw new Error("Nonce too short");
|
|
74
|
+
const prefix = bytes.slice(0, 4);
|
|
75
|
+
const version = bytes[4];
|
|
76
|
+
const borshData = bytes.slice(5);
|
|
77
|
+
if (!prefix.every((byte, i) => byte === VERSIONED_MAGIC_PREFIX[i])) throw new Error("Invalid magic prefix");
|
|
78
|
+
return new VersionedNonce(version, (0, near_api_js_lib_utils_serialize.deserialize)(SALTED_NONCE_BORSH_SCHEMA, borshData));
|
|
79
|
+
}
|
|
80
|
+
_VersionedNonceBuilder.decodeNonce = decodeNonce;
|
|
81
|
+
})(VersionedNonceBuilder || (VersionedNonceBuilder = {}));
|
|
82
|
+
|
|
83
|
+
//#endregion
|
|
84
|
+
Object.defineProperty(exports, 'VersionedNonceBuilder', {
|
|
85
|
+
enumerable: true,
|
|
86
|
+
get: function () {
|
|
87
|
+
return VersionedNonceBuilder;
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
exports.saltedNonceSchema = saltedNonceSchema;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
//#region src/intents/expirable-nonce.d.ts
|
|
2
|
+
|
|
3
|
+
type Salt = Uint8Array;
|
|
4
|
+
declare class ExpirableNonce {
|
|
5
|
+
deadline: bigint;
|
|
6
|
+
nonce: Uint8Array;
|
|
7
|
+
constructor(deadline: bigint, nonce: Uint8Array);
|
|
8
|
+
}
|
|
9
|
+
declare class SaltedNonce {
|
|
10
|
+
salt: Salt;
|
|
11
|
+
inner: ExpirableNonce;
|
|
12
|
+
constructor(salt: Salt, inner: ExpirableNonce);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* VersionedNonce class representing a versioned expirable nonce
|
|
16
|
+
*
|
|
17
|
+
* @property version The version of the nonce
|
|
18
|
+
* @property value The current value of nonce, it is unknown to allow for future version types
|
|
19
|
+
*/
|
|
20
|
+
declare class VersionedNonce {
|
|
21
|
+
version: number;
|
|
22
|
+
value: unknown;
|
|
23
|
+
constructor(version: number, value: unknown);
|
|
24
|
+
static latest(saltedNonce: SaltedNonce): VersionedNonce;
|
|
25
|
+
}
|
|
26
|
+
declare namespace VersionedNonceBuilder {
|
|
27
|
+
/**
|
|
28
|
+
* Encodes a versioned expirable nonce with the given salt and deadline
|
|
29
|
+
*
|
|
30
|
+
* @param salt The salt to use for the nonce
|
|
31
|
+
* @param deadline The expiration deadline for the nonce
|
|
32
|
+
* @returns The encoded nonce as a base64 string
|
|
33
|
+
*/
|
|
34
|
+
function encodeNonce(salt: Salt, deadline: Date): string;
|
|
35
|
+
/**
|
|
36
|
+
* Decodes a versioned expirable nonce from a base64-encoded string
|
|
37
|
+
*
|
|
38
|
+
* @param encoded The encoded nonce string
|
|
39
|
+
* @returns The decoded VersionedNonce object
|
|
40
|
+
*/
|
|
41
|
+
function decodeNonce(encoded: string): VersionedNonce;
|
|
42
|
+
}
|
|
43
|
+
//#endregion
|
|
44
|
+
export { Salt, VersionedNonceBuilder };
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import "valibot";
|
|
2
|
+
|
|
3
|
+
//#region src/intents/expirable-nonce.d.ts
|
|
4
|
+
type Salt = Uint8Array;
|
|
5
|
+
declare class ExpirableNonce {
|
|
6
|
+
deadline: bigint;
|
|
7
|
+
nonce: Uint8Array;
|
|
8
|
+
constructor(deadline: bigint, nonce: Uint8Array);
|
|
9
|
+
}
|
|
10
|
+
declare class SaltedNonce {
|
|
11
|
+
salt: Salt;
|
|
12
|
+
inner: ExpirableNonce;
|
|
13
|
+
constructor(salt: Salt, inner: ExpirableNonce);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* VersionedNonce class representing a versioned expirable nonce
|
|
17
|
+
*
|
|
18
|
+
* @property version The version of the nonce
|
|
19
|
+
* @property value The current value of nonce, it is unknown to allow for future version types
|
|
20
|
+
*/
|
|
21
|
+
declare class VersionedNonce {
|
|
22
|
+
version: number;
|
|
23
|
+
value: unknown;
|
|
24
|
+
constructor(version: number, value: unknown);
|
|
25
|
+
static latest(saltedNonce: SaltedNonce): VersionedNonce;
|
|
26
|
+
}
|
|
27
|
+
declare namespace VersionedNonceBuilder {
|
|
28
|
+
/**
|
|
29
|
+
* Encodes a versioned expirable nonce with the given salt and deadline
|
|
30
|
+
*
|
|
31
|
+
* @param salt The salt to use for the nonce
|
|
32
|
+
* @param deadline The expiration deadline for the nonce
|
|
33
|
+
* @returns The encoded nonce as a base64 string
|
|
34
|
+
*/
|
|
35
|
+
function encodeNonce(salt: Salt, deadline: Date): string;
|
|
36
|
+
/**
|
|
37
|
+
* Decodes a versioned expirable nonce from a base64-encoded string
|
|
38
|
+
*
|
|
39
|
+
* @param encoded The encoded nonce string
|
|
40
|
+
* @returns The decoded VersionedNonce object
|
|
41
|
+
*/
|
|
42
|
+
function decodeNonce(encoded: string): VersionedNonce;
|
|
43
|
+
}
|
|
44
|
+
//#endregion
|
|
45
|
+
export { Salt, VersionedNonceBuilder };
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { base64 } from "@scure/base";
|
|
2
|
+
import * as v from "valibot";
|
|
3
|
+
import { deserialize } from "near-api-js/lib/utils/serialize";
|
|
4
|
+
|
|
5
|
+
//#region src/intents/expirable-nonce.ts
|
|
6
|
+
const VERSIONED_MAGIC_PREFIX = new Uint8Array([
|
|
7
|
+
86,
|
|
8
|
+
40,
|
|
9
|
+
246,
|
|
10
|
+
198
|
|
11
|
+
]);
|
|
12
|
+
const LATEST_VERSION = 0;
|
|
13
|
+
/**
|
|
14
|
+
* Schema for validating decoded salted nonce structure.
|
|
15
|
+
* The decoded value from `VersionedNonceBuilder.decodeNonce()` should match this structure.
|
|
16
|
+
*/
|
|
17
|
+
const saltedNonceSchema = v.object({
|
|
18
|
+
salt: v.array(v.number()),
|
|
19
|
+
inner: v.object({
|
|
20
|
+
deadline: v.bigint(),
|
|
21
|
+
nonce: v.array(v.number())
|
|
22
|
+
})
|
|
23
|
+
});
|
|
24
|
+
/**
|
|
25
|
+
* VersionedNonce class representing a versioned expirable nonce
|
|
26
|
+
*
|
|
27
|
+
* @property version The version of the nonce
|
|
28
|
+
* @property value The current value of nonce, it is unknown to allow for future version types
|
|
29
|
+
*/
|
|
30
|
+
var VersionedNonce = class VersionedNonce {
|
|
31
|
+
constructor(version, value) {
|
|
32
|
+
this.version = version;
|
|
33
|
+
this.value = value;
|
|
34
|
+
}
|
|
35
|
+
static latest(saltedNonce) {
|
|
36
|
+
return new VersionedNonce(LATEST_VERSION, saltedNonce);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
const SALTED_NONCE_BORSH_SCHEMA = { struct: {
|
|
40
|
+
salt: { array: {
|
|
41
|
+
type: "u8",
|
|
42
|
+
len: 4
|
|
43
|
+
} },
|
|
44
|
+
inner: { struct: {
|
|
45
|
+
deadline: "u64",
|
|
46
|
+
nonce: { array: {
|
|
47
|
+
type: "u8",
|
|
48
|
+
len: 15
|
|
49
|
+
} }
|
|
50
|
+
} }
|
|
51
|
+
} };
|
|
52
|
+
let VersionedNonceBuilder;
|
|
53
|
+
(function(_VersionedNonceBuilder) {
|
|
54
|
+
function encodeNonce(salt, deadline) {
|
|
55
|
+
if (salt.length !== 4) throw new Error(`Invalid salt length: ${salt.length}, expected 4`);
|
|
56
|
+
const deadlineBigInt = BigInt(deadline.getTime()) * 1000000n;
|
|
57
|
+
const nonceBytes = crypto.getRandomValues(new Uint8Array(15));
|
|
58
|
+
const borshBytes = new Uint8Array(27);
|
|
59
|
+
borshBytes.set(salt, 0);
|
|
60
|
+
new DataView(borshBytes.buffer, borshBytes.byteOffset, borshBytes.byteLength).setBigUint64(4, deadlineBigInt, true);
|
|
61
|
+
borshBytes.set(nonceBytes, 12);
|
|
62
|
+
const result = new Uint8Array(5 + borshBytes.length);
|
|
63
|
+
result.set(VERSIONED_MAGIC_PREFIX, 0);
|
|
64
|
+
result.set([LATEST_VERSION], 4);
|
|
65
|
+
result.set(borshBytes, 5);
|
|
66
|
+
return base64.encode(result);
|
|
67
|
+
}
|
|
68
|
+
_VersionedNonceBuilder.encodeNonce = encodeNonce;
|
|
69
|
+
function decodeNonce(encoded) {
|
|
70
|
+
const bytes = base64.decode(encoded);
|
|
71
|
+
if (bytes.length !== 32) throw new Error("Nonce too short");
|
|
72
|
+
const prefix = bytes.slice(0, 4);
|
|
73
|
+
const version = bytes[4];
|
|
74
|
+
const borshData = bytes.slice(5);
|
|
75
|
+
if (!prefix.every((byte, i) => byte === VERSIONED_MAGIC_PREFIX[i])) throw new Error("Invalid magic prefix");
|
|
76
|
+
return new VersionedNonce(version, deserialize(SALTED_NONCE_BORSH_SCHEMA, borshData));
|
|
77
|
+
}
|
|
78
|
+
_VersionedNonceBuilder.decodeNonce = decodeNonce;
|
|
79
|
+
})(VersionedNonceBuilder || (VersionedNonceBuilder = {}));
|
|
80
|
+
|
|
81
|
+
//#endregion
|
|
82
|
+
export { VersionedNonceBuilder, saltedNonceSchema };
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
const require_intent_hash = require('../intent-hash.cjs');
|
|
2
|
+
const require_intent_payload_factory = require('../intent-payload-factory.cjs');
|
|
3
|
+
|
|
4
|
+
//#region src/intents/intent-executer-impl/intent-executer.ts
|
|
5
|
+
var IntentExecuter = class {
|
|
6
|
+
constructor(args) {
|
|
7
|
+
this.envConfig = args.envConfig;
|
|
8
|
+
this.logger = args.logger;
|
|
9
|
+
this.intentPayloadFactory = args.intentPayloadFactory;
|
|
10
|
+
this.intentRelayer = args.intentRelayer;
|
|
11
|
+
this.intentSigner = args.intentSigner;
|
|
12
|
+
this.onBeforePublishIntent = args.onBeforePublishIntent;
|
|
13
|
+
}
|
|
14
|
+
async signAndSendIntent({ relayParams: relayParamsFactory, salt, signedIntents, ...intentParams }) {
|
|
15
|
+
const verifyingContract = this.envConfig.contractID;
|
|
16
|
+
let intentPayload = require_intent_payload_factory.defaultIntentPayloadFactory(salt, {
|
|
17
|
+
verifying_contract: verifyingContract,
|
|
18
|
+
...intentParams
|
|
19
|
+
});
|
|
20
|
+
if (this.intentPayloadFactory) intentPayload = await mergeIntentPayloads(intentPayload, this.intentPayloadFactory, salt);
|
|
21
|
+
const multiPayload = await this.intentSigner.signIntent(intentPayload);
|
|
22
|
+
const relayParams = relayParamsFactory ? await relayParamsFactory() : {};
|
|
23
|
+
if (this.onBeforePublishIntent) {
|
|
24
|
+
const intentHash = await require_intent_hash.computeIntentHash(multiPayload);
|
|
25
|
+
await this.onBeforePublishIntent({
|
|
26
|
+
intentHash,
|
|
27
|
+
intentPayload,
|
|
28
|
+
multiPayload,
|
|
29
|
+
relayParams
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
const composedPayloads = composeMultiPayloads(multiPayload, signedIntents);
|
|
33
|
+
if (composedPayloads.length > 1) {
|
|
34
|
+
const quoteHashes = relayParams.quoteHashes ?? [];
|
|
35
|
+
return { ticket: (await this.intentRelayer.publishIntents({
|
|
36
|
+
multiPayloads: composedPayloads,
|
|
37
|
+
quoteHashes
|
|
38
|
+
}, { logger: this.logger }))[signedIntents?.before?.length ?? 0] };
|
|
39
|
+
}
|
|
40
|
+
return { ticket: await this.intentRelayer.publishIntent({
|
|
41
|
+
multiPayload,
|
|
42
|
+
...relayParams
|
|
43
|
+
}, { logger: this.logger }) };
|
|
44
|
+
}
|
|
45
|
+
async waitForSettlement(ticket, ctx) {
|
|
46
|
+
return this.intentRelayer.waitForSettlement(ticket, {
|
|
47
|
+
logger: this.logger,
|
|
48
|
+
signal: ctx?.signal
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
async sendSignedIntents(params) {
|
|
52
|
+
return { tickets: await this.intentRelayer.publishIntents({
|
|
53
|
+
multiPayloads: params.multiPayloads,
|
|
54
|
+
quoteHashes: params.quoteHashes ?? []
|
|
55
|
+
}, { logger: this.logger }) };
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
async function mergeIntentPayloads(defaultPayload, intentPayloadFactory, salt) {
|
|
59
|
+
const customPayload = await intentPayloadFactory(defaultPayload);
|
|
60
|
+
const customPayloadIntents = customPayload.intents ?? [];
|
|
61
|
+
const { nonce: _nonce, ...basePayload } = defaultPayload;
|
|
62
|
+
return require_intent_payload_factory.defaultIntentPayloadFactory(salt, {
|
|
63
|
+
...basePayload,
|
|
64
|
+
...customPayload,
|
|
65
|
+
intents: Array.from(new Set([...customPayloadIntents, ...basePayload.intents]))
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Composes a new MultiPayload with pre-signed intents for atomic execution.
|
|
70
|
+
*
|
|
71
|
+
* @param newPayload - The newly signed MultiPayload
|
|
72
|
+
* @param signedIntents - Optional configuration with before/after intents
|
|
73
|
+
* @returns Array of MultiPayloads in execution order: [before...] -> newPayload -> [after...]
|
|
74
|
+
*/
|
|
75
|
+
function composeMultiPayloads(newPayload, signedIntents) {
|
|
76
|
+
if (!signedIntents) return [newPayload];
|
|
77
|
+
const result = [];
|
|
78
|
+
if (signedIntents.before && signedIntents.before.length > 0) result.push(...signedIntents.before);
|
|
79
|
+
result.push(newPayload);
|
|
80
|
+
if (signedIntents.after && signedIntents.after.length > 0) result.push(...signedIntents.after);
|
|
81
|
+
return result;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
//#endregion
|
|
85
|
+
exports.IntentExecuter = IntentExecuter;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { IntentHash, IntentPayload, MultiPayload, RelayParamsDefault } from "../shared-types.cjs";
|
|
2
|
+
import { EnvConfig, ILogger } from "lampamazaza-internal-utils";
|
|
3
|
+
|
|
4
|
+
//#region src/intents/intent-executer-impl/intent-executer.d.ts
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Hook function called before publishing an intent.
|
|
8
|
+
* Can be used for persistence, logging, analytics, etc.
|
|
9
|
+
*
|
|
10
|
+
* @param intentData - The intent data about to be published
|
|
11
|
+
* @returns A promise that resolves when the hook is complete
|
|
12
|
+
*/
|
|
13
|
+
type OnBeforePublishIntentHook<RelayParams = Omit<RelayParamsDefault, "multiPayload">> = (intentData: {
|
|
14
|
+
intentHash: IntentHash;
|
|
15
|
+
intentPayload: IntentPayload;
|
|
16
|
+
multiPayload: MultiPayload;
|
|
17
|
+
relayParams: RelayParams;
|
|
18
|
+
}) => Promise<void> | void;
|
|
19
|
+
//#endregion
|
|
20
|
+
export { OnBeforePublishIntentHook };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import "../expirable-nonce.js";
|
|
2
|
+
import { IntentHash, IntentPayload, MultiPayload, RelayParamsDefault } from "../shared-types.js";
|
|
3
|
+
import "../interfaces/intent-executer.js";
|
|
4
|
+
import "../../shared-types.js";
|
|
5
|
+
import "../interfaces/intent-relayer.js";
|
|
6
|
+
import { EnvConfig, ILogger } from "lampamazaza-internal-utils";
|
|
7
|
+
|
|
8
|
+
//#region src/intents/intent-executer-impl/intent-executer.d.ts
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Hook function called before publishing an intent.
|
|
12
|
+
* Can be used for persistence, logging, analytics, etc.
|
|
13
|
+
*
|
|
14
|
+
* @param intentData - The intent data about to be published
|
|
15
|
+
* @returns A promise that resolves when the hook is complete
|
|
16
|
+
*/
|
|
17
|
+
type OnBeforePublishIntentHook<RelayParams = Omit<RelayParamsDefault, "multiPayload">> = (intentData: {
|
|
18
|
+
intentHash: IntentHash;
|
|
19
|
+
intentPayload: IntentPayload;
|
|
20
|
+
multiPayload: MultiPayload;
|
|
21
|
+
relayParams: RelayParams;
|
|
22
|
+
}) => Promise<void> | void;
|
|
23
|
+
//#endregion
|
|
24
|
+
export { OnBeforePublishIntentHook };
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { computeIntentHash } from "../intent-hash.js";
|
|
2
|
+
import { defaultIntentPayloadFactory } from "../intent-payload-factory.js";
|
|
3
|
+
|
|
4
|
+
//#region src/intents/intent-executer-impl/intent-executer.ts
|
|
5
|
+
var IntentExecuter = class {
|
|
6
|
+
constructor(args) {
|
|
7
|
+
this.envConfig = args.envConfig;
|
|
8
|
+
this.logger = args.logger;
|
|
9
|
+
this.intentPayloadFactory = args.intentPayloadFactory;
|
|
10
|
+
this.intentRelayer = args.intentRelayer;
|
|
11
|
+
this.intentSigner = args.intentSigner;
|
|
12
|
+
this.onBeforePublishIntent = args.onBeforePublishIntent;
|
|
13
|
+
}
|
|
14
|
+
async signAndSendIntent({ relayParams: relayParamsFactory, salt, signedIntents, ...intentParams }) {
|
|
15
|
+
const verifyingContract = this.envConfig.contractID;
|
|
16
|
+
let intentPayload = defaultIntentPayloadFactory(salt, {
|
|
17
|
+
verifying_contract: verifyingContract,
|
|
18
|
+
...intentParams
|
|
19
|
+
});
|
|
20
|
+
if (this.intentPayloadFactory) intentPayload = await mergeIntentPayloads(intentPayload, this.intentPayloadFactory, salt);
|
|
21
|
+
const multiPayload = await this.intentSigner.signIntent(intentPayload);
|
|
22
|
+
const relayParams = relayParamsFactory ? await relayParamsFactory() : {};
|
|
23
|
+
if (this.onBeforePublishIntent) {
|
|
24
|
+
const intentHash = await computeIntentHash(multiPayload);
|
|
25
|
+
await this.onBeforePublishIntent({
|
|
26
|
+
intentHash,
|
|
27
|
+
intentPayload,
|
|
28
|
+
multiPayload,
|
|
29
|
+
relayParams
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
const composedPayloads = composeMultiPayloads(multiPayload, signedIntents);
|
|
33
|
+
if (composedPayloads.length > 1) {
|
|
34
|
+
const quoteHashes = relayParams.quoteHashes ?? [];
|
|
35
|
+
return { ticket: (await this.intentRelayer.publishIntents({
|
|
36
|
+
multiPayloads: composedPayloads,
|
|
37
|
+
quoteHashes
|
|
38
|
+
}, { logger: this.logger }))[signedIntents?.before?.length ?? 0] };
|
|
39
|
+
}
|
|
40
|
+
return { ticket: await this.intentRelayer.publishIntent({
|
|
41
|
+
multiPayload,
|
|
42
|
+
...relayParams
|
|
43
|
+
}, { logger: this.logger }) };
|
|
44
|
+
}
|
|
45
|
+
async waitForSettlement(ticket, ctx) {
|
|
46
|
+
return this.intentRelayer.waitForSettlement(ticket, {
|
|
47
|
+
logger: this.logger,
|
|
48
|
+
signal: ctx?.signal
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
async sendSignedIntents(params) {
|
|
52
|
+
return { tickets: await this.intentRelayer.publishIntents({
|
|
53
|
+
multiPayloads: params.multiPayloads,
|
|
54
|
+
quoteHashes: params.quoteHashes ?? []
|
|
55
|
+
}, { logger: this.logger }) };
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
async function mergeIntentPayloads(defaultPayload, intentPayloadFactory, salt) {
|
|
59
|
+
const customPayload = await intentPayloadFactory(defaultPayload);
|
|
60
|
+
const customPayloadIntents = customPayload.intents ?? [];
|
|
61
|
+
const { nonce: _nonce, ...basePayload } = defaultPayload;
|
|
62
|
+
return defaultIntentPayloadFactory(salt, {
|
|
63
|
+
...basePayload,
|
|
64
|
+
...customPayload,
|
|
65
|
+
intents: Array.from(new Set([...customPayloadIntents, ...basePayload.intents]))
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Composes a new MultiPayload with pre-signed intents for atomic execution.
|
|
70
|
+
*
|
|
71
|
+
* @param newPayload - The newly signed MultiPayload
|
|
72
|
+
* @param signedIntents - Optional configuration with before/after intents
|
|
73
|
+
* @returns Array of MultiPayloads in execution order: [before...] -> newPayload -> [after...]
|
|
74
|
+
*/
|
|
75
|
+
function composeMultiPayloads(newPayload, signedIntents) {
|
|
76
|
+
if (!signedIntents) return [newPayload];
|
|
77
|
+
const result = [];
|
|
78
|
+
if (signedIntents.before && signedIntents.before.length > 0) result.push(...signedIntents.before);
|
|
79
|
+
result.push(newPayload);
|
|
80
|
+
if (signedIntents.after && signedIntents.after.length > 0) result.push(...signedIntents.after);
|
|
81
|
+
return result;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
//#endregion
|
|
85
|
+
export { IntentExecuter };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
const require_rolldown_runtime = require('../../_virtual/rolldown_runtime.cjs');
|
|
2
|
+
const require_nep413 = require('./intent-hashes/nep413.cjs');
|
|
3
|
+
const require_erc191 = require('./intent-hashes/erc191.cjs');
|
|
4
|
+
const require_tip191 = require('./intent-hashes/tip191.cjs');
|
|
5
|
+
const require_raw_ed25519 = require('./intent-hashes/raw-ed25519.cjs');
|
|
6
|
+
const require_webauthn = require('./intent-hashes/webauthn.cjs');
|
|
7
|
+
const require_ton_connect = require('./intent-hashes/ton-connect.cjs');
|
|
8
|
+
const require_sep53 = require('./intent-hashes/sep53.cjs');
|
|
9
|
+
let _scure_base = require("@scure/base");
|
|
10
|
+
|
|
11
|
+
//#region src/intents/intent-hash.ts
|
|
12
|
+
/**
|
|
13
|
+
* Computes the intent hash for a MultiPayload locally, without needing to publish it.
|
|
14
|
+
* This follows the same logic as the NEAR intents repository:
|
|
15
|
+
* https://github.com/near/intents/blob/11fe297dddd50936b297485e147548f5f9a69200/core/src/payload/multi.rs#L56
|
|
16
|
+
*
|
|
17
|
+
* Different standards use different hash functions:
|
|
18
|
+
* - NEP-413: SHA-256 (of Borsh-serialized payload)
|
|
19
|
+
* - ERC-191: Keccak256 (of prefixed message)
|
|
20
|
+
* - TIP-191: Keccak256 (of prefixed message)
|
|
21
|
+
* - Raw Ed25519: SHA-256 (of raw message)
|
|
22
|
+
* - WebAuthn: SHA-256 (of raw message)
|
|
23
|
+
* - TON Connect: SHA-256 (of formatted message)
|
|
24
|
+
* - SEP-53: SHA-256 (of prefixed message)
|
|
25
|
+
*
|
|
26
|
+
* @param signed - The multi-payload to hash
|
|
27
|
+
* @returns 32-byte hash as Uint8Array
|
|
28
|
+
*/
|
|
29
|
+
async function computeIntentHashHashBytes(signed) {
|
|
30
|
+
const { standard } = signed;
|
|
31
|
+
switch (standard) {
|
|
32
|
+
case "nep413": return require_nep413.computeSignedNep413Hash(signed);
|
|
33
|
+
case "erc191": return require_erc191.computeSignedErc191Hash(signed);
|
|
34
|
+
case "tip191": return require_tip191.computeSignedTip191Hash(signed);
|
|
35
|
+
case "raw_ed25519": return require_raw_ed25519.computeSignedRawEd25519Hash(signed);
|
|
36
|
+
case "webauthn": return require_webauthn.computeSignedWebAuthnHash(signed);
|
|
37
|
+
case "ton_connect": return require_ton_connect.computeSignedTonConnectHash(signed);
|
|
38
|
+
case "sep53": return require_sep53.computeSignedSep53Hash(signed);
|
|
39
|
+
default: throw new Error(`Unknown payload standard: ${standard}`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
async function computeIntentHash(multiPayload) {
|
|
43
|
+
const hashBytes = await computeIntentHashHashBytes(multiPayload);
|
|
44
|
+
return _scure_base.base58.encode(hashBytes);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
//#endregion
|
|
48
|
+
exports.computeIntentHash = computeIntentHash;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { IntentHash } from "./shared-types.cjs";
|
|
2
|
+
import { MultiPayload } from "lampamazaza-contract-types";
|
|
3
|
+
|
|
4
|
+
//#region src/intents/intent-hash.d.ts
|
|
5
|
+
|
|
6
|
+
declare function computeIntentHash(multiPayload: MultiPayload): Promise<IntentHash>;
|
|
7
|
+
//#endregion
|
|
8
|
+
export { computeIntentHash };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { IntentHash } from "./shared-types.js";
|
|
2
|
+
import { MultiPayload } from "lampamazaza-contract-types";
|
|
3
|
+
|
|
4
|
+
//#region src/intents/intent-hash.d.ts
|
|
5
|
+
|
|
6
|
+
declare function computeIntentHash(multiPayload: MultiPayload): Promise<IntentHash>;
|
|
7
|
+
//#endregion
|
|
8
|
+
export { computeIntentHash };
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { computeSignedNep413Hash } from "./intent-hashes/nep413.js";
|
|
2
|
+
import { computeSignedErc191Hash } from "./intent-hashes/erc191.js";
|
|
3
|
+
import { computeSignedTip191Hash } from "./intent-hashes/tip191.js";
|
|
4
|
+
import { computeSignedRawEd25519Hash } from "./intent-hashes/raw-ed25519.js";
|
|
5
|
+
import { computeSignedWebAuthnHash } from "./intent-hashes/webauthn.js";
|
|
6
|
+
import { computeSignedTonConnectHash } from "./intent-hashes/ton-connect.js";
|
|
7
|
+
import { computeSignedSep53Hash } from "./intent-hashes/sep53.js";
|
|
8
|
+
import { base58 } from "@scure/base";
|
|
9
|
+
|
|
10
|
+
//#region src/intents/intent-hash.ts
|
|
11
|
+
/**
|
|
12
|
+
* Computes the intent hash for a MultiPayload locally, without needing to publish it.
|
|
13
|
+
* This follows the same logic as the NEAR intents repository:
|
|
14
|
+
* https://github.com/near/intents/blob/11fe297dddd50936b297485e147548f5f9a69200/core/src/payload/multi.rs#L56
|
|
15
|
+
*
|
|
16
|
+
* Different standards use different hash functions:
|
|
17
|
+
* - NEP-413: SHA-256 (of Borsh-serialized payload)
|
|
18
|
+
* - ERC-191: Keccak256 (of prefixed message)
|
|
19
|
+
* - TIP-191: Keccak256 (of prefixed message)
|
|
20
|
+
* - Raw Ed25519: SHA-256 (of raw message)
|
|
21
|
+
* - WebAuthn: SHA-256 (of raw message)
|
|
22
|
+
* - TON Connect: SHA-256 (of formatted message)
|
|
23
|
+
* - SEP-53: SHA-256 (of prefixed message)
|
|
24
|
+
*
|
|
25
|
+
* @param signed - The multi-payload to hash
|
|
26
|
+
* @returns 32-byte hash as Uint8Array
|
|
27
|
+
*/
|
|
28
|
+
async function computeIntentHashHashBytes(signed) {
|
|
29
|
+
const { standard } = signed;
|
|
30
|
+
switch (standard) {
|
|
31
|
+
case "nep413": return computeSignedNep413Hash(signed);
|
|
32
|
+
case "erc191": return computeSignedErc191Hash(signed);
|
|
33
|
+
case "tip191": return computeSignedTip191Hash(signed);
|
|
34
|
+
case "raw_ed25519": return computeSignedRawEd25519Hash(signed);
|
|
35
|
+
case "webauthn": return computeSignedWebAuthnHash(signed);
|
|
36
|
+
case "ton_connect": return computeSignedTonConnectHash(signed);
|
|
37
|
+
case "sep53": return computeSignedSep53Hash(signed);
|
|
38
|
+
default: throw new Error(`Unknown payload standard: ${standard}`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
async function computeIntentHash(multiPayload) {
|
|
42
|
+
const hashBytes = await computeIntentHashHashBytes(multiPayload);
|
|
43
|
+
return base58.encode(hashBytes);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
//#endregion
|
|
47
|
+
export { computeIntentHash };
|