Skip to main content

SDK Initialization 🔧

How to initialize the DolphinPay TypeScript SDK. The SDK talks to Sui over gRPC (SuiGrpcClient) — there is no JSON-RPC, GraphQL, or WebSocket transport.

Basic Initialization​

import { createClient } from '@dolphinpay/sdk';

const client = createClient({
network: 'testnet',
packageId: '<PACKAGE_ID>', // deployed DolphinPay package
adminConfigId: '<ADMIN_CONFIG_ID>', // shared AdminConfig object
});

createClient(config) returns a DolphinPayClient. You can also construct it directly with new DolphinPayClient(config).

Where do the IDs come from?

The project's Sui Testnet deployment is live. Take the current packageId and adminConfigId only from DEPLOYMENT.md in the repository — it is the sole source of truth for deployment identifiers. There is no mainnet deployment (the SDK's network type accepts 'mainnet', but no DolphinPay package exists there) — do not copy IDs from old documents.

Configuration Options​

interface SDKConfig {
/** Sui network to connect to */
network: 'mainnet' | 'testnet' | 'devnet' | 'localnet';

/** Package ID of the deployed DolphinPay contract */
packageId: string;

/**
* Shared AdminConfig object ID (required — the contract validates the
* currency and fee policy against it on payment create/execute)
*/
adminConfigId: string;

/** Optional: custom gRPC fullnode endpoint */
grpcUrl?: string;
}
Configuration validation

DolphinPayClient validates its config at construction time: it rejects unsupported runtime network values and malformed or all-zero (0x0) packageId/adminConfigId values, and normalizes valid shorthand IDs to their full form. The 'mainnet' type being accepted does not mean a DolphinPay package exists on mainnet.

Default gRPC endpoints​

When grpcUrl is omitted, the client uses the public fullnode for the network:

NetworkEndpoint
mainnethttps://fullnode.mainnet.sui.io:443
testnethttps://fullnode.testnet.sui.io:443
devnethttps://fullnode.devnet.sui.io:443
localnethttp://127.0.0.1:9000
// Custom gRPC endpoint
const client = createClient({
network: 'testnet',
packageId: '<PACKAGE_ID>',
adminConfigId: '<ADMIN_CONFIG_ID>',
grpcUrl: 'https://your-grpc-fullnode.example.com:443',
});

Environment-Based Configuration​

Keep deployment IDs in environment variables rather than hard-coding them:

# .env.local
NEXT_PUBLIC_SUI_NETWORK=<NETWORK>
NEXT_PUBLIC_PACKAGE_ID=<PACKAGE_ID>
NEXT_PUBLIC_ADMIN_CONFIG_ID=<ADMIN_CONFIG_ID>
import { createClient, type SDKConfig } from '@dolphinpay/sdk';

function requireEnv(name: string): string {
const value = process.env[name];
if (!value) {
throw new Error(`Missing required environment variable: ${name}`);
}
return value;
}

const client = createClient({
network: requireEnv('NEXT_PUBLIC_SUI_NETWORK') as SDKConfig['network'],
packageId: requireEnv('NEXT_PUBLIC_PACKAGE_ID'),
adminConfigId: requireEnv('NEXT_PUBLIC_ADMIN_CONFIG_ID'),
});

The as SDKConfig['network'] cast only narrows the string type for the compiler — DolphinPayClient still validates at runtime that the network is supported and that the object IDs are well-formed, so an invalid value fails fast at construction.

What the Client Exposes​

client.payment; // PaymentModule — payment builders and queries
client.merchant; // MerchantModule — merchant builders and queries
client.admin; // AdminModule — governance builders and queries (AdminCap-gated)
client.events; // EventModule — on-chain event queries

client.suiClient; // the underlying SuiGrpcClient
client.packageId; // configured package ID
client.adminConfigId; // configured AdminConfig ID
client.network; // configured network

Helper methods on the client itself:

// New empty Transaction (from @mysten/sui/transactions)
const txb = client.createTxBlock();

// Address helpers
client.getModuleAddress('payment'); // "<pkg>::payment"
client.getFunctionAddress('payment', 'create_payment');
client.getTypeAddress('merchant', 'MerchantCap');

// Fetch any object's Move struct fields as JSON via gRPC
const fields = await client.getObjectFields('0xOBJECT_ID');

// Simulate a transaction (gRPC simulateTransaction)
const sim = await client.dryRunTransaction(txb, '0xSENDER_ADDRESS');
// { success, status, effects, events, balanceChanges } or { success: false, error, details }

Verifying Connectivity​

A cheap end-to-end check is reading the shared AdminConfig:

const config = await client.admin.getAdminConfig();
console.log('Fee (bps):', config.defaultPlatformFeeBps); // 0 by policy
console.log('Allowed currency:', config.allowedCurrency); // native Circle USDC, or null until configured

If this throws, either the endpoint is unreachable or the adminConfigId is wrong for the network.

Multiple Clients​

For apps that target more than one network, create one client per network:

const testnetClient = createClient({
network: 'testnet',
packageId: process.env.TESTNET_PACKAGE_ID!,
adminConfigId: process.env.TESTNET_ADMIN_CONFIG_ID!,
});

const localClient = createClient({
network: 'localnet',
packageId: process.env.LOCAL_PACKAGE_ID!,
adminConfigId: process.env.LOCAL_ADMIN_CONFIG_ID!,
});

There is no mainnet deployment; mainnet requires explicit approval.

Next Steps​