跳到主要内容

DeBox Shares 协议

DeBox Shares 简介

什么是 DeBox Shares?

DeBox Shares 协议是 DeBox 为开发者、KOL 和用户提供服务的赋能工具。它是一套由 DeBox 定义的 API,开发者可以利用这些 API 进行定制化服务,为用户和平台创造价值。

在 DeBox 平台上,群主、群成员以及开发者都可以通过 Shares 协议获利。该协议通过将 DeBox 平台的部分收入分配给用户的方式,激励更多的用户参与分享、推广和使用小程序。

开发者可以基于 DeBox SDK 开发小程序,并通过收入分成等方式,鼓励 DeBox 用户使用、推广和分享这些小程序。当用户通过成员的分享链接打开小程序时,用户在程序中的消费收入的一部分将按照一定比例分配给分享人、DAO 资产以及群主等,形成一个良性循环的收益模式。

Shares 支持哪些参与方式?

  1. 支持 vBOX 支付:直接调用 DeBox-Shares 的 vBOX 支付接口即可;
  2. 支持链上 Token 支付:调用 DeBox-Shares 合约,略微调整 DAPP 的付款处合约代码即可;
  3. 支持多种网络:目前已支持 ETH, Arbitrum, Base, BSC, OP, Polygon 网络资产(不断更新中)。

如何接入 Shares?

1. vBOX 支付接入 Shares

  • vBOX 支付过程包含两个主要步骤:连接钱包并获取授权、调用支付 API 完成支付。支付完毕后可以查看支付详细信息。以下是详细步骤和使用方法:

1.1 连接钱包并请求授权

  • DAPP 可以通过 DeBox Wallet SDK 连接用户钱包并获取所需用户信息。

    DeBox Wallet SDK 是 DAPP 与 DeBox 钱包进行连接和交互的工具。当用户通过 DeBox 客户端打开网页时,DeBox 会自动在网页中注入 window.deboxWallet 对象(也可以通过别名 window.ethereum 访问)。DAPP 可以通过此对象检测 DeBox 钱包是否已经安装,并调用相应的 API 方法进行操作。

  • 以下方法可用于此过程:

eth_requestAccounts:该方法请求用户钱包授权连接。

  • 常用的钱包方法,DeBox对此进行了扩展
  • 在内部,该方法调用 debox_getUserInfo 方法请求用户信息权限 。
  • 此方法会弹出一个窗口,要求用户授权连接 DAPP 并获取钱包地址。

请求:

await window.deboxWallet.request({
"method": "eth_requestAccounts",
"params": [],
});

参数:

响应:

  • 成功时返回用户钱包地址。
[
"0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"
]

