@bit-gpt/h402
Version:
BitGPT's 402 open protocol for blockchain-native payments
99 lines • 3.87 kB
JavaScript
import { signResourceMessage, signAndSendTransaction, signTransaction, signAuthorization, utils, } from "./index.js";
import { evm } from "../../../shared/index.js";
const TRANSFER_WITH_AUTHORIZATION_ABI = [
{
type: "function",
name: "transferWithAuthorization",
inputs: [...evm.authorizationTypes.TransferWithAuthorization],
outputs: [],
stateMutability: "nonpayable",
},
];
async function _createPayment(client, h402Version, paymentRequirements) {
if (!client?.account?.address) {
throw new Error("Client account is required");
}
const from = client.account.address;
const to = paymentRequirements.payToAddress;
const value = paymentRequirements.amountRequired;
const basePayment = {
h402Version: h402Version,
scheme: paymentRequirements.scheme,
namespace: paymentRequirements.namespace,
networkId: paymentRequirements.networkId,
resource: paymentRequirements.resource,
};
// First try to sign authorization without broadcasting (ERC-3009)
const hasTransferWithAuthorization = await client
.readContract({
address: paymentRequirements.tokenAddress,
abi: TRANSFER_WITH_AUTHORIZATION_ABI,
functionName: "transferWithAuthorization",
})
.then(() => true)
.catch(() => false);
const resourceSignature = await signResourceMessage(client, from, paymentRequirements.resource);
try {
if (!hasTransferWithAuthorization) {
throw new Error("ERC-3009 not supported");
}
const authorizationResult = await signAuthorization(client, { from, to, value }, paymentRequirements);
return {
...basePayment,
payload: {
type: "authorization",
signature: authorizationResult.signature,
authorization: {
from,
to,
value,
validAfter: authorizationResult.validAfter,
validBefore: authorizationResult.validBefore,
nonce: authorizationResult.nonce,
version: authorizationResult.version,
},
},
};
}
catch {
try {
console.log("[Create Payment] SIGN TRANSACTION");
// Try to sign transaction without broadcasting
const result = await signTransaction(client, { from, to, value }, paymentRequirements);
return {
...basePayment,
payload: {
type: "signedTransaction",
signedTransaction: result.signedTransaction,
signedMessage: resourceSignature,
},
};
}
catch {
console.log("[Create Payment] SIGN AND SEND TRANSACTION");
const result = await signAndSendTransaction(client, { from, to, value }, paymentRequirements);
return {
...basePayment,
payload: {
type: "signAndSendTransaction",
signedMessage: resourceSignature,
transactionHash: result.txHash,
},
};
}
}
}
async function createPayment(client, h402Version, paymentRequirements) {
// Set defaults
let paymentRequirementsWithDefaults = paymentRequirements;
if (!paymentRequirements.resource) {
paymentRequirementsWithDefaults.resource = `402 signature ${Date.now()}`;
}
if (!paymentRequirements.scheme) {
paymentRequirementsWithDefaults.scheme = `exact`;
}
const payment = await _createPayment(client, h402Version, paymentRequirementsWithDefaults);
return utils.encodePaymentPayload(payment);
}
export { createPayment };
//# sourceMappingURL=client.js.map