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
package/README.md
ADDED
|
@@ -0,0 +1,1083 @@
|
|
|
1
|
+
# @defuse-protocol/intents-sdk
|
|
2
|
+
|
|
3
|
+
A comprehensive SDK for Near Intents protocol. This SDK provides tools for intent execution, deposits, withdrawals, and
|
|
4
|
+
interacting with various bridge implementations across multiple blockchains.
|
|
5
|
+
|
|
6
|
+
## Table of Contents
|
|
7
|
+
|
|
8
|
+
- [Installation](#installation)
|
|
9
|
+
- [Features](#features)
|
|
10
|
+
- [Quick Start](#quick-start)
|
|
11
|
+
- [Core Functionalities](#core-functionalities)
|
|
12
|
+
- [Core Concepts](#core-concepts)
|
|
13
|
+
- [Intent Execution](#intent-execution)
|
|
14
|
+
- [Deposits](#deposits)
|
|
15
|
+
- [Withdrawals](#withdrawals)
|
|
16
|
+
- [Routes and Bridges](#routes-and-bridges)
|
|
17
|
+
- [Route Types](#route-types)
|
|
18
|
+
- [Fee Estimation](#fee-estimation)
|
|
19
|
+
- [Advanced Usage](#advanced-usage)
|
|
20
|
+
- [Custom RPC URLs](#custom-rpc-urls)
|
|
21
|
+
- [Feature Flags](#feature-flags)
|
|
22
|
+
- [Other Intent Signers](#other-intent-signers)
|
|
23
|
+
- [Intent Payload Builder](#intent-payload-builder)
|
|
24
|
+
- [Intent Publishing Hooks](#intent-publishing-hooks)
|
|
25
|
+
- [Batch Withdrawals](#batch-withdrawals)
|
|
26
|
+
- [Waiting for Batch Completion](#waiting-for-batch-completion)
|
|
27
|
+
- [Intent Management](#intent-management)
|
|
28
|
+
- [Nonce Invalidation](#nonce-invalidation)
|
|
29
|
+
- [Configure Withdrawal Routes](#configure-withdrawal-routes)
|
|
30
|
+
- [Asset Information Parsing](#asset-information-parsing)
|
|
31
|
+
- [Waiting for Completion](#waiting-for-completion)
|
|
32
|
+
- [Error Handling](#error-handling)
|
|
33
|
+
- [Atomic Multi-Intent Publishing](#atomic-multi-intent-publishing)
|
|
34
|
+
- [Supported Networks](#supported-networks)
|
|
35
|
+
- [Development](#development)
|
|
36
|
+
|
|
37
|
+
## Installation
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
npm install @defuse-protocol/intents-sdk --save-exact
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Features
|
|
44
|
+
|
|
45
|
+
| Feature | Status | Description |
|
|
46
|
+
|------------------|:------:|------------------------------------------------------------------------|
|
|
47
|
+
| Intent Execution | ✅ | Sign, submit, and track intent execution on Near Intents |
|
|
48
|
+
| Deposits | ❌ | Deposit funds to Near Intents (use bridge interfaces directly) |
|
|
49
|
+
| Withdrawals | ✅ | Complete withdrawal functionality from Near Intents to external chains |
|
|
50
|
+
|
|
51
|
+
## Quick Start
|
|
52
|
+
|
|
53
|
+
### Basic Setup
|
|
54
|
+
|
|
55
|
+
First, initialize the SDK with your referral code and intent signer:
|
|
56
|
+
|
|
57
|
+
```typescript
|
|
58
|
+
import {IntentsSDK, createIntentSignerNearKeyPair} from '@defuse-protocol/intents-sdk';
|
|
59
|
+
import {KeyPair} from 'near-api-js';
|
|
60
|
+
|
|
61
|
+
// Initialize the SDK
|
|
62
|
+
const sdk = new IntentsSDK({
|
|
63
|
+
referral: 'your-referral-code', // Only referral is required
|
|
64
|
+
intentSigner: createIntentSignerNearKeyPair({
|
|
65
|
+
signer: KeyPair.fromString('your-private-key'),
|
|
66
|
+
accountId: 'your-account.near'
|
|
67
|
+
})
|
|
68
|
+
});
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Most Common Use Case: Withdrawals
|
|
72
|
+
|
|
73
|
+
For most users, the primary use case is withdrawing funds from Near Intents to external chains. Use the high-level
|
|
74
|
+
`processWithdrawal` method:
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
// Complete end-to-end withdrawal (recommended)
|
|
78
|
+
const result = await sdk.processWithdrawal({
|
|
79
|
+
withdrawalParams: {
|
|
80
|
+
assetId: 'nep141:usdt.tether-token.near', // USDT token on NEAR
|
|
81
|
+
amount: 1000000n, // 1 USDT (in smallest units - 6 decimals)
|
|
82
|
+
destinationAddress: '0x742d35Cc6634C0532925a3b8D84B2021F90a51A3', // Ethereum address
|
|
83
|
+
feeInclusive: false, // Amount excludes withdrawal fees
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
console.log('Intent hash:', result.intentHash);
|
|
88
|
+
console.log('Destination transaction:', result.destinationTx);
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Advanced Use Case: Custom Intents
|
|
92
|
+
|
|
93
|
+
For advanced users who need custom intent logic beyond withdrawals, use the lower-level `signAndSendIntent` method:
|
|
94
|
+
|
|
95
|
+
```typescript
|
|
96
|
+
// Custom intent execution (advanced)
|
|
97
|
+
const result = await sdk.signAndSendIntent({
|
|
98
|
+
intents: [
|
|
99
|
+
{
|
|
100
|
+
intent: "transfer", // Custom intent type
|
|
101
|
+
receiver_id: "recipient.near",
|
|
102
|
+
tokens: {"usdt.tether-token.near": "1000000"}, // 1 USDT
|
|
103
|
+
},
|
|
104
|
+
],
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
console.log('Intent hash:', result.intentHash);
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
> **💡 Tip**: Use `processWithdrawal` for withdrawals and `signAndSendIntent` for custom intent logic. The withdrawal
|
|
111
|
+
> method handles fee estimation, validation, and completion tracking automatically.
|
|
112
|
+
|
|
113
|
+
## Core Functionalities
|
|
114
|
+
|
|
115
|
+
### Core Concepts
|
|
116
|
+
|
|
117
|
+
#### Intent
|
|
118
|
+
|
|
119
|
+
TBD
|
|
120
|
+
|
|
121
|
+
#### Intent Signers
|
|
122
|
+
|
|
123
|
+
Intent signers are required to authenticate and sign both regular and withdrawal intents. The SDK supports
|
|
124
|
+
multiple signing methods:
|
|
125
|
+
|
|
126
|
+
| Singing Standard | Methods | Description |
|
|
127
|
+
|------------------|:------------------------------------------------------------------:|----------------------------------------------------------|
|
|
128
|
+
| nep413 | `createIntentSignerNEP413()`<br/>`createIntentSignerNearKeyPair()` | Almost all NEAR wallets support this standard |
|
|
129
|
+
| erc191 | `createIntentSignerViem()` | Only Viem library supported, Ethers.js signer is coming |
|
|
130
|
+
| raw_ed25519 | ❌ | Available on the protocol level, but not included to SDK |
|
|
131
|
+
| webauthn | ❌ | Available on the protocol level, but not included to SDK |
|
|
132
|
+
| ton_connect | ❌ | Available on the protocol level, but not included to SDK |
|
|
133
|
+
|
|
134
|
+
You must set an intent signer before processing withdrawals:
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
// Example: Set up a NEAR KeyPair signer
|
|
138
|
+
const signer = createIntentSignerNearKeyPair({
|
|
139
|
+
signer: KeyPair.fromString('your-private-key'),
|
|
140
|
+
accountId: 'your-account.near'
|
|
141
|
+
});
|
|
142
|
+
sdk.setIntentSigner(signer);
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
See the [Intent Signers](#intent-signers-1) section below for detailed implementation examples.
|
|
146
|
+
|
|
147
|
+
#### Asset Identifiers
|
|
148
|
+
|
|
149
|
+
The SDK uses standardized asset identifiers in the format:
|
|
150
|
+
|
|
151
|
+
- `nep141:contract.near` - NEP-141 tokens
|
|
152
|
+
- `nep245:contract.near:tokenId` - NEP-245 multi-tokens
|
|
153
|
+
|
|
154
|
+
Asset Identifier uniquely determines the corresponding withdrawal route and destination chain.
|
|
155
|
+
|
|
156
|
+
Examples:
|
|
157
|
+
|
|
158
|
+
- `nep141:usdt.tether-token.near` - USDT on NEAR
|
|
159
|
+
- `nep141:wrap.near` - Wrapped NEAR (native NEAR)
|
|
160
|
+
- `nep245:v2_1.omni.hot.tg:137_qiStmoQJDQPTebaPjgx5VBxZv6L` - Polygon USDC through Hot
|
|
161
|
+
- `nep141:base-0x833589fcd6edb6e08f4c7c32d4f71b54bda02913.omft.near` - Base USDC through PoA
|
|
162
|
+
- `nep141:sol.omdep.near` - SOL bridged through Omni Bridge
|
|
163
|
+
|
|
164
|
+
### Intent Execution
|
|
165
|
+
|
|
166
|
+
The primary functionality of the SDK - execute custom intents on Near Intents:
|
|
167
|
+
|
|
168
|
+
- **Sign Intents**: Create and sign intent payloads with various signer types
|
|
169
|
+
- **Submit Intents**: Publish intents to the Near Intents relayer network
|
|
170
|
+
- **Track Status**: Monitor intent settlement and execution status
|
|
171
|
+
- **Batch Intents**: Execute multiple intents in a single transaction
|
|
172
|
+
- **Custom Logic**: Support for any intent type supported by the protocol
|
|
173
|
+
|
|
174
|
+
```typescript
|
|
175
|
+
// Generic intent execution
|
|
176
|
+
const {intentHash} = await sdk.signAndSendIntent({
|
|
177
|
+
intents: [/* array of intent primitives */],
|
|
178
|
+
onBeforePublishIntent: async (data) => {
|
|
179
|
+
console.log('About to publish intent:', data.intentHash);
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
// Monitor settlement
|
|
184
|
+
const intentTx = await sdk.waitForIntentSettlement({intentHash});
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### Deposits
|
|
188
|
+
|
|
189
|
+
Deposit funds into Near Intents *(Coming Soon)*.
|
|
190
|
+
|
|
191
|
+
> **Note**: Deposit functionality is not yet implemented in this SDK. Currently, use bridge interfaces directly for
|
|
192
|
+
> deposit operations.
|
|
193
|
+
|
|
194
|
+
### Withdrawals
|
|
195
|
+
|
|
196
|
+
Complete withdrawal functionality from Near Intents to external chains:
|
|
197
|
+
|
|
198
|
+
- **Cross-Chain Transfers**: Withdraw to 20+ supported blockchains
|
|
199
|
+
- **Multi-Bridge Support**: Hot Bridge, PoA Bridge, Omni Bridge
|
|
200
|
+
- **Batch Processing**: Process multiple withdrawals at a time
|
|
201
|
+
- **Fee Management**: Automatic fee estimation with quote support
|
|
202
|
+
- **Validation**: Built-in validation for withdrawal constraints
|
|
203
|
+
- **Status Tracking**: End-to-end monitoring from intent to destination
|
|
204
|
+
|
|
205
|
+
```typescript
|
|
206
|
+
// Complete withdrawal process
|
|
207
|
+
const result = await sdk.processWithdrawal({
|
|
208
|
+
withdrawalParams: {
|
|
209
|
+
assetId: 'nep141:usdt.tether-token.near',
|
|
210
|
+
amount: 1000000n,
|
|
211
|
+
destinationAddress: '0x742d35Cc6634C0532925a3b8D84B2021F90a51A3',
|
|
212
|
+
feeInclusive: false
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
#### Routes and Bridges
|
|
218
|
+
|
|
219
|
+
The SDK uses two key concepts to organize withdrawal operations:
|
|
220
|
+
|
|
221
|
+
##### Routes
|
|
222
|
+
|
|
223
|
+
Routes define the **path** a withdrawal takes - the specific mechanism and destination for transferring assets. Each
|
|
224
|
+
route represents a different withdrawal flow:
|
|
225
|
+
|
|
226
|
+
```typescript
|
|
227
|
+
import {RouteEnum} from '@defuse-protocol/intents-sdk';
|
|
228
|
+
|
|
229
|
+
console.log(RouteEnum.HotBridge); // "hot_bridge" - Cross-chain via HOT protocol
|
|
230
|
+
console.log(RouteEnum.PoaBridge); // "poa_bridge" - Cross-chain via PoA bridge
|
|
231
|
+
console.log(RouteEnum.OmniBridge); // "omni_bridge" - Cross-chain via Omni bridge
|
|
232
|
+
console.log(RouteEnum.NearWithdrawal); // "near_withdrawal" - Direct to NEAR blockchain
|
|
233
|
+
console.log(RouteEnum.VirtualChain); // "virtual_chain" - To Aurora Engine chains
|
|
234
|
+
console.log(RouteEnum.InternalTransfer); // "internal_transfer" - Between protocol users
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
##### Bridge Names
|
|
238
|
+
|
|
239
|
+
Bridge names identify the **underlying bridge infrastructure** that handles the cross-chain transfer. This determines
|
|
240
|
+
which external protocol processes the withdrawal:
|
|
241
|
+
|
|
242
|
+
```typescript
|
|
243
|
+
import {BridgeNameEnum} from '@defuse-protocol/intents-sdk';
|
|
244
|
+
|
|
245
|
+
console.log(BridgeNameEnum.Hot); // "hot" - HOT Labs bridge infrastructure
|
|
246
|
+
console.log(BridgeNameEnum.Poa); // "poa" - Proof-of-Authority bridge by Defuse Labs
|
|
247
|
+
console.log(BridgeNameEnum.Omni); // "omni" - Omni bridge by NEAR
|
|
248
|
+
console.log(BridgeNameEnum.None); // null - No external bridge (NEAR-native or internal)
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
**Key Difference**:
|
|
252
|
+
|
|
253
|
+
- **Route** = "How and where" the withdrawal goes (the path)
|
|
254
|
+
- **Bridge Name** = "Who operates" the underlying infrastructure (the bridge provider)
|
|
255
|
+
|
|
256
|
+
For example, both `hot_bridge` and `poa_bridge` routes perform cross-chain transfers, but use different bridge
|
|
257
|
+
infrastructures (`hot` vs `poa`) with different fee structures and supported networks.
|
|
258
|
+
|
|
259
|
+
#### Route Types
|
|
260
|
+
|
|
261
|
+
The SDK automatically detects and supports multiple route types based on asset identifiers:
|
|
262
|
+
|
|
263
|
+
##### Hot Bridge Route
|
|
264
|
+
|
|
265
|
+
- **Purpose**: Cross-chain transfers via HOT Labs infrastructure
|
|
266
|
+
- **Supported Assets**: Multi-tokens (NEP-245) from Hot protocol (contract `v2_1.omni.hot.tg`)
|
|
267
|
+
- **Use Case**: Cross-chain transfers for assets bridged through Hot protocol
|
|
268
|
+
- **Route Type**: `hot_bridge`
|
|
269
|
+
|
|
270
|
+
##### PoA Bridge Route
|
|
271
|
+
|
|
272
|
+
- **Purpose**: Proof-of-Authority bridge transfers operated by Defuse Labs
|
|
273
|
+
- **Supported Assets**: Fungible tokens (NEP-141) ending with `.omft.near`
|
|
274
|
+
- **Use Case**: Cross-chain transfers for assets bridged through PoA protocol
|
|
275
|
+
- **Route Type**: `poa_bridge`
|
|
276
|
+
|
|
277
|
+
##### Omni Bridge Route
|
|
278
|
+
- **Purpose**: multi-chain asset bridge developed by Near
|
|
279
|
+
- **Supported Assets**: Fungible tokens (NEP-141) supported by omni bridge relayer.
|
|
280
|
+
- **Use Case**: multi-chain transfers for supported list of chains
|
|
281
|
+
- **Route Type**: `omni_bridge`
|
|
282
|
+
|
|
283
|
+
##### Internal Transfer Route
|
|
284
|
+
|
|
285
|
+
- **Purpose**: Transfer between Near Intents users within the protocol
|
|
286
|
+
- **Supported Assets**: All NEP-141 and NEP-245 tokens
|
|
287
|
+
- **Use Case**: User A having funds in the protocol wants to transfer to User B
|
|
288
|
+
- **Route Type**: `internal_transfer`
|
|
289
|
+
|
|
290
|
+
##### Near Withdrawal Route
|
|
291
|
+
|
|
292
|
+
- **Purpose**: Transfers within the NEAR blockchain
|
|
293
|
+
- **Supported Assets**: NEP-141 tokens on NEAR, including native NEAR (wrap.near)
|
|
294
|
+
- **Use Case**: Same-chain transfers on NEAR
|
|
295
|
+
- **Route Type**: `near_withdrawal`
|
|
296
|
+
|
|
297
|
+
##### Virtual Chain Route
|
|
298
|
+
|
|
299
|
+
- **Purpose**: Transfers to Aurora Engine-powered chains (aka Virtual chains)
|
|
300
|
+
- **Supported Assets**: NEP-141 tokens with Aurora Engine integration
|
|
301
|
+
- **Use Case**: Near Intents to Aurora ecosystem transfers
|
|
302
|
+
- **Route Type**: `virtual_chain`
|
|
303
|
+
- **Note**: Requires explicit `routeConfig` with `auroraEngineContractId`
|
|
304
|
+
|
|
305
|
+
#### Fee Estimation
|
|
306
|
+
|
|
307
|
+
The SDK now supports both single and batch fee estimation:
|
|
308
|
+
|
|
309
|
+
```typescript
|
|
310
|
+
// Single withdrawal fee estimation
|
|
311
|
+
const feeEstimation = await sdk.estimateWithdrawalFee({
|
|
312
|
+
withdrawalParams: {
|
|
313
|
+
assetId: 'nep141:usdt.tether-token.near',
|
|
314
|
+
amount: 1000000n,
|
|
315
|
+
destinationAddress: '0x742d35Cc6634C0532925a3b8D84B2021F90a51A3',
|
|
316
|
+
feeInclusive: false
|
|
317
|
+
}
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
console.log('Fee amount:', feeEstimation.amount);
|
|
321
|
+
|
|
322
|
+
// Batch fee estimation
|
|
323
|
+
const batchFees = await sdk.estimateWithdrawalFee({
|
|
324
|
+
withdrawalParams: [
|
|
325
|
+
{
|
|
326
|
+
assetId: 'nep141:usdt.tether-token.near',
|
|
327
|
+
amount: 1000000n,
|
|
328
|
+
destinationAddress: '0x742d35Cc...',
|
|
329
|
+
feeInclusive: false
|
|
330
|
+
},
|
|
331
|
+
{
|
|
332
|
+
assetId: 'nep245:v2_1.omni.hot.tg:137_qiStmoQJDQPTebaPjgx5VBxZv6L',
|
|
333
|
+
amount: 500000n,
|
|
334
|
+
destinationAddress: '0x742d35Cc...',
|
|
335
|
+
feeInclusive: false
|
|
336
|
+
}
|
|
337
|
+
]
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
console.log('Batch fees:', batchFees); // Array of FeeEstimation objects
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
## Advanced Usage
|
|
344
|
+
|
|
345
|
+
### Custom RPC URLs
|
|
346
|
+
|
|
347
|
+
Set NEAR and EVM chains RPC URLs in the constructor:
|
|
348
|
+
|
|
349
|
+
```typescript
|
|
350
|
+
import {Chains} from '@defuse-protocol/intents-sdk'
|
|
351
|
+
|
|
352
|
+
const sdk = new IntentsSDK({
|
|
353
|
+
...,
|
|
354
|
+
rpc: {
|
|
355
|
+
[Chains.Near]: ['https://rpc.mainnet.near.org'],
|
|
356
|
+
[Chains.Polygon]: ['https://polygon-rpc.com'],
|
|
357
|
+
[Chains.BNB]: ['https://bsc-dataseed.binance.org'],
|
|
358
|
+
}
|
|
359
|
+
});
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
### Feature Flags
|
|
363
|
+
|
|
364
|
+
Configure optional SDK features through the `features` configuration:
|
|
365
|
+
|
|
366
|
+
#### Migrated PoA Token Routing
|
|
367
|
+
|
|
368
|
+
Will route migrated PoA tokens (ending with `*.omft.near`) through Omni Bridge instead of the legacy PoA Bridge, unless explicitly set to route them through PoA bridge with routeConfig. Enable this when working with POA tokens that have been migrated to the Omni infrastructure:
|
|
369
|
+
|
|
370
|
+
```typescript
|
|
371
|
+
const sdk = new IntentsSDK({
|
|
372
|
+
referral: 'your-referral-code',
|
|
373
|
+
features: {
|
|
374
|
+
routeMigratedPoaTokensThroughOmniBridge: true
|
|
375
|
+
}
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
// With this flag enabled, tokens like 'nep141:sol-c58e6539c2f2e097c251f8edf11f9c03e581f8d4.omft.near' will route through Omni Bridge
|
|
379
|
+
const result = await sdk.processWithdrawal({
|
|
380
|
+
withdrawalParams: {
|
|
381
|
+
assetId: 'nep141:sol-c58e6539c2f2e097c251f8edf11f9c03e581f8d4.omft.near', // Migrated PoA token
|
|
382
|
+
amount: 1000000n,
|
|
383
|
+
destinationAddress: '39hqXivfCPUSqmXAaX3eo4JcA5bGFXhhs26dmg585DGb',
|
|
384
|
+
feeInclusive: false
|
|
385
|
+
}
|
|
386
|
+
});
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
**When to enable:**
|
|
390
|
+
- Working with PoA tokens that have been migrated to Omni Bridge
|
|
391
|
+
- Explicitly want to route `*.omft.near` tokens through the Omni Bridge
|
|
392
|
+
- Default behavior (when disabled) routes these tokens through the PoA Bridge
|
|
393
|
+
|
|
394
|
+
**Allowlisted Tokens:**
|
|
395
|
+
|
|
396
|
+
Not all PoA tokens can be routed through Omni Bridge. The SDK exports `POA_TOKENS_ROUTABLE_THROUGH_OMNI_BRIDGE` constant containing the tokens that support this routing:
|
|
397
|
+
|
|
398
|
+
```typescript
|
|
399
|
+
import { POA_TOKENS_ROUTABLE_THROUGH_OMNI_BRIDGE } from '@defuse-protocol/intents-sdk';
|
|
400
|
+
|
|
401
|
+
console.log(POA_TOKENS_ROUTABLE_THROUGH_OMNI_BRIDGE);
|
|
402
|
+
// { 'sol-...omft.near': ChainKind.Sol, ... }
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
The keys are token contract IDs and values are their `ChainKind`. Only tokens in this map will be routed through Omni Bridge when the feature flag is enabled. Other `*.omft.near` tokens will continue using the PoA Bridge.
|
|
406
|
+
|
|
407
|
+
### Other Intent Signers
|
|
408
|
+
|
|
409
|
+
The SDK supports multiple intent signing methods using factory functions:
|
|
410
|
+
|
|
411
|
+
#### NEAR KeyPair Signer
|
|
412
|
+
|
|
413
|
+
```typescript
|
|
414
|
+
import {createIntentSignerNearKeyPair, IntentsSDK} from '@defuse-protocol/intents-sdk';
|
|
415
|
+
import {KeyPair} from 'near-api-js';
|
|
416
|
+
|
|
417
|
+
const keyPair = KeyPair.fromString('your-private-key');
|
|
418
|
+
const signer = createIntentSignerNearKeyPair({
|
|
419
|
+
signer: keyPair,
|
|
420
|
+
accountId: 'your-account.near'
|
|
421
|
+
});
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
#### NEP-413 Signer
|
|
425
|
+
|
|
426
|
+
```typescript
|
|
427
|
+
import {createIntentSignerNEP413} from '@defuse-protocol/intents-sdk';
|
|
428
|
+
|
|
429
|
+
const signer = createIntentSignerNEP413({
|
|
430
|
+
signMessage: async (nep413Payload, nep413Hash) => {
|
|
431
|
+
// Implement your custom signing logic here
|
|
432
|
+
return {
|
|
433
|
+
publicKey: 'ed25519:YourPublicKey',
|
|
434
|
+
signature: 'base64-encoded-signature'
|
|
435
|
+
};
|
|
436
|
+
},
|
|
437
|
+
accountId: 'your-account.near'
|
|
438
|
+
});
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
#### EVM/Viem Signer
|
|
442
|
+
|
|
443
|
+
```typescript
|
|
444
|
+
import {createIntentSignerViem} from '@defuse-protocol/intents-sdk';
|
|
445
|
+
import {privateKeyToAccount} from 'viem/accounts';
|
|
446
|
+
|
|
447
|
+
const account = privateKeyToAccount('0x...');
|
|
448
|
+
const signer = createIntentSignerViem({ signer: account });
|
|
449
|
+
|
|
450
|
+
// Set the signer at runtime
|
|
451
|
+
sdk.setIntentSigner(signer);
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
### Intent Payload Builder
|
|
455
|
+
|
|
456
|
+
For API builders who need to generate intent payloads based on user metadata (e.g., generating payloads server-side for users to sign with MetaMask), the SDK provides a fluent `IntentPayloadBuilder`:
|
|
457
|
+
|
|
458
|
+
```typescript
|
|
459
|
+
// Build an intent payload for your users
|
|
460
|
+
const payload = await sdk.intentBuilder()
|
|
461
|
+
.setSigner('0x742d35cc6634c0532925a3b8d84b2021f90a51a3') // User's EVM address
|
|
462
|
+
.setDeadline(new Date(Date.now() + 5 * 60 * 1000)) // 5 minutes
|
|
463
|
+
.addIntent({
|
|
464
|
+
intent: "transfer",
|
|
465
|
+
tokens: { "token.near": "100" },
|
|
466
|
+
receiver_id: "receiver.near",
|
|
467
|
+
})
|
|
468
|
+
.build();
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
### Versioned Nonce Builder
|
|
472
|
+
|
|
473
|
+
By default, the nonce is generated during the intent construction process, but it is possible to generate and pass the nonce within the builder independently. All of the nonces have specific [requirements](https://github.com/near/intents/tree/main/defuse#nonces) for the structure reflecting their validity.
|
|
474
|
+
|
|
475
|
+
```typescript
|
|
476
|
+
import {VersionedNonceBuilder} from '@defuse-protocol/intents-sdk';
|
|
477
|
+
|
|
478
|
+
// Fetch current salt from the verifier contract
|
|
479
|
+
const salt_hex = await nearRPC.viewFunction({
|
|
480
|
+
contractId: "intents.near",
|
|
481
|
+
methodName: "current_salt",
|
|
482
|
+
});
|
|
483
|
+
|
|
484
|
+
// Example: 5-minute deadline, but actual deadline should not be greater than intent's deadline
|
|
485
|
+
const deadline = new Date(Date.now() + 5 * 60 * 1000)
|
|
486
|
+
|
|
487
|
+
// Create ready to use versioned nonce from salt and deadline
|
|
488
|
+
const versionedNonce = VersionedNonceBuilder.encodeNonce(
|
|
489
|
+
Uint8Array.from(Buffer.from(salt_hex, "hex")),
|
|
490
|
+
deadline
|
|
491
|
+
);
|
|
492
|
+
|
|
493
|
+
// Create intent builder with specified nonce
|
|
494
|
+
const builder = await sdk.intentBuilder().setNonce(versionedNonce);
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
|
|
498
|
+
### Intent Publishing Hooks
|
|
499
|
+
|
|
500
|
+
Use the `onBeforePublishIntent` hook to intercept and process intent data before it's published to the relayer. This is
|
|
501
|
+
useful for persistence, logging, analytics, or custom processing:
|
|
502
|
+
|
|
503
|
+
```typescript
|
|
504
|
+
import {type OnBeforePublishIntentHook} from '@defuse-protocol/intents-sdk';
|
|
505
|
+
|
|
506
|
+
// Define your hook function
|
|
507
|
+
const onBeforePublishIntent: OnBeforePublishIntentHook = async (intentData) => {
|
|
508
|
+
// Save to database for tracking
|
|
509
|
+
await saveIntentToDatabase({
|
|
510
|
+
hash: intentData.intentHash,
|
|
511
|
+
payload: intentData.intentPayload,
|
|
512
|
+
timestamp: new Date(),
|
|
513
|
+
});
|
|
514
|
+
|
|
515
|
+
// Send analytics
|
|
516
|
+
analytics.track('intent_about_to_publish', {
|
|
517
|
+
intentHash: intentData.intentHash,
|
|
518
|
+
intentType: intentData.intentPayload.intents[0]?.intent,
|
|
519
|
+
});
|
|
520
|
+
};
|
|
521
|
+
|
|
522
|
+
// Use the hook with the functional API
|
|
523
|
+
const result = await sdk.processWithdrawal({
|
|
524
|
+
withdrawalParams: { /* ... */},
|
|
525
|
+
intent: {
|
|
526
|
+
onBeforePublishIntent, // Add the hook here
|
|
527
|
+
}
|
|
528
|
+
});
|
|
529
|
+
|
|
530
|
+
// Or with granular control
|
|
531
|
+
const {intentHash} = await sdk.signAndSendWithdrawalIntent({
|
|
532
|
+
withdrawalParams: { /* ... */},
|
|
533
|
+
feeEstimation: fee,
|
|
534
|
+
intent: {
|
|
535
|
+
onBeforePublishIntent, // Add the hook here
|
|
536
|
+
}
|
|
537
|
+
});
|
|
538
|
+
|
|
539
|
+
// Or with generic intent publishing
|
|
540
|
+
const {intentHash} = await sdk.signAndSendIntent({
|
|
541
|
+
intents: [/* ... */],
|
|
542
|
+
onBeforePublishIntent, // Add the hook here
|
|
543
|
+
});
|
|
544
|
+
```
|
|
545
|
+
|
|
546
|
+
**Hook Parameters:**
|
|
547
|
+
|
|
548
|
+
- `intentHash` - The computed hash of the intent payload
|
|
549
|
+
- `intentPayload` - The unsigned intent payload
|
|
550
|
+
- `multiPayload` - The signed multi-payload containing signature and metadata
|
|
551
|
+
- `relayParams` - Additional parameters passed to the relayer (quote hashes)
|
|
552
|
+
|
|
553
|
+
**Important Notes:**
|
|
554
|
+
|
|
555
|
+
- The hook is called synchronously before publishing the intent
|
|
556
|
+
- If the hook throws an error, the withdrawal will fail
|
|
557
|
+
- The hook can be async and return a Promise
|
|
558
|
+
|
|
559
|
+
### Batch Withdrawals
|
|
560
|
+
|
|
561
|
+
Process multiple withdrawals in a single intent:
|
|
562
|
+
|
|
563
|
+
```typescript
|
|
564
|
+
const withdrawalParams = [
|
|
565
|
+
{
|
|
566
|
+
assetId: 'nep141:usdt.tether-token.near',
|
|
567
|
+
amount: 1000000n,
|
|
568
|
+
destinationAddress: '0x742d35Cc...',
|
|
569
|
+
feeInclusive: false
|
|
570
|
+
},
|
|
571
|
+
{
|
|
572
|
+
assetId: 'nep245:v2_1.omni.hot.tg:137_qiStmoQJDQPTebaPjgx5VBxZv6L',
|
|
573
|
+
amount: 100000n,
|
|
574
|
+
destinationAddress: '0x742d35Cc...',
|
|
575
|
+
feeInclusive: false
|
|
576
|
+
}
|
|
577
|
+
]
|
|
578
|
+
|
|
579
|
+
// Method 1: Complete end-to-end batch processing
|
|
580
|
+
const batchResult = await sdk.processWithdrawal({
|
|
581
|
+
withdrawalParams,
|
|
582
|
+
// feeEstimation is optional - will be estimated automatically if not provided
|
|
583
|
+
});
|
|
584
|
+
|
|
585
|
+
console.log('Batch intent hash:', batchResult.intentHash);
|
|
586
|
+
console.log('Destination transactions:', batchResult.destinationTx); // Array of results
|
|
587
|
+
|
|
588
|
+
// Method 2: Step-by-step batch processing for granular control
|
|
589
|
+
const feeEstimation = await sdk.estimateWithdrawalFee({
|
|
590
|
+
withdrawalParams
|
|
591
|
+
});
|
|
592
|
+
|
|
593
|
+
const {intentHash} = await sdk.signAndSendWithdrawalIntent({
|
|
594
|
+
withdrawalParams,
|
|
595
|
+
feeEstimation
|
|
596
|
+
});
|
|
597
|
+
|
|
598
|
+
const intentTx = await sdk.waitForIntentSettlement({intentHash});
|
|
599
|
+
|
|
600
|
+
// See "Waiting for Batch Completion" below for completion options
|
|
601
|
+
```
|
|
602
|
+
|
|
603
|
+
#### Waiting for Batch Completion
|
|
604
|
+
|
|
605
|
+
After the intent settles on NEAR, you need to wait for withdrawals to complete on destination chains. Two approaches are available:
|
|
606
|
+
|
|
607
|
+
**Option A: Wait for All (`waitForWithdrawalCompletion`)**
|
|
608
|
+
|
|
609
|
+
Waits for all withdrawals to complete before returning. Simple, but blocks on the slowest withdrawal.
|
|
610
|
+
|
|
611
|
+
> **Note:** Waits until completion or chain-specific p99 timeout (throws `PollTimeoutError`). Use `AbortSignal.timeout()` to set a shorter timeout.
|
|
612
|
+
|
|
613
|
+
```typescript
|
|
614
|
+
const destinationTxs = await sdk.waitForWithdrawalCompletion({
|
|
615
|
+
withdrawalParams,
|
|
616
|
+
intentTx,
|
|
617
|
+
signal: AbortSignal.timeout(10 * 60 * 1000), // 10 minute timeout
|
|
618
|
+
});
|
|
619
|
+
|
|
620
|
+
console.log('All destination transactions:', destinationTxs);
|
|
621
|
+
```
|
|
622
|
+
|
|
623
|
+
**Option B: Independent Promises (`createWithdrawalCompletionPromises`)**
|
|
624
|
+
|
|
625
|
+
For scenarios where fast withdrawals (Solana ~2s) shouldn't wait for slow ones (Bitcoin ~1hr), use `createWithdrawalCompletionPromises` to get promises that resolve independently:
|
|
626
|
+
|
|
627
|
+
```typescript
|
|
628
|
+
// Get array of promises - one per withdrawal
|
|
629
|
+
const promises = sdk.createWithdrawalCompletionPromises({
|
|
630
|
+
withdrawalParams,
|
|
631
|
+
intentTx
|
|
632
|
+
});
|
|
633
|
+
|
|
634
|
+
// Fire and forget - handle each independently
|
|
635
|
+
promises[0].then(tx => saveUsdc(tx)).catch(err => logError(0, err));
|
|
636
|
+
promises[1].then(tx => saveBtc(tx)).catch(err => logError(1, err));
|
|
637
|
+
|
|
638
|
+
// Or await a specific withdrawal (fast chain first)
|
|
639
|
+
const usdcTx = await promises[0];
|
|
640
|
+
await notifyUser('USDC received', usdcTx.hash);
|
|
641
|
+
|
|
642
|
+
// Or process as they complete with backpressure
|
|
643
|
+
const pending = new Map(promises.map((p, i) => [i, p]));
|
|
644
|
+
while (pending.size > 0) {
|
|
645
|
+
const { index, tx } = await Promise.race(
|
|
646
|
+
[...pending.entries()].map(async ([i, p]) => ({ index: i, tx: await p }))
|
|
647
|
+
);
|
|
648
|
+
pending.delete(index);
|
|
649
|
+
await saveSuccess(index, tx); // Backpressure maintained
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
// Or wait for all with independent error handling
|
|
653
|
+
const results = await Promise.allSettled(promises);
|
|
654
|
+
for (const [i, result] of results.entries()) {
|
|
655
|
+
if (result.status === 'fulfilled') {
|
|
656
|
+
await saveSuccess(i, result.value);
|
|
657
|
+
} else {
|
|
658
|
+
await saveFailure(i, result.reason);
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
```
|
|
662
|
+
|
|
663
|
+
**With timeout control:**
|
|
664
|
+
|
|
665
|
+
```typescript
|
|
666
|
+
const promises = sdk.createWithdrawalCompletionPromises({
|
|
667
|
+
withdrawalParams,
|
|
668
|
+
intentTx,
|
|
669
|
+
signal: AbortSignal.timeout(30_000) // 30 second timeout
|
|
670
|
+
});
|
|
671
|
+
```
|
|
672
|
+
|
|
673
|
+
**Key benefits:**
|
|
674
|
+
- Fast withdrawals (Solana ~2s) aren't blocked by slow ones (Bitcoin ~1hr)
|
|
675
|
+
- One failure doesn't affect other withdrawals
|
|
676
|
+
- Recovery-friendly: recreate promises from saved `{ withdrawalParams, intentTx }`
|
|
677
|
+
- Index correspondence: `promises[i]` corresponds to `withdrawalParams[i]`
|
|
678
|
+
|
|
679
|
+
> **Note:** Both methods wait until completion or chain-specific p99 timeout (throws `PollTimeoutError`). Use `AbortSignal.timeout()` for a shorter timeout.
|
|
680
|
+
|
|
681
|
+
### Intent Management
|
|
682
|
+
|
|
683
|
+
The SDK provides direct access to intent operations for advanced use cases:
|
|
684
|
+
|
|
685
|
+
```typescript
|
|
686
|
+
// Generic intent signing and publishing
|
|
687
|
+
const {intentHash} = await sdk.signAndSendIntent({
|
|
688
|
+
intents: [/* array of intent primitives */],
|
|
689
|
+
signer: customIntentSigner, // optional - uses SDK default if not provided
|
|
690
|
+
onBeforePublishIntent: async (data) => {
|
|
691
|
+
// Custom logic before publishing
|
|
692
|
+
console.log('About to publish intent:', data.intentHash);
|
|
693
|
+
}
|
|
694
|
+
});
|
|
695
|
+
|
|
696
|
+
// Wait for intent settlement
|
|
697
|
+
const intentTx = await sdk.waitForIntentSettlement({
|
|
698
|
+
intentHash
|
|
699
|
+
});
|
|
700
|
+
|
|
701
|
+
// or manual status check
|
|
702
|
+
|
|
703
|
+
// Check intent status at any time
|
|
704
|
+
const status = await sdk.getIntentStatus({
|
|
705
|
+
intentHash: intentHash
|
|
706
|
+
});
|
|
707
|
+
|
|
708
|
+
console.log('Intent status:', status.status); // "PENDING" | "TX_BROADCASTED" | "SETTLED" | "NOT_FOUND_OR_NOT_VALID"
|
|
709
|
+
|
|
710
|
+
if (status.status === 'SETTLED') {
|
|
711
|
+
console.log('Settlement transaction:', status.txHash);
|
|
712
|
+
}
|
|
713
|
+
```
|
|
714
|
+
|
|
715
|
+
**Intent Status Values:**
|
|
716
|
+
|
|
717
|
+
- `PENDING` - Intent published but not yet processed
|
|
718
|
+
- `TX_BROADCASTED` - Intent being processed, transaction broadcasted
|
|
719
|
+
- `SETTLED` - Intent successfully completed
|
|
720
|
+
- `NOT_FOUND_OR_NOT_VALID` - Intent not found or invalid, it isn't executed onchain
|
|
721
|
+
|
|
722
|
+
### Nonce Invalidation
|
|
723
|
+
|
|
724
|
+
Invalidate nonces to prevent execution of previously created intent payloads. Primarily used by **solvers** to revoke quotes due to price volatility, liquidity changes, or risk management.
|
|
725
|
+
|
|
726
|
+
```typescript
|
|
727
|
+
await sdk.invalidateNonces({
|
|
728
|
+
nonces: ['VigoxLwmUGf35MGLVBG9Fh5cCtJw3D68pSKFcqGCkHU='],
|
|
729
|
+
signer: customIntentSigner, // optional - uses SDK default if not provided
|
|
730
|
+
});
|
|
731
|
+
```
|
|
732
|
+
|
|
733
|
+
### Configure Withdrawal Routes
|
|
734
|
+
|
|
735
|
+
**Recommended**: Use factory functions to create route configurations. The SDK provides factory functions for type-safe
|
|
736
|
+
and convenient route configuration creation:
|
|
737
|
+
|
|
738
|
+
```typescript
|
|
739
|
+
import {
|
|
740
|
+
createVirtualChainRoute,
|
|
741
|
+
createNearWithdrawalRoute,
|
|
742
|
+
createInternalTransferRoute
|
|
743
|
+
} from '@defuse-protocol/intents-sdk';
|
|
744
|
+
|
|
745
|
+
// Create virtual chain route configuration (recommended)
|
|
746
|
+
const virtualChainRoute = createVirtualChainRoute(
|
|
747
|
+
'0x4e45415f.c.aurora', // Aurora Engine contract ID
|
|
748
|
+
null // Proxy token contract ID (optional)
|
|
749
|
+
);
|
|
750
|
+
|
|
751
|
+
// Create near withdrawal route with custom message
|
|
752
|
+
const nearWithdrawalRoute = createNearWithdrawalRoute(
|
|
753
|
+
'Custom withdrawal message' // Optional message
|
|
754
|
+
);
|
|
755
|
+
|
|
756
|
+
// Create internal transfer route
|
|
757
|
+
const internalTransferRoute = createInternalTransferRoute();
|
|
758
|
+
|
|
759
|
+
// Use the factory-created route configuration in withdrawal
|
|
760
|
+
const result = await sdk.processWithdrawal({
|
|
761
|
+
withdrawalParams: {
|
|
762
|
+
assetId: 'nep141:a35923162c49cf95e6bf26623385eb431ad920d3.factory.bridge.near',
|
|
763
|
+
amount: BigInt('1000000'),
|
|
764
|
+
destinationAddress: '0x742d35Cc6634C0532925a3b8D84B2021F90a51A3',
|
|
765
|
+
feeInclusive: false,
|
|
766
|
+
routeConfig: virtualChainRoute // Recommended: Use factory function
|
|
767
|
+
}
|
|
768
|
+
});
|
|
769
|
+
```
|
|
770
|
+
|
|
771
|
+
### Asset Information Parsing
|
|
772
|
+
|
|
773
|
+
Get detailed information about supported assets:
|
|
774
|
+
|
|
775
|
+
```typescript
|
|
776
|
+
try {
|
|
777
|
+
const assetInfo = sdk.parseAssetId('nep141:usdt.tether-token.near');
|
|
778
|
+
console.log('Bridge name:', assetInfo.bridgeName);
|
|
779
|
+
console.log('Blockchain:', assetInfo.blockchain);
|
|
780
|
+
console.log('Contract ID:', assetInfo.contractId);
|
|
781
|
+
console.log('Standard:', assetInfo.standard);
|
|
782
|
+
} catch (error) {
|
|
783
|
+
console.log('Asset not supported');
|
|
784
|
+
}
|
|
785
|
+
```
|
|
786
|
+
|
|
787
|
+
### Waiting for Completion
|
|
788
|
+
|
|
789
|
+
Monitor withdrawal completion:
|
|
790
|
+
|
|
791
|
+
```typescript
|
|
792
|
+
// Method 1: Using the orchestrated approach (automatic monitoring)
|
|
793
|
+
const result = await sdk.processWithdrawal({
|
|
794
|
+
withdrawalParams: {
|
|
795
|
+
assetId: 'nep141:usdt.tether-token.near',
|
|
796
|
+
amount: 1000000n,
|
|
797
|
+
destinationAddress: '0x742d35Cc...',
|
|
798
|
+
feeInclusive: false
|
|
799
|
+
}
|
|
800
|
+
});
|
|
801
|
+
|
|
802
|
+
console.log('Intent settled:', result.intentTx.hash);
|
|
803
|
+
console.log('Withdrawal completed:', result.destinationTx);
|
|
804
|
+
|
|
805
|
+
// Method 2: Step-by-step monitoring for granular control
|
|
806
|
+
const feeEstimation = await sdk.estimateWithdrawalFee({
|
|
807
|
+
withdrawalParams: {
|
|
808
|
+
assetId: 'nep141:usdt.tether-token.near',
|
|
809
|
+
amount: 1000000n,
|
|
810
|
+
destinationAddress: '0x742d35Cc...',
|
|
811
|
+
feeInclusive: false
|
|
812
|
+
}
|
|
813
|
+
});
|
|
814
|
+
|
|
815
|
+
const {intentHash} = await sdk.signAndSendWithdrawalIntent({
|
|
816
|
+
withdrawalParams: {
|
|
817
|
+
assetId: 'nep141:usdt.tether-token.near',
|
|
818
|
+
amount: 1000000n,
|
|
819
|
+
destinationAddress: '0x742d35Cc...',
|
|
820
|
+
feeInclusive: false
|
|
821
|
+
},
|
|
822
|
+
feeEstimation
|
|
823
|
+
});
|
|
824
|
+
|
|
825
|
+
// Monitor intent settlement
|
|
826
|
+
const intentTx = await sdk.waitForIntentSettlement({intentHash});
|
|
827
|
+
console.log('Intent settled:', intentTx.hash);
|
|
828
|
+
|
|
829
|
+
// Wait for withdrawal completion on destination chain
|
|
830
|
+
// Note: Has chain-specific p99 timeout - use signal for a shorter timeout
|
|
831
|
+
const completionResult = await sdk.waitForWithdrawalCompletion({
|
|
832
|
+
withdrawalParams: {
|
|
833
|
+
assetId: 'nep141:usdt.tether-token.near',
|
|
834
|
+
amount: 1000000n,
|
|
835
|
+
destinationAddress: '0x742d35Cc...',
|
|
836
|
+
feeInclusive: false
|
|
837
|
+
},
|
|
838
|
+
intentTx,
|
|
839
|
+
signal: AbortSignal.timeout(10 * 60 * 1000), // 10 minute timeout
|
|
840
|
+
});
|
|
841
|
+
|
|
842
|
+
if ('hash' in completionResult) {
|
|
843
|
+
console.log('Withdrawal completed with hash:', completionResult.hash);
|
|
844
|
+
} else {
|
|
845
|
+
console.log('Withdrawal completion not trackable for this bridge');
|
|
846
|
+
}
|
|
847
|
+
```
|
|
848
|
+
|
|
849
|
+
### Error Handling
|
|
850
|
+
|
|
851
|
+
```typescript
|
|
852
|
+
import {FeeExceedsAmountError, MinWithdrawalAmountError} from '@defuse-protocol/intents-sdk';
|
|
853
|
+
|
|
854
|
+
try {
|
|
855
|
+
const result = await sdk.processWithdrawal({
|
|
856
|
+
withdrawalParams: {
|
|
857
|
+
assetId: 'nep141:usdt.tether-token.near',
|
|
858
|
+
amount: BigInt('100'), // Very small amount
|
|
859
|
+
destinationAddress: '0x742d35Cc...',
|
|
860
|
+
feeInclusive: true // Fee must be less than amount
|
|
861
|
+
}
|
|
862
|
+
});
|
|
863
|
+
} catch (error) {
|
|
864
|
+
if (error instanceof FeeExceedsAmountError) {
|
|
865
|
+
console.log('Fee exceeds withdrawal amount');
|
|
866
|
+
console.log('Required fee:', error.feeEstimation.amount);
|
|
867
|
+
console.log('Withdrawal amount:', error.amount);
|
|
868
|
+
} else if (error instanceof MinWithdrawalAmountError) {
|
|
869
|
+
console.log('Amount below minimum withdrawal limit');
|
|
870
|
+
console.log('Minimum required:', error.minAmount);
|
|
871
|
+
console.log('Requested amount:', error.requestedAmount);
|
|
872
|
+
console.log('Asset:', error.assetId);
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
|
|
876
|
+
// Error handling with granular control
|
|
877
|
+
try {
|
|
878
|
+
const feeEstimation = await sdk.estimateWithdrawalFee({
|
|
879
|
+
withdrawalParams: {
|
|
880
|
+
assetId: 'nep141:usdt.tether-token.near',
|
|
881
|
+
amount: 100n,
|
|
882
|
+
destinationAddress: '0x742d35Cc...',
|
|
883
|
+
feeInclusive: true
|
|
884
|
+
}
|
|
885
|
+
});
|
|
886
|
+
|
|
887
|
+
// Continue with other operations...
|
|
888
|
+
} catch (error) {
|
|
889
|
+
// Handle specific errors at each step
|
|
890
|
+
console.error('Fee estimation failed:', error);
|
|
891
|
+
}
|
|
892
|
+
```
|
|
893
|
+
|
|
894
|
+
#### PoA Bridge Minimum Withdrawal Amount Validation
|
|
895
|
+
|
|
896
|
+
PoA bridge has minimum withdrawal amount requirements that vary per token and blockchain. The SDK automatically
|
|
897
|
+
validates this for all withdrawals.
|
|
898
|
+
|
|
899
|
+
```typescript
|
|
900
|
+
// Validation happens automatically during withdrawal processing:
|
|
901
|
+
try {
|
|
902
|
+
const result = await sdk.processWithdrawal({
|
|
903
|
+
withdrawalParams: {
|
|
904
|
+
assetId: 'nep141:zec.omft.near', // Zcash token
|
|
905
|
+
amount: BigInt('50000000'), // 0.5 ZEC (in smallest units)
|
|
906
|
+
destinationAddress: 'your-zcash-address',
|
|
907
|
+
feeInclusive: false
|
|
908
|
+
}
|
|
909
|
+
});
|
|
910
|
+
} catch (error) {
|
|
911
|
+
if (error instanceof MinWithdrawalAmountError) {
|
|
912
|
+
console.log(`Minimum withdrawal for ${error.assetId}: ${error.minAmount}`);
|
|
913
|
+
console.log(`Requested amount: ${error.requestedAmount}`);
|
|
914
|
+
// For Zcash: minimum is typically 1.0 ZEC (100000000 in smallest units)
|
|
915
|
+
// Plus 0.2 ZEC fee, so user needs at least 1.2 ZEC to withdraw 1.0 ZEC
|
|
916
|
+
}
|
|
917
|
+
}
|
|
918
|
+
```
|
|
919
|
+
|
|
920
|
+
Note: Other routes (Near Withdrawal, Virtual Chain, Internal Transfer) don't have minimum withdrawal restrictions, so
|
|
921
|
+
validation passes through for those routes.
|
|
922
|
+
|
|
923
|
+
#### Hot Bridge Stellar Trustline Validation
|
|
924
|
+
|
|
925
|
+
Hot Bridge validates that destination addresses have the required trustlines when withdrawing to Stellar blockchain.
|
|
926
|
+
This prevents failed transactions due to missing trustlines.
|
|
927
|
+
|
|
928
|
+
```typescript
|
|
929
|
+
import {TrustlineNotFoundError} from '@defuse-protocol/intents-sdk';
|
|
930
|
+
|
|
931
|
+
// Validation happens automatically during withdrawal processing:
|
|
932
|
+
try {
|
|
933
|
+
const result = await sdk.processWithdrawal({
|
|
934
|
+
withdrawalParams: {
|
|
935
|
+
assetId: 'nep245:v2_1.omni.hot.tg:stellar_1_USD_GBDMM6LG7YX7YGF6JFAEWX3KFUSBXGAEPZ2IHDLWH:1100', // Stellar USD token
|
|
936
|
+
amount: BigInt('1000000'), // 1 USD (in smallest units)
|
|
937
|
+
destinationAddress: 'GCKFBEIYTKP6RYVDYGMVVMJ6J6XKCRZL74JPWTFGD2NQNMPBQC2LGTVZ', // Stellar address
|
|
938
|
+
feeInclusive: false
|
|
939
|
+
}
|
|
940
|
+
});
|
|
941
|
+
} catch (error) {
|
|
942
|
+
if (error instanceof TrustlineNotFoundError) {
|
|
943
|
+
console.log(`Trustline not found for token: ${error.assetId}`);
|
|
944
|
+
console.log(`Destination address: ${error.destinationAddress}`);
|
|
945
|
+
console.log('The destination address must have a trustline for this token before withdrawal');
|
|
946
|
+
// User needs to create a trustline for the token on Stellar before withdrawing
|
|
947
|
+
}
|
|
948
|
+
}
|
|
949
|
+
```
|
|
950
|
+
|
|
951
|
+
**What is a trustline?**
|
|
952
|
+
On Stellar, accounts must explicitly create "trustlines" to hold non-native assets. Before receiving any token (except
|
|
953
|
+
XLM), the destination address must:
|
|
954
|
+
|
|
955
|
+
1. Create a trustline for that specific token
|
|
956
|
+
2. Have sufficient XLM balance to maintain the trustline
|
|
957
|
+
|
|
958
|
+
**Why this validation matters:**
|
|
959
|
+
|
|
960
|
+
- Prevents failed withdrawals due to missing trustlines
|
|
961
|
+
- Saves gas fees and reduces user frustration
|
|
962
|
+
- Provides clear error messages for troubleshooting
|
|
963
|
+
|
|
964
|
+
Note: This validation only applies to Stellar destinations via Hot Bridge. Other blockchains and routes don't require
|
|
965
|
+
trustline validation.
|
|
966
|
+
|
|
967
|
+
#### Omni Bridge Withdrawal Validation
|
|
968
|
+
|
|
969
|
+
SDK verifies that the token exists on the destination chain.
|
|
970
|
+
|
|
971
|
+
```typescript
|
|
972
|
+
import { TokenNotFoundInDestinationChainError } from '@defuse-protocol/intents-sdk';
|
|
973
|
+
|
|
974
|
+
try {
|
|
975
|
+
const result = await sdk.processWithdrawal({
|
|
976
|
+
withdrawalParams: {
|
|
977
|
+
assetId: 'nep141:aaaaaa20d9e0e2461697782ef11675f668207961.factory.bridge.near', // Aurora token
|
|
978
|
+
amount: 70000000000000000000n, // 70 Aurora (in smallest units)
|
|
979
|
+
destinationAddress: '0x741b0b0F27c4b4047ecFCcDf4690F749C6Cfd66c',
|
|
980
|
+
feeInclusive: false
|
|
981
|
+
}
|
|
982
|
+
});
|
|
983
|
+
} catch (error) {
|
|
984
|
+
if (error instanceof TokenNotFoundInDestinationChainError) {
|
|
985
|
+
console.log(`Token ${error.token} was not found on ${error.destinationChain}.`);
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
```
|
|
989
|
+
|
|
990
|
+
### Atomic Multi-Intent Publishing
|
|
991
|
+
|
|
992
|
+
Include pre-signed intents (from other users or prior operations) to be published atomically with your new intent.
|
|
993
|
+
Useful for multi-user coordination and batch operations.
|
|
994
|
+
|
|
995
|
+
```typescript
|
|
996
|
+
import type { MultiPayload } from '@defuse-protocol/intents-sdk';
|
|
997
|
+
|
|
998
|
+
// Include pre-signed intents before/after your new intent
|
|
999
|
+
await sdk.signAndSendIntent({
|
|
1000
|
+
intents: [{ intent: "transfer", receiver_id: "alice.near", tokens: {...} }],
|
|
1001
|
+
signedIntents: {
|
|
1002
|
+
before: [preSigned1], // Execute before new intent
|
|
1003
|
+
after: [preSigned2] // Execute after new intent
|
|
1004
|
+
}
|
|
1005
|
+
});
|
|
1006
|
+
|
|
1007
|
+
// Also works with withdrawals
|
|
1008
|
+
await sdk.processWithdrawal({
|
|
1009
|
+
withdrawalParams: {...},
|
|
1010
|
+
intent: {
|
|
1011
|
+
signedIntents: {
|
|
1012
|
+
before: [preSigned1],
|
|
1013
|
+
after: [preSigned2]
|
|
1014
|
+
}
|
|
1015
|
+
}
|
|
1016
|
+
});
|
|
1017
|
+
```
|
|
1018
|
+
|
|
1019
|
+
**Key Points:**
|
|
1020
|
+
- All intents execute atomically in order: `before` → new intent → `after`
|
|
1021
|
+
- Returned `intentHash` is for your newly created intent, not the included ones
|
|
1022
|
+
|
|
1023
|
+
## Supported Networks
|
|
1024
|
+
|
|
1025
|
+
For a list of supported chains, see
|
|
1026
|
+
the [Chain Support page](https://docs.near-intents.org/near-intents/chain-address-support) in the Near Intents
|
|
1027
|
+
documentation.
|
|
1028
|
+
|
|
1029
|
+
## Development
|
|
1030
|
+
|
|
1031
|
+
### Prerequisites
|
|
1032
|
+
|
|
1033
|
+
- [Node.js](https://nodejs.org/) (v20 or later)
|
|
1034
|
+
- [pnpm](https://pnpm.io/) for package management
|
|
1035
|
+
|
|
1036
|
+
### Setup
|
|
1037
|
+
|
|
1038
|
+
```bash
|
|
1039
|
+
# Install dependencies (from the monorepo root)
|
|
1040
|
+
pnpm install
|
|
1041
|
+
```
|
|
1042
|
+
|
|
1043
|
+
### Build
|
|
1044
|
+
|
|
1045
|
+
```bash
|
|
1046
|
+
# Build the package
|
|
1047
|
+
pnpm run build
|
|
1048
|
+
|
|
1049
|
+
# Build in watch mode
|
|
1050
|
+
pnpm run dev
|
|
1051
|
+
```
|
|
1052
|
+
|
|
1053
|
+
### Test
|
|
1054
|
+
|
|
1055
|
+
```bash
|
|
1056
|
+
# Run tests
|
|
1057
|
+
pnpm run test
|
|
1058
|
+
|
|
1059
|
+
# Run tests in watch mode
|
|
1060
|
+
pnpm run test:watch
|
|
1061
|
+
```
|
|
1062
|
+
|
|
1063
|
+
### Lint and Format
|
|
1064
|
+
|
|
1065
|
+
```bash
|
|
1066
|
+
# Check code style
|
|
1067
|
+
pnpm run lint
|
|
1068
|
+
|
|
1069
|
+
# Format code
|
|
1070
|
+
pnpm run format
|
|
1071
|
+
```
|
|
1072
|
+
|
|
1073
|
+
## Version History
|
|
1074
|
+
|
|
1075
|
+
See [CHANGELOG.md](./CHANGELOG.md) for detailed version history and migration guides.
|
|
1076
|
+
|
|
1077
|
+
## Contributing
|
|
1078
|
+
|
|
1079
|
+
This package is part of Near Intents SDK monorepo. Please refer to the main repository's contributing guidelines.
|
|
1080
|
+
|
|
1081
|
+
## License
|
|
1082
|
+
|
|
1083
|
+
MIT License © 2025 NEAR Foundation
|