mppx 0.4.10 → 0.4.12
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/CHANGELOG.md +23 -1
- package/dist/internal/env.d.ts +1 -1
- package/dist/internal/env.d.ts.map +1 -1
- package/dist/internal/env.js +2 -6
- package/dist/internal/env.js.map +1 -1
- package/dist/internal/types.d.ts +23 -0
- package/dist/internal/types.d.ts.map +1 -1
- package/dist/server/Mppx.d.ts +1 -1
- package/dist/server/Mppx.d.ts.map +1 -1
- package/dist/server/Mppx.js +49 -2
- package/dist/server/Mppx.js.map +1 -1
- package/dist/stripe/internal/types.d.ts +3 -0
- package/dist/stripe/internal/types.d.ts.map +1 -1
- package/dist/stripe/server/Charge.d.ts.map +1 -1
- package/dist/stripe/server/Charge.js +9 -2
- package/dist/stripe/server/Charge.js.map +1 -1
- package/dist/tempo/Methods.d.ts +15 -0
- package/dist/tempo/Methods.d.ts.map +1 -1
- package/dist/tempo/Methods.js +27 -3
- package/dist/tempo/Methods.js.map +1 -1
- package/dist/tempo/client/Charge.d.ts +21 -0
- package/dist/tempo/client/Charge.d.ts.map +1 -1
- package/dist/tempo/client/Charge.js +33 -7
- package/dist/tempo/client/Charge.js.map +1 -1
- package/dist/tempo/client/Methods.d.ts +15 -0
- package/dist/tempo/client/Methods.d.ts.map +1 -1
- package/dist/tempo/internal/account.d.ts +5 -11
- package/dist/tempo/internal/account.d.ts.map +1 -1
- package/dist/tempo/internal/charge.d.ts +20 -0
- package/dist/tempo/internal/charge.d.ts.map +1 -0
- package/dist/tempo/internal/charge.js +23 -0
- package/dist/tempo/internal/charge.js.map +1 -0
- package/dist/tempo/internal/fee-payer.d.ts.map +1 -1
- package/dist/tempo/internal/fee-payer.js +15 -3
- package/dist/tempo/internal/fee-payer.js.map +1 -1
- package/dist/tempo/server/Charge.d.ts +17 -2
- package/dist/tempo/server/Charge.d.ts.map +1 -1
- package/dist/tempo/server/Charge.js +148 -99
- package/dist/tempo/server/Charge.js.map +1 -1
- package/dist/tempo/server/Methods.d.ts +17 -2
- package/dist/tempo/server/Methods.d.ts.map +1 -1
- package/dist/tempo/server/Methods.js +4 -1
- package/dist/tempo/server/Methods.js.map +1 -1
- package/dist/tempo/server/Session.d.ts +9 -4
- package/dist/tempo/server/Session.d.ts.map +1 -1
- package/dist/tempo/server/Session.js +25 -6
- package/dist/tempo/server/Session.js.map +1 -1
- package/dist/tempo/session/Chain.d.ts +18 -2
- package/dist/tempo/session/Chain.d.ts.map +1 -1
- package/dist/tempo/session/Chain.js +18 -14
- package/dist/tempo/session/Chain.js.map +1 -1
- package/package.json +1 -1
- package/src/internal/env.test.ts +12 -12
- package/src/internal/env.ts +2 -6
- package/src/internal/types.ts +25 -0
- package/src/server/Mppx.test.ts +287 -0
- package/src/server/Mppx.ts +59 -5
- package/src/stripe/internal/types.ts +5 -1
- package/src/stripe/server/Charge.test.ts +52 -1
- package/src/stripe/server/Charge.ts +12 -4
- package/src/tempo/Methods.test.ts +79 -0
- package/src/tempo/Methods.ts +53 -17
- package/src/tempo/client/Charge.ts +41 -8
- package/src/tempo/internal/account.ts +7 -14
- package/src/tempo/internal/charge.ts +43 -0
- package/src/tempo/internal/fee-payer.test.ts +33 -14
- package/src/tempo/internal/fee-payer.ts +21 -6
- package/src/tempo/server/Charge.test.ts +231 -0
- package/src/tempo/server/Charge.ts +193 -124
- package/src/tempo/server/Methods.ts +4 -1
- package/src/tempo/server/Session.test.ts +57 -0
- package/src/tempo/server/Session.ts +33 -20
- package/src/tempo/session/Chain.test.ts +25 -5
- package/src/tempo/session/Chain.ts +30 -14
|
@@ -8,6 +8,7 @@ import * as Client from '../../viem/Client.js';
|
|
|
8
8
|
import * as z from '../../zod.js';
|
|
9
9
|
import * as Attribution from '../Attribution.js';
|
|
10
10
|
import * as AutoSwap from '../internal/auto-swap.js';
|
|
11
|
+
import * as Charge_internal from '../internal/charge.js';
|
|
11
12
|
import * as defaults from '../internal/defaults.js';
|
|
12
13
|
import * as Methods from '../Methods.js';
|
|
13
14
|
/**
|
|
@@ -45,16 +46,33 @@ export function charge(parameters = {}) {
|
|
|
45
46
|
const { request } = challenge;
|
|
46
47
|
const { amount, methodDetails } = request;
|
|
47
48
|
const currency = request.currency;
|
|
48
|
-
|
|
49
|
+
if (parameters.expectedRecipients) {
|
|
50
|
+
const allowed = new Set(parameters.expectedRecipients.map((a) => a.toLowerCase()));
|
|
51
|
+
const splits = methodDetails?.splits;
|
|
52
|
+
if (splits) {
|
|
53
|
+
for (const split of splits) {
|
|
54
|
+
if (!allowed.has(split.recipient.toLowerCase()))
|
|
55
|
+
throw new Error(`Unexpected split recipient: ${split.recipient}`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
49
59
|
const memo = methodDetails?.memo
|
|
50
60
|
? methodDetails.memo
|
|
51
61
|
: Attribution.encode({ serverId: challenge.realm, clientId });
|
|
52
|
-
const
|
|
53
|
-
amount
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
62
|
+
const transfers = Charge_internal.getTransfers({
|
|
63
|
+
amount,
|
|
64
|
+
methodDetails: {
|
|
65
|
+
...methodDetails,
|
|
66
|
+
memo,
|
|
67
|
+
},
|
|
68
|
+
recipient: request.recipient,
|
|
57
69
|
});
|
|
70
|
+
const transferCalls = transfers.map((transfer) => Actions.token.transfer.call({
|
|
71
|
+
amount: BigInt(transfer.amount),
|
|
72
|
+
...(transfer.memo && { memo: transfer.memo }),
|
|
73
|
+
to: transfer.recipient,
|
|
74
|
+
token: currency,
|
|
75
|
+
}));
|
|
58
76
|
const autoSwap = AutoSwap.resolve(context?.autoSwap ?? parameters.autoSwap, AutoSwap.defaultCurrencies);
|
|
59
77
|
const swapCalls = autoSwap
|
|
60
78
|
? await AutoSwap.findCalls(client, {
|
|
@@ -65,7 +83,14 @@ export function charge(parameters = {}) {
|
|
|
65
83
|
slippage: autoSwap.slippage,
|
|
66
84
|
})
|
|
67
85
|
: undefined;
|
|
68
|
-
const calls = [...(swapCalls ?? []),
|
|
86
|
+
const calls = [...(swapCalls ?? []), ...transferCalls];
|
|
87
|
+
const validBefore = (() => {
|
|
88
|
+
const defaultExpiry = Math.floor(Date.now() / 1000) + 25;
|
|
89
|
+
if (!challenge.expires)
|
|
90
|
+
return defaultExpiry;
|
|
91
|
+
const challengeExpiry = Math.floor(new Date(challenge.expires).getTime() / 1000);
|
|
92
|
+
return Math.min(defaultExpiry, challengeExpiry);
|
|
93
|
+
})();
|
|
69
94
|
if (mode === 'push') {
|
|
70
95
|
const { receipts } = await sendCallsSync(client, {
|
|
71
96
|
account,
|
|
@@ -86,6 +111,7 @@ export function charge(parameters = {}) {
|
|
|
86
111
|
calls,
|
|
87
112
|
...(methodDetails?.feePayer && { feePayer: true }),
|
|
88
113
|
nonceKey: 'expiring',
|
|
114
|
+
validBefore,
|
|
89
115
|
});
|
|
90
116
|
// FIXME: figure out gas estimation issue for fee payer tx
|
|
91
117
|
prepared.gas = prepared.gas + 5000n;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Charge.js","sourceRoot":"","sources":["../../../src/tempo/client/Charge.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,yBAAyB,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AACxF,OAAO,EAAE,KAAK,IAAI,WAAW,EAAE,MAAM,aAAa,CAAA;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AAEpC,OAAO,KAAK,UAAU,MAAM,qBAAqB,CAAA;AACjD,OAAO,KAAK,MAAM,MAAM,iBAAiB,CAAA;AACzC,OAAO,KAAK,OAAO,MAAM,uBAAuB,CAAA;AAChD,OAAO,KAAK,MAAM,MAAM,sBAAsB,CAAA;AAC9C,OAAO,KAAK,CAAC,MAAM,cAAc,CAAA;AACjC,OAAO,KAAK,WAAW,MAAM,mBAAmB,CAAA;AAChD,OAAO,KAAK,QAAQ,MAAM,0BAA0B,CAAA;AACpD,OAAO,KAAK,QAAQ,MAAM,yBAAyB,CAAA;AACnD,OAAO,KAAK,OAAO,MAAM,eAAe,CAAA;AAExC;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,MAAM,CAAC,aAAgC,EAAE;IACvD,MAAM,EAAE,QAAQ,EAAE,GAAG,UAAU,CAAA;IAC/B,MAAM,SAAS,GAAG,MAAM,CAAC,WAAW,CAAC;QACnC,KAAK,EAAE,WAAW;QAClB,SAAS,EAAE,UAAU,CAAC,SAAS;QAC/B,MAAM,EAAE,QAAQ,CAAC,MAAM;KACxB,CAAC,CAAA;IACF,MAAM,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,UAAU,CAAC,OAAO,EAAE,CAAC,CAAA;IAEvE,OAAO,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE;QACrC,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC;YAChB,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAA6C,CAAC;YAC1E,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAmB,CAAC;YACjD,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;SAC3C,CAAC;QAEF,KAAK,CAAC,gBAAgB,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE;YAC3C,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC,aAAa,EAAE,OAAO,CAAA;YACxD,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,EAAE,OAAO,EAAE,CAAC,CAAA;YAC3C,MAAM,OAAO,GAAG,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;YAE3C,MAAM,IAAI,GACR,OAAO,EAAE,IAAI,IAAI,UAAU,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAA;YAErF,MAAM,EAAE,OAAO,EAAE,GAAG,SAAS,CAAA;YAC7B,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,CAAA;YACzC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAmB,CAAA;
|
|
1
|
+
{"version":3,"file":"Charge.js","sourceRoot":"","sources":["../../../src/tempo/client/Charge.ts"],"names":[],"mappings":"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"}
|
|
@@ -36,8 +36,18 @@ export declare function tempo(parameters?: tempo.Parameters): readonly [import("
|
|
|
36
36
|
feePayer: import("zod/mini").ZodMiniOptional<import("zod/mini").ZodMiniPipe<import("zod/mini").ZodMiniUnion<readonly [import("zod/mini").ZodMiniBoolean<boolean>, import("zod/mini").ZodMiniCustom<import("viem").Account, import("viem").Account>]>, import("zod/mini").ZodMiniTransform<boolean, boolean | import("viem").Account>>>;
|
|
37
37
|
memo: import("zod/mini").ZodMiniOptional<import("zod/mini").ZodMiniString<string>>;
|
|
38
38
|
recipient: import("zod/mini").ZodMiniOptional<import("zod/mini").ZodMiniString<string>>;
|
|
39
|
+
splits: import("zod/mini").ZodMiniOptional<import("zod/mini").ZodMiniArray<import("zod/mini").ZodMiniObject<{
|
|
40
|
+
amount: import("zod/mini").ZodMiniString<string>;
|
|
41
|
+
memo: import("zod/mini").ZodMiniOptional<import("zod/mini").ZodMiniString<string>>;
|
|
42
|
+
recipient: import("zod/mini").ZodMiniPipe<import("zod/mini").ZodMiniString<string>, import("zod/mini").ZodMiniTransform<`0x${string}`, string>>;
|
|
43
|
+
}, import("zod/v4/core").$strip>>>;
|
|
39
44
|
}, import("zod/v4/core").$strip>, import("zod/mini").ZodMiniTransform<{
|
|
40
45
|
methodDetails?: {
|
|
46
|
+
splits?: {
|
|
47
|
+
amount: string;
|
|
48
|
+
recipient: `0x${string}`;
|
|
49
|
+
memo?: string | undefined;
|
|
50
|
+
}[] | undefined;
|
|
41
51
|
memo?: string | undefined;
|
|
42
52
|
feePayer?: boolean | undefined;
|
|
43
53
|
chainId?: number | undefined;
|
|
@@ -57,6 +67,11 @@ export declare function tempo(parameters?: tempo.Parameters): readonly [import("
|
|
|
57
67
|
feePayer?: boolean | undefined;
|
|
58
68
|
memo?: string | undefined;
|
|
59
69
|
recipient?: string | undefined;
|
|
70
|
+
splits?: {
|
|
71
|
+
amount: string;
|
|
72
|
+
recipient: `0x${string}`;
|
|
73
|
+
memo?: string | undefined;
|
|
74
|
+
}[] | undefined;
|
|
60
75
|
}>>;
|
|
61
76
|
};
|
|
62
77
|
}, import("zod/mini").ZodMiniObject<{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Methods.d.ts","sourceRoot":"","sources":["../../../src/tempo/client/Methods.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,OAAO,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,cAAc,CAAA;AACxD,OAAO,EAAE,cAAc,IAAI,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AAEhE;;;;;;;;;;;GAWG;AACH,wBAAgB,KAAK,CAAC,UAAU,GAAE,KAAK,CAAC,UAAe
|
|
1
|
+
{"version":3,"file":"Methods.d.ts","sourceRoot":"","sources":["../../../src/tempo/client/Methods.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,OAAO,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,cAAc,CAAA;AACxD,OAAO,EAAE,cAAc,IAAI,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AAEhE;;;;;;;;;;;GAWG;AACH,wBAAgB,KAAK,CAAC,UAAU,GAAE,KAAK,CAAC,UAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mCAEtD;AAED,yBAAiB,KAAK,CAAC;IACrB,KAAY,UAAU,GAAG,OAAO,CAAC,UAAU,GAAG,cAAc,CAAC,UAAU,CAAA;IAEvE,kFAAkF;IAC3E,MAAM,MAAM,gBAAU,CAAA;IAC7B,6EAA6E;IACtE,MAAM,OAAO,iBAAW,CAAA;CAChC"}
|
|
@@ -19,16 +19,10 @@ export declare function resolve(parameters: resolve.Parameters): {
|
|
|
19
19
|
export declare namespace resolve {
|
|
20
20
|
type Parameters = {
|
|
21
21
|
recipient?: Address | undefined;
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
account
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
} | {
|
|
28
|
-
/** Address that receives payment. */
|
|
29
|
-
account?: Address | undefined;
|
|
30
|
-
/** Optional fee payer account or fee payer URL for covering transaction fees. */
|
|
31
|
-
feePayer?: Account | string | undefined;
|
|
32
|
-
});
|
|
22
|
+
/** Account or address that performs payment operations / receives payment. */
|
|
23
|
+
account?: Account | Address | undefined;
|
|
24
|
+
/** When `true`, the account also sponsors fees. An `Account` object or URL string can also be provided as a dedicated fee payer. */
|
|
25
|
+
feePayer?: Account | string | true | undefined;
|
|
26
|
+
};
|
|
33
27
|
}
|
|
34
28
|
//# sourceMappingURL=account.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"account.d.ts","sourceRoot":"","sources":["../../../src/tempo/internal/account.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAE5C;;;;;;;;;;GAUG;AACH,wBAAgB,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,UAAU;;;;eAkBa,OAAO,GAAG,SAAS;EACrF;AAED,MAAM,CAAC,OAAO,WAAW,OAAO,CAAC;IAC/B,KAAK,UAAU,GAAG;
|
|
1
|
+
{"version":3,"file":"account.d.ts","sourceRoot":"","sources":["../../../src/tempo/internal/account.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAE5C;;;;;;;;;;GAUG;AACH,wBAAgB,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,UAAU;;;;eAkBa,OAAO,GAAG,SAAS;EACrF;AAED,MAAM,CAAC,OAAO,WAAW,OAAO,CAAC;IAC/B,KAAK,UAAU,GAAG;QAChB,SAAS,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;QAC/B,8EAA8E;QAC9E,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,GAAG,SAAS,CAAA;QACvC,oIAAoI;QACpI,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,CAAA;KAC/C,CAAA;CACF"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Address } from 'viem';
|
|
2
|
+
export type Split = {
|
|
3
|
+
amount: string;
|
|
4
|
+
memo?: string | undefined;
|
|
5
|
+
recipient: Address;
|
|
6
|
+
};
|
|
7
|
+
export type Transfer = {
|
|
8
|
+
amount: string;
|
|
9
|
+
memo?: string | undefined;
|
|
10
|
+
recipient: Address;
|
|
11
|
+
};
|
|
12
|
+
export declare function getTransfers(request: {
|
|
13
|
+
amount: string;
|
|
14
|
+
methodDetails?: {
|
|
15
|
+
memo?: string | undefined;
|
|
16
|
+
splits?: readonly Split[] | undefined;
|
|
17
|
+
};
|
|
18
|
+
recipient: Address;
|
|
19
|
+
}): Transfer[];
|
|
20
|
+
//# sourceMappingURL=charge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"charge.d.ts","sourceRoot":"","sources":["../../../src/tempo/internal/charge.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAEnC,MAAM,MAAM,KAAK,GAAG;IAClB,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACzB,SAAS,EAAE,OAAO,CAAA;CACnB,CAAA;AAED,MAAM,MAAM,QAAQ,GAAG;IACrB,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACzB,SAAS,EAAE,OAAO,CAAA;CACnB,CAAA;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE;IACpC,MAAM,EAAE,MAAM,CAAA;IACd,aAAa,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,MAAM,CAAC,EAAE,SAAS,KAAK,EAAE,GAAG,SAAS,CAAA;KAAE,CAAA;IACpF,SAAS,EAAE,OAAO,CAAA;CACnB,GAAG,QAAQ,EAAE,CAwBb"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export function getTransfers(request) {
|
|
2
|
+
const totalAmount = BigInt(request.amount);
|
|
3
|
+
const splits = request.methodDetails?.splits ?? [];
|
|
4
|
+
const splitTotal = splits.reduce((sum, split) => sum + BigInt(split.amount), 0n);
|
|
5
|
+
if (splitTotal >= totalAmount)
|
|
6
|
+
throw new Error('Invalid charge request: split total must be less than total amount.');
|
|
7
|
+
const primaryAmount = totalAmount - splitTotal;
|
|
8
|
+
if (primaryAmount <= 0n)
|
|
9
|
+
throw new Error('Invalid charge request: primary transfer amount must be positive.');
|
|
10
|
+
return [
|
|
11
|
+
{
|
|
12
|
+
amount: primaryAmount.toString(),
|
|
13
|
+
memo: request.methodDetails?.memo,
|
|
14
|
+
recipient: request.recipient,
|
|
15
|
+
},
|
|
16
|
+
...splits.map((split) => ({
|
|
17
|
+
amount: split.amount,
|
|
18
|
+
memo: split.memo,
|
|
19
|
+
recipient: split.recipient,
|
|
20
|
+
})),
|
|
21
|
+
];
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=charge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"charge.js","sourceRoot":"","sources":["../../../src/tempo/internal/charge.ts"],"names":[],"mappings":"AAcA,MAAM,UAAU,YAAY,CAAC,OAI5B;IACC,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;IAC1C,MAAM,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,MAAM,IAAI,EAAE,CAAA;IAElD,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,CAAA;IAChF,IAAI,UAAU,IAAI,WAAW;QAC3B,MAAM,IAAI,KAAK,CAAC,qEAAqE,CAAC,CAAA;IAExF,MAAM,aAAa,GAAG,WAAW,GAAG,UAAU,CAAA;IAC9C,IAAI,aAAa,IAAI,EAAE;QACrB,MAAM,IAAI,KAAK,CAAC,mEAAmE,CAAC,CAAA;IAEtF,OAAO;QACL;YACE,MAAM,EAAE,aAAa,CAAC,QAAQ,EAAE;YAChC,IAAI,EAAE,OAAO,CAAC,aAAa,EAAE,IAAI;YACjC,SAAS,EAAE,OAAO,CAAC,SAAS;SAC7B;QACD,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YACxB,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,SAAS,EAAE,KAAK,CAAC,SAAS;SAC3B,CAAC,CAAC;KACJ,CAAA;AACH,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fee-payer.d.ts","sourceRoot":"","sources":["../../../src/tempo/internal/fee-payer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAQ5C,8EAA8E;AAC9E,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAK1E;AAED;;;GAGG;AACH,eAAO,MAAM,UAAU,mBAKtB,CAAA;AAED,sFAAsF;AACtF,wBAAgB,aAAa,CAC3B,KAAK,EAAE,SAAS;IAAE,IAAI,CAAC,EAAE,KAAK,MAAM,EAAE,GAAG,SAAS,CAAC;IAAC,EAAE,CAAC,EAAE,YAAY,CAAC,OAAO,GAAG,SAAS,CAAA;CAAE,EAAE,EAC7F,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"fee-payer.d.ts","sourceRoot":"","sources":["../../../src/tempo/internal/fee-payer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAQ5C,8EAA8E;AAC9E,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAK1E;AAED;;;GAGG;AACH,eAAO,MAAM,UAAU,mBAKtB,CAAA;AAED,sFAAsF;AACtF,wBAAgB,aAAa,CAC3B,KAAK,EAAE,SAAS;IAAE,IAAI,CAAC,EAAE,KAAK,MAAM,EAAE,GAAG,SAAS,CAAC;IAAC,EAAE,CAAC,EAAE,YAAY,CAAC,OAAO,GAAG,SAAS,CAAA;CAAE,EAAE,EAC7F,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,QAuChC;AAED,qBAAa,uBAAwB,SAAQ,KAAK;IAChD,SAAkB,IAAI,6BAA4B;gBAEtC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;CAQ5D"}
|
|
@@ -20,11 +20,23 @@ export const callScopes = [
|
|
|
20
20
|
];
|
|
21
21
|
/** Validates that a set of transaction calls matches an allowed fee-payer pattern. */
|
|
22
22
|
export function validateCalls(calls, details) {
|
|
23
|
+
if (calls.length === 0)
|
|
24
|
+
throw new FeePayerValidationError('disallowed call pattern in fee-payer transaction', details);
|
|
23
25
|
const callSelectors = calls.map((c) => c.data?.slice(0, 10));
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
26
|
+
const hasSwapPrefix = callSelectors[0] === Selectors.approve;
|
|
27
|
+
if (hasSwapPrefix) {
|
|
28
|
+
if (callSelectors[1] !== Selectors.swapExactAmountOut)
|
|
29
|
+
throw new FeePayerValidationError('disallowed call pattern in fee-payer transaction', details);
|
|
30
|
+
}
|
|
31
|
+
else if (callSelectors[0] === Selectors.swapExactAmountOut) {
|
|
27
32
|
throw new FeePayerValidationError('disallowed call pattern in fee-payer transaction', details);
|
|
33
|
+
}
|
|
34
|
+
const transferSelectors = callSelectors.slice(hasSwapPrefix ? 2 : 0);
|
|
35
|
+
if (transferSelectors.length === 0 ||
|
|
36
|
+
transferSelectors.length > 11 ||
|
|
37
|
+
transferSelectors.some((selector) => selector !== Selectors.transfer && selector !== Selectors.transferWithMemo)) {
|
|
38
|
+
throw new FeePayerValidationError('disallowed call pattern in fee-payer transaction', details);
|
|
39
|
+
}
|
|
28
40
|
// Validate approve spender and buy target are the DEX.
|
|
29
41
|
const approveCall = calls.find((c) => c.data?.slice(0, 10) === Selectors.approve);
|
|
30
42
|
if (approveCall) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fee-payer.js","sourceRoot":"","sources":["../../../src/tempo/internal/fee-payer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAC1C,OAAO,EAAE,kBAAkB,EAAE,MAAM,MAAM,CAAA;AACzC,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAE5C,OAAO,KAAK,qBAAqB,MAAM,cAAc,CAAA;AACrD,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAE3C,8EAA8E;AAC9E,MAAM,UAAU,kBAAkB,CAAC,UAA8B;IAC/D,OAAO,CACL,UAAU,EAAE,UAAU,CAAC,eAAe,CAAC,cAAc,CAAC,KAAK,IAAI;QAC/D,UAAU,EAAE,UAAU,CAAC,eAAe,CAAC,aAAa,CAAC,KAAK,IAAI,CAC/D,CAAA;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,CAAC,SAAS,CAAC,QAAQ,CAAC;IACpB,CAAC,SAAS,CAAC,gBAAgB,CAAC;IAC5B,CAAC,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC,kBAAkB,EAAE,SAAS,CAAC,QAAQ,CAAC;IACrE,CAAC,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC,kBAAkB,EAAE,SAAS,CAAC,gBAAgB,CAAC;CAC9E,CAAA;AAED,sFAAsF;AACtF,MAAM,UAAU,aAAa,CAC3B,KAA6F,EAC7F,OAA+B;IAE/B,MAAM,aAAa,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAA;IAC5D,MAAM,
|
|
1
|
+
{"version":3,"file":"fee-payer.js","sourceRoot":"","sources":["../../../src/tempo/internal/fee-payer.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { LooseOmit } from '../../internal/types.js';
|
|
1
|
+
import type { LooseOmit, NoExtraKeys } from '../../internal/types.js';
|
|
2
2
|
import * as Method from '../../Method.js';
|
|
3
3
|
import * as Store from '../../Store.js';
|
|
4
4
|
import * as Client from '../../viem/Client.js';
|
|
@@ -15,7 +15,7 @@ import * as Methods from '../Methods.js';
|
|
|
15
15
|
* const charge = tempo.charge()
|
|
16
16
|
* ```
|
|
17
17
|
*/
|
|
18
|
-
export declare function charge<const parameters extends charge.Parameters>(parameters?: parameters): Method.Server<{
|
|
18
|
+
export declare function charge<const parameters extends charge.Parameters>(parameters?: NoExtraKeys<parameters, charge.Parameters>): Method.Server<{
|
|
19
19
|
readonly name: "tempo";
|
|
20
20
|
readonly intent: "charge";
|
|
21
21
|
readonly schema: {
|
|
@@ -38,8 +38,18 @@ export declare function charge<const parameters extends charge.Parameters>(param
|
|
|
38
38
|
feePayer: import("zod/mini").ZodMiniOptional<import("zod/mini").ZodMiniPipe<import("zod/mini").ZodMiniUnion<readonly [import("zod/mini").ZodMiniBoolean<boolean>, import("zod/mini").ZodMiniCustom<import("viem").Account, import("viem").Account>]>, import("zod/mini").ZodMiniTransform<boolean, boolean | import("viem").Account>>>;
|
|
39
39
|
memo: import("zod/mini").ZodMiniOptional<import("zod/mini").ZodMiniString<string>>;
|
|
40
40
|
recipient: import("zod/mini").ZodMiniOptional<import("zod/mini").ZodMiniString<string>>;
|
|
41
|
+
splits: import("zod/mini").ZodMiniOptional<import("zod/mini").ZodMiniArray<import("zod/mini").ZodMiniObject<{
|
|
42
|
+
amount: import("zod/mini").ZodMiniString<string>;
|
|
43
|
+
memo: import("zod/mini").ZodMiniOptional<import("zod/mini").ZodMiniString<string>>;
|
|
44
|
+
recipient: import("zod/mini").ZodMiniPipe<import("zod/mini").ZodMiniString<string>, import("zod/mini").ZodMiniTransform<`0x${string}`, string>>;
|
|
45
|
+
}, import("zod/v4/core").$strip>>>;
|
|
41
46
|
}, import("zod/v4/core").$strip>, import("zod/mini").ZodMiniTransform<{
|
|
42
47
|
methodDetails?: {
|
|
48
|
+
splits?: {
|
|
49
|
+
amount: string;
|
|
50
|
+
recipient: `0x${string}`;
|
|
51
|
+
memo?: string | undefined;
|
|
52
|
+
}[] | undefined;
|
|
43
53
|
memo?: string | undefined;
|
|
44
54
|
feePayer?: boolean | undefined;
|
|
45
55
|
chainId?: number | undefined;
|
|
@@ -59,6 +69,11 @@ export declare function charge<const parameters extends charge.Parameters>(param
|
|
|
59
69
|
feePayer?: boolean | undefined;
|
|
60
70
|
memo?: string | undefined;
|
|
61
71
|
recipient?: string | undefined;
|
|
72
|
+
splits?: {
|
|
73
|
+
amount: string;
|
|
74
|
+
recipient: `0x${string}`;
|
|
75
|
+
memo?: string | undefined;
|
|
76
|
+
}[] | undefined;
|
|
62
77
|
}>>;
|
|
63
78
|
};
|
|
64
79
|
}, charge.DeriveDefaults<parameters>, undefined>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Charge.d.ts","sourceRoot":"","sources":["../../../src/tempo/server/Charge.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Charge.d.ts","sourceRoot":"","sources":["../../../src/tempo/server/Charge.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AACrE,OAAO,KAAK,MAAM,MAAM,iBAAiB,CAAA;AACzC,OAAO,KAAK,KAAK,MAAM,gBAAgB,CAAA;AACvC,OAAO,KAAK,MAAM,MAAM,sBAAsB,CAAA;AAC9C,OAAO,KAAK,OAAO,MAAM,wBAAwB,CAAA;AAMjD,OAAO,KAAK,KAAK,KAAK,MAAM,sBAAsB,CAAA;AAClD,OAAO,KAAK,OAAO,MAAM,eAAe,CAAA;AAExC;;;;;;;;;GASG;AACH,wBAAgB,MAAM,CAAC,KAAK,CAAC,UAAU,SAAS,MAAM,CAAC,UAAU,EAC/D,UAAU,GAAE,WAAW,CAAC,UAAU,EAAE,MAAM,CAAC,UAAU,CAGpD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iDAuMF;AAED,MAAM,CAAC,OAAO,WAAW,MAAM,CAAC;IAC9B,KAAK,YAAY,GAAG;QAAE,CAAC,GAAG,EAAE,eAAe,MAAM,EAAE,GAAG,MAAM,CAAA;KAAE,CAAA;IAE9D,KAAK,QAAQ,GAAG,SAAS,CAAC,MAAM,CAAC,eAAe,CAAC,OAAO,OAAO,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,WAAW,CAAC,CAAA;IAElG,KAAK,UAAU,GAAG;QAChB,oBAAoB;QACpB,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;QAC7B;;;;;WAKG;QACH,KAAK,CAAC,EAAE,KAAK,CAAC,KAAK,GAAG,SAAS,CAAA;QAC/B;;;;;;;;;;WAUG;QACH,mBAAmB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;KAC1C,GAAG,MAAM,CAAC,WAAW,CAAC,UAAU,GAC/B,OAAO,CAAC,OAAO,CAAC,UAAU,GAC1B,QAAQ,CAAA;IAEV,KAAK,cAAc,CAAC,UAAU,SAAS,UAAU,IAAI,KAAK,CAAC,cAAc,CACvE,UAAU,EACV,QAAQ,CACT,GAAG;QACF,QAAQ,EAAE,MAAM,CAAA;KACjB,CAAA;CACF"}
|
|
@@ -8,6 +8,7 @@ import * as Store from '../../Store.js';
|
|
|
8
8
|
import * as Client from '../../viem/Client.js';
|
|
9
9
|
import * as Account from '../internal/account.js';
|
|
10
10
|
import * as TempoAddress from '../internal/address.js';
|
|
11
|
+
import * as Charge_internal from '../internal/charge.js';
|
|
11
12
|
import * as defaults from '../internal/defaults.js';
|
|
12
13
|
import * as FeePayer from '../internal/fee-payer.js';
|
|
13
14
|
import * as Selectors from '../internal/selectors.js';
|
|
@@ -94,15 +95,12 @@ export function charge(parameters = {}) {
|
|
|
94
95
|
case 'hash': {
|
|
95
96
|
const hash = payload.hash;
|
|
96
97
|
await assertHashUnused(store, hash);
|
|
97
|
-
const
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
assertTransferLog(receipt, {
|
|
101
|
-
amount,
|
|
98
|
+
const expectedTransfers = getExpectedTransfers({ amount, memo, methodDetails, recipient });
|
|
99
|
+
const receipt = await getTransactionReceipt(client, { hash });
|
|
100
|
+
assertTransferLogs(receipt, {
|
|
102
101
|
currency,
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
recipient,
|
|
102
|
+
sender: receipt.from,
|
|
103
|
+
transfers: expectedTransfers,
|
|
106
104
|
});
|
|
107
105
|
await markHashUsed(store, hash);
|
|
108
106
|
return toReceipt(receipt);
|
|
@@ -118,55 +116,11 @@ export function charge(parameters = {}) {
|
|
|
118
116
|
const transaction = Transaction.deserialize(serializedTransaction);
|
|
119
117
|
if (!transaction.signature || !transaction.from)
|
|
120
118
|
throw new MismatchError('Transaction must be signed by the sender before fee payer co-signing.', {});
|
|
121
|
-
const
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
const selector = call.data.slice(0, 10);
|
|
127
|
-
if (memo) {
|
|
128
|
-
if (selector !== Selectors.transferWithMemo)
|
|
129
|
-
return false;
|
|
130
|
-
try {
|
|
131
|
-
const { args } = decodeFunctionData({ abi: Abis.tip20, data: call.data });
|
|
132
|
-
const [to, amount_, memo_] = args;
|
|
133
|
-
return (TempoAddress.isEqual(to, recipient) &&
|
|
134
|
-
amount_.toString() === amount &&
|
|
135
|
-
memo_.toLowerCase() === memo.toLowerCase());
|
|
136
|
-
}
|
|
137
|
-
catch {
|
|
138
|
-
return false;
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
if (selector === Selectors.transfer) {
|
|
142
|
-
try {
|
|
143
|
-
const { args } = decodeFunctionData({ abi: Abis.tip20, data: call.data });
|
|
144
|
-
const [to, amount_] = args;
|
|
145
|
-
return TempoAddress.isEqual(to, recipient) && amount_.toString() === amount;
|
|
146
|
-
}
|
|
147
|
-
catch {
|
|
148
|
-
return false;
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
if (selector === Selectors.transferWithMemo) {
|
|
152
|
-
try {
|
|
153
|
-
const { args } = decodeFunctionData({ abi: Abis.tip20, data: call.data });
|
|
154
|
-
const [to, amount_] = args;
|
|
155
|
-
return TempoAddress.isEqual(to, recipient) && amount_.toString() === amount;
|
|
156
|
-
}
|
|
157
|
-
catch {
|
|
158
|
-
return false;
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
return false;
|
|
162
|
-
});
|
|
163
|
-
if (!call)
|
|
164
|
-
throw new MismatchError('Invalid transaction: no matching payment call found', {
|
|
165
|
-
amount,
|
|
166
|
-
currency,
|
|
167
|
-
recipient,
|
|
168
|
-
});
|
|
169
|
-
if ((feePayer || feePayerUrl) && methodDetails?.feePayer !== false)
|
|
119
|
+
const calls = (transaction.calls ?? []);
|
|
120
|
+
const transfers = getExpectedTransfers({ amount, memo, methodDetails, recipient });
|
|
121
|
+
const isFeePayerTx = !!(feePayer || feePayerUrl) && methodDetails?.feePayer !== false;
|
|
122
|
+
assertTransferCalls(calls, { currency, exactCount: isFeePayerTx, transfers });
|
|
123
|
+
if (isFeePayerTx)
|
|
170
124
|
FeePayer.validateCalls(transaction.calls, { amount, currency, recipient });
|
|
171
125
|
const resolvedFeeToken = transaction.feeToken ?? defaults.currency[chainId];
|
|
172
126
|
const serializedTransaction_final = await (async () => {
|
|
@@ -184,12 +138,10 @@ export function charge(parameters = {}) {
|
|
|
184
138
|
const receipt = await sendRawTransactionSync(client, {
|
|
185
139
|
serializedTransaction: serializedTransaction_final,
|
|
186
140
|
});
|
|
187
|
-
|
|
188
|
-
amount,
|
|
141
|
+
assertTransferLogs(receipt, {
|
|
189
142
|
currency,
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
recipient,
|
|
143
|
+
sender: transaction.from,
|
|
144
|
+
transfers,
|
|
193
145
|
});
|
|
194
146
|
// Post-broadcast dedup: catch malleable input variants
|
|
195
147
|
// (different serialized bytes, same underlying tx) that
|
|
@@ -233,49 +185,146 @@ export function charge(parameters = {}) {
|
|
|
233
185
|
},
|
|
234
186
|
});
|
|
235
187
|
}
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
188
|
+
function getExpectedTransfers(parameters) {
|
|
189
|
+
return Charge_internal.getTransfers({
|
|
190
|
+
amount: parameters.amount,
|
|
191
|
+
methodDetails: {
|
|
192
|
+
memo: parameters.memo,
|
|
193
|
+
splits: parameters.methodDetails?.splits,
|
|
194
|
+
},
|
|
195
|
+
recipient: parameters.recipient,
|
|
196
|
+
}).map((transfer) => ({
|
|
197
|
+
...transfer,
|
|
198
|
+
...(!transfer.memo ? { allowAnyMemo: true } : {}),
|
|
199
|
+
}));
|
|
200
|
+
}
|
|
201
|
+
function assertTransferCalls(calls, parameters) {
|
|
202
|
+
const transferCalls = getTransferCalls(calls);
|
|
203
|
+
if (parameters.exactCount && transferCalls.length !== parameters.transfers.length)
|
|
204
|
+
throw new MismatchError('Invalid transaction: no matching payment call found', {
|
|
205
|
+
expectedCalls: String(parameters.transfers.length),
|
|
206
|
+
actualCalls: String(transferCalls.length),
|
|
207
|
+
});
|
|
208
|
+
const used = new Set();
|
|
209
|
+
// Match memo-specific transfers before wildcards to avoid greedy
|
|
210
|
+
// consumption of memo-bearing calls by allowAnyMemo entries.
|
|
211
|
+
const sorted = [...parameters.transfers].sort((a, b) => {
|
|
212
|
+
if (a.memo && !b.memo)
|
|
213
|
+
return -1;
|
|
214
|
+
if (!a.memo && b.memo)
|
|
215
|
+
return 1;
|
|
216
|
+
return 0;
|
|
217
|
+
});
|
|
218
|
+
for (const expected of sorted) {
|
|
219
|
+
const matchIndex = transferCalls.findIndex((call, index) => {
|
|
220
|
+
if (used.has(index))
|
|
221
|
+
return false;
|
|
222
|
+
const decoded = decodeTransferCall(call, parameters.currency);
|
|
223
|
+
if (!decoded)
|
|
224
|
+
return false;
|
|
225
|
+
if (!TempoAddress.isEqual(decoded.recipient, expected.recipient))
|
|
226
|
+
return false;
|
|
227
|
+
if (decoded.amount !== expected.amount)
|
|
228
|
+
return false;
|
|
229
|
+
if (expected.memo) {
|
|
230
|
+
return decoded.memo?.toLowerCase() === expected.memo.toLowerCase();
|
|
231
|
+
}
|
|
232
|
+
if (expected.allowAnyMemo)
|
|
233
|
+
return true;
|
|
234
|
+
return decoded.memo === undefined;
|
|
244
235
|
});
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
if (!match)
|
|
251
|
-
throw new MismatchError('Payment verification failed: no matching transfer with memo found.', {
|
|
252
|
-
amount,
|
|
253
|
-
currency,
|
|
254
|
-
memo,
|
|
255
|
-
recipient,
|
|
236
|
+
if (matchIndex === -1) {
|
|
237
|
+
throw new MismatchError('Invalid transaction: no matching payment call found', {
|
|
238
|
+
amount: expected.amount,
|
|
239
|
+
currency: parameters.currency,
|
|
240
|
+
recipient: expected.recipient,
|
|
256
241
|
});
|
|
242
|
+
}
|
|
243
|
+
used.add(matchIndex);
|
|
257
244
|
}
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
245
|
+
}
|
|
246
|
+
function getTransferCalls(calls) {
|
|
247
|
+
const selectors = calls.map((call) => call.data?.slice(0, 10));
|
|
248
|
+
const offset = selectors[0] === Selectors.approve && selectors[1] === Selectors.swapExactAmountOut ? 2 : 0;
|
|
249
|
+
const transferCalls = calls.slice(offset);
|
|
250
|
+
if (transferCalls.length === 0 ||
|
|
251
|
+
selectors
|
|
252
|
+
.slice(offset)
|
|
253
|
+
.some((selector) => selector !== Selectors.transfer && selector !== Selectors.transferWithMemo)) {
|
|
254
|
+
throw new MismatchError('Invalid transaction: no matching payment call found', {});
|
|
255
|
+
}
|
|
256
|
+
return transferCalls;
|
|
257
|
+
}
|
|
258
|
+
function decodeTransferCall(call, currency) {
|
|
259
|
+
if (!call.to || !TempoAddress.isEqual(call.to, currency) || !call.data)
|
|
260
|
+
return null;
|
|
261
|
+
try {
|
|
262
|
+
const selector = call.data.slice(0, 10);
|
|
263
|
+
if (selector === Selectors.transfer) {
|
|
264
|
+
const { args } = decodeFunctionData({ abi: Abis.tip20, data: call.data });
|
|
265
|
+
const [recipient, amount] = args;
|
|
266
|
+
return { amount: amount.toString(), recipient };
|
|
267
|
+
}
|
|
268
|
+
if (selector === Selectors.transferWithMemo) {
|
|
269
|
+
const { args } = decodeFunctionData({ abi: Abis.tip20, data: call.data });
|
|
270
|
+
const [recipient, amount, memo] = args;
|
|
271
|
+
return { amount: amount.toString(), memo, recipient };
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
catch {
|
|
275
|
+
return null;
|
|
276
|
+
}
|
|
277
|
+
return null;
|
|
278
|
+
}
|
|
279
|
+
function assertTransferLogs(receipt, parameters) {
|
|
280
|
+
const transferLogs = parseEventLogs({
|
|
281
|
+
abi: Abis.tip20,
|
|
282
|
+
eventName: 'Transfer',
|
|
283
|
+
logs: receipt.logs,
|
|
284
|
+
}).map((log) => ({ ...log, kind: 'transfer' }));
|
|
285
|
+
const memoLogs = parseEventLogs({
|
|
286
|
+
abi: Abis.tip20,
|
|
287
|
+
eventName: 'TransferWithMemo',
|
|
288
|
+
logs: receipt.logs,
|
|
289
|
+
}).map((log) => ({ ...log, kind: 'memo' }));
|
|
290
|
+
const logs = [...transferLogs, ...memoLogs];
|
|
291
|
+
const used = new Set();
|
|
292
|
+
// Match memo-specific transfers before wildcards to avoid greedy
|
|
293
|
+
// consumption of memo-bearing logs by allowAnyMemo entries.
|
|
294
|
+
const sorted = [...parameters.transfers].sort((a, b) => {
|
|
295
|
+
if (a.memo && !b.memo)
|
|
296
|
+
return -1;
|
|
297
|
+
if (!a.memo && b.memo)
|
|
298
|
+
return 1;
|
|
299
|
+
return 0;
|
|
300
|
+
});
|
|
301
|
+
for (const transfer of sorted) {
|
|
302
|
+
const matchIndex = logs.findIndex((log, index) => {
|
|
303
|
+
if (used.has(index))
|
|
304
|
+
return false;
|
|
305
|
+
if (!TempoAddress.isEqual(log.address, parameters.currency))
|
|
306
|
+
return false;
|
|
307
|
+
if (!TempoAddress.isEqual(log.args.from, parameters.sender))
|
|
308
|
+
return false;
|
|
309
|
+
if (!TempoAddress.isEqual(log.args.to, transfer.recipient))
|
|
310
|
+
return false;
|
|
311
|
+
if (log.args.amount.toString() !== transfer.amount)
|
|
312
|
+
return false;
|
|
313
|
+
if (transfer.memo) {
|
|
314
|
+
return log.kind === 'memo' && log.args.memo.toLowerCase() === transfer.memo.toLowerCase();
|
|
315
|
+
}
|
|
316
|
+
if (transfer.allowAnyMemo)
|
|
317
|
+
return log.kind === 'transfer' || log.kind === 'memo';
|
|
318
|
+
return log.kind === 'transfer';
|
|
268
319
|
});
|
|
269
|
-
|
|
270
|
-
TempoAddress.isEqual(log.args.from, from) &&
|
|
271
|
-
TempoAddress.isEqual(log.args.to, recipient) &&
|
|
272
|
-
log.args.amount.toString() === amount);
|
|
273
|
-
if (!match)
|
|
320
|
+
if (matchIndex === -1) {
|
|
274
321
|
throw new MismatchError('Payment verification failed: no matching transfer found.', {
|
|
275
|
-
amount,
|
|
276
|
-
currency,
|
|
277
|
-
recipient,
|
|
322
|
+
amount: transfer.amount,
|
|
323
|
+
currency: parameters.currency,
|
|
324
|
+
recipient: transfer.recipient,
|
|
278
325
|
});
|
|
326
|
+
}
|
|
327
|
+
used.add(matchIndex);
|
|
279
328
|
}
|
|
280
329
|
}
|
|
281
330
|
/** @internal */
|