@ldgr/client 0.5.0 → 0.6.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/README.md +139 -4
- package/dist/client.d.ts +1 -0
- package/dist/index.d.ts +30 -2
- package/dist/index.js +99 -19
- package/dist/types.d.ts +139 -2
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -8,6 +8,22 @@ It does not create a hosted wallet, persist a private key, or replace the
|
|
|
8
8
|
browser extension. Use `@ldgr/wallet-sdk` when a website needs an explicit
|
|
9
9
|
user confirmation in the LDGR extension.
|
|
10
10
|
|
|
11
|
+
## Contract reads
|
|
12
|
+
|
|
13
|
+
Version `0.6.1` publishes `getLedraContract`, `getMilestoneEscrow`,
|
|
14
|
+
`getAtomicOffer`, and `getClaimDistribution`, together with their typed mutation
|
|
15
|
+
methods. It requires `@ldgr/protocol@^0.5.1` for the corresponding payload types.
|
|
16
|
+
Version `0.6.0` does not include these methods. Upgrade the installed client and
|
|
17
|
+
restart consumers before using these contract APIs.
|
|
18
|
+
|
|
19
|
+
## Primary usernames
|
|
20
|
+
|
|
21
|
+
`client.usernames.findPrimary(address)` returns the primary username record or
|
|
22
|
+
`null` when the address has no active primary username. It uses the optional
|
|
23
|
+
lookup endpoint (`?optional=true`); lookup and transport failures still throw.
|
|
24
|
+
`client.usernames.getPrimary(address)` keeps the required lookup behavior and
|
|
25
|
+
throws on the endpoint's default 404 when no primary username exists.
|
|
26
|
+
|
|
11
27
|
## Service wallets and recovery keys
|
|
12
28
|
|
|
13
29
|
`generateLocalWallet()` creates caller-owned key material for a service wallet.
|
|
@@ -67,9 +83,10 @@ Settlement failures return `status: "failed"`; they do not have a transaction
|
|
|
67
83
|
hash or fee because the ledger rejected them before appending a transaction.
|
|
68
84
|
Transport and unexpected response errors still throw.
|
|
69
85
|
|
|
70
|
-
##
|
|
86
|
+
## Confidential payments
|
|
71
87
|
|
|
72
|
-
|
|
88
|
+
The product term is **confidential payments**. The compatibility-stable
|
|
89
|
+
`silentPayments.send()` API accepts a reusable LDGR payment code and a
|
|
73
90
|
`LocalLdgrWallet`. It signs and publishes the wallet's immutable sender-DH
|
|
74
91
|
public key, fetches the asset nonce, derives a fresh one-time destination, and
|
|
75
92
|
submits an ordinary transfer. A `NONCE_MISMATCH` causes one fresh derivation;
|
|
@@ -112,8 +129,9 @@ ledger-sequence `nextAfter` checkpoint, and `moreAvailable`. Matching requires
|
|
|
112
129
|
the receiver scan secret and belongs in wallet code such as
|
|
113
130
|
`@ldgr/wallet-core`, never on a server that does not own the recovery key. This
|
|
114
131
|
LDGR-specific construction is not BIP-352-compatible and remains experimental.
|
|
115
|
-
Wallet discovery is available on both ledgers
|
|
116
|
-
|
|
132
|
+
Wallet discovery is available on both ledgers. The extension and Web Wallet
|
|
133
|
+
display reusable codes; the Web Wallet also sends to them. Spending or
|
|
134
|
+
consolidating confidential-payment outputs remains gated pending testnet-first
|
|
117
135
|
operational testing and external cryptographic review.
|
|
118
136
|
|
|
119
137
|
```ts
|
|
@@ -139,6 +157,59 @@ transaction hash as the idempotency key. AMM quotes are estimates: pass an
|
|
|
139
157
|
explicit minimum output in the signed swap payload and re-quote immediately
|
|
140
158
|
before signing.
|
|
141
159
|
|
|
160
|
+
## Widget and Checkout merchant verification
|
|
161
|
+
|
|
162
|
+
Available in `@ldgr/client` **0.6.0**. These methods work on servers without
|
|
163
|
+
DOM globals or wallet keys. Configure the client's network from your saved
|
|
164
|
+
order and pass only the widget's identifiers as the submitted proof:
|
|
165
|
+
|
|
166
|
+
```ts
|
|
167
|
+
import { createLdgrClient } from "@ldgr/client";
|
|
168
|
+
|
|
169
|
+
const order = await orders.load(orderId); // Your persisted server order.
|
|
170
|
+
const client = createLdgrClient({ network: order.network });
|
|
171
|
+
const payment = await client.payments.verifyPayment({
|
|
172
|
+
transactionHash: submitted.transactionHash,
|
|
173
|
+
checkoutSessionId: submitted.checkoutSessionId, // Optional for wallet payments.
|
|
174
|
+
}, {
|
|
175
|
+
to: order.recipient,
|
|
176
|
+
asset: order.assetCode,
|
|
177
|
+
amount: order.grossAmount, // Exact decimal string, including Checkout's fee.
|
|
178
|
+
reference: order.publicReference,
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
if (payment.status === "confirmed") {
|
|
182
|
+
// In one database transaction: check order expiry, claim a unique
|
|
183
|
+
// (network, transactionHash), bind it to this order, and fulfil once.
|
|
184
|
+
await orders.fulfilOnce(order.id, order.network, payment.transactionHash);
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
`verifyPayment` explicitly dispatches to Checkout when `checkoutSessionId` is
|
|
189
|
+
provided; otherwise it requires a plain transfer. It never infers Checkout
|
|
190
|
+
from arbitrary batch metadata or falls back after a session mismatch. Expected
|
|
191
|
+
`to`, `asset`, gross decimal `amount`, and `reference` must come from your server,
|
|
192
|
+
not from the browser. Amount comparisons use exact strings, never floating point.
|
|
193
|
+
|
|
194
|
+
For a known Checkout session, use `payments.verifyCheckout(sessionId, {
|
|
195
|
+
to, asset, amount, reference, transactionHash? })`. It checks the authoritative
|
|
196
|
+
session ID, ledger, recipient, asset, gross amount, reference, paid state, and
|
|
197
|
+
optional submitted hash. A confirmed result includes `sessionId`,
|
|
198
|
+
`transactionHash`, `from`, `to`, `asset`, gross `amount`, `merchantAmount`, and
|
|
199
|
+
`checkoutFee`. With the default fee, a gross `1` USDL receipt reports merchant
|
|
200
|
+
`0.995` USDL and Checkout fee `0.005` USDL. Do not compare the net receipt with
|
|
201
|
+
the gross order amount.
|
|
202
|
+
|
|
203
|
+
Non-confirmed Checkout results are `pending`, `expired`, `not_found`, or
|
|
204
|
+
`mismatch`. An expired funding instruction does not invalidate a paid receipt.
|
|
205
|
+
Network/server errors and invalid arguments throw; callers must not fulfil on
|
|
206
|
+
an error. `verifyTransfer` remains a strict plain-transfer verifier. It also
|
|
207
|
+
checks that the response hash matches the requested hash.
|
|
208
|
+
|
|
209
|
+
The SDK reads receipts; your service owns authentication, order persistence,
|
|
210
|
+
order expiry rules, and atomic duplicate-payment protection. Browser SDK
|
|
211
|
+
`getPaymentStatus` / `getCheckoutStatus` results are UX hints only.
|
|
212
|
+
|
|
142
213
|
## LDGR402 merchant verification
|
|
143
214
|
|
|
144
215
|
For a persisted LDGR402 requirement and the browser's
|
|
@@ -159,3 +230,67 @@ if (verification.status === "confirmed") {
|
|
|
159
230
|
requirements, and verifies the exact settled transfer through the
|
|
160
231
|
authoritative Worker. The merchant still owns challenge persistence and
|
|
161
232
|
idempotent fulfillment.
|
|
233
|
+
|
|
234
|
+
## Caller-signed atomic offers
|
|
235
|
+
|
|
236
|
+
`getAtomicOffer(contractId)` reads the authoritative fixed-counterparty offer.
|
|
237
|
+
`openAtomicOffer`, `acceptAtomicOffer`, `cancelAtomicOffer` and `refundAtomicOffer`
|
|
238
|
+
submit typed caller-signed envelopes and return canonical terms plus the committed
|
|
239
|
+
action's `transactionHash`. The four submission types are exported as
|
|
240
|
+
`AtomicOfferOpenSubmission`, `AtomicOfferAcceptSubmission`,
|
|
241
|
+
`AtomicOfferCancelSubmission` and `AtomicOfferRefundSubmission`.
|
|
242
|
+
|
|
243
|
+
```ts
|
|
244
|
+
const offer = await client.getAtomicOffer(contractId);
|
|
245
|
+
const receipt = await client.acceptAtomicOffer(callerSignedAcceptance);
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
Sign the protocol's canonical payload using bigint atomic amounts, then transport
|
|
249
|
+
each traded amount as an exact decimal string using that asset's registry
|
|
250
|
+
decimals. `maxFeeAtomic` is an atomic integer string; nonce, timestamp and expiry
|
|
251
|
+
are integer strings. Preserve exact asset codes, signature, fields and original
|
|
252
|
+
open payload hash. These methods forward the supplied envelope unchanged and do
|
|
253
|
+
not sign, resolve aliases, replace nonces or automatically retry. A timeout leaves
|
|
254
|
+
the submission status unknown: read the offer or retry the identical signed
|
|
255
|
+
submission. Exact committed retries return the original action hash, even if a
|
|
256
|
+
later action changed the offer's status.
|
|
257
|
+
|
|
258
|
+
This is the protocol/API/client foundation. First-party wallet provider methods,
|
|
259
|
+
confirmation screens, offer-detail pages and a Utilities builder are deferred.
|
|
260
|
+
|
|
261
|
+
## Caller-signed milestone escrow
|
|
262
|
+
|
|
263
|
+
`getMilestoneEscrow(contractId)` reads the canonical prepaid escrow.
|
|
264
|
+
`openMilestoneEscrow(signed)`, `releaseMilestoneEscrow(signed)` and
|
|
265
|
+
`refundMilestoneEscrow(signed)` submit typed caller-signed envelopes unchanged.
|
|
266
|
+
Opening `amount` and every `milestones[].amount` are exact decimal strings in
|
|
267
|
+
the escrow asset. Nonce, timestamp, expiry and native `maxFeeAtomic` are integer
|
|
268
|
+
strings; release `milestoneIndex` is a zero-based integer number. Every action
|
|
269
|
+
uses the actual escrow asset and its payer nonce lane.
|
|
270
|
+
|
|
271
|
+
Only the payer can release the next step before expiry or refund the residual
|
|
272
|
+
at or after expiry. Records include `releasedMilestones`, `releasedAmount`,
|
|
273
|
+
`remainingAmount` and `refundedAmount`; released payments remain final.
|
|
274
|
+
These methods never sign or rebuild submissions and never retry automatically.
|
|
275
|
+
After an ambiguous submission, reconcile canonical state and preserve the exact
|
|
276
|
+
signed envelope when retrying.
|
|
277
|
+
|
|
278
|
+
## Caller-signed claim distributions
|
|
279
|
+
|
|
280
|
+
`getClaimDistribution(contractId)` reads the canonical prepaid distribution.
|
|
281
|
+
`openClaimDistribution(signed)`, `claimClaimDistribution(signed)` and
|
|
282
|
+
`refundClaimDistribution(signed)` forward typed caller-signed envelopes unchanged.
|
|
283
|
+
Opening `amount` and `allocations[].amount` are exact asset decimal strings over
|
|
284
|
+
HTTP; sign their protocol equivalents as bigint atomic amounts. Nonce, timestamp,
|
|
285
|
+
expiry and opening `maxFeeAtomic` use integer strings. Every action uses the exact
|
|
286
|
+
distribution asset and the signing account's nonce lane.
|
|
287
|
+
|
|
288
|
+
Opening allocates the total to 1–64 unique recipients other than the funder.
|
|
289
|
+
Each recipient can claim its complete zero-based `claimIndex` once before expiry,
|
|
290
|
+
in any order. Claims and refunds require the original `openPayloadHash`; only the
|
|
291
|
+
funder can refund unclaimed funds at or after expiry. Opening pays a capped native
|
|
292
|
+
fee; settlement is fee-free and supports known inactive assets. Records expose
|
|
293
|
+
per-allocation `claimed` flags, `claimedAllocations`, `claimedAmount`,
|
|
294
|
+
`remainingAmount` and `refundedAmount`. Mutations return the committed
|
|
295
|
+
`transactionHash`. These methods never sign, replace nonces or automatically
|
|
296
|
+
retry: preserve the exact signed envelope after an unknown outcome.
|
package/dist/client.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type LdgrClientOptions } from "./types";
|
|
2
2
|
export type Transport = {
|
|
3
3
|
readonly get: <T>(path: string) => Promise<T>;
|
|
4
|
+
readonly getOptional: <T>(path: string) => Promise<T | null>;
|
|
4
5
|
readonly post: <T>(path: string, body: unknown) => Promise<T>;
|
|
5
6
|
};
|
|
6
7
|
export declare function createTransport(options: LdgrClientOptions): Transport;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
|
+
import type { LedraContractDeploySubmission, LedraContractInvokeSubmission, LedraContractRefundSubmission } from "./types";
|
|
2
|
+
export type { LedraContractDeploySubmission, LedraContractInvokeSubmission, LedraContractRefundSubmission, LdgrLedraContract, LdgrLedraContractMutation } from "./types";
|
|
3
|
+
import type { ClaimDistributionOpenSubmission, ClaimDistributionClaimSubmission, ClaimDistributionRefundSubmission, LdgrClaimDistribution, LdgrClaimDistributionMutation } from "./types";
|
|
4
|
+
export type { ClaimDistributionOpenSubmission, ClaimDistributionClaimSubmission, ClaimDistributionRefundSubmission, LdgrClaimDistribution, LdgrClaimDistributionMutation } from "./types";
|
|
5
|
+
import type { MilestoneEscrowOpenSubmission, MilestoneEscrowReleaseSubmission, MilestoneEscrowRefundSubmission, LdgrMilestoneEscrow, LdgrMilestoneEscrowMutation } from "./types";
|
|
6
|
+
export type { MilestoneEscrowOpenSubmission, MilestoneEscrowReleaseSubmission, MilestoneEscrowRefundSubmission, LdgrMilestoneEscrow, LdgrMilestoneEscrowMutation } from "./types";
|
|
7
|
+
import type { AtomicOfferOpenSubmission, AtomicOfferAcceptSubmission, AtomicOfferCancelSubmission, AtomicOfferRefundSubmission, LdgrAtomicOffer, LdgrAtomicOfferMutation } from "./types";
|
|
8
|
+
export type { AtomicOfferOpenSubmission, AtomicOfferAcceptSubmission, AtomicOfferCancelSubmission, AtomicOfferRefundSubmission, LdgrAtomicOffer, LdgrAtomicOfferMutation } from "./types";
|
|
1
9
|
import { type LdgrTransferResult, type SendTransferInput } from "./transfer";
|
|
2
10
|
import { type Ldgr402Requirement } from "@ldgr/protocol";
|
|
3
|
-
import { type LdgrAccountTransactionPage, type LdgrClientOptions, type LdgrAsset, type Ldgr402Verification, type LdgrTransaction, type PaymentExpectation, type PaymentVerification, type SignedSubmission, type SilentPaymentSendInput, type SilentPaymentScanPage, type WalletPublicKeyRecord, type WalletPublicKeyRegistration } from "./types";
|
|
11
|
+
import { type LdgrAccountTransactionPage, type LdgrClientOptions, type LdgrAsset, type Ldgr402Verification, type LdgrTransaction, type PaymentExpectation, type PaymentVerification, type CheckoutPaymentExpectation, type CheckoutPaymentVerification, type MerchantPaymentExpectation, type MerchantPaymentVerification, type PaymentSubmission, type SignedSubmission, type SilentPaymentSendInput, type SilentPaymentScanPage, type WalletPublicKeyRecord, type WalletPublicKeyRegistration } from "./types";
|
|
4
12
|
export declare function createLdgrClient(options: LdgrClientOptions): {
|
|
5
13
|
ledger: {
|
|
6
14
|
get: () => Promise<{
|
|
@@ -8,6 +16,23 @@ export declare function createLdgrClient(options: LdgrClientOptions): {
|
|
|
8
16
|
}>;
|
|
9
17
|
getProtocolConfig: () => Promise<Record<string, unknown>>;
|
|
10
18
|
};
|
|
19
|
+
getClaimDistribution: (contractId: string) => Promise<LdgrClaimDistribution>;
|
|
20
|
+
openClaimDistribution: (signed: ClaimDistributionOpenSubmission) => Promise<LdgrClaimDistributionMutation>;
|
|
21
|
+
claimClaimDistribution: (signed: ClaimDistributionClaimSubmission) => Promise<LdgrClaimDistributionMutation>;
|
|
22
|
+
refundClaimDistribution: (signed: ClaimDistributionRefundSubmission) => Promise<LdgrClaimDistributionMutation>;
|
|
23
|
+
getLedraContract: (id: string) => Promise<import("@ldgr/protocol").LedraContractRecord>;
|
|
24
|
+
deployLedraContract: (signed: LedraContractDeploySubmission) => Promise<import("@ldgr/protocol").LedraContractMutation>;
|
|
25
|
+
invokeLedraContract: (signed: LedraContractInvokeSubmission) => Promise<import("@ldgr/protocol").LedraContractMutation>;
|
|
26
|
+
refundLedraContract: (signed: LedraContractRefundSubmission) => Promise<import("@ldgr/protocol").LedraContractMutation>;
|
|
27
|
+
getMilestoneEscrow: (contractId: string) => Promise<LdgrMilestoneEscrow>;
|
|
28
|
+
openMilestoneEscrow: (signed: MilestoneEscrowOpenSubmission) => Promise<LdgrMilestoneEscrowMutation>;
|
|
29
|
+
releaseMilestoneEscrow: (signed: MilestoneEscrowReleaseSubmission) => Promise<LdgrMilestoneEscrowMutation>;
|
|
30
|
+
refundMilestoneEscrow: (signed: MilestoneEscrowRefundSubmission) => Promise<LdgrMilestoneEscrowMutation>;
|
|
31
|
+
getAtomicOffer: (contractId: string) => Promise<LdgrAtomicOffer>;
|
|
32
|
+
openAtomicOffer: (signed: AtomicOfferOpenSubmission) => Promise<LdgrAtomicOfferMutation>;
|
|
33
|
+
acceptAtomicOffer: (signed: AtomicOfferAcceptSubmission) => Promise<LdgrAtomicOfferMutation>;
|
|
34
|
+
cancelAtomicOffer: (signed: AtomicOfferCancelSubmission) => Promise<LdgrAtomicOfferMutation>;
|
|
35
|
+
refundAtomicOffer: (signed: AtomicOfferRefundSubmission) => Promise<LdgrAtomicOfferMutation>;
|
|
11
36
|
accounts: {
|
|
12
37
|
listBalances: (address: string) => Promise<{
|
|
13
38
|
readonly address: string;
|
|
@@ -68,6 +93,7 @@ export declare function createLdgrClient(options: LdgrClientOptions): {
|
|
|
68
93
|
usernames: {
|
|
69
94
|
get: (name: string) => Promise<Record<string, unknown>>;
|
|
70
95
|
getPrimary: (address: string) => Promise<Record<string, unknown>>;
|
|
96
|
+
findPrimary: (address: string) => Promise<Record<string, unknown> | null>;
|
|
71
97
|
listOwned: (address: string, options?: {
|
|
72
98
|
readonly cursor?: string;
|
|
73
99
|
readonly limit?: number;
|
|
@@ -75,6 +101,8 @@ export declare function createLdgrClient(options: LdgrClientOptions): {
|
|
|
75
101
|
};
|
|
76
102
|
payments: {
|
|
77
103
|
verifyTransfer: (transactionHash: string, expected: PaymentExpectation) => Promise<PaymentVerification>;
|
|
104
|
+
verifyCheckout: (sessionId: string, expected: CheckoutPaymentExpectation) => Promise<CheckoutPaymentVerification>;
|
|
105
|
+
verifyPayment: (submission: PaymentSubmission, expected: MerchantPaymentExpectation) => Promise<MerchantPaymentVerification>;
|
|
78
106
|
verifyLdgr402: (proofHeader: string, requirementInput: Ldgr402Requirement, options?: {
|
|
79
107
|
readonly nowMs?: number;
|
|
80
108
|
}) => Promise<Ldgr402Verification>;
|
|
@@ -93,7 +121,7 @@ export declare function createLdgrClient(options: LdgrClientOptions): {
|
|
|
93
121
|
};
|
|
94
122
|
export { LdgrClientError, SilentPaymentSubmissionUnknownError } from "./types";
|
|
95
123
|
export { decodeMerchantLdgr402Payment, parseMerchantLdgr402Requirement } from "./ldgr402";
|
|
96
|
-
export type { LdgrAccountTransaction, LdgrAccountTransactionPage, Ldgr402Requirement, Ldgr402Verification, LdgrAsset, LdgrClientOptions, LdgrNetwork, LdgrTransaction, PaymentExpectation, PaymentVerification, SignedSubmission, SilentPaymentScanPage, SilentPaymentScanRecord, SilentPaymentSendInput, WalletPublicKeyRecord, WalletPublicKeyRegistration } from "./types";
|
|
124
|
+
export type { CheckoutPaymentExpectation, CheckoutPaymentVerification, MerchantPaymentExpectation, MerchantPaymentVerification, PaymentSubmission, LdgrAccountTransaction, LdgrAccountTransactionPage, Ldgr402Requirement, Ldgr402Verification, LdgrAsset, LdgrClientOptions, LdgrNetwork, LdgrTransaction, PaymentExpectation, PaymentVerification, SignedSubmission, SilentPaymentScanPage, SilentPaymentScanRecord, SilentPaymentSendInput, WalletPublicKeyRecord, WalletPublicKeyRegistration } from "./types";
|
|
97
125
|
export { createWebCryptoSigner, deriveLocalSilentPaymentIdentity, generateLocalWallet, loadLocalWallet } from "./signer";
|
|
98
126
|
export type { LdgrSigner, LocalLdgrWallet, LocalSilentPaymentIdentity } from "./signer";
|
|
99
127
|
export { buildTransferSubmission } from "./transfer";
|
package/dist/index.js
CHANGED
|
@@ -41,7 +41,7 @@ function assertApiPath(path) {
|
|
|
41
41
|
throw new TypeError("path must be an /api/v1/ relative path");
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
|
-
async function parseJson(response) {
|
|
44
|
+
async function parseJson(response, allowNull = false) {
|
|
45
45
|
const body = await response.json().catch(() => {
|
|
46
46
|
return;
|
|
47
47
|
});
|
|
@@ -50,6 +50,8 @@ async function parseJson(response) {
|
|
|
50
50
|
const code = typeof body?.code === "string" ? body.code : undefined;
|
|
51
51
|
throw new LdgrClientError(response.status, message, code);
|
|
52
52
|
}
|
|
53
|
+
if (body === null && allowNull)
|
|
54
|
+
return body;
|
|
53
55
|
if (body === undefined || body === null || typeof body !== "object") {
|
|
54
56
|
throw new TypeError("LDGR response must be a JSON object");
|
|
55
57
|
}
|
|
@@ -60,12 +62,13 @@ function createTransport(options) {
|
|
|
60
62
|
const request = options.fetch ?? globalThis.fetch;
|
|
61
63
|
if (typeof request !== "function")
|
|
62
64
|
throw new TypeError("fetch is required");
|
|
63
|
-
const call = async (path, init) => {
|
|
65
|
+
const call = async (path, init, allowNull = false) => {
|
|
64
66
|
assertApiPath(path);
|
|
65
|
-
return parseJson(await request(`${apiBase}${path}`, init));
|
|
67
|
+
return parseJson(await request(`${apiBase}${path}`, init), allowNull);
|
|
66
68
|
};
|
|
67
69
|
return {
|
|
68
70
|
get: (path) => call(path),
|
|
71
|
+
getOptional: (path) => call(path, undefined, true),
|
|
69
72
|
post: (path, body) => call(path, {
|
|
70
73
|
method: "POST",
|
|
71
74
|
headers: { "content-type": "application/json" },
|
|
@@ -225,7 +228,7 @@ function decodeMerchantLdgr402Payment(headerValue) {
|
|
|
225
228
|
// src/index.ts
|
|
226
229
|
function normalizedHash(transactionHash) {
|
|
227
230
|
const hash = transactionHash.toLowerCase();
|
|
228
|
-
if (!/^[0-9a-f]{64}$/.test(hash))
|
|
231
|
+
if (hash.length !== 64 || !/^[0-9a-f]{64}$/.test(hash))
|
|
229
232
|
throw new TypeError("transactionHash must be a 64-character hexadecimal hash");
|
|
230
233
|
return hash;
|
|
231
234
|
}
|
|
@@ -247,6 +250,18 @@ function paymentReference(metadata) {
|
|
|
247
250
|
function transactionFields(transaction) {
|
|
248
251
|
return typeof transaction.from === "string" && typeof transaction.to === "string" && typeof transaction.asset === "string" && typeof transaction.amount === "string" ? { from: transaction.from, to: transaction.to, asset: transaction.asset, amount: transaction.amount } : null;
|
|
249
252
|
}
|
|
253
|
+
function assertMerchantTerms(expected) {
|
|
254
|
+
if (typeof expected.to !== "string" || !expected.to)
|
|
255
|
+
throw new TypeError("to is required");
|
|
256
|
+
if (typeof expected.asset !== "string" || !expected.asset.trim())
|
|
257
|
+
throw new TypeError("asset is required");
|
|
258
|
+
if (typeof expected.reference !== "string" || !expected.reference || new TextEncoder().encode(expected.reference).byteLength > 128) {
|
|
259
|
+
throw new TypeError("reference must be 1 to 128 UTF-8 bytes");
|
|
260
|
+
}
|
|
261
|
+
if (typeof expected.amount !== "string" || !sameDecimalAmount(expected.amount, expected.amount) || !/[1-9]/.test(expected.amount)) {
|
|
262
|
+
throw new TypeError("amount must be a positive exact decimal string");
|
|
263
|
+
}
|
|
264
|
+
}
|
|
250
265
|
function isNonceMismatch(error) {
|
|
251
266
|
return error instanceof LdgrClientError && error.code === "NONCE_MISMATCH";
|
|
252
267
|
}
|
|
@@ -282,18 +297,65 @@ function createLdgrClient(options) {
|
|
|
282
297
|
throw error;
|
|
283
298
|
}
|
|
284
299
|
const fields = transactionFields(transaction);
|
|
285
|
-
if (transaction.action !== "transfer" || fields === null || fields.to !== expected.to || fields.asset !== expectedAsset || !sameDecimalAmount(fields.amount, expected.amount) || expected.reference !== undefined && paymentReference(transaction.metadata) !== expected.reference) {
|
|
300
|
+
if (transaction.transactionHash !== hash || transaction.action !== "transfer" || fields === null || fields.to !== expected.to || fields.asset !== expectedAsset || !sameDecimalAmount(fields.amount, expected.amount) || expected.reference !== undefined && paymentReference(transaction.metadata) !== expected.reference) {
|
|
286
301
|
return { status: "mismatch", transactionHash: hash };
|
|
287
302
|
}
|
|
288
303
|
return { status: "confirmed", transactionHash: hash, ...fields };
|
|
289
304
|
};
|
|
290
|
-
const
|
|
305
|
+
const verifyCheckout = async (sessionId, expected) => {
|
|
306
|
+
if (ledgerId === undefined)
|
|
307
|
+
throw new TypeError("network is required for Checkout verification");
|
|
308
|
+
if (sessionId.length !== 36 || !/^chk_[0-9a-f]{32}$/.test(sessionId))
|
|
309
|
+
throw new TypeError("Invalid Checkout session ID");
|
|
310
|
+
assertMerchantTerms(expected);
|
|
311
|
+
const asset = resolveAsset(expected.asset.trim());
|
|
312
|
+
const expectedHash = expected.transactionHash === undefined ? undefined : normalizedHash(expected.transactionHash);
|
|
313
|
+
let body;
|
|
314
|
+
try {
|
|
315
|
+
body = await transport.get(`/api/v1/checkout/sessions/${sessionId}`);
|
|
316
|
+
} catch (error) {
|
|
317
|
+
if (error instanceof LdgrClientError && error.status === 404)
|
|
318
|
+
return { status: "not_found", sessionId };
|
|
319
|
+
throw error;
|
|
320
|
+
}
|
|
321
|
+
const mismatch = { status: "mismatch", sessionId };
|
|
322
|
+
if (body === null || typeof body !== "object" || Array.isArray(body))
|
|
323
|
+
return mismatch;
|
|
324
|
+
const session = body;
|
|
325
|
+
if (session.id !== sessionId || session.ledgerId !== ledgerId || session.recipient !== expected.to || session.asset !== asset || typeof session.amount !== "string" || !sameDecimalAmount(session.amount, expected.amount) || session.paymentReference !== expected.reference)
|
|
326
|
+
return mismatch;
|
|
327
|
+
if (session.status === "open")
|
|
328
|
+
return { status: "pending", sessionId };
|
|
329
|
+
if (session.status === "expired")
|
|
330
|
+
return { status: "expired", sessionId };
|
|
331
|
+
if (session.status !== "paid" || typeof session.transactionHash !== "string" || session.transactionHash.length !== 64 || !/^[0-9a-f]{64}$/.test(session.transactionHash) || expectedHash !== undefined && session.transactionHash !== expectedHash || typeof session.guestAddress !== "string" || !session.guestAddress || typeof session.merchantAmount !== "string" || !sameDecimalAmount(session.merchantAmount, session.merchantAmount) || typeof session.checkoutFee !== "string" || !sameDecimalAmount(session.checkoutFee, session.checkoutFee))
|
|
332
|
+
return mismatch;
|
|
333
|
+
return {
|
|
334
|
+
status: "confirmed",
|
|
335
|
+
sessionId,
|
|
336
|
+
transactionHash: session.transactionHash,
|
|
337
|
+
from: session.guestAddress,
|
|
338
|
+
to: expected.to,
|
|
339
|
+
asset,
|
|
340
|
+
amount: session.amount,
|
|
341
|
+
merchantAmount: session.merchantAmount,
|
|
342
|
+
checkoutFee: session.checkoutFee
|
|
343
|
+
};
|
|
344
|
+
};
|
|
345
|
+
const verifyPayment = async (submission, expected) => {
|
|
346
|
+
if (ledgerId === undefined)
|
|
347
|
+
throw new TypeError("network is required for merchant payment verification");
|
|
348
|
+
assertMerchantTerms(expected);
|
|
349
|
+
const hash = normalizedHash(submission.transactionHash);
|
|
350
|
+
return submission.checkoutSessionId === undefined ? verifyTransfer(hash, expected) : verifyCheckout(submission.checkoutSessionId, { ...expected, transactionHash: hash });
|
|
351
|
+
};
|
|
352
|
+
const verifyLdgr402 = async (proofHeader, requirementInput, options = {}) => {
|
|
291
353
|
const proof = decodeLdgr402Payment3(proofHeader);
|
|
292
354
|
const requirement = parseLdgr402Requirement3(requirementInput, {
|
|
293
|
-
nowMs:
|
|
355
|
+
nowMs: options.nowMs,
|
|
294
356
|
allowExpired: true
|
|
295
357
|
});
|
|
296
|
-
const nowMs =
|
|
358
|
+
const nowMs = options.nowMs ?? Date.now();
|
|
297
359
|
if (ledgerId === undefined)
|
|
298
360
|
throw new TypeError("network is required for LDGR402 verification");
|
|
299
361
|
if (proof.ledgerId !== requirement.ledgerId || ledgerId !== requirement.ledgerId || proof.challenge !== requirement.challenge) {
|
|
@@ -348,9 +410,9 @@ function createLdgrClient(options) {
|
|
|
348
410
|
try {
|
|
349
411
|
return await submit();
|
|
350
412
|
} catch (retryError) {
|
|
351
|
-
const
|
|
352
|
-
if (
|
|
353
|
-
return
|
|
413
|
+
const failure = transferFailure(retryError);
|
|
414
|
+
if (failure !== undefined)
|
|
415
|
+
return failure;
|
|
354
416
|
throw retryError;
|
|
355
417
|
}
|
|
356
418
|
}
|
|
@@ -440,9 +502,9 @@ function createLdgrClient(options) {
|
|
|
440
502
|
try {
|
|
441
503
|
return await submit();
|
|
442
504
|
} catch (retryError) {
|
|
443
|
-
const
|
|
444
|
-
if (
|
|
445
|
-
return
|
|
505
|
+
const failure = transferFailure(retryError);
|
|
506
|
+
if (failure !== undefined)
|
|
507
|
+
return failure;
|
|
446
508
|
throw retryError;
|
|
447
509
|
}
|
|
448
510
|
}
|
|
@@ -457,16 +519,33 @@ function createLdgrClient(options) {
|
|
|
457
519
|
get: () => transport.get("/api/v1/ledger"),
|
|
458
520
|
getProtocolConfig: () => transport.get("/api/v1/protocol/config")
|
|
459
521
|
},
|
|
522
|
+
getClaimDistribution: (contractId) => transport.get(`/api/v1/contracts/claim-distributions/${encodePathSegment(contractId)}`),
|
|
523
|
+
openClaimDistribution: (signed) => transport.post("/api/v1/contracts/claim-distributions", signed),
|
|
524
|
+
claimClaimDistribution: (signed) => transport.post(`/api/v1/contracts/claim-distributions/${encodePathSegment(signed.payload.contractId)}/claim`, signed),
|
|
525
|
+
refundClaimDistribution: (signed) => transport.post(`/api/v1/contracts/claim-distributions/${encodePathSegment(signed.payload.contractId)}/refund`, signed),
|
|
526
|
+
getLedraContract: (id) => transport.get(`/api/v1/contracts/programs/${encodePathSegment(id)}`),
|
|
527
|
+
deployLedraContract: (signed) => transport.post("/api/v1/contracts/programs", signed),
|
|
528
|
+
invokeLedraContract: (signed) => transport.post(`/api/v1/contracts/programs/${encodePathSegment(signed.payload.contractId)}/invoke`, signed),
|
|
529
|
+
refundLedraContract: (signed) => transport.post(`/api/v1/contracts/programs/${encodePathSegment(signed.payload.contractId)}/refund`, signed),
|
|
530
|
+
getMilestoneEscrow: (contractId) => transport.get(`/api/v1/contracts/milestone-escrows/${encodePathSegment(contractId)}`),
|
|
531
|
+
openMilestoneEscrow: (signed) => transport.post("/api/v1/contracts/milestone-escrows", signed),
|
|
532
|
+
releaseMilestoneEscrow: (signed) => transport.post(`/api/v1/contracts/milestone-escrows/${encodePathSegment(signed.payload.contractId)}/release`, signed),
|
|
533
|
+
refundMilestoneEscrow: (signed) => transport.post(`/api/v1/contracts/milestone-escrows/${encodePathSegment(signed.payload.contractId)}/refund`, signed),
|
|
534
|
+
getAtomicOffer: (contractId) => transport.get(`/api/v1/contracts/atomic-offers/${encodePathSegment(contractId)}`),
|
|
535
|
+
openAtomicOffer: (signed) => transport.post("/api/v1/contracts/atomic-offers", signed),
|
|
536
|
+
acceptAtomicOffer: (signed) => transport.post(`/api/v1/contracts/atomic-offers/${encodePathSegment(signed.payload.contractId)}/accept`, signed),
|
|
537
|
+
cancelAtomicOffer: (signed) => transport.post(`/api/v1/contracts/atomic-offers/${encodePathSegment(signed.payload.contractId)}/cancel`, signed),
|
|
538
|
+
refundAtomicOffer: (signed) => transport.post(`/api/v1/contracts/atomic-offers/${encodePathSegment(signed.payload.contractId)}/refund`, signed),
|
|
460
539
|
accounts: {
|
|
461
540
|
listBalances: (address) => transport.get(`/api/v1/balances/${encodePathSegment(address)}`),
|
|
462
541
|
getBalance: (address, asset) => transport.get(`/api/v1/balances/${encodePathSegment(address)}/${encodePathSegment(resolveAsset(asset))}`),
|
|
463
542
|
getNextNonce: (address, asset) => transport.get(`/api/v1/nonces/${encodePathSegment(address)}/${encodePathSegment(resolveAsset(asset))}`),
|
|
464
543
|
getWalletPublicKey: (address) => transport.get(`/api/v1/wallets/${encodePathSegment(address)}/public-key`),
|
|
465
544
|
registerWalletPublicKey: (address, registration) => transport.post(`/api/v1/wallets/${encodePathSegment(address)}/public-key`, registration),
|
|
466
|
-
async listTransactions(address,
|
|
545
|
+
async listTransactions(address, options = {}) {
|
|
467
546
|
const path = queryPath(`/api/v1/explorer/addresses/${encodePathSegment(address)}/transactions`, {
|
|
468
|
-
before:
|
|
469
|
-
asset:
|
|
547
|
+
before: options.before,
|
|
548
|
+
asset: options.asset === undefined ? undefined : resolveAsset(options.asset)
|
|
470
549
|
});
|
|
471
550
|
try {
|
|
472
551
|
return await transport.get(path);
|
|
@@ -518,9 +597,10 @@ function createLdgrClient(options) {
|
|
|
518
597
|
usernames: {
|
|
519
598
|
get: (name) => transport.get(`/api/v1/usernames/${encodePathSegment(name)}`),
|
|
520
599
|
getPrimary: (address) => transport.get(`/api/v1/usernames/by-address/${encodePathSegment(address)}`),
|
|
521
|
-
|
|
600
|
+
findPrimary: (address) => transport.getOptional(`/api/v1/usernames/by-address/${encodePathSegment(address)}?optional=true`),
|
|
601
|
+
listOwned: (address, options) => transport.get(queryPath(`/api/v1/usernames/owned-by/${encodePathSegment(address)}`, options ?? {}))
|
|
522
602
|
},
|
|
523
|
-
payments: { verifyTransfer, verifyLdgr402 },
|
|
603
|
+
payments: { verifyTransfer, verifyCheckout, verifyPayment, verifyLdgr402 },
|
|
524
604
|
silentPayments: {
|
|
525
605
|
scan: (after = "0", limit) => transport.get(queryPath("/api/v1/silent-payments/scan", { after, limit })),
|
|
526
606
|
send: sendSilentPayment,
|
package/dist/types.d.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { LedraContractDeployPayload, LedraContractInvokePayload, LedraContractRefundPayload, LedraContractRecord, LedraContractMutation } from '@ldgr/protocol';
|
|
2
|
+
import type { ClaimDistributionOpenPayload, ClaimDistributionClaimPayload, ClaimDistributionRefundPayload } from "@ldgr/protocol";
|
|
3
|
+
import type { MilestoneEscrowOpenPayload, MilestoneEscrowReleasePayload, MilestoneEscrowRefundPayload } from "@ldgr/protocol";
|
|
4
|
+
import type { AssetBridgePolicy, LdgrNetwork, AtomicOfferOpenPayload, AtomicOfferAcceptPayload, AtomicOfferCancelPayload, AtomicOfferRefundPayload } from "@ldgr/protocol";
|
|
2
5
|
import type { LocalLdgrWallet } from "./signer";
|
|
3
6
|
export type LedgerId = 0 | 1;
|
|
4
7
|
export type { LdgrNetwork } from "@ldgr/protocol";
|
|
@@ -64,6 +67,34 @@ export type PaymentVerification = {
|
|
|
64
67
|
readonly status: "not_found" | "mismatch";
|
|
65
68
|
readonly transactionHash: string;
|
|
66
69
|
};
|
|
70
|
+
/** Immutable merchant order terms; amount is the gross exact decimal amount. */
|
|
71
|
+
export type MerchantPaymentExpectation = PaymentExpectation & {
|
|
72
|
+
readonly asset: string;
|
|
73
|
+
readonly reference: string;
|
|
74
|
+
};
|
|
75
|
+
export type CheckoutPaymentExpectation = MerchantPaymentExpectation & {
|
|
76
|
+
readonly transactionHash?: string;
|
|
77
|
+
};
|
|
78
|
+
/** Identifiers forwarded from a widget event, never trusted order terms. */
|
|
79
|
+
export type PaymentSubmission = {
|
|
80
|
+
readonly transactionHash: string;
|
|
81
|
+
readonly checkoutSessionId?: string;
|
|
82
|
+
};
|
|
83
|
+
export type CheckoutPaymentVerification = {
|
|
84
|
+
readonly status: "confirmed";
|
|
85
|
+
readonly sessionId: string;
|
|
86
|
+
readonly transactionHash: string;
|
|
87
|
+
readonly from: string;
|
|
88
|
+
readonly to: string;
|
|
89
|
+
readonly asset: string;
|
|
90
|
+
readonly amount: string;
|
|
91
|
+
readonly merchantAmount: string;
|
|
92
|
+
readonly checkoutFee: string;
|
|
93
|
+
} | {
|
|
94
|
+
readonly status: "pending" | "expired" | "not_found" | "mismatch";
|
|
95
|
+
readonly sessionId: string;
|
|
96
|
+
};
|
|
97
|
+
export type MerchantPaymentVerification = PaymentVerification | CheckoutPaymentVerification;
|
|
67
98
|
export type Ldgr402Verification = PaymentVerification | {
|
|
68
99
|
readonly status: "expired";
|
|
69
100
|
readonly transactionHash: string;
|
|
@@ -76,6 +107,38 @@ export type SignedSubmission = {
|
|
|
76
107
|
readonly feeSponsor?: unknown;
|
|
77
108
|
readonly submittedAtMs?: number;
|
|
78
109
|
};
|
|
110
|
+
/** HTTP amounts are exact decimals; nonce/time/cap fields are integer strings. */
|
|
111
|
+
type AtomicOfferWire<T> = {
|
|
112
|
+
readonly [K in keyof T]: T[K] extends bigint ? string : T[K];
|
|
113
|
+
};
|
|
114
|
+
type AtomicOfferSubmission<T> = Omit<SignedSubmission, "payload" | "feeSponsor"> & {
|
|
115
|
+
readonly payload: AtomicOfferWire<T>;
|
|
116
|
+
};
|
|
117
|
+
export type AtomicOfferOpenSubmission = AtomicOfferSubmission<AtomicOfferOpenPayload>;
|
|
118
|
+
export type AtomicOfferAcceptSubmission = AtomicOfferSubmission<AtomicOfferAcceptPayload>;
|
|
119
|
+
export type AtomicOfferCancelSubmission = AtomicOfferSubmission<AtomicOfferCancelPayload>;
|
|
120
|
+
export type AtomicOfferRefundSubmission = AtomicOfferSubmission<AtomicOfferRefundPayload>;
|
|
121
|
+
export type LdgrAtomicOffer = {
|
|
122
|
+
readonly contractId: string;
|
|
123
|
+
readonly template: "atomic_offer_v1";
|
|
124
|
+
readonly maker: string;
|
|
125
|
+
readonly taker: string;
|
|
126
|
+
readonly offeredAsset: string;
|
|
127
|
+
readonly offeredAmount: string;
|
|
128
|
+
readonly requestedAsset: string;
|
|
129
|
+
readonly requestedAmount: string;
|
|
130
|
+
readonly expiresAt: string;
|
|
131
|
+
readonly status: "open" | "accepted" | "cancelled" | "refunded";
|
|
132
|
+
readonly expired: boolean;
|
|
133
|
+
readonly openPayloadHash: string;
|
|
134
|
+
readonly reference?: string;
|
|
135
|
+
readonly createdTransactionHash: string;
|
|
136
|
+
readonly latestTransactionHash: string;
|
|
137
|
+
readonly terminalTransactionHash?: string;
|
|
138
|
+
};
|
|
139
|
+
export type LdgrAtomicOfferMutation = LdgrAtomicOffer & {
|
|
140
|
+
readonly transactionHash: string;
|
|
141
|
+
};
|
|
79
142
|
export type WalletPublicKeyRegistration = {
|
|
80
143
|
readonly version: 1;
|
|
81
144
|
readonly action: "wallet_key_register";
|
|
@@ -133,7 +196,8 @@ export type LdgrClientOptions = {
|
|
|
133
196
|
readonly network?: LdgrNetwork;
|
|
134
197
|
/** Defaults to the canonical public origin when `network` is supplied. */
|
|
135
198
|
readonly apiBase?: string;
|
|
136
|
-
|
|
199
|
+
/** A Fetch-compatible function; runtime-specific helper properties are not required. */
|
|
200
|
+
readonly fetch?: (...args: Parameters<typeof globalThis.fetch>) => ReturnType<typeof globalThis.fetch>;
|
|
137
201
|
};
|
|
138
202
|
export type LdgrClientErrorBody = {
|
|
139
203
|
readonly error?: unknown;
|
|
@@ -144,3 +208,76 @@ export declare class LdgrClientError extends Error {
|
|
|
144
208
|
readonly code: string | undefined;
|
|
145
209
|
constructor(status: number, message: string, code: string | undefined);
|
|
146
210
|
}
|
|
211
|
+
/** Atomic payload amounts become exact asset decimals over HTTP, including nested steps. */
|
|
212
|
+
type ContractSignedWire<T> = T extends bigint ? string : T extends readonly (infer U)[] ? readonly ContractSignedWire<U>[] : T extends object ? {
|
|
213
|
+
readonly [K in keyof T]: ContractSignedWire<T[K]>;
|
|
214
|
+
} : T;
|
|
215
|
+
type ContractSignedSubmission<T> = Omit<SignedSubmission, "payload" | "feeSponsor"> & {
|
|
216
|
+
readonly payload: ContractSignedWire<T>;
|
|
217
|
+
};
|
|
218
|
+
export type MilestoneEscrowOpenSubmission = ContractSignedSubmission<MilestoneEscrowOpenPayload>;
|
|
219
|
+
export type MilestoneEscrowReleaseSubmission = ContractSignedSubmission<MilestoneEscrowReleasePayload>;
|
|
220
|
+
export type MilestoneEscrowRefundSubmission = ContractSignedSubmission<MilestoneEscrowRefundPayload>;
|
|
221
|
+
export type LdgrMilestoneEscrow = {
|
|
222
|
+
readonly contractId: string;
|
|
223
|
+
readonly template: "milestone_escrow_v1";
|
|
224
|
+
readonly payer: string;
|
|
225
|
+
readonly beneficiary: string;
|
|
226
|
+
readonly asset: string;
|
|
227
|
+
readonly amount: string;
|
|
228
|
+
readonly milestones: readonly {
|
|
229
|
+
readonly label: string;
|
|
230
|
+
readonly amount: string;
|
|
231
|
+
}[];
|
|
232
|
+
readonly releasedMilestones: number;
|
|
233
|
+
readonly releasedAmount: string;
|
|
234
|
+
readonly remainingAmount: string;
|
|
235
|
+
readonly refundedAmount: string;
|
|
236
|
+
readonly expiresAt: string;
|
|
237
|
+
readonly expired: boolean;
|
|
238
|
+
readonly status: "open" | "completed" | "refunded";
|
|
239
|
+
readonly openPayloadHash: string;
|
|
240
|
+
readonly reference?: string;
|
|
241
|
+
readonly createdTransactionHash: string;
|
|
242
|
+
readonly latestTransactionHash: string;
|
|
243
|
+
readonly terminalTransactionHash?: string;
|
|
244
|
+
};
|
|
245
|
+
export type LdgrMilestoneEscrowMutation = LdgrMilestoneEscrow & {
|
|
246
|
+
readonly transactionHash: string;
|
|
247
|
+
};
|
|
248
|
+
/** Atomic payload amounts become exact asset decimals over HTTP, including nested steps. */
|
|
249
|
+
export type ClaimDistributionOpenSubmission = ContractSignedSubmission<ClaimDistributionOpenPayload>;
|
|
250
|
+
export type ClaimDistributionClaimSubmission = ContractSignedSubmission<ClaimDistributionClaimPayload>;
|
|
251
|
+
export type ClaimDistributionRefundSubmission = ContractSignedSubmission<ClaimDistributionRefundPayload>;
|
|
252
|
+
export type LdgrClaimDistribution = {
|
|
253
|
+
readonly contractId: string;
|
|
254
|
+
readonly template: "claim_distribution_v1";
|
|
255
|
+
readonly funder: string;
|
|
256
|
+
readonly asset: string;
|
|
257
|
+
readonly amount: string;
|
|
258
|
+
readonly allocations: readonly {
|
|
259
|
+
readonly to: string;
|
|
260
|
+
readonly amount: string;
|
|
261
|
+
readonly claimed: boolean;
|
|
262
|
+
}[];
|
|
263
|
+
readonly claimedAllocations: number;
|
|
264
|
+
readonly claimedAmount: string;
|
|
265
|
+
readonly remainingAmount: string;
|
|
266
|
+
readonly refundedAmount: string;
|
|
267
|
+
readonly expiresAt: string;
|
|
268
|
+
readonly expired: boolean;
|
|
269
|
+
readonly status: "open" | "completed" | "refunded";
|
|
270
|
+
readonly openPayloadHash: string;
|
|
271
|
+
readonly reference?: string;
|
|
272
|
+
readonly createdTransactionHash: string;
|
|
273
|
+
readonly latestTransactionHash: string;
|
|
274
|
+
readonly terminalTransactionHash?: string;
|
|
275
|
+
};
|
|
276
|
+
export type LdgrClaimDistributionMutation = LdgrClaimDistribution & {
|
|
277
|
+
readonly transactionHash: string;
|
|
278
|
+
};
|
|
279
|
+
export type LedraContractDeploySubmission = ContractSignedSubmission<LedraContractDeployPayload>;
|
|
280
|
+
export type LedraContractInvokeSubmission = ContractSignedSubmission<LedraContractInvokePayload>;
|
|
281
|
+
export type LedraContractRefundSubmission = ContractSignedSubmission<LedraContractRefundPayload>;
|
|
282
|
+
export type LdgrLedraContract = LedraContractRecord;
|
|
283
|
+
export type LdgrLedraContractMutation = LedraContractMutation;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ldgr/client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"types": "./dist/index.d.ts",
|
|
6
6
|
"exports": {
|
|
@@ -12,14 +12,14 @@
|
|
|
12
12
|
"files": ["dist", "README.md"],
|
|
13
13
|
"publishConfig": { "access": "public" },
|
|
14
14
|
"engines": { "node": ">=20.19.0" },
|
|
15
|
-
"dependencies": { "@ldgr/protocol": "^0.5.
|
|
15
|
+
"dependencies": { "@ldgr/protocol": "^0.5.1" },
|
|
16
16
|
"scripts": {
|
|
17
|
-
"build": "rm -rf dist && bun build src/index.ts --outdir dist --target node --format esm --packages external &&
|
|
17
|
+
"build": "rm -rf dist && bun build src/index.ts --outdir dist --target node --format esm --packages external && tsrs -p tsconfig.build.json",
|
|
18
18
|
"prepack": "bun run build",
|
|
19
19
|
"test": "bun test",
|
|
20
|
-
"typecheck": "
|
|
20
|
+
"typecheck": "tsrs --noEmit -p tsconfig.json && tsrs --noEmit -p test/tsconfig.json"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
|
-
"
|
|
23
|
+
"tsrs": "0.20.0-ts7.1.0-beta"
|
|
24
24
|
}
|
|
25
25
|
}
|