@myzonerocks/pact 0.1.3 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/adapter.d.ts +1 -1
- package/dist/src/adapters/erc20.d.ts +13 -3
- package/dist/src/adapters/erc20.js +93 -49
- package/dist/src/adapters/http.d.ts +2 -0
- package/dist/src/adapters/http.js +12 -0
- package/dist/src/adapters/mpesa.d.ts +9 -2
- package/dist/src/adapters/mpesa.js +82 -12
- package/dist/src/adapters/paypal.d.ts +5 -1
- package/dist/src/adapters/paypal.js +76 -25
- package/dist/src/adapters/stripe.d.ts +3 -2
- package/dist/src/adapters/stripe.js +14 -11
- package/dist/src/bridge.js +12 -5
- package/dist/src/canonical.js +5 -0
- package/dist/src/client.d.ts +8 -2
- package/dist/src/client.js +181 -20
- package/dist/src/compliance.d.ts +4 -0
- package/dist/src/compliance.js +10 -3
- package/dist/src/crypto.js +4 -1
- package/dist/src/index.d.ts +0 -1
- package/dist/src/index.js +0 -1
- package/dist/src/ledger.d.ts +6 -2
- package/dist/src/ledger.js +2 -2
- package/dist/src/leg.d.ts +1 -1
- package/dist/src/message.d.ts +1 -1
- package/dist/src/message.js +8 -5
- package/dist/src/money.d.ts +1 -0
- package/dist/src/money.js +18 -3
- package/dist/src/protocol.d.ts +1 -0
- package/dist/src/protocol.js +8 -0
- package/dist/src/router.d.ts +2 -0
- package/dist/src/router.js +45 -7
- package/dist/src/wire.js +19 -2
- package/dist/test/erc20.test.js +95 -31
- package/dist/test/fake.d.ts +29 -0
- package/dist/test/fake.js +79 -0
- package/dist/test/lifecycle.test.js +31 -3
- package/dist/test/money.test.d.ts +1 -0
- package/dist/test/money.test.js +27 -0
- package/dist/test/mpesa.test.js +41 -8
- package/dist/test/paypal.test.js +33 -8
- package/dist/test/policy.test.js +6 -2
- package/dist/test/router.test.d.ts +1 -0
- package/dist/test/router.test.js +52 -0
- package/dist/test/stripe.test.js +5 -4
- package/dist/test/vectors.test.js +48 -2
- package/dist/test/wire.test.js +15 -0
- package/package.json +1 -1
- package/src/adapter.ts +7 -2
- package/src/adapters/erc20.ts +118 -51
- package/src/adapters/http.ts +14 -0
- package/src/adapters/mpesa.ts +102 -13
- package/src/adapters/paypal.ts +102 -24
- package/src/adapters/stripe.ts +16 -13
- package/src/bridge.ts +12 -5
- package/src/canonical.ts +5 -0
- package/src/client.ts +194 -22
- package/src/compliance.ts +20 -3
- package/src/crypto.ts +4 -1
- package/src/index.ts +0 -1
- package/src/ledger.ts +12 -4
- package/src/leg.ts +4 -1
- package/src/message.ts +8 -5
- package/src/money.ts +19 -3
- package/src/protocol.ts +9 -0
- package/src/router.ts +44 -4
- package/src/wire.ts +20 -3
- package/src/fake.ts +0 -96
package/src/wire.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Money } from "./money.js";
|
|
2
|
-
import { State } from "./state.js";
|
|
2
|
+
import { State, stateName } from "./state.js";
|
|
3
3
|
import { CanonicalWriter } from "./canonical.js";
|
|
4
4
|
import type { Intent, Quote, Authorization, Settlement } from "./message.js";
|
|
5
5
|
|
|
@@ -146,7 +146,14 @@ class WireReader {
|
|
|
146
146
|
}
|
|
147
147
|
const view = new DataView(this.buf.buffer, this.buf.byteOffset + this.pos, 8);
|
|
148
148
|
this.pos += 8;
|
|
149
|
-
|
|
149
|
+
const value = view.getBigUint64(0, false);
|
|
150
|
+
// A value above 2^53 cannot be held exactly in a JS number, so reject it
|
|
151
|
+
// rather than decode a Go or Dart value into a silently different one. Every
|
|
152
|
+
// real field here — millisecond timestamps, ordinals, latency — fits easily.
|
|
153
|
+
if (value > BigInt(Number.MAX_SAFE_INTEGER)) {
|
|
154
|
+
throw new Error("pact: u64 field exceeds the exact-integer range");
|
|
155
|
+
}
|
|
156
|
+
return Number(value);
|
|
150
157
|
}
|
|
151
158
|
|
|
152
159
|
money(): Money {
|
|
@@ -231,11 +238,21 @@ export function decodeAuthorization(b: Uint8Array): Authorization {
|
|
|
231
238
|
return auth;
|
|
232
239
|
}
|
|
233
240
|
|
|
241
|
+
// stateFromOrdinal rejects an ordinal outside the known states rather than pass
|
|
242
|
+
// an out-of-range number through as a State, so a corrupt wire byte cannot decode
|
|
243
|
+
// to a nonexistent state.
|
|
244
|
+
function stateFromOrdinal(n: number): State {
|
|
245
|
+
if (!(n in stateName)) {
|
|
246
|
+
throw new Error(`pact: unknown settlement state ordinal ${n}`);
|
|
247
|
+
}
|
|
248
|
+
return n as State;
|
|
249
|
+
}
|
|
250
|
+
|
|
234
251
|
export function decodeSettlement(b: Uint8Array): Settlement {
|
|
235
252
|
const r = new WireReader(b);
|
|
236
253
|
const settlement: Settlement = {
|
|
237
254
|
intentId: r.str(),
|
|
238
|
-
state: r.u64()
|
|
255
|
+
state: stateFromOrdinal(r.u64()),
|
|
239
256
|
adapterId: r.str(),
|
|
240
257
|
providerTxRef: r.str(),
|
|
241
258
|
onchainTxHash: r.str(),
|
package/src/fake.ts
DELETED
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import { State } from "./state.js";
|
|
2
|
-
import { RefundKind } from "./adapter.js";
|
|
3
|
-
import type { Money } from "./money.js";
|
|
4
|
-
import type { Quote, Authorization, Settlement } from "./message.js";
|
|
5
|
-
import type { RateSource, EscrowVault } from "./bridge.js";
|
|
6
|
-
import type {
|
|
7
|
-
PayInLeg,
|
|
8
|
-
PayOutLeg,
|
|
9
|
-
PayInCapabilities,
|
|
10
|
-
PayOutCapabilities,
|
|
11
|
-
CollectResult,
|
|
12
|
-
DisburseResult,
|
|
13
|
-
} from "./leg.js";
|
|
14
|
-
|
|
15
|
-
// FakeLeg is a deterministic, in-memory pay-in and pay-out leg. It settles
|
|
16
|
-
// instantly with no network and implements both sides so a test can build a
|
|
17
|
-
// direct corridor from one leg or a bridged corridor from two. failPayout makes
|
|
18
|
-
// its disburse fail so a test can exercise the escrow-unwind path.
|
|
19
|
-
export class FakeLeg implements PayInLeg, PayOutLeg {
|
|
20
|
-
failPayout = false;
|
|
21
|
-
|
|
22
|
-
constructor(
|
|
23
|
-
readonly id: string,
|
|
24
|
-
private readonly rail: string,
|
|
25
|
-
private readonly currency: string,
|
|
26
|
-
private readonly ids: () => string,
|
|
27
|
-
) {}
|
|
28
|
-
|
|
29
|
-
payInCapabilities(): PayInCapabilities {
|
|
30
|
-
return { rails: [this.rail], currencies: [this.currency], refunds: RefundKind.Full };
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// collect takes the payer's funds. received is the net the bridge converts —
|
|
34
|
-
// the source the payer paid less the corridor fees.
|
|
35
|
-
async collect(_intentId: string, quote: Quote, _auth: Authorization, _deliverTo: string): Promise<CollectResult> {
|
|
36
|
-
return { providerRef: this.ids(), received: quote.srcAmount.sub(quote.fees) };
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
async refundIn(intentId: string, _kind: RefundKind, reason: string): Promise<Settlement> {
|
|
40
|
-
return this.terminal(intentId, reason);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
payOutCapabilities(): PayOutCapabilities {
|
|
44
|
-
return { rails: [this.rail], currencies: [this.currency], reversible: false };
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
async disburse(_intentId: string, _quote: Quote, _recipientRef: string): Promise<DisburseResult> {
|
|
48
|
-
if (this.failPayout) {
|
|
49
|
-
throw new Error("fake: payout failed");
|
|
50
|
-
}
|
|
51
|
-
return { providerRef: this.ids() };
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
async reverseOut(intentId: string, reason: string): Promise<Settlement> {
|
|
55
|
-
return this.terminal(intentId, reason);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
private terminal(intentId: string, reason: string): Settlement {
|
|
59
|
-
return {
|
|
60
|
-
intentId,
|
|
61
|
-
state: State.Refunded,
|
|
62
|
-
adapterId: this.id,
|
|
63
|
-
providerTxRef: this.ids(),
|
|
64
|
-
onchainTxHash: "",
|
|
65
|
-
receiptHash: new Uint8Array(0),
|
|
66
|
-
reason,
|
|
67
|
-
settledAt: 0,
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// FakeRates is an in-memory rate source keyed by "FROM:TO", standing in for a
|
|
73
|
-
// price feed so a bridge can be tested without a live market.
|
|
74
|
-
export class FakeRates implements RateSource {
|
|
75
|
-
constructor(private readonly table: Record<string, string>) {}
|
|
76
|
-
|
|
77
|
-
async rate(from: string, to: string): Promise<string> {
|
|
78
|
-
const rate = this.table[`${from}:${to}`];
|
|
79
|
-
if (rate === undefined) {
|
|
80
|
-
throw new Error(`fake: no rate for ${from}:${to}`);
|
|
81
|
-
}
|
|
82
|
-
return rate;
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
// FakeVault is an in-memory escrow that records holds and releases, standing in
|
|
87
|
-
// for the custody a real bridge relies on.
|
|
88
|
-
export class FakeVault implements EscrowVault {
|
|
89
|
-
async hold(intentId: string, _amount: Money): Promise<string> {
|
|
90
|
-
return `escrow-${intentId}`;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
async release(_intentId: string): Promise<void> {
|
|
94
|
-
// Nothing to release in memory.
|
|
95
|
-
}
|
|
96
|
-
}
|