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.
Files changed (179) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1083 -0
  3. package/dist/_virtual/rolldown_runtime.cjs +29 -0
  4. package/dist/index.cjs +124 -0
  5. package/dist/index.d.cts +22 -0
  6. package/dist/index.d.ts +22 -0
  7. package/dist/index.js +19 -0
  8. package/dist/src/bridges/aurora-engine-bridge/aurora-engine-bridge-constants.cjs +10 -0
  9. package/dist/src/bridges/aurora-engine-bridge/aurora-engine-bridge-constants.js +7 -0
  10. package/dist/src/bridges/aurora-engine-bridge/aurora-engine-bridge-utils.cjs +44 -0
  11. package/dist/src/bridges/aurora-engine-bridge/aurora-engine-bridge-utils.js +42 -0
  12. package/dist/src/bridges/aurora-engine-bridge/aurora-engine-bridge.cjs +111 -0
  13. package/dist/src/bridges/aurora-engine-bridge/aurora-engine-bridge.js +110 -0
  14. package/dist/src/bridges/direct-bridge/direct-bridge-constants.cjs +8 -0
  15. package/dist/src/bridges/direct-bridge/direct-bridge-constants.js +6 -0
  16. package/dist/src/bridges/direct-bridge/direct-bridge-utils.cjs +47 -0
  17. package/dist/src/bridges/direct-bridge/direct-bridge-utils.js +44 -0
  18. package/dist/src/bridges/direct-bridge/direct-bridge.cjs +155 -0
  19. package/dist/src/bridges/direct-bridge/direct-bridge.js +154 -0
  20. package/dist/src/bridges/direct-bridge/error.cjs +16 -0
  21. package/dist/src/bridges/direct-bridge/error.d.cts +12 -0
  22. package/dist/src/bridges/direct-bridge/error.d.ts +12 -0
  23. package/dist/src/bridges/direct-bridge/error.js +15 -0
  24. package/dist/src/bridges/hot-bridge/error.cjs +23 -0
  25. package/dist/src/bridges/hot-bridge/error.d.cts +19 -0
  26. package/dist/src/bridges/hot-bridge/error.d.ts +19 -0
  27. package/dist/src/bridges/hot-bridge/error.js +21 -0
  28. package/dist/src/bridges/hot-bridge/hot-bridge-chains.cjs +21 -0
  29. package/dist/src/bridges/hot-bridge/hot-bridge-chains.d.cts +6 -0
  30. package/dist/src/bridges/hot-bridge/hot-bridge-chains.d.ts +6 -0
  31. package/dist/src/bridges/hot-bridge/hot-bridge-chains.js +20 -0
  32. package/dist/src/bridges/hot-bridge/hot-bridge-constants.cjs +11 -0
  33. package/dist/src/bridges/hot-bridge/hot-bridge-constants.js +9 -0
  34. package/dist/src/bridges/hot-bridge/hot-bridge-utils.cjs +66 -0
  35. package/dist/src/bridges/hot-bridge/hot-bridge-utils.js +61 -0
  36. package/dist/src/bridges/hot-bridge/hot-bridge.cjs +241 -0
  37. package/dist/src/bridges/hot-bridge/hot-bridge.js +239 -0
  38. package/dist/src/bridges/intents-bridge/intents-bridge.cjs +59 -0
  39. package/dist/src/bridges/intents-bridge/intents-bridge.js +59 -0
  40. package/dist/src/bridges/omni-bridge/error.cjs +54 -0
  41. package/dist/src/bridges/omni-bridge/error.d.cts +41 -0
  42. package/dist/src/bridges/omni-bridge/error.d.ts +41 -0
  43. package/dist/src/bridges/omni-bridge/error.js +49 -0
  44. package/dist/src/bridges/omni-bridge/omni-bridge-constants.cjs +12 -0
  45. package/dist/src/bridges/omni-bridge/omni-bridge-constants.js +8 -0
  46. package/dist/src/bridges/omni-bridge/omni-bridge-utils.cjs +153 -0
  47. package/dist/src/bridges/omni-bridge/omni-bridge-utils.js +143 -0
  48. package/dist/src/bridges/omni-bridge/omni-bridge.cjs +316 -0
  49. package/dist/src/bridges/omni-bridge/omni-bridge.js +314 -0
  50. package/dist/src/bridges/poa-bridge/poa-bridge-utils.cjs +76 -0
  51. package/dist/src/bridges/poa-bridge/poa-bridge-utils.js +73 -0
  52. package/dist/src/bridges/poa-bridge/poa-bridge.cjs +175 -0
  53. package/dist/src/bridges/poa-bridge/poa-bridge.js +173 -0
  54. package/dist/src/bridges/poa-bridge/poa-constants.cjs +6 -0
  55. package/dist/src/bridges/poa-bridge/poa-constants.js +5 -0
  56. package/dist/src/classes/errors.cjs +87 -0
  57. package/dist/src/classes/errors.d.cts +48 -0
  58. package/dist/src/classes/errors.d.ts +48 -0
  59. package/dist/src/classes/errors.js +81 -0
  60. package/dist/src/constants/bridge-name-enum.cjs +11 -0
  61. package/dist/src/constants/bridge-name-enum.d.cts +11 -0
  62. package/dist/src/constants/bridge-name-enum.d.ts +11 -0
  63. package/dist/src/constants/bridge-name-enum.js +10 -0
  64. package/dist/src/constants/poa-tokens-routable-through-omni-bridge.cjs +17 -0
  65. package/dist/src/constants/poa-tokens-routable-through-omni-bridge.d.cts +12 -0
  66. package/dist/src/constants/poa-tokens-routable-through-omni-bridge.d.ts +12 -0
  67. package/dist/src/constants/poa-tokens-routable-through-omni-bridge.js +16 -0
  68. package/dist/src/constants/public-rpc-urls.cjs +25 -0
  69. package/dist/src/constants/public-rpc-urls.js +24 -0
  70. package/dist/src/constants/route-enum.cjs +13 -0
  71. package/dist/src/constants/route-enum.d.cts +13 -0
  72. package/dist/src/constants/route-enum.d.ts +13 -0
  73. package/dist/src/constants/route-enum.js +12 -0
  74. package/dist/src/constants/withdrawal-timing.cjs +68 -0
  75. package/dist/src/constants/withdrawal-timing.js +68 -0
  76. package/dist/src/core/withdrawal-watcher.cjs +86 -0
  77. package/dist/src/core/withdrawal-watcher.d.cts +18 -0
  78. package/dist/src/core/withdrawal-watcher.d.ts +19 -0
  79. package/dist/src/core/withdrawal-watcher.js +82 -0
  80. package/dist/src/intents/expirable-nonce.cjs +90 -0
  81. package/dist/src/intents/expirable-nonce.d.cts +44 -0
  82. package/dist/src/intents/expirable-nonce.d.ts +45 -0
  83. package/dist/src/intents/expirable-nonce.js +82 -0
  84. package/dist/src/intents/intent-executer-impl/intent-executer.cjs +85 -0
  85. package/dist/src/intents/intent-executer-impl/intent-executer.d.cts +20 -0
  86. package/dist/src/intents/intent-executer-impl/intent-executer.d.ts +24 -0
  87. package/dist/src/intents/intent-executer-impl/intent-executer.js +85 -0
  88. package/dist/src/intents/intent-hash.cjs +48 -0
  89. package/dist/src/intents/intent-hash.d.cts +8 -0
  90. package/dist/src/intents/intent-hash.d.ts +8 -0
  91. package/dist/src/intents/intent-hash.js +47 -0
  92. package/dist/src/intents/intent-hashes/erc191.cjs +38 -0
  93. package/dist/src/intents/intent-hashes/erc191.js +37 -0
  94. package/dist/src/intents/intent-hashes/nep413.cjs +23 -0
  95. package/dist/src/intents/intent-hashes/nep413.js +22 -0
  96. package/dist/src/intents/intent-hashes/raw-ed25519.cjs +26 -0
  97. package/dist/src/intents/intent-hashes/raw-ed25519.js +25 -0
  98. package/dist/src/intents/intent-hashes/sep53.cjs +36 -0
  99. package/dist/src/intents/intent-hashes/sep53.js +35 -0
  100. package/dist/src/intents/intent-hashes/tip191.cjs +39 -0
  101. package/dist/src/intents/intent-hashes/tip191.js +38 -0
  102. package/dist/src/intents/intent-hashes/ton-connect.cjs +105 -0
  103. package/dist/src/intents/intent-hashes/ton-connect.js +104 -0
  104. package/dist/src/intents/intent-hashes/webauthn.cjs +26 -0
  105. package/dist/src/intents/intent-hashes/webauthn.js +25 -0
  106. package/dist/src/intents/intent-payload-builder.cjs +208 -0
  107. package/dist/src/intents/intent-payload-builder.d.cts +161 -0
  108. package/dist/src/intents/intent-payload-builder.d.ts +161 -0
  109. package/dist/src/intents/intent-payload-builder.js +207 -0
  110. package/dist/src/intents/intent-payload-factory.cjs +23 -0
  111. package/dist/src/intents/intent-payload-factory.js +21 -0
  112. package/dist/src/intents/intent-relayer-impl/intent-relayer-public.cjs +43 -0
  113. package/dist/src/intents/intent-relayer-impl/intent-relayer-public.js +42 -0
  114. package/dist/src/intents/intent-signer-impl/factories.cjs +19 -0
  115. package/dist/src/intents/intent-signer-impl/factories.d.cts +11 -0
  116. package/dist/src/intents/intent-signer-impl/factories.d.ts +11 -0
  117. package/dist/src/intents/intent-signer-impl/factories.js +17 -0
  118. package/dist/src/intents/intent-signer-impl/intent-signer-near-keypair.cjs +22 -0
  119. package/dist/src/intents/intent-signer-impl/intent-signer-near-keypair.d.cts +15 -0
  120. package/dist/src/intents/intent-signer-impl/intent-signer-near-keypair.d.ts +16 -0
  121. package/dist/src/intents/intent-signer-impl/intent-signer-near-keypair.js +21 -0
  122. package/dist/src/intents/intent-signer-impl/intent-signer-nep413.cjs +37 -0
  123. package/dist/src/intents/intent-signer-impl/intent-signer-nep413.d.cts +14 -0
  124. package/dist/src/intents/intent-signer-impl/intent-signer-nep413.d.ts +14 -0
  125. package/dist/src/intents/intent-signer-impl/intent-signer-nep413.js +36 -0
  126. package/dist/src/intents/intent-signer-impl/intent-signer-noop.cjs +8 -0
  127. package/dist/src/intents/intent-signer-impl/intent-signer-noop.js +7 -0
  128. package/dist/src/intents/intent-signer-impl/intent-signer-viem.cjs +31 -0
  129. package/dist/src/intents/intent-signer-impl/intent-signer-viem.d.cts +17 -0
  130. package/dist/src/intents/intent-signer-impl/intent-signer-viem.d.ts +17 -0
  131. package/dist/src/intents/intent-signer-impl/intent-signer-viem.js +30 -0
  132. package/dist/src/intents/interfaces/intent-executer.d.ts +2 -0
  133. package/dist/src/intents/interfaces/intent-relayer.d.cts +43 -0
  134. package/dist/src/intents/interfaces/intent-relayer.d.ts +43 -0
  135. package/dist/src/intents/interfaces/intent-signer.d.cts +8 -0
  136. package/dist/src/intents/interfaces/intent-signer.d.ts +8 -0
  137. package/dist/src/intents/interfaces/salt-manager.d.cts +9 -0
  138. package/dist/src/intents/interfaces/salt-manager.d.ts +9 -0
  139. package/dist/src/intents/salt-manager.cjs +74 -0
  140. package/dist/src/intents/salt-manager.js +72 -0
  141. package/dist/src/intents/shared-types.d.cts +20 -0
  142. package/dist/src/intents/shared-types.d.ts +20 -0
  143. package/dist/src/lib/array.cjs +11 -0
  144. package/dist/src/lib/array.js +10 -0
  145. package/dist/src/lib/caip2.cjs +50 -0
  146. package/dist/src/lib/caip2.d.cts +38 -0
  147. package/dist/src/lib/caip2.d.ts +38 -0
  148. package/dist/src/lib/caip2.js +48 -0
  149. package/dist/src/lib/configure-rpc-config.cjs +20 -0
  150. package/dist/src/lib/configure-rpc-config.js +18 -0
  151. package/dist/src/lib/estimate-fee.cjs +96 -0
  152. package/dist/src/lib/estimate-fee.js +94 -0
  153. package/dist/src/lib/hex.cjs +11 -0
  154. package/dist/src/lib/hex.js +10 -0
  155. package/dist/src/lib/nep413.cjs +42 -0
  156. package/dist/src/lib/nep413.d.cts +14 -0
  157. package/dist/src/lib/nep413.d.ts +14 -0
  158. package/dist/src/lib/nep413.js +41 -0
  159. package/dist/src/lib/object.cjs +10 -0
  160. package/dist/src/lib/object.js +9 -0
  161. package/dist/src/lib/parse-defuse-asset-id.cjs +15 -0
  162. package/dist/src/lib/parse-defuse-asset-id.js +14 -0
  163. package/dist/src/lib/route-config-factory.cjs +43 -0
  164. package/dist/src/lib/route-config-factory.d.cts +13 -0
  165. package/dist/src/lib/route-config-factory.d.ts +13 -0
  166. package/dist/src/lib/route-config-factory.js +37 -0
  167. package/dist/src/lib/tokensUsdPricesHttpClient/apis.cjs +17 -0
  168. package/dist/src/lib/tokensUsdPricesHttpClient/apis.js +16 -0
  169. package/dist/src/lib/validateAddress.cjs +271 -0
  170. package/dist/src/lib/validateAddress.d.cts +14 -0
  171. package/dist/src/lib/validateAddress.d.ts +14 -0
  172. package/dist/src/lib/validateAddress.js +270 -0
  173. package/dist/src/sdk.cjs +435 -0
  174. package/dist/src/sdk.d.cts +231 -0
  175. package/dist/src/sdk.d.ts +231 -0
  176. package/dist/src/sdk.js +433 -0
  177. package/dist/src/shared-types.d.cts +378 -0
  178. package/dist/src/shared-types.d.ts +378 -0
  179. 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