Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 19 additions & 5 deletions .agents/skills/oneshot-embedded-wallet/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,12 +111,26 @@ await proxy.rpc("configure", options);
| `copy.personalSign.rejectLabel` | string | Reject button |
| `copy.personalSign.signLabel` | string | Sign button |
| `copy.typedData.title` | string | EIP-712 modal title |
| `copy.typedData.accountLabel` | string | Account field label |
| `copy.typedData.body` | string | Intro paragraph |
| `copy.typedData.networkLabel` | string | Network summary row label |
| `copy.typedData.requestFromLabel` | string | Requesting domain row label |
| `copy.typedData.accountLabel` | string | Signing account row label |
| `copy.typedData.interactingWithLabel` | string | Verifying contract row label |
| `copy.typedData.primaryTypeLabel` | string | Primary type label |
| `copy.typedData.domainLabel` | string | Domain label |
| `copy.typedData.messageLabel` | string | Message label |
| `copy.typedData.messageSectionLabel` | string | Message card heading |
| `copy.typedData.signingHint` | string | Hint shown while signing |
| `copy.typedData.rejectLabel` | string | Reject button |
| `copy.typedData.signLabel` | string | Sign button |
| `copy.grantExecutionPermission.title` | string | ERC-20 periodic grant modal title |
| `copy.grantExecutionPermission.permissionKindLabel` | string | Summary card eyebrow |
| `copy.grantExecutionPermission.amountLabel` | string | Summary amount row |
| `copy.grantExecutionPermission.transferWindowLabel` | string | Summary cadence row |
| `copy.grantExecutionPermission.toLabel` | string | Delegate summary row |
| `copy.grantExecutionPermission.viewOnExplorerLabel` | string | Delegate explorer link a11y |
| `copy.grantExecutionPermission.justificationLabel` | string | Host justification in terms card |
| `copy.grantExecutionPermission.advancedLabel` | string | Toggle for Unix start field |
| `copy.grantExecutionPermission.grantLabel` | string | Grant button |
| `copy.grantExecutionPermission.rejectLabel` | string | Reject button |
| `copy.credentialOffer.title` | string | offer modal title |
| `copy.credentialOffer.body` | string | supports `{issuerName}` `{issuerId}` |
| `copy.credentialOffer.offeredHeading` | string | offered list heading |
Expand Down Expand Up @@ -389,8 +403,8 @@ EIP-7715 host RPCs: `wallet_requestExecutionPermissions`, `wallet_revokeExecutio
| `permission.type` | Chains (v1) | Purpose |
|-------------------|-------------|---------|
| `erc20-token-periodic` | All relayer chains | Periodic ERC-20 `transfer` budget (`ScopeType.Erc20PeriodTransfer`) |
| `lifi-swap-approve` | Base (`0x2105`) | One-time `approve(inputToken → LiFi Diamond)` onboarding |
| `lifi-swap-periodic` | Base (`0x2105`) | Periodic LiFi swap via `LiFiSwapEnforcer` (`0x47472E8AA7012D1c23336aa28514AE94389318f5`) |
| `lifi-swap-approve` | Arc (`0x13b2`), Base (`0x2105`), Ethereum (`0x1`) | One-time `approve(inputToken → LiFi Diamond)` onboarding |
| `lifi-swap-periodic` | Arc, Base, Ethereum mainnet | Periodic LiFi swap via `LiFiSwapEnforcer` proxy (`0x29fcBBa852439616c4D614A2fa6411E42b760153`) |

**`erc20-token-periodic` / `lifi-swap-periodic` amounts:** Hosts should pass `periodAmount` (hex atoms) to prefill the grant form. Playground demos default to **10 USDC** (`0x989680`).

Expand Down
3 changes: 0 additions & 3 deletions .github/workflows/Deploy Dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,8 @@ jobs:
gcloud --quiet auth configure-docker $GAR_LOCATION-docker.pkg.dev

- name: Build Wallet
env:
CLOUDSMITH_TOKEN: ${{ secrets.CLOUDSMITH_TOKEN }}
run: |-
docker build \
--secret id=cloudsmith_token,env=CLOUDSMITH_TOKEN \
--tag "$GAR_LOCATION-docker.pkg.dev/$PROJECT_ID/$PRODUCT_NAME/oneshot-wallet:$GITHUB_SHA" \
--tag "$GAR_LOCATION-docker.pkg.dev/$PROJECT_ID/$PRODUCT_NAME/oneshot-wallet:${GITHUB_REF##*/}" \
--tag "$GAR_LOCATION-docker.pkg.dev/$PROJECT_ID/$PRODUCT_NAME/oneshot-wallet:latest" \
Expand Down
3 changes: 0 additions & 3 deletions .github/workflows/Deploy Prod.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,8 @@ jobs:
gcloud --quiet auth configure-docker $GAR_LOCATION-docker.pkg.dev

- name: Build Wallet
env:
CLOUDSMITH_TOKEN: ${{ secrets.CLOUDSMITH_TOKEN }}
run: |-
docker build \
--secret id=cloudsmith_token,env=CLOUDSMITH_TOKEN \
--tag "$GAR_LOCATION-docker.pkg.dev/$PROJECT_ID/$PRODUCT_NAME/oneshot-wallet:$GITHUB_SHA" \
--tag "$GAR_LOCATION-docker.pkg.dev/$PROJECT_ID/$PRODUCT_NAME/oneshot-wallet:${GITHUB_REF##*/}" \
--tag "$GAR_LOCATION-docker.pkg.dev/$PROJECT_ID/$PRODUCT_NAME/oneshot-wallet:latest" \
Expand Down
2 changes: 0 additions & 2 deletions .npmrc

This file was deleted.

2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Prefer **clean code over backwards compatibility**. Do not add legacy redirects,

Test Host Layer: `host/` (`npm run dev:host`). Browser extension: `extension/` (`npm run dev:extension`) — see [`extension/README.md`](extension/README.md). Branding / host config via Host RPC `configure`, not in-wallet debug knobs.

Fiat onramp: Asset Details **Buy** and host RPC `onramp({ chainId?, amount? })` open `OnrampView` (Circle AppKit). Sessions come from Relayer `POST /wallet/onramp` — never put the Circle kit key in this SPA. When Branding is nested in a Host iframe (`window.self !== window.top`), UI prefers `openWindow` (prefetch session, then a sync click) because Transak `frame-ancestors` cannot authorize arbitrary hosts. Top-level Branding uses `mountIframe`. Override with `localStorage.circlePopup = "true"|"false"`. Cloudsmith: set `CLOUDSMITH_TOKEN` before `npm install` (see README).
Fiat onramp: Asset Details **Buy** and host RPC `onramp({ chainId?, amount? })` open `OnrampView` (Circle AppKit). Sessions come from Relayer `POST /wallet/onramp` — never put the Circle kit key in this SPA. When Branding is nested in a Host iframe (`window.self !== window.top`), UI prefers `openWindow` (prefetch session, then a sync click) because Transak `frame-ancestors` cannot authorize arbitrary hosts. Top-level Branding uses `mountIframe`. Override with `localStorage.circlePopup = "true"|"false"`. Circle App Kit is the public npm package `@circle-fin/app-kit`.

CCTP bridge: Asset Details **Bridge** (native USDC with `useCCTPBridge`) and host RPC `bridge({ amount?, sourceChainId?, destinationChainId? })` open `CCTPBridge`. Source omit → session chain. Burns via `TokenMessengerV2.depositForBurnWithHook` + `cctp-forward` hook through the EIP-7710 relayer (same USDC fee as Send). Destination mint is Circle’s Forwarding Service — no dest-chain signature, no native gas, no BridgeKit.

Expand Down
7 changes: 1 addition & 6 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,8 @@ WORKDIR /app

COPY package.json package-lock.json ./
COPY host/package.json ./host/
COPY .npmrc ./

# Circle @crcl-main/* requires CLOUDSMITH_TOKEN BuildKit secret
RUN --mount=type=secret,id=cloudsmith_token \
CLOUDSMITH_TOKEN="$(cat /run/secrets/cloudsmith_token)" \
npm ci \
&& rm -f .npmrc
RUN npm ci

COPY index.html vite.config.ts tsconfig.json tsconfig.node.json components.json ./
COPY src ./src
Expand Down
15 changes: 0 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,21 +29,6 @@ Production deliverable: a static **nginx** Docker image (no server-side runtime)

## Setup

Circle’s private AppKit canary requires Cloudsmith auth. The repo includes `.npmrc`;
export your token before installing:

```bash
# Linux / macOS
export CLOUDSMITH_TOKEN=<your-cloudsmith-token>
```

```powershell
# Windows PowerShell
$env:CLOUDSMITH_TOKEN = "<your-cloudsmith-token>"
```

CI Docker builds expect GitHub Actions secret `CLOUDSMITH_TOKEN`.

```bash
npm install
cp .env.example .env # set NGROK_AUTHTOKEN (and optional NGROK_DOMAIN)
Expand Down
72 changes: 51 additions & 21 deletions host/src/components/WalletConfiguratorTextTabSigningSections.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,12 @@ export function WalletConfiguratorTextTabSigningSections({
value={form.typedTitle}
onChange={(value) => patch("typedTitle", value)}
/>
<BodyField
id="typed-body"
label="Body"
value={form.typedBody}
onChange={(value) => patch("typedBody", value)}
/>
<TextField
id="typed-sign"
label="Sign"
Expand All @@ -231,6 +237,12 @@ export function WalletConfiguratorTextTabSigningSections({
value={form.typedReject}
onChange={(value) => patch("typedReject", value)}
/>
<TextField
id="typed-signing-hint"
label="Signing hint"
value={form.typedSigningHint}
onChange={(value) => patch("typedSigningHint", value)}
/>
</AccordionContent>
</AccordionItem>

Expand All @@ -243,36 +255,18 @@ export function WalletConfiguratorTextTabSigningSections({
value={form.siweTitle}
onChange={(value) => patch("siweTitle", value)}
/>
<TextField
<BodyField
id="siwe-body"
label="Body"
label="Body ({domain})"
value={form.siweBody}
onChange={(value) => patch("siweBody", value)}
/>
<TextField
id="siwe-estimated-changes"
label="Estimated changes label"
value={form.siweEstimatedChangesLabel}
onChange={(value) => patch("siweEstimatedChangesLabel", value)}
/>
<TextField
id="siwe-no-changes"
label="No changes label"
value={form.siweNoChangesLabel}
onChange={(value) => patch("siweNoChangesLabel", value)}
/>
<TextField
id="siwe-network"
label="Network label"
value={form.siweNetworkLabel}
onChange={(value) => patch("siweNetworkLabel", value)}
/>
<TextField
id="siwe-request-from"
label="Request from label"
value={form.siweRequestFromLabel}
onChange={(value) => patch("siweRequestFromLabel", value)}
/>
<TextField
id="siwe-signing-in-with"
label="Signing in with label"
Expand All @@ -291,6 +285,42 @@ export function WalletConfiguratorTextTabSigningSections({
value={form.siweUriLabel}
onChange={(value) => patch("siweUriLabel", value)}
/>
<TextField
id="siwe-version"
label="Version label"
value={form.siweVersionLabel}
onChange={(value) => patch("siweVersionLabel", value)}
/>
<TextField
id="siwe-nonce"
label="Nonce label"
value={form.siweNonceLabel}
onChange={(value) => patch("siweNonceLabel", value)}
/>
<TextField
id="siwe-issued-at"
label="Issued at label"
value={form.siweIssuedAtLabel}
onChange={(value) => patch("siweIssuedAtLabel", value)}
/>
<TextField
id="siwe-expiration"
label="Expiration time label"
value={form.siweExpirationTimeLabel}
onChange={(value) => patch("siweExpirationTimeLabel", value)}
/>
<TextField
id="siwe-not-before"
label="Not before label"
value={form.siweNotBeforeLabel}
onChange={(value) => patch("siweNotBeforeLabel", value)}
/>
<TextField
id="siwe-resources"
label="Resources label"
value={form.siweResourcesLabel}
onChange={(value) => patch("siweResourcesLabel", value)}
/>
<TextField
id="siwe-reject"
label="Reject"
Expand All @@ -299,7 +329,7 @@ export function WalletConfiguratorTextTabSigningSections({
/>
<TextField
id="siwe-sign"
label="Confirm"
label="Sign in"
value={form.siweSignLabel}
onChange={(value) => patch("siweSignLabel", value)}
/>
Expand Down
68 changes: 68 additions & 0 deletions host/src/components/WalletConfiguratorTextTabWalletSections.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,54 @@ export function WalletConfiguratorTextTabWalletSections({
value={form.confirmTransferReject}
onChange={(value) => patch("confirmTransferReject", value)}
/>
<TextField
id="onramp-title"
label="Onramp title"
value={form.onrampTitle}
onChange={(value) => patch("onrampTitle", value)}
/>
<BodyField
id="onramp-body"
label="Onramp body ({token}, {network})"
value={form.onrampBody}
onChange={(value) => patch("onrampBody", value)}
/>
<TextField
id="onramp-destination-label"
label="Onramp destination label"
value={form.onrampDestinationLabel}
onChange={(value) => patch("onrampDestinationLabel", value)}
/>
<TextField
id="onramp-close"
label="Onramp close"
value={form.onrampCloseLabel}
onChange={(value) => patch("onrampCloseLabel", value)}
/>
<TextField
id="onramp-open"
label="Onramp open"
value={form.onrampOpenLabel}
onChange={(value) => patch("onrampOpenLabel", value)}
/>
<TextField
id="onramp-reopen"
label="Onramp reopen"
value={form.onrampReopenLabel}
onChange={(value) => patch("onrampReopenLabel", value)}
/>
<BodyField
id="onramp-popup-ready"
label="Onramp popup ready hint"
value={form.onrampPopupReadyBody}
onChange={(value) => patch("onrampPopupReadyBody", value)}
/>
<BodyField
id="onramp-popup-opened"
label="Onramp popup opened hint"
value={form.onrampPopupOpenedBody}
onChange={(value) => patch("onrampPopupOpenedBody", value)}
/>
<TextField
id="transfer-tokens-title"
label="Transfer modal title"
Expand Down Expand Up @@ -225,6 +273,26 @@ export function WalletConfiguratorTextTabWalletSections({
value={form.grantPermissionTitle}
onChange={(value) => patch("grantPermissionTitle", value)}
/>
<TextField
id="grant-permission-kind"
label="Grant permission kind (eyebrow)"
value={form.grantPermissionKindLabel}
onChange={(value) => patch("grantPermissionKindLabel", value)}
/>
<TextField
id="grant-permission-amount-label"
label="Grant amount row label"
value={form.grantPermissionAmountLabel}
onChange={(value) => patch("grantPermissionAmountLabel", value)}
/>
<TextField
id="grant-permission-window-label"
label="Grant transfer window label"
value={form.grantPermissionTransferWindowLabel}
onChange={(value) =>
patch("grantPermissionTransferWindowLabel", value)
}
/>
<TextField
id="grant-permission-grant"
label="Grant permission confirm"
Expand Down
2 changes: 1 addition & 1 deletion host/src/constants/signDemo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export const DEFAULT_EIP712_TYPED_DATA = {
domain: {
name: "Ether Mail",
version: "1",
chainId: 421614,
chainId: 84532,
verifyingContract: "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC",
},
types: {
Expand Down
Loading
Loading