@playmos/sdk 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-B7SHFZYY.js → chunk-TMBBEGIF.js} +12 -3
- package/dist/chunk-TMBBEGIF.js.map +1 -0
- package/dist/{errors-BVESr920.d.cts → errors-DMtMpbR6.d.cts} +48 -4
- package/dist/{errors-BVESr920.d.ts → errors-DMtMpbR6.d.ts} +48 -4
- package/dist/index.cjs +193 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +32 -3
- package/dist/index.d.ts +32 -3
- package/dist/index.js +184 -3
- package/dist/index.js.map +1 -1
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +1 -1
- package/dist/server.d.ts +1 -1
- package/dist/server.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-B7SHFZYY.js.map +0 -1
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { N as Network, P as PlaymosConfig, W as WebhookEvent, R as RoundOpenInput, a as RoundState, b as RoundSettleInput, S as SettleRoundResult, A as AgentWallet,
|
|
2
|
-
export {
|
|
1
|
+
import { N as Network, P as PlaymosConfig, W as WebhookEvent, R as RoundOpenInput, a as RoundState, b as RoundSettleInput, S as SettleRoundResult, c as PrizeBalance, d as WithdrawResult, A as AgentWallet, e as AgentFundResult, T as TransferResult, E as EscrowHoldInput, f as EscrowHoldResult, g as EscrowResolveResult, M as MarketplaceListInput, L as Listing, h as MarketplaceSaleResult, i as MarketplaceGetResult, j as PayInput, k as Payment, l as EnterRoundInput, m as TransferReconcile, n as WaitOptions, o as TransferInput, p as TransferConfirmOptions, V as VerifyResult } from './errors-DMtMpbR6.cjs';
|
|
2
|
+
export { q as AgentEconomyConfig, r as ApiError, s as AuthError, C as ConfigError, t as ContractConfig, u as Eip1193Provider, G as GasConfig, v as GasMode, I as InsufficientGasError, w as InvalidAmountError, x as ListingStatus, y as MarketplaceItem, z as MarketplaceSale, B as MissingFieldError, D as NothingToWithdrawError, F as PaymentFailedError, H as PaymentStatus, J as PayoutRule, K as PlaymosError, O as PlaymosErrorCode, Q as RetryOptions, U as RoundStatus, X as WalletConfig, Y as WalletConnectionError, Z as WalletConnector, _ as WebhookEventType } from './errors-DMtMpbR6.cjs';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Environment resolution + the canonical address book.
|
|
@@ -80,6 +80,30 @@ declare class Playmos {
|
|
|
80
80
|
get: (input: {
|
|
81
81
|
roundId: string;
|
|
82
82
|
}) => Promise<RoundState>;
|
|
83
|
+
/**
|
|
84
|
+
* Read a wallet's **claimable** prize balance for a round (issue #41).
|
|
85
|
+
* Prefers the service chain read (`GET /v1/rounds/:id/prize?wallet=`); falls
|
|
86
|
+
* back to a direct eth_call when `prizePoolAddress` is supplied and no wallet
|
|
87
|
+
* connector is needed for the read path… actually uses service first, then
|
|
88
|
+
* on-chain via the player's provider if the service is unavailable.
|
|
89
|
+
*/
|
|
90
|
+
prize: (input: {
|
|
91
|
+
roundId: string;
|
|
92
|
+
wallet: `0x${string}`;
|
|
93
|
+
/** Optional override if you already hold the pool address from enterRound. */
|
|
94
|
+
prizePoolAddress?: `0x${string}`;
|
|
95
|
+
}) => Promise<PrizeBalance>;
|
|
96
|
+
/**
|
|
97
|
+
* Winner **claim** — call PrizePool.withdraw() from the player's wallet (issue #41).
|
|
98
|
+
* Pull-payment: credits from settle live in `withdrawable[msg.sender]`. No approve needed.
|
|
99
|
+
* Pass either `prizePoolAddress` (from enterRound / rounds.get) or `roundId` (service resolves).
|
|
100
|
+
*/
|
|
101
|
+
withdraw: (input: {
|
|
102
|
+
prizePoolAddress?: `0x${string}`;
|
|
103
|
+
roundId?: string;
|
|
104
|
+
/** Pre-check claimable; default true. Set false only if you already called `prize()`. */
|
|
105
|
+
checkBalance?: boolean;
|
|
106
|
+
}) => Promise<WithdrawResult>;
|
|
83
107
|
};
|
|
84
108
|
/**
|
|
85
109
|
* `agents` — assign wallets to the NPCs YOUR game already owns, so they can transact USDC in your economy.
|
|
@@ -245,6 +269,11 @@ declare class Playmos {
|
|
|
245
269
|
/** Prefer the service's authoritative micro-USDC amount; fall back to the
|
|
246
270
|
* locally-parsed value if the service didn't echo one. */
|
|
247
271
|
private resolveUnits;
|
|
272
|
+
/**
|
|
273
|
+
* Read PrizePool.withdrawable[wallet] via eth_call (issue #41).
|
|
274
|
+
* Uses the wallet provider when present; otherwise a public Base Sepolia RPC in test.
|
|
275
|
+
*/
|
|
276
|
+
private readWithdrawable;
|
|
248
277
|
private sponsorUrl;
|
|
249
278
|
/**
|
|
250
279
|
* After the batch lands, resolve the authoritative status via the service's
|
|
@@ -514,4 +543,4 @@ declare function isWalletSignatureAuthorization(auth: Authorization): auth is Wa
|
|
|
514
543
|
/** Narrow to the declared-but-unimplemented x402 variant. */
|
|
515
544
|
declare function isX402PayloadAuthorization(auth: Authorization): auth is X402PayloadAuthorization;
|
|
516
545
|
|
|
517
|
-
export { AgentFundResult, AgentWallet, type Authorization, CHAIN_ID, type CreatePaymentRequirementInput, DEFAULT_API_BASE_URL, EnterRoundInput, EscrowHoldInput, EscrowHoldResult, EscrowResolveResult, Listing, MICRO_PER_USDC, MarketplaceGetResult, MarketplaceListInput, MarketplaceSaleResult, Network, PayInput, Payment, type PaymentRequirement, PayoutError, type PayoutRule as PayoutRuleCompute, Playmos, PlaymosConfig, RoundOpenInput, RoundSettleInput, RoundState, SettleRoundResult, type SettlementAsset, TransferConfirmOptions, TransferInput, TransferReconcile, TransferResult, USDC_ADDRESS, USDC_DECIMALS, VerifyResult, WaitOptions, type WalletSignatureAuthorization, WebhookEvent, type X402PayloadAuthorization, computeIapSplit, computePayout, computePoolSplit, createPaymentRequirement, formatMicroToUsd, isWalletSignatureAuthorization, isX402PayloadAuthorization, parsePaymentRequirement, parseUsdToMicro, prefixedId, previewEscrowFee, previewIapSplit, previewMarketplaceSplit, previewPoolSplit, previewTransferSplit, serializePaymentRequirement, ulid };
|
|
546
|
+
export { AgentFundResult, AgentWallet, type Authorization, CHAIN_ID, type CreatePaymentRequirementInput, DEFAULT_API_BASE_URL, EnterRoundInput, EscrowHoldInput, EscrowHoldResult, EscrowResolveResult, Listing, MICRO_PER_USDC, MarketplaceGetResult, MarketplaceListInput, MarketplaceSaleResult, Network, PayInput, Payment, type PaymentRequirement, PayoutError, type PayoutRule as PayoutRuleCompute, Playmos, PlaymosConfig, PrizeBalance, RoundOpenInput, RoundSettleInput, RoundState, SettleRoundResult, type SettlementAsset, TransferConfirmOptions, TransferInput, TransferReconcile, TransferResult, USDC_ADDRESS, USDC_DECIMALS, VerifyResult, WaitOptions, type WalletSignatureAuthorization, WebhookEvent, WithdrawResult, type X402PayloadAuthorization, computeIapSplit, computePayout, computePoolSplit, createPaymentRequirement, formatMicroToUsd, isWalletSignatureAuthorization, isX402PayloadAuthorization, parsePaymentRequirement, parseUsdToMicro, prefixedId, previewEscrowFee, previewIapSplit, previewMarketplaceSplit, previewPoolSplit, previewTransferSplit, serializePaymentRequirement, ulid };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { N as Network, P as PlaymosConfig, W as WebhookEvent, R as RoundOpenInput, a as RoundState, b as RoundSettleInput, S as SettleRoundResult, A as AgentWallet,
|
|
2
|
-
export {
|
|
1
|
+
import { N as Network, P as PlaymosConfig, W as WebhookEvent, R as RoundOpenInput, a as RoundState, b as RoundSettleInput, S as SettleRoundResult, c as PrizeBalance, d as WithdrawResult, A as AgentWallet, e as AgentFundResult, T as TransferResult, E as EscrowHoldInput, f as EscrowHoldResult, g as EscrowResolveResult, M as MarketplaceListInput, L as Listing, h as MarketplaceSaleResult, i as MarketplaceGetResult, j as PayInput, k as Payment, l as EnterRoundInput, m as TransferReconcile, n as WaitOptions, o as TransferInput, p as TransferConfirmOptions, V as VerifyResult } from './errors-DMtMpbR6.js';
|
|
2
|
+
export { q as AgentEconomyConfig, r as ApiError, s as AuthError, C as ConfigError, t as ContractConfig, u as Eip1193Provider, G as GasConfig, v as GasMode, I as InsufficientGasError, w as InvalidAmountError, x as ListingStatus, y as MarketplaceItem, z as MarketplaceSale, B as MissingFieldError, D as NothingToWithdrawError, F as PaymentFailedError, H as PaymentStatus, J as PayoutRule, K as PlaymosError, O as PlaymosErrorCode, Q as RetryOptions, U as RoundStatus, X as WalletConfig, Y as WalletConnectionError, Z as WalletConnector, _ as WebhookEventType } from './errors-DMtMpbR6.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Environment resolution + the canonical address book.
|
|
@@ -80,6 +80,30 @@ declare class Playmos {
|
|
|
80
80
|
get: (input: {
|
|
81
81
|
roundId: string;
|
|
82
82
|
}) => Promise<RoundState>;
|
|
83
|
+
/**
|
|
84
|
+
* Read a wallet's **claimable** prize balance for a round (issue #41).
|
|
85
|
+
* Prefers the service chain read (`GET /v1/rounds/:id/prize?wallet=`); falls
|
|
86
|
+
* back to a direct eth_call when `prizePoolAddress` is supplied and no wallet
|
|
87
|
+
* connector is needed for the read path… actually uses service first, then
|
|
88
|
+
* on-chain via the player's provider if the service is unavailable.
|
|
89
|
+
*/
|
|
90
|
+
prize: (input: {
|
|
91
|
+
roundId: string;
|
|
92
|
+
wallet: `0x${string}`;
|
|
93
|
+
/** Optional override if you already hold the pool address from enterRound. */
|
|
94
|
+
prizePoolAddress?: `0x${string}`;
|
|
95
|
+
}) => Promise<PrizeBalance>;
|
|
96
|
+
/**
|
|
97
|
+
* Winner **claim** — call PrizePool.withdraw() from the player's wallet (issue #41).
|
|
98
|
+
* Pull-payment: credits from settle live in `withdrawable[msg.sender]`. No approve needed.
|
|
99
|
+
* Pass either `prizePoolAddress` (from enterRound / rounds.get) or `roundId` (service resolves).
|
|
100
|
+
*/
|
|
101
|
+
withdraw: (input: {
|
|
102
|
+
prizePoolAddress?: `0x${string}`;
|
|
103
|
+
roundId?: string;
|
|
104
|
+
/** Pre-check claimable; default true. Set false only if you already called `prize()`. */
|
|
105
|
+
checkBalance?: boolean;
|
|
106
|
+
}) => Promise<WithdrawResult>;
|
|
83
107
|
};
|
|
84
108
|
/**
|
|
85
109
|
* `agents` — assign wallets to the NPCs YOUR game already owns, so they can transact USDC in your economy.
|
|
@@ -245,6 +269,11 @@ declare class Playmos {
|
|
|
245
269
|
/** Prefer the service's authoritative micro-USDC amount; fall back to the
|
|
246
270
|
* locally-parsed value if the service didn't echo one. */
|
|
247
271
|
private resolveUnits;
|
|
272
|
+
/**
|
|
273
|
+
* Read PrizePool.withdrawable[wallet] via eth_call (issue #41).
|
|
274
|
+
* Uses the wallet provider when present; otherwise a public Base Sepolia RPC in test.
|
|
275
|
+
*/
|
|
276
|
+
private readWithdrawable;
|
|
248
277
|
private sponsorUrl;
|
|
249
278
|
/**
|
|
250
279
|
* After the batch lands, resolve the authoritative status via the service's
|
|
@@ -514,4 +543,4 @@ declare function isWalletSignatureAuthorization(auth: Authorization): auth is Wa
|
|
|
514
543
|
/** Narrow to the declared-but-unimplemented x402 variant. */
|
|
515
544
|
declare function isX402PayloadAuthorization(auth: Authorization): auth is X402PayloadAuthorization;
|
|
516
545
|
|
|
517
|
-
export { AgentFundResult, AgentWallet, type Authorization, CHAIN_ID, type CreatePaymentRequirementInput, DEFAULT_API_BASE_URL, EnterRoundInput, EscrowHoldInput, EscrowHoldResult, EscrowResolveResult, Listing, MICRO_PER_USDC, MarketplaceGetResult, MarketplaceListInput, MarketplaceSaleResult, Network, PayInput, Payment, type PaymentRequirement, PayoutError, type PayoutRule as PayoutRuleCompute, Playmos, PlaymosConfig, RoundOpenInput, RoundSettleInput, RoundState, SettleRoundResult, type SettlementAsset, TransferConfirmOptions, TransferInput, TransferReconcile, TransferResult, USDC_ADDRESS, USDC_DECIMALS, VerifyResult, WaitOptions, type WalletSignatureAuthorization, WebhookEvent, type X402PayloadAuthorization, computeIapSplit, computePayout, computePoolSplit, createPaymentRequirement, formatMicroToUsd, isWalletSignatureAuthorization, isX402PayloadAuthorization, parsePaymentRequirement, parseUsdToMicro, prefixedId, previewEscrowFee, previewIapSplit, previewMarketplaceSplit, previewPoolSplit, previewTransferSplit, serializePaymentRequirement, ulid };
|
|
546
|
+
export { AgentFundResult, AgentWallet, type Authorization, CHAIN_ID, type CreatePaymentRequirementInput, DEFAULT_API_BASE_URL, EnterRoundInput, EscrowHoldInput, EscrowHoldResult, EscrowResolveResult, Listing, MICRO_PER_USDC, MarketplaceGetResult, MarketplaceListInput, MarketplaceSaleResult, Network, PayInput, Payment, type PaymentRequirement, PayoutError, type PayoutRule as PayoutRuleCompute, Playmos, PlaymosConfig, PrizeBalance, RoundOpenInput, RoundSettleInput, RoundState, SettleRoundResult, type SettlementAsset, TransferConfirmOptions, TransferInput, TransferReconcile, TransferResult, USDC_ADDRESS, USDC_DECIMALS, VerifyResult, WaitOptions, type WalletSignatureAuthorization, WebhookEvent, WithdrawResult, type X402PayloadAuthorization, computeIapSplit, computePayout, computePoolSplit, createPaymentRequirement, formatMicroToUsd, isWalletSignatureAuthorization, isX402PayloadAuthorization, parsePaymentRequirement, parseUsdToMicro, prefixedId, previewEscrowFee, previewIapSplit, previewMarketplaceSplit, previewPoolSplit, previewTransferSplit, serializePaymentRequirement, ulid };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { InvalidAmountError, ConfigError, ApiError, MissingFieldError,
|
|
2
|
-
export { ApiError, AuthError, ConfigError, InsufficientGasError, InvalidAmountError, MissingFieldError, PaymentFailedError, PlaymosError, WalletConnectionError } from './chunk-
|
|
3
|
-
import { encodeFunctionData, numberToHex, keccak256, toBytes } from 'viem';
|
|
1
|
+
import { InvalidAmountError, ConfigError, NothingToWithdrawError, PaymentFailedError, ApiError, MissingFieldError, WalletConnectionError, InsufficientGasError, AuthError } from './chunk-TMBBEGIF.js';
|
|
2
|
+
export { ApiError, AuthError, ConfigError, InsufficientGasError, InvalidAmountError, MissingFieldError, NothingToWithdrawError, PaymentFailedError, PlaymosError, WalletConnectionError } from './chunk-TMBBEGIF.js';
|
|
3
|
+
import { encodeFunctionData, decodeFunctionResult, numberToHex, keccak256, toBytes } from 'viem';
|
|
4
4
|
|
|
5
5
|
// src/config.ts
|
|
6
6
|
var CHAIN_ID = {
|
|
@@ -403,6 +403,13 @@ var prizePoolAbi = [
|
|
|
403
403
|
],
|
|
404
404
|
outputs: [{ type: "bool" }]
|
|
405
405
|
},
|
|
406
|
+
{
|
|
407
|
+
type: "function",
|
|
408
|
+
name: "withdrawable",
|
|
409
|
+
stateMutability: "view",
|
|
410
|
+
inputs: [{ name: "account", type: "address" }],
|
|
411
|
+
outputs: [{ type: "uint256" }]
|
|
412
|
+
},
|
|
406
413
|
{
|
|
407
414
|
type: "function",
|
|
408
415
|
name: "withdraw",
|
|
@@ -490,6 +497,14 @@ function buildEntryCalls(args) {
|
|
|
490
497
|
{ to: args.prizePool, data: enterData }
|
|
491
498
|
];
|
|
492
499
|
}
|
|
500
|
+
function buildWithdrawCall(prizePool) {
|
|
501
|
+
const data = encodeFunctionData({
|
|
502
|
+
abi: prizePoolAbi,
|
|
503
|
+
functionName: "withdraw",
|
|
504
|
+
args: []
|
|
505
|
+
});
|
|
506
|
+
return { to: prizePool, data };
|
|
507
|
+
}
|
|
493
508
|
|
|
494
509
|
// src/mock.ts
|
|
495
510
|
var MOCK_TX = "0x000000000000000000000000000000000000000000000000000000000000mock";
|
|
@@ -534,6 +549,9 @@ function mockEntryPayment(args) {
|
|
|
534
549
|
},
|
|
535
550
|
gameId: args.gameId,
|
|
536
551
|
roundId: args.roundId,
|
|
552
|
+
roundKey: args.roundId,
|
|
553
|
+
// Deterministic mock pool address so claim-flow unit tests can assert shape (#41).
|
|
554
|
+
prizePoolAddress: "0x0000000000000000000000000000000000000001",
|
|
537
555
|
playerId: args.playerId,
|
|
538
556
|
txHash: MOCK_TX,
|
|
539
557
|
chain: args.chain,
|
|
@@ -646,6 +664,112 @@ var Playmos = class {
|
|
|
646
664
|
`/rounds/${encodeURIComponent(input.roundId)}`
|
|
647
665
|
);
|
|
648
666
|
return round;
|
|
667
|
+
},
|
|
668
|
+
/**
|
|
669
|
+
* Read a wallet's **claimable** prize balance for a round (issue #41).
|
|
670
|
+
* Prefers the service chain read (`GET /v1/rounds/:id/prize?wallet=`); falls
|
|
671
|
+
* back to a direct eth_call when `prizePoolAddress` is supplied and no wallet
|
|
672
|
+
* connector is needed for the read path… actually uses service first, then
|
|
673
|
+
* on-chain via the player's provider if the service is unavailable.
|
|
674
|
+
*/
|
|
675
|
+
prize: async (input) => {
|
|
676
|
+
requireField(input?.roundId, "roundId");
|
|
677
|
+
const wallet = requireAddressField(input?.wallet, "wallet");
|
|
678
|
+
try {
|
|
679
|
+
const res = await this.http.get(
|
|
680
|
+
`/rounds/${encodeURIComponent(input.roundId)}/prize?wallet=${encodeURIComponent(wallet)}`
|
|
681
|
+
);
|
|
682
|
+
return res.prize;
|
|
683
|
+
} catch (e) {
|
|
684
|
+
if (!input.prizePoolAddress && !(e instanceof ApiError)) throw e;
|
|
685
|
+
if (!input.prizePoolAddress) throw e;
|
|
686
|
+
}
|
|
687
|
+
const prizePoolAddress = requireAddressField(input.prizePoolAddress, "prizePoolAddress");
|
|
688
|
+
const claimableMicro = await this.readWithdrawable(prizePoolAddress, wallet);
|
|
689
|
+
return {
|
|
690
|
+
roundId: input.roundId,
|
|
691
|
+
prizePoolAddress,
|
|
692
|
+
wallet,
|
|
693
|
+
claimable: formatMicroToUsd(claimableMicro),
|
|
694
|
+
claimableMicro: claimableMicro.toString()
|
|
695
|
+
};
|
|
696
|
+
},
|
|
697
|
+
/**
|
|
698
|
+
* Winner **claim** — call PrizePool.withdraw() from the player's wallet (issue #41).
|
|
699
|
+
* Pull-payment: credits from settle live in `withdrawable[msg.sender]`. No approve needed.
|
|
700
|
+
* Pass either `prizePoolAddress` (from enterRound / rounds.get) or `roundId` (service resolves).
|
|
701
|
+
*/
|
|
702
|
+
withdraw: async (input) => {
|
|
703
|
+
if (this.config.mock) {
|
|
704
|
+
return {
|
|
705
|
+
prizePoolAddress: input.prizePoolAddress ?? "0x0000000000000000000000000000000000000001",
|
|
706
|
+
amount: "0.00",
|
|
707
|
+
amountMicro: "0",
|
|
708
|
+
txHash: "0x000000000000000000000000000000000000000000000000000000000000mock",
|
|
709
|
+
status: "confirmed"
|
|
710
|
+
};
|
|
711
|
+
}
|
|
712
|
+
let prizePool = input.prizePoolAddress ? requireAddressField(input.prizePoolAddress, "prizePoolAddress") : void 0;
|
|
713
|
+
if (!prizePool) {
|
|
714
|
+
requireField(input?.roundId, "roundId");
|
|
715
|
+
const round = await this.rounds.get({ roundId: input.roundId });
|
|
716
|
+
if (!round.prizePoolAddress) {
|
|
717
|
+
throw new ConfigError(
|
|
718
|
+
"rounds.get did not return prizePoolAddress \u2014 pass prizePoolAddress from enterRound or configure contracts.prizePool"
|
|
719
|
+
);
|
|
720
|
+
}
|
|
721
|
+
prizePool = round.prizePoolAddress;
|
|
722
|
+
}
|
|
723
|
+
const provider = resolveProvider(this.config.wallet);
|
|
724
|
+
if (this.config.gas?.mode === "player") {
|
|
725
|
+
const from0 = await getAccount(provider);
|
|
726
|
+
await assertEnoughGas(provider, from0);
|
|
727
|
+
}
|
|
728
|
+
const from = await getAccount(provider);
|
|
729
|
+
let amountMicro = 0n;
|
|
730
|
+
if (input.checkBalance !== false) {
|
|
731
|
+
amountMicro = await this.readWithdrawable(prizePool, from);
|
|
732
|
+
if (amountMicro === 0n) {
|
|
733
|
+
throw new NothingToWithdrawError({ prizePoolAddress: prizePool, wallet: from });
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
const call = buildWithdrawCall(prizePool);
|
|
737
|
+
const paymasterUrl = this.config.gas?.mode === "sponsored" ? this.config.gas.paymasterUrl : void 0;
|
|
738
|
+
let txHash;
|
|
739
|
+
let status = "pending";
|
|
740
|
+
try {
|
|
741
|
+
const { id: callsId } = await sendCalls(
|
|
742
|
+
provider,
|
|
743
|
+
from,
|
|
744
|
+
this.env.chainId,
|
|
745
|
+
[call],
|
|
746
|
+
paymasterUrl
|
|
747
|
+
);
|
|
748
|
+
const waited = await waitForCalls(provider, callsId);
|
|
749
|
+
txHash = waited.txHash;
|
|
750
|
+
status = waited.status === "CONFIRMED" ? "confirmed" : waited.status === "FAILED" ? "failed" : "pending";
|
|
751
|
+
} catch (e) {
|
|
752
|
+
const msg = e?.message ?? String(e);
|
|
753
|
+
if (/NothingToWithdraw|nothing to withdraw/i.test(msg)) {
|
|
754
|
+
throw new NothingToWithdrawError({ prizePoolAddress: prizePool, wallet: from, cause: msg });
|
|
755
|
+
}
|
|
756
|
+
if (e instanceof NothingToWithdrawError || e instanceof PaymentFailedError) throw e;
|
|
757
|
+
throw new PaymentFailedError("PrizePool.withdraw() failed.", { cause: msg });
|
|
758
|
+
}
|
|
759
|
+
if (status === "failed") {
|
|
760
|
+
throw new PaymentFailedError("PrizePool.withdraw() did not confirm on-chain.", {
|
|
761
|
+
prizePoolAddress: prizePool,
|
|
762
|
+
txHash
|
|
763
|
+
});
|
|
764
|
+
}
|
|
765
|
+
if (amountMicro === 0n && input.checkBalance === false) ;
|
|
766
|
+
return {
|
|
767
|
+
prizePoolAddress: prizePool,
|
|
768
|
+
amount: formatMicroToUsd(amountMicro),
|
|
769
|
+
amountMicro: amountMicro.toString(),
|
|
770
|
+
txHash,
|
|
771
|
+
status
|
|
772
|
+
};
|
|
649
773
|
}
|
|
650
774
|
};
|
|
651
775
|
/**
|
|
@@ -975,6 +1099,9 @@ var Playmos = class {
|
|
|
975
1099
|
);
|
|
976
1100
|
const payment2 = this.mapServerPayment(res.payment, "entry", amountMicro);
|
|
977
1101
|
if (input.identity) payment2.identity = input.identity;
|
|
1102
|
+
const pool = res.clientParams?.contractAddress ?? this.config.contracts?.prizePool;
|
|
1103
|
+
if (pool) payment2.prizePoolAddress = pool.toLowerCase();
|
|
1104
|
+
payment2.roundKey = res.clientParams?.roundKey ?? res.clientParams?.roundId ?? payment2.roundId ?? input.roundId;
|
|
978
1105
|
return payment2;
|
|
979
1106
|
}
|
|
980
1107
|
const intent = await this.http.post(
|
|
@@ -1002,6 +1129,8 @@ var Playmos = class {
|
|
|
1002
1129
|
const { txHash } = await waitForCalls(provider, callsId);
|
|
1003
1130
|
const payment = await this.settle(intent.payment.id, txHash);
|
|
1004
1131
|
payment.identity = identity;
|
|
1132
|
+
payment.prizePoolAddress = prizePool.toLowerCase();
|
|
1133
|
+
payment.roundKey = roundKey;
|
|
1005
1134
|
return payment;
|
|
1006
1135
|
}
|
|
1007
1136
|
/**
|
|
@@ -1111,6 +1240,58 @@ var Playmos = class {
|
|
|
1111
1240
|
const fromServer = intent.clientParams?.amountUnits ?? intent.clientParams?.amountMicro;
|
|
1112
1241
|
return fromServer ? BigInt(fromServer) : local;
|
|
1113
1242
|
}
|
|
1243
|
+
/**
|
|
1244
|
+
* Read PrizePool.withdrawable[wallet] via eth_call (issue #41).
|
|
1245
|
+
* Uses the wallet provider when present; otherwise a public Base Sepolia RPC in test.
|
|
1246
|
+
*/
|
|
1247
|
+
async readWithdrawable(prizePool, wallet) {
|
|
1248
|
+
const data = encodeFunctionData({
|
|
1249
|
+
abi: prizePoolAbi,
|
|
1250
|
+
functionName: "withdrawable",
|
|
1251
|
+
args: [wallet]
|
|
1252
|
+
});
|
|
1253
|
+
let raw;
|
|
1254
|
+
try {
|
|
1255
|
+
if (await walletAvailable(this.config.wallet)) {
|
|
1256
|
+
const provider = resolveProvider(this.config.wallet);
|
|
1257
|
+
raw = await provider.request({
|
|
1258
|
+
method: "eth_call",
|
|
1259
|
+
params: [{ to: prizePool, data }, "latest"]
|
|
1260
|
+
});
|
|
1261
|
+
} else {
|
|
1262
|
+
const rpc = this.env.network === "base" ? "https://mainnet.base.org" : "https://sepolia.base.org";
|
|
1263
|
+
const res = await fetch(rpc, {
|
|
1264
|
+
method: "POST",
|
|
1265
|
+
headers: { "content-type": "application/json" },
|
|
1266
|
+
body: JSON.stringify({
|
|
1267
|
+
jsonrpc: "2.0",
|
|
1268
|
+
id: 1,
|
|
1269
|
+
method: "eth_call",
|
|
1270
|
+
params: [{ to: prizePool, data }, "latest"]
|
|
1271
|
+
})
|
|
1272
|
+
});
|
|
1273
|
+
const json = await res.json();
|
|
1274
|
+
if (!json.result) {
|
|
1275
|
+
throw new ApiError(
|
|
1276
|
+
`eth_call withdrawable failed: ${json.error?.message ?? "no result"}`,
|
|
1277
|
+
{ prizePool, wallet }
|
|
1278
|
+
);
|
|
1279
|
+
}
|
|
1280
|
+
raw = json.result;
|
|
1281
|
+
}
|
|
1282
|
+
} catch (e) {
|
|
1283
|
+
if (e instanceof ApiError) throw e;
|
|
1284
|
+
throw new ApiError(`Could not read withdrawable balance: ${e.message}`, {
|
|
1285
|
+
prizePool,
|
|
1286
|
+
wallet
|
|
1287
|
+
});
|
|
1288
|
+
}
|
|
1289
|
+
return decodeFunctionResult({
|
|
1290
|
+
abi: prizePoolAbi,
|
|
1291
|
+
functionName: "withdrawable",
|
|
1292
|
+
data: raw
|
|
1293
|
+
});
|
|
1294
|
+
}
|
|
1114
1295
|
sponsorUrl(intent) {
|
|
1115
1296
|
if (this.config.gas?.mode === "player") return void 0;
|
|
1116
1297
|
return this.config.gas?.paymasterUrl ?? intent.clientParams?.paymasterUrl;
|