wallet_requestPermissions:该方法用于请求用户批准 DAPP 某些访问权限

  • 需要先请求用户授权的方法有: debox_getUserInfo(获取用户公开信息), debox_getVBoxBalance(获取用户钱包 vBOX 余额)
  1. 权限请求信息参数为空。此时默认会请求用户批准 debox_getUserInfo 方法权限

    请求:

    await window.deboxWallet.request({
    "method": "wallet_requestPermissions",
    "params": [{
    eth_accounts: {}
    }],
    });

    参数:

    • eth_accounts :其值为空对象 {},表示请求默认权限(即 debox_getUserInfo

    响应:

    • 成功时返回:
    [
    {
    "parentCapability": "eth_accounts",
    "invoker": "https://connect-nu-one.vercel.app/",
    "caveats": [
    {
    "type": "restrictReturnedAccounts",
    "value": [
    "0xa56b4f0c7622bd076c2ba48b17d1e8d3fbf5303e"
    ]
    },
    {
    "type": "debox_getUserInfo",
    "value": {
    "uid":"jkdi123",
    "address":"0xa56b4f0c7622bd076c2ba48b17d1e8d3fbf5303e",
    "name":"张三",
    "avatar":"https://debox......png"
    }
    },
    ],
    "date": 1728348403194
    },
    ]
  2. 权限请求信息带有参数。此时会请求用户批准开发者所指定方法的权限:

    请求:

    await window.deboxWallet.request({
    "method": "wallet_requestPermissions",
    "params": [{
    eth_accounts: {
    "debox_getUserInfo": {},
    "debox_getVBoxBalance": {}
    }
    }],
    });

    参数:

    • eth_accounts属性,属性值为一个对象,里面指定了两个权限:
      • "debox_getUserInfo": 请求获取用户信息(如头像、昵称等)的权限,值为空对象 {}
      • "debox_getVBoxBalance": 请求获取用户 vBOX 余额的权限,值为空对象 {}

    响应:

    • 成功时返回:
    [
    {
    "id": "QbOgSTaFmS3UK1qS6pese",
    "parentCapability": "eth_accounts",
    "invoker": "https://connect-nu-one.vercel.app/",
    "caveats": [
    {
    "type": "restrictReturnedAccounts",
    "value": [
    "0xa56b4f0c7622bd076c2ba48b17d1e8d3fbf5303e"
    ]
    },
    {
    "type": "debox_getUserInfo",
    "value": {
    "uid":"jkdi123",
    "address":"0xa56b4f0c7622bd076c2ba48b17d1e8d3fbf5303e",
    "name":"张三",
    "avatar":"https://debox......png"
    }
    },
    {
    "type": "debox_getVBoxBalance",
    "value": {
    "usable_balance": 0.12
    }
    },
    ],
    "date": 1728348403194
    },
    ]

debox_getUserInfo:该方法获取用户的公开信息,如用户 ID、钱包地址、昵称和头像。

  • 前提条件: 已通过wallet_requestPermissions 请求用户批准 debox_getUserInfo 访问权限,否则拒绝服务
  • 如果用户没有授权 debox_getUserInfo 访问,则弹出授权确认框,用户允许后再返回信息或者拒绝服务。

请求

await window.deboxWallet.request({
"method": "debox_getUserInfo",
"params": [],
});

参数

响应

  • 如果用户已授权访问,成功时返回用户的基本信息(ID、地址、昵称、头像)。
{
"address":"0xa56b4f0c7622bd076c2ba48b17d1e8d3fbf5303e",
"name":"张三",
"avatar":"https://debox......png",
"uid":"jkdi123"
}

debox_getVBoxBalance :该方法获取用户的 vBOX 余额

  • 前提条件: 已通过wallet_requestPermissions 请求用户批准 debox_getVBoxBalance 访问权限,否则拒绝服务

请求

await window.deboxWallet.request({
"method": "debox_getVBoxBalance",
"params": [],
});
  • 返回用户的可用 vBOX 余额(需用户授权)。

参数

响应

  • 成功时返回用户的可用 vBOX 余额,如果用户已授权访问。
{
"usable_balance": 0.12
}
错误代码
  1. 用户没有授权该方法调用时
{
"code": 4100,
"message": "The requested account and/or method has not been authorized by the user."
}
  1. 用户拒绝了请求时
{
"code": 4001,
"message": "User rejected the request."
}

1.2 调用 vBOX 支付 API

  • 在用户授权后,Dapp 前端可以调用 debox_paymentVBox 方法进行支付。
  • 以下方法可用于此过程:

debox_paymentVBox:该方法进行 vBOX 支付,可指定收款地址、支付金额、支付备注和分佣金额。

  • 前提条件: 已通过wallet_requestPermissions 请求用户批准 debox_getUserInfo 访问权限,否则拒绝服务

请求

await window.deboxWallet.request({
"method": "debox_paymentVBox",
"params": [{
"receiver_address": "0x4c7d41C915a12BCe634d619144941a51FA83DfF5",
"amount": 100,// 支付的 vBox 数量,最小值为 0.01
"nonce": 12893019283,
"note": "购买道具",
"donation_amount": 40
}],
});
  • 用户可以输入收款地址、支付金额、备注以及分佣金额,API 会返回交易结果,如订单 ID 或支付状态。

参数

  • receiver_address:收款人钱包地址(如果地址不存在或无效,会导致支付失败)。
  • amount:支付的 vBOX 数量,最小值为 0.01。
  • nonce: Int64, 可选,如果为空则由DeBox客户端使用当前时间戳生成。这是一个防止同一笔支付多次消费的防重编码。
  • note:支付备注信息,最长不超过 100 个字符。
  • donation_amount:分配给 DeBox 平台进行分佣的金额,不能超过 amount 值。

响应

  • order_id : 本次支付的订单ID
{
"order_id": "0xd85554eb6e2ab48dd36209eb8db65d1fa540621c3679c7388f469ff314a194a8"
}

错误代码

  1. 用户没有授权该方法调用时
{
"code": 4100,
"message": "The requested account and/or method has not been authorized by the user."
}
  1. 用户拒绝了请求时
{
"code": 4001,
"message": "User rejected the request."
}
注意
  • 收款地址 receiver_address 须要是DeBox用户的地址。否则支付失败,提示“不合法的参数”
  • 收款地址 receiver_address 不可与付款地址相同。否则支付失败,提示“系统繁忙,请稍后再试”

1.3 查询支付结果

  • 在调用 debox_paymentVBox 支付后,Dapp 可以检查回执的真实性:
  • 以下方法可用于此过程:

GET https://open.debox.pro/openapi/payment/receipt :该接口用于查看支付结果的详细信息

接口端点https://open.debox.pro/openapi/payment/receipt

请求方法GET

请求示例

curl 
https://open.debox.pro/openapi/payment/receipt?order_id=0x0aabbccxx

参数

Header

  • X-API-KEY : String
    • 开发者 key,在开放平台可以获取;
    • 少量查询时可以不使用。大量发起请求时,添加该请求头以避免限流。

Query:

  • order_id : String
    • 支付的订单ID

响应

  • 成功时返回:
{
"code": 1,
"data": {
"order_id": "0x0aabbccxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"receiver_id": "okqwerty",
"payer_id": "0cqwerte",
"amount": "0.02",
"fee": "0.01",
"invoker_note": "buy a cup of coffee"
},
"message": "success",
"success": true
}
  • 失败时返回:
{
"code":-4018,
"data":{
"amount":"0",
"fee":"0"
},
"message":"Record not found",
"success":false
}

1.4 部署、交互示例:

https://connect-nu-one.vercel.app/ (在DeBox中打开)

vBOX Shares Example

点击各个按钮调用对应方法,在右下角 ”vConsole” 中即可观察到执行结果。

示例代码:

// test the availability of deboxWallet
if (typeof window.deboxWallet !== "undefined") {
window.ethersProvider = new ethers.providers.Web3Provider(
window.deboxWallet
);
console.log("deboxWallet is available");
} else {
console.error("deboxWallet is not installed!");
}
console.log(
"window.ethersProvider ethers provider:",
window.ethersProvider
);

// eth_requestAccounts
async function connectWallet() {
console.log("window.deboxWallet", window.deboxWallet);
if (typeof window.deboxWallet !== "undefined") {
// connectButton.addEventListener("click", async () => {
try {
// Request account access if needed
const accounts = await window.deboxWallet.request({
method: "eth_requestAccounts",
});

console.log("eth_requestAccounts: ", accounts, typeof accounts);

// Display the connected wallet address
walletAddress.innerText = `Connected Wallet: ${accounts[0].slice(
0,
6
)}...${accounts[0].slice(-4)}`;
errorMessage.innerText = "";

requestPermissions();
} catch (error) {
// Handle error (e.g., user denied account access)
errorMessage.innerText =
"Error connecting wallet: " + error.message;
}
} else {
// If no wallet is installed
errorMessage.innerText =
"No Ethereum wallet found. Please install DeBoxWallet.";
}
}

// wallet_requestPermissions
async function requestPermissions() {
console.log("testSDK run wallet_requestPermissions");
if (typeof window.deboxWallet !== "undefined") {
try {
window.deboxWallet
.request({
method: "wallet_requestPermissions",
params: [
{
eth_accounts: {},
},
],
})
.then((response) => {
console.log(
"wallet_requestPermissions: ",
response,
typeof response
);
});
} catch (error) {
console.error(error);
alert(error.message);
}
} else {
// If no wallet is installed
errorMessage.innerText =
"No Ethereum wallet found. Please install DeBoxWallet.";
}
}

// requestPermissionsParams
async function requestPermissionsParams() {
console.log("testSDK run wallet_requestPermissions");
if (typeof window.deboxWallet !== "undefined") {
try {
window.deboxWallet
.request({
method: "wallet_requestPermissions",
params: [
{
eth_accounts: {
debox_getUserInfo: {},
debox_getVBoxBalance: {},
},
},
],
})
.then((response) => {
console.log(
"wallet_requestPermissions_params: ",
response,
typeof response
);
const item = response[0]; // []
const deboxUserInfo = item.caveats.find(
(caveat) => caveat.type === "debox_user_public_info"
);

if (deboxUserInfo) {
const avatar = deboxUserInfo
? deboxUserInfo.value.avatar
: null;
const name = deboxUserInfo ? deboxUserInfo.value.name : null;
const address = deboxUserInfo
? deboxUserInfo.value.address
: null;
const uid = deboxUserInfo ? deboxUserInfo.value.uid : null;

console.log(
"wallet_requestPermissions_params data",
response?.[0]?.caveats?.[1]
);

const imgElement = document.getElementById("walletAvatar");
imgElement.src = avatar;

walletNickName.innerText = `NickName: ${name}`;
walletAddress.innerText = `Connected Wallet: ${address?.slice(
0,
6
)}...${address?.slice(-4)}`;
walletUid.innerText = `uid: ${uid}`;
errorMessage.innerText = "";
}
});
} catch (error) {
console.error(error);
alert(error.message);
}
} else {
// If no wallet is installed
errorMessage.innerText =
"No Ethereum wallet found. Please install DeBoxWallet.";
}
}

// debox_getUserInfo
async function getUserInfo() {
console.log("testSDK run debox_getUserInfo");

window.deboxWallet
.request({
method: "debox_getUserInfo",
params: [],
})
.then((response) => {
console.log("debox_getUserInfo", response, typeof response);
if (response) {
const imgElement = document.getElementById("walletAvatarUser");
imgElement.src = response?.avatar;
walletNickNameUser.innerText = `NickName: ${response?.name}`;
walletAddressUser.innerText = `Connected Wallet: ${response?.address?.slice(
0,
6
)}...${response?.address?.slice(-4)}`;
walletUidUser.innerText = `uid: ${response?.uid}`;

errorMessage.innerText = "";
}
})
.catch((error) => {
console.error(error);
alert(error.message);
});
}

// debox_getVBoxBalance
async function getVBoxBalance() {
console.log("testSDK run debox_getVBoxBalance");

window.deboxWallet
.request({
method: "debox_getVBoxBalance",
params: [],
})
.then((response) => {
console.log("debox_getVBoxBalance", response, typeof response);
walletAddressBalance.innerText = `vBOX: ${response?.usable_balance}`;
})
.catch((error) => {
console.error(error);
alert(error.message);
});
}

// debox_paymentVBox
async function paymentVBox() {
console.log("testSDK run debox_paymentVBox");

if (typeof window.deboxWallet !== "undefined") {
const walletUid = document.getElementById("walletUid");
const addressInput = document.getElementById("addressInput");
const amountInput = document.getElementById("amountInput");
const donationAmountInput = document.getElementById(
"donationAmountInput"
);
const noteInput = document.getElementById("noteInput");

let receiver_address = addressInput.value;
let amount = amountInput.value;
let donation_amount = donationAmountInput.value;
let note = noteInput.value;

console.log(walletUid.innerText, amount, donation_amount, note);

if (!receiver_address) {
alert("Please enter receiver");
return;
}
window.deboxWallet
.request({
method: "debox_paymentVBox",
params: [
{
receiver_address: receiver_address, // address of the receiver
amount: amount || 0.01, // amount of payment, minimum 0.01
// nonce: 0, // integer, optional
note: note || "buy a cup of coffee in the game",
donation_amount: donation_amount || 40,
},
],
})
.then((response) => {
console.log("debox_paymentVBox", response, typeof response);
orderIdShow.innerText = `${response?.order_id}`;
})
.catch((error) => {
console.error(error);
alert(error.message);
});
} else {
errorMessage.innerText =
"No Ethereum wallet found. Please install DeBoxWallet.";
}
}

2. 链上支付接入 Shares

链上 Shares 是一种实时的分佣方式。当用户使用 Token 进行支付时,部分支付金额会被自动捐赠给 DeBox Shares 协议进行分佣,完成收益分配。

开发者只需微调 Dapp 支付部分逻辑,即可快速实现高度定制化的链上支付分佣功能。

2.1 链上支付分佣的调用过程

链上支付的分佣有两类:链上原生代币(ETH)支付分佣;ERC20代币支付分佣:

2.1.1 链上原生代币(ETH)支付分佣

链上原生代币(ETH)支付分佣分两步:计算分佣金额;调用合约的捐赠函数以触发后续处理。

  1. 计算分佣金额

    • Dapp 根据业务设计,计算通过 DeBox Shares 分配的分佣金额额。
  2. 调用 donationToShares方法,同时附加分佣金额,触发后续分佣逻辑:

    • Dapp 在完成分佣金额计算后,调用 DeBox Shares 合约的 donationToShares 方法,将计算好的金额正式进行分佣。
    // ...
    uint256 donatedAmountETH = amountAcquiredETH / 10; // 计算分佣金额
    doxShares.donationToShares{ value: donatedAmountETH }(); // 触发后续分佣逻辑
    // ...
  3. 示例合约逻辑

  • Dapp 合约集成 Shares 协议示例:

    // SPDX-License-Identifier: Apache License 2.0
    pragma solidity ^0.8.22;

    import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
    import { IDeBoxShares } from "@debox/deboxdapp/interfaces/facets/IShares.sol";
    import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

    contract PlayGameWithShares {
    IDeBoxShares public doxShares;
    event GamePlayed(address player, IERC20 token, uint256 amount);
    constructor(IDeBoxShares _doxShares) {
    doxShares = _doxShares;
    }

    // Dapp中,集成了Shares协议的ETH支付函数
    function playGameWithETH() external payable {
    uint256 amount = msg.value;
    uint256 donatedAmount = amount / 10;
    if (donatedAmount > 0) {
    doxShares.donationToShares{ value: donatedAmount }();
    }
    emit GamePlayed(msg.sender, IERC20(address(0)), amount);
    }
    }

2.1.2 ERC20代币支付分佣

ERC20代币支付分佣分两步:计算分佣金额并授权 DeBox Shares 合约;调用合约的捐赠函数以触发后续处理。

  1. 计算分佣金额,将权限授予 DeBox-Shares 合约

    • 首先,Dapp将用户支付的代币转入Dapp合约,并根据业务设计,计算通过 DeBox Shares 分配的分佣金额。
    • 然后,合约调用 safeIncreaseAllowance 方法,将分佣金额的使用权限授予 DeBox Shares 合约地址。
    // ...
    SafeERC20.safeTransferFrom(token, msg.sender, address(this), amount); // 将用户支付的代币转入 Dapp 合约
    uint256 donatedAmount = amountAcquired / 10; // 计算通过 DeBox Shares 分配的分佣金额
    SafeERC20.safeIncreaseAllowance(token, address(doxShares), donatedAmount); // 将分佣金额的使用权限授予 DeBox Shares 合约
    // ...
  2. 调用 donationToShares 方法,触发后续分佣逻辑

    • 合约授予分佣金额使用权后,调用 DeBox Shares 合约的 donationToShares 方法,将计算好的金额正式进行分佣。
    • 该方法会触发 DeBox Shares 协议的后续处理逻辑,将分佣金额转入 DAO 资产池或分配给受益方等。
    // ...
    // 上述的计算分佣金额、授予权限逻辑
    // ...
    doxShares.donationToShares(token, donatedAmount); // 触发后续分佣逻辑
    // ...
  3. 示例合约逻辑

  • Dapp 合约集成 Shares 协议示例:

    // SPDX-License-Identifier: Apache License 2.0
    pragma solidity ^0.8.22;

    import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
    import { IDeBoxShares } from "@debox/deboxdapp/interfaces/facets/IShares.sol";
    import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

    contract PlayGameWithShares {
    IDeBoxShares public doxShares;
    event GamePlayed(address player, IERC20 token, uint256 amount);
    constructor(IDeBoxShares _doxShares) {
    doxShares = _doxShares;
    }

    // Dapp中的集成了Shares协议的ERC20代币支付函数
    function playGame(IERC20 token, uint256 amount) external {
    SafeERC20.safeTransferFrom(token, msg.sender, address(this), amount);

    uint256 donatedAmount = amount / 10;
    if (donatedAmount > 0) {
    SafeERC20.safeIncreaseAllowance(token, address(doxShares), donatedAmount);
    doxShares.donationToShares(address(token), donatedAmount);
    }
    emit GamePlayed(msg.sender, token, amount);
    }

2.2 Shares 合约接口:

  • DeBox-shares 合约接口:

    // SPDX-License-Identifier: Apache License 2.0
    pragma solidity ^0.8.22;

    interface IDeBoxShares {
    event DonationToShares(address indexed contributor, address indexed token, uint256 amount);
    event SharesConfigSet(address vault, address weth);

    /**
    * @notice Donate tokens to the shares protocol.
    * @dev The donated tokens will be transferred to the vault.
    * before the donation, the caller must approve me to spend the token.
    * @param token The token to donate. must be a valid ERC20 token.
    * @param amount The amount of `token` to donate. must be greater than 0.
    */
    function donationToShares(address token, uint256 amount) external;

    /**
    * @notice Donate Native coin (ETH) to the shares protocol.
    */
    function donationToShares() external payable;
    function getSharesConfig() external view returns (address vault, address weth);
    }

2.3 DeBox-Shares 合约部署地址:

NetworkContract Address
Ethereum0x2e6168f9ca3fe204a2110c4613ce18985f3fbf39
Arbitrum One0x509Ca4ff42cECAA1FF4988514211b26e72BDa840
Base0x2f8Ae1cC4ab784f7b9E07A61F714ecDe18A4A6d2
BSC0x32303FFcb9B6564C2b8a373433A043a7f17E4B37
Optimism0x18574E5a838B3FE16948653873386DD114ba1D7C
Polygon0xb8Af0Fa3E38E8Cb95870091b0d4e32CA232b780D

2.4 简化的链上分佣接口

对于没有复杂业务逻辑的 Dapp,DeBox 提供了简化的链上分佣接口,支持链上原生代币支付和 ERC20 代币支付过程的分佣。

支持方法:
  1. payAndShareWithETH: 该方法用于 ETH 支付过程的分佣

    • 合约方法:
    /**
    * @notice 使用 ETH 支付并分佣,可指定收款地址和分佣金额。
    * @param recipient 接收 ETH 支付的目标地址。
    * @param shareAmount 在 ETH 支付总额中,用于 Shares 分佣的 ETH 量。
    */
    function payAndShareWithETH(address payable recipient, uint256 shareAmount) external payable;
    • 合约方法调用示例:
    contract Example {
    function examplePayAndShare(address payable recipient) external payable {
    // 假设支付 1 ETH,其中分佣 0.2 ETH
    payAndShareWithETH{value: 1 ether}(recipient, 0.2 ether);
    // 交易后,recipient 收到 0.8 ETH,0.2ETH 通过 Shares 协议完成分佣
    }
    }
    • ABI 接口定义:
    [
    {
    "type": "function",
    "name": "payAndShareWithETH",
    "inputs": [
    {
    "name": "recipient",
    "type": "address",
    "internalType": "address payable"
    },
    {
    "name": "shareAmount",
    "type": "uint256",
    "internalType": "uint256"
    }
    ],
    "outputs": [],
    "stateMutability": "payable"
    }
    ]
    • ABI 调用示例(基于 ethers.js)
    const { ethers } = require("ethers");

    // 假设合约地址和 ABI
    const contractAddress = "SimplifiedSharesContractDeploymentAddress";
    const abi = [
    {
    "type": "function",
    "name": "payAndShareWithETH",
    "inputs": [
    { "name": "recipient", "type": "address" },
    { "name": "shareAmount", "type": "uint256" }
    ],
    "outputs": [],
    "stateMutability": "payable"
    }
    ];

    // 设置 Provider 和 Signer
    const provider = new ethers.providers.JsonRpcProvider("https://your-rpc-url");
    const signer = provider.getSigner();
    const contract = new ethers.Contract(contractAddress, abi, signer);

    // 调用方法
    async function callPayAndShare() {
    const recipient = "0xRecipientAddress";
    const shareAmount = ethers.utils.parseEther("0.2");
    const totalAmount = ethers.utils.parseEther("1.0");

    const tx = await contract.payAndShareWithETH(recipient, shareAmount, {
    value: totalAmount
    });
    console.log("Transaction sent:", tx.hash);

    // 等待交易完成
    const receipt = await tx.wait();
    console.log("Transaction mined:", receipt.transactionHash);
    }

    callPayAndShare();

  2. payAndShareWithERC20:该方法用于 ERC20 代币支付过程的分佣

    • 合约方法:
    /**
    * @notice 使用 ERC20 代币执行支付并分佣,可指定收款地址、代币地址及分佣金额。
    * @param recipient 接收 ERC20 代币的目标地址。
    * @param tokenAddress 用于支付的 ERC20 代币的合约地址。
    * @param amount 支付的 ERC20 代币总额。
    * @param shareAmount 在 ERC20 代币支付总额中,用于 Shares 分佣的代币量。
    */
    function payAndShareWithERC20(address recipient, address tokenAddress, uint256 amount, uint256 shareAmount) external;
    • 合约方法调用示例:
    contract Example {
    function examplePayAndShareWithERC20( address recipient, address tokenAddress) external {
    // 假设支付 1000 个代币,其中分佣 200 个
    payAndShareWithERC20(recipient, tokenAddress, 1000, 200);
    // 交易后,recipient 收到 800 个代币,200 个代币通过 Shares 协议完成分佣
    }
    }
    • ABI 接口定义:
    [
    {
    "type": "function",
    "name": "payAndShareWithERC20",
    "inputs": [
    {
    "name": "recipient",
    "type": "address",
    "internalType": "address"
    },
    {
    "name": "tokenAddress",
    "type": "address",
    "internalType": "address"
    },
    {
    "name": "amount",
    "type": "uint256",
    "internalType": "uint256"
    },
    {
    "name": "shareAmount",
    "type": "uint256",
    "internalType": "uint256"
    }
    ],
    "outputs": [],
    "stateMutability": "nonpayable"
    }
    ]
    • ABI 调用示例(基于 ethers.js)
    const { ethers } = require("ethers");

    // 合约地址和 ABI
    const contractAddress = "SimplifiedSharesContractDeploymentAddress";
    const abi = [
    {
    "type": "function",
    "name": "payAndShareWithERC20",
    "inputs": [
    { "name": "recipient", "type": "address" },
    { "name": "tokenAddress", "type": "address" },
    { "name": "amount", "type": "uint256" },
    { "name": "shareAmount", "type": "uint256" }
    ],
    "outputs": [],
    "stateMutability": "nonpayable"
    }
    ];

    // 初始化 Provider 和 Signer
    const provider = new ethers.providers.JsonRpcProvider("https://your-rpc-url");
    const signer = provider.getSigner();
    const contract = new ethers.Contract(contractAddress, abi, signer);

    async function callPayAndShareWithERC20() {
    const recipient = "0xRecipientAddress";
    const tokenAddress = "0xTokenAddress";
    const amount = ethers.utils.parseUnits("1000", 18); // 假设代币有 18 位小数
    const shareAmount = ethers.utils.parseUnits("200", 18);

    const tx = await contract.payAndShareWithERC20(
    recipient,
    tokenAddress,
    amount,
    shareAmount
    );
    console.log("Transaction sent:", tx.hash);

    // 等待交易完成
    const receipt = await tx.wait();
    console.log("Transaction mined:", receipt.transactionHash);
    }

    callPayAndShareWithERC20();

简化的分佣合约部署地址:
NetworkContract Address
BSC0xf0Cc35840394eD6274e058620FC6eb3aBA27Ba2d

2.5 部署、交互示例:

https://connect-nu-one.vercel.app/op_.html (在DeBox中打开)

Onchain Shares Example

点击各个按钮调用对应方法,在右下角 ”vConsole” 中即可观察到执行结果。