@t402/btc 2.7.0
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 +120 -0
- package/dist/cjs/exact/client/index.d.ts +89 -0
- package/dist/cjs/exact/client/index.js +145 -0
- package/dist/cjs/exact/client/index.js.map +1 -0
- package/dist/cjs/exact/facilitator/index.d.ts +114 -0
- package/dist/cjs/exact/facilitator/index.js +218 -0
- package/dist/cjs/exact/facilitator/index.js.map +1 -0
- package/dist/cjs/exact/server/index.d.ts +101 -0
- package/dist/cjs/exact/server/index.js +161 -0
- package/dist/cjs/exact/server/index.js.map +1 -0
- package/dist/cjs/index.d.ts +179 -0
- package/dist/cjs/index.js +849 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/lightning/client/index.d.ts +82 -0
- package/dist/cjs/lightning/client/index.js +114 -0
- package/dist/cjs/lightning/client/index.js.map +1 -0
- package/dist/cjs/lightning/facilitator/index.d.ts +93 -0
- package/dist/cjs/lightning/facilitator/index.js +211 -0
- package/dist/cjs/lightning/facilitator/index.js.map +1 -0
- package/dist/cjs/lightning/server/index.d.ts +96 -0
- package/dist/cjs/lightning/server/index.js +157 -0
- package/dist/cjs/lightning/server/index.js.map +1 -0
- package/dist/cjs/signer-B_Z4WGLa.d.ts +64 -0
- package/dist/esm/chunk-2DEKJ7ER.mjs +123 -0
- package/dist/esm/chunk-2DEKJ7ER.mjs.map +1 -0
- package/dist/esm/chunk-3IOPLDQH.mjs +74 -0
- package/dist/esm/chunk-3IOPLDQH.mjs.map +1 -0
- package/dist/esm/chunk-7IU3Z36R.mjs +103 -0
- package/dist/esm/chunk-7IU3Z36R.mjs.map +1 -0
- package/dist/esm/chunk-HNFWDITA.mjs +170 -0
- package/dist/esm/chunk-HNFWDITA.mjs.map +1 -0
- package/dist/esm/chunk-MX3PAUPJ.mjs +65 -0
- package/dist/esm/chunk-MX3PAUPJ.mjs.map +1 -0
- package/dist/esm/chunk-YJYTK2QQ.mjs +127 -0
- package/dist/esm/chunk-YJYTK2QQ.mjs.map +1 -0
- package/dist/esm/chunk-YWZC2RR7.mjs +38 -0
- package/dist/esm/chunk-YWZC2RR7.mjs.map +1 -0
- package/dist/esm/chunk-ZOL5R3HZ.mjs +177 -0
- package/dist/esm/chunk-ZOL5R3HZ.mjs.map +1 -0
- package/dist/esm/exact/client/index.d.mts +89 -0
- package/dist/esm/exact/client/index.mjs +11 -0
- package/dist/esm/exact/client/index.mjs.map +1 -0
- package/dist/esm/exact/facilitator/index.d.mts +114 -0
- package/dist/esm/exact/facilitator/index.mjs +11 -0
- package/dist/esm/exact/facilitator/index.mjs.map +1 -0
- package/dist/esm/exact/server/index.d.mts +101 -0
- package/dist/esm/exact/server/index.mjs +10 -0
- package/dist/esm/exact/server/index.mjs.map +1 -0
- package/dist/esm/index.d.mts +179 -0
- package/dist/esm/index.mjs +77 -0
- package/dist/esm/index.mjs.map +1 -0
- package/dist/esm/lightning/client/index.d.mts +82 -0
- package/dist/esm/lightning/client/index.mjs +11 -0
- package/dist/esm/lightning/client/index.mjs.map +1 -0
- package/dist/esm/lightning/facilitator/index.d.mts +93 -0
- package/dist/esm/lightning/facilitator/index.mjs +11 -0
- package/dist/esm/lightning/facilitator/index.mjs.map +1 -0
- package/dist/esm/lightning/server/index.d.mts +96 -0
- package/dist/esm/lightning/server/index.mjs +10 -0
- package/dist/esm/lightning/server/index.mjs.map +1 -0
- package/dist/esm/signer-B_Z4WGLa.d.mts +64 -0
- package/package.json +142 -0
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import {
|
|
2
|
+
SATS_PER_BTC,
|
|
3
|
+
SCHEME_EXACT,
|
|
4
|
+
__publicField
|
|
5
|
+
} from "./chunk-YWZC2RR7.mjs";
|
|
6
|
+
|
|
7
|
+
// src/exact/server/scheme.ts
|
|
8
|
+
var ExactBtcScheme = class {
|
|
9
|
+
constructor(config) {
|
|
10
|
+
__publicField(this, "scheme", SCHEME_EXACT);
|
|
11
|
+
__publicField(this, "moneyParsers", []);
|
|
12
|
+
__publicField(this, "config");
|
|
13
|
+
this.config = config;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Register a custom money parser in the parser chain.
|
|
17
|
+
*
|
|
18
|
+
* @param parser - Custom function to convert amount to AssetAmount (or null to skip)
|
|
19
|
+
* @returns The server instance for chaining
|
|
20
|
+
*/
|
|
21
|
+
registerMoneyParser(parser) {
|
|
22
|
+
this.moneyParsers.push(parser);
|
|
23
|
+
return this;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Parses a price into an asset amount in satoshis.
|
|
27
|
+
*
|
|
28
|
+
* Accepts:
|
|
29
|
+
* - Number: treated as USD, converted to satoshis at a default rate
|
|
30
|
+
* - String with $: treated as USD
|
|
31
|
+
* - AssetAmount: returned directly
|
|
32
|
+
*
|
|
33
|
+
* For Bitcoin, amounts are always in satoshis and the asset is "BTC".
|
|
34
|
+
*
|
|
35
|
+
* @param price - The price to parse
|
|
36
|
+
* @param network - The network to use
|
|
37
|
+
* @returns Promise that resolves to the parsed asset amount
|
|
38
|
+
*/
|
|
39
|
+
async parsePrice(price, network) {
|
|
40
|
+
if (typeof price === "object" && price !== null && "amount" in price) {
|
|
41
|
+
if (!price.asset) {
|
|
42
|
+
throw new Error(`Asset must be specified for AssetAmount on network ${network}`);
|
|
43
|
+
}
|
|
44
|
+
return {
|
|
45
|
+
amount: price.amount,
|
|
46
|
+
asset: price.asset,
|
|
47
|
+
extra: price.extra || {}
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
const amount = this.parseMoneyToDecimal(price);
|
|
51
|
+
for (const parser of this.moneyParsers) {
|
|
52
|
+
const result = await parser(amount, network);
|
|
53
|
+
if (result !== null) {
|
|
54
|
+
return result;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return this.defaultMoneyConversion(amount);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Build payment requirements for this scheme/network combination.
|
|
61
|
+
*
|
|
62
|
+
* @param paymentRequirements - Base payment requirements with amount/asset already set
|
|
63
|
+
* @param supportedKind - The supported kind from facilitator
|
|
64
|
+
* @param extensionKeys - Extensions supported by the facilitator
|
|
65
|
+
* @returns Enhanced payment requirements
|
|
66
|
+
*/
|
|
67
|
+
async enhancePaymentRequirements(paymentRequirements, supportedKind, extensionKeys) {
|
|
68
|
+
void supportedKind;
|
|
69
|
+
void extensionKeys;
|
|
70
|
+
return {
|
|
71
|
+
...paymentRequirements,
|
|
72
|
+
payTo: paymentRequirements.payTo || this.config.payTo,
|
|
73
|
+
asset: paymentRequirements.asset || "BTC"
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Parse Money (string | number) to a decimal number.
|
|
78
|
+
*/
|
|
79
|
+
parseMoneyToDecimal(money) {
|
|
80
|
+
if (typeof money === "number") {
|
|
81
|
+
if (!Number.isFinite(money)) {
|
|
82
|
+
throw new Error(`Invalid money value: ${money}`);
|
|
83
|
+
}
|
|
84
|
+
return money;
|
|
85
|
+
}
|
|
86
|
+
const cleanMoney = money.replace(/^\$/, "").trim();
|
|
87
|
+
const amount = parseFloat(cleanMoney);
|
|
88
|
+
if (isNaN(amount)) {
|
|
89
|
+
throw new Error(`Invalid money format: ${money}`);
|
|
90
|
+
}
|
|
91
|
+
return amount;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Default money conversion: treat amount as satoshis.
|
|
95
|
+
* For direct satoshi amounts, the amount is used as-is.
|
|
96
|
+
*/
|
|
97
|
+
defaultMoneyConversion(amount) {
|
|
98
|
+
const sats = Math.floor(amount * SATS_PER_BTC);
|
|
99
|
+
return {
|
|
100
|
+
amount: sats.toString(),
|
|
101
|
+
asset: "BTC",
|
|
102
|
+
extra: {
|
|
103
|
+
symbol: "BTC",
|
|
104
|
+
decimals: 8
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
// src/exact/server/register.ts
|
|
111
|
+
function registerExactBtcScheme(server, config) {
|
|
112
|
+
const scheme = new ExactBtcScheme(config.schemeConfig);
|
|
113
|
+
if (config.networks && config.networks.length > 0) {
|
|
114
|
+
config.networks.forEach((network) => {
|
|
115
|
+
server.register(network, scheme);
|
|
116
|
+
});
|
|
117
|
+
} else {
|
|
118
|
+
server.register("bip122:*", scheme);
|
|
119
|
+
}
|
|
120
|
+
return server;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export {
|
|
124
|
+
ExactBtcScheme,
|
|
125
|
+
registerExactBtcScheme
|
|
126
|
+
};
|
|
127
|
+
//# sourceMappingURL=chunk-YJYTK2QQ.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/exact/server/scheme.ts","../../src/exact/server/register.ts"],"sourcesContent":["/**\n * Bitcoin On-chain Server Scheme Implementation\n *\n * Handles price parsing and payment requirement enhancement for\n * Bitcoin on-chain payments using the exact scheme.\n */\n\nimport type {\n AssetAmount,\n Network,\n PaymentRequirements,\n Price,\n SchemeNetworkServer,\n MoneyParser,\n} from '@t402/core/types'\nimport { SCHEME_EXACT, SATS_PER_BTC } from '../../constants.js'\n\n/**\n * Configuration options for ExactBtcScheme server\n */\nexport interface ExactBtcSchemeConfig {\n /**\n * The Bitcoin address to receive payments\n */\n payTo: string\n}\n\n/**\n * Bitcoin server implementation for the Exact payment scheme.\n * Handles price parsing and converts user-friendly amounts to satoshis.\n *\n * For Bitcoin, the asset is always \"BTC\" and amounts are in satoshis.\n */\nexport class ExactBtcScheme implements SchemeNetworkServer {\n readonly scheme = SCHEME_EXACT\n private moneyParsers: MoneyParser[] = []\n private config: ExactBtcSchemeConfig\n\n constructor(config: ExactBtcSchemeConfig) {\n this.config = config\n }\n\n /**\n * Register a custom money parser in the parser chain.\n *\n * @param parser - Custom function to convert amount to AssetAmount (or null to skip)\n * @returns The server instance for chaining\n */\n registerMoneyParser(parser: MoneyParser): ExactBtcScheme {\n this.moneyParsers.push(parser)\n return this\n }\n\n /**\n * Parses a price into an asset amount in satoshis.\n *\n * Accepts:\n * - Number: treated as USD, converted to satoshis at a default rate\n * - String with $: treated as USD\n * - AssetAmount: returned directly\n *\n * For Bitcoin, amounts are always in satoshis and the asset is \"BTC\".\n *\n * @param price - The price to parse\n * @param network - The network to use\n * @returns Promise that resolves to the parsed asset amount\n */\n async parsePrice(price: Price, network: Network): Promise<AssetAmount> {\n // If already an AssetAmount, return it directly\n if (typeof price === 'object' && price !== null && 'amount' in price) {\n if (!price.asset) {\n throw new Error(`Asset must be specified for AssetAmount on network ${network}`)\n }\n return {\n amount: price.amount,\n asset: price.asset,\n extra: price.extra || {},\n }\n }\n\n // Parse Money to decimal number\n const amount = this.parseMoneyToDecimal(price)\n\n // Try each custom money parser in order\n for (const parser of this.moneyParsers) {\n const result = await parser(amount, network)\n if (result !== null) {\n return result\n }\n }\n\n // Default: treat amount as satoshis directly\n return this.defaultMoneyConversion(amount)\n }\n\n /**\n * Build payment requirements for this scheme/network combination.\n *\n * @param paymentRequirements - Base payment requirements with amount/asset already set\n * @param supportedKind - The supported kind from facilitator\n * @param extensionKeys - Extensions supported by the facilitator\n * @returns Enhanced payment requirements\n */\n async enhancePaymentRequirements(\n paymentRequirements: PaymentRequirements,\n supportedKind: {\n t402Version: number\n scheme: string\n network: Network\n extra?: Record<string, unknown>\n },\n extensionKeys: string[],\n ): Promise<PaymentRequirements> {\n void supportedKind\n void extensionKeys\n\n return {\n ...paymentRequirements,\n payTo: paymentRequirements.payTo || this.config.payTo,\n asset: paymentRequirements.asset || 'BTC',\n }\n }\n\n /**\n * Parse Money (string | number) to a decimal number.\n */\n private parseMoneyToDecimal(money: string | number): number {\n if (typeof money === 'number') {\n if (!Number.isFinite(money)) {\n throw new Error(`Invalid money value: ${money}`)\n }\n return money\n }\n\n const cleanMoney = money.replace(/^\\$/, '').trim()\n const amount = parseFloat(cleanMoney)\n\n if (isNaN(amount)) {\n throw new Error(`Invalid money format: ${money}`)\n }\n\n return amount\n }\n\n /**\n * Default money conversion: treat amount as satoshis.\n * For direct satoshi amounts, the amount is used as-is.\n */\n private defaultMoneyConversion(amount: number): AssetAmount {\n // Amount is treated as satoshis directly\n const sats = Math.floor(amount * SATS_PER_BTC)\n\n return {\n amount: sats.toString(),\n asset: 'BTC',\n extra: {\n symbol: 'BTC',\n decimals: 8,\n },\n }\n }\n}\n","import { t402ResourceServer } from '@t402/core/server'\nimport { Network } from '@t402/core/types'\nimport { ExactBtcScheme, ExactBtcSchemeConfig } from './scheme.js'\n\n/**\n * Configuration options for registering BTC schemes to an t402ResourceServer\n */\nexport interface BtcResourceServerConfig {\n /**\n * Optional specific networks to register\n * If not provided, registers wildcard support (bip122:*)\n */\n networks?: Network[]\n\n /**\n * Scheme configuration (payTo address, etc.)\n */\n schemeConfig: ExactBtcSchemeConfig\n}\n\n/**\n * Registers Bitcoin exact payment schemes to an t402ResourceServer instance.\n *\n * @param server - The t402ResourceServer instance to register schemes to\n * @param config - Configuration for BTC resource server registration\n * @returns The server instance for chaining\n */\nexport function registerExactBtcScheme(\n server: t402ResourceServer,\n config: BtcResourceServerConfig,\n): t402ResourceServer {\n const scheme = new ExactBtcScheme(config.schemeConfig)\n\n if (config.networks && config.networks.length > 0) {\n config.networks.forEach((network) => {\n server.register(network, scheme)\n })\n } else {\n server.register('bip122:*', scheme)\n }\n\n return server\n}\n"],"mappings":";;;;;;;AAiCO,IAAM,iBAAN,MAAoD;AAAA,EAKzD,YAAY,QAA8B;AAJ1C,wBAAS,UAAS;AAClB,wBAAQ,gBAA8B,CAAC;AACvC,wBAAQ;AAGN,SAAK,SAAS;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,oBAAoB,QAAqC;AACvD,SAAK,aAAa,KAAK,MAAM;AAC7B,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,MAAM,WAAW,OAAc,SAAwC;AAErE,QAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,YAAY,OAAO;AACpE,UAAI,CAAC,MAAM,OAAO;AAChB,cAAM,IAAI,MAAM,sDAAsD,OAAO,EAAE;AAAA,MACjF;AACA,aAAO;AAAA,QACL,QAAQ,MAAM;AAAA,QACd,OAAO,MAAM;AAAA,QACb,OAAO,MAAM,SAAS,CAAC;AAAA,MACzB;AAAA,IACF;AAGA,UAAM,SAAS,KAAK,oBAAoB,KAAK;AAG7C,eAAW,UAAU,KAAK,cAAc;AACtC,YAAM,SAAS,MAAM,OAAO,QAAQ,OAAO;AAC3C,UAAI,WAAW,MAAM;AACnB,eAAO;AAAA,MACT;AAAA,IACF;AAGA,WAAO,KAAK,uBAAuB,MAAM;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,2BACJ,qBACA,eAMA,eAC8B;AAC9B,SAAK;AACL,SAAK;AAEL,WAAO;AAAA,MACL,GAAG;AAAA,MACH,OAAO,oBAAoB,SAAS,KAAK,OAAO;AAAA,MAChD,OAAO,oBAAoB,SAAS;AAAA,IACtC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,oBAAoB,OAAgC;AAC1D,QAAI,OAAO,UAAU,UAAU;AAC7B,UAAI,CAAC,OAAO,SAAS,KAAK,GAAG;AAC3B,cAAM,IAAI,MAAM,wBAAwB,KAAK,EAAE;AAAA,MACjD;AACA,aAAO;AAAA,IACT;AAEA,UAAM,aAAa,MAAM,QAAQ,OAAO,EAAE,EAAE,KAAK;AACjD,UAAM,SAAS,WAAW,UAAU;AAEpC,QAAI,MAAM,MAAM,GAAG;AACjB,YAAM,IAAI,MAAM,yBAAyB,KAAK,EAAE;AAAA,IAClD;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,uBAAuB,QAA6B;AAE1D,UAAM,OAAO,KAAK,MAAM,SAAS,YAAY;AAE7C,WAAO;AAAA,MACL,QAAQ,KAAK,SAAS;AAAA,MACtB,OAAO;AAAA,MACP,OAAO;AAAA,QACL,QAAQ;AAAA,QACR,UAAU;AAAA,MACZ;AAAA,IACF;AAAA,EACF;AACF;;;ACtIO,SAAS,uBACd,QACA,QACoB;AACpB,QAAM,SAAS,IAAI,eAAe,OAAO,YAAY;AAErD,MAAI,OAAO,YAAY,OAAO,SAAS,SAAS,GAAG;AACjD,WAAO,SAAS,QAAQ,CAAC,YAAY;AACnC,aAAO,SAAS,SAAS,MAAM;AAAA,IACjC,CAAC;AAAA,EACH,OAAO;AACL,WAAO,SAAS,YAAY,MAAM;AAAA,EACpC;AAEA,SAAO;AACT;","names":[]}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
|
+
|
|
5
|
+
// src/constants.ts
|
|
6
|
+
var BTC_MAINNET = "bip122:000000000019d6689c085ae165831e93";
|
|
7
|
+
var BTC_TESTNET = "bip122:000000000933ea01ad0ee984209779ba";
|
|
8
|
+
var LIGHTNING_MAINNET = "lightning:mainnet";
|
|
9
|
+
var LIGHTNING_TESTNET = "lightning:testnet";
|
|
10
|
+
var BTC_NETWORKS = [BTC_MAINNET, BTC_TESTNET];
|
|
11
|
+
var LIGHTNING_NETWORKS = [LIGHTNING_MAINNET, LIGHTNING_TESTNET];
|
|
12
|
+
var ALL_NETWORKS = [...BTC_NETWORKS, ...LIGHTNING_NETWORKS];
|
|
13
|
+
var DUST_LIMIT = 546;
|
|
14
|
+
var MIN_RELAY_FEE = 1e3;
|
|
15
|
+
var SATS_PER_BTC = 1e8;
|
|
16
|
+
var SCHEME_EXACT = "exact";
|
|
17
|
+
var DEFAULT_VALIDITY_DURATION = 3600;
|
|
18
|
+
var MAINNET_ADDRESS_PREFIXES = ["bc1", "1", "3"];
|
|
19
|
+
var TESTNET_ADDRESS_PREFIXES = ["tb1", "m", "n", "2"];
|
|
20
|
+
|
|
21
|
+
export {
|
|
22
|
+
__publicField,
|
|
23
|
+
BTC_MAINNET,
|
|
24
|
+
BTC_TESTNET,
|
|
25
|
+
LIGHTNING_MAINNET,
|
|
26
|
+
LIGHTNING_TESTNET,
|
|
27
|
+
BTC_NETWORKS,
|
|
28
|
+
LIGHTNING_NETWORKS,
|
|
29
|
+
ALL_NETWORKS,
|
|
30
|
+
DUST_LIMIT,
|
|
31
|
+
MIN_RELAY_FEE,
|
|
32
|
+
SATS_PER_BTC,
|
|
33
|
+
SCHEME_EXACT,
|
|
34
|
+
DEFAULT_VALIDITY_DURATION,
|
|
35
|
+
MAINNET_ADDRESS_PREFIXES,
|
|
36
|
+
TESTNET_ADDRESS_PREFIXES
|
|
37
|
+
};
|
|
38
|
+
//# sourceMappingURL=chunk-YWZC2RR7.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/constants.ts"],"sourcesContent":["/**\n * Bitcoin & Lightning Network Constants\n *\n * CAIP-2 network identifiers, dust limits, and fee constants.\n */\n\n/**\n * CAIP-2 Network Identifiers for Bitcoin\n * Uses BIP-122 chain genesis block hashes\n */\nexport const BTC_MAINNET = 'bip122:000000000019d6689c085ae165831e93'\nexport const BTC_TESTNET = 'bip122:000000000933ea01ad0ee984209779ba'\n\n/**\n * CAIP-2 Network Identifiers for Lightning Network\n */\nexport const LIGHTNING_MAINNET = 'lightning:mainnet'\nexport const LIGHTNING_TESTNET = 'lightning:testnet'\n\n/**\n * All supported BTC on-chain networks\n */\nexport const BTC_NETWORKS = [BTC_MAINNET, BTC_TESTNET] as const\n\n/**\n * All supported Lightning networks\n */\nexport const LIGHTNING_NETWORKS = [LIGHTNING_MAINNET, LIGHTNING_TESTNET] as const\n\n/**\n * All supported networks (on-chain + Lightning)\n */\nexport const ALL_NETWORKS = [...BTC_NETWORKS, ...LIGHTNING_NETWORKS] as const\n\nexport type BtcNetwork = (typeof BTC_NETWORKS)[number]\nexport type LightningNetwork = (typeof LIGHTNING_NETWORKS)[number]\n\n/**\n * Dust limit in satoshis - minimum viable output value\n * Outputs below this threshold are rejected by Bitcoin nodes\n */\nexport const DUST_LIMIT = 546\n\n/**\n * Minimum relay fee in satoshis\n * Transactions with fees below this are not relayed by default\n */\nexport const MIN_RELAY_FEE = 1000\n\n/**\n * Satoshis per BTC\n */\nexport const SATS_PER_BTC = 100_000_000\n\n/**\n * Scheme identifiers\n */\nexport const SCHEME_EXACT = 'exact'\n\n/**\n * Default timeout for payment validity (in seconds)\n */\nexport const DEFAULT_VALIDITY_DURATION = 3600 // 1 hour\n\n/**\n * Bitcoin address prefixes for basic validation\n */\nexport const MAINNET_ADDRESS_PREFIXES = ['bc1', '1', '3']\nexport const TESTNET_ADDRESS_PREFIXES = ['tb1', 'm', 'n', '2']\n"],"mappings":";;;;;AAUO,IAAM,cAAc;AACpB,IAAM,cAAc;AAKpB,IAAM,oBAAoB;AAC1B,IAAM,oBAAoB;AAK1B,IAAM,eAAe,CAAC,aAAa,WAAW;AAK9C,IAAM,qBAAqB,CAAC,mBAAmB,iBAAiB;AAKhE,IAAM,eAAe,CAAC,GAAG,cAAc,GAAG,kBAAkB;AAS5D,IAAM,aAAa;AAMnB,IAAM,gBAAgB;AAKtB,IAAM,eAAe;AAKrB,IAAM,eAAe;AAKrB,IAAM,4BAA4B;AAKlC,IAAM,2BAA2B,CAAC,OAAO,KAAK,GAAG;AACjD,IAAM,2BAA2B,CAAC,OAAO,KAAK,KAAK,GAAG;","names":[]}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import {
|
|
2
|
+
validateBitcoinAddress
|
|
3
|
+
} from "./chunk-MX3PAUPJ.mjs";
|
|
4
|
+
import {
|
|
5
|
+
BTC_NETWORKS,
|
|
6
|
+
DUST_LIMIT,
|
|
7
|
+
SCHEME_EXACT,
|
|
8
|
+
__publicField
|
|
9
|
+
} from "./chunk-YWZC2RR7.mjs";
|
|
10
|
+
|
|
11
|
+
// src/exact/facilitator/scheme.ts
|
|
12
|
+
var ExactBtcScheme = class {
|
|
13
|
+
constructor(signer) {
|
|
14
|
+
this.signer = signer;
|
|
15
|
+
__publicField(this, "scheme", SCHEME_EXACT);
|
|
16
|
+
__publicField(this, "caipFamily", "bip122:*");
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Get mechanism-specific extra data for the supported kinds endpoint.
|
|
20
|
+
* Bitcoin on-chain has no extra data.
|
|
21
|
+
*/
|
|
22
|
+
getExtra(_network) {
|
|
23
|
+
return void 0;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Get signer addresses used by this facilitator.
|
|
27
|
+
*/
|
|
28
|
+
getSigners(_network) {
|
|
29
|
+
return [...this.signer.getAddresses()];
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Verifies a payment payload.
|
|
33
|
+
*
|
|
34
|
+
* Validates:
|
|
35
|
+
* 1. Scheme and network matching
|
|
36
|
+
* 2. PSBT structure and signatures
|
|
37
|
+
* 3. Output matches (payTo, amount)
|
|
38
|
+
* 4. Amount above dust limit
|
|
39
|
+
*/
|
|
40
|
+
async verify(payload, requirements) {
|
|
41
|
+
const btcPayload = payload.payload;
|
|
42
|
+
if (!btcPayload?.signedPsbt) {
|
|
43
|
+
return {
|
|
44
|
+
isValid: false,
|
|
45
|
+
invalidReason: "invalid_payload_structure",
|
|
46
|
+
payer: void 0
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
if (payload.accepted.scheme !== SCHEME_EXACT || requirements.scheme !== SCHEME_EXACT) {
|
|
50
|
+
return {
|
|
51
|
+
isValid: false,
|
|
52
|
+
invalidReason: "unsupported_scheme",
|
|
53
|
+
payer: void 0
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
const validNetworks = BTC_NETWORKS;
|
|
57
|
+
if (!validNetworks.includes(requirements.network)) {
|
|
58
|
+
return {
|
|
59
|
+
isValid: false,
|
|
60
|
+
invalidReason: "unsupported_network",
|
|
61
|
+
payer: void 0
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
if (payload.accepted.network !== requirements.network) {
|
|
65
|
+
return {
|
|
66
|
+
isValid: false,
|
|
67
|
+
invalidReason: "network_mismatch",
|
|
68
|
+
payer: void 0
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
if (!validateBitcoinAddress(requirements.payTo)) {
|
|
72
|
+
return {
|
|
73
|
+
isValid: false,
|
|
74
|
+
invalidReason: "invalid_pay_to_address",
|
|
75
|
+
payer: void 0
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
if (BigInt(requirements.amount) < BigInt(DUST_LIMIT)) {
|
|
79
|
+
return {
|
|
80
|
+
isValid: false,
|
|
81
|
+
invalidReason: "amount_below_dust_limit",
|
|
82
|
+
payer: void 0
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
try {
|
|
86
|
+
const result = await this.signer.verifyPsbt({
|
|
87
|
+
signedPsbt: btcPayload.signedPsbt,
|
|
88
|
+
expectedPayTo: requirements.payTo,
|
|
89
|
+
expectedAmount: requirements.amount
|
|
90
|
+
});
|
|
91
|
+
if (!result.valid) {
|
|
92
|
+
return {
|
|
93
|
+
isValid: false,
|
|
94
|
+
invalidReason: result.reason || "psbt_verification_failed",
|
|
95
|
+
payer: result.payer
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
return {
|
|
99
|
+
isValid: true,
|
|
100
|
+
invalidReason: void 0,
|
|
101
|
+
payer: result.payer
|
|
102
|
+
};
|
|
103
|
+
} catch (error) {
|
|
104
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
105
|
+
return {
|
|
106
|
+
isValid: false,
|
|
107
|
+
invalidReason: `verification_error: ${errorMessage}`,
|
|
108
|
+
payer: void 0
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Settles a payment by finalizing and broadcasting the PSBT.
|
|
114
|
+
*/
|
|
115
|
+
async settle(payload, requirements) {
|
|
116
|
+
const btcPayload = payload.payload;
|
|
117
|
+
if (!btcPayload?.signedPsbt) {
|
|
118
|
+
return {
|
|
119
|
+
success: false,
|
|
120
|
+
network: payload.accepted.network,
|
|
121
|
+
transaction: "",
|
|
122
|
+
errorReason: "invalid_payload_structure",
|
|
123
|
+
payer: void 0
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
const verifyResult = await this.verify(payload, requirements);
|
|
127
|
+
if (!verifyResult.isValid) {
|
|
128
|
+
return {
|
|
129
|
+
success: false,
|
|
130
|
+
network: payload.accepted.network,
|
|
131
|
+
transaction: "",
|
|
132
|
+
errorReason: verifyResult.invalidReason ?? "verification_failed",
|
|
133
|
+
payer: verifyResult.payer
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
try {
|
|
137
|
+
const txId = await this.signer.broadcastPsbt(btcPayload.signedPsbt);
|
|
138
|
+
const confirmation = await this.signer.waitForConfirmation(txId, 1);
|
|
139
|
+
if (!confirmation.confirmed) {
|
|
140
|
+
return {
|
|
141
|
+
success: false,
|
|
142
|
+
errorReason: "transaction_not_confirmed",
|
|
143
|
+
transaction: txId,
|
|
144
|
+
network: payload.accepted.network,
|
|
145
|
+
payer: verifyResult.payer
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
return {
|
|
149
|
+
success: true,
|
|
150
|
+
transaction: txId,
|
|
151
|
+
network: payload.accepted.network,
|
|
152
|
+
payer: verifyResult.payer
|
|
153
|
+
};
|
|
154
|
+
} catch (error) {
|
|
155
|
+
console.error("Failed to settle Bitcoin transaction:", error);
|
|
156
|
+
return {
|
|
157
|
+
success: false,
|
|
158
|
+
errorReason: "transaction_failed",
|
|
159
|
+
transaction: "",
|
|
160
|
+
network: payload.accepted.network,
|
|
161
|
+
payer: verifyResult.payer
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
// src/exact/facilitator/register.ts
|
|
168
|
+
function registerExactBtcScheme(facilitator, config) {
|
|
169
|
+
facilitator.register(config.networks, new ExactBtcScheme(config.signer));
|
|
170
|
+
return facilitator;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export {
|
|
174
|
+
ExactBtcScheme,
|
|
175
|
+
registerExactBtcScheme
|
|
176
|
+
};
|
|
177
|
+
//# sourceMappingURL=chunk-ZOL5R3HZ.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/exact/facilitator/scheme.ts","../../src/exact/facilitator/register.ts"],"sourcesContent":["/**\n * Bitcoin On-chain Facilitator Scheme Implementation\n *\n * Verifies and settles Bitcoin on-chain payments using the exact scheme.\n * Validates signed PSBTs and broadcasts transactions to the Bitcoin network.\n */\n\nimport type {\n PaymentPayload,\n PaymentRequirements,\n SchemeNetworkFacilitator,\n SettleResponse,\n VerifyResponse,\n} from '@t402/core/types'\nimport type { BtcOnchainPayload } from '../../types.js'\nimport { SCHEME_EXACT, DUST_LIMIT, BTC_NETWORKS } from '../../constants.js'\nimport { validateBitcoinAddress } from '../../utils.js'\n\n/**\n * Facilitator BTC signer interface for verify and settle operations\n */\nexport interface FacilitatorBtcSigner {\n /**\n * Get all addresses this facilitator can use\n */\n getAddresses(): readonly string[]\n\n /**\n * Verify a signed PSBT\n * Checks that outputs match expected values and signatures are valid\n *\n * @param params - Verification parameters\n * @returns Verification result\n */\n verifyPsbt(params: {\n signedPsbt: string\n expectedPayTo: string\n expectedAmount: string\n }): Promise<{\n valid: boolean\n reason?: string\n payer?: string\n }>\n\n /**\n * Finalize and broadcast a signed PSBT\n *\n * @param signedPsbt - Base64-encoded signed PSBT\n * @returns Transaction ID\n */\n broadcastPsbt(signedPsbt: string): Promise<string>\n\n /**\n * Wait for a transaction to be confirmed\n *\n * @param txId - Transaction ID\n * @param confirmations - Number of confirmations to wait for\n * @returns Confirmation result\n */\n waitForConfirmation(\n txId: string,\n confirmations?: number,\n ): Promise<{\n confirmed: boolean\n txId: string\n blockHash?: string\n confirmations: number\n }>\n}\n\n/**\n * Bitcoin facilitator implementation for the Exact payment scheme.\n *\n * Verifies signed PSBTs and broadcasts transactions to settle payments.\n */\nexport class ExactBtcScheme implements SchemeNetworkFacilitator {\n readonly scheme = SCHEME_EXACT\n readonly caipFamily = 'bip122:*'\n\n constructor(private readonly signer: FacilitatorBtcSigner) {}\n\n /**\n * Get mechanism-specific extra data for the supported kinds endpoint.\n * Bitcoin on-chain has no extra data.\n */\n getExtra(_network: string): Record<string, unknown> | undefined {\n return undefined\n }\n\n /**\n * Get signer addresses used by this facilitator.\n */\n getSigners(_network: string): string[] {\n return [...this.signer.getAddresses()]\n }\n\n /**\n * Verifies a payment payload.\n *\n * Validates:\n * 1. Scheme and network matching\n * 2. PSBT structure and signatures\n * 3. Output matches (payTo, amount)\n * 4. Amount above dust limit\n */\n async verify(\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n ): Promise<VerifyResponse> {\n const btcPayload = payload.payload as BtcOnchainPayload | undefined\n\n // Validate payload structure\n if (!btcPayload?.signedPsbt) {\n return {\n isValid: false,\n invalidReason: 'invalid_payload_structure',\n payer: undefined,\n }\n }\n\n // Verify scheme matches\n if (payload.accepted.scheme !== SCHEME_EXACT || requirements.scheme !== SCHEME_EXACT) {\n return {\n isValid: false,\n invalidReason: 'unsupported_scheme',\n payer: undefined,\n }\n }\n\n // Verify network is a valid BTC network\n const validNetworks: readonly string[] = BTC_NETWORKS\n if (!validNetworks.includes(requirements.network)) {\n return {\n isValid: false,\n invalidReason: 'unsupported_network',\n payer: undefined,\n }\n }\n\n // Verify network matches\n if (payload.accepted.network !== requirements.network) {\n return {\n isValid: false,\n invalidReason: 'network_mismatch',\n payer: undefined,\n }\n }\n\n // Validate payTo address\n if (!validateBitcoinAddress(requirements.payTo)) {\n return {\n isValid: false,\n invalidReason: 'invalid_pay_to_address',\n payer: undefined,\n }\n }\n\n // Validate amount above dust limit\n if (BigInt(requirements.amount) < BigInt(DUST_LIMIT)) {\n return {\n isValid: false,\n invalidReason: 'amount_below_dust_limit',\n payer: undefined,\n }\n }\n\n // Verify the PSBT\n try {\n const result = await this.signer.verifyPsbt({\n signedPsbt: btcPayload.signedPsbt,\n expectedPayTo: requirements.payTo,\n expectedAmount: requirements.amount,\n })\n\n if (!result.valid) {\n return {\n isValid: false,\n invalidReason: result.reason || 'psbt_verification_failed',\n payer: result.payer,\n }\n }\n\n return {\n isValid: true,\n invalidReason: undefined,\n payer: result.payer,\n }\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error)\n return {\n isValid: false,\n invalidReason: `verification_error: ${errorMessage}`,\n payer: undefined,\n }\n }\n }\n\n /**\n * Settles a payment by finalizing and broadcasting the PSBT.\n */\n async settle(\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n ): Promise<SettleResponse> {\n const btcPayload = payload.payload as BtcOnchainPayload | undefined\n\n if (!btcPayload?.signedPsbt) {\n return {\n success: false,\n network: payload.accepted.network,\n transaction: '',\n errorReason: 'invalid_payload_structure',\n payer: undefined,\n }\n }\n\n // Re-verify before settling\n const verifyResult = await this.verify(payload, requirements)\n if (!verifyResult.isValid) {\n return {\n success: false,\n network: payload.accepted.network,\n transaction: '',\n errorReason: verifyResult.invalidReason ?? 'verification_failed',\n payer: verifyResult.payer,\n }\n }\n\n try {\n // Broadcast the signed transaction\n const txId = await this.signer.broadcastPsbt(btcPayload.signedPsbt)\n\n // Wait for at least 1 confirmation\n const confirmation = await this.signer.waitForConfirmation(txId, 1)\n\n if (!confirmation.confirmed) {\n return {\n success: false,\n errorReason: 'transaction_not_confirmed',\n transaction: txId,\n network: payload.accepted.network,\n payer: verifyResult.payer,\n }\n }\n\n return {\n success: true,\n transaction: txId,\n network: payload.accepted.network,\n payer: verifyResult.payer,\n }\n } catch (error) {\n console.error('Failed to settle Bitcoin transaction:', error)\n return {\n success: false,\n errorReason: 'transaction_failed',\n transaction: '',\n network: payload.accepted.network,\n payer: verifyResult.payer,\n }\n }\n }\n}\n","import { t402Facilitator } from '@t402/core/facilitator'\nimport { Network } from '@t402/core/types'\nimport { FacilitatorBtcSigner, ExactBtcScheme } from './scheme.js'\n\n/**\n * Configuration options for registering BTC schemes to an t402Facilitator\n */\nexport interface BtcFacilitatorConfig {\n /**\n * The Bitcoin signer for facilitator operations (verify and settle)\n */\n signer: FacilitatorBtcSigner\n\n /**\n * Networks to register (single network or array of networks)\n * Examples: \"bip122:000000000019d6689c085ae165831e93\"\n */\n networks: Network | Network[]\n}\n\n/**\n * Registers Bitcoin exact payment schemes to an t402Facilitator instance.\n *\n * @param facilitator - The t402Facilitator instance to register schemes to\n * @param config - Configuration for BTC facilitator registration\n * @returns The facilitator instance for chaining\n */\nexport function registerExactBtcScheme(\n facilitator: t402Facilitator,\n config: BtcFacilitatorConfig,\n): t402Facilitator {\n facilitator.register(config.networks, new ExactBtcScheme(config.signer))\n return facilitator\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { SchemeNetworkClient, PaymentRequirements, PaymentPayload, Network } from '@t402/core/types';
|
|
2
|
+
import { C as ClientBtcSigner } from '../../signer-B_Z4WGLa.mjs';
|
|
3
|
+
import { PaymentPolicy, t402Client } from '@t402/core/client';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Bitcoin On-chain Client Scheme Implementation
|
|
7
|
+
*
|
|
8
|
+
* Creates payment payloads for Bitcoin on-chain transfers using the exact scheme.
|
|
9
|
+
* Builds PSBTs (Partially Signed Bitcoin Transactions) and signs them with the client's wallet.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Bitcoin client implementation for the Exact payment scheme.
|
|
14
|
+
*
|
|
15
|
+
* Creates signed PSBTs for on-chain Bitcoin payments that can be
|
|
16
|
+
* finalized and broadcast by a facilitator.
|
|
17
|
+
*/
|
|
18
|
+
declare class ExactBtcScheme implements SchemeNetworkClient {
|
|
19
|
+
private readonly signer;
|
|
20
|
+
readonly scheme = "exact";
|
|
21
|
+
/**
|
|
22
|
+
* Creates a new ExactBtcScheme instance.
|
|
23
|
+
*
|
|
24
|
+
* @param signer - The Bitcoin signer for client operations
|
|
25
|
+
*/
|
|
26
|
+
constructor(signer: ClientBtcSigner);
|
|
27
|
+
/**
|
|
28
|
+
* Creates a payment payload for the Exact scheme.
|
|
29
|
+
*
|
|
30
|
+
* The payload contains a signed PSBT with a single output
|
|
31
|
+
* paying the required amount to the payTo address.
|
|
32
|
+
*
|
|
33
|
+
* @param t402Version - The t402 protocol version
|
|
34
|
+
* @param paymentRequirements - The payment requirements
|
|
35
|
+
* @returns Promise resolving to a payment payload
|
|
36
|
+
*/
|
|
37
|
+
createPaymentPayload(t402Version: number, paymentRequirements: PaymentRequirements): Promise<Pick<PaymentPayload, 't402Version' | 'payload'>>;
|
|
38
|
+
/**
|
|
39
|
+
* Build an unsigned PSBT for the payment.
|
|
40
|
+
*
|
|
41
|
+
* Creates a minimal PSBT representation with the required output.
|
|
42
|
+
* The actual UTXO selection and fee calculation should be handled
|
|
43
|
+
* by the signer implementation (which typically has wallet context).
|
|
44
|
+
*
|
|
45
|
+
* @param requirements - Payment requirements
|
|
46
|
+
* @returns Base64-encoded unsigned PSBT
|
|
47
|
+
*/
|
|
48
|
+
private buildUnsignedPsbt;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Configuration options for registering BTC schemes to an t402Client
|
|
53
|
+
*/
|
|
54
|
+
interface BtcClientConfig {
|
|
55
|
+
/**
|
|
56
|
+
* The Bitcoin signer to use for creating payment payloads
|
|
57
|
+
*/
|
|
58
|
+
signer: ClientBtcSigner;
|
|
59
|
+
/**
|
|
60
|
+
* Optional policies to apply to the client
|
|
61
|
+
*/
|
|
62
|
+
policies?: PaymentPolicy[];
|
|
63
|
+
/**
|
|
64
|
+
* Optional specific networks to register
|
|
65
|
+
* If not provided, registers wildcard support (bip122:*)
|
|
66
|
+
*/
|
|
67
|
+
networks?: Network[];
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Registers Bitcoin exact payment schemes to an t402Client instance.
|
|
71
|
+
*
|
|
72
|
+
* @param client - The t402Client instance to register schemes to
|
|
73
|
+
* @param config - Configuration for BTC client registration
|
|
74
|
+
* @returns The client instance for chaining
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* ```typescript
|
|
78
|
+
* import { registerExactBtcScheme } from "@t402/btc/exact/client";
|
|
79
|
+
* import { t402Client } from "@t402/core/client";
|
|
80
|
+
*
|
|
81
|
+
* const client = new t402Client();
|
|
82
|
+
* registerExactBtcScheme(client, {
|
|
83
|
+
* signer: myBtcSigner,
|
|
84
|
+
* });
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
declare function registerExactBtcScheme(client: t402Client, config: BtcClientConfig): t402Client;
|
|
88
|
+
|
|
89
|
+
export { type BtcClientConfig, ExactBtcScheme, registerExactBtcScheme };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ExactBtcScheme,
|
|
3
|
+
registerExactBtcScheme
|
|
4
|
+
} from "../../chunk-7IU3Z36R.mjs";
|
|
5
|
+
import "../../chunk-MX3PAUPJ.mjs";
|
|
6
|
+
import "../../chunk-YWZC2RR7.mjs";
|
|
7
|
+
export {
|
|
8
|
+
ExactBtcScheme,
|
|
9
|
+
registerExactBtcScheme
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { SchemeNetworkFacilitator, PaymentPayload, PaymentRequirements, VerifyResponse, SettleResponse, Network } from '@t402/core/types';
|
|
2
|
+
import { t402Facilitator } from '@t402/core/facilitator';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Bitcoin On-chain Facilitator Scheme Implementation
|
|
6
|
+
*
|
|
7
|
+
* Verifies and settles Bitcoin on-chain payments using the exact scheme.
|
|
8
|
+
* Validates signed PSBTs and broadcasts transactions to the Bitcoin network.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Facilitator BTC signer interface for verify and settle operations
|
|
13
|
+
*/
|
|
14
|
+
interface FacilitatorBtcSigner {
|
|
15
|
+
/**
|
|
16
|
+
* Get all addresses this facilitator can use
|
|
17
|
+
*/
|
|
18
|
+
getAddresses(): readonly string[];
|
|
19
|
+
/**
|
|
20
|
+
* Verify a signed PSBT
|
|
21
|
+
* Checks that outputs match expected values and signatures are valid
|
|
22
|
+
*
|
|
23
|
+
* @param params - Verification parameters
|
|
24
|
+
* @returns Verification result
|
|
25
|
+
*/
|
|
26
|
+
verifyPsbt(params: {
|
|
27
|
+
signedPsbt: string;
|
|
28
|
+
expectedPayTo: string;
|
|
29
|
+
expectedAmount: string;
|
|
30
|
+
}): Promise<{
|
|
31
|
+
valid: boolean;
|
|
32
|
+
reason?: string;
|
|
33
|
+
payer?: string;
|
|
34
|
+
}>;
|
|
35
|
+
/**
|
|
36
|
+
* Finalize and broadcast a signed PSBT
|
|
37
|
+
*
|
|
38
|
+
* @param signedPsbt - Base64-encoded signed PSBT
|
|
39
|
+
* @returns Transaction ID
|
|
40
|
+
*/
|
|
41
|
+
broadcastPsbt(signedPsbt: string): Promise<string>;
|
|
42
|
+
/**
|
|
43
|
+
* Wait for a transaction to be confirmed
|
|
44
|
+
*
|
|
45
|
+
* @param txId - Transaction ID
|
|
46
|
+
* @param confirmations - Number of confirmations to wait for
|
|
47
|
+
* @returns Confirmation result
|
|
48
|
+
*/
|
|
49
|
+
waitForConfirmation(txId: string, confirmations?: number): Promise<{
|
|
50
|
+
confirmed: boolean;
|
|
51
|
+
txId: string;
|
|
52
|
+
blockHash?: string;
|
|
53
|
+
confirmations: number;
|
|
54
|
+
}>;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Bitcoin facilitator implementation for the Exact payment scheme.
|
|
58
|
+
*
|
|
59
|
+
* Verifies signed PSBTs and broadcasts transactions to settle payments.
|
|
60
|
+
*/
|
|
61
|
+
declare class ExactBtcScheme implements SchemeNetworkFacilitator {
|
|
62
|
+
private readonly signer;
|
|
63
|
+
readonly scheme = "exact";
|
|
64
|
+
readonly caipFamily = "bip122:*";
|
|
65
|
+
constructor(signer: FacilitatorBtcSigner);
|
|
66
|
+
/**
|
|
67
|
+
* Get mechanism-specific extra data for the supported kinds endpoint.
|
|
68
|
+
* Bitcoin on-chain has no extra data.
|
|
69
|
+
*/
|
|
70
|
+
getExtra(_network: string): Record<string, unknown> | undefined;
|
|
71
|
+
/**
|
|
72
|
+
* Get signer addresses used by this facilitator.
|
|
73
|
+
*/
|
|
74
|
+
getSigners(_network: string): string[];
|
|
75
|
+
/**
|
|
76
|
+
* Verifies a payment payload.
|
|
77
|
+
*
|
|
78
|
+
* Validates:
|
|
79
|
+
* 1. Scheme and network matching
|
|
80
|
+
* 2. PSBT structure and signatures
|
|
81
|
+
* 3. Output matches (payTo, amount)
|
|
82
|
+
* 4. Amount above dust limit
|
|
83
|
+
*/
|
|
84
|
+
verify(payload: PaymentPayload, requirements: PaymentRequirements): Promise<VerifyResponse>;
|
|
85
|
+
/**
|
|
86
|
+
* Settles a payment by finalizing and broadcasting the PSBT.
|
|
87
|
+
*/
|
|
88
|
+
settle(payload: PaymentPayload, requirements: PaymentRequirements): Promise<SettleResponse>;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Configuration options for registering BTC schemes to an t402Facilitator
|
|
93
|
+
*/
|
|
94
|
+
interface BtcFacilitatorConfig {
|
|
95
|
+
/**
|
|
96
|
+
* The Bitcoin signer for facilitator operations (verify and settle)
|
|
97
|
+
*/
|
|
98
|
+
signer: FacilitatorBtcSigner;
|
|
99
|
+
/**
|
|
100
|
+
* Networks to register (single network or array of networks)
|
|
101
|
+
* Examples: "bip122:000000000019d6689c085ae165831e93"
|
|
102
|
+
*/
|
|
103
|
+
networks: Network | Network[];
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Registers Bitcoin exact payment schemes to an t402Facilitator instance.
|
|
107
|
+
*
|
|
108
|
+
* @param facilitator - The t402Facilitator instance to register schemes to
|
|
109
|
+
* @param config - Configuration for BTC facilitator registration
|
|
110
|
+
* @returns The facilitator instance for chaining
|
|
111
|
+
*/
|
|
112
|
+
declare function registerExactBtcScheme(facilitator: t402Facilitator, config: BtcFacilitatorConfig): t402Facilitator;
|
|
113
|
+
|
|
114
|
+
export { type BtcFacilitatorConfig, ExactBtcScheme, type FacilitatorBtcSigner, registerExactBtcScheme };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ExactBtcScheme,
|
|
3
|
+
registerExactBtcScheme
|
|
4
|
+
} from "../../chunk-ZOL5R3HZ.mjs";
|
|
5
|
+
import "../../chunk-MX3PAUPJ.mjs";
|
|
6
|
+
import "../../chunk-YWZC2RR7.mjs";
|
|
7
|
+
export {
|
|
8
|
+
ExactBtcScheme,
|
|
9
|
+
registerExactBtcScheme
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|